From 8f25aa80b65d74955887685eafa2ae258e7cd700 Mon Sep 17 00:00:00 2001 From: cristy Date: Sat, 23 Feb 2013 02:14:37 +0000 Subject: [PATCH] --- MagickCore/version.h | 2 +- coders/webp.c | 58 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/MagickCore/version.h b/MagickCore/version.h index 3b5d523d4..461e77c72 100644 --- a/MagickCore/version.h +++ b/MagickCore/version.h @@ -34,7 +34,7 @@ extern "C" { #define MagickLibAddendum "-0" #define MagickLibInterface 1 #define MagickLibMinInterface 1 -#define MagickReleaseDate "2013-02-18" +#define MagickReleaseDate "2013-02-22" #define MagickChangeDate "20121005" #define MagickAuthoritativeURL "http://www.imagemagick.org" #define MagickFeatures "DPC HDRI OpenMP" diff --git a/coders/webp.c b/coders/webp.c index 398364dac..6f57eb239 100644 --- a/coders/webp.c +++ b/coders/webp.c @@ -136,6 +136,62 @@ static MagickBooleanType IsWEBP(const unsigned char *magick,const size_t length) % o exception: return any errors or warnings in this structure. % */ + +static inline uint32_t get_le24(const unsigned char *const data) +{ + return((uint32_t) (data[0] | (data[1] << 8) | (data[2] << 16))); +} + +static inline uint32_t get_le32(const unsigned char *const data) +{ + return((uint32_t) (get_le24(data) | (data[3] << 24))); +} + +static MagickBooleanType IsWEBPImageLossless(const unsigned char *stream, + const size_t length) +{ +#define VP8_CHUNK_INDEX 15 /* file/header type */ +#define LOSSLESS_FLAG 'L' +#define EXTENDED_HEADER 'X' +#define VP8_CHUNK_HEADER "VP8" +#define VP8_CHUNK_HEADER_SIZE 3 +#define RIFF_HEADER_SIZE 12 /* size of the RIFF header ("RIFFnnnnWEBP") */ +#define VP8X_CHUNK_SIZE 10 +#define TAG_SIZE 4 +#define CHUNK_SIZE_BYTES 4 +#define CHUNK_HEADER_SIZE 8 +#define MAX_CHUNK_PAYLOAD (~0U-CHUNK_HEADER_SIZE-1) /* header padding */ + + ssize_t + offset; + + /* + Read simple header. + */ + if (stream[VP8_CHUNK_INDEX] != EXTENDED_HEADER) + return(stream[VP8_CHUNK_INDEX] == LOSSLESS_FLAG ? MagickTrue : MagickFalse); + /* + Read extended header. + */ + offset=RIFF_HEADER_SIZE+TAG_SIZE+CHUNK_SIZE_BYTES+VP8X_CHUNK_SIZE; + while (offset <= length) + { + uint32_t + chunk_size, + chunk_size_pad; + + chunk_size=get_le32(stream+pos+TAG_SIZE); + if (chunk_size > MAX_CHUNK_PAYLOAD) + break; + chunk_size_pad=(CHUNK_HEADER_SIZE+chunk_size+1) & ~1; + if (memcmp( stream+offset,VP8_CHUNK_HEADER,VP8_CHUNK_HEADER_SIZE) == 0) + return*(stream+offset+VP8_CHUNK_HEADER_SIZE) == LOSSLESS_FLAG ? + MagickTrue : MagickFalse); + offset+=chunk_size_pad; + } + return(MagickFalse); +} + static Image *ReadWEBPImage(const ImageInfo *image_info, ExceptionInfo *exception) { @@ -208,7 +264,7 @@ static Image *ReadWEBPImage(const ImageInfo *image_info, image->rows=(size_t) webp_image->height; image->alpha_trait=features->has_alpha != 0 ? BlendPixelTrait : UndefinedPixelTrait; - if (stream[15] == 'L') + if (IsWEBPImageLossless(stream,length) != MagickFalse) image->quality=100; p=webp_image->u.RGBA.rgba; for (y=0; y < (ssize_t) image->rows; y++) -- 2.40.0