0

I am unable to figure out what I am lacking or doing wrong in my code. The output image large.bmp becomes just some random colors. Hopefully, someone can guide me here.

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

#include "bmp.h"

int factor;

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

factor = atoi(argv[1]);
if (factor<0 || factor >100)
{
    fprintf(stderr, "Provide an integer between 1 and 100.\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;
}

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

BITMAPFILEHEADER new_bf;
new_bf = bf;

BITMAPINFOHEADER new_bi;
new_bi = bi;

new_bi.biHeight *= factor;
new_bi.biWidth *= factor;
int new_padding = (4 - (new_bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

new_bi.biSizeImage = ((sizeof(RGBTRIPLE) * new_bi.biWidth) + new_padding) * abs(new_bi.biHeight);
new_bf.bfSize = new_bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

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

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



// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    RGBTRIPLE array[new_bi.biWidth];
    int counter = 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);

        for (int m = 0; m<factor; m++)
        {
            array[counter] = triple;
            counter++;
        }


        for (int p = 0; p < factor; p++)
        {
            for (int l = 0; l < sizeof(new_bi.biWidth); l++)
            {
                fwrite(&array[l], sizeof(array), 1, outptr);
            }


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

        }
    }

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

}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

0

Let's see what you are doing with the first pixel. Suppose you resize small.bmp with factor = 2.

  1. read from infile 1 pixel
  2. put this pixel in the first two elements of array

Now, it would be quite logically to go to the next pixel and continue to fill array. Instead, you do quite odd thing:

  1. you go to the address &array[0]
  2. take starting from this address sizeof(array) = new width * sizeof(RGBTRIPLE) = 6 * 3 = 18 bites or 6 pixels
  3. write these 6 pixels to outfile
  4. repeat sizeof(new_bi.biWidth) = 4 times
  5. add padding and go to the second pixel.

For now, you read just 1 pixel from infile but write 6 * 4 = 24 pixes in outfile.

You need to rethink your logic but before make clear for yourself what sizeof(x) does.

It returns size in bytes that is reserved for variable x. It does not depend on x value, it depends on type of x only. For example, sizeof(new_bi.biWidth) is always 4 as the type is uint32_t.

1
  • Thank you so much. It works now. – jurum Jul 8 '17 at 13:47

You must log in to answer this question.

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