| 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 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 return kUnimplemented; | 443 return kUnimplemented; |
| 444 } | 444 } |
| 445 | 445 |
| 446 // FIXME: Here is where we should likely insert some of the modifications | 446 // FIXME: Here is where we should likely insert some of the modifications |
| 447 // made in the factory. | 447 // made in the factory. |
| 448 png_read_update_info(fPng_ptr, fInfo_ptr); | 448 png_read_update_info(fPng_ptr, fInfo_ptr); |
| 449 | 449 |
| 450 return kSuccess; | 450 return kSuccess; |
| 451 } | 451 } |
| 452 | 452 |
| 453 bool SkPngCodec::handleRewind() { |
| 454 switch (this->rewindIfNeeded()) { |
| 455 case kNoRewindNecessary_RewindState: |
| 456 return true; |
| 457 case kCouldNotRewind_RewindState: |
| 458 return false; |
| 459 case kRewound_RewindState: { |
| 460 // This sets fPng_ptr and fInfo_ptr to NULL. If read_header |
| 461 // succeeds, they will be repopulated, and if it fails, they will |
| 462 // remain NULL. Any future accesses to fPng_ptr and fInfo_ptr will |
| 463 // come through this function which will rewind and again attempt |
| 464 // to reinitialize them. |
| 465 this->destroyReadStruct(); |
| 466 png_structp png_ptr; |
| 467 png_infop info_ptr; |
| 468 if (read_header(this->stream(), &png_ptr, &info_ptr, NULL)) { |
| 469 fPng_ptr = png_ptr; |
| 470 fInfo_ptr = info_ptr; |
| 471 return true; |
| 472 } |
| 473 return false; |
| 474 } |
| 475 default: |
| 476 SkASSERT(false); |
| 477 return false; |
| 478 } |
| 479 } |
| 480 |
| 453 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
dst, | 481 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
dst, |
| 454 size_t rowBytes, const Options& options, | 482 size_t rowBytes, const Options& options, |
| 455 SkPMColor ctable[], int* ctableCount) { | 483 SkPMColor ctable[], int* ctableCount) { |
| 456 SkCodec::RewindState rewindState = this->rewindIfNeeded(); | 484 if (!this->handleRewind()) { |
| 457 if (rewindState == kCouldNotRewind_RewindState) { | |
| 458 return kCouldNotRewind; | 485 return kCouldNotRewind; |
| 459 } else if (rewindState == kRewound_RewindState) { | |
| 460 // This sets fPng_ptr and fInfo_ptr to NULL. If read_header succeeds, | |
| 461 // they will be repopulated, and if it fails, they will remain NULL. | |
| 462 // Any future accesses to fPng_ptr and fInfo_ptr will come through this | |
| 463 // function which will rewind and again attempt to reinitialize them. | |
| 464 this->destroyReadStruct(); | |
| 465 png_structp png_ptr; | |
| 466 png_infop info_ptr; | |
| 467 if (read_header(this->stream(), &png_ptr, &info_ptr, NULL)) { | |
| 468 fPng_ptr = png_ptr; | |
| 469 fInfo_ptr = info_ptr; | |
| 470 } else { | |
| 471 return kCouldNotRewind; | |
| 472 } | |
| 473 | |
| 474 } | 486 } |
| 475 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { | 487 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { |
| 476 return kInvalidScale; | 488 return kInvalidScale; |
| 477 } | 489 } |
| 478 if (!conversion_possible(requestedInfo, this->getInfo())) { | 490 if (!conversion_possible(requestedInfo, this->getInfo())) { |
| 479 return kInvalidConversion; | 491 return kInvalidConversion; |
| 480 } | 492 } |
| 481 | 493 |
| 482 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes, | 494 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes, |
| 483 options); | 495 options); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 private: | 603 private: |
| 592 SkPngCodec* fCodec; // Unowned. | 604 SkPngCodec* fCodec; // Unowned. |
| 593 bool fHasAlpha; | 605 bool fHasAlpha; |
| 594 SkAutoMalloc fStorage; | 606 SkAutoMalloc fStorage; |
| 595 uint8_t* fSrcRow; | 607 uint8_t* fSrcRow; |
| 596 | 608 |
| 597 typedef SkScanlineDecoder INHERITED; | 609 typedef SkScanlineDecoder INHERITED; |
| 598 }; | 610 }; |
| 599 | 611 |
| 600 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo)
{ | 612 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo)
{ |
| 613 if (!this->handleRewind()) { |
| 614 return NULL; |
| 615 } |
| 616 |
| 601 // Check to see if scaling was requested. | 617 // Check to see if scaling was requested. |
| 602 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 618 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 603 return NULL; | 619 return NULL; |
| 604 } | 620 } |
| 605 | 621 |
| 606 if (!conversion_possible(dstInfo, this->getInfo())) { | 622 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 607 SkCodecPrintf("no conversion possible\n"); | 623 SkCodecPrintf("no conversion possible\n"); |
| 608 return NULL; | 624 return NULL; |
| 609 } | 625 } |
| 610 | 626 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 621 | 637 |
| 622 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); | 638 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); |
| 623 if (fNumberPasses > 1) { | 639 if (fNumberPasses > 1) { |
| 624 // We cannot efficiently do scanline decoding. | 640 // We cannot efficiently do scanline decoding. |
| 625 return NULL; | 641 return NULL; |
| 626 } | 642 } |
| 627 | 643 |
| 628 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); | 644 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); |
| 629 } | 645 } |
| 630 | 646 |
| OLD | NEW |