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