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

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

Issue 1692053002: Delete SkDecodingImageGenerator (Closed) Base URL: https://skia.googlesource.com/skia.git@noble
Patch Set: Created 4 years, 10 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkData.h"
9 #include "SkDecodingImageGenerator.h"
10 #include "SkImageDecoder.h"
11 #include "SkImageInfo.h"
12 #include "SkImageGenerator.h"
13 #include "SkImagePriv.h"
14 #include "SkStream.h"
15 #include "SkUtils.h"
16
17 namespace {
18 bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) {
19 return a.width() == b.width() && a.height() == b.height() &&
20 a.colorType() == b.colorType();
21 }
22
23 class DecodingImageGenerator : public SkImageGenerator {
24 public:
25 virtual ~DecodingImageGenerator();
26
27 SkData* fData;
28 SkAutoTDelete<SkStreamRewindable> fStream;
29 const SkImageInfo fInfo;
30 const int fSampleSize;
31 const bool fDitherImage;
32
33 DecodingImageGenerator(SkData* data,
34 SkStreamRewindable* stream,
35 const SkImageInfo& info,
36 int sampleSize,
37 bool ditherImage);
38
39 protected:
40 SkData* onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM) override;
41 bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
42 SkPMColor ctable[], int* ctableCount) override;
43 bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
44 SkYUVColorSpace* colorSpace) override;
45
46 private:
47 typedef SkImageGenerator INHERITED;
48 };
49
50 /**
51 * Special allocator used by getPixels(). Uses preallocated memory
52 * provided if possible, else fall-back on the default allocator
53 */
54 class TargetAllocator : public SkBitmap::Allocator {
55 public:
56 TargetAllocator(const SkImageInfo& info,
57 void* target,
58 size_t rowBytes)
59 : fInfo(info)
60 , fTarget(target)
61 , fRowBytes(rowBytes)
62 {}
63
64 bool isReady() { return (fTarget != nullptr); }
65
66 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) {
67 if (nullptr == fTarget || !equal_modulo_alpha(fInfo, bm->info())) {
68 // Call default allocator.
69 return bm->tryAllocPixels(nullptr, ct);
70 }
71
72 // TODO(halcanary): verify that all callers of this function
73 // will respect new RowBytes. Will be moot once rowbytes belongs
74 // to PixelRef.
75 bm->installPixels(fInfo, fTarget, fRowBytes, ct, nullptr, nullptr);
76
77 fTarget = nullptr; // never alloc same pixels twice!
78 return true;
79 }
80
81 private:
82 const SkImageInfo fInfo;
83 void* fTarget; // Block of memory to be supplied as pixel memory
84 // in allocPixelRef. Must be large enough to hold
85 // a bitmap described by fInfo and fRowBytes
86 const size_t fRowBytes; // rowbytes for the destination bitmap
87
88 typedef SkBitmap::Allocator INHERITED;
89 };
90
91 // TODO(halcanary): Give this macro a better name and move it into SkTypes.h
92 #ifdef SK_DEBUG
93 #define SkCheckResult(expr, value) SkASSERT((value) == (expr))
94 #else
95 #define SkCheckResult(expr, value) (void)(expr)
96 #endif
97
98 #ifdef SK_DEBUG
99 inline bool check_alpha(SkAlphaType reported, SkAlphaType actual) {
100 return ((reported == actual)
101 || ((reported == kPremul_SkAlphaType)
102 && (actual == kOpaque_SkAlphaType)));
103 }
104 #endif // SK_DEBUG
105
106 ////////////////////////////////////////////////////////////////////////////////
107
108 DecodingImageGenerator::DecodingImageGenerator(
109 SkData* data,
110 SkStreamRewindable* stream,
111 const SkImageInfo& info,
112 int sampleSize,
113 bool ditherImage)
114 : INHERITED(info)
115 , fData(data)
116 , fStream(stream)
117 , fInfo(info)
118 , fSampleSize(sampleSize)
119 , fDitherImage(ditherImage)
120 {
121 SkASSERT(stream != nullptr);
122 SkSafeRef(fData); // may be nullptr.
123 }
124
125 DecodingImageGenerator::~DecodingImageGenerator() {
126 SkSafeUnref(fData);
127 }
128
129 SkData* DecodingImageGenerator::onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM) {
130 // This functionality is used in `gm --serialize`
131 // Does not encode options.
132 if (nullptr == fData) {
133 // TODO(halcanary): SkStreamRewindable needs a refData() function
134 // which returns a cheap copy of the underlying data.
135 if (!fStream->rewind()) {
136 return nullptr;
137 }
138 size_t length = fStream->getLength();
139 if (length) {
140 fData = SkData::NewFromStream(fStream, length);
141 }
142 }
143 return SkSafeRef(fData);
144 }
145
146 bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
147 SkPMColor ctableEntries[], int* ctableC ount) {
148 if (fInfo != info) {
149 // The caller has specified a different info. This is an
150 // error for this kind of SkImageGenerator. Use the Options
151 // to change the settings.
152 return false;
153 }
154
155 SkAssertResult(fStream->rewind());
156 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
157 if (nullptr == decoder.get()) {
158 return false;
159 }
160 decoder->setDitherImage(fDitherImage);
161 decoder->setSampleSize(fSampleSize);
162 decoder->setRequireUnpremultipliedColors(info.alphaType() == kUnpremul_SkAlp haType);
163
164 SkBitmap bitmap;
165 TargetAllocator allocator(fInfo, pixels, rowBytes);
166 decoder->setAllocator(&allocator);
167 const SkImageDecoder::Result decodeResult = decoder->decode(fStream, &bitmap , info.colorType(),
168 SkImageDecoder:: kDecodePixels_Mode);
169 decoder->setAllocator(nullptr);
170 if (SkImageDecoder::kFailure == decodeResult) {
171 return false;
172 }
173 if (allocator.isReady()) { // Did not use pixels!
174 SkBitmap bm;
175 SkASSERT(bitmap.canCopyTo(info.colorType()));
176 bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator);
177 if (!copySuccess || allocator.isReady()) {
178 SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed.");
179 // Earlier we checked canCopyto(); we expect consistency.
180 return false;
181 }
182 SkASSERT(check_alpha(info.alphaType(), bm.alphaType()));
183 } else {
184 SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType()));
185 }
186
187 if (kIndex_8_SkColorType == info.colorType()) {
188 if (kIndex_8_SkColorType != bitmap.colorType()) {
189 // they asked for Index8, but we didn't receive that from decoder
190 return false;
191 }
192 SkColorTable* ctable = bitmap.getColorTable();
193 if (nullptr == ctable) {
194 return false;
195 }
196 const int count = ctable->count();
197 memcpy(ctableEntries, ctable->readColors(), count * sizeof(SkPMColor));
198 *ctableCount = count;
199 }
200 return true;
201 }
202
203 bool DecodingImageGenerator::onGetYUV8Planes(SkISize sizes[3], void* planes[3],
204 size_t rowBytes[3], SkYUVColorSpace * colorSpace) {
205 if (!fStream->rewind()) {
206 return false;
207 }
208
209 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream));
210 if (nullptr == decoder.get()) {
211 return false;
212 }
213
214 return decoder->decodeYUV8Planes(fStream, sizes, planes, rowBytes, colorSpac e);
215 }
216
217 // A contructor-type function that returns nullptr on failure. This
218 // prevents the returned SkImageGenerator from ever being in a bad
219 // state. Called by both Create() functions
220 SkImageGenerator* CreateDecodingImageGenerator(
221 SkData* data,
222 SkStreamRewindable* stream,
223 const SkDecodingImageGenerator::Options& opts) {
224 SkASSERT(stream);
225 SkAutoTDelete<SkStreamRewindable> autoStream(stream); // always delete this
226 SkAssertResult(autoStream->rewind());
227 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream));
228 if (nullptr == decoder.get()) {
229 return nullptr;
230 }
231 SkBitmap bitmap;
232 decoder->setSampleSize(opts.fSampleSize);
233 decoder->setRequireUnpremultipliedColors(opts.fRequireUnpremul);
234 if (!decoder->decode(stream, &bitmap, SkImageDecoder::kDecodeBounds_Mode)) {
235 return nullptr;
236 }
237 if (kUnknown_SkColorType == bitmap.colorType()) {
238 return nullptr;
239 }
240
241 SkImageInfo info = bitmap.info();
242
243 if (opts.fUseRequestedColorType && (opts.fRequestedColorType != info.colorTy pe())) {
244 if (!bitmap.canCopyTo(opts.fRequestedColorType)) {
245 SkASSERT(bitmap.colorType() != opts.fRequestedColorType);
246 return nullptr; // Can not translate to needed config.
247 }
248 info = info.makeColorType(opts.fRequestedColorType);
249 }
250
251 if (opts.fRequireUnpremul && info.alphaType() != kOpaque_SkAlphaType) {
252 info = info.makeAlphaType(kUnpremul_SkAlphaType);
253 }
254
255 SkAlphaType newAlphaType = info.alphaType();
256 if (!SkColorTypeValidateAlphaType(info.colorType(), info.alphaType(), &newAl phaType)) {
257 return nullptr;
258 }
259
260 return new DecodingImageGenerator(data, autoStream.detach(), info.makeAlphaT ype(newAlphaType),
261 opts.fSampleSize, opts.fDitherImage);
262 }
263
264 } // namespace
265
266 ////////////////////////////////////////////////////////////////////////////////
267
268 SkImageGenerator* SkDecodingImageGenerator::Create(
269 SkData* data,
270 const SkDecodingImageGenerator::Options& opts) {
271 SkASSERT(data != nullptr);
272 if (nullptr == data) {
273 return nullptr;
274 }
275 SkStreamRewindable* stream = new SkMemoryStream(data);
276 SkASSERT(stream != nullptr);
277 return CreateDecodingImageGenerator(data, stream, opts);
278 }
279
280 SkImageGenerator* SkDecodingImageGenerator::Create(
281 SkStreamRewindable* stream,
282 const SkDecodingImageGenerator::Options& opts) {
283 SkASSERT(stream != nullptr);
284 if (stream == nullptr) {
285 return nullptr;
286 }
287 return CreateDecodingImageGenerator(nullptr, stream, opts);
288 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698