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

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

Issue 2651883004: libwebp-0.6.0-rc1 (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « third_party/libwebp/dec/webp.c ('k') | third_party/libwebp/dec/webpi.h » ('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.
11 // 11 //
12 // Author: Skal (pascal.massimino@gmail.com) 12 // Author: Skal (pascal.massimino@gmail.com)
13 13
14 #include <stdlib.h> 14 #include <stdlib.h>
15 15
16 #include "./vp8i.h" 16 #include "./vp8i_dec.h"
17 #include "./vp8li.h" 17 #include "./vp8li_dec.h"
18 #include "./webpi.h" 18 #include "./webpi_dec.h"
19 #include "../utils/utils.h" 19 #include "../utils/utils.h"
20 #include "../webp/mux_types.h" // ALPHA_FLAG 20 #include "../webp/mux_types.h" // ALPHA_FLAG
21 21
22 //------------------------------------------------------------------------------ 22 //------------------------------------------------------------------------------
23 // RIFF layout is: 23 // RIFF layout is:
24 // Offset tag 24 // Offset tag
25 // 0...3 "RIFF" 4-byte tag 25 // 0...3 "RIFF" 4-byte tag
26 // 4...7 size of image data (including metadata) starting at offset 8 26 // 4...7 size of image data (including metadata) starting at offset 8
27 // 8...11 "WEBP" our form-type signature 27 // 8...11 "WEBP" our form-type signature
28 // The RIFF container (12 bytes) is followed by appropriate chunks: 28 // The RIFF container (12 bytes) is followed by appropriate chunks:
29 // 12..15 "VP8 ": 4-bytes tags, signaling the use of VP8 video format 29 // 12..15 "VP8 ": 4-bytes tags, signaling the use of VP8 video format
30 // 16..19 size of the raw VP8 image data, starting at offset 20 30 // 16..19 size of the raw VP8 image data, starting at offset 20
31 // 20.... the VP8 bytes 31 // 20.... the VP8 bytes
32 // Or, 32 // Or,
33 // 12..15 "VP8L": 4-bytes tags, signaling the use of VP8L lossless format 33 // 12..15 "VP8L": 4-bytes tags, signaling the use of VP8L lossless format
34 // 16..19 size of the raw VP8L image data, starting at offset 20 34 // 16..19 size of the raw VP8L image data, starting at offset 20
35 // 20.... the VP8L bytes 35 // 20.... the VP8L bytes
36 // Or, 36 // Or,
37 // 12..15 "VP8X": 4-bytes tags, describing the extended-VP8 chunk. 37 // 12..15 "VP8X": 4-bytes tags, describing the extended-VP8 chunk.
38 // 16..19 size of the VP8X chunk starting at offset 20. 38 // 16..19 size of the VP8X chunk starting at offset 20.
39 // 20..23 VP8X flags bit-map corresponding to the chunk-types present. 39 // 20..23 VP8X flags bit-map corresponding to the chunk-types present.
40 // 24..26 Width of the Canvas Image. 40 // 24..26 Width of the Canvas Image.
41 // 27..29 Height of the Canvas Image. 41 // 27..29 Height of the Canvas Image.
42 // There can be extra chunks after the "VP8X" chunk (ICCP, FRGM, ANMF, VP8, 42 // There can be extra chunks after the "VP8X" chunk (ICCP, ANMF, VP8, VP8L,
43 // VP8L, XMP, EXIF ...) 43 // XMP, EXIF ...)
44 // All sizes are in little-endian order. 44 // All sizes are in little-endian order.
45 // Note: chunk data size must be padded to multiple of 2 when written. 45 // Note: chunk data size must be padded to multiple of 2 when written.
46 46
47 // Validates the RIFF container (if detected) and skips over it. 47 // Validates the RIFF container (if detected) and skips over it.
48 // If a RIFF container is detected, returns: 48 // If a RIFF container is detected, returns:
49 // VP8_STATUS_BITSTREAM_ERROR for invalid header, 49 // VP8_STATUS_BITSTREAM_ERROR for invalid header,
50 // VP8_STATUS_NOT_ENOUGH_DATA for truncated data if have_all_data is true, 50 // VP8_STATUS_NOT_ENOUGH_DATA for truncated data if have_all_data is true,
51 // and VP8_STATUS_OK otherwise. 51 // and VP8_STATUS_OK otherwise.
52 // In case there are not enough bytes (partial RIFF container), return 0 for 52 // In case there are not enough bytes (partial RIFF container), return 0 for
53 // *riff_size. Else return the RIFF size extracted from the header. 53 // *riff_size. Else return the RIFF size extracted from the header.
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 int* const has_animation, 282 int* const has_animation,
283 int* const format, 283 int* const format,
284 WebPHeaderStructure* const headers) { 284 WebPHeaderStructure* const headers) {
285 int canvas_width = 0; 285 int canvas_width = 0;
286 int canvas_height = 0; 286 int canvas_height = 0;
287 int image_width = 0; 287 int image_width = 0;
288 int image_height = 0; 288 int image_height = 0;
289 int found_riff = 0; 289 int found_riff = 0;
290 int found_vp8x = 0; 290 int found_vp8x = 0;
291 int animation_present = 0; 291 int animation_present = 0;
292 int fragments_present = 0;
293 const int have_all_data = (headers != NULL) ? headers->have_all_data : 0; 292 const int have_all_data = (headers != NULL) ? headers->have_all_data : 0;
294 293
295 VP8StatusCode status; 294 VP8StatusCode status;
296 WebPHeaderStructure hdrs; 295 WebPHeaderStructure hdrs;
297 296
298 if (data == NULL || data_size < RIFF_HEADER_SIZE) { 297 if (data == NULL || data_size < RIFF_HEADER_SIZE) {
299 return VP8_STATUS_NOT_ENOUGH_DATA; 298 return VP8_STATUS_NOT_ENOUGH_DATA;
300 } 299 }
301 memset(&hdrs, 0, sizeof(hdrs)); 300 memset(&hdrs, 0, sizeof(hdrs));
302 hdrs.data = data; 301 hdrs.data = data;
303 hdrs.data_size = data_size; 302 hdrs.data_size = data_size;
304 303
305 // Skip over RIFF header. 304 // Skip over RIFF header.
306 status = ParseRIFF(&data, &data_size, have_all_data, &hdrs.riff_size); 305 status = ParseRIFF(&data, &data_size, have_all_data, &hdrs.riff_size);
307 if (status != VP8_STATUS_OK) { 306 if (status != VP8_STATUS_OK) {
308 return status; // Wrong RIFF header / insufficient data. 307 return status; // Wrong RIFF header / insufficient data.
309 } 308 }
310 found_riff = (hdrs.riff_size > 0); 309 found_riff = (hdrs.riff_size > 0);
311 310
312 // Skip over VP8X. 311 // Skip over VP8X.
313 { 312 {
314 uint32_t flags = 0; 313 uint32_t flags = 0;
315 status = ParseVP8X(&data, &data_size, &found_vp8x, 314 status = ParseVP8X(&data, &data_size, &found_vp8x,
316 &canvas_width, &canvas_height, &flags); 315 &canvas_width, &canvas_height, &flags);
317 if (status != VP8_STATUS_OK) { 316 if (status != VP8_STATUS_OK) {
318 return status; // Wrong VP8X / insufficient data. 317 return status; // Wrong VP8X / insufficient data.
319 } 318 }
320 animation_present = !!(flags & ANIMATION_FLAG); 319 animation_present = !!(flags & ANIMATION_FLAG);
321 fragments_present = !!(flags & FRAGMENTS_FLAG);
322 if (!found_riff && found_vp8x) { 320 if (!found_riff && found_vp8x) {
323 // Note: This restriction may be removed in the future, if it becomes 321 // Note: This restriction may be removed in the future, if it becomes
324 // necessary to send VP8X chunk to the decoder. 322 // necessary to send VP8X chunk to the decoder.
325 return VP8_STATUS_BITSTREAM_ERROR; 323 return VP8_STATUS_BITSTREAM_ERROR;
326 } 324 }
327 if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG); 325 if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG);
328 if (has_animation != NULL) *has_animation = animation_present; 326 if (has_animation != NULL) *has_animation = animation_present;
329 if (format != NULL) *format = 0; // default = undefined 327 if (format != NULL) *format = 0; // default = undefined
330 328
331 if (found_vp8x && (animation_present || fragments_present) && 329 if (found_vp8x && animation_present && headers == NULL) {
332 headers == NULL) {
333 if (width != NULL) *width = canvas_width; 330 if (width != NULL) *width = canvas_width;
334 if (height != NULL) *height = canvas_height; 331 if (height != NULL) *height = canvas_height;
335 return VP8_STATUS_OK; // Just return features from VP8X header. 332 return VP8_STATUS_OK; // Just return features from VP8X header.
336 } 333 }
337 } 334 }
338 335
339 if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA; 336 if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA;
340 337
341 // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH". 338 // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH".
342 if ((found_riff && found_vp8x) || 339 if ((found_riff && found_vp8x) ||
343 (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) { 340 (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) {
344 status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size, 341 status = ParseOptionalChunks(&data, &data_size, hdrs.riff_size,
345 &hdrs.alpha_data, &hdrs.alpha_data_size); 342 &hdrs.alpha_data, &hdrs.alpha_data_size);
346 if (status != VP8_STATUS_OK) { 343 if (status != VP8_STATUS_OK) {
347 return status; // Found an invalid chunk size / insufficient data. 344 return status; // Found an invalid chunk size / insufficient data.
348 } 345 }
349 } 346 }
350 347
351 // Skip over VP8/VP8L header. 348 // Skip over VP8/VP8L header.
352 status = ParseVP8Header(&data, &data_size, have_all_data, hdrs.riff_size, 349 status = ParseVP8Header(&data, &data_size, have_all_data, hdrs.riff_size,
353 &hdrs.compressed_size, &hdrs.is_lossless); 350 &hdrs.compressed_size, &hdrs.is_lossless);
354 if (status != VP8_STATUS_OK) { 351 if (status != VP8_STATUS_OK) {
355 return status; // Wrong VP8/VP8L chunk-header / insufficient data. 352 return status; // Wrong VP8/VP8L chunk-header / insufficient data.
356 } 353 }
357 if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) { 354 if (hdrs.compressed_size > MAX_CHUNK_PAYLOAD) {
358 return VP8_STATUS_BITSTREAM_ERROR; 355 return VP8_STATUS_BITSTREAM_ERROR;
359 } 356 }
360 357
361 if (format != NULL && !(animation_present || fragments_present)) { 358 if (format != NULL && !animation_present) {
362 *format = hdrs.is_lossless ? 2 : 1; 359 *format = hdrs.is_lossless ? 2 : 1;
363 } 360 }
364 361
365 if (!hdrs.is_lossless) { 362 if (!hdrs.is_lossless) {
366 if (data_size < VP8_FRAME_HEADER_SIZE) { 363 if (data_size < VP8_FRAME_HEADER_SIZE) {
367 return VP8_STATUS_NOT_ENOUGH_DATA; 364 return VP8_STATUS_NOT_ENOUGH_DATA;
368 } 365 }
369 // Validates raw VP8 data. 366 // Validates raw VP8 data.
370 if (!VP8GetInfo(data, data_size, (uint32_t)hdrs.compressed_size, 367 if (!VP8GetInfo(data, data_size, (uint32_t)hdrs.compressed_size,
371 &image_width, &image_height)) { 368 &image_width, &image_height)) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 if (io->use_scaling) { 822 if (io->use_scaling) {
826 // disable filter (only for large downscaling ratio). 823 // disable filter (only for large downscaling ratio).
827 io->bypass_filtering = (io->scaled_width < W * 3 / 4) && 824 io->bypass_filtering = (io->scaled_width < W * 3 / 4) &&
828 (io->scaled_height < H * 3 / 4); 825 (io->scaled_height < H * 3 / 4);
829 io->fancy_upsampling = 0; 826 io->fancy_upsampling = 0;
830 } 827 }
831 return 1; 828 return 1;
832 } 829 }
833 830
834 //------------------------------------------------------------------------------ 831 //------------------------------------------------------------------------------
OLDNEW
« no previous file with comments | « third_party/libwebp/dec/webp.c ('k') | third_party/libwebp/dec/webpi.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698