OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
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 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 size_t colorXformBytes = fColorXform ? width * sizeof(uint32_t) : 0; | 363 size_t colorXformBytes = fColorXform ? width * sizeof(uint32_t) : 0; |
364 | 364 |
365 fStorage.reset(SkAlign4(fSrcRowBytes) + colorXformBytes); | 365 fStorage.reset(SkAlign4(fSrcRowBytes) + colorXformBytes); |
366 fSwizzlerSrcRow = fStorage.get(); | 366 fSwizzlerSrcRow = fStorage.get(); |
367 fColorXformSrcRow = | 367 fColorXformSrcRow = |
368 fColorXform ? SkTAddOffset<uint32_t>(fSwizzlerSrcRow, SkAlign4(fSrcR
owBytes)) : 0; | 368 fColorXform ? SkTAddOffset<uint32_t>(fSwizzlerSrcRow, SkAlign4(fSrcR
owBytes)) : 0; |
369 } | 369 } |
370 | 370 |
371 class SkPngNormalCodec : public SkPngCodec { | 371 class SkPngNormalCodec : public SkPngCodec { |
372 public: | 372 public: |
373 SkPngNormalCodec(int width, int height, const SkEncodedInfo& info, SkStream*
stream, | 373 SkPngNormalCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imageI
nfo, |
374 SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_p
tr, int bitDepth, | 374 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, |
375 sk_sp<SkColorSpace> colorSpace) | 375 png_infop info_ptr, int bitDepth) |
376 : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr,
bitDepth, 1, | 376 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, 1) |
377 colorSpace) | |
378 {} | 377 {} |
379 | 378 |
380 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 379 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
381 SkPMColor ctable[], int* ctableCount) override { | 380 SkPMColor ctable[], int* ctableCount) override { |
382 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 381 if (!png_conversion_possible(dstInfo, this->getInfo()) || |
383 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 382 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
384 { | 383 { |
385 return kInvalidConversion; | 384 return kInvalidConversion; |
386 } | 385 } |
387 | 386 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 } | 439 } |
441 return true; | 440 return true; |
442 } | 441 } |
443 | 442 |
444 typedef SkPngCodec INHERITED; | 443 typedef SkPngCodec INHERITED; |
445 }; | 444 }; |
446 | 445 |
447 | 446 |
448 class SkPngInterlacedCodec : public SkPngCodec { | 447 class SkPngInterlacedCodec : public SkPngCodec { |
449 public: | 448 public: |
450 SkPngInterlacedCodec(int width, int height, const SkEncodedInfo& info, | 449 SkPngInterlacedCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& im
ageInfo, |
451 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, | 450 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, |
452 png_infop info_ptr, int bitDepth, int numberPasses, sk_sp<SkColorSpa
ce> colorSpace) | 451 png_infop info_ptr, int bitDepth, int numberPasses) |
453 : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr,
bitDepth, | 452 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, |
454 numberPasses, colorSpace) | 453 numberPasses) |
455 , fCanSkipRewind(false) | 454 , fCanSkipRewind(false) |
456 { | 455 { |
457 SkASSERT(numberPasses != 1); | 456 SkASSERT(numberPasses != 1); |
458 } | 457 } |
459 | 458 |
460 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 459 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
461 SkPMColor ctable[], int* ctableCount) override { | 460 SkPMColor ctable[], int* ctableCount) override { |
462 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 461 if (!png_conversion_possible(dstInfo, this->getInfo()) || |
463 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 462 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
464 { | 463 { |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 *info_ptrp = info_ptr; | 715 *info_ptrp = info_ptr; |
717 } | 716 } |
718 | 717 |
719 if (outCodec) { | 718 if (outCodec) { |
720 sk_sp<SkColorSpace> colorSpace = read_color_space(png_ptr, info_ptr); | 719 sk_sp<SkColorSpace> colorSpace = read_color_space(png_ptr, info_ptr); |
721 if (!colorSpace) { | 720 if (!colorSpace) { |
722 // Treat unmarked pngs as sRGB. | 721 // Treat unmarked pngs as sRGB. |
723 colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); | 722 colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); |
724 } | 723 } |
725 | 724 |
726 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8); | 725 SkEncodedInfo encodedInfo = SkEncodedInfo::Make(color, alpha, 8); |
| 726 SkImageInfo imageInfo = encodedInfo.makeImageInfo(origWidth, origHeight,
colorSpace); |
| 727 |
| 728 if (SkEncodedInfo::kOpaque_Alpha == alpha) { |
| 729 png_color_8p sigBits; |
| 730 if (png_get_sBIT(png_ptr, info_ptr, &sigBits)) { |
| 731 if (5 == sigBits->red && 6 == sigBits->green && 5 == sigBits->bl
ue) { |
| 732 // Recommend a decode to 565 if the sBIT indicates 565. |
| 733 imageInfo = imageInfo.makeColorType(kRGB_565_SkColorType); |
| 734 } |
| 735 } |
| 736 } |
727 | 737 |
728 if (1 == numberPasses) { | 738 if (1 == numberPasses) { |
729 *outCodec = new SkPngNormalCodec(origWidth, origHeight, info, stream
, | 739 *outCodec = new SkPngNormalCodec(encodedInfo, imageInfo, stream, |
730 chunkReader, png_ptr, info_ptr, bitDepth, colorSpace); | 740 chunkReader, png_ptr, info_ptr, bitDepth); |
731 } else { | 741 } else { |
732 *outCodec = new SkPngInterlacedCodec(origWidth, origHeight, info, st
ream, | 742 *outCodec = new SkPngInterlacedCodec(encodedInfo, imageInfo, stream, |
733 chunkReader, png_ptr, info_ptr, bitDepth, numberPasses, colo
rSpace); | 743 chunkReader, png_ptr, info_ptr, bitDepth, numberPasses); |
734 } | 744 } |
735 } | 745 } |
736 | 746 |
737 return true; | 747 return true; |
738 } | 748 } |
739 | 749 |
740 SkPngCodec::SkPngCodec(int width, int height, const SkEncodedInfo& info, SkStrea
m* stream, | 750 SkPngCodec::SkPngCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imag
eInfo, |
741 SkPngChunkReader* chunkReader, png_structp png_ptr, png_i
nfop info_ptr, | 751 SkStream* stream, SkPngChunkReader* chunkReader, png_stru
ctp png_ptr, |
742 int bitDepth, int numberPasses, sk_sp<SkColorSpace> color
Space) | 752 png_infop info_ptr, int bitDepth, int numberPasses) |
743 : INHERITED(width, height, info, stream, colorSpace) | 753 : INHERITED(encodedInfo, imageInfo, stream) |
744 , fPngChunkReader(SkSafeRef(chunkReader)) | 754 , fPngChunkReader(SkSafeRef(chunkReader)) |
745 , fPng_ptr(png_ptr) | 755 , fPng_ptr(png_ptr) |
746 , fInfo_ptr(info_ptr) | 756 , fInfo_ptr(info_ptr) |
747 , fSwizzlerSrcRow(nullptr) | 757 , fSwizzlerSrcRow(nullptr) |
748 , fColorXformSrcRow(nullptr) | 758 , fColorXformSrcRow(nullptr) |
749 , fSrcRowBytes(width * (bytes_per_pixel(this->getEncodedInfo().bitsPerPixel(
)))) | 759 , fSrcRowBytes(imageInfo.width() * (bytes_per_pixel(this->getEncodedInfo().b
itsPerPixel()))) |
750 , fNumberPasses(numberPasses) | 760 , fNumberPasses(numberPasses) |
751 , fBitDepth(bitDepth) | 761 , fBitDepth(bitDepth) |
752 {} | 762 {} |
753 | 763 |
754 SkPngCodec::~SkPngCodec() { | 764 SkPngCodec::~SkPngCodec() { |
755 this->destroyReadStruct(); | 765 this->destroyReadStruct(); |
756 } | 766 } |
757 | 767 |
758 void SkPngCodec::destroyReadStruct() { | 768 void SkPngCodec::destroyReadStruct() { |
759 if (fPng_ptr) { | 769 if (fPng_ptr) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 SkCodec* outCodec; | 889 SkCodec* outCodec; |
880 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { | 890 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { |
881 // Codec has taken ownership of the stream. | 891 // Codec has taken ownership of the stream. |
882 SkASSERT(outCodec); | 892 SkASSERT(outCodec); |
883 streamDeleter.release(); | 893 streamDeleter.release(); |
884 return outCodec; | 894 return outCodec; |
885 } | 895 } |
886 | 896 |
887 return nullptr; | 897 return nullptr; |
888 } | 898 } |
OLD | NEW |