0

I'm on Pset4's Resize (less comfortable), using the recopy method. When I plug in small.bmp and resize it with a scale factor of 2, I get a black block in the middle. With any higher scale factors, it prints excess padding at the end, which shows up as black pixels. Even with a scale factor of 1, I'm getting a black block in the middle. Any idea why this is happening? Code shortened for readability, missing lines are just error-checking. In case it wasn't apparent, scale_f is the scale factor.

    //set the infile's padding
    int inf_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //scale the BITMAPINFOHEADER
    bi.biWidth *= scale_f;
    bi.biHeight *= scale_f;

    // determine padding for new file
    int new_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //finish scaling the BITMAPINFOHEADER
    bi.biSizeImage = sizeof(RGBTRIPLE) * bi.biWidth * abs(bi.biHeight) + (new_padding * abs(bi.biHeight));

    //scale the BITMAPFILEHEADER
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);

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

        //iterate over the scanline scale_f times
        for (int h = 0; h < scale_f; h++)
        {

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

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

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

            }

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

            //go to the beginning of the scanline
            if (h < scale_f){
                fseek(inptr, -bi.biWidth/scale_f, SEEK_CUR);
            }else{
                // skip over padding, if any
                fseek(inptr, inf_padding, SEEK_CUR);
            }
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

0

Your fseek back is missing the factor sizeof(RGBTRIPLE).

Guess you meant if (h < scale_f - 1) instead of if (h < scale_f), as the last iteration is with h of value scale_f - 1.

I don't like this approach, and would do it more like

repeat scale_f times
    read input line, write horizontally resized line
    write output padding
    go back to beginning of input line
end repeat
skip forward for a complete line, pixels plus input padding

or

read input line into an array
repeat scale_f times
    write horizontally resized line
    write output padding
end repeat
skip input padding

Both would go without any if in the loop. There would be a difference only if you were using a factor that can become zero or negative, as your code relies on the loop being run at least once. With all possible values being >0, it's probably less relevant.

You must log in to answer this question.