?? main.cpp
字號:
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 + -