/* CONVERT A 24-BIT TRUE COLOR IMAGE TO GRAYSCALE IMAGE USING C/C++ CODE*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<conio.h>
/*-------PROTOTYPES-------*/
long getImageInfo(FILE*, long, int);
void copyImageInfo(FILE* inputFile, FILE* outputFile);
void createColorTable(FILE* inputFile, FILE* outputFile);
/*------STRUCTURES--------*/
typedef struct
{ int rows;
int cols;
unsigned char* data;
} sImage;
int main(int argc, char* argv[])
{
FILE *bmpInput, *rasterOutput, *bmpOutput, *grayBmpInput;
sImage originalImage;
unsigned char someChar;
unsigned char *pChar;
unsigned long someLong;
unsigned long *pLong;
long fileSize;
int vectorSize, nColors;
int r, c, i;
int redValue, greenValue, blueValue, grayValue;
/*--------INITIALIZE POINTER----------*/
someChar = '0';
pChar = &someChar;
someLong = '0';
pLong = &someLong;
clrscr();
if(argc < 2)
{
printf("Usage: %s bmpInput.bmp\n", argv[0]);
exit(0);
}
printf("Reading file %s\n", argv[1]);
/*----DECLARE INPUT FILES----*/
bmpInput = fopen(argv[1], "rb");
fseek(bmpInput, 0L, SEEK_END);
grayBmpInput = fopen("p1.bmp", "rb");
fseek(grayBmpInput, 0L, SEEK_END);
/*----DECLARE OUTPUT FILES----*/
rasterOutput = fopen("\\data24.txt", "w");
bmpOutput = fopen("\\gray24.bmp", "wb");
/*-----GET INPUT BMP DATA-----*/
originalImage.cols = (int)getImageInfo(bmpInput, 18, 4);
originalImage.rows = (int)getImageInfo(bmpInput, 22, 4);
/*------------------------------------------------------
TRIED TO COPY COLOR TABLE OF ANOTHER
GRAYSCALE IMAGE???????
------------------------------------------------------*/
copyImageInfo(bmpInput, bmpOutput);
/*----EDIT FILE SIZE TO CONFORM TO 8 BIT BMP---*/
fseek(bmpOutput, 2, SEEK_SET);
*pLong = (unsigned long)(54 + 4*256 + (originalImage.cols * originalImage.rows));
fwrite(pLong, sizeof(unsigned long), 1, bmpOutput);
printf("File size: %ld\n", (long)getImageInfo(bmpOutput, 2, 4));
/*----CHANGE BIT DEPTH FROM 24 TO 8----*/
fseek(bmpOutput, 28, SEEK_SET);
*pLong = (unsigned long)(8);
fwrite(pLong, sizeof(unsigned long), 1, bmpOutput);
printf("Bits/pixel: %d\n", (int)getImageInfo(bmpOutput, 28, 2));
/*---CHANGE #COLORS FROM 16M TO 256---*/
fseek(bmpOutput, 46, SEEK_SET);
*pLong = (unsigned long)(256);
fwrite(pLong, sizeof(unsigned long), 1, bmpOutput);
printf("No. colors: %d\n", (int)getImageInfo(bmpOutput, 46, 4));
createColorTable(grayBmpInput, bmpOutput);
/*----FOR 24-BIT BMP, THERE IS NO COLOR TABLE-----*/
fseek(bmpInput, 54, SEEK_SET);
fseek(bmpOutput, (54 + 4*256), SEEK_SET);
/*-----------READ RASTER DATA-----------*/
for(r=0; r<=originalImage.rows-1; r++)
{
for(c=0; c<=originalImage.cols-1; c++)
{
/*-----READ FIRST BYTE TO GET BLUE VALUE-----*/
fread(pChar, sizeof(char), 1, bmpInput);
blueValue = *pChar;
/*-----READ NEXT BYTE TO GET GREEN VALUE-----*/
fread(pChar, sizeof(char), 1, bmpInput);
greenValue = *pChar;
/*-----READ NEXT BYTE TO GET RED VALUE-----*/
fread(pChar, sizeof(char), 1, bmpInput);
redValue = *pChar;
/*-----USE FORMULA TO CONVERT RGB VALUE TO GRAYSCALE-----*/
grayValue = (int)(0.299*redValue + 0.587*greenValue + 0.114*blueValue);
/*-----PRINT TO TEXT FILE-----*/
fprintf(rasterOutput, "(%d %d) = \tRed \t%d", r, c, redValue);
fprintf(rasterOutput, "\tGreen \t%d \tBlue \t%d \tGray \t%d\n", greenValue, blueValue, grayValue);
/*-----WRITE TO NEW BMP FILE------*/
*pChar = grayValue;
fwrite(pChar, sizeof(char), 1, bmpOutput);
}
}
fclose(bmpInput);
fclose(rasterOutput);
fclose(bmpOutput);
fclose(grayBmpInput);
return 0;
}
/*----GET IMAGE INFO SUBPROGRAM------*/
long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
unsigned char *ptrC;
long value=0L;
int i;
unsigned char dummy;
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);
}
/*--------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 createColorTable(FILE* inputFile, FILE* outputFile)
{
unsigned char *ptrC;
unsigned char dummy;
int i;
dummy = '0';
ptrC = &dummy;
fseek(inputFile, 54L, SEEK_SET);
fseek(outputFile, 54L, SEEK_SET);
for(i=1; i<=4*256; i++)
{
fread(ptrC, sizeof(char), 1, inputFile);
fwrite(ptrC, sizeof(char), 1, outputFile);
}
}