OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include <setjmp.h> | 7 #include <setjmp.h> |
8 | 8 |
9 #include "core/fxcodec/codec/codec_int.h" | 9 #include "core/fxcodec/codec/codec_int.h" |
10 #include "core/fxcodec/fx_codec.h" | 10 #include "core/fxcodec/fx_codec.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 src.skip_input_data = _src_skip_data; | 119 src.skip_input_data = _src_skip_data; |
120 src.fill_input_buffer = _src_fill_buffer; | 120 src.fill_input_buffer = _src_fill_buffer; |
121 src.resync_to_restart = _src_resync; | 121 src.resync_to_restart = _src_resync; |
122 src.bytes_in_buffer = src_size; | 122 src.bytes_in_buffer = src_size; |
123 src.next_input_byte = src_buf; | 123 src.next_input_byte = src_buf; |
124 cinfo.src = &src; | 124 cinfo.src = &src; |
125 if (setjmp(mark) == -1) { | 125 if (setjmp(mark) == -1) { |
126 jpeg_destroy_decompress(&cinfo); | 126 jpeg_destroy_decompress(&cinfo); |
127 return false; | 127 return false; |
128 } | 128 } |
129 int ret = jpeg_read_header(&cinfo, TRUE); | 129 int ret = jpeg_read_header(&cinfo, true); |
130 if (ret != JPEG_HEADER_OK) { | 130 if (ret != JPEG_HEADER_OK) { |
131 jpeg_destroy_decompress(&cinfo); | 131 jpeg_destroy_decompress(&cinfo); |
132 return false; | 132 return false; |
133 } | 133 } |
134 *width = cinfo.image_width; | 134 *width = cinfo.image_width; |
135 *height = cinfo.image_height; | 135 *height = cinfo.image_height; |
136 *num_components = cinfo.num_components; | 136 *num_components = cinfo.num_components; |
137 *color_transform = | 137 *color_transform = |
138 cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK; | 138 cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_space == JCS_YCCK; |
139 *bits_per_components = cinfo.data_precision; | 139 *bits_per_components = cinfo.data_precision; |
140 jpeg_destroy_decompress(&cinfo); | 140 jpeg_destroy_decompress(&cinfo); |
141 return true; | 141 return true; |
142 } | 142 } |
143 | 143 |
144 class CCodec_JpegDecoder : public CCodec_ScanlineDecoder { | 144 class CCodec_JpegDecoder : public CCodec_ScanlineDecoder { |
145 public: | 145 public: |
146 CCodec_JpegDecoder(); | 146 CCodec_JpegDecoder(); |
147 ~CCodec_JpegDecoder() override; | 147 ~CCodec_JpegDecoder() override; |
148 | 148 |
149 FX_BOOL Create(const uint8_t* src_buf, | 149 bool Create(const uint8_t* src_buf, |
150 uint32_t src_size, | 150 uint32_t src_size, |
151 int width, | 151 int width, |
152 int height, | 152 int height, |
153 int nComps, | 153 int nComps, |
154 FX_BOOL ColorTransform); | 154 bool ColorTransform); |
155 | 155 |
156 // CCodec_ScanlineDecoder | 156 // CCodec_ScanlineDecoder |
157 FX_BOOL v_Rewind() override; | 157 bool v_Rewind() override; |
158 uint8_t* v_GetNextLine() override; | 158 uint8_t* v_GetNextLine() override; |
159 uint32_t GetSrcOffset() override; | 159 uint32_t GetSrcOffset() override; |
160 | 160 |
161 FX_BOOL InitDecode(); | 161 bool InitDecode(); |
162 | 162 |
163 jmp_buf m_JmpBuf; | 163 jmp_buf m_JmpBuf; |
164 struct jpeg_decompress_struct cinfo; | 164 struct jpeg_decompress_struct cinfo; |
165 struct jpeg_error_mgr jerr; | 165 struct jpeg_error_mgr jerr; |
166 struct jpeg_source_mgr src; | 166 struct jpeg_source_mgr src; |
167 const uint8_t* m_SrcBuf; | 167 const uint8_t* m_SrcBuf; |
168 uint32_t m_SrcSize; | 168 uint32_t m_SrcSize; |
169 uint8_t* m_pScanlineBuf; | 169 uint8_t* m_pScanlineBuf; |
170 | 170 |
171 FX_BOOL m_bInited; | 171 bool m_bInited; |
172 FX_BOOL m_bStarted; | 172 bool m_bStarted; |
173 FX_BOOL m_bJpegTransform; | 173 bool m_bJpegTransform; |
174 | 174 |
175 protected: | 175 protected: |
176 uint32_t m_nDefaultScaleDenom; | 176 uint32_t m_nDefaultScaleDenom; |
177 }; | 177 }; |
178 | 178 |
179 CCodec_JpegDecoder::CCodec_JpegDecoder() { | 179 CCodec_JpegDecoder::CCodec_JpegDecoder() { |
180 m_pScanlineBuf = nullptr; | 180 m_pScanlineBuf = nullptr; |
181 m_bStarted = FALSE; | 181 m_bStarted = false; |
182 m_bInited = FALSE; | 182 m_bInited = false; |
183 FXSYS_memset(&cinfo, 0, sizeof(cinfo)); | 183 FXSYS_memset(&cinfo, 0, sizeof(cinfo)); |
184 FXSYS_memset(&jerr, 0, sizeof(jerr)); | 184 FXSYS_memset(&jerr, 0, sizeof(jerr)); |
185 FXSYS_memset(&src, 0, sizeof(src)); | 185 FXSYS_memset(&src, 0, sizeof(src)); |
186 m_nDefaultScaleDenom = 1; | 186 m_nDefaultScaleDenom = 1; |
187 } | 187 } |
188 | 188 |
189 CCodec_JpegDecoder::~CCodec_JpegDecoder() { | 189 CCodec_JpegDecoder::~CCodec_JpegDecoder() { |
190 FX_Free(m_pScanlineBuf); | 190 FX_Free(m_pScanlineBuf); |
191 if (m_bInited) | 191 if (m_bInited) |
192 jpeg_destroy_decompress(&cinfo); | 192 jpeg_destroy_decompress(&cinfo); |
193 } | 193 } |
194 | 194 |
195 FX_BOOL CCodec_JpegDecoder::InitDecode() { | 195 bool CCodec_JpegDecoder::InitDecode() { |
196 cinfo.err = &jerr; | 196 cinfo.err = &jerr; |
197 cinfo.client_data = &m_JmpBuf; | 197 cinfo.client_data = &m_JmpBuf; |
198 if (setjmp(m_JmpBuf) == -1) | 198 if (setjmp(m_JmpBuf) == -1) |
199 return FALSE; | 199 return false; |
200 | 200 |
201 jpeg_create_decompress(&cinfo); | 201 jpeg_create_decompress(&cinfo); |
202 m_bInited = TRUE; | 202 m_bInited = true; |
203 cinfo.src = &src; | 203 cinfo.src = &src; |
204 src.bytes_in_buffer = m_SrcSize; | 204 src.bytes_in_buffer = m_SrcSize; |
205 src.next_input_byte = m_SrcBuf; | 205 src.next_input_byte = m_SrcBuf; |
206 if (setjmp(m_JmpBuf) == -1) { | 206 if (setjmp(m_JmpBuf) == -1) { |
207 jpeg_destroy_decompress(&cinfo); | 207 jpeg_destroy_decompress(&cinfo); |
208 m_bInited = FALSE; | 208 m_bInited = false; |
209 return FALSE; | 209 return false; |
210 } | 210 } |
211 cinfo.image_width = m_OrigWidth; | 211 cinfo.image_width = m_OrigWidth; |
212 cinfo.image_height = m_OrigHeight; | 212 cinfo.image_height = m_OrigHeight; |
213 int ret = jpeg_read_header(&cinfo, TRUE); | 213 int ret = jpeg_read_header(&cinfo, true); |
214 if (ret != JPEG_HEADER_OK) | 214 if (ret != JPEG_HEADER_OK) |
215 return FALSE; | 215 return false; |
216 | 216 |
217 if (cinfo.saw_Adobe_marker) | 217 if (cinfo.saw_Adobe_marker) |
218 m_bJpegTransform = TRUE; | 218 m_bJpegTransform = true; |
219 | 219 |
220 if (cinfo.num_components == 3 && !m_bJpegTransform) | 220 if (cinfo.num_components == 3 && !m_bJpegTransform) |
221 cinfo.out_color_space = cinfo.jpeg_color_space; | 221 cinfo.out_color_space = cinfo.jpeg_color_space; |
222 | 222 |
223 m_OrigWidth = cinfo.image_width; | 223 m_OrigWidth = cinfo.image_width; |
224 m_OrigHeight = cinfo.image_height; | 224 m_OrigHeight = cinfo.image_height; |
225 m_OutputWidth = m_OrigWidth; | 225 m_OutputWidth = m_OrigWidth; |
226 m_OutputHeight = m_OrigHeight; | 226 m_OutputHeight = m_OrigHeight; |
227 m_nDefaultScaleDenom = cinfo.scale_denom; | 227 m_nDefaultScaleDenom = cinfo.scale_denom; |
228 return TRUE; | 228 return true; |
229 } | 229 } |
230 | 230 |
231 FX_BOOL CCodec_JpegDecoder::Create(const uint8_t* src_buf, | 231 bool CCodec_JpegDecoder::Create(const uint8_t* src_buf, |
232 uint32_t src_size, | 232 uint32_t src_size, |
233 int width, | 233 int width, |
234 int height, | 234 int height, |
235 int nComps, | 235 int nComps, |
236 FX_BOOL ColorTransform) { | 236 bool ColorTransform) { |
237 JpegScanSOI(&src_buf, &src_size); | 237 JpegScanSOI(&src_buf, &src_size); |
238 m_SrcBuf = src_buf; | 238 m_SrcBuf = src_buf; |
239 m_SrcSize = src_size; | 239 m_SrcSize = src_size; |
240 jerr.error_exit = _error_fatal; | 240 jerr.error_exit = _error_fatal; |
241 jerr.emit_message = _error_do_nothing1; | 241 jerr.emit_message = _error_do_nothing1; |
242 jerr.output_message = _error_do_nothing; | 242 jerr.output_message = _error_do_nothing; |
243 jerr.format_message = _error_do_nothing2; | 243 jerr.format_message = _error_do_nothing2; |
244 jerr.reset_error_mgr = _error_do_nothing; | 244 jerr.reset_error_mgr = _error_do_nothing; |
245 src.init_source = _src_do_nothing; | 245 src.init_source = _src_do_nothing; |
246 src.term_source = _src_do_nothing; | 246 src.term_source = _src_do_nothing; |
247 src.skip_input_data = _src_skip_data; | 247 src.skip_input_data = _src_skip_data; |
248 src.fill_input_buffer = _src_fill_buffer; | 248 src.fill_input_buffer = _src_fill_buffer; |
249 src.resync_to_restart = _src_resync; | 249 src.resync_to_restart = _src_resync; |
250 m_bJpegTransform = ColorTransform; | 250 m_bJpegTransform = ColorTransform; |
251 if (src_size > 1 && | 251 if (src_size > 1 && |
252 FXSYS_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) { | 252 FXSYS_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0) { |
253 ((uint8_t*)src_buf)[src_size - 2] = 0xFF; | 253 ((uint8_t*)src_buf)[src_size - 2] = 0xFF; |
254 ((uint8_t*)src_buf)[src_size - 1] = 0xD9; | 254 ((uint8_t*)src_buf)[src_size - 1] = 0xD9; |
255 } | 255 } |
256 m_OutputWidth = m_OrigWidth = width; | 256 m_OutputWidth = m_OrigWidth = width; |
257 m_OutputHeight = m_OrigHeight = height; | 257 m_OutputHeight = m_OrigHeight = height; |
258 if (!InitDecode()) | 258 if (!InitDecode()) |
259 return FALSE; | 259 return false; |
260 | 260 |
261 if (cinfo.num_components < nComps) | 261 if (cinfo.num_components < nComps) |
262 return FALSE; | 262 return false; |
263 | 263 |
264 if ((int)cinfo.image_width < width) | 264 if ((int)cinfo.image_width < width) |
265 return FALSE; | 265 return false; |
266 | 266 |
267 m_Pitch = | 267 m_Pitch = |
268 (static_cast<uint32_t>(cinfo.image_width) * cinfo.num_components + 3) / | 268 (static_cast<uint32_t>(cinfo.image_width) * cinfo.num_components + 3) / |
269 4 * 4; | 269 4 * 4; |
270 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); | 270 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); |
271 m_nComps = cinfo.num_components; | 271 m_nComps = cinfo.num_components; |
272 m_bpc = 8; | 272 m_bpc = 8; |
273 m_bStarted = FALSE; | 273 m_bStarted = false; |
274 return TRUE; | 274 return true; |
275 } | 275 } |
276 | 276 |
277 FX_BOOL CCodec_JpegDecoder::v_Rewind() { | 277 bool CCodec_JpegDecoder::v_Rewind() { |
278 if (m_bStarted) { | 278 if (m_bStarted) { |
279 jpeg_destroy_decompress(&cinfo); | 279 jpeg_destroy_decompress(&cinfo); |
280 if (!InitDecode()) { | 280 if (!InitDecode()) { |
281 return FALSE; | 281 return false; |
282 } | 282 } |
283 } | 283 } |
284 if (setjmp(m_JmpBuf) == -1) { | 284 if (setjmp(m_JmpBuf) == -1) { |
285 return FALSE; | 285 return false; |
286 } | 286 } |
287 cinfo.scale_denom = m_nDefaultScaleDenom; | 287 cinfo.scale_denom = m_nDefaultScaleDenom; |
288 m_OutputWidth = m_OrigWidth; | 288 m_OutputWidth = m_OrigWidth; |
289 m_OutputHeight = m_OrigHeight; | 289 m_OutputHeight = m_OrigHeight; |
290 if (!jpeg_start_decompress(&cinfo)) { | 290 if (!jpeg_start_decompress(&cinfo)) { |
291 jpeg_destroy_decompress(&cinfo); | 291 jpeg_destroy_decompress(&cinfo); |
292 return FALSE; | 292 return false; |
293 } | 293 } |
294 if ((int)cinfo.output_width > m_OrigWidth) { | 294 if ((int)cinfo.output_width > m_OrigWidth) { |
295 ASSERT(FALSE); | 295 ASSERT(false); |
296 return FALSE; | 296 return false; |
297 } | 297 } |
298 m_bStarted = TRUE; | 298 m_bStarted = true; |
299 return TRUE; | 299 return true; |
300 } | 300 } |
301 | 301 |
302 uint8_t* CCodec_JpegDecoder::v_GetNextLine() { | 302 uint8_t* CCodec_JpegDecoder::v_GetNextLine() { |
303 if (setjmp(m_JmpBuf) == -1) | 303 if (setjmp(m_JmpBuf) == -1) |
304 return nullptr; | 304 return nullptr; |
305 | 305 |
306 int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1); | 306 int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1); |
307 return nlines > 0 ? m_pScanlineBuf : nullptr; | 307 return nlines > 0 ? m_pScanlineBuf : nullptr; |
308 } | 308 } |
309 | 309 |
310 uint32_t CCodec_JpegDecoder::GetSrcOffset() { | 310 uint32_t CCodec_JpegDecoder::GetSrcOffset() { |
311 return (uint32_t)(m_SrcSize - src.bytes_in_buffer); | 311 return (uint32_t)(m_SrcSize - src.bytes_in_buffer); |
312 } | 312 } |
313 | 313 |
314 CCodec_ScanlineDecoder* CCodec_JpegModule::CreateDecoder( | 314 CCodec_ScanlineDecoder* CCodec_JpegModule::CreateDecoder(const uint8_t* src_buf, |
315 const uint8_t* src_buf, | 315 uint32_t src_size, |
316 uint32_t src_size, | 316 int width, |
317 int width, | 317 int height, |
318 int height, | 318 int nComps, |
319 int nComps, | 319 bool ColorTransform) { |
320 FX_BOOL ColorTransform) { | |
321 if (!src_buf || src_size == 0) | 320 if (!src_buf || src_size == 0) |
322 return nullptr; | 321 return nullptr; |
323 | 322 |
324 std::unique_ptr<CCodec_JpegDecoder> pDecoder(new CCodec_JpegDecoder); | 323 std::unique_ptr<CCodec_JpegDecoder> pDecoder(new CCodec_JpegDecoder); |
325 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, | 324 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, |
326 ColorTransform)) { | 325 ColorTransform)) { |
327 return nullptr; | 326 return nullptr; |
328 } | 327 } |
329 return pDecoder.release(); | 328 return pDecoder.release(); |
330 } | 329 } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 | 441 |
443 *width = ctx->m_Info.image_width; | 442 *width = ctx->m_Info.image_width; |
444 *height = ctx->m_Info.image_height; | 443 *height = ctx->m_Info.image_height; |
445 *nComps = ctx->m_Info.num_components; | 444 *nComps = ctx->m_Info.num_components; |
446 #ifdef PDF_ENABLE_XFA | 445 #ifdef PDF_ENABLE_XFA |
447 JpegLoadAttribute(&ctx->m_Info, pAttribute); | 446 JpegLoadAttribute(&ctx->m_Info, pAttribute); |
448 #endif | 447 #endif |
449 return 0; | 448 return 0; |
450 } | 449 } |
451 | 450 |
452 FX_BOOL CCodec_JpegModule::StartScanline(FXJPEG_Context* ctx, int down_scale) { | 451 bool CCodec_JpegModule::StartScanline(FXJPEG_Context* ctx, int down_scale) { |
453 if (setjmp(ctx->m_JumpMark) == -1) | 452 if (setjmp(ctx->m_JumpMark) == -1) |
454 return FALSE; | 453 return false; |
455 | 454 |
456 ctx->m_Info.scale_denom = down_scale; | 455 ctx->m_Info.scale_denom = down_scale; |
457 return !!jpeg_start_decompress(&ctx->m_Info); | 456 return !!jpeg_start_decompress(&ctx->m_Info); |
458 } | 457 } |
459 | 458 |
460 FX_BOOL CCodec_JpegModule::ReadScanline(FXJPEG_Context* ctx, | 459 bool CCodec_JpegModule::ReadScanline(FXJPEG_Context* ctx, |
461 unsigned char* dest_buf) { | 460 unsigned char* dest_buf) { |
462 if (setjmp(ctx->m_JumpMark) == -1) | 461 if (setjmp(ctx->m_JumpMark) == -1) |
463 return FALSE; | 462 return false; |
464 | 463 |
465 int nlines = jpeg_read_scanlines(&ctx->m_Info, &dest_buf, 1); | 464 int nlines = jpeg_read_scanlines(&ctx->m_Info, &dest_buf, 1); |
466 return nlines == 1; | 465 return nlines == 1; |
467 } | 466 } |
468 | 467 |
469 uint32_t CCodec_JpegModule::GetAvailInput(FXJPEG_Context* ctx, | 468 uint32_t CCodec_JpegModule::GetAvailInput(FXJPEG_Context* ctx, |
470 uint8_t** avail_buf_ptr) { | 469 uint8_t** avail_buf_ptr) { |
471 if (avail_buf_ptr) { | 470 if (avail_buf_ptr) { |
472 *avail_buf_ptr = nullptr; | 471 *avail_buf_ptr = nullptr; |
473 if (ctx->m_SrcMgr.bytes_in_buffer > 0) { | 472 if (ctx->m_SrcMgr.bytes_in_buffer > 0) { |
474 *avail_buf_ptr = (uint8_t*)ctx->m_SrcMgr.next_input_byte; | 473 *avail_buf_ptr = (uint8_t*)ctx->m_SrcMgr.next_input_byte; |
475 } | 474 } |
476 } | 475 } |
477 return (uint32_t)ctx->m_SrcMgr.bytes_in_buffer; | 476 return (uint32_t)ctx->m_SrcMgr.bytes_in_buffer; |
478 } | 477 } |
OLD | NEW |