📄 winbmp.c
字号:
/******************************************************************************** Copyright 2006 National ASIC Center, All right Reserved** FILE NAME: winbmp.c* PROGRAMMER: ming.c* Date of Creation: 2006/08/8** DESCRIPTION:** NOTE:** FUNCTIONS LIST:* -----------------------------------------------------------------------------** -----------------------------------------------------------------------------** MODIFICATION HISTORY* LastModify 2006/10/30******************************************************************************/#include "mingui.h"//---------------------------------------------------------------------------
extern int CM_DecodeBMP(TImageHead *imgHead, STREAM *stream);
extern int CM_DecodeLCDIMG(TImageHead *imgHead, const BYTE *pImage);
static int CM_DecodeRLE4(BYTE *buf, STREAM *stream);
static int CM_DecodeRLE8(BYTE *buf,STREAM *stream);
//---------------------------------------------------------------------------
int CM_DecodeBMP(TImageHead *imgHead, STREAM *stream)
{ int size,i,imgPitch,PalBlockSize;
BYTE *imgBits;
BMPFILEHEADER fileheader;
BMPINFOHEADER infoheader;
RGBQUAD tempPal[256];
size=StreamRead(&fileheader,sizeof(WORD),stream);
if(fileheader.bfType!=0x4d42 || size!=sizeof(WORD)) return false;
size=StreamRead(&fileheader.bfSize,12,stream);
if(size!=12) return false;
size=StreamRead(&infoheader,sizeof(DWORD),stream);
if(size<sizeof(DWORD)) return false;
if(infoheader.BiSize>=sizeof(BMPINFOHEADER))
{ size=StreamRead((BYTE *)&infoheader+4,sizeof(BMPINFOHEADER)-4,stream);
if(size!=sizeof(BMPINFOHEADER)-4) return false;
i=infoheader.BiSize - sizeof(BMPINFOHEADER);
if(!i) StreamSeek(stream,i,SEEK_CUR);
PalBlockSize = (fileheader.bfOffBits - sizeof(BMPINFOHEADER) - 14);
imgHead->palsize=PalBlockSize>>2;
imgHead->width=infoheader.BiWidth;
imgHead->height=infoheader.BiHeight;
imgHead->bpp=infoheader.BiBitCount;
imgHead->compression=infoheader.BiCompression;
if(imgHead->palsize>0 && imgHead->palsize<=256)
{
imgHead->transPal=(PIXEL *)GetMem(imgHead->palsize * sizeof(PIXEL));
if(!imgHead->transPal) return false;
size=StreamRead(tempPal,PalBlockSize,stream);
if(PalBlockSize!=size) return false;
if(imgHead->bpp<=8)
{ for(i=0;i<imgHead->palsize;i++)
{ imgHead->transPal[i]=ColorMapToPixel(&tempPal[i]);
}
}
}
}
else if(infoheader.BiSize==sizeof(BMPCOREHEADER))
{ BMPCOREHEADER coreheader;
size=StreamRead((BYTE *)&coreheader+4,sizeof(BMPCOREHEADER)-4,stream);
if(size!=sizeof(BMPCOREHEADER)-4) return false;
imgHead->width=coreheader.bcWidth;
imgHead->height=coreheader.bcHeight;
imgHead->bpp=coreheader.bcBitCount;
imgHead->compression=0;
PalBlockSize = (fileheader.bfOffBits - 26);
imgHead->palsize = PalBlockSize / 3;
if(imgHead->palsize>0 && imgHead->palsize<=256)
{ BYTE *myPal=(BYTE *)tempPal;
RGBQUAD rgbColor;
imgHead->transPal=(PIXEL *)GetMem(imgHead->palsize * sizeof(PIXEL));
if(!imgHead->transPal) return false;
size=StreamRead(myPal,PalBlockSize,stream);
if(PalBlockSize!=size) return false;
rgbColor.a=0;
for(i=0;i<imgHead->palsize;i++)
{ rgbColor.b=*myPal++;
rgbColor.g=*myPal++;
rgbColor.r=*myPal++;
imgHead->transPal[i]=ColorMapToPixel(&rgbColor);
}
}
}
else
{ return false;
}
imgHead->pitch = ( (imgHead->width*imgHead->bpp+31)>>3 ) & ~0x3;
if(imgHead->bpp==16)
{ if(imgHead->compression==BI_BITFIELDS)
{ if(*(DWORD *)&tempPal[1] == 0x03e0)
imgHead->bpp=15;
}
else imgHead->bpp=15;
}
imgHead->bits = (BYTE *)GetMem(imgHead->pitch * imgHead->height);
if(!imgHead->bits) return false;
imgHead->bitsFromHeap=true;
//fseek(f,fileheader.bfOffBits,0);
i=imgHead->height;
imgPitch=imgHead->pitch;
imgBits=imgHead->bits + i*imgHead->pitch;
if(imgHead->compression==BI_RLE8)
{ while (--i >= 0)
{ imgBits-=imgPitch;
if(!CM_DecodeRLE8(imgBits, stream)) return false;
}
}
else if(imgHead->compression==BI_RLE4)
{ while (--i >= 0)
{ imgBits-=imgPitch;
if(!CM_DecodeRLE4(imgBits, stream)) return false;
}
}
else
{ while (--i >= 0)
{ imgBits-=imgPitch;
StreamRead(imgBits,imgPitch,stream);
}
}
return true;
}
//---------------------------------------------------------------------------
int CM_DecodeRLE8(BYTE *buf,STREAM *stream)
{ int c, n;
BYTE * p = buf;
while(1)
{ n = StreamGetByte(stream);
switch(n)
{ case EOF: return(0);
case 0: /* 0 = escape*/
n = StreamGetByte(stream);
switch(n)
{ case 0: return(1); /* 0 0 = end of current scan line*/
case 1: return(1); /* 0 1 = end of data*/
case 2: /* 0 2 xx yy delta mode - NOT SUPPORTED*/
(void)StreamGetByte(stream);
(void)StreamGetByte(stream);
continue;
default: /* 0 3..255 xx nn uncompressed data*/
for(c=0; c<n; c++)
*p++ = StreamGetByte(stream);
if(n & 1)
(void)StreamGetByte(stream);
continue;
}
default:
c = StreamGetByte(stream);
while(n--)
*p++ = c;
continue;
}
}
}
//---------------------------------------------------------------------------
/*
* Decode one line of RLE4, return 0 when done with all bitmap data
*/
int CM_DecodeRLE4(BYTE *buf, STREAM *stream)
{ static int last;
#define rle_put4(b)\
{ last = (last << 4) | (b);\
if(++once == 2)\
{ *p++ = last;\
once = 0;\
}\
}
BYTE *p=buf;
int once=0,c, n, c1, c2;
while(1)
{ n = StreamGetByte(stream);
switch(n)
{ case EOF: return(0);
case 0: /* 0 = escape*/
n =StreamGetByte(stream);
switch(n)
{ case 0: /* 0 0 = end of current scan line*/
if(once)
rle_put4(0);
return(1);
case 1: /* 0 1 = end of data*/
if(once)
rle_put4(0);
return(1);
case 2: /* 0 2 xx yy delta mode - NOT SUPPORTED*/
(void)StreamGetByte(stream);
(void)StreamGetByte(stream);
continue;
default: /* 0 3..255 xx nn uncompressed data*/
c2 = (n+3) & ~3;
for(c=0; c<c2; c++)
{ if((c & 1) == 0)
c1 = StreamGetByte(stream);
if(c < n)
rle_put4((c1 >> 4) & 0x0f);
c1 <<= 4;
}
continue;
}
default:
c = StreamGetByte(stream);
c1 = (c >> 4) & 0x0f;
c2 = c & 0x0f;
for(c=0; c<n; c++)
{ rle_put4((c&1)? c2: c1);
}
continue;
}
}
}
//---------------------------------------------------------------------------
int CM_DecodeLCDIMG(TImageHead *imgHead, const BYTE *pImage)
{ TLcdImageHead *LcdIMG=(TLcdImageHead *)pImage;
int LcdScanMode;
LcdScanMode=LcdIMG->scan;
if(LcdScanMode&0x3)
{ DebugAlert("图像格式错误\n非水平方式扫描的位图!");
return false;
}
imgHead->bpp=LcdIMG->bpp;
if(LcdScanMode & 0x10)
{ imgHead->width=(LcdIMG->width[0]<<8)+LcdIMG->width[1];
imgHead->height=(LcdIMG->height[0]<<8)+LcdIMG->height[1];
}
else
{ imgHead->width=LcdIMG->width[0] + (LcdIMG->width[1]<<8);
imgHead->height=LcdIMG->height[0] + (LcdIMG->height[1]<<8);
}
if(imgHead->width<=0 || imgHead->height<=0)
{ return false;
}
imgHead->pitch = (imgHead->width*imgHead->bpp+7)/8;
pImage+=sizeof(TLcdImageHead);
switch(imgHead->bpp)
{ case 1:
case 2:
case 4: //LCD灰度图象
{ int i,j,palSize= 1<<imgHead->bpp;
DWORD rgbColor;
PIXEL *imgTransPal=(PIXEL *)GetMem(sizeof(PIXEL)*palSize);
if(!imgTransPal)return false;
else imgHead->transPal=imgTransPal;
imgHead->palsize=palSize;
j=imgHead->bpp<<1;
for(i=1;i<=palSize;i++)
{ rgbColor= ( i * i * 255 ) >> j;
rgbColor=rgbColor|(rgbColor<<8)|(rgbColor<<16);
imgTransPal[palSize-i]=ColorMapToPixel((RGBQUAD *)&rgbColor);
}
}
break;
case 8: /* 256 color */
{ int i,palSize;
PIXEL *imgTransPal;
RGBQUAD rgbColor;
if(LcdScanMode & 0x10)
{ palSize=*pImage++<<8;
palSize=palSize|*pImage++;
}
else
{ palSize=*pImage++;
palSize=palSize|(*pImage++<<8);
}
if(palSize>0 && palSize<=256)
{ imgHead->palsize=palSize;
imgTransPal=(PIXEL *)GetMem(sizeof(PIXEL)*palSize);
if(!imgTransPal)return false;
else imgHead->transPal=imgTransPal;
} else return false;
rgbColor.a=0;
for(i=0;i<palSize;i++)
{ rgbColor.r = *pImage++;
rgbColor.g = *pImage++;
rgbColor.b = *pImage++;
imgTransPal[i]=ColorMapToPixel(&rgbColor);
}
}
break;
case 16: { int is565=*pImage;
pImage+=2;
if(is565==0) imgHead->bpp=15;
else if(is565!=1) return false;
}
break;
case 24:
case 32: pImage+=2;break;
default: return false;
}
imgHead->bits=(BYTE *)pImage;
imgHead->bitsFromHeap=false;
return true;
}
/*---------------------------------------------------------------------------END --- Thank you! ming.c---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -