📄 libmng_read.c
字号:
#ifndef MNG_SKIPCHUNK_eXPI
{MNG_UINT_eXPI, mng_init_expi, mng_free_expi, mng_read_expi, mng_write_expi, mng_assign_expi, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_evNT
{MNG_UINT_evNT, mng_init_evnt, mng_free_evnt, mng_read_evnt, mng_write_evnt, mng_assign_evnt, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_fPRI
{MNG_UINT_fPRI, mng_init_fpri, mng_free_fpri, mng_read_fpri, mng_write_fpri, mng_assign_fpri, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_gAMA
{MNG_UINT_gAMA, mng_init_gama, mng_free_gama, mng_read_gama, mng_write_gama, mng_assign_gama, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_hIST
{MNG_UINT_hIST, mng_init_hist, mng_free_hist, mng_read_hist, mng_write_hist, mng_assign_hist, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_iCCP
{MNG_UINT_iCCP, mng_init_iccp, mng_free_iccp, mng_read_iccp, mng_write_iccp, mng_assign_iccp, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_iTXt
{MNG_UINT_iTXt, mng_init_itxt, mng_free_itxt, mng_read_itxt, mng_write_itxt, mng_assign_itxt, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_nEED
{MNG_UINT_nEED, mng_init_need, mng_free_need, mng_read_need, mng_write_need, mng_assign_need, 0, 0},
#endif
/* TODO: {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0}, */
/* TODO: {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0}, */
#ifndef MNG_SKIPCHUNK_pHYg
{MNG_UINT_pHYg, mng_init_phyg, mng_free_phyg, mng_read_phyg, mng_write_phyg, mng_assign_phyg, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_pHYs
{MNG_UINT_pHYs, mng_init_phys, mng_free_phys, mng_read_phys, mng_write_phys, mng_assign_phys, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_sBIT
{MNG_UINT_sBIT, mng_init_sbit, mng_free_sbit, mng_read_sbit, mng_write_sbit, mng_assign_sbit, 0, 0},
#endif
/* TODO: {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0}, */
#ifndef MNG_SKIPCHUNK_sPLT
{MNG_UINT_sPLT, mng_init_splt, mng_free_splt, mng_read_splt, mng_write_splt, mng_assign_splt, 0, 0},
#endif
{MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0},
#ifndef MNG_SKIPCHUNK_tEXt
{MNG_UINT_tEXt, mng_init_text, mng_free_text, mng_read_text, mng_write_text, mng_assign_text, 0, 0},
#endif
#ifndef MNG_SKIPCHUNK_tIME
{MNG_UINT_tIME, mng_init_time, mng_free_time, mng_read_time, mng_write_time, mng_assign_time, 0, 0},
#endif
{MNG_UINT_tRNS, mng_init_trns, mng_free_trns, mng_read_trns, mng_write_trns, mng_assign_trns, 0, 0},
#ifndef MNG_SKIPCHUNK_zTXt
{MNG_UINT_zTXt, mng_init_ztxt, mng_free_ztxt, mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt, 0, 0},
#endif
};
/* binary search variables */
mng_int32 iTop, iLower, iUpper, iMiddle;
mng_chunk_headerp pEntry; /* pointer to found entry */
mng_chunkid iChunkname; /* the chunk's tag */
mng_chunkp pChunk; /* chunk structure (if #define MNG_STORE_CHUNKS) */
mng_retcode iRetcode; /* temporary error-code */
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_START)
#endif
/* reset timer indicator on read-cycle */
if ((pData->bReading) && (!pData->bDisplaying))
pData->bTimerset = MNG_FALSE;
/* get the chunkname */
iChunkname = (mng_chunkid)(mng_get_uint32 (pBuf));
pBuf += sizeof (mng_chunkid); /* adjust the buffer */
iBuflen -= sizeof (mng_chunkid);
/* determine max index of table */
iTop = (sizeof (chunk_table) / sizeof (chunk_table [0])) - 1;
/* binary search; with 54 chunks, worst-case is 7 comparisons */
iLower = 0;
#ifndef MNG_NO_DELTA_PNG
iMiddle = 11; /* start with the IDAT entry */
#else
iMiddle = 8;
#endif
iUpper = iTop;
pEntry = 0; /* no goods yet! */
pChunk = 0;
do /* the binary search itself */
{
if (chunk_table [iMiddle].iChunkname < iChunkname)
iLower = iMiddle + 1;
else if (chunk_table [iMiddle].iChunkname > iChunkname)
iUpper = iMiddle - 1;
else
{
pEntry = &chunk_table [iMiddle];
break;
}
iMiddle = (iLower + iUpper) >> 1;
}
while (iLower <= iUpper);
if (!pEntry) /* unknown chunk ? */
pEntry = &chunk_unknown; /* make it so! */
pData->iChunkname = iChunkname; /* keep track of where we are */
pData->iChunkseq++;
if (pEntry->fRead) /* read-callback available ? */
{
iRetcode = pEntry->fRead (pData, pEntry, iBuflen, (mng_ptr)pBuf, &pChunk);
if (!iRetcode) /* everything oke ? */
{ /* remember unknown chunk's id */
if ((pChunk) && (pEntry == &chunk_unknown))
((mng_chunk_headerp)pChunk)->iChunkname = iChunkname;
}
}
else
iRetcode = MNG_NOERROR;
if (pChunk) /* store this chunk ? */
mng_add_chunk (pData, pChunk); /* do it */
#ifdef MNG_INCLUDE_JNG /* implicit EOF ? */
if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && (!pData->bHasJHDR))
#else
if ((!pData->bHasMHDR) && (!pData->bHasIHDR))
#endif
iRetcode = mng_process_eof (pData);/* then do some EOF processing */
if (iRetcode) /* on error bail out */
return iRetcode;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_END)
#endif
return MNG_NOERROR;
}
/* ************************************************************************** */
MNG_LOCAL mng_retcode check_chunk_crc (mng_datap pData,
mng_uint8p pBuf,
mng_uint32 iBuflen)
{
mng_uint32 iCrc; /* calculated CRC */
mng_bool bDiscard = MNG_FALSE;
mng_retcode iRetcode = MNG_NOERROR;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_READ_CHUNK_CRC, MNG_LC_START)
#endif
if (pData->iCrcmode & MNG_CRC_INPUT) /* crc included ? */
{
mng_bool bCritical = (mng_bool)((*pBuf & 0x20) == 0);
mng_uint32 iL = iBuflen - (mng_uint32)(sizeof (iCrc));
if (((bCritical ) && (pData->iCrcmode & MNG_CRC_CRITICAL )) ||
((!bCritical) && (pData->iCrcmode & MNG_CRC_ANCILLARY)))
{ /* calculate the crc */
iCrc = mng_crc (pData, pBuf, iL);
/* and check it */
if (!(iCrc == mng_get_uint32 (pBuf + iL)))
{
mng_bool bWarning = MNG_FALSE;
mng_bool bError = MNG_FALSE;
if (bCritical)
{
switch (pData->iCrcmode & MNG_CRC_CRITICAL)
{
case MNG_CRC_CRITICAL_WARNING : { bWarning = MNG_TRUE; break; }
case MNG_CRC_CRITICAL_ERROR : { bError = MNG_TRUE; break; }
}
}
else
{
switch (pData->iCrcmode & MNG_CRC_ANCILLARY)
{
case MNG_CRC_ANCILLARY_DISCARD : { bDiscard = MNG_TRUE; break; }
case MNG_CRC_ANCILLARY_WARNING : { bWarning = MNG_TRUE; break; }
case MNG_CRC_ANCILLARY_ERROR : { bError = MNG_TRUE; break; }
}
}
if (bWarning)
MNG_WARNING (pData, MNG_INVALIDCRC)
if (bError)
MNG_ERROR (pData, MNG_INVALIDCRC)
}
}
if (!bDiscard) /* still processing ? */
iRetcode = process_raw_chunk (pData, pBuf, iL);
}
else
{ /* no crc => straight onto processing */
iRetcode = process_raw_chunk (pData, pBuf, iBuflen);
}
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_READ_CHUNK_CRC, MNG_LC_END)
#endif
return iRetcode;
}
/* ************************************************************************** */
MNG_LOCAL mng_retcode read_chunk (mng_datap pData)
{
mng_uint32 iBufmax = pData->iReadbufsize;
mng_uint8p pBuf = pData->pReadbuf;
mng_uint32 iBuflen = 0; /* number of bytes requested */
mng_uint32 iRead = 0; /* number of bytes read */
mng_retcode iRetcode = MNG_NOERROR;
#ifdef MNG_SUPPORT_TRACE
MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_START)
#endif
#ifdef MNG_SUPPORT_DISPLAY
if (pData->pCurraniobj) /* processing an animation object ? */
{
do /* process it then */
{
iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
/* refresh needed ? */
/* if ((!iRetcode) && (!pData->bTimerset) && (pData->bNeedrefresh))
iRetcode = display_progressive_refresh (pData, 1); */
/* can we advance to next object ? */
if ((!iRetcode) && (pData->pCurraniobj) &&
(!pData->bTimerset) && (!pData->bSectionwait))
{ /* reset timer indicator on read-cycle */
if ((pData->bReading) && (!pData->bDisplaying))
pData->bTimerset = MNG_FALSE;
pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
/* TERM processing to be done ? */
if ((!pData->pCurraniobj) && (pData->bHasTERM) && (!pData->bHasMHDR))
iRetcode = mng_process_display_mend (pData);
}
} /* until error or a break or no more objects */
while ((!iRetcode) && (pData->pCurraniobj) &&
(!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
}
else
{
if (pData->iBreakpoint) /* do we need to finish something first ? */
{
switch (pData->iBreakpoint) /* return to broken display routine */
{
#ifndef MNG_SKIPCHUNK_FRAM
case 1 : { iRetcode = mng_process_display_fram2 (pData); break; }
#endif
case 2 : { iRetcode = mng_process_display_ihdr (pData); break; }
#ifndef MNG_SKIPCHUNK_SHOW
case 3 : ; /* same as 4 !!! */
case 4 : { iRetcode = mng_process_display_show (pData); break; }
#endif
#ifndef MNG_SKIPCHUNK_CLON
case 5 : { iRetcode = mng_process_display_clon2 (pData); break; }
#endif
#ifdef MNG_INCLUDE_JNG
case 7 : { iRetcode = mng_process_display_jhdr (pData); break; }
#endif
case 6 : ; /* same as 8 !!! */
case 8 : { iRetcode = mng_process_display_iend (pData); break; }
#ifndef MNG_SKIPCHUNK_MAGN
case 9 : { iRetcode = mng_process_display_magn2 (pData); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -