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 |