0

I think I'm close but I'm still getting the wrong image each time I try to resize small.bmp to large.bmp.

I know it's somewhere in the loops at the end of the code but I'm just not seeing it for some reason. Thanks in advance for any advice.

Here is the code:

  // Resizes a BMP file
//To resize a file use /.resize (Positive int to size) inputfile outputfile

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

    // Make sure the first argument is a positive int <= 100
    int increase = atoi(argv[1]);
    if(increase > 100 || increase < 0){

        fprintf(stderr, "You must enter a positive number equal to or less than 100");
    }

    char *infile = argv[2];

    FILE *inptr = fopen(infile, "r");

    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    char *outfile = argv[3];

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

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

    BITMAPFILEHEADER bfResize = bf;
    BITMAPINFOHEADER biResize = bi;
    biResize.biWidth = bi.biWidth * increase;
    biResize.biHeight = bi.biHeight * increase;
    //biResize.biSize = biResize.biSize * increase;

    int paddingResize = (4 - (biResize.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // resize the image size
    biResize.biSizeImage = ((sizeof(RGBTRIPLE) * biResize.biWidth) + paddingResize) * abs(biResize.biHeight);
    bfResize.bfSize = biResize.biSizeImage + sizeof(bf) + sizeof(bi);



    // write outfile's BITMAPFILEHEADER
    fwrite(&bfResize, sizeof(BITMAPFILEHEADER), 1, outptr);
    // write outfile's BITMAPINFOHEADER
    fwrite(&biResize, sizeof(BITMAPINFOHEADER), 1, outptr);

    bi.biHeight = abs(bi.biHeight);
    biResize.biHeight = abs(biResize.biHeight);

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

            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
        }

        }

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

        // Add padding based off new width
        for (int k = 0; k < paddingResize; k++)
        {
            fputc(0x00, outptr);
        }

    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}
2

It works for increase = 1, but not for anything larger. There are two problems there. First, the header isn't being processed correctly. Certain header values have to be calculated from numerous other values and cannot simply be multiplied by increase.

Second, the vertical scaling hasn't been done. There doesn't appear to be any code to vertically scale a current line before moving on to the next line. If you look at the image data using xxd, when increase = 2, the image line data is the correct width and even contains the correct data, but there are only half of the required number of lines, i.e., the same number of image lines as the original file.

Look at the output from the staff example and compare it to your output using xxd.

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

2
  • Thank you for your help. I figured out the two formulas I was missing to adjust the header sizes and added them above. I'm still trying to figure out vertical scaling. I'm really stuck on how to get two of the exact same lines printed one -> line break -> then second line
    – ndjustin20
    Feb 12 '18 at 2:02
  • maybe you should back up and reprocess the current line again?
    – Cliff B
    Feb 12 '18 at 2:12

You must log in to answer this question.

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