0

I'm stuck at resize.c its not working. Code seems fine to me but it doesn't output expected image. Please help me ..

/**
 * copy.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * 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)
    {
        printf("3 Command line arguments expected\n");
        return 1;
    }

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

     // ensure n is is a positive int less than or equal to 100
    if(factor < 1 || factor > 100)
    {
        printf("Scale must be a positive int less than or equal to 100\n");
        return 1;
    }

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

    // 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 variables for old height and width
    int oldwidth = bi.biWidth;
    int oldheight = bi.biHeight;

    // create variables for new height and width
    int newwidth = bi.biWidth * factor;
    int newheight = bi.biHeight * factor;

    // determine padding
    int oldpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE) % 4)) % 4;
    int newpadding = (4 - (newwidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // update file size
    bf.bfSize = bf.bfSize * factor;

    // update image size
    bi.biSizeImage = abs(newheight) * ((newwidth - oldpadding) * sizeof(RGBTRIPLE) + newpadding);

    // update height and width
    bi.biWidth = newwidth;
    bi.biHeight = newheight;

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

    // iterate over infile's scanlines
    for (int i = 0; i < oldheight; i++)
    {
        //iterate factor no. of times
        for (int p = 0; p < factor; p++)
        {
            //move back cursor
            fseek(inptr, 54 + ((oldwidth + oldpadding) * i) , SEEK_SET);

            // iterate over pixels in scanline
            for (int j = 0; j < oldwidth; j++)
            {
                // temporary storage
                RGBTRIPLE triple;

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

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

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

            // add new padding
            for (int k = 0; k < newpadding; k++)
            {
                fputc(0x00, outptr);
            }
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}

1 Answer 1

1

One suggestion is to consider that bf.bfSize and bi.biSizeImage are will not always change by "factor" as the padding on each scan line may change.

You must log in to answer this question.