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

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

Issue 1911613002: Use SkEncodedInfo in place of SkSwizzler::SrcConfig (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix bmp bug Created 4 years, 8 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/SkPngCodec.h ('k') | src/codec/SkRawCodec.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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 return true; 432 return true;
433 } 433 }
434 434
435 SkPngCodec::SkPngCodec(int width, int height, const SkEncodedInfo& info, SkStrea m* stream, 435 SkPngCodec::SkPngCodec(int width, int height, const SkEncodedInfo& info, SkStrea m* stream,
436 SkPngChunkReader* chunkReader, png_structp png_ptr, png_i nfop info_ptr, 436 SkPngChunkReader* chunkReader, png_structp png_ptr, png_i nfop info_ptr,
437 int bitDepth, int numberPasses, sk_sp<SkColorSpace> color Space) 437 int bitDepth, int numberPasses, sk_sp<SkColorSpace> color Space)
438 : INHERITED(width, height, info, stream, colorSpace) 438 : INHERITED(width, height, info, stream, colorSpace)
439 , fPngChunkReader(SkSafeRef(chunkReader)) 439 , fPngChunkReader(SkSafeRef(chunkReader))
440 , fPng_ptr(png_ptr) 440 , fPng_ptr(png_ptr)
441 , fInfo_ptr(info_ptr) 441 , fInfo_ptr(info_ptr)
442 , fSrcConfig(SkSwizzler::kUnknown)
443 , fNumberPasses(numberPasses) 442 , fNumberPasses(numberPasses)
444 , fBitDepth(bitDepth) 443 , fBitDepth(bitDepth)
445 {} 444 {}
446 445
447 SkPngCodec::~SkPngCodec() { 446 SkPngCodec::~SkPngCodec() {
448 this->destroyReadStruct(); 447 this->destroyReadStruct();
449 } 448 }
450 449
451 void SkPngCodec::destroyReadStruct() { 450 void SkPngCodec::destroyReadStruct() {
452 if (fPng_ptr) { 451 if (fPng_ptr) {
(...skipping 14 matching lines...) Expand all
467 SkPMColor ctable[], 466 SkPMColor ctable[],
468 int* ctableCount) { 467 int* ctableCount) {
469 // FIXME: Could we use the return value of setjmp to specify the type of 468 // FIXME: Could we use the return value of setjmp to specify the type of
470 // error? 469 // error?
471 if (setjmp(png_jmpbuf(fPng_ptr))) { 470 if (setjmp(png_jmpbuf(fPng_ptr))) {
472 SkCodecPrintf("setjmp long jump!\n"); 471 SkCodecPrintf("setjmp long jump!\n");
473 return kInvalidInput; 472 return kInvalidInput;
474 } 473 }
475 png_read_update_info(fPng_ptr, fInfo_ptr); 474 png_read_update_info(fPng_ptr, fInfo_ptr);
476 475
477 // suggestedColorType was determined in read_header() based on the encodedCo lorType 476 if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) {
478 const SkColorType suggestedColorType = this->getInfo().colorType(); 477 if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType( ), ctableCount)) {
479 478 return kInvalidInput;
480 switch (suggestedColorType) {
481 case kIndex_8_SkColorType:
482 //decode palette to Skia format
483 fSrcConfig = SkSwizzler::kIndex;
484 if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaT ype(),
485 ctableCount)) {
486 return kInvalidInput;
487 }
488 break;
489 case kGray_8_SkColorType:
490 fSrcConfig = SkSwizzler::kGray;
491 break;
492 case kN32_SkColorType: {
493 const uint8_t encodedColorType = png_get_color_type(fPng_ptr, fInfo_ ptr);
494 if (PNG_COLOR_TYPE_GRAY_ALPHA == encodedColorType ||
495 PNG_COLOR_TYPE_GRAY == encodedColorType) {
496 // If encodedColorType is GRAY, there must be a transparent chun k.
497 // Otherwise, suggestedColorType would be kGray. We have alread y
498 // instructed libpng to convert the transparent chunk to alpha,
499 // so we can treat both GRAY and GRAY_ALPHA as kGrayAlpha.
500 SkASSERT(encodedColorType == PNG_COLOR_TYPE_GRAY_ALPHA ||
501 png_get_valid(fPng_ptr, fInfo_ptr, PNG_INFO_tRNS));
502
503 fSrcConfig = SkSwizzler::kGrayAlpha;
504 } else {
505 if (this->getInfo().alphaType() == kOpaque_SkAlphaType) {
506 fSrcConfig = SkSwizzler::kRGB;
507 } else {
508 fSrcConfig = SkSwizzler::kRGBA;
509 }
510 }
511 break;
512 } 479 }
513 default:
514 // We will always recommend one of the above colorTypes.
515 SkASSERT(false);
516 } 480 }
517 481
518 // Copy the color table to the client if they request kIndex8 mode 482 // Copy the color table to the client if they request kIndex8 mode
519 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); 483 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount);
520 484
521 // Create the swizzler. SkPngCodec retains ownership of the color table. 485 // Create the swizzler. SkPngCodec retains ownership of the color table.
522 const SkPMColor* colors = get_color_ptr(fColorTable.get()); 486 const SkPMColor* colors = get_color_ptr(fColorTable.get());
523 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo , options)); 487 fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, r equestedInfo,
488 options));
524 SkASSERT(fSwizzler); 489 SkASSERT(fSwizzler);
525 490
526 return kSuccess; 491 return kSuccess;
527 } 492 }
528 493
529 494
530 bool SkPngCodec::onRewind() { 495 bool SkPngCodec::onRewind() {
531 // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header 496 // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header
532 // succeeds, they will be repopulated, and if it fails, they will 497 // succeeds, they will be repopulated, and if it fails, they will
533 // remain nullptr. Any future accesses to fPng_ptr and fInfo_ptr will 498 // remain nullptr. Any future accesses to fPng_ptr and fInfo_ptr will
534 // come through this function which will rewind and again attempt 499 // come through this function which will rewind and again attempt
535 // to reinitialize them. 500 // to reinitialize them.
536 this->destroyReadStruct(); 501 this->destroyReadStruct();
537 502
538 png_structp png_ptr; 503 png_structp png_ptr;
539 png_infop info_ptr; 504 png_infop info_ptr;
540 if (!read_header(this->stream(), fPngChunkReader.get(), &png_ptr, &info_ptr, 505 if (!read_header(this->stream(), fPngChunkReader.get(), &png_ptr, &info_ptr,
541 nullptr, nullptr, nullptr, nullptr, nullptr)) { 506 nullptr, nullptr, nullptr, nullptr, nullptr)) {
542 return false; 507 return false;
543 } 508 }
544 509
545 fPng_ptr = png_ptr; 510 fPng_ptr = png_ptr;
546 fInfo_ptr = info_ptr; 511 fInfo_ptr = info_ptr;
547 return true; 512 return true;
548 } 513 }
549 514
515 static int bytes_per_pixel(int bitsPerPixel) {
516 // Note that we will have to change this implementation if we start
517 // supporting outputs from libpng that are less than 8-bits per component.
518 return bitsPerPixel / 8;
519 }
520
550 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst, 521 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst,
551 size_t dstRowBytes, const Options& optio ns, 522 size_t dstRowBytes, const Options& optio ns,
552 SkPMColor ctable[], int* ctableCount, 523 SkPMColor ctable[], int* ctableCount,
553 int* rowsDecoded) { 524 int* rowsDecoded) {
554 if (!conversion_possible(requestedInfo, this->getInfo())) { 525 if (!conversion_possible(requestedInfo, this->getInfo())) {
555 return kInvalidConversion; 526 return kInvalidConversion;
556 } 527 }
557 if (options.fSubset) { 528 if (options.fSubset) {
558 // Subsets are not supported. 529 // Subsets are not supported.
559 return kUnimplemented; 530 return kUnimplemented;
560 } 531 }
561 532
562 // Note that ctable and ctableCount may be modified if there is a color tabl e 533 // Note that ctable and ctableCount may be modified if there is a color tabl e
563 const Result result = this->initializeSwizzler(requestedInfo, options, ctabl e, ctableCount); 534 const Result result = this->initializeSwizzler(requestedInfo, options, ctabl e, ctableCount);
564 if (result != kSuccess) { 535 if (result != kSuccess) {
565 return result; 536 return result;
566 } 537 }
567 538
568 const int width = requestedInfo.width(); 539 const int width = requestedInfo.width();
569 const int height = requestedInfo.height(); 540 const int height = requestedInfo.height();
570 const int bpp = SkSwizzler::BytesPerPixel(fSrcConfig); 541 const int bpp = bytes_per_pixel(this->getEncodedInfo().bitsPerPixel());
571 const size_t srcRowBytes = width * bpp; 542 const size_t srcRowBytes = width * bpp;
572 543
573 // FIXME: Could we use the return value of setjmp to specify the type of 544 // FIXME: Could we use the return value of setjmp to specify the type of
574 // error? 545 // error?
575 int row = 0; 546 int row = 0;
576 // This must be declared above the call to setjmp to avoid memory leaks on i ncomplete images. 547 // This must be declared above the call to setjmp to avoid memory leaks on i ncomplete images.
577 SkAutoTMalloc<uint8_t> storage; 548 SkAutoTMalloc<uint8_t> storage;
578 if (setjmp(png_jmpbuf(fPng_ptr))) { 549 if (setjmp(png_jmpbuf(fPng_ptr))) {
579 // Assume that any error that occurs while reading rows is caused by an incomplete input. 550 // Assume that any error that occurs while reading rows is caused by an incomplete input.
580 if (fNumberPasses > 1) { 551 if (fNumberPasses > 1) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 if (!conversion_possible(dstInfo, this->getInfo())) { 628 if (!conversion_possible(dstInfo, this->getInfo())) {
658 return kInvalidConversion; 629 return kInvalidConversion;
659 } 630 }
660 631
661 const Result result = this->initializeSwizzler(dstInfo, options, ctable, 632 const Result result = this->initializeSwizzler(dstInfo, options, ctable,
662 ctableCount); 633 ctableCount);
663 if (result != kSuccess) { 634 if (result != kSuccess) {
664 return result; 635 return result;
665 } 636 }
666 637
667 fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(this- >srcConfig())); 638 fStorage.reset(this->getInfo().width() *
639 (bytes_per_pixel(this->getEncodedInfo().bitsPerPixel())));
668 fSrcRow = fStorage.get(); 640 fSrcRow = fStorage.get();
669 641
670 return kSuccess; 642 return kSuccess;
671 } 643 }
672 644
673 int onGetScanlines(void* dst, int count, size_t rowBytes) override { 645 int onGetScanlines(void* dst, int count, size_t rowBytes) override {
674 // Assume that an error in libpng indicates an incomplete input. 646 // Assume that an error in libpng indicates an incomplete input.
675 int row = 0; 647 int row = 0;
676 if (setjmp(png_jmpbuf(this->png_ptr()))) { 648 if (setjmp(png_jmpbuf(this->png_ptr()))) {
677 SkCodecPrintf("setjmp long jump!\n"); 649 SkCodecPrintf("setjmp long jump!\n");
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 } 701 }
730 702
731 const Result result = this->initializeSwizzler(dstInfo, options, ctable, 703 const Result result = this->initializeSwizzler(dstInfo, options, ctable,
732 ctableCount); 704 ctableCount);
733 if (result != kSuccess) { 705 if (result != kSuccess) {
734 return result; 706 return result;
735 } 707 }
736 708
737 fHeight = dstInfo.height(); 709 fHeight = dstInfo.height();
738 // FIXME: This need not be called on a second call to onStartScanlineDec ode. 710 // FIXME: This need not be called on a second call to onStartScanlineDec ode.
739 fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(this- >srcConfig()); 711 fSrcRowBytes = this->getInfo().width() *
712 (bytes_per_pixel(this->getEncodedInfo().bitsPerPixel()));
740 fGarbageRow.reset(fSrcRowBytes); 713 fGarbageRow.reset(fSrcRowBytes);
741 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); 714 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get());
742 fCanSkipRewind = true; 715 fCanSkipRewind = true;
743 716
744 return SkCodec::kSuccess; 717 return SkCodec::kSuccess;
745 } 718 }
746 719
747 int onGetScanlines(void* dst, int count, size_t dstRowBytes) override { 720 int onGetScanlines(void* dst, int count, size_t dstRowBytes) override {
748 // rewind stream if have previously called onGetScanlines, 721 // rewind stream if have previously called onGetScanlines,
749 // since we need entire progressive image to get scanlines 722 // since we need entire progressive image to get scanlines
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 824
852 if (1 == numberPasses) { 825 if (1 == numberPasses) {
853 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter. release(), 826 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter. release(),
854 chunkReader, png_ptr, info_ptr, bitDepth , colorSpace); 827 chunkReader, png_ptr, info_ptr, bitDepth , colorSpace);
855 } 828 }
856 829
857 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe leter.release(), 830 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe leter.release(),
858 chunkReader, png_ptr, info_ptr, bi tDepth, 831 chunkReader, png_ptr, info_ptr, bi tDepth,
859 numberPasses, colorSpace); 832 numberPasses, colorSpace);
860 } 833 }
OLDNEW
« no previous file with comments | « src/codec/SkPngCodec.h ('k') | src/codec/SkRawCodec.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698