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 |