0

I've browsed through the other solutions to this problem but I couldn't find why mine code isn't working. I compared my header output to a staff solution and it was the same, as well as the size of the image area in the program. I think I'm having a problem with the padding calculation or output but I can't figure out why. Any suggestions?

int main(int argc, char *argv[])

// ensure proper usage
if (argc != 4)
{
    fprintf(stderr, "Usage: ./copy n infile outfile\n");
    return 1;
}// remember filenames
int n = atoi(argv[1]);
char *infile = argv[2];
char *outfile = argv[3];

if (n > 100) {
    fprintf(stderr, "Please enter a value for n that is 100 or less.");
}

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

int oldPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int oldBiWidth = bi.biWidth;
int oldBiHeight = bi.biHeight;
bi.biWidth = bi.biWidth * n;
bi.biHeight = bi.biHeight * n;

int posBiHeight;

if (bi.biHeight < 0) {
    posBiHeight = bi.biHeight * -1;
}

int newPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE) ) % 4) % 4;

if (newPadding != 0) {
    bi.biSizeImage = ( ( (bi.biWidth * posBiHeight) * 3 )  + (newPadding * 3 * posBiHeight) );
}

else if (newPadding == 0){
    bi.biSizeImage = (bi.biWidth * posBiHeight) * 3;
}

bf.bfSize = bi.biSizeImage + 54;

// 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(oldBiHeight); i < biHeight; i++) {

    //vertical resizing n times per row
    for (int p = 0; p < n - 1; p++) {

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

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

            for (int k = 0; k < n; k++) {
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        for (int m = 0; m < newPadding; m++) {
            fputc(0x00, outptr);

        }

        fseek(inptr, (oldBiWidth * -3), SEEK_CUR); 
    }


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

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

            for (int k = 0; k < n; k++) {
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        for (int m = 0; m < newPadding; m++) {
            fputc(0x00, outptr);

        }

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


}


// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

0

biSizeImage will only be correct if padding is 0. Why? biSizeImage is measured in bytes. Since biWidth is measured in pixels, you need a factor of 3 (* 3) to convert it to bytes. But newPadding is already measured in bytes. Check the equation here bi.biSizeImage = ( ( (bi.biWidth * posBiHeight) * 3 ) + (newPadding * 3 * posBiHeight) );

There is another problem, which may not be evident from your testing or check50. What is the value of posBiHeight; if bi.biHeight is positive? Try this program with clue.bmp from the whodunit exercise to see what happens.

| improve this answer | |
  • Great answer. Didn't even notice the issue with posBiHeight. Thanks a lot. – George Wright May 12 '17 at 14:38

You must log in to answer this question.

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