OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2007 The Android Open Source Project | 2 * Copyright 2007 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
10 #include "SkImageEncoder.h" | 10 #include "SkImageEncoder.h" |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. | 473 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. |
474 Used when decoding fails partway through reading scanlines to fill | 474 Used when decoding fails partway through reading scanlines to fill |
475 remaining lines. */ | 475 remaining lines. */ |
476 static void fill_below_level(int y, SkBitmap* bitmap) { | 476 static void fill_below_level(int y, SkBitmap* bitmap) { |
477 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); | 477 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); |
478 SkCanvas canvas(*bitmap); | 478 SkCanvas canvas(*bitmap); |
479 canvas.clipRect(SkRect::Make(rect)); | 479 canvas.clipRect(SkRect::Make(rect)); |
480 canvas.drawColor(SK_ColorWHITE); | 480 canvas.drawColor(SK_ColorWHITE); |
481 } | 481 } |
482 | 482 |
483 /** | |
484 * Get the config and bytes per pixel of the source data. Return | |
485 * whether the data is supported. | |
486 */ | |
487 static bool get_src_config(const jpeg_decompress_struct& cinfo, | |
488 SkScaledBitmapSampler::SrcConfig* sc, | |
489 int* srcBytesPerPixel) { | |
490 SkASSERT(sc != NULL && srcBytesPerPixel != NULL); | |
491 if (JCS_CMYK == cinfo.out_color_space) { | |
492 // In this case we will manually convert the CMYK values to RGB | |
493 *sc = SkScaledBitmapSampler::kRGBX; | |
494 // The CMYK work-around relies on 4 components per pixel here | |
495 *srcBytesPerPixel = 4; | |
496 } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_spa ce) { | |
497 *sc = SkScaledBitmapSampler::kRGB; | |
498 *srcBytesPerPixel = 3; | |
499 #ifdef ANDROID_RGB | |
500 } else if (JCS_RGBA_8888 == cinfo.out_color_space) { | |
501 *sc = SkScaledBitmapSampler::kRGBX; | |
502 *srcBytesPerPixel = 4; | |
503 } else if (JCS_RGB_565 == cinfo.out_color_space) { | |
504 *sc = SkScaledBitmapSampler::kRGB_565; | |
505 *srcBytesPerPixel = 2; | |
506 #endif | |
507 } else if (1 == cinfo.out_color_components && | |
508 JCS_GRAYSCALE == cinfo.out_color_space) { | |
509 *sc = SkScaledBitmapSampler::kGray; | |
510 *srcBytesPerPixel = 1; | |
511 } else { | |
512 return false; | |
513 } | |
514 return true; | |
515 } | |
483 | 516 |
484 bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | 517 bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
485 #ifdef TIME_DECODE | 518 #ifdef TIME_DECODE |
486 SkAutoTime atm("JPEG Decode"); | 519 SkAutoTime atm("JPEG Decode"); |
487 #endif | 520 #endif |
488 | 521 |
489 JPEGAutoClean autoClean; | 522 JPEGAutoClean autoClean; |
490 | 523 |
491 jpeg_decompress_struct cinfo; | 524 jpeg_decompress_struct cinfo; |
492 skjpeg_source_mgr srcManager(stream, this); | 525 skjpeg_source_mgr srcManager(stream, this); |
(...skipping 29 matching lines...) Expand all Loading... | |
522 turn_off_visual_optimizations(&cinfo); | 555 turn_off_visual_optimizations(&cinfo); |
523 | 556 |
524 const SkBitmap::Config config = this->getBitmapConfig(&cinfo); | 557 const SkBitmap::Config config = this->getBitmapConfig(&cinfo); |
525 | 558 |
526 #ifdef ANDROID_RGB | 559 #ifdef ANDROID_RGB |
527 adjust_out_color_space_and_dither(&cinfo, config, *this); | 560 adjust_out_color_space_and_dither(&cinfo, config, *this); |
528 #endif | 561 #endif |
529 | 562 |
530 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { | 563 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { |
531 bm->setConfig(config, cinfo.image_width, cinfo.image_height); | 564 bm->setConfig(config, cinfo.image_width, cinfo.image_height); |
565 // Assume an A8 bitmap is opaque to avoid the check of each | |
reed1
2013/10/08 16:24:17
"is not" ?
same question for all copies of this c
scroggo
2013/10/10 21:46:59
Done.
| |
566 // individual pixel. It is very unlikely to be opaque, since | |
567 // an opaque A8 bitmap would not be very interesting. | |
568 // Otherwise, a jpeg image is opaque. | |
532 bm->setIsOpaque(config != SkBitmap::kA8_Config); | 569 bm->setIsOpaque(config != SkBitmap::kA8_Config); |
533 return true; | 570 return true; |
534 } | 571 } |
535 | 572 |
536 /* image_width and image_height are the original dimensions, available | 573 /* image_width and image_height are the original dimensions, available |
537 after jpeg_read_header(). To see the scaled dimensions, we have to call | 574 after jpeg_read_header(). To see the scaled dimensions, we have to call |
538 jpeg_start_decompress(), and then read output_width and output_height. | 575 jpeg_start_decompress(), and then read output_width and output_height. |
539 */ | 576 */ |
540 if (!jpeg_start_decompress(&cinfo)) { | 577 if (!jpeg_start_decompress(&cinfo)) { |
541 /* If we failed here, we may still have enough information to return | 578 /* If we failed here, we may still have enough information to return |
542 to the caller if they just wanted (subsampled bounds). If sampleSize | 579 to the caller if they just wanted (subsampled bounds). If sampleSize |
543 was 1, then we would have already returned. Thus we just check if | 580 was 1, then we would have already returned. Thus we just check if |
544 we're in kDecodeBounds_Mode, and that we have valid output sizes. | 581 we're in kDecodeBounds_Mode, and that we have valid output sizes. |
545 | 582 |
546 One reason to fail here is that we have insufficient stream data | 583 One reason to fail here is that we have insufficient stream data |
547 to complete the setup. However, output dimensions seem to get | 584 to complete the setup. However, output dimensions seem to get |
548 computed very early, which is why this special check can pay off. | 585 computed very early, which is why this special check can pay off. |
549 */ | 586 */ |
550 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension s(cinfo)) { | 587 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension s(cinfo)) { |
551 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, | 588 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, |
552 recompute_sampleSize(sampleSize, cinfo)); | 589 recompute_sampleSize(sampleSize, cinfo)); |
553 bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight()); | 590 bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight()); |
591 // Assume an A8 bitmap is opaque to avoid the check of each | |
592 // individual pixel. It is very unlikely to be opaque, since | |
593 // an opaque A8 bitmap would not be very interesting. | |
594 // Otherwise, a jpeg image is opaque. | |
554 bm->setIsOpaque(config != SkBitmap::kA8_Config); | 595 bm->setIsOpaque(config != SkBitmap::kA8_Config); |
555 return true; | 596 return true; |
556 } else { | 597 } else { |
557 return return_false(cinfo, *bm, "start_decompress"); | 598 return return_false(cinfo, *bm, "start_decompress"); |
558 } | 599 } |
559 } | 600 } |
560 sampleSize = recompute_sampleSize(sampleSize, cinfo); | 601 sampleSize = recompute_sampleSize(sampleSize, cinfo); |
561 | 602 |
562 // should we allow the Chooser (if present) to pick a config for us??? | 603 // should we allow the Chooser (if present) to pick a config for us??? |
563 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig ht)) { | 604 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig ht)) { |
564 return return_false(cinfo, *bm, "chooseFromOneChoice"); | 605 return return_false(cinfo, *bm, "chooseFromOneChoice"); |
565 } | 606 } |
566 | 607 |
567 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl eSize); | 608 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl eSize); |
568 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); | 609 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
610 // Assume an A8 bitmap is opaque to avoid the check of each | |
611 // individual pixel. It is very unlikely to be opaque, since | |
612 // an opaque A8 bitmap would not be very interesting. | |
613 // Otherwise, a jpeg image is opaque. | |
569 bm->setIsOpaque(config != SkBitmap::kA8_Config); | 614 bm->setIsOpaque(config != SkBitmap::kA8_Config); |
570 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 615 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
571 return true; | 616 return true; |
572 } | 617 } |
573 if (!this->allocPixelRef(bm, NULL)) { | 618 if (!this->allocPixelRef(bm, NULL)) { |
574 return return_false(cinfo, *bm, "allocPixelRef"); | 619 return return_false(cinfo, *bm, "allocPixelRef"); |
575 } | 620 } |
576 | 621 |
577 SkAutoLockPixels alp(*bm); | 622 SkAutoLockPixels alp(*bm); |
578 | 623 |
(...skipping 24 matching lines...) Expand all Loading... | |
603 } | 648 } |
604 rowptr += bpr; | 649 rowptr += bpr; |
605 } | 650 } |
606 jpeg_finish_decompress(&cinfo); | 651 jpeg_finish_decompress(&cinfo); |
607 return true; | 652 return true; |
608 } | 653 } |
609 #endif | 654 #endif |
610 | 655 |
611 // check for supported formats | 656 // check for supported formats |
612 SkScaledBitmapSampler::SrcConfig sc; | 657 SkScaledBitmapSampler::SrcConfig sc; |
613 if (JCS_CMYK == cinfo.out_color_space) { | 658 int srcBytesPerPixel; |
614 // In this case we will manually convert the CMYK values to RGB | 659 |
615 sc = SkScaledBitmapSampler::kRGBX; | 660 if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { |
616 } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_spa ce) { | |
617 sc = SkScaledBitmapSampler::kRGB; | |
618 #ifdef ANDROID_RGB | |
619 } else if (JCS_RGBA_8888 == cinfo.out_color_space) { | |
620 sc = SkScaledBitmapSampler::kRGBX; | |
621 } else if (JCS_RGB_565 == cinfo.out_color_space) { | |
622 sc = SkScaledBitmapSampler::kRGB_565; | |
623 #endif | |
624 } else if (1 == cinfo.out_color_components && | |
625 JCS_GRAYSCALE == cinfo.out_color_space) { | |
626 sc = SkScaledBitmapSampler::kGray; | |
627 } else { | |
628 return return_false(cinfo, *bm, "jpeg colorspace"); | 661 return return_false(cinfo, *bm, "jpeg colorspace"); |
629 } | 662 } |
630 | 663 |
631 if (!sampler.begin(bm, sc, *this)) { | 664 if (!sampler.begin(bm, sc, *this)) { |
632 return return_false(cinfo, *bm, "sampler.begin"); | 665 return return_false(cinfo, *bm, "sampler.begin"); |
633 } | 666 } |
634 | 667 |
635 // The CMYK work-around relies on 4 components per pixel here | 668 SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); |
636 SkAutoMalloc srcStorage(cinfo.output_width * 4); | |
637 uint8_t* srcRow = (uint8_t*)srcStorage.get(); | 669 uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
638 | 670 |
639 // Possibly skip initial rows [sampler.srcY0] | 671 // Possibly skip initial rows [sampler.srcY0] |
640 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { | 672 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { |
641 return return_false(cinfo, *bm, "skip rows"); | 673 return return_false(cinfo, *bm, "skip rows"); |
642 } | 674 } |
643 | 675 |
644 // now loop through scanlines until y == bm->height() - 1 | 676 // now loop through scanlines until y == bm->height() - 1 |
645 for (int y = 0;; y++) { | 677 for (int y = 0;; y++) { |
646 JSAMPLE* rowptr = (JSAMPLE*)srcRow; | 678 JSAMPLE* rowptr = (JSAMPLE*)srcRow; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
780 | 812 |
781 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(), | 813 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(), |
782 &startX, &startY, &width, &height); | 814 &startX, &startY, &width, &height); |
783 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo); | 815 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo); |
784 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz e); | 816 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz e); |
785 | 817 |
786 SkScaledBitmapSampler sampler(width, height, skiaSampleSize); | 818 SkScaledBitmapSampler sampler(width, height, skiaSampleSize); |
787 | 819 |
788 SkBitmap bitmap; | 820 SkBitmap bitmap; |
789 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); | 821 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
790 bitmap.setIsOpaque(true); | 822 // Assume an A8 bitmap is opaque to avoid the check of each |
823 // individual pixel. It is very unlikely to be opaque, since | |
824 // an opaque A8 bitmap would not be very interesting. | |
825 // Otherwise, a jpeg image is opaque. | |
826 bitmap.setIsOpaque(config != SkBitmap::kA8_Config); | |
791 | 827 |
792 // Check ahead of time if the swap(dest, src) is possible or not. | 828 // Check ahead of time if the swap(dest, src) is possible or not. |
793 // If yes, then we will stick to AllocPixelRef since it's cheaper with the | 829 // If yes, then we will stick to AllocPixelRef since it's cheaper with the |
794 // swap happening. If no, then we will use alloc to allocate pixels to | 830 // swap happening. If no, then we will use alloc to allocate pixels to |
795 // prevent garbage collection. | 831 // prevent garbage collection. |
796 int w = rect.width() / actualSampleSize; | 832 int w = rect.width() / actualSampleSize; |
797 int h = rect.height() / actualSampleSize; | 833 int h = rect.height() / actualSampleSize; |
798 bool swapOnly = (rect == region) && bm->isNull() && | 834 bool swapOnly = (rect == region) && bm->isNull() && |
799 (w == bitmap.width()) && (h == bitmap.height()) && | 835 (w == bitmap.width()) && (h == bitmap.height()) && |
800 ((startX - rect.x()) / actualSampleSize == 0) && | 836 ((startX - rect.x()) / actualSampleSize == 0) && |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 } else { | 883 } else { |
848 cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(), | 884 cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(), |
849 region.width(), region.height(), startX, startY); | 885 region.width(), region.height(), startX, startY); |
850 } | 886 } |
851 return true; | 887 return true; |
852 } | 888 } |
853 #endif | 889 #endif |
854 | 890 |
855 // check for supported formats | 891 // check for supported formats |
856 SkScaledBitmapSampler::SrcConfig sc; | 892 SkScaledBitmapSampler::SrcConfig sc; |
857 if (JCS_CMYK == cinfo->out_color_space) { | 893 int srcBytesPerPixel; |
858 // In this case we will manually convert the CMYK values to RGB | 894 |
859 sc = SkScaledBitmapSampler::kRGBX; | 895 if (!get_src_config(*cinfo, &sc, &srcBytesPerPixel)) { |
860 } else if (3 == cinfo->out_color_components && JCS_RGB == cinfo->out_color_s pace) { | |
861 sc = SkScaledBitmapSampler::kRGB; | |
862 #ifdef ANDROID_RGB | |
863 } else if (JCS_RGBA_8888 == cinfo->out_color_space) { | |
864 sc = SkScaledBitmapSampler::kRGBX; | |
865 } else if (JCS_RGB_565 == cinfo->out_color_space) { | |
866 sc = SkScaledBitmapSampler::kRGB_565; | |
867 #endif | |
868 } else if (1 == cinfo->out_color_components && | |
869 JCS_GRAYSCALE == cinfo->out_color_space) { | |
870 sc = SkScaledBitmapSampler::kGray; | |
871 } else { | |
872 return return_false(*cinfo, *bm, "jpeg colorspace"); | 896 return return_false(*cinfo, *bm, "jpeg colorspace"); |
873 } | 897 } |
874 | 898 |
875 if (!sampler.begin(&bitmap, sc, *this)) { | 899 if (!sampler.begin(&bitmap, sc, *this)) { |
876 return return_false(*cinfo, bitmap, "sampler.begin"); | 900 return return_false(*cinfo, bitmap, "sampler.begin"); |
877 } | 901 } |
878 | 902 |
879 // The CMYK work-around relies on 4 components per pixel here | 903 SkAutoMalloc srcStorage(width * srcBytesPerPixel); |
880 SkAutoMalloc srcStorage(width * 4); | |
881 uint8_t* srcRow = (uint8_t*)srcStorage.get(); | 904 uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
882 | 905 |
883 // Possibly skip initial rows [sampler.srcY0] | 906 // Possibly skip initial rows [sampler.srcY0] |
884 if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow, sampler. srcY0())) { | 907 if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow, sampler. srcY0())) { |
885 return return_false(*cinfo, bitmap, "skip rows"); | 908 return return_false(*cinfo, bitmap, "skip rows"); |
886 } | 909 } |
887 | 910 |
888 // now loop through scanlines until y == bitmap->height() - 1 | 911 // now loop through scanlines until y == bitmap->height() - 1 |
889 for (int y = 0;; y++) { | 912 for (int y = 0;; y++) { |
890 JSAMPLE* rowptr = (JSAMPLE*)srcRow; | 913 JSAMPLE* rowptr = (JSAMPLE*)srcRow; |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1200 return SkImageDecoder::kUnknown_Format; | 1223 return SkImageDecoder::kUnknown_Format; |
1201 } | 1224 } |
1202 | 1225 |
1203 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { | 1226 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { |
1204 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; | 1227 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; |
1205 } | 1228 } |
1206 | 1229 |
1207 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); | 1230 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); |
1208 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); | 1231 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); |
1209 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); | 1232 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); |
OLD | NEW |