0

I can't seem to figure out what's wrong with my resize code - it only resizes correctly for n = 1. I've checked the header data when n = 4 compared to large.bmp, and it's the same. If anyone knows what I'm doing wrong, please let me know.

Edit: I've changed my code to make a new bf and bi, and this almost works, but not quite. If you can see the problem here, please help!

// Resizes a bmp file

#include

#include

#include "bmp.h"

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

// remember filenames
int n = atoi(argv[1]);
//printf("%i", n);
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, nbf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

nbf = bf;

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi, nbi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

nbi = bi;

// 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 ogWidth = bi.biWidth;
// int ogHeight = bi.biHeight;
int ogPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
printf("og Padding: %i\n", ogPadding);

// multiply width and height by n
// this is where the problem is?
nbi.biWidth = bi.biWidth * n;
nbi.biHeight = bi.biHeight * n;

// determine padding for scanlines
int newPadding = (4 - (nbi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4; // Here
printf("new Padding: %i\n", newPadding);

nbi.biSizeImage = ((sizeof(RGBTRIPLE) * nbi.biWidth) + newPadding) * abs(nbi.biHeight); // Here
nbf.bfSize = nbi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

// incorrect because bi.biWidth is still og

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

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

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

    for (int o = 0; o < n - 1; o++)
    {
        printf("Yay %i\n", o);
        // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++) // Here
        {
            // temporary storage
            RGBTRIPLE triple;

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

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

                //printf("in loop %i", p);
            }


        }

        // add padding
        for (int k = 0; k < newPadding; k++)
        {
            fputc(0x00, outptr);
            printf("Padding\n");
        }

        fseek(inptr, -1 * bi.biWidth, SEEK_CUR); // Here

    }

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

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

        // write RGB triple to outfile
        for (int p = 0; p < n; p++){
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            //printf("in loop %i", p);
        }


    }

    // add padding
    for (int k = 0; k < newPadding; k++)
    {
        fputc(0x00, outptr);
        //printf("Padding");
    }

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

    // // Skip back to previous line if necessary
    // int o = (i + 1) % n;
    // printf("o: %i\n", o);

    // if (o > 0)
    // {
    //     int skip = bi.biWidth + ogPadding;
    //     printf("skip: %i\n", skip);
    //     fseek(inptr, -4, SEEK_CUR);
    //     //printf("Gotcha\n");
    // }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

1

You should create a new variable for the width and height of outfile. As you are using the same variable of infile, the compiler may mistakes when adding padding to outfile.

| improve this answer | |
  • Thanks for answering. I've been trying to do what you suggested, but it's still not fully working. Take a look above if you have the time to see what's wrong. Thanks! – Canderson115 Oct 16 '19 at 15:31
  • Could you be more specific on what problem you are facing? Why are there two loops for iterating over pixels in scanline? Remember that you also have to scale up scanline by n times. I would suggest you to store every pixel in scanline into an array, and then write the array n times to the outfile. – Jason Chu Oct 18 '19 at 10:05
  • I switched to the recopy method, like you suggested, and finally got it working. Thanks for all the help! – Canderson115 Oct 24 '19 at 16:58

You must log in to answer this question.

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