I implemented resize using recopy method as bellow but I think there are still some mistakes in my code that why it didn't yield the correct result. The thing is I'm not really sure how to implement "send infile cursor back". Please give me advice and thank you in advance.
Here is psuedocode: "recopy" method from Resize's Walkthrough
for each row
for n-1 times
write pixels, padding to outfile
send infile cursor back
write pixels, padding to outfile
skip over infile padding
Code:
// Resize a BMP file
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
fprintf(stderr, "Usage: %s n infile outfile\n", argv[0]);
return 1;
}
// remember filenames
int n = atoi(argv[1]);
if ( n < 0 )
{
fprintf(stderr, "Usage: %s n infile outfile\n", argv[0]);
return 2;
}
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 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;
}
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int new_padding = (4 - (n * bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// Update BITMAPINFOHEADER
BITMAPINFOHEADER new_bi;
new_bi.biWidth = n * bi.biWidth;
new_bi.biHeight = n * bi.biHeight;
new_bi.biSizeImage = ((sizeof(RGBTRIPLE) * new_bi.biWidth) + new_padding) + abs(new_bi.biHeight);
// Update BITMAPFILEHEADER
BITMAPFILEHEADER new_bf;
new_bf.bfSize = new_bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//printf("%lu\n",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
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
for (int l = 0; l < n - 1 ; l++)
{
// 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
for (int a = 0; a < n; a++)
{
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
}
// then add it back (to demonstrate how)
for (int k = 0; k < new_padding; k++)
{
fputc(0x00, outptr);
}
// send infile cursor back
fseek(inptr, padding, SEEK_CUR);
}
// 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
for (int a = 0; a < n; a++)
{
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
}
// then add it back (to demonstrate how)
for (int k = 0; k < new_padding; k++)
{
fputc(0x00, outptr);
}
// skip over infile padding, if any
fseek(inptr, padding, SEEK_CUR);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}