/src/skia/src/codec/SkTiffUtility.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2023 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 | | #ifndef SkTiffUtility_codec_DEFINED |
9 | | #define SkTiffUtility_codec_DEFINED |
10 | | |
11 | | #include "include/core/SkData.h" |
12 | | #include "include/core/SkRefCnt.h" |
13 | | |
14 | | #include <cstddef> |
15 | | #include <cstdint> |
16 | | #include <memory> |
17 | | |
18 | | /* |
19 | | * Helper function for parsing a Tiff Image File Directory (IFD) structure. This structure is used |
20 | | * by EXIF tags, multi-picture, and maker note metadata. |
21 | | */ |
22 | | class SkTiffImageFileDirectory { |
23 | | public: |
24 | | /* |
25 | | * Parse |data| to read the endian-ness into |outLittleEndian| and the IFD offset into |
26 | | * |outIfdOffset|. Return true if the endian-ness was successfully parsed and there was |
27 | | * the IFD offset was read. |
28 | | */ |
29 | | static bool ParseHeader(const SkData* data, bool* outLittleEndian, uint32_t* outIfdOffset); |
30 | | |
31 | | /* |
32 | | * Create an object for parsing an IFD at offset |ifdOffset| inside |data| which has endianness |
33 | | * indicated by |littleEndian|. |
34 | | */ |
35 | | static std::unique_ptr<SkTiffImageFileDirectory> MakeFromOffset(sk_sp<SkData> data, |
36 | | bool littleEndian, |
37 | | uint32_t ifdOffset); |
38 | | |
39 | | /* |
40 | | * Return the number of entries. |
41 | | */ |
42 | 267k | uint16_t getNumEntries() const { return fNumEntries; } |
43 | | |
44 | | /* |
45 | | * Return the offset (within the specified SkData) of the next IFD in the list of IFDs. |
46 | | */ |
47 | 0 | uint32_t nextIfdOffset() const { return fNextIfdOffset; } |
48 | | |
49 | | /* |
50 | | * Return the tag, of a specific entry. |
51 | | */ |
52 | | uint16_t getEntryTag(uint16_t entryIndex) const; |
53 | | |
54 | | /* |
55 | | * If |entryIndex| has type unsigned short (3), unsigned long (4), or signed rational (10), and |
56 | | * count |count|, then populate |values| with the data for the tag and return true. Otherwise |
57 | | * return false. |
58 | | */ |
59 | 6.89k | bool getEntryUnsignedShort(uint16_t entryIndex, uint32_t count, uint16_t* values) const { |
60 | 6.89k | return getEntryValuesGeneric(entryIndex, kTypeUnsignedShort, count, values); |
61 | 6.89k | } |
62 | 7.44k | bool getEntryUnsignedLong(uint16_t entryIndex, uint32_t count, uint32_t* values) const { |
63 | 7.44k | return getEntryValuesGeneric(entryIndex, kTypeUnsignedLong, count, values); |
64 | 7.44k | } |
65 | 288 | bool getEntrySignedRational(uint16_t entryIndex, uint32_t count, float* values) const { |
66 | 288 | return getEntryValuesGeneric(entryIndex, kTypeSignedRational, count, values); |
67 | 288 | } |
68 | 1.71k | bool getEntryUnsignedRational(uint16_t entryIndex, uint32_t count, float* values) const { |
69 | 1.71k | return getEntryValuesGeneric(entryIndex, kTypeUnsignedRational, count, values); |
70 | 1.71k | } |
71 | | |
72 | | /* |
73 | | * If |entryIndex| has type undefined (7), then return the bytes specified by the count field |
74 | | * and the offset (read from the value field as an unsigned long). |
75 | | */ |
76 | | sk_sp<SkData> getEntryUndefinedData(uint16_t entryIndex) const; |
77 | | |
78 | | private: |
79 | | static constexpr uint16_t kTypeUnsignedByte = 1; |
80 | | static constexpr uint16_t kTypeAsciiString = 2; |
81 | | static constexpr uint16_t kTypeUnsignedShort = 3; |
82 | | static constexpr uint16_t kTypeUnsignedLong = 4; |
83 | | static constexpr uint16_t kTypeUnsignedRational = 5; |
84 | | static constexpr uint16_t kTypeSignedByte = 6; |
85 | | static constexpr uint16_t kTypeUndefined = 7; |
86 | | static constexpr uint16_t kTypeSignedShort = 8; |
87 | | static constexpr uint16_t kTypeSignedLong = 9; |
88 | | static constexpr uint16_t kTypeSignedRational = 10; |
89 | | static constexpr uint16_t kTypeSingleFloat = 11; |
90 | | static constexpr uint16_t kTypeDoubleFloat = 12; |
91 | | |
92 | | static bool IsValidType(uint16_t type); |
93 | | static size_t BytesForType(uint16_t type); |
94 | | |
95 | | SkTiffImageFileDirectory(sk_sp<SkData> data, |
96 | | bool littleEndian, |
97 | | uint32_t offset, |
98 | | uint16_t ifdNumEntries, |
99 | | uint32_t ifdNextOffset); |
100 | | |
101 | | /* |
102 | | * Return the tag, type, count, and data for the specified entry. Return false if the type |
103 | | * is invalid, or if the data in the IFD is out of bounds. |
104 | | */ |
105 | | bool getEntryRawData(uint16_t entryIndex, |
106 | | uint16_t* outTag, |
107 | | uint16_t* outType, |
108 | | uint32_t* outCount, |
109 | | const uint8_t** outData, |
110 | | size_t* outDataSize) const; |
111 | | |
112 | | /* |
113 | | * Helper function for assorted getTag functions. |
114 | | */ |
115 | | bool getEntryValuesGeneric(uint16_t entryIndex, |
116 | | uint16_t type, |
117 | | uint32_t count, |
118 | | void* values) const; |
119 | | |
120 | | // The data that the IFD indexes into. |
121 | | const sk_sp<SkData> fData; |
122 | | |
123 | | // True if the data is little endian. |
124 | | const bool fLittleEndian; |
125 | | |
126 | | // The offset where the IFD starts. |
127 | | const uint32_t fOffset; |
128 | | |
129 | | // The number of entries of the IFD (read from the first 2 bytes at the IFD offset). |
130 | | const uint16_t fNumEntries; |
131 | | |
132 | | // The offset of the next IFD (read from the next 4 bytes after the IFD entries). |
133 | | const uint32_t fNextIfdOffset; |
134 | | }; |
135 | | |
136 | | #endif |