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