Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: core/src/fxcodec/jbig2/JBig2_Context.cpp

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

Powered by Google App Engine
This is Rietveld 408576698