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