Cleanup some numeric code.
[pdfium.git] / core / src / fxcodec / codec / fx_codec_jbig.cpp
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 "../../../include/fxcodec/fx_codec.h"
8 #include "codec_int.h"
9
10 // Holds per-document JBig2 related data.
11 class JBig2DocumentContext : public CFX_DestructObject {
12  public:
13   std::list<CJBig2_CachePair>* GetSymbolDictCache() {
14     return &m_SymbolDictCache;
15   }
16
17   ~JBig2DocumentContext() {
18     for (auto it : m_SymbolDictCache) {
19       delete it.second;
20     }
21   }
22
23  private:
24   std::list<CJBig2_CachePair> m_SymbolDictCache;
25 };
26
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
40 CCodec_Jbig2Context::CCodec_Jbig2Context() {
41   FXSYS_memset(this, 0, sizeof(CCodec_Jbig2Context));
42 }
43
44 CCodec_Jbig2Module::~CCodec_Jbig2Module() {
45 }
46
47 void* CCodec_Jbig2Module::CreateJbig2Context() {
48   return new CCodec_Jbig2Context();
49 }
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 }
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 }
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 }