I'm now doing the pset4 resize more version as I have already done the 'less version' with successfull check50.
For my 'more version' check50 indicates 3 errors although visually my outputs look good.
So I focus on resizing 1x1 with factors 3, 4 and 5 (name: onepix.bmp).
I have created 1x1 pixel bmp file (24 bits) and use it as a source for resizing in order to be on the same line with check50. The intension was to compare files created by my code and the staff code (using programs peek, xxd and diff). Firstly I have created files for comparison like so:
~/workspace/pset4/resizeMORE/ $ ./resize 4 onepix.bmp student.bmp
~/workspace/pset4/resizeMORE/ $ ~cs50/hacker4/resize 4 onepix.bmp staff.bmp
Comparing headers with PEEK
using:~cs50/pset4/peek student.bmp staff.bmp
Comparing with XXD (headers including)
using:~/workspace/pset4/resizeMORE/ $ xxd -c 24 -g 3 staff.bmp
and ~/workspace/pset4/resizeMORE/ $ xxd -c 24 -g 3 student.bmp
Comparison with DIFF
I have also tried diff program but there wasn't found any difference between compared two files.Source code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
fprintf(stderr, "Usage: ./resize factor infile outfile (factor in range (0.0 100.0])\n");
return 1;
}
// remember filenames
char *infile = argv[2];
char *outfile = argv[3];
//n has to be positive integer
float factor = atof(argv[1]);
if (factor <= 0 || factor > 100)
{
fprintf(stderr, "factor in range (0.0, 100.0].\n");
return 1;
}
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", infile);
return 1;
}
// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 1;
}
// 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;
}
// temp headers for resized image
BITMAPFILEHEADER newBf;
BITMAPINFOHEADER newBi;
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int newPadding;
//change headers
newBi = bi;
newBi.biWidth = round(bi.biWidth * factor); // padding excluding
if(bi.biHeight < 0)
newBi.biHeight = round(fabsf(bi.biHeight * factor)) * -1;
else
newBi.biHeight = round(bi.biHeight * factor);
newPadding = (4 - (newBi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
newBi.biSizeImage = (newBi.biWidth * sizeof(RGBTRIPLE) + newPadding) * abs(newBi.biHeight);
newBf = bf;
newBf.bfSize = newBi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // headers, pixels, padding including
// write outfile's BITMAPFILEHEADER
fwrite(&newBf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&newBi, sizeof(BITMAPINFOHEADER), 1, outptr);
// remember sizes for seek position in the loop
long tripleSize = sizeof(RGBTRIPLE);
long BMfileSize = sizeof(BITMAPFILEHEADER);
long BMinfoSize = sizeof(BITMAPINFOHEADER);
int row = 0;
int col = 0;
// iterate over outfile's scanlines
for (int i = 0, biHeight = abs(newBi.biHeight); i < biHeight; i++)
{
// corresponding row in infile
row = round((float)i / (abs(newBi.biHeight) - 1) * (abs(bi.biHeight) - 1));
// iterate over pixels in scanline
for (int j = 0; j < newBi.biWidth; j++)
{
// temporary storage
RGBTRIPLE triple;
// corresponding column in infile
col = round((float)j / (newBi.biWidth - 1) * (bi.biWidth - 1));
//set proper position in infile
long position = BMfileSize + BMinfoSize + (row * (tripleSize * bi.biWidth + padding)) + (col * tripleSize);
fseek(inptr, position, SEEK_SET);
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
// add new padding
for (int k = 0; k < newPadding; k++)
{
fputc(0x00, outptr);
}
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}
After these tests I am at the end of my limited knowledge/possibilites and ask for your help. I see two fields where the error could be:
1. Bug in my code - which is probably the case :-)
2. Something in check50 which is not obvious and check more than just resulting files.
As I am not very experienced I would probably bet on bug in my code - please help me.
I don't necessarily need clean check50 output but I would like to know what is wrong with my code just to learn from that mistake.
Thank very much in advance.