Don't bother checking pointers before delete[] and FX_Free().
[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   FX_Free(src_buf);
86   return FALSE;
87 }
88 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context,
89                                                FX_DWORD width,
90                                                FX_DWORD height,
91                                                const uint8_t* src_buf,
92                                                FX_DWORD src_size,
93                                                const uint8_t* global_data,
94                                                FX_DWORD global_size,
95                                                uint8_t* dest_buf,
96                                                FX_DWORD dest_pitch,
97                                                IFX_Pause* pPause) {
98   if (!pJbig2Context) {
99     return FXCODEC_STATUS_ERR_PARAMS;
100   }
101   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
102   m_pJbig2Context->m_width = width;
103   m_pJbig2Context->m_height = height;
104   m_pJbig2Context->m_src_buf = (unsigned char*)src_buf;
105   m_pJbig2Context->m_src_size = src_size;
106   m_pJbig2Context->m_global_data = global_data;
107   m_pJbig2Context->m_global_size = global_size;
108   m_pJbig2Context->m_dest_buf = dest_buf;
109   m_pJbig2Context->m_dest_pitch = dest_pitch;
110   m_pJbig2Context->m_pPause = pPause;
111   m_pJbig2Context->m_bFileReader = FALSE;
112   FXSYS_memset(dest_buf, 0, height * dest_pitch);
113   m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(
114       &m_Module, (uint8_t*)global_data, global_size, (uint8_t*)src_buf,
115       src_size, JBIG2_EMBED_STREAM, &m_SymbolDictCache, pPause);
116   if (!m_pJbig2Context->m_pContext) {
117     return FXCODEC_STATUS_ERROR;
118   }
119   int ret = m_pJbig2Context->m_pContext->getFirstPage(dest_buf, width, height,
120                                                       dest_pitch, pPause);
121   if (m_pJbig2Context->m_pContext->GetProcessiveStatus() ==
122       FXCODEC_STATUS_DECODE_FINISH) {
123     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
124     m_pJbig2Context->m_pContext = NULL;
125     if (ret != JBIG2_SUCCESS) {
126       return FXCODEC_STATUS_ERROR;
127     }
128     int dword_size = height * dest_pitch / 4;
129     FX_DWORD* dword_buf = (FX_DWORD*)dest_buf;
130     for (int i = 0; i < dword_size; i++) {
131       dword_buf[i] = ~dword_buf[i];
132     }
133     return FXCODEC_STATUS_DECODE_FINISH;
134   }
135   return m_pJbig2Context->m_pContext->GetProcessiveStatus();
136 }
137 FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(void* pJbig2Context,
138                                                IFX_FileRead* file_ptr,
139                                                FX_DWORD& width,
140                                                FX_DWORD& height,
141                                                FX_DWORD& pitch,
142                                                uint8_t*& dest_buf,
143                                                IFX_Pause* pPause) {
144   if (!pJbig2Context) {
145     return FXCODEC_STATUS_ERR_PARAMS;
146   }
147   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
148   m_pJbig2Context->m_bFileReader = TRUE;
149   m_pJbig2Context->m_dest_image = NULL;
150   m_pJbig2Context->m_src_size = (FX_DWORD)file_ptr->GetSize();
151   m_pJbig2Context->m_src_buf = FX_Alloc(uint8_t, m_pJbig2Context->m_src_size);
152   int ret = 0;
153   if (!file_ptr->ReadBlock((void*)m_pJbig2Context->m_src_buf, 0,
154                            m_pJbig2Context->m_src_size)) {
155     goto failed;
156   }
157   m_pJbig2Context->m_pContext = CJBig2_Context::CreateContext(
158       &m_Module, NULL, 0, m_pJbig2Context->m_src_buf,
159       m_pJbig2Context->m_src_size, JBIG2_FILE_STREAM, &m_SymbolDictCache,
160       pPause);
161   if (m_pJbig2Context->m_pContext == NULL) {
162     goto failed;
163   }
164   ret = m_pJbig2Context->m_pContext->getFirstPage(
165       &m_pJbig2Context->m_dest_image, pPause);
166   if (m_pJbig2Context->m_pContext->GetProcessiveStatus() ==
167       FXCODEC_STATUS_DECODE_TOBECONTINUE) {
168     width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
169     height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
170     pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
171     dest_buf = m_pJbig2Context->m_dest_image->m_pData;
172     m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
173     return FXCODEC_STATUS_DECODE_TOBECONTINUE;
174   }
175   CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
176   m_pJbig2Context->m_pContext = NULL;
177   if (ret != JBIG2_SUCCESS) {
178     goto failed;
179   }
180   width = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nWidth;
181   height = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nHeight;
182   pitch = (FX_DWORD)m_pJbig2Context->m_dest_image->m_nStride;
183   dest_buf = m_pJbig2Context->m_dest_image->m_pData;
184   m_pJbig2Context->m_dest_image->m_bNeedFree = FALSE;
185   delete m_pJbig2Context->m_dest_image;
186   FX_Free(m_pJbig2Context->m_src_buf);
187   return FXCODEC_STATUS_DECODE_FINISH;
188 failed:
189   FX_Free(m_pJbig2Context->m_src_buf);
190   m_pJbig2Context->m_src_buf = NULL;
191   return FXCODEC_STATUS_ERROR;
192 }
193 FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(void* pJbig2Context,
194                                                   IFX_Pause* pPause) {
195   CCodec_Jbig2Context* m_pJbig2Context = (CCodec_Jbig2Context*)pJbig2Context;
196   int ret = m_pJbig2Context->m_pContext->Continue(pPause);
197   if (m_pJbig2Context->m_pContext->GetProcessiveStatus() !=
198       FXCODEC_STATUS_DECODE_FINISH) {
199     return m_pJbig2Context->m_pContext->GetProcessiveStatus();
200   }
201   if (m_pJbig2Context->m_bFileReader) {
202     CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
203     m_pJbig2Context->m_pContext = NULL;
204     if (ret != JBIG2_SUCCESS) {
205       FX_Free(m_pJbig2Context->m_src_buf);
206       m_pJbig2Context->m_src_buf = NULL;
207       return FXCODEC_STATUS_ERROR;
208     }
209     delete m_pJbig2Context->m_dest_image;
210     FX_Free(m_pJbig2Context->m_src_buf);
211     return FXCODEC_STATUS_DECODE_FINISH;
212   }
213   CJBig2_Context::DestroyContext(m_pJbig2Context->m_pContext);
214   m_pJbig2Context->m_pContext = NULL;
215   if (ret != JBIG2_SUCCESS) {
216     return FXCODEC_STATUS_ERROR;
217   }
218   int dword_size =
219       m_pJbig2Context->m_height * m_pJbig2Context->m_dest_pitch / 4;
220   FX_DWORD* dword_buf = (FX_DWORD*)m_pJbig2Context->m_dest_buf;
221   for (int i = 0; i < dword_size; i++) {
222     dword_buf[i] = ~dword_buf[i];
223   }
224   return FXCODEC_STATUS_DECODE_FINISH;
225 }