Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Side by Side Diff: src/codec/SkPngCodec.cpp

Issue 2420843003: Incremental decode: only use subset for subsetting (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/codec/SkSampledCodec.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 fXformWidth, fXformAlphaType)); 451 fXformWidth, fXformAlphaType));
452 break; 452 break;
453 } 453 }
454 } 454 }
455 455
456 class SkPngNormalDecoder : public SkPngCodec { 456 class SkPngNormalDecoder : public SkPngCodec {
457 public: 457 public:
458 SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo, SkStream* stream, 458 SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo, SkStream* stream,
459 SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, i nt bitDepth) 459 SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, i nt bitDepth)
460 : INHERITED(info, imageInfo, stream, reader, png_ptr, info_ptr, bitDepth ) 460 : INHERITED(info, imageInfo, stream, reader, png_ptr, info_ptr, bitDepth )
461 , fLinesDecoded(0)
462 , fRowsWrittenToOutput(0) 461 , fRowsWrittenToOutput(0)
463 , fDst(nullptr) 462 , fDst(nullptr)
464 , fRowBytes(0) 463 , fRowBytes(0)
465 , fFirstRow(0) 464 , fFirstRow(0)
466 , fLastRow(0) 465 , fLastRow(0)
467 {} 466 {}
468 467
469 static void AllRowsCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int /*pass*/) { 468 static void AllRowsCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int /*pass*/) {
470 GetDecoder(png_ptr)->allRowsCallback(row, rowNum); 469 GetDecoder(png_ptr)->allRowsCallback(row, rowNum);
471 } 470 }
472 471
473 static void RowCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowN um, int /*pass*/) { 472 static void RowCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowN um, int /*pass*/) {
474 GetDecoder(png_ptr)->rowCallback(row, rowNum); 473 GetDecoder(png_ptr)->rowCallback(row, rowNum);
475 } 474 }
476 475
477 #ifdef SK_GOOGLE3_PNG_HACK 476 #ifdef SK_GOOGLE3_PNG_HACK
478 static void RereadInfoCallback(png_structp png_ptr, png_infop) { 477 static void RereadInfoCallback(png_structp png_ptr, png_infop) {
479 GetDecoder(png_ptr)->rereadInfoCallback(); 478 GetDecoder(png_ptr)->rereadInfoCallback();
480 } 479 }
481 #endif 480 #endif
482 481
483 private: 482 private:
484 // This represents the number of lines reported by libpng, minus any we skip ped at the
485 // beginning. Only used when we are skipping lines (i.e. not in decodeAllRow s).
486 int fLinesDecoded;
487 // While fLinesDecoded include lines that we skipped, this only includes lin es written to the
488 // output so we can report it to the caller for filling.
489 // FIXME: Can we remove fLinesDecoded and just rely on fRowsWrittenToOutput?
490 int fRowsWrittenToOutput; 483 int fRowsWrittenToOutput;
491 void* fDst; 484 void* fDst;
492 size_t fRowBytes; 485 size_t fRowBytes;
493 486
494 // Variables for partial decode 487 // Variables for partial decode
495 int fFirstRow; // FIXME: Move to baseclass? 488 int fFirstRow; // FIXME: Move to baseclass?
496 int fLastRow; 489 int fLastRow;
490 int fRowsNeeded;
497 491
498 typedef SkPngCodec INHERITED; 492 typedef SkPngCodec INHERITED;
499 493
500 static SkPngNormalDecoder* GetDecoder(png_structp png_ptr) { 494 static SkPngNormalDecoder* GetDecoder(png_structp png_ptr) {
501 return static_cast<SkPngNormalDecoder*>(png_get_progressive_ptr(png_ptr) ); 495 return static_cast<SkPngNormalDecoder*>(png_get_progressive_ptr(png_ptr) );
502 } 496 }
503 497
504 Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override { 498 Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override {
505 const int height = this->getInfo().height(); 499 const int height = this->getInfo().height();
506 png_progressive_info_ptr callback = nullptr; 500 png_progressive_info_ptr callback = nullptr;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) overrid e { 532 void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) overrid e {
539 png_progressive_info_ptr callback = nullptr; 533 png_progressive_info_ptr callback = nullptr;
540 #ifdef SK_GOOGLE3_PNG_HACK 534 #ifdef SK_GOOGLE3_PNG_HACK
541 callback = RereadInfoCallback; 535 callback = RereadInfoCallback;
542 #endif 536 #endif
543 png_set_progressive_read_fn(this->png_ptr(), this, callback, RowCallback , nullptr); 537 png_set_progressive_read_fn(this->png_ptr(), this, callback, RowCallback , nullptr);
544 fFirstRow = firstRow; 538 fFirstRow = firstRow;
545 fLastRow = lastRow; 539 fLastRow = lastRow;
546 fDst = dst; 540 fDst = dst;
547 fRowBytes = rowBytes; 541 fRowBytes = rowBytes;
548 fLinesDecoded = 0;
549 fRowsWrittenToOutput = 0; 542 fRowsWrittenToOutput = 0;
543 fRowsNeeded = fLastRow - fFirstRow + 1;
550 } 544 }
551 545
552 SkCodec::Result decode(int* rowsDecoded) override { 546 SkCodec::Result decode(int* rowsDecoded) override {
547 if (this->swizzler()) {
548 const int sampleY = this->swizzler()->sampleY();
549 fRowsNeeded = get_scaled_dimension(fLastRow - fFirstRow + 1, sampleY );
550 }
553 this->processData(); 551 this->processData();
554 552
555 if (fLinesDecoded == fLastRow - fFirstRow + 1) { 553 if (fRowsWrittenToOutput == fRowsNeeded) {
556 return SkCodec::kSuccess; 554 return SkCodec::kSuccess;
557 } 555 }
558 556
559 if (rowsDecoded) { 557 if (rowsDecoded) {
560 *rowsDecoded = fRowsWrittenToOutput; 558 *rowsDecoded = fRowsWrittenToOutput;
561 } 559 }
562 560
563 return SkCodec::kIncompleteInput; 561 return SkCodec::kIncompleteInput;
564 } 562 }
565 563
566 void rowCallback(png_bytep row, int rowNum) { 564 void rowCallback(png_bytep row, int rowNum) {
567 if (rowNum < fFirstRow) { 565 if (rowNum < fFirstRow) {
568 // Ignore this row. 566 // Ignore this row.
569 return; 567 return;
570 } 568 }
571 569
572 SkASSERT(rowNum <= fLastRow); 570 SkASSERT(rowNum <= fLastRow);
571 SkASSERT(fRowsWrittenToOutput < fRowsNeeded);
573 572
574 // If there is no swizzler, all rows are needed. 573 // If there is no swizzler, all rows are needed.
575 if (!this->swizzler() || this->swizzler()->rowNeeded(fLinesDecoded)) { 574 if (!this->swizzler() || this->swizzler()->rowNeeded(rowNum - fFirstRow) ) {
576 this->applyXformRow(fDst, row); 575 this->applyXformRow(fDst, row);
577 fDst = SkTAddOffset<void>(fDst, fRowBytes); 576 fDst = SkTAddOffset<void>(fDst, fRowBytes);
578 fRowsWrittenToOutput++; 577 fRowsWrittenToOutput++;
579 } 578 }
580 579
581 fLinesDecoded++; 580 if (fRowsWrittenToOutput == fRowsNeeded) {
582
583 if (rowNum == fLastRow) {
584 // Fake error to stop decoding scanlines. 581 // Fake error to stop decoding scanlines.
585 longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding); 582 longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding);
586 } 583 }
587 } 584 }
588 }; 585 };
589 586
590 class SkPngInterlacedDecoder : public SkPngCodec { 587 class SkPngInterlacedDecoder : public SkPngCodec {
591 public: 588 public:
592 SkPngInterlacedDecoder(const SkEncodedInfo& info, const SkImageInfo& imageIn fo, 589 SkPngInterlacedDecoder(const SkEncodedInfo& info, const SkImageInfo& imageIn fo,
593 SkStream* stream, SkPngChunkReader* reader, png_structp png_ptr, png _infop info_ptr, 590 SkStream* stream, SkPngChunkReader* reader, png_structp png_ptr, png _infop info_ptr,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 SkCodec::Result decode(int* rowsDecoded) override { 712 SkCodec::Result decode(int* rowsDecoded) override {
716 this->processData(); 713 this->processData();
717 714
718 // Now apply Xforms on all the rows that were decoded. 715 // Now apply Xforms on all the rows that were decoded.
719 if (!fLinesDecoded) { 716 if (!fLinesDecoded) {
720 if (rowsDecoded) { 717 if (rowsDecoded) {
721 *rowsDecoded = 0; 718 *rowsDecoded = 0;
722 } 719 }
723 return SkCodec::kIncompleteInput; 720 return SkCodec::kIncompleteInput;
724 } 721 }
725 const int lastRow = fLinesDecoded + fFirstRow - 1;
726 SkASSERT(lastRow <= fLastRow);
727 722
723 const int sampleY = this->swizzler() ? this->swizzler()->sampleY() : 1;
724 const int rowsNeeded = get_scaled_dimension(fLastRow - fFirstRow + 1, sa mpleY);
728 int rowsWrittenToOutput = 0; 725 int rowsWrittenToOutput = 0;
729 726
730 // FIXME: For resuming interlace, we may swizzle a row that hasn't chang ed. But it 727 // FIXME: For resuming interlace, we may swizzle a row that hasn't chang ed. But it
731 // may be too tricky/expensive to handle that correctly. 728 // may be too tricky/expensive to handle that correctly.
732 png_bytep srcRow = fInterlaceBuffer.get(); 729 png_bytep srcRow = fInterlaceBuffer.get();
733 const int sampleY = this->swizzler() ? this->swizzler()->sampleY() : 1;
734 void* dst = fDst; 730 void* dst = fDst;
735 for (int rowNum = fFirstRow; rowNum <= lastRow; rowNum += sampleY) { 731 for (int rowNum = fFirstRow + get_start_coord(sampleY); rowsWrittenToOut put < rowsNeeded;
732 rowNum += sampleY) {
736 this->applyXformRow(dst, srcRow); 733 this->applyXformRow(dst, srcRow);
737 dst = SkTAddOffset<void>(dst, fRowBytes); 734 dst = SkTAddOffset<void>(dst, fRowBytes);
738 srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes * sampleY); 735 srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes * sampleY);
739 rowsWrittenToOutput++; 736 rowsWrittenToOutput++;
740 } 737 }
741 738
742 if (fInterlacedComplete) { 739 if (fInterlacedComplete) {
743 return SkCodec::kSuccess; 740 return SkCodec::kSuccess;
744 } 741 }
745 742
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 SkCodec* outCodec = nullptr; 1256 SkCodec* outCodec = nullptr;
1260 if (read_header(streamDeleter.get(), chunkReader, &outCodec, nullptr, nullpt r)) { 1257 if (read_header(streamDeleter.get(), chunkReader, &outCodec, nullptr, nullpt r)) {
1261 // Codec has taken ownership of the stream. 1258 // Codec has taken ownership of the stream.
1262 SkASSERT(outCodec); 1259 SkASSERT(outCodec);
1263 streamDeleter.release(); 1260 streamDeleter.release();
1264 return outCodec; 1261 return outCodec;
1265 } 1262 }
1266 1263
1267 return nullptr; 1264 return nullptr;
1268 } 1265 }
OLDNEW
« no previous file with comments | « no previous file | src/codec/SkSampledCodec.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698