| 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 |