Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: third_party/libwebp/dec/webp.c

Issue 18528004: libwebp: upstream canvas size check cherry-picks (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/libwebp/README.chromium ('k') | third_party/libwebp/demux/demux.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 Google Inc. All Rights Reserved. 1 // Copyright 2010 Google Inc. All Rights Reserved.
2 // 2 //
3 // Use of this source code is governed by a BSD-style license 3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source 4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found 5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may 6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree. 7 // be found in the AUTHORS file in the root of the source tree.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 // 9 //
10 // Main decoding functions for WEBP images. 10 // Main decoding functions for WEBP images.
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 // RIFF + VP8X + (optional chunks) + VP8(L) 279 // RIFF + VP8X + (optional chunks) + VP8(L)
280 // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. 280 // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
281 // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. 281 // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
282 static VP8StatusCode ParseHeadersInternal(const uint8_t* data, 282 static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
283 size_t data_size, 283 size_t data_size,
284 int* const width, 284 int* const width,
285 int* const height, 285 int* const height,
286 int* const has_alpha, 286 int* const has_alpha,
287 int* const has_animation, 287 int* const has_animation,
288 WebPHeaderStructure* const headers) { 288 WebPHeaderStructure* const headers) {
289 int canvas_width = 0;
290 int canvas_height = 0;
291 int image_width = 0;
292 int image_height = 0;
289 int found_riff = 0; 293 int found_riff = 0;
290 int found_vp8x = 0; 294 int found_vp8x = 0;
291 VP8StatusCode status; 295 VP8StatusCode status;
292 WebPHeaderStructure hdrs; 296 WebPHeaderStructure hdrs;
293 297
294 if (data == NULL || data_size < RIFF_HEADER_SIZE) { 298 if (data == NULL || data_size < RIFF_HEADER_SIZE) {
295 return VP8_STATUS_NOT_ENOUGH_DATA; 299 return VP8_STATUS_NOT_ENOUGH_DATA;
296 } 300 }
297 memset(&hdrs, 0, sizeof(hdrs)); 301 memset(&hdrs, 0, sizeof(hdrs));
298 hdrs.data = data; 302 hdrs.data = data;
299 hdrs.data_size = data_size; 303 hdrs.data_size = data_size;
300 304
301 // Skip over RIFF header. 305 // Skip over RIFF header.
302 status = ParseRIFF(&data, &data_size, &hdrs.riff_size); 306 status = ParseRIFF(&data, &data_size, &hdrs.riff_size);
303 if (status != VP8_STATUS_OK) { 307 if (status != VP8_STATUS_OK) {
304 return status; // Wrong RIFF header / insufficient data. 308 return status; // Wrong RIFF header / insufficient data.
305 } 309 }
306 found_riff = (hdrs.riff_size > 0); 310 found_riff = (hdrs.riff_size > 0);
307 311
308 // Skip over VP8X. 312 // Skip over VP8X.
309 { 313 {
310 uint32_t flags = 0; 314 uint32_t flags = 0;
311 status = ParseVP8X(&data, &data_size, &found_vp8x, width, height, &flags); 315 int animation_present;
316 status = ParseVP8X(&data, &data_size, &found_vp8x,
317 &canvas_width, &canvas_height, &flags);
312 if (status != VP8_STATUS_OK) { 318 if (status != VP8_STATUS_OK) {
313 return status; // Wrong VP8X / insufficient data. 319 return status; // Wrong VP8X / insufficient data.
314 } 320 }
321 animation_present = !!(flags & ANIMATION_FLAG);
315 if (!found_riff && found_vp8x) { 322 if (!found_riff && found_vp8x) {
316 // Note: This restriction may be removed in the future, if it becomes 323 // Note: This restriction may be removed in the future, if it becomes
317 // necessary to send VP8X chunk to the decoder. 324 // necessary to send VP8X chunk to the decoder.
318 return VP8_STATUS_BITSTREAM_ERROR; 325 return VP8_STATUS_BITSTREAM_ERROR;
319 } 326 }
320 if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG); 327 if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG);
321 if (has_animation != NULL) *has_animation = !!(flags & ANIMATION_FLAG); 328 if (has_animation != NULL) *has_animation = animation_present;
322 if (found_vp8x && headers == NULL) { 329
323 return VP8_STATUS_OK; // Return features from VP8X header. 330 if (found_vp8x && animation_present && headers == NULL) {
331 if (width != NULL) *width = canvas_width;
332 if (height != NULL) *height = canvas_height;
333 return VP8_STATUS_OK; // Just return features from VP8X header.
324 } 334 }
325 } 335 }
326 336
327 if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA; 337 if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA;
328 338
329 // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH". 339 // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH".
330 if ((found_riff && found_vp8x) || 340 if ((found_riff && found_vp8x) ||
331 (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) { 341 (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) {
332 status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size, 342 status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size,
333 &hdrs.alpha_data, &hdrs.alpha_data_size); 343 &hdrs.alpha_data, &hdrs.alpha_data_size);
(...skipping 10 matching lines...) Expand all
344 } 354 }
345 if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) { 355 if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) {
346 return VP8_STATUS_BITSTREAM_ERROR; 356 return VP8_STATUS_BITSTREAM_ERROR;
347 } 357 }
348 358
349 if (!hdrs.is_lossless) { 359 if (!hdrs.is_lossless) {
350 if (data_size < VP8_FRAME_HEADER_SIZE) { 360 if (data_size < VP8_FRAME_HEADER_SIZE) {
351 return VP8_STATUS_NOT_ENOUGH_DATA; 361 return VP8_STATUS_NOT_ENOUGH_DATA;
352 } 362 }
353 // Validates raw VP8 data. 363 // Validates raw VP8 data.
354 if (!VP8GetInfo(data, data_size, 364 if (!VP8GetInfo(data, data_size, (uint32_t)hdrs.compressed_size,
355 (uint32_t)hdrs.compressed_size, width, height)) { 365 &image_width, &image_height)) {
356 return VP8_STATUS_BITSTREAM_ERROR; 366 return VP8_STATUS_BITSTREAM_ERROR;
357 } 367 }
358 } else { 368 } else {
359 if (data_size < VP8L_FRAME_HEADER_SIZE) { 369 if (data_size < VP8L_FRAME_HEADER_SIZE) {
360 return VP8_STATUS_NOT_ENOUGH_DATA; 370 return VP8_STATUS_NOT_ENOUGH_DATA;
361 } 371 }
362 // Validates raw VP8L data. 372 // Validates raw VP8L data.
363 if (!VP8LGetInfo(data, data_size, width, height, has_alpha)) { 373 if (!VP8LGetInfo(data, data_size, &image_width, &image_height, has_alpha)) {
364 return VP8_STATUS_BITSTREAM_ERROR; 374 return VP8_STATUS_BITSTREAM_ERROR;
365 } 375 }
366 } 376 }
367 377 // Validates image size coherency. TODO(urvang): what about FRGM?
378 if (found_vp8x) {
379 if (canvas_width != image_width || canvas_height != image_height) {
380 return VP8_STATUS_BITSTREAM_ERROR;
381 }
382 }
383 if (width != NULL) *width = image_width;
384 if (height != NULL) *height = image_height;
368 if (has_alpha != NULL) { 385 if (has_alpha != NULL) {
369 // If the data did not contain a VP8X/VP8L chunk the only definitive way 386 // If the data did not contain a VP8X/VP8L chunk the only definitive way
370 // to set this is by looking for alpha data (from an ALPH chunk). 387 // to set this is by looking for alpha data (from an ALPH chunk).
371 *has_alpha |= (hdrs.alpha_data != NULL); 388 *has_alpha |= (hdrs.alpha_data != NULL);
372 } 389 }
373 if (headers != NULL) { 390 if (headers != NULL) {
374 *headers = hdrs; 391 *headers = hdrs;
375 headers->offset = data - headers->data; 392 headers->offset = data - headers->data;
376 assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD); 393 assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD);
377 assert(headers->offset == headers->data_size - data_size); 394 assert(headers->offset == headers->data_size - data_size);
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 io->fancy_upsampling = 0; 799 io->fancy_upsampling = 0;
783 } 800 }
784 return 1; 801 return 1;
785 } 802 }
786 803
787 //------------------------------------------------------------------------------ 804 //------------------------------------------------------------------------------
788 805
789 #if defined(__cplusplus) || defined(c_plusplus) 806 #if defined(__cplusplus) || defined(c_plusplus)
790 } // extern "C" 807 } // extern "C"
791 #endif 808 #endif
OLDNEW
« no previous file with comments | « third_party/libwebp/README.chromium ('k') | third_party/libwebp/demux/demux.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698