0

Just got stuck on PSET4's resize.c. Had a look through available threads on it, and found out that I have a standard problem - it just doesn't work as it is expected to! LOL.

My guess is that there's a problem with the way i'm using "fseek". I wanted it just to "move the cursor" to the beginning of the loop and make a one more scanline for me... but instead of this i get a distorted picture in the output file. Probably, there are more bugs.

I would appreciate any help so much.

Thank you in advance, guys.

My code is below.

#include <stdio.h>
#include <stdlib.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
char* factor = argv[1];
char* infile = argv[2];
char* outfile = argv[3];


// factor 
int n = atoi(factor); 
if (n <= 0 || n >= 100)
{
    printf("Factor must be a positive integer less than or equal to 100");
    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 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;
}

// remember input file's original headers
int in_biWidth = bi.biWidth;
int in_biHeight = bi.biHeight;

// remember input file's original padding
int in_padding = (4 - (in_biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

// define output file's headers

bi.biWidth = (bi.biWidth * n);
bi.biHeight = (bi.biHeight * n);

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

bi.biSizeImage = ((bi.biWidth  * sizeof(RGBTRIPLE) + padding) * abs(bi.biHeight)); // bi.SizeImage also includes padding!

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(in_biHeight); i < biHeight; i++)
{
    // iterate over pixels in scanline
    for (int j = 0; j < in_biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

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

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

    // height loop

    for (int l = 0; l < n - 1 ; l++)
    {
        fseek(inptr, -in_biWidth * sizeof(RGBTRIPLE), SEEK_CUR); 

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

    }

    // skip padding for input file
    fseek(inptr, in_padding, SEEK_CUR);    

}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}
1

You have a couple of problems going on. Without giving away the game, you should run your program with resize = 1 and compare the output file to the input file and see what is different. With resize = 1, the two files should be identical.

Start by comparing the headers with the peek tool and seeing what is different. If the headers are wrong, the image is probably going to be wrong too. When you see that something in the headers differs, look at the code that modifies the bad values.

Once you get the header right, work on getting the image right for a scale of 1. Don't depend on a visual inspection of the image. Inspect the output file image using the xxd tool and compare it to the input file.

Only after that is right, change to a scale of 2 and go back through the process.

Also, I see that you calculate the padding once. Are you aware that the padding has to be calculated for both the input file and the output file? Depending on the scaling factor, they are probably different.

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

1
  • thank you very much for your answer. I fixed a lot of stuff in my code thanks to you. And i uploaded the new code to the original message of this thread. 1) Fixed the headers, checked with peek tool, it is ok now. 2) Got the correct image with factor of 1, passed the diff tool. But it still is not working properly for other factors. Could you please give me another hint?
    – ruthless_g
    Jan 5 '16 at 18:28

You must log in to answer this question.

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