% July 1992 %
% %
% %
-% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
#include "MagickCore/quantum-private.h"
#include "MagickCore/static.h"
#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
#include "MagickCore/module.h"
\f
/*
c=ReadBlobLZWByte(lzw_info);
if (c < 0)
break;
- index=ConstrainColormapIndex(image,(size_t) c);
+ index=ConstrainColormapIndex(image,(size_t) c,exception);
SetPixelIndex(image,index,q);
- SetPixelPacket(image,image->colormap+(ssize_t) index,q);
+ SetPixelInfoPixel(image,image->colormap+(ssize_t) index,q);
SetPixelAlpha(image,(ssize_t) index == opacity ? TransparentAlpha :
OpaqueAlpha,q);
x++;
%
*/
static MagickBooleanType EncodeImage(const ImageInfo *image_info,Image *image,
- const size_t data_size)
+ const size_t data_size,ExceptionInfo *exception)
{
#define MaxCode(number_bits) ((one << (number_bits))-1)
#define MaxHashTable 5003
register ssize_t
x;
- p=GetVirtualPixels(image,0,offset,image->columns,1,&image->exception);
+ p=GetVirtualPixels(image,0,offset,image->columns,1,exception);
if (p == (const Quantum *) NULL)
break;
if (y == 0)
/*
GIF Extension block.
*/
-
count=ReadBlob(image,1,&c);
if (count != 1)
{
char
*comments;
+ size_t
+ length;
+
/*
Read comment extension.
*/
comments=AcquireString((char *) NULL);
- for ( ; ; )
+ for (length=0; ; length+=count)
{
count=(ssize_t) ReadBlobBlock(image,header);
if (count == 0)
break;
header[count]='\0';
- (void) ConcatenateString(&comments,(const char *) header);
+ comments=(char *) ResizeQuantumMemory(comments,length+count,
+ sizeof(*comments));
+ if (comments == (char *) NULL)
+ ThrowReaderException(ResourceLimitError,
+ "MemoryAllocationFailed");
+ (void) CopyMagickMemory(comments+length,header,(size_t) count);
}
- (void) SetImageProperty(image,"comment",comments);
+ comments[length+count]='\0';
+ (void) SetImageProperty(image,"comment",comments,exception);
comments=DestroyString(comments);
break;
}
case 0xff:
{
- /* Read GIF application extension */
-
MagickBooleanType
loop;
MagickBooleanType
i8bim,
icc,
- iptc;
+ iptc,
+ magick;
StringInfo
*profile;
/*
Store GIF application extension as a generic profile.
*/
- i8bim=LocaleNCompare((char *) header,"MGK8BIM0000",11) == 0 ?
- MagickTrue : MagickFalse;
icc=LocaleNCompare((char *) header,"ICCRGBG1012",11) == 0 ?
MagickTrue : MagickFalse;
+ magick=LocaleNCompare((char *) header,"ImageMagick",11) == 0 ?
+ MagickTrue : MagickFalse;
+ i8bim=LocaleNCompare((char *) header,"MGK8BIM0000",11) == 0 ?
+ MagickTrue : MagickFalse;
iptc=LocaleNCompare((char *) header,"MGKIPTC0000",11) == 0 ?
MagickTrue : MagickFalse;
number_extensionss++;
if (profile == (StringInfo *) NULL)
ThrowReaderException(ResourceLimitError,
"MemoryAllocationFailed");
- info=(unsigned char *) RelinquishMagickMemory(info);
if (i8bim == MagickTrue)
(void) CopyMagickString(name,"8bim",sizeof(name));
else if (icc == MagickTrue)
(void) CopyMagickString(name,"icc",sizeof(name));
else if (iptc == MagickTrue)
(void) CopyMagickString(name,"iptc",sizeof(name));
+ else if (magick == MagickTrue)
+ {
+ (void) CopyMagickString(name,"magick",sizeof(name));
+ image->gamma=StringToDouble((char *) info+6,(char **) NULL);
+ }
else
(void) FormatLocaleString(name,sizeof(name),"gif:%.11s",
header);
- (void) SetImageProfile(image,name,profile);
+ info=(unsigned char *) RelinquishMagickMemory(info);
+ if (magick == MagickFalse)
+ (void) SetImageProfile(image,name,profile,exception);
profile=DestroyStringInfo(profile);
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" profile name=%s",name);
image->rows=ReadBlobLSBShort(image);
image->depth=8;
flag=(unsigned char) ReadBlobByte(image);
- image->interlace=BitSet((int) flag,0x40) != 0 ? GIFInterlace :
- NoInterlace;
- image->colors=BitSet((int) flag,0x80) == 0 ? global_colors :
- one << ((size_t) (flag & 0x07)+1);
+ image->interlace=BitSet((int) flag,0x40) != 0 ? GIFInterlace : NoInterlace;
+ image->colors=BitSet((int) flag,0x80) == 0 ? global_colors : one <<
+ ((size_t) (flag & 0x07)+1);
if (opacity >= (ssize_t) image->colors)
opacity=(-1);
image->page.width=page.width;
p=global_colormap;
for (i=0; i < (ssize_t) image->colors; i++)
{
- image->colormap[i].red=ScaleCharToQuantum(*p++);
- image->colormap[i].green=ScaleCharToQuantum(*p++);
- image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ image->colormap[i].red=(double) ScaleCharToQuantum(*p++);
+ image->colormap[i].green=(double) ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=(double) ScaleCharToQuantum(*p++);
if (i == opacity)
{
- image->colormap[i].alpha=(Quantum) TransparentAlpha;
+ image->colormap[i].alpha=(double) TransparentAlpha;
image->transparent_color=image->colormap[opacity];
}
}
/*
Read local colormap.
*/
- colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
- 3*sizeof(*colormap));
+ colormap=(unsigned char *) AcquireQuantumMemory(image->colors,3*
+ sizeof(*colormap));
if (colormap == (unsigned char *) NULL)
{
global_colormap=(unsigned char *) RelinquishMagickMemory(
p=colormap;
for (i=0; i < (ssize_t) image->colors; i++)
{
- image->colormap[i].red=ScaleCharToQuantum(*p++);
- image->colormap[i].green=ScaleCharToQuantum(*p++);
- image->colormap[i].blue=ScaleCharToQuantum(*p++);
+ image->colormap[i].red=(double) ScaleCharToQuantum(*p++);
+ image->colormap[i].green=(double) ScaleCharToQuantum(*p++);
+ image->colormap[i].blue=(double) ScaleCharToQuantum(*p++);
if (i == opacity)
- image->colormap[i].alpha=(Quantum) TransparentAlpha;
+ image->colormap[i].alpha=(double) TransparentAlpha;
}
colormap=(unsigned char *) RelinquishMagickMemory(colormap);
}
+ if (image->gamma == 1.0)
+ {
+ for (i=0; i < (ssize_t) image->colors; i++)
+ if (IsPixelInfoGray(image->colormap+i) == MagickFalse)
+ break;
+ (void) SetImageColorspace(image,i == (ssize_t) image->colors ?
+ GRAYColorspace : RGBColorspace,exception);
+ }
if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
if (image->scene >= (image_info->scene+image_info->number_scenes-1))
break;
static MagickBooleanType WriteGIFImage(const ImageInfo *image_info,Image *image,
ExceptionInfo *exception)
{
- Image
- *next_image;
-
int
c;
Determine image bounding box.
*/
page.width=image->columns;
+ if (image->page.width > page.width)
+ page.width=image->page.width;
page.height=image->rows;
- page.x=0;
- page.y=0;
- if (write_info->adjoin != MagickFalse)
- for (next_image=image; next_image != (Image *) NULL; )
- {
- page.x=next_image->page.x;
- page.y=next_image->page.y;
- if ((next_image->page.width+page.x) > page.width)
- page.width=next_image->page.width+page.x;
- if ((next_image->page.height+page.y) > page.height)
- page.height=next_image->page.height+page.y;
- next_image=GetNextImageInList(next_image);
- }
+ if (image->page.height > page.height)
+ page.height=image->page.height;
page.x=image->page.x;
page.y=image->page.y;
- if ((image->page.width != 0) && (image->page.height != 0))
- page=image->page;
(void) WriteBlobLSBShort(image,(unsigned short) page.width);
(void) WriteBlobLSBShort(image,(unsigned short) page.height);
/*
one=1;
do
{
- if (IsRGBColorspace(image->colorspace) == MagickFalse)
- (void) TransformImageColorspace(image,RGBColorspace);
+ if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
opacity=(-1);
if (IsImageOpaque(image,exception) != MagickFalse)
{
q=colormap;
for (i=0; i < (ssize_t) image->colors; i++)
{
- *q++=ScaleQuantumToChar(image->colormap[i].red);
- *q++=ScaleQuantumToChar(image->colormap[i].green);
- *q++=ScaleQuantumToChar(image->colormap[i].blue);
+ *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red));
+ *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green));
+ *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue));
}
for ( ; i < (ssize_t) (one << bits_per_pixel); i++)
{
c|=(bits_per_pixel-1); /* size of global colormap */
(void) WriteBlobByte(image,(unsigned char) c);
for (j=0; j < (ssize_t) image->colors; j++)
- if (IsPixelPacketEquivalent(&image->background_color,image->colormap+j))
+ if (IsPixelInfoEquivalent(&image->background_color,image->colormap+j))
break;
(void) WriteBlobByte(image,(unsigned char)
(j == (ssize_t) image->colors ? 0 : j)); /* background color */
0));
(void) WriteBlobByte(image,(unsigned char) 0x00);
if ((LocaleCompare(write_info->magick,"GIF87") != 0) &&
- (GetImageProperty(image,"comment") != (const char *) NULL))
+ (GetImageProperty(image,"comment",exception) != (const char *) NULL))
{
const char
*value;
- register const char
+ register const char
*p;
size_t
count;
-
+
/*
- Write Comment extension.
+ Write comment extension.
*/
(void) WriteBlobByte(image,(unsigned char) 0x21);
(void) WriteBlobByte(image,(unsigned char) 0xfe);
- value=GetImageProperty(image,"comment");
- p=value;
- while (strlen(p) != 0)
+ value=GetImageProperty(image,"comment",exception);
+ for (p=value; *p != '\0'; )
{
count=MagickMin(strlen(p),255);
(void) WriteBlobByte(image,(unsigned char) count);
(void) WriteBlobLSBShort(image,(unsigned short) image->iterations);
(void) WriteBlobByte(image,(unsigned char) 0x00);
}
+ if ((image->gamma != 1.0f/2.2f))
+ {
+ char
+ attributes[MaxTextExtent];
+
+ ssize_t
+ length;
+
+ /*
+ Write ImageMagick extension.
+ */
+ (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+ " Writing GIF Extension %s","ImageMagick");
+ (void) WriteBlobByte(image,(unsigned char) 0x21);
+ (void) WriteBlobByte(image,(unsigned char) 0xff);
+ (void) WriteBlobByte(image,(unsigned char) 0x0b);
+ (void) WriteBlob(image,11,(unsigned char *) "ImageMagick");
+ length=FormatLocaleString(attributes,MaxTextExtent,"gamma=%g",
+ image->gamma);
+ (void) WriteBlobByte(image,(unsigned char) length);
+ (void) WriteBlob(image,length,(unsigned char *) attributes);
+ (void) WriteBlobByte(image,(unsigned char) 0x00);
+ }
ResetImageProfileIterator(image);
for ( ; ; )
{
/*
Write ICC extension.
*/
- (void) WriteBlob(image,11,(unsigned char *)"ICCRGBG1012");
+ (void) WriteBlob(image,11,(unsigned char *) "ICCRGBG1012");
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Writing GIF Extension %s","ICCRGBG1012");
}
if ((LocaleCompare(name,"IPTC") == 0))
{
/*
- write IPTC extension.
+ Write IPTC extension.
*/
- (void) WriteBlob(image,11,(unsigned char *)"MGKIPTC0000");
+ (void) WriteBlob(image,11,(unsigned char *) "MGKIPTC0000");
(void) LogMagickEvent(CoderEvent,GetMagickModule(),
" Writing GIF Extension %s","MGKIPTC0000");
}
if ((LocaleCompare(name,"8BIM") == 0))
{
/*
- Write 8BIM extension>
+ Write 8BIM extension.
*/
(void) WriteBlob(image,11,(unsigned char *)
"MGK8BIM0000");
char
extension[MaxTextExtent];
- /* write generic extension */
+ /*
+ Write generic extension.
+ */
(void) CopyMagickString(extension,name+4,
sizeof(extension));
(void) WriteBlob(image,11,(unsigned char *) extension);
*/
c=(int) MagickMax(bits_per_pixel,2);
(void) WriteBlobByte(image,(unsigned char) c);
- status=EncodeImage(write_info,image,(size_t) MagickMax(bits_per_pixel,2)+1);
+ status=EncodeImage(write_info,image,(size_t) MagickMax(bits_per_pixel,2)+1,
+ exception);
if (status == MagickFalse)
{
global_colormap=(unsigned char *) RelinquishMagickMemory(