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 "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 break; | 508 break; |
509 } | 509 } |
510 } | 510 } |
511 | 511 |
512 class SkPngNormalDecoder : public SkPngCodec { | 512 class SkPngNormalDecoder : public SkPngCodec { |
513 public: | 513 public: |
514 SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo, SkStream* stream, | 514 SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo, SkStream* stream, |
515 SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, i nt bitDepth) | 515 SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, i nt bitDepth) |
516 : INHERITED(info, imageInfo, stream, reader, png_ptr, info_ptr, bitDepth ) | 516 : INHERITED(info, imageInfo, stream, reader, png_ptr, info_ptr, bitDepth ) |
517 , fLinesDecoded(0) | 517 , fLinesDecoded(0) |
518 , fRowsWrittenToOutput(0) | |
518 , fDst(nullptr) | 519 , fDst(nullptr) |
519 , fRowBytes(0) | 520 , fRowBytes(0) |
520 , fFirstRow(0) | 521 , fFirstRow(0) |
521 , fLastRow(0) | 522 , fLastRow(0) |
522 {} | 523 {} |
523 | 524 |
524 static void AllRowsCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int /*pass*/) { | 525 static void AllRowsCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int /*pass*/) { |
525 GetDecoder(png_ptr)->allRowsCallback(row, rowNum); | 526 GetDecoder(png_ptr)->allRowsCallback(row, rowNum); |
526 } | 527 } |
527 | 528 |
528 static void RowCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowN um, int /*pass*/) { | 529 static void RowCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowN um, int /*pass*/) { |
529 GetDecoder(png_ptr)->rowCallback(row, rowNum); | 530 GetDecoder(png_ptr)->rowCallback(row, rowNum); |
530 } | 531 } |
531 | 532 |
532 #ifdef SK_GOOGLE3_PNG_HACK | 533 #ifdef SK_GOOGLE3_PNG_HACK |
533 static void RereadInfoCallback(png_structp png_ptr, png_infop) { | 534 static void RereadInfoCallback(png_structp png_ptr, png_infop) { |
534 GetDecoder(png_ptr)->rereadInfoCallback(); | 535 GetDecoder(png_ptr)->rereadInfoCallback(); |
535 } | 536 } |
536 #endif | 537 #endif |
537 | 538 |
538 private: | 539 private: |
539 int fLinesDecoded; // FIXME: Move to baseclass? | 540 // This represents the number of lines reported by libpng, minus any we skip ped at the |
541 // beginning. Only used when we are skipping lines (i.e. not in decodeAllRow s). | |
542 int fLinesDecoded; | |
543 // While fLinesDecoded include lines that we skipped, this only includes lin es written to the | |
544 // output so we can report it to the caller for filling. | |
545 // FIXME: Can we remove fLinesDecoded and just rely on fRowsWrittenToOutput? | |
msarett
2016/10/10 17:19:58
I think this would be good. IMO using this to cou
scroggo_chromium
2016/10/10 18:15:04
Agreed. I don't think it's terribly hard, but it's
| |
546 int fRowsWrittenToOutput; | |
540 void* fDst; | 547 void* fDst; |
541 size_t fRowBytes; | 548 size_t fRowBytes; |
542 | 549 |
543 // Variables for partial decode | 550 // Variables for partial decode |
544 int fFirstRow; // FIXME: Move to baseclass? | 551 int fFirstRow; // FIXME: Move to baseclass? |
545 int fLastRow; | 552 int fLastRow; |
546 | 553 |
547 typedef SkPngCodec INHERITED; | 554 typedef SkPngCodec INHERITED; |
548 | 555 |
549 static SkPngNormalDecoder* GetDecoder(png_structp png_ptr) { | 556 static SkPngNormalDecoder* GetDecoder(png_structp png_ptr) { |
550 return static_cast<SkPngNormalDecoder*>(png_get_progressive_ptr(png_ptr) ); | 557 return static_cast<SkPngNormalDecoder*>(png_get_progressive_ptr(png_ptr) ); |
551 } | 558 } |
552 | 559 |
553 Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override { | 560 Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override { |
554 const int height = this->getInfo().height(); | 561 const int height = this->getInfo().height(); |
555 png_progressive_info_ptr callback = nullptr; | 562 png_progressive_info_ptr callback = nullptr; |
556 #ifdef SK_GOOGLE3_PNG_HACK | 563 #ifdef SK_GOOGLE3_PNG_HACK |
557 callback = RereadInfoCallback; | 564 callback = RereadInfoCallback; |
558 #endif | 565 #endif |
559 png_set_progressive_read_fn(this->png_ptr(), this, callback, AllRowsCall back, nullptr); | 566 png_set_progressive_read_fn(this->png_ptr(), this, callback, AllRowsCall back, nullptr); |
560 fDst = dst; | 567 fDst = dst; |
561 fRowBytes = rowBytes; | 568 fRowBytes = rowBytes; |
562 | 569 |
563 fLinesDecoded = 0; | 570 fRowsWrittenToOutput = 0; |
564 | 571 |
565 this->processData(); | 572 this->processData(); |
566 | 573 |
567 if (fLinesDecoded == height) { | 574 if (fRowsWrittenToOutput == height) { |
568 return SkCodec::kSuccess; | 575 return SkCodec::kSuccess; |
569 } | 576 } |
570 | 577 |
571 if (rowsDecoded) { | 578 if (rowsDecoded) { |
572 *rowsDecoded = fLinesDecoded; | 579 *rowsDecoded = fRowsWrittenToOutput; |
573 } | 580 } |
574 | 581 |
575 return SkCodec::kIncompleteInput; | 582 return SkCodec::kIncompleteInput; |
576 } | 583 } |
577 | 584 |
578 void allRowsCallback(png_bytep row, int rowNum) { | 585 void allRowsCallback(png_bytep row, int rowNum) { |
579 SkASSERT(rowNum == fLinesDecoded); | 586 SkASSERT(rowNum == fLinesDecoded); |
580 fLinesDecoded++; | 587 fLinesDecoded++; |
581 this->applyXformRow(fDst, row); | 588 this->applyXformRow(fDst, row); |
582 fDst = SkTAddOffset<void>(fDst, fRowBytes); | 589 fDst = SkTAddOffset<void>(fDst, fRowBytes); |
583 } | 590 } |
584 | 591 |
585 void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) overrid e { | 592 void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) overrid e { |
586 png_progressive_info_ptr callback = nullptr; | 593 png_progressive_info_ptr callback = nullptr; |
587 #ifdef SK_GOOGLE3_PNG_HACK | 594 #ifdef SK_GOOGLE3_PNG_HACK |
588 callback = RereadInfoCallback; | 595 callback = RereadInfoCallback; |
589 #endif | 596 #endif |
590 png_set_progressive_read_fn(this->png_ptr(), this, callback, RowCallback , nullptr); | 597 png_set_progressive_read_fn(this->png_ptr(), this, callback, RowCallback , nullptr); |
591 fFirstRow = firstRow; | 598 fFirstRow = firstRow; |
592 fLastRow = lastRow; | 599 fLastRow = lastRow; |
593 fDst = dst; | 600 fDst = dst; |
594 fRowBytes = rowBytes; | 601 fRowBytes = rowBytes; |
595 fLinesDecoded = 0; | 602 fLinesDecoded = 0; |
603 fRowsWrittenToOutput = 0; | |
596 } | 604 } |
597 | 605 |
598 SkCodec::Result decode(int* rowsDecoded) override { | 606 SkCodec::Result decode(int* rowsDecoded) override { |
599 this->processData(); | 607 this->processData(); |
600 | 608 |
601 if (fLinesDecoded == fLastRow - fFirstRow + 1) { | 609 if (fLinesDecoded == fLastRow - fFirstRow + 1) { |
602 return SkCodec::kSuccess; | 610 return SkCodec::kSuccess; |
603 } | 611 } |
604 | 612 |
605 if (rowsDecoded) { | 613 if (rowsDecoded) { |
606 *rowsDecoded = fLinesDecoded; | 614 *rowsDecoded = fRowsWrittenToOutput; |
607 } | 615 } |
608 | 616 |
609 return SkCodec::kIncompleteInput; | 617 return SkCodec::kIncompleteInput; |
610 } | 618 } |
611 | 619 |
612 void rowCallback(png_bytep row, int rowNum) { | 620 void rowCallback(png_bytep row, int rowNum) { |
613 if (rowNum < fFirstRow) { | 621 if (rowNum < fFirstRow) { |
614 // Ignore this row. | 622 // Ignore this row. |
615 return; | 623 return; |
616 } | 624 } |
617 | 625 |
618 SkASSERT(rowNum <= fLastRow); | 626 SkASSERT(rowNum <= fLastRow); |
619 | 627 |
620 // If there is no swizzler, all rows are needed. | 628 // If there is no swizzler, all rows are needed. |
621 if (!this->swizzler() || this->swizzler()->rowNeeded(fLinesDecoded)) { | 629 if (!this->swizzler() || this->swizzler()->rowNeeded(fLinesDecoded)) { |
622 this->applyXformRow(fDst, row); | 630 this->applyXformRow(fDst, row); |
623 fDst = SkTAddOffset<void>(fDst, fRowBytes); | 631 fDst = SkTAddOffset<void>(fDst, fRowBytes); |
632 fRowsWrittenToOutput++; | |
624 } | 633 } |
625 | 634 |
626 fLinesDecoded++; | 635 fLinesDecoded++; |
627 | 636 |
628 if (rowNum == fLastRow) { | 637 if (rowNum == fLastRow) { |
629 // Fake error to stop decoding scanlines. | 638 // Fake error to stop decoding scanlines. |
630 longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding); | 639 longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding); |
631 } | 640 } |
632 } | 641 } |
633 }; | 642 }; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
763 // Now apply Xforms on all the rows that were decoded. | 772 // Now apply Xforms on all the rows that were decoded. |
764 if (!fLinesDecoded) { | 773 if (!fLinesDecoded) { |
765 if (rowsDecoded) { | 774 if (rowsDecoded) { |
766 *rowsDecoded = 0; | 775 *rowsDecoded = 0; |
767 } | 776 } |
768 return SkCodec::kIncompleteInput; | 777 return SkCodec::kIncompleteInput; |
769 } | 778 } |
770 const int lastRow = fLinesDecoded + fFirstRow - 1; | 779 const int lastRow = fLinesDecoded + fFirstRow - 1; |
771 SkASSERT(lastRow <= fLastRow); | 780 SkASSERT(lastRow <= fLastRow); |
772 | 781 |
782 int rowsWrittenToOutput = 0; | |
783 | |
773 // FIXME: For resuming interlace, we may swizzle a row that hasn't chang ed. But it | 784 // FIXME: For resuming interlace, we may swizzle a row that hasn't chang ed. But it |
774 // may be too tricky/expensive to handle that correctly. | 785 // may be too tricky/expensive to handle that correctly. |
775 png_bytep srcRow = fInterlaceBuffer.get(); | 786 png_bytep srcRow = fInterlaceBuffer.get(); |
776 const int sampleY = this->swizzler() ? this->swizzler()->sampleY() : 1; | 787 const int sampleY = this->swizzler() ? this->swizzler()->sampleY() : 1; |
777 void* dst = fDst; | 788 void* dst = fDst; |
778 for (int rowNum = fFirstRow; rowNum <= lastRow; rowNum += sampleY) { | 789 for (int rowNum = fFirstRow; rowNum <= lastRow; rowNum += sampleY) { |
779 this->applyXformRow(dst, srcRow); | 790 this->applyXformRow(dst, srcRow); |
780 dst = SkTAddOffset<void>(dst, fRowBytes); | 791 dst = SkTAddOffset<void>(dst, fRowBytes); |
781 srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes * sampleY); | 792 srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes * sampleY); |
793 rowsWrittenToOutput++; | |
782 } | 794 } |
783 | 795 |
784 if (fInterlacedComplete) { | 796 if (fInterlacedComplete) { |
785 return SkCodec::kSuccess; | 797 return SkCodec::kSuccess; |
786 } | 798 } |
787 | 799 |
788 if (rowsDecoded) { | 800 if (rowsDecoded) { |
789 *rowsDecoded = fLinesDecoded; | 801 *rowsDecoded = rowsWrittenToOutput; |
790 } | 802 } |
791 return SkCodec::kIncompleteInput; | 803 return SkCodec::kIncompleteInput; |
792 } | 804 } |
793 | 805 |
794 void setUpInterlaceBuffer(int height) { | 806 void setUpInterlaceBuffer(int height) { |
795 fPng_rowbytes = png_get_rowbytes(this->png_ptr(), this->info_ptr()); | 807 fPng_rowbytes = png_get_rowbytes(this->png_ptr(), this->info_ptr()); |
796 fInterlaceBuffer.reset(fPng_rowbytes * height); | 808 fInterlaceBuffer.reset(fPng_rowbytes * height); |
797 fInterlacedComplete = false; | 809 fInterlacedComplete = false; |
798 } | 810 } |
799 }; | 811 }; |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1302 SkCodec* outCodec = nullptr; | 1314 SkCodec* outCodec = nullptr; |
1303 if (read_header(streamDeleter.get(), chunkReader, &outCodec, nullptr, nullpt r)) { | 1315 if (read_header(streamDeleter.get(), chunkReader, &outCodec, nullptr, nullpt r)) { |
1304 // Codec has taken ownership of the stream. | 1316 // Codec has taken ownership of the stream. |
1305 SkASSERT(outCodec); | 1317 SkASSERT(outCodec); |
1306 streamDeleter.release(); | 1318 streamDeleter.release(); |
1307 return outCodec; | 1319 return outCodec; |
1308 } | 1320 } |
1309 | 1321 |
1310 return nullptr; | 1322 return nullptr; |
1311 } | 1323 } |
OLD | NEW |