2cdff9f88c30deade3d156ac15a991feb917757c
[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 CCodec_Jbig2Context::CCodec_Jbig2Context() {
11   FXSYS_memset(this, 0, sizeof(CCodec_Jbig2Context));
12 }
13
14 CCodec_Jbig2Module::~CCodec_Jbig2Module() {
15   for (auto it : m_SymbolDictCache) {
16     delete it.second;
17   }
18 }
19
20 void* CCodec_Jbig2Module::CreateJbig2Context() {
21   return new CCodec_Jbig2Context();
22 }
23 void CCodec_Jbig2Module::DestroyJbig2Context(void* pJbig2Content) {
24   if (pJbig2Content) {
25     CJBig2_Context::DestroyContext(
26         ((CCodec_Jbig2Context*)pJbig2Content)->m_pContext);
27     delete (CCodec_Jbig2Context*)pJbig2Content;
28   }
29   pJbig2Content = NULL;
30 }
31 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context,
32                                                FX_DWORD width,
33                                                FX_DWORD height,
34                                                const uint8_t* src_buf,
35                                                FX_DWORD src_size,
36                                                const uint8_t* global_data,
37                                                FX_DWORD global_size,
38                                                uint8_t* dest_buf,
39                                                FX_DWORD dest_pitch,
40                                                IFX_Pause* pPause) {
41   if (!pJbig2Context) {
42     return FXCODEC_STATUS_ERR_PARAMS;
43   }
44   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
45   m_pJbig2Context->m_width = width;
46   m_pJbig2Context->m_height = height;
47   m_pJbig2Context->m_src_buf = (unsigned char*)src_buf;
48   m_pJbig2Context->m_src_size = src_size;
49   m_pJbig2Context->m_global_data = global_data;
50   m_pJbig2Context->m_global_size = global_size;
51   m_pJbig2Context->m_dest_buf = dest_buf;
52   m_pJbig2Context->m_dest_pitch = dest_pitch;
53   m_pJbig2Context->m_pPause = pPause;
54   m_pJbig2Context->m_bFileReader = FALSE;
55   FXSYS_memset(dest_buf, 0, height * dest_pitch);
56   m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(
57       global_data, global_size, src_buf, src_size, &m_SymbolDictCache, pPause);
58   if (!m_pJbig2Context->m_pContext) {
59     return FXCODEC_STATUS_ERROR;
60   }
61   int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height,
62                                                       dest_pitch, pPause);
63   if (m_pJbig2Context->m_pContext->GetProcessingStatus() ==
64       FXCODEC_STATUS_DECODE_FINISH) {
65     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
66     m_pJbig2Context->m_pContext = NULL;
67     if (ret != JBIG2_SUCCESS) {
68       return FXCODEC_STATUS_ERROR;
69     }
70     int dword_size = height * dest_pitch / 4;
71     FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
72     for (int i = 0; i < dword_size; i++) {
73       dword_buf[i] = ~dword_buf[i];
74     }
75     return FXCODEC_STATUS_DECODE_FINISH;
76   }
77   return m_pJbig2Context->m_pContext->GetProcessingStatus();
78 }
79 FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context,
80                                                   IFX_Pause* pPause) {
81   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
82   int ret = m_pJbig2Context->m_pContext->Continue(pPause);
83   if (m_pJbig2Context->m_pContext->GetProcessingStatus() !=
84       FXCODEC_STATUS_DECODE_FINISH) {
85     return m_pJbig2Context->m_pContext->GetProcessingStatus();
86   }
87   if (m_pJbig2Context->m_bFileReader) {
88     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
89     m_pJbig2Context->m_pContext = NULL;
90     if (ret != JBIG2_SUCCESS) {
91       FX_Free(m_pJbig2Context->m_src_buf);
92       m_pJbig2Context->m_src_buf = NULL;
93       return FXCODEC_STATUS_ERROR;
94     }
95     delete m_pJbig2Context->m_dest_image;
96     FX_Free(m_pJbig2Context->m_src_buf);
97     return FXCODEC_STATUS_DECODE_FINISH;
98   }
99   CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
100   m_pJbig2Context->m_pContext = NULL;
101   if (ret != JBIG2_SUCCESS) {
102     return FXCODEC_STATUS_ERROR;
103   }
104   int dword_size =
105       m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4;
106   FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf;
107   for (int i = 0; i < dword_size; i++) {
108     dword_buf[i] = ~dword_buf[i];
109   }
110   return FXCODEC_STATUS_DECODE_FINISH;
111 }