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

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

Issue 12942006: libwebp: update snapshot to v0.3.0-rc6 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: local webkit layout expectations Created 7 years, 9 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
OLDNEW
1 // Copyright 2010 Google Inc. All Rights Reserved. 1 // Copyright 2010 Google Inc. All Rights Reserved.
2 // 2 //
3 // This code is licensed under the same terms as WebM: 3 // This code is licensed under the same terms as WebM:
4 // Software License Agreement: http://www.webmproject.org/license/software/ 4 // Software License Agreement: http://www.webmproject.org/license/software/
5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/
6 // ----------------------------------------------------------------------------- 6 // -----------------------------------------------------------------------------
7 // 7 //
8 // Main decoding functions for WEBP images. 8 // Main decoding functions for WEBP images.
9 // 9 //
10 // Author: Skal (pascal.massimino@gmail.com) 10 // Author: Skal (pascal.massimino@gmail.com)
11 11
12 #include <stdlib.h> 12 #include <stdlib.h>
13 13
14 #include "./vp8i.h" 14 #include "./vp8i.h"
15 #include "./vp8li.h" 15 #include "./vp8li.h"
16 #include "./webpi.h" 16 #include "./webpi.h"
17 #include "../webp/format_constants.h" 17 #include "../webp/mux_types.h" // ALPHA_FLAG
18 18
19 #if defined(__cplusplus) || defined(c_plusplus) 19 #if defined(__cplusplus) || defined(c_plusplus)
20 extern "C" { 20 extern "C" {
21 #endif 21 #endif
22 22
23 //------------------------------------------------------------------------------ 23 //------------------------------------------------------------------------------
24 // RIFF layout is: 24 // RIFF layout is:
25 // Offset tag 25 // Offset tag
26 // 0...3 "RIFF" 4-byte tag 26 // 0...3 "RIFF" 4-byte tag
27 // 4...7 size of image data (including metadata) starting at offset 8 27 // 4...7 size of image data (including metadata) starting at offset 8
28 // 8...11 "WEBP" our form-type signature 28 // 8...11 "WEBP" our form-type signature
29 // The RIFF container (12 bytes) is followed by appropriate chunks: 29 // The RIFF container (12 bytes) is followed by appropriate chunks:
30 // 12..15 "VP8 ": 4-bytes tags, signaling the use of VP8 video format 30 // 12..15 "VP8 ": 4-bytes tags, signaling the use of VP8 video format
31 // 16..19 size of the raw VP8 image data, starting at offset 20 31 // 16..19 size of the raw VP8 image data, starting at offset 20
32 // 20.... the VP8 bytes 32 // 20.... the VP8 bytes
33 // Or, 33 // Or,
34 // 12..15 "VP8L": 4-bytes tags, signaling the use of VP8L lossless format 34 // 12..15 "VP8L": 4-bytes tags, signaling the use of VP8L lossless format
35 // 16..19 size of the raw VP8L image data, starting at offset 20 35 // 16..19 size of the raw VP8L image data, starting at offset 20
36 // 20.... the VP8L bytes 36 // 20.... the VP8L bytes
37 // Or, 37 // Or,
38 // 12..15 "VP8X": 4-bytes tags, describing the extended-VP8 chunk. 38 // 12..15 "VP8X": 4-bytes tags, describing the extended-VP8 chunk.
39 // 16..19 size of the VP8X chunk starting at offset 20. 39 // 16..19 size of the VP8X chunk starting at offset 20.
40 // 20..23 VP8X flags bit-map corresponding to the chunk-types present. 40 // 20..23 VP8X flags bit-map corresponding to the chunk-types present.
41 // 24..26 Width of the Canvas Image. 41 // 24..26 Width of the Canvas Image.
42 // 27..29 Height of the Canvas Image. 42 // 27..29 Height of the Canvas Image.
43 // There can be extra chunks after the "VP8X" chunk (ICCP, TILE, FRM, VP8, 43 // There can be extra chunks after the "VP8X" chunk (ICCP, FRGM, ANMF, VP8,
44 // META ...) 44 // VP8L, XMP, EXIF ...)
45 // All sizes are in little-endian order. 45 // All sizes are in little-endian order.
46 // Note: chunk data size must be padded to multiple of 2 when written. 46 // Note: chunk data size must be padded to multiple of 2 when written.
47 47
48 static WEBP_INLINE uint32_t get_le24(const uint8_t* const data) { 48 static WEBP_INLINE uint32_t get_le24(const uint8_t* const data) {
49 return data[0] | (data[1] << 8) | (data[2] << 16); 49 return data[0] | (data[1] << 8) | (data[2] << 16);
50 } 50 }
51 51
52 static WEBP_INLINE uint32_t get_le32(const uint8_t* const data) { 52 static WEBP_INLINE uint32_t get_le32(const uint8_t* const data) {
53 return (uint32_t)get_le24(data) | (data[3] << 24); 53 return (uint32_t)get_le24(data) | (data[3] << 24);
54 } 54 }
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 // considered valid by this function: 269 // considered valid by this function:
270 // RIFF + VP8(L) 270 // RIFF + VP8(L)
271 // RIFF + VP8X + (optional chunks) + VP8(L) 271 // RIFF + VP8X + (optional chunks) + VP8(L)
272 // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose. 272 // ALPH + VP8 <-- Not a valid WebP format: only allowed for internal purpose.
273 // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose. 273 // VP8(L) <-- Not a valid WebP format: only allowed for internal purpose.
274 static VP8StatusCode ParseHeadersInternal(const uint8_t* data, 274 static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
275 size_t data_size, 275 size_t data_size,
276 int* const width, 276 int* const width,
277 int* const height, 277 int* const height,
278 int* const has_alpha, 278 int* const has_alpha,
279 int* const has_animation,
279 WebPHeaderStructure* const headers) { 280 WebPHeaderStructure* const headers) {
280 int found_riff = 0; 281 int found_riff = 0;
281 int found_vp8x = 0; 282 int found_vp8x = 0;
282 VP8StatusCode status; 283 VP8StatusCode status;
283 WebPHeaderStructure hdrs; 284 WebPHeaderStructure hdrs;
284 285
285 if (data == NULL || data_size < RIFF_HEADER_SIZE) { 286 if (data == NULL || data_size < RIFF_HEADER_SIZE) {
286 return VP8_STATUS_NOT_ENOUGH_DATA; 287 return VP8_STATUS_NOT_ENOUGH_DATA;
287 } 288 }
288 memset(&hdrs, 0, sizeof(hdrs)); 289 memset(&hdrs, 0, sizeof(hdrs));
(...skipping 12 matching lines...) Expand all
301 uint32_t flags = 0; 302 uint32_t flags = 0;
302 status = ParseVP8X(&data, &data_size, &found_vp8x, width, height, &flags); 303 status = ParseVP8X(&data, &data_size, &found_vp8x, width, height, &flags);
303 if (status != VP8_STATUS_OK) { 304 if (status != VP8_STATUS_OK) {
304 return status; // Wrong VP8X / insufficient data. 305 return status; // Wrong VP8X / insufficient data.
305 } 306 }
306 if (!found_riff && found_vp8x) { 307 if (!found_riff && found_vp8x) {
307 // Note: This restriction may be removed in the future, if it becomes 308 // Note: This restriction may be removed in the future, if it becomes
308 // necessary to send VP8X chunk to the decoder. 309 // necessary to send VP8X chunk to the decoder.
309 return VP8_STATUS_BITSTREAM_ERROR; 310 return VP8_STATUS_BITSTREAM_ERROR;
310 } 311 }
311 if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG_BIT); 312 if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG);
313 if (has_animation != NULL) *has_animation = !!(flags & ANIMATION_FLAG);
312 if (found_vp8x && headers == NULL) { 314 if (found_vp8x && headers == NULL) {
313 return VP8_STATUS_OK; // Return features from VP8X header. 315 return VP8_STATUS_OK; // Return features from VP8X header.
314 } 316 }
315 } 317 }
316 318
317 if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA; 319 if (data_size < TAG_SIZE) return VP8_STATUS_NOT_ENOUGH_DATA;
318 320
319 // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH". 321 // Skip over optional chunks if data started with "RIFF + VP8X" or "ALPH".
320 if ((found_riff && found_vp8x) || 322 if ((found_riff && found_vp8x) ||
321 (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) { 323 (!found_riff && !found_vp8x && !memcmp(data, "ALPH", TAG_SIZE))) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 if (headers != NULL) { 365 if (headers != NULL) {
364 *headers = hdrs; 366 *headers = hdrs;
365 headers->offset = data - headers->data; 367 headers->offset = data - headers->data;
366 assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD); 368 assert((uint64_t)(data - headers->data) < MAX_CHUNK_PAYLOAD);
367 assert(headers->offset == headers->data_size - data_size); 369 assert(headers->offset == headers->data_size - data_size);
368 } 370 }
369 return VP8_STATUS_OK; // Return features from VP8 header. 371 return VP8_STATUS_OK; // Return features from VP8 header.
370 } 372 }
371 373
372 VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { 374 VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
375 VP8StatusCode status;
376 int has_animation = 0;
373 assert(headers != NULL); 377 assert(headers != NULL);
374 // fill out headers, ignore width/height/has_alpha. 378 // fill out headers, ignore width/height/has_alpha.
375 return ParseHeadersInternal(headers->data, headers->data_size, 379 status = ParseHeadersInternal(headers->data, headers->data_size,
376 NULL, NULL, NULL, headers); 380 NULL, NULL, NULL, &has_animation, headers);
381 if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
382 // TODO(jzern): full support of animation frames will require API additions.
383 if (has_animation) {
384 status = VP8_STATUS_UNSUPPORTED_FEATURE;
385 }
386 }
387 return status;
377 } 388 }
378 389
379 //------------------------------------------------------------------------------ 390 //------------------------------------------------------------------------------
380 // WebPDecParams 391 // WebPDecParams
381 392
382 void WebPResetDecParams(WebPDecParams* const params) { 393 void WebPResetDecParams(WebPDecParams* const params) {
383 if (params) { 394 if (params) {
384 memset(params, 0, sizeof(*params)); 395 memset(params, 0, sizeof(*params));
385 } 396 }
386 } 397 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 features->bitstream_version = 0; 629 features->bitstream_version = 0;
619 } 630 }
620 631
621 static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size, 632 static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size,
622 WebPBitstreamFeatures* const features) { 633 WebPBitstreamFeatures* const features) {
623 if (features == NULL || data == NULL) { 634 if (features == NULL || data == NULL) {
624 return VP8_STATUS_INVALID_PARAM; 635 return VP8_STATUS_INVALID_PARAM;
625 } 636 }
626 DefaultFeatures(features); 637 DefaultFeatures(features);
627 638
628 // Only parse enough of the data to retrieve width/height/has_alpha. 639 // Only parse enough of the data to retrieve the features.
629 return ParseHeadersInternal(data, data_size, 640 return ParseHeadersInternal(data, data_size,
630 &features->width, &features->height, 641 &features->width, &features->height,
631 &features->has_alpha, NULL); 642 &features->has_alpha, &features->has_animation,
643 NULL);
632 } 644 }
633 645
634 //------------------------------------------------------------------------------ 646 //------------------------------------------------------------------------------
635 // WebPGetInfo() 647 // WebPGetInfo()
636 648
637 int WebPGetInfo(const uint8_t* data, size_t data_size, 649 int WebPGetInfo(const uint8_t* data, size_t data_size,
638 int* width, int* height) { 650 int* width, int* height) {
639 WebPBitstreamFeatures features; 651 WebPBitstreamFeatures features;
640 652
641 if (GetFeatures(data, data_size, &features) != VP8_STATUS_OK) { 653 if (GetFeatures(data, data_size, &features) != VP8_STATUS_OK) {
(...skipping 23 matching lines...) Expand all
665 } 677 }
666 memset(config, 0, sizeof(*config)); 678 memset(config, 0, sizeof(*config));
667 DefaultFeatures(&config->input); 679 DefaultFeatures(&config->input);
668 WebPInitDecBuffer(&config->output); 680 WebPInitDecBuffer(&config->output);
669 return 1; 681 return 1;
670 } 682 }
671 683
672 VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size, 684 VP8StatusCode WebPGetFeaturesInternal(const uint8_t* data, size_t data_size,
673 WebPBitstreamFeatures* features, 685 WebPBitstreamFeatures* features,
674 int version) { 686 int version) {
675 VP8StatusCode status;
676 if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { 687 if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
677 return VP8_STATUS_INVALID_PARAM; // version mismatch 688 return VP8_STATUS_INVALID_PARAM; // version mismatch
678 } 689 }
679 if (features == NULL) { 690 if (features == NULL) {
680 return VP8_STATUS_INVALID_PARAM; 691 return VP8_STATUS_INVALID_PARAM;
681 } 692 }
682 693 return GetFeatures(data, data_size, features);
683 status = GetFeatures(data, data_size, features);
684 if (status == VP8_STATUS_NOT_ENOUGH_DATA) {
685 return VP8_STATUS_BITSTREAM_ERROR; // Not-enough-data treated as error.
686 }
687 return status;
688 } 694 }
689 695
690 VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size, 696 VP8StatusCode WebPDecode(const uint8_t* data, size_t data_size,
691 WebPDecoderConfig* config) { 697 WebPDecoderConfig* config) {
692 WebPDecParams params; 698 WebPDecParams params;
693 VP8StatusCode status; 699 VP8StatusCode status;
694 700
695 if (config == NULL) { 701 if (config == NULL) {
696 return VP8_STATUS_INVALID_PARAM; 702 return VP8_STATUS_INVALID_PARAM;
697 } 703 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 io->fancy_upsampling = 0; 774 io->fancy_upsampling = 0;
769 } 775 }
770 return 1; 776 return 1;
771 } 777 }
772 778
773 //------------------------------------------------------------------------------ 779 //------------------------------------------------------------------------------
774 780
775 #if defined(__cplusplus) || defined(c_plusplus) 781 #if defined(__cplusplus) || defined(c_plusplus)
776 } // extern "C" 782 } // extern "C"
777 #endif 783 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698