1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "codec_int.h"
8 #include "core/include/fxcodec/fx_codec.h"
9
10 // Holds per-document JBig2 related data.
11 class JBig2DocumentContext : public CFX_DestructObject {
12 public:
GetSymbolDictCache()13 std::list<CJBig2_CachePair>* GetSymbolDictCache() {
14 return &m_SymbolDictCache;
15 }
16
~JBig2DocumentContext()17 ~JBig2DocumentContext() override {
18 for (auto it : m_SymbolDictCache) {
19 delete it.second;
20 }
21 }
22
23 private:
24 std::list<CJBig2_CachePair> m_SymbolDictCache;
25 };
26
GetJBig2DocumentContext(CCodec_Jbig2Module * pModule,CFX_PrivateData * pPrivateData)27 JBig2DocumentContext* GetJBig2DocumentContext(CCodec_Jbig2Module* pModule,
28 CFX_PrivateData* pPrivateData) {
29 void* pModulePrivateData = pPrivateData->GetPrivateData(pModule);
30 if (pModulePrivateData) {
31 CFX_DestructObject* pDestructObject =
32 reinterpret_cast<CFX_DestructObject*>(pModulePrivateData);
33 return static_cast<JBig2DocumentContext*>(pDestructObject);
34 }
35 JBig2DocumentContext* pJBig2DocumentContext = new JBig2DocumentContext();
36 pPrivateData->SetPrivateObj(pModule, pJBig2DocumentContext);
37 return pJBig2DocumentContext;
38 }
39
CCodec_Jbig2Context()40 CCodec_Jbig2Context::CCodec_Jbig2Context() {
41 FXSYS_memset(this, 0, sizeof(CCodec_Jbig2Context));
42 }
43
~CCodec_Jbig2Module()44 CCodec_Jbig2Module::~CCodec_Jbig2Module() {
45 }
46
CreateJbig2Context()47 void* CCodec_Jbig2Module::CreateJbig2Context() {
48 return new CCodec_Jbig2Context();
49 }
DestroyJbig2Context(void * pJbig2Content)50 void CCodec_Jbig2Module::DestroyJbig2Context(void* pJbig2Content) {
51 if (pJbig2Content) {
52 CJBig2_Context::DestroyContext(
53 ((CCodec_Jbig2Context*)pJbig2Content)->m_pContext);
54 delete (CCodec_Jbig2Context*)pJbig2Content;
55 }
56 pJbig2Content = NULL;
57 }
StartDecode(void * pJbig2Context,CFX_PrivateData * pPrivateData,FX_DWORD width,FX_DWORD height,CPDF_StreamAcc * src_stream,CPDF_StreamAcc * global_stream,uint8_t * dest_buf,FX_DWORD dest_pitch,IFX_Pause * pPause)58 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context,
59 CFX_PrivateData* pPrivateData,
60 FX_DWORD width,
61 FX_DWORD height,
62 CPDF_StreamAcc* src_stream,
63 CPDF_StreamAcc* global_stream,
64 uint8_t* dest_buf,
65 FX_DWORD dest_pitch,
66 IFX_Pause* pPause) {
67 if (!pJbig2Context) {
68 return FXCODEC_STATUS_ERR_PARAMS;
69 }
70 JBig2DocumentContext* pJBig2DocumentContext =
71 GetJBig2DocumentContext(this, pPrivateData);
72 CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
73 m_pJbig2Context->m_width = width;
74 m_pJbig2Context->m_height = height;
75 m_pJbig2Context->m_pSrcStream = src_stream;
76 m_pJbig2Context->m_pGlobalStream = global_stream;
77 m_pJbig2Context->m_dest_buf = dest_buf;
78 m_pJbig2Context->m_dest_pitch = dest_pitch;
79 m_pJbig2Context->m_pPause = pPause;
80 FXSYS_memset(dest_buf, 0, height * dest_pitch);
81 m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(
82 global_stream, src_stream, pJBig2DocumentContext->GetSymbolDictCache(),
83 pPause);
84 if (!m_pJbig2Context->m_pContext) {
85 return FXCODEC_STATUS_ERROR;
86 }
87 int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height,
88 dest_pitch, pPause);
89 if (m_pJbig2Context->m_pContext->GetProcessingStatus() ==
90 FXCODEC_STATUS_DECODE_FINISH) {
91 CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
92 m_pJbig2Context->m_pContext = NULL;
93 if (ret != JBIG2_SUCCESS) {
94 return FXCODEC_STATUS_ERROR;
95 }
96 int dword_size = height * dest_pitch / 4;
97 FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
98 for (int i = 0; i < dword_size; i++) {
99 dword_buf[i] = ~dword_buf[i];
100 }
101 return FXCODEC_STATUS_DECODE_FINISH;
102 }
103 return m_pJbig2Context->m_pContext->GetProcessingStatus();
104 }
ContinueDecode(void * pJbig2Context,IFX_Pause * pPause)105 FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context,
106 IFX_Pause* pPause) {
107 CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
108 int ret = m_pJbig2Context->m_pContext->Continue(pPause);
109 if (m_pJbig2Context->m_pContext->GetProcessingStatus() !=
110 FXCODEC_STATUS_DECODE_FINISH) {
111 return m_pJbig2Context->m_pContext->GetProcessingStatus();
112 }
113 CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
114 m_pJbig2Context->m_pContext = NULL;
115 if (ret != JBIG2_SUCCESS) {
116 return FXCODEC_STATUS_ERROR;
117 }
118 int dword_size =
119 m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4;
120 FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf;
121 for (int i = 0; i < dword_size; i++) {
122 dword_buf[i] = ~dword_buf[i];
123 }
124 return FXCODEC_STATUS_DECODE_FINISH;
125 }
126