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 "SkCodec_libpng.h" | 8 #include "SkCodec_libpng.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 } | 387 } |
388 } | 388 } |
389 | 389 |
390 /////////////////////////////////////////////////////////////////////////////// | 390 /////////////////////////////////////////////////////////////////////////////// |
391 // Getting the pixels | 391 // Getting the pixels |
392 /////////////////////////////////////////////////////////////////////////////// | 392 /////////////////////////////////////////////////////////////////////////////// |
393 | 393 |
394 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, | 394 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, |
395 const Options& options, | 395 const Options& options, |
396 SkPMColor ctable[], | 396 SkPMColor ctable[], |
397 int* ctableCount) { | 397 int* ctableCount, |
| 398 int subsetLeft, |
| 399 int subsetWidth) { |
398 // FIXME: Could we use the return value of setjmp to specify the type of | 400 // FIXME: Could we use the return value of setjmp to specify the type of |
399 // error? | 401 // error? |
400 if (setjmp(png_jmpbuf(fPng_ptr))) { | 402 if (setjmp(png_jmpbuf(fPng_ptr))) { |
401 SkCodecPrintf("setjmp long jump!\n"); | 403 SkCodecPrintf("setjmp long jump!\n"); |
402 return kInvalidInput; | 404 return kInvalidInput; |
403 } | 405 } |
404 png_read_update_info(fPng_ptr, fInfo_ptr); | 406 png_read_update_info(fPng_ptr, fInfo_ptr); |
405 | 407 |
406 //srcColorType was determined in read_header() which determined png color ty
pe | 408 //srcColorType was determined in read_header() which determined png color ty
pe |
407 const SkColorType srcColorType = this->getInfo().colorType(); | 409 const SkColorType srcColorType = this->getInfo().colorType(); |
(...skipping 21 matching lines...) Expand all Loading... |
429 //would have exited before now if the colorType was supported by png | 431 //would have exited before now if the colorType was supported by png |
430 SkASSERT(false); | 432 SkASSERT(false); |
431 } | 433 } |
432 | 434 |
433 // Copy the color table to the client if they request kIndex8 mode | 435 // Copy the color table to the client if they request kIndex8 mode |
434 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); | 436 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); |
435 | 437 |
436 // Create the swizzler. SkPngCodec retains ownership of the color table. | 438 // Create the swizzler. SkPngCodec retains ownership of the color table. |
437 const SkPMColor* colors = get_color_ptr(fColorTable.get()); | 439 const SkPMColor* colors = get_color_ptr(fColorTable.get()); |
438 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, | 440 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, |
439 options.fZeroInitialized, this->getInfo())); | 441 options.fZeroInitialized, this->getInfo(), subsetLeft, subse
tWidth)); |
440 if (!fSwizzler) { | 442 if (!fSwizzler) { |
441 // FIXME: CreateSwizzler could fail for another reason. | 443 // FIXME: CreateSwizzler could fail for another reason. |
442 return kUnimplemented; | 444 return kUnimplemented; |
443 } | 445 } |
444 return kSuccess; | 446 return kSuccess; |
445 } | 447 } |
446 | 448 |
447 | 449 |
448 bool SkPngCodec::onRewind() { | 450 bool SkPngCodec::onRewind() { |
449 // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header | 451 // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header |
(...skipping 23 matching lines...) Expand all Loading... |
473 } | 475 } |
474 if (options.fSubset) { | 476 if (options.fSubset) { |
475 // Subsets are not supported. | 477 // Subsets are not supported. |
476 return kUnimplemented; | 478 return kUnimplemented; |
477 } | 479 } |
478 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { | 480 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { |
479 return kInvalidScale; | 481 return kInvalidScale; |
480 } | 482 } |
481 | 483 |
482 // Note that ctable and ctableCount may be modified if there is a color tabl
e | 484 // Note that ctable and ctableCount may be modified if there is a color tabl
e |
483 const Result result = this->initializeSwizzler(requestedInfo, options, | 485 const Result result = this->initializeSwizzler(requestedInfo, options, ctabl
e, ctableCount, 0, |
484 ctable, ctableCount); | 486 requestedInfo.width()); |
485 if (result != kSuccess) { | 487 if (result != kSuccess) { |
486 return result; | 488 return result; |
487 } | 489 } |
488 // FIXME: Could we use the return value of setjmp to specify the type of | 490 // FIXME: Could we use the return value of setjmp to specify the type of |
489 // error? | 491 // error? |
490 int row = 0; | 492 int row = 0; |
491 if (setjmp(png_jmpbuf(fPng_ptr))) { | 493 if (setjmp(png_jmpbuf(fPng_ptr))) { |
492 // Assume that any error that occurs while reading rows is caused by an
incomplete input. | 494 // Assume that any error that occurs while reading rows is caused by an
incomplete input. |
493 if (fNumberPasses > 1) { | 495 if (fNumberPasses > 1) { |
494 // FIXME (msarett): Handle incomplete interlaced pngs. | 496 // FIXME (msarett): Handle incomplete interlaced pngs. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 class SkPngScanlineDecoder : public SkPngCodec { | 609 class SkPngScanlineDecoder : public SkPngCodec { |
608 public: | 610 public: |
609 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream, | 611 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream, |
610 png_structp png_ptr, png_infop info_ptr, int bitDepth) | 612 png_structp png_ptr, png_infop info_ptr, int bitDepth) |
611 : INHERITED(srcInfo, stream, png_ptr, info_ptr, bitDepth, 1) | 613 : INHERITED(srcInfo, stream, png_ptr, info_ptr, bitDepth, 1) |
612 , fSrcRow(nullptr) | 614 , fSrcRow(nullptr) |
613 , fAlphaState(kUnknown_AlphaState) | 615 , fAlphaState(kUnknown_AlphaState) |
614 {} | 616 {} |
615 | 617 |
616 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 618 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
617 SkPMColor ctable[], int* ctableCount) override { | 619 SkPMColor ctable[], int* ctableCount, int subsetLeft, int subsetWidt
h) override { |
618 if (!conversion_possible(dstInfo, this->getInfo())) { | 620 if (!conversion_possible(dstInfo, this->getInfo())) { |
619 return kInvalidConversion; | 621 return kInvalidConversion; |
620 } | 622 } |
621 | 623 |
622 // Check to see if scaling was requested. | 624 // Check to see if scaling was requested. |
623 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 625 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
624 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { | 626 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { |
625 return kInvalidScale; | 627 return kInvalidScale; |
626 } | 628 } |
627 } | 629 } |
628 | 630 |
629 const Result result = this->initializeSwizzler(dstInfo, options, ctable, | 631 const Result result = this->initializeSwizzler(dstInfo, options, ctable, |
630 ctableCount); | 632 ctableCount, subsetLeft,
subsetWidth); |
631 if (result != kSuccess) { | 633 if (result != kSuccess) { |
632 return result; | 634 return result; |
633 } | 635 } |
634 | 636 |
635 fAlphaState = kUnknown_AlphaState; | 637 fAlphaState = kUnknown_AlphaState; |
636 fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(this-
>srcConfig())); | 638 fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(this-
>srcConfig())); |
637 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 639 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
638 | 640 |
639 return kSuccess; | 641 return kSuccess; |
640 } | 642 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 png_structp png_ptr, png_infop info_ptr, int bitDepth, int numberPas
ses) | 703 png_structp png_ptr, png_infop info_ptr, int bitDepth, int numberPas
ses) |
702 : INHERITED(srcInfo, stream, png_ptr, info_ptr, bitDepth, numberPasses) | 704 : INHERITED(srcInfo, stream, png_ptr, info_ptr, bitDepth, numberPasses) |
703 , fAlphaState(kUnknown_AlphaState) | 705 , fAlphaState(kUnknown_AlphaState) |
704 , fHeight(-1) | 706 , fHeight(-1) |
705 , fCanSkipRewind(false) | 707 , fCanSkipRewind(false) |
706 { | 708 { |
707 SkASSERT(numberPasses != 1); | 709 SkASSERT(numberPasses != 1); |
708 } | 710 } |
709 | 711 |
710 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, | 712 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opti
ons, |
711 SkPMColor ctable[], int* ctableCount) override | 713 SkPMColor ctable[], int* ctableCount, int subsetLeft, int subsetWidt
h) override { |
712 { | |
713 if (!conversion_possible(dstInfo, this->getInfo())) { | 714 if (!conversion_possible(dstInfo, this->getInfo())) { |
714 return kInvalidConversion; | 715 return kInvalidConversion; |
715 } | 716 } |
716 | 717 |
717 // Check to see if scaling was requested. | 718 // Check to see if scaling was requested. |
718 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 719 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
719 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { | 720 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { |
720 return kInvalidScale; | 721 return kInvalidScale; |
721 } | 722 } |
722 } | 723 } |
723 | 724 |
724 const Result result = this->initializeSwizzler(dstInfo, options, ctable, | 725 const Result result = this->initializeSwizzler(dstInfo, options, ctable, |
725 ctableCount); | 726 ctableCount, subsetLeft,
subsetWidth); |
726 if (result != kSuccess) { | 727 if (result != kSuccess) { |
727 return result; | 728 return result; |
728 } | 729 } |
729 | 730 |
730 fAlphaState = kUnknown_AlphaState; | 731 fAlphaState = kUnknown_AlphaState; |
731 fHeight = dstInfo.height(); | 732 fHeight = dstInfo.height(); |
732 // FIXME: This need not be called on a second call to onStartScanlineDec
ode. | 733 // FIXME: This need not be called on a second call to onStartScanlineDec
ode. |
733 fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(this-
>srcConfig()); | 734 fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(this-
>srcConfig()); |
734 fGarbageRow.reset(fSrcRowBytes); | 735 fGarbageRow.reset(fSrcRowBytes); |
735 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); | 736 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 | 857 |
857 if (1 == numberPasses) { | 858 if (1 == numberPasses) { |
858 return new SkPngScanlineDecoder(imageInfo, streamDeleter.detach(), png_p
tr, info_ptr, | 859 return new SkPngScanlineDecoder(imageInfo, streamDeleter.detach(), png_p
tr, info_ptr, |
859 bitDepth); | 860 bitDepth); |
860 } | 861 } |
861 | 862 |
862 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.detach(),
png_ptr, | 863 return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.detach(),
png_ptr, |
863 info_ptr, bitDepth, numberPasses); | 864 info_ptr, bitDepth, numberPasses); |
864 } | 865 } |
865 | 866 |
OLD | NEW |