| 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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, | 464 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, |
| 465 options.fZeroInitialized)); | 465 options.fZeroInitialized)); |
| 466 if (!fSwizzler) { | 466 if (!fSwizzler) { |
| 467 // FIXME: CreateSwizzler could fail for another reason. | 467 // FIXME: CreateSwizzler could fail for another reason. |
| 468 return kUnimplemented; | 468 return kUnimplemented; |
| 469 } | 469 } |
| 470 return kSuccess; | 470 return kSuccess; |
| 471 } | 471 } |
| 472 | 472 |
| 473 | 473 |
| 474 bool SkPngCodec::handleRewind() { | 474 bool SkPngCodec::onRewind() { |
| 475 switch (this->rewindIfNeeded()) { | 475 // This sets fPng_ptr and fInfo_ptr to NULL. If read_header |
| 476 case kNoRewindNecessary_RewindState: | 476 // succeeds, they will be repopulated, and if it fails, they will |
| 477 return true; | 477 // remain NULL. Any future accesses to fPng_ptr and fInfo_ptr will |
| 478 case kCouldNotRewind_RewindState: | 478 // come through this function which will rewind and again attempt |
| 479 return false; | 479 // to reinitialize them. |
| 480 case kRewound_RewindState: { | 480 this->destroyReadStruct(); |
| 481 // This sets fPng_ptr and fInfo_ptr to NULL. If read_header | 481 |
| 482 // succeeds, they will be repopulated, and if it fails, they will | 482 png_structp png_ptr; |
| 483 // remain NULL. Any future accesses to fPng_ptr and fInfo_ptr will | 483 png_infop info_ptr; |
| 484 // come through this function which will rewind and again attempt | 484 if (!read_header(this->stream(), &png_ptr, &info_ptr, NULL, NULL)) { |
| 485 // to reinitialize them. | 485 return false; |
| 486 this->destroyReadStruct(); | |
| 487 png_structp png_ptr; | |
| 488 png_infop info_ptr; | |
| 489 if (read_header(this->stream(), &png_ptr, &info_ptr, NULL, NULL)) { | |
| 490 fPng_ptr = png_ptr; | |
| 491 fInfo_ptr = info_ptr; | |
| 492 return true; | |
| 493 } | |
| 494 return false; | |
| 495 } | |
| 496 default: | |
| 497 SkASSERT(false); | |
| 498 return false; | |
| 499 } | 486 } |
| 487 |
| 488 fPng_ptr = png_ptr; |
| 489 fInfo_ptr = info_ptr; |
| 490 return true; |
| 500 } | 491 } |
| 501 | 492 |
| 502 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
dst, | 493 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
dst, |
| 503 size_t dstRowBytes, const Options& optio
ns, | 494 size_t dstRowBytes, const Options& optio
ns, |
| 504 SkPMColor ctable[], int* ctableCount) { | 495 SkPMColor ctable[], int* ctableCount) { |
| 505 if (!conversion_possible(requestedInfo, this->getInfo())) { | 496 if (!conversion_possible(requestedInfo, this->getInfo())) { |
| 506 return kInvalidConversion; | 497 return kInvalidConversion; |
| 507 } | 498 } |
| 508 if (options.fSubset) { | 499 if (options.fSubset) { |
| 509 // Subsets are not supported. | 500 // Subsets are not supported. |
| 510 return kUnimplemented; | 501 return kUnimplemented; |
| 511 } | 502 } |
| 512 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { | 503 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { |
| 513 return kInvalidScale; | 504 return kInvalidScale; |
| 514 } | 505 } |
| 515 if (!this->handleRewind()) { | 506 if (!this->rewindIfNeeded()) { |
| 516 return kCouldNotRewind; | 507 return kCouldNotRewind; |
| 517 } | 508 } |
| 518 | 509 |
| 519 // Note that ctable and ctableCount may be modified if there is a color tabl
e | 510 // Note that ctable and ctableCount may be modified if there is a color tabl
e |
| 520 const Result result = this->initializeSwizzler(requestedInfo, options, | 511 const Result result = this->initializeSwizzler(requestedInfo, options, |
| 521 ctable, ctableCount); | 512 ctable, ctableCount); |
| 522 if (result != kSuccess) { | 513 if (result != kSuccess) { |
| 523 return result; | 514 return result; |
| 524 } | 515 } |
| 525 // FIXME: Could we use the return value of setjmp to specify the type of | 516 // FIXME: Could we use the return value of setjmp to specify the type of |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) | 577 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) |
| 587 : INHERITED(srcInfo) | 578 : INHERITED(srcInfo) |
| 588 , fCodec(codec) | 579 , fCodec(codec) |
| 589 , fHasAlpha(false) | 580 , fHasAlpha(false) |
| 590 {} | 581 {} |
| 591 | 582 |
| 592 SkCodec::Result onStart(const SkImageInfo& dstInfo, | 583 SkCodec::Result onStart(const SkImageInfo& dstInfo, |
| 593 const SkCodec::Options& options, | 584 const SkCodec::Options& options, |
| 594 SkPMColor ctable[], int* ctableCount) override | 585 SkPMColor ctable[], int* ctableCount) override |
| 595 { | 586 { |
| 596 if (!fCodec->handleRewind()) { | 587 if (!fCodec->rewindIfNeeded()) { |
| 597 return SkCodec::kCouldNotRewind; | 588 return SkCodec::kCouldNotRewind; |
| 598 } | 589 } |
| 599 | 590 |
| 600 if (!conversion_possible(dstInfo, this->getInfo())) { | 591 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 601 return SkCodec::kInvalidConversion; | 592 return SkCodec::kInvalidConversion; |
| 602 } | 593 } |
| 603 | 594 |
| 604 // Check to see if scaling was requested. | 595 // Check to see if scaling was requested. |
| 605 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 596 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 606 return SkCodec::kInvalidScale; | 597 return SkCodec::kInvalidScale; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 , fHasAlpha(false) | 661 , fHasAlpha(false) |
| 671 , fCurrentRow(0) | 662 , fCurrentRow(0) |
| 672 , fHeight(srcInfo.height()) | 663 , fHeight(srcInfo.height()) |
| 673 , fCanSkipRewind(false) | 664 , fCanSkipRewind(false) |
| 674 {} | 665 {} |
| 675 | 666 |
| 676 SkCodec::Result onStart(const SkImageInfo& dstInfo, | 667 SkCodec::Result onStart(const SkImageInfo& dstInfo, |
| 677 const SkCodec::Options& options, | 668 const SkCodec::Options& options, |
| 678 SkPMColor ctable[], int* ctableCount) override | 669 SkPMColor ctable[], int* ctableCount) override |
| 679 { | 670 { |
| 680 if (!fCodec->handleRewind()) { | 671 if (!fCodec->rewindIfNeeded()) { |
| 681 return SkCodec::kCouldNotRewind; | 672 return SkCodec::kCouldNotRewind; |
| 682 } | 673 } |
| 683 | 674 |
| 684 if (!conversion_possible(dstInfo, this->getInfo())) { | 675 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 685 return SkCodec::kInvalidConversion; | 676 return SkCodec::kInvalidConversion; |
| 686 } | 677 } |
| 687 | 678 |
| 688 // Check to see if scaling was requested. | 679 // Check to see if scaling was requested. |
| 689 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 680 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 690 return SkCodec::kInvalidScale; | 681 return SkCodec::kInvalidScale; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 707 return SkCodec::kSuccess; | 698 return SkCodec::kSuccess; |
| 708 } | 699 } |
| 709 | 700 |
| 710 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { | 701 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { |
| 711 // rewind stream if have previously called onGetScanlines, | 702 // rewind stream if have previously called onGetScanlines, |
| 712 // since we need entire progressive image to get scanlines | 703 // since we need entire progressive image to get scanlines |
| 713 if (fCanSkipRewind) { | 704 if (fCanSkipRewind) { |
| 714 // We already rewound in onStart, so there is no reason to rewind. | 705 // We already rewound in onStart, so there is no reason to rewind. |
| 715 // Next time onGetScanlines is called, we will need to rewind. | 706 // Next time onGetScanlines is called, we will need to rewind. |
| 716 fCanSkipRewind = false; | 707 fCanSkipRewind = false; |
| 717 } else if (!fCodec->handleRewind()) { | 708 } else if (!fCodec->rewindIfNeeded()) { |
| 718 return SkCodec::kCouldNotRewind; | 709 return SkCodec::kCouldNotRewind; |
| 719 } | 710 } |
| 720 | 711 |
| 721 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 712 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
| 722 SkCodecPrintf("setjmp long jump!\n"); | 713 SkCodecPrintf("setjmp long jump!\n"); |
| 723 return SkCodec::kInvalidInput; | 714 return SkCodec::kInvalidInput; |
| 724 } | 715 } |
| 725 const int number_passes = png_set_interlace_handling(fCodec->fPng_ptr); | 716 const int number_passes = png_set_interlace_handling(fCodec->fPng_ptr); |
| 726 SkAutoMalloc storage(count * fSrcRowBytes); | 717 SkAutoMalloc storage(count * fSrcRowBytes); |
| 727 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); | 718 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 | 785 |
| 795 const SkImageInfo& srcInfo = codec->getInfo(); | 786 const SkImageInfo& srcInfo = codec->getInfo(); |
| 796 if (codec->fNumberPasses > 1) { | 787 if (codec->fNumberPasses > 1) { |
| 797 // interlaced image | 788 // interlaced image |
| 798 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach
())); | 789 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach
())); |
| 799 } | 790 } |
| 800 | 791 |
| 801 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); | 792 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); |
| 802 } | 793 } |
| 803 | 794 |
| OLD | NEW |