OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkErrorInternals.h" | 9 #include "SkErrorInternals.h" |
10 #include "SkImage.h" | 10 #include "SkImage.h" |
11 #include "SkImageDeserializer.h" | |
11 #include "SkImageGenerator.h" | 12 #include "SkImageGenerator.h" |
12 #include "SkReadBuffer.h" | 13 #include "SkReadBuffer.h" |
13 #include "SkStream.h" | 14 #include "SkStream.h" |
14 #include "SkTypeface.h" | 15 #include "SkTypeface.h" |
15 | 16 |
17 namespace { | |
18 | |
19 // This generator intentionally should always fail on all attempts to get it s pixels, | |
20 // simulating a bad or empty codec stream. | |
21 class EmptyImageGenerator final : public SkImageGenerator { | |
22 public: | |
23 EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { } | |
24 | |
25 private: | |
26 typedef SkImageGenerator INHERITED; | |
27 }; | |
28 | |
29 static sk_sp<SkImage> MakeEmptyImage(int width, int height) { | |
30 return SkImage::MakeFromGenerator( | |
31 new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height))); | |
32 } | |
33 | |
34 } // anonymous namespace | |
35 | |
36 | |
16 static uint32_t default_flags() { | 37 static uint32_t default_flags() { |
17 uint32_t flags = 0; | 38 uint32_t flags = 0; |
18 flags |= SkReadBuffer::kScalarIsFloat_Flag; | 39 flags |= SkReadBuffer::kScalarIsFloat_Flag; |
19 if (8 == sizeof(void*)) { | 40 if (8 == sizeof(void*)) { |
20 flags |= SkReadBuffer::kPtrIs64Bit_Flag; | 41 flags |= SkReadBuffer::kPtrIs64Bit_Flag; |
21 } | 42 } |
22 return flags; | 43 return flags; |
23 } | 44 } |
24 | 45 |
25 SkReadBuffer::SkReadBuffer() { | 46 SkReadBuffer::SkReadBuffer() { |
26 fFlags = default_flags(); | 47 fFlags = default_flags(); |
27 fVersion = 0; | 48 fVersion = 0; |
28 fMemoryPtr = nullptr; | 49 fMemoryPtr = nullptr; |
29 | 50 |
30 fTFArray = nullptr; | 51 fTFArray = nullptr; |
31 fTFCount = 0; | 52 fTFCount = 0; |
32 | 53 |
33 fFactoryArray = nullptr; | 54 fFactoryArray = nullptr; |
34 fFactoryCount = 0; | 55 fFactoryCount = 0; |
35 fBitmapDecoder = nullptr; | 56 // fBitmapDecoder = nullptr; |
57 fImageDeserializer = nullptr; | |
36 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | 58 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
37 fDecodedBitmapIndex = -1; | 59 fDecodedBitmapIndex = -1; |
38 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | 60 #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
39 } | 61 } |
40 | 62 |
41 SkReadBuffer::SkReadBuffer(const void* data, size_t size) { | 63 SkReadBuffer::SkReadBuffer(const void* data, size_t size) { |
42 fFlags = default_flags(); | 64 fFlags = default_flags(); |
43 fVersion = 0; | 65 fVersion = 0; |
44 fReader.setMemory(data, size); | 66 fReader.setMemory(data, size); |
45 fMemoryPtr = nullptr; | 67 fMemoryPtr = nullptr; |
46 | 68 |
47 fTFArray = nullptr; | 69 fTFArray = nullptr; |
48 fTFCount = 0; | 70 fTFCount = 0; |
49 | 71 |
50 fFactoryArray = nullptr; | 72 fFactoryArray = nullptr; |
51 fFactoryCount = 0; | 73 fFactoryCount = 0; |
52 fBitmapDecoder = nullptr; | 74 // fBitmapDecoder = nullptr; |
75 fImageDeserializer = nullptr; | |
53 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | 76 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
54 fDecodedBitmapIndex = -1; | 77 fDecodedBitmapIndex = -1; |
55 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | 78 #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
56 } | 79 } |
57 | 80 |
58 SkReadBuffer::SkReadBuffer(SkStream* stream) { | 81 SkReadBuffer::SkReadBuffer(SkStream* stream) { |
59 fFlags = default_flags(); | 82 fFlags = default_flags(); |
60 fVersion = 0; | 83 fVersion = 0; |
61 const size_t length = stream->getLength(); | 84 const size_t length = stream->getLength(); |
62 fMemoryPtr = sk_malloc_throw(length); | 85 fMemoryPtr = sk_malloc_throw(length); |
63 stream->read(fMemoryPtr, length); | 86 stream->read(fMemoryPtr, length); |
64 fReader.setMemory(fMemoryPtr, length); | 87 fReader.setMemory(fMemoryPtr, length); |
65 | 88 |
66 fTFArray = nullptr; | 89 fTFArray = nullptr; |
67 fTFCount = 0; | 90 fTFCount = 0; |
68 | 91 |
69 fFactoryArray = nullptr; | 92 fFactoryArray = nullptr; |
70 fFactoryCount = 0; | 93 fFactoryCount = 0; |
71 fBitmapDecoder = nullptr; | 94 // fBitmapDecoder = nullptr; |
95 fImageDeserializer = nullptr; | |
72 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | 96 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
73 fDecodedBitmapIndex = -1; | 97 fDecodedBitmapIndex = -1; |
74 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | 98 #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
75 } | 99 } |
76 | 100 |
77 SkReadBuffer::~SkReadBuffer() { | 101 SkReadBuffer::~SkReadBuffer() { |
78 sk_free(fMemoryPtr); | 102 sk_free(fMemoryPtr); |
79 } | 103 } |
80 | 104 |
81 bool SkReadBuffer::readBool() { | 105 bool SkReadBuffer::readBool() { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
172 } | 196 } |
173 | 197 |
174 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) { | 198 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) { |
175 return readArray(values, size, sizeof(SkScalar)); | 199 return readArray(values, size, sizeof(SkScalar)); |
176 } | 200 } |
177 | 201 |
178 uint32_t SkReadBuffer::getArrayCount() { | 202 uint32_t SkReadBuffer::getArrayCount() { |
179 return *(uint32_t*)fReader.peek(); | 203 return *(uint32_t*)fReader.peek(); |
180 } | 204 } |
181 | 205 |
182 bool SkReadBuffer::readBitmap(SkBitmap* bitmap) { | 206 sk_sp<SkImage> SkReadBuffer::readBitmapAsImage() { |
183 const int width = this->readInt(); | 207 const int width = this->readInt(); |
184 const int height = this->readInt(); | 208 const int height = this->readInt(); |
185 | 209 |
186 // The writer stored a boolean value to determine whether an SkBitmapHeap wa s used during | 210 // The writer stored a boolean value to determine whether an SkBitmapHeap wa s used during |
187 // writing. That feature is deprecated. | 211 // writing. That feature is deprecated. |
188 if (this->readBool()) { | 212 if (this->readBool()) { |
189 this->readUInt(); // Bitmap index | 213 this->readUInt(); // Bitmap index |
190 this->readUInt(); // Bitmap generation ID | 214 this->readUInt(); // Bitmap generation ID |
191 SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBit map " | 215 SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBit map " |
192 "stored the SkBitmap in an SkBitmapHeap, but " | 216 "stored the SkBitmap in an SkBitmapHeap, but " |
193 "that feature is no longer supported."); | 217 "that feature is no longer supported."); |
194 } else { | 218 } else { |
195 // The writer stored false, meaning the SkBitmap was not stored in an Sk BitmapHeap. | 219 // The writer stored false, meaning the SkBitmap was not stored in an Sk BitmapHeap. |
196 const size_t length = this->readUInt(); | 220 const size_t length = this->readUInt(); |
197 if (length > 0) { | 221 if (length > 0) { |
198 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | 222 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
199 fDecodedBitmapIndex++; | 223 fDecodedBitmapIndex++; |
200 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | 224 #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
201 // A non-zero size means the SkBitmap was encoded. Read the data and pixel | 225 // A non-zero size means the SkBitmap was encoded. Read the data and pixel |
202 // offset. | 226 // offset. |
203 const void* data = this->skip(length); | 227 const void* data = this->skip(length); |
204 const int32_t xOffset = this->readInt(); | 228 const int32_t xOffset = this->readInt(); |
205 const int32_t yOffset = this->readInt(); | 229 const int32_t yOffset = this->readInt(); |
230 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height); | |
231 #if 0 | |
206 if (fBitmapDecoder != nullptr && fBitmapDecoder(data, length, bitmap )) { | 232 if (fBitmapDecoder != nullptr && fBitmapDecoder(data, length, bitmap )) { |
207 if (bitmap->width() == width && bitmap->height() == height) { | 233 if (bitmap->width() == width && bitmap->height() == height) { |
208 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT | 234 #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
209 if (0 != xOffset || 0 != yOffset) { | 235 if (0 != xOffset || 0 != yOffset) { |
210 SkDebugf("SkReadBuffer::readBitmap: heights match," | 236 SkDebugf("SkReadBuffer::readBitmap: heights match," |
211 " but offset is not zero. \nInfo about the bitm ap:" | 237 " but offset is not zero. \nInfo about the bitm ap:" |
212 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncode d" | 238 "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncode d" |
213 " data size: %d\n\tOffset: (%d, %d)\n", | 239 " data size: %d\n\tOffset: (%d, %d)\n", |
214 fDecodedBitmapIndex, width, height, length, xOf fset, | 240 fDecodedBitmapIndex, width, height, length, xOf fset, |
215 yOffset); | 241 yOffset); |
216 } | 242 } |
217 #endif // DEBUG_NON_DETERMINISTIC_ASSERT | 243 #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
218 // If the width and height match, there should be no offset. | 244 // If the width and height match, there should be no offset. |
219 SkASSERT(0 == xOffset && 0 == yOffset); | 245 SkASSERT(0 == xOffset && 0 == yOffset); |
220 return true; | 246 return true; |
221 } | 247 } |
222 | 248 |
223 // This case can only be reached if extractSubset was called, so | 249 // This case can only be reached if extractSubset was called, so |
224 // the recorded width and height must be smaller than or equal t o | 250 // the recorded width and height must be smaller than or equal t o |
225 // the encoded width and height. | 251 // the encoded width and height. |
226 // FIXME (scroggo): This assert assumes that our decoder and the | 252 // FIXME (scroggo): This assert assumes that our decoder and the |
227 // sources encoder agree on the width and height which may not | 253 // sources encoder agree on the width and height which may not |
228 // always be the case. Removing until it can be investigated | 254 // always be the case. Removing until it can be investigated |
229 // further. | 255 // further. |
230 //SkASSERT(width <= bitmap->width() && height <= bitmap->height( )); | 256 //SkASSERT(width <= bitmap->width() && height <= bitmap->height( )); |
231 | 257 |
232 SkBitmap subsetBm; | 258 SkBitmap subsetBm; |
233 SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, heig ht); | |
234 if (bitmap->extractSubset(&subsetBm, subset)) { | 259 if (bitmap->extractSubset(&subsetBm, subset)) { |
235 bitmap->swap(subsetBm); | 260 bitmap->swap(subsetBm); |
236 return true; | 261 return true; |
237 } | 262 } |
238 } | 263 } |
264 #else | |
265 if (fImageDeserializer) { | |
mtklein
2016/08/10 21:48:31
Might be nice to default this to a singleton defau
reed1
2016/08/10 23:43:19
Agreed. I had meant to mark that as a TODO. WIll i
| |
266 sk_sp<SkImage> image = | |
267 fImageDeserializer->deserialize(SkData::MakeWithCopy(data, l ength), &subset); | |
268 if (image) { | |
269 return image; | |
270 } | |
271 } | |
272 #endif | |
239 // This bitmap was encoded when written, but we are unable to decode , possibly due to | 273 // This bitmap was encoded when written, but we are unable to decode , possibly due to |
240 // not having a decoder. | 274 // not having a decoder. |
241 SkErrorInternals::SetError(kParseError_SkError, | 275 SkErrorInternals::SetError(kParseError_SkError, |
242 "Could not decode bitmap. Resulting bitma p will be empty."); | 276 "Could not decode bitmap. Resulting bitma p will be empty."); |
243 // Even though we weren't able to decode the pixels, the readbuffer should still be | 277 // Even though we weren't able to decode the pixels, the readbuffer should still be |
244 // intact, so we return true with an empty bitmap, so we don't force an abort of the | 278 // intact, so we return true with an empty bitmap, so we don't force an abort of the |
245 // larger deserialize. | 279 // larger deserialize. |
246 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height)); | 280 return MakeEmptyImage(width, height); |
247 return true; | 281 } else { |
248 } else if (SkBitmap::ReadRawPixels(this, bitmap)) { | 282 SkBitmap bitmap; |
249 return true; | 283 if (SkBitmap::ReadRawPixels(this, &bitmap)) { |
284 bitmap.setImmutable(); | |
285 return SkImage::MakeFromBitmap(bitmap); | |
286 } | |
250 } | 287 } |
251 } | 288 } |
252 // Could not read the SkBitmap. Use a placeholder bitmap. | 289 // Could not read the SkBitmap. Use a placeholder bitmap. |
253 bitmap->setInfo(SkImageInfo::MakeUnknown(width, height)); | 290 return nullptr; |
254 return false; | |
255 } | 291 } |
256 | 292 |
257 namespace { | 293 sk_sp<SkImage> SkReadBuffer::readImage() { |
258 | |
259 // This generator intentionally should always fail on all attempts to get its pi xels, | |
260 // simulating a bad or empty codec stream. | |
261 class EmptyImageGenerator final : public SkImageGenerator { | |
262 public: | |
263 EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { } | |
264 | |
265 private: | |
266 typedef SkImageGenerator INHERITED; | |
267 }; | |
268 | |
269 } // anonymous namespace | |
270 | |
271 SkImage* SkReadBuffer::readImage() { | |
272 int width = this->read32(); | 294 int width = this->read32(); |
273 int height = this->read32(); | 295 int height = this->read32(); |
274 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension | 296 if (width <= 0 || height <= 0) { // SkImage never has a zero dimension |
275 this->validate(false); | 297 this->validate(false); |
276 return nullptr; | 298 return nullptr; |
277 } | 299 } |
278 | 300 |
279 auto placeholder = [=] { | |
280 return SkImage::MakeFromGenerator( | |
281 new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height))). release(); | |
282 }; | |
283 | |
284 uint32_t encoded_size = this->getArrayCount(); | 301 uint32_t encoded_size = this->getArrayCount(); |
285 if (encoded_size == 0) { | 302 if (encoded_size == 0) { |
286 // The image could not be encoded at serialization time - return an empt y placeholder. | 303 // The image could not be encoded at serialization time - return an empt y placeholder. |
287 (void)this->readUInt(); // Swallow that encoded_size == 0 sentinel. | 304 (void)this->readUInt(); // Swallow that encoded_size == 0 sentinel. |
288 return placeholder(); | 305 return MakeEmptyImage(width, height); |
289 } | 306 } |
290 if (encoded_size == 1) { | 307 if (encoded_size == 1) { |
291 // We had to encode the image as raw pixels via SkBitmap. | 308 // We had to encode the image as raw pixels via SkBitmap. |
292 (void)this->readUInt(); // Swallow that encoded_size == 1 sentinel. | 309 (void)this->readUInt(); // Swallow that encoded_size == 1 sentinel. |
293 SkBitmap bm; | 310 SkBitmap bm; |
294 if (SkBitmap::ReadRawPixels(this, &bm)) { | 311 if (SkBitmap::ReadRawPixels(this, &bm)) { |
295 return SkImage::MakeFromBitmap(bm).release(); | 312 return SkImage::MakeFromBitmap(bm); |
296 } | 313 } |
297 return placeholder(); | 314 return MakeEmptyImage(width, height); |
298 } | 315 } |
299 | 316 |
300 // The SkImage encoded itself. | 317 // The SkImage encoded itself. |
301 sk_sp<SkData> encoded(this->readByteArrayAsData()); | 318 sk_sp<SkData> encoded(this->readByteArrayAsData()); |
302 | 319 |
303 int originX = this->read32(); | 320 int originX = this->read32(); |
304 int originY = this->read32(); | 321 int originY = this->read32(); |
305 if (originX < 0 || originY < 0) { | 322 if (originX < 0 || originY < 0) { |
306 this->validate(false); | 323 this->validate(false); |
307 return nullptr; | 324 return nullptr; |
308 } | 325 } |
309 | 326 |
310 const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); | 327 const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); |
311 SkImage* image = SkImage::MakeFromEncoded(std::move(encoded), &subset).relea se(); | 328 |
312 if (image) { | 329 sk_sp<SkImage> image; |
313 return image; | 330 if (fImageDeserializer) { |
331 image = fImageDeserializer->deserialize(std::move(encoded), &subset); | |
332 } else { | |
333 image = SkImage::MakeFromEncoded(std::move(encoded), &subset); | |
314 } | 334 } |
315 | 335 return image ? image : MakeEmptyImage(width, height); |
316 return SkImage::MakeFromGenerator( | |
317 new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height))). release(); | |
318 } | 336 } |
319 | 337 |
320 SkTypeface* SkReadBuffer::readTypeface() { | 338 SkTypeface* SkReadBuffer::readTypeface() { |
321 | 339 |
322 uint32_t index = fReader.readU32(); | 340 uint32_t index = fReader.readU32(); |
323 if (0 == index || index > (unsigned)fTFCount) { | 341 if (0 == index || index > (unsigned)fTFCount) { |
324 return nullptr; | 342 return nullptr; |
325 } else { | 343 } else { |
326 SkASSERT(fTFArray); | 344 SkASSERT(fTFArray); |
327 return fTFArray[index - 1]; | 345 return fTFArray[index - 1]; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 if (sizeRecorded != sizeRead) { | 406 if (sizeRecorded != sizeRead) { |
389 this->validate(false); | 407 this->validate(false); |
390 return nullptr; | 408 return nullptr; |
391 } | 409 } |
392 } else { | 410 } else { |
393 // we must skip the remaining data | 411 // we must skip the remaining data |
394 fReader.skip(sizeRecorded); | 412 fReader.skip(sizeRecorded); |
395 } | 413 } |
396 return obj.release(); | 414 return obj.release(); |
397 } | 415 } |
OLD | NEW |