0

my code does not seem to work and I can't figure out the problem. When I executed it using a factor of 4, the program created some weird image. Any help is appreciated, including any tips on better code design. Thanks

    /**
 * Resizes a BMP by a factor chosen by the user
 */

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

#include "bmp.h"

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

//check factor provided by user after converting argv[1] to float
float factor = atof(argv[1]);
if (factor <= 0 || factor > 100)
{
    fprintf(stderr, "Usage: Input a number between the values of \n");
    return 1;
}

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

// determine padding for input file
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

//define BITMAPINFOHEADER AND BITMAPFILEHEADER for outptr and initialise it
BITMAPFILEHEADER outputbf;
BITMAPINFOHEADER outputbi;

//copy the BITMAPINFOHEADER and BITMAPFILEHEADER from inptr to outptr
outputbi = bi;
outputbf = bf;

//change the height and width of the output file
outputbi.biHeight = (bi.biHeight * factor);
outputbi.biWidth = (bi.biWidth * factor);

// determine padding for output file
int outputpadding = (4 - (outputbi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;


//change biSize and bfSize
outputbi.biSizeImage = (((sizeof(RGBTRIPLE) * outputbi.biWidth) + outputpadding) * abs(outputbi.biHeight));
outputbf.bfSize = outputbi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

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

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

//temporary storage one array with each element being a pixel
RGBTRIPLE *input_scanline;
input_scanline = malloc(sizeof(RGBTRIPLE) * bi.biWidth);

// iterate over infile's scanlines (ie resizing height)
for (int i = 0, j = 0, biHeight = abs(outputbi.biHeight); i < biHeight; i++)
{
    //each scanline in the outfile corresponds to a pixel in infile using formula newline[n] = oldline[n/factor]
    //if they are the same 
    if ((int)(i / factor) == j)
    {
        fread(input_scanline, sizeof(RGBTRIPLE), bi.biWidth, inptr);

        // iterate over pixels in scanline
        for (int k = 0, l = 0; k < outputbi.biWidth; k++)
        {
            //each pixel in the outfile corresponds to a pixel in the infile using formula newpixel[n] = oldpixel[n/factor]
            //if they are the same
            if ((int)(k / factor) == l)
            {
                //temporary storage
                RGBTRIPLE triple;
                //assigning the correct pixel in the input_scanfile array to triple
                triple = input_scanline[l];
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }

            else 
            {
                //if the pixels do not correspond, cycle through l to get to the correct pixel on the scanline
                while ((int)(k / factor) != l)
                {
                    l++;
                }

                //temporary storage
                RGBTRIPLE triple;
                //assigning the correct pixel in the input_scanfile array to triple
                triple = input_scanline[l];
                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

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

        // then add it back 
        for (int k = 0; k < outputpadding; k++)
        {
            fputc(0x00, outptr);
        }
    }

    //same principle with the corresponding pixels. If lines do not correspond, run through the lines of the inptr until ... 
    //both match
    else 
    {
        while ((int)(i / factor) != j)
        {
            j++;
        }
        //to ensure that the for loop repeats this newline number again.
        i--;

        //offsets to the correct location in inptr
        fseek(inptr, (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + j * (sizeof(RGBTRIPLE) * bi.biWidth + padding)), 
SEEK_SET);
    }
}

//free memory used earlier
free(input_scanline);

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

-3

Ok nevermind I solved it the order of the code was wrong

1
  • Glad you found the solution. Now, can you please put more detail in your answer and then accept your answer? Otherwise, it will remain in the unanswered question pool forever.
    – Cliff B
    Feb 16 '17 at 19:50

You must log in to answer this question.

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