0

Update: I changed everything, what was mentioned, however it is not working yet. Maybe my assumption was wrong that the headers are updating correctly, when i run peek, i see green numbers... Has anyone an idea, what is wrong with the code? The program is running, but the output is wrong

thank you for helping me!

/**
 * copy.c
 *
 * Computer Science 50
 * Problem Set 5
 *
 * Copies a BMP piece by piece, just because.
 */

#include <stdio.h>
#include <stdlib.h>

#include "bmp.h"

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./copy infile outfile\n");
        return 1;
    }

    // remember filenames
    char* infile = argv[2];
    char* outfile = argv[3];
    int n = atoi(argv[1]);

    //check for proper usage 
    while(n < 1 && n > 100)
    {
        printf("Give a range from 1 to 100!\n");
        return 1;
    }

    // open input file 
    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE* outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 3;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi;
    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);


    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }

    // New BITMAPFILEHEADER & BITMAPINFOHEADER
    BITMAPFILEHEADER bf_new;
    BITMAPINFOHEADER bi_new;
    bf_new = bf;
    bi_new = bi;

    // New Dimensions
    int bi_newbiWidth = n*bi.biWidth;
    int bi_newbiHeight = n*bi.biHeight;

    //calculate padding
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int padding_new = (4 - (bi_newbiWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // Sizes
    bi_new.biSizeImage = bi.biSizeImage * n;
    bf_new.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (bi.biSizeImage * n);

    // write outfile's BITMAPFILEHEADER
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);

    // iterate over infile's scanlines
    for (int a = 0, biHeight = abs(bi.biHeight); a < biHeight; a++)
    {
        //setting position
        fpos_t position;
        fgetpos(inptr, &position);

        //executing each line n times
        for (int b = 0; b < n; b++)
        {    
            //get back to position
            if(b < n)
                fsetpos(inptr, &position);

            // iterate over pixels in scanline
            for (int c = 0; c < bi.biWidth; c++)
            {
                // temporary storage
                RGBTRIPLE triple;

                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

                // write RGB triple to outfile multiplied by n
                for(int d = 0; d < n; d++)
                {
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);  

                }
            }
            // skip over padding, if any
            fseek(inptr, padding, SEEK_CUR);

            // add padding
            for(int e = 0; e < padding_new; e++)
                fputc(0x00, outptr);


        }   


    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
1

Since you claim that the headers are updated correctly, I'll ignore the part on the headers and concentrate on the resizing part. Here what caught my eyes

  1. Your new padding is the same as the old padding -- they're calculated identically.

  2. In your first nested for loop, you're iterating as long as b < n - 1. Meanwhile, if n = 2, you're iterating only a single time (because b = 1 is NOT less than n - 1 which in this case would be 1 either).

  3. You're repeating the same logical error as 2 in the third nested loop -- the one that uses the variable named d as the counter.

  4. You probably can't rely on the method you're using to seek back to the beginning of the current scanline because after you correct the number of iterations in 2 and 3, the loop will exit once b is equal to n. So inside the loop, b is always less than n. Alternatively, maybe you should set the file position indicator to be at the beginning of the current scanline at the beginning of the loop, but be wary that in the first iteration of this loop, this should be done differently because, obviously, if you were at the beginning of the current scanline, you wouldn't wanna seek -bi.biWidth * sizeof(RGBTRIPLE) bytes back.

  5. After ensuring the new padding is calculated correctly, make sure you're using the old and the new padding each where it should be used in the program. Don't mix them -- use the old padding where you should use the new one and vice-versa.

Hope that helps!


Update #0: unfortunately, your claim about the headers being correct appears to be wrong.

First of all, you did not update the members of bf_new and bi_new that should be updated.

You're basically writing the headers of "old" BMP into the new BMP which is definitely not correct, giving that some of their data are not the same.

Also, pay attention to biHeight when using it in calculations because it's negative!

You appear to be not calculating the biSizeImage and the bfSize correctly. You probably should think again about their formulas. Recall that biSizeImage is the number of bytes in the image itself (i.e., the pixels) including the padding! Recall also that bfSize is the size of the BMP file as a whole — biSizeImage + the size of the headers.

Lastly, n can't be < 1 AND > 100 at the same time. That's logically invalid.

4
  • ok, i changed it, but somehow it is still not working... maybe i got something in the header wrong, however when i run "peek", it is fine...
    – user1638
    Sep 14 '14 at 10:45
  • @user1638 You may update your question with the things you modified!
    – kzidane
    Sep 14 '14 at 11:27
  • i did so. thank you
    – user1638
    Sep 14 '14 at 13:36
  • @user1638 updated the answer! Please let me know if something is not clear or if you have any follow ups!
    – kzidane
    Sep 14 '14 at 15:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .