0

I have no problems with the horizontal resizing but can't identify what is the problem in my code with the vertical resizing. Any help would be much appreciated.

/**
 * 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: ./copy infile outfile\n");
        return 1;
    }

    //Conversion of string(command line argument) to int//
    int n = atoi(argv[1]);

    //Ensuring that value of n is from 0 to 100//
    if(n<0 || n>100)
    {
      printf("try again!\n");
      return 1;
    }

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

    //change in new header info//
    BITMAPFILEHEADER bfo = bf;
    BITMAPINFOHEADER bio = bi;

    bio.biWidth = bi.biWidth*n;
    bio.biHeight = bi.biHeight*n;

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



    // determine padding for scanlines
    int oldPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    int newPadding = (4 - (bio.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    //change of file size//
    bfo.bfSize = 54 + (bio.biWidth * sizeof(RGBTRIPLE) + newPadding) * abs(bio.biHeight);
    bio.biSizeImage = bfo.bfSize - 54;

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

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



    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bio.biHeight); i < biHeight; i++)
    {
        for(int m = 0; m < n; m++)
        {

        // iterate over pixels in scanline
        for (int j = 0; j < bio.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);
            }
            //return to previous scanline and repeat same process//

        }


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

        if(m == (n-1))
        {
             // skip over padding, if any
            fseek(inptr, oldPadding, SEEK_CUR);
        }
        else
        {
            fseek(inptr, -(bi.biWidth*sizeof(RGBTRIPLE)), SEEK_CUR);
        }



        }
    }


    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}
1
  • Moreover, I also don't understand the purpose of oldPadding in this program. Why does it even matter if all I need to care about at the end is the newPadding for the outflie? Really confused about this too..
    – Prav Elan
    Nov 25, 2017 at 4:33

1 Answer 1

1

Have you looked at the raw image data using xxd? The image data for anything larger than n=1 is far too much! The code is using the output file's biHeight and biWidth to control reading the input file when it should use the original values, resulting in almost n * n times larger than the correct amount of image data. (I say almost n * n because the image data is being processed n * n times, but not the padding.)

Padding: Both the old and new padding must be calculated. There is no guarantee that the padding for both would be the same. (The chances are about 1 in 4. ;-) and while there is a correlation formula, it's far simpler to just calculate the new padding.)

The confusion probably comes from the copy exercise. The idea of calculating the padding, skipping it in the old file and adding it in the new file using a different process may seem pointless, but it was actually setting up the code needed to process the padding values in this exercise.

The old padding value is needed to skip over it and properly position at the beginning of the next line in the input file.

The new padding value is needed to know how much padding to add to the end of each line in the output file.

There may or may not be other issues, but I'll let you fix these first. ;-)

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

1
  • Thank you very much for the explanation. I finally figured out where I went wrong and rectified the problem :)
    – Prav Elan
    Nov 26, 2017 at 8:11

You must log in to answer this question.

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