| 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 |