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

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

Issue 647023006: Qualify the return value of SkImageDecoder::decode (Closed) Base URL: https://skia.googlesource.com/skia.git/+/master
Patch Set: fix a sample Created 6 years, 2 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
« no previous file with comments | « src/images/SkImageDecoder_astc.cpp ('k') | src/images/SkImageDecoder_libbmp.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 2014 Google Inc. 2 * Copyright 2014 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 "SkColorPriv.h" 8 #include "SkColorPriv.h"
9 #include "SkImageDecoder.h" 9 #include "SkImageDecoder.h"
10 #include "SkPixelRef.h" 10 #include "SkPixelRef.h"
(...skipping 23 matching lines...) Expand all
34 34
35 class SkKTXImageDecoder : public SkImageDecoder { 35 class SkKTXImageDecoder : public SkImageDecoder {
36 public: 36 public:
37 SkKTXImageDecoder() { } 37 SkKTXImageDecoder() { }
38 38
39 virtual Format getFormat() const SK_OVERRIDE { 39 virtual Format getFormat() const SK_OVERRIDE {
40 return kKTX_Format; 40 return kKTX_Format;
41 } 41 }
42 42
43 protected: 43 protected:
44 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; 44 virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE;
45 45
46 private: 46 private:
47 typedef SkImageDecoder INHERITED; 47 typedef SkImageDecoder INHERITED;
48 }; 48 };
49 49
50 bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { 50 SkImageDecoder::Result SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* b m, Mode mode) {
51 // TODO: Implement SkStream::copyToData() that's cheap for memory and file s treams 51 // TODO: Implement SkStream::copyToData() that's cheap for memory and file s treams
52 SkAutoDataUnref data(SkCopyStreamToData(stream)); 52 SkAutoDataUnref data(SkCopyStreamToData(stream));
53 if (NULL == data) { 53 if (NULL == data) {
54 return false; 54 return kFailure;
55 } 55 }
56 56
57 SkKTXFile ktxFile(data); 57 SkKTXFile ktxFile(data);
58 if (!ktxFile.valid()) { 58 if (!ktxFile.valid()) {
59 return false; 59 return kFailure;
60 } 60 }
61 61
62 const unsigned short width = ktxFile.width(); 62 const unsigned short width = ktxFile.width();
63 const unsigned short height = ktxFile.height(); 63 const unsigned short height = ktxFile.height();
64 64
65 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER 65 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
66 // should we allow the Chooser (if present) to pick a config for us??? 66 // should we allow the Chooser (if present) to pick a config for us???
67 if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) { 67 if (!this->chooseFromOneChoice(kN32_SkColorType, width, height)) {
68 return false; 68 return kFailure;
69 } 69 }
70 #endif 70 #endif
71 71
72 // Set a flag if our source is premultiplied alpha 72 // Set a flag if our source is premultiplied alpha
73 const SkString premulKey("KTXPremultipliedAlpha"); 73 const SkString premulKey("KTXPremultipliedAlpha");
74 const bool bSrcIsPremul = ktxFile.getValueForKey(premulKey) == SkString("Tru e"); 74 const bool bSrcIsPremul = ktxFile.getValueForKey(premulKey) == SkString("Tru e");
75 75
76 // Setup the sampler... 76 // Setup the sampler...
77 SkScaledBitmapSampler sampler(width, height, this->getSampleSize()); 77 SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
78 78
79 // Determine the alpha of the bitmap... 79 // Determine the alpha of the bitmap...
80 SkAlphaType alphaType = kOpaque_SkAlphaType; 80 SkAlphaType alphaType = kOpaque_SkAlphaType;
81 if (ktxFile.isRGBA8()) { 81 if (ktxFile.isRGBA8()) {
82 if (this->getRequireUnpremultipliedColors()) { 82 if (this->getRequireUnpremultipliedColors()) {
83 alphaType = kUnpremul_SkAlphaType; 83 alphaType = kUnpremul_SkAlphaType;
84 // If the client wants unpremul colors and we only have 84 // If the client wants unpremul colors and we only have
85 // premul, then we cannot honor their wish. 85 // premul, then we cannot honor their wish.
86 if (bSrcIsPremul) { 86 if (bSrcIsPremul) {
87 return false; 87 return kFailure;
88 } 88 }
89 } else { 89 } else {
90 alphaType = kPremul_SkAlphaType; 90 alphaType = kPremul_SkAlphaType;
91 } 91 }
92 } 92 }
93 93
94 // Search through the compressed formats to see if the KTX file is holding 94 // Search through the compressed formats to see if the KTX file is holding
95 // compressed data 95 // compressed data
96 bool ktxIsCompressed = false; 96 bool ktxIsCompressed = false;
97 SkTextureCompressor::Format ktxCompressedFormat; 97 SkTextureCompressor::Format ktxCompressedFormat;
(...skipping 16 matching lines...) Expand all
114 const int w = sampler.scaledWidth(); 114 const int w = sampler.scaledWidth();
115 const int h = sampler.scaledHeight(); 115 const int h = sampler.scaledHeight();
116 bm->setInfo(SkImageInfo::MakeA8(w, h)); 116 bm->setInfo(SkImageInfo::MakeA8(w, h));
117 } else { 117 } else {
118 const int w = sampler.scaledWidth(); 118 const int w = sampler.scaledWidth();
119 const int h = sampler.scaledHeight(); 119 const int h = sampler.scaledHeight();
120 bm->setInfo(SkImageInfo::MakeN32(w, h, alphaType)); 120 bm->setInfo(SkImageInfo::MakeN32(w, h, alphaType));
121 } 121 }
122 122
123 if (SkImageDecoder::kDecodeBounds_Mode == mode) { 123 if (SkImageDecoder::kDecodeBounds_Mode == mode) {
124 return true; 124 return kSuccess;
125 } 125 }
126 126
127 // If we've made it this far, then we know how to grok the data. 127 // If we've made it this far, then we know how to grok the data.
128 if (!this->allocPixelRef(bm, NULL)) { 128 if (!this->allocPixelRef(bm, NULL)) {
129 return false; 129 return kFailure;
130 } 130 }
131 131
132 // Lock the pixels, since we're about to write to them... 132 // Lock the pixels, since we're about to write to them...
133 SkAutoLockPixels alp(*bm); 133 SkAutoLockPixels alp(*bm);
134 134
135 if (isCompressedAlpha) { 135 if (isCompressedAlpha) {
136 if (!sampler.begin(bm, SkScaledBitmapSampler::kGray, *this)) { 136 if (!sampler.begin(bm, SkScaledBitmapSampler::kGray, *this)) {
137 return false; 137 return kFailure;
138 } 138 }
139 139
140 // Alpha data is only a single byte per pixel. 140 // Alpha data is only a single byte per pixel.
141 int nPixels = width * height; 141 int nPixels = width * height;
142 SkAutoMalloc outRGBData(nPixels); 142 SkAutoMalloc outRGBData(nPixels);
143 uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get()); 143 uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
144 144
145 // Decode the compressed format 145 // Decode the compressed format
146 const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData ()); 146 const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData ());
147 if (!SkTextureCompressor::DecompressBufferFromFormat( 147 if (!SkTextureCompressor::DecompressBufferFromFormat(
148 outRGBDataPtr, width, buf, width, height, ktxCompressedFormat)) { 148 outRGBDataPtr, width, buf, width, height, ktxCompressedFormat)) {
149 return false; 149 return kFailure;
150 } 150 }
151 151
152 // Set each of the pixels... 152 // Set each of the pixels...
153 const int srcRowBytes = width; 153 const int srcRowBytes = width;
154 const int dstHeight = sampler.scaledHeight(); 154 const int dstHeight = sampler.scaledHeight();
155 const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr); 155 const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr);
156 srcRow += sampler.srcY0() * srcRowBytes; 156 srcRow += sampler.srcY0() * srcRowBytes;
157 for (int y = 0; y < dstHeight; ++y) { 157 for (int y = 0; y < dstHeight; ++y) {
158 sampler.next(srcRow); 158 sampler.next(srcRow);
159 srcRow += sampler.srcDY() * srcRowBytes; 159 srcRow += sampler.srcDY() * srcRowBytes;
160 } 160 }
161 161
162 return true; 162 return kSuccess;
163 163
164 } else if (ktxFile.isCompressedFormat(SkTextureCompressor::kETC1_Format)) { 164 } else if (ktxFile.isCompressedFormat(SkTextureCompressor::kETC1_Format)) {
165 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { 165 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
166 return false; 166 return kFailure;
167 } 167 }
168 168
169 // ETC1 Data is encoded as RGB pixels, so we should extract it as such 169 // ETC1 Data is encoded as RGB pixels, so we should extract it as such
170 int nPixels = width * height; 170 int nPixels = width * height;
171 SkAutoMalloc outRGBData(nPixels * 3); 171 SkAutoMalloc outRGBData(nPixels * 3);
172 uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get()); 172 uint8_t *outRGBDataPtr = reinterpret_cast<uint8_t *>(outRGBData.get());
173 173
174 // Decode ETC1 174 // Decode ETC1
175 const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData ()); 175 const uint8_t *buf = reinterpret_cast<const uint8_t *>(ktxFile.pixelData ());
176 if (!SkTextureCompressor::DecompressBufferFromFormat( 176 if (!SkTextureCompressor::DecompressBufferFromFormat(
177 outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor: :kETC1_Format)) { 177 outRGBDataPtr, width*3, buf, width, height, SkTextureCompressor: :kETC1_Format)) {
178 return false; 178 return kFailure;
179 } 179 }
180 180
181 // Set each of the pixels... 181 // Set each of the pixels...
182 const int srcRowBytes = width * 3; 182 const int srcRowBytes = width * 3;
183 const int dstHeight = sampler.scaledHeight(); 183 const int dstHeight = sampler.scaledHeight();
184 const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr); 184 const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr);
185 srcRow += sampler.srcY0() * srcRowBytes; 185 srcRow += sampler.srcY0() * srcRowBytes;
186 for (int y = 0; y < dstHeight; ++y) { 186 for (int y = 0; y < dstHeight; ++y) {
187 sampler.next(srcRow); 187 sampler.next(srcRow);
188 srcRow += sampler.srcDY() * srcRowBytes; 188 srcRow += sampler.srcDY() * srcRowBytes;
189 } 189 }
190 190
191 return true; 191 return kSuccess;
192 192
193 } else if (ktxFile.isRGB8()) { 193 } else if (ktxFile.isRGB8()) {
194 194
195 // Uncompressed RGB data (without alpha) 195 // Uncompressed RGB data (without alpha)
196 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { 196 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
197 return false; 197 return kFailure;
198 } 198 }
199 199
200 // Just need to read RGB pixels 200 // Just need to read RGB pixels
201 const int srcRowBytes = width * 3; 201 const int srcRowBytes = width * 3;
202 const int dstHeight = sampler.scaledHeight(); 202 const int dstHeight = sampler.scaledHeight();
203 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelD ata()); 203 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelD ata());
204 srcRow += sampler.srcY0() * srcRowBytes; 204 srcRow += sampler.srcY0() * srcRowBytes;
205 for (int y = 0; y < dstHeight; ++y) { 205 for (int y = 0; y < dstHeight; ++y) {
206 sampler.next(srcRow); 206 sampler.next(srcRow);
207 srcRow += sampler.srcDY() * srcRowBytes; 207 srcRow += sampler.srcDY() * srcRowBytes;
208 } 208 }
209 209
210 return true; 210 return kSuccess;
211 211
212 } else if (ktxFile.isRGBA8()) { 212 } else if (ktxFile.isRGBA8()) {
213 213
214 // Uncompressed RGBA data 214 // Uncompressed RGBA data
215 215
216 // If we know that the image contains premultiplied alpha, then 216 // If we know that the image contains premultiplied alpha, then
217 // we need to turn off the premultiplier 217 // we need to turn off the premultiplier
218 SkScaledBitmapSampler::Options opts (*this); 218 SkScaledBitmapSampler::Options opts (*this);
219 if (bSrcIsPremul) { 219 if (bSrcIsPremul) {
220 SkASSERT(bm->alphaType() == kPremul_SkAlphaType); 220 SkASSERT(bm->alphaType() == kPremul_SkAlphaType);
221 SkASSERT(!this->getRequireUnpremultipliedColors()); 221 SkASSERT(!this->getRequireUnpremultipliedColors());
222 222
223 opts.fPremultiplyAlpha = false; 223 opts.fPremultiplyAlpha = false;
224 } 224 }
225 225
226 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, opts)) { 226 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, opts)) {
227 return false; 227 return kFailure;
228 } 228 }
229 229
230 // Just need to read RGBA pixels 230 // Just need to read RGBA pixels
231 const int srcRowBytes = width * 4; 231 const int srcRowBytes = width * 4;
232 const int dstHeight = sampler.scaledHeight(); 232 const int dstHeight = sampler.scaledHeight();
233 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelD ata()); 233 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelD ata());
234 srcRow += sampler.srcY0() * srcRowBytes; 234 srcRow += sampler.srcY0() * srcRowBytes;
235 for (int y = 0; y < dstHeight; ++y) { 235 for (int y = 0; y < dstHeight; ++y) {
236 sampler.next(srcRow); 236 sampler.next(srcRow);
237 srcRow += sampler.srcDY() * srcRowBytes; 237 srcRow += sampler.srcDY() * srcRowBytes;
238 } 238 }
239 239
240 return true; 240 return kSuccess;
241 } 241 }
242 242
243 return false; 243 return kFailure;
244 } 244 }
245 245
246 /////////////////////////////////////////////////////////////////////////////// 246 ///////////////////////////////////////////////////////////////////////////////
247 247
248 // KTX Image Encoder 248 // KTX Image Encoder
249 // 249 //
250 // This encoder takes a best guess at how to encode the bitmap passed to it. If 250 // This encoder takes a best guess at how to encode the bitmap passed to it. If
251 // there is an installed discardable pixel ref with existing PKM data, then we 251 // there is an installed discardable pixel ref with existing PKM data, then we
252 // will repurpose the existing ETC1 data into a KTX file. If the data contains 252 // will repurpose the existing ETC1 data into a KTX file. If the data contains
253 // KTX data, then we simply return a copy of the same data. For all other files, 253 // KTX data, then we simply return a copy of the same data. For all other files,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 return SkImageDecoder::kUnknown_Format; 328 return SkImageDecoder::kUnknown_Format;
329 } 329 }
330 330
331 SkImageEncoder* sk_libktx_efactory(SkImageEncoder::Type t) { 331 SkImageEncoder* sk_libktx_efactory(SkImageEncoder::Type t) {
332 return (SkImageEncoder::kKTX_Type == t) ? SkNEW(SkKTXImageEncoder) : NULL; 332 return (SkImageEncoder::kKTX_Type == t) ? SkNEW(SkKTXImageEncoder) : NULL;
333 } 333 }
334 334
335 static SkImageDecoder_DecodeReg gReg(sk_libktx_dfactory); 335 static SkImageDecoder_DecodeReg gReg(sk_libktx_dfactory);
336 static SkImageDecoder_FormatReg gFormatReg(get_format_ktx); 336 static SkImageDecoder_FormatReg gFormatReg(get_format_ktx);
337 static SkImageEncoder_EncodeReg gEReg(sk_libktx_efactory); 337 static SkImageEncoder_EncodeReg gEReg(sk_libktx_efactory);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_astc.cpp ('k') | src/images/SkImageDecoder_libbmp.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698