Convert all line endings to LF.
[pdfium.git] / core / src / fxcodec / jbig2 / JBig2_Context.cpp
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 }