1ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com/* 2ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com * Copyright 2013 Google Inc. 3ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com * 4ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com * Use of this source code is governed by a BSD-style license that can be 5ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com * found in the LICENSE file. 6ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com */ 7ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com 81ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org#include "SkData.h" 93d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#include "SkDecodingImageGenerator.h" 10ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com#include "SkImageDecoder.h" 113d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#include "SkImageInfo.h" 12edd370f949a457f5d8f7a62efdaf685d4caf46fehalcanary@google.com#include "SkImageGenerator.h" 1329d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com#include "SkImagePriv.h" 1429d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com#include "SkStream.h" 153d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#include "SkUtils.h" 1629d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com 171f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgnamespace { 181f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgbool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { 198a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org return a.width() == b.width() && a.height() == b.height() && 208a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org a.colorType() == b.colorType(); 218a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org} 228a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org 231f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgclass DecodingImageGenerator : public SkImageGenerator { 241f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgpublic: 251f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org virtual ~DecodingImageGenerator(); 261f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 271f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkData* fData; 281f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkStreamRewindable* fStream; 291f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org const SkImageInfo fInfo; 301f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org const int fSampleSize; 311f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org const bool fDitherImage; 321f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 331f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org DecodingImageGenerator(SkData* data, 341f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkStreamRewindable* stream, 351f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org const SkImageInfo& info, 361f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org int sampleSize, 371f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org bool ditherImage); 3800f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org 3900f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.orgprotected: 4000f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org virtual SkData* onRefEncodedData() SK_OVERRIDE; 4100f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org virtual bool onGetInfo(SkImageInfo* info) SK_OVERRIDE { 4200f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org *info = fInfo; 4300f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return true; 4400f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org } 4500f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org virtual bool onGetPixels(const SkImageInfo& info, 4600f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org void* pixels, size_t rowBytes, 4700f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org SkPMColor ctable[], int* ctableCount) SK_OVERRIDE; 4800f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org 4900f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.orgprivate: 501f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org typedef SkImageGenerator INHERITED; 511f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org}; 521f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 5329d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com/** 5429d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com * Special allocator used by getPixels(). Uses preallocated memory 558a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org * provided if possible, else fall-back on the default allocator 5629d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com */ 5729d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.comclass TargetAllocator : public SkBitmap::Allocator { 5829d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.compublic: 598a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org TargetAllocator(const SkImageInfo& info, 608a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org void* target, 618a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org size_t rowBytes) 628a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org : fInfo(info) 638a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org , fTarget(target) 6429d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com , fRowBytes(rowBytes) 658a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org {} 66d665dc4c100f73272422dd17b4dd2c5d57a6b6dehalcanary@google.com 673d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com bool isReady() { return (fTarget != NULL); } 683d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 693d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) { 708a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (NULL == fTarget || !equal_modulo_alpha(fInfo, bm->info())) { 713d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // Call default allocator. 72848250415eddc54075f7eb8795e8db79e749c6abreed return bm->tryAllocPixels(NULL, ct); 7329d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com } 7486cbf99a5122cd419eb76fd07cea80499f31a383skia.committer@gmail.com 753d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // TODO(halcanary): verify that all callers of this function 763d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // will respect new RowBytes. Will be moot once rowbytes belongs 773d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // to PixelRef. 7800f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org bm->installPixels(fInfo, fTarget, fRowBytes, ct, NULL, NULL); 798a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org 803d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com fTarget = NULL; // never alloc same pixels twice! 8129d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com return true; 8229d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com } 8329d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com 8429d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.comprivate: 858a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org const SkImageInfo fInfo; 863d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com void* fTarget; // Block of memory to be supplied as pixel memory 873d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // in allocPixelRef. Must be large enough to hold 888a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org // a bitmap described by fInfo and fRowBytes 898a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org const size_t fRowBytes; // rowbytes for the destination bitmap 908a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org 9129d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com typedef SkBitmap::Allocator INHERITED; 9229d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com}; 933d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 943d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com// TODO(halcanary): Give this macro a better name and move it into SkTypes.h 953d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#ifdef SK_DEBUG 963d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com #define SkCheckResult(expr, value) SkASSERT((value) == (expr)) 973d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#else 983d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com #define SkCheckResult(expr, value) (void)(expr) 993d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#endif 1003d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 1013d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#ifdef SK_DEBUG 1023d50ea1b87132833d7eab38964f40315ba553205halcanary@google.cominline bool check_alpha(SkAlphaType reported, SkAlphaType actual) { 1033d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com return ((reported == actual) 1043d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com || ((reported == kPremul_SkAlphaType) 1053d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com && (actual == kOpaque_SkAlphaType))); 1063d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com} 1073d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com#endif // SK_DEBUG 1083d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 10929d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com//////////////////////////////////////////////////////////////////////////////// 110ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com 1111f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgDecodingImageGenerator::DecodingImageGenerator( 1123d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkData* data, 1133d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkStreamRewindable* stream, 1143d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com const SkImageInfo& info, 1153d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com int sampleSize, 1168a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org bool ditherImage) 11729d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com : fData(data) 11829d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com , fStream(stream) 1193d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com , fInfo(info) 1203d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com , fSampleSize(sampleSize) 1213d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com , fDitherImage(ditherImage) 1228a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org{ 1233d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkASSERT(stream != NULL); 1243d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkSafeRef(fData); // may be NULL. 12529d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com} 12629d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com 1271f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgDecodingImageGenerator::~DecodingImageGenerator() { 12829d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com SkSafeUnref(fData); 12929d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com fStream->unref(); 130ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com} 131ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com 13200f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.orgSkData* DecodingImageGenerator::onRefEncodedData() { 1332c7c7ee47d75e7815ea8db05e924ab55958cb402halcanary@google.com // This functionality is used in `gm --serialize` 1343d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // Does not encode options. 13533a30503d76fdd989358cedd78445ba96bb809ddreed if (NULL == fData) { 13633a30503d76fdd989358cedd78445ba96bb809ddreed // TODO(halcanary): SkStreamRewindable needs a refData() function 13733a30503d76fdd989358cedd78445ba96bb809ddreed // which returns a cheap copy of the underlying data. 13833a30503d76fdd989358cedd78445ba96bb809ddreed if (!fStream->rewind()) { 13933a30503d76fdd989358cedd78445ba96bb809ddreed return NULL; 14033a30503d76fdd989358cedd78445ba96bb809ddreed } 14133a30503d76fdd989358cedd78445ba96bb809ddreed size_t length = fStream->getLength(); 1429594da111dc1c36c1912eb61207aaa54c17ea550reed if (length) { 1439594da111dc1c36c1912eb61207aaa54c17ea550reed fData = SkData::NewFromStream(fStream, length); 14433a30503d76fdd989358cedd78445ba96bb809ddreed } 14529d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com } 1469594da111dc1c36c1912eb61207aaa54c17ea550reed return SkSafeRef(fData); 147ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com} 148ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com 14900f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.orgbool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, 15000f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org void* pixels, size_t rowBytes, 15100f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org SkPMColor ctableEntries[], int* ctableCount) { 1521ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org if (fInfo != info) { 1533d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // The caller has specified a different info. This is an 1543d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // error for this kind of SkImageGenerator. Use the Options 1553d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // to change the settings. 1561ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org return false; 1571ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org } 1583d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 1593d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkAssertResult(fStream->rewind()); 1603d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); 1613d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com if (NULL == decoder.get()) { 1621ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org return false; 1631ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org } 1643d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com decoder->setDitherImage(fDitherImage); 1653d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com decoder->setSampleSize(fSampleSize); 166e5ea500d4714a7d84de2bf913e81be3b65d2de68reed decoder->setRequireUnpremultipliedColors(info.alphaType() == kUnpremul_SkAlphaType); 1671ad518bf38184ae820f31f9b79dfb4e4daf5841acommit-bot@chromium.org 1683d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkBitmap bitmap; 1698a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org TargetAllocator allocator(fInfo, pixels, rowBytes); 1703d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com decoder->setAllocator(&allocator); 171bfefc7c95fc0e8ebd5000c68f6d16e1a3ea0e71ereed bool success = decoder->decode(fStream, &bitmap, info.colorType(), 17229d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com SkImageDecoder::kDecodePixels_Mode); 17329d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com decoder->setAllocator(NULL); 17429d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com if (!success) { 17529d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com return false; 17629d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com } 1773d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com if (allocator.isReady()) { // Did not use pixels! 1783d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkBitmap bm; 1798a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkASSERT(bitmap.canCopyTo(info.colorType())); 1808a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator); 1818a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (!copySuccess || allocator.isReady()) { 1823d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); 1833d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com // Earlier we checked canCopyto(); we expect consistency. 1843d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com return false; 1853d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com } 1868a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); 1873d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com } else { 1888a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); 18929d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com } 19000f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org 19100f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org if (kIndex_8_SkColorType == info.colorType()) { 19200f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org if (kIndex_8_SkColorType != bitmap.colorType()) { 19300f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return false; // they asked for Index8, but we didn't receive that from decoder 19400f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org } 19500f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org SkColorTable* ctable = bitmap.getColorTable(); 19600f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org if (NULL == ctable) { 19700f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org return false; 19800f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org } 19900f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org const int count = ctable->count(); 20000f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org memcpy(ctableEntries, ctable->lockColors(), count * sizeof(SkPMColor)); 20100f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org ctable->unlockColors(); 20200f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org *ctableCount = count; 20300f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org } 20429d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com return true; 205ad04eb49f5d3f324e6b85411c776d7466c1fef92halcanary@google.com} 2063d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 2073d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com// A contructor-type function that returns NULL on failure. This 2083d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com// prevents the returned SkImageGenerator from ever being in a bad 2093d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com// state. Called by both Create() functions 2101f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgSkImageGenerator* CreateDecodingImageGenerator( 2113d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkData* data, 2123d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkStreamRewindable* stream, 2133d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com const SkDecodingImageGenerator::Options& opts) { 2143d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkASSERT(stream); 2153d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. 2163d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkAssertResult(autoStream->rewind()); 2173d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream)); 2183d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com if (NULL == decoder.get()) { 2193d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com return NULL; 2203d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com } 2213d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com SkBitmap bitmap; 2223d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com decoder->setSampleSize(opts.fSampleSize); 2231ae492f19bc3e1ddbe97b5be6380c82f9e6eacb8commit-bot@chromium.org decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul); 22400f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org if (!decoder->decode(stream, &bitmap, SkImageDecoder::kDecodeBounds_Mode)) { 2253d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com return NULL; 2263d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com } 22700f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org if (kUnknown_SkColorType == bitmap.colorType()) { 2283d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com return NULL; 2293d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com } 2303d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 2318a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkImageInfo info = bitmap.info(); 2323d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com 23300f8d6c75d22ce8f95f932c5b101354b196fa0dfcommit-bot@chromium.org if (opts.fUseRequestedColorType && (opts.fRequestedColorType != info.colorType())) { 2348a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org if (!bitmap.canCopyTo(opts.fRequestedColorType)) { 2358a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org SkASSERT(bitmap.colorType() != opts.fRequestedColorType); 2363d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com return NULL; // Can not translate to needed config. 2373d50ea1b87132833d7eab38964f40315ba553205halcanary@google.com } 238e5ea500d4714a7d84de2bf913e81be3b65d2de68reed info = info.makeColorType(opts.fRequestedColorType); 23929d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com } 2401ae492f19bc3e1ddbe97b5be6380c82f9e6eacb8commit-bot@chromium.org 241e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (opts.fRequireUnpremul && info.alphaType() != kOpaque_SkAlphaType) { 242e5ea500d4714a7d84de2bf913e81be3b65d2de68reed info = info.makeAlphaType(kUnpremul_SkAlphaType); 2431ae492f19bc3e1ddbe97b5be6380c82f9e6eacb8commit-bot@chromium.org } 2442fd0d14b9be34a7a945942733c3516d97d07f516scroggo 245e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkAlphaType newAlphaType = info.alphaType(); 246e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (!SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAlphaType)) { 2472fd0d14b9be34a7a945942733c3516d97d07f516scroggo return NULL; 2482fd0d14b9be34a7a945942733c3516d97d07f516scroggo } 2492fd0d14b9be34a7a945942733c3516d97d07f516scroggo 2501f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org return SkNEW_ARGS(DecodingImageGenerator, 251e5ea500d4714a7d84de2bf913e81be3b65d2de68reed (data, autoStream.detach(), info.makeAlphaType(newAlphaType), 2528a2ad3cae710f05cca57e48dd1732d575dba2dc7commit-bot@chromium.org opts.fSampleSize, opts.fDitherImage)); 25329d96935ae34dfcd6e403f9beefa7436e226836ehalcanary@google.com} 2541f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 2551f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org} // namespace 2561f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 2571f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 2581f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 2591f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgSkImageGenerator* SkDecodingImageGenerator::Create( 2601f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkData* data, 2611f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org const SkDecodingImageGenerator::Options& opts) { 2621f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkASSERT(data != NULL); 2631f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org if (NULL == data) { 2641f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org return NULL; 2651f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org } 2661f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data)); 2671f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkASSERT(stream != NULL); 2681f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkASSERT(stream->unique()); 2691f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org return CreateDecodingImageGenerator(data, stream, opts); 2701f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org} 2711f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org 2721f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.orgSkImageGenerator* SkDecodingImageGenerator::Create( 2731f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkStreamRewindable* stream, 2741f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org const SkDecodingImageGenerator::Options& opts) { 2751f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkASSERT(stream != NULL); 2761f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkASSERT(stream->unique()); 2771f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org if ((stream == NULL) || !stream->unique()) { 2781f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org SkSafeUnref(stream); 2791f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org return NULL; 2801f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org } 2811f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org return CreateDecodingImageGenerator(NULL, stream, opts); 2821f2d357436c7d133873b8f7d497c01afa70a6f32commit-bot@chromium.org} 283