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

index 80f09f2ee121e12ed61c5546974b5fe141dcd3bd..7f600de38472401e412e20e1404ea4dfb5052272 100644 (file)
@@ -58,6 +58,7 @@
 #include "MagickCore/quantum-private.h"
 #include "MagickCore/static.h"
 #include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
 #include "MagickCore/module.h"
 #include "MagickCore/utility.h"
 #include "MagickCore/xwindow.h"
@@ -164,6 +165,8 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
   image->columns=(size_t) width;
   image->rows=(size_t) height;
   image->alpha_trait=BlendPixelTrait;
+  if ((stream[15] == 'L') || (stream[15] == ' '))
+    image->quality=100;
   p=pixels;
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -187,6 +190,7 @@ static Image *ReadWEBPImage(const ImageInfo *image_info,
   }
   free(pixels);
   pixels=(unsigned char *) NULL;
+  stream=(unsigned char*) RelinquishMagickMemory(stream);
   return(image);
 }
 #endif
@@ -295,6 +299,9 @@ static int WebPWriter(const unsigned char *stream,size_t length,
 static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   Image *image,ExceptionInfo *exception)
 {
+  const char
+    *value;
+
   int
     webp_status;
 
@@ -307,15 +314,12 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   register ssize_t
     x;
 
-  register unsigned char
+  register uint32_t
     *restrict q;
 
   ssize_t
     y;
 
-  unsigned char
-    *pixels;
-
   WebPConfig
     configure;
 
@@ -346,23 +350,85 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
   picture.stats=(&statistics);
   picture.width=(int) image->columns;
   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
+    if (image->quality >= 100)
+      configure.lossless=1;
+  value=GetImageOption(image_info,"webp:lossless");
+  if (value != (char *) NULL)
+   configure.lossless=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:method");
+  if (value != (char *) NULL)
+    configure.method=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:image-hint");
+  if (value != (char *) NULL)
+    configure.image_hint=(WebPImageHint) StringToInteger(value);
+  value=GetImageOption(image_info,"webp:target-size");
+  if (value != (char *) NULL)
+    configure.target_size=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:target-psnr");
+  if (value != (char *) NULL)
+    configure.target_PSNR=(float) StringToDouble(value,(char **) NULL);
+  value=GetImageOption(image_info,"webp:segments");
+  if (value != (char *) NULL)
+    configure.segments=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:sns-strength");
+  if (value != (char *) NULL)
+    configure.sns_strength=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:filter-strength");
+  if (value != (char *) NULL)
+    configure.filter_strength=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:filter-sharpness");
+  if (value != (char *) NULL)
+    configure.filter_sharpness=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:filter-type");
+  if (value != (char *) NULL)
+    configure.filter_type=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:autofilter");
+  if (value != (char *) NULL)
+    configure.autofilter=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:alpha-compression");
+  if (value != (char *) NULL)
+    configure.alpha_compression=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:alpha-filtering");
+  if (value != (char *) NULL)
+    configure.alpha_filtering=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:alpha-quality");
+  if (value != (char *) NULL)
+    configure.alpha_quality=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:pass");
+  if (value != (char *) NULL)
+    configure.pass=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:show-compressed");
+  if (value != (char *) NULL)
+    configure.show_compressed=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:preprocessing");
+  if (value != (char *) NULL)
+    configure.preprocessing=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:partitions");
+  if (value != (char *) NULL)
+    configure.partitions=StringToInteger(value);
+  value=GetImageOption(image_info,"webp:partition-limit");
+  if (value != (char *) NULL)
+    configure.partition_limit=StringToInteger(value);
   if (WebPValidateConfig(&configure) == 0)
     ThrowWriterException(ResourceLimitError,"UnableToEncodeImageFile");
   /*
     Allocate memory for pixels.
   */
-  pixels=(unsigned char *) AcquireQuantumMemory(image->columns,4*image->rows*
-    sizeof(*pixels));
-  if (pixels == (unsigned char *) NULL)
+  picture.argb=(uint32_t *) AcquireQuantumMemory(image->columns,image->rows*
+    sizeof(*picture.argb));
+  if (picture.argb == (uint32_t *) NULL)
     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   /*
     Convert image to WebP raster pixels.
   */
-  q=pixels;
+  q=picture.argb;
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
@@ -370,11 +436,11 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
       break;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      *q++=ScaleQuantumToChar(GetPixelRed(image,p));
-      *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
-      *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
-      if (image->alpha_trait == BlendPixelTrait)
-        *q++=ScaleQuantumToChar(GetPixelAlpha(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,
@@ -382,13 +448,9 @@ static MagickBooleanType WriteWEBPImage(const ImageInfo *image_info,
     if (status == MagickFalse)
       break;
   }
-  if (image->alpha_trait != BlendPixelTrait)
-    webp_status=WebPPictureImportRGB(&picture,pixels,3*picture.width);
-  else
-    webp_status=WebPPictureImportRGBA(&picture,pixels,4*picture.width);
-  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
   webp_status=WebPEncode(&configure,&picture);
   WebPPictureFree(&picture);
+  picture.argb=(uint32_t *) RelinquishMagickMemory(picture.argb);
   (void) CloseBlob(image);
   return(webp_status == 0 ? MagickFalse : MagickTrue);
 }