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

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? Jul 25 '19 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
    Jul 25 '19 at 22:38
  • Should I redefine BITMAPFILEHEADER and BITMAPINFOHEADER to update them? (e.g. bf = bfOffBits + bfReserved1 + bfReserved2 + bfSize + bfType) Jul 25 '19 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
    Jul 26 '19 at 0:09
  • This fixed the error completely, and I now have a working program. Thank you! Jul 26 '19 at 13:17

You must log in to answer this question.

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