0

Yet again I have a problem with my resize.c problem. The output file is only correct, when no padding is needed(when the width is a multiple of 4). This can be approved by the check50 output(https://sandbox.cs50.net/checks/d4d2b8f94e1b4cf2b7224817893728ab). I think I have a problem with my fseek calls, but I can't really locate it. Here is my code.

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

#include "bmp.h"

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

// remember filenames
char* infile = argv[2];
char* outfile = argv[3];

// remembers factor to resize
int n = atoi(argv[1]);
if (n <= 0 || n > 100)
{
    printf("n must be a positive integer less than or equal to 100\n");
    return 2;
}

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
    printf("Could not open %s.\n", infile);
    return 3;
}

// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 4;
}

// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bfold;
fread(&bfold, sizeof(BITMAPFILEHEADER), 1, inptr);

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

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bfold.bfType != 0x4d42 || bfold.bfOffBits != 54 || biold.biSize != 40 || 
    biold.biBitCount != 24 || biold.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 5;
}

// creates new headers
BITMAPFILEHEADER bfnew = bfold;
BITMAPINFOHEADER binew = biold;

// calculates resized dimensions
binew.biWidth = biold.biWidth * n;
binew.biHeight = biold.biHeight * n;

// determines padding for the new image
int padding_new = (4 - (binew.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// updates headers for the outfile
binew.biSizeImage = (binew.biWidth * abs(binew.biHeight) * sizeof(RGBTRIPLE)) + (padding_new * abs(binew.biHeight) * sizeof(RGBTRIPLE));
bfnew.bfSize = 54 + binew.biSizeImage;

// calculates the old padding
int padding_old = (4 - (biold.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

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

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

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(biold.biHeight); i < biHeight; i++)
{
    // resize vertically
    for (int a = 0; a < n; a++)
    {
        // iterate over pixels in scanline
        for (int j = 0; j < biold.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

            // write RGB triple to outfile as many times as needed(resize horizontally)
            for (int l = 0; l < n; l++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        // fseek
        if (a == n - 1)
        {
            fseek(inptr, padding_old, SEEK_CUR);
        }
        else
        {
            fseek(inptr, -biold.biWidth * sizeof(RGBTRIPLE), SEEK_CUR);
        }

        // add padding
        for (int k = 0; k < padding_new; k++)
        {
            fputc(0x00, outptr);
        }
    }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

Any help would be appreciated. Thanks.

1 Answer 1

1

It would be easy to say what the problem is, but what fun would that be for you? ;-)

The problem is only indirectly related to padding. You still don't have your header calculations right. When you work on them, think carefully about the units of measure used by each variable in the calculations.

It sounds vague, but when you figure it out, it'll make perfect sense. ;-)

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

You must log in to answer this question.

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