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