Chromium Code Reviews| Index: core/src/fxcodec/jbig2/JBig2_Context.cpp |
| diff --git a/core/src/fxcodec/jbig2/JBig2_Context.cpp b/core/src/fxcodec/jbig2/JBig2_Context.cpp |
| index e8d4bb8cc81e118d74c015a167e79a9b8b008150..fe480932bd62984b231333b4752faf0b9ba58134 100644 |
| --- a/core/src/fxcodec/jbig2/JBig2_Context.cpp |
| +++ b/core/src/fxcodec/jbig2/JBig2_Context.cpp |
| @@ -34,35 +34,26 @@ size_t GetRefAggContextSize(FX_BOOL val) { |
| // list keeps track of the freshness of entries, with freshest ones |
| // at the front. Even a tiny cache size like 2 makes a dramatic |
| // difference for typical JBIG2 documents. |
| -// |
| -// Disabled until we can figure out how to clear cache between documents. |
| -// https://code.google.com/p/pdfium/issues/detail?id=207 |
| -#define DISABLE_SYMBOL_CACHE |
| -#ifndef DISABLE_SYMBOL_CACHE |
| static const int kSymbolDictCacheMaxSize = 2; |
| -#endif |
| CJBig2_Context* CJBig2_Context::CreateContext( |
| - const uint8_t* pGlobalData, |
| - FX_DWORD dwGlobalLength, |
| - const uint8_t* pData, |
| - FX_DWORD dwLength, |
| + CPDF_StreamAcc* pGlobalStream, |
| + CPDF_StreamAcc* pSrcStream, |
| std::list<CJBig2_CachePair>* pSymbolDictCache, |
| IFX_Pause* pPause) { |
| - return new CJBig2_Context(pGlobalData, dwGlobalLength, pData, dwLength, |
| - pSymbolDictCache, pPause); |
| + return new CJBig2_Context(pGlobalStream, pSrcStream, pSymbolDictCache, pPause, |
| + false); |
| } |
| void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) { |
| delete pContext; |
| } |
| -CJBig2_Context::CJBig2_Context(const uint8_t* pGlobalData, |
| - FX_DWORD dwGlobalLength, |
| - const uint8_t* pData, |
| - FX_DWORD dwLength, |
| +CJBig2_Context::CJBig2_Context(CPDF_StreamAcc* pGlobalStream, |
| + CPDF_StreamAcc* pSrcStream, |
| std::list<CJBig2_CachePair>* pSymbolDictCache, |
| - IFX_Pause* pPause) |
| + IFX_Pause* pPause, |
| + bool bIsGlobal) |
| : m_nSegmentDecoded(0), |
| m_bInPage(false), |
| m_bBufSpecified(false), |
| @@ -71,15 +62,16 @@ CJBig2_Context::CJBig2_Context(const uint8_t* pGlobalData, |
| m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY), |
| m_gbContext(NULL), |
| m_dwOffset(0), |
| - m_pSymbolDictCache(pSymbolDictCache) { |
| - if (pGlobalData && (dwGlobalLength > 0)) { |
| - m_pGlobalContext = new CJBig2_Context( |
| - nullptr, 0, pGlobalData, dwGlobalLength, pSymbolDictCache, pPause); |
| + m_pSymbolDictCache(pSymbolDictCache), |
| + m_bIsGlobal(bIsGlobal) { |
| + if (pGlobalStream && (pGlobalStream->GetSize() > 0)) { |
| + m_pGlobalContext = |
| + 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.
|
| } else { |
| m_pGlobalContext = nullptr; |
| } |
| - m_pStream.reset(new CJBig2_BitStream(pData, dwLength)); |
| + m_pStream.reset(new CJBig2_BitStream(pSrcStream)); |
| } |
| CJBig2_Context::~CJBig2_Context() { |
| @@ -330,7 +322,8 @@ int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { |
| if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0) |
| return JBIG2_ERROR_TOO_SHORT; |
| - pSegment->m_pData = m_pStream->getPointer(); |
| + pSegment->m_dwObjNum = m_pStream->getObjNum(); |
| + pSegment->m_dwDataOffset = m_pStream->getOffset(); |
| pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; |
| return JBIG2_SUCCESS; |
| } |
| @@ -600,18 +593,21 @@ int32_t CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, |
| JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
| } |
| } |
| - const uint8_t* key = pSegment->m_pData; |
| + CJBig2_CacheKey key = |
| + CJBig2_CacheKey(pSegment->m_dwObjNum, pSegment->m_dwDataOffset); |
| FX_BOOL cache_hit = false; |
| pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; |
| - for (std::list<CJBig2_CachePair>::iterator it = m_pSymbolDictCache->begin(); |
| - it != m_pSymbolDictCache->end(); ++it) { |
| - if (it->first == key) { |
| - nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); |
| - pSegment->m_Result.sd = copy.release(); |
| - m_pSymbolDictCache->push_front(*it); |
| - m_pSymbolDictCache->erase(it); |
| - cache_hit = true; |
| - break; |
| + if (m_bIsGlobal) { |
| + for (auto it = m_pSymbolDictCache->begin(); it != m_pSymbolDictCache->end(); |
| + ++it) { |
| + if (it->first == key) { |
| + nonstd::unique_ptr<CJBig2_SymbolDict> copy(it->second->DeepCopy()); |
| + pSegment->m_Result.sd = copy.release(); |
| + m_pSymbolDictCache->push_front(*it); |
| + m_pSymbolDictCache->erase(it); |
| + cache_hit = true; |
| + break; |
| + } |
| } |
| } |
| if (!cache_hit) { |
| @@ -632,17 +628,17 @@ int32_t CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, |
| return JBIG2_ERROR_FATAL; |
| m_pStream->alignByte(); |
| } |
| -#ifndef DISABLE_SYMBOL_CACHE |
| - nonstd::unique_ptr<CJBig2_SymbolDict> value = |
| - pSegment->m_Result.sd->DeepCopy(); |
| - if (value && kSymbolDictCacheMaxSize > 0) { |
| - while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { |
| - delete m_pSymbolDictCache->back().second; |
| - m_pSymbolDictCache->pop_back(); |
| + if (m_bIsGlobal && kSymbolDictCacheMaxSize > 0) { |
| + nonstd::unique_ptr<CJBig2_SymbolDict> value = |
| + pSegment->m_Result.sd->DeepCopy(); |
| + if (value) { |
| + while (m_pSymbolDictCache->size() >= kSymbolDictCacheMaxSize) { |
| + delete m_pSymbolDictCache->back().second; |
| + m_pSymbolDictCache->pop_back(); |
| + } |
| + m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release())); |
| } |
| - m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release())); |
| } |
| -#endif |
| } |
| if (wFlags & 0x0200) { |
| pSegment->m_Result.sd->m_bContextRetained = TRUE; |