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

Side by Side Diff: src/images/SkDecodingImageGenerator.cpp

Issue 304443003: add colortable support to imagegenerator (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fix spelling Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « include/core/SkImageGenerator.h ('k') | src/images/SkImageGenerator.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 2013 Google Inc. 2 * Copyright 2013 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 "SkData.h" 8 #include "SkData.h"
9 #include "SkDecodingImageGenerator.h" 9 #include "SkDecodingImageGenerator.h"
10 #include "SkImageDecoder.h" 10 #include "SkImageDecoder.h"
11 #include "SkImageInfo.h" 11 #include "SkImageInfo.h"
12 #include "SkImageGenerator.h" 12 #include "SkImageGenerator.h"
13 #include "SkImagePriv.h" 13 #include "SkImagePriv.h"
14 #include "SkStream.h" 14 #include "SkStream.h"
15 #include "SkUtils.h" 15 #include "SkUtils.h"
16 16
17 namespace { 17 namespace {
18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { 18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) {
19 return a.width() == b.width() && a.height() == b.height() && 19 return a.width() == b.width() && a.height() == b.height() &&
20 a.colorType() == b.colorType(); 20 a.colorType() == b.colorType();
21 } 21 }
22 22
23 class DecodingImageGenerator : public SkImageGenerator { 23 class DecodingImageGenerator : public SkImageGenerator {
24 public: 24 public:
25 virtual ~DecodingImageGenerator(); 25 virtual ~DecodingImageGenerator();
26 virtual SkData* refEncodedData() SK_OVERRIDE;
27 // This implementaion of getInfo() always returns true.
28 virtual bool getInfo(SkImageInfo* info) SK_OVERRIDE;
29 virtual bool getPixels(const SkImageInfo& info,
30 void* pixels,
31 size_t rowBytes) SK_OVERRIDE;
32 26
33 SkData* fData; 27 SkData* fData;
34 SkStreamRewindable* fStream; 28 SkStreamRewindable* fStream;
35 const SkImageInfo fInfo; 29 const SkImageInfo fInfo;
36 const int fSampleSize; 30 const int fSampleSize;
37 const bool fDitherImage; 31 const bool fDitherImage;
38 32
39 DecodingImageGenerator(SkData* data, 33 DecodingImageGenerator(SkData* data,
40 SkStreamRewindable* stream, 34 SkStreamRewindable* stream,
41 const SkImageInfo& info, 35 const SkImageInfo& info,
42 int sampleSize, 36 int sampleSize,
43 bool ditherImage); 37 bool ditherImage);
38
39 protected:
40 virtual SkData* onRefEncodedData() SK_OVERRIDE;
41 virtual bool onGetInfo(SkImageInfo* info) SK_OVERRIDE {
42 *info = fInfo;
43 return true;
44 }
45 virtual bool onGetPixels(const SkImageInfo& info,
46 void* pixels, size_t rowBytes,
47 SkPMColor ctable[], int* ctableCount) SK_OVERRIDE;
48
49 private:
44 typedef SkImageGenerator INHERITED; 50 typedef SkImageGenerator INHERITED;
45 }; 51 };
46 52
47 /** 53 /**
48 * Special allocator used by getPixels(). Uses preallocated memory 54 * Special allocator used by getPixels(). Uses preallocated memory
49 * provided if possible, else fall-back on the default allocator 55 * provided if possible, else fall-back on the default allocator
50 */ 56 */
51 class TargetAllocator : public SkBitmap::Allocator { 57 class TargetAllocator : public SkBitmap::Allocator {
52 public: 58 public:
53 TargetAllocator(const SkImageInfo& info, 59 TargetAllocator(const SkImageInfo& info,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 { 122 {
117 SkASSERT(stream != NULL); 123 SkASSERT(stream != NULL);
118 SkSafeRef(fData); // may be NULL. 124 SkSafeRef(fData); // may be NULL.
119 } 125 }
120 126
121 DecodingImageGenerator::~DecodingImageGenerator() { 127 DecodingImageGenerator::~DecodingImageGenerator() {
122 SkSafeUnref(fData); 128 SkSafeUnref(fData);
123 fStream->unref(); 129 fStream->unref();
124 } 130 }
125 131
126 bool DecodingImageGenerator::getInfo(SkImageInfo* info) { 132 SkData* DecodingImageGenerator::onRefEncodedData() {
127 if (info != NULL) {
128 *info = fInfo;
129 }
130 return true;
131 }
132
133 SkData* DecodingImageGenerator::refEncodedData() {
134 // This functionality is used in `gm --serialize` 133 // This functionality is used in `gm --serialize`
135 // Does not encode options. 134 // Does not encode options.
136 if (fData != NULL) { 135 if (fData != NULL) {
137 return SkSafeRef(fData); 136 return SkSafeRef(fData);
138 } 137 }
139 // TODO(halcanary): SkStreamRewindable needs a refData() function 138 // TODO(halcanary): SkStreamRewindable needs a refData() function
140 // which returns a cheap copy of the underlying data. 139 // which returns a cheap copy of the underlying data.
141 if (!fStream->rewind()) { 140 if (!fStream->rewind()) {
142 return NULL; 141 return NULL;
143 } 142 }
144 size_t length = fStream->getLength(); 143 size_t length = fStream->getLength();
145 if (0 == length) { 144 if (0 == length) {
146 return NULL; 145 return NULL;
147 } 146 }
148 void* buffer = sk_malloc_flags(length, 0); 147 void* buffer = sk_malloc_flags(length, 0);
149 SkCheckResult(fStream->read(buffer, length), length); 148 SkCheckResult(fStream->read(buffer, length), length);
150 fData = SkData::NewFromMalloc(buffer, length); 149 fData = SkData::NewFromMalloc(buffer, length);
151 return SkSafeRef(fData); 150 return SkSafeRef(fData);
152 } 151 }
153 152
154 bool DecodingImageGenerator::getPixels(const SkImageInfo& info, 153 bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info,
155 void* pixels, 154 void* pixels, size_t rowBytes,
156 size_t rowBytes) { 155 SkPMColor ctableEntries[], int* ctableC ount) {
157 if (NULL == pixels) {
158 return false;
159 }
160 if (fInfo != info) { 156 if (fInfo != info) {
161 // The caller has specified a different info. This is an 157 // The caller has specified a different info. This is an
162 // error for this kind of SkImageGenerator. Use the Options 158 // error for this kind of SkImageGenerator. Use the Options
163 // to change the settings. 159 // to change the settings.
164 return false; 160 return false;
165 } 161 }
166 if (info.minRowBytes() > rowBytes) {
167 // The caller has specified a bad rowBytes.
168 return false;
169 }
170 162
171 SkAssertResult(fStream->rewind()); 163 SkAssertResult(fStream->rewind());
172 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); 164 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
173 if (NULL == decoder.get()) { 165 if (NULL == decoder.get()) {
174 return false; 166 return false;
175 } 167 }
176 decoder->setDitherImage(fDitherImage); 168 decoder->setDitherImage(fDitherImage);
177 decoder->setSampleSize(fSampleSize); 169 decoder->setSampleSize(fSampleSize);
178 decoder->setRequireUnpremultipliedColors( 170 decoder->setRequireUnpremultipliedColors(
179 info.fAlphaType == kUnpremul_SkAlphaType); 171 info.fAlphaType == kUnpremul_SkAlphaType);
(...skipping 15 matching lines...) Expand all
195 bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator); 187 bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator);
196 if (!copySuccess || allocator.isReady()) { 188 if (!copySuccess || allocator.isReady()) {
197 SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); 189 SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed.");
198 // Earlier we checked canCopyto(); we expect consistency. 190 // Earlier we checked canCopyto(); we expect consistency.
199 return false; 191 return false;
200 } 192 }
201 SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); 193 SkASSERT(check_alpha(info.alphaType(), bm.alphaType()));
202 } else { 194 } else {
203 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); 195 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType()));
204 } 196 }
197
198 if (kIndex_8_SkColorType == info.colorType()) {
199 if (kIndex_8_SkColorType != bitmap.colorType()) {
200 return false; // they asked for Index8, but we didn't receive that from decoder
201 }
202 SkColorTable* ctable = bitmap.getColorTable();
203 if (NULL == ctable) {
204 return false;
205 }
206 const int count = ctable->count();
207 memcpy(ctableEntries, ctable->lockColors(), count * sizeof(SkPMColor));
208 ctable->unlockColors();
209 *ctableCount = count;
210 }
205 return true; 211 return true;
206 } 212 }
207 213
208 // A contructor-type function that returns NULL on failure. This 214 // A contructor-type function that returns NULL on failure. This
209 // prevents the returned SkImageGenerator from ever being in a bad 215 // prevents the returned SkImageGenerator from ever being in a bad
210 // state. Called by both Create() functions 216 // state. Called by both Create() functions
211 SkImageGenerator* CreateDecodingImageGenerator( 217 SkImageGenerator* CreateDecodingImageGenerator(
212 SkData* data, 218 SkData* data,
213 SkStreamRewindable* stream, 219 SkStreamRewindable* stream,
214 const SkDecodingImageGenerator::Options& opts) { 220 const SkDecodingImageGenerator::Options& opts) {
215 SkASSERT(stream); 221 SkASSERT(stream);
216 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. 222 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this.
217 if (opts.fUseRequestedColorType &&
218 (kIndex_8_SkColorType == opts.fRequestedColorType)) {
219 // We do not support indexed color with SkImageGenerators,
220 return NULL;
221 }
222 SkAssertResult(autoStream->rewind()); 223 SkAssertResult(autoStream->rewind());
223 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream)); 224 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream));
224 if (NULL == decoder.get()) { 225 if (NULL == decoder.get()) {
225 return NULL; 226 return NULL;
226 } 227 }
227 SkBitmap bitmap; 228 SkBitmap bitmap;
228 decoder->setSampleSize(opts.fSampleSize); 229 decoder->setSampleSize(opts.fSampleSize);
229 decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul); 230 decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul);
230 if (!decoder->decode(stream, &bitmap, 231 if (!decoder->decode(stream, &bitmap, SkImageDecoder::kDecodeBounds_Mode)) {
231 SkImageDecoder::kDecodeBounds_Mode)) {
232 return NULL; 232 return NULL;
233 } 233 }
234 if (bitmap.config() == SkBitmap::kNo_Config) { 234 if (kUnknown_SkColorType == bitmap.colorType()) {
235 return NULL; 235 return NULL;
236 } 236 }
237 237
238 SkImageInfo info = bitmap.info(); 238 SkImageInfo info = bitmap.info();
239 239
240 if (!opts.fUseRequestedColorType) { 240 if (opts.fUseRequestedColorType && (opts.fRequestedColorType != info.colorTy pe())) {
241 // Use default
242 if (kIndex_8_SkColorType == bitmap.colorType()) {
243 // We don't support kIndex8 because we don't support
244 // colortables in this workflow.
245 info.fColorType = kN32_SkColorType;
246 }
247 } else {
248 if (!bitmap.canCopyTo(opts.fRequestedColorType)) { 241 if (!bitmap.canCopyTo(opts.fRequestedColorType)) {
249 SkASSERT(bitmap.colorType() != opts.fRequestedColorType); 242 SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
250 return NULL; // Can not translate to needed config. 243 return NULL; // Can not translate to needed config.
251 } 244 }
252 info.fColorType = opts.fRequestedColorType; 245 info.fColorType = opts.fRequestedColorType;
253 } 246 }
254 247
255 if (opts.fRequireUnpremul && info.fAlphaType != kOpaque_SkAlphaType) { 248 if (opts.fRequireUnpremul && info.fAlphaType != kOpaque_SkAlphaType) {
256 info.fAlphaType = kUnpremul_SkAlphaType; 249 info.fAlphaType = kUnpremul_SkAlphaType;
257 } 250 }
(...skipping 23 matching lines...) Expand all
281 SkStreamRewindable* stream, 274 SkStreamRewindable* stream,
282 const SkDecodingImageGenerator::Options& opts) { 275 const SkDecodingImageGenerator::Options& opts) {
283 SkASSERT(stream != NULL); 276 SkASSERT(stream != NULL);
284 SkASSERT(stream->unique()); 277 SkASSERT(stream->unique());
285 if ((stream == NULL) || !stream->unique()) { 278 if ((stream == NULL) || !stream->unique()) {
286 SkSafeUnref(stream); 279 SkSafeUnref(stream);
287 return NULL; 280 return NULL;
288 } 281 }
289 return CreateDecodingImageGenerator(NULL, stream, opts); 282 return CreateDecodingImageGenerator(NULL, stream, opts);
290 } 283 }
OLDNEW
« no previous file with comments | « include/core/SkImageGenerator.h ('k') | src/images/SkImageGenerator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698