]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Mon, 18 Feb 2013 15:06:48 +0000 (15:06 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Mon, 18 Feb 2013 15:06:48 +0000 (15:06 +0000)
coders/webp.c

index 7f600de38472401e412e20e1404ea4dfb5052272..2ad9c6a4853440415a8b1191f395be13ba509ac4 100644 (file)
@@ -105,22 +105,12 @@ static MagickBooleanType
 static Image *ReadWEBPImage(const ImageInfo *image_info,
   ExceptionInfo *exception)
 {
-  int
-    height,
-    width;
-
   Image
     *image;
 
   MagickBooleanType
     status;
 
-  register Quantum
-    *q;
-
-  register ssize_t
-    x;
-
   register unsigned char
     *p;
 
@@ -132,8 +122,16 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
     y;
 
   unsigned char
-    *stream,
-    *pixels;
+    *stream;
+
+  WebPDecoderConfig
+    configure;
+
+  WebPDecBuffer
+    *const webp_image = &configure.output;
+
+  WebPBitstreamFeatures
+    *const features = &configure.input;
 
   /*
     Open image file.
@@ -152,6 +150,8 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
       image=DestroyImageList(image);
       return((Image *) NULL);
     }
+  if (WebPInitDecoderConfig(&configure) == 0)
+    ThrowReaderException(ResourceLimitError,"UnableToDecodeImageFile");
   length=(size_t) GetBlobSize(image);
   stream=(unsigned char *) AcquireQuantumMemory(length,sizeof(*stream));
   if (stream == (unsigned char *) NULL)
@@ -159,17 +159,32 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
   count=ReadBlob(image,length,stream);
   if (count != (ssize_t) length)
     ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
-  pixels=(unsigned char *) WebPDecodeRGBA(stream,length,&width,&height);
-  if (pixels == (unsigned char *) NULL)
-    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-  image->columns=(size_t) width;
-  image->rows=(size_t) height;
-  image->alpha_trait=BlendPixelTrait;
+  if (WebPGetFeatures(stream,length,features) != 0)
+    {
+      stream=(unsigned char*) RelinquishMagickMemory(stream);
+      ThrowReaderException(ResourceLimitError,"UnableToDecodeImageFile");
+    }
+  webp_image->colorspace=MODE_RGBA;
+  if (WebPDecode(stream,length,&configure) != 0)
+    {
+      stream=(unsigned char*) RelinquishMagickMemory(stream);
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    }
+  image->columns=(size_t) webp_image->width;
+  image->rows=(size_t) webp_image->height;
+  image->alpha_trait=features->has_alpha != 0 ? BlendPixelTrait :
+    UndefinedPixelTrait;
   if ((stream[15] == 'L') || (stream[15] == ' '))
     image->quality=100;
-  p=pixels;
+  p=webp_image->u.RGBA.rgba;
   for (y=0; y < (ssize_t) image->rows; y++)
   {
+    register Quantum
+      *q;
+
+    register ssize_t
+      x;
+
     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
     if (q == (Quantum *) NULL)
       break;
@@ -188,8 +203,7 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
     if (status == MagickFalse)
       break;
   }
-  free(pixels);
-  pixels=(unsigned char *) NULL;
+  WebPFreeDecBuffer(webp_image);
   stream=(unsigned char*) RelinquishMagickMemory(stream);
   return(image);
 }
@@ -220,17 +234,27 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
 */
 ModuleExport size_t RegisterWEBPImage(void)
 {
+  char
+    version[MaxTextExtent];
+
   MagickInfo
     *entry;
 
+  *version='\0';
   entry=SetMagickInfo("WEBP");
 #if defined(MAGICKCORE_WEBP_DELEGATE)
   entry->decoder=(DecodeImageHandler *) ReadWEBPImage;
   entry->encoder=(EncodeImageHandler *) WriteWEBPImage;
+  (void) FormatLocaleString(version,MaxTextExtent,"libwebp %d.%d.%d",
+    (WebPGetDecoderVersion() >> 16) & 0xff,
+    (WebPGetDecoderVersion() >> 8) & 0xff,
+    (WebPGetDecoderVersion() >> 0) & 0xff);
 #endif
   entry->description=ConstantString("WebP Image Format");
   entry->adjoin=MagickFalse;
   entry->module=ConstantString("WEBP");
+  if (*version != '\0')
+    entry->version=ConstantString(version);
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
 }
@@ -308,12 +332,6 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   MagickBooleanType
     status;
 
-  register const Quantum
-    *restrict p;
-
-  register ssize_t
-    x;
-
   register uint32_t
     *restrict q;
 
@@ -343,8 +361,8 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   if (status == MagickFalse)
     return(status);
-  if (WebPPictureInit(&picture) == 0)
-    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+  if ((WebPPictureInit(&picture) == 0) || (WebPConfigInit(&configure) == 0))
+    ThrowWriterException(ResourceLimitError,"UnableToEncodeImageFile");
   picture.writer=WebPWriter;
   picture.custom_ptr=(void *) image;
   picture.stats=(&statistics);
@@ -352,8 +370,6 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   picture.height=(int) image->rows;
   picture.argb_stride=(int) image->columns;
   picture.use_argb=1;
-  if (WebPConfigInit(&configure) == 0)
-    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   if (image->quality != UndefinedCompressionQuality)
     configure.quality=(float) image->quality;
   else
@@ -431,16 +447,22 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   q=picture.argb;
   for (y=0; y < (ssize_t) image->rows; y++)
   {
+    register const Quantum
+      *restrict p;
+
+    register ssize_t
+      x;
+
     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
     if (p == (const Quantum *) NULL)
       break;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-     *q++=(uint32_t) (image->alpha_trait == BlendPixelTrait ?
-       ScaleQuantumToChar(GetPixelAlpha(image,p)) << 24 : 0xff000000u) |
-       (ScaleQuantumToChar(GetPixelRed(image,p)) << 16) |
-       (ScaleQuantumToChar(GetPixelGreen(image,p)) << 8) |
-       (ScaleQuantumToChar(GetPixelBlue(image,p)));
+      *q++=(uint32_t) (image->alpha_trait == BlendPixelTrait ?
+        ScaleQuantumToChar(GetPixelAlpha(image,p)) << 24 : 0xff000000u) |
+        (ScaleQuantumToChar(GetPixelRed(image,p)) << 16) |
+        (ScaleQuantumToChar(GetPixelGreen(image,p)) << 8) |
+        (ScaleQuantumToChar(GetPixelBlue(image,p)));
       p+=GetPixelChannels(image);
     }
     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,