0

I am having trouble figuring out how to place my loops to properly resize the image. Here is what I have:

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

#include "bmp.h"

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

// remember filenames
int scale = atoi(argv[1]);
scale = scale + 1 - 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);
bi.biWidth = bi.biWidth * scale;
bi.biHeight = bi.biHeight * scale;

// 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 * scale) * sizeof(RGBTRIPLE)) % 4) % 4;

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    for (int j = 0; j < scale; j++) {
        // iterate over pixels in scanline
        for (int k = 0; k < bi.biWidth; k++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

            // write RGB triple to outfile
            for (int l = 0; l < scale; l++) {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }
    }
    // skip over padding, if any
    fseek(inptr, padding, SEEK_CUR);

    // then add it back (to demonstrate how)
    for (int m = 0; m < padding; m++)
    {
        fputc(0x00, outptr);
    }
}
// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

What am I doing wrong here?

2 Answers 2

1

There are a number of problems here.

Some of the header elements that need to be recalculated are not.

Header elements from the original are changed, but not saved elsewhere, even though they will be needed to control the input file.

The padding for the input file and the output file are not necessarily the same and each must be calculated separately, using the appropriate header elements for that file.

When replicating each line, the code needs to fseek backwards to the start of the current input line each time that line is replicated.

I recommend starting by testing with ./resize small.bmp s2.bmp` This should produce a file, s2.bmp, that is identical to small.bmp. Get the header right, then get the image right. Next, change 1 to 2 and get that header right before moving on to the image part. (Use the staff version to generate a good result file to compare to.) Use both the peek and xxd tools to look at the data. Don't depend on simply looking at the image.

Also, it is a good idea here to create a separate set of headers for the output file that can be changed, leaving the input file headers intact so that the data in those headers can be used.

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

1
  • p.s. why scale = scale + 1 - 1;??? This serves no purpose.
    – Cliff B
    Jun 8, 2016 at 21:29
0

Needs more fseek. You need to fseek over the padding not only in the original image but also the new resized the image. Also you need to fseek back to the beginning of the line of the original image after you read it for the first time so that it can read that same line from the original image over again for subsequent writes until it writes it the correct number of times.

You must log in to answer this question.

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