52 {
53
54
56 return nullptr;
57 }
59 return nullptr;
60 }
64
65
66
67
68 bool littleEndian = false;
69 uint32_t ifdOffset = 0;
71 SkCodecPrintf(
"Failed to parse endian-ness and index IFD offset.\n");
72 return nullptr;
73 }
74
75
77 if (!ifd) {
79 return nullptr;
80 }
81
82
83
84 uint16_t tagCount = ifd->getNumEntries();
85
86
87 uint32_t numberOfImages = 0;
88
89
91
92
93
94 uint16_t previousTag = 0;
95 for (uint16_t idfEntryIndex = 0; idfEntryIndex < tagCount; ++idfEntryIndex) {
96 uint16_t tag = ifd->getEntryTag(idfEntryIndex);
97 if (previousTag >= tag) {
99 return nullptr;
100 }
101 previousTag = tag;
102
103 switch (tag) {
105
107 if (!data) {
109 return nullptr;
110 }
113 return nullptr;
114 }
117 return nullptr;
118 }
119 break;
120 }
122
123 if (!ifd->getEntryUnsignedLong(idfEntryIndex, 1, &numberOfImages)) {
124 SkCodecPrintf(
"Number of Images was not 1 unsigned long.\n");
125 }
126 if (numberOfImages < 1) {
128 return nullptr;
129 }
130 break;
132
133 mpEntriesData = ifd->getEntryUndefinedData(idfEntryIndex);
134 if (!mpEntriesData) {
136 return nullptr;
137 }
138 if (mpEntriesData->size() !=
kMPEntrySize * numberOfImages) {
139 SkCodecPrintf(
"MP entries data should be %ux%u bytes, was %u.\n",
141 numberOfImages,
142 static_cast<uint32_t>(mpEntriesData->size()));
143 return nullptr;
144 }
145 break;
146 }
148
149
150
152 if (!data) {
154 return nullptr;
155 }
158 return nullptr;
159 }
160 break;
161 }
163
164 uint32_t totalNumCapturedFrames = 0;
165 if (!ifd->getEntryUnsignedLong(idfEntryIndex, 1, &totalNumCapturedFrames)) {
166 SkCodecPrintf(
"Total Number of Captures Frames was not 1 unsigned long.\n");
167 }
168 break;
169 }
170 default:
171 return nullptr;
172 }
173 }
174 if (!numberOfImages) {
175 SkCodecPrintf(
"Number of images must be greater than zero.\n");
176 return nullptr;
177 }
178 if (!mpEntriesData) {
180 return nullptr;
181 }
182
183
184 auto result = std::make_unique<SkJpegMultiPictureParameters>();
185 result->images.resize(numberOfImages);
186
187
188
189
190 for (uint32_t i = 0; i < numberOfImages; ++i) {
191 const uint8_t* mpEntryData = mpEntriesData->bytes() +
kMPEntrySize * i;
192 const uint32_t attribute =
get_endian_int(mpEntryData + 0, littleEndian);
194 const uint32_t dataOffset =
get_endian_int(mpEntryData + 8, littleEndian);
195
196 const bool isPrimary =
198 const bool isJpeg =
200
201 if (isPrimary != (i == 0)) {
202 SkCodecPrintf(
"Image must be primary iff it is the first image..\n");
203 return nullptr;
204 }
205 if (!isJpeg) {
207 return nullptr;
208 }
209
210 if (i == 0 && dataOffset != 0) {
211 SkCodecPrintf(
"First individual Image offset must be NULL.\n");
212 return nullptr;
213 }
214
215 result->images[i].dataOffset = dataOffset;
217 }
218
220}
static uint32_t get_endian_int(const uint8_t *data, bool littleEndian)
#define SkCodecPrintf(...)
constexpr uint16_t kIndividualImageUniqueIDTag
constexpr uint8_t kVersionExpected[kVersionSize]
constexpr uint16_t kVersionTag
constexpr uint16_t kMPEntryTag
constexpr size_t kVersionSize
constexpr uint32_t kMPEntryAttributeFormatJpeg
constexpr uint32_t kMPEntryAttributeTypeMask
constexpr uint32_t kMPEntrySize
constexpr uint16_t kTotalNumberCapturedFramesTag
constexpr uint32_t kMPEntryAttributeFormatMask
constexpr uint32_t kMPEntryAttributeTypePrimary
constexpr uint16_t kNumberOfImagesTag
constexpr uint32_t kIndividualImageUniqueIDSize
const void * data() 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)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size