0

Hi guys I've scratched my head about this for a week now and I'm struggling to see what the issue is. The smiley.bmp file seems to be resizing correctly but not the others. Can anyone offer some kinda hint to what I'm not getting here? Any guidance would be greatly appreciated.

Below is my code so far

// 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 amount infile outfile\n");
        return 1;
    }

    // remember filenames
    int n = atoi(argv[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;
    }


    //create new outfile header files
    BITMAPFILEHEADER bfNew = bf;
    BITMAPINFOHEADER biNew = bi;

    //adjust outfile's width and height
    biNew.biWidth = bi.biWidth * n;
    biNew.biHeight = bi.biHeight * n;

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

    //calculate new padding amount
    int paddingOutfile = (4 - (biNew.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //adjust outfile's image size and file size
    biNew.biSizeImage = ((sizeof(RGBTRIPLE)*biNew.biWidth) + paddingOutfile) * abs(biNew.biHeight);
    bfNew.bfSize = biNew.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);


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

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

    // temporary storage for each individual pixel
    RGBTRIPLE triple;


    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        //rewrite row's n - 1 times
        for (int row = 0; row < n; row ++)
        {

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

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

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

            }

            // skip over infile's padding, if any
            fseek(inptr, paddingInfile, SEEK_CUR);

            // add any required padding to outfile
            for (int l = 0; l < paddingOutfile; l++)

            {
            fputc(0x00, outptr);
            }

            //Move cursor back to start of the row
            if (row < (n - 1))
            {
            fseek(inptr, -(bi.biWidth * sizeof(RGBTRIPLE)), SEEK_CUR);
            }
        }

    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

0

After each line from the input file is read, the code moves forward over the padding.

When you move backwards in the input file to repeat a line, are you considering the size of the input line's padding?

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

3
  • You sir are a legend thanks! I was thrown off by another post I'd read discussing not considering input line's padding as it was skipped but I that would still leave the cursor after any padding, correct?
    – GFitzP
    Mar 30, 2020 at 21:18
  • Ordinarily, one would either move back to the beginning of the input line or move forward past the padding. Your approach involved moving forward always and moving back when needed. That's why the other posts probably confused you. I bet this sticks in your mind forever! ;-)
    – Cliff B
    Mar 30, 2020 at 21:35
  • I hope so! Cheers bud
    – GFitzP
    Mar 30, 2020 at 21:38

You must log in to answer this question.

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