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;
y;
unsigned char
- *stream,
- *pixels;
+ *stream;
+
+ WebPDecoderConfig
+ configure;
+
+ WebPDecBuffer
+ *const webp_image = &configure.output;
+
+ WebPBitstreamFeatures
+ *const features = &configure.input;
/*
Open image file.
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)
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;
if (status == MagickFalse)
break;
}
- free(pixels);
- pixels=(unsigned char *) NULL;
+ WebPFreeDecBuffer(webp_image);
stream=(unsigned char*) RelinquishMagickMemory(stream);
return(image);
}
*/
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);
}
MagickBooleanType
status;
- register const Quantum
- *restrict p;
-
- register ssize_t
- x;
-
register uint32_t
*restrict q;
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);
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
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,