0

I'm stuck with the resize exercise. I can compile and run the program (no error messages) but no new output file appears. Where did I go wrong? Also, my vertical resizing does not seem to work but I don't see what the problem is. Thanks for your help!

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

int main (int argc, char *argv[])
{
    if (argc != 4)
    {
        fprintf (stderr, "Usage: resize number infile outfile\n");
        return 1;
    }

    int n = atoi(argv[1]);

    if (n < 0 || n > 100)
    {
        fprintf (stderr, "Number should be between 0 and 100\n");
        return 2;
    }

    // remember file names
    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 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 BITMAPFILEHEADER
    BITMAPFILEHEADER bf;
    fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

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

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

    //change size in BITMAPFILEHEADER
    BITMAPFILEHEADER bf2 = bf;
    BITMAPINFOHEADER bi2 = bi;
    bi2.biHeight = bi.biHeight * n;
    bi2.biWidth = bi.biWidth * n;
    bi2.biSizeImage = ((sizeof(RGBTRIPLE)*bi2.biWidth + outpadding) *   abs(bi2.biHeight));
    bf2.bfSize = bi2.biSizeImage + 54;

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

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


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

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

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

            //bring pointer back to beginning of line infile
            fseek(inptr, - bi.biWidth, SEEK_CUR);

        }

        // 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 n times
            for(int m = 0; m < n; m++)
            {
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }

        // add padding in outfile
        for (int k = 0; k < outpadding; k++)
        {
            fputc(0x00, outptr);
        }

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

    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;

}
1

Your vertical resizing does not work, because you fail to jump back to the start of the input line.

You try to jump back using

        //bring pointer back to beginning of line infile
        fseek(inptr, - bi.biWidth, SEEK_CUR);

But that way you only jump back biwidth bytes, whereas you should jump back biwidth pixels. And you know how many bytes go into one pixel for this type of file ...


And to quote Cliff B:

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

| improve this answer | |
  • Thanks, it worked! – Ida Oct 21 '18 at 22:51

You must log in to answer this question.

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