Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
SkJpegMultiPictureParameters Struct Reference

#include <SkJpegMultiPicture.h>

Classes

struct  Image
 

Public Member Functions

sk_sp< SkDataserialize () const
 

Static Public Member Functions

static std::unique_ptr< SkJpegMultiPictureParametersMake (const sk_sp< const SkData > &segmentParameters)
 
static size_t GetAbsoluteOffset (uint32_t dataOffset, size_t mpSegmentOffset)
 

Public Attributes

std::vector< Imageimages
 

Detailed Description

Definition at line 25 of file SkJpegMultiPicture.h.

Member Function Documentation

◆ GetAbsoluteOffset()

size_t SkJpegMultiPictureParameters::GetAbsoluteOffset ( uint32_t  dataOffset,
size_t  mpSegmentOffset 
)
static

Definition at line 328 of file SkJpegMultiPicture.cpp.

329 {
330 // The value of zero is used by the primary image.
331 if (dataOffset == 0) {
332 return 0;
333 }
334 return mpSegmentOffset + // The offset to the marker
335 kJpegMarkerCodeSize + // The marker itself
336 kJpegSegmentParameterLengthSize + // The parameter length
337 sizeof(kMpfSig) + // The signature
338 dataOffset;
339}
static constexpr uint8_t kMpfSig[]
static constexpr size_t kJpegSegmentParameterLengthSize
static constexpr size_t kJpegMarkerCodeSize

◆ Make()

std::unique_ptr< SkJpegMultiPictureParameters > SkJpegMultiPictureParameters::Make ( const sk_sp< const SkData > &  segmentParameters)
static

Definition at line 51 of file SkJpegMultiPicture.cpp.

52 {
53 // Read the MP Format identifier starting after the APP2 Field Length. See Figure 4 of CIPA
54 // DC-x007-2009.
55 if (segmentParameters->size() < sizeof(kMpfSig)) {
56 return nullptr;
57 }
58 if (memcmp(segmentParameters->data(), kMpfSig, sizeof(kMpfSig)) != 0) {
59 return nullptr;
60 }
61 auto ifdData = SkData::MakeSubset(
62 segmentParameters.get(), sizeof(kMpfSig), segmentParameters->size() - sizeof(kMpfSig));
63 SkASSERT(ifdData);
64
65 // The rest of this function reads the structure described in Figure 6 of CIPA DC-x007-2009.
66 // Determine the endianness of the values in the structure. See Figure 5 (MP endian tag
67 // structure), and read the Index IFD offset.
68 bool littleEndian = false;
69 uint32_t ifdOffset = 0;
70 if (!SkTiffImageFileDirectory::ParseHeader(ifdData.get(), &littleEndian, &ifdOffset)) {
71 SkCodecPrintf("Failed to parse endian-ness and index IFD offset.\n");
72 return nullptr;
73 }
74
75 // Create the Index Image File Directory (Index IFD).
76 auto ifd = SkTiffImageFileDirectory::MakeFromOffset(ifdData, littleEndian, ifdOffset);
77 if (!ifd) {
78 SkCodecPrintf("Failed to create MP Index IFD offset.\n");
79 return nullptr;
80 }
81
82 // Read the number of tags in the Index IFD. See Table 3 (MP Index IFD Tags) for a description
83 // of all possible tags.
84 uint16_t tagCount = ifd->getNumEntries();
85
86 // We will extract the number of images from the tags.
87 uint32_t numberOfImages = 0;
88
89 // The data for the MP entries.
90 sk_sp<SkData> mpEntriesData;
91
92 // The MP Index IFD tags shall be specified in the order of their tag IDs (text from
93 // section 5.2.3), so keep track of the previous tag id read.
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) {
98 SkCodecPrintf("MPF tags not in order.\n");
99 return nullptr;
100 }
101 previousTag = tag;
102
103 switch (tag) {
104 case kVersionTag: {
105 // See 5.2.3.1: MP Format Version.
106 sk_sp<SkData> data = ifd->getEntryUndefinedData(idfEntryIndex);
107 if (!data) {
108 SkCodecPrintf("Version must be undefined type.\n");
109 return nullptr;
110 }
111 if (data->size() != kVersionSize) {
112 SkCodecPrintf("Version must be 4 bytes.\n");
113 return nullptr;
114 }
115 if (memcmp(data->data(), kVersionExpected, kVersionSize) != 0) {
116 SkCodecPrintf("Version value is not 0100.\n");
117 return nullptr;
118 }
119 break;
120 }
122 // See 5.2.3.2: Number of Images.
123 if (!ifd->getEntryUnsignedLong(idfEntryIndex, 1, &numberOfImages)) {
124 SkCodecPrintf("Number of Images was not 1 unsigned long.\n");
125 }
126 if (numberOfImages < 1) {
127 SkCodecPrintf("Invalid number of images.\n");
128 return nullptr;
129 }
130 break;
131 case kMPEntryTag: {
132 // See 5.2.3.3: MP Entry.
133 mpEntriesData = ifd->getEntryUndefinedData(idfEntryIndex);
134 if (!mpEntriesData) {
135 SkCodecPrintf("MP entries data could not be extracted.\n");
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 // See 5.2.3.4: Individual Image Unique ID List.
149 // Validate that the count parameter is correct, but do not extract any other
150 // information.
151 sk_sp<SkData> data = ifd->getEntryUndefinedData(idfEntryIndex);
152 if (!data) {
153 SkCodecPrintf("Image Unique ID must be undefined type.\n");
154 return nullptr;
155 }
156 if (data->size() != kIndividualImageUniqueIDSize * numberOfImages) {
157 SkCodecPrintf("Invalid Image Unique ID count.\n");
158 return nullptr;
159 }
160 break;
161 }
163 // See 5.2.3.5: Total Number of Captured Frames.
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) {
179 SkCodecPrintf("MP Entry data was not present.\n");
180 return nullptr;
181 }
182
183 // Start to prepare the result that we will return.
184 auto result = std::make_unique<SkJpegMultiPictureParameters>();
185 result->images.resize(numberOfImages);
186
187 // The next IFD is the Attribute IFD offset. We will not read or validate the Attribute IFD.
188
189 // Parse the MP Entries data.
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);
193 const uint32_t size = get_endian_int(mpEntryData + 4, 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) {
206 SkCodecPrintf("Image format must be 0 (JPEG).\n");
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;
216 result->images[i].size = size;
217 }
218
219 return result;
220}
#define SkASSERT(cond)
Definition SkAssert.h:116
static uint32_t get_endian_int(const uint8_t *data, bool littleEndian)
#define SkCodecPrintf(...)
Definition SkCodecPriv.h:23
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
Definition SkData.h:37
static sk_sp< SkData > MakeSubset(const SkData *src, size_t offset, size_t length)
Definition SkData.cpp:173
size_t size() const
Definition SkData.h:30
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)
T * get() const
Definition SkRefCnt.h:303
GAsyncResult * result
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
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
Definition switches.h:259

◆ serialize()

sk_sp< SkData > SkJpegMultiPictureParameters::serialize ( ) const

Definition at line 250 of file SkJpegMultiPicture.cpp.

250 {
251 // Write the MPF signature.
253 if (!s.write(kMpfSig, sizeof(kMpfSig))) {
254 SkCodecPrintf("Failed to write signature.\n");
255 return nullptr;
256 }
257
258 // We will always write as big-endian.
259 if (!s.write(kMpBigEndian, kMpEndianSize)) {
260 SkCodecPrintf("Failed to write endianness.\n");
261 return nullptr;
262 }
263 // Compute the number of images.
264 uint32_t numberOfImages = static_cast<uint32_t>(images.size());
265
266 // Set the Index IFD offset be the position after the endianness value and this offset.
267 constexpr uint32_t indexIfdOffset =
268 static_cast<uint16_t>(sizeof(kMpBigEndian) + sizeof(uint32_t));
269 WRITE_UINT32(indexIfdOffset);
270
271 // We will write 3 tags (version, number of images, MP entries).
272 constexpr uint32_t numberOfTags = 3;
273 WRITE_UINT16(numberOfTags);
274
275 // Write the version tag.
279 if (!s.write(kVersionExpected, kVersionSize)) {
280 SkCodecPrintf("Failed to write version.\n");
281 return nullptr;
282 }
283
284 // Write the number of images.
288 WRITE_UINT32(numberOfImages);
289
290 // Write the MP entries.
293 WRITE_UINT32(kMPEntrySize * numberOfImages);
294 const uint32_t mpEntryOffset =
295 static_cast<uint32_t>(s.bytesWritten() - // The bytes written so far
296 sizeof(kMpfSig) + // Excluding the MPF signature
297 sizeof(uint32_t) + // The 4 bytes for this offset
298 sizeof(uint32_t)); // The 4 bytes for the attribute IFD offset.
299 WRITE_UINT32(mpEntryOffset);
300
301 // Write the attribute IFD offset (zero because we don't write it).
302 WRITE_UINT32(0);
303
304 // Write the MP entries.
305 for (size_t i = 0; i < images.size(); ++i) {
306 const auto& image = images[i];
307
308 uint32_t attribute = kMPEntryAttributeFormatJpeg;
309 if (i == 0) {
310 attribute |= kMPEntryAttributeTypePrimary;
311 }
312
313 WRITE_UINT32(attribute);
314 WRITE_UINT32(image.size);
315 WRITE_UINT32(image.dataOffset);
316 // Dependent image 1 and 2 entries are zero.
317 WRITE_UINT16(0);
318 WRITE_UINT16(0);
319 }
320
321 SkASSERT(s.bytesWritten() == multi_picture_params_serialized_size(images.size()));
322 return s.detachAsData();
323}
constexpr uint8_t kMpBigEndian[kMpEndianSize]
constexpr size_t kMpEndianSize
constexpr uint32_t kNumberOfImagesCount
constexpr uint16_t kTypeUndefined
constexpr uint32_t kVersionCount
#define WRITE_UINT16(value)
#define WRITE_UINT32(value)
constexpr uint16_t kTypeUnsignedLong
size_t multi_picture_params_serialized_size(size_t numberOfImages)
sk_sp< SkImage > image
Definition examples.cpp:29
struct MyStruct s

Member Data Documentation

◆ images

std::vector<Image> SkJpegMultiPictureParameters::images

Definition at line 37 of file SkJpegMultiPicture.h.


The documentation for this struct was generated from the following files: