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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 #endif | 468 #endif |
467 if (overrideColorSpace == JCS_YCbCr) { | 469 if (overrideColorSpace == JCS_YCbCr) { |
468 m_info.out_color_space = JCS_YCbCr; | 470 m_info.out_color_space = JCS_YCbCr; |
469 m_info.raw_data_out = TRUE; | 471 m_info.raw_data_out = TRUE; |
470 m_uvSize = computeYUVSize(&m_info, 1, ImageDecoder::SizeForMemor
yAllocation); // U size and V size have to be the same if we got here | 472 m_uvSize = computeYUVSize(&m_info, 1, ImageDecoder::SizeForMemor
yAllocation); // U size and V size have to be the same if we got here |
471 } | 473 } |
472 | 474 |
473 // Don't allocate a giant and superfluous memory buffer when the | 475 // Don't allocate a giant and superfluous memory buffer when the |
474 // image is a sequential JPEG. | 476 // image is a sequential JPEG. |
475 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); | 477 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); |
| 478 if (m_info.buffered_image) { |
| 479 m_err.pub.emit_message = emit_message; |
| 480 m_err.num_corrupt_warnings = 0; |
| 481 } |
476 | 482 |
477 if (onlySize) { | 483 if (onlySize) { |
478 // We can stop here. Reduce our buffer length and available data
. | 484 // We can stop here. Reduce our buffer length and available data
. |
479 m_bufferLength -= m_info.src->bytes_in_buffer; | 485 m_bufferLength -= m_info.src->bytes_in_buffer; |
480 m_info.src->bytes_in_buffer = 0; | 486 m_info.src->bytes_in_buffer = 0; |
481 return true; | 487 return true; |
482 } | 488 } |
483 // FALL THROUGH | 489 // FALL THROUGH |
484 | 490 |
485 case JPEG_START_DECOMPRESS: | 491 case JPEG_START_DECOMPRESS: |
486 // Set parameters for decompression. | 492 // Set parameters for decompression. |
487 // FIXME -- Should reset dct_method and dither mode for final pass | 493 // FIXME -- Should reset dct_method and dither mode for final pass |
488 // of progressive JPEG. | 494 // of progressive JPEG. |
489 m_info.dct_method = dctMethod(); | 495 m_info.dct_method = dctMethod(); |
490 m_info.dither_mode = ditherMode(); | 496 m_info.dither_mode = ditherMode(); |
491 m_info.do_fancy_upsampling = doFancyUpsampling(); | 497 m_info.do_fancy_upsampling = doFancyUpsampling(); |
| 498 m_info.do_block_smoothing = true; |
492 m_info.enable_2pass_quant = false; | 499 m_info.enable_2pass_quant = false; |
493 m_info.do_block_smoothing = true; | 500 // FIXME: should we just assert these? |
| 501 m_info.enable_external_quant = false; |
| 502 m_info.enable_1pass_quant = false; |
| 503 m_info.quantize_colors = false; |
| 504 m_info.colormap = 0; |
494 | 505 |
495 // Make a one-row-high sample array that will go away when done with | 506 // 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 | 507 // 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 | 508 // uses the IJG memory manager, it must be allocated before the call |
498 // to jpeg_start_compress(). | 509 // to jpeg_start_compress(). |
499 // FIXME: note that some output color spaces do not need the samples | 510 // FIXME: note that some output color spaces do not need the samples |
500 // buffer. Remove this allocation for those color spaces. | 511 // buffer. Remove this allocation for those color spaces. |
501 { | 512 { |
502 int samplesWidth = (m_info.out_color_space == JCS_YCbCr) ? compu
teYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAllocation).width() : m_info.ou
tput_width; | 513 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); | 514 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... | 531 // If we've completed image output... |
521 ASSERT(m_info.output_scanline == m_info.output_height); | 532 ASSERT(m_info.output_scanline == m_info.output_height); |
522 m_state = JPEG_DONE; | 533 m_state = JPEG_DONE; |
523 } | 534 } |
524 // FALL THROUGH | 535 // FALL THROUGH |
525 | 536 |
526 case JPEG_DECOMPRESS_PROGRESSIVE: | 537 case JPEG_DECOMPRESS_PROGRESSIVE: |
527 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) { | 538 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) { |
528 int status; | 539 int status; |
529 do { | 540 do { |
| 541 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_
mgr *>(m_info.err); |
| 542 if (err->num_corrupt_warnings) |
| 543 break; |
530 status = jpeg_consume_input(&m_info); | 544 status = jpeg_consume_input(&m_info); |
531 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_E
OI)); | 545 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_E
OI)); |
532 | 546 |
533 for (;;) { | 547 for (;;) { |
534 if (!m_info.output_scanline) { | 548 if (!m_info.output_scanline) { |
535 int scan = m_info.input_scan_number; | 549 int scan = m_info.input_scan_number; |
536 | 550 |
537 // If we haven't displayed anything yet | 551 // If we haven't displayed anything yet |
538 // (output_scan_number == 0) and we have enough data for | 552 // (output_scan_number == 0) and we have enough data for |
539 // a complete scan, force output of the last full scan. | 553 // a complete scan, force output of the last full scan. |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 | 649 |
636 #if USE(QCMSLIB) | 650 #if USE(QCMSLIB) |
637 qcms_transform* m_transform; | 651 qcms_transform* m_transform; |
638 #endif | 652 #endif |
639 }; | 653 }; |
640 | 654 |
641 // Override the standard error method in the IJG JPEG decoder code. | 655 // Override the standard error method in the IJG JPEG decoder code. |
642 void error_exit(j_common_ptr cinfo) | 656 void error_exit(j_common_ptr cinfo) |
643 { | 657 { |
644 // Return control to the setjmp point. | 658 // Return control to the setjmp point. |
645 decoder_error_mgr *err = reinterpret_cast_ptr<decoder_error_mgr *>(cinfo->er
r); | 659 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr *>(cinfo->er
r); |
646 longjmp(err->setjmp_buffer, -1); | 660 longjmp(err->setjmp_buffer, -1); |
647 } | 661 } |
648 | 662 |
| 663 void emit_message(j_common_ptr cinfo, int msg_level) |
| 664 { |
| 665 if (msg_level >= 0) |
| 666 return; |
| 667 |
| 668 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr *>(cinfo->er
r); |
| 669 err->pub.num_warnings++; |
| 670 |
| 671 // Detect and count corrupt JPEG warning messages. |
| 672 const char* warning = 0; |
| 673 int code = err->pub.msg_code; |
| 674 if (code > 0 && code <= err->pub.last_jpeg_message) |
| 675 warning = err->pub.jpeg_message_table[code]; |
| 676 if (warning && !strncmp("Corrupt JPEG", warning, 12)) |
| 677 err->num_corrupt_warnings++; |
| 678 } |
| 679 |
649 void init_source(j_decompress_ptr) | 680 void init_source(j_decompress_ptr) |
650 { | 681 { |
651 } | 682 } |
652 | 683 |
653 void skip_input_data(j_decompress_ptr jd, long num_bytes) | 684 void skip_input_data(j_decompress_ptr jd, long num_bytes) |
654 { | 685 { |
655 decoder_source_mgr *src = (decoder_source_mgr *)jd->src; | 686 decoder_source_mgr *src = (decoder_source_mgr *)jd->src; |
656 src->decoder->skipBytes(num_bytes); | 687 src->decoder->skipBytes(num_bytes); |
657 } | 688 } |
658 | 689 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 // has failed. | 992 // has failed. |
962 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 993 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
963 setFailed(); | 994 setFailed(); |
964 | 995 |
965 // If decoding is done or failed, we don't need the JPEGImageReader anymore. | 996 // If decoding is done or failed, we don't need the JPEGImageReader anymore. |
966 if (isComplete(this, onlySize) || failed()) | 997 if (isComplete(this, onlySize) || failed()) |
967 m_reader.clear(); | 998 m_reader.clear(); |
968 } | 999 } |
969 | 1000 |
970 } | 1001 } |
OLD | NEW |