I don't understand how the new image will implement new data i imput in like new_biWidth or new_biheigh. I added this new variables in bmp.h and I asigned to them same tipes of data like the old ones. But how does my new image know how to incorporate in header new variables instead of using the old ones. Is it better to just modify the old variables and use for example just bi.biweight *= n;
?
About padding, i don't exactly know how to implement it inheader to calculate the size of the image. Do I need to modify it before calculating other stuff, like the new image width? Or can i use the old formula like i used in the code.
for the moment when i try to run the program I recive the following
error:Unsupported file format
Why does it behave like that? Is it becasue I mess up by creating the new variables in the header ?
// Copies a BMP file
#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
fprintf(stderr, "Usage: copy infile outfile\n");
return 1;
}
int n = atoi(argv[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;
}
// Updteing the header
bi.new_biWidth = bi.biWidth * n;
bi.new_biHeight = bi.biHeight * n;
int padding = (4 - (bi.new_biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.new_biWidth) + padding) * abs(bi.new_biHeight);
bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// 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
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);
}
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}
bi.new_biWidth = bi.biWidth * n;
. You need to modify the old variables likebi.biWidth
, but also save them to use them latererror:Unsupported file format
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
andfread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
. Now you need to change the attributes of these headers using for examplebi.biweight *= n;
but also you need to save the old values in a variable to use them later in the for loop for example. Now after changing the attributes, you will write the new header in the new BMP usingfwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);