OLD | NEW |
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 static bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { | 17 namespace { |
| 18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { |
18 return a.width() == b.width() && a.height() == b.height() && | 19 return a.width() == b.width() && a.height() == b.height() && |
19 a.colorType() == b.colorType(); | 20 a.colorType() == b.colorType(); |
20 } | 21 } |
21 | 22 |
22 namespace { | 23 class DecodingImageGenerator : public SkImageGenerator { |
| 24 public: |
| 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 |
| 33 SkData* fData; |
| 34 SkStreamRewindable* fStream; |
| 35 const SkImageInfo fInfo; |
| 36 const int fSampleSize; |
| 37 const bool fDitherImage; |
| 38 |
| 39 DecodingImageGenerator(SkData* data, |
| 40 SkStreamRewindable* stream, |
| 41 const SkImageInfo& info, |
| 42 int sampleSize, |
| 43 bool ditherImage); |
| 44 typedef SkImageGenerator INHERITED; |
| 45 }; |
| 46 |
23 /** | 47 /** |
24 * Special allocator used by getPixels(). Uses preallocated memory | 48 * Special allocator used by getPixels(). Uses preallocated memory |
25 * provided if possible, else fall-back on the default allocator | 49 * provided if possible, else fall-back on the default allocator |
26 */ | 50 */ |
27 class TargetAllocator : public SkBitmap::Allocator { | 51 class TargetAllocator : public SkBitmap::Allocator { |
28 public: | 52 public: |
29 TargetAllocator(const SkImageInfo& info, | 53 TargetAllocator(const SkImageInfo& info, |
30 void* target, | 54 void* target, |
31 size_t rowBytes) | 55 size_t rowBytes) |
32 : fInfo(info) | 56 : fInfo(info) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 #endif | 93 #endif |
70 | 94 |
71 #ifdef SK_DEBUG | 95 #ifdef SK_DEBUG |
72 inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) { | 96 inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) { |
73 return ((reported == actual) | 97 return ((reported == actual) |
74 || ((reported == kPremul_SkAlphaType) | 98 || ((reported == kPremul_SkAlphaType) |
75 && (actual == kOpaque_SkAlphaType))); | 99 && (actual == kOpaque_SkAlphaType))); |
76 } | 100 } |
77 #endif // SK_DEBUG | 101 #endif // SK_DEBUG |
78 | 102 |
79 } // namespace | |
80 //////////////////////////////////////////////////////////////////////////////// | 103 //////////////////////////////////////////////////////////////////////////////// |
81 | 104 |
82 SkDecodingImageGenerator::SkDecodingImageGenerator( | 105 DecodingImageGenerator::DecodingImageGenerator( |
83 SkData* data, | 106 SkData* data, |
84 SkStreamRewindable* stream, | 107 SkStreamRewindable* stream, |
85 const SkImageInfo& info, | 108 const SkImageInfo& info, |
86 int sampleSize, | 109 int sampleSize, |
87 bool ditherImage) | 110 bool ditherImage) |
88 : fData(data) | 111 : fData(data) |
89 , fStream(stream) | 112 , fStream(stream) |
90 , fInfo(info) | 113 , fInfo(info) |
91 , fSampleSize(sampleSize) | 114 , fSampleSize(sampleSize) |
92 , fDitherImage(ditherImage) | 115 , fDitherImage(ditherImage) |
93 { | 116 { |
94 SkASSERT(stream != NULL); | 117 SkASSERT(stream != NULL); |
95 SkSafeRef(fData); // may be NULL. | 118 SkSafeRef(fData); // may be NULL. |
96 } | 119 } |
97 | 120 |
98 SkDecodingImageGenerator::~SkDecodingImageGenerator() { | 121 DecodingImageGenerator::~DecodingImageGenerator() { |
99 SkSafeUnref(fData); | 122 SkSafeUnref(fData); |
100 fStream->unref(); | 123 fStream->unref(); |
101 } | 124 } |
102 | 125 |
103 bool SkDecodingImageGenerator::getInfo(SkImageInfo* info) { | 126 bool DecodingImageGenerator::getInfo(SkImageInfo* info) { |
104 if (info != NULL) { | 127 if (info != NULL) { |
105 *info = fInfo; | 128 *info = fInfo; |
106 } | 129 } |
107 return true; | 130 return true; |
108 } | 131 } |
109 | 132 |
110 SkData* SkDecodingImageGenerator::refEncodedData() { | 133 SkData* DecodingImageGenerator::refEncodedData() { |
111 // This functionality is used in `gm --serialize` | 134 // This functionality is used in `gm --serialize` |
112 // Does not encode options. | 135 // Does not encode options. |
113 if (fData != NULL) { | 136 if (fData != NULL) { |
114 return SkSafeRef(fData); | 137 return SkSafeRef(fData); |
115 } | 138 } |
116 // TODO(halcanary): SkStreamRewindable needs a refData() function | 139 // TODO(halcanary): SkStreamRewindable needs a refData() function |
117 // which returns a cheap copy of the underlying data. | 140 // which returns a cheap copy of the underlying data. |
118 if (!fStream->rewind()) { | 141 if (!fStream->rewind()) { |
119 return NULL; | 142 return NULL; |
120 } | 143 } |
121 size_t length = fStream->getLength(); | 144 size_t length = fStream->getLength(); |
122 if (0 == length) { | 145 if (0 == length) { |
123 return NULL; | 146 return NULL; |
124 } | 147 } |
125 void* buffer = sk_malloc_flags(length, 0); | 148 void* buffer = sk_malloc_flags(length, 0); |
126 SkCheckResult(fStream->read(buffer, length), length); | 149 SkCheckResult(fStream->read(buffer, length), length); |
127 fData = SkData::NewFromMalloc(buffer, length); | 150 fData = SkData::NewFromMalloc(buffer, length); |
128 return SkSafeRef(fData); | 151 return SkSafeRef(fData); |
129 } | 152 } |
130 | 153 |
131 bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, | 154 bool DecodingImageGenerator::getPixels(const SkImageInfo& info, |
132 void* pixels, | 155 void* pixels, |
133 size_t rowBytes) { | 156 size_t rowBytes) { |
134 if (NULL == pixels) { | 157 if (NULL == pixels) { |
135 return false; | 158 return false; |
136 } | 159 } |
137 if (fInfo != info) { | 160 if (fInfo != info) { |
138 // The caller has specified a different info. This is an | 161 // The caller has specified a different info. This is an |
139 // error for this kind of SkImageGenerator. Use the Options | 162 // error for this kind of SkImageGenerator. Use the Options |
140 // to change the settings. | 163 // to change the settings. |
141 return false; | 164 return false; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 // Earlier we checked canCopyto(); we expect consistency. | 196 // Earlier we checked canCopyto(); we expect consistency. |
174 return false; | 197 return false; |
175 } | 198 } |
176 SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); | 199 SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); |
177 } else { | 200 } else { |
178 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); | 201 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); |
179 } | 202 } |
180 return true; | 203 return true; |
181 } | 204 } |
182 | 205 |
183 SkImageGenerator* SkDecodingImageGenerator::Create( | |
184 SkData* data, | |
185 const SkDecodingImageGenerator::Options& opts) { | |
186 SkASSERT(data != NULL); | |
187 if (NULL == data) { | |
188 return NULL; | |
189 } | |
190 SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data)); | |
191 SkASSERT(stream != NULL); | |
192 SkASSERT(stream->unique()); | |
193 return SkDecodingImageGenerator::Create(data, stream, opts); | |
194 } | |
195 | |
196 SkImageGenerator* SkDecodingImageGenerator::Create( | |
197 SkStreamRewindable* stream, | |
198 const SkDecodingImageGenerator::Options& opts) { | |
199 SkASSERT(stream != NULL); | |
200 SkASSERT(stream->unique()); | |
201 if ((stream == NULL) || !stream->unique()) { | |
202 SkSafeUnref(stream); | |
203 return NULL; | |
204 } | |
205 return SkDecodingImageGenerator::Create(NULL, stream, opts); | |
206 } | |
207 | |
208 // A contructor-type function that returns NULL on failure. This | 206 // A contructor-type function that returns NULL on failure. This |
209 // prevents the returned SkImageGenerator from ever being in a bad | 207 // prevents the returned SkImageGenerator from ever being in a bad |
210 // state. Called by both Create() functions | 208 // state. Called by both Create() functions |
211 SkImageGenerator* SkDecodingImageGenerator::Create( | 209 SkImageGenerator* CreateDecodingImageGenerator( |
212 SkData* data, | 210 SkData* data, |
213 SkStreamRewindable* stream, | 211 SkStreamRewindable* stream, |
214 const SkDecodingImageGenerator::Options& opts) { | 212 const SkDecodingImageGenerator::Options& opts) { |
215 SkASSERT(stream); | 213 SkASSERT(stream); |
216 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. | 214 SkAutoTUnref<SkStreamRewindable> autoStream(stream); // always unref this. |
217 if (opts.fUseRequestedColorType && | 215 if (opts.fUseRequestedColorType && |
218 (kIndex_8_SkColorType == opts.fRequestedColorType)) { | 216 (kIndex_8_SkColorType == opts.fRequestedColorType)) { |
219 // We do not support indexed color with SkImageGenerators, | 217 // We do not support indexed color with SkImageGenerators, |
220 return NULL; | 218 return NULL; |
221 } | 219 } |
(...skipping 21 matching lines...) Expand all Loading... |
243 // colortables in this workflow. | 241 // colortables in this workflow. |
244 info.fColorType = kPMColor_SkColorType; | 242 info.fColorType = kPMColor_SkColorType; |
245 } | 243 } |
246 } else { | 244 } else { |
247 if (!bitmap.canCopyTo(opts.fRequestedColorType)) { | 245 if (!bitmap.canCopyTo(opts.fRequestedColorType)) { |
248 SkASSERT(bitmap.colorType() != opts.fRequestedColorType); | 246 SkASSERT(bitmap.colorType() != opts.fRequestedColorType); |
249 return NULL; // Can not translate to needed config. | 247 return NULL; // Can not translate to needed config. |
250 } | 248 } |
251 info.fColorType = opts.fRequestedColorType; | 249 info.fColorType = opts.fRequestedColorType; |
252 } | 250 } |
253 return SkNEW_ARGS(SkDecodingImageGenerator, | 251 return SkNEW_ARGS(DecodingImageGenerator, |
254 (data, autoStream.detach(), info, | 252 (data, autoStream.detach(), info, |
255 opts.fSampleSize, opts.fDitherImage)); | 253 opts.fSampleSize, opts.fDitherImage)); |
256 } | 254 } |
| 255 |
| 256 } // namespace |
| 257 |
| 258 //////////////////////////////////////////////////////////////////////////////// |
| 259 |
| 260 SkImageGenerator* SkDecodingImageGenerator::Create( |
| 261 SkData* data, |
| 262 const SkDecodingImageGenerator::Options& opts) { |
| 263 SkASSERT(data != NULL); |
| 264 if (NULL == data) { |
| 265 return NULL; |
| 266 } |
| 267 SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data)); |
| 268 SkASSERT(stream != NULL); |
| 269 SkASSERT(stream->unique()); |
| 270 return CreateDecodingImageGenerator(data, stream, opts); |
| 271 } |
| 272 |
| 273 SkImageGenerator* SkDecodingImageGenerator::Create( |
| 274 SkStreamRewindable* stream, |
| 275 const SkDecodingImageGenerator::Options& opts) { |
| 276 SkASSERT(stream != NULL); |
| 277 SkASSERT(stream->unique()); |
| 278 if ((stream == NULL) || !stream->unique()) { |
| 279 SkSafeUnref(stream); |
| 280 return NULL; |
| 281 } |
| 282 return CreateDecodingImageGenerator(NULL, stream, opts); |
| 283 } |
OLD | NEW |