| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include "JBig2_Context.h" | 8 #include "JBig2_Context.h" |
| 9 | 9 |
| 10 // Implement a very small least recently used (LRU) cache. It is very | 10 // Implement a very small least recently used (LRU) cache. It is very |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 m_gbContext = NULL; | 68 m_gbContext = NULL; |
| 69 delete m_pGlobalContext; | 69 delete m_pGlobalContext; |
| 70 m_pGlobalContext = NULL; | 70 m_pGlobalContext = NULL; |
| 71 if (m_bBufSpecified) { | 71 if (m_bBufSpecified) { |
| 72 delete m_pPage; | 72 delete m_pPage; |
| 73 } | 73 } |
| 74 m_pPage = NULL; | 74 m_pPage = NULL; |
| 75 delete m_pStream; | 75 delete m_pStream; |
| 76 m_pStream = NULL; | 76 m_pStream = NULL; |
| 77 } | 77 } |
| 78 |
| 78 int32_t CJBig2_Context::decodeFile(IFX_Pause* pPause) { | 79 int32_t CJBig2_Context::decodeFile(IFX_Pause* pPause) { |
| 80 if (m_pStream->getByteLeft() < 8) |
| 81 return JBIG2_ERROR_TOO_SHORT; |
| 82 |
| 83 const uint8_t fileID[] = {0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A}; |
| 84 if (JBIG2_memcmp(m_pStream->getPointer(), fileID, 8) != 0) |
| 85 return JBIG2_ERROR_FILE_FORMAT; |
| 86 |
| 87 m_pStream->offset(8); |
| 88 |
| 79 uint8_t cFlags; | 89 uint8_t cFlags; |
| 80 FX_DWORD dwTemp; | 90 if (m_pStream->read1Byte(&cFlags) != 0) |
| 81 const uint8_t fileID[] = {0x97, 0x4A, 0x42, 0x32, 0x0D, 0x0A, 0x1A, 0x0A}; | 91 return JBIG2_ERROR_TOO_SHORT; |
| 82 int32_t nRet; | 92 |
| 83 if (m_pStream->getByteLeft() < 8) { | |
| 84 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 85 goto failed; | |
| 86 } | |
| 87 if (JBIG2_memcmp(m_pStream->getPointer(), fileID, 8) != 0) { | |
| 88 nRet = JBIG2_ERROR_FILE_FORMAT; | |
| 89 goto failed; | |
| 90 } | |
| 91 m_pStream->offset(8); | |
| 92 if (m_pStream->read1Byte(&cFlags) != 0) { | |
| 93 nRet = JBIG2_ERROR_TOO_SHORT; | |
| 94 goto failed; | |
| 95 } | |
| 96 if (!(cFlags & 0x02)) { | 93 if (!(cFlags & 0x02)) { |
| 97 if (m_pStream->readInteger(&dwTemp) != 0) { | 94 FX_DWORD dwTemp; |
| 98 nRet = JBIG2_ERROR_TOO_SHORT; | 95 if (m_pStream->readInteger(&dwTemp) != 0) |
| 99 goto failed; | 96 return JBIG2_ERROR_TOO_SHORT; |
| 100 } | 97 |
| 101 if (dwTemp > 0) { | 98 if (dwTemp > 0) { |
| 102 m_PageInfoList.clear(); | 99 m_PageInfoList.clear(); |
| 103 m_PageInfoList.resize(dwTemp); | 100 m_PageInfoList.resize(dwTemp); |
| 104 } | 101 } |
| 105 } | 102 } |
| 103 |
| 106 if (cFlags & 0x01) { | 104 if (cFlags & 0x01) { |
| 107 m_nStreamType = JBIG2_SQUENTIAL_STREAM; | 105 m_nStreamType = JBIG2_SQUENTIAL_STREAM; |
| 108 return decode_SquentialOrgnazation(pPause); | 106 return decode_SquentialOrgnazation(pPause); |
| 109 } else { | |
| 110 m_nStreamType = JBIG2_RANDOM_STREAM; | |
| 111 return decode_RandomOrgnazation_FirstPage(pPause); | |
| 112 } | 107 } |
| 113 failed: | 108 |
| 114 return nRet; | 109 m_nStreamType = JBIG2_RANDOM_STREAM; |
| 110 return decode_RandomOrgnazation_FirstPage(pPause); |
| 115 } | 111 } |
| 112 |
| 116 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { | 113 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { |
| 117 int32_t nRet; | 114 int32_t nRet; |
| 118 if (m_pStream->getByteLeft() <= 0) | 115 if (m_pStream->getByteLeft() <= 0) |
| 119 return JBIG2_END_OF_FILE; | 116 return JBIG2_END_OF_FILE; |
| 120 | 117 |
| 121 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { | 118 while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { |
| 122 if (!m_pSegment) { | 119 if (!m_pSegment) { |
| 123 m_pSegment.reset(new CJBig2_Segment); | 120 m_pSegment.reset(new CJBig2_Segment); |
| 124 nRet = parseSegmentHeader(m_pSegment.get()); | 121 nRet = parseSegmentHeader(m_pSegment.get()); |
| 125 if (nRet != JBIG2_SUCCESS) { | 122 if (nRet != JBIG2_SUCCESS) { |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if (count == nIndex) { | 314 if (count == nIndex) { |
| 318 return pSeg; | 315 return pSeg; |
| 319 } else { | 316 } else { |
| 320 count++; | 317 count++; |
| 321 } | 318 } |
| 322 } | 319 } |
| 323 } | 320 } |
| 324 return NULL; | 321 return NULL; |
| 325 } | 322 } |
| 326 int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { | 323 int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { |
| 327 uint8_t cSSize, cPSize; | |
| 328 uint8_t cTemp; | |
| 329 FX_WORD wTemp; | |
| 330 FX_DWORD dwTemp; | |
| 331 if ((m_pStream->readInteger(&pSegment->m_dwNumber) != 0) || | 324 if ((m_pStream->readInteger(&pSegment->m_dwNumber) != 0) || |
| 332 (m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0)) { | 325 (m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0)) { |
| 333 goto failed; | 326 return JBIG2_ERROR_TOO_SHORT; |
| 334 } | 327 } |
| 335 cTemp = m_pStream->getCurByte(); | 328 |
| 329 FX_DWORD dwTemp; |
| 330 uint8_t cTemp = m_pStream->getCurByte(); |
| 336 if ((cTemp >> 5) == 7) { | 331 if ((cTemp >> 5) == 7) { |
| 337 if (m_pStream->readInteger( | 332 if (m_pStream->readInteger( |
| 338 (FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) { | 333 (FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) { |
| 339 goto failed; | 334 return JBIG2_ERROR_TOO_SHORT; |
| 340 } | 335 } |
| 341 pSegment->m_nReferred_to_segment_count &= 0x1fffffff; | 336 pSegment->m_nReferred_to_segment_count &= 0x1fffffff; |
| 342 if (pSegment->m_nReferred_to_segment_count > | 337 if (pSegment->m_nReferred_to_segment_count > |
| 343 JBIG2_MAX_REFERRED_SEGMENT_COUNT) { | 338 JBIG2_MAX_REFERRED_SEGMENT_COUNT) { |
| 344 return JBIG2_ERROR_LIMIT; | 339 return JBIG2_ERROR_LIMIT; |
| 345 } | 340 } |
| 346 dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; | 341 dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; |
| 347 } else { | 342 } else { |
| 348 if (m_pStream->read1Byte(&cTemp) != 0) { | 343 if (m_pStream->read1Byte(&cTemp) != 0) |
| 349 goto failed; | 344 return JBIG2_ERROR_TOO_SHORT; |
| 350 } | 345 |
| 351 pSegment->m_nReferred_to_segment_count = cTemp >> 5; | 346 pSegment->m_nReferred_to_segment_count = cTemp >> 5; |
| 352 dwTemp = 5 + 1; | 347 dwTemp = 5 + 1; |
| 353 } | 348 } |
| 354 cSSize = | 349 uint8_t cSSize = |
| 355 pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1; | 350 pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1; |
| 356 cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; | 351 uint8_t cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; |
| 357 if (pSegment->m_nReferred_to_segment_count) { | 352 if (pSegment->m_nReferred_to_segment_count) { |
| 358 pSegment->m_pReferred_to_segment_numbers = | 353 pSegment->m_pReferred_to_segment_numbers = |
| 359 FX_Alloc(FX_DWORD, pSegment->m_nReferred_to_segment_count); | 354 FX_Alloc(FX_DWORD, pSegment->m_nReferred_to_segment_count); |
| 360 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { | 355 for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; i++) { |
| 361 switch (cSSize) { | 356 switch (cSSize) { |
| 362 case 1: | 357 case 1: |
| 363 if (m_pStream->read1Byte(&cTemp) != 0) { | 358 if (m_pStream->read1Byte(&cTemp) != 0) |
| 364 goto failed; | 359 return JBIG2_ERROR_TOO_SHORT; |
| 365 } | 360 |
| 366 pSegment->m_pReferred_to_segment_numbers[i] = cTemp; | 361 pSegment->m_pReferred_to_segment_numbers[i] = cTemp; |
| 367 break; | 362 break; |
| 368 case 2: | 363 case 2: |
| 369 if (m_pStream->readShortInteger(&wTemp) != 0) { | 364 FX_WORD wTemp; |
| 370 goto failed; | 365 if (m_pStream->readShortInteger(&wTemp) != 0) |
| 371 } | 366 return JBIG2_ERROR_TOO_SHORT; |
| 367 |
| 372 pSegment->m_pReferred_to_segment_numbers[i] = wTemp; | 368 pSegment->m_pReferred_to_segment_numbers[i] = wTemp; |
| 373 break; | 369 break; |
| 374 case 4: | 370 case 4: |
| 375 if (m_pStream->readInteger(&dwTemp) != 0) { | 371 if (m_pStream->readInteger(&dwTemp) != 0) |
| 376 goto failed; | 372 return JBIG2_ERROR_TOO_SHORT; |
| 377 } | 373 |
| 378 pSegment->m_pReferred_to_segment_numbers[i] = dwTemp; | 374 pSegment->m_pReferred_to_segment_numbers[i] = dwTemp; |
| 379 break; | 375 break; |
| 380 } | 376 } |
| 381 if (pSegment->m_pReferred_to_segment_numbers[i] >= pSegment->m_dwNumber) { | 377 if (pSegment->m_pReferred_to_segment_numbers[i] >= pSegment->m_dwNumber) |
| 382 goto failed; | 378 return JBIG2_ERROR_TOO_SHORT; |
| 383 } | |
| 384 } | 379 } |
| 385 } | 380 } |
| 386 if (cPSize == 1) { | 381 if (cPSize == 1) { |
| 387 if (m_pStream->read1Byte(&cTemp) != 0) { | 382 if (m_pStream->read1Byte(&cTemp) != 0) |
| 388 goto failed; | 383 return JBIG2_ERROR_TOO_SHORT; |
| 389 } | |
| 390 pSegment->m_dwPage_association = cTemp; | 384 pSegment->m_dwPage_association = cTemp; |
| 391 } else { | 385 } else { |
| 392 if (m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) { | 386 if (m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) { |
| 393 goto failed; | 387 return JBIG2_ERROR_TOO_SHORT; |
| 394 } | 388 } |
| 395 } | 389 } |
| 396 if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0) { | 390 if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0) |
| 397 goto failed; | 391 return JBIG2_ERROR_TOO_SHORT; |
| 398 } | 392 |
| 399 pSegment->m_pData = m_pStream->getPointer(); | 393 pSegment->m_pData = m_pStream->getPointer(); |
| 400 pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; | 394 pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; |
| 401 return JBIG2_SUCCESS; | 395 return JBIG2_SUCCESS; |
| 402 failed: | |
| 403 return JBIG2_ERROR_TOO_SHORT; | |
| 404 } | 396 } |
| 405 | 397 |
| 406 int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, | 398 int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, |
| 407 IFX_Pause* pPause) { | 399 IFX_Pause* pPause) { |
| 408 int32_t ret = ProcessiveParseSegmentData(pSegment, pPause); | 400 int32_t ret = ProcessiveParseSegmentData(pSegment, pPause); |
| 409 while (m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE && | 401 while (m_ProcessiveStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE && |
| 410 m_pStream->getByteLeft() > 0) { | 402 m_pStream->getByteLeft() > 0) { |
| 411 ret = ProcessiveParseSegmentData(pSegment, pPause); | 403 ret = ProcessiveParseSegmentData(pSegment, pPause); |
| 412 } | 404 } |
| 413 return ret; | 405 return ret; |
| (...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 SBSYMCODES[CURTEMP].code = CURCODE; | 1626 SBSYMCODES[CURTEMP].code = CURCODE; |
| 1635 CURCODE = CURCODE + 1; | 1627 CURCODE = CURCODE + 1; |
| 1636 } | 1628 } |
| 1637 CURTEMP = CURTEMP + 1; | 1629 CURTEMP = CURTEMP + 1; |
| 1638 } | 1630 } |
| 1639 CURLEN = CURLEN + 1; | 1631 CURLEN = CURLEN + 1; |
| 1640 } | 1632 } |
| 1641 FX_Free(LENCOUNT); | 1633 FX_Free(LENCOUNT); |
| 1642 FX_Free(FIRSTCODE); | 1634 FX_Free(FIRSTCODE); |
| 1643 } | 1635 } |
| OLD | NEW |