0

Could someone please review my code for Resize (Less) pset? My code resized everything correctly before I added a couple of extra variables and changed some things up, so I had some base sizes that worked correctly to work off of. However, even though it seems like the sizes are the same, and the math seems correct (e.g. biSizeImage = 768 and bfSize = 822 on both accounts), the image size stays the same. Any help with this would be greatly appreciated.

// Copies a BMP file

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bmp.h"

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

    int n = atoi(argv[1]);

    if (n < 1 || n > 100)
    {
        fprintf(stderr, "Usage: ./resize n infile outfile\n");
        return 1;
    }

    char *infile = argv[2];
    char *outfile = argv[3];

    // 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 newWidth = bi.biWidth * n;
    int newHeight = bi.biHeight * n;
    int newPadding = (4 - (newWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int oldPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    bi.biSizeImage = (newWidth * sizeof(RGBTRIPLE) + newPadding) * abs(newHeight);
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // write outfile's BITMAPFILEHEADER
    fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);


    // determine padding for scanlines


    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        // iterate over pixels in scanline
        for (int j = 0; j < n; j++)
        {

            for (int k = 0; k < bi.biWidth; k++)
            {
                // temporary storage
                RGBTRIPLE triple;

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

                // write RGB triple to outfile n times
                for (int l = 0; l < n; l++)
                {
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                }
            }
            // add padding
            for (int m = 0; m < newPadding; m++)
            {
                fputc(0x00, outptr);
            }
            // move pointer back
            if (j < n - 1)
            {
                fseek(inptr, -bi.biWidth * sizeof(RGBTRIPLE), SEEK_CUR);
            }
        }
        // skip over padding, if any
        fseek(inptr, oldPadding, SEEK_CUR);
    }
    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

1

The code will work when the scaling factor is 1, but not otherwise.

The problem is straightforward. The code calculates the new biHeight and biWidth values, but it doesn't plug them back into the new headers.

Remember too that the code needs to have both the old and the new values for these vars in order to process the image.

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

5
  • How would I plug these into the headers? Don't the fwrite functions on the following lines write the new headers with the updated values? Commented Jul 25, 2019 at 22:29
  • They do write the headers out, but first, those two fields have to be updated in the header before writing the headers out to the output file. You already did the same thing by updating bi.biSizeImage and bf.bfSize.
    – Cliff B
    Commented Jul 25, 2019 at 22:38
  • Should I redefine BITMAPFILEHEADER and BITMAPINFOHEADER to update them? (e.g. bf = bfOffBits + bfReserved1 + bfReserved2 + bfSize + bfType) Commented Jul 25, 2019 at 22:48
  • Absolutely not! You're overthinking it way too much. The two header structs bi and bf exist and contain all the correct data already, except for the few fields that need to be updated. So just update them! bi.biHeight = [whatever you think it should be changed to];
    – Cliff B
    Commented Jul 26, 2019 at 0:09
  • This fixed the error completely, and I now have a working program. Thank you! Commented Jul 26, 2019 at 13:17

You must log in to answer this question.

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