I've checked other similar questions and answers and found some problems(and then fixed up), but(seems like the problems weren't there), I still have the same problem "invalid or unsupported image format".
What I want to do is, store the each pixels of input image file "n" times in an array called "tripleScale" then draw these pixels "n" times in output image file in order to have the primary image "n" times bigger.
I've watched some videos explaining about the resizing algorithm and I don't know where to put the "ftell()" function, and if it's a must in order to have this program run properly.
-
int main(int argc, char *argv[]) { // ensure proper usage if (argc != 4) { fprintf(stderr, "Usage: ./resize n infile outfile\n"); return 1; }
// remember scale n
int scale = atoi(argv[1]);
// tripleScale's array iteration
int count = 0;
// check if n is between 0 and 100
if (scale < 0 || scale > 100)
{
fprintf(stderr, "The scale n must be in between 0 and 100\n");
return 1;
}
// 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 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;
}
// save original necessary primary data
int oriWidth = bi.biWidth;
int oriHeight = bi.biHeight;
// determine the new biHeight and biWidth with scale n
bi.biWidth = oriWidth * scale;
bi.biHeight = oriHeight * scale;
// determine padding for scanlines
int padding = (4 - (oriWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int paddingScale = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// determine new biSizeImage and biSize with scale n
bi.biSizeImage = (bi.biWidth * sizeof(RGBTRIPLE) + paddingScale) * abs(bi.biHeight);
bi.biSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
RGBTRIPLE *tripleScale = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(oriHeight); i < biHeight; i++)
{
// reset the counter(index) to start at 0 for each row
count=0;
// iterate over pixels in scanline
for (int j = 0; j < oriWidth; j++)
{
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
// write RGB triple to array scale times (n times)
for(int px = 0; px < scale; px++){
tripleScale[count] = triple;
count++;
}
}
// skip over padding, if any
fseek(inptr, padding, SEEK_CUR);
//repeat scale times (n times) for vertical rows
for(int row=0; row<scale; row++){
// write RGB triple to outfile
fwrite(tripleScale, sizeof(RGBTRIPLE), bi.biWidth, outptr);
// add the padding back (to demonstrate how)
for (int k = 0; k < paddingScale; k++)
{
fputc(0x00, outptr);
}
}
}
// free the allocated memory with malloc
// free(tripleScale);
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}