1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 9cb93a386Sopenharmony_ci#include "include/core/SkData.h" 10cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 11cb93a386Sopenharmony_ci#include "include/core/SkImageGenerator.h" 12cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 13cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h" 14cb93a386Sopenharmony_ci#include "src/core/SkAutoMalloc.h" 15cb93a386Sopenharmony_ci#include "src/core/SkMathPriv.h" 16cb93a386Sopenharmony_ci#include "src/core/SkMatrixPriv.h" 17cb93a386Sopenharmony_ci#include "src/core/SkMipmapBuilder.h" 18cb93a386Sopenharmony_ci#include "src/core/SkReadBuffer.h" 19cb93a386Sopenharmony_ci#include "src/core/SkSafeMath.h" 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_cinamespace { 22cb93a386Sopenharmony_ci // This generator intentionally should always fail on all attempts to get its pixels, 23cb93a386Sopenharmony_ci // simulating a bad or empty codec stream. 24cb93a386Sopenharmony_ci class EmptyImageGenerator final : public SkImageGenerator { 25cb93a386Sopenharmony_ci public: 26cb93a386Sopenharmony_ci EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { } 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci private: 29cb93a386Sopenharmony_ci using INHERITED = SkImageGenerator; 30cb93a386Sopenharmony_ci }; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci static sk_sp<SkImage> MakeEmptyImage(int width, int height) { 33cb93a386Sopenharmony_ci return SkImage::MakeFromGenerator( 34cb93a386Sopenharmony_ci std::make_unique<EmptyImageGenerator>(SkImageInfo::MakeN32Premul(width, height))); 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci} // anonymous namespace 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_civoid SkReadBuffer::setMemory(const void* data, size_t size) { 40cb93a386Sopenharmony_ci this->validate(IsPtrAlign4(data) && (SkAlign4(size) == size)); 41cb93a386Sopenharmony_ci if (!fError) { 42cb93a386Sopenharmony_ci fBase = fCurr = (const char*)data; 43cb93a386Sopenharmony_ci fStop = fBase + size; 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci} 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_civoid SkReadBuffer::setInvalid() { 48cb93a386Sopenharmony_ci if (!fError) { 49cb93a386Sopenharmony_ci // When an error is found, send the read cursor to the end of the stream 50cb93a386Sopenharmony_ci fCurr = fStop; 51cb93a386Sopenharmony_ci fError = true; 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ciconst void* SkReadBuffer::skip(size_t size) { 56cb93a386Sopenharmony_ci size_t inc = SkAlign4(size); 57cb93a386Sopenharmony_ci this->validate(inc >= size); 58cb93a386Sopenharmony_ci const void* addr = fCurr; 59cb93a386Sopenharmony_ci this->validate(IsPtrAlign4(addr) && this->isAvailable(inc)); 60cb93a386Sopenharmony_ci if (fError) { 61cb93a386Sopenharmony_ci return nullptr; 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci fCurr += inc; 65cb93a386Sopenharmony_ci return addr; 66cb93a386Sopenharmony_ci} 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ciconst void* SkReadBuffer::skip(size_t count, size_t size) { 69cb93a386Sopenharmony_ci return this->skip(SkSafeMath::Mul(count, size)); 70cb93a386Sopenharmony_ci} 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_civoid SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) { 73cb93a386Sopenharmony_ci fProcs = procs; 74cb93a386Sopenharmony_ci} 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_cibool SkReadBuffer::readBool() { 77cb93a386Sopenharmony_ci uint32_t value = this->readUInt(); 78cb93a386Sopenharmony_ci // Boolean value should be either 0 or 1 79cb93a386Sopenharmony_ci this->validate(!(value & ~1)); 80cb93a386Sopenharmony_ci return value != 0; 81cb93a386Sopenharmony_ci} 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ciSkColor SkReadBuffer::readColor() { 84cb93a386Sopenharmony_ci return this->readUInt(); 85cb93a386Sopenharmony_ci} 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ciint32_t SkReadBuffer::readInt() { 88cb93a386Sopenharmony_ci const size_t inc = sizeof(int32_t); 89cb93a386Sopenharmony_ci if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) { 90cb93a386Sopenharmony_ci return 0; 91cb93a386Sopenharmony_ci } 92cb93a386Sopenharmony_ci int32_t value = *((const int32_t*)fCurr); 93cb93a386Sopenharmony_ci fCurr += inc; 94cb93a386Sopenharmony_ci return value; 95cb93a386Sopenharmony_ci} 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ciSkScalar SkReadBuffer::readScalar() { 98cb93a386Sopenharmony_ci const size_t inc = sizeof(SkScalar); 99cb93a386Sopenharmony_ci if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) { 100cb93a386Sopenharmony_ci return 0; 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci SkScalar value = *((const SkScalar*)fCurr); 103cb93a386Sopenharmony_ci fCurr += inc; 104cb93a386Sopenharmony_ci return value; 105cb93a386Sopenharmony_ci} 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ciuint32_t SkReadBuffer::readUInt() { 108cb93a386Sopenharmony_ci return this->readInt(); 109cb93a386Sopenharmony_ci} 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ciint32_t SkReadBuffer::read32() { 112cb93a386Sopenharmony_ci return this->readInt(); 113cb93a386Sopenharmony_ci} 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ciuint8_t SkReadBuffer::peekByte() { 116cb93a386Sopenharmony_ci if (this->available() <= 0) { 117cb93a386Sopenharmony_ci fError = true; 118cb93a386Sopenharmony_ci return 0; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci return *((uint8_t*)fCurr); 121cb93a386Sopenharmony_ci} 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_cibool SkReadBuffer::readPad32(void* buffer, size_t bytes) { 124cb93a386Sopenharmony_ci if (const void* src = this->skip(bytes)) { 125cb93a386Sopenharmony_ci // buffer might be null if bytes is zero (see SkAutoMalloc), hence we call 126cb93a386Sopenharmony_ci // the careful version of memcpy. 127cb93a386Sopenharmony_ci sk_careful_memcpy(buffer, src, bytes); 128cb93a386Sopenharmony_ci return true; 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ci return false; 131cb93a386Sopenharmony_ci} 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ciconst char* SkReadBuffer::readString(size_t* len) { 134cb93a386Sopenharmony_ci *len = this->readUInt(); 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_ci // The string is len characters and a terminating \0. 137cb93a386Sopenharmony_ci const char* c_str = this->skipT<char>(*len+1); 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci if (this->validate(c_str && c_str[*len] == '\0')) { 140cb93a386Sopenharmony_ci return c_str; 141cb93a386Sopenharmony_ci } 142cb93a386Sopenharmony_ci return nullptr; 143cb93a386Sopenharmony_ci} 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_civoid SkReadBuffer::readString(SkString* string) { 146cb93a386Sopenharmony_ci size_t len; 147cb93a386Sopenharmony_ci if (const char* c_str = this->readString(&len)) { 148cb93a386Sopenharmony_ci string->set(c_str, len); 149cb93a386Sopenharmony_ci return; 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci string->reset(); 152cb93a386Sopenharmony_ci} 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_civoid SkReadBuffer::readColor4f(SkColor4f* color) { 155cb93a386Sopenharmony_ci if (!this->readPad32(color, sizeof(SkColor4f))) { 156cb93a386Sopenharmony_ci *color = {0, 0, 0, 0}; 157cb93a386Sopenharmony_ci } 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_civoid SkReadBuffer::readPoint(SkPoint* point) { 161cb93a386Sopenharmony_ci point->fX = this->readScalar(); 162cb93a386Sopenharmony_ci point->fY = this->readScalar(); 163cb93a386Sopenharmony_ci} 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_civoid SkReadBuffer::readPoint3(SkPoint3* point) { 166cb93a386Sopenharmony_ci this->readPad32(point, sizeof(SkPoint3)); 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_civoid SkReadBuffer::read(SkM44* matrix) { 170cb93a386Sopenharmony_ci if (this->isValid()) { 171cb93a386Sopenharmony_ci if (const float* m = (const float*)this->skip(sizeof(float) * 16)) { 172cb93a386Sopenharmony_ci *matrix = SkM44::ColMajor(m); 173cb93a386Sopenharmony_ci } 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci if (!this->isValid()) { 176cb93a386Sopenharmony_ci *matrix = SkM44(); 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci} 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_civoid SkReadBuffer::readMatrix(SkMatrix* matrix) { 181cb93a386Sopenharmony_ci size_t size = 0; 182cb93a386Sopenharmony_ci if (this->isValid()) { 183cb93a386Sopenharmony_ci size = SkMatrixPriv::ReadFromMemory(matrix, fCurr, this->available()); 184cb93a386Sopenharmony_ci (void)this->validate((SkAlign4(size) == size) && (0 != size)); 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci if (!this->isValid()) { 187cb93a386Sopenharmony_ci matrix->reset(); 188cb93a386Sopenharmony_ci } 189cb93a386Sopenharmony_ci (void)this->skip(size); 190cb93a386Sopenharmony_ci} 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_civoid SkReadBuffer::readIRect(SkIRect* rect) { 193cb93a386Sopenharmony_ci if (!this->readPad32(rect, sizeof(SkIRect))) { 194cb93a386Sopenharmony_ci rect->setEmpty(); 195cb93a386Sopenharmony_ci } 196cb93a386Sopenharmony_ci} 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_civoid SkReadBuffer::readRect(SkRect* rect) { 199cb93a386Sopenharmony_ci if (!this->readPad32(rect, sizeof(SkRect))) { 200cb93a386Sopenharmony_ci rect->setEmpty(); 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci} 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_ciSkRect SkReadBuffer::readRect() { 205cb93a386Sopenharmony_ci SkRect r; 206cb93a386Sopenharmony_ci if (!this->readPad32(&r, sizeof(SkRect))) { 207cb93a386Sopenharmony_ci r.setEmpty(); 208cb93a386Sopenharmony_ci } 209cb93a386Sopenharmony_ci return r; 210cb93a386Sopenharmony_ci} 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ciSkSamplingOptions SkReadBuffer::readSampling() { 213cb93a386Sopenharmony_ci if (this->readBool()) { 214cb93a386Sopenharmony_ci float B = this->readScalar(); 215cb93a386Sopenharmony_ci float C = this->readScalar(); 216cb93a386Sopenharmony_ci return SkSamplingOptions({B, C}); 217cb93a386Sopenharmony_ci } else { 218cb93a386Sopenharmony_ci SkFilterMode filter = this->read32LE(SkFilterMode::kLinear); 219cb93a386Sopenharmony_ci SkMipmapMode mipmap = this->read32LE(SkMipmapMode::kLinear); 220cb93a386Sopenharmony_ci return SkSamplingOptions(filter, mipmap); 221cb93a386Sopenharmony_ci } 222cb93a386Sopenharmony_ci} 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_civoid SkReadBuffer::readRRect(SkRRect* rrect) { 225cb93a386Sopenharmony_ci size_t size = 0; 226cb93a386Sopenharmony_ci if (!fError) { 227cb93a386Sopenharmony_ci size = rrect->readFromMemory(fCurr, this->available()); 228cb93a386Sopenharmony_ci if (!this->validate((SkAlign4(size) == size) && (0 != size))) { 229cb93a386Sopenharmony_ci rrect->setEmpty(); 230cb93a386Sopenharmony_ci } 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci (void)this->skip(size); 233cb93a386Sopenharmony_ci} 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_civoid SkReadBuffer::readRegion(SkRegion* region) { 236cb93a386Sopenharmony_ci size_t size = 0; 237cb93a386Sopenharmony_ci if (!fError) { 238cb93a386Sopenharmony_ci size = region->readFromMemory(fCurr, this->available()); 239cb93a386Sopenharmony_ci if (!this->validate((SkAlign4(size) == size) && (0 != size))) { 240cb93a386Sopenharmony_ci region->setEmpty(); 241cb93a386Sopenharmony_ci } 242cb93a386Sopenharmony_ci } 243cb93a386Sopenharmony_ci (void)this->skip(size); 244cb93a386Sopenharmony_ci} 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_civoid SkReadBuffer::readPath(SkPath* path) { 247cb93a386Sopenharmony_ci size_t size = 0; 248cb93a386Sopenharmony_ci if (!fError) { 249cb93a386Sopenharmony_ci size = path->readFromMemory(fCurr, this->available()); 250cb93a386Sopenharmony_ci if (!this->validate((SkAlign4(size) == size) && (0 != size))) { 251cb93a386Sopenharmony_ci path->reset(); 252cb93a386Sopenharmony_ci } 253cb93a386Sopenharmony_ci } 254cb93a386Sopenharmony_ci (void)this->skip(size); 255cb93a386Sopenharmony_ci} 256cb93a386Sopenharmony_ci 257cb93a386Sopenharmony_cibool SkReadBuffer::readArray(void* value, size_t size, size_t elementSize) { 258cb93a386Sopenharmony_ci const uint32_t count = this->readUInt(); 259cb93a386Sopenharmony_ci return this->validate(size == count) && 260cb93a386Sopenharmony_ci this->readPad32(value, SkSafeMath::Mul(size, elementSize)); 261cb93a386Sopenharmony_ci} 262cb93a386Sopenharmony_ci 263cb93a386Sopenharmony_cibool SkReadBuffer::readByteArray(void* value, size_t size) { 264cb93a386Sopenharmony_ci return this->readArray(value, size, sizeof(uint8_t)); 265cb93a386Sopenharmony_ci} 266cb93a386Sopenharmony_ci 267cb93a386Sopenharmony_cibool SkReadBuffer::readColorArray(SkColor* colors, size_t size) { 268cb93a386Sopenharmony_ci return this->readArray(colors, size, sizeof(SkColor)); 269cb93a386Sopenharmony_ci} 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_cibool SkReadBuffer::readColor4fArray(SkColor4f* colors, size_t size) { 272cb93a386Sopenharmony_ci return this->readArray(colors, size, sizeof(SkColor4f)); 273cb93a386Sopenharmony_ci} 274cb93a386Sopenharmony_ci 275cb93a386Sopenharmony_cibool SkReadBuffer::readIntArray(int32_t* values, size_t size) { 276cb93a386Sopenharmony_ci return this->readArray(values, size, sizeof(int32_t)); 277cb93a386Sopenharmony_ci} 278cb93a386Sopenharmony_ci 279cb93a386Sopenharmony_cibool SkReadBuffer::readPointArray(SkPoint* points, size_t size) { 280cb93a386Sopenharmony_ci return this->readArray(points, size, sizeof(SkPoint)); 281cb93a386Sopenharmony_ci} 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_cibool SkReadBuffer::readScalarArray(SkScalar* values, size_t size) { 284cb93a386Sopenharmony_ci return this->readArray(values, size, sizeof(SkScalar)); 285cb93a386Sopenharmony_ci} 286cb93a386Sopenharmony_ci 287cb93a386Sopenharmony_ciconst void* SkReadBuffer::skipByteArray(size_t* size) { 288cb93a386Sopenharmony_ci const uint32_t count = this->readUInt(); 289cb93a386Sopenharmony_ci const void* buf = this->skip(count); 290cb93a386Sopenharmony_ci if (size) { 291cb93a386Sopenharmony_ci *size = this->isValid() ? count : 0; 292cb93a386Sopenharmony_ci } 293cb93a386Sopenharmony_ci return buf; 294cb93a386Sopenharmony_ci} 295cb93a386Sopenharmony_ci 296cb93a386Sopenharmony_cisk_sp<SkData> SkReadBuffer::readByteArrayAsData() { 297cb93a386Sopenharmony_ci size_t numBytes = this->getArrayCount(); 298cb93a386Sopenharmony_ci if (!this->validate(this->isAvailable(numBytes))) { 299cb93a386Sopenharmony_ci return nullptr; 300cb93a386Sopenharmony_ci } 301cb93a386Sopenharmony_ci 302cb93a386Sopenharmony_ci SkAutoMalloc buffer(numBytes); 303cb93a386Sopenharmony_ci if (!this->readByteArray(buffer.get(), numBytes)) { 304cb93a386Sopenharmony_ci return nullptr; 305cb93a386Sopenharmony_ci } 306cb93a386Sopenharmony_ci return SkData::MakeFromMalloc(buffer.release(), numBytes); 307cb93a386Sopenharmony_ci} 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ciuint32_t SkReadBuffer::getArrayCount() { 310cb93a386Sopenharmony_ci const size_t inc = sizeof(uint32_t); 311cb93a386Sopenharmony_ci if (!this->validate(IsPtrAlign4(fCurr) && this->isAvailable(inc))) { 312cb93a386Sopenharmony_ci return 0; 313cb93a386Sopenharmony_ci } 314cb93a386Sopenharmony_ci return *((uint32_t*)fCurr); 315cb93a386Sopenharmony_ci} 316cb93a386Sopenharmony_ci 317cb93a386Sopenharmony_ci#include "src/core/SkMipmap.h" 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci// If we see a corrupt stream, we return null (fail). If we just fail trying to decode 320cb93a386Sopenharmony_ci// the image, we don't fail, but return a 1x1 empty image. 321cb93a386Sopenharmony_cisk_sp<SkImage> SkReadBuffer::readImage() { 322cb93a386Sopenharmony_ci uint32_t flags = this->read32(); 323cb93a386Sopenharmony_ci 324cb93a386Sopenharmony_ci sk_sp<SkImage> image; 325cb93a386Sopenharmony_ci { 326cb93a386Sopenharmony_ci sk_sp<SkData> data = this->readByteArrayAsData(); 327cb93a386Sopenharmony_ci if (!data) { 328cb93a386Sopenharmony_ci this->validate(false); 329cb93a386Sopenharmony_ci return nullptr; 330cb93a386Sopenharmony_ci } 331cb93a386Sopenharmony_ci if (fProcs.fImageProc) { 332cb93a386Sopenharmony_ci image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx); 333cb93a386Sopenharmony_ci } 334cb93a386Sopenharmony_ci if (!image) { 335cb93a386Sopenharmony_ci image = SkImage::MakeFromEncoded(std::move(data)); 336cb93a386Sopenharmony_ci } 337cb93a386Sopenharmony_ci } 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci if (flags & SkWriteBufferImageFlags::kHasSubsetRect) { 340cb93a386Sopenharmony_ci SkIRect subset; 341cb93a386Sopenharmony_ci this->readIRect(&subset); 342cb93a386Sopenharmony_ci if (image) { 343cb93a386Sopenharmony_ci image = image->makeSubset(subset); 344cb93a386Sopenharmony_ci } 345cb93a386Sopenharmony_ci } 346cb93a386Sopenharmony_ci 347cb93a386Sopenharmony_ci if (flags & SkWriteBufferImageFlags::kHasMipmap) { 348cb93a386Sopenharmony_ci sk_sp<SkData> data = this->readByteArrayAsData(); 349cb93a386Sopenharmony_ci if (!data) { 350cb93a386Sopenharmony_ci this->validate(false); 351cb93a386Sopenharmony_ci return nullptr; 352cb93a386Sopenharmony_ci } 353cb93a386Sopenharmony_ci if (image) { 354cb93a386Sopenharmony_ci SkMipmapBuilder builder(image->imageInfo()); 355cb93a386Sopenharmony_ci if (SkMipmap::Deserialize(&builder, data->data(), data->size())) { 356cb93a386Sopenharmony_ci // TODO: need to make lazy images support mips 357cb93a386Sopenharmony_ci if (auto ri = image->makeRasterImage()) { 358cb93a386Sopenharmony_ci image = ri; 359cb93a386Sopenharmony_ci } 360cb93a386Sopenharmony_ci image = builder.attachTo(image); 361cb93a386Sopenharmony_ci SkASSERT(image); // withMipmaps should never return null 362cb93a386Sopenharmony_ci } 363cb93a386Sopenharmony_ci } 364cb93a386Sopenharmony_ci } 365cb93a386Sopenharmony_ci return image ? image : MakeEmptyImage(1, 1); 366cb93a386Sopenharmony_ci} 367cb93a386Sopenharmony_ci 368cb93a386Sopenharmony_cisk_sp<SkTypeface> SkReadBuffer::readTypeface() { 369cb93a386Sopenharmony_ci // Read 32 bits (signed) 370cb93a386Sopenharmony_ci // 0 -- return null (default font) 371cb93a386Sopenharmony_ci // >0 -- index 372cb93a386Sopenharmony_ci // <0 -- custom (serial procs) : negative size in bytes 373cb93a386Sopenharmony_ci 374cb93a386Sopenharmony_ci int32_t index = this->read32(); 375cb93a386Sopenharmony_ci if (index == 0) { 376cb93a386Sopenharmony_ci return nullptr; 377cb93a386Sopenharmony_ci } else if (index > 0) { 378cb93a386Sopenharmony_ci if (!this->validate(index <= fTFCount)) { 379cb93a386Sopenharmony_ci return nullptr; 380cb93a386Sopenharmony_ci } 381cb93a386Sopenharmony_ci return fTFArray[index - 1]; 382cb93a386Sopenharmony_ci } else { // custom 383cb93a386Sopenharmony_ci size_t size = sk_negate_to_size_t(index); 384cb93a386Sopenharmony_ci const void* data = this->skip(size); 385cb93a386Sopenharmony_ci if (!this->validate(data != nullptr && fProcs.fTypefaceProc)) { 386cb93a386Sopenharmony_ci return nullptr; 387cb93a386Sopenharmony_ci } 388cb93a386Sopenharmony_ci return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx); 389cb93a386Sopenharmony_ci } 390cb93a386Sopenharmony_ci} 391cb93a386Sopenharmony_ci 392cb93a386Sopenharmony_ciSkFlattenable* SkReadBuffer::readFlattenable(SkFlattenable::Type ft) { 393cb93a386Sopenharmony_ci SkFlattenable::Factory factory = nullptr; 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci if (fFactoryCount > 0) { 396cb93a386Sopenharmony_ci int32_t index = this->read32(); 397cb93a386Sopenharmony_ci if (0 == index || !this->isValid()) { 398cb93a386Sopenharmony_ci return nullptr; // writer failed to give us the flattenable 399cb93a386Sopenharmony_ci } 400cb93a386Sopenharmony_ci index -= 1; // we stored the index-base-1 401cb93a386Sopenharmony_ci if ((unsigned)index >= (unsigned)fFactoryCount) { 402cb93a386Sopenharmony_ci this->validate(false); 403cb93a386Sopenharmony_ci return nullptr; 404cb93a386Sopenharmony_ci } 405cb93a386Sopenharmony_ci factory = fFactoryArray[index]; 406cb93a386Sopenharmony_ci } else { 407cb93a386Sopenharmony_ci if (this->peekByte() != 0) { 408cb93a386Sopenharmony_ci // If the first byte is non-zero, the flattenable is specified by a string. 409cb93a386Sopenharmony_ci size_t ignored_length; 410cb93a386Sopenharmony_ci if (const char* name = this->readString(&ignored_length)) { 411cb93a386Sopenharmony_ci factory = SkFlattenable::NameToFactory(name); 412cb93a386Sopenharmony_ci fFlattenableDict.set(fFlattenableDict.count() + 1, factory); 413cb93a386Sopenharmony_ci } 414cb93a386Sopenharmony_ci } else { 415cb93a386Sopenharmony_ci // Read the index. We are guaranteed that the first byte 416cb93a386Sopenharmony_ci // is zeroed, so we must shift down a byte. 417cb93a386Sopenharmony_ci uint32_t index = this->readUInt() >> 8; 418cb93a386Sopenharmony_ci if (index == 0) { 419cb93a386Sopenharmony_ci return nullptr; // writer failed to give us the flattenable 420cb93a386Sopenharmony_ci } 421cb93a386Sopenharmony_ci 422cb93a386Sopenharmony_ci if (SkFlattenable::Factory* found = fFlattenableDict.find(index)) { 423cb93a386Sopenharmony_ci factory = *found; 424cb93a386Sopenharmony_ci } 425cb93a386Sopenharmony_ci } 426cb93a386Sopenharmony_ci 427cb93a386Sopenharmony_ci if (!this->validate(factory != nullptr)) { 428cb93a386Sopenharmony_ci return nullptr; 429cb93a386Sopenharmony_ci } 430cb93a386Sopenharmony_ci } 431cb93a386Sopenharmony_ci 432cb93a386Sopenharmony_ci // if we get here, factory may still be null, but if that is the case, the 433cb93a386Sopenharmony_ci // failure was ours, not the writer. 434cb93a386Sopenharmony_ci sk_sp<SkFlattenable> obj; 435cb93a386Sopenharmony_ci uint32_t sizeRecorded = this->read32(); 436cb93a386Sopenharmony_ci if (factory) { 437cb93a386Sopenharmony_ci size_t offset = this->offset(); 438cb93a386Sopenharmony_ci obj = (*factory)(*this); 439cb93a386Sopenharmony_ci // check that we read the amount we expected 440cb93a386Sopenharmony_ci size_t sizeRead = this->offset() - offset; 441cb93a386Sopenharmony_ci if (sizeRecorded != sizeRead) { 442cb93a386Sopenharmony_ci this->validate(false); 443cb93a386Sopenharmony_ci return nullptr; 444cb93a386Sopenharmony_ci } 445cb93a386Sopenharmony_ci if (obj && obj->getFlattenableType() != ft) { 446cb93a386Sopenharmony_ci this->validate(false); 447cb93a386Sopenharmony_ci return nullptr; 448cb93a386Sopenharmony_ci } 449cb93a386Sopenharmony_ci } else { 450cb93a386Sopenharmony_ci // we must skip the remaining data 451cb93a386Sopenharmony_ci this->skip(sizeRecorded); 452cb93a386Sopenharmony_ci } 453cb93a386Sopenharmony_ci if (!this->isValid()) { 454cb93a386Sopenharmony_ci return nullptr; 455cb93a386Sopenharmony_ci } 456cb93a386Sopenharmony_ci return obj.release(); 457cb93a386Sopenharmony_ci} 458cb93a386Sopenharmony_ci 459cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////////////////////////// 460cb93a386Sopenharmony_ci 461cb93a386Sopenharmony_ciint32_t SkReadBuffer::checkInt(int32_t min, int32_t max) { 462cb93a386Sopenharmony_ci SkASSERT(min <= max); 463cb93a386Sopenharmony_ci int32_t value = this->read32(); 464cb93a386Sopenharmony_ci if (value < min || value > max) { 465cb93a386Sopenharmony_ci this->validate(false); 466cb93a386Sopenharmony_ci value = min; 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci return value; 469cb93a386Sopenharmony_ci} 470cb93a386Sopenharmony_ci 471cb93a386Sopenharmony_ciSkLegacyFQ SkReadBuffer::checkFilterQuality() { 472cb93a386Sopenharmony_ci return this->checkRange<SkLegacyFQ>(kNone_SkLegacyFQ, kLast_SkLegacyFQ); 473cb93a386Sopenharmony_ci} 474