0

I'm on problem set 4 and stuck on resize.c, it works perfectly...
As long as you don't need any padding, then you get some weird results. (Messed up colors)
I can't tell what's wrong!, please help.

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

#include "bmp.h"

int main(int argc, char* argv[])
{
// ensure proper usage
if (argc != 4)
{
    printf("Usage: ./resize n 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)
{
    printf("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);

int padding2 =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

bi.biSizeImage = pow(bi.biSizeImage, n);
bi.biWidth *= n;
bi.biHeight *= n;


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

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

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

// determine padding for scanlines
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
printf("Padding: %i",padding);

int length = 0;
fpos_t lineStart;
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    fgetpos(inptr, &lineStart);
    for (int m = 0; m < n; m++)
    {
        fsetpos(inptr,&lineStart);
        length = 0;
        // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

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

        }

         //printf("%i\n",length);

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

        // then add it back (to demonstrate how)
        for (int l = 0; l < padding; l++)
        {
            fputc(0x00, outptr);
        }
    }
    fseek(inptr, padding, SEEK_CUR);
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;

}

1
  • Your formula for calculating the new bi.biSizeImage looks wrong, remember padding doesn't grow exponentially as the rest of the image bytes. – dLopez Aug 1 '16 at 21:24
1

This code is far from perfect. It incorrectly calculates biSizeImage. biSizeImage cannot simply be raised to a power. The biSizeImage of the new file must be calculated using the new padding size, height and width.

Next, the image scaling requires the use of the original biHeight and biWidth to track the input file, which have been overwritten and lost. You should consider creating a second set of headers for the output file so that you preserve the original values while calculating the new ones. While it is possible to save the few original values that need to be preserved, it's much safer to create a second set of headers.

Finally, it skips over the input file's padding twice, so only the first line comes out right. After that, the code is out of synch with the image.

There may be other issues, but these issues need to be addressed first.

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 .