1

This is my code:

// Resizes a BMP file pixel by pixel, given a factor n

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

// remember resizing factor n and convert it to int
int n = atoi(argv[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);

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

// updating the new headers to update
BITMAPFILEHEADER new_bf = bf;
BITMAPINFOHEADER new_bi = bi;

// updating new values for biWidth, biHeight, padding, biSizeImage and sizeImage
new_bi.biWidth *= n;
new_bi.biHeight *= n;

int new_padding = (4 - (new_bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

new_bi.biSizeImage = (sizeof(RGBTRIPLE) * new_bi.biWidth + new_padding) * abs(new_bi.biHeight);
new_bf.bfSize = new_bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

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

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

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    for (int ntimes = 0; ntimes < n; ntimes++)
    {
        // set pointer to beginning of line
        fseek(inptr, 54 + (bi.biWidth * 3 + new_padding) * i, SEEK_SET);

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

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

        // adding the new padding
        for (int k = 0; k < new_padding; k++)
        {
            fputc(0x00, outptr);
        }
    }
}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;
}

It compiles fine without any errors and apparently works with small.bmp and smiley.bmp but it doesn't check all the :) in cs50

:( resizes small.bmp correctly when n is 2
    Byte 42 of pixel data doesn't match. Expected 0xff, not 0x00
:( resizes small.bmp correctly when n is 3
    Byte 86 of pixel data doesn't match. Expected 0xff, not 0x00
:( resizes small.bmp correctly when n is 4
    Byte 146 of pixel data doesn't match. Expected 0xff, not 0x00

I think it's a problem with my padding that shifts my scanlines so it appears correct but I've been debugging for so long that my brain is melting.

2

You're on the right track, and oh, so close!

So tell me, when you're repositioning the pointer in the input file to reprocess a line, which padding value should you use?

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

3
  • Damn dude. I love you
    – Pexan
    Nov 23 '18 at 20:30
  • You should feel good about this one. You wrote the code, you debugged most of it, and for the last remaining problem, you were able to at least identify the most likely cause of the problem! You were just too close to the trees to see the forest! If you had put it aside for a day and forgot about it before coming back, I'm sure that you would have solved it on your own! ;-)
    – Cliff B
    Nov 23 '18 at 20:46
  • Yes you might be right. I was on the pc for so long trying to do this that it stopped making sense ahah
    – Pexan
    Nov 24 '18 at 11:26

You must log in to answer this question.

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