0

CS50 Pset4 Resize Padding. again I need help! I got lost The code creates a scalable bmp file but is distorted. I think there is a mistake with padding

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./resize n infile outfile\n");
        return 1;
    }

    // scaling option  
    int scaleN = abs(atoi(argv[1])); // atoi - convert string to an int
    if (scaleN < 0 || scaleN > 100)
    {
        printf("n must be an integer berween 1 & 100");
        return 2;
    }

    // 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 bfIn;
    fread(&bfIn, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER biIn;
    fread(&biIn, sizeof(BITMAPINFOHEADER), 1, inptr);

    // ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bfIn.bfType != 0x4d42 || bfIn.bfOffBits != 54 || biIn.biSize != 40 || 
        biIn.biBitCount != 24 || biIn.biCompression != 0)
    {
        fclose(outptr);
        fclose(inptr);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }

    // set outfile's BITMAPFILEHEADER
    BITMAPFILEHEADER bfOut = bfIn;
    bfOut.bfSize = bfIn.bfSize * scaleN * scaleN;
    // set outfile's BITMAPINFOHEADER
    BITMAPINFOHEADER biOut = biIn;
    biOut.biWidth = biIn.biWidth * scaleN;
    biOut.biHeight = biIn.biHeight * scaleN;

    // determine padding for scanlines
    int paddingIn =  (4 - (biIn.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int paddingOut =  (4 - (biOut.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    biOut.biSizeImage = (biOut.biWidth * sizeof(RGBTRIPLE) + paddingOut) * abs(biOut.biHeight);

    // 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 (int i = 0, biHeight = abs(biIn.biHeight); i < biHeight; i++)
    {
        // temporary storage
        RGBTRIPLE triple[biIn.biWidth];

        // iterate over pixels in scanline
        for (int j = 0; j < biIn.biWidth; j++)
        {
            // read RGB triple from infile
            fread(&triple[j], sizeof(RGBTRIPLE), 1, inptr);
        }

        // write multiple line 
        for (int l = 0; l < scaleN; l++)
        {
            for (int j = 0; j < biIn.biWidth; j++)
            {

                // write RGB triple to outfile
                for (int s = 0; s < scaleN; s++)
                {
                    fwrite(&triple[j], sizeof(RGBTRIPLE), 1, outptr);
                }
            }

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

            // then add it back (to demonstrate how)
            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

2

If you look at the actual data of the output file, certain patterns become obvious. Say that the input file is being scaled up to 2. The first line from the input file is being scaled up correctly, and is being done twice correctly. But the first problem appears next. If you look at the output for the second line from the input file (the third line in the output file), it doesn't start where it should. It starts further on.

That means that somehow, the input file pointer has moved too far. In fact, it's moved the same distance as the input file padding.

Take a close look at where the code skips over the input padding. How many times does it execute? Why? Where is it with respect to for loop placement? ;-)

This should get you going. There's another minor bug, but it's an easy fix and unrelated to this question. You'll fix it easy enough.

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

1
  • thanks for the advice. code works. Sincerely, Igor Commented Feb 16, 2019 at 17:58

You must log in to answer this question.

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