I'm trying to resize bmp image and it's almost works, but for some reason I get extra bytes filled with zeros. It kinda works, but I'd like to know where did those zeros come from.
I'm not sure if it's connected somehow with those zeros, but sometimes image depth (biBitCount) changes from 24 in original file to 32. I wasn't able to figure out why it does that. Unfortunately, I didn't save screenshots of that.
I'm sure, that I just did some stupid mistake I can't see. Help me, please. original bmp double sized bmp with extra zeros
My Code :
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "bmp.h"
float atoi2_0(char* S);
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
fprintf(stderr, "Usage: ./resize f infile outfile\n");
return 1;
}
// remember filenames
float f = atoi2_0(argv[1]);
if(f == -1 || f <= 0.0 || f > 100)
{
printf("Usage: ./resize f infile outfile\n");
return 1;
}
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;
}
int oldpadding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biWidth *= f;
bi.biHeight *= f;
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + padding) * abs(bi.biHeight);
bf.bfSize = bi.biSizeImage + 54;
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
float df = f - (int)f;
int revdf = 1 / df;
int bbw = bi.biWidth / f;
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
RGBTRIPLE * oldtriple = (RGBTRIPLE*)calloc(bbw, sizeof(RGBTRIPLE));
if (oldtriple == NULL)
{
fclose(inptr);
fclose(outptr);
return 5;
}
fread(oldtriple, sizeof(RGBTRIPLE), bbw, inptr);
RGBTRIPLE * triple = (RGBTRIPLE*)calloc(bi.biWidth, sizeof(RGBTRIPLE));
if (triple == NULL)
{
free(oldtriple);
fclose(inptr);
fclose(outptr);
return 5;
}
for (int j = 0; j < bbw; j++)
{
int jxf = j * f;
for (int n = 0; n < f; n++)
{
*(triple + jxf + n) = *(oldtriple + j);
}
}
for (int j = 0; j < f; j++)
{
if (i % revdf && f - j == df) continue;
fwrite(triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
for (int n = 0; n < padding; n++)
{
fputc(0x00, outptr);
}
}
fseek(inptr, oldpadding, SEEK_CUR);
free(triple);
free(oldtriple);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}
float atoi2_0(char* S)//kinda atoi for floats
{
int strl = strlen(S);
for (int i = 0; i < strl; i++)//input check
{
if ((S[i] < '0' || S[i] > '9') && (S[i] != '.'))
{
printf("Invalid input");
return -1;
}
}
float a = atoi(S);
char D[10] = { 0 };
for (int i = 0; i < strl; i++)
{
if (S[i] == '.')
{
++i;
for (int j = 0; i < strl; i++, j++)
{
D[j] = S[i];
}
}
}
a += (float)atoi(D) / pow(10, strlen(D));
return a;
}
BMP.h :
``` // BMP-related data types based on Microsoft's own
#include <stdint.h>
// aliases for C/C++ primitive data types
// https://msdn.microsoft.com/en-us/library/cc230309.aspx
typedef uint8_t BYTE;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef uint16_t WORD;
// information about the type, size, and layout of a file
// https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx
typedef struct
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} __attribute__((__packed__))
BITMAPFILEHEADER;
// information about the dimensions and color format
// https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx
typedef struct
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} __attribute__((__packed__))
BITMAPINFOHEADER;
// relative intensities of red, green, and blue
// https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
Yeah, I fixed it myself. Problem was in cycle length.