Chromium Code Reviews| 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 |