Flutter Engine
The Flutter Engine
SkJpegSegmentScan.h
Go to the documentation of this file.
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 SkJpegSegmentScan_codec_DEFINED
9#define SkJpegSegmentScan_codec_DEFINED
10
13
14#include <cstddef>
15#include <cstdint>
16#include <memory>
17#include <vector>
18
19class SkData;
20class SkStream;
21
22/*
23 * A JPEG segment.
24 */
26 // The offset in bytes from the initial position to where this segment starts.
27 size_t offset = 0;
28 // The second byte of the marker code, which determines the segment type.
29 uint8_t marker = 0;
30 // The length of the parameters for this segment (including the two bytes used to specify
31 // the length).
32 uint16_t parameterLength = 0;
33};
34
35/*
36 * Class for scanning JPEG data. The JPEG format consists of a sequence of segments that begin with
37 * a marker, with entropy-coded data in between.
38 */
40public:
41 SkJpegSegmentScanner(uint8_t stopMarker = kJpegMarkerEndOfImage);
42
43 bool isDone() const { return fState == State::kDone; }
44 bool hadError() const { return fState == State::kError; }
45
46 // Provide more bytes of data to the state machine.
47 void onBytes(const void* data, size_t size);
48
49 // Return the segments that have been retrieved so far. If an error was encountered, this will
50 // include all segments up to the error.
51 const std::vector<SkJpegSegment>& getSegments() const;
52
53 // Helper function to retrieve the parameters for a segment. ScannedData must be the data that
54 // was scanned to produce segment, starting at StartOfImage.
55 static sk_sp<SkData> GetParameters(const SkData* scannedData, const SkJpegSegment& segment);
56
57private:
58 // The scanner is a state machine. State transitions happen when a byte is read.
59 enum class State {
60 // The initial state, before we read the 0xFF,0xD8,0xFF JPEG signature.
61 kStartOfImageByte0,
62 // We have read the 0xFF of the JPEG signature.
63 kStartOfImageByte1,
64 // We have read the 0xFF,0xD8 of the JPEG signature. The next byte should be the 0xFF that
65 // completes the JPEG signature and starts the second marker (the one after StartOfImage).
66 kSecondMarkerByte0,
67 // We have read the full JPEG signature. The next byte should be the the second byte of the
68 // second marker.
69 kSecondMarkerByte1,
70 // We have read a marker that does not stand alone. The next byte is the first byte of the
71 // length of the parameters,
72 kSegmentParamLengthByte0,
73 // We have read the first byte of the length of the parameters (and it is stored in
74 // |fSegmentParamLengthByte0|). The next byte we read is the second byte of the length of
75 // the parameters.
76 kSegmentParamLengthByte1,
77 // We have read the full length of the parameters. The next |fSegmentParamBytesRemaining|
78 // bytes are the parameters.
79 kSegmentParam,
80 // We have read a marker and (optionally) its parameters, and we are now reading entropy-
81 // coded data. All subsequent bytes until we reach 0xFF are entropy-coded data.
82 kEntropyCodedData,
83 // We reached an 0xFF in entropy-coded data. If the next byte is 0x00 then we continue
84 // reading entropy-coded data. If the next byte is 0xFF then we are reading fill data.
85 // If the next byte is anything else then it is the second byte of a marker.
86 kEntropyCodedDataSentinel,
87 // We are reading fill data. If the next byte is 0xFF then we are still reading fill data,
88 // otherwise the next byte is the second byte of a marker.
89 kPostEntropyCodedDataFill,
90 // We reached |fStopMarker| and have stopped tracking our state.
91 kDone,
92 // We hit an error somewhere and have given up.
93 kError,
94 };
95 State fState = State::kStartOfImageByte0;
96
97 // Update state transition when a single byte is read.
98 void onByte(uint8_t byte);
99
100 // Perform the appropriate state transition for when a marker is read. This will set
101 // |fCurrentSegmentMarker| and |fCurrentSegmentOffset|, and potentially call saveCurrentSegment.
102 void onMarkerSecondByte(uint8_t byte);
103
104 // Add a new entry in |segments| for |fCurrentSegmentMarker| and offset |fCurrentSegmentOffset|
105 // and the specified length.
106 void saveCurrentSegment(uint16_t length);
107
108 static bool MarkerStandsAlone(uint8_t marker) {
109 // These markers are TEM (0x01), RSTm (0xD0 through 0xD7), SOI (0xD8), and
110 // EOI (0xD9). See section B.1.1.3, Marker assignments.
111 return marker == 0x01 || (marker >= 0xD0 && marker <= 0xD9);
112 }
113
114 // Stop tracking state when we hit this marker. If this is 0x00, then never stop.
115 const uint8_t fStopMarker;
116
117 // The number of bytes that have been processed so far.
118 size_t fOffset = 0;
119
120 // If |fState| is kSegmentParamLengthByte1, then this is the value of the the previous byte.
121 uint8_t fSegmentParamLengthByte0 = 0;
122
123 // If |fState| is kSegmentParam, then this is the number of bytes reamining in the current
124 // segment.
125 size_t fSegmentParamBytesRemaining = 0;
126
127 // The offset and marker for the segment started by the previous call to OnMarkerSecondByte.
128 // These are re-set when SaveCurrentSegment is called.
129 size_t fCurrentSegmentOffset = 0;
130 uint8_t fCurrentSegmentMarker = 0;
131
132 std::vector<SkJpegSegment> fSegments;
133};
134
135#endif
static const char marker[]
static constexpr uint8_t kJpegMarkerEndOfImage
Definition: SkData.h:25
const std::vector< SkJpegSegment > & getSegments() const
static sk_sp< SkData > GetParameters(const SkData *scannedData, const SkJpegSegment &segment)
SkJpegSegmentScanner(uint8_t stopMarker=kJpegMarkerEndOfImage)
void onBytes(const void *data, size_t size)
size_t length
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
uint16_t parameterLength
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63