Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / core / SkReadBuffer.cpp
1 /*
2  * Copyright 2012 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 "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"
20
21 namespace {
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 {
25     public:
26         EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
27
28     private:
29         using INHERITED = SkImageGenerator;
30     };
31
32     static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
33         return SkImage::MakeFromGenerator(
34               std::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height)));
35     }
36
37 } // anonymous namespace
38
39 void SkReadBuffer::setMemory(const void* data, size_t size) {
40     this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size));
41     if (!fError) {
42         fBase = fCurr = (const char*)data;
43         fStop = fBase + size;
44     }
45 }
46
47 void SkReadBuffer::setInvalid() {
48     if (!fError) {
49         // When an error is found, send the read cursor to the end of the stream
50         fCurr = fStop;
51         fError = true;
52     }
53 }
54
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));
60     if (fError) {
61         return nullptr;
62     }
63
64     fCurr += inc;
65     return addr;
66 }
67
68 const void* SkReadBuffer::skip(size_t count, size_t size) {
69     return this->skip(SkSafeMath::Mul(count, size));
70 }
71
72 void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) {
73     fProcs = procs;
74 }
75
76 bool SkReadBuffer::readBool() {
77     uint32_t value = this->readUInt();
78     // Boolean value should be either 0 or 1
79     this->validate(!(value & ~1));
80     return value != 0;
81 }
82
83 SkColor SkReadBuffer::readColor() {
84     return this->readUInt();
85 }
86
87 int32_t SkReadBuffer::readInt() {
88     const size_t inc = sizeof(int32_t);
89     if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
90         return 0;
91     }
92     int32_t value = *((const int32_t*)fCurr);
93     fCurr += inc;
94     return value;
95 }
96
97 SkScalar SkReadBuffer::readScalar() {
98     const size_t inc = sizeof(SkScalar);
99     if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
100         return 0;
101     }
102     SkScalar value = *((const SkScalar*)fCurr);
103     fCurr += inc;
104     return value;
105 }
106
107 uint32_t SkReadBuffer::readUInt() {
108     return this->readInt();
109 }
110
111 int32_t SkReadBuffer::read32() {
112     return this->readInt();
113 }
114
115 uint8_t SkReadBuffer::peekByte() {
116     if (this->available() <= 0) {
117         fError = true;
118         return 0;
119     }
120     return *((uint8_t*)fCurr);
121 }
122
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);
128         return true;
129     }
130     return false;
131 }
132
133 const char* SkReadBuffer::readString(size_t* len) {
134     *len = this->readUInt();
135
136     // The string is len characters and a terminating \0.
137     const char* c_str = this->skipT<char>(*len+1);
138
139     if (this->validate(c_str && c_str[*len] == '\0')) {
140         return c_str;
141     }
142     return nullptr;
143 }
144
145 void SkReadBuffer::readString(SkString* string) {
146     size_t len;
147     if (const char* c_str = this->readString(&len)) {
148         string->set(c_str, len);
149         return;
150     }
151     string->reset();
152 }
153
154 void SkReadBuffer::readColor4f(SkColor4f* color) {
155     if (!this->readPad32(color, sizeof(SkColor4f))) {
156         *color = {0, 0, 0, 0};
157     }
158 }
159
160 void SkReadBuffer::readPoint(SkPoint* point) {
161     point->fX = this->readScalar();
162     point->fY = this->readScalar();
163 }
164
165 void SkReadBuffer::readPoint3(SkPoint3* point) {
166     this->readPad32(point, sizeof(SkPoint3));
167 }
168
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);
173         }
174     }
175     if (!this->isValid()) {
176         *matrix = SkM44();
177     }
178 }
179
180 void SkReadBuffer::readMatrix(SkMatrix* matrix) {
181     size_t size = 0;
182     if (this->isValid()) {
183         size = SkMatrixPriv::ReadFromMemory(matrix, fCurr, this->available());
184         (void)this->validate((SkAlign4(size) == size) && (0 != size));
185     }
186     if (!this->isValid()) {
187         matrix->reset();
188     }
189     (void)this->skip(size);
190 }
191
192 void SkReadBuffer::readIRect(SkIRect* rect) {
193     if (!this->readPad32(rect, sizeof(SkIRect))) {
194         rect->setEmpty();
195     }
196 }
197
198 void SkReadBuffer::readRect(SkRect* rect) {
199     if (!this->readPad32(rect, sizeof(SkRect))) {
200         rect->setEmpty();
201     }
202 }
203
204 SkRect SkReadBuffer::readRect() {
205     SkRect r;
206     if (!this->readPad32(&r, sizeof(SkRect))) {
207         r.setEmpty();
208     }
209     return r;
210 }
211
212 SkSamplingOptions SkReadBuffer::readSampling() {
213     if (!this->isVersionLT(SkPicturePriv::kAnisotropicFilter)) {
214         int maxAniso = this->readInt();
215         if (maxAniso != 0) {
216             return SkSamplingOptions::Aniso(maxAniso);
217         }
218     }
219     if (this->readBool()) {
220         float B = this->readScalar();
221         float C = this->readScalar();
222         return SkSamplingOptions({B, C});
223     } else {
224         SkFilterMode filter = this->read32LE(SkFilterMode::kLinear);
225         SkMipmapMode mipmap = this->read32LE(SkMipmapMode::kLinear);
226         return SkSamplingOptions(filter, mipmap);
227     }
228 }
229
230 void SkReadBuffer::readRRect(SkRRect* rrect) {
231     size_t size = 0;
232     if (!fError) {
233         size = rrect->readFromMemory(fCurr, this->available());
234         if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
235             rrect->setEmpty();
236         }
237     }
238     (void)this->skip(size);
239 }
240
241 void SkReadBuffer::readRegion(SkRegion* region) {
242     size_t size = 0;
243     if (!fError) {
244         size = region->readFromMemory(fCurr, this->available());
245         if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
246             region->setEmpty();
247         }
248     }
249     (void)this->skip(size);
250 }
251
252 void SkReadBuffer::readPath(SkPath* path) {
253     size_t size = 0;
254     if (!fError) {
255         size = path->readFromMemory(fCurr, this->available());
256         if (!this->validate((SkAlign4(size) == size) && (0 != size))) {
257             path->reset();
258         }
259     }
260     (void)this->skip(size);
261 }
262
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));
267 }
268
269 bool SkReadBuffer::readByteArray(void* value, size_t size) {
270     return this->readArray(value, size, sizeof(uint8_t));
271 }
272
273 bool SkReadBuffer::readColorArray(SkColor* colors, size_t size) {
274     return this->readArray(colors, size, sizeof(SkColor));
275 }
276
277 bool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) {
278     return this->readArray(colors, size, sizeof(SkColor4f));
279 }
280
281 bool SkReadBuffer::readIntArray(int32_t* values, size_t size) {
282     return this->readArray(values, size, sizeof(int32_t));
283 }
284
285 bool SkReadBuffer::readPointArray(SkPoint* points, size_t size) {
286     return this->readArray(points, size, sizeof(SkPoint));
287 }
288
289 bool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) {
290     return this->readArray(values, size, sizeof(SkScalar));
291 }
292
293 const void* SkReadBuffer::skipByteArray(size_t* size) {
294     const uint32_t count = this->readUInt();
295     const void* buf = this->skip(count);
296     if (size) {
297         *size = this->isValid() ? count : 0;
298     }
299     return buf;
300 }
301
302 sk_sp<SkData> SkReadBuffer::readByteArrayAsData() {
303     size_t numBytes = this->getArrayCount();
304     if (!this->validate(this->isAvailable(numBytes))) {
305         return nullptr;
306     }
307
308     SkAutoMalloc buffer(numBytes);
309     if (!this->readByteArray(buffer.get(), numBytes)) {
310         return nullptr;
311     }
312     return SkData::MakeFromMalloc(buffer.release(), numBytes);
313 }
314
315 uint32_t SkReadBuffer::getArrayCount() {
316     const size_t inc = sizeof(uint32_t);
317     if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) {
318         return 0;
319     }
320     return *((uint32_t*)fCurr);
321 }
322
323 #include "src/core/SkMipmap.h"
324
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();
329
330     sk_sp<SkImage> image;
331     {
332         sk_sp<SkData> data = this->readByteArrayAsData();
333         if (!data) {
334             this->validate(false);
335             return nullptr;
336         }
337         if (fProcs.fImageProc) {
338             image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx);
339         }
340         if (!image) {
341             std::optional<SkAlphaType> alphaType = std::nullopt;
342             if (flags & SkWriteBufferImageFlags::kUnpremul) {
343                 alphaType = kUnpremul_SkAlphaType;
344             }
345             image = SkImage::MakeFromEncoded(std::move(data), alphaType);
346         }
347     }
348
349     if (flags & SkWriteBufferImageFlags::kHasSubsetRect) {
350         SkIRect subset;
351         this->readIRect(&subset);
352         if (image) {
353             image = image->makeSubset(subset);
354         }
355     }
356
357     if (flags & SkWriteBufferImageFlags::kHasMipmap) {
358         sk_sp<SkData> data = this->readByteArrayAsData();
359         if (!data) {
360             this->validate(false);
361             return nullptr;
362         }
363         if (image) {
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()) {
368                     image = ri;
369                 }
370                 image = builder.attachTo(image);
371                 SkASSERT(image);    // withMipmaps should never return null
372             }
373         }
374     }
375     return image ? image : MakeEmptyImage(1, 1);
376 }
377
378 sk_sp<SkTypeface> SkReadBuffer::readTypeface() {
379     // Read 32 bits (signed)
380     //   0 -- return null (default font)
381     //  >0 -- index
382     //  <0 -- custom (serial procs) : negative size in bytes
383
384     int32_t index = this->read32();
385     if (index == 0) {
386         return nullptr;
387     } else if (index > 0) {
388         if (!this->validate(index <= fTFCount)) {
389             return nullptr;
390         }
391         return fTFArray[index - 1];
392     } else {    // custom
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)) {
396             return nullptr;
397         }
398         return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx);
399     }
400 }
401
402 SkFlattenable* SkReadBuffer::readRawFlattenable() {
403     SkFlattenable::Factory factory = nullptr;
404
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
409         }
410         if (index < 0) {
411             this->validate(false);
412             return nullptr;
413         }
414         index -= 1;     // we stored the index-base-1
415         if ((unsigned)index >= (unsigned)fFactoryCount) {
416             this->validate(false);
417             return nullptr;
418         }
419         factory = fFactoryArray[index];
420     } else {
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);
427             }
428         } else {
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;
432             if (index == 0) {
433                 return nullptr; // writer failed to give us the flattenable
434             }
435
436             if (SkFlattenable::Factory* found = fFlattenableDict.find(index)) {
437                 factory = *found;
438             }
439         }
440
441         if (!this->validate(factory != nullptr)) {
442             return nullptr;
443         }
444     }
445
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();
450     if (factory) {
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);
457             return nullptr;
458         }
459     } else {
460         // we must skip the remaining data
461         this->skip(sizeRecorded);
462     }
463     if (!this->isValid()) {
464         return nullptr;
465     }
466     return obj.release();
467 }
468
469 SkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) {
470     SkFlattenable* obj = this->readRawFlattenable();
471     if (obj && obj->getFlattenableType() != ft) {
472         this->validate(false);
473         obj->unref();
474         return nullptr;
475     }
476     return obj;
477 }
478
479 ///////////////////////////////////////////////////////////////////////////////////////////////////
480
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);
486         value = min;
487     }
488     return value;
489 }
490
491 SkLegacyFQ SkReadBuffer::checkFilterQuality() {
492     return this->checkRange<SkLegacyFQ>(kNone_SkLegacyFQ, kLast_SkLegacyFQ);
493 }