Currently doing resize (less) problem on the CS50 course and can't understand why this code is not working as it should.
It will resize the large.bmp and the smiley.bmp but not the small.bmp correctly.
The small.bmp will show yellow pixels instead of the green on some of the images. So if the resize value was 2 the image would look like this:
And a resize value of 4 looks like:
Any help would be greatly appreciated!
Results for cs50/problems/2019/x/resize/less generated by check50 v3.0.9
:) resize.c and bmp.h exist.
:) resize.c compiles.
:) doesn't resize small.bmp when n is 1
:( resizes small.bmp correctly when n is 2 expected 0x0, not 0xdb in byte 35 of pixel data
:( resizes small.bmp correctly when n is 3 expected 0x0, not 0xdb in byte 49 of pixel data
:( resizes small.bmp correctly when n is 4 expected 0x0, not 0xdb in byte 63 of pixel data
:( resizes small.bmp correctly when n is 5 expected 0x0, not 0xdb in byte 81 of pixel data
:) resizes large.bmp correctly when n is 2
:) resizes smiley.bmp correctly when n is 2
:) resizes smiley.bmp correctly when n is 3
// Resizes a BMP file
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
fprintf(stderr, "Usage: resize scale infile outfile\n");
return 1;
}
// remember filenames and scale
char *infile = argv[2];
char *outfile = argv[3];
int scale = argv[1][0] - 48;
// check scale factor is positive integer
if (argv[1][0] == '-' || argv[1][1] != '\0')
{
fprintf(stderr, "Scale factor must a positive integer.\n");
return 2;
}
for (int x = 48; x < 58; x++)
{
if (x == argv[1][0])
{
break;
}
if (x == 9)
{
fprintf(stderr, "Scale factor must a positive integer.\n");
return 2;
}
}
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "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;
}
// find original padding
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// change the BITMAPINFOHEADER info and determine scaled padding for scanlines
int orgBiWidth = bi.biWidth;
int orgBiHeight = bi.biHeight;
bi.biWidth *= scale;
bi.biHeight *= scale;
int scaledPadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + scaledPadding) * abs(bi.biHeight);
// change the BITMAPFILEHEADER info
bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// iterate over infile's scanlines
for (int i = 0; i < abs(bi.biHeight); i++)
{
RGBTRIPLE array[orgBiWidth];
if (i == 0 || i % scale == 0)
{
// iterate over pixels in scanline
for (int j = 0; j < orgBiWidth; j++)
{
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
// write RGB trible to array
array[j] = triple;
// write RGB triple to outfile
for (int x = 0; x < scale; x++)
{
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
}
// skip over padding, if any
fseek(inptr, padding, SEEK_CUR);
// then add it back
for (int k = 0; k < scaledPadding; k++)
{
fputc(0x00, outptr);
}
}
else
{
for (int y = 0; y < orgBiWidth; y++)
{
for (int z = 0; z < scale; z++)
{
fwrite(&array[y], sizeof(RGBTRIPLE), 1, outptr);
}
}
for (int k = 0; k < scaledPadding; k++)
{
fputc(0x00, outptr);
}
}
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}