0

I have checked everything and searched everywhere for an answer.

Both the images and headers were identical, but check50 gives me this:

:) resize.c and bmp.h exist.
:) resize.c compiles.
:) doesn't resize 3x3-pixel BMP when n is 1
:( resizes 3x3-pixel BMP to 6x6 correctly when n is 2
    resized image does not match expected image
:( resizes 3x3-pixel BMP to 9x9 correctly when n is 3
    resized image does not match expected image
:( resizes 3x3-pixel BMP to 12x12 correctly when n is 4
    resized image does not match expected image
:( resizes 3x3-pixel BMP to 15x15 correctly when n is 5
    resized image does not match expected image
:( resizes 6x6-pixel BMP to 12x12 correctly when n is 2
    resized image does not match expected image
:( resizes 9x9-pixel BMP to 18x18 correctly when n is 2
    resized image does not match expected image
:( resizes 6x6-pixel BMP to 18x18 correctly when n is 3
    resized image does not match expected image

All of the header info is correct.

Here is my source code:

/**
 * 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)
    {
        fprintf(stderr, "Usage: ./resize infile outfile size\n");
        return 1;
    }

    int sizemultiplier = atoi(argv[1]);
    if (sizemultiplier < 2)
    {
        printf("The size you imput is not valid. (Range: 2+)");
    }

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


    // set infile width and height ---J---
    int inwidth = bi.biWidth;
    // int inheight = bi.biHeight;

    // set outfile widthand height ---J---
    bi.biWidth = bi.biWidth * sizemultiplier;
    bi.biHeight = bi.biHeight * sizemultiplier;

    // determine padding for outfile scanlines ---J---
    int outpadding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // determine padding for infile scanlines
    int padding =  (4 - (inwidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // set other info ---J---
    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + outpadding) * abs(bi.biHeight);
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);


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

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

    int row = 0;

    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        row = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + ((((inwidth) * sizeof(RGBTRIPLE)) + padding) * i);

        for (int rerow = 0; rerow < sizemultiplier; rerow++) // repeat row
        {
            if (rerow == 0)
            {
                fseek(inptr, row, SEEK_SET);
            }

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

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

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

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

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

            if (rerow < sizemultiplier)
            {
                fseek(inptr, row, SEEK_SET);
            }
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

1 Answer 1

0

My guess is that you looked at the output images. But did you compare your image output with the output from the staff sample using xxd? Your images seem to have about sizemultiplier times as much data as it should. Perhaps there's an error in the code posted above? ;-)

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

4
  • What else is there to compare, that I didn't already show above? The images get resized to the proper height and width, and all of the header info and header file data is the same! If you could be more specific than saying that the problem is too much "data", then I might have something to work with. Sep 28, 2017 at 20:01
  • peek only looks at the headers. It doesn't show the actual image data that follows. Did you actually use xxd to look at the raw data in the files? You could also look at the file sizes with ls -al
    – Cliff B
    Sep 28, 2017 at 20:53
  • I opened the hex for my image, arranged it in a grid of triples (separated from the headers). From that, I figured out that my code was reading over the number of rows in the bigger image, on top of writing each row sizemultiplier times. Once I fixed this, my program started creating blank images. I figured out that this was caused by bi.biHeight being negative, instead of positive. I have no idea how this happened, but I managed fix it, and finally got my program running properly. Thanks for the help. :) Sep 28, 2017 at 22:04
  • biHeight can be + or -. The sign of biHeight determines whether the image is written to the screen from top to bottom or bottom to top. It can be either, so the abs() function is your best friend here. ;-)
    – Cliff B
    Sep 28, 2017 at 22:07

You must log in to answer this question.

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