一份png解析代码,希望对初学者有帮助。
int32 File_ReadInt32(int32 fp, int32* des, int32 pos)
{
if(fp && des)
{
char data[4] = {0};
mrc_seek(fp, pos, MR_SEEK_SET);
mrc_read(fp, data, 4);
*des = ((data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16) | ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
return MR_SUCCESS;
}
return MR_FAILED;
}
int32 File_ReadInt16(int32 fp, int16* des, int32 pos)
{
if(fp && des)
{
int32 ret = 0;
char data[2] = {0};
mrc_seek(fp, pos, MR_SEEK_SET);
ret = mrc_read(fp, data, 2);
if(ret==2)
{
*des = (((data[0] & 0xFF) << 8) | (data[1] & 0xFF));
return MR_SUCCESS;
}
}
return MR_FAILED;
}
int32 File_ReadInt8(int32 fp, int8* des, int32 pos)
{
if(fp && des)
{
int32 ret = 0;
mrc_seek(fp, pos, MR_SEEK_SET);
ret = mrc_read(fp, des, 2);
return MR_SUCCESS;
}
return MR_FAILED;
}
int32 File_ReadBuff(int32 fp, char* des, int32 pos, int32 len)
{
if(fp && des)
{
mrc_seek(fp, pos, MR_SEEK_SET);
mrc_read(fp, des, len);
return MR_SUCCESS;
}
return MR_FAILED;
}
uint8* GetBmpDataFromPngData(int32 imgW,int32 imgH,uint8*
pPngData,uint8* pPlte, int8 nTrnsIndex, int8 bitDepth,int32* dataLen)
{
int32 i,j,rw,k,t;
register int32 i32index;
register uint8* pIDataTmp;
register uint16* pBmpData565=NULL;
uint16* pBmpData565Return=NULL;
rw=imgW;
// rw += 3;
// rw &= ~3;
pBmpData565=(uint16*)mpsEmMalloc(imgH*rw*2);
if (pBmpData565==NULL) return NULL;
memset(pBmpData565,0,imgH*rw*2);
pBmpData565Return=pBmpData565;
*dataLen=imgH*rw*2;
pIDataTmp=pPngData;
if(nTrnsIndex!=-1)
{//透明处理
pPlte[nTrnsIndex<<1] = 248;
pPlte[(nTrnsIndex<<1)+1] = 31;
}
j=imgH;
if (bitDepth==8){
while (j-->0){
pIDataTmp++;
i=0;
while (ii32index=pIDataTmp[i];i32index=(i32index<<1);// + i32index;
pBmpData565[i]=(((pPlte[i32index]&0xFF)<<8) |
(pPlte[i32index+1]&0xFF));//RGB2PIXEL565(pPlte[i32index],pPlte[i32index+1],pPlte[i32index+2]);
i++;
}
pBmpData565+=imgW;
pIDataTmp+=imgW;
}
}else if (bitDepth==4){
t=imgW % 2;
while (j-->0){
pIDataTmp++;
i=0;
k=0;
while (ii32index=(pIDataTmp[k]) >> 4;i32index=(i32index<<1);
pBmpData565[i]=(((pPlte[i32index]&0xFF)<<8) | (pPlte[i32index+1]&0xFF));
i32index=(pIDataTmp[k]) & 0x0F;
i32index=(i32index<<1);
pBmpData565[i+1]=(((pPlte[i32index]&0xFF)<<8) | (pPlte[i32index+1]&0xFF));
i+=2;
k++;
}
if (t>0){
i32index=(pIDataTmp[k]) >> 4;
i32index=(i32index<<1);
pBmpData565[i]=(((pPlte[i32index]&0xFF)<<8) | (pPlte[i32index+1]&0xFF));
}
pBmpData565+=rw;
pIDataTmp+=imgW;
}
}
return (uint8*)pBmpData565Return;
}
int32 NewCreatePngToBmp(int16 index)
{
int16 nLen = 0;
int16 nBeginPos = 2;
int32 nPngPos = 0;
int32 nidPng = 0, l = 0;
int16 w = 0, h = 0, nPLTELen = 0, nIdatLen = 0; //图片高度、宽度、缓冲长度
char pszFileName[] = {0};
char* pPLTE = NULL;
char* pIdat = NULL;
int32 fdes = 0;
int32 fo = 0;
int32 fpng = 0;
int8 nBitdepth = 0;
int8 nTrnsIndex = 0;
int32 onlinebyte = 0;
int32 i32tmp = 0;
//char pszFileHead[22] ={0};
fo = mrc_open(_PNGDATA_IMAGE_O, MR_FILE_RDONLY);
if(fo==0)
return MR_FAILED;
File_ReadInt16(fo, &nLen, 0);//文件长度
while (nBeginPos<=nLen-2)
{
File_ReadInt32(fo, &nidPng, nBeginPos);
if (nidPng == index) {
break;
}
nBeginPos += 7;
}
if (nBeginPos >= nLen+2) {
goto ERROR_01;
}
File_ReadInt16(fo, (int16*)&nPngPos, nBeginPos+5); //读取所在位置(.p)
// nPngPos~ +22 为FileHead;
fpng = mrc_open(_PNGDATA_IMAGE_P, MR_FILE_RDONLY);
if(fpng==0){
goto ERROR_01;
}
File_ReadInt16(fpng, &w, nPngPos);
File_ReadInt16(fpng, &h, nPngPos+2);
File_ReadInt8(fpng, &nBitdepth, nPngPos+4);
File_ReadInt8(fpng, &nTrnsIndex, nPngPos+5);
File_ReadInt16(fpng, &nPLTELen, nPngPos+18);
File_ReadInt16(fpng, &nIdatLen, nPngPos+20);
nIdatLen = nIdatLen - nPLTELen;
pPLTE = _malloc(nPLTELen);
if(pPLTE==NULL){
goto ERROR_02;
}
pIdat = _malloc(nIdatLen-2);
if(pIdat==NULL)
{
_free(pPLTE);
goto ERROR_02;
}
File_ReadBuff(fpng, pPLTE, nPngPos+22, nPLTELen); //调色版数据 nPLTELen
File_ReadBuff(fpng, pIdat, nPngPos+22+nPLTELen+2, nIdatLen-10); // idat数据
_snprintf(pszFileName, sizeof(pszFileName)-1, _PNGDATA_BMP, index);
// memset(g_pBuffer, 0, g_nBuffW*g_nBuffH*2);
memset(pIdat+nIdatLen-10, 0, 4);
onlinebyte=w*nBitdepth*1;
onlinebyte += 7;
onlinebyte &= ~7;
i32tmp=h*onlinebyte/8+h;
memcpy(pIdat+nIdatLen-6,&i32tmp,4);
{
stZipData* pZipData = CreateZipData((PSTR)pIdat);
uint8* pDes = NULL;
int16 iDataZipLen = 0;
char* retData = _malloc(i32tmp);
iDataZipLen= inflate(pZipData, (PSTR)retData, 0, nIdatLen-2);
_free(pZipData);
if(iDataZipLen<=0)
{
goto ERROR_03;
}
pDes = GetBmpDataFromPngData(w, h, (uint8*)retData, (uint8*)pPLTE, nTrnsIndex,
nBitdepth,
&l);//pwd_getBmpData565FromPngDataType3(w,
h,
g_pBuffer, pPLTE, NULL, 0, nBitdepth, &l);
_free(retData);
if(pDes==NULL)
{
goto ERROR_03;
}
fdes = mrc_open(pszFileName, MR_FILE_RDWR|MR_FILE_CREATE);
if(fdes)
{
mrc_seek(fdes, 0, MR_SEEK_SET);
mrc_write(fdes, &w, 2);
mrc_write(fdes, &h, 2);
mrc_write(fdes, &l, 4);
mrc_write(fdes, pDes, l);
mrc_close(fdes);
}
mpsEmFree(pDes);
}
ERROR_03:
_free(pIdat);
_free(pPLTE);
ERROR_02:
mrc_close(fpng);
ERROR_01:
mrc_close(fo);
return MR_SUCCESS;
}