📄 libmng_chunk_io.c
字号:
return pOut;}/* ************************************************************************** */mng_retcode inflate_buffer (mng_datap pData, mng_uint8p pInbuf, mng_uint32 iInsize, mng_uint8p *pOutbuf, mng_uint32 *iOutsize, mng_uint32 *iRealsize){ mng_retcode iRetcode = MNG_NOERROR;#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_START)#endif if (iInsize) /* anything to do ? */ { *iOutsize = iInsize * 3; /* estimate uncompressed size */ /* and allocate a temporary buffer */ MNG_ALLOC (pData, *pOutbuf, *iOutsize) do { mngzlib_inflateinit (pData); /* initialize zlib */ /* let zlib know where to store the output */ pData->sZlib.next_out = *pOutbuf; /* "size - 1" so we've got space for the zero-termination of a possible string */ pData->sZlib.avail_out = *iOutsize - 1; /* ok; let's inflate... */ iRetcode = mngzlib_inflatedata (pData, iInsize, pInbuf); /* determine actual output size */ *iRealsize = (mng_uint32)pData->sZlib.total_out; mngzlib_inflatefree (pData); /* zlib's done */ if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */ { /* then get some more */ MNG_FREEX (pData, *pOutbuf, *iOutsize) *iOutsize = *iOutsize + iInsize; MNG_ALLOC (pData, *pOutbuf, *iOutsize) } } /* repeat if we didn't have enough space */ while ((iRetcode == MNG_BUFOVERFLOW) && (*iOutsize < 20 * iInsize)); if (!iRetcode) /* if oke ? */ *((*pOutbuf) + *iRealsize) = 0; /* then put terminator zero */ } else { *pOutbuf = 0; /* nothing to do; then there's no output */ *iOutsize = 0; *iRealsize = 0; }#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_END)#endif return iRetcode;}/* ************************************************************************** */#endif /* MNG_INCLUDE_READ_PROCS *//* ************************************************************************** *//* * * *//* * Helper routines to simplify chunk writing * *//* * * *//* ************************************************************************** *//* B004 */#ifdef MNG_INCLUDE_WRITE_PROCS/* B004 *//* ************************************************************************** */mng_retcode deflate_buffer (mng_datap pData, mng_uint8p pInbuf, mng_uint32 iInsize, mng_uint8p *pOutbuf, mng_uint32 *iOutsize, mng_uint32 *iRealsize){ mng_retcode iRetcode = MNG_NOERROR;#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_START)#endif if (iInsize) /* anything to do ? */ { *iOutsize = (iInsize * 5) >> 2; /* estimate compressed size */ /* and allocate a temporary buffer */ MNG_ALLOC (pData, *pOutbuf, *iOutsize) do { mngzlib_deflateinit (pData); /* initialize zlib */ /* let zlib know where to store the output */ pData->sZlib.next_out = *pOutbuf; pData->sZlib.avail_out = *iOutsize; /* ok; let's deflate... */ iRetcode = mngzlib_deflatedata (pData, iInsize, pInbuf); /* determine actual output size */ *iRealsize = pData->sZlib.total_out; mngzlib_deflatefree (pData); /* zlib's done */ if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */ { /* then get some more */ MNG_FREEX (pData, *pOutbuf, *iOutsize) *iOutsize = *iOutsize + (iInsize >> 1); MNG_ALLOC (pData, *pOutbuf, *iOutsize) } } /* repeat if we didn't have enough space */ while (iRetcode == MNG_BUFOVERFLOW); } else { *pOutbuf = 0; /* nothing to do; then there's no output */ *iOutsize = 0; *iRealsize = 0; }#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_END)#endif return iRetcode;}/* ************************************************************************** */mng_retcode write_raw_chunk (mng_datap pData, mng_chunkid iChunkname, mng_uint32 iRawlen, mng_uint8p pRawdata){ mng_uint32 iCrc; mng_uint32 iWritten;#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_START)#endif /* temporary buffer ? */ if ((pRawdata != 0) && (pRawdata != pData->pWritebuf+8)) { /* store length & chunktype in default buffer */ mng_put_uint32 (pData->pWritebuf, iRawlen); mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname); /* calculate the crc */ iCrc = update_crc (pData, 0xffffffffL, pData->pWritebuf+4, 4); iCrc = update_crc (pData, iCrc, pRawdata, iRawlen) ^ 0xffffffffL; /* store crc in default buffer */ mng_put_uint32 (pData->pWritebuf+8, iCrc); /* write the length & chunktype */ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten)) MNG_ERROR (pData, MNG_APPIOERROR) if (iWritten != 8) /* disk full ? */ 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) /* 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); /* calculate the crc */ iCrc = crc (pData, pData->pWritebuf+4, iRawlen + 4); /* 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) }#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/* ************************************************************************** */READ_CHUNK (read_ihdr){#ifdef MNG_SUPPORT_TRACE MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_START)#endif if (iRawlen != 13) /* length oke ? */ MNG_ERROR (pData, MNG_INVALIDLENGTH) /* only allowed inside PNG or MNG */ if ((pData->eSigtype != mng_it_png) && (pData->eSigtype != mng_it_mng)) MNG_ERROR (pData, MNG_CHUNKNOTALLOWED) /* sequence checks */ if ((pData->eSigtype == mng_it_png) && (pData->iChunkseq > 1)) MNG_ERROR (pData, MNG_SEQUENCEERROR)#ifdef MNG_INCLUDE_JNG if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT) || (pData->bHasJHDR))#else if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT))#endif MNG_ERROR (pData, MNG_SEQUENCEERROR) pData->bHasIHDR = MNG_TRUE; /* indicate IHDR is present */ /* and store interesting fields */ if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)) { pData->iDatawidth = mng_get_uint32 (pRawdata); pData->iDataheight = mng_get_uint32 (pRawdata+4); } pData->iBitdepth = *(pRawdata+8); pData->iColortype = *(pRawdata+9); pData->iCompression = *(pRawdata+10); pData->iFilter = *(pRawdata+11); pData->iInterlace = *(pRawdata+12); if ((pData->iBitdepth != 1) && /* parameter validity checks */ (pData->iBitdepth != 2) && (pData->iBitdepth != 4) && (pData->iBitdepth != 8) && (pData->iBitdepth != 16) ) MNG_ERROR (pData, MNG_INVALIDBITDEPTH) if ((pData->iColortype != MNG_COLORTYPE_GRAY ) && (pData->iColortype != MNG_COLORTYPE_RGB ) && (pData->iColortype != MNG_COLORTYPE_INDEXED) && (pData->iColortype != MNG_COLORTYPE_GRAYA ) && (pData->iColortype != MNG_COLORTYPE_RGBA ) ) MNG_ERROR (pData, MNG_INVALIDCOLORTYPE) if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8)) MNG_ERROR (pData, MNG_INVALIDBITDEPTH) if (((pData->iColortype == MNG_COLORTYPE_RGB ) || (pData->iColortype == MNG_COLORTYPE_GRAYA ) || (pData->iColortype == MNG_COLORTYPE_RGBA ) ) && (pData->iBitdepth < 8 ) ) MNG_ERROR (pData, MNG_INVALIDBITDEPTH) if (pData->iCompression != MNG_COMPRESSION_DEFLATE) MNG_ERROR (pData, MNG_INVALIDCOMPRESS) if ((pData->eSigtype == mng_it_png) && (pData->iFilter)) MNG_ERROR (pData, MNG_INVALIDFILTER) else if (pData->iFilter & (~MNG_FILTER_DIFFERING)) MNG_ERROR (pData, MNG_INVALIDFILTER) if ((pData->iInterlace != MNG_INTERLACE_NONE ) && (pData->iInterlace != MNG_INTERLACE_ADAM7) ) MNG_ERROR (pData, MNG_INVALIDINTERLACE) if (pData->bHasDHDR) /* check the colortype for delta-images ! */ { mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf; if (pData->iColortype != pBuf->iColortype) { if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) || (pBuf->iColortype == MNG_COLORTYPE_GRAY ) ) && ( (pData->iColortype != MNG_COLORTYPE_GRAY ) || (pBuf->iColortype == MNG_COLORTYPE_INDEXED) ) ) MNG_ERROR (pData, MNG_INVALIDCOLORTYPE) } } if (!pData->bHasheader) /* first chunk ? */ { pData->bHasheader = MNG_TRUE; /* we've got a header */ pData->eImagetype = mng_it_png; /* then this must be a PNG */ pData->iWidth = pData->iDatawidth; pData->iHeight = pData->iDataheight; /* predict alpha-depth ! */ if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) || (pData->iColortype == MNG_COLORTYPE_RGBA ) ) pData->iAlphadepth = pData->iBitdepth; else if (pData->iColortype == MNG_COLORTYPE_INDEXED) pData->iAlphadepth = 8; /* worst case scenario */ else pData->iAlphadepth = 0; /* fits on maximum canvas ? */ if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight)) MNG_WARNING (pData, MNG_IMAGETOOLARGE) if (pData->fProcessheader) /* inform the app ? */ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight)) MNG_ERROR (pData, MNG_APPMISCERROR) } if (!pData->bHasDHDR) pData->iImagelevel++; /* one level deeper */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -