Flutter Engine
The Flutter Engine
Functions
SkJpegMetadataDecoderImpl.cpp File Reference
#include "src/codec/SkJpegMetadataDecoderImpl.h"
#include "include/core/SkData.h"
#include "include/private/base/SkTemplates.h"
#include "src/codec/SkCodecPriv.h"
#include "src/codec/SkJpegConstants.h"
#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>

Go to the source code of this file.

Functions

static bool marker_has_signature (const SkJpegMarker &marker, const uint32_t targetMarker, const uint8_t *signature, size_t signatureSize)
 
static sk_sp< SkDataread_metadata (const SkJpegMarkerList &markerList, const uint32_t targetMarker, const uint8_t *signature, size_t signatureSize, size_t signaturePadding, size_t bytesInIndex, bool alwaysCopyData)
 

Function Documentation

◆ marker_has_signature()

static bool marker_has_signature ( const SkJpegMarker marker,
const uint32_t  targetMarker,
const uint8_t *  signature,
size_t  signatureSize 
)
static

Return true if the specified SkJpegMarker has marker |targetMarker| and begins with the specified signature.

Definition at line 250 of file SkJpegMetadataDecoderImpl.cpp.

253 {
254 if (targetMarker != marker.fMarker) {
255 return false;
256 }
257 if (marker.fData->size() <= signatureSize) {
258 return false;
259 }
260 if (memcmp(marker.fData->bytes(), signature, signatureSize) != 0) {
261 return false;
262 }
263 return true;
264}
static const char marker[]

◆ read_metadata()

static sk_sp< SkData > read_metadata ( const SkJpegMarkerList markerList,
const uint32_t  targetMarker,
const uint8_t *  signature,
size_t  signatureSize,
size_t  signaturePadding,
size_t  bytesInIndex,
bool  alwaysCopyData 
)
static

Definition at line 289 of file SkJpegMetadataDecoderImpl.cpp.

295 {
296 // Compute the total size of the entire header (signature plus padding plus index plus count),
297 // since we'll use it often.
298 const size_t headerSize = signatureSize + signaturePadding + 2 * bytesInIndex;
299
300 // A map from part index to the data in each part.
301 std::vector<sk_sp<SkData>> parts;
302
303 // Running total of number of data in all parts.
304 size_t partsTotalSize = 0;
305
306 // Running total number of parts found.
307 uint32_t foundPartCount = 0;
308
309 // The expected number of parts (initialized at the first part we encounter).
310 uint32_t expectedPartCount = 0;
311
312 // Iterate through the image's segments.
313 for (const auto& marker : markerList) {
314 // Skip segments that don't have the right marker or signature.
315 if (!marker_has_signature(marker, targetMarker, signature, signatureSize)) {
316 continue;
317 }
318
319 // Skip segments that are too small to include the index and count.
320 const size_t dataLength = marker.fData->size();
321 if (dataLength <= headerSize) {
322 continue;
323 }
324
325 // Read this part's index and count as big-endian (if they are present, otherwise hard-code
326 // them to 1).
327 const uint8_t* data = marker.fData->bytes();
328 uint32_t partIndex = 0;
329 uint32_t partCount = 0;
330 if (bytesInIndex == 0) {
331 partIndex = 1;
332 partCount = 1;
333 } else {
334 for (size_t i = 0; i < bytesInIndex; ++i) {
335 const size_t offset = signatureSize + signaturePadding;
336 partIndex = (partIndex << 8) + data[offset + i];
337 partCount = (partCount << 8) + data[offset + bytesInIndex + i];
338 }
339 }
340
341 // A part count of 0 is invalid.
342 if (!partCount) {
343 SkCodecPrintf("Invalid marker part count zero\n");
344 return nullptr;
345 }
346
347 // The indices must in the range 1, ..., count.
348 if (partIndex <= 0 || partIndex > partCount) {
349 SkCodecPrintf("Invalid marker index %u for count %u\n", partIndex, partCount);
350 return nullptr;
351 }
352
353 // If this is the first marker we've encountered set the expected part count to its count.
354 if (expectedPartCount == 0) {
355 expectedPartCount = partCount;
356 parts.resize(expectedPartCount);
357 }
358
359 // If this does not match the expected part count, then fail.
360 if (partCount != expectedPartCount) {
361 SkCodecPrintf("Conflicting marker counts %u vs %u\n", partCount, expectedPartCount);
362 return nullptr;
363 }
364
365 // Make an SkData directly referencing the decoder's data for this part.
366 auto partData = SkData::MakeWithoutCopy(data + headerSize, dataLength - headerSize);
367
368 // Fail if duplicates are found.
369 if (parts[partIndex - 1]) {
370 SkCodecPrintf("Duplicate parts for index %u of %u\n", partIndex, expectedPartCount);
371 return nullptr;
372 }
373
374 // Save part in the map.
375 partsTotalSize += partData->size();
376 parts[partIndex - 1] = std::move(partData);
377 foundPartCount += 1;
378
379 // Stop as soon as we find all of the parts.
380 if (foundPartCount == expectedPartCount) {
381 break;
382 }
383 }
384
385 // Return nullptr if we don't find the data (this is not an error).
386 if (expectedPartCount == 0) {
387 return nullptr;
388 }
389
390 // Fail if we don't have all of the parts.
391 if (foundPartCount != expectedPartCount) {
392 SkCodecPrintf("Incomplete set of markers (expected %u got %u)\n",
393 expectedPartCount,
394 foundPartCount);
395 return nullptr;
396 }
397
398 // Return a direct reference to the data if there is only one part and we're allowed to.
399 if (!alwaysCopyData && expectedPartCount == 1) {
400 return std::move(parts[0]);
401 }
402
403 // Copy all of the markers and stitch them together.
404 auto result = SkData::MakeUninitialized(partsTotalSize);
405 void* copyDest = result->writable_data();
406 for (const auto& part : parts) {
407 memcpy(copyDest, part->data(), part->size());
408 copyDest = SkTAddOffset<void>(copyDest, part->size());
409 }
410 return result;
411}
#define SkCodecPrintf(...)
Definition: SkCodecPriv.h:23
static bool marker_has_signature(const SkJpegMarker &marker, const uint32_t targetMarker, const uint8_t *signature, size_t signatureSize)
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
Definition: SkData.h:116
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
GAsyncResult * result
SeparatedVector2 offset
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63