| 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 "../../../include/fxcodec/fx_codec.h" | 9 #include "../../../include/fxcodec/fx_codec.h" |
| 10 #include "../../../include/fxcrt/fx_safe_types.h" | 10 #include "../../../include/fxcrt/fx_safe_types.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 static void _error_do_nothing1(j_common_ptr cinfo, int) {} | 71 static void _error_do_nothing1(j_common_ptr cinfo, int) {} |
| 72 }; | 72 }; |
| 73 extern "C" { | 73 extern "C" { |
| 74 static void _error_do_nothing2(j_common_ptr cinfo, char*) {} | 74 static void _error_do_nothing2(j_common_ptr cinfo, char*) {} |
| 75 }; | 75 }; |
| 76 #define JPEG_MARKER_EXIF (JPEG_APP0 + 1) | 76 #define JPEG_MARKER_EXIF (JPEG_APP0 + 1) |
| 77 #define JPEG_MARKER_ICC (JPEG_APP0 + 2) | 77 #define JPEG_MARKER_ICC (JPEG_APP0 + 2) |
| 78 #define JPEG_MARKER_AUTHORTIME (JPEG_APP0 + 3) | 78 #define JPEG_MARKER_AUTHORTIME (JPEG_APP0 + 3) |
| 79 #define JPEG_MARKER_MAXSIZE 0xFFFF | 79 #define JPEG_MARKER_MAXSIZE 0xFFFF |
| 80 #define JPEG_OVERHEAD_LEN 14 | 80 #define JPEG_OVERHEAD_LEN 14 |
| 81 static» FX_BOOL _JpegEmbedIccProfile(j_compress_ptr cinfo, const uint8_t* icc_bu
f_ptr, FX_DWORD icc_length) | 81 static» bool _JpegEmbedIccProfile(j_compress_ptr cinfo, const uint8_t* icc_buf_p
tr, FX_DWORD icc_length) |
| 82 { | 82 { |
| 83 if(icc_buf_ptr == NULL || icc_length == 0) { | 83 if(icc_buf_ptr == NULL || icc_length == 0) { |
| 84 return FALSE; | 84 return false; |
| 85 } | 85 } |
| 86 FX_DWORD icc_segment_size = (JPEG_MARKER_MAXSIZE - 2 - JPEG_OVERHEAD_LEN); | 86 FX_DWORD icc_segment_size = (JPEG_MARKER_MAXSIZE - 2 - JPEG_OVERHEAD_LEN); |
| 87 FX_DWORD icc_segment_num = (icc_length / icc_segment_size) + 1; | 87 FX_DWORD icc_segment_num = (icc_length / icc_segment_size) + 1; |
| 88 if (icc_segment_num > 255) { | 88 if (icc_segment_num > 255) { |
| 89 return FALSE; | 89 return false; |
| 90 } | 90 } |
| 91 FX_DWORD icc_data_length = JPEG_OVERHEAD_LEN + (icc_segment_num > 1 ? icc_se
gment_size : icc_length); | 91 FX_DWORD icc_data_length = JPEG_OVERHEAD_LEN + (icc_segment_num > 1 ? icc_se
gment_size : icc_length); |
| 92 uint8_t* icc_data = FX_Alloc(uint8_t, icc_data_length); | 92 uint8_t* icc_data = FX_Alloc(uint8_t, icc_data_length); |
| 93 FXSYS_memcpy(icc_data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 1
2); | 93 FXSYS_memcpy(icc_data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 1
2); |
| 94 icc_data[13] = (uint8_t)icc_segment_num; | 94 icc_data[13] = (uint8_t)icc_segment_num; |
| 95 for (uint8_t i = 0; i < (icc_segment_num - 1); i++) { | 95 for (uint8_t i = 0; i < (icc_segment_num - 1); i++) { |
| 96 icc_data[12] = i + 1; | 96 icc_data[12] = i + 1; |
| 97 FXSYS_memcpy(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + i * icc_segment
_size, icc_segment_size); | 97 FXSYS_memcpy(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + i * icc_segment
_size, icc_segment_size); |
| 98 jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, icc_data_length); | 98 jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, icc_data_length); |
| 99 } | 99 } |
| 100 icc_data[12] = (uint8_t)icc_segment_num; | 100 icc_data[12] = (uint8_t)icc_segment_num; |
| 101 FX_DWORD icc_size = (icc_segment_num - 1) * icc_segment_size; | 101 FX_DWORD icc_size = (icc_segment_num - 1) * icc_segment_size; |
| 102 FXSYS_memcpy(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + icc_size, icc_lengt
h - icc_size); | 102 FXSYS_memcpy(icc_data + JPEG_OVERHEAD_LEN, icc_buf_ptr + icc_size, icc_lengt
h - icc_size); |
| 103 jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, JPEG_OVERHEAD_LEN + icc_
length - icc_size); | 103 jpeg_write_marker(cinfo, JPEG_MARKER_ICC, icc_data, JPEG_OVERHEAD_LEN + icc_
length - icc_size); |
| 104 FX_Free(icc_data); | 104 FX_Free(icc_data); |
| 105 return TRUE; | 105 return true; |
| 106 } | 106 } |
| 107 extern "C" { | 107 extern "C" { |
| 108 static void _dest_do_nothing(j_compress_ptr cinfo) {} | 108 static void _dest_do_nothing(j_compress_ptr cinfo) {} |
| 109 }; | 109 }; |
| 110 extern "C" { | 110 extern "C" { |
| 111 static boolean _dest_empty(j_compress_ptr cinfo) | 111 static boolean _dest_empty(j_compress_ptr cinfo) |
| 112 { | 112 { |
| 113 return FALSE; | 113 return false; |
| 114 } | 114 } |
| 115 }; | 115 }; |
| 116 #define JPEG_BLOCK_SIZE 1048576 | 116 #define JPEG_BLOCK_SIZE 1048576 |
| 117 static void _JpegEncode(const CFX_DIBSource* pSource, uint8_t*& dest_buf, FX_STR
SIZE& dest_size, int quality, const uint8_t* icc_buf, FX_DWORD icc_length) | 117 static void _JpegEncode(const CFX_DIBSource* pSource, uint8_t*& dest_buf, FX_STR
SIZE& dest_size, int quality, const uint8_t* icc_buf, FX_DWORD icc_length) |
| 118 { | 118 { |
| 119 struct jpeg_error_mgr jerr; | 119 struct jpeg_error_mgr jerr; |
| 120 jerr.error_exit = _error_do_nothing; | 120 jerr.error_exit = _error_do_nothing; |
| 121 jerr.emit_message = _error_do_nothing1; | 121 jerr.emit_message = _error_do_nothing1; |
| 122 jerr.output_message = _error_do_nothing; | 122 jerr.output_message = _error_do_nothing; |
| 123 jerr.format_message = _error_do_nothing2; | 123 jerr.format_message = _error_do_nothing2; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 cinfo.in_color_space = JCS_RGB; | 171 cinfo.in_color_space = JCS_RGB; |
| 172 } else { | 172 } else { |
| 173 cinfo.in_color_space = JCS_CMYK; | 173 cinfo.in_color_space = JCS_CMYK; |
| 174 } | 174 } |
| 175 uint8_t* line_buf = NULL; | 175 uint8_t* line_buf = NULL; |
| 176 if (nComponents > 1) { | 176 if (nComponents > 1) { |
| 177 line_buf = FX_Alloc2D(uint8_t, width, nComponents); | 177 line_buf = FX_Alloc2D(uint8_t, width, nComponents); |
| 178 } | 178 } |
| 179 jpeg_set_defaults(&cinfo); | 179 jpeg_set_defaults(&cinfo); |
| 180 if(quality != 75) { | 180 if(quality != 75) { |
| 181 jpeg_set_quality(&cinfo, quality, TRUE); | 181 jpeg_set_quality(&cinfo, quality, true); |
| 182 } | 182 } |
| 183 jpeg_start_compress(&cinfo, TRUE); | 183 jpeg_start_compress(&cinfo, true); |
| 184 _JpegEmbedIccProfile(&cinfo, icc_buf, icc_length); | 184 _JpegEmbedIccProfile(&cinfo, icc_buf, icc_length); |
| 185 JSAMPROW row_pointer[1]; | 185 JSAMPROW row_pointer[1]; |
| 186 JDIMENSION row; | 186 JDIMENSION row; |
| 187 while (cinfo.next_scanline < cinfo.image_height) { | 187 while (cinfo.next_scanline < cinfo.image_height) { |
| 188 const uint8_t* src_scan = pSource->GetScanline(cinfo.next_scanline); | 188 const uint8_t* src_scan = pSource->GetScanline(cinfo.next_scanline); |
| 189 if (nComponents > 1) { | 189 if (nComponents > 1) { |
| 190 uint8_t* dest_scan = line_buf; | 190 uint8_t* dest_scan = line_buf; |
| 191 if (nComponents == 3) { | 191 if (nComponents == 3) { |
| 192 for (int i = 0; i < width; i ++) { | 192 for (int i = 0; i < width; i ++) { |
| 193 dest_scan[0] = src_scan[2]; | 193 dest_scan[0] = src_scan[2]; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 214 dest.free_in_buffer += JPEG_BLOCK_SIZE; | 214 dest.free_in_buffer += JPEG_BLOCK_SIZE; |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 jpeg_finish_compress(&cinfo); | 217 jpeg_finish_compress(&cinfo); |
| 218 jpeg_destroy_compress(&cinfo); | 218 jpeg_destroy_compress(&cinfo); |
| 219 if (line_buf) { | 219 if (line_buf) { |
| 220 FX_Free(line_buf); | 220 FX_Free(line_buf); |
| 221 } | 221 } |
| 222 dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer; | 222 dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer; |
| 223 } | 223 } |
| 224 static FX_BOOL _JpegLoadInfo(const uint8_t* src_buf, FX_DWORD src_size, int& wid
th, int& height, | 224 static bool _JpegLoadInfo(const uint8_t* src_buf, FX_DWORD src_size, int& width,
int& height, |
| 225 int& num_components, int& bits_per_components, FX_B
OOL& color_transform, | 225 int& num_components, int& bits_per_components, bool
& color_transform, |
| 226 uint8_t** icc_buf_ptr, FX_DWORD* icc_length) | 226 uint8_t** icc_buf_ptr, FX_DWORD* icc_length) |
| 227 { | 227 { |
| 228 _JpegScanSOI(src_buf, src_size); | 228 _JpegScanSOI(src_buf, src_size); |
| 229 struct jpeg_decompress_struct cinfo; | 229 struct jpeg_decompress_struct cinfo; |
| 230 struct jpeg_error_mgr jerr; | 230 struct jpeg_error_mgr jerr; |
| 231 jerr.error_exit = _error_fatal; | 231 jerr.error_exit = _error_fatal; |
| 232 jerr.emit_message = _error_do_nothing1; | 232 jerr.emit_message = _error_do_nothing1; |
| 233 jerr.output_message = _error_do_nothing; | 233 jerr.output_message = _error_do_nothing; |
| 234 jerr.format_message = _error_do_nothing2; | 234 jerr.format_message = _error_do_nothing2; |
| 235 jerr.reset_error_mgr = _error_do_nothing; | 235 jerr.reset_error_mgr = _error_do_nothing; |
| 236 jerr.trace_level = 0; | 236 jerr.trace_level = 0; |
| 237 cinfo.err = &jerr; | 237 cinfo.err = &jerr; |
| 238 jmp_buf mark; | 238 jmp_buf mark; |
| 239 cinfo.client_data = &mark; | 239 cinfo.client_data = &mark; |
| 240 if (setjmp(mark) == -1) { | 240 if (setjmp(mark) == -1) { |
| 241 return FALSE; | 241 return false; |
| 242 } | 242 } |
| 243 jpeg_create_decompress(&cinfo); | 243 jpeg_create_decompress(&cinfo); |
| 244 struct jpeg_source_mgr src; | 244 struct jpeg_source_mgr src; |
| 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 src.bytes_in_buffer = src_size; | 250 src.bytes_in_buffer = src_size; |
| 251 src.next_input_byte = src_buf; | 251 src.next_input_byte = src_buf; |
| 252 cinfo.src = &src; | 252 cinfo.src = &src; |
| 253 if (setjmp(mark) == -1) { | 253 if (setjmp(mark) == -1) { |
| 254 jpeg_destroy_decompress(&cinfo); | 254 jpeg_destroy_decompress(&cinfo); |
| 255 return FALSE; | 255 return false; |
| 256 } | 256 } |
| 257 if(icc_buf_ptr && icc_length) { | 257 if(icc_buf_ptr && icc_length) { |
| 258 jpeg_save_markers(&cinfo, JPEG_MARKER_ICC, JPEG_MARKER_MAXSIZE); | 258 jpeg_save_markers(&cinfo, JPEG_MARKER_ICC, JPEG_MARKER_MAXSIZE); |
| 259 } | 259 } |
| 260 int ret = jpeg_read_header(&cinfo, TRUE); | 260 int ret = jpeg_read_header(&cinfo, true); |
| 261 if (ret != JPEG_HEADER_OK) { | 261 if (ret != JPEG_HEADER_OK) { |
| 262 jpeg_destroy_decompress(&cinfo); | 262 jpeg_destroy_decompress(&cinfo); |
| 263 return FALSE; | 263 return false; |
| 264 } | 264 } |
| 265 width = cinfo.image_width; | 265 width = cinfo.image_width; |
| 266 height = cinfo.image_height; | 266 height = cinfo.image_height; |
| 267 num_components = cinfo.num_components; | 267 num_components = cinfo.num_components; |
| 268 color_transform = cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_sp
ace == JCS_YCCK; | 268 color_transform = cinfo.jpeg_color_space == JCS_YCbCr || cinfo.jpeg_color_sp
ace == JCS_YCCK; |
| 269 bits_per_components = cinfo.data_precision; | 269 bits_per_components = cinfo.data_precision; |
| 270 if(icc_buf_ptr != NULL) { | 270 if(icc_buf_ptr != NULL) { |
| 271 *icc_buf_ptr = NULL; | 271 *icc_buf_ptr = NULL; |
| 272 } | 272 } |
| 273 if(icc_length != NULL) { | 273 if(icc_length != NULL) { |
| 274 *icc_length = 0; | 274 *icc_length = 0; |
| 275 } | 275 } |
| 276 jpeg_destroy_decompress(&cinfo); | 276 jpeg_destroy_decompress(&cinfo); |
| 277 return TRUE; | 277 return true; |
| 278 } | 278 } |
| 279 class CCodec_JpegDecoder : public CCodec_ScanlineDecoder | 279 class CCodec_JpegDecoder : public CCodec_ScanlineDecoder |
| 280 { | 280 { |
| 281 public: | 281 public: |
| 282 CCodec_JpegDecoder(); | 282 CCodec_JpegDecoder(); |
| 283 ~CCodec_JpegDecoder(); | 283 ~CCodec_JpegDecoder(); |
| 284 FX_BOOL» » » » Create(const uint8_t* src_buf, FX_DWORD
src_size, int width, int height, int nComps, | 284 bool» » » » Create(const uint8_t* src_buf, FX_DWORD
src_size, int width, int height, int nComps, |
| 285 FX_BOOL ColorTransform, IFX_JpegProvider* pJP); | 285 bool ColorTransform, IFX_JpegProvider* pJP); |
| 286 virtual void Destroy() | 286 virtual void Destroy() |
| 287 { | 287 { |
| 288 delete this; | 288 delete this; |
| 289 } | 289 } |
| 290 virtual void v_DownScale(int dest_width, int dest_height); | 290 virtual void v_DownScale(int dest_width, int dest_height); |
| 291 virtual FX_BOOL» » v_Rewind(); | 291 virtual bool» » v_Rewind(); |
| 292 virtual uint8_t* v_GetNextLine(); | 292 virtual uint8_t* v_GetNextLine(); |
| 293 virtual FX_DWORD GetSrcOffset(); | 293 virtual FX_DWORD GetSrcOffset(); |
| 294 jmp_buf m_JmpBuf; | 294 jmp_buf m_JmpBuf; |
| 295 struct jpeg_decompress_struct cinfo; | 295 struct jpeg_decompress_struct cinfo; |
| 296 struct jpeg_error_mgr jerr; | 296 struct jpeg_error_mgr jerr; |
| 297 struct jpeg_source_mgr src; | 297 struct jpeg_source_mgr src; |
| 298 const uint8_t* m_SrcBuf; | 298 const uint8_t* m_SrcBuf; |
| 299 FX_DWORD m_SrcSize; | 299 FX_DWORD m_SrcSize; |
| 300 uint8_t* m_pScanlineBuf; | 300 uint8_t* m_pScanlineBuf; |
| 301 FX_BOOL» » InitDecode(); | 301 bool» » InitDecode(); |
| 302 FX_BOOL» » m_bInited, m_bStarted, m_bJpegTransform; | 302 bool» » m_bInited, m_bStarted, m_bJpegTransform; |
| 303 protected: | 303 protected: |
| 304 IFX_JpegProvider* m_pExtProvider; | 304 IFX_JpegProvider* m_pExtProvider; |
| 305 void* m_pExtContext; | 305 void* m_pExtContext; |
| 306 FX_DWORD m_nDefaultScaleDenom; | 306 FX_DWORD m_nDefaultScaleDenom; |
| 307 }; | 307 }; |
| 308 CCodec_JpegDecoder::CCodec_JpegDecoder() | 308 CCodec_JpegDecoder::CCodec_JpegDecoder() |
| 309 { | 309 { |
| 310 m_pScanlineBuf = NULL; | 310 m_pScanlineBuf = NULL; |
| 311 m_DownScale = 1; | 311 m_DownScale = 1; |
| 312 m_bStarted = FALSE; | 312 m_bStarted = false; |
| 313 m_bInited = FALSE; | 313 m_bInited = false; |
| 314 m_pExtProvider = NULL; | 314 m_pExtProvider = NULL; |
| 315 m_pExtContext = NULL; | 315 m_pExtContext = NULL; |
| 316 FXSYS_memset(&cinfo, 0, sizeof(cinfo)); | 316 FXSYS_memset(&cinfo, 0, sizeof(cinfo)); |
| 317 FXSYS_memset(&jerr, 0, sizeof(jerr)); | 317 FXSYS_memset(&jerr, 0, sizeof(jerr)); |
| 318 FXSYS_memset(&src, 0, sizeof(src)); | 318 FXSYS_memset(&src, 0, sizeof(src)); |
| 319 m_nDefaultScaleDenom = 1; | 319 m_nDefaultScaleDenom = 1; |
| 320 } | 320 } |
| 321 CCodec_JpegDecoder::~CCodec_JpegDecoder() | 321 CCodec_JpegDecoder::~CCodec_JpegDecoder() |
| 322 { | 322 { |
| 323 if (m_pExtProvider) { | 323 if (m_pExtProvider) { |
| 324 m_pExtProvider->DestroyDecoder(m_pExtContext); | 324 m_pExtProvider->DestroyDecoder(m_pExtContext); |
| 325 return; | 325 return; |
| 326 } | 326 } |
| 327 if (m_pScanlineBuf) { | 327 if (m_pScanlineBuf) { |
| 328 FX_Free(m_pScanlineBuf); | 328 FX_Free(m_pScanlineBuf); |
| 329 } | 329 } |
| 330 if (m_bInited) { | 330 if (m_bInited) { |
| 331 jpeg_destroy_decompress(&cinfo); | 331 jpeg_destroy_decompress(&cinfo); |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 FX_BOOL CCodec_JpegDecoder::InitDecode() | 334 bool CCodec_JpegDecoder::InitDecode() |
| 335 { | 335 { |
| 336 cinfo.err = &jerr; | 336 cinfo.err = &jerr; |
| 337 cinfo.client_data = &m_JmpBuf; | 337 cinfo.client_data = &m_JmpBuf; |
| 338 if (setjmp(m_JmpBuf) == -1) { | 338 if (setjmp(m_JmpBuf) == -1) { |
| 339 return FALSE; | 339 return false; |
| 340 } | 340 } |
| 341 jpeg_create_decompress(&cinfo); | 341 jpeg_create_decompress(&cinfo); |
| 342 m_bInited = TRUE; | 342 m_bInited = true; |
| 343 cinfo.src = &src; | 343 cinfo.src = &src; |
| 344 src.bytes_in_buffer = m_SrcSize; | 344 src.bytes_in_buffer = m_SrcSize; |
| 345 src.next_input_byte = m_SrcBuf; | 345 src.next_input_byte = m_SrcBuf; |
| 346 if (setjmp(m_JmpBuf) == -1) { | 346 if (setjmp(m_JmpBuf) == -1) { |
| 347 jpeg_destroy_decompress(&cinfo); | 347 jpeg_destroy_decompress(&cinfo); |
| 348 m_bInited = FALSE; | 348 m_bInited = false; |
| 349 return FALSE; | 349 return false; |
| 350 } | 350 } |
| 351 cinfo.image_width = m_OrigWidth; | 351 cinfo.image_width = m_OrigWidth; |
| 352 cinfo.image_height = m_OrigHeight; | 352 cinfo.image_height = m_OrigHeight; |
| 353 int ret = jpeg_read_header(&cinfo, TRUE); | 353 int ret = jpeg_read_header(&cinfo, true); |
| 354 if (ret != JPEG_HEADER_OK) { | 354 if (ret != JPEG_HEADER_OK) { |
| 355 return FALSE; | 355 return false; |
| 356 } | 356 } |
| 357 if (cinfo.saw_Adobe_marker) { | 357 if (cinfo.saw_Adobe_marker) { |
| 358 m_bJpegTransform = TRUE; | 358 m_bJpegTransform = true; |
| 359 } | 359 } |
| 360 if (cinfo.num_components == 3 && !m_bJpegTransform) { | 360 if (cinfo.num_components == 3 && !m_bJpegTransform) { |
| 361 cinfo.out_color_space = cinfo.jpeg_color_space; | 361 cinfo.out_color_space = cinfo.jpeg_color_space; |
| 362 } | 362 } |
| 363 m_OrigWidth = cinfo.image_width; | 363 m_OrigWidth = cinfo.image_width; |
| 364 m_OrigHeight = cinfo.image_height; | 364 m_OrigHeight = cinfo.image_height; |
| 365 m_OutputWidth = m_OrigWidth; | 365 m_OutputWidth = m_OrigWidth; |
| 366 m_OutputHeight = m_OrigHeight; | 366 m_OutputHeight = m_OrigHeight; |
| 367 m_nDefaultScaleDenom = cinfo.scale_denom; | 367 m_nDefaultScaleDenom = cinfo.scale_denom; |
| 368 return TRUE; | 368 return true; |
| 369 } | 369 } |
| 370 FX_BOOL CCodec_JpegDecoder::Create(const uint8_t* src_buf, FX_DWORD src_size, in
t width, int height, | 370 bool CCodec_JpegDecoder::Create(const uint8_t* src_buf, FX_DWORD src_size, int w
idth, int height, |
| 371 int nComps, FX_BOOL ColorTransform, IFX_JpegP
rovider* pJP) | 371 int nComps, bool ColorTransform, IFX_JpegProv
ider* pJP) |
| 372 { | 372 { |
| 373 if (pJP) { | 373 if (pJP) { |
| 374 m_pExtProvider = pJP; | 374 m_pExtProvider = pJP; |
| 375 m_pExtContext = m_pExtProvider->CreateDecoder(src_buf, src_size, width,
height, nComps, ColorTransform); | 375 m_pExtContext = m_pExtProvider->CreateDecoder(src_buf, src_size, width,
height, nComps, ColorTransform); |
| 376 return m_pExtContext != NULL; | 376 return m_pExtContext != NULL; |
| 377 } | 377 } |
| 378 _JpegScanSOI(src_buf, src_size); | 378 _JpegScanSOI(src_buf, src_size); |
| 379 m_SrcBuf = src_buf; | 379 m_SrcBuf = src_buf; |
| 380 m_SrcSize = src_size; | 380 m_SrcSize = src_size; |
| 381 jerr.error_exit = _error_fatal; | 381 jerr.error_exit = _error_fatal; |
| 382 jerr.emit_message = _error_do_nothing1; | 382 jerr.emit_message = _error_do_nothing1; |
| 383 jerr.output_message = _error_do_nothing; | 383 jerr.output_message = _error_do_nothing; |
| 384 jerr.format_message = _error_do_nothing2; | 384 jerr.format_message = _error_do_nothing2; |
| 385 jerr.reset_error_mgr = _error_do_nothing; | 385 jerr.reset_error_mgr = _error_do_nothing; |
| 386 src.init_source = _src_do_nothing; | 386 src.init_source = _src_do_nothing; |
| 387 src.term_source = _src_do_nothing; | 387 src.term_source = _src_do_nothing; |
| 388 src.skip_input_data = _src_skip_data; | 388 src.skip_input_data = _src_skip_data; |
| 389 src.fill_input_buffer = _src_fill_buffer; | 389 src.fill_input_buffer = _src_fill_buffer; |
| 390 src.resync_to_restart = _src_resync; | 390 src.resync_to_restart = _src_resync; |
| 391 m_bJpegTransform = ColorTransform; | 391 m_bJpegTransform = ColorTransform; |
| 392 if(src_size > 1 && FXSYS_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0)
{ | 392 if(src_size > 1 && FXSYS_memcmp(src_buf + src_size - 2, "\xFF\xD9", 2) != 0)
{ |
| 393 ((uint8_t*)src_buf)[src_size - 2] = 0xFF; | 393 ((uint8_t*)src_buf)[src_size - 2] = 0xFF; |
| 394 ((uint8_t*)src_buf)[src_size - 1] = 0xD9; | 394 ((uint8_t*)src_buf)[src_size - 1] = 0xD9; |
| 395 } | 395 } |
| 396 m_OutputWidth = m_OrigWidth = width; | 396 m_OutputWidth = m_OrigWidth = width; |
| 397 m_OutputHeight = m_OrigHeight = height; | 397 m_OutputHeight = m_OrigHeight = height; |
| 398 if (!InitDecode()) { | 398 if (!InitDecode()) { |
| 399 return FALSE; | 399 return false; |
| 400 } | 400 } |
| 401 if (cinfo.num_components < nComps) { | 401 if (cinfo.num_components < nComps) { |
| 402 return FALSE; | 402 return false; |
| 403 } | 403 } |
| 404 if ((int)cinfo.image_width < width) { | 404 if ((int)cinfo.image_width < width) { |
| 405 return FALSE; | 405 return false; |
| 406 } | 406 } |
| 407 m_Pitch = (cinfo.image_width * cinfo.num_components + 3) / 4 * 4; | 407 m_Pitch = (cinfo.image_width * cinfo.num_components + 3) / 4 * 4; |
| 408 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); | 408 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch); |
| 409 m_nComps = cinfo.num_components; | 409 m_nComps = cinfo.num_components; |
| 410 m_bpc = 8; | 410 m_bpc = 8; |
| 411 m_bColorTransformed = FALSE; | 411 m_bColorTransformed = false; |
| 412 m_bStarted = FALSE; | 412 m_bStarted = false; |
| 413 return TRUE; | 413 return true; |
| 414 } | 414 } |
| 415 extern "C" { | 415 extern "C" { |
| 416 int32_t FX_GetDownsampleRatio(int32_t originWidth, int32_t originHeight, int
32_t downsampleWidth, int32_t downsampleHeight) | 416 int32_t FX_GetDownsampleRatio(int32_t originWidth, int32_t originHeight, int
32_t downsampleWidth, int32_t downsampleHeight) |
| 417 { | 417 { |
| 418 int iratio_w = originWidth / downsampleWidth; | 418 int iratio_w = originWidth / downsampleWidth; |
| 419 int iratio_h = originHeight / downsampleHeight; | 419 int iratio_h = originHeight / downsampleHeight; |
| 420 int ratio = (iratio_w > iratio_h) ? iratio_h : iratio_w; | 420 int ratio = (iratio_w > iratio_h) ? iratio_h : iratio_w; |
| 421 if (ratio >= 8) { | 421 if (ratio >= 8) { |
| 422 return 8; | 422 return 8; |
| 423 } | 423 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 438 } | 438 } |
| 439 int old_scale = m_DownScale; | 439 int old_scale = m_DownScale; |
| 440 m_DownScale = FX_GetDownsampleRatio(m_OrigWidth, m_OrigHeight, dest_width, d
est_height); | 440 m_DownScale = FX_GetDownsampleRatio(m_OrigWidth, m_OrigHeight, dest_width, d
est_height); |
| 441 m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale; | 441 m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale; |
| 442 m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale; | 442 m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale; |
| 443 m_Pitch = (m_OutputWidth * m_nComps + 3) / 4 * 4; | 443 m_Pitch = (m_OutputWidth * m_nComps + 3) / 4 * 4; |
| 444 if (old_scale != m_DownScale) { | 444 if (old_scale != m_DownScale) { |
| 445 m_NextLine = -1; | 445 m_NextLine = -1; |
| 446 } | 446 } |
| 447 } | 447 } |
| 448 FX_BOOL CCodec_JpegDecoder::v_Rewind() | 448 bool CCodec_JpegDecoder::v_Rewind() |
| 449 { | 449 { |
| 450 if (m_pExtProvider) { | 450 if (m_pExtProvider) { |
| 451 return m_pExtProvider->Rewind(m_pExtContext); | 451 return m_pExtProvider->Rewind(m_pExtContext); |
| 452 } | 452 } |
| 453 if (m_bStarted) { | 453 if (m_bStarted) { |
| 454 jpeg_destroy_decompress(&cinfo); | 454 jpeg_destroy_decompress(&cinfo); |
| 455 if (!InitDecode()) { | 455 if (!InitDecode()) { |
| 456 return FALSE; | 456 return false; |
| 457 } | 457 } |
| 458 } | 458 } |
| 459 if (setjmp(m_JmpBuf) == -1) { | 459 if (setjmp(m_JmpBuf) == -1) { |
| 460 return FALSE; | 460 return false; |
| 461 } | 461 } |
| 462 cinfo.scale_denom = m_nDefaultScaleDenom * m_DownScale; | 462 cinfo.scale_denom = m_nDefaultScaleDenom * m_DownScale; |
| 463 m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale; | 463 m_OutputWidth = (m_OrigWidth + m_DownScale - 1) / m_DownScale; |
| 464 m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale; | 464 m_OutputHeight = (m_OrigHeight + m_DownScale - 1) / m_DownScale; |
| 465 if (!jpeg_start_decompress(&cinfo)) { | 465 if (!jpeg_start_decompress(&cinfo)) { |
| 466 jpeg_destroy_decompress(&cinfo); | 466 jpeg_destroy_decompress(&cinfo); |
| 467 return FALSE; | 467 return false; |
| 468 } | 468 } |
| 469 if ((int)cinfo.output_width > m_OrigWidth) { | 469 if ((int)cinfo.output_width > m_OrigWidth) { |
| 470 FXSYS_assert(FALSE); | 470 FXSYS_assert(false); |
| 471 return FALSE; | 471 return false; |
| 472 } | 472 } |
| 473 m_bStarted = TRUE; | 473 m_bStarted = true; |
| 474 return TRUE; | 474 return true; |
| 475 } | 475 } |
| 476 uint8_t* CCodec_JpegDecoder::v_GetNextLine() | 476 uint8_t* CCodec_JpegDecoder::v_GetNextLine() |
| 477 { | 477 { |
| 478 if (m_pExtProvider) { | 478 if (m_pExtProvider) { |
| 479 return m_pExtProvider->GetNextLine(m_pExtContext); | 479 return m_pExtProvider->GetNextLine(m_pExtContext); |
| 480 } | 480 } |
| 481 int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1); | 481 int nlines = jpeg_read_scanlines(&cinfo, &m_pScanlineBuf, 1); |
| 482 if (nlines < 1) { | 482 if (nlines < 1) { |
| 483 return NULL; | 483 return NULL; |
| 484 } | 484 } |
| 485 return m_pScanlineBuf; | 485 return m_pScanlineBuf; |
| 486 } | 486 } |
| 487 FX_DWORD CCodec_JpegDecoder::GetSrcOffset() | 487 FX_DWORD CCodec_JpegDecoder::GetSrcOffset() |
| 488 { | 488 { |
| 489 if (m_pExtProvider) { | 489 if (m_pExtProvider) { |
| 490 return m_pExtProvider->GetSrcOffset(m_pExtContext); | 490 return m_pExtProvider->GetSrcOffset(m_pExtContext); |
| 491 } | 491 } |
| 492 return (FX_DWORD)(m_SrcSize - src.bytes_in_buffer); | 492 return (FX_DWORD)(m_SrcSize - src.bytes_in_buffer); |
| 493 } | 493 } |
| 494 ICodec_ScanlineDecoder* CCodec_JpegModule::CreateDecoder(const uint8_t* src_buf,
FX_DWORD src_size, | 494 ICodec_ScanlineDecoder* CCodec_JpegModule::CreateDecoder(const uint8_t* src_buf,
FX_DWORD src_size, |
| 495 int width, int height, int nComps, FX_BOOL ColorTransform) | 495 int width, int height, int nComps, bool ColorTransform) |
| 496 { | 496 { |
| 497 if (src_buf == NULL || src_size == 0) { | 497 if (src_buf == NULL || src_size == 0) { |
| 498 return NULL; | 498 return NULL; |
| 499 } | 499 } |
| 500 CCodec_JpegDecoder* pDecoder = new CCodec_JpegDecoder; | 500 CCodec_JpegDecoder* pDecoder = new CCodec_JpegDecoder; |
| 501 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, ColorTransfo
rm, m_pExtProvider)) { | 501 if (!pDecoder->Create(src_buf, src_size, width, height, nComps, ColorTransfo
rm, m_pExtProvider)) { |
| 502 delete pDecoder; | 502 delete pDecoder; |
| 503 return NULL; | 503 return NULL; |
| 504 } | 504 } |
| 505 return pDecoder; | 505 return pDecoder; |
| 506 } | 506 } |
| 507 FX_BOOL CCodec_JpegModule::LoadInfo(const uint8_t* src_buf, FX_DWORD src_size, i
nt& width, int& height, | 507 bool CCodec_JpegModule::LoadInfo(const uint8_t* src_buf, FX_DWORD src_size, int&
width, int& height, |
| 508 int& num_components, int& bits_per_component
s, FX_BOOL& color_transform, | 508 int& num_components, int& bits_per_component
s, bool& color_transform, |
| 509 uint8_t** icc_buf_ptr, FX_DWORD* icc_length) | 509 uint8_t** icc_buf_ptr, FX_DWORD* icc_length) |
| 510 { | 510 { |
| 511 if (m_pExtProvider) { | 511 if (m_pExtProvider) { |
| 512 return m_pExtProvider->LoadInfo(src_buf, src_size, width, height, | 512 return m_pExtProvider->LoadInfo(src_buf, src_size, width, height, |
| 513 num_components, bits_per_components, col
or_transform, | 513 num_components, bits_per_components, col
or_transform, |
| 514 icc_buf_ptr, icc_length); | 514 icc_buf_ptr, icc_length); |
| 515 } | 515 } |
| 516 return _JpegLoadInfo(src_buf, src_size, width, height, num_components, bits_
per_components, color_transform, icc_buf_ptr, icc_length); | 516 return _JpegLoadInfo(src_buf, src_size, width, height, num_components, bits_
per_components, color_transform, icc_buf_ptr, icc_length); |
| 517 } | 517 } |
| 518 FX_BOOL CCodec_JpegModule::Encode(const CFX_DIBSource* pSource, uint8_t*& dest_b
uf, FX_STRSIZE& dest_size, int quality, const uint8_t* icc_buf, FX_DWORD icc_len
gth) | 518 bool CCodec_JpegModule::Encode(const CFX_DIBSource* pSource, uint8_t*& dest_buf,
FX_STRSIZE& dest_size, int quality, const uint8_t* icc_buf, FX_DWORD icc_length
) |
| 519 { | 519 { |
| 520 if (m_pExtProvider) { | 520 if (m_pExtProvider) { |
| 521 return m_pExtProvider->Encode(pSource, dest_buf, dest_size, quality, icc
_buf, icc_length); | 521 return m_pExtProvider->Encode(pSource, dest_buf, dest_size, quality, icc
_buf, icc_length); |
| 522 } | 522 } |
| 523 if(pSource->GetBPP() < 8 || pSource->GetPalette() != NULL) { | 523 if(pSource->GetBPP() < 8 || pSource->GetPalette() != NULL) { |
| 524 ASSERT(pSource->GetBPP() >= 8 && pSource->GetPalette() == NULL); | 524 ASSERT(pSource->GetBPP() >= 8 && pSource->GetPalette() == NULL); |
| 525 return FALSE; | 525 return false; |
| 526 } | 526 } |
| 527 _JpegEncode(pSource, dest_buf, dest_size, quality, icc_buf, icc_length); | 527 _JpegEncode(pSource, dest_buf, dest_size, quality, icc_buf, icc_length); |
| 528 return TRUE; | 528 return true; |
| 529 } | 529 } |
| 530 struct FXJPEG_Context { | 530 struct FXJPEG_Context { |
| 531 jmp_buf m_JumpMark; | 531 jmp_buf m_JumpMark; |
| 532 jpeg_decompress_struct m_Info; | 532 jpeg_decompress_struct m_Info; |
| 533 jpeg_error_mgr m_ErrMgr; | 533 jpeg_error_mgr m_ErrMgr; |
| 534 jpeg_source_mgr m_SrcMgr; | 534 jpeg_source_mgr m_SrcMgr; |
| 535 unsigned int m_SkipSize; | 535 unsigned int m_SkipSize; |
| 536 void* (*m_AllocFunc)(unsigned int); | 536 void* (*m_AllocFunc)(unsigned int); |
| 537 void (*m_FreeFunc)(void*); | 537 void (*m_FreeFunc)(void*); |
| 538 }; | 538 }; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 if (m_pExtProvider) { | 646 if (m_pExtProvider) { |
| 647 return m_pExtProvider->StartScanline(pContext, down_scale); | 647 return m_pExtProvider->StartScanline(pContext, down_scale); |
| 648 } | 648 } |
| 649 FXJPEG_Context* p = (FXJPEG_Context*)pContext; | 649 FXJPEG_Context* p = (FXJPEG_Context*)pContext; |
| 650 if (setjmp(p->m_JumpMark) == -1) { | 650 if (setjmp(p->m_JumpMark) == -1) { |
| 651 return 0; | 651 return 0; |
| 652 } | 652 } |
| 653 p->m_Info.scale_denom = down_scale; | 653 p->m_Info.scale_denom = down_scale; |
| 654 return jpeg_start_decompress(&p->m_Info); | 654 return jpeg_start_decompress(&p->m_Info); |
| 655 } | 655 } |
| 656 FX_BOOL CCodec_JpegModule::ReadScanline(void* pContext, unsigned char* dest_buf) | 656 bool CCodec_JpegModule::ReadScanline(void* pContext, unsigned char* dest_buf) |
| 657 { | 657 { |
| 658 if (m_pExtProvider) { | 658 if (m_pExtProvider) { |
| 659 return m_pExtProvider->ReadScanline(pContext, dest_buf); | 659 return m_pExtProvider->ReadScanline(pContext, dest_buf); |
| 660 } | 660 } |
| 661 FXJPEG_Context* p = (FXJPEG_Context*)pContext; | 661 FXJPEG_Context* p = (FXJPEG_Context*)pContext; |
| 662 if (setjmp(p->m_JumpMark) == -1) { | 662 if (setjmp(p->m_JumpMark) == -1) { |
| 663 return FALSE; | 663 return false; |
| 664 } | 664 } |
| 665 int nlines = jpeg_read_scanlines(&p->m_Info, &dest_buf, 1); | 665 int nlines = jpeg_read_scanlines(&p->m_Info, &dest_buf, 1); |
| 666 return nlines == 1; | 666 return nlines == 1; |
| 667 } | 667 } |
| 668 FX_DWORD CCodec_JpegModule::GetAvailInput(void* pContext, uint8_t** avail_buf_pt
r) | 668 FX_DWORD CCodec_JpegModule::GetAvailInput(void* pContext, uint8_t** avail_buf_pt
r) |
| 669 { | 669 { |
| 670 if (m_pExtProvider) { | 670 if (m_pExtProvider) { |
| 671 return m_pExtProvider->GetAvailInput(pContext, avail_buf_ptr); | 671 return m_pExtProvider->GetAvailInput(pContext, avail_buf_ptr); |
| 672 } | 672 } |
| 673 if(avail_buf_ptr != NULL) { | 673 if(avail_buf_ptr != NULL) { |
| 674 *avail_buf_ptr = NULL; | 674 *avail_buf_ptr = NULL; |
| 675 if(((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer > 0) { | 675 if(((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer > 0) { |
| 676 *avail_buf_ptr = (uint8_t*)((FXJPEG_Context*)pContext)->m_SrcMgr.nex
t_input_byte; | 676 *avail_buf_ptr = (uint8_t*)((FXJPEG_Context*)pContext)->m_SrcMgr.nex
t_input_byte; |
| 677 } | 677 } |
| 678 } | 678 } |
| 679 return (FX_DWORD)((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer; | 679 return (FX_DWORD)((FXJPEG_Context*)pContext)->m_SrcMgr.bytes_in_buffer; |
| 680 } | 680 } |
| OLD | NEW |