0

See code below:

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

#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 (atoi(argv[1]) > 100){
 printf("Please enter number smaller than 100...");
  return 1;
}

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)
{
    printf("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;
}

//need to modify height and width of bi.biWidth and bi.biHeight by increasing by n;
//also need to modify image size and filesize;

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

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

// copy these file headers so they can be written to output file
BITMAPFILEHEADER bfo = bf;
BITMAPINFOHEADER bio = bi;


   /* bio.biSize = bi.biSize * n; */ 
   /*
   bio.biSizeImage = bi.biSizeImage * n;

   bfo.bfSize = bf.bfSize * n; 
   */

bio.biWidth = bi.biWidth * n;
bio.biHeight = bi.biHeight * n;

// bio.biWidth must be a multiple of 4



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


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



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

 //padding for infile and outfile need to be calculated independently


// determine padding for scanlines

int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
   /* int newpadding = (bio.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 < padding; k++)
    {
        fputc(0x00, outptr);
    }


}

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

I've commented bi.biSize because when I change this it says unsupported image format, so I'm wondering if I can completley delete it? And the bio.biSizeImage and bfo.bfSize, should be automatically assigned so I don't need to set values for them - so can I delete the assignment of these?

For adding back the padding, I changed fputc to include different hex colors, but the images are still completely black - what exactly does this part of the code do?

Thanks :)

1
  • Currently my tests confirm that when I compare diff when n is 1..there is no difference, therefore the actual resizing is working....but I need to work on the padding. The header data is also changing as expected, check50 fails the tests after 'no difference when n is 1'.... Commented Jan 5, 2017 at 17:06

1 Answer 1

1

You should run the staff's version for a couple of files and different values of resize and then run peek on those files to see which are the headers that actually change.

Also, take a closer look at the code. bi.biSize is one of the headers used to make sure the file is a bmp. Do you think that one should really change?

Other than that, you're not resizing at all. You're updating the headers partially, with the new width and height, but nothing else other than that. Basically, your code is exactly the code of copy.c with partially updated headers.

Padding is, basically, bytes with value 0x00 that are added to the end of each scanline to make each line be of an amount of bytes that is a multiple of 4. So, for example, if width is 3, that is 3 pixels, so 9 bytes. You need to add 3 bytes of padding so that it's 12 bytes in total, which is a multiple of 4

You must log in to answer this question.

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