| 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 "JBig2_Context.h" | 7 #include "JBig2_Context.h" |
| 8 | 8 |
| 9 #include <list> | 9 #include <list> |
| 10 | 10 |
| 11 #include "JBig2_GrdProc.h" | 11 #include "JBig2_GrdProc.h" |
| 12 #include "JBig2_GrrdProc.h" | 12 #include "JBig2_GrrdProc.h" |
| 13 #include "JBig2_HtrdProc.h" | 13 #include "JBig2_HtrdProc.h" |
| 14 #include "JBig2_PddProc.h" | 14 #include "JBig2_PddProc.h" |
| 15 #include "JBig2_SddProc.h" | 15 #include "JBig2_SddProc.h" |
| 16 #include "JBig2_TrdProc.h" | 16 #include "JBig2_TrdProc.h" |
| 17 | 17 |
| 18 // Implement a very small least recently used (LRU) cache. It is very | 18 // Implement a very small least recently used (LRU) cache. It is very |
| 19 // common for a JBIG2 dictionary to span multiple pages in a PDF file, | 19 // common for a JBIG2 dictionary to span multiple pages in a PDF file, |
| 20 // and we do not want to decode the same dictionary over and over | 20 // and we do not want to decode the same dictionary over and over |
| 21 // again. We key off of the memory location of the dictionary. The | 21 // again. We key off of the memory location of the dictionary. The |
| 22 // list keeps track of the freshness of entries, with freshest ones | 22 // list keeps track of the freshness of entries, with freshest ones |
| 23 // at the front. Even a tiny cache size like 2 makes a dramatic | 23 // at the front. Even a tiny cache size like 2 makes a dramatic |
| 24 // difference for typical JBIG2 documents. | 24 // difference for typical JBIG2 documents. |
| 25 // | 25 // |
| 26 // Disabled until we can figure out how to clear cache between documents. | 26 // Disabled until we can figure out how to clear cache between documents. |
| 27 // https://code.google.com/p/pdfium/issues/detail?id=207 | 27 // https://code.google.com/p/pdfium/issues/detail?id=207 |
| 28 #define DISABLE_SYMBOL_CACHE |
| 29 #ifndef DISABLE_SYMBOL_CACHE |
| 28 static const int kSymbolDictCacheMaxSize = 2; | 30 static const int kSymbolDictCacheMaxSize = 2; |
| 31 #endif |
| 29 | 32 |
| 30 CJBig2_Context* CJBig2_Context::CreateContext( | 33 CJBig2_Context* CJBig2_Context::CreateContext( |
| 31 const uint8_t* pGlobalData, | 34 const uint8_t* pGlobalData, |
| 32 FX_DWORD dwGlobalLength, | 35 FX_DWORD dwGlobalLength, |
| 33 const uint8_t* pData, | 36 const uint8_t* pData, |
| 34 FX_DWORD dwLength, | 37 FX_DWORD dwLength, |
| 35 std::list<CJBig2_CachePair>* pSymbolDictCache, | 38 std::list<CJBig2_CachePair>* pSymbolDictCache, |
| 36 IFX_Pause* pPause) { | 39 IFX_Pause* pPause) { |
| 37 return new CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength, | 40 return new CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength, |
| 38 pSymbolDictCache, pPause); | 41 pSymbolDictCache, pPause); |
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 if (pSymbolDictDecoder->SDREFAGG == 1) { | 619 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 617 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; | 620 dwTemp = pSymbolDictDecoder->SDRTEMPLATE ? 1 << 10 : 1 << 13; |
| 618 grContext = FX_Alloc(JBig2ArithCtx, dwTemp); | 621 grContext = FX_Alloc(JBig2ArithCtx, dwTemp); |
| 619 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); | 622 JBIG2_memset(grContext, 0, sizeof(JBig2ArithCtx) * dwTemp); |
| 620 } | 623 } |
| 621 } | 624 } |
| 622 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; | 625 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; |
| 623 for (std::list<CJBig2_CachePair>::iterator it = m_pSymbolDictCache->begin(); | 626 for (std::list<CJBig2_CachePair>::iterator it = m_pSymbolDictCache->begin(); |
| 624 it != m_pSymbolDictCache->end(); ++it) { | 627 it != m_pSymbolDictCache->end(); ++it) { |
| 625 if (it->first == key) { | 628 if (it->first == key) { |
| 626 pSegment->m_Result.sd = it->second->DeepCopy(); | 629 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); |
| 630 pSegment->m_Result.sd = copy.release(); |
| 627 m_pSymbolDictCache->push_front(*it); | 631 m_pSymbolDictCache->push_front(*it); |
| 628 m_pSymbolDictCache->erase(it); | 632 m_pSymbolDictCache->erase(it); |
| 629 cache_hit = true; | 633 cache_hit = true; |
| 630 break; | 634 break; |
| 631 } | 635 } |
| 632 } | 636 } |
| 633 if (!cache_hit) { | 637 if (!cache_hit) { |
| 634 if (pSymbolDictDecoder->SDHUFF == 0) { | 638 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 635 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); | 639 pArithDecoder = new CJBig2_ArithDecoder(m_pStream.get()); |
| 636 pSegment->m_Result.sd = | 640 pSegment->m_Result.sd = |
| 637 pSymbolDictDecoder->decode_Arith(pArithDecoder, gbContext, grContext); | 641 pSymbolDictDecoder->decode_Arith(pArithDecoder, gbContext, grContext); |
| 638 delete pArithDecoder; | 642 delete pArithDecoder; |
| 639 if (pSegment->m_Result.sd == NULL) { | 643 if (pSegment->m_Result.sd == NULL) { |
| 640 nRet = JBIG2_ERROR_FATAL; | 644 nRet = JBIG2_ERROR_FATAL; |
| 641 goto failed; | 645 goto failed; |
| 642 } | 646 } |
| 643 m_pStream->alignByte(); | 647 m_pStream->alignByte(); |
| 644 m_pStream->offset(2); | 648 m_pStream->offset(2); |
| 645 } else { | 649 } else { |
| 646 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( | 650 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( |
| 647 m_pStream.get(), gbContext, grContext, pPause); | 651 m_pStream.get(), gbContext, grContext, pPause); |
| 648 if (pSegment->m_Result.sd == NULL) { | 652 if (pSegment->m_Result.sd == NULL) { |
| 649 nRet = JBIG2_ERROR_FATAL; | 653 nRet = JBIG2_ERROR_FATAL; |
| 650 goto failed; | 654 goto failed; |
| 651 } | 655 } |
| 652 m_pStream->alignByte(); | 656 m_pStream->alignByte(); |
| 653 } | 657 } |
| 654 CJBig2_SymbolDict* value = pSegment->m_Result.sd->DeepCopy(); | 658 #ifndef DISABLE_SYMBOL_CACHE |
| 659 nonstd::unique_ptr<CJBig2_SymbolDict> value = |
| 660 pSegment->m_Result.sd->DeepCopy(); |
| 655 if (value && kSymbolDictCacheMaxSize > 0) { | 661 if (value && kSymbolDictCacheMaxSize > 0) { |
| 656 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { | 662 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { |
| 657 delete m_pSymbolDictCache->back().second; | 663 delete m_pSymbolDictCache->back().second; |
| 658 m_pSymbolDictCache->pop_back(); | 664 m_pSymbolDictCache->pop_back(); |
| 659 } | 665 } |
| 660 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value)); | 666 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release())); |
| 661 } | 667 } |
| 668 #endif |
| 662 } | 669 } |
| 663 if (wFlags & 0x0200) { | 670 if (wFlags & 0x0200) { |
| 664 pSegment->m_Result.sd->m_bContextRetained = TRUE; | 671 pSegment->m_Result.sd->m_bContextRetained = TRUE; |
| 665 if (pSymbolDictDecoder->SDHUFF == 0) { | 672 if (pSymbolDictDecoder->SDHUFF == 0) { |
| 666 pSegment->m_Result.sd->m_gbContext = gbContext; | 673 pSegment->m_Result.sd->m_gbContext = gbContext; |
| 667 } | 674 } |
| 668 if (pSymbolDictDecoder->SDREFAGG == 1) { | 675 if (pSymbolDictDecoder->SDREFAGG == 1) { |
| 669 pSegment->m_Result.sd->m_grContext = grContext; | 676 pSegment->m_Result.sd->m_grContext = grContext; |
| 670 } | 677 } |
| 671 bUsed = TRUE; | 678 bUsed = TRUE; |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 SBSYMCODES[CURTEMP].code = CURCODE; | 1579 SBSYMCODES[CURTEMP].code = CURCODE; |
| 1573 CURCODE = CURCODE + 1; | 1580 CURCODE = CURCODE + 1; |
| 1574 } | 1581 } |
| 1575 CURTEMP = CURTEMP + 1; | 1582 CURTEMP = CURTEMP + 1; |
| 1576 } | 1583 } |
| 1577 CURLEN = CURLEN + 1; | 1584 CURLEN = CURLEN + 1; |
| 1578 } | 1585 } |
| 1579 FX_Free(LENCOUNT); | 1586 FX_Free(LENCOUNT); |
| 1580 FX_Free(FIRSTCODE); | 1587 FX_Free(FIRSTCODE); |
| 1581 } | 1588 } |
| OLD | NEW |