快讯
- 装机圈新宠儿,微星 MAG B850M MORTAR Wi-Fi迫击炮主板评测
- 微星MPG Z890I EDGE TI WIFI 刀锋 钛评测:14 层 PCB 加持,同级之中强无敌!
- 打造低调而卓越的Ai PC,微星MEG Z890 ACE战神主板开箱
- 解密“星”制造,微星深圳恩斯迈工厂探秘之旅
- 游泳也需音乐相伴!韶音OpenSwim Pro评测
- 又一款轻量化电竞
- 元气满满的充电之旅!铂陆帝商超活动嗨翻周末
- 雷柏机甲编码主题系列警戒线S-07图赏:以机械美感诠释潮流新理念桌搭!
- 更适合新手体质的枪战游戏,《无畏契约》开战!
- 现代与传统的融合之旅:贝尔金笔记本扩展坞体验
- 航天品质下的极速充电体验——航嘉G65 GaN快速充电器评测
- 有颜有实力的外设谁能不爱?来看雷柏商超巡演
- 新潮外设引爆全场!雷柏联合PC打造潮品酷玩趴
- 幻彩绚丽,玩趣十足!雷柏V700DIY键盘图赏
- U皇就该配板皇,超频玩家现身说法教你选主板
- 13代酷睿的超频利器,有好板才有好性能
- 全新升级,雷柏V20S RGB光学游戏鼠标2023版详解
- 马斯克30亿放“烟花”,民航故事为何值钱?
- 让露营生活更精致!铂陆帝户外电源AC180评测
- 惠威音响体验:音响中的艺术品,拥有好听的灵魂
- 装机圈新宠儿,微星 MAG B850M MORTAR WiFi迫击炮主板评测31日
- 微星MPG Z890I EDGE TI WIFI 刀锋 钛评测:14 层 PCB 加持,同级之中强无敌!29日
- 打造低调而卓越的Ai PC,微星MEG Z890 ACE战神主板开箱10日
- 解密“星”制造,微星深圳恩斯迈工厂探秘之旅02日
- 游泳也需要音乐相伴!韶音新一代游泳耳机OpenSwim Pro评测12日
- 又一款轻量化电竞"神鼠"来袭!玄熊猫3395游戏鼠标今晚首发149元10日
- 元气满满的充电之旅!铂陆帝商超活动嗨翻周末27日
- 雷柏机甲编码主题系列警戒线S-07图赏:以机械美感诠释潮流新理念桌搭!24日
- 更适合新手体质的枪战游戏,《无畏契约》国服正式开战!20日
- 玩物近话论:现代科技与甘南秘境的融合之旅 贝尔金笔记本扩展坞体验14日
- 航天品质下的极速充电体验——航嘉G65 GaN快速充电器评测12日
- 有颜有实力的外设好物谁能不爱?雷柏点燃PCGROUP潮品商超巡演15日
- 新潮外设好物引爆全场!雷柏联合PCGROUP打造潮品酷玩趴15日
- 幻彩绚丽,玩趣十足!雷柏V700DIY热插拔机械键盘图赏10日
- U皇就该配板皇,超频玩家现身说法教你选主板26日
- 13代酷睿的超频利器,有好板才有好性能25日
- 全新升级 经典复刻 雷柏V20S RGB光学游戏鼠标2023版详解25日
- 马斯克30亿放“烟花”,民航故事为何值钱?23日
- 告别电量焦虑,让露营生活多一分精致!铂陆帝户外电源AC180开箱评测17日
- 惠威音响体验:音响中的艺术品,拥有好听的灵魂04日
在BMP文件中隐藏信息
2004-02-14 09:34 出处:PConline 作者:网上收集 责任编辑:zwg
1回顶部 作者: John Collomosse
关键字: BMP 加密
原作者姓名: John Collomosse
文章原始出处: http://www.blindside.co.uk/
介绍
Blindside is a steganography application that hides
information inside .BMP (bitmap) images. It is
a command-line utility, for which source code and
precompiled Unix binaries are available.
The Blindside homepage is located at:
http://www.blindside.co.uk/
正文
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
/************************************\
* B L I N D S I D E *
* *
* Image stego/crypto tool, please *
* see http://www.blindside.co.uk *
* *
* Compile with GCC or equiv ANSI C *
* *
* John Collomosse (mapjpc@bath.ac.uk)*
* Freeware/public domain *
* *
\************************************/
#define HEAP_UNITSIZE (102400)
#define HEAP_INITUNITS (1)
#define LOOKUP_INITLEN (2048)
#define FALSE (0)
#define TRUE (-1)
#define PATH_SEP ('\\') /* OS Specific Path Seperator */
#define BANNER ("BlindSide BMP Cryptographic Tool - (c) John Collomosse 2000\nRelease v0.9. All Rights Reserved, contact: ma7jpc@bath.ac.uk\n\n")
#define THIS_PROTO_VER (1)
/* Heap Structure (memory storage class for uchars) */
typedef struct heapstruct {
unsigned int heapunits; /* Heap size to nearest 'unit' */
unsigned char *dataspace; /* Dataspace where data stored */
unsigned char *nextchar; /* Pointer to end of dataspace */
unsigned long heaplen; /* Length of data in heap */
} HEAP;
typedef struct lookupstruct {
unsigned long int* dataspace;
unsigned long int currentlen;
unsigned long int curitem;
} LOOKUP;
/* Bitmap Structure */
typedef struct bmpstruct {
char* signature;
long filesize;
long x_size;
long y_size;
int bitplanes;
int bpp;
long compression;
long compresssize;
long x_pix_per_metre;
long y_pix_per_metre;
long colours;
long cols_important;
HEAP* palette;
HEAP* raster;
} BITMAP;
typedef struct pixstruct {
unsigned char red;
unsigned char green;
unsigned char blue;
} PIXEL;
/* Function prototypes */
int initialiseHeap (HEAP*);
int expandHeap (int, HEAP*);
void removeHeap (HEAP*);
int putToHeap (unsigned char,HEAP*);
int streamFileToHeap (FILE*, HEAP*);
int readBitmapFile (FILE*, BITMAP*);
void promoteTo24 (BITMAP*, BITMAP*);
unsigned long resolveMaxEncode (BITMAP*, LOOKUP*);
void writeBitmapFile (FILE*, BITMAP*);
unsigned int biggest_of_3 (unsigned int,unsigned int,unsigned int);
void longToStream (FILE*,unsigned long int);
unsigned long streamToLong (FILE*);
void process24gotpixel (unsigned char, unsigned char*,HEAP*);
unsigned int calcEOLpad (int, long);
PIXEL getIndexedPixel (unsigned long int, BITMAP*);
void encodeData (BITMAP*, HEAP*, LOOKUP*);
void setIndexedPixel (unsigned long int, BITMAP*, PIXEL);
unsigned char getNextHeapBit (unsigned long int, int, HEAP*);
int decodeData (BITMAP*, HEAP*);
void cryptoData (HEAP* data, unsigned char* key);
unsigned char xor (unsigned char, unsigned char);
int rotl4 (int);
int hash_func (unsigned char*);
int pow (int,int);
int stricmp (const char*, const char*);
int formatDataspace (BITMAP*, HEAP*);
void dumpFileDirectory (HEAP*);
void dumpFileStats (BITMAP*, HEAP*);
void addFileToArchive (HEAP*, FILE*, char*);
int checkExists (char*);
int extractFile (HEAP*, char*);
void flattenBitmap (BITMAP*, LOOKUP*);
2回顶部
int main (int argc, char** argv) {
int mode;
FILE* bitmap_handle=NULL;
FILE* plaintext_handle=NULL;
FILE* outfile_handle=NULL;
BITMAP* BMPsource=NULL;
BITMAP* BMPworking=NULL;
HEAP* filespace=NULL;
LOOKUP* hotspots;
unsigned long int i;
int isencrypted=FALSE;
char password[130];
printf(BANNER);
mode=0;
if (argc >=2) {
/* deduce mode of operation */
if (stricmp(argv[1],"-A")==0)
mode=1;
if (stricmp(argv[1],"-X")==0)
mode=2;
if (stricmp(argv[1],"-C")==0)
mode=3;
if (stricmp(argv[1],"-L")==0)
mode=4;
}
if (mode==0 || (mode==1 && (argc!=5 && argc!=6)) || (mode==2 && (argc!=3 && argc!=4 && argc!=5)) || (mode==3 && argc!=3) || (mode==4 && argc!=3)) {
printf("USAGE: BSIDE < option > < filenames - see below >\n\n");
printf("Option Description\n");
printf("~~~~~~ ~~~~~~~~~~~\n");
printf(" -A Add a file into image, need to specify files as follows\n");
printf(" BSIDE -A < BMP file > < plaintext file > < result BMP file > [password]\n\n");
printf(" -X eXtract file(s) from image, need to specify files as follows\n");
printf(" BSIDE -X < BMP file > [file to extract] [password if needed]\n\n");
printf(" -C Calculate data storage statistics of a bitmap\n");
printf(" BSIDE -C < BMP file >\n\n");
printf(" -L List files stored within a bitmap\n");
printf(" BSIDE -L < BMP file >\n\n");
printf("Please note that wildcards are NOT currently supported\n\n");
printf("BlindSide is (c) John Collomosse 2000, All Rights Reserved\nComments/suggestions to ma7jpc@bath.ac.uk, updates see www.blindside.co.uk\n");
exit(1);
}3回顶部
/* Read Password off of command line */
for (i=0; i< 129; i++)
password[i]='\0';
if ((argc==6 && mode==1) || (argc==5 && mode==2)) {
isencrypted=TRUE;
for (i=0; i< 129; i++) {
password[i]=argv[6-mode][i];
if (argv[6-mode][i]=='\0')
break;
}
password[129]='\0';
}
/* Open all necessary files */
bitmap_handle=fopen(argv[2],"rb");
if (mode==1)
plaintext_handle=fopen(argv[3],"rb");
if (bitmap_handle==NULL) {
printf("FATAL: Could not open bitmap %s!\n",argv[2]);
exit(2);
}
if (plaintext_handle==NULL && mode==1) {
printf("FATAL: Could not open plaintext %s!\n",argv[3]);
exit(3);
}
/* Read source bitmap (this must be done for every command line variation) */
printf("? Reading bitmap file....");
BMPsource=(BITMAP*)calloc(1,sizeof(BITMAP));
BMPsource- >palette=(HEAP*)calloc(1,sizeof(HEAP));
BMPsource- >raster=(HEAP*)calloc(1,sizeof(HEAP));
initialiseHeap(BMPsource- >palette);
initialiseHeap(BMPsource- >raster);
if (!readBitmapFile(bitmap_handle,BMPsource)) {
printf("ERROR\n\nFATAL: Out of memory, while reading bitmap file\n");
exit(4);
}
printf("OK\n");
/* Analyse Bitmap */
if (stricmp("BM",BMPsource- >signature) || BMPsource- >bitplanes!=1) {
printf("FATAL: Not a valid bitmap file\n");
exit(5);
}
if (BMPsource- >compression!=0) {
printf("FATAL: BlindSide cannot work with compressed bitmaps yet\n");
exit(6);
}
if (BMPsource- >bpp==1) {
printf("FATAL: BlindSide can't work with monochrome images, as it is the colours\nwithin the image itself that are used to hide files within a bitmap.\nYou can only use bitmaps of greater colour depth (16c, 256c, 16Mc)\n");
exit(8);
}
if (BMPsource- >bpp!=4 && BMPsource- >bpp!=8 && BMPsource- >bpp!=24) {
printf("FATAL: Can't work with a bitmap with %d bits per pixel\n\nTry saving the bitmap into a different bit depth in a graphics package.\n",BMPsource- >bpp);
exit(8);
}
printf("? Image is %ld bytes (%ldx%ld), %d bits/pixel\n",BMPsource- >filesize,BMPsource- >x_size,BMPsource- >y_size,BMPsource- >bpp);
4回顶部
/* Colour depth increase if need be */
if (BMPsource- >bpp< 24) {
printf("? Increasing Colour Depth to 16M colours (24bpp)...");
BMPworking=(BITMAP*)calloc(1,sizeof(BITMAP));
if (BMPworking==NULL) {
printf("\n\nFATAL: Out of memory while increasing colour depth");
exit(4);
}
BMPworking- >palette=(HEAP*)calloc(1,sizeof(HEAP));
BMPworking- >raster=(HEAP*)calloc(1,sizeof(HEAP));
if (BMPworking- >palette==NULL || BMPworking- >raster==NULL) {
printf("\n\nFATAL: Out of memory while increasing colour depth");
exit(4);
}
if (!initialiseHeap(BMPworking- >palette) || !initialiseHeap(BMPworking- >raster)) {
printf("\n\nFATAL: Out of memory while increasing colour depth");
exit(4);
}
/* Do the promote to 24bpp */
promoteTo24(BMPsource, BMPworking);
/* cleanup source */
removeHeap(BMPsource- >palette);
removeHeap(BMPsource- >raster);
free(BMPsource);
BMPsource=NULL;
printf("OK\n");
}
else {
/* Source was fine - > already 24 bpp */
BMPworking=BMPsource;
BMPsource=NULL;
}
/* Prepare BS dataspace */
printf("? Analysing Data Patterns....");
filespace=(HEAP*)calloc(1,sizeof(HEAP));
initialiseHeap(filespace);
switch (decodeData(BMPworking,filespace)) {
case 0: printf("OK\n");
break;
case 1: removeHeap(filespace);
initialiseHeap(filespace);
if (mode==2 || mode==4) {
printf("ERROR\n\nFATAL: File does not contain any BlindSide hidden data\n");
exit(4);
}
printf("OK\n");
if (mode==1) {
printf("? Creating New Archive....");
if (formatDataspace(BMPworking, filespace))
printf("OK\n");
else {
printf("ERROR\n\nFATAL: There isn't enough space in the bitmap to hold any Blindside hidden data\n");
exit(4);
}
}
break;
case 2: printf("\nFATAL: Out of memory while analysing bitmap\n");
exit(4);
break;
case 3: printf("\nFATAL: Bitmap was encoded using a higher version of BlindSide than this one\n");
exit(4);
break;
}
5回顶部
/* At this point 'filespace' is always a working BS archive (although it may be one with no files contained) */
/* In case of Mode 3 it MAY NOT be the case that filespace is archive - it may be empty heap */
/* Decrypt if necessary */
if (filespace- >heaplen!=0) {
if (*(filespace- >dataspace+1)=='E') {
/* decrypt */
if (strcmp(password,"")==0) {
/* get pword */
printf("\nData is encrypted, please enter password: ");
scanf("%s",password);
printf("\n");
}
printf("? Decrypting Data....");
cryptoData(filespace,password);
if (*(filespace- >dataspace+7)=='O' && *(filespace- >dataspace+8)=='K') {
printf("OK\n");
isencrypted=TRUE;
}
else {
printf("ERROR\n\nFATAL: Incorrect password\n");
exit(9);
}
}
}
/* Do whichever of the operations was requested */
switch (mode) {
case 1: printf("\n");
for (i=strlen(argv[3]); i >0; i--) {
if (argv[3][i]==PATH_SEP)
break;
}
if (i!=0 || (argv[3][0]==PATH_SEP))
i++;
addFileToArchive(filespace,plaintext_handle,&(argv[3][i]));
printf("\n");
break;
case 2: printf("\n");
if (argc >=3)
extractFile(filespace,argv[3]);
else
extractFile(filespace,NULL);
break;
case 3: dumpFileStats(BMPworking, filespace);
break;
case 4: dumpFileDirectory(filespace);
break;
}
/* Output to disk */
/* If we were in ADD mode, write the bitmap out (Xtract, Calc, and List are READ ONLY) */
if (mode==1) {
/* close plaintext */
fclose(plaintext_handle);
if (isencrypted==TRUE) {
printf("? Encrypting Data....");
cryptoData(filespace,password);
printf("OK\n");
}
printf("? Encoding Data....");
hotspots=(LOOKUP*)calloc(1,sizeof(LOOKUP));
if (hotspots==NULL) {
printf("ERROR\n\nOut of memory\n");
exit(4);
}
hotspots- >dataspace=(unsigned long int*)calloc(LOOKUP_INITLEN,sizeof(unsigned long int));
if (hotspots==NULL) {
printf("ERROR\n\nOut of memory\n");
exit (4);
}
hotspots- >currentlen=LOOKUP_INITLEN;
flattenBitmap(BMPworking,hotspots);
encodeData(BMPworking,filespace,hotspots);
printf("OK\n");
printf("? Writing result to %s....",argv[4]);
outfile_handle=fopen(argv[4],"wb");
writeBitmapFile(outfile_handle, BMPworking);
fclose(outfile_handle);
printf("OK\n");
}
/* Cleaup and exit */
printf("\nDone!\n");
removeHeap(filespace);
free(filespace);
removeHeap(BMPworking- >palette);
free(BMPworking- >palette);
removeHeap(BMPworking- >raster);
free(BMPworking- >raster);
free(BMPworking);
return(0);
}
6回顶部
/***************************** HEAP MANAGEMENT ***********************/
int initialiseHeap(HEAP* heap) {
heap- >dataspace=NULL;
heap- >heapunits=0;
heap- >nextchar=NULL;
heap- >heaplen=0;
heap- >dataspace=(unsigned char*)calloc(HEAP_INITUNITS,HEAP_UNITSIZE*sizeof(unsigned char));
if (heap- >dataspace==NULL)
return FALSE;
else {
heap- >heapunits=HEAP_INITUNITS;
heap- >nextchar=heap- >dataspace;
return TRUE;
}
}
int expandHeap(int newunits, HEAP* heap) {
if (newunits >heap- >heapunits) {
unsigned char* tmpheap;
int i;
tmpheap=heap- >dataspace;
heap- >dataspace=(unsigned char*)calloc(newunits,HEAP_UNITSIZE*sizeof(unsigned char));
if (heap- >dataspace==NULL) {
heap- >dataspace=tmpheap;
return FALSE;
}
else {
for (i=0; i< heap- >heapunits*HEAP_UNITSIZE; i++)
heap- >dataspace[i]=tmpheap[i];
free(tmpheap);
heap- >nextchar=(heap- >dataspace)+(heap- >heapunits*HEAP_UNITSIZE);
heap- >heapunits=newunits;
}
}
return TRUE;
}
void removeHeap(HEAP* heap) {
if (heap- >dataspace!=NULL) {
free (heap- >dataspace);
heap- >heapunits=0;
heap- >dataspace=NULL;
heap- >nextchar=NULL;
heap- >heaplen=0;
}
}
int streamFileToHeap(FILE* infile, HEAP* heap) {
unsigned char readchar;
while (fscanf(infile,"%c",&readchar) >0) {
if (!putToHeap(readchar,heap))
return FALSE;
}
return TRUE;
}
int putToHeap(unsigned char data, HEAP* heap) {
unsigned long hopeful_pos=heap- >heaplen;
unsigned long current_pos=(heap- >heapunits*HEAP_UNITSIZE);
if (hopeful_pos >= current_pos) {
int discrep=(int)hopeful_pos/HEAP_UNITSIZE;
discrep++;
if (!expandHeap(discrep, heap)) {
return FALSE;
}
}
*(heap- >nextchar)=data;
heap- >heaplen++;
heap- >nextchar++;
return TRUE;
}
7回顶部
/*********************************************************************/
/******************************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;}
8回顶部
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++;
}
}9回顶部
/*********************************************************************/
/**************************** 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;
}10回顶部
/*********************************************************************/
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;
unsigned long int result=0;
dataread=fscanf(strm,"%c",&tmpchar);
if (dataread==1)
result+=((unsigned long int)tmpchar*1);
dataread=fscanf(strm,"%c",&tmpchar);
if (dataread==1)
result+=((unsigned long int)tmpchar*256);
dataread=fscanf(strm,"%c",&tmpchar);
if (dataread==1)
result+=((unsigned long int)tmpchar*65536);
dataread=fscanf(strm,"%c",&tmpchar);
if (dataread==1)
result+=((unsigned long int)tmpchar*16777216);
return result;
}
unsigned int calcEOLpad(int bitlen, long linelen) {
unsigned long int bitsperline;
unsigned int padder;
bitsperline=(unsigned long)bitlen*(unsigned long)linelen;
padder=bitsperline%32;
padder=32-padder;
if (padder==32)
padder=0;
return (int)(padder/8);
}
PIXEL getIndexedPixel(unsigned long int idx, BITMAP* bmp) {
unsigned long int offset;
PIXEL result;
unsigned int EOLpad;
unsigned long int x;
unsigned long int y;
EOLpad=calcEOLpad(24,bmp- >x_size);
x=idx%(bmp- >x_size);
y=(idx-x)/(bmp- >x_size);
y=(bmp- >y_size-1)-y;
offset=(y*((bmp- >x_size*3)+EOLpad))+(x*3);
result.blue=*(bmp- >raster- >dataspace+(offset++));
result.green=*(bmp- >raster- >dataspace+(offset++));
result.red=*(bmp- >raster- >dataspace+(offset));
return result;
}
void setIndexedPixel(unsigned long int idx, BITMAP* bmp, PIXEL pix) {
unsigned long int offset;
unsigned int EOLpad;
unsigned long int x;
unsigned long int y;
EOLpad=calcEOLpad(24,bmp- >x_size);
x=idx%(bmp- >x_size);
y=(idx-x)/(bmp- >x_size);
y=(bmp- >y_size-1)-y;
offset=(y*((bmp- >x_size*3)+EOLpad))+(x*3);
*(bmp- >raster- >dataspace+(offset++))=pix.blue;
*(bmp- >raster- >dataspace+(offset++))=pix.green;
*(bmp- >raster- >dataspace+(offset))=pix.red;
}11回顶部
/****************DATA CODING **********************************/
void encodeData(BITMAP* dest, HEAP* data, LOOKUP* hotspots) {
/* encodes data bit by bit into dest */
/* hotspots contains actual data storage locations */
unsigned long int i;
unsigned long int heapitem;
PIXEL blititem;
int bitshift;
unsigned char theBool;
unsigned char dom;
bitshift=0;
heapitem=0;
for (i=0; i< hotspots- >curitem; i++) {
/* get next bit */
theBool=getNextHeapBit(heapitem,bitshift,data);
bitshift++;
if (bitshift==8) {
bitshift=0;
heapitem++;
if (heapitem >data- >heaplen)
break;
}
blititem=getIndexedPixel(*(hotspots- >dataspace+i),dest);
dom=biggest_of_3(blititem.red, blititem.green, blititem.blue);
if (dom==blititem.red) {
if (theBool==1) {
/* R */
if (dom==255)
dom--;
else
dom++;
blititem.red=dom;
}
}
else if (dom==blititem.green) {
if (theBool==1) {
/* G */
if (dom==255)
dom--;
else
dom++;
blititem.green=dom;
}
}
else {
if (theBool==1) {
/* B */
if (dom==255)
dom--;
else
dom++;
blititem.blue=dom;
}
}
setIndexedPixel(*(hotspots- >dataspace+i),dest,blititem);
}
}
unsigned char getNextHeapBit (unsigned long int item, int bit, HEAP* data) {
unsigned char thisitem;
int bitshift;
bit=7-bit; /* reverse bit order */
thisitem=*(data- >dataspace+item);
bitshift=pow(2,bit);
thisitem=thisitem&bitshift;
thisitem=thisitem > >bit;
return thisitem;
}
int decodeData(BITMAP* src, HEAP* dest) {
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;
PIXEL controlPixel, thisPixel;
int theBool;
unsigned long int longtmp;
int currentBit;
int bitshifts;
offset=0;
currentBit=0;
bitshifts=0;
while (offset< (src- >x_size*src- >y_size)) {
getdata=getIndexedPixel(offset, src);
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(+ or - 1) and that other
cols dont challenge its dominance */
tmp=offset+1;
hits=1;
while (tmp< (src- >x_size*src- >y_size)) {
getdata=getIndexedPixel(tmp, src);
lookaheadR=getdata.red;
lookaheadG=getdata.green;
lookaheadB=getdata.blue;
keepflag=FALSE;
if (dom==thisG && abs(lookaheadG-thisG)< 2)
keepflag=TRUE;
if (dom==thisR && abs(lookaheadR-thisR)< 2)
keepflag=TRUE;
if (dom==thisB && abs(lookaheadB-thisB)< 2)
keepflag=TRUE;
/* check dom is still dominant col by at least 3 */
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)
break;
hits++;
tmp++;
}
if (hits >2) {
/* store in lookup table */
for (longtmp=offset+2; longtmp< offset+hits; longtmp++) {
controlPixel=getIndexedPixel(offset,src);
thisPixel=getIndexedPixel(longtmp,src);
dom=biggest_of_3(controlPixel.red, controlPixel.green, controlPixel.blue);
if (dom==controlPixel.red) {
if (thisPixel.red-dom==0)
theBool=0;
else
theBool=1;
}
if (dom==controlPixel.green) {
if (thisPixel.green-dom==0)
theBool=0;
else
theBool=1;
}
if (dom==controlPixel.blue) {
if (thisPixel.blue-dom==0)
theBool=0;
else
theBool=1;
}
currentBit=currentBit< < 1;
currentBit+=theBool;
bitshifts++;
if (bitshifts==8) {
if (!putToHeap((char)currentBit,dest))
return 2;
bitshifts=0;
currentBit=0;
}
}
offset+=hits;
}
else {
offset++;
}
}
/* decoded and in heap */
if (dest- >heaplen< 13)
return 1;
if (!(*(dest- >dataspace)=='B') || (*(dest- >dataspace+1)!='S' && *(dest- >dataspace+1)!='E'))
return 1;
if (*(dest- >dataspace+6) >THIS_PROTO_VER)
return 3;
/* set data length by truncation */
longtmp=0;
longtmp+=((unsigned long int)(*(dest- >dataspace+2))*1);
longtmp+=((unsigned long int)(*(dest- >dataspace+3))*256);
longtmp+=((unsigned long int)(*(dest- >dataspace+4))*65536);
longtmp+=((unsigned long int)(*(dest- >dataspace+5))*16777216);
if (longtmp< =dest- >heaplen)
dest- >heaplen=longtmp;
else
return 1;
return 0;
}
12回顶部
/*************************** ENCRYPTION ROUTINES ***********************/
int hash_func(unsigned char* password) {
/* This hash function steps thru the string, storing the */
/* lowest 4 bits, and shifting the running total left 4 bits */
/* The shift is a rotational one, e.g. the top nibble comes */
/* back in the bottom (LSB) nibble */
unsigned int hash_ttl=0;
unsigned int ptr=0;
char this_chr;
while (password[ptr] != '\0') {
/* Step through string one char at a time */
this_chr=password[ptr++];
/* Add lowest 4 bits of character */
hash_ttl=hash_ttl + (this_chr & 0x0f);
/* Rotate hash total 4 bits to left (to MSB) */
hash_ttl = rotl4 (hash_ttl);
}
return (hash_ttl);
}
int rotl4(int inval) {
/* Rotate 16bit integer INVAL left by 4 bits */
unsigned int result;
unsigned int tmp;
tmp = inval & 0xf000; /* MSB nibble of the 4 */
result = inval & 0xfff; /* 3 LSB nibbles of the 4 */
result < < = 4; /* Shift nibs 2-0 to 3-1 posns */
tmp > >= 12; /* Shift nib 3 to nib 0 posn */
result = result + tmp; /* Add nib 0 into 3-1 value */
return (result);
}
void cryptoData(HEAP* data, unsigned char* password) {
unsigned long int i;
unsigned int passhash;
unsigned char pupper,plower;
int alternhash=FALSE;
passhash=hash_func(password);
pupper=passhash&0xff00;
plower=passhash&0xff;
*(data- >dataspace+1)='E';
for (i=7; i< data- >heaplen; i++) {
if (alternhash) {
*(data- >dataspace+i)=xor(*(data- >dataspace+i),pupper);
alternhash=FALSE;
}
else {
*(data- >dataspace+i)=xor(*(data- >dataspace+i),plower);
alternhash=TRUE;
}
}
}
unsigned char xor(unsigned char A, unsigned char B) {
unsigned char t1,t2,t3;
t1=A|B;
t2=A&B;
t3=t1-t2;
return ~t3;
}
13回顶部
/************************************POW******************************/
int pow (int a, int b) {
int result=1;
int lp;
for (lp=b; lp >0; lp--) {
result=result*a;
}
return result;
}
/*******************************STRICMP*******************************/
int stricmp (const char* a, const char* b) {
int i;
char acmp,bcmp;
if (strlen(a)!=strlen(b))
return 1;
for (i=0; i< strlen(a); i++) {
acmp=a[i];
bcmp=b[i];
if (acmp >='a' && acmp< ='z')
acmp=acmp-0x20;
if (bcmp >='a' && bcmp< ='z')
bcmp=bcmp-0x20;
if (acmp!=bcmp)
return 1;
}
return 0;
} 14回顶部
/**********************ARCHIVE MANAGER*******************************/
int formatDataspace(BITMAP* BMPworking, HEAP* filespace) {
LOOKUP* hotspots;
unsigned long int bit1,bit2,bit3,bit4;
unsigned long int maxencode,longtemp,i;
putToHeap('B',filespace);
putToHeap('S',filespace);
putToHeap('\0',filespace); /* archive total length inc all hdr:- changed later LONG */
putToHeap('\0',filespace);
putToHeap('\0',filespace);
putToHeap('\0',filespace);
putToHeap(THIS_PROTO_VER,filespace);
putToHeap('O',filespace);
putToHeap('K',filespace);
putToHeap('\0',filespace); /* length of this file block inc filename hdr */
putToHeap('\0',filespace);
putToHeap('\0',filespace);
putToHeap('\0',filespace);
hotspots=(LOOKUP*)calloc(1,sizeof(LOOKUP));
if (hotspots==NULL) {
printf("ERROR\n\nOut of memory\n");
exit(4);
}
hotspots- >dataspace=(unsigned long int*)calloc(LOOKUP_INITLEN,sizeof(unsigned long int));
if (hotspots==NULL) {
printf("ERROR\n\nOut of memory\n");
exit (4);
}
hotspots- >currentlen=LOOKUP_INITLEN;
maxencode=resolveMaxEncode(BMPworking, hotspots);
if (maxencode< 13)
return FALSE;
longtemp=maxencode;
bit4=(unsigned int)longtemp/16777216;
longtemp=longtemp-(unsigned long)((unsigned long)bit4*16777216);
bit3=(unsigned int)longtemp/65536;
longtemp=longtemp-(unsigned long)((unsigned long)bit3*65536);
bit2=(unsigned int)longtemp/256;
longtemp=longtemp-(unsigned long)((unsigned long)bit2*256);
bit1=(unsigned int)longtemp;
*(filespace- >dataspace+2)=bit1;
*(filespace- >dataspace+3)=bit2;
*(filespace- >dataspace+4)=bit3;
*(filespace- >dataspace+5)=bit4;
for (i=filespace- >heaplen; i< maxencode; i++)
putToHeap('\0',filespace);
/* encode blank data into bitmap */
encodeData(BMPworking,filespace,hotspots);
return TRUE;
}
void dumpFileDirectory(HEAP* filespace) {
unsigned long int offset,filelen;
unsigned long int filectr,bytectr;
int filenamelen;
offset=9;
filectr=0;
bytectr=0;
printf("\nFilename Size (bytes)\n-------- ------------\n");
for (;;) {
filelen=0;
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*1);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*256);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*65536);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*16777216);
if (filelen==0)
break;
filenamelen=strlen(filespace- >dataspace+offset)+1;
printf("%-18s%lu\n",filespace- >dataspace+offset,filelen-filenamelen);
offset=offset+filelen;
filectr++;
bytectr+=filelen-filenamelen;
}
if (filectr==0)
printf("No files found in archive!\n");
else
printf("\nTotal %lu byte(s), in %lu file(s)\n",bytectr,filectr);
}
15回顶部
void dumpFileStats(BITMAP* BMPworking, HEAP* filespace) {
unsigned long int offset,filelen,totalsize;
unsigned long int filectr,bytectr;
unsigned long int maxencode;
float perc_used;
LOOKUP* hotspots;
if (filespace- >heaplen==0) {
hotspots=(LOOKUP*)calloc(1,sizeof(LOOKUP));
hotspots- >dataspace=(unsigned long int*)calloc(LOOKUP_INITLEN,sizeof(unsigned long int));
hotspots- >currentlen=LOOKUP_INITLEN;
printf("? Calculating Data Capacity....");
maxencode=resolveMaxEncode(BMPworking, hotspots);
free(hotspots);
printf("OK\n\nThis file does not contain any BlindSide hidden data\n");
printf("The predicted storage capacity for this image is %lu byte(s) [%d Kb]\n",maxencode,(int)((float)maxencode/1024));
}
else {
totalsize=0;
totalsize+=((unsigned long int)(*(filespace- >dataspace+2))*1);
totalsize+=((unsigned long int)(*(filespace- >dataspace+3))*256);
totalsize+=((unsigned long int)(*(filespace- >dataspace+4))*65536);
totalsize+=((unsigned long int)(*(filespace- >dataspace+5))*16777216);
offset=9;
filectr=0;
bytectr=0;
for (;;) {
filelen=0;
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*1);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*256);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*65536);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*16777216);
bytectr+=filelen+4;
if (filelen==0)
break;
offset=offset+filelen;
filectr++;
}
bytectr+=9;
perc_used=(float)100/totalsize;
perc_used=perc_used*(float)(totalsize-bytectr);
printf("\nArchive Found - Capacity %lu byte(s) [%lu Kb]\n\n",totalsize,totalsize/1024);
printf("Total files - %lu, using %lu byte(s)\n",filectr,bytectr);
printf("Freespace remaining: %lu byte(s) [%d%%]\n",totalsize-bytectr,(int)perc_used);
}
}
void addFileToArchive(HEAP* filespace, FILE* handle, char* filename) {
HEAP* filedump;
int i;
unsigned long int offset,filelen,freespace,ilong;
unsigned long int lastfile,lastfile2;
unsigned int bit4,bit3,bit2,bit1;
offset=9;
for (;;) {
filelen=0;
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*1);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*256);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*65536);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*16777216);
lastfile=offset-4;
if (filelen==0)
break;
if (stricmp(filename,filespace- >dataspace+offset)==0) {
printf("FATAL: File %s already exists in the archive\n",filename);
exit(4);
}
offset=offset+filelen;
}
freespace=(filespace- >heaplen)-(lastfile+4);
filedump=(HEAP*)calloc(1,sizeof(HEAP));
initialiseHeap(filedump);
printf("Adding.... %s\n",filename);
/* Write filename */
for (i=0; i< strlen(filename); i++) {
putToHeap(filename[i],filedump);
}
putToHeap('\0',filedump);
/* Write file */
if (!streamFileToHeap(handle,filedump)) {
printf("\nFATAL: Out of memory, while reading file to encode\n");
exit(4);
}
if (filedump- >heaplen==(strlen(filename)+1)) {
printf("\nFATAL: File to encode is empty! (zero length)\n");
exit(4);
}
/* Write next file length (end of chain) */
putToHeap('\0',filedump);
putToHeap('\0',filedump);
putToHeap('\0',filedump);
putToHeap('\0',filedump);
if (freespace< filedump- >heaplen) {
printf("\nFATAL: There isn't enough room inside your image to encode that file\n\nYour data coding needs: %ld bytes\nFreespace inside bitmap: %ld bytes\n\n",filedump- >heaplen,freespace);
printf("It is possible the image you are trying to encode into is too complex,\nor your file to encode is too large. Maybe try zipping it first?\n");
exit(7);
}
for (ilong=0; ilong< filedump- >heaplen; ilong++) {
*(filespace- >dataspace+offset+ilong)=*(filedump- >dataspace+ilong);
}
lastfile2=filedump- >heaplen-4;
bit4=(unsigned int)lastfile2/16777216;
lastfile2=lastfile2-(unsigned long)((unsigned long)bit4*16777216);
bit3=(unsigned int)lastfile2/65536;
lastfile2=lastfile2-(unsigned long)((unsigned long)bit3*65536);
bit2=(unsigned int)lastfile2/256;
lastfile2=lastfile2-(unsigned long)((unsigned long)bit2*256);
bit1=(unsigned int)lastfile2;
*(filespace- >dataspace+lastfile)=bit1;
*(filespace- >dataspace+lastfile+1)=bit2;
*(filespace- >dataspace+lastfile+2)=bit3;
*(filespace- >dataspace+lastfile+3)=bit4;
removeHeap(filedump);
free(filedump);
}16回顶部
int extractFile(HEAP* filespace, char* criteria) {
unsigned long int offset,filelen,filectr;
unsigned long int extractctr,i;
int alwaysoverwrite;
int extractIt;
int wasprompt;
char tmpchar[129];
FILE* outfile;
int filenamelen;
offset=9;
extractctr=0;
filectr=0;
alwaysoverwrite=FALSE;
for (;;) {
filelen=0;
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*1);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*256);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*65536);
filelen+=((unsigned long int)(*(filespace- >dataspace+(offset++)))*16777216);
if (filelen==0)
break;
filectr++;
if (criteria==NULL || stricmp(filespace- >dataspace+offset,criteria)==0) {
/* extract this file */
printf("Extracting.... %s",filespace- >dataspace+offset);
extractIt=TRUE;
if (checkExists(filespace- >dataspace+offset) && !alwaysoverwrite) {
wasprompt=TRUE;
printf(" - already exists, Overwrite? (y/N/a)");
fflush(stdin);
fscanf(stdin,"%s",tmpchar);
if (stricmp(tmpchar,"A")==0) {
alwaysoverwrite=TRUE;
printf("\n");
}
else if (stricmp(tmpchar,"Y")==0) {
printf("\n");
}
else {
printf("Skipping file--^\n");
extractIt=FALSE;
}
}
else {
printf("\n");
wasprompt=FALSE;
}
if (extractIt) {
/* Do the actual extraction */
extractctr++;
outfile=fopen(filespace- >dataspace+offset,"wb");
filenamelen=strlen(filespace- >dataspace+offset)+1;
while ((*(filespace- >dataspace+offset))!='\0') {
offset++;
}
offset++;
for (i=0; i< filelen-filenamelen; i++)
fprintf(outfile,"%c",*(filespace- >dataspace+offset+i));
fclose(outfile);
offset=offset+(filelen-filenamelen);
}
else {
offset+=filelen;
}
}
else {
offset+=filelen;
}
}
if (filectr==0) {
printf("This BlindSide archive is empty - no files to extract\n");
}
else {
if (!wasprompt)
printf("\n");
if (extractctr==0)
printf("No files in the archive matched your extract request!\n");
else
printf("Extracted %lu file(s) successfully.\n",extractctr);
}
return extractctr;
}
int checkExists(char* filename) {
FILE* tester;
if ((tester=fopen(filename,"rb"))) {
fclose(tester);
return TRUE;
}
return FALSE;
}
17回顶部
void flattenBitmap(BITMAP* src, LOOKUP* store) {
/* passes over data as if reading it - but just flattens all data to '0' bits and
compiles a hotspots list */
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;
PIXEL controlPixel, thisPixel;
unsigned long int longtmp;
unsigned long int longtmp2;
unsigned long int *longptrtmp;
offset=0;
while (offset< (src- >x_size*src- >y_size)) {
getdata=getIndexedPixel(offset, src);
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(+ or - 1) and that other
cols dont challenge its dominance */
tmp=offset+1;
hits=1;
while (tmp< (src- >x_size*src- >y_size)) {
getdata=getIndexedPixel(tmp, src);
lookaheadR=getdata.red;
lookaheadG=getdata.green;
lookaheadB=getdata.blue;
keepflag=FALSE;
if (dom==thisG && abs(lookaheadG-thisG)< 2)
keepflag=TRUE;
if (dom==thisR && abs(lookaheadR-thisR)< 2)
keepflag=TRUE;
if (dom==thisB && abs(lookaheadB-thisB)< 2)
keepflag=TRUE;
/* check dom is still dominant col by at least 3 */
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)
break;
hits++;
tmp++;
}
if (hits >2) {
for (longtmp=offset+2; longtmp< offset+hits; longtmp++) {
controlPixel=getIndexedPixel(offset,src);
thisPixel=getIndexedPixel(longtmp,src);
dom=biggest_of_3(controlPixel.red, controlPixel.green, controlPixel.blue);
if (dom==controlPixel.red) {
thisPixel.red=controlPixel.red;
}
if (dom==controlPixel.green) {
thisPixel.green=controlPixel.green;
}
if (dom==controlPixel.blue) {
thisPixel.blue=controlPixel.blue;
}
setIndexedPixel(longtmp,src,thisPixel);
/* store in lookup table */
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++;
}
}
}
正文完
附件:
在BMP中隐藏信息-Win32下的可执行文件 bs_win32.zip
|
最热搜索
无线路由器怎么用 会说话的汤姆猫电脑版 12306网上订火车票 跳舞吧 flash player 下载 PP助手电脑版 Adobe Reader(pdf阅读) iOS6正式版12项新功能 QQ空间克隆器 9158视频KTV 植物大战僵尸辅助工具 Win8怎么关机 QQ空间进不去 2013年春节是几月几号 QQ昵称 QQ空间皮肤 PPT模板 电脑输入法不见了怎么办 2012中秋节是几月几日 word安全模式 qq输入法怎么点亮 IE修复 感恩节是几月几日 CSS布局 PS快捷键 Outlook设置 声卡驱动器官方免费下载 格式工厂怎么用 桌面图标有阴影怎么去掉 Windows RT是什么意思 2013年日历设计 Word打不开怎么办 Win8专区 腾讯微云网 windows8激活工具 剑灵什么时候公测 QQ通讯录怎么用 开心斗地主 拖拉机小游戏 麻将游戏 中国象棋 德州扑克 黄金矿工中文版 保皇扑克游戏 四国军棋 万圣节是几月几日 ps抠图教程 12306订票助手 万圣节小游戏大全 rar文件怎么打开 Photoshop CS6教程 iOS6完美越狱 QQ个性签名