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

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

Issue 1061713007: Adding png scanline decoding to kIndex8 (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: ctableCount requirements Created 5 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
« include/codec/SkCodec.h ('K') | « src/codec/SkCodec_libpng.h ('k') | no next file » | 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"
11 #include "SkColorTable.h" 11 #include "SkColorTable.h"
12 #include "SkBitmap.h" 12 #include "SkBitmap.h"
13 #include "SkMath.h" 13 #include "SkMath.h"
14 #include "SkScanlineDecoder.h" 14 #include "SkScanlineDecoder.h"
15 #include "SkSize.h" 15 #include "SkSize.h"
16 #include "SkStream.h" 16 #include "SkStream.h"
17 #include "SkSwizzler.h" 17 #include "SkSwizzler.h"
18 #include "SkUtils.h"
19 18
20 /////////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////////
21 // Helper macros 20 // Helper macros
22 /////////////////////////////////////////////////////////////////////////////// 21 ///////////////////////////////////////////////////////////////////////////////
23 22
24 #ifndef png_jmpbuf 23 #ifndef png_jmpbuf
25 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 24 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
26 #endif 25 #endif
27 26
28 /* These were dropped in libpng >= 1.4 */ 27 /* These were dropped in libpng >= 1.4 */
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 the palette is empty (really broken image). 177 the palette is empty (really broken image).
179 */ 178 */
180 int colorCount = SkTMax(numPalette, 1 << SkTMin(bitDepth, 8)); 179 int colorCount = SkTMax(numPalette, 1 << SkTMin(bitDepth, 8));
181 SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0) ; 180 SkPMColor lastColor = index > 0 ? colorPtr[-1] : SkPackARGB32(0xFF, 0, 0, 0) ;
182 for (; index < colorCount; index++) { 181 for (; index < colorCount; index++) {
183 *colorPtr++ = lastColor; 182 *colorPtr++ = lastColor;
184 } 183 }
185 184
186 // Set the new color count 185 // Set the new color count
187 if (ctableCount != NULL) { 186 if (ctableCount != NULL) {
188 SkASSERT(256 == *ctableCount);
189 *ctableCount = colorCount; 187 *ctableCount = colorCount;
190 } 188 }
191 189
192 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorStorage, colorCount))); 190 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorStorage, colorCount)));
193 return true; 191 return true;
194 } 192 }
195 193
196 /////////////////////////////////////////////////////////////////////////////// 194 ///////////////////////////////////////////////////////////////////////////////
197 // Creation 195 // Creation
198 /////////////////////////////////////////////////////////////////////////////// 196 ///////////////////////////////////////////////////////////////////////////////
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 case kN32_SkColorType: 420 case kN32_SkColorType:
423 return true; 421 return true;
424 default: 422 default:
425 return dst.colorType() == src.colorType(); 423 return dst.colorType() == src.colorType();
426 } 424 }
427 } 425 }
428 426
429 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, 427 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo,
430 void* dst, size_t rowBytes, 428 void* dst, size_t rowBytes,
431 const Options& options, 429 const Options& options,
430 SkPMColor ctable[],
432 int* ctableCount) { 431 int* ctableCount) {
433 // FIXME: Could we use the return value of setjmp to specify the type of 432 // FIXME: Could we use the return value of setjmp to specify the type of
434 // error? 433 // error?
435 if (setjmp(png_jmpbuf(fPng_ptr))) { 434 if (setjmp(png_jmpbuf(fPng_ptr))) {
436 SkCodecPrintf("setjmp long jump!\n"); 435 SkCodecPrintf("setjmp long jump!\n");
437 return kInvalidInput; 436 return kInvalidInput;
438 } 437 }
439 438
440 // FIXME: We already retrieved this information. Store it in SkPngCodec? 439 // FIXME: We already retrieved this information. Store it in SkPngCodec?
441 png_uint_32 origWidth, origHeight; 440 png_uint_32 origWidth, origHeight;
(...skipping 15 matching lines...) Expand all
457 } else if (kAlpha_8_SkColorType == requestedInfo.colorType()) { 456 } else if (kAlpha_8_SkColorType == requestedInfo.colorType()) {
458 // Note: we check the destination, since otherwise we would have 457 // Note: we check the destination, since otherwise we would have
459 // told png to upscale. 458 // told png to upscale.
460 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType); 459 SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
461 fSrcConfig = SkSwizzler::kGray; 460 fSrcConfig = SkSwizzler::kGray;
462 } else if (this->getInfo().alphaType() == kOpaque_SkAlphaType) { 461 } else if (this->getInfo().alphaType() == kOpaque_SkAlphaType) {
463 fSrcConfig = SkSwizzler::kRGBX; 462 fSrcConfig = SkSwizzler::kRGBX;
464 } else { 463 } else {
465 fSrcConfig = SkSwizzler::kRGBA; 464 fSrcConfig = SkSwizzler::kRGBA;
466 } 465 }
466
467 // Copy the color table to the client if they request kIndex8 mode
468 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount);
469
470 // Create the swizzler. SkPngCodec retains ownership of the color table.
467 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL; 471 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL;
468 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo , 472 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo ,
469 dst, rowBytes, options.fZeroInitialized)); 473 dst, rowBytes, options.fZeroInitialized));
470 if (!fSwizzler) { 474 if (!fSwizzler) {
471 // FIXME: CreateSwizzler could fail for another reason. 475 // FIXME: CreateSwizzler could fail for another reason.
472 return kUnimplemented; 476 return kUnimplemented;
473 } 477 }
474 478
475 // FIXME: Here is where we should likely insert some of the modifications 479 // FIXME: Here is where we should likely insert some of the modifications
476 // made in the factory. 480 // made in the factory.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 if (!this->handleRewind()) { 517 if (!this->handleRewind()) {
514 return kCouldNotRewind; 518 return kCouldNotRewind;
515 } 519 }
516 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { 520 if (requestedInfo.dimensions() != this->getInfo().dimensions()) {
517 return kInvalidScale; 521 return kInvalidScale;
518 } 522 }
519 if (!conversion_possible(requestedInfo, this->getInfo())) { 523 if (!conversion_possible(requestedInfo, this->getInfo())) {
520 return kInvalidConversion; 524 return kInvalidConversion;
521 } 525 }
522 526
523 // Note that ctableCount will be modified if there is a color table 527 // Note that ctable and ctableCount may be modified if there is a color tabl e
524 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes, 528 const Result result = this->initializeSwizzler(requestedInfo, dst, rowBytes,
525 options, ctableCount); 529 options, ctable, ctableCount) ;
526
527 // Copy the color table to the client if necessary
528 if (kIndex_8_SkColorType == requestedInfo.colorType()) {
529 SkASSERT(NULL != ctable);
530 SkASSERT(NULL != ctableCount);
531 SkASSERT(NULL != fColorTable.get());
532 sk_memcpy32(ctable, fColorTable->readColors(), *ctableCount);
533 }
534 530
535 if (result != kSuccess) { 531 if (result != kSuccess) {
536 return result; 532 return result;
537 } 533 }
538 534
539 // FIXME: Could we use the return value of setjmp to specify the type of 535 // FIXME: Could we use the return value of setjmp to specify the type of
540 // error? 536 // error?
541 if (setjmp(png_jmpbuf(fPng_ptr))) { 537 if (setjmp(png_jmpbuf(fPng_ptr))) {
542 SkCodecPrintf("setjmp long jump!\n"); 538 SkCodecPrintf("setjmp long jump!\n");
543 return kInvalidInput; 539 return kInvalidInput;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 637
642 private: 638 private:
643 SkPngCodec* fCodec; // Unowned. 639 SkPngCodec* fCodec; // Unowned.
644 bool fHasAlpha; 640 bool fHasAlpha;
645 SkAutoMalloc fStorage; 641 SkAutoMalloc fStorage;
646 uint8_t* fSrcRow; 642 uint8_t* fSrcRow;
647 643
648 typedef SkScanlineDecoder INHERITED; 644 typedef SkScanlineDecoder INHERITED;
649 }; 645 };
650 646
651 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo) { 647 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
648 const Options& options, SkPMColor ctable[], int* ctableCount) {
652 if (!this->handleRewind()) { 649 if (!this->handleRewind()) {
653 return NULL; 650 return NULL;
654 } 651 }
655 652
656 // Check to see if scaling was requested. 653 // Check to see if scaling was requested.
657 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 654 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
658 return NULL; 655 return NULL;
659 } 656 }
660 657
661 if (!conversion_possible(dstInfo, this->getInfo())) { 658 if (!conversion_possible(dstInfo, this->getInfo())) {
662 SkCodecPrintf("no conversion possible\n"); 659 SkCodecPrintf("no conversion possible\n");
663 return NULL; 660 return NULL;
664 } 661 }
665 662
666 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded, 663 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded,
667 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to 664 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to
668 // be at least dstInfo.minRowBytes. 665 // be at least dstInfo.minRowBytes.
669 Options opts; 666 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable,
670 // FIXME: Pass this in to getScanlineDecoder? 667 ctableCount) != kSuccess) {
671 opts.fZeroInitialized = kNo_ZeroInitialized;
672 // FIXME: onGetScanlineDecoder does not currently have a way to get color ta ble information
673 // for a kIndex8 decoder.
674 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), opts, NUL L) != kSuccess) {
675 SkCodecPrintf("failed to initialize the swizzler.\n"); 668 SkCodecPrintf("failed to initialize the swizzler.\n");
676 return NULL; 669 return NULL;
677 } 670 }
678 671
679 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); 672 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES);
680 if (fNumberPasses > 1) { 673 if (fNumberPasses > 1) {
681 // We cannot efficiently do scanline decoding. 674 // We cannot efficiently do scanline decoding.
682 return NULL; 675 return NULL;
683 } 676 }
684 677
685 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); 678 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this));
686 } 679 }
687 680
OLDNEW
« include/codec/SkCodec.h ('K') | « src/codec/SkCodec_libpng.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698