0
// Copies a BMP file

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

#include "bmp.h"

int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
    fprintf(stderr, "Please give 3 arguments; size to be multiplied, infile, outfile\n");
    return 1;
}


// number by which the file is resized.
int n = atoi(argv[1]);
if(n < 0 || n > 101)
{
    fprintf(stderr,"The number given must be between 100 and 0 %i\n",n);
}
// 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;
}
// this needs to be initialized for it to start
BITMAPFILEHEADER bfNew = bf;
BITMAPINFOHEADER biNew = bi;
// Update Width
biNew.biWidth = bi.biWidth * n;
// Update Height
biNew.biHeight =bi.biHeight * n;
// Update Padding
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int newPadding = (4 - (biNew.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// Update SizeImage
biNew.biSizeImage = abs(biNew.biHeight)*(biNew.biWidth*sizeof(RGBTRIPLE)+newPadding);
// Update Size Total
biNew.biSize = sizeof(bf.bfOffBits) + biNew.biSizeImage;

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

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

// iterate over infile's scanlines
 for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    // Repeat scanline multiple times
    for(int w = 0;w<n;w++)
    {
        // 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);
            // writes each pixel n times
            for(int o = 0;o < n;o++)
            {
                // 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 < newPadding; k++)
        {
            fputc(0x00, outptr);
        }
        // Idea for scaling vertically
        // fseek(inptr, (bi.biWidth+padding), SEEK_CUR);
    }
}


// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;
}

When I switch n=1 to n=2 it seems the file won't display anymore. My question is, Does this occur because I haven't filled the file with enough pixels? I haven't figured out vertical scaling yet so it could be that the file throws an invalid because it expects x amount of pixels and I give it x - 30.

1

Have you tried the steps described in the problem statement's "Testing" chapter?

https://docs.cs50.net/2018/x/psets/4/resize/less/resize.html#testing

The total file size is part of the BITMAPFILEHEADER. As far as I know, there are a few other fields containing various size information, most of them are optional in case of a simple non-compressed image (we can derive bitmap size in bytes from image dimension and bits per pixel), if not used those fields would have to be 0. Try changing only the fields used in the staff implementation.

| improve this answer | |

You must log in to answer this question.

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