0

I used the peek command to check my headers using the command ~cs50/pset4/peek student.bmp staff.bmp and everything is alright and perfectly matches with the staff's implementation as follows :

~/workspace/pset4/bmp $ ~cs50/pset4/peek student.bmp staff.bmp
offset  type   name              argv[1]   argv[2]
0       WORD   bfType               4d42      4d42
2       DWORD  bfSize           000001e6  000001e6
6       WORD   bfReserved1          0000      0000
8       WORD   bfReserved2          0000      0000
10      DWORD  bfOffBits        00000036  00000036
14      DWORD  biSize           00000028  00000028
18      LONG   biWidth          0000000c  0000000c
22      LONG   biHeight         fffffff4  fffffff4
26      WORD   biPlanes             0001      0001
28      WORD   biBitCount           0018      0018
30      DWORD  biCompression    00000000  00000000
34      DWORD  biSizeImage      000001b0  000001b0
38      LONG   biXPelsPerMeter  00000b12  00000b12
42      LONG   biYPelsPerMeter  00000b12  00000b12
46      DWORD  biClrUsed        00000000  00000000
50      DWORD  biClrImportant   00000000  00000000

And also I tried using diff student.bmp staff.bmp but it doesn't return anything indicating that both are exactly same. In spite of this, I am getting the following errors with check50 2015.fall.pset4.resize bmp.h resize.c :

~/workspace/pset4/bmp $ check50 2015.fall.pset4.resize bmp.h resize.c
:) resize.c and bmp.h exist
:) resize.c compiles
:( doesn't resize 1x1-pixel BMP when n is 1
:( resizes 1x1-pixel BMP to 2x2 correctly when n is 2
:( resizes 1x1-pixel BMP to 3x3 correctly when n is 3
:) resizes 1x1-pixel BMP to 4x4 correctly when n is 4
:( resizes 1x1-pixel BMP to 5x5 correctly when n is 5
:) resizes 2x2-pixel BMP to 4x4 correctly when n is 2

My code of resize.c is as follows :

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

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

#include "bmp.h"

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

    // remember filenames
    uint32_t fact=atoi(argv[1]);
    char* infile = argv[2];
    char* outfile = argv[3];

    if(fact<1)
    {
        printf("Factor less than 1 is not accepted\n");
        return 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)
    {
        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;
    }
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    BITMAPFILEHEADER bf2 = bf;
    BITMAPINFOHEADER bi2 = bi;

    bi2.biWidth=bi2.biWidth*fact;
    bi2.biHeight=bi2.biHeight*fact;
    bi2.biSizeImage = (bi2.biWidth * sizeof(RGBTRIPLE)) * abs(bi2.biHeight);
    //bi2.biXPelsPerMeter=bi2.biXPelsPerMeter*fact;
    //bi2.biYPelsPerMeter=bi2.biYPelsPerMeter*fact;

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

    bf2.bfSize = (((bi2.biWidth * sizeof(RGBTRIPLE)) + padding2) * abs(bi2.biHeight)) + 54;

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

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

    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        for(int n=1;n<=fact;n++)
        {

        // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            if(n!=1&&j==0)
            {
                fseek( inptr, -(bi.biWidth*sizeof(RGBTRIPLE)+padding), SEEK_CUR );
            }
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            for(int m=1;m<=fact;m++)
            {

            // 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 < padding2; k++)
        {
            fputc(0x00, outptr);
        }
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}

Note: I did take reference from the question resize fails check50 for final sizes other than 4x4 and made changes to the calculation of biSizeImage and bfSize. But that still doesn't help.

0

After learning from my own mistake (and before running your code as I am away from home right now), I am wondering whether one change might do the trick for you: your bfSize includes an element that is missing in biImageSize; remember, however, that the difference between image size and file size is only the additional bytes from the headers. I hope this helps!

1

So you say that it works, but check50 is failing. Funny thing - when I ran the code, it fails. Is it possible that you're working from different versions of the code?

3
  • I didn't get you. What do you mean exactly ?? Are you telling me that my code isn't giving the correct resized file or only check50 fails ?? As I stated above in the question, diff and peek commands give a positive result. I didn't get how it fails when you're trying to run the code. Jul 13 '16 at 5:23
  • And also this code is the only version of mine. I am making changes in just one file/version. I didn't create any copy of this and then make the changes. Please look into it. Jul 13 '16 at 5:28
  • When I ran the code posted above, using ./resize 1 small.bmp s2.bmp it should have produced an identical file, but it doesn't. There is still an error in the header info.
    – Cliff B
    Jul 13 '16 at 5:29
0

You should add padding to your bi2.biSizeImage.

You must log in to answer this question.

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