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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 // implemented to guess sRGB in this case. | 350 // implemented to guess sRGB in this case. |
351 return nullptr; | 351 return nullptr; |
352 } | 352 } |
353 | 353 |
354 static int bytes_per_pixel(int bitsPerPixel) { | 354 static int bytes_per_pixel(int bitsPerPixel) { |
355 // Note that we will have to change this implementation if we start | 355 // Note that we will have to change this implementation if we start |
356 // supporting outputs from libpng that are less than 8-bits per component. | 356 // supporting outputs from libpng that are less than 8-bits per component. |
357 return bitsPerPixel / 8; | 357 return bitsPerPixel / 8; |
358 } | 358 } |
359 | 359 |
360 static bool png_conversion_possible(const SkImageInfo& dst, const SkImageInfo& s
rc) { | |
361 // Ensure the alpha type is valid | |
362 if (!valid_alpha(dst.alphaType(), src.alphaType())) { | |
363 return false; | |
364 } | |
365 | |
366 // Check for supported color types | |
367 switch (dst.colorType()) { | |
368 case kRGBA_8888_SkColorType: | |
369 case kBGRA_8888_SkColorType: | |
370 case kRGBA_F16_SkColorType: | |
371 return true; | |
372 case kRGB_565_SkColorType: | |
373 return kOpaque_SkAlphaType == src.alphaType(); | |
374 default: | |
375 return dst.colorType() == src.colorType(); | |
376 } | |
377 } | |
378 | |
379 void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) { | 360 void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) { |
380 switch (fXformMode) { | 361 switch (fXformMode) { |
381 case kSwizzleOnly_XformMode: | 362 case kSwizzleOnly_XformMode: |
382 fStorage.reset(SkAlign4(fSrcRowBytes)); | 363 fStorage.reset(SkAlign4(fSrcRowBytes)); |
383 fSwizzlerSrcRow = fStorage.get(); | 364 fSwizzlerSrcRow = fStorage.get(); |
384 break; | 365 break; |
385 case kColorOnly_XformMode: | 366 case kColorOnly_XformMode: |
386 // Intentional fall through. A swizzler hasn't been created yet, bu
t one will | 367 // Intentional fall through. A swizzler hasn't been created yet, bu
t one will |
387 // be created later if we are sampling. We'll go ahead and allocate | 368 // be created later if we are sampling. We'll go ahead and allocate |
388 // enough memory to swizzle if necessary. | 369 // enough memory to swizzle if necessary. |
(...skipping 26 matching lines...) Expand all Loading... |
415 class SkPngNormalCodec : public SkPngCodec { | 396 class SkPngNormalCodec : public SkPngCodec { |
416 public: | 397 public: |
417 SkPngNormalCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imageI
nfo, | 398 SkPngNormalCodec(const SkEncodedInfo& encodedInfo, const SkImageInfo& imageI
nfo, |
418 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, | 399 SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr
, |
419 png_infop info_ptr, int bitDepth) | 400 png_infop info_ptr, int bitDepth) |
420 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, 1) | 401 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, 1) |
421 {} | 402 {} |
422 | 403 |
423 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 404 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
424 SkPMColor ctable[], int* ctableCount) override { | 405 SkPMColor ctable[], int* ctableCount) override { |
425 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 406 if (!conversion_possible(dstInfo, this->getInfo()) || |
426 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 407 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
427 { | 408 { |
428 return kInvalidConversion; | 409 return kInvalidConversion; |
429 } | 410 } |
430 | 411 |
431 this->allocateStorage(dstInfo); | 412 this->allocateStorage(dstInfo); |
432 return kSuccess; | 413 return kSuccess; |
433 } | 414 } |
434 | 415 |
435 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int cou
nt, int startRow) | 416 int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int cou
nt, int startRow) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 png_infop info_ptr, int bitDepth, int numberPasses) | 463 png_infop info_ptr, int bitDepth, int numberPasses) |
483 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, | 464 : INHERITED(encodedInfo, imageInfo, stream, chunkReader, png_ptr, info_p
tr, bitDepth, |
484 numberPasses) | 465 numberPasses) |
485 , fCanSkipRewind(false) | 466 , fCanSkipRewind(false) |
486 { | 467 { |
487 SkASSERT(numberPasses != 1); | 468 SkASSERT(numberPasses != 1); |
488 } | 469 } |
489 | 470 |
490 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 471 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
491 SkPMColor ctable[], int* ctableCount) override { | 472 SkPMColor ctable[], int* ctableCount) override { |
492 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 473 if (!conversion_possible(dstInfo, this->getInfo()) || |
493 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 474 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
494 { | 475 { |
495 return kInvalidConversion; | 476 return kInvalidConversion; |
496 } | 477 } |
497 | 478 |
498 this->allocateStorage(dstInfo); | 479 this->allocateStorage(dstInfo); |
499 fCanSkipRewind = true; | 480 fCanSkipRewind = true; |
500 return SkCodec::kSuccess; | 481 return SkCodec::kSuccess; |
501 } | 482 } |
502 | 483 |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 } | 783 } |
803 png_read_update_info(fPng_ptr, fInfo_ptr); | 784 png_read_update_info(fPng_ptr, fInfo_ptr); |
804 | 785 |
805 // Reset fSwizzler and fColorXform. We can't do this in onRewind() because
the | 786 // Reset fSwizzler and fColorXform. We can't do this in onRewind() because
the |
806 // interlaced scanline decoder may need to rewind. | 787 // interlaced scanline decoder may need to rewind. |
807 fSwizzler.reset(nullptr); | 788 fSwizzler.reset(nullptr); |
808 fColorXform = nullptr; | 789 fColorXform = nullptr; |
809 | 790 |
810 bool needsColorXform = needs_color_xform(dstInfo, this->getInfo()); | 791 bool needsColorXform = needs_color_xform(dstInfo, this->getInfo()); |
811 if (needsColorXform) { | 792 if (needsColorXform) { |
812 if (kGray_8_SkColorType == dstInfo.colorType() || | |
813 kRGB_565_SkColorType == dstInfo.colorType()) | |
814 { | |
815 return false; | |
816 } | |
817 | |
818 fColorXform = SkColorSpaceXform::New(sk_ref_sp(this->getInfo().colorSpac
e()), | 793 fColorXform = SkColorSpaceXform::New(sk_ref_sp(this->getInfo().colorSpac
e()), |
819 sk_ref_sp(dstInfo.colorSpace())); | 794 sk_ref_sp(dstInfo.colorSpace())); |
820 | 795 |
821 if (!fColorXform && kRGBA_F16_SkColorType == dstInfo.colorType()) { | 796 // TODO (msarett): Possibly working toward asserting this? |
| 797 if (!fColorXform) { |
822 return false; | 798 return false; |
823 } | 799 } |
824 } | 800 } |
825 | 801 |
826 // If the image is RGBA and we have a color xform, we can skip the swizzler. | 802 // If the image is RGBA and we have a color xform, we can skip the swizzler. |
827 // FIXME (msarett): | 803 // FIXME (msarett): |
828 // Support more input types to fColorXform (ex: RGB, Gray) and skip the swiz
zler more often. | 804 // Support more input types to fColorXform (ex: RGB, Gray) and skip the swiz
zler more often. |
829 if (fColorXform && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().colo
r() && | 805 if (fColorXform && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().colo
r() && |
830 !options.fSubset) | 806 !options.fSubset) |
831 { | 807 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 | 876 |
901 fPng_ptr = png_ptr; | 877 fPng_ptr = png_ptr; |
902 fInfo_ptr = info_ptr; | 878 fInfo_ptr = info_ptr; |
903 return true; | 879 return true; |
904 } | 880 } |
905 | 881 |
906 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, | 882 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, |
907 size_t rowBytes, const Options& options, | 883 size_t rowBytes, const Options& options, |
908 SkPMColor ctable[], int* ctableCount, | 884 SkPMColor ctable[], int* ctableCount, |
909 int* rowsDecoded) { | 885 int* rowsDecoded) { |
910 if (!png_conversion_possible(dstInfo, this->getInfo()) || | 886 if (!conversion_possible(dstInfo, this->getInfo()) || |
911 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 887 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
912 { | 888 { |
913 return kInvalidConversion; | 889 return kInvalidConversion; |
914 } | 890 } |
915 | 891 |
916 if (options.fSubset) { | 892 if (options.fSubset) { |
917 return kUnimplemented; | 893 return kUnimplemented; |
918 } | 894 } |
919 | 895 |
920 this->allocateStorage(dstInfo); | 896 this->allocateStorage(dstInfo); |
(...skipping 20 matching lines...) Expand all Loading... |
941 SkCodec* outCodec; | 917 SkCodec* outCodec; |
942 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { | 918 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { |
943 // Codec has taken ownership of the stream. | 919 // Codec has taken ownership of the stream. |
944 SkASSERT(outCodec); | 920 SkASSERT(outCodec); |
945 streamDeleter.release(); | 921 streamDeleter.release(); |
946 return outCodec; | 922 return outCodec; |
947 } | 923 } |
948 | 924 |
949 return nullptr; | 925 return nullptr; |
950 } | 926 } |
OLD | NEW |