OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. | 2 * Copyright (C) 2006 Apple Computer, Inc. |
3 * | 3 * |
4 * Portions are Copyright (C) 2001-6 mozilla.org | 4 * Portions are Copyright (C) 2001-6 mozilla.org |
5 * | 5 * |
6 * Other contributors: | 6 * Other contributors: |
7 * Stuart Parmenter <stuart@mozilla.com> | 7 * Stuart Parmenter <stuart@mozilla.com> |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 | 82 |
83 // JPEG only supports a denominator of 8. | 83 // JPEG only supports a denominator of 8. |
84 const unsigned scaleDenominator = 8; | 84 const unsigned scaleDenominator = 8; |
85 | 85 |
86 } // namespace | 86 } // namespace |
87 | 87 |
88 namespace blink { | 88 namespace blink { |
89 | 89 |
90 struct decoder_error_mgr { | 90 struct decoder_error_mgr { |
91 struct jpeg_error_mgr pub; // "public" fields for IJG library | 91 struct jpeg_error_mgr pub; // "public" fields for IJG library |
92 int num_corrupt_warnings; // Counts corrupt warning messages | |
92 jmp_buf setjmp_buffer; // For handling catastropic errors | 93 jmp_buf setjmp_buffer; // For handling catastropic errors |
93 }; | 94 }; |
94 | 95 |
95 enum jstate { | 96 enum jstate { |
96 JPEG_HEADER, // Reading JFIF headers | 97 JPEG_HEADER, // Reading JFIF headers |
97 JPEG_START_DECOMPRESS, | 98 JPEG_START_DECOMPRESS, |
98 JPEG_DECOMPRESS_PROGRESSIVE, // Output progressive pixels | 99 JPEG_DECOMPRESS_PROGRESSIVE, // Output progressive pixels |
99 JPEG_DECOMPRESS_SEQUENTIAL, // Output sequential pixels | 100 JPEG_DECOMPRESS_SEQUENTIAL, // Output sequential pixels |
100 JPEG_DONE, | 101 JPEG_DONE, |
101 JPEG_ERROR | 102 JPEG_ERROR |
102 }; | 103 }; |
103 | 104 |
104 enum yuv_subsampling { | 105 enum yuv_subsampling { |
105 YUV_UNKNOWN, | 106 YUV_UNKNOWN, |
106 YUV_410, | 107 YUV_410, |
107 YUV_411, | 108 YUV_411, |
108 YUV_420, | 109 YUV_420, |
109 YUV_422, | 110 YUV_422, |
110 YUV_440, | 111 YUV_440, |
111 YUV_444 | 112 YUV_444 |
112 }; | 113 }; |
113 | 114 |
114 void init_source(j_decompress_ptr jd); | 115 void init_source(j_decompress_ptr jd); |
115 boolean fill_input_buffer(j_decompress_ptr jd); | 116 boolean fill_input_buffer(j_decompress_ptr jd); |
116 void skip_input_data(j_decompress_ptr jd, long num_bytes); | 117 void skip_input_data(j_decompress_ptr jd, long num_bytes); |
117 void term_source(j_decompress_ptr jd); | 118 void term_source(j_decompress_ptr jd); |
118 void error_exit(j_common_ptr cinfo); | 119 void error_exit(j_common_ptr cinfo); |
120 void emit_message(j_common_ptr cinfo, int msg_level); | |
119 | 121 |
120 // Implementation of a JPEG src object that understands our state machine | 122 // Implementation of a JPEG src object that understands our state machine |
121 struct decoder_source_mgr { | 123 struct decoder_source_mgr { |
122 // public fields; must be first in this struct! | 124 // public fields; must be first in this struct! |
123 struct jpeg_source_mgr pub; | 125 struct jpeg_source_mgr pub; |
124 | 126 |
125 JPEGImageReader* decoder; | 127 JPEGImageReader* decoder; |
126 }; | 128 }; |
127 | 129 |
128 static unsigned readUint16(JOCTET* data, bool isBigEndian) | 130 static unsigned readUint16(JOCTET* data, bool isBigEndian) |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 , m_bufferLength(0) | 307 , m_bufferLength(0) |
306 , m_bytesToSkip(0) | 308 , m_bytesToSkip(0) |
307 , m_state(JPEG_HEADER) | 309 , m_state(JPEG_HEADER) |
308 , m_samples(0) | 310 , m_samples(0) |
309 #if USE(QCMSLIB) | 311 #if USE(QCMSLIB) |
310 , m_transform(0) | 312 , m_transform(0) |
311 #endif | 313 #endif |
312 { | 314 { |
313 memset(&m_info, 0, sizeof(jpeg_decompress_struct)); | 315 memset(&m_info, 0, sizeof(jpeg_decompress_struct)); |
314 | 316 |
315 // Set up the normal JPEG error routines, then override error_exit. | 317 // Set up the normal JPEG error routines and install overrides. |
316 m_info.err = jpeg_std_error(&m_err.pub); | 318 m_info.err = jpeg_std_error(&m_err.pub); |
319 m_err.pub.emit_message = emit_message; | |
scroggo_chromium
2015/06/15 15:57:06
Besides error reporting, it looks like the behavio
Noel Gordon
2015/06/18 12:10:07
Good points. Since we have corruption for sequent
| |
317 m_err.pub.error_exit = error_exit; | 320 m_err.pub.error_exit = error_exit; |
321 m_err.num_corrupt_warnings = 0; | |
318 | 322 |
319 // Allocate and initialize JPEG decompression object. | 323 // Allocate and initialize JPEG decompression object. |
320 jpeg_create_decompress(&m_info); | 324 jpeg_create_decompress(&m_info); |
321 | 325 |
322 ASSERT(!m_info.src); | 326 ASSERT(!m_info.src); |
323 decoder_source_mgr* src = (decoder_source_mgr*)fastZeroedMalloc(sizeof(d ecoder_source_mgr)); | 327 decoder_source_mgr* src = (decoder_source_mgr*)fastZeroedMalloc(sizeof(d ecoder_source_mgr)); |
324 if (!src) { | 328 if (!src) { |
325 m_state = JPEG_ERROR; | 329 m_state = JPEG_ERROR; |
326 return; | 330 return; |
327 } | 331 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
482 } | 486 } |
483 // FALL THROUGH | 487 // FALL THROUGH |
484 | 488 |
485 case JPEG_START_DECOMPRESS: | 489 case JPEG_START_DECOMPRESS: |
486 // Set parameters for decompression. | 490 // Set parameters for decompression. |
487 // FIXME -- Should reset dct_method and dither mode for final pass | 491 // FIXME -- Should reset dct_method and dither mode for final pass |
488 // of progressive JPEG. | 492 // of progressive JPEG. |
489 m_info.dct_method = dctMethod(); | 493 m_info.dct_method = dctMethod(); |
490 m_info.dither_mode = ditherMode(); | 494 m_info.dither_mode = ditherMode(); |
491 m_info.do_fancy_upsampling = doFancyUpsampling(); | 495 m_info.do_fancy_upsampling = doFancyUpsampling(); |
496 m_info.do_block_smoothing = true; | |
492 m_info.enable_2pass_quant = false; | 497 m_info.enable_2pass_quant = false; |
493 m_info.do_block_smoothing = true; | 498 m_info.enable_external_quant = false; |
scroggo_chromium
2015/06/15 15:57:06
Are these (setting to false and 0) necessary or ju
Noel Gordon
2015/06/18 12:10:07
For completeness. Two variables related to buffere
scroggo_chromium
2015/06/18 13:19:24
Either way. I just wanted to make sure I understan
| |
499 m_info.enable_1pass_quant = false; | |
500 m_info.quantize_colors = false; | |
501 m_info.colormap = 0; | |
494 | 502 |
495 // Make a one-row-high sample array that will go away when done with | 503 // Make a one-row-high sample array that will go away when done with |
496 // image. Always make it big enough to hold an RGB row. Since this | 504 // image. Always make it big enough to hold an RGB row. Since this |
497 // uses the IJG memory manager, it must be allocated before the call | 505 // uses the IJG memory manager, it must be allocated before the call |
498 // to jpeg_start_compress(). | 506 // to jpeg_start_compress(). |
499 // FIXME: note that some output color spaces do not need the samples | 507 // FIXME: note that some output color spaces do not need the samples |
500 // buffer. Remove this allocation for those color spaces. | 508 // buffer. Remove this allocation for those color spaces. |
501 { | 509 { |
502 int samplesWidth = (m_info.out_color_space == JCS_YCbCr) ? compu teYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAllocation).width() : m_info.ou tput_width; | 510 int samplesWidth = (m_info.out_color_space == JCS_YCbCr) ? compu teYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAllocation).width() : m_info.ou tput_width; |
503 m_samples = (*m_info.mem->alloc_sarray)(reinterpret_cast<j_commo n_ptr>(&m_info), JPOOL_IMAGE, samplesWidth * 4, 1); | 511 m_samples = (*m_info.mem->alloc_sarray)(reinterpret_cast<j_commo n_ptr>(&m_info), JPOOL_IMAGE, samplesWidth * 4, 1); |
(...skipping 16 matching lines...) Expand all Loading... | |
520 // If we've completed image output... | 528 // If we've completed image output... |
521 ASSERT(m_info.output_scanline == m_info.output_height); | 529 ASSERT(m_info.output_scanline == m_info.output_height); |
522 m_state = JPEG_DONE; | 530 m_state = JPEG_DONE; |
523 } | 531 } |
524 // FALL THROUGH | 532 // FALL THROUGH |
525 | 533 |
526 case JPEG_DECOMPRESS_PROGRESSIVE: | 534 case JPEG_DECOMPRESS_PROGRESSIVE: |
527 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) { | 535 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) { |
528 int status; | 536 int status; |
529 do { | 537 do { |
538 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_ mgr *>(m_info.err); | |
539 if (err->num_corrupt_warnings) | |
540 break; | |
530 status = jpeg_consume_input(&m_info); | 541 status = jpeg_consume_input(&m_info); |
531 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_E OI)); | 542 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_E OI)); |
532 | 543 |
533 for (;;) { | 544 for (;;) { |
534 if (!m_info.output_scanline) { | 545 if (!m_info.output_scanline) { |
535 int scan = m_info.input_scan_number; | 546 int scan = m_info.input_scan_number; |
536 | 547 |
537 // If we haven't displayed anything yet | 548 // If we haven't displayed anything yet |
538 // (output_scan_number == 0) and we have enough data for | 549 // (output_scan_number == 0) and we have enough data for |
539 // a complete scan, force output of the last full scan. | 550 // a complete scan, force output of the last full scan. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 | 646 |
636 #if USE(QCMSLIB) | 647 #if USE(QCMSLIB) |
637 qcms_transform* m_transform; | 648 qcms_transform* m_transform; |
638 #endif | 649 #endif |
639 }; | 650 }; |
640 | 651 |
641 // Override the standard error method in the IJG JPEG decoder code. | 652 // Override the standard error method in the IJG JPEG decoder code. |
642 void error_exit(j_common_ptr cinfo) | 653 void error_exit(j_common_ptr cinfo) |
643 { | 654 { |
644 // Return control to the setjmp point. | 655 // Return control to the setjmp point. |
645 decoder_error_mgr *err = reinterpret_cast_ptr<decoder_error_mgr *>(cinfo->er r); | 656 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr *>(cinfo->er r); |
646 longjmp(err->setjmp_buffer, -1); | 657 longjmp(err->setjmp_buffer, -1); |
647 } | 658 } |
648 | 659 |
660 void emit_message(j_common_ptr cinfo, int msg_level) | |
661 { | |
662 if (msg_level >= 0) | |
663 return; | |
664 | |
665 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr *>(cinfo->er r); | |
666 err->pub.num_warnings++; | |
667 | |
668 // Detect and count corrupt JPEG warning messages. | |
669 const char* warning = 0; | |
670 int code = err->pub.msg_code; | |
671 if (code > 0 && code <= err->pub.last_jpeg_message) | |
672 warning = err->pub.jpeg_message_table[code]; | |
673 if (warning && !strncmp("Corrupt JPEG", warning, 12)) | |
674 err->num_corrupt_warnings++; | |
scroggo_chromium
2015/06/15 15:57:05
This appears to be used as a boolean. Do we need t
Noel Gordon
2015/06/18 12:10:07
For debug but also compat with the way libjpeg int
scroggo_chromium
2015/06/18 13:19:24
sgtm
| |
675 } | |
676 | |
649 void init_source(j_decompress_ptr) | 677 void init_source(j_decompress_ptr) |
650 { | 678 { |
651 } | 679 } |
652 | 680 |
653 void skip_input_data(j_decompress_ptr jd, long num_bytes) | 681 void skip_input_data(j_decompress_ptr jd, long num_bytes) |
654 { | 682 { |
655 decoder_source_mgr *src = (decoder_source_mgr *)jd->src; | 683 decoder_source_mgr *src = (decoder_source_mgr *)jd->src; |
656 src->decoder->skipBytes(num_bytes); | 684 src->decoder->skipBytes(num_bytes); |
657 } | 685 } |
658 | 686 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
961 // has failed. | 989 // has failed. |
962 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 990 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
963 setFailed(); | 991 setFailed(); |
964 | 992 |
965 // If decoding is done or failed, we don't need the JPEGImageReader anymore. | 993 // If decoding is done or failed, we don't need the JPEGImageReader anymore. |
966 if (isComplete(this, onlySize) || failed()) | 994 if (isComplete(this, onlySize) || failed()) |
967 m_reader.clear(); | 995 m_reader.clear(); |
968 } | 996 } |
969 | 997 |
970 } | 998 } |
OLD | NEW |