1

I've looked at others who had the same problem as me but I'm still not sure what the error is. My program seems to resize small.bmp to large.bmp correctly, but it only passes some checks when ran through check50:

:) resize.c and bmp.h exist
:) resize.c compiles
:) doesn't resize 1x1-pixel BMP when n is 1
:( resizes 1x1-pixel BMP to 2x2 correctly when n is 2
:( resizes 1x1-pixel BMP to 3x3 correctly when n is 3
:) resizes 1x1-pixel BMP to 4x4 correctly when n is 4
:( resizes 1x1-pixel BMP to 5x5 correctly when n is 5
:) resizes 2x2-pixel BMP to 4x4 correctly when n is 2

I don't understand why it would be correct in some situations and incorrect in others? Here is my code:

int main(int argc, char* argv[])
{
// ensure proper usage
if (argc != 4)
{
    printf("Usage: ./resize n infile outfile \n");
    return 1;
}
int n = atoi(argv[1]);
if (n<0 || n>100)
{
    printf("n must be an integer between 1 100, inclusive \n");
    return 1;
}

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

// 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;
}

// create header variables for the outfile
BITMAPFILEHEADER bfOUT;
BITMAPINFOHEADER biOUT;
// copy the values from infile to outfile
bfOUT = bf;
biOUT = bi;

//multiply the values by n
biOUT.biWidth *= n;
biOUT.biHeight *= n;

// determine padding for scanlines of both outfile and infile
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int paddingOUT =  (4 - (biOUT.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// determine size of outfile
biOUT.biSizeImage = ((sizeof(RGBTRIPLE)*biOUT.biWidth) + paddingOUT) * abs(biOUT.biHeight);
bfOUT.bfSize = biOUT.biSizeImage + sizeof(BITMAPINFOHEADER)+ sizeof(BITMAPFILEHEADER);

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

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


// iterate over infile's scanlines
// for each row:
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    // vertical repeats
    for ( int l = 0 ; l < n ; l++)
    {
        // jump over everything read so far
        fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + (i * (bi.biWidth * sizeof(RGBTRIPLE) + padding)), SEEK_SET);
        // write pixels
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;
            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
            // write pixel n times
            for (int k = 0 ; k < (n) ; k++)
            {
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

    }
    // skip padding
    fseek(inptr, padding, SEEK_CUR);
    // add outfile padding
    for (int k = 0; k < paddingOUT; k++)
    {
        fputc(0x00, outptr);
    }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

1 Answer 1

0

I'll try to only give you guidelines instead of straight answers, because you seem to know what you're doing, given that there's only 1 line left to correct in your program.

You need to add paddingOUT for the outfile right after you finish writing one scanline.

But you're doing this: writing the scanline n times and only then adding the paddingOUT.

What you want instead is: write a scanline, add paddingOUT, write scanline again, add paddingOUT... etc.

That's why your program only works when the outfile needs no padding.

1
  • 1
    Wow. That was so simple. Thank you very much!
    – Jeremy Yii
    Commented Oct 20, 2016 at 19:49

You must log in to answer this question.

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