https://sandbox.cs50.net/checks/480ca0b5599747bf966ef0c139584d60
/**
* resize.c
*
* Computer Science 50
* Problem Set 4
*
* Magnifies a BMP piece by piece in accordance to the inputted value by the user.
*/
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<math.h>
#include<ctype.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
char* infile = argv[2];
char* outfile = argv[3];
//checking if n is a number
for(int i = 0, l = strlen(argv[1]); i < l; i++)
{
if(!isdigit(argv[1][i]))
{
printf("n should be an integer");
return 2;
}
}
//remember resizing factor;
int n =atoi(argv[1]);
if((n>100) || (n<0))
{
printf("n should be less than 100 and greater than 0");
return 2;
}
// 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;
}
//calculating width of original file to ultimately calculate padding
int orig_Width = bi.biWidth;
//calculate padding of the infile
int orig_Padding = (4 - (orig_Width * sizeof(RGBTRIPLE)) % 4) % 4;
//update header file's info
bi.biWidth*=n;
bi.biHeight*=n;
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
//Calculate biSize = (biWidth * biHeight * 3bytesper pixel) + padding per line
bi.biSize = (bi.biWidth * abs(bi.biHeight) * 3) + padding * abs(bi.biHeight);
//bf.bfOffBits contains the size from start till the RGB is reached(i.e. 54)
bf.bfSize = bi.biSize + bf.bfOffBits;
// 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, 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 after resizing it horizontally
for(int k = 0; k < n; k++)
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);
}
//resize vertically by using re-copy method. if i % n becomes 0, then continue to the next row
long offset = orig_Width*sizeof(RGBTRIPLE) + orig_Padding;
if((i+1)%n!=0)
fseek(inptr, -offset, SEEK_CUR);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// that's all folks
return 0;
}
Add a comment
|
1 Answer
You have a problem in your header. Take a close look at which header fields you are changing, and then review which ones you should be changing. Keep in mind that some fields have very similar names. You might also want to google the microsoft bitmap header specifications and review the field descriptions.
If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)
-
Thanks a lot @Cliff B. I understood my mistakes. After watching the short again, I realized that I had to store the original padding and width in a variable. Also, I made a mistake when I biSize in place of biSizeImage. When I iterate in the last loop, I needed to read through the conditions according to the original values and not the updated ones. Commented Jun 23, 2016 at 7:36