From 9388ef4adb3c897713b738d722c2858d61a512d9 Mon Sep 17 00:00:00 2001 From: dirk Date: Mon, 7 Jul 2014 18:39:23 +0000 Subject: [PATCH] Added support for R5G6B5, RGB5A1 and RGBA4 dds files. --- coders/dds.c | 120 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 25 deletions(-) diff --git a/coders/dds.c b/coders/dds.c index dd6034e82..6bb8ec451 100644 --- a/coders/dds.c +++ b/coders/dds.c @@ -748,6 +748,9 @@ if (max - min < steps) \ #define VectorInit(vector, value) vector.x = vector.y = vector.z = vector.w \ = value #define VectorInit3(vector, value) vector.x = vector.y = vector.z = value + +#define IsBitMask(mask, r, g, b, a) (mask.r_bitmask == r && mask.g_bitmask == \ + g && mask.b_bitmask == b && mask.alpha_bitmask == a) /* Forward declarations @@ -2170,12 +2173,20 @@ static MagickBooleanType ReadDXT5(Image *image, DDSInfo *dds_info, static MagickBooleanType ReadUncompressedRGB(Image *image, DDSInfo *dds_info, ExceptionInfo *exception) { - ssize_t - x, y; - register Quantum *q; - + + ssize_t + x, y; + + unsigned short + color; + + if (dds_info->pixelformat.rgb_bitcount == 16 && !IsBitMask( + dds_info->pixelformat,0xf800,0x07e0,0x001f,0x0000)) + ThrowBinaryException(CorruptImageError,"ImageTypeNotSupported", + image->filename); + for (y = 0; y < (ssize_t) dds_info->height; y++) { q = QueueAuthenticPixels(image, 0, y, dds_info->width, 1,exception); @@ -2185,14 +2196,28 @@ static MagickBooleanType ReadUncompressedRGB(Image *image, DDSInfo *dds_info, for (x = 0; x < (ssize_t) dds_info->width; x++) { - SetPixelBlue(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); - SetPixelGreen(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); - SetPixelRed(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); - if (dds_info->pixelformat.rgb_bitcount == 32) - (void) ReadBlobByte(image); + + if (dds_info->pixelformat.rgb_bitcount == 16) + { + color=ReadBlobShort(image); + SetPixelRed(image,ScaleCharToQuantum((unsigned char) + (((color >> 11)/31.0)*255)),q); + SetPixelGreen(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 5) >> 10)/63.0)*255)),q); + SetPixelBlue(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 11) >> 11)/31.0)*255)),q); + } + else + { + SetPixelBlue(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + SetPixelGreen(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + SetPixelRed(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + if (dds_info->pixelformat.rgb_bitcount == 32) + (void) ReadBlobByte(image); + } q+=GetPixelChannels(image); } @@ -2208,12 +2233,29 @@ static MagickBooleanType ReadUncompressedRGB(Image *image, DDSInfo *dds_info, static MagickBooleanType ReadUncompressedRGBA(Image *image, DDSInfo *dds_info, ExceptionInfo *exception) { - ssize_t - x, y; - register Quantum *q; - + + ssize_t + alphaBits, + x, + y; + + unsigned short + color; + + alphaBits=0; + if (dds_info->pixelformat.rgb_bitcount == 16) + { + if (IsBitMask(dds_info->pixelformat,0x7c00,0x03e0,0x001f,0x8000)) + alphaBits=1; + else if (IsBitMask(dds_info->pixelformat,0x0f00,0x00f0,0x000f,0xf000)) + alphaBits=4; + else + ThrowBinaryException(CorruptImageError,"ImageTypeNotSupported", + image->filename); + } + for (y = 0; y < (ssize_t) dds_info->height; y++) { q = QueueAuthenticPixels(image, 0, y, dds_info->width, 1,exception); @@ -2222,15 +2264,43 @@ static MagickBooleanType ReadUncompressedRGBA(Image *image, DDSInfo *dds_info, return MagickFalse; for (x = 0; x < (ssize_t) dds_info->width; x++) - { - SetPixelBlue(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); - SetPixelGreen(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); - SetPixelRed(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); - SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) - ReadBlobByte(image)),q); + { + if (dds_info->pixelformat.rgb_bitcount == 16) + { + color=ReadBlobShort(image); + if (alphaBits == 1) + { + SetPixelAlpha(image,(color & (1 << 15)) ? QuantumRange : 0,q); + SetPixelRed(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 1) >> 11)/31.0)*255)),q); + SetPixelGreen(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 6) >> 11)/31.0)*255)),q); + SetPixelBlue(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 11) >> 11)/31.0)*255)),q); + } + else + { + SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) + (((color >> 12)/15.0)*255)),q); + SetPixelRed(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 4) >> 12)/15.0)*255)),q); + SetPixelGreen(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 8) >> 12)/15.0)*255)),q); + SetPixelBlue(image,ScaleCharToQuantum((unsigned char) + ((((unsigned short)(color << 12) >> 12)/15.0)*255)),q); + } + } + else + { + SetPixelBlue(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + SetPixelGreen(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + SetPixelRed(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) + ReadBlobByte(image)),q); + } q+=GetPixelChannels(image); } -- 2.40.0