20bool SkTiffImageFileDirectory::IsValidType(uint16_t
type) {
return type >= 1 &&
type <= 12; }
22size_t SkTiffImageFileDirectory::BytesForType(uint16_t
type) {
24 case kTypeUnsignedByte:
26 case kTypeAsciiString:
28 case kTypeUnsignedShort:
30 case kTypeUnsignedLong:
32 case kTypeUnsignedRational:
38 case kTypeSignedShort:
42 case kTypeSignedRational:
44 case kTypeSingleFloat:
46 case kTypeDoubleFloat:
55 uint16_t entryIndex) {
56 return data->bytes() +
67 uint16_t* outNumEntries,
68 uint32_t* outNextIfdOffset) {
69 const uint8_t* dataCurrent = data->bytes();
70 size_t dataSize = data->size();
73 if (dataSize < ifdOffset) {
77 dataCurrent += ifdOffset;
78 dataSize -= ifdOffset;
82 SkCodecPrintf(
"Insufficient space to store number of entries.\n");
91 SkCodecPrintf(
"Insufficient space (%u) to store all %u entries.\n",
92 static_cast<uint32_t
>(data->size()),
98 *outNumEntries = numEntries;
106 SkCodecPrintf(
"Insufficient space to store next IFD offset.\n");
116 bool* outLittleEndian,
117 uint32_t* outIfdOffset) {
119 if (data->size() < 8) {
124 SkCodecPrintf(
"Tiff header had invalid endian marker 0x%x,0x%x,0x%x,0x%x.\n",
131 *outIfdOffset =
get_endian_int(data->bytes() + 4, *outLittleEndian);
137 uint16_t numEntries = 0;
138 uint32_t nextOffset = 0;
139 if (!
validate_ifd(data.get(), littleEndian, ifdOffset, &numEntries, &nextOffset)) {
144 std::move(data), littleEndian, ifdOffset, numEntries, nextOffset));
147SkTiffImageFileDirectory::SkTiffImageFileDirectory(
sk_sp<SkData> data,
151 uint32_t nextIfdOffset)
152 : fData(
std::move(data))
153 , fLittleEndian(littleEndian)
155 , fNumEntries(numEntries)
156 , fNextIfdOffset(nextIfdOffset) {}
163bool SkTiffImageFileDirectory::getEntryRawData(uint16_t entryIndex,
167 const uint8_t** outData,
168 size_t* outDataSize)
const {
178 if (!IsValidType(
type)) {
187 const size_t entryDataBytes = BytesForType(
type) *
count;
188 const uint8_t* entryData =
nullptr;
193 const uint32_t entryDataOffset =
get_endian_int(entry, fLittleEndian);
194 if (fData->
size() < entryDataOffset || fData->
size() - entryDataOffset < entryDataBytes) {
197 entryData = fData->
bytes() + entryDataOffset;
200 if (outTag) *outTag = tag;
201 if (outType) *outType =
type;
202 if (outCount) *outCount =
count;
203 if (outData) *outData = entryData;
204 if (outDataSize) *outDataSize = entryDataBytes;
211 const uint8_t* data =
nullptr;
213 if (!getEntryRawData(entryIndex,
nullptr, &
type, &
count, &data, &size)) {
216 if (
type != kTypeUndefined) {
222bool SkTiffImageFileDirectory::getEntryValuesGeneric(uint16_t entryIndex,
225 void* values)
const {
226 uint16_t entryType = 0;
227 uint32_t entryCount = 0;
228 const uint8_t* entryData =
nullptr;
229 if (!getEntryRawData(entryIndex,
nullptr, &entryType, &entryCount, &entryData,
nullptr)) {
232 if (
type != entryType) {
235 if (
count != entryCount) {
238 for (uint32_t i = 0; i <
count; ++i) {
239 const uint8_t*
data = entryData + i * BytesForType(kTypeUnsignedLong);
241 case kTypeUnsignedShort:
244 case kTypeUnsignedLong:
247 case kTypeSignedRational: {
250 if (denominator == 0) {
254 reinterpret_cast<float*
>(
values)[i] = 0;
256 reinterpret_cast<float*
>(
values)[i] =
257 numerator /
static_cast<float>(denominator);
261 case kTypeUnsignedRational: {
264 if (denominator == 0) {
266 reinterpret_cast<float*
>(
values)[i] = 0.f;
268 reinterpret_cast<float*
>(
values)[i] =
269 numerator /
static_cast<float>(denominator);
static uint32_t get_endian_int(const uint8_t *data, bool littleEndian)
static uint16_t get_endian_short(const uint8_t *data, bool littleEndian)
#define SkCodecPrintf(...)
static bool is_valid_endian_marker(const uint8_t *data, bool *isLittleEndian)
static bool validate_ifd(const SkData *data, bool littleEndian, uint32_t ifdOffset, uint16_t *outNumEntries, uint32_t *outNextIfdOffset)
constexpr size_t kSizeLong
static const uint8_t * get_entry_address(const SkData *data, uint32_t ifdOffset, uint16_t entryIndex)
constexpr size_t kSizeShort
constexpr size_t kSizeEntry
const uint8_t * bytes() const
static sk_sp< SkData > MakeSubset(const SkData *src, size_t offset, size_t length)
static std::unique_ptr< SkTiffImageFileDirectory > MakeFromOffset(sk_sp< SkData > data, bool littleEndian, uint32_t ifdOffset)
static bool ParseHeader(const SkData *data, bool *outLittleEndian, uint32_t *outIfdOffset)
sk_sp< SkData > getEntryUndefinedData(uint16_t entryIndex) const
uint16_t getEntryTag(uint16_t entryIndex) const
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data