I'm working on resize (less comfortable) in pset3 and it returns segmentation error when I execute the code. However, when I try to work out which line actually went wrong using debug50 and go through it step by step, the program suddenly worked and successfully create the larger bmp. Can someone take a look on my codes and give me some advice? Thanks a lot in advance!
// Resize 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 infile outfile\n");
return 1;
}
//check value of n
if (!isdigit(argv[1]))
{
fprintf(stderr, "Usage: resize infile outfile\n");
return 2;
}
int n = atoi(argv[1]);
if (n <= 0 || n > 100)
{
fprintf(stderr, "incorrect resize value\n");
return 3;
}
// remember filenames
char *infile = argv[2];
char *outfile = argv[3];
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", infile);
return 4;
}
// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// 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;
}
BITMAPFILEHEADER new_bf = bf;
BITMAPINFOHEADER new_bi = bi;
//new biwidth biheight
new_bi.biWidth = bi.biWidth * n;
new_bi.biHeight = bi.biHeight * n;
//padding
int ori_padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int new_padding = (4 - (new_bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
//new bisizeimage
new_bi.biSizeImage = ((new_bi.biWidth * sizeof(RGBTRIPLE)) + new_padding) * abs(new_bi.biHeight);
//new bfsize
new_bf.bfSize = new_bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// write outfile's BITMAPFILEHEADER
fwrite(&new_bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&new_bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// iterate over infile's scanlines by n times
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
for (int b = 0; b < n; b++)
{
// 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);
for (int a = 0; a < n; a++)
{
// write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
}
//padding if required
for (int k = 0; k < new_padding; k++)
{
fputc(0x00, outptr);
}
//move back cursor
if (b < n - 1)
{
fseek(inptr, -(bi.biWidth * sizeof(RGBTRIPLE)), SEEK_CUR);
}
}
// skip over padding, if any
fseek(inptr, ori_padding, SEEK_CUR);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}