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