Home | History | Annotate | Download | only in jbig2
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "JBig2_Context.h"
      8 void OutputBitmap(CJBig2_Image* pImage)
      9 {
     10     if(!pImage) {
     11         return;
     12     }
     13 }
     14 CJBig2_Context *CJBig2_Context::CreateContext(CJBig2_Module *pModule, FX_BYTE *pGlobalData, FX_DWORD dwGlobalLength,
     15         FX_BYTE *pData, FX_DWORD dwLength, FX_INT32 nStreamType, IFX_Pause* pPause)
     16 {
     17     return new(pModule) CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength, nStreamType, pPause);
     18 }
     19 void CJBig2_Context::DestroyContext(CJBig2_Context *pContext)
     20 {
     21     if(pContext) {
     22         delete pContext;
     23     }
     24 }
     25 CJBig2_Context::CJBig2_Context(FX_BYTE *pGlobalData, FX_DWORD dwGlobalLength,
     26                                FX_BYTE *pData, FX_DWORD dwLength, FX_INT32 nStreamType, IFX_Pause* pPause)
     27 {
     28     if(pGlobalData && (dwGlobalLength > 0)) {
     29         JBIG2_ALLOC(m_pGlobalContext, CJBig2_Context(NULL, 0, pGlobalData, dwGlobalLength,
     30                     JBIG2_EMBED_STREAM, pPause));
     31     } else {
     32         m_pGlobalContext = NULL;
     33     }
     34     JBIG2_ALLOC(m_pStream, CJBig2_BitStream(pData, dwLength));
     35     m_nStreamType = nStreamType;
     36     m_nState = JBIG2_OUT_OF_PAGE;
     37     JBIG2_ALLOC(m_pSegmentList, CJBig2_List<CJBig2_Segment>);
     38     JBIG2_ALLOC(m_pPageInfoList, CJBig2_List<JBig2PageInfo>(1));
     39     m_pPage = NULL;
     40     m_bBufSpecified = FALSE;
     41     m_pPause = pPause;
     42     m_nSegmentDecoded = 0;
     43     m_PauseStep = 10;
     44     m_pArithDecoder = NULL;
     45     m_pGRD = NULL;
     46     m_gbContext = NULL;
     47     m_pSegment = NULL;
     48     m_dwOffset = 0;
     49     m_ProcessiveStatus = FXCODEC_STATUS_FRAME_READY;
     50 }
     51 CJBig2_Context::~CJBig2_Context()
     52 {
     53     if(m_pArithDecoder) {
     54         delete m_pArithDecoder;
     55     }
     56     m_pArithDecoder = NULL;
     57     if(m_pGRD) {
     58         delete m_pGRD;
     59     }
     60     m_pGRD = NULL;
     61     if(m_gbContext) {
     62         delete m_gbContext;
     63     }
     64     m_gbContext = NULL;
     65     if(m_pGlobalContext) {
     66         delete m_pGlobalContext;
     67     }
     68     m_pGlobalContext = NULL;
     69     if(m_pPageInfoList) {
     70         delete m_pPageInfoList;
     71     }
     72     m_pPageInfoList = NULL;
     73     if(m_bBufSpecified && m_pPage) {
     74         delete m_pPage;
     75     }
     76     m_pPage = NULL;
     77     if(m_pStream) {
     78         delete m_pStream;
     79     }
     80     m_pStream = NULL;
     81     if(m_pSegmentList) {
     82         delete m_pSegmentList;
     83     }
     84     m_pSegmentList = NULL;
     85 }
     86 FX_INT32 CJBig2_Context::decodeFile(IFX_Pause* pPause)
     87 {
     88     FX_BYTE cFlags;
     89     FX_DWORD dwTemp;
     90     const FX_BYTE fileID[] = {0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A};
     91     FX_INT32 nRet;
     92     if(m_pStream->getByteLeft() < 8) {
     93         m_pModule->JBig2_Error("file header too short.");
     94         nRet = JBIG2_ERROR_TOO_SHORT;
     95         goto failed;
     96     }
     97     if(JBIG2_memcmp(m_pStream->getPointer(), fileID, 8) != 0) {
     98         m_pModule->JBig2_Error("not jbig2 file");
     99         nRet = JBIG2_ERROR_FILE_FORMAT;
    100         goto failed;
    101     }
    102     m_pStream->offset(8);
    103     if(m_pStream->read1Byte(&cFlags) != 0) {
    104         m_pModule->JBig2_Error("file header too short.");
    105         nRet = JBIG2_ERROR_TOO_SHORT;
    106         goto failed;
    107     }
    108     if(!(cFlags & 0x02)) {
    109         if(m_pStream->readInteger(&dwTemp) != 0) {
    110             m_pModule->JBig2_Error("file header too short.");
    111             nRet = JBIG2_ERROR_TOO_SHORT;
    112             goto failed;
    113         }
    114         if(dwTemp > 0) {
    115             delete m_pPageInfoList;
    116             JBIG2_ALLOC(m_pPageInfoList, CJBig2_List<JBig2PageInfo>(dwTemp));
    117         }
    118     }
    119     if(cFlags & 0x01) {
    120         m_nStreamType = JBIG2_SQUENTIAL_STREAM;
    121         return decode_SquentialOrgnazation(pPause);
    122     } else {
    123         m_nStreamType = JBIG2_RANDOM_STREAM;
    124         return decode_RandomOrgnazation_FirstPage(pPause);
    125     }
    126 failed:
    127     return nRet;
    128 }
    129 FX_INT32 CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause)
    130 {
    131     FX_INT32 nRet;
    132     if(m_pStream->getByteLeft() > 0) {
    133         while(m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) {
    134             if(m_pSegment == NULL) {
    135                 JBIG2_ALLOC(m_pSegment, CJBig2_Segment());
    136                 nRet = parseSegmentHeader(m_pSegment);
    137                 if(nRet != JBIG2_SUCCESS) {
    138                     delete m_pSegment;
    139                     m_pSegment = NULL;
    140                     return nRet;
    141                 }
    142                 m_dwOffset = m_pStream->getOffset();
    143             }
    144             nRet = parseSegmentData(m_pSegment, pPause);
    145             if(m_ProcessiveStatus  == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
    146                 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    147                 m_PauseStep = 2;
    148                 return JBIG2_SUCCESS;
    149             }
    150             if((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) {
    151                 delete m_pSegment;
    152                 m_pSegment = NULL;
    153                 break;
    154             } else if(nRet != JBIG2_SUCCESS) {
    155                 delete m_pSegment;
    156                 m_pSegment = NULL;
    157                 return nRet;
    158             }
    159             m_pSegmentList->addItem(m_pSegment);
    160             if(m_pSegment->m_dwData_length != 0xffffffff) {
    161                 m_dwOffset = m_dwOffset + m_pSegment->m_dwData_length;
    162                 m_pStream->setOffset(m_dwOffset);
    163             } else {
    164                 m_pStream->offset(4);
    165             }
    166             OutputBitmap(m_pPage);
    167             m_pSegment = NULL;
    168             if(m_pStream->getByteLeft() > 0 && m_pPage && pPause && pPause->NeedToPauseNow()) {
    169                 m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    170                 m_PauseStep = 2;
    171                 return JBIG2_SUCCESS;
    172             }
    173         }
    174     } else {
    175         return JBIG2_END_OF_FILE;
    176     }
    177     return JBIG2_SUCCESS;
    178 }
    179 FX_INT32 CJBig2_Context::decode_EmbedOrgnazation(IFX_Pause* pPause)
    180 {
    181     return decode_SquentialOrgnazation(pPause);
    182 }
    183 FX_INT32 CJBig2_Context::decode_RandomOrgnazation_FirstPage(IFX_Pause* pPause)
    184 {
    185     CJBig2_Segment *pSegment;
    186     FX_INT32 nRet;
    187     while(m_pStream->getByteLeft() > JBIG2_MIN_SEGMENT_SIZE) {
    188         JBIG2_ALLOC(pSegment, CJBig2_Segment());
    189         nRet = parseSegmentHeader(pSegment);
    190         if(nRet != JBIG2_SUCCESS) {
    191             delete pSegment;
    192             return nRet;
    193         } else if(pSegment->m_cFlags.s.type == 51) {
    194             delete pSegment;
    195             break;
    196         }
    197         m_pSegmentList->addItem(pSegment);
    198         if(pPause && m_pPause && pPause->NeedToPauseNow()) {
    199             m_PauseStep = 3;
    200             m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    201             return JBIG2_SUCCESS;
    202         }
    203     }
    204     m_nSegmentDecoded = 0;
    205     return decode_RandomOrgnazation(pPause);
    206 }
    207 FX_INT32 CJBig2_Context::decode_RandomOrgnazation(IFX_Pause* pPause)
    208 {
    209     FX_INT32 nRet;
    210     for(; m_nSegmentDecoded < m_pSegmentList->getLength(); m_nSegmentDecoded++) {
    211         nRet = parseSegmentData(m_pSegmentList->getAt(m_nSegmentDecoded), pPause);
    212         if((nRet == JBIG2_END_OF_PAGE) || (nRet == JBIG2_END_OF_FILE)) {
    213             break;
    214         } else if(nRet != JBIG2_SUCCESS) {
    215             return nRet;
    216         }
    217         if(m_pPage && pPause && pPause->NeedToPauseNow()) {
    218             m_PauseStep = 4;
    219             m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    220             return JBIG2_SUCCESS;
    221         }
    222     }
    223     return JBIG2_SUCCESS;
    224 }
    225 FX_INT32 CJBig2_Context::getFirstPage(FX_BYTE *pBuf, FX_INT32 width, FX_INT32 height, FX_INT32 stride, IFX_Pause* pPause)
    226 {
    227     FX_INT32 nRet = 0;
    228     if(m_pGlobalContext) {
    229         nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause);
    230         if(nRet != JBIG2_SUCCESS) {
    231             m_ProcessiveStatus = FXCODEC_STATUS_ERROR;
    232             return nRet;
    233         }
    234     }
    235     m_bFirstPage = TRUE;
    236     m_PauseStep = 0;
    237     if(m_pPage) {
    238         delete m_pPage;
    239     }
    240     JBIG2_ALLOC(m_pPage, CJBig2_Image(width, height, stride, pBuf));
    241     m_bBufSpecified = TRUE;
    242     if(m_pPage && pPause && pPause->NeedToPauseNow()) {
    243         m_PauseStep = 1;
    244         m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    245         return nRet;
    246     }
    247     int ret = Continue(pPause);
    248     return ret;
    249 }
    250 FX_INT32 CJBig2_Context::Continue(IFX_Pause* pPause)
    251 {
    252     m_ProcessiveStatus = FXCODEC_STATUS_DECODE_READY;
    253     FX_INT32 nRet;
    254     if(m_PauseStep <= 1) {
    255         switch(m_nStreamType) {
    256             case JBIG2_FILE_STREAM:
    257                 nRet = decodeFile(pPause);
    258                 break;
    259             case JBIG2_SQUENTIAL_STREAM:
    260                 nRet = decode_SquentialOrgnazation(pPause);
    261                 break;
    262             case JBIG2_RANDOM_STREAM:
    263                 if(m_bFirstPage) {
    264                     nRet = decode_RandomOrgnazation_FirstPage(pPause);
    265                 } else {
    266                     nRet = decode_RandomOrgnazation(pPause);
    267                 }
    268                 break;
    269             case JBIG2_EMBED_STREAM:
    270                 nRet = decode_EmbedOrgnazation(pPause);
    271                 break;
    272             default:
    273                 m_ProcessiveStatus = FXCODEC_STATUS_ERROR;
    274                 return JBIG2_ERROR_STREAM_TYPE;
    275         }
    276     } else if(m_PauseStep == 2) {
    277         nRet = decode_SquentialOrgnazation(pPause);
    278     } else if(m_PauseStep == 3) {
    279         nRet = decode_RandomOrgnazation_FirstPage(pPause);
    280     } else if(m_PauseStep == 4) {
    281         nRet = decode_RandomOrgnazation(pPause);
    282     } else if(m_PauseStep == 5) {
    283         m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    284         return JBIG2_SUCCESS;
    285     }
    286     if(m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
    287         return nRet;
    288     }
    289     m_PauseStep = 5;
    290     if(!m_bBufSpecified && nRet == JBIG2_SUCCESS) {
    291         m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    292         return JBIG2_SUCCESS;
    293     }
    294     if(nRet == JBIG2_SUCCESS) {
    295         m_ProcessiveStatus = FXCODEC_STATUS_DECODE_FINISH;
    296     } else {
    297         m_ProcessiveStatus = FXCODEC_STATUS_ERROR;
    298     }
    299     return nRet;
    300 }
    301 FX_INT32 CJBig2_Context::getNextPage(FX_BYTE *pBuf, FX_INT32 width, FX_INT32 height, FX_INT32 stride, IFX_Pause* pPause)
    302 {
    303     FX_INT32 nRet = JBIG2_ERROR_STREAM_TYPE;
    304     m_bFirstPage = FALSE;
    305     m_PauseStep = 0;
    306     if(m_pPage) {
    307         delete m_pPage;
    308     }
    309     JBIG2_ALLOC(m_pPage, CJBig2_Image(width, height, stride, pBuf));
    310     m_bBufSpecified = TRUE;
    311     if(m_pPage && pPause && pPause->NeedToPauseNow()) {
    312         m_PauseStep = 1;
    313         m_ProcessiveStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE;
    314         return nRet;
    315     }
    316     return Continue(pPause);
    317     switch(m_nStreamType) {
    318         case JBIG2_FILE_STREAM:
    319             nRet = decodeFile(pPause);
    320             break;
    321         case JBIG2_SQUENTIAL_STREAM:
    322             nRet = decode_SquentialOrgnazation(pPause);
    323             break;
    324         case JBIG2_RANDOM_STREAM:
    325             nRet = decode_RandomOrgnazation(pPause);
    326             break;
    327         case JBIG2_EMBED_STREAM:
    328             nRet = decode_EmbedOrgnazation(pPause);
    329             break;
    330         default:
    331             return JBIG2_ERROR_STREAM_TYPE;
    332     }
    333     return nRet;
    334 }
    335 FX_INT32 CJBig2_Context::getFirstPage(CJBig2_Image **image, IFX_Pause* pPause)
    336 {
    337     FX_INT32 nRet;
    338     m_bFirstPage = TRUE;
    339     m_PauseStep = 0;
    340     if(m_pGlobalContext) {
    341         nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause);
    342         if(nRet != JBIG2_SUCCESS) {
    343             return nRet;
    344         }
    345     }
    346     m_bBufSpecified = FALSE;
    347     return Continue(pPause);
    348 }
    349 FX_INT32 CJBig2_Context::getNextPage(CJBig2_Image **image, IFX_Pause* pPause)
    350 {
    351     FX_INT32 nRet;
    352     m_bBufSpecified = FALSE;
    353     m_bFirstPage = FALSE;
    354     m_PauseStep = 0;
    355     switch(m_nStreamType) {
    356         case JBIG2_FILE_STREAM:
    357             nRet = decodeFile(pPause);
    358             break;
    359         case JBIG2_SQUENTIAL_STREAM:
    360             nRet = decode_SquentialOrgnazation(pPause);
    361             break;
    362         case JBIG2_RANDOM_STREAM:
    363             nRet = decode_RandomOrgnazation(pPause);
    364             break;
    365         case JBIG2_EMBED_STREAM:
    366             nRet = decode_EmbedOrgnazation(pPause);
    367             break;
    368         default:
    369             return JBIG2_ERROR_STREAM_TYPE;
    370     }
    371     if(nRet == JBIG2_SUCCESS) {
    372         *image = m_pPage;
    373         m_pPage = NULL;
    374         return JBIG2_SUCCESS;
    375     }
    376     return nRet;
    377 }
    378 CJBig2_Segment *CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber)
    379 {
    380     CJBig2_Segment *pSeg;
    381     FX_INT32 i;
    382     if(m_pGlobalContext) {
    383         pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber);
    384         if(pSeg) {
    385             return pSeg;
    386         }
    387     }
    388     for(i = 0; i < m_pSegmentList->getLength(); i++) {
    389         pSeg = m_pSegmentList->getAt(i);
    390         if(pSeg->m_dwNumber == dwNumber) {
    391             return pSeg;
    392         }
    393     }
    394     return NULL;
    395 }
    396 CJBig2_Segment *CJBig2_Context::findReferredSegmentByTypeAndIndex(CJBig2_Segment *pSegment,
    397         FX_BYTE cType, FX_INT32 nIndex)
    398 {
    399     CJBig2_Segment *pSeg;
    400     FX_INT32 i, count;
    401     count = 0;
    402     for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    403         pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]);
    404         if(pSeg && pSeg->m_cFlags.s.type == cType) {
    405             if(count == nIndex) {
    406                 return pSeg;
    407             } else {
    408                 count ++;
    409             }
    410         }
    411     }
    412     return NULL;
    413 }
    414 FX_INT32 CJBig2_Context::parseSegmentHeader(CJBig2_Segment *pSegment)
    415 {
    416     FX_BYTE  cSSize, cPSize;
    417     FX_BYTE cTemp;
    418     FX_WORD wTemp;
    419     FX_DWORD dwTemp;
    420     if((m_pStream->readInteger(&pSegment->m_dwNumber) != 0)
    421             || (m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0)) {
    422         goto failed;
    423     }
    424     cTemp = m_pStream->getCurByte();
    425     if((cTemp >> 5) == 7) {
    426         if(m_pStream->readInteger((FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) {
    427             goto failed;
    428         }
    429         pSegment->m_nReferred_to_segment_count &= 0x1fffffff;
    430         if (pSegment->m_nReferred_to_segment_count > JBIG2_MAX_REFERRED_SEGMENT_COUNT) {
    431             m_pModule->JBig2_Error("Too many referred segments.");
    432             return JBIG2_ERROR_LIMIT;
    433         }
    434         dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8;
    435     } else {
    436         if(m_pStream->read1Byte(&cTemp) != 0) {
    437             goto failed;
    438         }
    439         pSegment->m_nReferred_to_segment_count = cTemp >> 5;
    440         dwTemp = 5 + 1;
    441     }
    442     cSSize = pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1;
    443     cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1;
    444     if(pSegment->m_nReferred_to_segment_count) {
    445         pSegment->m_pReferred_to_segment_numbers = (FX_DWORD*)m_pModule->JBig2_Malloc2(
    446                     sizeof(FX_DWORD), pSegment->m_nReferred_to_segment_count);
    447         for(FX_INT32 i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    448             switch(cSSize) {
    449                 case 1:
    450                     if(m_pStream->read1Byte(&cTemp) != 0) {
    451                         goto failed;
    452                     }
    453                     pSegment->m_pReferred_to_segment_numbers[i] = cTemp;
    454                     break;
    455                 case 2:
    456                     if(m_pStream->readShortInteger(&wTemp) != 0) {
    457                         goto failed;
    458                     }
    459                     pSegment->m_pReferred_to_segment_numbers[i] = wTemp;
    460                     break;
    461                 case 4:
    462                     if(m_pStream->readInteger(&dwTemp) != 0) {
    463                         goto failed;
    464                     }
    465                     pSegment->m_pReferred_to_segment_numbers[i] = dwTemp;
    466                     break;
    467             }
    468             if (pSegment->m_pReferred_to_segment_numbers[i] >= pSegment->m_dwNumber) {
    469                 m_pModule->JBig2_Error("The referred segment number is greater than this segment number.");
    470                 goto failed;
    471             }
    472         }
    473     }
    474     if(cPSize == 1) {
    475         if(m_pStream->read1Byte(&cTemp) != 0) {
    476             goto failed;
    477         }
    478         pSegment->m_dwPage_association = cTemp;
    479     } else {
    480         if(m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) {
    481             goto failed;
    482         }
    483     }
    484     if(m_pStream->readInteger(&pSegment->m_dwData_length) != 0) {
    485         goto failed;
    486     }
    487     pSegment->m_pData = m_pStream->getPointer();
    488     pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED;
    489     return JBIG2_SUCCESS;
    490 failed:
    491     m_pModule->JBig2_Error("header too short.");
    492     return JBIG2_ERROR_TOO_SHORT;
    493 }
    494 FX_INT32 CJBig2_Context::parseSegmentData(CJBig2_Segment *pSegment, IFX_Pause* pPause)
    495 {
    496     FX_INT32 ret = ProcessiveParseSegmentData(pSegment, pPause);
    497     while(m_ProcessiveStatus  == FXCODEC_STATUS_DECODE_TOBECONTINUE && m_pStream->getByteLeft() > 0) {
    498         ret = ProcessiveParseSegmentData(pSegment, pPause);
    499     }
    500     return ret;
    501 }
    502 FX_INT32 CJBig2_Context::ProcessiveParseSegmentData(CJBig2_Segment *pSegment, IFX_Pause* pPause)
    503 {
    504     switch(pSegment->m_cFlags.s.type) {
    505         case 0:
    506             return parseSymbolDict(pSegment, pPause);
    507         case 4:
    508         case 6:
    509         case 7:
    510             if(m_nState == JBIG2_OUT_OF_PAGE) {
    511                 goto failed2;
    512             } else {
    513                 return parseTextRegion(pSegment);
    514             }
    515         case 16:
    516             return parsePatternDict(pSegment, pPause);
    517         case 20:
    518         case 22:
    519         case 23:
    520             if(m_nState == JBIG2_OUT_OF_PAGE) {
    521                 goto failed2;
    522             } else {
    523                 return parseHalftoneRegion(pSegment, pPause);
    524             }
    525         case 36:
    526         case 38:
    527         case 39:
    528             if(m_nState == JBIG2_OUT_OF_PAGE) {
    529                 goto failed2;
    530             } else {
    531                 return parseGenericRegion(pSegment, pPause);
    532             }
    533         case 40:
    534         case 42:
    535         case 43:
    536             if(m_nState == JBIG2_OUT_OF_PAGE) {
    537                 goto failed2;
    538             } else {
    539                 return parseGenericRefinementRegion(pSegment);
    540             }
    541         case 48: {
    542                 FX_WORD wTemp;
    543                 JBig2PageInfo *pPageInfo;
    544                 JBIG2_ALLOC(pPageInfo, JBig2PageInfo);
    545                 if((m_pStream->readInteger(&pPageInfo->m_dwWidth) != 0)
    546                         || (m_pStream->readInteger(&pPageInfo->m_dwHeight) != 0)
    547                         || (m_pStream->readInteger(&pPageInfo->m_dwResolutionX) != 0)
    548                         || (m_pStream->readInteger(&pPageInfo->m_dwResolutionY) != 0)
    549                         || (m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0)
    550                         || (m_pStream->readShortInteger(&wTemp) != 0)) {
    551                     delete pPageInfo;
    552                     goto failed1;
    553                 }
    554                 pPageInfo->m_bIsStriped = ((wTemp >> 15) & 1) ? 1 : 0;
    555                 pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff;
    556                 if((pPageInfo->m_dwHeight == 0xffffffff) && (pPageInfo->m_bIsStriped != 1)) {
    557                     m_pModule->JBig2_Warn("page height = 0xffffffff buf stripe field is 0");
    558                     pPageInfo->m_bIsStriped = 1;
    559                 }
    560                 if(!m_bBufSpecified) {
    561                     if(m_pPage) {
    562                         delete m_pPage;
    563                     }
    564                     if(pPageInfo->m_dwHeight == 0xffffffff) {
    565                         JBIG2_ALLOC(m_pPage, CJBig2_Image(pPageInfo->m_dwWidth, pPageInfo->m_wMaxStripeSize));
    566                     } else {
    567                         JBIG2_ALLOC(m_pPage, CJBig2_Image(pPageInfo->m_dwWidth, pPageInfo->m_dwHeight));
    568                     }
    569                 }
    570                 m_pPage->fill((pPageInfo->m_cFlags & 4) ? 1 : 0);
    571                 m_pPageInfoList->addItem(pPageInfo);
    572                 m_nState = JBIG2_IN_PAGE;
    573             }
    574             break;
    575         case 49:
    576             m_nState = JBIG2_OUT_OF_PAGE;
    577             return JBIG2_END_OF_PAGE;
    578             break;
    579         case 50:
    580             m_pStream->offset(pSegment->m_dwData_length);
    581             break;
    582         case 51:
    583             return JBIG2_END_OF_FILE;
    584         case 52:
    585             m_pStream->offset(pSegment->m_dwData_length);
    586             break;
    587         case 53:
    588             return parseTable(pSegment);
    589         case 62:
    590             m_pStream->offset(pSegment->m_dwData_length);
    591             break;
    592         default:
    593             break;
    594     }
    595     return JBIG2_SUCCESS;
    596 failed1:
    597     m_pModule->JBig2_Error("segment data too short.");
    598     return JBIG2_ERROR_TOO_SHORT;
    599 failed2:
    600     m_pModule->JBig2_Error("segment syntax error.");
    601     return JBIG2_ERROR_FETAL;
    602 }
    603 FX_INT32 CJBig2_Context::parseSymbolDict(CJBig2_Segment *pSegment, IFX_Pause* pPause)
    604 {
    605     FX_DWORD dwTemp;
    606     FX_WORD wFlags;
    607     FX_BYTE cSDHUFFDH, cSDHUFFDW, cSDHUFFBMSIZE, cSDHUFFAGGINST;
    608     CJBig2_HuffmanTable *Table_B1 = NULL, *Table_B2 = NULL, *Table_B3 = NULL, *Table_B4 = NULL, *Table_B5 = NULL;
    609     FX_INT32 i, nIndex, nRet;
    610     CJBig2_Segment *pSeg = NULL, *pLRSeg = NULL;
    611     FX_BOOL bUsed;
    612     CJBig2_Image ** SDINSYMS = NULL;
    613     CJBig2_SDDProc *pSymbolDictDecoder;
    614     JBig2ArithCtx *gbContext = NULL, *grContext = NULL;
    615     CJBig2_ArithDecoder *pArithDecoder;
    616     JBIG2_ALLOC(pSymbolDictDecoder, CJBig2_SDDProc());
    617     if(m_pStream->readShortInteger(&wFlags) != 0) {
    618         m_pModule->JBig2_Error("symbol dictionary segment : data header too short.");
    619         nRet = JBIG2_ERROR_TOO_SHORT;
    620         goto failed;
    621     }
    622     pSymbolDictDecoder->SDHUFF = wFlags & 0x0001;
    623     pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001;
    624     pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003;
    625     pSymbolDictDecoder->SDRTEMPLATE = (wFlags >> 12) & 0x0003;
    626     cSDHUFFDH = (wFlags >> 2) & 0x0003;
    627     cSDHUFFDW = (wFlags >> 4) & 0x0003;
    628     cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001;
    629     cSDHUFFAGGINST = (wFlags >> 7) & 0x0001;
    630     if(pSymbolDictDecoder->SDHUFF == 0) {
    631         if(pSymbolDictDecoder->SDTEMPLATE == 0) {
    632             dwTemp = 8;
    633         } else {
    634             dwTemp = 2;
    635         }
    636         for(i = 0; i < (FX_INT32)dwTemp; i++) {
    637             if(m_pStream->read1Byte((FX_BYTE*)&pSymbolDictDecoder->SDAT[i]) != 0) {
    638                 m_pModule->JBig2_Error("symbol dictionary segment : data header too short.");
    639                 nRet = JBIG2_ERROR_TOO_SHORT;
    640                 goto failed;
    641             }
    642         }
    643     }
    644     if((pSymbolDictDecoder->SDREFAGG == 1) && (pSymbolDictDecoder->SDRTEMPLATE == 0)) {
    645         for(i = 0; i < 4; i++) {
    646             if(m_pStream->read1Byte((FX_BYTE*)&pSymbolDictDecoder->SDRAT[i]) != 0) {
    647                 m_pModule->JBig2_Error("symbol dictionary segment : data header too short.");
    648                 nRet = JBIG2_ERROR_TOO_SHORT;
    649                 goto failed;
    650             }
    651         }
    652     }
    653     if((m_pStream->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0)
    654             || (m_pStream->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0)) {
    655         m_pModule->JBig2_Error("symbol dictionary segment : data header too short.");
    656         nRet = JBIG2_ERROR_TOO_SHORT;
    657         goto failed;
    658     }
    659     if (pSymbolDictDecoder->SDNUMEXSYMS > JBIG2_MAX_EXPORT_SYSMBOLS
    660             || pSymbolDictDecoder->SDNUMNEWSYMS > JBIG2_MAX_NEW_SYSMBOLS) {
    661         m_pModule->JBig2_Error("symbol dictionary segment : too many export/new symbols.");
    662         nRet = JBIG2_ERROR_LIMIT;
    663         goto failed;
    664     }
    665     for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    666         if(!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) {
    667             m_pModule->JBig2_Error("symbol dictionary segment : can't find refered to segments");
    668             nRet = JBIG2_ERROR_FETAL;
    669             goto failed;
    670         }
    671     }
    672     pSymbolDictDecoder->SDNUMINSYMS = 0;
    673     for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    674         pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]);
    675         if(pSeg->m_cFlags.s.type == 0) {
    676             pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_Result.sd->SDNUMEXSYMS;
    677             pLRSeg = pSeg;
    678         }
    679     }
    680     if(pSymbolDictDecoder->SDNUMINSYMS == 0) {
    681         SDINSYMS = NULL;
    682     } else {
    683         SDINSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(
    684                        sizeof(CJBig2_Image*), pSymbolDictDecoder->SDNUMINSYMS);
    685         dwTemp = 0;
    686         for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    687             pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]);
    688             if(pSeg->m_cFlags.s.type == 0) {
    689                 JBIG2_memcpy(SDINSYMS + dwTemp, pSeg->m_Result.sd->SDEXSYMS,
    690                              pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*));
    691                 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS;
    692             }
    693         }
    694     }
    695     pSymbolDictDecoder->SDINSYMS = SDINSYMS;
    696     if(pSymbolDictDecoder->SDHUFF == 1) {
    697         if((cSDHUFFDH == 2) || (cSDHUFFDW == 2)) {
    698             m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFDH=2 or SDHUFFDW=2 is not permitted.");
    699             nRet = JBIG2_ERROR_FETAL;
    700             goto failed;
    701         }
    702         nIndex = 0;
    703         if(cSDHUFFDH == 0) {
    704             JBIG2_ALLOC(Table_B4, CJBig2_HuffmanTable(HuffmanTable_B4,
    705                         sizeof(HuffmanTable_B4) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B4));
    706             pSymbolDictDecoder->SDHUFFDH = Table_B4;
    707         } else if(cSDHUFFDH == 1) {
    708             JBIG2_ALLOC(Table_B5, CJBig2_HuffmanTable(HuffmanTable_B5,
    709                         sizeof(HuffmanTable_B5) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B5));
    710             pSymbolDictDecoder->SDHUFFDH = Table_B5;
    711         } else {
    712             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
    713             if(!pSeg) {
    714                 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFDH can't find user supplied table.");
    715                 nRet = JBIG2_ERROR_FETAL;
    716                 goto failed;
    717             }
    718             pSymbolDictDecoder->SDHUFFDH = pSeg->m_Result.ht;
    719         }
    720         if(cSDHUFFDW == 0) {
    721             JBIG2_ALLOC(Table_B2, CJBig2_HuffmanTable(HuffmanTable_B2,
    722                         sizeof(HuffmanTable_B2) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B2));
    723             pSymbolDictDecoder->SDHUFFDW = Table_B2;
    724         } else if(cSDHUFFDW == 1) {
    725             JBIG2_ALLOC(Table_B3, CJBig2_HuffmanTable(HuffmanTable_B3,
    726                         sizeof(HuffmanTable_B3) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B3));
    727             pSymbolDictDecoder->SDHUFFDW = Table_B3;
    728         } else {
    729             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
    730             if(!pSeg) {
    731                 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFDW can't find user supplied table.");
    732                 nRet = JBIG2_ERROR_FETAL;
    733                 goto failed;
    734             }
    735             pSymbolDictDecoder->SDHUFFDW = pSeg->m_Result.ht;
    736         }
    737         if(cSDHUFFBMSIZE == 0) {
    738             JBIG2_ALLOC(Table_B1, CJBig2_HuffmanTable(HuffmanTable_B1,
    739                         sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
    740             pSymbolDictDecoder->SDHUFFBMSIZE = Table_B1;
    741         } else {
    742             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
    743             if(!pSeg) {
    744                 m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFBMSIZE can't find user supplied table.");
    745                 nRet = JBIG2_ERROR_FETAL;
    746                 goto failed;
    747             }
    748             pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->m_Result.ht;
    749         }
    750         if(pSymbolDictDecoder->SDREFAGG == 1) {
    751             if(cSDHUFFAGGINST == 0) {
    752                 if(!Table_B1) {
    753                     JBIG2_ALLOC(Table_B1, CJBig2_HuffmanTable(HuffmanTable_B1,
    754                                 sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
    755                 }
    756                 pSymbolDictDecoder->SDHUFFAGGINST = Table_B1;
    757             } else {
    758                 pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
    759                 if(!pSeg) {
    760                     m_pModule->JBig2_Error("symbol dictionary segment : SDHUFFAGGINST can't find user supplied table.");
    761                     nRet = JBIG2_ERROR_FETAL;
    762                     goto failed;
    763                 }
    764                 pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht;
    765             }
    766         }
    767     }
    768     if((wFlags & 0x0100) && pLRSeg && pLRSeg->m_Result.sd->m_bContextRetained) {
    769         if (pSymbolDictDecoder->SDHUFF == 0) {
    770             dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 ? 65536 : pSymbolDictDecoder->SDTEMPLATE == 1 ?
    771                      8192 : 1024;
    772             gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
    773             JBIG2_memcpy(gbContext, pLRSeg->m_Result.sd->m_gbContext, sizeof(JBig2ArithCtx)*dwTemp);
    774         }
    775         if (pSymbolDictDecoder->SDREFAGG == 1) {
    776             dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13;
    777             grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
    778             JBIG2_memcpy(grContext, pLRSeg->m_Result.sd->m_grContext, sizeof(JBig2ArithCtx)*dwTemp);
    779         }
    780     } else {
    781         if (pSymbolDictDecoder->SDHUFF == 0) {
    782             dwTemp = pSymbolDictDecoder->SDTEMPLATE == 0 ? 65536 : pSymbolDictDecoder->SDTEMPLATE == 1 ?
    783                      8192 : 1024;
    784             gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
    785             JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
    786         }
    787         if (pSymbolDictDecoder->SDREFAGG == 1) {
    788             dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13;
    789             grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
    790             JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
    791         }
    792     }
    793     pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER;
    794     if(pSymbolDictDecoder->SDHUFF == 0) {
    795         JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream));
    796         pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith(pArithDecoder, gbContext, grContext);
    797         delete pArithDecoder;
    798         if(pSegment->m_Result.sd == NULL) {
    799             nRet = JBIG2_ERROR_FETAL;
    800             goto failed;
    801         }
    802         m_pStream->alignByte();
    803         m_pStream->offset(2);
    804     } else {
    805         pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman(m_pStream, gbContext, grContext, pPause);
    806         if(pSegment->m_Result.sd == NULL) {
    807             nRet = JBIG2_ERROR_FETAL;
    808             goto failed;
    809         }
    810         m_pStream->alignByte();
    811     }
    812     if(wFlags & 0x0200) {
    813         pSegment->m_Result.sd->m_bContextRetained = TRUE;
    814         if(pSymbolDictDecoder->SDHUFF == 0) {
    815             pSegment->m_Result.sd->m_gbContext = gbContext;
    816         }
    817         if(pSymbolDictDecoder->SDREFAGG == 1) {
    818             pSegment->m_Result.sd->m_grContext = grContext;
    819         }
    820         bUsed = TRUE;
    821     } else {
    822         bUsed = FALSE;
    823     }
    824     delete pSymbolDictDecoder;
    825     if(SDINSYMS) {
    826         m_pModule->JBig2_Free(SDINSYMS);
    827     }
    828     if(Table_B1) {
    829         delete Table_B1;
    830     }
    831     if(Table_B2) {
    832         delete Table_B2;
    833     }
    834     if(Table_B3) {
    835         delete Table_B3;
    836     }
    837     if(Table_B4) {
    838         delete Table_B4;
    839     }
    840     if(Table_B5) {
    841         delete Table_B5;
    842     }
    843     if(bUsed == FALSE) {
    844         if(gbContext) {
    845             m_pModule->JBig2_Free(gbContext);
    846         }
    847         if(grContext) {
    848             m_pModule->JBig2_Free(grContext);
    849         }
    850     }
    851     return JBIG2_SUCCESS;
    852 failed:
    853     delete pSymbolDictDecoder;
    854     if(SDINSYMS) {
    855         m_pModule->JBig2_Free(SDINSYMS);
    856     }
    857     if(Table_B1) {
    858         delete Table_B1;
    859     }
    860     if(Table_B2) {
    861         delete Table_B2;
    862     }
    863     if(Table_B3) {
    864         delete Table_B3;
    865     }
    866     if(Table_B4) {
    867         delete Table_B4;
    868     }
    869     if(Table_B5) {
    870         delete Table_B5;
    871     }
    872     if(gbContext) {
    873         m_pModule->JBig2_Free(gbContext);
    874     }
    875     if(grContext) {
    876         m_pModule->JBig2_Free(grContext);
    877     }
    878     return nRet;
    879 }
    880 
    881 FX_BOOL CJBig2_Context::parseTextRegion(CJBig2_Segment *pSegment)
    882 {
    883     FX_DWORD dwTemp;
    884     FX_WORD wFlags;
    885     FX_INT32 i, nIndex, nRet;
    886     JBig2RegionInfo ri;
    887     CJBig2_Segment *pSeg;
    888     CJBig2_Image **SBSYMS = NULL;
    889     JBig2HuffmanCode *SBSYMCODES = NULL;
    890     FX_BYTE cSBHUFFFS, cSBHUFFDS, cSBHUFFDT, cSBHUFFRDW, cSBHUFFRDH, cSBHUFFRDX, cSBHUFFRDY, cSBHUFFRSIZE;
    891     CJBig2_HuffmanTable *Table_B1 = NULL,
    892                          *Table_B6 = NULL,
    893                           *Table_B7 = NULL,
    894                            *Table_B8 = NULL,
    895                             *Table_B9 = NULL,
    896                              *Table_B10 = NULL,
    897                               *Table_B11 = NULL,
    898                                *Table_B12 = NULL,
    899                                 *Table_B13 = NULL,
    900                                  *Table_B14 = NULL,
    901                                   *Table_B15 = NULL;
    902     JBig2ArithCtx *grContext = NULL;
    903     CJBig2_ArithDecoder *pArithDecoder;
    904     CJBig2_TRDProc *pTRD;
    905     JBIG2_ALLOC(pTRD, CJBig2_TRDProc());
    906     if((parseRegionInfo(&ri) != JBIG2_SUCCESS)
    907             || (m_pStream->readShortInteger(&wFlags) != 0)) {
    908         m_pModule->JBig2_Error("text region segment : data header too short.");
    909         nRet = JBIG2_ERROR_TOO_SHORT;
    910         goto failed;
    911     }
    912     pTRD->SBW = ri.width;
    913     pTRD->SBH = ri.height;
    914     pTRD->SBHUFF = wFlags & 0x0001;
    915     pTRD->SBREFINE = (wFlags >> 1) & 0x0001;
    916     dwTemp = (wFlags >> 2) & 0x0003;
    917     pTRD->SBSTRIPS = 1 << dwTemp;
    918     pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003);
    919     pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001;
    920     pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003);
    921     pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001;
    922     pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f;
    923     if(pTRD->SBDSOFFSET >= 0x0010) {
    924         pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020;
    925     }
    926     pTRD->SBRTEMPLATE = (wFlags >> 15) & 0x0001;
    927     if(pTRD->SBHUFF == 1) {
    928         if(m_pStream->readShortInteger(&wFlags) != 0) {
    929             m_pModule->JBig2_Error("text region segment : data header too short.");
    930             nRet = JBIG2_ERROR_TOO_SHORT;
    931             goto failed;
    932         }
    933         cSBHUFFFS = wFlags & 0x0003;
    934         cSBHUFFDS = (wFlags >> 2) & 0x0003;
    935         cSBHUFFDT = (wFlags >> 4) & 0x0003;
    936         cSBHUFFRDW = (wFlags >> 6) & 0x0003;
    937         cSBHUFFRDH = (wFlags >> 8) & 0x0003;
    938         cSBHUFFRDX = (wFlags >> 10) & 0x0003;
    939         cSBHUFFRDY = (wFlags >> 12) & 0x0003;
    940         cSBHUFFRSIZE = (wFlags >> 14) & 0x0001;
    941     }
    942     if((pTRD->SBREFINE == 1) && (pTRD->SBRTEMPLATE == 0)) {
    943         for(i = 0; i < 4; i++) {
    944             if(m_pStream->read1Byte((FX_BYTE*)&pTRD->SBRAT[i]) != 0) {
    945                 m_pModule->JBig2_Error("text region segment : data header too short.");
    946                 nRet = JBIG2_ERROR_TOO_SHORT;
    947                 goto failed;
    948             }
    949         }
    950     }
    951     if(m_pStream->readInteger(&pTRD->SBNUMINSTANCES) != 0) {
    952         m_pModule->JBig2_Error("text region segment : data header too short.");
    953         nRet = JBIG2_ERROR_TOO_SHORT;
    954         goto failed;
    955     }
    956     for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    957         if(!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) {
    958             m_pModule->JBig2_Error("text region segment : can't find refered to segments");
    959             nRet = JBIG2_ERROR_FETAL;
    960             goto failed;
    961         }
    962     }
    963     pTRD->SBNUMSYMS = 0;
    964     for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    965         pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]);
    966         if(pSeg->m_cFlags.s.type == 0) {
    967             pTRD->SBNUMSYMS += pSeg->m_Result.sd->SDNUMEXSYMS;
    968         }
    969     }
    970     if (pTRD->SBNUMSYMS > 0) {
    971         SBSYMS = (CJBig2_Image**)m_pModule->JBig2_Malloc2(
    972                      sizeof(CJBig2_Image*), pTRD->SBNUMSYMS);
    973         dwTemp = 0;
    974         for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
    975             pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]);
    976             if(pSeg->m_cFlags.s.type == 0) {
    977                 JBIG2_memcpy(SBSYMS + dwTemp, pSeg->m_Result.sd->SDEXSYMS,
    978                              pSeg->m_Result.sd->SDNUMEXSYMS * sizeof(CJBig2_Image*));
    979                 dwTemp += pSeg->m_Result.sd->SDNUMEXSYMS;
    980             }
    981         }
    982         pTRD->SBSYMS = SBSYMS;
    983     } else {
    984         pTRD->SBSYMS = NULL;
    985     }
    986     if(pTRD->SBHUFF == 1) {
    987         SBSYMCODES = decodeSymbolIDHuffmanTable(m_pStream, pTRD->SBNUMSYMS);
    988         if(SBSYMCODES == NULL) {
    989             m_pModule->JBig2_Error("text region segment: symbol ID huffman table decode failure!");
    990             nRet = JBIG2_ERROR_FETAL;
    991             goto failed;
    992         }
    993         m_pStream->alignByte();
    994         pTRD->SBSYMCODES = SBSYMCODES;
    995     } else {
    996         dwTemp = 0;
    997         while((FX_DWORD)(1 << dwTemp) < pTRD->SBNUMSYMS) {
    998             dwTemp ++;
    999         }
   1000         pTRD->SBSYMCODELEN = (FX_BYTE)dwTemp;
   1001     }
   1002     if(pTRD->SBHUFF == 1) {
   1003         if((cSBHUFFFS == 2) || (cSBHUFFRDW == 2) || (cSBHUFFRDH == 2)
   1004                 || (cSBHUFFRDX == 2) || (cSBHUFFRDY == 2)) {
   1005             m_pModule->JBig2_Error("text region segment : SBHUFFFS=2 or SBHUFFRDW=2 or "
   1006                                    "SBHUFFRDH=2 or SBHUFFRDX=2 or SBHUFFRDY=2 is not permitted");
   1007             nRet = JBIG2_ERROR_FETAL;
   1008             goto failed;
   1009         }
   1010         nIndex = 0;
   1011         if(cSBHUFFFS == 0) {
   1012             JBIG2_ALLOC(Table_B6, CJBig2_HuffmanTable(HuffmanTable_B6,
   1013                         sizeof(HuffmanTable_B6) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B6));
   1014             pTRD->SBHUFFFS = Table_B6;
   1015         } else if(cSBHUFFFS == 1) {
   1016             JBIG2_ALLOC(Table_B7, CJBig2_HuffmanTable(HuffmanTable_B7,
   1017                         sizeof(HuffmanTable_B7) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B7));
   1018             pTRD->SBHUFFFS = Table_B7;
   1019         } else {
   1020             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1021             if(!pSeg) {
   1022                 m_pModule->JBig2_Error("text region segment : SBHUFFFS can't find user supplied table");
   1023                 nRet = JBIG2_ERROR_FETAL;
   1024                 goto failed;
   1025             }
   1026             pTRD->SBHUFFFS = pSeg->m_Result.ht;
   1027         }
   1028         if(cSBHUFFDS == 0) {
   1029             JBIG2_ALLOC(Table_B8, CJBig2_HuffmanTable(HuffmanTable_B8,
   1030                         sizeof(HuffmanTable_B8) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B8));
   1031             pTRD->SBHUFFDS = Table_B8;
   1032         } else if(cSBHUFFDS == 1) {
   1033             JBIG2_ALLOC(Table_B9, CJBig2_HuffmanTable(HuffmanTable_B9,
   1034                         sizeof(HuffmanTable_B9) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B9));
   1035             pTRD->SBHUFFDS = Table_B9;
   1036         } else if(cSBHUFFDS == 2) {
   1037             JBIG2_ALLOC(Table_B10, CJBig2_HuffmanTable(HuffmanTable_B10,
   1038                         sizeof(HuffmanTable_B10) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B10));
   1039             pTRD->SBHUFFDS = Table_B10;
   1040         } else {
   1041             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1042             if(!pSeg) {
   1043                 m_pModule->JBig2_Error("text region segment : SBHUFFDS can't find user supplied table");
   1044                 nRet = JBIG2_ERROR_FETAL;
   1045                 goto failed;
   1046             }
   1047             pTRD->SBHUFFDS = pSeg->m_Result.ht;
   1048         }
   1049         if(cSBHUFFDT == 0) {
   1050             JBIG2_ALLOC(Table_B11, CJBig2_HuffmanTable(HuffmanTable_B11,
   1051                         sizeof(HuffmanTable_B11) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B11));
   1052             pTRD->SBHUFFDT = Table_B11;
   1053         } else if(cSBHUFFDT == 1) {
   1054             JBIG2_ALLOC(Table_B12, CJBig2_HuffmanTable(HuffmanTable_B12,
   1055                         sizeof(HuffmanTable_B12) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B12));
   1056             pTRD->SBHUFFDT = Table_B12;
   1057         } else if(cSBHUFFDT == 2) {
   1058             JBIG2_ALLOC(Table_B13, CJBig2_HuffmanTable(HuffmanTable_B13,
   1059                         sizeof(HuffmanTable_B13) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B13));
   1060             pTRD->SBHUFFDT = Table_B13;
   1061         } else {
   1062             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1063             if(!pSeg) {
   1064                 m_pModule->JBig2_Error("text region segment : SBHUFFDT can't find user supplied table");
   1065                 nRet = JBIG2_ERROR_FETAL;
   1066                 goto failed;
   1067             }
   1068             pTRD->SBHUFFDT = pSeg->m_Result.ht;
   1069         }
   1070         if(cSBHUFFRDW == 0) {
   1071             JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14,
   1072                         sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B14));
   1073             pTRD->SBHUFFRDW = Table_B14;
   1074         } else if(cSBHUFFRDW == 1) {
   1075             JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15,
   1076                         sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
   1077             pTRD->SBHUFFRDW = Table_B15;
   1078         } else {
   1079             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1080             if(!pSeg) {
   1081                 m_pModule->JBig2_Error("text region segment : SBHUFFRDW can't find user supplied table");
   1082                 nRet = JBIG2_ERROR_FETAL;
   1083                 goto failed;
   1084             }
   1085             pTRD->SBHUFFRDW = pSeg->m_Result.ht;
   1086         }
   1087         if(cSBHUFFRDH == 0) {
   1088             if(!Table_B14) {
   1089                 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14,
   1090                             sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B14));
   1091             }
   1092             pTRD->SBHUFFRDH = Table_B14;
   1093         } else if(cSBHUFFRDH == 1) {
   1094             if(!Table_B15) {
   1095                 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15,
   1096                             sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
   1097             }
   1098             pTRD->SBHUFFRDH = Table_B15;
   1099         } else {
   1100             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1101             if(!pSeg) {
   1102                 m_pModule->JBig2_Error("text region segment : SBHUFFRDH can't find user supplied table");
   1103                 nRet = JBIG2_ERROR_FETAL;
   1104                 goto failed;
   1105             }
   1106             pTRD->SBHUFFRDH = pSeg->m_Result.ht;
   1107         }
   1108         if(cSBHUFFRDX == 0) {
   1109             if(!Table_B14) {
   1110                 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14,
   1111                             sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B14));
   1112             }
   1113             pTRD->SBHUFFRDX = Table_B14;
   1114         } else if(cSBHUFFRDX == 1) {
   1115             if(!Table_B15) {
   1116                 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15,
   1117                             sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
   1118             }
   1119             pTRD->SBHUFFRDX = Table_B15;
   1120         } else {
   1121             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1122             if(!pSeg) {
   1123                 m_pModule->JBig2_Error("text region segment : SBHUFFRDX can't find user supplied table");
   1124                 nRet = JBIG2_ERROR_FETAL;
   1125                 goto failed;
   1126             }
   1127             pTRD->SBHUFFRDX = pSeg->m_Result.ht;
   1128         }
   1129         if(cSBHUFFRDY == 0) {
   1130             if(!Table_B14) {
   1131                 JBIG2_ALLOC(Table_B14, CJBig2_HuffmanTable(HuffmanTable_B14,
   1132                             sizeof(HuffmanTable_B14) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B14));
   1133             }
   1134             pTRD->SBHUFFRDY = Table_B14;
   1135         } else if(cSBHUFFRDY == 1) {
   1136             if(!Table_B15) {
   1137                 JBIG2_ALLOC(Table_B15, CJBig2_HuffmanTable(HuffmanTable_B15,
   1138                             sizeof(HuffmanTable_B15) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B15));
   1139             }
   1140             pTRD->SBHUFFRDY = Table_B15;
   1141         } else {
   1142             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1143             if(!pSeg) {
   1144                 m_pModule->JBig2_Error("text region segment : SBHUFFRDY can't find user supplied table");
   1145                 nRet = JBIG2_ERROR_FETAL;
   1146                 goto failed;
   1147             }
   1148             pTRD->SBHUFFRDY = pSeg->m_Result.ht;
   1149         }
   1150         if(cSBHUFFRSIZE == 0) {
   1151             JBIG2_ALLOC(Table_B1, CJBig2_HuffmanTable(HuffmanTable_B1,
   1152                         sizeof(HuffmanTable_B1) / sizeof(JBig2TableLine), HuffmanTable_HTOOB_B1));
   1153             pTRD->SBHUFFRSIZE = Table_B1;
   1154         } else {
   1155             pSeg = findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++);
   1156             if(!pSeg) {
   1157                 m_pModule->JBig2_Error("text region segment : SBHUFFRSIZE can't find user supplied table");
   1158                 nRet = JBIG2_ERROR_FETAL;
   1159                 goto failed;
   1160             }
   1161             pTRD->SBHUFFRSIZE = pSeg->m_Result.ht;
   1162         }
   1163     }
   1164     if(pTRD->SBREFINE == 1) {
   1165         dwTemp = pTRD->SBRTEMPLATE ? 1 << 10 : 1 << 13;
   1166         grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
   1167         JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
   1168     }
   1169     if(pTRD->SBHUFF == 0) {
   1170         JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream));
   1171         pSegment->m_nResultType = JBIG2_IMAGE_POINTER;
   1172         pSegment->m_Result.im = pTRD->decode_Arith(pArithDecoder, grContext);
   1173         delete pArithDecoder;
   1174         if(pSegment->m_Result.im == NULL) {
   1175             nRet = JBIG2_ERROR_FETAL;
   1176             goto failed;
   1177         }
   1178         m_pStream->alignByte();
   1179         m_pStream->offset(2);
   1180     } else {
   1181         pSegment->m_nResultType = JBIG2_IMAGE_POINTER;
   1182         pSegment->m_Result.im = pTRD->decode_Huffman(m_pStream, grContext);
   1183         if(pSegment->m_Result.im == NULL) {
   1184             nRet = JBIG2_ERROR_FETAL;
   1185             goto failed;
   1186         }
   1187         m_pStream->alignByte();
   1188     }
   1189     if(pSegment->m_cFlags.s.type != 4) {
   1190         if(!m_bBufSpecified) {
   1191             JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast();
   1192             if ((pPageInfo->m_bIsStriped == 1) && (ri.y + ri.height > m_pPage->m_nHeight)) {
   1193                 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
   1194             }
   1195         }
   1196         m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)(ri.flags & 0x03));
   1197         delete pSegment->m_Result.im;
   1198         pSegment->m_Result.im = NULL;
   1199     }
   1200     delete pTRD;
   1201     if(SBSYMS) {
   1202         m_pModule->JBig2_Free(SBSYMS);
   1203     }
   1204     if(SBSYMCODES) {
   1205         m_pModule->JBig2_Free(SBSYMCODES);
   1206     }
   1207     if(grContext) {
   1208         m_pModule->JBig2_Free(grContext);
   1209     }
   1210     if(Table_B1) {
   1211         delete Table_B1;
   1212     }
   1213     if(Table_B6) {
   1214         delete Table_B6;
   1215     }
   1216     if(Table_B7) {
   1217         delete Table_B7;
   1218     }
   1219     if(Table_B8) {
   1220         delete Table_B8;
   1221     }
   1222     if(Table_B9) {
   1223         delete Table_B9;
   1224     }
   1225     if(Table_B10) {
   1226         delete Table_B10;
   1227     }
   1228     if(Table_B11) {
   1229         delete Table_B11;
   1230     }
   1231     if(Table_B12) {
   1232         delete Table_B12;
   1233     }
   1234     if(Table_B13) {
   1235         delete Table_B13;
   1236     }
   1237     if(Table_B14) {
   1238         delete Table_B14;
   1239     }
   1240     if(Table_B15) {
   1241         delete Table_B15;
   1242     }
   1243     return JBIG2_SUCCESS;
   1244 failed:
   1245     delete pTRD;
   1246     if(SBSYMS) {
   1247         m_pModule->JBig2_Free(SBSYMS);
   1248     }
   1249     if(SBSYMCODES) {
   1250         m_pModule->JBig2_Free(SBSYMCODES);
   1251     }
   1252     if(grContext) {
   1253         m_pModule->JBig2_Free(grContext);
   1254     }
   1255     if(Table_B1) {
   1256         delete Table_B1;
   1257     }
   1258     if(Table_B6) {
   1259         delete Table_B6;
   1260     }
   1261     if(Table_B7) {
   1262         delete Table_B7;
   1263     }
   1264     if(Table_B8) {
   1265         delete Table_B8;
   1266     }
   1267     if(Table_B9) {
   1268         delete Table_B9;
   1269     }
   1270     if(Table_B10) {
   1271         delete Table_B10;
   1272     }
   1273     if(Table_B11) {
   1274         delete Table_B11;
   1275     }
   1276     if(Table_B12) {
   1277         delete Table_B12;
   1278     }
   1279     if(Table_B13) {
   1280         delete Table_B13;
   1281     }
   1282     if(Table_B14) {
   1283         delete Table_B14;
   1284     }
   1285     if(Table_B15) {
   1286         delete Table_B15;
   1287     }
   1288     return nRet;
   1289 }
   1290 
   1291 FX_BOOL CJBig2_Context::parsePatternDict(CJBig2_Segment *pSegment, IFX_Pause* pPause)
   1292 {
   1293     FX_DWORD dwTemp;
   1294     FX_BYTE cFlags;
   1295     JBig2ArithCtx *gbContext;
   1296     CJBig2_ArithDecoder *pArithDecoder;
   1297     CJBig2_PDDProc *pPDD;
   1298     FX_INT32 nRet;
   1299     JBIG2_ALLOC(pPDD, CJBig2_PDDProc());
   1300     if((m_pStream->read1Byte(&cFlags) != 0)
   1301             || (m_pStream->read1Byte(&pPDD->HDPW) != 0)
   1302             || (m_pStream->read1Byte(&pPDD->HDPH) != 0)
   1303             || (m_pStream->readInteger(&pPDD->GRAYMAX) != 0)) {
   1304         m_pModule->JBig2_Error("pattern dictionary segment : data header too short.");
   1305         nRet = JBIG2_ERROR_TOO_SHORT;
   1306         goto failed;
   1307     }
   1308     if (pPDD->GRAYMAX > JBIG2_MAX_PATTERN_INDEX) {
   1309         m_pModule->JBig2_Error("pattern dictionary segment : too max gray max.");
   1310         nRet = JBIG2_ERROR_LIMIT;
   1311         goto failed;
   1312     }
   1313     pPDD->HDMMR = cFlags & 0x01;
   1314     pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03;
   1315     pSegment->m_nResultType = JBIG2_PATTERN_DICT_POINTER;
   1316     if(pPDD->HDMMR == 0) {
   1317         dwTemp = pPDD->HDTEMPLATE == 0 ? 65536 : pPDD->HDTEMPLATE == 1 ? 8192 : 1024;
   1318         gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
   1319         JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
   1320         JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream));
   1321         pSegment->m_Result.pd = pPDD->decode_Arith(pArithDecoder, gbContext, pPause);
   1322         delete pArithDecoder;
   1323         if(pSegment->m_Result.pd == NULL) {
   1324             m_pModule->JBig2_Free(gbContext);
   1325             nRet = JBIG2_ERROR_FETAL;
   1326             goto failed;
   1327         }
   1328         m_pModule->JBig2_Free(gbContext);
   1329         m_pStream->alignByte();
   1330         m_pStream->offset(2);
   1331     } else {
   1332         pSegment->m_Result.pd = pPDD->decode_MMR(m_pStream, pPause);
   1333         if(pSegment->m_Result.pd == NULL) {
   1334             nRet = JBIG2_ERROR_FETAL;
   1335             goto failed;
   1336         }
   1337         m_pStream->alignByte();
   1338     }
   1339     delete pPDD;
   1340     return JBIG2_SUCCESS;
   1341 failed:
   1342     delete pPDD;
   1343     return nRet;
   1344 }
   1345 FX_BOOL CJBig2_Context::parseHalftoneRegion(CJBig2_Segment *pSegment, IFX_Pause* pPause)
   1346 {
   1347     FX_DWORD dwTemp;
   1348     FX_BYTE cFlags;
   1349     JBig2RegionInfo ri;
   1350     CJBig2_Segment *pSeg;
   1351     CJBig2_PatternDict *pPatternDict;
   1352     JBig2ArithCtx *gbContext;
   1353     CJBig2_ArithDecoder *pArithDecoder;
   1354     CJBig2_HTRDProc *pHRD;
   1355     FX_INT32 nRet;
   1356     JBIG2_ALLOC(pHRD, CJBig2_HTRDProc());
   1357     if((parseRegionInfo(&ri) != JBIG2_SUCCESS)
   1358             || (m_pStream->read1Byte(&cFlags) != 0)
   1359             || (m_pStream->readInteger(&pHRD->HGW) != 0)
   1360             || (m_pStream->readInteger(&pHRD->HGH) != 0)
   1361             || (m_pStream->readInteger((FX_DWORD*)&pHRD->HGX) != 0)
   1362             || (m_pStream->readInteger((FX_DWORD*)&pHRD->HGY) != 0)
   1363             || (m_pStream->readShortInteger(&pHRD->HRX) != 0)
   1364             || (m_pStream->readShortInteger(&pHRD->HRY) != 0)) {
   1365         m_pModule->JBig2_Error("halftone region segment : data header too short.");
   1366         nRet = JBIG2_ERROR_TOO_SHORT;
   1367         goto failed;
   1368     }
   1369     pHRD->HBW = ri.width;
   1370     pHRD->HBH = ri.height;
   1371     pHRD->HMMR = cFlags & 0x01;
   1372     pHRD->HTEMPLATE = (cFlags >> 1) & 0x03;
   1373     pHRD->HENABLESKIP = (cFlags >> 3) & 0x01;
   1374     pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07);
   1375     pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01;
   1376     if(pSegment->m_nReferred_to_segment_count != 1) {
   1377         m_pModule->JBig2_Error("halftone region segment : refered to segment count not equals 1");
   1378         nRet = JBIG2_ERROR_FETAL;
   1379         goto failed;
   1380     }
   1381     pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]);
   1382     if( (pSeg == NULL) || (pSeg->m_cFlags.s.type != 16)) {
   1383         m_pModule->JBig2_Error("halftone region segment : refered to segment is not pattern dict");
   1384         nRet = JBIG2_ERROR_FETAL;
   1385         goto failed;
   1386     }
   1387     pPatternDict = pSeg->m_Result.pd;
   1388     if((pPatternDict == NULL) || (pPatternDict->NUMPATS == 0)) {
   1389         m_pModule->JBig2_Error("halftone region segment : has no patterns input");
   1390         nRet = JBIG2_ERROR_FETAL;
   1391         goto failed;
   1392     }
   1393     pHRD->HNUMPATS = pPatternDict->NUMPATS;
   1394     pHRD->HPATS = pPatternDict->HDPATS;
   1395     pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth;
   1396     pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight;
   1397     pSegment->m_nResultType = JBIG2_IMAGE_POINTER;
   1398     if(pHRD->HMMR == 0) {
   1399         dwTemp = pHRD->HTEMPLATE == 0 ? 65536 : pHRD->HTEMPLATE == 1 ? 8192 : 1024;
   1400         gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
   1401         JBIG2_memset(gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
   1402         JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream));
   1403         pSegment->m_Result.im = pHRD->decode_Arith(pArithDecoder, gbContext, pPause);
   1404         delete pArithDecoder;
   1405         if(pSegment->m_Result.im == NULL) {
   1406             m_pModule->JBig2_Free(gbContext);
   1407             nRet = JBIG2_ERROR_FETAL;
   1408             goto failed;
   1409         }
   1410         m_pModule->JBig2_Free(gbContext);
   1411         m_pStream->alignByte();
   1412         m_pStream->offset(2);
   1413     } else {
   1414         pSegment->m_Result.im = pHRD->decode_MMR(m_pStream, pPause);
   1415         if(pSegment->m_Result.im == NULL) {
   1416             nRet = JBIG2_ERROR_FETAL;
   1417             goto failed;
   1418         }
   1419         m_pStream->alignByte();
   1420     }
   1421     if(pSegment->m_cFlags.s.type != 20) {
   1422         if(!m_bBufSpecified) {
   1423             JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast();
   1424             if ((pPageInfo->m_bIsStriped == 1) && (ri.y + ri.height > m_pPage->m_nHeight)) {
   1425                 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
   1426             }
   1427         }
   1428         m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)(ri.flags & 0x03));
   1429         delete pSegment->m_Result.im;
   1430         pSegment->m_Result.im = NULL;
   1431     }
   1432     delete pHRD;
   1433     return JBIG2_SUCCESS;
   1434 failed:
   1435     delete pHRD;
   1436     return nRet;
   1437 }
   1438 
   1439 FX_BOOL CJBig2_Context::parseGenericRegion(CJBig2_Segment *pSegment, IFX_Pause* pPause)
   1440 {
   1441     FX_DWORD dwTemp;
   1442     FX_BYTE cFlags;
   1443     FX_INT32 i, nRet;
   1444     if(m_pGRD == NULL) {
   1445         JBIG2_ALLOC(m_pGRD, CJBig2_GRDProc());
   1446         if((parseRegionInfo(&m_ri) != JBIG2_SUCCESS)
   1447                 || (m_pStream->read1Byte(&cFlags) != 0)) {
   1448             m_pModule->JBig2_Error("generic region segment : data header too short.");
   1449             nRet = JBIG2_ERROR_TOO_SHORT;
   1450             goto failed;
   1451         }
   1452         if (m_ri.height < 0 || m_ri.width < 0) {
   1453             m_pModule->JBig2_Error("generic region segment : wrong data.");
   1454             nRet = JBIG2_FAILED;
   1455             goto failed;
   1456         }
   1457         m_pGRD->GBW = m_ri.width;
   1458         m_pGRD->GBH = m_ri.height;
   1459         m_pGRD->MMR = cFlags & 0x01;
   1460         m_pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03;
   1461         m_pGRD->TPGDON = (cFlags >> 3) & 0x01;
   1462         if(m_pGRD->MMR == 0) {
   1463             if(m_pGRD->GBTEMPLATE == 0) {
   1464                 for(i = 0; i < 8; i++) {
   1465                     if(m_pStream->read1Byte((FX_BYTE*)&m_pGRD->GBAT[i]) != 0) {
   1466                         m_pModule->JBig2_Error("generic region segment : data header too short.");
   1467                         nRet = JBIG2_ERROR_TOO_SHORT;
   1468                         goto failed;
   1469                     }
   1470                 }
   1471             } else {
   1472                 for(i = 0; i < 2; i++) {
   1473                     if(m_pStream->read1Byte((FX_BYTE*)&m_pGRD->GBAT[i]) != 0) {
   1474                         m_pModule->JBig2_Error("generic region segment : data header too short.");
   1475                         nRet = JBIG2_ERROR_TOO_SHORT;
   1476                         goto failed;
   1477                     }
   1478                 }
   1479             }
   1480         }
   1481         m_pGRD->USESKIP = 0;
   1482     }
   1483     pSegment->m_nResultType = JBIG2_IMAGE_POINTER;
   1484     if(m_pGRD->MMR == 0) {
   1485         dwTemp = m_pGRD->GBTEMPLATE == 0 ? 65536 : m_pGRD->GBTEMPLATE == 1 ? 8192 : 1024;
   1486         if(m_gbContext == NULL) {
   1487             m_gbContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc(sizeof(JBig2ArithCtx) * dwTemp);
   1488             JBIG2_memset(m_gbContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
   1489         }
   1490         if(m_pArithDecoder == NULL) {
   1491             JBIG2_ALLOC(m_pArithDecoder, CJBig2_ArithDecoder(m_pStream));
   1492             m_ProcessiveStatus = m_pGRD->Start_decode_Arith(&pSegment->m_Result.im, m_pArithDecoder, m_gbContext, pPause);
   1493         } else {
   1494             m_ProcessiveStatus = m_pGRD->Continue_decode(pPause);
   1495         }
   1496         OutputBitmap(pSegment->m_Result.im);
   1497         if(m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
   1498             if(pSegment->m_cFlags.s.type != 36) {
   1499                 if(!m_bBufSpecified) {
   1500                     JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast();
   1501                     if ((pPageInfo->m_bIsStriped == 1) && (m_ri.y + m_ri.height > m_pPage->m_nHeight)) {
   1502                         m_pPage->expand(m_ri.y + m_ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
   1503                     }
   1504                 }
   1505                 FX_RECT Rect = m_pGRD->GetReplaceRect();
   1506                 m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, pSegment->m_Result.im, (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect);
   1507             }
   1508             return JBIG2_SUCCESS;
   1509         } else {
   1510             delete m_pArithDecoder;
   1511             m_pArithDecoder = NULL;
   1512             if(pSegment->m_Result.im == NULL) {
   1513                 m_pModule->JBig2_Free(m_gbContext);
   1514                 nRet = JBIG2_ERROR_FETAL;
   1515                 m_gbContext = NULL;
   1516                 m_ProcessiveStatus = FXCODEC_STATUS_ERROR;
   1517                 goto failed;
   1518             }
   1519             m_pModule->JBig2_Free(m_gbContext);
   1520             m_gbContext = NULL;
   1521             m_pStream->alignByte();
   1522             m_pStream->offset(2);
   1523         }
   1524     } else {
   1525         FXCODEC_STATUS status = m_pGRD->Start_decode_MMR(&pSegment->m_Result.im, m_pStream, pPause);
   1526         while(status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
   1527             m_pGRD->Continue_decode(pPause);
   1528         }
   1529         if(pSegment->m_Result.im == NULL) {
   1530             nRet = JBIG2_ERROR_FETAL;
   1531             goto failed;
   1532         }
   1533         m_pStream->alignByte();
   1534     }
   1535     if(pSegment->m_cFlags.s.type != 36) {
   1536         if(!m_bBufSpecified) {
   1537             JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast();
   1538             if ((pPageInfo->m_bIsStriped == 1) && (m_ri.y + m_ri.height > m_pPage->m_nHeight)) {
   1539                 m_pPage->expand(m_ri.y + m_ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
   1540             }
   1541         }
   1542         FX_RECT Rect = m_pGRD->GetReplaceRect();
   1543         m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, pSegment->m_Result.im, (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect);
   1544         delete pSegment->m_Result.im;
   1545         pSegment->m_Result.im = NULL;
   1546     }
   1547     delete m_pGRD;
   1548     m_pGRD = NULL;
   1549     return JBIG2_SUCCESS;
   1550 failed:
   1551     delete m_pGRD;
   1552     m_pGRD = NULL;
   1553     return nRet;
   1554 }
   1555 
   1556 FX_BOOL CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment *pSegment)
   1557 {
   1558     FX_DWORD dwTemp;
   1559     JBig2RegionInfo ri;
   1560     CJBig2_Segment *pSeg;
   1561     FX_INT32 i, nRet;
   1562     FX_BYTE cFlags;
   1563     JBig2ArithCtx *grContext;
   1564     CJBig2_GRRDProc *pGRRD;
   1565     CJBig2_ArithDecoder *pArithDecoder;
   1566     JBIG2_ALLOC(pGRRD, CJBig2_GRRDProc());
   1567     if((parseRegionInfo(&ri) != JBIG2_SUCCESS)
   1568             || (m_pStream->read1Byte(&cFlags) != 0)) {
   1569         m_pModule->JBig2_Error("generic refinement region segment : data header too short.");
   1570         nRet = JBIG2_ERROR_TOO_SHORT;
   1571         goto failed;
   1572     }
   1573     pGRRD->GRW = ri.width;
   1574     pGRRD->GRH = ri.height;
   1575     pGRRD->GRTEMPLATE = cFlags & 0x01;
   1576     pGRRD->TPGRON = (cFlags >> 1) & 0x01;
   1577     if(pGRRD->GRTEMPLATE == 0) {
   1578         for(i = 0; i < 4; i++) {
   1579             if(m_pStream->read1Byte((FX_BYTE*)&pGRRD->GRAT[i]) != 0) {
   1580                 m_pModule->JBig2_Error("generic refinement region segment : data header too short.");
   1581                 nRet = JBIG2_ERROR_TOO_SHORT;
   1582                 goto failed;
   1583             }
   1584         }
   1585     }
   1586     pSeg = NULL;
   1587     if(pSegment->m_nReferred_to_segment_count > 0) {
   1588         for(i = 0; i < pSegment->m_nReferred_to_segment_count; i++) {
   1589             pSeg = this->findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]);
   1590             if(pSeg == NULL) {
   1591                 m_pModule->JBig2_Error("generic refinement region segment : can't find refered to segments");
   1592                 nRet = JBIG2_ERROR_FETAL;
   1593                 goto failed;
   1594             }
   1595             if((pSeg->m_cFlags.s.type == 4) || (pSeg->m_cFlags.s.type == 20)
   1596                     || (pSeg->m_cFlags.s.type == 36) || (pSeg->m_cFlags.s.type == 40)) {
   1597                 break;
   1598             }
   1599         }
   1600         if(i >= pSegment->m_nReferred_to_segment_count) {
   1601             m_pModule->JBig2_Error("generic refinement region segment : can't find refered to intermediate region");
   1602             nRet = JBIG2_ERROR_FETAL;
   1603             goto failed;
   1604         }
   1605         pGRRD->GRREFERENCE = pSeg->m_Result.im;
   1606     } else {
   1607         pGRRD->GRREFERENCE = m_pPage;
   1608     }
   1609     pGRRD->GRREFERENCEDX = 0;
   1610     pGRRD->GRREFERENCEDY = 0;
   1611     dwTemp = pGRRD->GRTEMPLATE ? 1 << 10 : 1 << 13;
   1612     grContext = (JBig2ArithCtx*)m_pModule->JBig2_Malloc2(sizeof(JBig2ArithCtx), dwTemp);
   1613     JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx)*dwTemp);
   1614     JBIG2_ALLOC(pArithDecoder, CJBig2_ArithDecoder(m_pStream));
   1615     pSegment->m_nResultType = JBIG2_IMAGE_POINTER;
   1616     pSegment->m_Result.im = pGRRD->decode(pArithDecoder, grContext);
   1617     delete pArithDecoder;
   1618     if(pSegment->m_Result.im == NULL) {
   1619         m_pModule->JBig2_Free(grContext);
   1620         nRet = JBIG2_ERROR_FETAL;
   1621         goto failed;
   1622     }
   1623     m_pModule->JBig2_Free(grContext);
   1624     m_pStream->alignByte();
   1625     m_pStream->offset(2);
   1626     if(pSegment->m_cFlags.s.type != 40) {
   1627         if(!m_bBufSpecified) {
   1628             JBig2PageInfo *pPageInfo = m_pPageInfoList->getLast();
   1629             if ((pPageInfo->m_bIsStriped == 1) && (ri.y + ri.height > m_pPage->m_nHeight)) {
   1630                 m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0);
   1631             }
   1632         }
   1633         m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, (JBig2ComposeOp)(ri.flags & 0x03));
   1634         delete pSegment->m_Result.im;
   1635         pSegment->m_Result.im = NULL;
   1636     }
   1637     delete pGRRD;
   1638     return JBIG2_SUCCESS;
   1639 failed:
   1640     delete pGRRD;
   1641     return nRet;
   1642 }
   1643 FX_BOOL CJBig2_Context::parseTable(CJBig2_Segment *pSegment)
   1644 {
   1645     pSegment->m_nResultType = JBIG2_HUFFMAN_TABLE_POINTER;
   1646     JBIG2_ALLOC(pSegment->m_Result.ht, CJBig2_HuffmanTable(m_pStream));
   1647     if(!pSegment->m_Result.ht->isOK()) {
   1648         delete pSegment->m_Result.ht;
   1649         pSegment->m_Result.ht = NULL;
   1650         return JBIG2_ERROR_FETAL;
   1651     }
   1652     m_pStream->alignByte();
   1653     return JBIG2_SUCCESS;
   1654 }
   1655 FX_INT32 CJBig2_Context::parseRegionInfo(JBig2RegionInfo *pRI)
   1656 {
   1657     if((m_pStream->readInteger((FX_DWORD*)&pRI->width) != 0)
   1658             || (m_pStream->readInteger((FX_DWORD*)&pRI->height) != 0)
   1659             || (m_pStream->readInteger((FX_DWORD*)&pRI->x) != 0)
   1660             || (m_pStream->readInteger((FX_DWORD*)&pRI->y) != 0)
   1661             || (m_pStream->read1Byte(&pRI->flags) != 0)) {
   1662         return JBIG2_ERROR_TOO_SHORT;
   1663     }
   1664     return JBIG2_SUCCESS;
   1665 }
   1666 JBig2HuffmanCode *CJBig2_Context::decodeSymbolIDHuffmanTable(CJBig2_BitStream *pStream,
   1667         FX_DWORD SBNUMSYMS)
   1668 {
   1669     JBig2HuffmanCode *SBSYMCODES;
   1670     FX_INT32 runcodes[35], runcodes_len[35], runcode;
   1671     FX_INT32 i, j, nTemp, nVal, nBits;
   1672     FX_INT32 run;
   1673     SBSYMCODES = (JBig2HuffmanCode*)m_pModule->JBig2_Malloc2(sizeof(JBig2HuffmanCode), SBNUMSYMS);
   1674     for (i = 0; i < 35; i ++) {
   1675         if(pStream->readNBits(4, &runcodes_len[i]) != 0) {
   1676             goto failed;
   1677         }
   1678     }
   1679     huffman_assign_code(runcodes, runcodes_len, 35);
   1680     i = 0;
   1681     while(i < (int)SBNUMSYMS) {
   1682         nVal = 0;
   1683         nBits = 0;
   1684         for(;;) {
   1685             if(pStream->read1Bit(&nTemp) != 0) {
   1686                 goto failed;
   1687             }
   1688             nVal = (nVal << 1) | nTemp;
   1689             nBits ++;
   1690             for(j = 0; j < 35; j++) {
   1691                 if((nBits == runcodes_len[j]) && (nVal == runcodes[j])) {
   1692                     break;
   1693                 }
   1694             }
   1695             if(j < 35) {
   1696                 break;
   1697             }
   1698         }
   1699         runcode = j;
   1700         if(runcode < 32) {
   1701             SBSYMCODES[i].codelen = runcode;
   1702             run = 0;
   1703         } else if(runcode == 32) {
   1704             if(pStream->readNBits(2, &nTemp) != 0) {
   1705                 goto failed;
   1706             }
   1707             run = nTemp + 3;
   1708         } else if(runcode == 33) {
   1709             if(pStream->readNBits(3, &nTemp) != 0) {
   1710                 goto failed;
   1711             }
   1712             run = nTemp + 3;
   1713         } else if(runcode == 34) {
   1714             if(pStream->readNBits(7, &nTemp) != 0) {
   1715                 goto failed;
   1716             }
   1717             run = nTemp + 11;
   1718         }
   1719         if(run > 0) {
   1720             if (i + run > (int)SBNUMSYMS) {
   1721                 goto failed;
   1722             }
   1723             for(j = 0; j < run; j++) {
   1724                 if(runcode == 32 && i > 0) {
   1725                     SBSYMCODES[i + j].codelen = SBSYMCODES[i - 1].codelen;
   1726                 } else {
   1727                     SBSYMCODES[i + j].codelen = 0;
   1728                 }
   1729             }
   1730             i += run;
   1731         } else {
   1732             i ++;
   1733         }
   1734     }
   1735     huffman_assign_code(SBSYMCODES, SBNUMSYMS);
   1736     return SBSYMCODES;
   1737 failed:
   1738     m_pModule->JBig2_Free(SBSYMCODES);
   1739     return NULL;
   1740 }
   1741 void CJBig2_Context::huffman_assign_code(int* CODES, int* PREFLEN, int NTEMP)
   1742 {
   1743     int CURLEN, LENMAX, CURCODE, CURTEMP, i;
   1744     int *LENCOUNT;
   1745     int *FIRSTCODE;
   1746     LENMAX = 0;
   1747     for(i = 0; i < NTEMP; i++) {
   1748         if(PREFLEN[i] > LENMAX) {
   1749             LENMAX = PREFLEN[i];
   1750         }
   1751     }
   1752     LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
   1753     JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
   1754     FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
   1755     for(i = 0; i < NTEMP; i++) {
   1756         LENCOUNT[PREFLEN[i]] ++;
   1757     }
   1758     CURLEN = 1;
   1759     FIRSTCODE[0] = 0;
   1760     LENCOUNT[0]  = 0;
   1761     while(CURLEN <= LENMAX) {
   1762         FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
   1763         CURCODE = FIRSTCODE[CURLEN];
   1764         CURTEMP = 0;
   1765         while(CURTEMP < NTEMP) {
   1766             if(PREFLEN[CURTEMP] == CURLEN) {
   1767                 CODES[CURTEMP] = CURCODE;
   1768                 CURCODE = CURCODE + 1;
   1769             }
   1770             CURTEMP = CURTEMP + 1;
   1771         }
   1772         CURLEN = CURLEN + 1;
   1773     }
   1774     m_pModule->JBig2_Free(LENCOUNT);
   1775     m_pModule->JBig2_Free(FIRSTCODE);
   1776 }
   1777 void CJBig2_Context::huffman_assign_code(JBig2HuffmanCode *SBSYMCODES, int NTEMP)
   1778 {
   1779     int CURLEN, LENMAX, CURCODE, CURTEMP, i;
   1780     int *LENCOUNT;
   1781     int *FIRSTCODE;
   1782     LENMAX = 0;
   1783     for(i = 0; i < NTEMP; i++) {
   1784         if(SBSYMCODES[i].codelen > LENMAX) {
   1785             LENMAX = SBSYMCODES[i].codelen;
   1786         }
   1787     }
   1788     LENCOUNT = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
   1789     JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1));
   1790     FIRSTCODE = (int*)m_pModule->JBig2_Malloc2(sizeof(int), (LENMAX + 1));
   1791     for(i = 0; i < NTEMP; i++) {
   1792         LENCOUNT[SBSYMCODES[i].codelen] ++;
   1793     }
   1794     CURLEN = 1;
   1795     FIRSTCODE[0] = 0;
   1796     LENCOUNT[0]  = 0;
   1797     while(CURLEN <= LENMAX) {
   1798         FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1;
   1799         CURCODE = FIRSTCODE[CURLEN];
   1800         CURTEMP = 0;
   1801         while(CURTEMP < NTEMP) {
   1802             if(SBSYMCODES[CURTEMP].codelen == CURLEN) {
   1803                 SBSYMCODES[CURTEMP].code = CURCODE;
   1804                 CURCODE = CURCODE + 1;
   1805             }
   1806             CURTEMP = CURTEMP + 1;
   1807         }
   1808         CURLEN = CURLEN + 1;
   1809     }
   1810     m_pModule->JBig2_Free(LENCOUNT);
   1811     m_pModule->JBig2_Free(FIRSTCODE);
   1812 }
   1813