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

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

Issue 1256373002: Pass the destination pointer to next (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Thanks windows bot! Created 5 years, 4 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 | « src/codec/SkCodec_libpng.h ('k') | src/codec/SkMaskSwizzler.h » ('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 "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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 // Check for supported color types 418 // Check for supported color types
419 switch (dst.colorType()) { 419 switch (dst.colorType()) {
420 case kN32_SkColorType: 420 case kN32_SkColorType:
421 return true; 421 return true;
422 default: 422 default:
423 return dst.colorType() == src.colorType(); 423 return dst.colorType() == src.colorType();
424 } 424 }
425 } 425 }
426 426
427 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, 427 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo,
428 void* dst, size_t rowBytes,
429 const Options& options, 428 const Options& options,
430 SkPMColor ctable[], 429 SkPMColor ctable[],
431 int* ctableCount) { 430 int* ctableCount) {
432 // FIXME: Could we use the return value of setjmp to specify the type of 431 // FIXME: Could we use the return value of setjmp to specify the type of
433 // error? 432 // error?
434 if (setjmp(png_jmpbuf(fPng_ptr))) { 433 if (setjmp(png_jmpbuf(fPng_ptr))) {
435 SkCodecPrintf("setjmp long jump!\n"); 434 SkCodecPrintf("setjmp long jump!\n");
436 return kInvalidInput; 435 return kInvalidInput;
437 } 436 }
438 fNumberPasses = png_set_interlace_handling(fPng_ptr); 437 fNumberPasses = png_set_interlace_handling(fPng_ptr);
(...skipping 28 matching lines...) Expand all
467 //would have exited before now if the colorType was supported by png 466 //would have exited before now if the colorType was supported by png
468 SkASSERT(false); 467 SkASSERT(false);
469 } 468 }
470 469
471 // Copy the color table to the client if they request kIndex8 mode 470 // Copy the color table to the client if they request kIndex8 mode
472 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); 471 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount);
473 472
474 // Create the swizzler. SkPngCodec retains ownership of the color table. 473 // Create the swizzler. SkPngCodec retains ownership of the color table.
475 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL; 474 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL;
476 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo , 475 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo ,
477 dst, rowBytes, options.fZeroInitialized)); 476 options.fZeroInitialized));
478 if (!fSwizzler) { 477 if (!fSwizzler) {
479 // FIXME: CreateSwizzler could fail for another reason. 478 // FIXME: CreateSwizzler could fail for another reason.
480 return kUnimplemented; 479 return kUnimplemented;
481 } 480 }
482 return kSuccess; 481 return kSuccess;
483 } 482 }
484 483
485 484
486 bool SkPngCodec::handleRewind() { 485 bool SkPngCodec::handleRewind() {
487 switch (this->rewindIfNeeded()) { 486 switch (this->rewindIfNeeded()) {
(...skipping 17 matching lines...) Expand all
505 } 504 }
506 return false; 505 return false;
507 } 506 }
508 default: 507 default:
509 SkASSERT(false); 508 SkASSERT(false);
510 return false; 509 return false;
511 } 510 }
512 } 511 }
513 512
514 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst, 513 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst,
515 size_t rowBytes, const Options& options, 514 size_t dstRowBytes, const Options& optio ns,
516 SkPMColor ctable[], int* ctableCount) { 515 SkPMColor ctable[], int* ctableCount) {
517 if (!conversion_possible(requestedInfo, this->getInfo())) { 516 if (!conversion_possible(requestedInfo, this->getInfo())) {
518 return kInvalidConversion; 517 return kInvalidConversion;
519 } 518 }
520 if (options.fSubset) { 519 if (options.fSubset) {
521 // Subsets are not supported. 520 // Subsets are not supported.
522 return kUnimplemented; 521 return kUnimplemented;
523 } 522 }
524 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { 523 if (requestedInfo.dimensions() != this->getInfo().dimensions()) {
525 return kInvalidScale; 524 return kInvalidScale;
526 } 525 }
527 if (!this->handleRewind()) { 526 if (!this->handleRewind()) {
528 return kCouldNotRewind; 527 return kCouldNotRewind;
529 } 528 }
530 529
531 // Note that ctable and ctableCount may be modified if there is a color tabl e 530 // Note that ctable and ctableCount may be modified if there is a color tabl e
532 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes, 531 const Result result = this->initializeSwizzler(requestedInfo, options,
533 options, ctable, ctableCount) ; 532 ctable, ctableCount);
534 if (result != kSuccess) { 533 if (result != kSuccess) {
535 return result; 534 return result;
536 } 535 }
537 // FIXME: Could we use the return value of setjmp to specify the type of 536 // FIXME: Could we use the return value of setjmp to specify the type of
538 // error? 537 // error?
539 if (setjmp(png_jmpbuf(fPng_ptr))) { 538 if (setjmp(png_jmpbuf(fPng_ptr))) {
540 SkCodecPrintf("setjmp long jump!\n"); 539 SkCodecPrintf("setjmp long jump!\n");
541 return kInvalidInput; 540 return kInvalidInput;
542 } 541 }
543 542
544 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); 543 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES);
545 SkAutoMalloc storage; 544 SkAutoMalloc storage;
545 void* dstRow = dst;
546 if (fNumberPasses > 1) { 546 if (fNumberPasses > 1) {
547 const int width = requestedInfo.width(); 547 const int width = requestedInfo.width();
548 const int height = requestedInfo.height(); 548 const int height = requestedInfo.height();
549 const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig); 549 const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig);
550 const size_t rowBytes = width * bpp; 550 const size_t srcRowBytes = width * bpp;
551 551
552 storage.reset(width * height * bpp); 552 storage.reset(width * height * bpp);
553 uint8_t* const base = static_cast<uint8_t*>(storage.get()); 553 uint8_t* const base = static_cast<uint8_t*>(storage.get());
554 554
555 for (int i = 0; i < fNumberPasses; i++) { 555 for (int i = 0; i < fNumberPasses; i++) {
556 uint8_t* row = base; 556 uint8_t* srcRow = base;
557 for (int y = 0; y < height; y++) { 557 for (int y = 0; y < height; y++) {
558 uint8_t* bmRow = row; 558 uint8_t* bmRow = srcRow;
559 png_read_rows(fPng_ptr, &bmRow, png_bytepp_NULL, 1); 559 png_read_rows(fPng_ptr, &bmRow, png_bytepp_NULL, 1);
560 row += rowBytes; 560 srcRow += srcRowBytes;
561 } 561 }
562 } 562 }
563 563
564 // Now swizzle it. 564 // Now swizzle it.
565 uint8_t* row = base; 565 uint8_t* srcRow = base;
566 for (int y = 0; y < height; y++) { 566 for (int y = 0; y < height; y++) {
567 fReallyHasAlpha |= !SkSwizzler::IsOpaque(fSwizzler->next(row)); 567 fReallyHasAlpha |= !SkSwizzler::IsOpaque(fSwizzler->swizzle(dstRow, srcRow));
568 row += rowBytes; 568 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
569 srcRow += srcRowBytes;
569 } 570 }
570 } else { 571 } else {
571 storage.reset(requestedInfo.width() * SkSwizzler::BytesPerPixel(fSrcConf ig)); 572 storage.reset(requestedInfo.width() * SkSwizzler::BytesPerPixel(fSrcConf ig));
572 uint8_t* srcRow = static_cast<uint8_t*>(storage.get()); 573 uint8_t* srcRow = static_cast<uint8_t*>(storage.get());
573 for (int y = 0; y < requestedInfo.height(); y++) { 574 for (int y = 0; y < requestedInfo.height(); y++) {
574 png_read_rows(fPng_ptr, &srcRow, png_bytepp_NULL, 1); 575 png_read_rows(fPng_ptr, &srcRow, png_bytepp_NULL, 1);
575 fReallyHasAlpha |= !SkSwizzler::IsOpaque(fSwizzler->next(srcRow)); 576 fReallyHasAlpha |= !SkSwizzler::IsOpaque(fSwizzler->swizzle(dstRow, srcRow));
577 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
576 } 578 }
577 } 579 }
578 580
579 // FIXME: do we need substituteTranspColor? Note that we cannot do it for 581 // FIXME: do we need substituteTranspColor? Note that we cannot do it for
580 // scanline decoding, but we could do it here. Alternatively, we could do 582 // scanline decoding, but we could do it here. Alternatively, we could do
581 // it as we go, instead of in post-processing like SkPNGImageDecoder. 583 // it as we go, instead of in post-processing like SkPNGImageDecoder.
582 584
583 if (setjmp(png_jmpbuf(fPng_ptr))) { 585 if (setjmp(png_jmpbuf(fPng_ptr))) {
584 // We've already read all the scanlines. This is a success. 586 // We've already read all the scanlines. This is a success.
585 return kSuccess; 587 return kSuccess;
(...skipping 14 matching lines...) Expand all
600 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig)); 602 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig));
601 fSrcRow = static_cast<uint8_t*>(fStorage.get()); 603 fSrcRow = static_cast<uint8_t*>(fStorage.get());
602 } 604 }
603 605
604 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { 606 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de {
605 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { 607 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) {
606 SkCodecPrintf("setjmp long jump!\n"); 608 SkCodecPrintf("setjmp long jump!\n");
607 return SkCodec::kInvalidInput; 609 return SkCodec::kInvalidInput;
608 } 610 }
609 611
612 void* dstRow = dst;
610 for (int i = 0; i < count; i++) { 613 for (int i = 0; i < count; i++) {
611 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); 614 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1);
612 fCodec->fSwizzler->setDstRow(dst); 615 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->swizzle(dstRow , fSrcRow));
613 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(fSrcRow)) ; 616 dstRow = SkTAddOffset<void>(dstRow, rowBytes);
614 dst = SkTAddOffset<void>(dst, rowBytes);
615 } 617 }
616 return SkCodec::kSuccess; 618 return SkCodec::kSuccess;
617 } 619 }
618 620
619 SkCodec::Result onSkipScanlines(int count) override { 621 SkCodec::Result onSkipScanlines(int count) override {
620 // FIXME: Could we use the return value of setjmp to specify the type of 622 // FIXME: Could we use the return value of setjmp to specify the type of
621 // error? 623 // error?
622 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { 624 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) {
623 SkCodecPrintf("setjmp long jump!\n"); 625 SkCodecPrintf("setjmp long jump!\n");
624 return SkCodec::kInvalidInput; 626 return SkCodec::kInvalidInput;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 png_read_rows(fCodec->fPng_ptr, &srcRow, png_bytepp_NULL, 1); 685 png_read_rows(fCodec->fPng_ptr, &srcRow, png_bytepp_NULL, 1);
684 srcRow += fSrcRowBytes; 686 srcRow += fSrcRowBytes;
685 } 687 }
686 //read rows we don't want into garbage buffer 688 //read rows we don't want into garbage buffer
687 for (int y = 0; y < fHeight - fCurrentRow - count; y++) { 689 for (int y = 0; y < fHeight - fCurrentRow - count; y++) {
688 png_read_rows(fCodec->fPng_ptr, &fGarbageRowPtr, png_bytepp_NULL , 1); 690 png_read_rows(fCodec->fPng_ptr, &fGarbageRowPtr, png_bytepp_NULL , 1);
689 } 691 }
690 } 692 }
691 //swizzle the rows we care about 693 //swizzle the rows we care about
692 srcRow = storagePtr; 694 srcRow = storagePtr;
695 void* dstRow = dst;
693 for (int y = 0; y < count; y++) { 696 for (int y = 0; y < count; y++) {
694 fCodec->fSwizzler->setDstRow(dst); 697 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->swizzle(dstRow , srcRow));
695 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(srcRow)); 698 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
696 dst = SkTAddOffset<void>(dst, dstRowBytes);
697 srcRow += fSrcRowBytes; 699 srcRow += fSrcRowBytes;
698 } 700 }
699 fCurrentRow += count; 701 fCurrentRow += count;
700 return SkCodec::kSuccess; 702 return SkCodec::kSuccess;
701 } 703 }
702 704
703 SkCodec::Result onSkipScanlines(int count) override { 705 SkCodec::Result onSkipScanlines(int count) override {
704 //when ongetScanlines is called it will skip to fCurrentRow 706 //when ongetScanlines is called it will skip to fCurrentRow
705 fCurrentRow += count; 707 fCurrentRow += count;
706 return SkCodec::kSuccess; 708 return SkCodec::kSuccess;
(...skipping 27 matching lines...) Expand all
734 // Create a new SkPngCodec, to be owned by the scanline decoder. 736 // Create a new SkPngCodec, to be owned by the scanline decoder.
735 SkStream* stream = this->stream()->duplicate(); 737 SkStream* stream = this->stream()->duplicate();
736 if (!stream) { 738 if (!stream) {
737 return NULL; 739 return NULL;
738 } 740 }
739 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); 741 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream)));
740 if (!codec) { 742 if (!codec) {
741 return NULL; 743 return NULL;
742 } 744 }
743 745
744 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded, 746 if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuc cess) {
745 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to
746 // be at least dstInfo.minRowBytes.
747 if (codec->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable,
748 ctableCount) != kSuccess) {
749 SkCodecPrintf("failed to initialize the swizzler.\n"); 747 SkCodecPrintf("failed to initialize the swizzler.\n");
750 return NULL; 748 return NULL;
751 } 749 }
752 750
753 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); 751 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES);
754 if (codec->fNumberPasses > 1) { 752 if (codec->fNumberPasses > 1) {
755 // interlaced image 753 // interlaced image
756 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ())); 754 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ()));
757 } 755 }
758 756
759 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); 757 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach()));
760 } 758 }
761 759
OLDNEW
« no previous file with comments | « src/codec/SkCodec_libpng.h ('k') | src/codec/SkMaskSwizzler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698