MCPcopy Create free account
hub / github.com/Tencent/libpag / ParseOptionalChunks

Function ParseOptionalChunks

src/codec/utils/WebpDecoder.cpp:120–183  ·  view source on GitHub ↗

Skips to the next VP8/VP8L chunk header in the data given the size of the RIFF chunk 'riff_size'. Returns VP8_STATUS_BITSTREAM_ERROR if any invalid chunk size is encountered, VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and VP8_STATUS_OK otherwise. If an alpha chunk is found, *alpha_data and *alpha_size are set appropriately.

Source from the content-addressed store, hash-verified

118// If an alpha chunk is found, *alpha_data and *alpha_size are set
119// appropriately.
120static VP8StatusCode ParseOptionalChunks(const uint8_t** const data, size_t* const data_size,
121 size_t const riff_size, const uint8_t** const alpha_data,
122 size_t* const alpha_size) {
123 const uint8_t* buf;
124 size_t buf_size;
125 uint32_t total_size = TAG_SIZE + // "WEBP".
126 CHUNK_HEADER_SIZE + // "VP8Xnnnn".
127 VP8X_CHUNK_SIZE; // data.
128 assert(data != nullptr);
129 assert(data_size != nullptr);
130 buf = *data;
131 buf_size = *data_size;
132
133 assert(alpha_data != nullptr);
134 assert(alpha_size != nullptr);
135 *alpha_data = nullptr;
136 *alpha_size = 0;
137
138 while (1) {
139 uint32_t chunk_size;
140 uint32_t disk_chunk_size; // chunk_size with padding
141
142 *data = buf;
143 *data_size = buf_size;
144
145 if (buf_size < CHUNK_HEADER_SIZE) { // Insufficient data.
146 return VP8_STATUS_NOT_ENOUGH_DATA;
147 }
148
149 chunk_size = GetLE32(buf + TAG_SIZE);
150 if (chunk_size > MAX_CHUNK_PAYLOAD) {
151 return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
152 }
153 // For odd-sized chunk-payload, there's one byte padding at the end.
154 disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
155 total_size += disk_chunk_size;
156
157 // Check that total bytes skipped so far does not exceed riff_size.
158 if (riff_size > 0 && (total_size > riff_size)) {
159 return VP8_STATUS_BITSTREAM_ERROR; // Not a valid chunk size.
160 }
161
162 // Start of a (possibly incomplete) VP8/VP8L chunk implies that we have
163 // parsed all the optional chunks.
164 // Note: This check must occur before the check 'buf_size < disk_chunk_size'
165 // below to allow incomplete VP8/VP8L chunks.
166 if (!memcmp(buf, "VP8 ", TAG_SIZE) || !memcmp(buf, "VP8L", TAG_SIZE)) {
167 return VP8_STATUS_OK;
168 }
169
170 if (buf_size < disk_chunk_size) { // Insufficient data.
171 return VP8_STATUS_NOT_ENOUGH_DATA;
172 }
173
174 if (!memcmp(buf, "ALPH", TAG_SIZE)) { // A valid ALPH header.
175 *alpha_data = buf + CHUNK_HEADER_SIZE;
176 *alpha_size = chunk_size;
177 }

Callers 1

ParseHeadersInternalFunction · 0.85

Calls 1

GetLE32Function · 0.85

Tested by

no test coverage detected