0

My code for resize works unless the file I'm resizing requires padding. For the life of me I can't figure out what I'm doing wrong. I've been messing around in gdb for hours. Help and explanations would be much appreciated.

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

    // remember filenames
    char* resize = argv[1];
    char* infile = argv[2];
    char* outfile = argv[3];
    int sizer = atoi(resize);

    if (sizer > 100 || sizer <= 0)
    {
        printf("Resize between 0-100");
        return -1;
    }

    // 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 bi2 and bf2
    BITMAPINFOHEADER bi2 = bi;
    BITMAPFILEHEADER bf2 = bf;

    // determine padding for scanlines
    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int padding2 = (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //adjust bi2
    bi2.biWidth = bi.biWidth*sizer;
    bi2.biHeight = bi.biHeight*sizer;
    bi2.biSizeImage = bi2.biWidth*abs(bi2.biHeight) * sizeof(RGBTRIPLE) + padding2*abs(bi2.biHeight);

    //adjust bf2
    bf2.bfSize = bi2.biSizeImage + 54;

    // write outfile's BITMAPFILEHEADER
    fwrite(&bf2, sizeof(BITMAPFILEHEADER), 1, outptr);
    // write outfile's BITMAPINFOHEADER
    fwrite(&bi2, sizeof(BITMAPINFOHEADER), 1, outptr);



    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        RGBTRIPLE line[bi2.biWidth];
        // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

            // size up horizontally
            for (int n = 0; n < sizer; n++)
            {
                line[sizer*j + n] = triple;
            }

        }
        //Write each line, sizing vertically
        for (int m = 0; m < sizer; m++)
        {
            for (int mm = 0; mm < bi2.biWidth; mm++)
            {
                fwrite(&line[mm], sizeof(RGBTRIPLE), 1, outptr);

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

            // then add it back (to demonstrate how)
            for (int k = 0; k < padding2; k++)
            {
                fputc(0x00, outptr);
            }
        }

    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
2

Two small problems with significant impact. First, the code calculates the output padding before calculating the output file width. This is disrupting the size of the output padding and two header values.

Second, when vertically scaling, the code outputs the current line as many times as necessary, but each time it does, it also skips forward over padding in the input file that many times. It should only do this once.

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

1
  • The first issue I created trying to make my code look organized before sharing. Now I'm banging my head against the table. Thank you for the great explanation, you're the bomb. Aug 22 '16 at 16:06

You must log in to answer this question.

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