0
/**

* copy.c * * Computer Science 50 * Problem Set 4 * * Copies a BMP piece by piece, just because. */

include

include

include "bmp.h"

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

// converting n to an actual int
int k = atoi(argv[1]);

// limiting the range of n to be bw 1 and 100
if (k < 1 || k > 100)
{
    printf("n must be between 1 and 100 \n");
    return 2;
}

// remember filenames
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 5;
}

// declaring new header and info
BITMAPFILEHEADER bf2 = bf;
BITMAPINFOHEADER bi2 = bi;

// changing the height and width of output bitmapinfoheader bi
bi2.biWidth = bi.biWidth * k;
bi2.biHeight = bi.biHeight * k;

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

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

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

// new padding
int newpadding =  (4 - (bi2.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

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

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;

}

ok first let me tell I am amongst the less comfortable ones, and felt that pset4's difficulty increased like 5 times from the difficulty of pset3. I am stuck on resize at the moment. From what i have understood I made a new variable of type BITMAPFILEHEADER and BITMAPINFOHEADER so that i can change their elements width and height n times.Made a new int for padding and used it in the last loop. Now I wanna know if i have done the things so far right and what to do next? and although I did all the reading and stuff mentioned in the specs of pset4 im still having trouble as to what is happening in the three loops. would really appreciate if someone explains me in easy english whats happening in the three loops and what should i do next

1 Answer 1

2

1) Apart from biWidth and biHeight, there's 2 more headers you're meant to update, you can read the MSDN pages to get an idea of which two they are. They're the only two that will change when the size of the file changes.

2) You need to actually resize the bmp. You should read on fread and fwrite to help understand what happens in the loops. Basically, what you have there, in copy.c is a nested loop that will iterate through the width of the file (inner loop) as many times as the height of the file requires it (outer loop). You'll see in bmp.h what an RGBTRIPLE is exactly and if you understand those two functions inside the loop, you should see what they are doing.

3) Also, read about fseek and see what it does there (the comments are clear enough on that one, though)

Use the tools the pset mentions, like peek to see the differences between the original and the resized file using the staff's implementation. That will help you see which headers you're meant to change.

You must log in to answer this question.

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