9d78bba3bb1b3e645978bf790e0d9129efd9de6f
[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 CCodec_Jbig2Module::~CCodec_Jbig2Module() {}
14 void* CCodec_Jbig2Module::CreateJbig2Context() {
15   return new CCodec_Jbig2Context();
16 }
17 void CCodec_Jbig2Module::DestroyJbig2Context(void* pJbig2Content) {
18   if (pJbig2Content) {
19     CJBig2_Context::DestroyContext(
20         ((CCodec_Jbig2Context*)pJbig2Content)->m_pContext);
21     delete (CCodec_Jbig2Context*)pJbig2Content;
22   }
23   pJbig2Content = NULL;
24 }
25 FX_BOOL CCodec_Jbig2Module::Decode(FX_DWORD width,
26                                    FX_DWORD height,
27                                    const uint8_t* src_buf,
28                                    FX_DWORD src_size,
29                                    const uint8_t* global_data,
30                                    FX_DWORD global_size,
31                                    uint8_t* dest_buf,
32                                    FX_DWORD dest_pitch) {
33   FXSYS_memset(dest_buf, 0, height * dest_pitch);
34   CJBig2_Context* pContext = CJBig2_Context::CreateContext(
35       &m_Module, (uint8_t*)global_data, global_size, (uint8_t*)src_buf,
36       src_size, JBIG2_EMBED_STREAM, &m_SymbolDictCache);
37   if (pContext == NULL) {
38     return FALSE;
39   }
40   int ret = pContext->getFirstPage(dest_buf, width, height, dest_pitch, NULL);
41   CJBig2_Context::DestroyContext(pContext);
42   if (ret != JBIG2_SUCCESS) {
43     return FALSE;
44   }
45   int dword_size = height * dest_pitch / 4;
46   FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
47   for (int i = 0; i < dword_size; i++) {
48     dword_buf[i] = ~dword_buf[i];
49   }
50   return TRUE;
51 }
52 FX_BOOL CCodec_Jbig2Module::Decode(IFX_FileRead* file_ptr,
53                                    FX_DWORD& width,
54                                    FX_DWORD& height,
55                                    FX_DWORD& pitch,
56                                    uint8_t*& dest_buf) {
57   CJBig2_Context* pContext = NULL;
58   CJBig2_Image* dest_image = NULL;
59   FX_DWORD src_size = (FX_DWORD)file_ptr->GetSize();
60   uint8_t* src_buf = FX_Alloc(uint8_t, src_size);
61   int ret = 0;
62   if (!file_ptr->ReadBlock(src_buf, 0, src_size)) {
63     goto failed;
64   }
65   pContext =
66       CJBig2_Context::CreateContext(&m_Module, NULL, 0, src_buf, src_size,
67                                     JBIG2_FILE_STREAM, &m_SymbolDictCache);
68   if (pContext == NULL) {
69     goto failed;
70   }
71   ret = pContext->getFirstPage(&dest_image, NULL);
72   CJBig2_Context::DestroyContext(pContext);
73   if (ret != JBIG2_SUCCESS) {
74     goto failed;
75   }
76   width = (FX_DWORD)dest_image->m_nWidth;
77   height = (FX_DWORD)dest_image->m_nHeight;
78   pitch = (FX_DWORD)dest_image->m_nStride;
79   dest_buf = dest_image->m_pData;
80   dest_image->m_bNeedFree = FALSE;
81   delete dest_image;
82   FX_Free(src_buf);
83   return TRUE;
84 failed:
85   if (src_buf) {
86     FX_Free(src_buf);
87   }
88   return FALSE;
89 }
90 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context,
91                                                FX_DWORD width,
92                                                FX_DWORD height,
93                                                const uint8_t* src_buf,
94                                                FX_DWORD src_size,
95                                                const uint8_t* global_data,
96                                                FX_DWORD global_size,
97                                                uint8_t* dest_buf,
98                                                FX_DWORD dest_pitch,
99                                                IFX_Pause* pPause) {
100   if (!pJbig2Context) {
101     return FXCODEC_STATUS_ERR_PARAMS;
102   }
103   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
104   m_pJbig2Context->m_width = width;
105   m_pJbig2Context->m_height = height;
106   m_pJbig2Context->m_src_buf = (unsigned char*)src_buf;
107   m_pJbig2Context->m_src_size = src_size;
108   m_pJbig2Context->m_global_data = global_data;
109   m_pJbig2Context->m_global_size = global_size;
110   m_pJbig2Context->m_dest_buf = dest_buf;
111   m_pJbig2Context->m_dest_pitch = dest_pitch;
112   m_pJbig2Context->m_pPause = pPause;
113   m_pJbig2Context->m_bFileReader = FALSE;
114   FXSYS_memset(dest_buf, 0, height * dest_pitch);
115   m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(
116       &m_Module, (uint8_t*)global_data, global_size, (uint8_t*)src_buf,
117       src_size, JBIG2_EMBED_STREAM, &m_SymbolDictCache, pPause);
118   if (!m_pJbig2Context->m_pContext) {
119     return FXCODEC_STATUS_ERROR;
120   }
121   int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height,
122                                                       dest_pitch, pPause);
123   if (m_pJbig2Context->m_pContext->GetProcessiveStatus() ==
124       FXCODEC_STATUS_DECODE_FINISH) {
125     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
126     m_pJbig2Context->m_pContext = NULL;
127     if (ret != JBIG2_SUCCESS) {
128       return FXCODEC_STATUS_ERROR;
129     }
130     int dword_size = height * dest_pitch / 4;
131     FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
132     for (int i = 0; i < dword_size; i++) {
133       dword_buf[i] = ~dword_buf[i];
134     }
135     return FXCODEC_STATUS_DECODE_FINISH;
136   }
137   return m_pJbig2Context->m_pContext->GetProcessiveStatus();
138 }
139 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context,
140                                                IFX_FileRead* file_ptr,
141                                                FX_DWORD& width,
142                                                FX_DWORD& height,
143                                                FX_DWORD& pitch,
144                                                uint8_t*& dest_buf,
145                                                IFX_Pause* pPause) {
146   if (!pJbig2Context) {
147     return FXCODEC_STATUS_ERR_PARAMS;
148   }
149   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
150   m_pJbig2Context->m_bFileReader = TRUE;
151   m_pJbig2Context->m_dest_image = NULL;
152   m_pJbig2Context->m_src_size = (FX_DWORD)file_ptr->GetSize();
153   m_pJbig2Context->m_src_buf = FX_Alloc(uint8_t, m_pJbig2Context->m_src_size);
154   int ret = 0;
155   if (!file_ptr->ReadBlock((void*)m_pJbig2Context->m_src_buf, 0,
156                            m_pJbig2Context->m_src_size)) {
157     goto failed;
158   }
159   m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(
160       &m_Module, NULL, 0, m_pJbig2Context->m_src_buf,
161       m_pJbig2Context->m_src_size, JBIG2_FILE_STREAM, &m_SymbolDictCache,
162       pPause);
163   if (m_pJbig2Context->m_pContext == NULL) {
164     goto failed;
165   }
166   ret = m_pJbig2Context->m_pContext->getFirstPage(
167       &m_pJbig2Context->m_dest_image, pPause);
168   if (m_pJbig2Context->m_pContext->GetProcessiveStatus() ==
169       FXCODEC_STATUS_DECODE_TOBECONTINUE) {
170     width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
171     height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
172     pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
173     dest_buf = m_pJbig2Context->m_dest_image->m_pData;
174     m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
175     return FXCODEC_STATUS_DECODE_TOBECONTINUE;
176   }
177   CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
178   m_pJbig2Context->m_pContext = NULL;
179   if (ret != JBIG2_SUCCESS) {
180     goto failed;
181   }
182   width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
183   height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
184   pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
185   dest_buf = m_pJbig2Context->m_dest_image->m_pData;
186   m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
187   delete m_pJbig2Context->m_dest_image;
188   FX_Free(m_pJbig2Context->m_src_buf);
189   return FXCODEC_STATUS_DECODE_FINISH;
190 failed:
191   if (m_pJbig2Context->m_src_buf) {
192     FX_Free(m_pJbig2Context->m_src_buf);
193   }
194   m_pJbig2Context->m_src_buf = NULL;
195   return FXCODEC_STATUS_ERROR;
196 }
197 FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context,
198                                                   IFX_Pause* pPause) {
199   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
200   int ret = m_pJbig2Context->m_pContext->Continue(pPause);
201   if (m_pJbig2Context->m_pContext->GetProcessiveStatus() !=
202       FXCODEC_STATUS_DECODE_FINISH) {
203     return m_pJbig2Context->m_pContext->GetProcessiveStatus();
204   }
205   if (m_pJbig2Context->m_bFileReader) {
206     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
207     m_pJbig2Context->m_pContext = NULL;
208     if (ret != JBIG2_SUCCESS) {
209       if (m_pJbig2Context->m_src_buf) {
210         FX_Free(m_pJbig2Context->m_src_buf);
211       }
212       m_pJbig2Context->m_src_buf = NULL;
213       return FXCODEC_STATUS_ERROR;
214     }
215     delete m_pJbig2Context->m_dest_image;
216     FX_Free(m_pJbig2Context->m_src_buf);
217     return FXCODEC_STATUS_DECODE_FINISH;
218   }
219   CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
220   m_pJbig2Context->m_pContext = NULL;
221   if (ret != JBIG2_SUCCESS) {
222     return FXCODEC_STATUS_ERROR;
223   }
224   int dword_size =
225       m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4;
226   FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf;
227   for (int i = 0; i < dword_size; i++) {
228     dword_buf[i] = ~dword_buf[i];
229   }
230   return FXCODEC_STATUS_DECODE_FINISH;
231 }