0

My code compiles and shows no error. However, it does not work when the resize value is less than 1. Can't figure out this part and would appreciate your help.

enter image description here

/**
* Copies a BMP piece by piece, just because.
*/

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

int main(int argc, char* argv[])
{
// ensure proper usage
if (argc != 4)
{
    printf("Usage: ./resize n infile outfile\n");
    return 1;
}

// remember filenames
int resize = 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 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 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;
}

// store original dimensions
int originalWidth = abs(bi.biWidth);
int originalHeight = abs(bi.biHeight);

// change dimensions in BITMAPINFOHEADER
bi.biWidth *= resize;
bi.biHeight *= resize;

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

bi.biSizeImage = (abs(bi.biWidth) * 3 + padding) * abs(bi.biHeight);

// change dimensions in BITMAPFILEHEADER
bf.bfSize = bf.bfOffBits + bi.biSizeImage;

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

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

// iterate over infile's scanlines
for (int i = 0; i < originalHeight; i++)
{
    for (int l = 0; l < resize; l++)
    {
        fseek(inptr, bf.bfOffBits + i * (originalPadding + (originalWidth * 3)), SEEK_SET);
        //printf("%d, %d, %d . %d\n", i, padding, originalWidth, i * (originalPadding + (originalWidth * 3)));
        // iterate over pixels in scanline
        for (int j = 0; j < originalWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

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

            // write RGB triple to outfile
            for (int k = 0; k < resize; k++)
            {
                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 < padding; k++)
            fputc(0x00, outptr);

        // reset to start of scanline
        //fseek(inptr, -(padding + bi.biWidth * 3), SEEK_CUR);
    }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;
}

1 Answer 1

1

0.5 is not an integer its a float so when your creating your int resize variable its not taking that into account and probably rounding it up to 1

4
  • Integers don't get rounded up, right? So it's probably rounded to 0 Commented Mar 7, 2017 at 11:01
  • I'm not sure either way its where the problem arises Commented Mar 7, 2017 at 11:34
  • just checked in cs50 IDE you are correct it rounds down or most likely ignores the values after the decimal point because 75/20=3.75 was rounded down to 3 to Commented Mar 7, 2017 at 11:51
  • That's how integers always work ;) I'm sure I've heard David Malan make a remark about it at some point, but it's always cool to see it in practice eh :p Commented Mar 7, 2017 at 11:59

You must log in to answer this question.

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