% July 1992 %
% %
% %
-% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2013 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 declarations.
*/
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/color-private.h"
-#include "magick/colormap.h"
-#include "magick/colormap-private.h"
-#include "magick/colorspace.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/attribute.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/color-private.h"
+#include "MagickCore/colormap.h"
+#include "MagickCore/colormap-private.h"
+#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/module.h"
\f
/*
Forward declarations.
*/
static MagickBooleanType
- WriteTGAImage(const ImageInfo *,Image *);
+ WriteTGAImage(const ImageInfo *,Image *,ExceptionInfo *);
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Image
*image;
- IndexPacket
- index;
-
- ssize_t
- y;
-
MagickBooleanType
status;
- PixelPacket
+ PixelInfo
pixel;
- register IndexPacket
- *indexes;
+ Quantum
+ index;
+
+ register Quantum
+ *q;
register ssize_t
i,
x;
- register PixelPacket
- *q;
+ size_t
+ base,
+ flag,
+ offset,
+ real,
+ skip;
ssize_t
- count;
+ count,
+ y;
TGAInfo
tga_info;
unsigned char
j,
k,
+ pixels[4],
runlength;
- size_t
- base,
- flag,
- offset,
- real,
- skip;
+ unsigned int
+ alpha_bits;
/*
Open image file.
image_info->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
- image=AcquireImage(image_info);
+ image=AcquireImage(image_info,exception);
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
if (status == MagickFalse)
{
*/
image->columns=tga_info.width;
image->rows=tga_info.height;
- image->matte=(tga_info.attributes & 0x0FU) != 0 ? MagickTrue : MagickFalse;
+ alpha_bits=(tga_info.attributes & 0x0FU);
+ image->alpha_trait=(alpha_bits > 0) || (tga_info.bits_per_pixel == 32) ?
+ BlendPixelTrait : UndefinedPixelTrait;
if ((tga_info.image_type != TGAColormap) &&
(tga_info.image_type != TGARLEColormap))
image->depth=(size_t) ((tga_info.bits_per_pixel <= 8) ? 8 :
one=1;
image->colors=one << tga_info.bits_per_pixel;
- if (AcquireImageColormap(image,image->colors) == MagickFalse)
+ if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
}
*/
length=(size_t) tga_info.id_length;
comment=(char *) NULL;
- if (~length >= MaxTextExtent)
+ if (~length >= (MaxTextExtent-1))
comment=(char *) AcquireQuantumMemory(length+MaxTextExtent,
sizeof(*comment));
if (comment == (char *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
count=ReadBlob(image,tga_info.id_length,(unsigned char *) comment);
comment[tga_info.id_length]='\0';
- (void) SetImageProperty(image,"comment",comment);
+ (void) SetImageProperty(image,"comment",comment,exception);
comment=DestroyString(comment);
}
(void) ResetMagickMemory(&pixel,0,sizeof(pixel));
- pixel.opacity=(Quantum) OpaqueOpacity;
+ pixel.alpha=(Quantum) OpaqueAlpha;
if (tga_info.colormap_type != 0)
{
/*
Read TGA raster colormap.
*/
- if (AcquireImageColormap(image,image->colors) == MagickFalse)
+ if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
for (i=0; i < (ssize_t) image->colors; i++)
{
flag=0;
skip=MagickFalse;
real=0;
- index=(IndexPacket) 0;
+ index=0;
runlength=0;
offset=0;
for (y=0; y < (ssize_t) image->rows; y++)
if (((unsigned char) (tga_info.attributes & 0x20) >> 5) == 0)
real=image->rows-real-1;
q=QueueAuthenticPixels(image,0,(ssize_t) real,image->columns,1,exception);
- if (q == (PixelPacket *) NULL)
+ if (q == (Quantum *) NULL)
break;
- indexes=GetAuthenticIndexQueue(image);
for (x=0; x < (ssize_t) image->columns; x++)
{
if ((tga_info.image_type == TGARLEColormap) ||
/*
Gray scale.
*/
- index=(IndexPacket) ReadBlobByte(image);
+ index=(Quantum) ReadBlobByte(image);
if (tga_info.colormap_type != 0)
pixel=image->colormap[(ssize_t) ConstrainColormapIndex(image,
- 1UL*index)];
+ 1UL*index,exception)];
else
{
pixel.red=ScaleCharToQuantum((unsigned char) index);
range;
/*
- 5 bits each of red green and blue.
+ 5 bits each of RGB.
*/
- j=(unsigned char) ReadBlobByte(image);
- k=(unsigned char) ReadBlobByte(image);
+ if (ReadBlob(image,2,pixels) != 2)
+ ThrowReaderException(CorruptImageError,"UnableToReadImageData");
+ j=pixels[0];
+ k=pixels[1];
range=GetQuantumRange(5UL);
pixel.red=ScaleAnyToQuantum(1UL*(k & 0x7c) >> 2,range);
pixel.green=ScaleAnyToQuantum((1UL*(k & 0x03) << 3)+
(1UL*(j & 0xe0) >> 5),range);
pixel.blue=ScaleAnyToQuantum(1UL*(j & 0x1f),range);
- if (image->matte != MagickFalse)
- pixel.opacity=(k & 0x80) == 0 ? (Quantum) OpaqueOpacity :
- (Quantum) TransparentOpacity;
+ if (image->alpha_trait == BlendPixelTrait)
+ pixel.alpha=(k & 0x80) == 0 ? (Quantum) OpaqueAlpha : (Quantum)
+ TransparentAlpha;
if (image->storage_class == PseudoClass)
- index=ConstrainColormapIndex(image,((size_t) k << 8)+j);
+ index=ConstrainColormapIndex(image,((size_t) k << 8)+j,exception);
break;
}
case 24:
+ {
+ /*
+ BGR pixels.
+ */
+ if (ReadBlob(image,3,pixels) != 3)
+ ThrowReaderException(CorruptImageError,"UnableToReadImageData");
+ pixel.blue=ScaleCharToQuantum(pixels[0]);
+ pixel.green=ScaleCharToQuantum(pixels[1]);
+ pixel.red=ScaleCharToQuantum(pixels[2]);
+ break;
+ }
case 32:
{
/*
- 8 bits each of blue green and red.
+ BGRA pixels.
*/
- pixel.blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
- pixel.green=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
- pixel.red=ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
- if (tga_info.bits_per_pixel == 32)
- pixel.opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(
- (unsigned char) ReadBlobByte(image)));
+ if (ReadBlob(image,4,pixels) != 4)
+ ThrowReaderException(CorruptImageError,"UnableToReadImageData");
+ pixel.blue=ScaleCharToQuantum(pixels[0]);
+ pixel.green=ScaleCharToQuantum(pixels[1]);
+ pixel.red=ScaleCharToQuantum(pixels[2]);
+ pixel.alpha=ScaleCharToQuantum(pixels[3]);
break;
}
}
if (status == MagickFalse)
ThrowReaderException(CorruptImageError,"UnableToReadImageData");
if (image->storage_class == PseudoClass)
- indexes[x]=index;
- q->red=pixel.red;
- q->green=pixel.green;
- q->blue=pixel.blue;
- if (image->matte != MagickFalse)
- q->opacity=pixel.opacity;
- q++;
+ SetPixelIndex(image,index,q);
+ SetPixelRed(image,pixel.red,q);
+ SetPixelGreen(image,pixel.green,q);
+ SetPixelBlue(image,pixel.blue,q);
+ if (image->alpha_trait == BlendPixelTrait)
+ SetPixelAlpha(image,pixel.alpha,q);
+ q+=GetPixelChannels(image);
}
if (((unsigned char) (tga_info.attributes & 0xc0) >> 6) == 4)
offset+=4;
%
% The format of the WriteTGAImage method is:
%
-% MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image)
+% MagickBooleanType WriteTGAImage(const ImageInfo *image_info,
+% Image *image,ExceptionInfo *exception)
%
% A description of each parameter follows.
%
return(y);
}
-static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image,
+ ExceptionInfo *exception)
{
#define TargaColormap 1
#define TargaRGB 2
const char
*value;
- ssize_t
- y;
-
MagickBooleanType
status;
- register const IndexPacket
- *indexes;
-
- register const PixelPacket
+ register const Quantum
*p;
register ssize_t
*q;
ssize_t
- count;
+ count,
+ y;
TargaInfo
targa_info;
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
/*
*/
if ((image->columns > 65535L) || (image->rows > 65535L))
ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
- if (image->colorspace != RGBColorspace)
- (void) TransformImageColorspace(image,RGBColorspace);
+ if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
targa_info.id_length=0;
- value=GetImageProperty(image,"comment");
+ value=GetImageProperty(image,"comment",exception);
if (value != (const char *) NULL)
targa_info.id_length=(unsigned char) MagickMin(strlen(value),255);
targa_info.colormap_type=0;
if ((image_info->type != TrueColorType) &&
(image_info->type != TrueColorMatteType) &&
(image_info->type != PaletteType) &&
- (image->matte == MagickFalse) &&
- (IsGrayImage(image,&image->exception) != MagickFalse))
+ (image->alpha_trait != BlendPixelTrait) &&
+ (IsImageGray(image,exception) != MagickFalse))
targa_info.image_type=TargaMonochrome;
else
if ((image->storage_class == DirectClass) || (image->colors > 256))
*/
targa_info.image_type=TargaRGB;
targa_info.bits_per_pixel=24;
- if (image->matte != MagickFalse)
+ if (image->alpha_trait == BlendPixelTrait)
{
targa_info.bits_per_pixel=32;
targa_info.attributes=8; /* # of alpha bits */
ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
for (y=(ssize_t) (image->rows-1); y >= 0; y--)
{
- p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
- if (p == (const PixelPacket *) NULL)
+ p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+ if (p == (const Quantum *) NULL)
break;
q=targa_pixels;
- indexes=GetVirtualIndexQueue(image);
for (x=0; x < (ssize_t) image->columns; x++)
{
if (targa_info.image_type == TargaColormap)
- *q++=(unsigned char) indexes[x];
+ *q++=(unsigned char) GetPixelIndex(image,p);
else
if (targa_info.image_type == TargaMonochrome)
- *q++=(unsigned char) ScaleQuantumToChar(PixelIntensityToQuantum(p));
+ *q++=(unsigned char) ScaleQuantumToChar(GetPixelIntensity(image,p));
else
{
- *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
- *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
- *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
- if (image->matte != MagickFalse)
- *q++=(unsigned char) ScaleQuantumToChar((Quantum)
- (GetAlphaPixelComponent(p)));
- if (image->colorspace == CMYKColorspace)
- *q++=ScaleQuantumToChar(indexes[x]);
+ *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
+ *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
+ *q++=ScaleQuantumToChar(GetPixelRed(image,p));
+ if (image->alpha_trait == BlendPixelTrait)
+ *q++=(unsigned char) ScaleQuantumToChar(GetPixelAlpha(image,p));
}
- p++;
+ p+=GetPixelChannels(image);
}
(void) WriteBlob(image,(size_t) (q-targa_pixels),targa_pixels);
if (image->previous == (Image *) NULL)
{
status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
- image->rows);
+ image->rows);
if (status == MagickFalse)
break;
}