Flutter Engine
The Flutter Engine
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

 SkJpegMultiPictureParameters (size_t numberOfImages)
 
sk_sp< SkDataserialize (uint32_t individualImageNumber) const
 

Static Public Member Functions

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

Public Attributes

std::vector< Imageimages
 

Detailed Description

Definition at line 25 of file SkJpegMultiPicture.h.

Constructor & Destructor Documentation

◆ SkJpegMultiPictureParameters()

SkJpegMultiPictureParameters::SkJpegMultiPictureParameters ( size_t  numberOfImages)
inlineexplicit

Definition at line 26 of file SkJpegMultiPicture.h.

26: images(numberOfImages) {}

Member Function Documentation

◆ GetImageAbsoluteOffset()

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

Definition at line 305 of file SkJpegMultiPicture.cpp.

306 {
307 // The value of zero is used by the primary image.
308 if (dataOffset == 0) {
309 return 0;
310 }
311 return mp_header_absolute_offset(mpSegmentOffset) + dataOffset;
312}
static size_t mp_header_absolute_offset(size_t mpSegmentOffset)

◆ GetImageDataOffset()

uint32_t SkJpegMultiPictureParameters::GetImageDataOffset ( size_t  imageAbsoluteOffset,
size_t  mpSegmentOffset 
)
static

Definition at line 314 of file SkJpegMultiPicture.cpp.

315 {
316 // The value of zero is used by the primary image.
317 if (imageAbsoluteOffset == 0) {
318 return 0;
319 }
320 return static_cast<uint32_t>(imageAbsoluteOffset - mp_header_absolute_offset(mpSegmentOffset));
321}

◆ Make()

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

Definition at line 43 of file SkJpegMultiPicture.cpp.

44 {
45 // Read the MP Format identifier starting after the APP2 Field Length. See Figure 4 of CIPA
46 // DC-x007-2009.
47 if (segmentParameters->size() < sizeof(kMpfSig)) {
48 return nullptr;
49 }
50 if (memcmp(segmentParameters->data(), kMpfSig, sizeof(kMpfSig)) != 0) {
51 return nullptr;
52 }
53 auto ifdData = SkData::MakeSubset(
54 segmentParameters.get(), sizeof(kMpfSig), segmentParameters->size() - sizeof(kMpfSig));
55 SkASSERT(ifdData);
56
57 // The rest of this function reads the structure described in Figure 6 of CIPA DC-x007-2009.
58 // Determine the endianness of the values in the structure. See Figure 5 (MP endian tag
59 // structure), and read the Index IFD offset.
60 bool littleEndian = false;
61 uint32_t ifdOffset = 0;
62 if (!SkTiff::ImageFileDirectory::ParseHeader(ifdData.get(), &littleEndian, &ifdOffset)) {
63 SkCodecPrintf("Failed to parse endian-ness and index IFD offset.\n");
64 return nullptr;
65 }
66
67 // Create the Index Image File Directory (Index IFD).
68 auto ifd = SkTiff::ImageFileDirectory::MakeFromOffset(ifdData, littleEndian, ifdOffset);
69 if (!ifd) {
70 SkCodecPrintf("Failed to create MP Index IFD offset.\n");
71 return nullptr;
72 }
73
74 // Read the number of tags in the Index IFD. See Table 3 (MP Index IFD Tags) for a description
75 // of all possible tags.
76 uint16_t tagCount = ifd->getNumEntries();
77
78 // We will extract the number of images from the tags.
79 uint32_t numberOfImages = 0;
80
81 // The data for the MP entries.
82 sk_sp<SkData> mpEntriesData;
83
84 // The MP Index IFD tags shall be specified in the order of their tag IDs (text from
85 // section 5.2.3), so keep track of the previous tag id read.
86 uint16_t previousTag = 0;
87 for (uint16_t idfEntryIndex = 0; idfEntryIndex < tagCount; ++idfEntryIndex) {
88 uint16_t tag = ifd->getEntryTag(idfEntryIndex);
89 if (previousTag >= tag) {
90 SkCodecPrintf("MPF tags not in order.\n");
91 return nullptr;
92 }
93 previousTag = tag;
94
95 switch (tag) {
96 case kVersionTag: {
97 // See 5.2.3.1: MP Format Version.
98 sk_sp<SkData> data = ifd->getEntryUndefinedData(idfEntryIndex);
99 if (!data) {
100 SkCodecPrintf("Version must be undefined type.\n");
101 return nullptr;
102 }
103 if (data->size() != kVersionSize) {
104 SkCodecPrintf("Version must be 4 bytes.\n");
105 return nullptr;
106 }
107 if (memcmp(data->data(), kVersionExpected, kVersionSize) != 0) {
108 SkCodecPrintf("Version value is not 0100.\n");
109 return nullptr;
110 }
111 break;
112 }
114 // See 5.2.3.2: Number of Images.
115 if (!ifd->getEntryUnsignedLong(idfEntryIndex, 1, &numberOfImages)) {
116 SkCodecPrintf("Number of Images was not 1 unsigned long.\n");
117 }
118 if (numberOfImages < 1) {
119 SkCodecPrintf("Invalid number of images.\n");
120 return nullptr;
121 }
122 break;
123 case kMPEntryTag: {
124 // See 5.2.3.3: MP Entry.
125 mpEntriesData = ifd->getEntryUndefinedData(idfEntryIndex);
126 if (!mpEntriesData) {
127 SkCodecPrintf("MP entries data could not be extracted.\n");
128 return nullptr;
129 }
130 if (mpEntriesData->size() != kMPEntrySize * numberOfImages) {
131 SkCodecPrintf("MP entries data should be %ux%u bytes, was %u.\n",
133 numberOfImages,
134 static_cast<uint32_t>(mpEntriesData->size()));
135 return nullptr;
136 }
137 break;
138 }
140 // See 5.2.3.4: Individual Image Unique ID List.
141 // Validate that the count parameter is correct, but do not extract any other
142 // information.
143 sk_sp<SkData> data = ifd->getEntryUndefinedData(idfEntryIndex);
144 if (!data) {
145 SkCodecPrintf("Image Unique ID must be undefined type.\n");
146 return nullptr;
147 }
148 if (data->size() != kIndividualImageUniqueIDSize * numberOfImages) {
149 SkCodecPrintf("Invalid Image Unique ID count.\n");
150 return nullptr;
151 }
152 break;
153 }
155 // See 5.2.3.5: Total Number of Captured Frames.
156 uint32_t totalNumCapturedFrames = 0;
157 if (!ifd->getEntryUnsignedLong(idfEntryIndex, 1, &totalNumCapturedFrames)) {
158 SkCodecPrintf("Total Number of Captures Frames was not 1 unsigned long.\n");
159 }
160 break;
161 }
162 default:
163 return nullptr;
164 }
165 }
166 if (!numberOfImages) {
167 SkCodecPrintf("Number of images must be greater than zero.\n");
168 return nullptr;
169 }
170 if (!mpEntriesData) {
171 SkCodecPrintf("MP Entry data was not present.\n");
172 return nullptr;
173 }
174
175 // Start to prepare the result that we will return.
176 auto result = std::make_unique<SkJpegMultiPictureParameters>(numberOfImages);
177
178 // The next IFD is the Attribute IFD offset. We will not read or validate the Attribute IFD.
179
180 // Parse the MP Entries data.
181 for (uint32_t i = 0; i < numberOfImages; ++i) {
182 const uint8_t* mpEntryData = mpEntriesData->bytes() + kMPEntrySize * i;
183 const uint32_t attribute = get_endian_int(mpEntryData + 0, littleEndian);
184 const uint32_t size = get_endian_int(mpEntryData + 4, littleEndian);
185 const uint32_t dataOffset = get_endian_int(mpEntryData + 8, littleEndian);
186
187 const bool isPrimary =
189 const bool isJpeg =
191
192 if (isPrimary != (i == 0)) {
193 SkCodecPrintf("Image must be primary iff it is the first image..\n");
194 return nullptr;
195 }
196 if (!isJpeg) {
197 SkCodecPrintf("Image format must be 0 (JPEG).\n");
198 return nullptr;
199 }
200
201 if (i == 0 && dataOffset != 0) {
202 SkCodecPrintf("First individual Image offset must be NULL.\n");
203 return nullptr;
204 }
205
206 result->images[i].dataOffset = dataOffset;
207 result->images[i].size = size;
208 }
209
210 return result;
211}
#define SkASSERT(cond)
Definition: SkAssert.h:116
static uint32_t get_endian_int(const uint8_t *data, bool littleEndian)
Definition: SkCodecPriv.h:202
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
static constexpr uint8_t kMpfSig[]
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 uint8_t * bytes() const
Definition: SkData.h:43
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 bool ParseHeader(const SkData *data, bool *outLittleEndian, uint32_t *outIfdOffset)
static std::unique_ptr< ImageFileDirectory > MakeFromOffset(sk_sp< SkData > data, bool littleEndian, uint32_t ifdOffset, bool allowTruncated=false)
T * get() const
Definition: SkRefCnt.h:303
GAsyncResult * result
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
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ serialize()

sk_sp< SkData > SkJpegMultiPictureParameters::serialize ( uint32_t  individualImageNumber) const

Definition at line 213 of file SkJpegMultiPicture.cpp.

213 {
215
216 const uint32_t numberOfImages = static_cast<uint32_t>(images.size());
217
218 // Write the MPF signature.
219 s.write(kMpfSig, sizeof(kMpfSig));
220
221 // We will always write as big-endian.
223
224 // Set the first IFD offset be the position after the endianness value and this offset. This
225 // will be the MP Index IFD for the first individual image and the MP Attribute IFD for all
226 // other images.
227 constexpr uint32_t firstIfdOffset = sizeof(SkTiff::kEndianBig) + // Endian-ness
228 sizeof(uint32_t); // Index IFD offset
229 SkWStreamWriteU32BE(&s, firstIfdOffset);
230 SkASSERT(s.bytesWritten() - sizeof(kMpfSig) == firstIfdOffset);
231
232 if (individualImageNumber == 0) {
233 // The MP Index IFD will write 3 tags (version, number of images, and MP entries). See
234 // in Table 6 (MP Index IFD Tag Support Level) that these are the only mandatory entries.
235 const uint32_t mpIndexIfdNumberOfTags = 3;
236 SkWStreamWriteU16BE(&s, mpIndexIfdNumberOfTags);
237 } else {
238 // The MP Attribute IFD will write 1 tags (version). See in Table 7 (MP Attribute IFD Tag
239 // Support Level for Baseline MP Files) that no tags are required. If gainmap images support
240 // is added to CIPA DC-007, then some tags may be added and become mandatory.
241 const uint16_t mpAttributeIfdNumberOfTags = 1;
242 SkWStreamWriteU16BE(&s, mpAttributeIfdNumberOfTags);
243 }
244
245 // Write the version.
250
251 if (individualImageNumber == 0) {
252 // Write the number of images.
256 SkWStreamWriteU32BE(&s, numberOfImages);
257
258 // Write the MP entries tag.
261 const uint32_t mpEntriesSize = kMPEntrySize * numberOfImages;
262 SkWStreamWriteU32BE(&s, mpEntriesSize);
263 const uint32_t mpEntryOffset = static_cast<uint32_t>(
264 s.bytesWritten() - // The bytes written so far
265 sizeof(kMpfSig) + // Excluding the MPF signature
266 sizeof(uint32_t) + // The 4 bytes for this offset
267 sizeof(uint32_t)); // The 4 bytes for the attribute IFD offset.
268 SkWStreamWriteU32BE(&s, mpEntryOffset);
269
270 // Write the attribute IFD offset (zero because there is none).
272
273 // Write the MP entries data.
274 SkASSERT(s.bytesWritten() - sizeof(kMpfSig) == mpEntryOffset);
275 for (size_t i = 0; i < images.size(); ++i) {
276 const auto& image = images[i];
277
278 uint32_t attribute = kMPEntryAttributeFormatJpeg;
279 if (i == 0) {
280 attribute |= kMPEntryAttributeTypePrimary;
281 }
282
283 SkWStreamWriteU32BE(&s, attribute);
285 SkWStreamWriteU32BE(&s, image.dataOffset);
286 // Dependent image 1 and 2 entries are zero.
289 }
290 } else {
291 // The non-first-individual-images do not have any further IFDs.
293 }
294
295 return s.detachAsData();
296}
constexpr uint32_t kNumberOfImagesCount
constexpr uint32_t kVersionCount
bool SkWStreamWriteU32BE(SkWStream *s, uint32_t value)
Definition: SkStreamPriv.h:54
bool SkWStreamWriteU16BE(SkWStream *s, uint16_t value)
Definition: SkStreamPriv.h:49
struct MyStruct s
sk_sp< const SkImage > image
Definition: SkRecords.h:269
constexpr uint8_t kEndianBig[kEndianSize]
Definition: SkTiffUtility.h:22
constexpr uint16_t kTypeUnsignedLong
Definition: SkTiffUtility.h:29
constexpr uint16_t kTypeUndefined
Definition: SkTiffUtility.h:32

Member Data Documentation

◆ images

std::vector<Image> SkJpegMultiPictureParameters::images

Definition at line 39 of file SkJpegMultiPicture.h.


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