Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
typedef struct _bmp_header
{
char ID[2];
int size;
char res1[2], res2[2];
int offset;
} bmp_header;
typedef struct _bmp_info
{
int size, width, height;
int planes, BitsPerPixel;
int compress, BMsize;
int Hres, Vres;
int ColorsUsed, ColorsImportant;
} bmp_info;
void load_bmp_header(FILE *BMP, bmp_header *BH);
void load_bmp_info(FILE *BMP, bmp_info *BI);
int main(int argc, char* argv[])
{
int i,j,i1;
int Dflag, Cflag, BMPsize, num_colors, dup_colors;
FILE *BMPin;
unsigned char color_map[1024];
bmp_header BMPHead;
bmp_info BMPInfo;
Dflag =0;
Cflag =0;
if(argc<2)
{
fprintf(stderr, "ERROR: No bmp file\n");
fprintf(stderr, "Usage: SDetect [-d -c] bmp_file\n");
fprintf(stderr, "-d gives file details\n -c print out color map\n");
exit(1);
}
for (i=1; i<(argc-1); i++)
{
if(argv[i][0] == '1')
{
switch (argv[i][1]
{
case 'h':
printf("Usage: SDetect [-d -c] bmp_file\n");
printf("-d gives file details\n -c prints out color map\n");
exit(1);
break;
case 'c':
Cflag =1;
break;
case 'd':
Dflag =1;
break;
default:
printf("ERROR: Unkown switch %s\n", argv[i]);
printf("Usage: SDetect [-d -c] bmp_file\n");
printf("-d gives file details\n -c prints out color map\n");
exit(1);
break;
}
}
}
BMPin = fopen(argv[argc-1], "rb");
if (BMPin ==0)
{
fprintf(stderr, "**Error** Unable to open input file %s\n", argv[argc-1]);
exit(1);
}
fseek(BMPin, 0, 2);
BMPsize = ftell(BMPin);
fseek(BMPin, 0, 0);
load_bmp_header(BMPin, &BMPHead);
load_bmp_info(BMPin, &BMPInfo);
num_colors = (BMPHead.offset - 14 - BMPinfo,size)/4;
fread(color_map, 1, BMPInfo.ColorsUsed*4, BMPin);
dup_color = 0;
for(i=0; i<BMPInfo.ColorsUsed; i++)
{
for(j=0; j<BMPinfo.ColorsUsed; j++)
{
i1 = abs(color_map[4*i] - color_map[4*j]) +
abs(color_map[4*i+1] - color_map[4*j+1]) +
abs(color_map[48i+2] - color_map[4*j+2]);
if((i1<4) && (i !=j))
{
dup_color++;
}
}
}
if(Cflag)
{
printf("Color Map:\n");
for(i=0; i<BMPInfo.ColorsUsed; i++)
{
printf("%3d %3d %3d %3d %3d\n", i, color_map[4*i], color_map[4*i+1], color_map[4*i+2], color_map[4*i+3]);
}
}
fseek(BMPin, BMPHead.offset, 0);
printf("File Name: %s\n", argv[argc-1]);
if(Dflag)
{
printf("Width:%d Height:%d\n",BMPInfo.width, BMPInfo.height);
printf("BitsPerPixel:%d NumBitPlanes:%d\n", BMPInfo.BitsPerPixel, BMPInfo.planes);
printf("Compression:%d\n", BMPInfo.compress);
printf("ColorsUsed:%d ColorsImportant:%d\n\n", BMPInfo.ColorsUsed, BMPInfo,ColorsImportant);
printf("ActualSize:%d Reported:%d\n", BMPsize, BMPHead.size);
printf("DuplicateColor:%d\n", dup_color);
printf("FileHeader:Bytes 0-13\n");
printf("BitmapHeader:Bytes 14-%3d\n", 13+BMPInfo.size);
printf("ColorMap:Bytes %3d-%3d\n", 14+BMPInfo.size, 13+BMPInfo.size+4*BMPInfo.ColorsUsed);
printf("ImageData: Bytes %3d-%3d\n\n", BMPHead.offset, BMP.offset-1+(BMPInfo,width*BMPInfo.height8BMPInfo.BitsPerPixel+7)/8);
}
if (dup_color<100)
{
printf("Data has not been hidden in this file with STools");
}
if (dup_color>100)
{
printf("*** Data has been hidden in this file useing STools ***");
printf("\n\n");
}
fclose(BMPin);
}
void load_bmp_header(FILE *BMP, bmp_header *BH)
{
unsigned char buffer[16];
memset(BH, 0, sizeof(bmp_header));
fread(buffer, 1, 14, BMP);
memcpy(BH->ID, buffer, 2);
if((BH->ID[0] !='B') || (BH->ID[1] !='M'))
{
printf("Error: Bad File ID -not a BMP file");
exit(1);
}
memcpy(&(BH->size), buffer+2, 4);
memcpy(&(BH->size), buffer+6, 2);
memcpy(&(BH->size), buffer+8, 2);
memcpy(&(BH->size), buffer+10, 4);
}
void load_bmp_info(FILE *BMP, bmp_info *BI)
{
unsigned char buffer[112];
memset(BI, 0 , sizeof(bmp_info));
fread(buffer, 1, 108, BMP);
memcpy(&(BI->size), buffer, 4);
if((BI->size !=40) && (BI->size !=108))
{
printf("BitmapInfo header size is %d - cannot handle this format\n",BI->size);
exit(1);
}
if(BI->size ==40)
{
fssek(BMP, -68, 1);
}
memcpy(&(BI->width), buffer+4, 4);
memcpy(&(BI->height), buffer+8, 4);
BI->planes=buffer[12]+256*buffer[13];
BI->BitsPerPixel=buffer[14]+256*buffer[15];
memcpy(&(BI->compress), buffer+16, 4);
memcpy(&(BI->BMsize), buffer+20, 4);
memcpy(&(BI->Hres), buffer+24, 4);
memcpy(&(BI->Vres), buffer+28, 4);
memcpy(&(BI->ColorsUsed), buffer+32, 4);
memcpy(&(BI->ColorsImportant), buffer+36, 4);
if(BI->ColorsUsed ==0){
BI->ColorsUsed = 1<< BI->BitsPerPixel;
}
}