0
/**
 * resize.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 *resizes 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)
    {
        printf("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 < 1 && n > 100)
    {
        printf("Invalid input!!!");
        return 2;
    }

    // open input file 
    FILE* inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        printf("Could not open %s.\n", infile);
        return 3;
    }

    // open output file
    FILE* outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 4;
    }

    // read infile's BITMAPFILEHEADER
    BITMAPFILEHEADER bf, bfn;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

    // read infile's BITMAPINFOHEADER
    BITMAPINFOHEADER bi, bin;
    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;
    }


    // Update outfile;
    bin.biWidth = bi.biWidth * n;
    bin.biHeight = bi.biHeight * n;

    int padding_1 =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int padding_2 =  (4 - (bin.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    bin.biSizeImage = (bin.biWidth * sizeof(RGBTRIPLE) + padding_2) * abs(bin.biHeight);
    bfn.bfSize = bin.biSizeImage + bfn.bfOffBits;

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

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

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

                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

                for(int c = 0; c < n; c++)
                {
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                }
            }

            for (int b = 0; b < padding_2; b ++)
            {
                fputc(0x00, outptr);
            }

            if (j < n - 1)
            {
                fseek(inptr, -bi.biWidth * sizeof(RGBTRIPLE), SEEK_CUR);
            }
        }

        fseek(inptr, padding_1, SEEK_CUR);
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}

1 Answer 1

1

If you had used the xxd tool to look at the output file, you would see that most of the header data is wrong. If you run the program multiple times, that incorrect data also changes from run to run. Interestingly, the fields that are explicitly changed in the program are correct.

Did you remember to initialize the headers by copying the original header data to the output file headers?

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

1
  • Thank you so much. I was so fed up with resize cuz I knew I'm updating the headers correctly. Now i understood my problem!!!!! Commented Jul 28, 2016 at 13:45

You must log in to answer this question.

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