Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/////////////// Structures
typedef struct{
char type[2]; // file type
unsigned int size; // file size in bytes
unsigned short int reserved1,reserved2;
unsigned int offset; // offset to image data
}HEADER;
typedef struct{
unsigned int size;
int width,height;
unsigned short int planes;
unsigned short int bpp;
unsigned int compression;
unsigned int imagesize;
int xresolution,yresolution;
unsigned int colours;
unsigned int impcolours;
unsigned char colourtable[1024]; // 256*4 bytes long
}INFOHEADER;
/////////////// Verify if the file exist
FILE* exist(char *name){
FILE *tmp;
tmp = fopen(name,"rb");
if (!tmp){
printf("\nERROR: Incorrect file or not exist!\n");
exit(0);
}
fseek(tmp,0,0);
return(tmp);
}
/////////////// Verify if the file is 8 bit BMP
void isBMP(FILE* arq){
char type[3];
unsigned short int bpp;
fseek(arq,0,0);
fread(type,1,2,arq);
type[2] = '\0';
fseek(arq,28,0);
fread(&bpp,1,2,arq);
if (strcmp(type,"BM") || (bpp != 8)){
printf("\nThe file is not BMP format or is not 8 bits\n");
exit(0);
}
}
/////////////// Read BMP info from file
INFOHEADER readInfo(FILE* arq){
INFOHEADER info;
// Image Width in pixels
fseek(arq,18,0);
fread(&info.width,1,4,arq);
printf("info.width: %d\n", info.width);
// Image Height in pixels
fseek(arq,22,0);
fread(&info.height,1,4,arq);
printf("info.height: %d\n", info.height);
// Color depth, BPP (bits per pixel)
fseek(arq,28,0);
fread(&info.bpp,1,2,arq);
printf("info.bbp: %d\n", info.bpp);
// Compression type
// 0 = Normmally
// 1 = 8 bits per pixel
// 2 = 4 bits per pixel
fseek(arq,30,0);
fread(&info.compression,1,4,arq);
printf("info.compression: %d\n", info.compression);
// Image size in bytes
fseek(arq,34,0);
fread(&info.imagesize,1,4,arq);
printf("info.imagesize: %d\n", info.imagesize);
// Number of color used (NCL)
// value = 0 for full color set
fseek(arq,46,0);
fread(&info.colours,1,4,arq);
printf("info.colours: %d\n", info.colours);
// Number of important color (NIC)
// value = 0 means all collors important
fseek(arq,50,0);
fread(&info.impcolours,1,4,arq);
// Colour table
fseek(arq,54,0);
fread(&info.colourtable,256,4,arq);
return(info);
}
/////////////// Create Matrix
unsigned char** createMatrix(INFOHEADER info){
unsigned char** Matrix;
int i;
Matrix = (unsigned char**) malloc(info.height * sizeof(unsigned char*));
if (Matrix == NULL){
perror("***** No memory available *****");
exit(0);
}
for (i=0;i<info.height;i++){
Matrix[i] = (unsigned char*) malloc(info.width * sizeof(unsigned char));
if (Matrix[i] == NULL){
perror("***** No memory available *****");
exit(0);
}
}
return(Matrix);
}
/////////////// Load image data to matrix
void loadImage(FILE* arq, INFOHEADER info, unsigned char** Matrix){
int i,j;
unsigned char tmp;
int test;
long pos = 1077; // header + colourtable length is 1078 start reading pixel info from here
fseek(arq,0,0);
for (i=0; i<info.height; i++){
for (j=0; j<info.width; j++){
pos+= 1;
fseek(arq,pos,0);
fread(&tmp,(sizeof(unsigned char)),1,arq);
Matrix[i][j] = tmp;
//printf("Matrix[%i][%i]= %i \n", i,j,tmp);
}
}
}
// ********** Image Output **********
void writeBMP(unsigned char **Matrix, HEADER head, INFOHEADER info, FILE* arq){
FILE* out;
int i,j;
unsigned char tmp;
long pos = 1077;
char header[54];
char colourtable[1024];
fseek(arq,0,0);
fread(header,54,1,arq); // read header 54 bytes
out = fopen("out.bmp","wb");
fseek(out,0,0);
fwrite(header,54,1,out); // write header to output
fseek(out,54,0);
fwrite(info.colourtable,1024,1,out); // write colour table to output
for(i=0;i<info.height;i++){
for(j=0;j<info.width;j++){
pos+= 1;
fseek(out,pos,0);
tmp = Matrix[i][j];
fwrite(&tmp,(sizeof(unsigned char)),1,out);
}
}
fflush(out);
fclose(out);
}
// ********** Free memory allocated for Matrix **********
void freeMatrix(unsigned char** Matrix,INFOHEADER info)
{
int i;
int lines = info.height;
for (i=0;i<lines;i++){
free(Matrix[i]);
}
free(Matrix);
}
/* in your main program you just call */
// FILE* arq; /* the bitmap file 24 bits */
/* RGB** Matrix_aux, Matrix;
INFOHEADER info;
info = readInfo(FILE* arq);
height = info.height;
width = info.width;
Matrix_aux = createMatrix();
Matrix = loadImage(arq,Matrix_aux);
*/
main(){
FILE *arq;
unsigned char **Matrix;
INFOHEADER info;
HEADER head;
char name[15];
printf("Type the image's name : ");
scanf("%s",name);
arq = exist(name);
isBMP(arq);
info = readInfo(arq);
Matrix = createMatrix(info);
loadImage(arq,info,Matrix);
writeBMP(Matrix,head,info,arq);
freeMatrix(Matrix,info);
}