1

For the past couple of days, I have been struggling with Resize (less comfortable). I have looked at similar questions and I've been able to fix some problems yet my largest one remains the same: my image format is invalid whenever I multiply by a factor greater than 1. My code works perfectly when I resize by a factor of 1, and peek shows that my header is fine. I'm not quite sure what I'm missing. All help would be appreciated and I would love detailed explanations as to why my code isn't working and what changes would help.

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

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

// 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;
}
bi.biWidth = bi.biWidth * n;
bi.biHeight = bi.biHeight * n;
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int padding2 =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = ((sizeof(RGBTRIPLE)*(bi.biWidth)+padding2)*(bi.biHeight));
bi.biSize = bi.biSizeImage + 54;

// write outfile's BITMAPFILEHEADER
fwrite(&bfh, sizeof(BITMAPFILEHEADER), n, outptr);

// write outfile's BITMAPINFOHEADER
fwrite(&bih, sizeof(BITMAPINFOHEADER), n, outptr);

// iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
    // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), n, outptr);
        }

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

    // then add it back (to demonstrate how)
    for (int k = 0; k < padding2; k++)
    {
        fputc(0x00, outptr);
    }
}
// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

Updated section of code:

bi2.biWidth = bi.biWidth * n;
bi2.biHeight = bi.biHeight * n;
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int padding2 =  (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi2.biSizeImage = (((sizeof(RGBTRIPLE)*(bi2.biWidth))+padding2)*abs(bi2.biHeight));
bi2.biSize = bi2.biSizeImage + sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);

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

// write outfile's BITMAPINFOHEADER
fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);
2
+50

There is a significant flaw in the code. The header vars are changed (probably correctly) but then stored in the original headers for the input file, bi, bf. Then the output file headers are written out to the output files, bih and bfh.

This has led to input and output header fields being intermixed in both being written out to files and used in the code. It's hiding some errors and causing others.

Once this is dealt with, you should have the opportunity to continue debugging and then if you have additional problems, post any new questions that you may have.

[EDIT] The header continues to have issues. The fields being updated need to be examined closely. Some of the fields have very similar names. One of those fields, one that must never be changed, has been altered. Another is incorrectly calculated. There may be more issues, but you should discover and fix all the issues yourself in order to improve your debugging skills.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

3
  • Thanks! I should've noticed that! I changed my code to now say: bih.biWidth = bi.biWidth * n; bih.biHeight = bi.biHeight * n; // determine padding for scanlines int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; int padding2 = (4 - (bih.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; bih.biSizeImage = ((sizeof(RGBTRIPLE)*(bih.biWidth)+padding2)*(bih.biHeight)); bih.biSize = bih.biSizeImage + 54; So now my code should read the infile as bi & bf and store as bih & bfh. However, I'm still seeing that it is invalid image format. I'm not sure what else I'm missing. – Tenacity Feb 28 '18 at 15:57
  • See edited answer. – Cliff B Mar 19 '18 at 20:35
  • A week or so ago I updated my code and posted a new question. This question contains my older code but I have my new header code under my updated section. I fixed the calculation of the size and I changed how the padding was calculated so that padding and padding2 are different (unlike my original code). My image is still invalid. I apologize for needing so much help but I really have been struggling on this problem set. Thanks – Tenacity Mar 20 '18 at 15:12

You must log in to answer this question.

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