0

I'm just trying the "resize horizontally" step for now, but I'm dreadfully confused and can't get it to work. Could someone take a look at my code and nudge me in the right direction? Thank you:

    // Copies a BMP file

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

#include "bmp.h"

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

    // convert second arg to int and assign to N
    int N = atoi(argv[1]);

    // check that second arg is positive int less than or equal to 100
    if (N < 1 || N > 100)
    {
        fprintf(stderr, "Second argument needs to be an integer between 1 and 100\n");
        return 1;
    }

    // remember filenames
    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;
    }

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

    // resize width
    bi.biWidth *= N;

    // resize height
    bi.biHeight *= N;

    // determine padding of resized image
    int resize_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // update biSizeImage
    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + resize_padding) * abs(bi.biHeight);

    // update bfSize
    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);


    // 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 < bi.biWidth; j++)
        {
            // write to outfile for each pixel
            for (int k = 0; k < N; k++)
            {
            // temporary storage
            RGBTRIPLE triple;

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

            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        // write outfile's padding
        for (int l = 0; l < resize_padding; l++)
        {
            fputc(0x00, outptr);
        }
        // skip over infile's padding
        fseek(inptr, padding, SEEK_CUR);
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}
1

I'll give you several nudges. Most of the problems arise from the nested for loop structure being off. For example, the current code writes out padding after writing out every pixel. It should only write out padding at the end of each line.

Next, the code currently reads one pixel and writes one pixel, N times. It should be reading each pixel ONCE and then writing it N times. How is your for loop constructed? What's inside the loop? What should be inside the loop and what shouldn't?

The height and width variables need to be applied properly. Specifically, the input file's width and height parameters need to be used when reading from the input file and not used to write to the output file, and vice-versa.

OK, that should be enough nudges to get you going.

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

1
  • Thank you so much.
    – royloth
    Sep 20 '19 at 1:58

You must log in to answer this question.

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