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