0

Using check50 to ensure my code is correct, I get this strange error in red. Could anyone help me find out what the issue is?

:) resize.c and bmp.h exist

:) resize.c compiles

:) doesn't resize 1x1-pixel BMP when n is 1

:( resizes 1x1-pixel BMP to 2x2 correctly when n is 2

:( resizes 1x1-pixel BMP to 3x3 correctly when n is 3

:( resizes 1x1-pixel BMP to 4x4 correctly when n is 4

:( resizes 1x1-pixel BMP to 5x5 correctly when n is 5

:( resizes 2x2-pixel BMP to 4x4 correctly when n is 2

This is the code.

/**
* Copies a BMP piece by piece, just because.
*/

#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 n infile outfile\n");
    return 1;
}

// remember filenames
int n =atoi(argv[1]);
char *infile = argv[2];
char *outfile = argv[3];

if (n>100 || n<0)
{
    fprintf(stderr, "Please input a valid number.");
    return 5;
}

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

// outfile's file and info headers declared
BITMAPFILEHEADER outbf=bf;
BITMAPINFOHEADER outbi=bi;

// width and height of the outfile
outbi.biWidth=bi.biWidth*n;
outbi.biHeight=bi.biHeight*n;

// padding for infile and outfile
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int outpadding = (4 - (outbi.biWidth)*sizeof(RGBTRIPLE) % 4) % 4;

// biSizeImage for outfile
outbi.biSizeImage=((sizeof(RGBTRIPLE) * outbi.biWidth) + outpadding) * abs(outbi.biHeight);

// bfSize for outfile
outbf.bfSize=outbi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

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

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

// length of the infile line in bytes
int seeknum = bi.biWidth * sizeof(RGBTRIPLE);

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    // vertical resizing
    for (int v = 0; v<n;v++)
    {
        // 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);

            // horizontal resizing
            for (int h = 0; h<n;h++)
            {
                // 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 (to demonstrate how)
        for (int k = 0; k < outpadding; k++)
        {
            fputc(0x00, outptr);
        }

        fseek(inptr, -seeknum, SEEK_CUR);
    }
    fseek(inptr, seeknum, SEEK_CUR);
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;
}
0

The problem is that the image data isn't being processed correctly. Note that the program works when the scaling factor n is 1. Using the peek tool shows that when n > 1, the headers are correct, so all that is good.

When n>1, and you look at the image data with the xxd tool, the image data is not correct. Looking closer, there's a pattern to how the data is off. The image data is shifted left by a fixed number of bytes on each line, depending on the value of n. This implies that when the code processes each line, the fseek call is not repositioning the filepointer correctly in the input file. It's coming up short.

Have you accounted for everything that exists on each line in the image data, including pixels and padding?

If you still can't figure it out, leave a comment and I'll give you a big push in the right direction, but this should get you going.

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

| improve this answer | |
  • Oh, just forgot to account for the padding. Thanks alot! – Harry Jun 29 '17 at 23:23

You must log in to answer this question.

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