I'm having a really hard time grasping pset4, I think I've changed the header files correctly but I'm not sure.. I feel like this pset is WAAAY harder than the last. I still barely understand a lot of it even after going through all of the videos at least twice each and writing most of it down. Anyway.. I've managed to get the image to resize but it comes out black and multi colored. I know I haven't done the padding yet but I don't even know where to start ): I'm getting pretty discouraged with cs and programming because I know it's only going to get tougher. So if anyone can give me some tips on where to get started with the padding or anything that's already wrong with my code it would be greatly appreciated.

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

#include "bmp.h"

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

if (argv[1] < 0 || argv[1] > 101)
    printf("Enter a resize amount between 1 and 100!\n");
    return 1;

// remember filenames
char* infile = argv[2];
char* outfile = argv[3];

int n = atoi(argv[1]);

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
    printf("Could not open %s.\n", infile);
    return 2;

// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;

// read infile's BITMAPFILEHEADER
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

bi.biHeight *= n;
bi.biWidth *= n;
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = abs(bi.biWidth) * (bi.biWidth + padding);
bf.bfSize = bi.biSizeImage + 54;

// 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)
    fprintf(stderr, "Unsupported file format.\n");
    return 4;

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

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

// determine padding for scanlines

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

        // write RGB triple to outfile

        for (a = 0; a < n; a++)
            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);

// close infile

// close outfile

// that's all folks
return 0;

1 Answer 1


Your code has a number of problems. Based on what you have said, and what is in the code, I think you'd benefit more from some guidance on how to work through this pset and some general advice.

When attacking a project like this, it's best to break a problem down into smaller and smaller pieces and to do them one at a time. If you're working on something that is doing too much at once, break it down some more until you're doing just one thing! Programming can sometimes seem to be a tedious process - what may feel overwhelmingly complex is really more like an overwhelming number of small, simple tasks. You just need to work through them. There's a fine line between overwhelming and tedious. ;-)

For instance, resize breaks down into two major parts, processing the headers and processing the image. The header part breaks down into processing two headers. Each of those breaks down into reading the individual headers, processing individual values, and outputting the headers.

Generally speaking, you should get each piece right before moving on to the next, especially when one part depends on a previous part being correct. If B depends on A, then it doesn't matter what you do with B if A isn't right. In this program, that means that you need to get certain header values right before others that depend on them. It also means that you really need to get the headers right before you work on the image part.

Now, looking at some more specific suggestions, you need to get the program to where it will compile. Here, you need to work through the errors in order. Often, a syntax error is the cause of numerous errors that follow, especially something like a variable declaration. Work through the syntax errors until the program compiles. Then work on the logic errors.

For resize.c, start testing by resizing by a factor of 1 and a small file, like small.bmp. The output file should be identical to the input file, so any difference will show where to look for errors. Start with the headers. If they're not right, the image will probably be wrong too. Once the headers process correctly, then work on the image.

This is where tools are your friends. peek will show you the headers for both the input and output files. Anything highlighted in red requires attention. Once all are green (still resizing to 1), then use xxd to compare the digital values of the image. Looking at the image isn't enough. It doesn't always show differences, while looking at the raw data shows exactly what is different. It can also show specific patterns and give you a better idea of what's happening when the output is compared to the input.

Padding: A very common error is to only calculate one padding value. It's necessary to calculate padding for both the input and the output file. There's no guarantee that the padding values will be the same.

Hopefully, this will give you more insight into what you need to do.

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

You must log in to answer this question.

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