I know that this question has been "answered" numerous times but those revelations haven't related to me for some reason. My code is edited from copy.c and a few other resources. The FILE reads and writes before INFO headers in both instances. I ran debug50 on my code and then someone elses that I copied into a different file but same results happen each time. I tried it with a third and same thing. The only thing I saw that was weird was that it skipped completely over the scanLine for loop and I think it's because bi.biHeight is -3 throughout the whole process. I don't know if that's supposed to be a negative or if it even matters but nothing is happening within that for loop I'm sure. I did the math manually and it makes sense. the xxd terminal output is fudged. Please, please, please, help even though this has been answered. I'm not finding success through those answers.
/**
* Resizes a BMP piece by piece
*/
#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
fprintf(stderr, "Usage: ./resize n infile outfile\n");
return 1;
}
// remember filenames
char *infile = argv[2];
char *outfile = argv[3];
int multiplier = atoi(argv[1]);
printf("multiplier: %d\n", multiplier);
//end program if multiplier is negative or too large
if(multiplier < 1 || multiplier > 100)
{
printf("Invalid zoom factor of %i\n Zoom factor must be 1-100\n", multiplier);
return 5;
}
// open input file
FILE *small = fopen(infile, "r");
if (small == NULL)
{
fprintf(stderr, "Could not open %s.\n", "small");
return 2;
}
// open output file
FILE *zoom = fopen(outfile, "w");
if (zoom == NULL)
{
fclose(small);
fprintf(stderr, "Could not create %s.\n", "zoom");
return 3;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, small);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, small);
// 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(zoom);
fclose(small);
fprintf(stderr, "Unsupported file format.\n");
return 4;
}
BITMAPFILEHEADER bfOut;
BITMAPINFOHEADER biOut;
bfOut = bf;
biOut = bi;
biOut.biWidth = bi.biWidth * multiplier;
biOut.biHeight = bi.biHeight * multiplier;
int paddingIn = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int paddingOut = (4 - (biOut.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bfOut.bfSize = 54 + biOut.biWidth * abs(biOut.biHeight) * 3 + abs(biOut.biHeight) * paddingOut;
biOut.biSizeImage = ((((biOut.biWidth * biOut.biBitCount) + 31) & ~31) / 8) * abs(biOut.biHeight);
// //multiply image size
// biOut.biWidth = bi.biWidth * multiplier;
// biOut.biHeight = bi.biHeight * multiplier;
// printf("biWidth: %d\n", biOut.biWidth);
// printf("biHeight: %d\n", biOut.biHeight);
// //determine padding for scanlines
// int paddingIn = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// int paddingOut = (4 - (biOut.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// printf("paddingIn: %d | width: %d\n", paddingIn, bi.biWidth);
// printf("paddingOut: %d\n", paddingOut);
// determine file size
// biOut.biSizeImage = ((biOut.biWidth * sizeof(RGBTRIPLE)) + paddingOut) * biOut.biHeight;
// bfOut.bfSize = bf.bfSize - bi.biSizeImage + biOut.biSizeImage;
// write outfile's BITMAPFILEHEADER
fwrite(&bfOut, sizeof(BITMAPFILEHEADER), 1, zoom);
// write outfile's BITMAPINFOHEADER
fwrite(&biOut, sizeof(BITMAPINFOHEADER), 1, zoom);
// iterate over height of file
for (int i = 0; i < (bi.biHeight = abs(bi.biHeight)); i++)
{
// iterate over infile's scanlines
for (int scanLine = 0; scanLine < multiplier; scanLine++)
{
// 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, small);
// write RGB triple to outfile
for (int w = 0; w < multiplier; w++)
{
fwrite(&triple, sizeof(RGBTRIPLE), 1, zoom);
}
}
// skip over padding, if any
fseek(small, paddingIn, SEEK_CUR);
// then add it back (to demonstrate how)
for (int k = 0; k < paddingOut; k++)
{
fputc(0x00, zoom);
}
fseek(small, -(bi.biWidth * 3 + paddingIn), SEEK_CUR);
}
fseek(small, bi.biWidth * 3 + paddingIn, SEEK_CUR);
// if(i % multiplier != 0)
// {
// fseek(small, (-biOut.biWidth * /*sizeof(RGBTRIPLE)*/3) + paddingIn, SEEK_CUR);
// }
}
// close infile
fclose(small);
// close outfile
fclose(zoom);
// success
return 0;
}