I'm having trouble making getting to work correctly even though I spent so much on it. I feel it's somewhere in the for loop where I'm storing the RGBTRIPLE in current_row.

Here's my code:

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

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

    // check to see if there is padding in original file (if any) and copy over original height and width (doesn't include padding)
    int input_padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int input_width = bi.biWidth;
    int input_height = bi.biHeight; 

    // change values of biWidth and biHeight according to n and calculate padding and calculate biSizeImage and bfSize
    bi.biWidth = bi.biWidth * n;
    bi.biHeight = bi.biHeight * n;
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    bi.biSizeImage = (bi.biWidth + padding) * bi.biHeight;
    bf.bfSize = sizeof(bi) + sizeof(bf) + bi.biSizeImage;

    // 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 i = 0; i < input_height; i++)
        // make array to hold RGB triple and padding of each row
        RGBTRIPLE current_row[bi.biWidth];

        // iterate over pixels in scanline
        for (int j = 0; j < input_width; j++)
            // temporary storage
            RGBTRIPLE triple;

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

            // Store RGBTRIPLE in current_row
            for (int k = 0, l = j * n; k < n; k += 1, l += 1)
                current_row[l] = triple;

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

        // write the current_row array as many times as needed + padding
        for (int o = 0; o < n; o += 1)
            fwrite(&current_row, sizeof(RGBTRIPLE), bi.biWidth, outptr);
            for (int p = 0; p < padding; p++)
                fputc(0x00, outptr);

Thanks! :)


You have at least three issues to deal with. Because of them, the header is wrong and, for most bmp files, you will never output the actual bitmap content.

First, the header. Look at the following:

bi.biSizeImage = (bi.biWidth + padding) * bi.biHeight;

It has two problems. First,bi.biSizeImage is the size of the image in BYTES, but this line calculates pixels, not bytes. It doesn't account for the actual size of a pixel, so the result is going to be way too small.

Second, you've overlooked the sign of bi.biHeight. The sign of this value determines whether the bitmap is painted from the top down or from the bottom up. Most are negative, which means top down. So, what happens when you have a negative? You end up with a negative biSizeImage.

That leads us to the next problem - no image output. Your for loops write out the image to the output file from line 0 to line "biHeight". With a negative value for the height, the most common form, that means that it will never write out anything for the actual image because the test condition of the for loop will always fail. The big clue on this is that the file size of your output files is 54 bytes, the size of the headers only.

So that gives you something to work on. Once you fix these, I think it will work, but there may still be some latent problems in hiding. If there are, and you can't fix them, well, time for a new question. In the meantime, this will get you going.

If this answers your current question, please accept this answer to remove your question from the unanswered question pool. Let's keep up on forum maintenance. ;-)

  • Perfect!!!!! These were EXACTLY the problems I had! I can't thank you enough! I also learned that I should've concentrated more on the Microsoft Developer Network details about the structs of BITMAPINFOHEADER and BITMAPFILEHEADER.
    – Xiggi
    Jun 20 '15 at 13:22

You must log in to answer this question.

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