⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 基于BMP图像的信息隐藏
💻 CPP
📖 第 1 页 / 共 4 页
字号:
return FALSE; 
} 
} 

*(heap->nextchar)=data; 
heap->heaplen++; 
heap->nextchar++; 

return TRUE; 
} 

/*********************************************************************/ 
/******************************BMP HANDLER ROUTINES*******************/ 

int readBitmapFile(FILE* bmpfile, BITMAP* datazone) { 

unsigned char tmpchar; 
int dataread; 
int i; 
long offsetToRaster=0; 

/* Get Signature */ 
datazone->signature=(char*)calloc(3,sizeof(char)); 
datazone->signature[2]='\0'; 
dataread=fscanf(bmpfile,"%c",&tmpchar); 
if (dataread==1) 
datazone->signature[0]=tmpchar; 
dataread=fscanf(bmpfile,"%c",&tmpchar); 
if (dataread==1) 
datazone->signature[1]=tmpchar; 

/* Get Filesize */ 
datazone->filesize=streamToLong(bmpfile); 

/* Skip reserved section */ 
for (i=0; i< 4; i++) 
dataread=fscanf(bmpfile,"%c",&tmpchar); 

/* Get Raster Offset */ 
offsetToRaster=streamToLong(bmpfile); 

/* Skip size of infoheader (always=40 anyway) */ 
for (i=0; i< 4; i++) 
dataread=fscanf(bmpfile,"%c",&tmpchar); 

/* Get Bitmap width (x_size) */ 
datazone->x_size=streamToLong(bmpfile); 

/* Get Bitmap height (y_size) */ 
datazone->y_size=streamToLong(bmpfile); 

/* Get number bitplanes */ 
dataread=fscanf(bmpfile,"%c",&tmpchar); 
if (dataread==1) 
datazone->bitplanes=((unsigned int)tmpchar*1); 
dataread=fscanf(bmpfile,"%c",&tmpchar); 
if (dataread==1) 
datazone->bitplanes+=((unsigned int)tmpchar*256); 

/* Get bits per pixel */ 
dataread=fscanf(bmpfile,"%c",&tmpchar); 
if (dataread==1) 
datazone->bpp=((unsigned int)tmpchar*1); 
dataread=fscanf(bmpfile,"%c",&tmpchar); 
if (dataread==1) 
datazone->bpp+=((unsigned int)tmpchar*256); 

/* Get Compression */ 
datazone->compression=streamToLong(bmpfile); 

/* Get Compressed Image Size */ 
datazone->compresssize=streamToLong(bmpfile); 

/* Get X pix per metre */ 
datazone->x_pix_per_metre=streamToLong(bmpfile); 

/* Get Y pix per metre */ 
datazone->y_pix_per_metre=streamToLong(bmpfile); 

/* Get Colours Used */ 
datazone->colours=streamToLong(bmpfile); 

/* Get num important colours*/ 
datazone->cols_important=streamToLong(bmpfile); 

if (datazone->bpp<=8) 
{ 
int numcolors=0; 
switch(datazone->bpp) { 
case 1: numcolors=1; 
case 4: numcolors=16; 
case 8: numcolors=256; 
} 
for (i=0; i<numcolors; i++) { 
unsigned char readchar; 
/* RED */ 
if (fscanf(bmpfile,"%c",&readchar) >0) { 
if (!putToHeap(readchar,datazone->palette)) 
return FALSE; 
} 
/* GREEN */ 
if (fscanf(bmpfile,"%c",&readchar) >0) { 
if (!putToHeap(readchar,datazone->palette)) 
return FALSE; 
} 
/* BLUE */ 
if (fscanf(bmpfile,"%c",&readchar) >0) { 
if (!putToHeap(readchar,datazone->palette)) 
return FALSE; 
} 
/* RESERVED */ 
if (fscanf(bmpfile,"%c",&readchar) >0) { 
if (!putToHeap(readchar,datazone->palette)) 
return FALSE; 
} 
} 
} 


if (fseek(bmpfile,offsetToRaster,SEEK_SET)==0) 
if(!streamFileToHeap(bmpfile,datazone->raster)) 
return FALSE; 

return TRUE;} 

void promoteTo24(BITMAP* source, BITMAP* dest) { 
unsigned long int ctr; 
unsigned char* tmpptr; 
unsigned char tmpchar[4]; 
unsigned char split16_1,split16_2; 
unsigned int EOLtargetpadding; /*in bits, for 24 target*/ 
unsigned long int xpos; 
int i; 

/* translate */ 
EOLtargetpadding=calcEOLpad(24,source->x_size); 

xpos=0; 
tmpptr=source->raster->dataspace; 
for (ctr=0; ctr< source->raster->heaplen; ctr+=4) { 
switch(source->bpp) { 
case 4: /* 16colour */ 
for (i=0; i< 4; i++) 
tmpchar[i]=*(tmpptr++); 
for (i=0; i< 4; i++) { 
split16_1=tmpchar[i]; 
split16_2=tmpchar[i]; 
split16_1=(split16_1&0xf0) >>4; 
split16_2=split16_2&0xf; 
if (xpos<source->x_size) { 
process24gotpixel(split16_1,source->palette->dataspace,dest->raster); 
xpos++; 
} 
if (xpos< source->x_size) { 
process24gotpixel(split16_2,source->palette->dataspace,dest->raster); 
xpos++; 
} 
} 
break; 
case 8: /* 256 cols */ 
for (i=0; i< 4; i++) { 
tmpchar[i]=*(tmpptr++); 
} 
for (i=0; i< 4; i++) { 
if (xpos< source->x_size) { 
process24gotpixel(tmpchar[i],source->palette->dataspace,dest->raster); 
xpos++; 
} 
} 
break; 
} 
if (xpos==source->x_size) { 
/* align on source */ 
xpos=0; 
/* align on 24bit target */ 
for (i=0; i<EOLtargetpadding; i++) 
putToHeap('\0',dest->raster); 
} 
} 

/* sort header info out */ 
dest->signature=(char*)calloc(3,sizeof(char)); 
dest->signature[0]='B'; 
dest->signature[1]='M'; 
dest->signature[2]='\0'; 
dest->compression=0; 
dest->x_pix_per_metre=source->x_pix_per_metre; 
dest->y_pix_per_metre=source->y_pix_per_metre; 
dest->bitplanes=1; 
dest->bpp=24; 
dest->x_size=source->x_size; 
dest->y_size=source->y_size; 
dest->colours=0; 
dest->cols_important=0; 
/*file sizes */ 
dest->compresssize=dest->raster->heaplen; 
dest->filesize=54+(dest->compresssize); 
} 

void process24gotpixel(unsigned char pal, unsigned char* palette, HEAP* raster) { 
/* got pixel palette entry# PAL */ 
palette+=(unsigned int)pal*4; 
putToHeap(*palette,raster); 
putToHeap(*(palette+1),raster); 
putToHeap(*(palette+2),raster); 

} 

void writeBitmapFile(FILE* outfile, BITMAP* source) { 
unsigned char* curspace=NULL; 
unsigned long int ctr; 

fprintf(outfile,"%c%c",source->signature[0],source->signature[1]); 
longToStream(outfile,source->filesize); 
longToStream(outfile,0); 
longToStream(outfile,54); 
longToStream(outfile,40); 
longToStream(outfile,source->x_size); 
longToStream(outfile,source->y_size); 
fprintf(outfile,"%c%c%c%c",1,0,24,0); 
longToStream(outfile,source->compression); 
longToStream(outfile,source->compresssize); 
longToStream(outfile,source->x_pix_per_metre); 
longToStream(outfile,source->y_pix_per_metre); 
longToStream(outfile,0); 
longToStream(outfile,0); 
/* stream out dataspace */ 

ctr=0; 
curspace=(source->raster->dataspace); 
while (ctr< source->raster->heaplen) { 
fprintf(outfile,"%c",*(curspace++)); 
ctr++; 
} 
} 


/*********************************************************************/ 
/**************************** ENCODE FUNCTIONS ***********************/ 
unsigned long int resolveMaxEncode(BITMAP* bmp, LOOKUP* store) { 
/* return maximum possible storage space in BMP */ 

unsigned long storage; 
unsigned long offset,tmp; 
unsigned char thisR; 
unsigned char thisG; 
unsigned char thisB; 
unsigned char lookaheadR; 
unsigned char lookaheadG; 
unsigned char lookaheadB; 
int dom,lookaheaddom; 
int keepflag,keepflag2; 
unsigned long int hits; 
PIXEL getdata, corrupta; 
unsigned long int longtmp; 
unsigned long int longtmp2; 
unsigned long int *longptrtmp; 

offset=0; 
storage=0; /* running total */ 

while (offset<(bmp->x_size*bmp->y_size)) { 
getdata=getIndexedPixel(offset, bmp); 
thisR=getdata.red; 
thisG=getdata.green; 
thisB=getdata.blue; 

dom=biggest_of_3(thisR,thisG,thisB); 
keepflag=FALSE; 

/* If 1 col varies from others by at least 3 = > candidate */ 
if (dom==thisG && abs(thisG-thisR) >2 && abs(thisG-thisB) >2) 
keepflag=TRUE; 
if (dom==thisB && abs(thisB-thisR) >2 && abs(thisB-thisG) >2) 
keepflag=TRUE; 
if (dom==thisR && abs(thisR-thisB) >2 && abs(thisR-thisG) >2) 
keepflag=TRUE; 
if (keepflag==FALSE) { 
offset++; 
continue; 
} 

/* only one of the 3 cols=dom here, and that col is at least 
3 points greater than the others */ 

/* see if dominant col continues on more pixels + that other 
cols dont challenge its dominance */ 

tmp=offset+1; 
hits=1; 
while (tmp<(bmp->x_size*bmp->y_size)) { 
getdata=getIndexedPixel(tmp, bmp); 
lookaheadR=getdata.red; 
lookaheadG=getdata.green; 
lookaheadB=getdata.blue; 
keepflag=FALSE; 
if (dom==thisG && lookaheadG==thisG) 
keepflag=TRUE; 
if (dom==thisR && lookaheadR==thisR) 
keepflag=TRUE; 
if (dom==thisB && lookaheadB==thisB) 
keepflag=TRUE; 

/* check dom is still dominant col by at least 4 */ 
lookaheaddom=biggest_of_3(lookaheadR,lookaheadG,lookaheadB); 
keepflag2=FALSE; 
if (thisR==dom && lookaheadR==lookaheaddom && abs(lookaheadR-lookaheadG) >2 && abs(lookaheadR-lookaheadB) >2) 
keepflag2=TRUE; 
if (thisG==dom && lookaheadG==lookaheaddom && abs(lookaheadG-lookaheadR) >2 && abs(lookaheadG-lookaheadB) >2) 
keepflag2=TRUE; 
if (thisB==dom && lookaheadB==lookaheaddom && abs(lookaheadB-lookaheadR) >2 && abs(lookaheadB-lookaheadG) >2) 
keepflag2=TRUE; 

if (keepflag==FALSE || keepflag2==FALSE) { 
/* make this byte (that broke chain) much 
different to running colour byte to prevent decode confusion */ 
if (thisR==dom && lookaheadR!=thisR && abs(thisR-lookaheadR)< 3) { 
/* chain was red, and broke with a minor difference*/ 
corrupta.blue=lookaheadB; 
corrupta.green=lookaheadG; 
if (lookaheadR >thisR) { 
if (lookaheadR< 253) 
corrupta.red=lookaheadR+3; 
else 
corrupta.red=lookaheadR-6; 
} 
else { 
if (lookaheadR< 253) 
corrupta.red=lookaheadR-3; 
else 
corrupta.red=lookaheadR-6; 
} 
setIndexedPixel(tmp,bmp,corrupta); 

} 
else if (thisG==dom && lookaheadG!=thisG && abs(thisG-lookaheadG)< 3) { 
/* chain was green and broke with minor diff*/ 
corrupta.red=lookaheadR; 
corrupta.blue=lookaheadB; 
if (lookaheadG >thisG) { 
if (lookaheadG< 253) 
corrupta.green=lookaheadG+3; 
else 
corrupta.green=lookaheadG-6; 
} 
else { 
if (lookaheadG< 253) 
corrupta.green=lookaheadG-3; 
else 
corrupta.green=lookaheadG-6; 
} 
setIndexedPixel(tmp,bmp,corrupta); 
} 
else if (thisB==dom && lookaheadB!=thisB && abs(thisB-lookaheadB)< 3) { 
/* chain was blue and broke with minor diff */ 
corrupta.green=lookaheadG; 
corrupta.red=lookaheadR; 
if (lookaheadB >thisB) { 
if (lookaheadB< 253) 
corrupta.blue=lookaheadB+3; 
else 
corrupta.blue=lookaheadB-6; 
} 
else { 
if (lookaheadB< 253) 
corrupta.blue=lookaheadB-3; 
else 
corrupta.blue=lookaheadB-6; 
} 
setIndexedPixel(tmp,bmp,corrupta); 
} 
break; 
} 
hits++; 
tmp++; 
} 

if (hits >2) { 
storage+=(hits-2); 
/* store in lookup table */ 
for (longtmp=offset+2; longtmp< offset+hits; longtmp++) { 
if (store->curitem >=store->currentlen) { 
longptrtmp=store->dataspace; 
store->dataspace=(unsigned long int*)calloc(2*store->currentlen,sizeof(unsigned long int)); 
for (longtmp2=0; longtmp2< store->currentlen; longtmp2++) { 
*(store->dataspace+longtmp2)=*(longptrtmp+longtmp2); 
} 
free (longptrtmp); 
longptrtmp=NULL; 
store->currentlen*=2; 
} 
*(store->dataspace+(store->curitem++))=longtmp; 
} 
offset+=hits; 
} 
else { 
offset++; 
} 
} 

return (unsigned long)(storage/8); 
} 

unsigned int biggest_of_3 (unsigned int a, unsigned int b, unsigned int c) { 
int pr1,pr2; 
if (a >b) 
pr1=a; 
else 
pr1=b; 
if (b >c) 
pr2=b; 
else 
pr2=c; 
if (pr1 >pr2) 
return pr1; 
else 
return pr2; 
} 


/*********************************************************************/ 
void longToStream(FILE* strm, unsigned long int x) { 
unsigned int bit4,bit3,bit2,bit1; 

bit4=(unsigned int)x/16777216; 
x=x-(unsigned long)((unsigned long)bit4*16777216); 
bit3=(unsigned int)x/65536; 
x=x-(unsigned long)((unsigned long)bit3*65536); 
bit2=(unsigned int)x/256; 
x=x-(unsigned long)((unsigned long)bit2*256); 
bit1=(unsigned int)x; 

fprintf(strm,"%c%c%c%c",bit1,bit2,bit3,bit4); 
} 

unsigned long int streamToLong(FILE* strm) { 
unsigned char dataread; 
unsigned char tmpchar; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -