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 |
deleted file mode 100644 |
index 9279971b46c21ec9381c107c8b79bfb4c7e75cdf..0000000000000000000000000000000000000000 |
--- a/core/src/fxcodec/jbig2/JBig2_Context.cpp |
+++ /dev/null |
@@ -1,1439 +0,0 @@ |
-// Copyright 2014 PDFium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
- |
-#include "core/src/fxcodec/jbig2/JBig2_Context.h" |
- |
-#include <algorithm> |
-#include <list> |
-#include <utility> |
-#include <vector> |
- |
-#include "core/include/fpdfapi/cpdf_stream.h" |
-#include "core/src/fxcodec/jbig2/JBig2_ArithDecoder.h" |
-#include "core/src/fxcodec/jbig2/JBig2_BitStream.h" |
-#include "core/src/fxcodec/jbig2/JBig2_GrdProc.h" |
-#include "core/src/fxcodec/jbig2/JBig2_GrrdProc.h" |
-#include "core/src/fxcodec/jbig2/JBig2_HtrdProc.h" |
-#include "core/src/fxcodec/jbig2/JBig2_HuffmanTable_Standard.h" |
-#include "core/src/fxcodec/jbig2/JBig2_PddProc.h" |
-#include "core/src/fxcodec/jbig2/JBig2_SddProc.h" |
-#include "core/src/fxcodec/jbig2/JBig2_TrdProc.h" |
-#include "third_party/base/stl_util.h" |
- |
-namespace { |
- |
-size_t GetHuffContextSize(uint8_t val) { |
- return val == 0 ? 65536 : val == 1 ? 8192 : 1024; |
-} |
- |
-size_t GetRefAggContextSize(FX_BOOL val) { |
- return val ? 1024 : 8192; |
-} |
- |
-} // namespace |
- |
-// Implement a very small least recently used (LRU) cache. It is very |
-// common for a JBIG2 dictionary to span multiple pages in a PDF file, |
-// and we do not want to decode the same dictionary over and over |
-// again. We key off of the memory location of the dictionary. The |
-// 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. |
-static const int kSymbolDictCacheMaxSize = 2; |
- |
-CJBig2_Context* CJBig2_Context::CreateContext( |
- CPDF_StreamAcc* pGlobalStream, |
- CPDF_StreamAcc* pSrcStream, |
- std::list<CJBig2_CachePair>* pSymbolDictCache, |
- IFX_Pause* pPause) { |
- return new CJBig2_Context(pGlobalStream, pSrcStream, pSymbolDictCache, pPause, |
- false); |
-} |
- |
-void CJBig2_Context::DestroyContext(CJBig2_Context* pContext) { |
- delete pContext; |
-} |
- |
-CJBig2_Context::CJBig2_Context(CPDF_StreamAcc* pGlobalStream, |
- CPDF_StreamAcc* pSrcStream, |
- std::list<CJBig2_CachePair>* pSymbolDictCache, |
- IFX_Pause* pPause, |
- bool bIsGlobal) |
- : m_nSegmentDecoded(0), |
- m_bInPage(false), |
- m_bBufSpecified(false), |
- m_PauseStep(10), |
- m_pPause(pPause), |
- m_ProcessingStatus(FXCODEC_STATUS_FRAME_READY), |
- m_gbContext(NULL), |
- m_dwOffset(0), |
- m_pSymbolDictCache(pSymbolDictCache), |
- m_bIsGlobal(bIsGlobal) { |
- if (pGlobalStream && (pGlobalStream->GetSize() > 0)) { |
- m_pGlobalContext = new CJBig2_Context(nullptr, pGlobalStream, |
- pSymbolDictCache, pPause, true); |
- } else { |
- m_pGlobalContext = nullptr; |
- } |
- |
- m_pStream.reset(new CJBig2_BitStream(pSrcStream)); |
-} |
- |
-CJBig2_Context::~CJBig2_Context() { |
- FX_Free(m_gbContext); |
- m_gbContext = NULL; |
- delete m_pGlobalContext; |
- m_pGlobalContext = NULL; |
-} |
- |
-int32_t CJBig2_Context::decode_SquentialOrgnazation(IFX_Pause* pPause) { |
- int32_t nRet; |
- if (m_pStream->getByteLeft() <= 0) |
- return JBIG2_END_OF_FILE; |
- |
- while (m_pStream->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) { |
- if (!m_pSegment) { |
- m_pSegment.reset(new CJBig2_Segment); |
- nRet = parseSegmentHeader(m_pSegment.get()); |
- if (nRet != JBIG2_SUCCESS) { |
- m_pSegment.reset(); |
- return nRet; |
- } |
- m_dwOffset = m_pStream->getOffset(); |
- } |
- nRet = parseSegmentData(m_pSegment.get(), pPause); |
- if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- m_PauseStep = 2; |
- return JBIG2_SUCCESS; |
- } |
- if (nRet == JBIG2_END_OF_PAGE || nRet == JBIG2_END_OF_FILE) { |
- m_pSegment.reset(); |
- return JBIG2_SUCCESS; |
- } |
- if (nRet != JBIG2_SUCCESS) { |
- m_pSegment.reset(); |
- return nRet; |
- } |
- if (m_pSegment->m_dwData_length != 0xffffffff) { |
- m_dwOffset += m_pSegment->m_dwData_length; |
- m_pStream->setOffset(m_dwOffset); |
- } else { |
- m_pStream->offset(4); |
- } |
- m_SegmentList.push_back(m_pSegment.release()); |
- if (m_pStream->getByteLeft() > 0 && m_pPage && pPause && |
- pPause->NeedToPauseNow()) { |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- m_PauseStep = 2; |
- return JBIG2_SUCCESS; |
- } |
- } |
- return JBIG2_SUCCESS; |
-} |
-int32_t CJBig2_Context::decode_EmbedOrgnazation(IFX_Pause* pPause) { |
- return decode_SquentialOrgnazation(pPause); |
-} |
-int32_t CJBig2_Context::decode_RandomOrgnazation_FirstPage(IFX_Pause* pPause) { |
- int32_t nRet; |
- while (m_pStream->getByteLeft() > JBIG2_MIN_SEGMENT_SIZE) { |
- std::unique_ptr<CJBig2_Segment> pSegment(new CJBig2_Segment); |
- nRet = parseSegmentHeader(pSegment.get()); |
- if (nRet != JBIG2_SUCCESS) { |
- return nRet; |
- } else if (pSegment->m_cFlags.s.type == 51) { |
- break; |
- } |
- m_SegmentList.push_back(pSegment.release()); |
- if (pPause && m_pPause && pPause->NeedToPauseNow()) { |
- m_PauseStep = 3; |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- return JBIG2_SUCCESS; |
- } |
- } |
- m_nSegmentDecoded = 0; |
- return decode_RandomOrgnazation(pPause); |
-} |
-int32_t CJBig2_Context::decode_RandomOrgnazation(IFX_Pause* pPause) { |
- for (; m_nSegmentDecoded < m_SegmentList.size(); ++m_nSegmentDecoded) { |
- int32_t nRet = |
- parseSegmentData(m_SegmentList.get(m_nSegmentDecoded), pPause); |
- if (nRet == JBIG2_END_OF_PAGE || nRet == JBIG2_END_OF_FILE) |
- return JBIG2_SUCCESS; |
- |
- if (nRet != JBIG2_SUCCESS) |
- return nRet; |
- |
- if (m_pPage && pPause && pPause->NeedToPauseNow()) { |
- m_PauseStep = 4; |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- return JBIG2_SUCCESS; |
- } |
- } |
- return JBIG2_SUCCESS; |
-} |
-int32_t CJBig2_Context::getFirstPage(uint8_t* pBuf, |
- int32_t width, |
- int32_t height, |
- int32_t stride, |
- IFX_Pause* pPause) { |
- int32_t nRet = 0; |
- if (m_pGlobalContext) { |
- nRet = m_pGlobalContext->decode_EmbedOrgnazation(pPause); |
- if (nRet != JBIG2_SUCCESS) { |
- m_ProcessingStatus = FXCODEC_STATUS_ERROR; |
- return nRet; |
- } |
- } |
- m_PauseStep = 0; |
- m_pPage.reset(new CJBig2_Image(width, height, stride, pBuf)); |
- m_bBufSpecified = true; |
- if (pPause && pPause->NeedToPauseNow()) { |
- m_PauseStep = 1; |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_TOBECONTINUE; |
- return nRet; |
- } |
- return Continue(pPause); |
-} |
-int32_t CJBig2_Context::Continue(IFX_Pause* pPause) { |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_READY; |
- int32_t nRet; |
- if (m_PauseStep <= 1) { |
- nRet = decode_EmbedOrgnazation(pPause); |
- } else if (m_PauseStep == 2) { |
- nRet = decode_SquentialOrgnazation(pPause); |
- } else if (m_PauseStep == 3) { |
- nRet = decode_RandomOrgnazation_FirstPage(pPause); |
- } else if (m_PauseStep == 4) { |
- nRet = decode_RandomOrgnazation(pPause); |
- } else if (m_PauseStep == 5) { |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; |
- return JBIG2_SUCCESS; |
- } |
- if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
- return nRet; |
- } |
- m_PauseStep = 5; |
- if (!m_bBufSpecified && nRet == JBIG2_SUCCESS) { |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; |
- return JBIG2_SUCCESS; |
- } |
- if (nRet == JBIG2_SUCCESS) { |
- m_ProcessingStatus = FXCODEC_STATUS_DECODE_FINISH; |
- } else { |
- m_ProcessingStatus = FXCODEC_STATUS_ERROR; |
- } |
- return nRet; |
-} |
- |
-CJBig2_Segment* CJBig2_Context::findSegmentByNumber(FX_DWORD dwNumber) { |
- if (m_pGlobalContext) { |
- CJBig2_Segment* pSeg = m_pGlobalContext->findSegmentByNumber(dwNumber); |
- if (pSeg) { |
- return pSeg; |
- } |
- } |
- for (size_t i = 0; i < m_SegmentList.size(); ++i) { |
- CJBig2_Segment* pSeg = m_SegmentList.get(i); |
- if (pSeg->m_dwNumber == dwNumber) { |
- return pSeg; |
- } |
- } |
- return nullptr; |
-} |
-CJBig2_Segment* CJBig2_Context::findReferredSegmentByTypeAndIndex( |
- CJBig2_Segment* pSegment, |
- uint8_t cType, |
- int32_t nIndex) { |
- int32_t count = 0; |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- CJBig2_Segment* pSeg = |
- findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
- if (pSeg && pSeg->m_cFlags.s.type == cType) { |
- if (count == nIndex) |
- return pSeg; |
- ++count; |
- } |
- } |
- return NULL; |
-} |
-int32_t CJBig2_Context::parseSegmentHeader(CJBig2_Segment* pSegment) { |
- if (m_pStream->readInteger(&pSegment->m_dwNumber) != 0 || |
- m_pStream->read1Byte(&pSegment->m_cFlags.c) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- |
- FX_DWORD dwTemp; |
- uint8_t cTemp = m_pStream->getCurByte(); |
- if ((cTemp >> 5) == 7) { |
- if (m_pStream->readInteger( |
- (FX_DWORD*)&pSegment->m_nReferred_to_segment_count) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- pSegment->m_nReferred_to_segment_count &= 0x1fffffff; |
- if (pSegment->m_nReferred_to_segment_count > |
- JBIG2_MAX_REFERRED_SEGMENT_COUNT) { |
- return JBIG2_ERROR_LIMIT; |
- } |
- dwTemp = 5 + 4 + (pSegment->m_nReferred_to_segment_count + 1) / 8; |
- } else { |
- if (m_pStream->read1Byte(&cTemp) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- pSegment->m_nReferred_to_segment_count = cTemp >> 5; |
- dwTemp = 5 + 1; |
- } |
- uint8_t cSSize = |
- pSegment->m_dwNumber > 65536 ? 4 : pSegment->m_dwNumber > 256 ? 2 : 1; |
- uint8_t cPSize = pSegment->m_cFlags.s.page_association_size ? 4 : 1; |
- if (pSegment->m_nReferred_to_segment_count) { |
- pSegment->m_pReferred_to_segment_numbers = |
- FX_Alloc(FX_DWORD, pSegment->m_nReferred_to_segment_count); |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- switch (cSSize) { |
- case 1: |
- if (m_pStream->read1Byte(&cTemp) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- pSegment->m_pReferred_to_segment_numbers[i] = cTemp; |
- break; |
- case 2: |
- FX_WORD wTemp; |
- if (m_pStream->readShortInteger(&wTemp) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- pSegment->m_pReferred_to_segment_numbers[i] = wTemp; |
- break; |
- case 4: |
- if (m_pStream->readInteger(&dwTemp) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- pSegment->m_pReferred_to_segment_numbers[i] = dwTemp; |
- break; |
- } |
- if (pSegment->m_pReferred_to_segment_numbers[i] >= pSegment->m_dwNumber) |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- if (cPSize == 1) { |
- if (m_pStream->read1Byte(&cTemp) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- pSegment->m_dwPage_association = cTemp; |
- } else { |
- if (m_pStream->readInteger(&pSegment->m_dwPage_association) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- if (m_pStream->readInteger(&pSegment->m_dwData_length) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- pSegment->m_dwObjNum = m_pStream->getObjNum(); |
- pSegment->m_dwDataOffset = m_pStream->getOffset(); |
- pSegment->m_State = JBIG2_SEGMENT_DATA_UNPARSED; |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseSegmentData(CJBig2_Segment* pSegment, |
- IFX_Pause* pPause) { |
- int32_t ret = ProcessingParseSegmentData(pSegment, pPause); |
- while (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE && |
- m_pStream->getByteLeft() > 0) { |
- ret = ProcessingParseSegmentData(pSegment, pPause); |
- } |
- return ret; |
-} |
- |
-int32_t CJBig2_Context::ProcessingParseSegmentData(CJBig2_Segment* pSegment, |
- IFX_Pause* pPause) { |
- switch (pSegment->m_cFlags.s.type) { |
- case 0: |
- return parseSymbolDict(pSegment, pPause); |
- case 4: |
- case 6: |
- case 7: |
- if (!m_bInPage) |
- return JBIG2_ERROR_FATAL; |
- return parseTextRegion(pSegment); |
- case 16: |
- return parsePatternDict(pSegment, pPause); |
- case 20: |
- case 22: |
- case 23: |
- if (!m_bInPage) |
- return JBIG2_ERROR_FATAL; |
- return parseHalftoneRegion(pSegment, pPause); |
- case 36: |
- case 38: |
- case 39: |
- if (!m_bInPage) |
- return JBIG2_ERROR_FATAL; |
- return parseGenericRegion(pSegment, pPause); |
- case 40: |
- case 42: |
- case 43: |
- if (!m_bInPage) |
- return JBIG2_ERROR_FATAL; |
- return parseGenericRefinementRegion(pSegment); |
- case 48: { |
- FX_WORD wTemp; |
- std::unique_ptr<JBig2PageInfo> pPageInfo(new JBig2PageInfo); |
- if (m_pStream->readInteger(&pPageInfo->m_dwWidth) != 0 || |
- m_pStream->readInteger(&pPageInfo->m_dwHeight) != 0 || |
- m_pStream->readInteger(&pPageInfo->m_dwResolutionX) != 0 || |
- m_pStream->readInteger(&pPageInfo->m_dwResolutionY) != 0 || |
- m_pStream->read1Byte(&pPageInfo->m_cFlags) != 0 || |
- m_pStream->readShortInteger(&wTemp) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- pPageInfo->m_bIsStriped = !!(wTemp & 0x8000); |
- pPageInfo->m_wMaxStripeSize = wTemp & 0x7fff; |
- bool bMaxHeight = (pPageInfo->m_dwHeight == 0xffffffff); |
- if (bMaxHeight && pPageInfo->m_bIsStriped != TRUE) |
- pPageInfo->m_bIsStriped = TRUE; |
- |
- if (!m_bBufSpecified) { |
- FX_DWORD height = |
- bMaxHeight ? pPageInfo->m_wMaxStripeSize : pPageInfo->m_dwHeight; |
- m_pPage.reset(new CJBig2_Image(pPageInfo->m_dwWidth, height)); |
- } |
- |
- if (!m_pPage->m_pData) { |
- m_ProcessingStatus = FXCODEC_STATUS_ERROR; |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- |
- m_pPage->fill((pPageInfo->m_cFlags & 4) ? 1 : 0); |
- m_PageInfoList.push_back(pPageInfo.release()); |
- m_bInPage = true; |
- } break; |
- case 49: |
- m_bInPage = false; |
- return JBIG2_END_OF_PAGE; |
- break; |
- case 50: |
- m_pStream->offset(pSegment->m_dwData_length); |
- break; |
- case 51: |
- return JBIG2_END_OF_FILE; |
- case 52: |
- m_pStream->offset(pSegment->m_dwData_length); |
- break; |
- case 53: |
- return parseTable(pSegment); |
- case 62: |
- m_pStream->offset(pSegment->m_dwData_length); |
- break; |
- default: |
- break; |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseSymbolDict(CJBig2_Segment* pSegment, |
- IFX_Pause* pPause) { |
- FX_WORD wFlags; |
- if (m_pStream->readShortInteger(&wFlags) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- std::unique_ptr<CJBig2_SDDProc> pSymbolDictDecoder(new CJBig2_SDDProc); |
- pSymbolDictDecoder->SDHUFF = wFlags & 0x0001; |
- pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001; |
- pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003; |
- pSymbolDictDecoder->SDRTEMPLATE = (wFlags >> 12) & 0x0003; |
- uint8_t cSDHUFFDH = (wFlags >> 2) & 0x0003; |
- uint8_t cSDHUFFDW = (wFlags >> 4) & 0x0003; |
- uint8_t cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001; |
- uint8_t cSDHUFFAGGINST = (wFlags >> 7) & 0x0001; |
- if (pSymbolDictDecoder->SDHUFF == 0) { |
- const FX_DWORD dwTemp = (pSymbolDictDecoder->SDTEMPLATE == 0) ? 8 : 2; |
- for (FX_DWORD i = 0; i < dwTemp; ++i) { |
- if (m_pStream->read1Byte((uint8_t*)&pSymbolDictDecoder->SDAT[i]) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- if (pSymbolDictDecoder->SDREFAGG == 1 && |
- pSymbolDictDecoder->SDRTEMPLATE == 0) { |
- for (int32_t i = 0; i < 4; ++i) { |
- if (m_pStream->read1Byte((uint8_t*)&pSymbolDictDecoder->SDRAT[i]) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- if (m_pStream->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0 || |
- m_pStream->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- if (pSymbolDictDecoder->SDNUMEXSYMS > JBIG2_MAX_EXPORT_SYSMBOLS || |
- pSymbolDictDecoder->SDNUMNEWSYMS > JBIG2_MAX_NEW_SYSMBOLS) { |
- return JBIG2_ERROR_LIMIT; |
- } |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) |
- return JBIG2_ERROR_FATAL; |
- } |
- CJBig2_Segment* pLRSeg = nullptr; |
- pSymbolDictDecoder->SDNUMINSYMS = 0; |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- CJBig2_Segment* pSeg = |
- findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
- if (pSeg->m_cFlags.s.type == 0) { |
- pSymbolDictDecoder->SDNUMINSYMS += pSeg->m_Result.sd->NumImages(); |
- pLRSeg = pSeg; |
- } |
- } |
- |
- std::unique_ptr<CJBig2_Image*, FxFreeDeleter> SDINSYMS; |
- if (pSymbolDictDecoder->SDNUMINSYMS != 0) { |
- SDINSYMS.reset(FX_Alloc(CJBig2_Image*, pSymbolDictDecoder->SDNUMINSYMS)); |
- FX_DWORD dwTemp = 0; |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- CJBig2_Segment* pSeg = |
- findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
- if (pSeg->m_cFlags.s.type == 0) { |
- const CJBig2_SymbolDict& dict = *pSeg->m_Result.sd; |
- for (size_t j = 0; j < dict.NumImages(); ++j) |
- SDINSYMS.get()[dwTemp + j] = dict.GetImage(j); |
- dwTemp += dict.NumImages(); |
- } |
- } |
- } |
- pSymbolDictDecoder->SDINSYMS = SDINSYMS.get(); |
- |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B1; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B2; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B3; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B4; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B5; |
- if (pSymbolDictDecoder->SDHUFF == 1) { |
- if (cSDHUFFDH == 2 || cSDHUFFDW == 2) |
- return JBIG2_ERROR_FATAL; |
- |
- int32_t nIndex = 0; |
- if (cSDHUFFDH == 0) { |
- Table_B4.reset(new CJBig2_HuffmanTable(HuffmanTable_B4, |
- FX_ArraySize(HuffmanTable_B4), |
- HuffmanTable_HTOOB_B4)); |
- pSymbolDictDecoder->SDHUFFDH = Table_B4.get(); |
- } else if (cSDHUFFDH == 1) { |
- Table_B5.reset(new CJBig2_HuffmanTable(HuffmanTable_B5, |
- FX_ArraySize(HuffmanTable_B5), |
- HuffmanTable_HTOOB_B5)); |
- pSymbolDictDecoder->SDHUFFDH = Table_B5.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pSymbolDictDecoder->SDHUFFDH = pSeg->m_Result.ht; |
- } |
- if (cSDHUFFDW == 0) { |
- Table_B2.reset(new CJBig2_HuffmanTable(HuffmanTable_B2, |
- FX_ArraySize(HuffmanTable_B2), |
- HuffmanTable_HTOOB_B2)); |
- pSymbolDictDecoder->SDHUFFDW = Table_B2.get(); |
- } else if (cSDHUFFDW == 1) { |
- Table_B3.reset(new CJBig2_HuffmanTable(HuffmanTable_B3, |
- FX_ArraySize(HuffmanTable_B3), |
- HuffmanTable_HTOOB_B3)); |
- pSymbolDictDecoder->SDHUFFDW = Table_B3.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pSymbolDictDecoder->SDHUFFDW = pSeg->m_Result.ht; |
- } |
- if (cSDHUFFBMSIZE == 0) { |
- Table_B1.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, |
- FX_ArraySize(HuffmanTable_B1), |
- HuffmanTable_HTOOB_B1)); |
- pSymbolDictDecoder->SDHUFFBMSIZE = Table_B1.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->m_Result.ht; |
- } |
- if (pSymbolDictDecoder->SDREFAGG == 1) { |
- if (cSDHUFFAGGINST == 0) { |
- if (!Table_B1) { |
- Table_B1.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, |
- FX_ArraySize(HuffmanTable_B1), |
- HuffmanTable_HTOOB_B1)); |
- } |
- pSymbolDictDecoder->SDHUFFAGGINST = Table_B1.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pSymbolDictDecoder->SDHUFFAGGINST = pSeg->m_Result.ht; |
- } |
- } |
- } |
- |
- const bool bUseGbContext = (pSymbolDictDecoder->SDHUFF == 0); |
- const bool bUseGrContext = (pSymbolDictDecoder->SDREFAGG == 1); |
- const size_t gbContextSize = |
- GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE); |
- const size_t grContextSize = |
- GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE); |
- std::vector<JBig2ArithCtx> gbContext; |
- std::vector<JBig2ArithCtx> grContext; |
- if ((wFlags & 0x0100) && pLRSeg) { |
- if (bUseGbContext) { |
- gbContext = pLRSeg->m_Result.sd->GbContext(); |
- if (gbContext.size() != gbContextSize) |
- return JBIG2_ERROR_FATAL; |
- } |
- if (bUseGrContext) { |
- grContext = pLRSeg->m_Result.sd->GrContext(); |
- if (grContext.size() != grContextSize) |
- return JBIG2_ERROR_FATAL; |
- } |
- } else { |
- if (bUseGbContext) |
- gbContext.resize(gbContextSize); |
- if (bUseGrContext) |
- grContext.resize(grContextSize); |
- } |
- |
- CJBig2_CacheKey key = |
- CJBig2_CacheKey(pSegment->m_dwObjNum, pSegment->m_dwDataOffset); |
- FX_BOOL cache_hit = false; |
- pSegment->m_nResultType = JBIG2_SYMBOL_DICT_POINTER; |
- if (m_bIsGlobal && key.first != 0) { |
- for (auto it = m_pSymbolDictCache->begin(); it != m_pSymbolDictCache->end(); |
- ++it) { |
- if (it->first == key) { |
- std::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) { |
- if (bUseGbContext) { |
- std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
- new CJBig2_ArithDecoder(m_pStream.get())); |
- pSegment->m_Result.sd = pSymbolDictDecoder->decode_Arith( |
- pArithDecoder.get(), &gbContext, &grContext); |
- if (!pSegment->m_Result.sd) |
- return JBIG2_ERROR_FATAL; |
- |
- m_pStream->alignByte(); |
- m_pStream->offset(2); |
- } else { |
- pSegment->m_Result.sd = pSymbolDictDecoder->decode_Huffman( |
- m_pStream.get(), &gbContext, &grContext, pPause); |
- if (!pSegment->m_Result.sd) |
- return JBIG2_ERROR_FATAL; |
- m_pStream->alignByte(); |
- } |
- if (m_bIsGlobal && kSymbolDictCacheMaxSize > 0) { |
- std::unique_ptr<CJBig2_SymbolDict> value = |
- pSegment->m_Result.sd->DeepCopy(); |
- int size = pdfium::CollectionSize<int>(*m_pSymbolDictCache); |
- while (size >= kSymbolDictCacheMaxSize) { |
- delete m_pSymbolDictCache->back().second; |
- m_pSymbolDictCache->pop_back(); |
- --size; |
- } |
- m_pSymbolDictCache->push_front(CJBig2_CachePair(key, value.release())); |
- } |
- } |
- if (wFlags & 0x0200) { |
- if (bUseGbContext) |
- pSegment->m_Result.sd->SetGbContext(gbContext); |
- if (bUseGrContext) |
- pSegment->m_Result.sd->SetGrContext(grContext); |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseTextRegion(CJBig2_Segment* pSegment) { |
- FX_WORD wFlags; |
- JBig2RegionInfo ri; |
- if (parseRegionInfo(&ri) != JBIG2_SUCCESS || |
- m_pStream->readShortInteger(&wFlags) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- |
- std::unique_ptr<CJBig2_TRDProc> pTRD(new CJBig2_TRDProc); |
- pTRD->SBW = ri.width; |
- pTRD->SBH = ri.height; |
- pTRD->SBHUFF = wFlags & 0x0001; |
- pTRD->SBREFINE = (wFlags >> 1) & 0x0001; |
- FX_DWORD dwTemp = (wFlags >> 2) & 0x0003; |
- pTRD->SBSTRIPS = 1 << dwTemp; |
- pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003); |
- pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001; |
- pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003); |
- pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001; |
- pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f; |
- if (pTRD->SBDSOFFSET >= 0x0010) { |
- pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020; |
- } |
- pTRD->SBRTEMPLATE = (wFlags >> 15) & 0x0001; |
- |
- uint8_t cSBHUFFFS; |
- uint8_t cSBHUFFDS; |
- uint8_t cSBHUFFDT; |
- uint8_t cSBHUFFRDW; |
- uint8_t cSBHUFFRDH; |
- uint8_t cSBHUFFRDX; |
- uint8_t cSBHUFFRDY; |
- uint8_t cSBHUFFRSIZE; |
- if (pTRD->SBHUFF == 1) { |
- if (m_pStream->readShortInteger(&wFlags) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- cSBHUFFFS = wFlags & 0x0003; |
- cSBHUFFDS = (wFlags >> 2) & 0x0003; |
- cSBHUFFDT = (wFlags >> 4) & 0x0003; |
- cSBHUFFRDW = (wFlags >> 6) & 0x0003; |
- cSBHUFFRDH = (wFlags >> 8) & 0x0003; |
- cSBHUFFRDX = (wFlags >> 10) & 0x0003; |
- cSBHUFFRDY = (wFlags >> 12) & 0x0003; |
- cSBHUFFRSIZE = (wFlags >> 14) & 0x0001; |
- } |
- if (pTRD->SBREFINE == 1 && pTRD->SBRTEMPLATE == 0) { |
- for (int32_t i = 0; i < 4; ++i) { |
- if (m_pStream->read1Byte((uint8_t*)&pTRD->SBRAT[i]) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- if (m_pStream->readInteger(&pTRD->SBNUMINSTANCES) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- if (!findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i])) |
- return JBIG2_ERROR_FATAL; |
- } |
- |
- pTRD->SBNUMSYMS = 0; |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- CJBig2_Segment* pSeg = |
- findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
- if (pSeg->m_cFlags.s.type == 0) { |
- pTRD->SBNUMSYMS += pSeg->m_Result.sd->NumImages(); |
- } |
- } |
- |
- std::unique_ptr<CJBig2_Image*, FxFreeDeleter> SBSYMS; |
- if (pTRD->SBNUMSYMS > 0) { |
- SBSYMS.reset(FX_Alloc(CJBig2_Image*, pTRD->SBNUMSYMS)); |
- dwTemp = 0; |
- for (int32_t i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- CJBig2_Segment* pSeg = |
- findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[i]); |
- if (pSeg->m_cFlags.s.type == 0) { |
- const CJBig2_SymbolDict& dict = *pSeg->m_Result.sd; |
- for (size_t j = 0; j < dict.NumImages(); ++j) |
- SBSYMS.get()[dwTemp + j] = dict.GetImage(j); |
- dwTemp += dict.NumImages(); |
- } |
- } |
- pTRD->SBSYMS = SBSYMS.get(); |
- } else { |
- pTRD->SBSYMS = NULL; |
- } |
- |
- std::unique_ptr<JBig2HuffmanCode, FxFreeDeleter> SBSYMCODES; |
- if (pTRD->SBHUFF == 1) { |
- SBSYMCODES.reset( |
- decodeSymbolIDHuffmanTable(m_pStream.get(), pTRD->SBNUMSYMS)); |
- if (!SBSYMCODES) |
- return JBIG2_ERROR_FATAL; |
- |
- m_pStream->alignByte(); |
- pTRD->SBSYMCODES = SBSYMCODES.get(); |
- } else { |
- dwTemp = 0; |
- while ((FX_DWORD)(1 << dwTemp) < pTRD->SBNUMSYMS) { |
- ++dwTemp; |
- } |
- pTRD->SBSYMCODELEN = (uint8_t)dwTemp; |
- } |
- |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B1; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B6; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B7; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B8; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B9; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B10; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B11; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B12; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B13; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B14; |
- std::unique_ptr<CJBig2_HuffmanTable> Table_B15; |
- if (pTRD->SBHUFF == 1) { |
- if (cSBHUFFFS == 2 || cSBHUFFRDW == 2 || cSBHUFFRDH == 2 || |
- cSBHUFFRDX == 2 || cSBHUFFRDY == 2) { |
- return JBIG2_ERROR_FATAL; |
- } |
- int32_t nIndex = 0; |
- if (cSBHUFFFS == 0) { |
- Table_B6.reset(new CJBig2_HuffmanTable(HuffmanTable_B6, |
- FX_ArraySize(HuffmanTable_B6), |
- HuffmanTable_HTOOB_B6)); |
- pTRD->SBHUFFFS = Table_B6.get(); |
- } else if (cSBHUFFFS == 1) { |
- Table_B7.reset(new CJBig2_HuffmanTable(HuffmanTable_B7, |
- FX_ArraySize(HuffmanTable_B7), |
- HuffmanTable_HTOOB_B7)); |
- pTRD->SBHUFFFS = Table_B7.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFFS = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFDS == 0) { |
- Table_B8.reset(new CJBig2_HuffmanTable(HuffmanTable_B8, |
- FX_ArraySize(HuffmanTable_B8), |
- HuffmanTable_HTOOB_B8)); |
- pTRD->SBHUFFDS = Table_B8.get(); |
- } else if (cSBHUFFDS == 1) { |
- Table_B9.reset(new CJBig2_HuffmanTable(HuffmanTable_B9, |
- FX_ArraySize(HuffmanTable_B9), |
- HuffmanTable_HTOOB_B9)); |
- pTRD->SBHUFFDS = Table_B9.get(); |
- } else if (cSBHUFFDS == 2) { |
- Table_B10.reset(new CJBig2_HuffmanTable(HuffmanTable_B10, |
- FX_ArraySize(HuffmanTable_B10), |
- HuffmanTable_HTOOB_B10)); |
- pTRD->SBHUFFDS = Table_B10.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFDS = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFDT == 0) { |
- Table_B11.reset(new CJBig2_HuffmanTable(HuffmanTable_B11, |
- FX_ArraySize(HuffmanTable_B11), |
- HuffmanTable_HTOOB_B11)); |
- pTRD->SBHUFFDT = Table_B11.get(); |
- } else if (cSBHUFFDT == 1) { |
- Table_B12.reset(new CJBig2_HuffmanTable(HuffmanTable_B12, |
- FX_ArraySize(HuffmanTable_B12), |
- HuffmanTable_HTOOB_B12)); |
- pTRD->SBHUFFDT = Table_B12.get(); |
- } else if (cSBHUFFDT == 2) { |
- Table_B13.reset(new CJBig2_HuffmanTable(HuffmanTable_B13, |
- FX_ArraySize(HuffmanTable_B13), |
- HuffmanTable_HTOOB_B13)); |
- pTRD->SBHUFFDT = Table_B13.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFDT = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFRDW == 0) { |
- Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
- FX_ArraySize(HuffmanTable_B14), |
- HuffmanTable_HTOOB_B14)); |
- pTRD->SBHUFFRDW = Table_B14.get(); |
- } else if (cSBHUFFRDW == 1) { |
- Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
- FX_ArraySize(HuffmanTable_B15), |
- HuffmanTable_HTOOB_B15)); |
- pTRD->SBHUFFRDW = Table_B15.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFRDW = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFRDH == 0) { |
- if (!Table_B14) { |
- Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
- FX_ArraySize(HuffmanTable_B14), |
- HuffmanTable_HTOOB_B14)); |
- } |
- pTRD->SBHUFFRDH = Table_B14.get(); |
- } else if (cSBHUFFRDH == 1) { |
- if (!Table_B15) { |
- Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
- FX_ArraySize(HuffmanTable_B15), |
- HuffmanTable_HTOOB_B15)); |
- } |
- pTRD->SBHUFFRDH = Table_B15.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFRDH = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFRDX == 0) { |
- if (!Table_B14) { |
- Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
- FX_ArraySize(HuffmanTable_B14), |
- HuffmanTable_HTOOB_B14)); |
- } |
- pTRD->SBHUFFRDX = Table_B14.get(); |
- } else if (cSBHUFFRDX == 1) { |
- if (!Table_B15) { |
- Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
- FX_ArraySize(HuffmanTable_B15), |
- HuffmanTable_HTOOB_B15)); |
- } |
- pTRD->SBHUFFRDX = Table_B15.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFRDX = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFRDY == 0) { |
- if (!Table_B14) { |
- Table_B14.reset(new CJBig2_HuffmanTable(HuffmanTable_B14, |
- FX_ArraySize(HuffmanTable_B14), |
- HuffmanTable_HTOOB_B14)); |
- } |
- pTRD->SBHUFFRDY = Table_B14.get(); |
- } else if (cSBHUFFRDY == 1) { |
- if (!Table_B15) { |
- Table_B15.reset(new CJBig2_HuffmanTable(HuffmanTable_B15, |
- FX_ArraySize(HuffmanTable_B15), |
- HuffmanTable_HTOOB_B15)); |
- } |
- pTRD->SBHUFFRDY = Table_B15.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFRDY = pSeg->m_Result.ht; |
- } |
- if (cSBHUFFRSIZE == 0) { |
- Table_B1.reset(new CJBig2_HuffmanTable(HuffmanTable_B1, |
- FX_ArraySize(HuffmanTable_B1), |
- HuffmanTable_HTOOB_B1)); |
- pTRD->SBHUFFRSIZE = Table_B1.get(); |
- } else { |
- CJBig2_Segment* pSeg = |
- findReferredSegmentByTypeAndIndex(pSegment, 53, nIndex++); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- pTRD->SBHUFFRSIZE = pSeg->m_Result.ht; |
- } |
- } |
- std::unique_ptr<JBig2ArithCtx, FxFreeDeleter> grContext; |
- if (pTRD->SBREFINE == 1) { |
- const size_t size = GetRefAggContextSize(pTRD->SBRTEMPLATE); |
- grContext.reset(FX_Alloc(JBig2ArithCtx, size)); |
- JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
- } |
- if (pTRD->SBHUFF == 0) { |
- std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
- new CJBig2_ArithDecoder(m_pStream.get())); |
- pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
- pSegment->m_Result.im = |
- pTRD->decode_Arith(pArithDecoder.get(), grContext.get(), nullptr); |
- if (!pSegment->m_Result.im) |
- return JBIG2_ERROR_FATAL; |
- m_pStream->alignByte(); |
- m_pStream->offset(2); |
- } else { |
- pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
- pSegment->m_Result.im = |
- pTRD->decode_Huffman(m_pStream.get(), grContext.get()); |
- if (!pSegment->m_Result.im) |
- return JBIG2_ERROR_FATAL; |
- m_pStream->alignByte(); |
- } |
- if (pSegment->m_cFlags.s.type != 4) { |
- if (!m_bBufSpecified) { |
- JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
- if ((pPageInfo->m_bIsStriped == 1) && |
- (ri.y + ri.height > m_pPage->m_nHeight)) { |
- m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
- } |
- } |
- m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, |
- (JBig2ComposeOp)(ri.flags & 0x03)); |
- delete pSegment->m_Result.im; |
- pSegment->m_Result.im = NULL; |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parsePatternDict(CJBig2_Segment* pSegment, |
- IFX_Pause* pPause) { |
- uint8_t cFlags; |
- std::unique_ptr<CJBig2_PDDProc> pPDD(new CJBig2_PDDProc); |
- if (m_pStream->read1Byte(&cFlags) != 0 || |
- m_pStream->read1Byte(&pPDD->HDPW) != 0 || |
- m_pStream->read1Byte(&pPDD->HDPH) != 0 || |
- m_pStream->readInteger(&pPDD->GRAYMAX) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- if (pPDD->GRAYMAX > JBIG2_MAX_PATTERN_INDEX) |
- return JBIG2_ERROR_LIMIT; |
- |
- pPDD->HDMMR = cFlags & 0x01; |
- pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03; |
- pSegment->m_nResultType = JBIG2_PATTERN_DICT_POINTER; |
- if (pPDD->HDMMR == 0) { |
- const size_t size = GetHuffContextSize(pPDD->HDTEMPLATE); |
- std::unique_ptr<JBig2ArithCtx, FxFreeDeleter> gbContext( |
- FX_Alloc(JBig2ArithCtx, size)); |
- JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
- std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
- new CJBig2_ArithDecoder(m_pStream.get())); |
- pSegment->m_Result.pd = |
- pPDD->decode_Arith(pArithDecoder.get(), gbContext.get(), pPause); |
- if (!pSegment->m_Result.pd) |
- return JBIG2_ERROR_FATAL; |
- |
- m_pStream->alignByte(); |
- m_pStream->offset(2); |
- } else { |
- pSegment->m_Result.pd = pPDD->decode_MMR(m_pStream.get(), pPause); |
- if (!pSegment->m_Result.pd) |
- return JBIG2_ERROR_FATAL; |
- m_pStream->alignByte(); |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseHalftoneRegion(CJBig2_Segment* pSegment, |
- IFX_Pause* pPause) { |
- uint8_t cFlags; |
- JBig2RegionInfo ri; |
- std::unique_ptr<CJBig2_HTRDProc> pHRD(new CJBig2_HTRDProc); |
- if (parseRegionInfo(&ri) != JBIG2_SUCCESS || |
- m_pStream->read1Byte(&cFlags) != 0 || |
- m_pStream->readInteger(&pHRD->HGW) != 0 || |
- m_pStream->readInteger(&pHRD->HGH) != 0 || |
- m_pStream->readInteger((FX_DWORD*)&pHRD->HGX) != 0 || |
- m_pStream->readInteger((FX_DWORD*)&pHRD->HGY) != 0 || |
- m_pStream->readShortInteger(&pHRD->HRX) != 0 || |
- m_pStream->readShortInteger(&pHRD->HRY) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- |
- if (pHRD->HGW == 0 || pHRD->HGH == 0) |
- return JBIG2_ERROR_FATAL; |
- |
- pHRD->HBW = ri.width; |
- pHRD->HBH = ri.height; |
- pHRD->HMMR = cFlags & 0x01; |
- pHRD->HTEMPLATE = (cFlags >> 1) & 0x03; |
- pHRD->HENABLESKIP = (cFlags >> 3) & 0x01; |
- pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07); |
- pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01; |
- if (pSegment->m_nReferred_to_segment_count != 1) |
- return JBIG2_ERROR_FATAL; |
- |
- CJBig2_Segment* pSeg = |
- findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); |
- if (!pSeg || (pSeg->m_cFlags.s.type != 16)) |
- return JBIG2_ERROR_FATAL; |
- |
- CJBig2_PatternDict* pPatternDict = pSeg->m_Result.pd; |
- if (!pPatternDict || (pPatternDict->NUMPATS == 0)) |
- return JBIG2_ERROR_FATAL; |
- |
- pHRD->HNUMPATS = pPatternDict->NUMPATS; |
- pHRD->HPATS = pPatternDict->HDPATS; |
- pHRD->HPW = pPatternDict->HDPATS[0]->m_nWidth; |
- pHRD->HPH = pPatternDict->HDPATS[0]->m_nHeight; |
- pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
- if (pHRD->HMMR == 0) { |
- const size_t size = GetHuffContextSize(pHRD->HTEMPLATE); |
- std::unique_ptr<JBig2ArithCtx, FxFreeDeleter> gbContext( |
- FX_Alloc(JBig2ArithCtx, size)); |
- JBIG2_memset(gbContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
- std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
- new CJBig2_ArithDecoder(m_pStream.get())); |
- pSegment->m_Result.im = |
- pHRD->decode_Arith(pArithDecoder.get(), gbContext.get(), pPause); |
- if (!pSegment->m_Result.im) |
- return JBIG2_ERROR_FATAL; |
- |
- m_pStream->alignByte(); |
- m_pStream->offset(2); |
- } else { |
- pSegment->m_Result.im = pHRD->decode_MMR(m_pStream.get(), pPause); |
- if (!pSegment->m_Result.im) |
- return JBIG2_ERROR_FATAL; |
- m_pStream->alignByte(); |
- } |
- if (pSegment->m_cFlags.s.type != 20) { |
- if (!m_bBufSpecified) { |
- JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
- if (pPageInfo->m_bIsStriped == 1 && |
- ri.y + ri.height > m_pPage->m_nHeight) { |
- m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
- } |
- } |
- m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, |
- (JBig2ComposeOp)(ri.flags & 0x03)); |
- delete pSegment->m_Result.im; |
- pSegment->m_Result.im = NULL; |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseGenericRegion(CJBig2_Segment* pSegment, |
- IFX_Pause* pPause) { |
- if (!m_pGRD) { |
- std::unique_ptr<CJBig2_GRDProc> pGRD(new CJBig2_GRDProc); |
- uint8_t cFlags; |
- if (parseRegionInfo(&m_ri) != JBIG2_SUCCESS || |
- m_pStream->read1Byte(&cFlags) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- if (m_ri.height < 0 || m_ri.width < 0) |
- return JBIG2_FAILED; |
- |
- pGRD->GBW = m_ri.width; |
- pGRD->GBH = m_ri.height; |
- pGRD->MMR = cFlags & 0x01; |
- pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03; |
- pGRD->TPGDON = (cFlags >> 3) & 0x01; |
- if (pGRD->MMR == 0) { |
- if (pGRD->GBTEMPLATE == 0) { |
- for (int32_t i = 0; i < 8; ++i) { |
- if (m_pStream->read1Byte((uint8_t*)&pGRD->GBAT[i]) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- } else { |
- for (int32_t i = 0; i < 2; ++i) { |
- if (m_pStream->read1Byte((uint8_t*)&pGRD->GBAT[i]) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- } |
- } |
- pGRD->USESKIP = 0; |
- m_pGRD = std::move(pGRD); |
- } |
- pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
- if (m_pGRD->MMR == 0) { |
- if (!m_gbContext) { |
- const size_t size = GetHuffContextSize(m_pGRD->GBTEMPLATE); |
- m_gbContext = FX_Alloc(JBig2ArithCtx, size); |
- JBIG2_memset(m_gbContext, 0, sizeof(JBig2ArithCtx) * size); |
- } |
- if (!m_pArithDecoder) { |
- m_pArithDecoder.reset(new CJBig2_ArithDecoder(m_pStream.get())); |
- m_ProcessingStatus = m_pGRD->Start_decode_Arith( |
- &pSegment->m_Result.im, m_pArithDecoder.get(), m_gbContext, pPause); |
- } else { |
- m_ProcessingStatus = m_pGRD->Continue_decode(pPause); |
- } |
- if (m_ProcessingStatus == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
- if (pSegment->m_cFlags.s.type != 36) { |
- if (!m_bBufSpecified) { |
- JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
- if ((pPageInfo->m_bIsStriped == 1) && |
- (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { |
- m_pPage->expand(m_ri.y + m_ri.height, |
- (pPageInfo->m_cFlags & 4) ? 1 : 0); |
- } |
- } |
- FX_RECT Rect = m_pGRD->GetReplaceRect(); |
- m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, |
- pSegment->m_Result.im, |
- (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); |
- } |
- return JBIG2_SUCCESS; |
- } else { |
- m_pArithDecoder.reset(); |
- FX_Free(m_gbContext); |
- m_gbContext = NULL; |
- if (!pSegment->m_Result.im) { |
- m_ProcessingStatus = FXCODEC_STATUS_ERROR; |
- m_pGRD.reset(); |
- return JBIG2_ERROR_FATAL; |
- } |
- m_pStream->alignByte(); |
- m_pStream->offset(2); |
- } |
- } else { |
- FXCODEC_STATUS status = m_pGRD->Start_decode_MMR(&pSegment->m_Result.im, |
- m_pStream.get(), pPause); |
- while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { |
- m_pGRD->Continue_decode(pPause); |
- } |
- if (!pSegment->m_Result.im) { |
- m_pGRD.reset(); |
- return JBIG2_ERROR_FATAL; |
- } |
- m_pStream->alignByte(); |
- } |
- if (pSegment->m_cFlags.s.type != 36) { |
- if (!m_bBufSpecified) { |
- JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
- if ((pPageInfo->m_bIsStriped == 1) && |
- (m_ri.y + m_ri.height > m_pPage->m_nHeight)) { |
- m_pPage->expand(m_ri.y + m_ri.height, |
- (pPageInfo->m_cFlags & 4) ? 1 : 0); |
- } |
- } |
- FX_RECT Rect = m_pGRD->GetReplaceRect(); |
- m_pPage->composeFrom(m_ri.x + Rect.left, m_ri.y + Rect.top, |
- pSegment->m_Result.im, |
- (JBig2ComposeOp)(m_ri.flags & 0x03), &Rect); |
- delete pSegment->m_Result.im; |
- pSegment->m_Result.im = NULL; |
- } |
- m_pGRD.reset(); |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseGenericRefinementRegion(CJBig2_Segment* pSegment) { |
- JBig2RegionInfo ri; |
- uint8_t cFlags; |
- if (parseRegionInfo(&ri) != JBIG2_SUCCESS || |
- m_pStream->read1Byte(&cFlags) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- std::unique_ptr<CJBig2_GRRDProc> pGRRD(new CJBig2_GRRDProc); |
- pGRRD->GRW = ri.width; |
- pGRRD->GRH = ri.height; |
- pGRRD->GRTEMPLATE = cFlags & 0x01; |
- pGRRD->TPGRON = (cFlags >> 1) & 0x01; |
- if (pGRRD->GRTEMPLATE == 0) { |
- for (int32_t i = 0; i < 4; ++i) { |
- if (m_pStream->read1Byte((uint8_t*)&pGRRD->GRAT[i]) != 0) |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- } |
- CJBig2_Segment* pSeg = nullptr; |
- if (pSegment->m_nReferred_to_segment_count > 0) { |
- int32_t i; |
- for (i = 0; i < pSegment->m_nReferred_to_segment_count; ++i) { |
- pSeg = findSegmentByNumber(pSegment->m_pReferred_to_segment_numbers[0]); |
- if (!pSeg) |
- return JBIG2_ERROR_FATAL; |
- |
- if (pSeg->m_cFlags.s.type == 4 || pSeg->m_cFlags.s.type == 20 || |
- pSeg->m_cFlags.s.type == 36 || pSeg->m_cFlags.s.type == 40) { |
- break; |
- } |
- } |
- if (i >= pSegment->m_nReferred_to_segment_count) |
- return JBIG2_ERROR_FATAL; |
- |
- pGRRD->GRREFERENCE = pSeg->m_Result.im; |
- } else { |
- pGRRD->GRREFERENCE = m_pPage.get(); |
- } |
- pGRRD->GRREFERENCEDX = 0; |
- pGRRD->GRREFERENCEDY = 0; |
- const size_t size = GetRefAggContextSize(pGRRD->GRTEMPLATE); |
- std::unique_ptr<JBig2ArithCtx, FxFreeDeleter> grContext( |
- FX_Alloc(JBig2ArithCtx, size)); |
- JBIG2_memset(grContext.get(), 0, sizeof(JBig2ArithCtx) * size); |
- std::unique_ptr<CJBig2_ArithDecoder> pArithDecoder( |
- new CJBig2_ArithDecoder(m_pStream.get())); |
- pSegment->m_nResultType = JBIG2_IMAGE_POINTER; |
- pSegment->m_Result.im = pGRRD->decode(pArithDecoder.get(), grContext.get()); |
- if (!pSegment->m_Result.im) |
- return JBIG2_ERROR_FATAL; |
- |
- m_pStream->alignByte(); |
- m_pStream->offset(2); |
- if (pSegment->m_cFlags.s.type != 40) { |
- if (!m_bBufSpecified) { |
- JBig2PageInfo* pPageInfo = m_PageInfoList.back(); |
- if ((pPageInfo->m_bIsStriped == 1) && |
- (ri.y + ri.height > m_pPage->m_nHeight)) { |
- m_pPage->expand(ri.y + ri.height, (pPageInfo->m_cFlags & 4) ? 1 : 0); |
- } |
- } |
- m_pPage->composeFrom(ri.x, ri.y, pSegment->m_Result.im, |
- (JBig2ComposeOp)(ri.flags & 0x03)); |
- delete pSegment->m_Result.im; |
- pSegment->m_Result.im = NULL; |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseTable(CJBig2_Segment* pSegment) { |
- pSegment->m_nResultType = JBIG2_HUFFMAN_TABLE_POINTER; |
- pSegment->m_Result.ht = nullptr; |
- std::unique_ptr<CJBig2_HuffmanTable> pHuff( |
- new CJBig2_HuffmanTable(m_pStream.get())); |
- if (!pHuff->IsOK()) |
- return JBIG2_ERROR_FATAL; |
- |
- pSegment->m_Result.ht = pHuff.release(); |
- m_pStream->alignByte(); |
- return JBIG2_SUCCESS; |
-} |
- |
-int32_t CJBig2_Context::parseRegionInfo(JBig2RegionInfo* pRI) { |
- if (m_pStream->readInteger((FX_DWORD*)&pRI->width) != 0 || |
- m_pStream->readInteger((FX_DWORD*)&pRI->height) != 0 || |
- m_pStream->readInteger((FX_DWORD*)&pRI->x) != 0 || |
- m_pStream->readInteger((FX_DWORD*)&pRI->y) != 0 || |
- m_pStream->read1Byte(&pRI->flags) != 0) { |
- return JBIG2_ERROR_TOO_SHORT; |
- } |
- return JBIG2_SUCCESS; |
-} |
- |
-JBig2HuffmanCode* CJBig2_Context::decodeSymbolIDHuffmanTable( |
- CJBig2_BitStream* pStream, |
- FX_DWORD SBNUMSYMS) { |
- const size_t kRunCodesSize = 35; |
- int32_t runcodes[kRunCodesSize]; |
- int32_t runcodes_len[kRunCodesSize]; |
- for (int32_t i = 0; i < kRunCodesSize; ++i) { |
- if (pStream->readNBits(4, &runcodes_len[i]) != 0) |
- return nullptr; |
- } |
- huffman_assign_code(runcodes, runcodes_len, kRunCodesSize); |
- |
- std::unique_ptr<JBig2HuffmanCode, FxFreeDeleter> SBSYMCODES( |
- FX_Alloc(JBig2HuffmanCode, SBNUMSYMS)); |
- int32_t run; |
- int32_t i = 0; |
- while (i < (int)SBNUMSYMS) { |
- int32_t j; |
- int32_t nVal = 0; |
- int32_t nBits = 0; |
- FX_DWORD nTemp; |
- while (true) { |
- if (pStream->read1Bit(&nTemp) != 0) |
- return nullptr; |
- |
- nVal = (nVal << 1) | nTemp; |
- ++nBits; |
- for (j = 0; j < kRunCodesSize; ++j) { |
- if (nBits == runcodes_len[j] && nVal == runcodes[j]) { |
- break; |
- } |
- } |
- if (j < kRunCodesSize) { |
- break; |
- } |
- } |
- int32_t runcode = j; |
- if (runcode < 32) { |
- SBSYMCODES.get()[i].codelen = runcode; |
- run = 0; |
- } else if (runcode == 32) { |
- if (pStream->readNBits(2, &nTemp) != 0) |
- return nullptr; |
- run = nTemp + 3; |
- } else if (runcode == 33) { |
- if (pStream->readNBits(3, &nTemp) != 0) |
- return nullptr; |
- run = nTemp + 3; |
- } else if (runcode == 34) { |
- if (pStream->readNBits(7, &nTemp) != 0) |
- return nullptr; |
- run = nTemp + 11; |
- } |
- if (run > 0) { |
- if (i + run > (int)SBNUMSYMS) |
- return nullptr; |
- for (j = 0; j < run; ++j) { |
- if (runcode == 32 && i > 0) { |
- SBSYMCODES.get()[i + j].codelen = SBSYMCODES.get()[i - 1].codelen; |
- } else { |
- SBSYMCODES.get()[i + j].codelen = 0; |
- } |
- } |
- i += run; |
- } else { |
- ++i; |
- } |
- } |
- huffman_assign_code(SBSYMCODES.get(), SBNUMSYMS); |
- return SBSYMCODES.release(); |
-} |
- |
-void CJBig2_Context::huffman_assign_code(int* CODES, int* PREFLEN, int NTEMP) { |
- // TODO(thestig) CJBig2_HuffmanTable::parseFromCodedBuffer() has similar code. |
- int CURLEN, LENMAX, CURCODE, CURTEMP, i; |
- int* LENCOUNT; |
- int* FIRSTCODE; |
- LENMAX = 0; |
- for (i = 0; i < NTEMP; ++i) { |
- if (PREFLEN[i] > LENMAX) { |
- LENMAX = PREFLEN[i]; |
- } |
- } |
- LENCOUNT = FX_Alloc(int, LENMAX + 1); |
- JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); |
- FIRSTCODE = FX_Alloc(int, LENMAX + 1); |
- for (i = 0; i < NTEMP; ++i) { |
- ++LENCOUNT[PREFLEN[i]]; |
- } |
- CURLEN = 1; |
- FIRSTCODE[0] = 0; |
- LENCOUNT[0] = 0; |
- while (CURLEN <= LENMAX) { |
- FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; |
- CURCODE = FIRSTCODE[CURLEN]; |
- CURTEMP = 0; |
- while (CURTEMP < NTEMP) { |
- if (PREFLEN[CURTEMP] == CURLEN) { |
- CODES[CURTEMP] = CURCODE; |
- CURCODE = CURCODE + 1; |
- } |
- CURTEMP = CURTEMP + 1; |
- } |
- CURLEN = CURLEN + 1; |
- } |
- FX_Free(LENCOUNT); |
- FX_Free(FIRSTCODE); |
-} |
-void CJBig2_Context::huffman_assign_code(JBig2HuffmanCode* SBSYMCODES, |
- int NTEMP) { |
- int CURLEN, LENMAX, CURCODE, CURTEMP, i; |
- int* LENCOUNT; |
- int* FIRSTCODE; |
- LENMAX = 0; |
- for (i = 0; i < NTEMP; ++i) { |
- if (SBSYMCODES[i].codelen > LENMAX) { |
- LENMAX = SBSYMCODES[i].codelen; |
- } |
- } |
- LENCOUNT = FX_Alloc(int, (LENMAX + 1)); |
- JBIG2_memset(LENCOUNT, 0, sizeof(int) * (LENMAX + 1)); |
- FIRSTCODE = FX_Alloc(int, (LENMAX + 1)); |
- for (i = 0; i < NTEMP; ++i) { |
- ++LENCOUNT[SBSYMCODES[i].codelen]; |
- } |
- CURLEN = 1; |
- FIRSTCODE[0] = 0; |
- LENCOUNT[0] = 0; |
- while (CURLEN <= LENMAX) { |
- FIRSTCODE[CURLEN] = (FIRSTCODE[CURLEN - 1] + LENCOUNT[CURLEN - 1]) << 1; |
- CURCODE = FIRSTCODE[CURLEN]; |
- CURTEMP = 0; |
- while (CURTEMP < NTEMP) { |
- if (SBSYMCODES[CURTEMP].codelen == CURLEN) { |
- SBSYMCODES[CURTEMP].code = CURCODE; |
- CURCODE = CURCODE + 1; |
- } |
- CURTEMP = CURTEMP + 1; |
- } |
- CURLEN = CURLEN + 1; |
- } |
- FX_Free(LENCOUNT); |
- FX_Free(FIRSTCODE); |
-} |