0

I've been working on my program to a point where I believe that my headers are being processed okay, they are matching the same output I get from the staff solution. But, when I am running my program on a 3x3 image and resizing by a factor of 2 for example, the first or second scanline seems as though its offset is wrong.

I've been scratching my head on this one for awhile now, was hoping someone could point me in the right direction.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bmp.h"

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./copy resize_factor infile outfile \n");
        return 1;
    }
    // test that resize value is within legal bounds
    else if (atoi(argv[1]) <= 0 || atoi(argv[1]) > 100)
    {
        printf("Error: Resize value is <= 0 or > 100 \n");
        return 1;
    }

    // remember filenames and resize value
    int resize_val = atoi(argv[1]);
    char* infile = argv[2];
    char* outfile = argv[3];

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

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

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

    // alter outfile BITMAPFILEHEADER for resizing
    int padding_bytes = abs((bi.biHeight * resize_val) * ((4 - ((bi.biWidth * resize_val) * sizeof(RGBTRIPLE)) % 4) % 4));
    bf.bfSize = 54 + padding_bytes + ((bi.biWidth * resize_val) * (abs(bi.biHeight) * resize_val)) * 3;

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

    // alter outfile BITMAPINFOHEADER for resizing
    bi.biWidth = bi.biWidth * resize_val; // don't add padding to real dimensions
    bi.biHeight = (bi.biHeight * resize_val); // make it negative, for top-down datastore
    bi.biHeight = -abs(bi.biHeight);
    bi.biSizeImage = bf.bfSize - 54;

    // 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, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {



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

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

            for (int l = 0; l < resize_val; l++)
            {
                // write RGB triple to outfile 
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr); 
            }

        }

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

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

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
1

It looks like you have successfully scaled up the horizontal line correctly, but you've forgotten to scale each line up vertically. The effect is that you have one line of pixels of output for each line of pixels input, and then when you have exhausted the input file, you're adding blank lines to the output file until it has what looks like the right number of lines. In short, you didn't scale the actual image vertically.

The effect is that the output image looks like the input image was stretched horizontally with a blank block below it.

If you think this answers your question effectively, please mark it as answered. Let's keep up on forum housekeeping. ;-)

You must log in to answer this question.

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