📄 libmng_chunk_io.c
字号:
MNG_ERROR (pData, MNG_OUTPUTERROR); /* write the temporary buffer */ if (!pData->fWritedata ((mng_handle)pData, pRawdata, iRawlen, &iWritten)) MNG_ERROR (pData, MNG_APPIOERROR); if (iWritten != iRawlen) /* disk full ? */ MNG_ERROR (pData, MNG_OUTPUTERROR); if (pData->iCrcmode & MNG_CRC_OUTPUT) { /* write the crc */ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf+8, 4, &iWritten)) MNG_ERROR (pData, MNG_APPIOERROR); if (iWritten != 4) /* disk full ? */ MNG_ERROR (pData, MNG_OUTPUTERROR); } } else { /* prefix with length & chunktype */ mng_put_uint32 (pData->pWritebuf, iRawlen); mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname); if (pData->iCrcmode & MNG_CRC_OUTPUT) { if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE) /* calculate the crc */ iCrc = mng_crc (pData, pData->pWritebuf+4, iRawlen + 4); else iCrc = 0; /* dummy crc */ /* add it to the buffer */ mng_put_uint32 (pData->pWritebuf + iRawlen + 8, iCrc); /* write it in a single pass */ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 12, &iWritten)) MNG_ERROR (pData, MNG_APPIOERROR); if (iWritten != iRawlen + 12) /* disk full ? */ MNG_ERROR (pData, MNG_OUTPUTERROR); } else { if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 8, &iWritten)) MNG_ERROR (pData, MNG_APPIOERROR); if (iWritten != iRawlen + 8) /* disk full ? */ MNG_ERROR (pData, MNG_OUTPUTERROR); } }#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_END);#endif return MNG_NOERROR;}/* ************************************************************************** *//* B004 */#endif /* MNG_INCLUDE_WRITE_PROCS *//* B004 *//* ************************************************************************** *//* * * *//* * chunk read functions * *//* * * *//* ************************************************************************** */#ifdef MNG_INCLUDE_READ_PROCS/* ************************************************************************** */#ifdef MNG_OPTIMIZE_CHUNKREADER/* ************************************************************************** */MNG_LOCAL mng_retcode create_chunk_storage (mng_datap pData, mng_chunkp pHeader, mng_uint32 iRawlen, mng_uint8p pRawdata, mng_field_descp pField, mng_uint16 iFields, mng_chunkp* ppChunk, mng_bool bWorkcopy){ mng_field_descp pTempfield = pField; mng_uint16 iFieldcount = iFields; mng_uint8p pTempdata = pRawdata; mng_uint32 iTemplen = iRawlen; mng_uint16 iLastgroup = 0; mng_uint8p pChunkdata; mng_uint32 iDatalen; mng_uint8 iColortype; mng_bool bProcess; /* initialize storage */ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); if (iRetcode) /* on error bail out */ return iRetcode; if (((mng_chunk_headerp)(*ppChunk))->iChunkname == MNG_UINT_HUH) ((mng_chunk_headerp)(*ppChunk))->iChunkname = pData->iChunkname; if ((!bWorkcopy) || ((((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_IDAT) && (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAT) && (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAA) )) { pChunkdata = (mng_uint8p)(*ppChunk);#ifdef MNG_INCLUDE_JNG /* determine current colortype */ if (pData->bHasJHDR) iColortype = (mng_uint8)(pData->iJHDRcolortype - 8); else#endif /* MNG_INCLUDE_JNG */ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) iColortype = pData->iColortype; else iColortype = 6; if (iTemplen) /* not empty ? */ { /* then go fill the fields */ while ((iFieldcount) && (iTemplen)) { if (pTempfield->iOffsetchunk) { if (pTempfield->iFlags & MNG_FIELD_PUTIMGTYPE) { *(pChunkdata+pTempfield->iOffsetchunk) = iColortype; bProcess = MNG_FALSE; } else if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES) bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6)) ); else bProcess = MNG_TRUE; if (bProcess) { iLastgroup = (mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK); /* numeric field ? */ if (pTempfield->iFlags & MNG_FIELD_INT) { if (iTemplen < pTempfield->iLengthmax) MNG_ERROR (pData, MNG_INVALIDLENGTH); switch (pTempfield->iLengthmax) { case 1 : { mng_uint8 iNum = *pTempdata; if (((mng_uint16)iNum < pTempfield->iMinvalue) || ((mng_uint16)iNum > pTempfield->iMaxvalue) ) MNG_ERROR (pData, MNG_INVALIDFIELDVAL); *(pChunkdata+pTempfield->iOffsetchunk) = iNum; break; } case 2 : { mng_uint16 iNum = mng_get_uint16 (pTempdata); if ((iNum < pTempfield->iMinvalue) || (iNum > pTempfield->iMaxvalue)) MNG_ERROR (pData, MNG_INVALIDFIELDVAL); *((mng_uint16p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum; break; } case 4 : { mng_uint32 iNum = mng_get_uint32 (pTempdata); if ((iNum < pTempfield->iMinvalue) || ((pTempfield->iFlags & MNG_FIELD_NOHIGHBIT) && (iNum & 0x80000000)) ) MNG_ERROR (pData, MNG_INVALIDFIELDVAL); *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum; break; } } pTempdata += pTempfield->iLengthmax; iTemplen -= pTempfield->iLengthmax; } else { /* not numeric so it's a bunch of bytes */ if (!pTempfield->iOffsetchunklen) /* big fat NONO */ MNG_ERROR (pData, MNG_INTERNALERROR); /* with terminating 0 ? */ if (pTempfield->iFlags & MNG_FIELD_TERMINATOR) { mng_uint8p pWork = pTempdata; while (*pWork) /* find the zero */ pWork++; iDatalen = (mng_uint32)(pWork - pTempdata); } else { /* no terminator, so everything that's left ! */ iDatalen = iTemplen; } if ((pTempfield->iLengthmax) && (iDatalen > pTempfield->iLengthmax)) MNG_ERROR (pData, MNG_INVALIDLENGTH); /* needs decompression ? */ if (pTempfield->iFlags & MNG_FIELD_DEFLATED) { mng_uint8p pBuf = 0; mng_uint32 iBufsize = 0; mng_uint32 iRealsize; mng_ptr pWork; iRetcode = mng_inflate_buffer (pData, pTempdata, iDatalen, &pBuf, &iBufsize, &iRealsize);#ifdef MNG_CHECK_BAD_ICCP /* Check for bad iCCP chunk */ if ((iRetcode) && (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_iCCP)) { *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = MNG_NULL; *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen; } else#endif { if (iRetcode) return iRetcode; /* don't forget to generate null terminator */ MNG_ALLOC (pData, pWork, iRealsize+1); MNG_COPY (pWork, pBuf, iRealsize); *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = pWork; *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iRealsize; } if (pBuf) /* free the temporary buffer */ MNG_FREEX (pData, pBuf, iBufsize); } else { /* no decompression, so just copy */ mng_ptr pWork; /* don't forget to generate null terminator */ MNG_ALLOC (pData, pWork, iDatalen+1); MNG_COPY (pWork, pTempdata, iDatalen); *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = pWork; *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen; } if (pTempfield->iFlags & MNG_FIELD_TERMINATOR) iDatalen++; /* skip the terminating zero as well !!! */ iTemplen -= iDatalen; pTempdata += iDatalen; } /* need to set an indicator ? */ if (pTempfield->iOffsetchunkind) *((mng_uint8p)(pChunkdata+pTempfield->iOffsetchunkind)) = MNG_TRUE; } } if (pTempfield->pSpecialfunc) /* special function required ? */ { iRetcode = pTempfield->pSpecialfunc(pData, *ppChunk, &iTemplen, &pTempdata); if (iRetcode) /* on error bail out */ return iRetcode; } pTempfield++; /* Neeeeeeexxxtt */ iFieldcount--; } if (iTemplen) /* extra data ??? */ MNG_ERROR (pData, MNG_INVALIDLENGTH); while (iFieldcount) /* not enough data ??? */ { if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES) bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) || ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6)) ); else bProcess = MNG_TRUE; if (bProcess) { if (!(pTempfield->iFlags & MNG_FIELD_OPTIONAL)) MNG_ERROR (pData, MNG_INVALIDLENGTH); if ((pTempfield->iFlags & MNG_FIELD_GROUPMASK) && ((mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK) == iLastgroup)) MNG_ERROR (pData, MNG_INVALIDLENGTH); } pTempfield++; iFieldcount--; } } } return MNG_NOERROR;}/* ************************************************************************** */READ_CHUNK (mng_read_general){ mng_chunk_descp pDescr = ((mng_chunk_headerp)pHeader)->pChunkdescr; mng_field_descp pField = pDescr->pFielddesc; mng_uint16 iFields = pDescr->iFielddesc; mng_retcode iRetcode = MNG_NOERROR; if (!pDescr) /* this is a bad booboo !!! */ MNG_ERROR (pData, MNG_INTERNALERROR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -