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 |