1

I've looked up previous questions and seen people have also tended to change bfSize as well, but when I did this the image was still unsupported so I changed it back. As such nothing in BITMAPFILEHEADER has been changed. I know there's some problem that occurs when writing the new file headers but I can't see what it is. Also I haven't yet tried to resize the image vertically, only horizontally. Thanks in advance for your help.

#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* infile = argv[2];
    char* outfile = argv[3];

    // remember size
    int n = atoi(argv[1]);

    //ensure size is inbetween 1 and 100
    if (n < 1 || n > 100)
    {
        printf("please enter a n between 1 and 100\n");
        return 5;
    }

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

    // create new values for height and width
    bi_new.biHeight = bi.biHeight * n;
    bi_new.biWidth = bi.biWidth * n;

    // determine padding for scanlines
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int new_padding = (4 - (bi_new.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // determine new image size
    bi_new.biSizeImage = (bi_new.biHeight * sizeof(RGBTRIPLE) + new_padding)
        * abs(bi_new.biHeight); 

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

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

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

            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), n, outptr);
        }

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

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

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}

1 Answer 1

8

The immediate problem lies with your header structures. You have created bi_new and modified two of it's fields, but you forgot to copy the contents of bi to bi_new, so all of the unmodified fields contain garbage data. This is why you're getting the unsupported image error. FYI, whole structures can be copied at once simply by a=b; so that you don't have to copy each structure element one by one.

There are a number of other issues to follow, but I'll let you work through them after you correct the problem above. You should carefully review the pset specification and any class material related to this assignment. Also, start with n=1 and small.bmp. Make sure that the header is copied correctly before moving on to the image handling code. Happy coding!

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

3
  • Thanks, it's solved but just a quick question. If bi and bi_new were both created on the same line, why is it bi was populated with correct data but bi_new was filled with garbage data?
    – roncook
    Commented Sep 18, 2016 at 11:25
  • When they were created, they were not initialized, so both had garbage data. The fread on the next line populated bi.
    – Cliff B
    Commented Sep 18, 2016 at 12:06
  • Oh I understand now, thanks :)
    – roncook
    Commented Sep 18, 2016 at 17:22

You must log in to answer this question.

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