From: dirk Date: Tue, 16 Dec 2014 09:48:03 +0000 (+0000) Subject: Added support for writing 16-bit TGA files X-Git-Tag: 7.0.1-0~1629 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f142f1f2fb88a3ec8189afa56ebb512741c6ff05;p=imagemagick Added support for writing 16-bit TGA files --- diff --git a/coders/tga.c b/coders/tga.c index 2168fac32..d2ebcd018 100644 --- a/coders/tga.c +++ b/coders/tga.c @@ -660,7 +660,7 @@ static inline size_t MagickMin(const size_t x,const size_t y) } static inline void WriteTGAPixel(Image *image,TGAImageType image_type, - const Quantum *p) + const Quantum *p,const QuantumAny range,const double midpoint) { if (image_type == TGAColormap || image_type == TGARLEColormap) (void) WriteBlobByte(image,(unsigned char) GetPixelIndex(image,p)); @@ -669,6 +669,23 @@ static inline void WriteTGAPixel(Image *image,TGAImageType image_type, if (image_type == TGAMonochrome || image_type == TGARLEMonochrome) (void) WriteBlobByte(image,ScaleQuantumToChar(ClampToQuantum( GetPixelLuma(image,p)))); + else if (image->depth == 5) + { + unsigned char + green, + value; + + green=(unsigned char) ScaleQuantumToAny(ClampToQuantum( + GetPixelGreen(image,p)),range); + value=((unsigned char) ScaleQuantumToAny(ClampToQuantum( + GetPixelBlue(image,p)),range)) | ((green & 0x07) << 5); + (void) WriteBlobByte(image,value); + value=(((image->alpha_trait == BlendPixelTrait) && (ClampToQuantum( + GetPixelAlpha(image,p)) < midpoint)) ? 80 : 0) | + ((unsigned char) ScaleQuantumToAny(ClampToQuantum( + GetPixelRed(image,p)),range) << 2) | ((green & 0x18) >> 3); + (void) WriteBlobByte(image,value); + } else { (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelBlue(image, @@ -692,9 +709,15 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, const char *value; + const double + midpoint=QuantumRange / 2.0; + MagickBooleanType status; + QuantumAny + range; + register const Quantum *p; @@ -740,6 +763,7 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; + range=GetQuantumRange(5UL); tga_info.id_length=0; value=GetImageProperty(image,"comment",exception); if (value != (const char *) NULL) @@ -769,11 +793,16 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, */ tga_info.image_type=compression == RLECompression ? TGARLERGB : TGARGB; - tga_info.bits_per_pixel=24; - if (image->alpha_trait == BlendPixelTrait) + if (image_info->depth == 5) + tga_info.bits_per_pixel=16; + else { - tga_info.bits_per_pixel=32; - tga_info.attributes=8; /* # of alpha bits */ + tga_info.bits_per_pixel=24; + if (image->alpha_trait == BlendPixelTrait) + { + tga_info.bits_per_pixel=32; + tga_info.attributes=8; /* # of alpha bits */ + } } } else @@ -785,7 +814,10 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, TGAColormap; tga_info.colormap_type=1; tga_info.colormap_length=(unsigned short) image->colors; - tga_info.colormap_size=24; + if (image_info->depth == 5) + tga_info.colormap_size=16; + else + tga_info.colormap_size=24; } /* Write TGA header. @@ -808,24 +840,40 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, if (tga_info.colormap_type != 0) { unsigned char + green, *targa_colormap; /* Dump colormap to file (blue, green, red byte order). */ targa_colormap=(unsigned char *) AcquireQuantumMemory((size_t) - tga_info.colormap_length,3UL*sizeof(*targa_colormap)); + tga_info.colormap_length,(tga_info.colormap_size/8)*sizeof( + *targa_colormap)); if (targa_colormap == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); q=targa_colormap; for (i=0; i < (ssize_t) image->colors; i++) { - *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue)); - *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green)); - *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red)); + if (image_info->depth == 5) + { + green=(unsigned char) ScaleQuantumToAny(ClampToQuantum( + image->colormap[i].green),range); + *q++=((unsigned char) ScaleQuantumToAny(ClampToQuantum( + image->colormap[i].blue),range)) | ((green & 0x07) << 5); + *q++=(((image->alpha_trait == BlendPixelTrait) && (ClampToQuantum( + image->colormap[i].alpha) < midpoint)) ? 80 : 0) | + ((unsigned char) ScaleQuantumToAny(ClampToQuantum( + image->colormap[i].red),range) << 2) | ((green & 0x18) >> 3); + } + else + { + *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].blue)); + *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].green)); + *q++=ScaleQuantumToChar(ClampToQuantum(image->colormap[i].red)); + } } - (void) WriteBlob(image,(size_t) (3*tga_info.colormap_length), - targa_colormap); + (void) WriteBlob(image,(size_t) ((tga_info.colormap_size/8)* + tga_info.colormap_length),targa_colormap); targa_colormap=(unsigned char *) RelinquishMagickMemory(targa_colormap); } /* @@ -889,7 +937,7 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, while (count >= 0) { WriteTGAPixel(image,tga_info.image_type,p-((count+1)* - channels)); + channels),range,midpoint); count--; } count=0; @@ -898,7 +946,7 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, if (i >= 3) { WriteBlobByte(image,(unsigned char) ((i-1) | 0x80)); - WriteTGAPixel(image,tga_info.image_type,p); + WriteTGAPixel(image,tga_info.image_type,p,range,midpoint); p+=(i*channels); } x+=i; @@ -908,7 +956,7 @@ static MagickBooleanType WriteTGAImage(const ImageInfo *image_info,Image *image, { for (x=0; x < (ssize_t) image->columns; x++) { - WriteTGAPixel(image,tga_info.image_type,p); + WriteTGAPixel(image,tga_info.image_type,p,range,midpoint); p+=channels; } }