2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "include/core/SkBitmap.h"
9 #include "include/core/SkData.h"
10 #include "include/core/SkImage.h"
11 #include "include/core/SkImageGenerator.h"
12 #include "include/core/SkStream.h"
13 #include "include/core/SkTypeface.h"
14 #include "src/core/SkAutoMalloc.h"
15 #include "src/core/SkMathPriv.h"
16 #include "src/core/SkMatrixPriv.h"
17 #include "src/core/SkMipmapBuilder.h"
18 #include "src/core/SkReadBuffer.h"
19 #include "src/core/SkSafeMath.h"
22 // This generator intentionally should always fail on all attempts to get its pixels,
23 // simulating a bad or empty codec stream.
24 class EmptyImageGenerator final : public SkImageGenerator {
26 EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
29 using INHERITED = SkImageGenerator;
32 static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
33 return SkImage::MakeFromGenerator(
34 std::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height)));
37 } // anonymous namespace
39 void SkReadBuffer::setMemory(const void* data, size_t size) {
40 this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
42 fBase = fCurr = (const char*)data;
47 void SkReadBuffer::setInvalid() {
49 // When an error is found, send the read cursor to the end of the stream
55 const void* SkReadBuffer::skip(size_t size) {
56 size_t inc = SkAlign4(size);
57 this->validate(inc >= size);
58 const void* addr = fCurr;
59 this->validate(IsPtrAlign4(addr) && this->isAvailable(inc));
68 const void* SkReadBuffer::skip(size_t count, size_t size) {
69 return this->skip(SkSafeMath::Mul(count, size));
72 void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) {
76 bool SkReadBuffer::readBool() {
77 uint32_t value = this->readUInt();
78 // Boolean value should be either 0 or 1
79 this->validate(!(value & ~1));
83 SkColor SkReadBuffer::readColor() {
84 return this->readUInt();
87 int32_t SkReadBuffer::readInt() {
88 const size_t inc = sizeof(int32_t);
89 if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
92 int32_t value = *((const int32_t*)fCurr);
97 SkScalar SkReadBuffer::readScalar() {
98 const size_t inc = sizeof(SkScalar);
99 if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
102 SkScalar value = *((const SkScalar*)fCurr);
107 uint32_t SkReadBuffer::readUInt() {
108 return this->readInt();
111 int32_t SkReadBuffer::read32() {
112 return this->readInt();
115 uint8_t SkReadBuffer::peekByte() {
116 if (this->available() <= 0) {
120 return *((uint8_t*)fCurr);
123 bool SkReadBuffer::readPad32(void* buffer, size_t bytes) {
124 if (const void* src = this->skip(bytes)) {
125 // buffer might be null if bytes is zero (see SkAutoMalloc), hence we call
126 // the careful version of memcpy.
127 sk_careful_memcpy(buffer, src, bytes);
133 const char* SkReadBuffer::readString(size_t* len) {
134 *len = this->readUInt();
136 // The string is len characters and a terminating \0.
137 const char* c_str = this->skipT<char>(*len+1);
139 if (this->validate(c_str && c_str[*len] == '\0')) {
145 void SkReadBuffer::readString(SkString* string) {
147 if (const char* c_str = this->readString(&len)) {
148 string->set(c_str, len);
154 void SkReadBuffer::readColor4f(SkColor4f* color) {
155 if (!this->readPad32(color, sizeof(SkColor4f))) {
156 *color = {0, 0, 0, 0};
160 void SkReadBuffer::readPoint(SkPoint* point) {
161 point->fX = this->readScalar();
162 point->fY = this->readScalar();
165 void SkReadBuffer::readPoint3(SkPoint3* point) {
166 this->readPad32(point, sizeof(SkPoint3));
169 void SkReadBuffer::read(SkM44* matrix) {
170 if (this->isValid()) {
171 if (const float* m = (const float*)this->skip(sizeof(float) * 16)) {
172 *matrix = SkM44::ColMajor(m);
175 if (!this->isValid()) {
180 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
182 if (this->isValid()) {
183 size = SkMatrixPriv::ReadFromMemory(matrix, fCurr, this->available());
184 (void)this->validate((SkAlign4(size) == size) && (0 != size));
186 if (!this->isValid()) {
189 (void)this->skip(size);
192 void SkReadBuffer::readIRect(SkIRect* rect) {
193 if (!this->readPad32(rect, sizeof(SkIRect))) {
198 void SkReadBuffer::readRect(SkRect* rect) {
199 if (!this->readPad32(rect, sizeof(SkRect))) {
204 SkRect SkReadBuffer::readRect() {
206 if (!this->readPad32(&r, sizeof(SkRect))) {
212 SkSamplingOptions SkReadBuffer::readSampling() {
213 if (!this->isVersionLT(SkPicturePriv::kAnisotropicFilter)) {
214 int maxAniso = this->readInt();
216 return SkSamplingOptions::Aniso(maxAniso);
219 if (this->readBool()) {
220 float B = this->readScalar();
221 float C = this->readScalar();
222 return SkSamplingOptions({B, C});
224 SkFilterMode filter = this->read32LE(SkFilterMode::kLinear);
225 SkMipmapMode mipmap = this->read32LE(SkMipmapMode::kLinear);
226 return SkSamplingOptions(filter, mipmap);
230 void SkReadBuffer::readRRect(SkRRect* rrect) {
233 size = rrect->readFromMemory(fCurr, this->available());
234 if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
238 (void)this->skip(size);
241 void SkReadBuffer::readRegion(SkRegion* region) {
244 size = region->readFromMemory(fCurr, this->available());
245 if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
249 (void)this->skip(size);
252 void SkReadBuffer::readPath(SkPath* path) {
255 size = path->readFromMemory(fCurr, this->available());
256 if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
260 (void)this->skip(size);
263 bool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) {
264 const uint32_t count = this->readUInt();
265 return this->validate(size == count) &&
266 this->readPad32(value, SkSafeMath::Mul(size, elementSize));
269 bool SkReadBuffer::readByteArray(void* value, size_t size) {
270 return this->readArray(value, size, sizeof(uint8_t));
273 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
274 return this->readArray(colors, size, sizeof(SkColor));
277 bool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
278 return this->readArray(colors, size, sizeof(SkColor4f));
281 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
282 return this->readArray(values, size, sizeof(int32_t));
285 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
286 return this->readArray(points, size, sizeof(SkPoint));
289 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
290 return this->readArray(values, size, sizeof(SkScalar));
293 const void* SkReadBuffer::skipByteArray(size_t* size) {
294 const uint32_t count = this->readUInt();
295 const void* buf = this->skip(count);
297 *size = this->isValid() ? count : 0;
302 sk_sp<SkData> SkReadBuffer::readByteArrayAsData() {
303 size_t numBytes = this->getArrayCount();
304 if (!this->validate(this->isAvailable(numBytes))) {
308 SkAutoMalloc buffer(numBytes);
309 if (!this->readByteArray(buffer.get(), numBytes)) {
312 return SkData::MakeFromMalloc(buffer.release(), numBytes);
315 uint32_t SkReadBuffer::getArrayCount() {
316 const size_t inc = sizeof(uint32_t);
317 if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
320 return *((uint32_t*)fCurr);
323 #include "src/core/SkMipmap.h"
325 // If we see a corrupt stream, we return null (fail). If we just fail trying to decode
326 // the image, we don't fail, but return a 1x1 empty image.
327 sk_sp<SkImage> SkReadBuffer::readImage() {
328 uint32_t flags = this->read32();
330 sk_sp<SkImage> image;
332 sk_sp<SkData> data = this->readByteArrayAsData();
334 this->validate(false);
337 if (fProcs.fImageProc) {
338 image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
341 std::optional<SkAlphaType> alphaType = std::nullopt;
342 if (flags & SkWriteBufferImageFlags::kUnpremul) {
343 alphaType = kUnpremul_SkAlphaType;
345 image = SkImage::MakeFromEncoded(std::move(data), alphaType);
349 if (flags & SkWriteBufferImageFlags::kHasSubsetRect) {
351 this->readIRect(&subset);
353 image = image->makeSubset(subset);
357 if (flags & SkWriteBufferImageFlags::kHasMipmap) {
358 sk_sp<SkData> data = this->readByteArrayAsData();
360 this->validate(false);
364 SkMipmapBuilder builder(image->imageInfo());
365 if (SkMipmap::Deserialize(&builder, data->data(), data->size())) {
366 // TODO: need to make lazy images support mips
367 if (auto ri = image->makeRasterImage()) {
370 image = builder.attachTo(image);
371 SkASSERT(image); // withMipmaps should never return null
375 return image ? image : MakeEmptyImage(1, 1);
378 sk_sp<SkTypeface> SkReadBuffer::readTypeface() {
379 // Read 32 bits (signed)
380 // 0 -- return null (default font)
382 // <0 -- custom (serial procs) : negative size in bytes
384 int32_t index = this->read32();
387 } else if (index > 0) {
388 if (!this->validate(index <= fTFCount)) {
391 return fTFArray[index - 1];
393 size_t size = sk_negate_to_size_t(index);
394 const void* data = this->skip(size);
395 if (!this->validate(data != nullptr && fProcs.fTypefaceProc)) {
398 return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
402 SkFlattenable* SkReadBuffer::readRawFlattenable() {
403 SkFlattenable::Factory factory = nullptr;
405 if (fFactoryCount > 0) {
406 int32_t index = this->read32();
407 if (0 == index || !this->isValid()) {
408 return nullptr; // writer failed to give us the flattenable
411 this->validate(false);
414 index -= 1; // we stored the index-base-1
415 if ((unsigned)index >= (unsigned)fFactoryCount) {
416 this->validate(false);
419 factory = fFactoryArray[index];
421 if (this->peekByte() != 0) {
422 // If the first byte is non-zero, the flattenable is specified by a string.
423 size_t ignored_length;
424 if (const char* name = this->readString(&ignored_length)) {
425 factory = SkFlattenable::NameToFactory(name);
426 fFlattenableDict.set(fFlattenableDict.count() + 1, factory);
429 // Read the index. We are guaranteed that the first byte
430 // is zeroed, so we must shift down a byte.
431 uint32_t index = this->readUInt() >> 8;
433 return nullptr; // writer failed to give us the flattenable
436 if (SkFlattenable::Factory* found = fFlattenableDict.find(index)) {
441 if (!this->validate(factory != nullptr)) {
446 // if we get here, factory may still be null, but if that is the case, the
447 // failure was ours, not the writer.
448 sk_sp<SkFlattenable> obj;
449 uint32_t sizeRecorded = this->read32();
451 size_t offset = this->offset();
452 obj = (*factory)(*this);
453 // check that we read the amount we expected
454 size_t sizeRead = this->offset() - offset;
455 if (sizeRecorded != sizeRead) {
456 this->validate(false);
460 // we must skip the remaining data
461 this->skip(sizeRecorded);
463 if (!this->isValid()) {
466 return obj.release();
469 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
470 SkFlattenable* obj = this->readRawFlattenable();
471 if (obj && obj->getFlattenableType() != ft) {
472 this->validate(false);
479 ///////////////////////////////////////////////////////////////////////////////////////////////////
481 int32_t SkReadBuffer::checkInt(int32_t min, int32_t max) {
482 SkASSERT(min <= max);
483 int32_t value = this->read32();
484 if (value < min || value > max) {
485 this->validate(false);
491 SkLegacyFQ SkReadBuffer::checkFilterQuality() {
492 return this->checkRange<SkLegacyFQ>(kNone_SkLegacyFQ, kLast_SkLegacyFQ);