Some thoughts.
1. Your functions are too long.
2. Your functions are working at too low a level.
All that *3, +4, % this, / that, +/- padding is clouding the issues.
You NEED abstraction.
If you're dealing with pixels, then read pixels. Fiddling with 3-byte blocks is just madness.
If it were any other image format apart from BMP, you would be doing this.
Your first step is making sure you can read an image in, then write it back out again
Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
typedef struct {
int width;
int height;
//int pixeloffset;
int padding;
unsigned char header[54];
//unsigned char* pixels;
//int size;
pixel **pixels;
}BMP;
void readHeader(FILE *fp, BMP *bmp) {
fread(bmp->header, sizeof(bmp->header), 1, fp);
}
void writeHeader(FILE *fp, BMP *bmp) {
fwrite(bmp->header, sizeof(bmp->header), 1, fp);
}
void decodeHeader(BMP *bmp) {
bmp->width = *(int*)&bmp->header[18];
bmp->height = *(int*)&bmp->header[22];
//bmp->pixeloffset = *(int*)&bmp->header[10];
bmp->padding = (bmp->width*3) % 4;
//bmp->size = 3 * bmp->width * bmp->height;
bmp->pixels = malloc( sizeof(*bmp->pixels) * bmp->height );
for ( int i = 0 ; i < bmp->height ; i++ ) {
bmp->pixels[i] = malloc( sizeof(*bmp->pixels[i]) * bmp->width );
}
}
void cleanupHeader(BMP *bmp) {
for ( int i = 0 ; i < bmp->height ; i++ ) {
free(bmp->pixels[i]);
}
free(bmp->pixels);
}
pixel readPixel(FILE *fp) {
pixel result;
fread(&result, sizeof(result), 1, fp );
return result;
}
void writePixel(FILE *fp, pixel p) {
fwrite(&p, sizeof(p), 1, fp);
}
void readPadding(FILE *fp, int padding) {
for ( int i = 0 ; i < padding ; i++ )
fgetc(fp); // we don't care, just burn them
}
void writePadding(FILE *fp, int padding) {
for ( int i = 0 ; i < padding ; i++ )
fputc(0,fp); // we don't care, just write zeros
}
void readImage(FILE *fp, BMP *bmp) {
for ( int r = 0 ; r < bmp->height ; r++ ) {
for ( int c = 0 ; c < bmp->width ; c++ ) {
bmp->pixels[r][c] = readPixel(fp);
}
readPadding(fp,bmp->padding);
}
}
void writeImage(FILE *fp, BMP *bmp) {
for ( int r = 0 ; r < bmp->height ; r++ ) {
for ( int c = 0 ; c < bmp->width ; c++ ) {
writePixel(fp,bmp->pixels[r][c]);
}
writePadding(fp,bmp->padding);
}
}
int main ( ) {
FILE *in = fopen("tiger.bmp","rb");
FILE *out= fopen("new.bmp","wb");
BMP bmp;
readHeader(in,&bmp);
decodeHeader(&bmp);
readImage(in,&bmp);
writeHeader(out,&bmp);
writeImage(out,&bmp);
cleanupHeader(&bmp);
fclose(in);
fclose(out);
}
With this, you should find writing mirrorImage a lot less stressful.