Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: core/src/fxcodec/jbig2/JBig2_Context.cpp

Issue 1380243004: Various changes to JBig2 cache: (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 16 matching lines...) Expand all
27 27
28 } // namespace 28 } // namespace
29 29
30 // Implement a very small least recently used (LRU) cache. It is very 30 // Implement a very small least recently used (LRU) cache. It is very
31 // common for a JBIG2 dictionary to span multiple pages in a PDF file, 31 // common for a JBIG2 dictionary to span multiple pages in a PDF file,
32 // and we do not want to decode the same dictionary over and over 32 // and we do not want to decode the same dictionary over and over
33 // again. We key off of the memory location of the dictionary. The 33 // again. We key off of the memory location of the dictionary. The
34 // list keeps track of the freshness of entries, with freshest ones 34 // list keeps track of the freshness of entries, with freshest ones
35 // at the front. Even a tiny cache size like 2 makes a dramatic 35 // at the front. Even a tiny cache size like 2 makes a dramatic
36 // difference for typical JBIG2 documents. 36 // difference for typical JBIG2 documents.
37 //
38 // Disabled until we can figure out how to clear cache between documents.
39 // https://code.google.com/p/pdfium/issues/detail?id=207
40 #define DISABLE_SYMBOL_CACHE
41 #ifndef DISABLE_SYMBOL_CACHE
42 static const int kSymbolDictCacheMaxSize = 2; 37 static const int kSymbolDictCacheMaxSize = 2;
43 #endif
44 38
45 CJBig2_Context* CJBig2_Context::CreateContext( 39 CJBig2_Context* CJBig2_Context::CreateContext(
46 const uint8_t* pGlobalData, 40 CPDF_StreamAcc* pGlobalStream,
47 FX_DWORD dwGlobalLength, 41 CPDF_StreamAcc* pSrcStream,
48 const uint8_t* pData,
49 FX_DWORD dwLength,
50 std::list<CJBig2_CachePair>* pSymbolDictCache, 42 std::list<CJBig2_CachePair>* pSymbolDictCache,
51 IFX_Pause* pPause) { 43 IFX_Pause* pPause) {
52 return new CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength, 44 return new CJBig2_Context(pGlobalStream, pSrcStream, pSymbolDictCache, pPause,
53 pSymbolDictCache, pPause); 45 false);
54 } 46 }
55 47
56 void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) { 48 void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) {
57 delete pContext; 49 delete pContext;
58 } 50 }
59 51
60 CJBig2_Context::CJBig2_Context(const uint8_t* pGlobalData, 52 CJBig2_Context::CJBig2_Context(CPDF_StreamAcc* pGlobalStream,
61 FX_DWORD dwGlobalLength, 53 CPDF_StreamAcc* pSrcStream,
62 const uint8_t* pData,
63 FX_DWORD dwLength,
64 std::list<CJBig2_CachePair>* pSymbolDictCache, 54 std::list<CJBig2_CachePair>* pSymbolDictCache,
65 IFX_Pause* pPause) 55 IFX_Pause* pPause,
56 bool bIsGlobal)
66 : m_nSegmentDecoded(0), 57 : m_nSegmentDecoded(0),
67 m_bInPage(false), 58 m_bInPage(false),
68 m_bBufSpecified(false), 59 m_bBufSpecified(false),
69 m_PauseStep(10), 60 m_PauseStep(10),
70 m_pPause(pPause), 61 m_pPause(pPause),
71 m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY), 62 m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY),
72 m_gbContext(NULL), 63 m_gbContext(NULL),
73 m_dwOffset(0), 64 m_dwOffset(0),
74 m_pSymbolDictCache(pSymbolDictCache) { 65 m_pSymbolDictCache(pSymbolDictCache),
75 if (pGlobalData && (dwGlobalLength > 0)) { 66 m_bIsGlobal(bIsGlobal) {
76 m_pGlobalContext = new CJBig2_Context( 67 if (pGlobalStream && (pGlobalStream->GetSize() > 0)) {
77 nullptr, 0, pGlobalData, dwGlobalLength, pSymbolDictCache, pPause); 68 m_pGlobalContext =
69 new CJBig2_Context(NULL, pGlobalStream, pSymbolDictCache, pPause, true);
Lei Zhang 2015/10/08 03:22:44 nit: nullptr
David Lattimore 2015/10/08 03:44:39 Done.
78 } else { 70 } else {
79 m_pGlobalContext = nullptr; 71 m_pGlobalContext = nullptr;
80 } 72 }
81 73
82 m_pStream.reset(new CJBig2_BitStream(pData, dwLength)); 74 m_pStream.reset(new CJBig2_BitStream(pSrcStream));
83 } 75 }
84 76
85 CJBig2_Context::~CJBig2_Context() { 77 CJBig2_Context::~CJBig2_Context() {
86 FX_Free(m_gbContext); 78 FX_Free(m_gbContext);
87 m_gbContext = NULL; 79 m_gbContext = NULL;
88 delete m_pGlobalContext; 80 delete m_pGlobalContext;
89 m_pGlobalContext = NULL; 81 m_pGlobalContext = NULL;
90 } 82 }
91 83
92 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { 84 int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) {
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 return JBIG2_ERROR_TOO_SHORT; 315 return JBIG2_ERROR_TOO_SHORT;
324 pSegment->m_dwPage_association = cTemp; 316 pSegment->m_dwPage_association = cTemp;
325 } else { 317 } else {
326 if (m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) { 318 if (m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) {
327 return JBIG2_ERROR_TOO_SHORT; 319 return JBIG2_ERROR_TOO_SHORT;
328 } 320 }
329 } 321 }
330 if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0) 322 if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0)
331 return JBIG2_ERROR_TOO_SHORT; 323 return JBIG2_ERROR_TOO_SHORT;
332 324
333 pSegment->m_pData = m_pStream->getPointer(); 325 pSegment->m_dwObjNum = m_pStream->getObjNum();
326 pSegment->m_dwDataOffset = m_pStream->getOffset();
334 pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; 327 pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED;
335 return JBIG2_SUCCESS; 328 return JBIG2_SUCCESS;
336 } 329 }
337 330
338 int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, 331 int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment,
339 IFX_Pause* pPause) { 332 IFX_Pause* pPause) {
340 int32_t ret = ProcessingParseSegmentData(pSegment, pPause); 333 int32_t ret = ProcessingParseSegmentData(pSegment, pPause);
341 while (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE && 334 while (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE &&
342 m_pStream->getByteLeft() > 0) { 335 m_pStream->getByteLeft() > 0) {
343 ret = ProcessingParseSegmentData(pSegment, pPause); 336 ret = ProcessingParseSegmentData(pSegment, pPause);
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 const size_t size = GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE); 586 const size_t size = GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE);
594 gbContext.reset(FX_Alloc(JBig2ArithCtx, size)); 587 gbContext.reset(FX_Alloc(JBig2ArithCtx, size));
595 JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); 588 JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size);
596 } 589 }
597 if (pSymbolDictDecoder->SDREFAGG == 1) { 590 if (pSymbolDictDecoder->SDREFAGG == 1) {
598 const size_t size = GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE); 591 const size_t size = GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE);
599 grContext.reset(FX_Alloc(JBig2ArithCtx, size)); 592 grContext.reset(FX_Alloc(JBig2ArithCtx, size));
600 JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); 593 JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size);
601 } 594 }
602 } 595 }
603 const uint8_t* key = pSegment->m_pData; 596 CJBig2_CacheKey key =
597 CJBig2_CacheKey(pSegment->m_dwObjNum, pSegment->m_dwDataOffset);
604 FX_BOOL cache_hit = false; 598 FX_BOOL cache_hit = false;
605 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; 599 pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER;
606 for (std::list<CJBig2_CachePair>::iterator it = m_pSymbolDictCache->begin(); 600 if (m_bIsGlobal) {
607 it != m_pSymbolDictCache->end(); ++it) { 601 for (auto it = m_pSymbolDictCache->begin(); it != m_pSymbolDictCache->end();
608 if (it->first == key) { 602 ++it) {
609 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); 603 if (it->first == key) {
610 pSegment->m_Result.sd = copy.release(); 604 nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy());
611 m_pSymbolDictCache->push_front(*it); 605 pSegment->m_Result.sd = copy.release();
612 m_pSymbolDictCache->erase(it); 606 m_pSymbolDictCache->push_front(*it);
613 cache_hit = true; 607 m_pSymbolDictCache->erase(it);
614 break; 608 cache_hit = true;
609 break;
610 }
615 } 611 }
616 } 612 }
617 if (!cache_hit) { 613 if (!cache_hit) {
618 if (pSymbolDictDecoder->SDHUFF == 0) { 614 if (pSymbolDictDecoder->SDHUFF == 0) {
619 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( 615 nonstd::unique_ptr<CJBig2_ArithDecoder> pArithDecoder(
620 new CJBig2_ArithDecoder(m_pStream.get())); 616 new CJBig2_ArithDecoder(m_pStream.get()));
621 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith( 617 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith(
622 pArithDecoder.get(), gbContext.get(), grContext.get()); 618 pArithDecoder.get(), gbContext.get(), grContext.get());
623 if (!pSegment->m_Result.sd) 619 if (!pSegment->m_Result.sd)
624 return JBIG2_ERROR_FATAL; 620 return JBIG2_ERROR_FATAL;
625 621
626 m_pStream->alignByte(); 622 m_pStream->alignByte();
627 m_pStream->offset(2); 623 m_pStream->offset(2);
628 } else { 624 } else {
629 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( 625 pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman(
630 m_pStream.get(), gbContext.get(), grContext.get(), pPause); 626 m_pStream.get(), gbContext.get(), grContext.get(), pPause);
631 if (!pSegment->m_Result.sd) 627 if (!pSegment->m_Result.sd)
632 return JBIG2_ERROR_FATAL; 628 return JBIG2_ERROR_FATAL;
633 m_pStream->alignByte(); 629 m_pStream->alignByte();
634 } 630 }
635 #ifndef DISABLE_SYMBOL_CACHE 631 if (m_bIsGlobal && kSymbolDictCacheMaxSize > 0) {
636 nonstd::unique_ptr<CJBig2_SymbolDict> value = 632 nonstd::unique_ptr<CJBig2_SymbolDict> value =
637 pSegment->m_Result.sd->DeepCopy(); 633 pSegment->m_Result.sd->DeepCopy();
638 if (value && kSymbolDictCacheMaxSize > 0) { 634 if (value) {
639 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { 635 while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) {
640 delete m_pSymbolDictCache->back().second; 636 delete m_pSymbolDictCache->back().second;
641 m_pSymbolDictCache->pop_back(); 637 m_pSymbolDictCache->pop_back();
638 }
639 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release()));
642 } 640 }
643 m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release()));
644 } 641 }
645 #endif
646 } 642 }
647 if (wFlags & 0x0200) { 643 if (wFlags & 0x0200) {
648 pSegment->m_Result.sd->m_bContextRetained = TRUE; 644 pSegment->m_Result.sd->m_bContextRetained = TRUE;
649 if (pSymbolDictDecoder->SDHUFF == 0) { 645 if (pSymbolDictDecoder->SDHUFF == 0) {
650 pSegment->m_Result.sd->m_gbContext = gbContext.release(); 646 pSegment->m_Result.sd->m_gbContext = gbContext.release();
651 } 647 }
652 if (pSymbolDictDecoder->SDREFAGG == 1) { 648 if (pSymbolDictDecoder->SDREFAGG == 1) {
653 pSegment->m_Result.sd->m_grContext = grContext.release(); 649 pSegment->m_Result.sd->m_grContext = grContext.release();
654 } 650 }
655 } 651 }
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 SBSYMCODES[CURTEMP].code = CURCODE; 1423 SBSYMCODES[CURTEMP].code = CURCODE;
1428 CURCODE = CURCODE + 1; 1424 CURCODE = CURCODE + 1;
1429 } 1425 }
1430 CURTEMP = CURTEMP + 1; 1426 CURTEMP = CURTEMP + 1;
1431 } 1427 }
1432 CURLEN = CURLEN + 1; 1428 CURLEN = CURLEN + 1;
1433 } 1429 }
1434 FX_Free(LENCOUNT); 1430 FX_Free(LENCOUNT);
1435 FX_Free(FIRSTCODE); 1431 FX_Free(FIRSTCODE);
1436 } 1432 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698