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