| 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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. | 488 Sets all pixels in given bitmap to SK_ColorWHITE for all rows >= y. |
| 489 Used when decoding fails partway through reading scanlines to fill | 489 Used when decoding fails partway through reading scanlines to fill |
| 490 remaining lines. */ | 490 remaining lines. */ |
| 491 static void fill_below_level(int y, SkBitmap* bitmap) { | 491 static void fill_below_level(int y, SkBitmap* bitmap) { |
| 492 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); | 492 SkIRect rect = SkIRect::MakeLTRB(0, y, bitmap->width(), bitmap->height()); |
| 493 SkCanvas canvas(*bitmap); | 493 SkCanvas canvas(*bitmap); |
| 494 canvas.clipRect(SkRect::Make(rect)); | 494 canvas.clipRect(SkRect::Make(rect)); |
| 495 canvas.drawColor(SK_ColorWHITE); | 495 canvas.drawColor(SK_ColorWHITE); |
| 496 } | 496 } |
| 497 | 497 |
| 498 /** |
| 499 * Get the config and bytes per pixel of the source data. Return |
| 500 * whether the data is supported. |
| 501 */ |
| 502 static bool get_src_config(const jpeg_decompress_struct& cinfo, |
| 503 SkScaledBitmapSampler::SrcConfig* sc, |
| 504 int* srcBytesPerPixel) { |
| 505 SkASSERT(sc != NULL && srcBytesPerPixel != NULL); |
| 506 if (JCS_CMYK == cinfo.out_color_space) { |
| 507 // In this case we will manually convert the CMYK values to RGB |
| 508 *sc = SkScaledBitmapSampler::kRGBX; |
| 509 // The CMYK work-around relies on 4 components per pixel here |
| 510 *srcBytesPerPixel = 4; |
| 511 } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_spa
ce) { |
| 512 *sc = SkScaledBitmapSampler::kRGB; |
| 513 *srcBytesPerPixel = 3; |
| 514 #ifdef ANDROID_RGB |
| 515 } else if (JCS_RGBA_8888 == cinfo.out_color_space) { |
| 516 *sc = SkScaledBitmapSampler::kRGBX; |
| 517 *srcBytesPerPixel = 4; |
| 518 } else if (JCS_RGB_565 == cinfo.out_color_space) { |
| 519 *sc = SkScaledBitmapSampler::kRGB_565; |
| 520 *srcBytesPerPixel = 2; |
| 521 #endif |
| 522 } else if (1 == cinfo.out_color_components && |
| 523 JCS_GRAYSCALE == cinfo.out_color_space) { |
| 524 *sc = SkScaledBitmapSampler::kGray; |
| 525 *srcBytesPerPixel = 1; |
| 526 } else { |
| 527 return false; |
| 528 } |
| 529 return true; |
| 530 } |
| 498 | 531 |
| 499 bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | 532 bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
| 500 #ifdef TIME_DECODE | 533 #ifdef TIME_DECODE |
| 501 SkAutoTime atm("JPEG Decode"); | 534 SkAutoTime atm("JPEG Decode"); |
| 502 #endif | 535 #endif |
| 503 | 536 |
| 504 JPEGAutoClean autoClean; | 537 JPEGAutoClean autoClean; |
| 505 | 538 |
| 506 jpeg_decompress_struct cinfo; | 539 jpeg_decompress_struct cinfo; |
| 507 skjpeg_source_mgr srcManager(stream, this); | 540 skjpeg_source_mgr srcManager(stream, this); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 536 | 569 |
| 537 turn_off_visual_optimizations(&cinfo); | 570 turn_off_visual_optimizations(&cinfo); |
| 538 | 571 |
| 539 const SkBitmap::Config config = this->getBitmapConfig(&cinfo); | 572 const SkBitmap::Config config = this->getBitmapConfig(&cinfo); |
| 540 | 573 |
| 541 #ifdef ANDROID_RGB | 574 #ifdef ANDROID_RGB |
| 542 adjust_out_color_space_and_dither(&cinfo, config, *this); | 575 adjust_out_color_space_and_dither(&cinfo, config, *this); |
| 543 #endif | 576 #endif |
| 544 | 577 |
| 545 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { | 578 if (1 == sampleSize && SkImageDecoder::kDecodeBounds_Mode == mode) { |
| 579 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 580 // individual pixel. It is very unlikely to be opaque, since |
| 581 // an opaque A8 bitmap would not be very interesting. |
| 582 // Otherwise, a jpeg image is opaque. |
| 546 return bm->setConfig(config, cinfo.image_width, cinfo.image_height, 0, | 583 return bm->setConfig(config, cinfo.image_width, cinfo.image_height, 0, |
| 547 SkBitmap::kA8_Config == config ? | 584 SkBitmap::kA8_Config == config ? |
| 548 kPremul_SkAlphaType : kOpaque_SkAlphaType); | 585 kPremul_SkAlphaType : kOpaque_SkAlphaType); |
| 549 } | 586 } |
| 550 | 587 |
| 551 /* image_width and image_height are the original dimensions, available | 588 /* image_width and image_height are the original dimensions, available |
| 552 after jpeg_read_header(). To see the scaled dimensions, we have to call | 589 after jpeg_read_header(). To see the scaled dimensions, we have to call |
| 553 jpeg_start_decompress(), and then read output_width and output_height. | 590 jpeg_start_decompress(), and then read output_width and output_height. |
| 554 */ | 591 */ |
| 555 if (!jpeg_start_decompress(&cinfo)) { | 592 if (!jpeg_start_decompress(&cinfo)) { |
| 556 /* If we failed here, we may still have enough information to return | 593 /* If we failed here, we may still have enough information to return |
| 557 to the caller if they just wanted (subsampled bounds). If sampleSize | 594 to the caller if they just wanted (subsampled bounds). If sampleSize |
| 558 was 1, then we would have already returned. Thus we just check if | 595 was 1, then we would have already returned. Thus we just check if |
| 559 we're in kDecodeBounds_Mode, and that we have valid output sizes. | 596 we're in kDecodeBounds_Mode, and that we have valid output sizes. |
| 560 | 597 |
| 561 One reason to fail here is that we have insufficient stream data | 598 One reason to fail here is that we have insufficient stream data |
| 562 to complete the setup. However, output dimensions seem to get | 599 to complete the setup. However, output dimensions seem to get |
| 563 computed very early, which is why this special check can pay off. | 600 computed very early, which is why this special check can pay off. |
| 564 */ | 601 */ |
| 565 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension
s(cinfo)) { | 602 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension
s(cinfo)) { |
| 566 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, | 603 SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height, |
| 567 recompute_sampleSize(sampleSize, cinfo)); | 604 recompute_sampleSize(sampleSize, cinfo)); |
| 605 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 606 // individual pixel. It is very unlikely to be opaque, since |
| 607 // an opaque A8 bitmap would not be very interesting. |
| 608 // Otherwise, a jpeg image is opaque. |
| 568 return bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight()
, | 609 return bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight()
, |
| 569 0, SkBitmap::kA8_Config == config ? | 610 0, SkBitmap::kA8_Config == config ? |
| 570 kPremul_SkAlphaType : kOpaque_SkAlphaType); | 611 kPremul_SkAlphaType : kOpaque_SkAlphaType); |
| 571 } else { | 612 } else { |
| 572 return return_false(cinfo, *bm, "start_decompress"); | 613 return return_false(cinfo, *bm, "start_decompress"); |
| 573 } | 614 } |
| 574 } | 615 } |
| 575 sampleSize = recompute_sampleSize(sampleSize, cinfo); | 616 sampleSize = recompute_sampleSize(sampleSize, cinfo); |
| 576 | 617 |
| 577 // should we allow the Chooser (if present) to pick a config for us??? | 618 // should we allow the Chooser (if present) to pick a config for us??? |
| 578 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig
ht)) { | 619 if (!this->chooseFromOneChoice(config, cinfo.output_width, cinfo.output_heig
ht)) { |
| 579 return return_false(cinfo, *bm, "chooseFromOneChoice"); | 620 return return_false(cinfo, *bm, "chooseFromOneChoice"); |
| 580 } | 621 } |
| 581 | 622 |
| 582 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl
eSize); | 623 SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampl
eSize); |
| 624 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 625 // individual pixel. It is very unlikely to be opaque, since |
| 626 // an opaque A8 bitmap would not be very interesting. |
| 627 // Otherwise, a jpeg image is opaque. |
| 583 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, | 628 bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, |
| 584 SkBitmap::kA8_Config != config ? kOpaque_SkAlphaType : kPremul
_SkAlphaType); | 629 SkBitmap::kA8_Config != config ? kOpaque_SkAlphaType : kPremul
_SkAlphaType); |
| 585 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 630 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
| 586 return true; | 631 return true; |
| 587 } | 632 } |
| 588 if (!this->allocPixelRef(bm, NULL)) { | 633 if (!this->allocPixelRef(bm, NULL)) { |
| 589 return return_false(cinfo, *bm, "allocPixelRef"); | 634 return return_false(cinfo, *bm, "allocPixelRef"); |
| 590 } | 635 } |
| 591 | 636 |
| 592 SkAutoLockPixels alp(*bm); | 637 SkAutoLockPixels alp(*bm); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 618 } | 663 } |
| 619 rowptr += bpr; | 664 rowptr += bpr; |
| 620 } | 665 } |
| 621 jpeg_finish_decompress(&cinfo); | 666 jpeg_finish_decompress(&cinfo); |
| 622 return true; | 667 return true; |
| 623 } | 668 } |
| 624 #endif | 669 #endif |
| 625 | 670 |
| 626 // check for supported formats | 671 // check for supported formats |
| 627 SkScaledBitmapSampler::SrcConfig sc; | 672 SkScaledBitmapSampler::SrcConfig sc; |
| 628 if (JCS_CMYK == cinfo.out_color_space) { | 673 int srcBytesPerPixel; |
| 629 // In this case we will manually convert the CMYK values to RGB | 674 |
| 630 sc = SkScaledBitmapSampler::kRGBX; | 675 if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { |
| 631 } else if (3 == cinfo.out_color_components && JCS_RGB == cinfo.out_color_spa
ce) { | |
| 632 sc = SkScaledBitmapSampler::kRGB; | |
| 633 #ifdef ANDROID_RGB | |
| 634 } else if (JCS_RGBA_8888 == cinfo.out_color_space) { | |
| 635 sc = SkScaledBitmapSampler::kRGBX; | |
| 636 } else if (JCS_RGB_565 == cinfo.out_color_space) { | |
| 637 sc = SkScaledBitmapSampler::kRGB_565; | |
| 638 #endif | |
| 639 } else if (1 == cinfo.out_color_components && | |
| 640 JCS_GRAYSCALE == cinfo.out_color_space) { | |
| 641 sc = SkScaledBitmapSampler::kGray; | |
| 642 } else { | |
| 643 return return_false(cinfo, *bm, "jpeg colorspace"); | 676 return return_false(cinfo, *bm, "jpeg colorspace"); |
| 644 } | 677 } |
| 645 | 678 |
| 646 if (!sampler.begin(bm, sc, *this)) { | 679 if (!sampler.begin(bm, sc, *this)) { |
| 647 return return_false(cinfo, *bm, "sampler.begin"); | 680 return return_false(cinfo, *bm, "sampler.begin"); |
| 648 } | 681 } |
| 649 | 682 |
| 650 // The CMYK work-around relies on 4 components per pixel here | 683 SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); |
| 651 SkAutoMalloc srcStorage(cinfo.output_width * 4); | |
| 652 uint8_t* srcRow = (uint8_t*)srcStorage.get(); | 684 uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
| 653 | 685 |
| 654 // Possibly skip initial rows [sampler.srcY0] | 686 // Possibly skip initial rows [sampler.srcY0] |
| 655 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { | 687 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { |
| 656 return return_false(cinfo, *bm, "skip rows"); | 688 return return_false(cinfo, *bm, "skip rows"); |
| 657 } | 689 } |
| 658 | 690 |
| 659 // now loop through scanlines until y == bm->height() - 1 | 691 // now loop through scanlines until y == bm->height() - 1 |
| 660 for (int y = 0;; y++) { | 692 for (int y = 0;; y++) { |
| 661 JSAMPLE* rowptr = (JSAMPLE*)srcRow; | 693 JSAMPLE* rowptr = (JSAMPLE*)srcRow; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 int height = rect.height(); | 826 int height = rect.height(); |
| 795 | 827 |
| 796 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(), | 828 jpeg_init_read_tile_scanline(cinfo, fImageIndex->huffmanIndex(), |
| 797 &startX, &startY, &width, &height); | 829 &startX, &startY, &width, &height); |
| 798 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo); | 830 int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo); |
| 799 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz
e); | 831 int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_siz
e); |
| 800 | 832 |
| 801 SkScaledBitmapSampler sampler(width, height, skiaSampleSize); | 833 SkScaledBitmapSampler sampler(width, height, skiaSampleSize); |
| 802 | 834 |
| 803 SkBitmap bitmap; | 835 SkBitmap bitmap; |
| 836 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); |
| 837 // Assume an A8 bitmap is not opaque to avoid the check of each |
| 838 // individual pixel. It is very unlikely to be opaque, since |
| 839 // an opaque A8 bitmap would not be very interesting. |
| 840 // Otherwise, a jpeg image is opaque. |
| 804 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, | 841 bitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(), 0, |
| 842 config == SkBitmap::kA8_Config ? kPremul_SkAlphaType : |
| 805 kOpaque_SkAlphaType); | 843 kOpaque_SkAlphaType); |
| 806 | 844 |
| 807 // Check ahead of time if the swap(dest, src) is possible or not. | 845 // Check ahead of time if the swap(dest, src) is possible or not. |
| 808 // If yes, then we will stick to AllocPixelRef since it's cheaper with the | 846 // If yes, then we will stick to AllocPixelRef since it's cheaper with the |
| 809 // swap happening. If no, then we will use alloc to allocate pixels to | 847 // swap happening. If no, then we will use alloc to allocate pixels to |
| 810 // prevent garbage collection. | 848 // prevent garbage collection. |
| 811 int w = rect.width() / actualSampleSize; | 849 int w = rect.width() / actualSampleSize; |
| 812 int h = rect.height() / actualSampleSize; | 850 int h = rect.height() / actualSampleSize; |
| 813 bool swapOnly = (rect == region) && bm->isNull() && | 851 bool swapOnly = (rect == region) && bm->isNull() && |
| 814 (w == bitmap.width()) && (h == bitmap.height()) && | 852 (w == bitmap.width()) && (h == bitmap.height()) && |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 } else { | 900 } else { |
| 863 cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(), | 901 cropBitmap(bm, &bitmap, actualSampleSize, region.x(), region.y(), |
| 864 region.width(), region.height(), startX, startY); | 902 region.width(), region.height(), startX, startY); |
| 865 } | 903 } |
| 866 return true; | 904 return true; |
| 867 } | 905 } |
| 868 #endif | 906 #endif |
| 869 | 907 |
| 870 // check for supported formats | 908 // check for supported formats |
| 871 SkScaledBitmapSampler::SrcConfig sc; | 909 SkScaledBitmapSampler::SrcConfig sc; |
| 872 if (JCS_CMYK == cinfo->out_color_space) { | 910 int srcBytesPerPixel; |
| 873 // In this case we will manually convert the CMYK values to RGB | 911 |
| 874 sc = SkScaledBitmapSampler::kRGBX; | 912 if (!get_src_config(*cinfo, &sc, &srcBytesPerPixel)) { |
| 875 } else if (3 == cinfo->out_color_components && JCS_RGB == cinfo->out_color_s
pace) { | |
| 876 sc = SkScaledBitmapSampler::kRGB; | |
| 877 #ifdef ANDROID_RGB | |
| 878 } else if (JCS_RGBA_8888 == cinfo->out_color_space) { | |
| 879 sc = SkScaledBitmapSampler::kRGBX; | |
| 880 } else if (JCS_RGB_565 == cinfo->out_color_space) { | |
| 881 sc = SkScaledBitmapSampler::kRGB_565; | |
| 882 #endif | |
| 883 } else if (1 == cinfo->out_color_components && | |
| 884 JCS_GRAYSCALE == cinfo->out_color_space) { | |
| 885 sc = SkScaledBitmapSampler::kGray; | |
| 886 } else { | |
| 887 return return_false(*cinfo, *bm, "jpeg colorspace"); | 913 return return_false(*cinfo, *bm, "jpeg colorspace"); |
| 888 } | 914 } |
| 889 | 915 |
| 890 if (!sampler.begin(&bitmap, sc, *this)) { | 916 if (!sampler.begin(&bitmap, sc, *this)) { |
| 891 return return_false(*cinfo, bitmap, "sampler.begin"); | 917 return return_false(*cinfo, bitmap, "sampler.begin"); |
| 892 } | 918 } |
| 893 | 919 |
| 894 // The CMYK work-around relies on 4 components per pixel here | 920 SkAutoMalloc srcStorage(width * srcBytesPerPixel); |
| 895 SkAutoMalloc srcStorage(width * 4); | |
| 896 uint8_t* srcRow = (uint8_t*)srcStorage.get(); | 921 uint8_t* srcRow = (uint8_t*)srcStorage.get(); |
| 897 | 922 |
| 898 // Possibly skip initial rows [sampler.srcY0] | 923 // Possibly skip initial rows [sampler.srcY0] |
| 899 if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow, sampler.
srcY0())) { | 924 if (!skip_src_rows_tile(cinfo, fImageIndex->huffmanIndex(), srcRow, sampler.
srcY0())) { |
| 900 return return_false(*cinfo, bitmap, "skip rows"); | 925 return return_false(*cinfo, bitmap, "skip rows"); |
| 901 } | 926 } |
| 902 | 927 |
| 903 // now loop through scanlines until y == bitmap->height() - 1 | 928 // now loop through scanlines until y == bitmap->height() - 1 |
| 904 for (int y = 0;; y++) { | 929 for (int y = 0;; y++) { |
| 905 JSAMPLE* rowptr = (JSAMPLE*)srcRow; | 930 JSAMPLE* rowptr = (JSAMPLE*)srcRow; |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 return SkImageDecoder::kUnknown_Format; | 1240 return SkImageDecoder::kUnknown_Format; |
| 1216 } | 1241 } |
| 1217 | 1242 |
| 1218 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { | 1243 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { |
| 1219 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; | 1244 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; |
| 1220 } | 1245 } |
| 1221 | 1246 |
| 1222 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); | 1247 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); |
| 1223 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); | 1248 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); |
| 1224 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); | 1249 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); |
| OLD | NEW |