]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Sat, 23 Feb 2013 02:14:37 +0000 (02:14 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Sat, 23 Feb 2013 02:14:37 +0000 (02:14 +0000)
MagickCore/version.h
coders/webp.c

index 3b5d523d4ef5fa50296aac89d35d23a9bcbecc12..461e77c729894fa2c6555462bb8ee9fc6c12dc02 100644 (file)
@@ -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"
index 398364dacd12c7ce173e574044ad31010d7e1b69..6f57eb2393127d48e7722a51c947d383d593da85 100644 (file)
@@ -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++)