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