Code:
/* greypic.c */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <malloc.h>
/*-------STRUCTURES---------*/
typedef struct sImage{int rows; int cols; int bits; unsigned char* data;} sImage ;
/*-------PROTOTYPES---------*/
long getImageInfo(FILE*, long, int);
void copyImageInfo(FILE*, FILE*);
void copyColorTable(FILE*, FILE*, int);
int main()
{
FILE *bmpInput;
FILE *bmpOutput;
sImage originalImage;
unsigned char someChar;
unsigned char *pChar;
int nColors; /* BMP number of colors */
long fileSize; /* BMP file size */
int vectorSize; /* BMP vector size */
int r, c; /* r = rows, c = cols */
int i;
int ** pixels;
char imagein[30];
char imageout[30];
/* initialize pointer */
someChar = '0';
pChar = &someChar;
printf("Enter input image : ");
fgets(imagein , sizeof(imagein) , stdin) ;
/* slash n strip added */
for(i = 0; i < sizeof(imagein) ; i++ )
{
if ( imagein[i] == '\n' )
{
imagein[i] = '\0';
break;
}
}
printf("Enter output image : ");
fgets(imageout , sizeof(imageout) , stdin) ;
/* slash n strip added */
for(i = 0; i < sizeof(imageout) ; i++ )
{
if ( imageout[i] == '\n' )
{
imageout[i] = '\0';
break;
}
}
/*--------READ INPUT FILE------------*/
bmpInput = fopen(imagein, "rb");
/* check for fopen failure */
if(bmpInput == NULL)
{
printf("Error opening file\n");
return 1;
}
fseek(bmpInput, 0L, SEEK_END);
/*--------DECLARE OUTPUT FILE--------*/
bmpOutput = fopen(imageout, "wb");
if (bmpOutput == NULL)
{
printf("Error opening file\n");
return 1;
}
pixels = (int**)malloc(600*600*sizeof(**pixels));
if(!pixels)
{
printf("Error allocating memory\n");
exit(1);
}
/*--------GET BMP DATA---------------*/
originalImage.cols = (int)getImageInfo(bmpInput, 18, 4);
originalImage.rows = (int)getImageInfo(bmpInput, 22, 4);
originalImage.bits = (int)getImageInfo(bmpInput, 28, 4);
fileSize = getImageInfo(bmpInput, 2, 4);
nColors = getImageInfo(bmpInput, 46, 4);
vectorSize = fileSize - (14 + 40 + 4*nColors);
/*-------PRINT DATA TO SCREEN-------------*/
printf("Width: %d\n", originalImage.cols);
printf("Height: %d\n", originalImage.rows);
printf("Bits per Pixel: %d\n", originalImage.bits);
printf("File size: %ld\n", fileSize);
printf("# Colors: %d\n", nColors);
printf("Vector size: %d\n", vectorSize);
copyImageInfo(bmpInput, bmpOutput);
copyColorTable(bmpInput, bmpOutput, nColors);
/*----START AT BEGINNING OF RASTER DATA-----*/
fseek(bmpInput, (54 + 4*nColors), SEEK_SET);
/*----------READ RASTER DATA----------*/
for(r=0; r< originalImage.rows ; r++)
{
for(c=0; c< originalImage.cols ; c++)
{
/*-----read data, reflect and write to output file----*/
fread(pChar, sizeof(char), 1, bmpInput);
pixels[r][c] = *pChar;
*pChar = 255 - *pChar;
fwrite(pChar, sizeof(char), 1, bmpOutput);
}
}
fclose(bmpInput);
fclose(bmpOutput);
getch();
free(pixels);
return 0;
}
/*----------GET IMAGE INFO SUBPROGRAM--------------*/
long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value = 0L;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, offset, SEEK_SET);
for(i=1; i< numberOfChars; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
/* calculate value based on adding bytes */
value = (long)(value + (*ptrC)*(pow(256, (i-1))));
}
return(value);
} /* end of getImageInfo */
/*-------------COPIES HEADER AND INFO HEADER----------------*/
void copyImageInfo(FILE* inputFile, FILE* outputFile)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 0L, SEEK_SET);
fseek(outputFile, 0L, SEEK_SET);
for(i=0; i<=50; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}
/*----------------COPIES COLOR TABLE-----------------------------*/
void copyColorTable(FILE* inputFile, FILE* outputFile, int nColors)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 54L, SEEK_SET);
fseek(outputFile, 54L, SEEK_SET);
for(i=0; i<(4*nColors); i++) /* there are (4*nColors) bytesin color table */
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}