⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libmng_read.c

📁 开源组态软件
💻 C
📖 第 1 页 / 共 4 页
字号:
#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 + -