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