0

This code works as expected visually, however when going through check50, it returns an error (resizing with a factor of 2 for example)

"Header field bfSize doesn't match. Expected 0xae, not 0x126"

When going through debug50, bfSize was calculated correctly, and I have already written the changes in before resizing the individual pixels. I have no real lead as to where in the code are the extra bytes being added in somehow.

// Upcales a BMP file according to a scaling factor

// includes removed for visual purposes

int main(int argc, char *argv[])
{
// remember the scaling factor
int scale = atoi(argv[1]);

// ensure proper usage
if (argc != 4 || scale > 100 || scale < 0)
{
    fprintf(stderr, "Usage: resize n infile outfile\n");
    return 1;
}

// remember filenames
char *infile = argv[2];
char *outfile = argv[3];

// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
    fprintf(stderr, "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;
}

// remember infile's padding for scanlines
int inPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// update image width and height according to scaling factor
bi.biWidth *= scale;
bi.biHeight *= scale;

// determine outfile's padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// update image size
bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding) * abs(bi.biHeight);

// update filesize
bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

// 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, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    // array to keep track of the pixels per scanline
    RGBTRIPLE pixels[bi.biWidth];

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

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

        // write to array n times
        for (int k = 0; k < scale; k++)
        {
            pixels[j + k] = triple;
        }
    }

    for (int l = 0; l < scale; l++)
    {
        // write array to outfile
        fwrite(pixels, sizeof(pixels), 1, outptr);

        // write padding to outfile
        for (int m = 0; m < padding; m++)
        {
            fputc(0x00, outptr);
        }
    }

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

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;
}

1 Answer 1

3

Well, your description is sort of right. The image size is incorrect.

When I ran the code, the headers are fine. The problem is that the image data that's being generated is too large by roughly the value of scale.

In your for loop, why are you using the biHeight value for the output file to control the reading of the input file????

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

1
  • Didn't notice that, works like a charm now! Thanks. Marked as solution Commented May 3, 2018 at 4:10

You must log in to answer this question.

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