18692172297647753b19567a180d52a6415193e3ddirk/*
28692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
48692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
58692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
68692172297647753b19567a180d52a6415193e3ddirk%                            DDDD   DDDD   SSSSS                              %
78692172297647753b19567a180d52a6415193e3ddirk%                            D   D  D   D  SS                                 %
88692172297647753b19567a180d52a6415193e3ddirk%                            D   D  D   D   SSS                               %
98692172297647753b19567a180d52a6415193e3ddirk%                            D   D  D   D     SS                              %
108692172297647753b19567a180d52a6415193e3ddirk%                            DDDD   DDDD   SSSSS                              %
118692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
128692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
138692172297647753b19567a180d52a6415193e3ddirk%           Read/Write Microsoft Direct Draw Surface Image Format             %
148692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
158692172297647753b19567a180d52a6415193e3ddirk%                              Software Design                                %
168692172297647753b19567a180d52a6415193e3ddirk%                             Bianca van Schaik                               %
178692172297647753b19567a180d52a6415193e3ddirk%                                March 2008                                   %
188692172297647753b19567a180d52a6415193e3ddirk%                               Dirk Lemstra                                  %
198692172297647753b19567a180d52a6415193e3ddirk%                              September 2013                                 %
208692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
218692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
227ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
238692172297647753b19567a180d52a6415193e3ddirk%  dedicated to making software imaging solutions freely available.           %
248692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
258692172297647753b19567a180d52a6415193e3ddirk%  You may not use this file except in compliance with the License.  You may  %
268692172297647753b19567a180d52a6415193e3ddirk%  obtain a copy of the License at                                            %
278692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
288692172297647753b19567a180d52a6415193e3ddirk%    http://www.imagemagick.org/script/license.php                            %
298692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
308692172297647753b19567a180d52a6415193e3ddirk%  Unless required by applicable law or agreed to in writing, software        %
318692172297647753b19567a180d52a6415193e3ddirk%  distributed under the License is distributed on an "AS IS" BASIS,          %
328692172297647753b19567a180d52a6415193e3ddirk%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
338692172297647753b19567a180d52a6415193e3ddirk%  See the License for the specific language governing permissions and        %
348692172297647753b19567a180d52a6415193e3ddirk%  limitations under the License.                                             %
358692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
368692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378692172297647753b19567a180d52a6415193e3ddirk%
388692172297647753b19567a180d52a6415193e3ddirk%
398692172297647753b19567a180d52a6415193e3ddirk*/
408692172297647753b19567a180d52a6415193e3ddirk
418692172297647753b19567a180d52a6415193e3ddirk/*
428692172297647753b19567a180d52a6415193e3ddirk  Include declarations.
438692172297647753b19567a180d52a6415193e3ddirk*/
448692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/studio.h"
456398fb41b2fa07b3234f02c533844504ede388dfdirk#include "MagickCore/attribute.h"
468692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/blob.h"
478692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/blob-private.h"
488692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/cache.h"
498692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/colorspace.h"
508692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/colorspace-private.h"
518692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/exception.h"
528692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/exception-private.h"
538692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/image.h"
548692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/image-private.h"
558692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/list.h"
566398fb41b2fa07b3234f02c533844504ede388dfdirk#include "MagickCore/log.h"
578692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/magick.h"
588692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/memory_.h"
598692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/monitor.h"
608692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/monitor-private.h"
618692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/option.h"
628692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/pixel-accessor.h"
636398fb41b2fa07b3234f02c533844504ede388dfdirk#include "MagickCore/profile.h"
648692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/quantum.h"
656398fb41b2fa07b3234f02c533844504ede388dfdirk#include "MagickCore/quantum-private.h"
66560a910a25df2b4ca46af343321575ca6fb2c3bfdirk#include "MagickCore/resource_.h"
678692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/static.h"
688692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/string_.h"
698692172297647753b19567a180d52a6415193e3ddirk#include "MagickCore/string-private.h"
706398fb41b2fa07b3234f02c533844504ede388dfdirk#include "MagickCore/module.h"
716398fb41b2fa07b3234f02c533844504ede388dfdirk#include "MagickCore/transform.h"
728692172297647753b19567a180d52a6415193e3ddirk
738692172297647753b19567a180d52a6415193e3ddirk/*
748692172297647753b19567a180d52a6415193e3ddirk  Definitions
758692172297647753b19567a180d52a6415193e3ddirk*/
768692172297647753b19567a180d52a6415193e3ddirk#define DDSD_CAPS         0x00000001
778692172297647753b19567a180d52a6415193e3ddirk#define DDSD_HEIGHT       0x00000002
788692172297647753b19567a180d52a6415193e3ddirk#define DDSD_WIDTH        0x00000004
798692172297647753b19567a180d52a6415193e3ddirk#define DDSD_PITCH        0x00000008
808692172297647753b19567a180d52a6415193e3ddirk#define DDSD_PIXELFORMAT  0x00001000
818692172297647753b19567a180d52a6415193e3ddirk#define DDSD_MIPMAPCOUNT  0x00020000
828692172297647753b19567a180d52a6415193e3ddirk#define DDSD_LINEARSIZE   0x00080000
838692172297647753b19567a180d52a6415193e3ddirk#define DDSD_DEPTH        0x00800000
848692172297647753b19567a180d52a6415193e3ddirk
858692172297647753b19567a180d52a6415193e3ddirk#define DDPF_ALPHAPIXELS  0x00000001
868692172297647753b19567a180d52a6415193e3ddirk#define DDPF_FOURCC       0x00000004
878692172297647753b19567a180d52a6415193e3ddirk#define DDPF_RGB          0x00000040
886398fb41b2fa07b3234f02c533844504ede388dfdirk#define DDPF_LUMINANCE    0x00020000
898692172297647753b19567a180d52a6415193e3ddirk
908692172297647753b19567a180d52a6415193e3ddirk#define FOURCC_DXT1       0x31545844
918692172297647753b19567a180d52a6415193e3ddirk#define FOURCC_DXT3       0x33545844
928692172297647753b19567a180d52a6415193e3ddirk#define FOURCC_DXT5       0x35545844
938692172297647753b19567a180d52a6415193e3ddirk
948692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS_COMPLEX   0x00000008
958692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS_TEXTURE   0x00001000
968692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS_MIPMAP    0x00400000
978692172297647753b19567a180d52a6415193e3ddirk
988692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP  0x00000200
998692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP_POSITIVEX  0x00000400
1008692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP_NEGATIVEX  0x00000800
1018692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP_POSITIVEY  0x00001000
1028692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP_NEGATIVEY  0x00002000
1038692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP_POSITIVEZ  0x00004000
1048692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_CUBEMAP_NEGATIVEZ  0x00008000
1058692172297647753b19567a180d52a6415193e3ddirk#define DDSCAPS2_VOLUME   0x00200000
1068692172297647753b19567a180d52a6415193e3ddirk
1078692172297647753b19567a180d52a6415193e3ddirk#ifndef SIZE_MAX
1088692172297647753b19567a180d52a6415193e3ddirk#define SIZE_MAX ((size_t) -1)
1098692172297647753b19567a180d52a6415193e3ddirk#endif
1108692172297647753b19567a180d52a6415193e3ddirk
1118692172297647753b19567a180d52a6415193e3ddirk/*
1128692172297647753b19567a180d52a6415193e3ddirk  Structure declarations.
1138692172297647753b19567a180d52a6415193e3ddirk*/
1148692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSPixelFormat
1158692172297647753b19567a180d52a6415193e3ddirk{
1168692172297647753b19567a180d52a6415193e3ddirk  size_t
1178692172297647753b19567a180d52a6415193e3ddirk    flags,
1188692172297647753b19567a180d52a6415193e3ddirk    fourcc,
1198692172297647753b19567a180d52a6415193e3ddirk    rgb_bitcount,
1208692172297647753b19567a180d52a6415193e3ddirk    r_bitmask,
1218692172297647753b19567a180d52a6415193e3ddirk    g_bitmask,
1228692172297647753b19567a180d52a6415193e3ddirk    b_bitmask,
1238692172297647753b19567a180d52a6415193e3ddirk    alpha_bitmask;
1248692172297647753b19567a180d52a6415193e3ddirk} DDSPixelFormat;
1258692172297647753b19567a180d52a6415193e3ddirk
1268692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSInfo
1278692172297647753b19567a180d52a6415193e3ddirk{
1288692172297647753b19567a180d52a6415193e3ddirk  size_t
1298692172297647753b19567a180d52a6415193e3ddirk    flags,
1308692172297647753b19567a180d52a6415193e3ddirk    height,
1318692172297647753b19567a180d52a6415193e3ddirk    width,
1328692172297647753b19567a180d52a6415193e3ddirk    pitchOrLinearSize,
1338692172297647753b19567a180d52a6415193e3ddirk    depth,
1348692172297647753b19567a180d52a6415193e3ddirk    mipmapcount,
1358692172297647753b19567a180d52a6415193e3ddirk    ddscaps1,
1368692172297647753b19567a180d52a6415193e3ddirk    ddscaps2;
1378692172297647753b19567a180d52a6415193e3ddirk
1388692172297647753b19567a180d52a6415193e3ddirk  DDSPixelFormat
1398692172297647753b19567a180d52a6415193e3ddirk    pixelformat;
1408692172297647753b19567a180d52a6415193e3ddirk} DDSInfo;
1418692172297647753b19567a180d52a6415193e3ddirk
1428692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSColors
1438692172297647753b19567a180d52a6415193e3ddirk{
1448692172297647753b19567a180d52a6415193e3ddirk  unsigned char
1458692172297647753b19567a180d52a6415193e3ddirk    r[4],
1468692172297647753b19567a180d52a6415193e3ddirk    g[4],
1478692172297647753b19567a180d52a6415193e3ddirk    b[4],
1488692172297647753b19567a180d52a6415193e3ddirk    a[4];
1498692172297647753b19567a180d52a6415193e3ddirk} DDSColors;
1508692172297647753b19567a180d52a6415193e3ddirk
1518692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSVector4
1528692172297647753b19567a180d52a6415193e3ddirk{
1538692172297647753b19567a180d52a6415193e3ddirk  float
1548692172297647753b19567a180d52a6415193e3ddirk    x,
1558692172297647753b19567a180d52a6415193e3ddirk    y,
1568692172297647753b19567a180d52a6415193e3ddirk    z,
1578692172297647753b19567a180d52a6415193e3ddirk    w;
1588692172297647753b19567a180d52a6415193e3ddirk} DDSVector4;
1598692172297647753b19567a180d52a6415193e3ddirk
1608692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSVector3
1618692172297647753b19567a180d52a6415193e3ddirk{
1628692172297647753b19567a180d52a6415193e3ddirk  float
1638692172297647753b19567a180d52a6415193e3ddirk    x,
1648692172297647753b19567a180d52a6415193e3ddirk    y,
1658692172297647753b19567a180d52a6415193e3ddirk    z;
1668692172297647753b19567a180d52a6415193e3ddirk} DDSVector3;
1678692172297647753b19567a180d52a6415193e3ddirk
1688692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSSourceBlock
1698692172297647753b19567a180d52a6415193e3ddirk{
1708692172297647753b19567a180d52a6415193e3ddirk  unsigned char
1718692172297647753b19567a180d52a6415193e3ddirk    start,
1728692172297647753b19567a180d52a6415193e3ddirk    end,
1738692172297647753b19567a180d52a6415193e3ddirk    error;
1748692172297647753b19567a180d52a6415193e3ddirk} DDSSourceBlock;
1758692172297647753b19567a180d52a6415193e3ddirk
1768692172297647753b19567a180d52a6415193e3ddirktypedef struct _DDSSingleColourLookup
1778692172297647753b19567a180d52a6415193e3ddirk{
1788692172297647753b19567a180d52a6415193e3ddirk  DDSSourceBlock sources[2];
1798692172297647753b19567a180d52a6415193e3ddirk} DDSSingleColourLookup;
1808692172297647753b19567a180d52a6415193e3ddirk
1818692172297647753b19567a180d52a6415193e3ddirktypedef MagickBooleanType
1828692172297647753b19567a180d52a6415193e3ddirk  DDSDecoder(Image *, DDSInfo *, ExceptionInfo *);
1838692172297647753b19567a180d52a6415193e3ddirk
1848692172297647753b19567a180d52a6415193e3ddirkstatic const DDSSingleColourLookup DDSLookup_5_4[] =
1858692172297647753b19567a180d52a6415193e3ddirk{
1868692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 0 }, { 0, 0, 0 } } },
1878692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 1 }, { 0, 1, 1 } } },
1888692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 2 }, { 0, 1, 0 } } },
1898692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 3 }, { 0, 1, 1 } } },
1908692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 4 }, { 0, 2, 1 } } },
1918692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 3 }, { 0, 2, 0 } } },
1928692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 2 }, { 0, 2, 1 } } },
1938692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 1 }, { 0, 3, 1 } } },
1948692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 0 }, { 0, 3, 0 } } },
1958692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 1 }, { 1, 2, 1 } } },
1968692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 2 }, { 1, 2, 0 } } },
1978692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 3 }, { 0, 4, 0 } } },
1988692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 4 }, { 0, 5, 1 } } },
1998692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 3 }, { 0, 5, 0 } } },
2008692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 2 }, { 0, 5, 1 } } },
2018692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 1 }, { 0, 6, 1 } } },
2028692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 0 }, { 0, 6, 0 } } },
2038692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 1 }, { 2, 3, 1 } } },
2048692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 2 }, { 2, 3, 0 } } },
2058692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 3 }, { 0, 7, 0 } } },
2068692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 4 }, { 1, 6, 1 } } },
2078692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 3 }, { 1, 6, 0 } } },
2088692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 2 }, { 0, 8, 0 } } },
2098692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 1 }, { 0, 9, 1 } } },
2108692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 0 }, { 0, 9, 0 } } },
2118692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 1 }, { 0, 9, 1 } } },
2128692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 2 }, { 0, 10, 1 } } },
2138692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 3 }, { 0, 10, 0 } } },
2148692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 4 }, { 2, 7, 1 } } },
2158692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 4 }, { 2, 7, 0 } } },
2168692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 3 }, { 0, 11, 0 } } },
2178692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 2 }, { 1, 10, 1 } } },
2188692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 1 }, { 1, 10, 0 } } },
2198692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 0 }, { 0, 12, 0 } } },
2208692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 1 }, { 0, 13, 1 } } },
2218692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 2 }, { 0, 13, 0 } } },
2228692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 3 }, { 0, 13, 1 } } },
2238692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 4 }, { 0, 14, 1 } } },
2248692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 3 }, { 0, 14, 0 } } },
2258692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 2 }, { 2, 11, 1 } } },
2268692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 1 }, { 2, 11, 0 } } },
2278692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 0 }, { 0, 15, 0 } } },
2288692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 1 }, { 1, 14, 1 } } },
2298692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 2 }, { 1, 14, 0 } } },
2308692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 3 }, { 0, 16, 0 } } },
2318692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 4 }, { 0, 17, 1 } } },
2328692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 3 }, { 0, 17, 0 } } },
2338692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 2 }, { 0, 17, 1 } } },
2348692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 1 }, { 0, 18, 1 } } },
2358692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 0 }, { 0, 18, 0 } } },
2368692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 1 }, { 2, 15, 1 } } },
2378692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 2 }, { 2, 15, 0 } } },
2388692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 3 }, { 0, 19, 0 } } },
2398692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 4 }, { 1, 18, 1 } } },
2408692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 3 }, { 1, 18, 0 } } },
2418692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 2 }, { 0, 20, 0 } } },
2428692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 1 }, { 0, 21, 1 } } },
2438692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 0 }, { 0, 21, 0 } } },
2448692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 1 }, { 0, 21, 1 } } },
2458692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 2 }, { 0, 22, 1 } } },
2468692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 3 }, { 0, 22, 0 } } },
2478692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 4 }, { 2, 19, 1 } } },
2488692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 4 }, { 2, 19, 0 } } },
2498692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 3 }, { 0, 23, 0 } } },
2508692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 2 }, { 1, 22, 1 } } },
2518692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 1 }, { 1, 22, 0 } } },
2528692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 0 }, { 0, 24, 0 } } },
2538692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 1 }, { 0, 25, 1 } } },
2548692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 2 }, { 0, 25, 0 } } },
2558692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 3 }, { 0, 25, 1 } } },
2568692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 4 }, { 0, 26, 1 } } },
2578692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 3 }, { 0, 26, 0 } } },
2588692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 2 }, { 2, 23, 1 } } },
2598692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 1 }, { 2, 23, 0 } } },
2608692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 0 }, { 0, 27, 0 } } },
2618692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 1 }, { 1, 26, 1 } } },
2628692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 2 }, { 1, 26, 0 } } },
2638692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 3 }, { 0, 28, 0 } } },
2648692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 4 }, { 0, 29, 1 } } },
2658692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 3 }, { 0, 29, 0 } } },
2668692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 2 }, { 0, 29, 1 } } },
2678692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 1 }, { 0, 30, 1 } } },
2688692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 0 }, { 0, 30, 0 } } },
2698692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 1 }, { 2, 27, 1 } } },
2708692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 2 }, { 2, 27, 0 } } },
2718692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 3 }, { 0, 31, 0 } } },
2728692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 4 }, { 1, 30, 1 } } },
2738692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 3 }, { 1, 30, 0 } } },
2748692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 2 }, { 4, 24, 0 } } },
2758692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 1 }, { 1, 31, 1 } } },
2768692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 0 }, { 1, 31, 0 } } },
2778692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 1 }, { 1, 31, 1 } } },
2788692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 2 }, { 2, 30, 1 } } },
2798692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 3 }, { 2, 30, 0 } } },
2808692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 4 }, { 2, 31, 1 } } },
2818692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 4 }, { 2, 31, 0 } } },
2828692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 3 }, { 4, 27, 0 } } },
2838692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 2 }, { 3, 30, 1 } } },
2848692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 1 }, { 3, 30, 0 } } },
2858692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 0 }, { 4, 28, 0 } } },
2868692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 1 }, { 3, 31, 1 } } },
2878692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 2 }, { 3, 31, 0 } } },
2888692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 3 }, { 3, 31, 1 } } },
2898692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 4 }, { 4, 30, 1 } } },
2908692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 3 }, { 4, 30, 0 } } },
2918692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 2 }, { 6, 27, 1 } } },
2928692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 1 }, { 6, 27, 0 } } },
2938692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 0 }, { 4, 31, 0 } } },
2948692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 1 }, { 5, 30, 1 } } },
2958692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 2 }, { 5, 30, 0 } } },
2968692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 3 }, { 8, 24, 0 } } },
2978692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 4 }, { 5, 31, 1 } } },
2988692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 3 }, { 5, 31, 0 } } },
2998692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 2 }, { 5, 31, 1 } } },
3008692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 1 }, { 6, 30, 1 } } },
3018692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 0 }, { 6, 30, 0 } } },
3028692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 1 }, { 6, 31, 1 } } },
3038692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 2 }, { 6, 31, 0 } } },
3048692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 3 }, { 8, 27, 0 } } },
3058692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 4 }, { 7, 30, 1 } } },
3068692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 3 }, { 7, 30, 0 } } },
3078692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 2 }, { 8, 28, 0 } } },
3088692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 1 }, { 7, 31, 1 } } },
3098692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 0 }, { 7, 31, 0 } } },
3108692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 1 }, { 7, 31, 1 } } },
3118692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 2 }, { 8, 30, 1 } } },
3128692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 3 }, { 8, 30, 0 } } },
3138692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 4 }, { 10, 27, 1 } } },
3148692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 4 }, { 10, 27, 0 } } },
3158692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 3 }, { 8, 31, 0 } } },
3168692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 2 }, { 9, 30, 1 } } },
3178692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 1 }, { 9, 30, 0 } } },
3188692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 0 }, { 12, 24, 0 } } },
3198692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 1 }, { 9, 31, 1 } } },
3208692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 2 }, { 9, 31, 0 } } },
3218692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 3 }, { 9, 31, 1 } } },
3228692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 4 }, { 10, 30, 1 } } },
3238692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 3 }, { 10, 30, 0 } } },
3248692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 2 }, { 10, 31, 1 } } },
3258692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 1 }, { 10, 31, 0 } } },
3268692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 0 }, { 12, 27, 0 } } },
3278692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 1 }, { 11, 30, 1 } } },
3288692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 2 }, { 11, 30, 0 } } },
3298692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 3 }, { 12, 28, 0 } } },
3308692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 4 }, { 11, 31, 1 } } },
3318692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 3 }, { 11, 31, 0 } } },
3328692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 2 }, { 11, 31, 1 } } },
3338692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 1 }, { 12, 30, 1 } } },
3348692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 0 }, { 12, 30, 0 } } },
3358692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 1 }, { 14, 27, 1 } } },
3368692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 2 }, { 14, 27, 0 } } },
3378692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 3 }, { 12, 31, 0 } } },
3388692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 4 }, { 13, 30, 1 } } },
3398692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 3 }, { 13, 30, 0 } } },
3408692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 2 }, { 16, 24, 0 } } },
3418692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 1 }, { 13, 31, 1 } } },
3428692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 0 }, { 13, 31, 0 } } },
3438692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 1 }, { 13, 31, 1 } } },
3448692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 2 }, { 14, 30, 1 } } },
3458692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 3 }, { 14, 30, 0 } } },
3468692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 4 }, { 14, 31, 1 } } },
3478692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 4 }, { 14, 31, 0 } } },
3488692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 3 }, { 16, 27, 0 } } },
3498692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 2 }, { 15, 30, 1 } } },
3508692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 1 }, { 15, 30, 0 } } },
3518692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 0 }, { 16, 28, 0 } } },
3528692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 1 }, { 15, 31, 1 } } },
3538692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 2 }, { 15, 31, 0 } } },
3548692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 3 }, { 15, 31, 1 } } },
3558692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 4 }, { 16, 30, 1 } } },
3568692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 3 }, { 16, 30, 0 } } },
3578692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 2 }, { 18, 27, 1 } } },
3588692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 1 }, { 18, 27, 0 } } },
3598692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 0 }, { 16, 31, 0 } } },
3608692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 1 }, { 17, 30, 1 } } },
3618692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 2 }, { 17, 30, 0 } } },
3628692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 3 }, { 20, 24, 0 } } },
3638692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 4 }, { 17, 31, 1 } } },
3648692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 3 }, { 17, 31, 0 } } },
3658692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 2 }, { 17, 31, 1 } } },
3668692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 1 }, { 18, 30, 1 } } },
3678692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 0 }, { 18, 30, 0 } } },
3688692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 1 }, { 18, 31, 1 } } },
3698692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 2 }, { 18, 31, 0 } } },
3708692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 3 }, { 20, 27, 0 } } },
3718692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 4 }, { 19, 30, 1 } } },
3728692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 3 }, { 19, 30, 0 } } },
3738692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 2 }, { 20, 28, 0 } } },
3748692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 1 }, { 19, 31, 1 } } },
3758692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 0 }, { 19, 31, 0 } } },
3768692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 1 }, { 19, 31, 1 } } },
3778692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 2 }, { 20, 30, 1 } } },
3788692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 3 }, { 20, 30, 0 } } },
3798692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 4 }, { 22, 27, 1 } } },
3808692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 4 }, { 22, 27, 0 } } },
3818692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 3 }, { 20, 31, 0 } } },
3828692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 2 }, { 21, 30, 1 } } },
3838692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 1 }, { 21, 30, 0 } } },
3848692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 0 }, { 24, 24, 0 } } },
3858692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 1 }, { 21, 31, 1 } } },
3868692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 2 }, { 21, 31, 0 } } },
3878692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 3 }, { 21, 31, 1 } } },
3888692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 4 }, { 22, 30, 1 } } },
3898692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 3 }, { 22, 30, 0 } } },
3908692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 2 }, { 22, 31, 1 } } },
3918692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 1 }, { 22, 31, 0 } } },
3928692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 0 }, { 24, 27, 0 } } },
3938692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 1 }, { 23, 30, 1 } } },
3948692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 2 }, { 23, 30, 0 } } },
3958692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 3 }, { 24, 28, 0 } } },
3968692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 4 }, { 23, 31, 1 } } },
3978692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 3 }, { 23, 31, 0 } } },
3988692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 2 }, { 23, 31, 1 } } },
3998692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 1 }, { 24, 30, 1 } } },
4008692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 0 }, { 24, 30, 0 } } },
4018692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 1 }, { 26, 27, 1 } } },
4028692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 2 }, { 26, 27, 0 } } },
4038692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 3 }, { 24, 31, 0 } } },
4048692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 4 }, { 25, 30, 1 } } },
4058692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 3 }, { 25, 30, 0 } } },
4068692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 2 }, { 28, 24, 0 } } },
4078692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 1 }, { 25, 31, 1 } } },
4088692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 0 }, { 25, 31, 0 } } },
4098692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 1 }, { 25, 31, 1 } } },
4108692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 2 }, { 26, 30, 1 } } },
4118692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 3 }, { 26, 30, 0 } } },
4128692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 4 }, { 26, 31, 1 } } },
4138692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 4 }, { 26, 31, 0 } } },
4148692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 3 }, { 28, 27, 0 } } },
4158692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 2 }, { 27, 30, 1 } } },
4168692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 1 }, { 27, 30, 0 } } },
4178692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 0 }, { 28, 28, 0 } } },
4188692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 1 }, { 27, 31, 1 } } },
4198692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 2 }, { 27, 31, 0 } } },
4208692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 3 }, { 27, 31, 1 } } },
4218692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 4 }, { 28, 30, 1 } } },
4228692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 3 }, { 28, 30, 0 } } },
4238692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 2 }, { 30, 27, 1 } } },
4248692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 1 }, { 30, 27, 0 } } },
4258692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 0 }, { 28, 31, 0 } } },
4268692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 1 }, { 29, 30, 1 } } },
4278692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 2 }, { 29, 30, 0 } } },
4288692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 3 }, { 29, 30, 1 } } },
4298692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 4 }, { 29, 31, 1 } } },
4308692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 3 }, { 29, 31, 0 } } },
4318692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 2 }, { 29, 31, 1 } } },
4328692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 1 }, { 30, 30, 1 } } },
4338692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 0 }, { 30, 30, 0 } } },
4348692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 1 }, { 30, 31, 1 } } },
4358692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 2 }, { 30, 31, 0 } } },
4368692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 3 }, { 30, 31, 1 } } },
4378692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 4 }, { 31, 30, 1 } } },
4388692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 3 }, { 31, 30, 0 } } },
4398692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 2 }, { 31, 30, 1 } } },
4408692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 1 }, { 31, 31, 1 } } },
4418692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 0 }, { 31, 31, 0 } } }
4428692172297647753b19567a180d52a6415193e3ddirk};
4438692172297647753b19567a180d52a6415193e3ddirk
4448692172297647753b19567a180d52a6415193e3ddirkstatic const DDSSingleColourLookup DDSLookup_6_4[] =
4458692172297647753b19567a180d52a6415193e3ddirk{
4468692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 0 }, { 0, 0, 0 } } },
4478692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 1 }, { 0, 1, 0 } } },
4488692172297647753b19567a180d52a6415193e3ddirk  { { { 0, 0, 2 }, { 0, 2, 0 } } },
4498692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 1 }, { 0, 3, 1 } } },
4508692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 0 }, { 0, 3, 0 } } },
4518692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 1 }, { 0, 4, 0 } } },
4528692172297647753b19567a180d52a6415193e3ddirk  { { { 1, 0, 2 }, { 0, 5, 0 } } },
4538692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 1 }, { 0, 6, 1 } } },
4548692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 0 }, { 0, 6, 0 } } },
4558692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 1 }, { 0, 7, 0 } } },
4568692172297647753b19567a180d52a6415193e3ddirk  { { { 2, 0, 2 }, { 0, 8, 0 } } },
4578692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 1 }, { 0, 9, 1 } } },
4588692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 0 }, { 0, 9, 0 } } },
4598692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 1 }, { 0, 10, 0 } } },
4608692172297647753b19567a180d52a6415193e3ddirk  { { { 3, 0, 2 }, { 0, 11, 0 } } },
4618692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 1 }, { 0, 12, 1 } } },
4628692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 0 }, { 0, 12, 0 } } },
4638692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 1 }, { 0, 13, 0 } } },
4648692172297647753b19567a180d52a6415193e3ddirk  { { { 4, 0, 2 }, { 0, 14, 0 } } },
4658692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 1 }, { 0, 15, 1 } } },
4668692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 0 }, { 0, 15, 0 } } },
4678692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 1 }, { 0, 16, 0 } } },
4688692172297647753b19567a180d52a6415193e3ddirk  { { { 5, 0, 2 }, { 1, 15, 0 } } },
4698692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 1 }, { 0, 17, 0 } } },
4708692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 0 }, { 0, 18, 0 } } },
4718692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 1 }, { 0, 19, 0 } } },
4728692172297647753b19567a180d52a6415193e3ddirk  { { { 6, 0, 2 }, { 3, 14, 0 } } },
4738692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 1 }, { 0, 20, 0 } } },
4748692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 0 }, { 0, 21, 0 } } },
4758692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 1 }, { 0, 22, 0 } } },
4768692172297647753b19567a180d52a6415193e3ddirk  { { { 7, 0, 2 }, { 4, 15, 0 } } },
4778692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 1 }, { 0, 23, 0 } } },
4788692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 0 }, { 0, 24, 0 } } },
4798692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 1 }, { 0, 25, 0 } } },
4808692172297647753b19567a180d52a6415193e3ddirk  { { { 8, 0, 2 }, { 6, 14, 0 } } },
4818692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 1 }, { 0, 26, 0 } } },
4828692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 0 }, { 0, 27, 0 } } },
4838692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 1 }, { 0, 28, 0 } } },
4848692172297647753b19567a180d52a6415193e3ddirk  { { { 9, 0, 2 }, { 7, 15, 0 } } },
4858692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 1 }, { 0, 29, 0 } } },
4868692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 0 }, { 0, 30, 0 } } },
4878692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 1 }, { 0, 31, 0 } } },
4888692172297647753b19567a180d52a6415193e3ddirk  { { { 10, 0, 2 }, { 9, 14, 0 } } },
4898692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 1 }, { 0, 32, 0 } } },
4908692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 0 }, { 0, 33, 0 } } },
4918692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 1 }, { 2, 30, 0 } } },
4928692172297647753b19567a180d52a6415193e3ddirk  { { { 11, 0, 2 }, { 0, 34, 0 } } },
4938692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 1 }, { 0, 35, 0 } } },
4948692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 0 }, { 0, 36, 0 } } },
4958692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 1 }, { 3, 31, 0 } } },
4968692172297647753b19567a180d52a6415193e3ddirk  { { { 12, 0, 2 }, { 0, 37, 0 } } },
4978692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 1 }, { 0, 38, 0 } } },
4988692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 0 }, { 0, 39, 0 } } },
4998692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 1 }, { 5, 30, 0 } } },
5008692172297647753b19567a180d52a6415193e3ddirk  { { { 13, 0, 2 }, { 0, 40, 0 } } },
5018692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 1 }, { 0, 41, 0 } } },
5028692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 0 }, { 0, 42, 0 } } },
5038692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 1 }, { 6, 31, 0 } } },
5048692172297647753b19567a180d52a6415193e3ddirk  { { { 14, 0, 2 }, { 0, 43, 0 } } },
5058692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 1 }, { 0, 44, 0 } } },
5068692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 0 }, { 0, 45, 0 } } },
5078692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 1 }, { 8, 30, 0 } } },
5088692172297647753b19567a180d52a6415193e3ddirk  { { { 15, 0, 2 }, { 0, 46, 0 } } },
5098692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 2 }, { 0, 47, 0 } } },
5108692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 1 }, { 1, 46, 0 } } },
5118692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 0 }, { 0, 48, 0 } } },
5128692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 1 }, { 0, 49, 0 } } },
5138692172297647753b19567a180d52a6415193e3ddirk  { { { 16, 0, 2 }, { 0, 50, 0 } } },
5148692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 1 }, { 2, 47, 0 } } },
5158692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 0 }, { 0, 51, 0 } } },
5168692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 1 }, { 0, 52, 0 } } },
5178692172297647753b19567a180d52a6415193e3ddirk  { { { 17, 0, 2 }, { 0, 53, 0 } } },
5188692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 1 }, { 4, 46, 0 } } },
5198692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 0 }, { 0, 54, 0 } } },
5208692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 1 }, { 0, 55, 0 } } },
5218692172297647753b19567a180d52a6415193e3ddirk  { { { 18, 0, 2 }, { 0, 56, 0 } } },
5228692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 1 }, { 5, 47, 0 } } },
5238692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 0 }, { 0, 57, 0 } } },
5248692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 1 }, { 0, 58, 0 } } },
5258692172297647753b19567a180d52a6415193e3ddirk  { { { 19, 0, 2 }, { 0, 59, 0 } } },
5268692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 1 }, { 7, 46, 0 } } },
5278692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 0 }, { 0, 60, 0 } } },
5288692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 1 }, { 0, 61, 0 } } },
5298692172297647753b19567a180d52a6415193e3ddirk  { { { 20, 0, 2 }, { 0, 62, 0 } } },
5308692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 1 }, { 8, 47, 0 } } },
5318692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 0 }, { 0, 63, 0 } } },
5328692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 1 }, { 1, 62, 0 } } },
5338692172297647753b19567a180d52a6415193e3ddirk  { { { 21, 0, 2 }, { 1, 63, 0 } } },
5348692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 1 }, { 10, 46, 0 } } },
5358692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 0 }, { 2, 62, 0 } } },
5368692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 1 }, { 2, 63, 0 } } },
5378692172297647753b19567a180d52a6415193e3ddirk  { { { 22, 0, 2 }, { 3, 62, 0 } } },
5388692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 1 }, { 11, 47, 0 } } },
5398692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 0 }, { 3, 63, 0 } } },
5408692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 1 }, { 4, 62, 0 } } },
5418692172297647753b19567a180d52a6415193e3ddirk  { { { 23, 0, 2 }, { 4, 63, 0 } } },
5428692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 1 }, { 13, 46, 0 } } },
5438692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 0 }, { 5, 62, 0 } } },
5448692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 1 }, { 5, 63, 0 } } },
5458692172297647753b19567a180d52a6415193e3ddirk  { { { 24, 0, 2 }, { 6, 62, 0 } } },
5468692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 1 }, { 14, 47, 0 } } },
5478692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 0 }, { 6, 63, 0 } } },
5488692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 1 }, { 7, 62, 0 } } },
5498692172297647753b19567a180d52a6415193e3ddirk  { { { 25, 0, 2 }, { 7, 63, 0 } } },
5508692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 1 }, { 16, 45, 0 } } },
5518692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 0 }, { 8, 62, 0 } } },
5528692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 1 }, { 8, 63, 0 } } },
5538692172297647753b19567a180d52a6415193e3ddirk  { { { 26, 0, 2 }, { 9, 62, 0 } } },
5548692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 1 }, { 16, 48, 0 } } },
5558692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 0 }, { 9, 63, 0 } } },
5568692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 1 }, { 10, 62, 0 } } },
5578692172297647753b19567a180d52a6415193e3ddirk  { { { 27, 0, 2 }, { 10, 63, 0 } } },
5588692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 1 }, { 16, 51, 0 } } },
5598692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 0 }, { 11, 62, 0 } } },
5608692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 1 }, { 11, 63, 0 } } },
5618692172297647753b19567a180d52a6415193e3ddirk  { { { 28, 0, 2 }, { 12, 62, 0 } } },
5628692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 1 }, { 16, 54, 0 } } },
5638692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 0 }, { 12, 63, 0 } } },
5648692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 1 }, { 13, 62, 0 } } },
5658692172297647753b19567a180d52a6415193e3ddirk  { { { 29, 0, 2 }, { 13, 63, 0 } } },
5668692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 1 }, { 16, 57, 0 } } },
5678692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 0 }, { 14, 62, 0 } } },
5688692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 1 }, { 14, 63, 0 } } },
5698692172297647753b19567a180d52a6415193e3ddirk  { { { 30, 0, 2 }, { 15, 62, 0 } } },
5708692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 1 }, { 16, 60, 0 } } },
5718692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 0 }, { 15, 63, 0 } } },
5728692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 1 }, { 24, 46, 0 } } },
5738692172297647753b19567a180d52a6415193e3ddirk  { { { 31, 0, 2 }, { 16, 62, 0 } } },
5748692172297647753b19567a180d52a6415193e3ddirk  { { { 32, 0, 2 }, { 16, 63, 0 } } },
5758692172297647753b19567a180d52a6415193e3ddirk  { { { 32, 0, 1 }, { 17, 62, 0 } } },
5768692172297647753b19567a180d52a6415193e3ddirk  { { { 32, 0, 0 }, { 25, 47, 0 } } },
5778692172297647753b19567a180d52a6415193e3ddirk  { { { 32, 0, 1 }, { 17, 63, 0 } } },
5788692172297647753b19567a180d52a6415193e3ddirk  { { { 32, 0, 2 }, { 18, 62, 0 } } },
5798692172297647753b19567a180d52a6415193e3ddirk  { { { 33, 0, 1 }, { 18, 63, 0 } } },
5808692172297647753b19567a180d52a6415193e3ddirk  { { { 33, 0, 0 }, { 27, 46, 0 } } },
5818692172297647753b19567a180d52a6415193e3ddirk  { { { 33, 0, 1 }, { 19, 62, 0 } } },
5828692172297647753b19567a180d52a6415193e3ddirk  { { { 33, 0, 2 }, { 19, 63, 0 } } },
5838692172297647753b19567a180d52a6415193e3ddirk  { { { 34, 0, 1 }, { 20, 62, 0 } } },
5848692172297647753b19567a180d52a6415193e3ddirk  { { { 34, 0, 0 }, { 28, 47, 0 } } },
5858692172297647753b19567a180d52a6415193e3ddirk  { { { 34, 0, 1 }, { 20, 63, 0 } } },
5868692172297647753b19567a180d52a6415193e3ddirk  { { { 34, 0, 2 }, { 21, 62, 0 } } },
5878692172297647753b19567a180d52a6415193e3ddirk  { { { 35, 0, 1 }, { 21, 63, 0 } } },
5888692172297647753b19567a180d52a6415193e3ddirk  { { { 35, 0, 0 }, { 30, 46, 0 } } },
5898692172297647753b19567a180d52a6415193e3ddirk  { { { 35, 0, 1 }, { 22, 62, 0 } } },
5908692172297647753b19567a180d52a6415193e3ddirk  { { { 35, 0, 2 }, { 22, 63, 0 } } },
5918692172297647753b19567a180d52a6415193e3ddirk  { { { 36, 0, 1 }, { 23, 62, 0 } } },
5928692172297647753b19567a180d52a6415193e3ddirk  { { { 36, 0, 0 }, { 31, 47, 0 } } },
5938692172297647753b19567a180d52a6415193e3ddirk  { { { 36, 0, 1 }, { 23, 63, 0 } } },
5948692172297647753b19567a180d52a6415193e3ddirk  { { { 36, 0, 2 }, { 24, 62, 0 } } },
5958692172297647753b19567a180d52a6415193e3ddirk  { { { 37, 0, 1 }, { 24, 63, 0 } } },
5968692172297647753b19567a180d52a6415193e3ddirk  { { { 37, 0, 0 }, { 32, 47, 0 } } },
5978692172297647753b19567a180d52a6415193e3ddirk  { { { 37, 0, 1 }, { 25, 62, 0 } } },
5988692172297647753b19567a180d52a6415193e3ddirk  { { { 37, 0, 2 }, { 25, 63, 0 } } },
5998692172297647753b19567a180d52a6415193e3ddirk  { { { 38, 0, 1 }, { 26, 62, 0 } } },
6008692172297647753b19567a180d52a6415193e3ddirk  { { { 38, 0, 0 }, { 32, 50, 0 } } },
6018692172297647753b19567a180d52a6415193e3ddirk  { { { 38, 0, 1 }, { 26, 63, 0 } } },
6028692172297647753b19567a180d52a6415193e3ddirk  { { { 38, 0, 2 }, { 27, 62, 0 } } },
6038692172297647753b19567a180d52a6415193e3ddirk  { { { 39, 0, 1 }, { 27, 63, 0 } } },
6048692172297647753b19567a180d52a6415193e3ddirk  { { { 39, 0, 0 }, { 32, 53, 0 } } },
6058692172297647753b19567a180d52a6415193e3ddirk  { { { 39, 0, 1 }, { 28, 62, 0 } } },
6068692172297647753b19567a180d52a6415193e3ddirk  { { { 39, 0, 2 }, { 28, 63, 0 } } },
6078692172297647753b19567a180d52a6415193e3ddirk  { { { 40, 0, 1 }, { 29, 62, 0 } } },
6088692172297647753b19567a180d52a6415193e3ddirk  { { { 40, 0, 0 }, { 32, 56, 0 } } },
6098692172297647753b19567a180d52a6415193e3ddirk  { { { 40, 0, 1 }, { 29, 63, 0 } } },
6108692172297647753b19567a180d52a6415193e3ddirk  { { { 40, 0, 2 }, { 30, 62, 0 } } },
6118692172297647753b19567a180d52a6415193e3ddirk  { { { 41, 0, 1 }, { 30, 63, 0 } } },
6128692172297647753b19567a180d52a6415193e3ddirk  { { { 41, 0, 0 }, { 32, 59, 0 } } },
6138692172297647753b19567a180d52a6415193e3ddirk  { { { 41, 0, 1 }, { 31, 62, 0 } } },
6148692172297647753b19567a180d52a6415193e3ddirk  { { { 41, 0, 2 }, { 31, 63, 0 } } },
6158692172297647753b19567a180d52a6415193e3ddirk  { { { 42, 0, 1 }, { 32, 61, 0 } } },
6168692172297647753b19567a180d52a6415193e3ddirk  { { { 42, 0, 0 }, { 32, 62, 0 } } },
6178692172297647753b19567a180d52a6415193e3ddirk  { { { 42, 0, 1 }, { 32, 63, 0 } } },
6188692172297647753b19567a180d52a6415193e3ddirk  { { { 42, 0, 2 }, { 41, 46, 0 } } },
6198692172297647753b19567a180d52a6415193e3ddirk  { { { 43, 0, 1 }, { 33, 62, 0 } } },
6208692172297647753b19567a180d52a6415193e3ddirk  { { { 43, 0, 0 }, { 33, 63, 0 } } },
6218692172297647753b19567a180d52a6415193e3ddirk  { { { 43, 0, 1 }, { 34, 62, 0 } } },
6228692172297647753b19567a180d52a6415193e3ddirk  { { { 43, 0, 2 }, { 42, 47, 0 } } },
6238692172297647753b19567a180d52a6415193e3ddirk  { { { 44, 0, 1 }, { 34, 63, 0 } } },
6248692172297647753b19567a180d52a6415193e3ddirk  { { { 44, 0, 0 }, { 35, 62, 0 } } },
6258692172297647753b19567a180d52a6415193e3ddirk  { { { 44, 0, 1 }, { 35, 63, 0 } } },
6268692172297647753b19567a180d52a6415193e3ddirk  { { { 44, 0, 2 }, { 44, 46, 0 } } },
6278692172297647753b19567a180d52a6415193e3ddirk  { { { 45, 0, 1 }, { 36, 62, 0 } } },
6288692172297647753b19567a180d52a6415193e3ddirk  { { { 45, 0, 0 }, { 36, 63, 0 } } },
6298692172297647753b19567a180d52a6415193e3ddirk  { { { 45, 0, 1 }, { 37, 62, 0 } } },
6308692172297647753b19567a180d52a6415193e3ddirk  { { { 45, 0, 2 }, { 45, 47, 0 } } },
6318692172297647753b19567a180d52a6415193e3ddirk  { { { 46, 0, 1 }, { 37, 63, 0 } } },
6328692172297647753b19567a180d52a6415193e3ddirk  { { { 46, 0, 0 }, { 38, 62, 0 } } },
6338692172297647753b19567a180d52a6415193e3ddirk  { { { 46, 0, 1 }, { 38, 63, 0 } } },
6348692172297647753b19567a180d52a6415193e3ddirk  { { { 46, 0, 2 }, { 47, 46, 0 } } },
6358692172297647753b19567a180d52a6415193e3ddirk  { { { 47, 0, 1 }, { 39, 62, 0 } } },
6368692172297647753b19567a180d52a6415193e3ddirk  { { { 47, 0, 0 }, { 39, 63, 0 } } },
6378692172297647753b19567a180d52a6415193e3ddirk  { { { 47, 0, 1 }, { 40, 62, 0 } } },
6388692172297647753b19567a180d52a6415193e3ddirk  { { { 47, 0, 2 }, { 48, 46, 0 } } },
6398692172297647753b19567a180d52a6415193e3ddirk  { { { 48, 0, 2 }, { 40, 63, 0 } } },
6408692172297647753b19567a180d52a6415193e3ddirk  { { { 48, 0, 1 }, { 41, 62, 0 } } },
6418692172297647753b19567a180d52a6415193e3ddirk  { { { 48, 0, 0 }, { 41, 63, 0 } } },
6428692172297647753b19567a180d52a6415193e3ddirk  { { { 48, 0, 1 }, { 48, 49, 0 } } },
6438692172297647753b19567a180d52a6415193e3ddirk  { { { 48, 0, 2 }, { 42, 62, 0 } } },
6448692172297647753b19567a180d52a6415193e3ddirk  { { { 49, 0, 1 }, { 42, 63, 0 } } },
6458692172297647753b19567a180d52a6415193e3ddirk  { { { 49, 0, 0 }, { 43, 62, 0 } } },
6468692172297647753b19567a180d52a6415193e3ddirk  { { { 49, 0, 1 }, { 48, 52, 0 } } },
6478692172297647753b19567a180d52a6415193e3ddirk  { { { 49, 0, 2 }, { 43, 63, 0 } } },
6488692172297647753b19567a180d52a6415193e3ddirk  { { { 50, 0, 1 }, { 44, 62, 0 } } },
6498692172297647753b19567a180d52a6415193e3ddirk  { { { 50, 0, 0 }, { 44, 63, 0 } } },
6508692172297647753b19567a180d52a6415193e3ddirk  { { { 50, 0, 1 }, { 48, 55, 0 } } },
6518692172297647753b19567a180d52a6415193e3ddirk  { { { 50, 0, 2 }, { 45, 62, 0 } } },
6528692172297647753b19567a180d52a6415193e3ddirk  { { { 51, 0, 1 }, { 45, 63, 0 } } },
6538692172297647753b19567a180d52a6415193e3ddirk  { { { 51, 0, 0 }, { 46, 62, 0 } } },
6548692172297647753b19567a180d52a6415193e3ddirk  { { { 51, 0, 1 }, { 48, 58, 0 } } },
6558692172297647753b19567a180d52a6415193e3ddirk  { { { 51, 0, 2 }, { 46, 63, 0 } } },
6568692172297647753b19567a180d52a6415193e3ddirk  { { { 52, 0, 1 }, { 47, 62, 0 } } },
6578692172297647753b19567a180d52a6415193e3ddirk  { { { 52, 0, 0 }, { 47, 63, 0 } } },
6588692172297647753b19567a180d52a6415193e3ddirk  { { { 52, 0, 1 }, { 48, 61, 0 } } },
6598692172297647753b19567a180d52a6415193e3ddirk  { { { 52, 0, 2 }, { 48, 62, 0 } } },
6608692172297647753b19567a180d52a6415193e3ddirk  { { { 53, 0, 1 }, { 56, 47, 0 } } },
6618692172297647753b19567a180d52a6415193e3ddirk  { { { 53, 0, 0 }, { 48, 63, 0 } } },
6628692172297647753b19567a180d52a6415193e3ddirk  { { { 53, 0, 1 }, { 49, 62, 0 } } },
6638692172297647753b19567a180d52a6415193e3ddirk  { { { 53, 0, 2 }, { 49, 63, 0 } } },
6648692172297647753b19567a180d52a6415193e3ddirk  { { { 54, 0, 1 }, { 58, 46, 0 } } },
6658692172297647753b19567a180d52a6415193e3ddirk  { { { 54, 0, 0 }, { 50, 62, 0 } } },
6668692172297647753b19567a180d52a6415193e3ddirk  { { { 54, 0, 1 }, { 50, 63, 0 } } },
6678692172297647753b19567a180d52a6415193e3ddirk  { { { 54, 0, 2 }, { 51, 62, 0 } } },
6688692172297647753b19567a180d52a6415193e3ddirk  { { { 55, 0, 1 }, { 59, 47, 0 } } },
6698692172297647753b19567a180d52a6415193e3ddirk  { { { 55, 0, 0 }, { 51, 63, 0 } } },
6708692172297647753b19567a180d52a6415193e3ddirk  { { { 55, 0, 1 }, { 52, 62, 0 } } },
6718692172297647753b19567a180d52a6415193e3ddirk  { { { 55, 0, 2 }, { 52, 63, 0 } } },
6728692172297647753b19567a180d52a6415193e3ddirk  { { { 56, 0, 1 }, { 61, 46, 0 } } },
6738692172297647753b19567a180d52a6415193e3ddirk  { { { 56, 0, 0 }, { 53, 62, 0 } } },
6748692172297647753b19567a180d52a6415193e3ddirk  { { { 56, 0, 1 }, { 53, 63, 0 } } },
6758692172297647753b19567a180d52a6415193e3ddirk  { { { 56, 0, 2 }, { 54, 62, 0 } } },
6768692172297647753b19567a180d52a6415193e3ddirk  { { { 57, 0, 1 }, { 62, 47, 0 } } },
6778692172297647753b19567a180d52a6415193e3ddirk  { { { 57, 0, 0 }, { 54, 63, 0 } } },
6788692172297647753b19567a180d52a6415193e3ddirk  { { { 57, 0, 1 }, { 55, 62, 0 } } },
6798692172297647753b19567a180d52a6415193e3ddirk  { { { 57, 0, 2 }, { 55, 63, 0 } } },
6808692172297647753b19567a180d52a6415193e3ddirk  { { { 58, 0, 1 }, { 56, 62, 1 } } },
6818692172297647753b19567a180d52a6415193e3ddirk  { { { 58, 0, 0 }, { 56, 62, 0 } } },
6828692172297647753b19567a180d52a6415193e3ddirk  { { { 58, 0, 1 }, { 56, 63, 0 } } },
6838692172297647753b19567a180d52a6415193e3ddirk  { { { 58, 0, 2 }, { 57, 62, 0 } } },
6848692172297647753b19567a180d52a6415193e3ddirk  { { { 59, 0, 1 }, { 57, 63, 1 } } },
6858692172297647753b19567a180d52a6415193e3ddirk  { { { 59, 0, 0 }, { 57, 63, 0 } } },
6868692172297647753b19567a180d52a6415193e3ddirk  { { { 59, 0, 1 }, { 58, 62, 0 } } },
6878692172297647753b19567a180d52a6415193e3ddirk  { { { 59, 0, 2 }, { 58, 63, 0 } } },
6888692172297647753b19567a180d52a6415193e3ddirk  { { { 60, 0, 1 }, { 59, 62, 1 } } },
6898692172297647753b19567a180d52a6415193e3ddirk  { { { 60, 0, 0 }, { 59, 62, 0 } } },
6908692172297647753b19567a180d52a6415193e3ddirk  { { { 60, 0, 1 }, { 59, 63, 0 } } },
6918692172297647753b19567a180d52a6415193e3ddirk  { { { 60, 0, 2 }, { 60, 62, 0 } } },
6928692172297647753b19567a180d52a6415193e3ddirk  { { { 61, 0, 1 }, { 60, 63, 1 } } },
6938692172297647753b19567a180d52a6415193e3ddirk  { { { 61, 0, 0 }, { 60, 63, 0 } } },
6948692172297647753b19567a180d52a6415193e3ddirk  { { { 61, 0, 1 }, { 61, 62, 0 } } },
6958692172297647753b19567a180d52a6415193e3ddirk  { { { 61, 0, 2 }, { 61, 63, 0 } } },
6968692172297647753b19567a180d52a6415193e3ddirk  { { { 62, 0, 1 }, { 62, 62, 1 } } },
6978692172297647753b19567a180d52a6415193e3ddirk  { { { 62, 0, 0 }, { 62, 62, 0 } } },
6988692172297647753b19567a180d52a6415193e3ddirk  { { { 62, 0, 1 }, { 62, 63, 0 } } },
6998692172297647753b19567a180d52a6415193e3ddirk  { { { 62, 0, 2 }, { 63, 62, 0 } } },
7008692172297647753b19567a180d52a6415193e3ddirk  { { { 63, 0, 1 }, { 63, 63, 1 } } },
7018692172297647753b19567a180d52a6415193e3ddirk  { { { 63, 0, 0 }, { 63, 63, 0 } } }
7028692172297647753b19567a180d52a6415193e3ddirk};
7038692172297647753b19567a180d52a6415193e3ddirk
7048692172297647753b19567a180d52a6415193e3ddirkstatic const DDSSingleColourLookup*
7058692172297647753b19567a180d52a6415193e3ddirk  DDS_LOOKUP[] =
7068692172297647753b19567a180d52a6415193e3ddirk{
7078692172297647753b19567a180d52a6415193e3ddirk  DDSLookup_5_4,
7088692172297647753b19567a180d52a6415193e3ddirk  DDSLookup_6_4,
7098692172297647753b19567a180d52a6415193e3ddirk  DDSLookup_5_4
7108692172297647753b19567a180d52a6415193e3ddirk};
7118692172297647753b19567a180d52a6415193e3ddirk
7128692172297647753b19567a180d52a6415193e3ddirk/*
7138692172297647753b19567a180d52a6415193e3ddirk  Macros
7148692172297647753b19567a180d52a6415193e3ddirk*/
7158692172297647753b19567a180d52a6415193e3ddirk#define C565_r(x) (((x) & 0xF800) >> 11)
7168692172297647753b19567a180d52a6415193e3ddirk#define C565_g(x) (((x) & 0x07E0) >> 5)
7178692172297647753b19567a180d52a6415193e3ddirk#define C565_b(x)  ((x) & 0x001F)
7188692172297647753b19567a180d52a6415193e3ddirk
7198692172297647753b19567a180d52a6415193e3ddirk#define C565_red(x)   ( (C565_r(x) << 3 | C565_r(x) >> 2))
7208692172297647753b19567a180d52a6415193e3ddirk#define C565_green(x) ( (C565_g(x) << 2 | C565_g(x) >> 4))
7218692172297647753b19567a180d52a6415193e3ddirk#define C565_blue(x)  ( (C565_b(x) << 3 | C565_b(x) >> 2))
7228692172297647753b19567a180d52a6415193e3ddirk
7238692172297647753b19567a180d52a6415193e3ddirk#define DIV2(x)  ((x) > 1 ? ((x) >> 1) : 1)
7248692172297647753b19567a180d52a6415193e3ddirk
7258692172297647753b19567a180d52a6415193e3ddirk#define FixRange(min, max, steps) \
7268692172297647753b19567a180d52a6415193e3ddirkif (min > max) \
7278692172297647753b19567a180d52a6415193e3ddirk  min = max; \
7288692172297647753b19567a180d52a6415193e3ddirkif (max - min < steps) \
729ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  max = MagickMin(min + steps, 255); \
7308692172297647753b19567a180d52a6415193e3ddirkif (max - min < steps) \
7313e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd  min = MagickMax(0, max - steps)
7328692172297647753b19567a180d52a6415193e3ddirk
7338692172297647753b19567a180d52a6415193e3ddirk#define Dot(left, right) (left.x*right.x) + (left.y*right.y) + (left.z*right.z)
7348692172297647753b19567a180d52a6415193e3ddirk
7358692172297647753b19567a180d52a6415193e3ddirk#define VectorInit(vector, value) vector.x = vector.y = vector.z = vector.w \
7368692172297647753b19567a180d52a6415193e3ddirk  = value
7378692172297647753b19567a180d52a6415193e3ddirk#define VectorInit3(vector, value) vector.x = vector.y = vector.z = value
7388692172297647753b19567a180d52a6415193e3ddirk
7398692172297647753b19567a180d52a6415193e3ddirk#define IsBitMask(mask, r, g, b, a) (mask.r_bitmask == r && mask.g_bitmask == \
7408692172297647753b19567a180d52a6415193e3ddirk  g && mask.b_bitmask == b && mask.alpha_bitmask == a)
7418692172297647753b19567a180d52a6415193e3ddirk
7428692172297647753b19567a180d52a6415193e3ddirk/*
7438692172297647753b19567a180d52a6415193e3ddirk  Forward declarations
7448692172297647753b19567a180d52a6415193e3ddirk*/
745ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk/*
746ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  Forward declarations
747ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk*/
7488692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType
749ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ConstructOrdering(const size_t,const DDSVector4 *,const DDSVector3,
750ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk    DDSVector4 *, DDSVector4 *, unsigned char *, size_t),
751ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ReadDDSInfo(Image *,DDSInfo *),
752ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ReadDXT1(Image *,DDSInfo *,ExceptionInfo *),
753ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ReadDXT3(Image *,DDSInfo *,ExceptionInfo *),
754ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ReadDXT5(Image *,DDSInfo *,ExceptionInfo *),
755ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ReadUncompressedRGB(Image *,DDSInfo *,ExceptionInfo *),
756ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  ReadUncompressedRGBA(Image *,DDSInfo *,ExceptionInfo *),
757ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  SkipDXTMipmaps(Image *,DDSInfo *,int,ExceptionInfo *),
758ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  SkipRGBMipmaps(Image *,DDSInfo *,int,ExceptionInfo *),
759ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteDDSImage(const ImageInfo *,Image *,ExceptionInfo *),
760ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteMipmaps(Image *,const size_t,const size_t,const size_t,
761ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk    const MagickBooleanType,const MagickBooleanType,ExceptionInfo *);
7628692172297647753b19567a180d52a6415193e3ddirk
7638692172297647753b19567a180d52a6415193e3ddirkstatic void
764ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  RemapIndices(const ssize_t *,const unsigned char *,unsigned char *),
765ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteDDSInfo(Image *,const size_t,const size_t,const size_t),
766ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteFourCC(Image *,const size_t,const MagickBooleanType,
767ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk    const MagickBooleanType,ExceptionInfo *),
768ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteImageData(Image *,const size_t,const size_t,const MagickBooleanType,
769ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk    const MagickBooleanType,ExceptionInfo *),
770ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteIndices(Image *,const DDSVector3,const DDSVector3,unsigned char *),
771ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteSingleColorFit(Image *,const DDSVector4 *,const ssize_t *),
772ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  WriteUncompressed(Image *,ExceptionInfo *);
7738692172297647753b19567a180d52a6415193e3ddirk
7748692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorAdd(const DDSVector4 left, const DDSVector4 right,
7758692172297647753b19567a180d52a6415193e3ddirk  DDSVector4 *destination)
7768692172297647753b19567a180d52a6415193e3ddirk{
7778692172297647753b19567a180d52a6415193e3ddirk  destination->x = left.x + right.x;
7788692172297647753b19567a180d52a6415193e3ddirk  destination->y = left.y + right.y;
7798692172297647753b19567a180d52a6415193e3ddirk  destination->z = left.z + right.z;
7808692172297647753b19567a180d52a6415193e3ddirk  destination->w = left.w + right.w;
7818692172297647753b19567a180d52a6415193e3ddirk}
7828692172297647753b19567a180d52a6415193e3ddirk
7838692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorClamp(DDSVector4 *value)
7848692172297647753b19567a180d52a6415193e3ddirk{
785ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->x = MagickMin(1.0f,MagickMax(0.0f,value->x));
786ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->y = MagickMin(1.0f,MagickMax(0.0f,value->y));
787ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->z = MagickMin(1.0f,MagickMax(0.0f,value->z));
788ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->w = MagickMin(1.0f,MagickMax(0.0f,value->w));
7898692172297647753b19567a180d52a6415193e3ddirk}
7908692172297647753b19567a180d52a6415193e3ddirk
7918692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorClamp3(DDSVector3 *value)
7928692172297647753b19567a180d52a6415193e3ddirk{
793ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->x = MagickMin(1.0f,MagickMax(0.0f,value->x));
794ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->y = MagickMin(1.0f,MagickMax(0.0f,value->y));
795ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  value->z = MagickMin(1.0f,MagickMax(0.0f,value->z));
7968692172297647753b19567a180d52a6415193e3ddirk}
7978692172297647753b19567a180d52a6415193e3ddirk
7988692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorCopy43(const DDSVector4 source,
7998692172297647753b19567a180d52a6415193e3ddirk  DDSVector3 *destination)
8008692172297647753b19567a180d52a6415193e3ddirk{
8018692172297647753b19567a180d52a6415193e3ddirk  destination->x = source.x;
8028692172297647753b19567a180d52a6415193e3ddirk  destination->y = source.y;
8038692172297647753b19567a180d52a6415193e3ddirk  destination->z = source.z;
8048692172297647753b19567a180d52a6415193e3ddirk}
8058692172297647753b19567a180d52a6415193e3ddirk
8068692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorCopy44(const DDSVector4 source,
8078692172297647753b19567a180d52a6415193e3ddirk  DDSVector4 *destination)
8088692172297647753b19567a180d52a6415193e3ddirk{
8098692172297647753b19567a180d52a6415193e3ddirk  destination->x = source.x;
8108692172297647753b19567a180d52a6415193e3ddirk  destination->y = source.y;
8118692172297647753b19567a180d52a6415193e3ddirk  destination->z = source.z;
8128692172297647753b19567a180d52a6415193e3ddirk  destination->w = source.w;
8138692172297647753b19567a180d52a6415193e3ddirk}
8148692172297647753b19567a180d52a6415193e3ddirk
8158692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorNegativeMultiplySubtract(const DDSVector4 a,
8168692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 b, const DDSVector4 c, DDSVector4 *destination)
8178692172297647753b19567a180d52a6415193e3ddirk{
8188692172297647753b19567a180d52a6415193e3ddirk  destination->x = c.x - (a.x * b.x);
8198692172297647753b19567a180d52a6415193e3ddirk  destination->y = c.y - (a.y * b.y);
8208692172297647753b19567a180d52a6415193e3ddirk  destination->z = c.z - (a.z * b.z);
8218692172297647753b19567a180d52a6415193e3ddirk  destination->w = c.w - (a.w * b.w);
8228692172297647753b19567a180d52a6415193e3ddirk}
8238692172297647753b19567a180d52a6415193e3ddirk
8248692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorMultiply(const DDSVector4 left,
8258692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 right, DDSVector4 *destination)
8268692172297647753b19567a180d52a6415193e3ddirk{
8278692172297647753b19567a180d52a6415193e3ddirk  destination->x = left.x * right.x;
8288692172297647753b19567a180d52a6415193e3ddirk  destination->y = left.y * right.y;
8298692172297647753b19567a180d52a6415193e3ddirk  destination->z = left.z * right.z;
8308692172297647753b19567a180d52a6415193e3ddirk  destination->w = left.w * right.w;
8318692172297647753b19567a180d52a6415193e3ddirk}
8328692172297647753b19567a180d52a6415193e3ddirk
8338692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorMultiply3(const DDSVector3 left,
8348692172297647753b19567a180d52a6415193e3ddirk  const DDSVector3 right, DDSVector3 *destination)
8358692172297647753b19567a180d52a6415193e3ddirk{
8368692172297647753b19567a180d52a6415193e3ddirk  destination->x = left.x * right.x;
8378692172297647753b19567a180d52a6415193e3ddirk  destination->y = left.y * right.y;
8388692172297647753b19567a180d52a6415193e3ddirk  destination->z = left.z * right.z;
8398692172297647753b19567a180d52a6415193e3ddirk}
8408692172297647753b19567a180d52a6415193e3ddirk
8418692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorMultiplyAdd(const DDSVector4 a, const DDSVector4 b,
8428692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 c, DDSVector4 *destination)
8438692172297647753b19567a180d52a6415193e3ddirk{
8448692172297647753b19567a180d52a6415193e3ddirk  destination->x = (a.x * b.x) + c.x;
8458692172297647753b19567a180d52a6415193e3ddirk  destination->y = (a.y * b.y) + c.y;
8468692172297647753b19567a180d52a6415193e3ddirk  destination->z = (a.z * b.z) + c.z;
8478692172297647753b19567a180d52a6415193e3ddirk  destination->w = (a.w * b.w) + c.w;
8488692172297647753b19567a180d52a6415193e3ddirk}
8498692172297647753b19567a180d52a6415193e3ddirk
8508692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorMultiplyAdd3(const DDSVector3 a, const DDSVector3 b,
8518692172297647753b19567a180d52a6415193e3ddirk  const DDSVector3 c, DDSVector3 *destination)
8528692172297647753b19567a180d52a6415193e3ddirk{
8538692172297647753b19567a180d52a6415193e3ddirk  destination->x = (a.x * b.x) + c.x;
8548692172297647753b19567a180d52a6415193e3ddirk  destination->y = (a.y * b.y) + c.y;
8558692172297647753b19567a180d52a6415193e3ddirk  destination->z = (a.z * b.z) + c.z;
8568692172297647753b19567a180d52a6415193e3ddirk}
8578692172297647753b19567a180d52a6415193e3ddirk
8588692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorReciprocal(const DDSVector4 value,
8598692172297647753b19567a180d52a6415193e3ddirk  DDSVector4 *destination)
8608692172297647753b19567a180d52a6415193e3ddirk{
8618692172297647753b19567a180d52a6415193e3ddirk  destination->x = 1.0f / value.x;
8628692172297647753b19567a180d52a6415193e3ddirk  destination->y = 1.0f / value.y;
8638692172297647753b19567a180d52a6415193e3ddirk  destination->z = 1.0f / value.z;
8648692172297647753b19567a180d52a6415193e3ddirk  destination->w = 1.0f / value.w;
8658692172297647753b19567a180d52a6415193e3ddirk}
8668692172297647753b19567a180d52a6415193e3ddirk
8678692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorSubtract(const DDSVector4 left,
8688692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 right, DDSVector4 *destination)
8698692172297647753b19567a180d52a6415193e3ddirk{
8708692172297647753b19567a180d52a6415193e3ddirk  destination->x = left.x - right.x;
8718692172297647753b19567a180d52a6415193e3ddirk  destination->y = left.y - right.y;
8728692172297647753b19567a180d52a6415193e3ddirk  destination->z = left.z - right.z;
8738692172297647753b19567a180d52a6415193e3ddirk  destination->w = left.w - right.w;
8748692172297647753b19567a180d52a6415193e3ddirk}
8758692172297647753b19567a180d52a6415193e3ddirk
8768692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorSubtract3(const DDSVector3 left,
8778692172297647753b19567a180d52a6415193e3ddirk  const DDSVector3 right, DDSVector3 *destination)
8788692172297647753b19567a180d52a6415193e3ddirk{
8798692172297647753b19567a180d52a6415193e3ddirk  destination->x = left.x - right.x;
8808692172297647753b19567a180d52a6415193e3ddirk  destination->y = left.y - right.y;
8818692172297647753b19567a180d52a6415193e3ddirk  destination->z = left.z - right.z;
8828692172297647753b19567a180d52a6415193e3ddirk}
8838692172297647753b19567a180d52a6415193e3ddirk
8848692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorTruncate(DDSVector4 *value)
8858692172297647753b19567a180d52a6415193e3ddirk{
8868692172297647753b19567a180d52a6415193e3ddirk  value->x = value->x > 0.0f ? floor(value->x) : ceil(value->x);
8878692172297647753b19567a180d52a6415193e3ddirk  value->y = value->y > 0.0f ? floor(value->y) : ceil(value->y);
8888692172297647753b19567a180d52a6415193e3ddirk  value->z = value->z > 0.0f ? floor(value->z) : ceil(value->z);
8898692172297647753b19567a180d52a6415193e3ddirk  value->w = value->w > 0.0f ? floor(value->w) : ceil(value->w);
8908692172297647753b19567a180d52a6415193e3ddirk}
8918692172297647753b19567a180d52a6415193e3ddirk
8928692172297647753b19567a180d52a6415193e3ddirkstatic inline void VectorTruncate3(DDSVector3 *value)
8938692172297647753b19567a180d52a6415193e3ddirk{
8948692172297647753b19567a180d52a6415193e3ddirk  value->x = value->x > 0.0f ? floor(value->x) : ceil(value->x);
8958692172297647753b19567a180d52a6415193e3ddirk  value->y = value->y > 0.0f ? floor(value->y) : ceil(value->y);
8968692172297647753b19567a180d52a6415193e3ddirk  value->z = value->z > 0.0f ? floor(value->z) : ceil(value->z);
8978692172297647753b19567a180d52a6415193e3ddirk}
8988692172297647753b19567a180d52a6415193e3ddirk
8998692172297647753b19567a180d52a6415193e3ddirkstatic void CalculateColors(unsigned short c0, unsigned short c1,
9008692172297647753b19567a180d52a6415193e3ddirk  DDSColors *c, MagickBooleanType ignoreAlpha)
9018692172297647753b19567a180d52a6415193e3ddirk{
9028692172297647753b19567a180d52a6415193e3ddirk  c->a[0] = c->a[1] = c->a[2] = c->a[3] = 0;
9038692172297647753b19567a180d52a6415193e3ddirk
9048692172297647753b19567a180d52a6415193e3ddirk  c->r[0] = (unsigned char) C565_red(c0);
9058692172297647753b19567a180d52a6415193e3ddirk  c->g[0] = (unsigned char) C565_green(c0);
9068692172297647753b19567a180d52a6415193e3ddirk  c->b[0] = (unsigned char) C565_blue(c0);
9078692172297647753b19567a180d52a6415193e3ddirk
9088692172297647753b19567a180d52a6415193e3ddirk  c->r[1] = (unsigned char) C565_red(c1);
9098692172297647753b19567a180d52a6415193e3ddirk  c->g[1] = (unsigned char) C565_green(c1);
9108692172297647753b19567a180d52a6415193e3ddirk  c->b[1] = (unsigned char) C565_blue(c1);
9118692172297647753b19567a180d52a6415193e3ddirk
9128692172297647753b19567a180d52a6415193e3ddirk  if (ignoreAlpha != MagickFalse || c0 > c1)
9138692172297647753b19567a180d52a6415193e3ddirk    {
9148692172297647753b19567a180d52a6415193e3ddirk      c->r[2] = (unsigned char) ((2 * c->r[0] + c->r[1]) / 3);
9158692172297647753b19567a180d52a6415193e3ddirk      c->g[2] = (unsigned char) ((2 * c->g[0] + c->g[1]) / 3);
9168692172297647753b19567a180d52a6415193e3ddirk      c->b[2] = (unsigned char) ((2 * c->b[0] + c->b[1]) / 3);
9178692172297647753b19567a180d52a6415193e3ddirk
9188692172297647753b19567a180d52a6415193e3ddirk      c->r[3] = (unsigned char) ((c->r[0] + 2 * c->r[1]) / 3);
9198692172297647753b19567a180d52a6415193e3ddirk      c->g[3] = (unsigned char) ((c->g[0] + 2 * c->g[1]) / 3);
9208692172297647753b19567a180d52a6415193e3ddirk      c->b[3] = (unsigned char) ((c->b[0] + 2 * c->b[1]) / 3);
9218692172297647753b19567a180d52a6415193e3ddirk    }
9228692172297647753b19567a180d52a6415193e3ddirk  else
9238692172297647753b19567a180d52a6415193e3ddirk    {
9248692172297647753b19567a180d52a6415193e3ddirk      c->r[2] = (unsigned char) ((c->r[0] + c->r[1]) / 2);
9258692172297647753b19567a180d52a6415193e3ddirk      c->g[2] = (unsigned char) ((c->g[0] + c->g[1]) / 2);
9268692172297647753b19567a180d52a6415193e3ddirk      c->b[2] = (unsigned char) ((c->b[0] + c->b[1]) / 2);
9278692172297647753b19567a180d52a6415193e3ddirk
9288692172297647753b19567a180d52a6415193e3ddirk      c->r[3] = c->g[3] = c->b[3] = 0;
9298692172297647753b19567a180d52a6415193e3ddirk      c->a[3] = 255;
9308692172297647753b19567a180d52a6415193e3ddirk    }
9318692172297647753b19567a180d52a6415193e3ddirk}
9328692172297647753b19567a180d52a6415193e3ddirk
9338692172297647753b19567a180d52a6415193e3ddirkstatic size_t CompressAlpha(const size_t min, const size_t max,
9348692172297647753b19567a180d52a6415193e3ddirk  const size_t steps, const ssize_t *alphas, unsigned char* indices)
9358692172297647753b19567a180d52a6415193e3ddirk{
9368692172297647753b19567a180d52a6415193e3ddirk  unsigned char
9378692172297647753b19567a180d52a6415193e3ddirk    codes[8];
9388692172297647753b19567a180d52a6415193e3ddirk
9398692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
9408692172297647753b19567a180d52a6415193e3ddirk    i;
9418692172297647753b19567a180d52a6415193e3ddirk
9428692172297647753b19567a180d52a6415193e3ddirk  size_t
9438692172297647753b19567a180d52a6415193e3ddirk    error,
9448692172297647753b19567a180d52a6415193e3ddirk    index,
9458692172297647753b19567a180d52a6415193e3ddirk    j,
9468692172297647753b19567a180d52a6415193e3ddirk    least,
9478692172297647753b19567a180d52a6415193e3ddirk    value;
9488692172297647753b19567a180d52a6415193e3ddirk
9498692172297647753b19567a180d52a6415193e3ddirk  codes[0] = (unsigned char) min;
9508692172297647753b19567a180d52a6415193e3ddirk  codes[1] = (unsigned char) max;
9518692172297647753b19567a180d52a6415193e3ddirk  codes[6] = 0;
9528692172297647753b19567a180d52a6415193e3ddirk  codes[7] = 255;
9538692172297647753b19567a180d52a6415193e3ddirk
9548692172297647753b19567a180d52a6415193e3ddirk  for (i=1; i <  (ssize_t) steps; i++)
9558692172297647753b19567a180d52a6415193e3ddirk    codes[i+1] = (unsigned char) (((steps-i)*min + i*max) / steps);
9568692172297647753b19567a180d52a6415193e3ddirk
9578692172297647753b19567a180d52a6415193e3ddirk  error = 0;
9588692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i<16; i++)
9598692172297647753b19567a180d52a6415193e3ddirk  {
9608692172297647753b19567a180d52a6415193e3ddirk    if (alphas[i] == -1)
9618692172297647753b19567a180d52a6415193e3ddirk      {
9628692172297647753b19567a180d52a6415193e3ddirk        indices[i] = 0;
9638692172297647753b19567a180d52a6415193e3ddirk        continue;
9648692172297647753b19567a180d52a6415193e3ddirk      }
9658692172297647753b19567a180d52a6415193e3ddirk
9668692172297647753b19567a180d52a6415193e3ddirk    value = alphas[i];
9678692172297647753b19567a180d52a6415193e3ddirk    least = SIZE_MAX;
9688692172297647753b19567a180d52a6415193e3ddirk    index = 0;
9698692172297647753b19567a180d52a6415193e3ddirk    for (j=0; j<8; j++)
9708692172297647753b19567a180d52a6415193e3ddirk    {
9718692172297647753b19567a180d52a6415193e3ddirk      size_t
9728692172297647753b19567a180d52a6415193e3ddirk        dist;
9738692172297647753b19567a180d52a6415193e3ddirk
9748692172297647753b19567a180d52a6415193e3ddirk      dist = value - (size_t)codes[j];
9758692172297647753b19567a180d52a6415193e3ddirk      dist *= dist;
9768692172297647753b19567a180d52a6415193e3ddirk
9778692172297647753b19567a180d52a6415193e3ddirk      if (dist < least)
9788692172297647753b19567a180d52a6415193e3ddirk        {
9798692172297647753b19567a180d52a6415193e3ddirk          least = dist;
9808692172297647753b19567a180d52a6415193e3ddirk          index = j;
9818692172297647753b19567a180d52a6415193e3ddirk        }
9828692172297647753b19567a180d52a6415193e3ddirk    }
9838692172297647753b19567a180d52a6415193e3ddirk
9848692172297647753b19567a180d52a6415193e3ddirk    indices[i] = (unsigned char)index;
9858692172297647753b19567a180d52a6415193e3ddirk    error += least;
9868692172297647753b19567a180d52a6415193e3ddirk  }
9878692172297647753b19567a180d52a6415193e3ddirk
9888692172297647753b19567a180d52a6415193e3ddirk  return error;
9898692172297647753b19567a180d52a6415193e3ddirk}
9908692172297647753b19567a180d52a6415193e3ddirk
9918692172297647753b19567a180d52a6415193e3ddirkstatic void CompressClusterFit(const size_t count,
9928692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 *points, const ssize_t *map, const DDSVector3 principle,
9938692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 metric, DDSVector3 *start, DDSVector3* end,
9948692172297647753b19567a180d52a6415193e3ddirk  unsigned char *indices)
9958692172297647753b19567a180d52a6415193e3ddirk{
9968692172297647753b19567a180d52a6415193e3ddirk  DDSVector3
9978692172297647753b19567a180d52a6415193e3ddirk    axis;
9988692172297647753b19567a180d52a6415193e3ddirk
9998692172297647753b19567a180d52a6415193e3ddirk  DDSVector4
10008692172297647753b19567a180d52a6415193e3ddirk    grid,
10018692172297647753b19567a180d52a6415193e3ddirk    gridrcp,
10028692172297647753b19567a180d52a6415193e3ddirk    half,
10038692172297647753b19567a180d52a6415193e3ddirk    onethird_onethird2,
10048692172297647753b19567a180d52a6415193e3ddirk    pointsWeights[16],
10058692172297647753b19567a180d52a6415193e3ddirk    two,
10068692172297647753b19567a180d52a6415193e3ddirk    twonineths,
10078692172297647753b19567a180d52a6415193e3ddirk    twothirds_twothirds2,
10088692172297647753b19567a180d52a6415193e3ddirk    xSumwSum;
10098692172297647753b19567a180d52a6415193e3ddirk
10108692172297647753b19567a180d52a6415193e3ddirk  float
10118692172297647753b19567a180d52a6415193e3ddirk    bestError = 1e+37f;
10128692172297647753b19567a180d52a6415193e3ddirk
10138692172297647753b19567a180d52a6415193e3ddirk  size_t
10148692172297647753b19567a180d52a6415193e3ddirk    bestIteration = 0,
10158692172297647753b19567a180d52a6415193e3ddirk    besti = 0,
10168692172297647753b19567a180d52a6415193e3ddirk    bestj = 0,
10178692172297647753b19567a180d52a6415193e3ddirk    bestk = 0,
1018560a910a25df2b4ca46af343321575ca6fb2c3bfdirk    iterationIndex;
1019560a910a25df2b4ca46af343321575ca6fb2c3bfdirk
1020560a910a25df2b4ca46af343321575ca6fb2c3bfdirk  ssize_t
1021560a910a25df2b4ca46af343321575ca6fb2c3bfdirk    i;
10228692172297647753b19567a180d52a6415193e3ddirk
10238692172297647753b19567a180d52a6415193e3ddirk  unsigned char
10248692172297647753b19567a180d52a6415193e3ddirk    *o,
10258692172297647753b19567a180d52a6415193e3ddirk    order[128],
10268692172297647753b19567a180d52a6415193e3ddirk    unordered[16];
10278692172297647753b19567a180d52a6415193e3ddirk
10288692172297647753b19567a180d52a6415193e3ddirk  VectorInit(half,0.5f);
10298692172297647753b19567a180d52a6415193e3ddirk  VectorInit(two,2.0f);
10308692172297647753b19567a180d52a6415193e3ddirk
10318692172297647753b19567a180d52a6415193e3ddirk  VectorInit(onethird_onethird2,1.0f/3.0f);
10328692172297647753b19567a180d52a6415193e3ddirk  onethird_onethird2.w = 1.0f/9.0f;
10338692172297647753b19567a180d52a6415193e3ddirk  VectorInit(twothirds_twothirds2,2.0f/3.0f);
10348692172297647753b19567a180d52a6415193e3ddirk  twothirds_twothirds2.w = 4.0f/9.0f;
10358692172297647753b19567a180d52a6415193e3ddirk  VectorInit(twonineths,2.0f/9.0f);
10368692172297647753b19567a180d52a6415193e3ddirk
10378692172297647753b19567a180d52a6415193e3ddirk  grid.x = 31.0f;
10388692172297647753b19567a180d52a6415193e3ddirk  grid.y = 63.0f;
10398692172297647753b19567a180d52a6415193e3ddirk  grid.z = 31.0f;
10408692172297647753b19567a180d52a6415193e3ddirk  grid.w = 0.0f;
10418692172297647753b19567a180d52a6415193e3ddirk
10428692172297647753b19567a180d52a6415193e3ddirk  gridrcp.x = 1.0f/31.0f;
10438692172297647753b19567a180d52a6415193e3ddirk  gridrcp.y = 1.0f/63.0f;
10448692172297647753b19567a180d52a6415193e3ddirk  gridrcp.z = 1.0f/31.0f;
10458692172297647753b19567a180d52a6415193e3ddirk  gridrcp.w = 0.0f;
10468692172297647753b19567a180d52a6415193e3ddirk
10478692172297647753b19567a180d52a6415193e3ddirk  xSumwSum.x = 0.0f;
10488692172297647753b19567a180d52a6415193e3ddirk  xSumwSum.y = 0.0f;
10498692172297647753b19567a180d52a6415193e3ddirk  xSumwSum.z = 0.0f;
10508692172297647753b19567a180d52a6415193e3ddirk  xSumwSum.w = 0.0f;
10518692172297647753b19567a180d52a6415193e3ddirk
10528692172297647753b19567a180d52a6415193e3ddirk  ConstructOrdering(count,points,principle,pointsWeights,&xSumwSum,order,0);
10538692172297647753b19567a180d52a6415193e3ddirk
10548692172297647753b19567a180d52a6415193e3ddirk  for (iterationIndex = 0;;)
10558692172297647753b19567a180d52a6415193e3ddirk  {
1056560a910a25df2b4ca46af343321575ca6fb2c3bfdirk#if defined(MAGICKCORE_OPENMP_SUPPORT)
1057560a910a25df2b4ca46af343321575ca6fb2c3bfdirk  #pragma omp parallel for schedule(dynamic,1) \
1058560a910a25df2b4ca46af343321575ca6fb2c3bfdirk    num_threads(GetMagickResourceLimit(ThreadResource))
1059560a910a25df2b4ca46af343321575ca6fb2c3bfdirk#endif
1060560a910a25df2b4ca46af343321575ca6fb2c3bfdirk    for (i=0; i < (ssize_t) count; i++)
10618692172297647753b19567a180d52a6415193e3ddirk    {
1062560a910a25df2b4ca46af343321575ca6fb2c3bfdirk      DDSVector4
1063560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        part0,
1064560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        part1,
1065560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        part2;
1066560a910a25df2b4ca46af343321575ca6fb2c3bfdirk
1067560a910a25df2b4ca46af343321575ca6fb2c3bfdirk      size_t
1068560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        ii,
1069560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        j,
1070560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        k,
1071560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        kmin;
1072560a910a25df2b4ca46af343321575ca6fb2c3bfdirk
1073560a910a25df2b4ca46af343321575ca6fb2c3bfdirk      VectorInit(part0,0.0f);
1074560a910a25df2b4ca46af343321575ca6fb2c3bfdirk      for(ii=0; ii < (size_t) i; ii++)
1075560a910a25df2b4ca46af343321575ca6fb2c3bfdirk        VectorAdd(pointsWeights[ii],part0,&part0);
1076560a910a25df2b4ca46af343321575ca6fb2c3bfdirk
10778692172297647753b19567a180d52a6415193e3ddirk      VectorInit(part1,0.0f);
1078560a910a25df2b4ca46af343321575ca6fb2c3bfdirk      for (j=(size_t) i;;)
10798692172297647753b19567a180d52a6415193e3ddirk      {
10808692172297647753b19567a180d52a6415193e3ddirk        if (j == 0)
10818692172297647753b19567a180d52a6415193e3ddirk          {
10828692172297647753b19567a180d52a6415193e3ddirk            VectorCopy44(pointsWeights[0],&part2);
10838692172297647753b19567a180d52a6415193e3ddirk            kmin = 1;
10848692172297647753b19567a180d52a6415193e3ddirk          }
10858692172297647753b19567a180d52a6415193e3ddirk          else
10868692172297647753b19567a180d52a6415193e3ddirk          {
10878692172297647753b19567a180d52a6415193e3ddirk            VectorInit(part2,0.0f);
10888692172297647753b19567a180d52a6415193e3ddirk            kmin = j;
10898692172297647753b19567a180d52a6415193e3ddirk          }
10908692172297647753b19567a180d52a6415193e3ddirk
10918692172297647753b19567a180d52a6415193e3ddirk        for (k=kmin;;)
10928692172297647753b19567a180d52a6415193e3ddirk        {
10938692172297647753b19567a180d52a6415193e3ddirk          DDSVector4
10948692172297647753b19567a180d52a6415193e3ddirk            a,
10958692172297647753b19567a180d52a6415193e3ddirk            alpha2_sum,
10968692172297647753b19567a180d52a6415193e3ddirk            alphax_sum,
10978692172297647753b19567a180d52a6415193e3ddirk            alphabeta_sum,
10988692172297647753b19567a180d52a6415193e3ddirk            b,
10998692172297647753b19567a180d52a6415193e3ddirk            beta2_sum,
11008692172297647753b19567a180d52a6415193e3ddirk            betax_sum,
11018692172297647753b19567a180d52a6415193e3ddirk            e1,
11028692172297647753b19567a180d52a6415193e3ddirk            e2,
1103560a910a25df2b4ca46af343321575ca6fb2c3bfdirk            factor,
1104560a910a25df2b4ca46af343321575ca6fb2c3bfdirk            part3;
11058692172297647753b19567a180d52a6415193e3ddirk
11068692172297647753b19567a180d52a6415193e3ddirk          float
11078692172297647753b19567a180d52a6415193e3ddirk            error;
11088692172297647753b19567a180d52a6415193e3ddirk
11098692172297647753b19567a180d52a6415193e3ddirk          VectorSubtract(xSumwSum,part2,&part3);
11108692172297647753b19567a180d52a6415193e3ddirk          VectorSubtract(part3,part1,&part3);
11118692172297647753b19567a180d52a6415193e3ddirk          VectorSubtract(part3,part0,&part3);
11128692172297647753b19567a180d52a6415193e3ddirk
11138692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(part1,twothirds_twothirds2,part0,&alphax_sum);
11148692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(part2,onethird_onethird2,alphax_sum,&alphax_sum);
11158692172297647753b19567a180d52a6415193e3ddirk          VectorInit(alpha2_sum,alphax_sum.w);
11168692172297647753b19567a180d52a6415193e3ddirk
11178692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(part2,twothirds_twothirds2,part3,&betax_sum);
11188692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(part1,onethird_onethird2,betax_sum,&betax_sum);
11198692172297647753b19567a180d52a6415193e3ddirk          VectorInit(beta2_sum,betax_sum.w);
11208692172297647753b19567a180d52a6415193e3ddirk
11218692172297647753b19567a180d52a6415193e3ddirk          VectorAdd(part1,part2,&alphabeta_sum);
11228692172297647753b19567a180d52a6415193e3ddirk          VectorInit(alphabeta_sum,alphabeta_sum.w);
11238692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(twonineths,alphabeta_sum,&alphabeta_sum);
11248692172297647753b19567a180d52a6415193e3ddirk
11258692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(alpha2_sum,beta2_sum,&factor);
11268692172297647753b19567a180d52a6415193e3ddirk          VectorNegativeMultiplySubtract(alphabeta_sum,alphabeta_sum,factor,
11278692172297647753b19567a180d52a6415193e3ddirk            &factor);
11288692172297647753b19567a180d52a6415193e3ddirk          VectorReciprocal(factor,&factor);
11298692172297647753b19567a180d52a6415193e3ddirk
11308692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(alphax_sum,beta2_sum,&a);
11318692172297647753b19567a180d52a6415193e3ddirk          VectorNegativeMultiplySubtract(betax_sum,alphabeta_sum,a,&a);
11328692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(a,factor,&a);
11338692172297647753b19567a180d52a6415193e3ddirk
11348692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(betax_sum,alpha2_sum,&b);
11358692172297647753b19567a180d52a6415193e3ddirk          VectorNegativeMultiplySubtract(alphax_sum,alphabeta_sum,b,&b);
11368692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(b,factor,&b);
11378692172297647753b19567a180d52a6415193e3ddirk
11388692172297647753b19567a180d52a6415193e3ddirk          VectorClamp(&a);
11398692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(grid,a,half,&a);
11408692172297647753b19567a180d52a6415193e3ddirk          VectorTruncate(&a);
11418692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(a,gridrcp,&a);
11428692172297647753b19567a180d52a6415193e3ddirk
11438692172297647753b19567a180d52a6415193e3ddirk          VectorClamp(&b);
11448692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(grid,b,half,&b);
11458692172297647753b19567a180d52a6415193e3ddirk          VectorTruncate(&b);
11468692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(b,gridrcp,&b);
11478692172297647753b19567a180d52a6415193e3ddirk
11488692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(b,b,&e1);
11498692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(e1,beta2_sum,&e1);
11508692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(a,a,&e2);
11518692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(e2,alpha2_sum,e1,&e1);
11528692172297647753b19567a180d52a6415193e3ddirk
11538692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(a,b,&e2);
11548692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(e2,alphabeta_sum,&e2);
11558692172297647753b19567a180d52a6415193e3ddirk          VectorNegativeMultiplySubtract(a,alphax_sum,e2,&e2);
11568692172297647753b19567a180d52a6415193e3ddirk          VectorNegativeMultiplySubtract(b,betax_sum,e2,&e2);
11578692172297647753b19567a180d52a6415193e3ddirk          VectorMultiplyAdd(two,e2,e1,&e2);
11588692172297647753b19567a180d52a6415193e3ddirk          VectorMultiply(e2,metric,&e2);
11598692172297647753b19567a180d52a6415193e3ddirk
11608692172297647753b19567a180d52a6415193e3ddirk          error = e2.x + e2.y + e2.z;
11618692172297647753b19567a180d52a6415193e3ddirk
11628692172297647753b19567a180d52a6415193e3ddirk          if (error < bestError)
1163560a910a25df2b4ca46af343321575ca6fb2c3bfdirk            {
1164560a910a25df2b4ca46af343321575ca6fb2c3bfdirk#if defined(MAGICKCORE_OPENMP_SUPPORT)
1165560a910a25df2b4ca46af343321575ca6fb2c3bfdirk              #pragma omp critical (DDS_CompressClusterFit)
1166560a910a25df2b4ca46af343321575ca6fb2c3bfdirk#endif
1167560a910a25df2b4ca46af343321575ca6fb2c3bfdirk              {
1168560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                if (error < bestError)
1169560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                  {
1170560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    VectorCopy43(a,start);
1171560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    VectorCopy43(b,end);
1172560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    bestError = error;
1173560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    besti = i;
1174560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    bestj = j;
1175560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    bestk = k;
1176560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                    bestIteration = iterationIndex;
1177560a910a25df2b4ca46af343321575ca6fb2c3bfdirk                  }
1178560a910a25df2b4ca46af343321575ca6fb2c3bfdirk              }
1179560a910a25df2b4ca46af343321575ca6fb2c3bfdirk            }
11808692172297647753b19567a180d52a6415193e3ddirk
11818692172297647753b19567a180d52a6415193e3ddirk          if (k == count)
11828692172297647753b19567a180d52a6415193e3ddirk            break;
11838692172297647753b19567a180d52a6415193e3ddirk
11848692172297647753b19567a180d52a6415193e3ddirk          VectorAdd(pointsWeights[k],part2,&part2);
11858692172297647753b19567a180d52a6415193e3ddirk          k++;
11868692172297647753b19567a180d52a6415193e3ddirk        }
11878692172297647753b19567a180d52a6415193e3ddirk
11888692172297647753b19567a180d52a6415193e3ddirk        if (j == count)
11898692172297647753b19567a180d52a6415193e3ddirk          break;
11908692172297647753b19567a180d52a6415193e3ddirk
11918692172297647753b19567a180d52a6415193e3ddirk        VectorAdd(pointsWeights[j],part1,&part1);
11928692172297647753b19567a180d52a6415193e3ddirk        j++;
11938692172297647753b19567a180d52a6415193e3ddirk      }
11948692172297647753b19567a180d52a6415193e3ddirk    }
11958692172297647753b19567a180d52a6415193e3ddirk
11968692172297647753b19567a180d52a6415193e3ddirk    if (bestIteration != iterationIndex)
11978692172297647753b19567a180d52a6415193e3ddirk      break;
11988692172297647753b19567a180d52a6415193e3ddirk
11998692172297647753b19567a180d52a6415193e3ddirk    iterationIndex++;
12008692172297647753b19567a180d52a6415193e3ddirk    if (iterationIndex == 8)
12018692172297647753b19567a180d52a6415193e3ddirk      break;
12028692172297647753b19567a180d52a6415193e3ddirk
12038692172297647753b19567a180d52a6415193e3ddirk    VectorSubtract3(*end,*start,&axis);
12048692172297647753b19567a180d52a6415193e3ddirk    if (ConstructOrdering(count,points,axis,pointsWeights,&xSumwSum,order,
12058692172297647753b19567a180d52a6415193e3ddirk      iterationIndex) == MagickFalse)
12068692172297647753b19567a180d52a6415193e3ddirk      break;
12078692172297647753b19567a180d52a6415193e3ddirk  }
12088692172297647753b19567a180d52a6415193e3ddirk
12098692172297647753b19567a180d52a6415193e3ddirk  o = order + (16*bestIteration);
12108692172297647753b19567a180d52a6415193e3ddirk
1211385d8662774e84cbcd0957322e81990cddffa4fecristy  for (i=0; i < (ssize_t) besti; i++)
12128692172297647753b19567a180d52a6415193e3ddirk    unordered[o[i]] = 0;
1213385d8662774e84cbcd0957322e81990cddffa4fecristy  for (i=besti; i < (ssize_t) bestj; i++)
12148692172297647753b19567a180d52a6415193e3ddirk    unordered[o[i]] = 2;
1215385d8662774e84cbcd0957322e81990cddffa4fecristy  for (i=bestj; i < (ssize_t) bestk; i++)
12168692172297647753b19567a180d52a6415193e3ddirk    unordered[o[i]] = 3;
1217385d8662774e84cbcd0957322e81990cddffa4fecristy  for (i=bestk; i < (ssize_t) count; i++)
12188692172297647753b19567a180d52a6415193e3ddirk    unordered[o[i]] = 1;
12198692172297647753b19567a180d52a6415193e3ddirk
12208692172297647753b19567a180d52a6415193e3ddirk  RemapIndices(map,unordered,indices);
12218692172297647753b19567a180d52a6415193e3ddirk}
12228692172297647753b19567a180d52a6415193e3ddirk
12238692172297647753b19567a180d52a6415193e3ddirkstatic void CompressRangeFit(const size_t count,
12248692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4* points, const ssize_t *map, const DDSVector3 principle,
12258692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 metric, DDSVector3 *start, DDSVector3 *end,
12268692172297647753b19567a180d52a6415193e3ddirk  unsigned char *indices)
12278692172297647753b19567a180d52a6415193e3ddirk{
12288692172297647753b19567a180d52a6415193e3ddirk  float
12298692172297647753b19567a180d52a6415193e3ddirk    d,
12308692172297647753b19567a180d52a6415193e3ddirk    bestDist,
12318692172297647753b19567a180d52a6415193e3ddirk    max,
12328692172297647753b19567a180d52a6415193e3ddirk    min,
12338692172297647753b19567a180d52a6415193e3ddirk    val;
12348692172297647753b19567a180d52a6415193e3ddirk
12358692172297647753b19567a180d52a6415193e3ddirk  DDSVector3
12368692172297647753b19567a180d52a6415193e3ddirk    codes[4],
12378692172297647753b19567a180d52a6415193e3ddirk    grid,
12388692172297647753b19567a180d52a6415193e3ddirk    gridrcp,
12398692172297647753b19567a180d52a6415193e3ddirk    half,
12408692172297647753b19567a180d52a6415193e3ddirk    dist;
12418692172297647753b19567a180d52a6415193e3ddirk
12428692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
12438692172297647753b19567a180d52a6415193e3ddirk    i;
12448692172297647753b19567a180d52a6415193e3ddirk
12458692172297647753b19567a180d52a6415193e3ddirk  size_t
12468692172297647753b19567a180d52a6415193e3ddirk    bestj,
12478692172297647753b19567a180d52a6415193e3ddirk    j;
12488692172297647753b19567a180d52a6415193e3ddirk
12498692172297647753b19567a180d52a6415193e3ddirk  unsigned char
12508692172297647753b19567a180d52a6415193e3ddirk    closest[16];
12518692172297647753b19567a180d52a6415193e3ddirk
12528692172297647753b19567a180d52a6415193e3ddirk  VectorInit3(half,0.5f);
12538692172297647753b19567a180d52a6415193e3ddirk
12548692172297647753b19567a180d52a6415193e3ddirk  grid.x = 31.0f;
12558692172297647753b19567a180d52a6415193e3ddirk  grid.y = 63.0f;
12568692172297647753b19567a180d52a6415193e3ddirk  grid.z = 31.0f;
12578692172297647753b19567a180d52a6415193e3ddirk
12588692172297647753b19567a180d52a6415193e3ddirk  gridrcp.x = 1.0f/31.0f;
12598692172297647753b19567a180d52a6415193e3ddirk  gridrcp.y = 1.0f/63.0f;
12608692172297647753b19567a180d52a6415193e3ddirk  gridrcp.z = 1.0f/31.0f;
12618692172297647753b19567a180d52a6415193e3ddirk
12628692172297647753b19567a180d52a6415193e3ddirk  if (count > 0)
12638692172297647753b19567a180d52a6415193e3ddirk    {
12648692172297647753b19567a180d52a6415193e3ddirk      VectorCopy43(points[0],start);
12658692172297647753b19567a180d52a6415193e3ddirk      VectorCopy43(points[0],end);
12668692172297647753b19567a180d52a6415193e3ddirk
12678692172297647753b19567a180d52a6415193e3ddirk      min = max = Dot(points[0],principle);
12688692172297647753b19567a180d52a6415193e3ddirk      for (i=1; i < (ssize_t) count; i++)
12698692172297647753b19567a180d52a6415193e3ddirk      {
12708692172297647753b19567a180d52a6415193e3ddirk        val = Dot(points[i],principle);
12718692172297647753b19567a180d52a6415193e3ddirk        if (val < min)
12728692172297647753b19567a180d52a6415193e3ddirk        {
12738692172297647753b19567a180d52a6415193e3ddirk          VectorCopy43(points[i],start);
12748692172297647753b19567a180d52a6415193e3ddirk          min = val;
12758692172297647753b19567a180d52a6415193e3ddirk        }
12768692172297647753b19567a180d52a6415193e3ddirk        else if (val > max)
12778692172297647753b19567a180d52a6415193e3ddirk        {
12788692172297647753b19567a180d52a6415193e3ddirk          VectorCopy43(points[i],end);
12798692172297647753b19567a180d52a6415193e3ddirk          max = val;
12808692172297647753b19567a180d52a6415193e3ddirk        }
12818692172297647753b19567a180d52a6415193e3ddirk      }
12828692172297647753b19567a180d52a6415193e3ddirk    }
12838692172297647753b19567a180d52a6415193e3ddirk
12848692172297647753b19567a180d52a6415193e3ddirk  VectorClamp3(start);
12858692172297647753b19567a180d52a6415193e3ddirk  VectorMultiplyAdd3(grid,*start,half,start);
12868692172297647753b19567a180d52a6415193e3ddirk  VectorTruncate3(start);
12878692172297647753b19567a180d52a6415193e3ddirk  VectorMultiply3(*start,gridrcp,start);
12888692172297647753b19567a180d52a6415193e3ddirk
12898692172297647753b19567a180d52a6415193e3ddirk  VectorClamp3(end);
12908692172297647753b19567a180d52a6415193e3ddirk  VectorMultiplyAdd3(grid,*end,half,end);
12918692172297647753b19567a180d52a6415193e3ddirk  VectorTruncate3(end);
12928692172297647753b19567a180d52a6415193e3ddirk  VectorMultiply3(*end,gridrcp,end);
12938692172297647753b19567a180d52a6415193e3ddirk
12948692172297647753b19567a180d52a6415193e3ddirk  codes[0] = *start;
12958692172297647753b19567a180d52a6415193e3ddirk  codes[1] = *end;
12968692172297647753b19567a180d52a6415193e3ddirk  codes[2].x = (start->x * (2.0f/3.0f)) + (end->x * (1.0f/3.0f));
12978692172297647753b19567a180d52a6415193e3ddirk  codes[2].y = (start->y * (2.0f/3.0f)) + (end->y * (1.0f/3.0f));
12988692172297647753b19567a180d52a6415193e3ddirk  codes[2].z = (start->z * (2.0f/3.0f)) + (end->z * (1.0f/3.0f));
12998692172297647753b19567a180d52a6415193e3ddirk  codes[3].x = (start->x * (1.0f/3.0f)) + (end->x * (2.0f/3.0f));
13008692172297647753b19567a180d52a6415193e3ddirk  codes[3].y = (start->y * (1.0f/3.0f)) + (end->y * (2.0f/3.0f));
13018692172297647753b19567a180d52a6415193e3ddirk  codes[3].z = (start->z * (1.0f/3.0f)) + (end->z * (2.0f/3.0f));
13028692172297647753b19567a180d52a6415193e3ddirk
13038692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < (ssize_t) count; i++)
13048692172297647753b19567a180d52a6415193e3ddirk  {
13058692172297647753b19567a180d52a6415193e3ddirk    bestDist = 1e+37f;
13068692172297647753b19567a180d52a6415193e3ddirk    bestj = 0;
13078692172297647753b19567a180d52a6415193e3ddirk    for (j=0; j < 4; j++)
13088692172297647753b19567a180d52a6415193e3ddirk    {
13098692172297647753b19567a180d52a6415193e3ddirk      dist.x = (points[i].x - codes[j].x) * metric.x;
13108692172297647753b19567a180d52a6415193e3ddirk      dist.y = (points[i].y - codes[j].y) * metric.y;
13118692172297647753b19567a180d52a6415193e3ddirk      dist.z = (points[i].z - codes[j].z) * metric.z;
13128692172297647753b19567a180d52a6415193e3ddirk
13138692172297647753b19567a180d52a6415193e3ddirk      d = Dot(dist,dist);
13148692172297647753b19567a180d52a6415193e3ddirk      if (d < bestDist)
13158692172297647753b19567a180d52a6415193e3ddirk        {
13168692172297647753b19567a180d52a6415193e3ddirk          bestDist = d;
13178692172297647753b19567a180d52a6415193e3ddirk          bestj = j;
13188692172297647753b19567a180d52a6415193e3ddirk        }
13198692172297647753b19567a180d52a6415193e3ddirk    }
13208692172297647753b19567a180d52a6415193e3ddirk
13218692172297647753b19567a180d52a6415193e3ddirk    closest[i] = (unsigned char) bestj;
13228692172297647753b19567a180d52a6415193e3ddirk  }
13238692172297647753b19567a180d52a6415193e3ddirk
13248692172297647753b19567a180d52a6415193e3ddirk  RemapIndices(map, closest, indices);
13258692172297647753b19567a180d52a6415193e3ddirk}
13268692172297647753b19567a180d52a6415193e3ddirk
13278692172297647753b19567a180d52a6415193e3ddirkstatic void ComputeEndPoints(const DDSSingleColourLookup *lookup[],
13288692172297647753b19567a180d52a6415193e3ddirk  const unsigned char *color, DDSVector3 *start, DDSVector3 *end,
13298692172297647753b19567a180d52a6415193e3ddirk  unsigned char *index)
13308692172297647753b19567a180d52a6415193e3ddirk{
13318692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
13328692172297647753b19567a180d52a6415193e3ddirk    i;
13338692172297647753b19567a180d52a6415193e3ddirk
13348692172297647753b19567a180d52a6415193e3ddirk  size_t
13358692172297647753b19567a180d52a6415193e3ddirk    c,
13368692172297647753b19567a180d52a6415193e3ddirk    maxError = SIZE_MAX;
13378692172297647753b19567a180d52a6415193e3ddirk
13388692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < 2; i++)
13398692172297647753b19567a180d52a6415193e3ddirk  {
13408692172297647753b19567a180d52a6415193e3ddirk    const DDSSourceBlock*
13418692172297647753b19567a180d52a6415193e3ddirk      sources[3];
13428692172297647753b19567a180d52a6415193e3ddirk
13438692172297647753b19567a180d52a6415193e3ddirk      size_t
13448692172297647753b19567a180d52a6415193e3ddirk        error = 0;
13458692172297647753b19567a180d52a6415193e3ddirk
13468692172297647753b19567a180d52a6415193e3ddirk    for (c=0; c < 3; c++)
13478692172297647753b19567a180d52a6415193e3ddirk    {
13488692172297647753b19567a180d52a6415193e3ddirk      sources[c] = &lookup[c][color[c]].sources[i];
13498692172297647753b19567a180d52a6415193e3ddirk      error += ((size_t) sources[c]->error) * ((size_t) sources[c]->error);
13508692172297647753b19567a180d52a6415193e3ddirk    }
13518692172297647753b19567a180d52a6415193e3ddirk
13528692172297647753b19567a180d52a6415193e3ddirk    if (error > maxError)
13538692172297647753b19567a180d52a6415193e3ddirk      continue;
13548692172297647753b19567a180d52a6415193e3ddirk
13558692172297647753b19567a180d52a6415193e3ddirk    start->x = (float) sources[0]->start / 31.0f;
13568692172297647753b19567a180d52a6415193e3ddirk    start->y = (float) sources[1]->start / 63.0f;
13578692172297647753b19567a180d52a6415193e3ddirk    start->z = (float) sources[2]->start / 31.0f;
13588692172297647753b19567a180d52a6415193e3ddirk
13598692172297647753b19567a180d52a6415193e3ddirk    end->x = (float) sources[0]->end / 31.0f;
13608692172297647753b19567a180d52a6415193e3ddirk    end->y = (float) sources[1]->end / 63.0f;
13618692172297647753b19567a180d52a6415193e3ddirk    end->z = (float) sources[2]->end / 31.0f;
13628692172297647753b19567a180d52a6415193e3ddirk
13638692172297647753b19567a180d52a6415193e3ddirk    *index = (unsigned char) (2*i);
13648692172297647753b19567a180d52a6415193e3ddirk    maxError = error;
13658692172297647753b19567a180d52a6415193e3ddirk  }
13668692172297647753b19567a180d52a6415193e3ddirk}
13678692172297647753b19567a180d52a6415193e3ddirk
13688692172297647753b19567a180d52a6415193e3ddirkstatic void ComputePrincipleComponent(const float *covariance,
13698692172297647753b19567a180d52a6415193e3ddirk  DDSVector3 *principle)
13708692172297647753b19567a180d52a6415193e3ddirk{
13718692172297647753b19567a180d52a6415193e3ddirk  DDSVector4
13728692172297647753b19567a180d52a6415193e3ddirk    row0,
13738692172297647753b19567a180d52a6415193e3ddirk    row1,
13748692172297647753b19567a180d52a6415193e3ddirk    row2,
13758692172297647753b19567a180d52a6415193e3ddirk    v;
13768692172297647753b19567a180d52a6415193e3ddirk
13778692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
13788692172297647753b19567a180d52a6415193e3ddirk    i;
13798692172297647753b19567a180d52a6415193e3ddirk
13808692172297647753b19567a180d52a6415193e3ddirk  row0.x = covariance[0];
13818692172297647753b19567a180d52a6415193e3ddirk  row0.y = covariance[1];
13828692172297647753b19567a180d52a6415193e3ddirk  row0.z = covariance[2];
13838692172297647753b19567a180d52a6415193e3ddirk  row0.w = 0.0f;
13848692172297647753b19567a180d52a6415193e3ddirk
13858692172297647753b19567a180d52a6415193e3ddirk  row1.x = covariance[1];
13868692172297647753b19567a180d52a6415193e3ddirk  row1.y = covariance[3];
13878692172297647753b19567a180d52a6415193e3ddirk  row1.z = covariance[4];
13888692172297647753b19567a180d52a6415193e3ddirk  row1.w = 0.0f;
13898692172297647753b19567a180d52a6415193e3ddirk
13908692172297647753b19567a180d52a6415193e3ddirk  row2.x = covariance[2];
13918692172297647753b19567a180d52a6415193e3ddirk  row2.y = covariance[4];
13928692172297647753b19567a180d52a6415193e3ddirk  row2.z = covariance[5];
13938692172297647753b19567a180d52a6415193e3ddirk  row2.w = 0.0f;
13948692172297647753b19567a180d52a6415193e3ddirk
13958692172297647753b19567a180d52a6415193e3ddirk  VectorInit(v,1.0f);
13968692172297647753b19567a180d52a6415193e3ddirk
13978692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < 8; i++)
13988692172297647753b19567a180d52a6415193e3ddirk  {
13998692172297647753b19567a180d52a6415193e3ddirk    DDSVector4
14008692172297647753b19567a180d52a6415193e3ddirk      w;
14018692172297647753b19567a180d52a6415193e3ddirk
14028692172297647753b19567a180d52a6415193e3ddirk    float
14038692172297647753b19567a180d52a6415193e3ddirk      a;
14048692172297647753b19567a180d52a6415193e3ddirk
14058692172297647753b19567a180d52a6415193e3ddirk    w.x = row0.x * v.x;
14068692172297647753b19567a180d52a6415193e3ddirk    w.y = row0.y * v.x;
14078692172297647753b19567a180d52a6415193e3ddirk    w.z = row0.z * v.x;
14088692172297647753b19567a180d52a6415193e3ddirk    w.w = row0.w * v.x;
14098692172297647753b19567a180d52a6415193e3ddirk
14108692172297647753b19567a180d52a6415193e3ddirk    w.x = (row1.x * v.y) + w.x;
14118692172297647753b19567a180d52a6415193e3ddirk    w.y = (row1.y * v.y) + w.y;
14128692172297647753b19567a180d52a6415193e3ddirk    w.z = (row1.z * v.y) + w.z;
14138692172297647753b19567a180d52a6415193e3ddirk    w.w = (row1.w * v.y) + w.w;
14148692172297647753b19567a180d52a6415193e3ddirk
14158692172297647753b19567a180d52a6415193e3ddirk    w.x = (row2.x * v.z) + w.x;
14168692172297647753b19567a180d52a6415193e3ddirk    w.y = (row2.y * v.z) + w.y;
14178692172297647753b19567a180d52a6415193e3ddirk    w.z = (row2.z * v.z) + w.z;
14188692172297647753b19567a180d52a6415193e3ddirk    w.w = (row2.w * v.z) + w.w;
14198692172297647753b19567a180d52a6415193e3ddirk
1420ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk    a = 1.0f / MagickMax(w.x,MagickMax(w.y,w.z));
14218692172297647753b19567a180d52a6415193e3ddirk
14228692172297647753b19567a180d52a6415193e3ddirk    v.x = w.x * a;
14238692172297647753b19567a180d52a6415193e3ddirk    v.y = w.y * a;
14248692172297647753b19567a180d52a6415193e3ddirk    v.z = w.z * a;
14258692172297647753b19567a180d52a6415193e3ddirk    v.w = w.w * a;
14268692172297647753b19567a180d52a6415193e3ddirk  }
14278692172297647753b19567a180d52a6415193e3ddirk
14288692172297647753b19567a180d52a6415193e3ddirk  VectorCopy43(v,principle);
14298692172297647753b19567a180d52a6415193e3ddirk}
14308692172297647753b19567a180d52a6415193e3ddirk
14318692172297647753b19567a180d52a6415193e3ddirkstatic void ComputeWeightedCovariance(const size_t count,
14328692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 *points, float *covariance)
14338692172297647753b19567a180d52a6415193e3ddirk{
14348692172297647753b19567a180d52a6415193e3ddirk  DDSVector3
14358692172297647753b19567a180d52a6415193e3ddirk    centroid;
14368692172297647753b19567a180d52a6415193e3ddirk
14378692172297647753b19567a180d52a6415193e3ddirk  float
14388692172297647753b19567a180d52a6415193e3ddirk    total;
14398692172297647753b19567a180d52a6415193e3ddirk
14408692172297647753b19567a180d52a6415193e3ddirk  size_t
14418692172297647753b19567a180d52a6415193e3ddirk    i;
14428692172297647753b19567a180d52a6415193e3ddirk
14438692172297647753b19567a180d52a6415193e3ddirk  total = 0.0f;
14448692172297647753b19567a180d52a6415193e3ddirk  VectorInit3(centroid,0.0f);
14458692172297647753b19567a180d52a6415193e3ddirk
14468692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < count; i++)
14478692172297647753b19567a180d52a6415193e3ddirk  {
14488692172297647753b19567a180d52a6415193e3ddirk    total += points[i].w;
14498692172297647753b19567a180d52a6415193e3ddirk    centroid.x += (points[i].x * points[i].w);
14508692172297647753b19567a180d52a6415193e3ddirk    centroid.y += (points[i].y * points[i].w);
14518692172297647753b19567a180d52a6415193e3ddirk    centroid.z += (points[i].z * points[i].w);
14528692172297647753b19567a180d52a6415193e3ddirk  }
14538692172297647753b19567a180d52a6415193e3ddirk
14548692172297647753b19567a180d52a6415193e3ddirk  if( total > 1.192092896e-07F)
14558692172297647753b19567a180d52a6415193e3ddirk    {
14568692172297647753b19567a180d52a6415193e3ddirk      centroid.x /= total;
14578692172297647753b19567a180d52a6415193e3ddirk      centroid.y /= total;
14588692172297647753b19567a180d52a6415193e3ddirk      centroid.z /= total;
14598692172297647753b19567a180d52a6415193e3ddirk    }
14608692172297647753b19567a180d52a6415193e3ddirk
14618692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < 6; i++)
14628692172297647753b19567a180d52a6415193e3ddirk    covariance[i] = 0.0f;
14638692172297647753b19567a180d52a6415193e3ddirk
14648692172297647753b19567a180d52a6415193e3ddirk  for (i = 0; i < count; i++)
14658692172297647753b19567a180d52a6415193e3ddirk  {
14668692172297647753b19567a180d52a6415193e3ddirk    DDSVector3
14678692172297647753b19567a180d52a6415193e3ddirk      a,
14688692172297647753b19567a180d52a6415193e3ddirk      b;
14698692172297647753b19567a180d52a6415193e3ddirk
14708692172297647753b19567a180d52a6415193e3ddirk    a.x = points[i].x - centroid.x;
14718692172297647753b19567a180d52a6415193e3ddirk    a.y = points[i].y - centroid.y;
14728692172297647753b19567a180d52a6415193e3ddirk    a.z = points[i].z - centroid.z;
14738692172297647753b19567a180d52a6415193e3ddirk
14748692172297647753b19567a180d52a6415193e3ddirk    b.x = points[i].w * a.x;
14758692172297647753b19567a180d52a6415193e3ddirk    b.y = points[i].w * a.y;
14768692172297647753b19567a180d52a6415193e3ddirk    b.z = points[i].w * a.z;
14778692172297647753b19567a180d52a6415193e3ddirk
14788692172297647753b19567a180d52a6415193e3ddirk    covariance[0] += a.x*b.x;
14798692172297647753b19567a180d52a6415193e3ddirk    covariance[1] += a.x*b.y;
14808692172297647753b19567a180d52a6415193e3ddirk    covariance[2] += a.x*b.z;
14818692172297647753b19567a180d52a6415193e3ddirk    covariance[3] += a.y*b.y;
14828692172297647753b19567a180d52a6415193e3ddirk    covariance[4] += a.y*b.z;
14838692172297647753b19567a180d52a6415193e3ddirk    covariance[5] += a.z*b.z;
14848692172297647753b19567a180d52a6415193e3ddirk  }
14858692172297647753b19567a180d52a6415193e3ddirk}
14868692172297647753b19567a180d52a6415193e3ddirk
14878692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ConstructOrdering(const size_t count,
14888692172297647753b19567a180d52a6415193e3ddirk  const DDSVector4 *points, const DDSVector3 axis, DDSVector4 *pointsWeights,
14898692172297647753b19567a180d52a6415193e3ddirk  DDSVector4 *xSumwSum, unsigned char *order, size_t iteration)
14908692172297647753b19567a180d52a6415193e3ddirk{
14918692172297647753b19567a180d52a6415193e3ddirk  float
14928692172297647753b19567a180d52a6415193e3ddirk     dps[16],
14938692172297647753b19567a180d52a6415193e3ddirk     f;
14948692172297647753b19567a180d52a6415193e3ddirk
14958692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
14968692172297647753b19567a180d52a6415193e3ddirk    i;
14978692172297647753b19567a180d52a6415193e3ddirk
14988692172297647753b19567a180d52a6415193e3ddirk  size_t
14998692172297647753b19567a180d52a6415193e3ddirk    j;
15008692172297647753b19567a180d52a6415193e3ddirk
15018692172297647753b19567a180d52a6415193e3ddirk  unsigned char
15028692172297647753b19567a180d52a6415193e3ddirk    c,
15038692172297647753b19567a180d52a6415193e3ddirk    *o,
15048692172297647753b19567a180d52a6415193e3ddirk    *p;
15058692172297647753b19567a180d52a6415193e3ddirk
15068692172297647753b19567a180d52a6415193e3ddirk  o = order + (16*iteration);
15078692172297647753b19567a180d52a6415193e3ddirk
15088692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < (ssize_t) count; i++)
15098692172297647753b19567a180d52a6415193e3ddirk  {
15108692172297647753b19567a180d52a6415193e3ddirk    dps[i] = Dot(points[i],axis);
15118692172297647753b19567a180d52a6415193e3ddirk    o[i] = (unsigned char)i;
15128692172297647753b19567a180d52a6415193e3ddirk  }
15138692172297647753b19567a180d52a6415193e3ddirk
15148692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < (ssize_t) count; i++)
15158692172297647753b19567a180d52a6415193e3ddirk  {
15168692172297647753b19567a180d52a6415193e3ddirk    for (j=i; j > 0 && dps[j] < dps[j - 1]; j--)
15178692172297647753b19567a180d52a6415193e3ddirk    {
15188692172297647753b19567a180d52a6415193e3ddirk      f = dps[j];
15198692172297647753b19567a180d52a6415193e3ddirk      dps[j] = dps[j - 1];
15208692172297647753b19567a180d52a6415193e3ddirk      dps[j - 1] = f;
15218692172297647753b19567a180d52a6415193e3ddirk
15228692172297647753b19567a180d52a6415193e3ddirk      c = o[j];
15238692172297647753b19567a180d52a6415193e3ddirk      o[j] = o[j - 1];
15248692172297647753b19567a180d52a6415193e3ddirk      o[j - 1] = c;
15258692172297647753b19567a180d52a6415193e3ddirk    }
15268692172297647753b19567a180d52a6415193e3ddirk  }
15278692172297647753b19567a180d52a6415193e3ddirk
15288692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < (ssize_t) iteration; i++)
15298692172297647753b19567a180d52a6415193e3ddirk  {
15308692172297647753b19567a180d52a6415193e3ddirk    MagickBooleanType
15318692172297647753b19567a180d52a6415193e3ddirk      same;
15328692172297647753b19567a180d52a6415193e3ddirk
15338692172297647753b19567a180d52a6415193e3ddirk    p = order + (16*i);
15348692172297647753b19567a180d52a6415193e3ddirk    same = MagickTrue;
15358692172297647753b19567a180d52a6415193e3ddirk
15368692172297647753b19567a180d52a6415193e3ddirk    for (j=0; j < count; j++)
15378692172297647753b19567a180d52a6415193e3ddirk    {
15388692172297647753b19567a180d52a6415193e3ddirk      if (o[j] != p[j])
15398692172297647753b19567a180d52a6415193e3ddirk        {
15408692172297647753b19567a180d52a6415193e3ddirk          same = MagickFalse;
15418692172297647753b19567a180d52a6415193e3ddirk          break;
15428692172297647753b19567a180d52a6415193e3ddirk        }
15438692172297647753b19567a180d52a6415193e3ddirk    }
15448692172297647753b19567a180d52a6415193e3ddirk
15458692172297647753b19567a180d52a6415193e3ddirk    if (same != MagickFalse)
15468692172297647753b19567a180d52a6415193e3ddirk      return MagickFalse;
15478692172297647753b19567a180d52a6415193e3ddirk  }
15488692172297647753b19567a180d52a6415193e3ddirk
15498692172297647753b19567a180d52a6415193e3ddirk  xSumwSum->x = 0;
15508692172297647753b19567a180d52a6415193e3ddirk  xSumwSum->y = 0;
15518692172297647753b19567a180d52a6415193e3ddirk  xSumwSum->z = 0;
15528692172297647753b19567a180d52a6415193e3ddirk  xSumwSum->w = 0;
15538692172297647753b19567a180d52a6415193e3ddirk
15548692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i < (ssize_t) count; i++)
15558692172297647753b19567a180d52a6415193e3ddirk  {
15568692172297647753b19567a180d52a6415193e3ddirk    DDSVector4
15578692172297647753b19567a180d52a6415193e3ddirk      v;
15588692172297647753b19567a180d52a6415193e3ddirk
15598692172297647753b19567a180d52a6415193e3ddirk    j = (size_t) o[i];
15608692172297647753b19567a180d52a6415193e3ddirk
15618692172297647753b19567a180d52a6415193e3ddirk    v.x = points[j].w * points[j].x;
15628692172297647753b19567a180d52a6415193e3ddirk    v.y = points[j].w * points[j].y;
15638692172297647753b19567a180d52a6415193e3ddirk    v.z = points[j].w * points[j].z;
15648692172297647753b19567a180d52a6415193e3ddirk    v.w = points[j].w * 1.0f;
15658692172297647753b19567a180d52a6415193e3ddirk
15668692172297647753b19567a180d52a6415193e3ddirk    VectorCopy44(v,&pointsWeights[i]);
15678692172297647753b19567a180d52a6415193e3ddirk    VectorAdd(*xSumwSum,v,xSumwSum);
15688692172297647753b19567a180d52a6415193e3ddirk  }
15698692172297647753b19567a180d52a6415193e3ddirk
15708692172297647753b19567a180d52a6415193e3ddirk  return MagickTrue;
15718692172297647753b19567a180d52a6415193e3ddirk}
15728692172297647753b19567a180d52a6415193e3ddirk
15738692172297647753b19567a180d52a6415193e3ddirk/*
15748692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15758692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
15768692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
15778692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
15788692172297647753b19567a180d52a6415193e3ddirk%   I s D D S                                                                 %
15798692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
15808692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
15818692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
15828692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15838692172297647753b19567a180d52a6415193e3ddirk%
15848692172297647753b19567a180d52a6415193e3ddirk%  IsDDS() returns MagickTrue if the image format type, identified by the
15858692172297647753b19567a180d52a6415193e3ddirk%  magick string, is DDS.
15868692172297647753b19567a180d52a6415193e3ddirk%
15878692172297647753b19567a180d52a6415193e3ddirk%  The format of the IsDDS method is:
15888692172297647753b19567a180d52a6415193e3ddirk%
15898692172297647753b19567a180d52a6415193e3ddirk%      MagickBooleanType IsDDS(const unsigned char *magick,const size_t length)
15908692172297647753b19567a180d52a6415193e3ddirk%
15918692172297647753b19567a180d52a6415193e3ddirk%  A description of each parameter follows:
15928692172297647753b19567a180d52a6415193e3ddirk%
15938692172297647753b19567a180d52a6415193e3ddirk%    o magick: compare image format pattern against these bytes.
15948692172297647753b19567a180d52a6415193e3ddirk%
15958692172297647753b19567a180d52a6415193e3ddirk%    o length: Specifies the length of the magick string.
15968692172297647753b19567a180d52a6415193e3ddirk%
15978692172297647753b19567a180d52a6415193e3ddirk*/
15988692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType IsDDS(const unsigned char *magick, const size_t length)
15998692172297647753b19567a180d52a6415193e3ddirk{
16008692172297647753b19567a180d52a6415193e3ddirk  if (length < 4)
16018692172297647753b19567a180d52a6415193e3ddirk    return(MagickFalse);
16028692172297647753b19567a180d52a6415193e3ddirk  if (LocaleNCompare((char *) magick,"DDS ", 4) == 0)
16038692172297647753b19567a180d52a6415193e3ddirk    return(MagickTrue);
16048692172297647753b19567a180d52a6415193e3ddirk  return(MagickFalse);
16058692172297647753b19567a180d52a6415193e3ddirk}
16068692172297647753b19567a180d52a6415193e3ddirk/*
16078692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16088692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
16098692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
16108692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
16118692172297647753b19567a180d52a6415193e3ddirk%   R e a d D D S I m a g e                                                   %
16128692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
16138692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
16148692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
16158692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16168692172297647753b19567a180d52a6415193e3ddirk%
16178692172297647753b19567a180d52a6415193e3ddirk%  ReadDDSImage() reads a DirectDraw Surface image file and returns it.  It
16188692172297647753b19567a180d52a6415193e3ddirk%  allocates the memory necessary for the new Image structure and returns a
16198692172297647753b19567a180d52a6415193e3ddirk%  pointer to the new image.
16208692172297647753b19567a180d52a6415193e3ddirk%
16218692172297647753b19567a180d52a6415193e3ddirk%  The format of the ReadDDSImage method is:
16228692172297647753b19567a180d52a6415193e3ddirk%
16238692172297647753b19567a180d52a6415193e3ddirk%      Image *ReadDDSImage(const ImageInfo *image_info,ExceptionInfo *exception)
16248692172297647753b19567a180d52a6415193e3ddirk%
16258692172297647753b19567a180d52a6415193e3ddirk%  A description of each parameter follows:
16268692172297647753b19567a180d52a6415193e3ddirk%
16278692172297647753b19567a180d52a6415193e3ddirk%    o image_info: The image info.
16288692172297647753b19567a180d52a6415193e3ddirk%
16298692172297647753b19567a180d52a6415193e3ddirk%    o exception: return any errors or warnings in this structure.
16308692172297647753b19567a180d52a6415193e3ddirk%
16318692172297647753b19567a180d52a6415193e3ddirk*/
16328692172297647753b19567a180d52a6415193e3ddirk
16338692172297647753b19567a180d52a6415193e3ddirkstatic Image *ReadDDSImage(const ImageInfo *image_info,ExceptionInfo *exception)
16348692172297647753b19567a180d52a6415193e3ddirk{
16358692172297647753b19567a180d52a6415193e3ddirk  Image
16368692172297647753b19567a180d52a6415193e3ddirk    *image;
16378692172297647753b19567a180d52a6415193e3ddirk
16388692172297647753b19567a180d52a6415193e3ddirk  MagickBooleanType
16398692172297647753b19567a180d52a6415193e3ddirk    status,
16408692172297647753b19567a180d52a6415193e3ddirk    cubemap = MagickFalse,
16418692172297647753b19567a180d52a6415193e3ddirk    volume = MagickFalse;
16428692172297647753b19567a180d52a6415193e3ddirk
16438692172297647753b19567a180d52a6415193e3ddirk  CompressionType
16448692172297647753b19567a180d52a6415193e3ddirk    compression;
16458692172297647753b19567a180d52a6415193e3ddirk
16468692172297647753b19567a180d52a6415193e3ddirk  DDSInfo
16478692172297647753b19567a180d52a6415193e3ddirk    dds_info;
16488692172297647753b19567a180d52a6415193e3ddirk
16498692172297647753b19567a180d52a6415193e3ddirk  DDSDecoder
16508692172297647753b19567a180d52a6415193e3ddirk    *decoder;
16518692172297647753b19567a180d52a6415193e3ddirk
16528692172297647753b19567a180d52a6415193e3ddirk  PixelTrait
16538692172297647753b19567a180d52a6415193e3ddirk    alpha_trait;
16548692172297647753b19567a180d52a6415193e3ddirk
16558692172297647753b19567a180d52a6415193e3ddirk  size_t
16568692172297647753b19567a180d52a6415193e3ddirk    n,
16578692172297647753b19567a180d52a6415193e3ddirk    num_images;
16588692172297647753b19567a180d52a6415193e3ddirk
16598692172297647753b19567a180d52a6415193e3ddirk  /*
16608692172297647753b19567a180d52a6415193e3ddirk    Open image file.
16618692172297647753b19567a180d52a6415193e3ddirk  */
16628692172297647753b19567a180d52a6415193e3ddirk  assert(image_info != (const ImageInfo *) NULL);
1663e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
16648692172297647753b19567a180d52a6415193e3ddirk  if (image_info->debug != MagickFalse)
16658692172297647753b19567a180d52a6415193e3ddirk    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
16668692172297647753b19567a180d52a6415193e3ddirk      image_info->filename);
16678692172297647753b19567a180d52a6415193e3ddirk  assert(exception != (ExceptionInfo *) NULL);
1668e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
16698692172297647753b19567a180d52a6415193e3ddirk  image=AcquireImage(image_info,exception);
16708692172297647753b19567a180d52a6415193e3ddirk  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
16718692172297647753b19567a180d52a6415193e3ddirk  if (status == MagickFalse)
16728692172297647753b19567a180d52a6415193e3ddirk    {
16738692172297647753b19567a180d52a6415193e3ddirk      image=DestroyImageList(image);
16748692172297647753b19567a180d52a6415193e3ddirk      return((Image *) NULL);
16758692172297647753b19567a180d52a6415193e3ddirk    }
16768692172297647753b19567a180d52a6415193e3ddirk
16778692172297647753b19567a180d52a6415193e3ddirk  /*
16788692172297647753b19567a180d52a6415193e3ddirk    Initialize image structure.
16798692172297647753b19567a180d52a6415193e3ddirk  */
16808692172297647753b19567a180d52a6415193e3ddirk  if (ReadDDSInfo(image, &dds_info) != MagickTrue) {
16818692172297647753b19567a180d52a6415193e3ddirk    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
16828692172297647753b19567a180d52a6415193e3ddirk  }
16838692172297647753b19567a180d52a6415193e3ddirk
16848692172297647753b19567a180d52a6415193e3ddirk  if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP)
16858692172297647753b19567a180d52a6415193e3ddirk    cubemap = MagickTrue;
16868692172297647753b19567a180d52a6415193e3ddirk
16878692172297647753b19567a180d52a6415193e3ddirk  if (dds_info.ddscaps2 & DDSCAPS2_VOLUME && dds_info.depth > 0)
16888692172297647753b19567a180d52a6415193e3ddirk    volume = MagickTrue;
16898692172297647753b19567a180d52a6415193e3ddirk
16908692172297647753b19567a180d52a6415193e3ddirk  (void) SeekBlob(image, 128, SEEK_SET);
16918692172297647753b19567a180d52a6415193e3ddirk
16928692172297647753b19567a180d52a6415193e3ddirk  /*
16938692172297647753b19567a180d52a6415193e3ddirk    Determine pixel format
16948692172297647753b19567a180d52a6415193e3ddirk  */
16958692172297647753b19567a180d52a6415193e3ddirk  if (dds_info.pixelformat.flags & DDPF_RGB)
16968692172297647753b19567a180d52a6415193e3ddirk    {
16978692172297647753b19567a180d52a6415193e3ddirk      compression = NoCompression;
16988692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.pixelformat.flags & DDPF_ALPHAPIXELS)
16998692172297647753b19567a180d52a6415193e3ddirk        {
17008692172297647753b19567a180d52a6415193e3ddirk          alpha_trait = BlendPixelTrait;
17018692172297647753b19567a180d52a6415193e3ddirk          decoder = ReadUncompressedRGBA;
17028692172297647753b19567a180d52a6415193e3ddirk        }
17038692172297647753b19567a180d52a6415193e3ddirk      else
17048692172297647753b19567a180d52a6415193e3ddirk        {
17058692172297647753b19567a180d52a6415193e3ddirk          alpha_trait = UndefinedPixelTrait;
17068692172297647753b19567a180d52a6415193e3ddirk          decoder = ReadUncompressedRGB;
17078692172297647753b19567a180d52a6415193e3ddirk        }
17088692172297647753b19567a180d52a6415193e3ddirk    }
17096398fb41b2fa07b3234f02c533844504ede388dfdirk  else if (dds_info.pixelformat.flags & DDPF_LUMINANCE)
17106398fb41b2fa07b3234f02c533844504ede388dfdirk   {
17116398fb41b2fa07b3234f02c533844504ede388dfdirk      compression = NoCompression;
17126398fb41b2fa07b3234f02c533844504ede388dfdirk      if (dds_info.pixelformat.flags & DDPF_ALPHAPIXELS)
17136398fb41b2fa07b3234f02c533844504ede388dfdirk        {
17146398fb41b2fa07b3234f02c533844504ede388dfdirk          /* Not sure how to handle this */
17156398fb41b2fa07b3234f02c533844504ede388dfdirk          ThrowReaderException(CorruptImageError, "ImageTypeNotSupported");
17166398fb41b2fa07b3234f02c533844504ede388dfdirk        }
17176398fb41b2fa07b3234f02c533844504ede388dfdirk      else
17186398fb41b2fa07b3234f02c533844504ede388dfdirk        {
17196398fb41b2fa07b3234f02c533844504ede388dfdirk          alpha_trait = UndefinedPixelTrait;
17206398fb41b2fa07b3234f02c533844504ede388dfdirk          decoder = ReadUncompressedRGB;
17216398fb41b2fa07b3234f02c533844504ede388dfdirk        }
17226398fb41b2fa07b3234f02c533844504ede388dfdirk    }
17238692172297647753b19567a180d52a6415193e3ddirk  else if (dds_info.pixelformat.flags & DDPF_FOURCC)
17248692172297647753b19567a180d52a6415193e3ddirk    {
17258692172297647753b19567a180d52a6415193e3ddirk      switch (dds_info.pixelformat.fourcc)
17268692172297647753b19567a180d52a6415193e3ddirk      {
17278692172297647753b19567a180d52a6415193e3ddirk        case FOURCC_DXT1:
17288692172297647753b19567a180d52a6415193e3ddirk        {
17298692172297647753b19567a180d52a6415193e3ddirk          alpha_trait = UndefinedPixelTrait;
17308692172297647753b19567a180d52a6415193e3ddirk          compression = DXT1Compression;
17318692172297647753b19567a180d52a6415193e3ddirk          decoder = ReadDXT1;
17328692172297647753b19567a180d52a6415193e3ddirk          break;
17338692172297647753b19567a180d52a6415193e3ddirk        }
17348692172297647753b19567a180d52a6415193e3ddirk        case FOURCC_DXT3:
17358692172297647753b19567a180d52a6415193e3ddirk        {
17368692172297647753b19567a180d52a6415193e3ddirk          alpha_trait = BlendPixelTrait;
17378692172297647753b19567a180d52a6415193e3ddirk          compression = DXT3Compression;
17388692172297647753b19567a180d52a6415193e3ddirk          decoder = ReadDXT3;
17398692172297647753b19567a180d52a6415193e3ddirk          break;
17408692172297647753b19567a180d52a6415193e3ddirk        }
17418692172297647753b19567a180d52a6415193e3ddirk        case FOURCC_DXT5:
17428692172297647753b19567a180d52a6415193e3ddirk        {
17438692172297647753b19567a180d52a6415193e3ddirk          alpha_trait = BlendPixelTrait;
17448692172297647753b19567a180d52a6415193e3ddirk          compression = DXT5Compression;
17458692172297647753b19567a180d52a6415193e3ddirk          decoder = ReadDXT5;
17468692172297647753b19567a180d52a6415193e3ddirk          break;
17478692172297647753b19567a180d52a6415193e3ddirk        }
17488692172297647753b19567a180d52a6415193e3ddirk        default:
17498692172297647753b19567a180d52a6415193e3ddirk        {
17508692172297647753b19567a180d52a6415193e3ddirk          /* Unknown FOURCC */
17518692172297647753b19567a180d52a6415193e3ddirk          ThrowReaderException(CorruptImageError, "ImageTypeNotSupported");
17528692172297647753b19567a180d52a6415193e3ddirk        }
17538692172297647753b19567a180d52a6415193e3ddirk      }
17548692172297647753b19567a180d52a6415193e3ddirk    }
17558692172297647753b19567a180d52a6415193e3ddirk  else
17568692172297647753b19567a180d52a6415193e3ddirk    {
17578692172297647753b19567a180d52a6415193e3ddirk      /* Neither compressed nor uncompressed... thus unsupported */
17588692172297647753b19567a180d52a6415193e3ddirk      ThrowReaderException(CorruptImageError, "ImageTypeNotSupported");
17598692172297647753b19567a180d52a6415193e3ddirk    }
17608692172297647753b19567a180d52a6415193e3ddirk
17618692172297647753b19567a180d52a6415193e3ddirk  num_images = 1;
17628692172297647753b19567a180d52a6415193e3ddirk  if (cubemap)
17638692172297647753b19567a180d52a6415193e3ddirk    {
17648692172297647753b19567a180d52a6415193e3ddirk      /*
17658692172297647753b19567a180d52a6415193e3ddirk        Determine number of faces defined in the cubemap
17668692172297647753b19567a180d52a6415193e3ddirk      */
17678692172297647753b19567a180d52a6415193e3ddirk      num_images = 0;
17688692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP_POSITIVEX) num_images++;
17698692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) num_images++;
17708692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP_POSITIVEY) num_images++;
17718692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) num_images++;
17728692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) num_images++;
17738692172297647753b19567a180d52a6415193e3ddirk      if (dds_info.ddscaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) num_images++;
17748692172297647753b19567a180d52a6415193e3ddirk    }
17758692172297647753b19567a180d52a6415193e3ddirk
17768692172297647753b19567a180d52a6415193e3ddirk  if (volume)
17778692172297647753b19567a180d52a6415193e3ddirk    num_images = dds_info.depth;
17788692172297647753b19567a180d52a6415193e3ddirk
17798692172297647753b19567a180d52a6415193e3ddirk  for (n = 0; n < num_images; n++)
17808692172297647753b19567a180d52a6415193e3ddirk  {
17818692172297647753b19567a180d52a6415193e3ddirk    if (n != 0)
17828692172297647753b19567a180d52a6415193e3ddirk      {
17838692172297647753b19567a180d52a6415193e3ddirk        /* Start a new image */
17848692172297647753b19567a180d52a6415193e3ddirk        AcquireNextImage(image_info,image,exception);
17858692172297647753b19567a180d52a6415193e3ddirk        if (GetNextImageInList(image) == (Image *) NULL)
17868692172297647753b19567a180d52a6415193e3ddirk          return(DestroyImageList(image));
17878692172297647753b19567a180d52a6415193e3ddirk        image=SyncNextImageInList(image);
17888692172297647753b19567a180d52a6415193e3ddirk      }
17898692172297647753b19567a180d52a6415193e3ddirk
17908692172297647753b19567a180d52a6415193e3ddirk    image->alpha_trait=alpha_trait;
17918692172297647753b19567a180d52a6415193e3ddirk    image->compression = compression;
17928692172297647753b19567a180d52a6415193e3ddirk    image->columns = dds_info.width;
17938692172297647753b19567a180d52a6415193e3ddirk    image->rows = dds_info.height;
17948692172297647753b19567a180d52a6415193e3ddirk    image->storage_class = DirectClass;
17958692172297647753b19567a180d52a6415193e3ddirk    image->endian = LSBEndian;
17968692172297647753b19567a180d52a6415193e3ddirk    image->depth = 8;
17978692172297647753b19567a180d52a6415193e3ddirk    if (image_info->ping != MagickFalse)
17988692172297647753b19567a180d52a6415193e3ddirk      {
17998692172297647753b19567a180d52a6415193e3ddirk        (void) CloseBlob(image);
18008692172297647753b19567a180d52a6415193e3ddirk        return(GetFirstImageInList(image));
18018692172297647753b19567a180d52a6415193e3ddirk      }
1802acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy    status=SetImageExtent(image,image->columns,image->rows,exception);
1803acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy    if (status == MagickFalse)
1804acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy      return(DestroyImageList(image));
18058692172297647753b19567a180d52a6415193e3ddirk    if ((decoder)(image, &dds_info, exception) != MagickTrue)
18068692172297647753b19567a180d52a6415193e3ddirk      {
18078692172297647753b19567a180d52a6415193e3ddirk        (void) CloseBlob(image);
18088692172297647753b19567a180d52a6415193e3ddirk        return(GetFirstImageInList(image));
18098692172297647753b19567a180d52a6415193e3ddirk      }
18108692172297647753b19567a180d52a6415193e3ddirk  }
18118692172297647753b19567a180d52a6415193e3ddirk  (void) CloseBlob(image);
18128692172297647753b19567a180d52a6415193e3ddirk  return(GetFirstImageInList(image));
18138692172297647753b19567a180d52a6415193e3ddirk}
18148692172297647753b19567a180d52a6415193e3ddirk
18158692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ReadDDSInfo(Image *image, DDSInfo *dds_info)
18168692172297647753b19567a180d52a6415193e3ddirk{
18178692172297647753b19567a180d52a6415193e3ddirk  size_t
18188692172297647753b19567a180d52a6415193e3ddirk    hdr_size,
18198692172297647753b19567a180d52a6415193e3ddirk    required;
18208692172297647753b19567a180d52a6415193e3ddirk
18218692172297647753b19567a180d52a6415193e3ddirk  /* Seek to start of header */
18228692172297647753b19567a180d52a6415193e3ddirk  (void) SeekBlob(image, 4, SEEK_SET);
18238692172297647753b19567a180d52a6415193e3ddirk
18248692172297647753b19567a180d52a6415193e3ddirk  /* Check header field */
18258692172297647753b19567a180d52a6415193e3ddirk  hdr_size = ReadBlobLSBLong(image);
18268692172297647753b19567a180d52a6415193e3ddirk  if (hdr_size != 124)
18278692172297647753b19567a180d52a6415193e3ddirk    return MagickFalse;
18288692172297647753b19567a180d52a6415193e3ddirk
18298692172297647753b19567a180d52a6415193e3ddirk  /* Fill in DDS info struct */
18308692172297647753b19567a180d52a6415193e3ddirk  dds_info->flags = ReadBlobLSBLong(image);
18318692172297647753b19567a180d52a6415193e3ddirk
18328692172297647753b19567a180d52a6415193e3ddirk  /* Check required flags */
18338692172297647753b19567a180d52a6415193e3ddirk  required=(size_t) (DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT);
18348692172297647753b19567a180d52a6415193e3ddirk  if ((dds_info->flags & required) != required)
18358692172297647753b19567a180d52a6415193e3ddirk    return MagickFalse;
18368692172297647753b19567a180d52a6415193e3ddirk
18378692172297647753b19567a180d52a6415193e3ddirk  dds_info->height = ReadBlobLSBLong(image);
18388692172297647753b19567a180d52a6415193e3ddirk  dds_info->width = ReadBlobLSBLong(image);
18398692172297647753b19567a180d52a6415193e3ddirk  dds_info->pitchOrLinearSize = ReadBlobLSBLong(image);
18408692172297647753b19567a180d52a6415193e3ddirk  dds_info->depth = ReadBlobLSBLong(image);
18418692172297647753b19567a180d52a6415193e3ddirk  dds_info->mipmapcount = ReadBlobLSBLong(image);
18428692172297647753b19567a180d52a6415193e3ddirk
18438692172297647753b19567a180d52a6415193e3ddirk  (void) SeekBlob(image, 44, SEEK_CUR);   /* reserved region of 11 DWORDs */
18448692172297647753b19567a180d52a6415193e3ddirk
18458692172297647753b19567a180d52a6415193e3ddirk  /* Read pixel format structure */
18468692172297647753b19567a180d52a6415193e3ddirk  hdr_size = ReadBlobLSBLong(image);
18478692172297647753b19567a180d52a6415193e3ddirk  if (hdr_size != 32)
18488692172297647753b19567a180d52a6415193e3ddirk    return MagickFalse;
18498692172297647753b19567a180d52a6415193e3ddirk
18508692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.flags = ReadBlobLSBLong(image);
18518692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.fourcc = ReadBlobLSBLong(image);
18528692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.rgb_bitcount = ReadBlobLSBLong(image);
18538692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.r_bitmask = ReadBlobLSBLong(image);
18548692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.g_bitmask = ReadBlobLSBLong(image);
18558692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.b_bitmask = ReadBlobLSBLong(image);
18568692172297647753b19567a180d52a6415193e3ddirk  dds_info->pixelformat.alpha_bitmask = ReadBlobLSBLong(image);
18578692172297647753b19567a180d52a6415193e3ddirk
18588692172297647753b19567a180d52a6415193e3ddirk  dds_info->ddscaps1 = ReadBlobLSBLong(image);
18598692172297647753b19567a180d52a6415193e3ddirk  dds_info->ddscaps2 = ReadBlobLSBLong(image);
18608692172297647753b19567a180d52a6415193e3ddirk  (void) SeekBlob(image, 12, SEEK_CUR); /* 3 reserved DWORDs */
18618692172297647753b19567a180d52a6415193e3ddirk
18628692172297647753b19567a180d52a6415193e3ddirk  return MagickTrue;
18638692172297647753b19567a180d52a6415193e3ddirk}
18648692172297647753b19567a180d52a6415193e3ddirk
18658692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ReadDXT1(Image *image, DDSInfo *dds_info,
18668692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
18678692172297647753b19567a180d52a6415193e3ddirk{
18688692172297647753b19567a180d52a6415193e3ddirk  DDSColors
18698692172297647753b19567a180d52a6415193e3ddirk    colors;
18708692172297647753b19567a180d52a6415193e3ddirk
18718692172297647753b19567a180d52a6415193e3ddirk  register Quantum
18728692172297647753b19567a180d52a6415193e3ddirk    *q;
18738692172297647753b19567a180d52a6415193e3ddirk
18748692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
18758692172297647753b19567a180d52a6415193e3ddirk    i,
18768692172297647753b19567a180d52a6415193e3ddirk    x;
18778692172297647753b19567a180d52a6415193e3ddirk
18788692172297647753b19567a180d52a6415193e3ddirk  size_t
18798692172297647753b19567a180d52a6415193e3ddirk    bits;
18808692172297647753b19567a180d52a6415193e3ddirk
18818692172297647753b19567a180d52a6415193e3ddirk  ssize_t
18828692172297647753b19567a180d52a6415193e3ddirk    j,
18838692172297647753b19567a180d52a6415193e3ddirk    y;
18848692172297647753b19567a180d52a6415193e3ddirk
18858692172297647753b19567a180d52a6415193e3ddirk  unsigned char
18868692172297647753b19567a180d52a6415193e3ddirk    code;
18878692172297647753b19567a180d52a6415193e3ddirk
18888692172297647753b19567a180d52a6415193e3ddirk  unsigned short
18898692172297647753b19567a180d52a6415193e3ddirk    c0,
18908692172297647753b19567a180d52a6415193e3ddirk    c1;
18918692172297647753b19567a180d52a6415193e3ddirk
18928692172297647753b19567a180d52a6415193e3ddirk  for (y = 0; y < (ssize_t) dds_info->height; y += 4)
18938692172297647753b19567a180d52a6415193e3ddirk  {
18948692172297647753b19567a180d52a6415193e3ddirk    for (x = 0; x < (ssize_t) dds_info->width; x += 4)
18958692172297647753b19567a180d52a6415193e3ddirk    {
18968692172297647753b19567a180d52a6415193e3ddirk      /* Get 4x4 patch of pixels to write on */
1897ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk      q = QueueAuthenticPixels(image, x, y, MagickMin(4, dds_info->width - x),
1898ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk        MagickMin(4, dds_info->height - y),exception);
18998692172297647753b19567a180d52a6415193e3ddirk
19008692172297647753b19567a180d52a6415193e3ddirk      if (q == (Quantum *) NULL)
19018692172297647753b19567a180d52a6415193e3ddirk        return MagickFalse;
19028692172297647753b19567a180d52a6415193e3ddirk
19038692172297647753b19567a180d52a6415193e3ddirk      /* Read 8 bytes of data from the image */
19048692172297647753b19567a180d52a6415193e3ddirk      c0 = ReadBlobLSBShort(image);
19058692172297647753b19567a180d52a6415193e3ddirk      c1 = ReadBlobLSBShort(image);
19068692172297647753b19567a180d52a6415193e3ddirk      bits = ReadBlobLSBLong(image);
19078692172297647753b19567a180d52a6415193e3ddirk
19088692172297647753b19567a180d52a6415193e3ddirk      CalculateColors(c0, c1, &colors, MagickFalse);
19098692172297647753b19567a180d52a6415193e3ddirk
19108692172297647753b19567a180d52a6415193e3ddirk      /* Write the pixels */
19118692172297647753b19567a180d52a6415193e3ddirk      for (j = 0; j < 4; j++)
19128692172297647753b19567a180d52a6415193e3ddirk      {
19138692172297647753b19567a180d52a6415193e3ddirk        for (i = 0; i < 4; i++)
19148692172297647753b19567a180d52a6415193e3ddirk        {
19158692172297647753b19567a180d52a6415193e3ddirk          if ((x + i) < (ssize_t) dds_info->width &&
19168692172297647753b19567a180d52a6415193e3ddirk              (y + j) < (ssize_t) dds_info->height)
19178692172297647753b19567a180d52a6415193e3ddirk            {
19188692172297647753b19567a180d52a6415193e3ddirk              code = (unsigned char) ((bits >> ((j*4+i)*2)) & 0x3);
19198692172297647753b19567a180d52a6415193e3ddirk              SetPixelRed(image,ScaleCharToQuantum(colors.r[code]),q);
19208692172297647753b19567a180d52a6415193e3ddirk              SetPixelGreen(image,ScaleCharToQuantum(colors.g[code]),q);
19218692172297647753b19567a180d52a6415193e3ddirk              SetPixelBlue(image,ScaleCharToQuantum(colors.b[code]),q);
19228692172297647753b19567a180d52a6415193e3ddirk              SetPixelAlpha(image,ScaleCharToQuantum(colors.a[code]),q);
192317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy              if (colors.a[code] && (image->alpha_trait == UndefinedPixelTrait))
19248692172297647753b19567a180d52a6415193e3ddirk                image->alpha_trait=BlendPixelTrait;  /* Correct matte */
19258692172297647753b19567a180d52a6415193e3ddirk              q+=GetPixelChannels(image);
19268692172297647753b19567a180d52a6415193e3ddirk            }
19278692172297647753b19567a180d52a6415193e3ddirk        }
19288692172297647753b19567a180d52a6415193e3ddirk      }
19298692172297647753b19567a180d52a6415193e3ddirk
19308692172297647753b19567a180d52a6415193e3ddirk      if (SyncAuthenticPixels(image,exception) == MagickFalse)
19318692172297647753b19567a180d52a6415193e3ddirk        return MagickFalse;
19328692172297647753b19567a180d52a6415193e3ddirk    }
19338692172297647753b19567a180d52a6415193e3ddirk  }
19348692172297647753b19567a180d52a6415193e3ddirk
1935ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(SkipDXTMipmaps(image,dds_info,8,exception));
19368692172297647753b19567a180d52a6415193e3ddirk}
19378692172297647753b19567a180d52a6415193e3ddirk
19388692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ReadDXT3(Image *image, DDSInfo *dds_info,
19398692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
19408692172297647753b19567a180d52a6415193e3ddirk{
19418692172297647753b19567a180d52a6415193e3ddirk  DDSColors
19428692172297647753b19567a180d52a6415193e3ddirk    colors;
19438692172297647753b19567a180d52a6415193e3ddirk
19448692172297647753b19567a180d52a6415193e3ddirk  register Quantum
19458692172297647753b19567a180d52a6415193e3ddirk    *q;
19468692172297647753b19567a180d52a6415193e3ddirk
19478692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
19488692172297647753b19567a180d52a6415193e3ddirk    i,
19498692172297647753b19567a180d52a6415193e3ddirk    x;
19508692172297647753b19567a180d52a6415193e3ddirk
19518692172297647753b19567a180d52a6415193e3ddirk  unsigned char
19528692172297647753b19567a180d52a6415193e3ddirk    alpha;
19538692172297647753b19567a180d52a6415193e3ddirk
19548692172297647753b19567a180d52a6415193e3ddirk  size_t
19558692172297647753b19567a180d52a6415193e3ddirk    a0,
19568692172297647753b19567a180d52a6415193e3ddirk    a1,
19578692172297647753b19567a180d52a6415193e3ddirk    bits,
19588692172297647753b19567a180d52a6415193e3ddirk    code;
19598692172297647753b19567a180d52a6415193e3ddirk
19608692172297647753b19567a180d52a6415193e3ddirk  ssize_t
19618692172297647753b19567a180d52a6415193e3ddirk    j,
19628692172297647753b19567a180d52a6415193e3ddirk    y;
19638692172297647753b19567a180d52a6415193e3ddirk
19648692172297647753b19567a180d52a6415193e3ddirk  unsigned short
19658692172297647753b19567a180d52a6415193e3ddirk    c0,
19668692172297647753b19567a180d52a6415193e3ddirk    c1;
19678692172297647753b19567a180d52a6415193e3ddirk
19688692172297647753b19567a180d52a6415193e3ddirk  for (y = 0; y < (ssize_t) dds_info->height; y += 4)
19698692172297647753b19567a180d52a6415193e3ddirk  {
19708692172297647753b19567a180d52a6415193e3ddirk    for (x = 0; x < (ssize_t) dds_info->width; x += 4)
19718692172297647753b19567a180d52a6415193e3ddirk    {
19728692172297647753b19567a180d52a6415193e3ddirk      /* Get 4x4 patch of pixels to write on */
1973ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk      q = QueueAuthenticPixels(image, x, y, MagickMin(4, dds_info->width - x),
1974ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk                         MagickMin(4, dds_info->height - y),exception);
19758692172297647753b19567a180d52a6415193e3ddirk
19768692172297647753b19567a180d52a6415193e3ddirk      if (q == (Quantum *) NULL)
19778692172297647753b19567a180d52a6415193e3ddirk        return MagickFalse;
19788692172297647753b19567a180d52a6415193e3ddirk
19798692172297647753b19567a180d52a6415193e3ddirk      /* Read alpha values (8 bytes) */
19808692172297647753b19567a180d52a6415193e3ddirk      a0 = ReadBlobLSBLong(image);
19818692172297647753b19567a180d52a6415193e3ddirk      a1 = ReadBlobLSBLong(image);
19828692172297647753b19567a180d52a6415193e3ddirk
19838692172297647753b19567a180d52a6415193e3ddirk      /* Read 8 bytes of data from the image */
19848692172297647753b19567a180d52a6415193e3ddirk      c0 = ReadBlobLSBShort(image);
19858692172297647753b19567a180d52a6415193e3ddirk      c1 = ReadBlobLSBShort(image);
19868692172297647753b19567a180d52a6415193e3ddirk      bits = ReadBlobLSBLong(image);
19878692172297647753b19567a180d52a6415193e3ddirk
19888692172297647753b19567a180d52a6415193e3ddirk      CalculateColors(c0, c1, &colors, MagickTrue);
19898692172297647753b19567a180d52a6415193e3ddirk
19908692172297647753b19567a180d52a6415193e3ddirk      /* Write the pixels */
19918692172297647753b19567a180d52a6415193e3ddirk      for (j = 0; j < 4; j++)
19928692172297647753b19567a180d52a6415193e3ddirk      {
19938692172297647753b19567a180d52a6415193e3ddirk        for (i = 0; i < 4; i++)
19948692172297647753b19567a180d52a6415193e3ddirk        {
19958692172297647753b19567a180d52a6415193e3ddirk          if ((x + i) < (ssize_t) dds_info->width && (y + j) < (ssize_t) dds_info->height)
19968692172297647753b19567a180d52a6415193e3ddirk            {
19978692172297647753b19567a180d52a6415193e3ddirk              code = (bits >> ((4*j+i)*2)) & 0x3;
19988692172297647753b19567a180d52a6415193e3ddirk              SetPixelRed(image,ScaleCharToQuantum(colors.r[code]),q);
19998692172297647753b19567a180d52a6415193e3ddirk              SetPixelGreen(image,ScaleCharToQuantum(colors.g[code]),q);
20008692172297647753b19567a180d52a6415193e3ddirk              SetPixelBlue(image,ScaleCharToQuantum(colors.b[code]),q);
20018692172297647753b19567a180d52a6415193e3ddirk              /*
20028692172297647753b19567a180d52a6415193e3ddirk                Extract alpha value: multiply 0..15 by 17 to get range 0..255
20038692172297647753b19567a180d52a6415193e3ddirk              */
20048692172297647753b19567a180d52a6415193e3ddirk              if (j < 2)
20058692172297647753b19567a180d52a6415193e3ddirk                alpha = 17U * (unsigned char) ((a0 >> (4*(4*j+i))) & 0xf);
20068692172297647753b19567a180d52a6415193e3ddirk              else
20078692172297647753b19567a180d52a6415193e3ddirk                alpha = 17U * (unsigned char) ((a1 >> (4*(4*(j-2)+i))) & 0xf);
20088692172297647753b19567a180d52a6415193e3ddirk              SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) alpha),q);
20098692172297647753b19567a180d52a6415193e3ddirk              q+=GetPixelChannels(image);
20108692172297647753b19567a180d52a6415193e3ddirk            }
20118692172297647753b19567a180d52a6415193e3ddirk        }
20128692172297647753b19567a180d52a6415193e3ddirk      }
20138692172297647753b19567a180d52a6415193e3ddirk
20148692172297647753b19567a180d52a6415193e3ddirk      if (SyncAuthenticPixels(image,exception) == MagickFalse)
20158692172297647753b19567a180d52a6415193e3ddirk        return MagickFalse;
20168692172297647753b19567a180d52a6415193e3ddirk    }
20178692172297647753b19567a180d52a6415193e3ddirk  }
20188692172297647753b19567a180d52a6415193e3ddirk
2019ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(SkipDXTMipmaps(image,dds_info,16,exception));
20208692172297647753b19567a180d52a6415193e3ddirk}
20218692172297647753b19567a180d52a6415193e3ddirk
20228692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ReadDXT5(Image *image, DDSInfo *dds_info,
20238692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
20248692172297647753b19567a180d52a6415193e3ddirk{
20258692172297647753b19567a180d52a6415193e3ddirk  DDSColors
20268692172297647753b19567a180d52a6415193e3ddirk    colors;
20278692172297647753b19567a180d52a6415193e3ddirk
20288692172297647753b19567a180d52a6415193e3ddirk  MagickSizeType
20298692172297647753b19567a180d52a6415193e3ddirk    alpha_bits;
20308692172297647753b19567a180d52a6415193e3ddirk
20318692172297647753b19567a180d52a6415193e3ddirk  register Quantum
20328692172297647753b19567a180d52a6415193e3ddirk    *q;
20338692172297647753b19567a180d52a6415193e3ddirk
20348692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
20358692172297647753b19567a180d52a6415193e3ddirk    i,
20368692172297647753b19567a180d52a6415193e3ddirk    x;
20378692172297647753b19567a180d52a6415193e3ddirk
20388692172297647753b19567a180d52a6415193e3ddirk  unsigned char
20398692172297647753b19567a180d52a6415193e3ddirk    a0,
20408692172297647753b19567a180d52a6415193e3ddirk    a1;
20418692172297647753b19567a180d52a6415193e3ddirk
20428692172297647753b19567a180d52a6415193e3ddirk  size_t
20438692172297647753b19567a180d52a6415193e3ddirk    alpha,
20448692172297647753b19567a180d52a6415193e3ddirk    bits,
20458692172297647753b19567a180d52a6415193e3ddirk    code,
20468692172297647753b19567a180d52a6415193e3ddirk    alpha_code;
20478692172297647753b19567a180d52a6415193e3ddirk
20488692172297647753b19567a180d52a6415193e3ddirk  ssize_t
20498692172297647753b19567a180d52a6415193e3ddirk    j,
20508692172297647753b19567a180d52a6415193e3ddirk    y;
20518692172297647753b19567a180d52a6415193e3ddirk
20528692172297647753b19567a180d52a6415193e3ddirk  unsigned short
20538692172297647753b19567a180d52a6415193e3ddirk    c0,
20548692172297647753b19567a180d52a6415193e3ddirk    c1;
20558692172297647753b19567a180d52a6415193e3ddirk
20568692172297647753b19567a180d52a6415193e3ddirk  for (y = 0; y < (ssize_t) dds_info->height; y += 4)
20578692172297647753b19567a180d52a6415193e3ddirk  {
20588692172297647753b19567a180d52a6415193e3ddirk    for (x = 0; x < (ssize_t) dds_info->width; x += 4)
20598692172297647753b19567a180d52a6415193e3ddirk    {
20608692172297647753b19567a180d52a6415193e3ddirk      /* Get 4x4 patch of pixels to write on */
2061ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk      q = QueueAuthenticPixels(image, x, y, MagickMin(4, dds_info->width - x),
2062ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk                         MagickMin(4, dds_info->height - y),exception);
20638692172297647753b19567a180d52a6415193e3ddirk
20648692172297647753b19567a180d52a6415193e3ddirk      if (q == (Quantum *) NULL)
20658692172297647753b19567a180d52a6415193e3ddirk        return MagickFalse;
20668692172297647753b19567a180d52a6415193e3ddirk
20678692172297647753b19567a180d52a6415193e3ddirk      /* Read alpha values (8 bytes) */
20688692172297647753b19567a180d52a6415193e3ddirk      a0 = (unsigned char) ReadBlobByte(image);
20698692172297647753b19567a180d52a6415193e3ddirk      a1 = (unsigned char) ReadBlobByte(image);
20708692172297647753b19567a180d52a6415193e3ddirk
20718692172297647753b19567a180d52a6415193e3ddirk      alpha_bits = (MagickSizeType)ReadBlobLSBLong(image);
20728692172297647753b19567a180d52a6415193e3ddirk      alpha_bits = alpha_bits | ((MagickSizeType)ReadBlobLSBShort(image) << 32);
20738692172297647753b19567a180d52a6415193e3ddirk
20748692172297647753b19567a180d52a6415193e3ddirk      /* Read 8 bytes of data from the image */
20758692172297647753b19567a180d52a6415193e3ddirk      c0 = ReadBlobLSBShort(image);
20768692172297647753b19567a180d52a6415193e3ddirk      c1 = ReadBlobLSBShort(image);
20778692172297647753b19567a180d52a6415193e3ddirk      bits = ReadBlobLSBLong(image);
20788692172297647753b19567a180d52a6415193e3ddirk
20798692172297647753b19567a180d52a6415193e3ddirk      CalculateColors(c0, c1, &colors, MagickTrue);
20808692172297647753b19567a180d52a6415193e3ddirk
20818692172297647753b19567a180d52a6415193e3ddirk      /* Write the pixels */
20828692172297647753b19567a180d52a6415193e3ddirk      for (j = 0; j < 4; j++)
20838692172297647753b19567a180d52a6415193e3ddirk      {
20848692172297647753b19567a180d52a6415193e3ddirk        for (i = 0; i < 4; i++)
20858692172297647753b19567a180d52a6415193e3ddirk        {
20868692172297647753b19567a180d52a6415193e3ddirk          if ((x + i) < (ssize_t) dds_info->width &&
20878692172297647753b19567a180d52a6415193e3ddirk              (y + j) < (ssize_t) dds_info->height)
20888692172297647753b19567a180d52a6415193e3ddirk            {
20898692172297647753b19567a180d52a6415193e3ddirk              code = (bits >> ((4*j+i)*2)) & 0x3;
20908692172297647753b19567a180d52a6415193e3ddirk              SetPixelRed(image,ScaleCharToQuantum(colors.r[code]),q);
20918692172297647753b19567a180d52a6415193e3ddirk              SetPixelGreen(image,ScaleCharToQuantum(colors.g[code]),q);
20928692172297647753b19567a180d52a6415193e3ddirk              SetPixelBlue(image,ScaleCharToQuantum(colors.b[code]),q);
20938692172297647753b19567a180d52a6415193e3ddirk              /* Extract alpha value */
20948692172297647753b19567a180d52a6415193e3ddirk              alpha_code = (size_t) (alpha_bits >> (3*(4*j+i))) & 0x7;
20958692172297647753b19567a180d52a6415193e3ddirk              if (alpha_code == 0)
20968692172297647753b19567a180d52a6415193e3ddirk                alpha = a0;
20978692172297647753b19567a180d52a6415193e3ddirk              else if (alpha_code == 1)
20988692172297647753b19567a180d52a6415193e3ddirk                alpha = a1;
20998692172297647753b19567a180d52a6415193e3ddirk              else if (a0 > a1)
21008692172297647753b19567a180d52a6415193e3ddirk                alpha = ((8-alpha_code) * a0 + (alpha_code-1) * a1) / 7;
21018692172297647753b19567a180d52a6415193e3ddirk              else if (alpha_code == 6)
21028692172297647753b19567a180d52a6415193e3ddirk                alpha = 0;
21038692172297647753b19567a180d52a6415193e3ddirk              else if (alpha_code == 7)
21048692172297647753b19567a180d52a6415193e3ddirk                alpha = 255;
21058692172297647753b19567a180d52a6415193e3ddirk              else
21068692172297647753b19567a180d52a6415193e3ddirk                alpha = (((6-alpha_code) * a0 + (alpha_code-1) * a1) / 5);
21078692172297647753b19567a180d52a6415193e3ddirk              SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) alpha),q);
21088692172297647753b19567a180d52a6415193e3ddirk              q+=GetPixelChannels(image);
21098692172297647753b19567a180d52a6415193e3ddirk            }
21108692172297647753b19567a180d52a6415193e3ddirk        }
21118692172297647753b19567a180d52a6415193e3ddirk      }
21128692172297647753b19567a180d52a6415193e3ddirk
21138692172297647753b19567a180d52a6415193e3ddirk      if (SyncAuthenticPixels(image,exception) == MagickFalse)
21148692172297647753b19567a180d52a6415193e3ddirk        return MagickFalse;
21158692172297647753b19567a180d52a6415193e3ddirk    }
21168692172297647753b19567a180d52a6415193e3ddirk  }
21178692172297647753b19567a180d52a6415193e3ddirk
2118ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(SkipDXTMipmaps(image,dds_info,16,exception));
21198692172297647753b19567a180d52a6415193e3ddirk}
21208692172297647753b19567a180d52a6415193e3ddirk
21218692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ReadUncompressedRGB(Image *image, DDSInfo *dds_info,
21228692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
21238692172297647753b19567a180d52a6415193e3ddirk{
21248692172297647753b19567a180d52a6415193e3ddirk  register Quantum
21258692172297647753b19567a180d52a6415193e3ddirk    *q;
21268692172297647753b19567a180d52a6415193e3ddirk
21278692172297647753b19567a180d52a6415193e3ddirk  ssize_t
21288692172297647753b19567a180d52a6415193e3ddirk    x, y;
21298692172297647753b19567a180d52a6415193e3ddirk
21308692172297647753b19567a180d52a6415193e3ddirk  unsigned short
21318692172297647753b19567a180d52a6415193e3ddirk    color;
21328692172297647753b19567a180d52a6415193e3ddirk
21336398fb41b2fa07b3234f02c533844504ede388dfdirk  if (dds_info->pixelformat.rgb_bitcount == 8)
21346398fb41b2fa07b3234f02c533844504ede388dfdirk    (void) SetImageType(image,GrayscaleType,exception);
21356398fb41b2fa07b3234f02c533844504ede388dfdirk  else if (dds_info->pixelformat.rgb_bitcount == 16 && !IsBitMask(
21368692172297647753b19567a180d52a6415193e3ddirk    dds_info->pixelformat,0xf800,0x07e0,0x001f,0x0000))
21378692172297647753b19567a180d52a6415193e3ddirk    ThrowBinaryException(CorruptImageError,"ImageTypeNotSupported",
21388692172297647753b19567a180d52a6415193e3ddirk      image->filename);
21398692172297647753b19567a180d52a6415193e3ddirk
21408692172297647753b19567a180d52a6415193e3ddirk  for (y = 0; y < (ssize_t) dds_info->height; y++)
21418692172297647753b19567a180d52a6415193e3ddirk  {
21428692172297647753b19567a180d52a6415193e3ddirk    q = QueueAuthenticPixels(image, 0, y, dds_info->width, 1,exception);
21438692172297647753b19567a180d52a6415193e3ddirk
21448692172297647753b19567a180d52a6415193e3ddirk    if (q == (Quantum *) NULL)
21458692172297647753b19567a180d52a6415193e3ddirk      return MagickFalse;
21468692172297647753b19567a180d52a6415193e3ddirk
21478692172297647753b19567a180d52a6415193e3ddirk    for (x = 0; x < (ssize_t) dds_info->width; x++)
21488692172297647753b19567a180d52a6415193e3ddirk    {
21496398fb41b2fa07b3234f02c533844504ede388dfdirk      if (dds_info->pixelformat.rgb_bitcount == 8)
21506398fb41b2fa07b3234f02c533844504ede388dfdirk        SetPixelGray(image,ScaleCharToQuantum(ReadBlobByte(image)),q);
21516398fb41b2fa07b3234f02c533844504ede388dfdirk      else if (dds_info->pixelformat.rgb_bitcount == 16)
21528692172297647753b19567a180d52a6415193e3ddirk        {
21538692172297647753b19567a180d52a6415193e3ddirk           color=ReadBlobShort(image);
21548692172297647753b19567a180d52a6415193e3ddirk           SetPixelRed(image,ScaleCharToQuantum((unsigned char)
21558692172297647753b19567a180d52a6415193e3ddirk             (((color >> 11)/31.0)*255)),q);
21568692172297647753b19567a180d52a6415193e3ddirk           SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
21578692172297647753b19567a180d52a6415193e3ddirk             ((((unsigned short)(color << 5) >> 10)/63.0)*255)),q);
21588692172297647753b19567a180d52a6415193e3ddirk           SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
21598692172297647753b19567a180d52a6415193e3ddirk             ((((unsigned short)(color << 11) >> 11)/31.0)*255)),q);
21608692172297647753b19567a180d52a6415193e3ddirk        }
21618692172297647753b19567a180d52a6415193e3ddirk      else
21628692172297647753b19567a180d52a6415193e3ddirk        {
21638692172297647753b19567a180d52a6415193e3ddirk          SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
21648692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
21658692172297647753b19567a180d52a6415193e3ddirk          SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
21668692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
21678692172297647753b19567a180d52a6415193e3ddirk          SetPixelRed(image,ScaleCharToQuantum((unsigned char)
21688692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
21698692172297647753b19567a180d52a6415193e3ddirk          if (dds_info->pixelformat.rgb_bitcount == 32)
21708692172297647753b19567a180d52a6415193e3ddirk            (void) ReadBlobByte(image);
21718692172297647753b19567a180d52a6415193e3ddirk        }
21728692172297647753b19567a180d52a6415193e3ddirk      q+=GetPixelChannels(image);
21738692172297647753b19567a180d52a6415193e3ddirk    }
21748692172297647753b19567a180d52a6415193e3ddirk
21758692172297647753b19567a180d52a6415193e3ddirk    if (SyncAuthenticPixels(image,exception) == MagickFalse)
21768692172297647753b19567a180d52a6415193e3ddirk      return MagickFalse;
21778692172297647753b19567a180d52a6415193e3ddirk  }
21788692172297647753b19567a180d52a6415193e3ddirk
2179ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(SkipRGBMipmaps(image,dds_info,3,exception));
21808692172297647753b19567a180d52a6415193e3ddirk}
21818692172297647753b19567a180d52a6415193e3ddirk
21828692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType ReadUncompressedRGBA(Image *image, DDSInfo *dds_info,
21838692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
21848692172297647753b19567a180d52a6415193e3ddirk{
21858692172297647753b19567a180d52a6415193e3ddirk  register Quantum
21868692172297647753b19567a180d52a6415193e3ddirk    *q;
21878692172297647753b19567a180d52a6415193e3ddirk
21888692172297647753b19567a180d52a6415193e3ddirk  ssize_t
21898692172297647753b19567a180d52a6415193e3ddirk    alphaBits,
21908692172297647753b19567a180d52a6415193e3ddirk    x,
21918692172297647753b19567a180d52a6415193e3ddirk    y;
21928692172297647753b19567a180d52a6415193e3ddirk
21938692172297647753b19567a180d52a6415193e3ddirk  unsigned short
21948692172297647753b19567a180d52a6415193e3ddirk    color;
21958692172297647753b19567a180d52a6415193e3ddirk
21968692172297647753b19567a180d52a6415193e3ddirk  alphaBits=0;
21978692172297647753b19567a180d52a6415193e3ddirk  if (dds_info->pixelformat.rgb_bitcount == 16)
21988692172297647753b19567a180d52a6415193e3ddirk    {
21998692172297647753b19567a180d52a6415193e3ddirk      if (IsBitMask(dds_info->pixelformat,0x7c00,0x03e0,0x001f,0x8000))
22008692172297647753b19567a180d52a6415193e3ddirk        alphaBits=1;
22016398fb41b2fa07b3234f02c533844504ede388dfdirk      else if (IsBitMask(dds_info->pixelformat,0x00ff,0x00ff,0x00ff,0xff00))
22026398fb41b2fa07b3234f02c533844504ede388dfdirk        {
22036398fb41b2fa07b3234f02c533844504ede388dfdirk          alphaBits=2;
2204def23e5d7331b1a13ed593b6d6aca516da382328cristy          (void) SetImageType(image,GrayscaleAlphaType,exception);
22056398fb41b2fa07b3234f02c533844504ede388dfdirk        }
22068692172297647753b19567a180d52a6415193e3ddirk      else if (IsBitMask(dds_info->pixelformat,0x0f00,0x00f0,0x000f,0xf000))
22078692172297647753b19567a180d52a6415193e3ddirk        alphaBits=4;
22088692172297647753b19567a180d52a6415193e3ddirk      else
22098692172297647753b19567a180d52a6415193e3ddirk        ThrowBinaryException(CorruptImageError,"ImageTypeNotSupported",
22108692172297647753b19567a180d52a6415193e3ddirk          image->filename);
22118692172297647753b19567a180d52a6415193e3ddirk    }
22128692172297647753b19567a180d52a6415193e3ddirk
22138692172297647753b19567a180d52a6415193e3ddirk  for (y = 0; y < (ssize_t) dds_info->height; y++)
22148692172297647753b19567a180d52a6415193e3ddirk  {
22158692172297647753b19567a180d52a6415193e3ddirk    q = QueueAuthenticPixels(image, 0, y, dds_info->width, 1,exception);
22168692172297647753b19567a180d52a6415193e3ddirk
22178692172297647753b19567a180d52a6415193e3ddirk    if (q == (Quantum *) NULL)
22188692172297647753b19567a180d52a6415193e3ddirk      return MagickFalse;
22198692172297647753b19567a180d52a6415193e3ddirk
22208692172297647753b19567a180d52a6415193e3ddirk    for (x = 0; x < (ssize_t) dds_info->width; x++)
22218692172297647753b19567a180d52a6415193e3ddirk    {
22228692172297647753b19567a180d52a6415193e3ddirk      if (dds_info->pixelformat.rgb_bitcount == 16)
22238692172297647753b19567a180d52a6415193e3ddirk        {
22248692172297647753b19567a180d52a6415193e3ddirk           color=ReadBlobShort(image);
22258692172297647753b19567a180d52a6415193e3ddirk           if (alphaBits == 1)
22268692172297647753b19567a180d52a6415193e3ddirk             {
22278692172297647753b19567a180d52a6415193e3ddirk               SetPixelAlpha(image,(color & (1 << 15)) ? QuantumRange : 0,q);
22288692172297647753b19567a180d52a6415193e3ddirk               SetPixelRed(image,ScaleCharToQuantum((unsigned char)
22298692172297647753b19567a180d52a6415193e3ddirk                 ((((unsigned short)(color << 1) >> 11)/31.0)*255)),q);
22308692172297647753b19567a180d52a6415193e3ddirk               SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
22318692172297647753b19567a180d52a6415193e3ddirk                 ((((unsigned short)(color << 6) >> 11)/31.0)*255)),q);
22328692172297647753b19567a180d52a6415193e3ddirk               SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
22338692172297647753b19567a180d52a6415193e3ddirk                 ((((unsigned short)(color << 11) >> 11)/31.0)*255)),q);
22348692172297647753b19567a180d52a6415193e3ddirk             }
22356398fb41b2fa07b3234f02c533844504ede388dfdirk          else if (alphaBits == 2)
22366398fb41b2fa07b3234f02c533844504ede388dfdirk            {
22376398fb41b2fa07b3234f02c533844504ede388dfdirk               SetPixelAlpha(image,ScaleCharToQuantum((unsigned char)
22386398fb41b2fa07b3234f02c533844504ede388dfdirk                 (color >> 8)),q);
22396398fb41b2fa07b3234f02c533844504ede388dfdirk               SetPixelGray(image,ScaleCharToQuantum((unsigned char)color),q);
22406398fb41b2fa07b3234f02c533844504ede388dfdirk            }
22418692172297647753b19567a180d52a6415193e3ddirk          else
22428692172297647753b19567a180d52a6415193e3ddirk            {
22438692172297647753b19567a180d52a6415193e3ddirk               SetPixelAlpha(image,ScaleCharToQuantum((unsigned char)
22448692172297647753b19567a180d52a6415193e3ddirk                 (((color >> 12)/15.0)*255)),q);
22458692172297647753b19567a180d52a6415193e3ddirk               SetPixelRed(image,ScaleCharToQuantum((unsigned char)
22468692172297647753b19567a180d52a6415193e3ddirk                 ((((unsigned short)(color << 4) >> 12)/15.0)*255)),q);
22478692172297647753b19567a180d52a6415193e3ddirk               SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
22488692172297647753b19567a180d52a6415193e3ddirk                 ((((unsigned short)(color << 8) >> 12)/15.0)*255)),q);
22498692172297647753b19567a180d52a6415193e3ddirk               SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
22508692172297647753b19567a180d52a6415193e3ddirk                 ((((unsigned short)(color << 12) >> 12)/15.0)*255)),q);
22518692172297647753b19567a180d52a6415193e3ddirk            }
22528692172297647753b19567a180d52a6415193e3ddirk        }
22538692172297647753b19567a180d52a6415193e3ddirk      else
22548692172297647753b19567a180d52a6415193e3ddirk        {
22558692172297647753b19567a180d52a6415193e3ddirk          SetPixelBlue(image,ScaleCharToQuantum((unsigned char)
22568692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
22578692172297647753b19567a180d52a6415193e3ddirk          SetPixelGreen(image,ScaleCharToQuantum((unsigned char)
22588692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
22598692172297647753b19567a180d52a6415193e3ddirk          SetPixelRed(image,ScaleCharToQuantum((unsigned char)
22608692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
22618692172297647753b19567a180d52a6415193e3ddirk          SetPixelAlpha(image,ScaleCharToQuantum((unsigned char)
22628692172297647753b19567a180d52a6415193e3ddirk            ReadBlobByte(image)),q);
22638692172297647753b19567a180d52a6415193e3ddirk        }
22648692172297647753b19567a180d52a6415193e3ddirk      q+=GetPixelChannels(image);
22658692172297647753b19567a180d52a6415193e3ddirk    }
22668692172297647753b19567a180d52a6415193e3ddirk
22678692172297647753b19567a180d52a6415193e3ddirk    if (SyncAuthenticPixels(image,exception) == MagickFalse)
22688692172297647753b19567a180d52a6415193e3ddirk      return MagickFalse;
22698692172297647753b19567a180d52a6415193e3ddirk  }
22708692172297647753b19567a180d52a6415193e3ddirk
2271ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(SkipRGBMipmaps(image,dds_info,4,exception));
22728692172297647753b19567a180d52a6415193e3ddirk}
22738692172297647753b19567a180d52a6415193e3ddirk
22748692172297647753b19567a180d52a6415193e3ddirk/*
22758692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22768692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
22778692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
22788692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
22798692172297647753b19567a180d52a6415193e3ddirk%   R e g i s t e r D D S I m a g e                                           %
22808692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
22818692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
22828692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
22838692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22848692172297647753b19567a180d52a6415193e3ddirk%
22858692172297647753b19567a180d52a6415193e3ddirk%  RegisterDDSImage() adds attributes for the DDS image format to
22868692172297647753b19567a180d52a6415193e3ddirk%  the list of supported formats.  The attributes include the image format
22878692172297647753b19567a180d52a6415193e3ddirk%  tag, a method to read and/or write the format, whether the format
22888692172297647753b19567a180d52a6415193e3ddirk%  supports the saving of more than one frame to the same file or blob,
22898692172297647753b19567a180d52a6415193e3ddirk%  whether the format supports native in-memory I/O, and a brief
22908692172297647753b19567a180d52a6415193e3ddirk%  description of the format.
22918692172297647753b19567a180d52a6415193e3ddirk%
22928692172297647753b19567a180d52a6415193e3ddirk%  The format of the RegisterDDSImage method is:
22938692172297647753b19567a180d52a6415193e3ddirk%
22948692172297647753b19567a180d52a6415193e3ddirk%      RegisterDDSImage(void)
22958692172297647753b19567a180d52a6415193e3ddirk%
22968692172297647753b19567a180d52a6415193e3ddirk*/
22978692172297647753b19567a180d52a6415193e3ddirkModuleExport size_t RegisterDDSImage(void)
22988692172297647753b19567a180d52a6415193e3ddirk{
22998692172297647753b19567a180d52a6415193e3ddirk  MagickInfo
23008692172297647753b19567a180d52a6415193e3ddirk    *entry;
23018692172297647753b19567a180d52a6415193e3ddirk
230206b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry = AcquireMagickInfo("DDS","DDS","Microsoft DirectDraw Surface");
23038692172297647753b19567a180d52a6415193e3ddirk  entry->decoder = (DecodeImageHandler *) ReadDDSImage;
23048692172297647753b19567a180d52a6415193e3ddirk  entry->encoder = (EncodeImageHandler *) WriteDDSImage;
23058692172297647753b19567a180d52a6415193e3ddirk  entry->magick = (IsImageFormatHandler *) IsDDS;
230608e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags|=CoderSeekableStreamFlag;
23078692172297647753b19567a180d52a6415193e3ddirk  (void) RegisterMagickInfo(entry);
230806b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry = AcquireMagickInfo("DDS","DXT1","Microsoft DirectDraw Surface");
23098692172297647753b19567a180d52a6415193e3ddirk  entry->decoder = (DecodeImageHandler *) ReadDDSImage;
23108692172297647753b19567a180d52a6415193e3ddirk  entry->encoder = (EncodeImageHandler *) WriteDDSImage;
23118692172297647753b19567a180d52a6415193e3ddirk  entry->magick = (IsImageFormatHandler *) IsDDS;
231208e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags|=CoderSeekableStreamFlag;
23138692172297647753b19567a180d52a6415193e3ddirk  (void) RegisterMagickInfo(entry);
231406b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry = AcquireMagickInfo("DDS","DXT5","Microsoft DirectDraw Surface");
23158692172297647753b19567a180d52a6415193e3ddirk  entry->decoder = (DecodeImageHandler *) ReadDDSImage;
23168692172297647753b19567a180d52a6415193e3ddirk  entry->encoder = (EncodeImageHandler *) WriteDDSImage;
23178692172297647753b19567a180d52a6415193e3ddirk  entry->magick = (IsImageFormatHandler *) IsDDS;
231808e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags|=CoderSeekableStreamFlag;
23198692172297647753b19567a180d52a6415193e3ddirk  (void) RegisterMagickInfo(entry);
23208692172297647753b19567a180d52a6415193e3ddirk  return(MagickImageCoderSignature);
23218692172297647753b19567a180d52a6415193e3ddirk}
23228692172297647753b19567a180d52a6415193e3ddirk
23238692172297647753b19567a180d52a6415193e3ddirkstatic void RemapIndices(const ssize_t *map, const unsigned char *source,
23248692172297647753b19567a180d52a6415193e3ddirk  unsigned char *target)
23258692172297647753b19567a180d52a6415193e3ddirk{
23268692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
23278692172297647753b19567a180d52a6415193e3ddirk    i;
23288692172297647753b19567a180d52a6415193e3ddirk
23298692172297647753b19567a180d52a6415193e3ddirk  for (i = 0; i < 16; i++)
23308692172297647753b19567a180d52a6415193e3ddirk  {
23318692172297647753b19567a180d52a6415193e3ddirk    if (map[i] == -1)
23328692172297647753b19567a180d52a6415193e3ddirk      target[i] = 3;
23338692172297647753b19567a180d52a6415193e3ddirk    else
23348692172297647753b19567a180d52a6415193e3ddirk      target[i] = source[map[i]];
23358692172297647753b19567a180d52a6415193e3ddirk  }
23368692172297647753b19567a180d52a6415193e3ddirk}
23378692172297647753b19567a180d52a6415193e3ddirk
23388692172297647753b19567a180d52a6415193e3ddirk/*
23398692172297647753b19567a180d52a6415193e3ddirk  Skip the mipmap images for compressed (DXTn) dds files
23408692172297647753b19567a180d52a6415193e3ddirk*/
2341ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirkstatic MagickBooleanType SkipDXTMipmaps(Image *image,DDSInfo *dds_info,
2342ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  int texel_size,ExceptionInfo *exception)
23438692172297647753b19567a180d52a6415193e3ddirk{
23448692172297647753b19567a180d52a6415193e3ddirk  MagickOffsetType
23458692172297647753b19567a180d52a6415193e3ddirk    offset;
23468692172297647753b19567a180d52a6415193e3ddirk
23478692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
23488692172297647753b19567a180d52a6415193e3ddirk    i;
23498692172297647753b19567a180d52a6415193e3ddirk
23508692172297647753b19567a180d52a6415193e3ddirk  size_t
23518692172297647753b19567a180d52a6415193e3ddirk    h,
23528692172297647753b19567a180d52a6415193e3ddirk    w;
23538692172297647753b19567a180d52a6415193e3ddirk
23548692172297647753b19567a180d52a6415193e3ddirk  /*
23558692172297647753b19567a180d52a6415193e3ddirk    Only skip mipmaps for textures and cube maps
23568692172297647753b19567a180d52a6415193e3ddirk  */
23578e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk  if (EOFBlob(image) != MagickFalse)
23588e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk    {
2359791aa82c8064ee8965a63ccf4384f56b95057e5bdirk      ThrowFileException(exception,CorruptImageWarning,"UnexpectedEndOfFile",
23608e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk        image->filename);
23618e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk      return(MagickFalse);
23628e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk    }
23638692172297647753b19567a180d52a6415193e3ddirk  if (dds_info->ddscaps1 & DDSCAPS_MIPMAP
23648692172297647753b19567a180d52a6415193e3ddirk      && (dds_info->ddscaps1 & DDSCAPS_TEXTURE
23658692172297647753b19567a180d52a6415193e3ddirk          || dds_info->ddscaps2 & DDSCAPS2_CUBEMAP))
23668692172297647753b19567a180d52a6415193e3ddirk    {
23678692172297647753b19567a180d52a6415193e3ddirk      w = DIV2(dds_info->width);
23688692172297647753b19567a180d52a6415193e3ddirk      h = DIV2(dds_info->height);
23698692172297647753b19567a180d52a6415193e3ddirk
23708692172297647753b19567a180d52a6415193e3ddirk      /*
23718692172297647753b19567a180d52a6415193e3ddirk        Mipmapcount includes the main image, so start from one
23728692172297647753b19567a180d52a6415193e3ddirk      */
23738692172297647753b19567a180d52a6415193e3ddirk      for (i = 1; (i < (ssize_t) dds_info->mipmapcount) && w && h; i++)
23748692172297647753b19567a180d52a6415193e3ddirk      {
23758692172297647753b19567a180d52a6415193e3ddirk        offset = (MagickOffsetType) ((w + 3) / 4) * ((h + 3) / 4) * texel_size;
2376cc2a4d2ba5371d25c58763e4db2dbc1f4691c0f7cristy        if (SeekBlob(image, offset, SEEK_CUR) < 0)
2377cc2a4d2ba5371d25c58763e4db2dbc1f4691c0f7cristy          break;
23788692172297647753b19567a180d52a6415193e3ddirk        w = DIV2(w);
23798692172297647753b19567a180d52a6415193e3ddirk        h = DIV2(h);
23808692172297647753b19567a180d52a6415193e3ddirk      }
23818692172297647753b19567a180d52a6415193e3ddirk    }
2382ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(MagickTrue);
23838692172297647753b19567a180d52a6415193e3ddirk}
23848692172297647753b19567a180d52a6415193e3ddirk
23858692172297647753b19567a180d52a6415193e3ddirk/*
23868692172297647753b19567a180d52a6415193e3ddirk  Skip the mipmap images for uncompressed (RGB or RGBA) dds files
23878692172297647753b19567a180d52a6415193e3ddirk*/
2388ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirkstatic MagickBooleanType SkipRGBMipmaps(Image *image,DDSInfo *dds_info,
2389ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  int pixel_size,ExceptionInfo *exception)
23908692172297647753b19567a180d52a6415193e3ddirk{
23918692172297647753b19567a180d52a6415193e3ddirk  MagickOffsetType
23928692172297647753b19567a180d52a6415193e3ddirk    offset;
23938692172297647753b19567a180d52a6415193e3ddirk
23948692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
23958692172297647753b19567a180d52a6415193e3ddirk    i;
23968692172297647753b19567a180d52a6415193e3ddirk
23978692172297647753b19567a180d52a6415193e3ddirk  size_t
23988692172297647753b19567a180d52a6415193e3ddirk    h,
23998692172297647753b19567a180d52a6415193e3ddirk    w;
24008692172297647753b19567a180d52a6415193e3ddirk
24018692172297647753b19567a180d52a6415193e3ddirk  /*
24028692172297647753b19567a180d52a6415193e3ddirk    Only skip mipmaps for textures and cube maps
24038692172297647753b19567a180d52a6415193e3ddirk  */
24048e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk  if (EOFBlob(image) != MagickFalse)
24058e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk    {
24068e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk      ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
24078e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk        image->filename);
24088e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk      return(MagickFalse);
24098e2b7d0d8ee0bf88fdba57059fcb87aef8f23c06dirk    }
24108692172297647753b19567a180d52a6415193e3ddirk  if (dds_info->ddscaps1 & DDSCAPS_MIPMAP
24118692172297647753b19567a180d52a6415193e3ddirk      && (dds_info->ddscaps1 & DDSCAPS_TEXTURE
24128692172297647753b19567a180d52a6415193e3ddirk          || dds_info->ddscaps2 & DDSCAPS2_CUBEMAP))
24138692172297647753b19567a180d52a6415193e3ddirk    {
24148692172297647753b19567a180d52a6415193e3ddirk      w = DIV2(dds_info->width);
24158692172297647753b19567a180d52a6415193e3ddirk      h = DIV2(dds_info->height);
24168692172297647753b19567a180d52a6415193e3ddirk
24178692172297647753b19567a180d52a6415193e3ddirk      /*
24188692172297647753b19567a180d52a6415193e3ddirk        Mipmapcount includes the main image, so start from one
24198692172297647753b19567a180d52a6415193e3ddirk      */
24208692172297647753b19567a180d52a6415193e3ddirk      for (i=1; (i < (ssize_t) dds_info->mipmapcount) && w && h; i++)
24218692172297647753b19567a180d52a6415193e3ddirk      {
24228692172297647753b19567a180d52a6415193e3ddirk        offset = (MagickOffsetType) w * h * pixel_size;
2423cc2a4d2ba5371d25c58763e4db2dbc1f4691c0f7cristy        if (SeekBlob(image, offset, SEEK_CUR) < 0)
2424cc2a4d2ba5371d25c58763e4db2dbc1f4691c0f7cristy          break;
24258692172297647753b19567a180d52a6415193e3ddirk        w = DIV2(w);
24268692172297647753b19567a180d52a6415193e3ddirk        h = DIV2(h);
24278692172297647753b19567a180d52a6415193e3ddirk      }
24288692172297647753b19567a180d52a6415193e3ddirk    }
2429ee6b4cb86fe4b5c2aabb40f50905be6bb04c5f56dirk  return(MagickTrue);
24308692172297647753b19567a180d52a6415193e3ddirk}
24318692172297647753b19567a180d52a6415193e3ddirk
24328692172297647753b19567a180d52a6415193e3ddirk/*
24338692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24348692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
24358692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
24368692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
24378692172297647753b19567a180d52a6415193e3ddirk%   U n r e g i s t e r D D S I m a g e                                       %
24388692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
24398692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
24408692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
24418692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24428692172297647753b19567a180d52a6415193e3ddirk%
24438692172297647753b19567a180d52a6415193e3ddirk%  UnregisterDDSImage() removes format registrations made by the
24448692172297647753b19567a180d52a6415193e3ddirk%  DDS module from the list of supported formats.
24458692172297647753b19567a180d52a6415193e3ddirk%
24468692172297647753b19567a180d52a6415193e3ddirk%  The format of the UnregisterDDSImage method is:
24478692172297647753b19567a180d52a6415193e3ddirk%
24488692172297647753b19567a180d52a6415193e3ddirk%      UnregisterDDSImage(void)
24498692172297647753b19567a180d52a6415193e3ddirk%
24508692172297647753b19567a180d52a6415193e3ddirk*/
24518692172297647753b19567a180d52a6415193e3ddirkModuleExport void UnregisterDDSImage(void)
24528692172297647753b19567a180d52a6415193e3ddirk{
24538692172297647753b19567a180d52a6415193e3ddirk  (void) UnregisterMagickInfo("DDS");
24548692172297647753b19567a180d52a6415193e3ddirk  (void) UnregisterMagickInfo("DXT1");
24558692172297647753b19567a180d52a6415193e3ddirk  (void) UnregisterMagickInfo("DXT5");
24568692172297647753b19567a180d52a6415193e3ddirk}
24578692172297647753b19567a180d52a6415193e3ddirk
24588692172297647753b19567a180d52a6415193e3ddirkstatic void WriteAlphas(Image *image, const ssize_t *alphas, size_t min5,
24598692172297647753b19567a180d52a6415193e3ddirk  size_t max5, size_t min7, size_t max7)
24608692172297647753b19567a180d52a6415193e3ddirk{
24618692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
24628692172297647753b19567a180d52a6415193e3ddirk    i;
24638692172297647753b19567a180d52a6415193e3ddirk
24648692172297647753b19567a180d52a6415193e3ddirk  size_t
24658692172297647753b19567a180d52a6415193e3ddirk    err5,
24668692172297647753b19567a180d52a6415193e3ddirk    err7,
24678692172297647753b19567a180d52a6415193e3ddirk    j;
24688692172297647753b19567a180d52a6415193e3ddirk
24698692172297647753b19567a180d52a6415193e3ddirk  unsigned char
24708692172297647753b19567a180d52a6415193e3ddirk    indices5[16],
24718692172297647753b19567a180d52a6415193e3ddirk    indices7[16];
24728692172297647753b19567a180d52a6415193e3ddirk
24738692172297647753b19567a180d52a6415193e3ddirk  FixRange(min5,max5,5);
24748692172297647753b19567a180d52a6415193e3ddirk  err5 = CompressAlpha(min5,max5,5,alphas,indices5);
24758692172297647753b19567a180d52a6415193e3ddirk
24768692172297647753b19567a180d52a6415193e3ddirk  FixRange(min7,max7,7);
24778692172297647753b19567a180d52a6415193e3ddirk  err7 = CompressAlpha(min7,max7,7,alphas,indices7);
24788692172297647753b19567a180d52a6415193e3ddirk
24798692172297647753b19567a180d52a6415193e3ddirk  if (err7 < err5)
24808692172297647753b19567a180d52a6415193e3ddirk  {
24818692172297647753b19567a180d52a6415193e3ddirk    for (i=0; i < 16; i++)
24828692172297647753b19567a180d52a6415193e3ddirk    {
24838692172297647753b19567a180d52a6415193e3ddirk      unsigned char
24848692172297647753b19567a180d52a6415193e3ddirk        index;
24858692172297647753b19567a180d52a6415193e3ddirk
24868692172297647753b19567a180d52a6415193e3ddirk      index = indices7[i];
24878692172297647753b19567a180d52a6415193e3ddirk      if( index == 0 )
24888692172297647753b19567a180d52a6415193e3ddirk        indices5[i] = 1;
24898692172297647753b19567a180d52a6415193e3ddirk      else if (index == 1)
24908692172297647753b19567a180d52a6415193e3ddirk        indices5[i] = 0;
24918692172297647753b19567a180d52a6415193e3ddirk      else
24928692172297647753b19567a180d52a6415193e3ddirk        indices5[i] = 9 - index;
24938692172297647753b19567a180d52a6415193e3ddirk    }
24948692172297647753b19567a180d52a6415193e3ddirk
24958692172297647753b19567a180d52a6415193e3ddirk    min5 = max7;
24968692172297647753b19567a180d52a6415193e3ddirk    max5 = min7;
24978692172297647753b19567a180d52a6415193e3ddirk  }
24988692172297647753b19567a180d52a6415193e3ddirk
24998692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobByte(image,(unsigned char) min5);
25008692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobByte(image,(unsigned char) max5);
25018692172297647753b19567a180d52a6415193e3ddirk
25028692172297647753b19567a180d52a6415193e3ddirk  for(i=0; i < 2; i++)
25038692172297647753b19567a180d52a6415193e3ddirk  {
25048692172297647753b19567a180d52a6415193e3ddirk    size_t
25058692172297647753b19567a180d52a6415193e3ddirk      value = 0;
25068692172297647753b19567a180d52a6415193e3ddirk
25078692172297647753b19567a180d52a6415193e3ddirk    for (j=0; j < 8; j++)
25088692172297647753b19567a180d52a6415193e3ddirk    {
25098692172297647753b19567a180d52a6415193e3ddirk      size_t index = (size_t) indices5[j + i*8];
25108692172297647753b19567a180d52a6415193e3ddirk      value |= ( index << 3*j );
25118692172297647753b19567a180d52a6415193e3ddirk    }
25128692172297647753b19567a180d52a6415193e3ddirk
25138692172297647753b19567a180d52a6415193e3ddirk    for (j=0; j < 3; j++)
25148692172297647753b19567a180d52a6415193e3ddirk    {
25158692172297647753b19567a180d52a6415193e3ddirk      size_t byte = (value >> 8*j) & 0xff;
25168692172297647753b19567a180d52a6415193e3ddirk      (void) WriteBlobByte(image,(unsigned char) byte);
25178692172297647753b19567a180d52a6415193e3ddirk    }
25188692172297647753b19567a180d52a6415193e3ddirk  }
25198692172297647753b19567a180d52a6415193e3ddirk}
25208692172297647753b19567a180d52a6415193e3ddirk
25218692172297647753b19567a180d52a6415193e3ddirkstatic void WriteCompressed(Image *image, const size_t count,
25228692172297647753b19567a180d52a6415193e3ddirk  DDSVector4 *points, const ssize_t *map, const MagickBooleanType clusterFit)
25238692172297647753b19567a180d52a6415193e3ddirk{
25248692172297647753b19567a180d52a6415193e3ddirk  float
25258692172297647753b19567a180d52a6415193e3ddirk    covariance[16];
25268692172297647753b19567a180d52a6415193e3ddirk
25278692172297647753b19567a180d52a6415193e3ddirk  DDSVector3
25288692172297647753b19567a180d52a6415193e3ddirk    end,
25298692172297647753b19567a180d52a6415193e3ddirk    principle,
25308692172297647753b19567a180d52a6415193e3ddirk    start;
25318692172297647753b19567a180d52a6415193e3ddirk
25328692172297647753b19567a180d52a6415193e3ddirk  DDSVector4
25338692172297647753b19567a180d52a6415193e3ddirk    metric;
25348692172297647753b19567a180d52a6415193e3ddirk
25358692172297647753b19567a180d52a6415193e3ddirk  unsigned char
25368692172297647753b19567a180d52a6415193e3ddirk    indices[16];
25378692172297647753b19567a180d52a6415193e3ddirk
25388692172297647753b19567a180d52a6415193e3ddirk  VectorInit(metric,1.0f);
25398692172297647753b19567a180d52a6415193e3ddirk  VectorInit3(start,0.0f);
25408692172297647753b19567a180d52a6415193e3ddirk  VectorInit3(end,0.0f);
25418692172297647753b19567a180d52a6415193e3ddirk
25428692172297647753b19567a180d52a6415193e3ddirk  ComputeWeightedCovariance(count,points,covariance);
25438692172297647753b19567a180d52a6415193e3ddirk  ComputePrincipleComponent(covariance,&principle);
25448692172297647753b19567a180d52a6415193e3ddirk
2545771c884804218f352efd091f15328cebd1696079cristy  if ((clusterFit == MagickFalse) || (count == 0))
25468692172297647753b19567a180d52a6415193e3ddirk    CompressRangeFit(count,points,map,principle,metric,&start,&end,indices);
25478692172297647753b19567a180d52a6415193e3ddirk  else
25488692172297647753b19567a180d52a6415193e3ddirk    CompressClusterFit(count,points,map,principle,metric,&start,&end,indices);
25498692172297647753b19567a180d52a6415193e3ddirk
25508692172297647753b19567a180d52a6415193e3ddirk  WriteIndices(image,start,end,indices);
25518692172297647753b19567a180d52a6415193e3ddirk}
25528692172297647753b19567a180d52a6415193e3ddirk
25538692172297647753b19567a180d52a6415193e3ddirk/*
25548692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25558692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
25568692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
25578692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
25588692172297647753b19567a180d52a6415193e3ddirk%   W r i t e D D S I m a g e                                                 %
25598692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
25608692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
25618692172297647753b19567a180d52a6415193e3ddirk%                                                                             %
25628692172297647753b19567a180d52a6415193e3ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25638692172297647753b19567a180d52a6415193e3ddirk%
25648692172297647753b19567a180d52a6415193e3ddirk%  WriteDDSImage() writes a DirectDraw Surface image file in the DXT5 format.
25658692172297647753b19567a180d52a6415193e3ddirk%
25668692172297647753b19567a180d52a6415193e3ddirk%  The format of the WriteBMPImage method is:
25678692172297647753b19567a180d52a6415193e3ddirk%
25688692172297647753b19567a180d52a6415193e3ddirk%     MagickBooleanType WriteDDSImage(const ImageInfo *image_info,Image *image)
25698692172297647753b19567a180d52a6415193e3ddirk%
25708692172297647753b19567a180d52a6415193e3ddirk%  A description of each parameter follows.
25718692172297647753b19567a180d52a6415193e3ddirk%
25728692172297647753b19567a180d52a6415193e3ddirk%    o image_info: the image info.
25738692172297647753b19567a180d52a6415193e3ddirk%
25748692172297647753b19567a180d52a6415193e3ddirk%    o image:  The image.
25758692172297647753b19567a180d52a6415193e3ddirk%
25768692172297647753b19567a180d52a6415193e3ddirk*/
25778692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType WriteDDSImage(const ImageInfo *image_info,
25788692172297647753b19567a180d52a6415193e3ddirk  Image *image, ExceptionInfo *exception)
25798692172297647753b19567a180d52a6415193e3ddirk{
25808692172297647753b19567a180d52a6415193e3ddirk  const char
25818692172297647753b19567a180d52a6415193e3ddirk    *option;
25828692172297647753b19567a180d52a6415193e3ddirk
25838692172297647753b19567a180d52a6415193e3ddirk  size_t
25848692172297647753b19567a180d52a6415193e3ddirk    compression,
25858692172297647753b19567a180d52a6415193e3ddirk    columns,
25868692172297647753b19567a180d52a6415193e3ddirk    maxMipmaps,
25878692172297647753b19567a180d52a6415193e3ddirk    mipmaps,
25888692172297647753b19567a180d52a6415193e3ddirk    pixelFormat,
25898692172297647753b19567a180d52a6415193e3ddirk    rows;
25908692172297647753b19567a180d52a6415193e3ddirk
25918692172297647753b19567a180d52a6415193e3ddirk  MagickBooleanType
25928692172297647753b19567a180d52a6415193e3ddirk    clusterFit,
25938692172297647753b19567a180d52a6415193e3ddirk    status,
25948692172297647753b19567a180d52a6415193e3ddirk    weightByAlpha;
25958692172297647753b19567a180d52a6415193e3ddirk
25968692172297647753b19567a180d52a6415193e3ddirk  assert(image_info != (const ImageInfo *) NULL);
2597e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
25988692172297647753b19567a180d52a6415193e3ddirk  assert(image != (Image *) NULL);
2599e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
26008692172297647753b19567a180d52a6415193e3ddirk  if (image->debug != MagickFalse)
26018692172297647753b19567a180d52a6415193e3ddirk    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
26028692172297647753b19567a180d52a6415193e3ddirk  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
26038692172297647753b19567a180d52a6415193e3ddirk  if (status == MagickFalse)
26048692172297647753b19567a180d52a6415193e3ddirk    return(status);
26058692172297647753b19567a180d52a6415193e3ddirk  (void) TransformImageColorspace(image,sRGBColorspace,exception);
26068692172297647753b19567a180d52a6415193e3ddirk  pixelFormat=DDPF_FOURCC;
26078692172297647753b19567a180d52a6415193e3ddirk  compression=FOURCC_DXT5;
26088692172297647753b19567a180d52a6415193e3ddirk
260917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  if (image->alpha_trait == UndefinedPixelTrait)
26108692172297647753b19567a180d52a6415193e3ddirk    compression=FOURCC_DXT1;
26118692172297647753b19567a180d52a6415193e3ddirk
26128692172297647753b19567a180d52a6415193e3ddirk  if (LocaleCompare(image_info->magick,"dxt1") == 0)
26138692172297647753b19567a180d52a6415193e3ddirk    compression=FOURCC_DXT1;
26148692172297647753b19567a180d52a6415193e3ddirk
26158692172297647753b19567a180d52a6415193e3ddirk  option=GetImageOption(image_info,"dds:compression");
26168692172297647753b19567a180d52a6415193e3ddirk  if (option != (char *) NULL)
26178692172297647753b19567a180d52a6415193e3ddirk    {
26188692172297647753b19567a180d52a6415193e3ddirk       if (LocaleCompare(option,"dxt1") == 0)
26198692172297647753b19567a180d52a6415193e3ddirk         compression=FOURCC_DXT1;
26208692172297647753b19567a180d52a6415193e3ddirk       if (LocaleCompare(option,"none") == 0)
26218692172297647753b19567a180d52a6415193e3ddirk         pixelFormat=DDPF_RGB;
26228692172297647753b19567a180d52a6415193e3ddirk    }
26238692172297647753b19567a180d52a6415193e3ddirk
26248692172297647753b19567a180d52a6415193e3ddirk  clusterFit=MagickFalse;
26258692172297647753b19567a180d52a6415193e3ddirk  weightByAlpha=MagickFalse;
26268692172297647753b19567a180d52a6415193e3ddirk
26278692172297647753b19567a180d52a6415193e3ddirk  if (pixelFormat == DDPF_FOURCC)
26288692172297647753b19567a180d52a6415193e3ddirk    {
26298692172297647753b19567a180d52a6415193e3ddirk      option=GetImageOption(image_info,"dds:cluster-fit");
2630cf97f6100e599b488fbe34390263c9688deebb54dirk      if (IsStringTrue(option) != MagickFalse)
26318692172297647753b19567a180d52a6415193e3ddirk        {
26328692172297647753b19567a180d52a6415193e3ddirk          clusterFit=MagickTrue;
26338692172297647753b19567a180d52a6415193e3ddirk          if (compression != FOURCC_DXT1)
26348692172297647753b19567a180d52a6415193e3ddirk            {
26358692172297647753b19567a180d52a6415193e3ddirk              option=GetImageOption(image_info,"dds:weight-by-alpha");
2636cf97f6100e599b488fbe34390263c9688deebb54dirk              if (IsStringTrue(option) != MagickFalse)
26378692172297647753b19567a180d52a6415193e3ddirk                weightByAlpha=MagickTrue;
26388692172297647753b19567a180d52a6415193e3ddirk            }
26398692172297647753b19567a180d52a6415193e3ddirk        }
26408692172297647753b19567a180d52a6415193e3ddirk    }
26418692172297647753b19567a180d52a6415193e3ddirk
26428692172297647753b19567a180d52a6415193e3ddirk  maxMipmaps=SIZE_MAX;
26438692172297647753b19567a180d52a6415193e3ddirk  mipmaps=0;
26448692172297647753b19567a180d52a6415193e3ddirk  if ((image->columns & (image->columns - 1)) == 0 &&
26458692172297647753b19567a180d52a6415193e3ddirk      (image->rows & (image->rows - 1)) == 0)
26468692172297647753b19567a180d52a6415193e3ddirk    {
26478692172297647753b19567a180d52a6415193e3ddirk      option=GetImageOption(image_info,"dds:mipmaps");
26488692172297647753b19567a180d52a6415193e3ddirk      if (option != (char *) NULL)
26498692172297647753b19567a180d52a6415193e3ddirk        maxMipmaps=StringToUnsignedLong(option);
26508692172297647753b19567a180d52a6415193e3ddirk
26518692172297647753b19567a180d52a6415193e3ddirk      if (maxMipmaps != 0)
26528692172297647753b19567a180d52a6415193e3ddirk        {
26538692172297647753b19567a180d52a6415193e3ddirk          columns=image->columns;
26548692172297647753b19567a180d52a6415193e3ddirk          rows=image->rows;
26558692172297647753b19567a180d52a6415193e3ddirk          while (columns != 1 && rows != 1 && mipmaps != maxMipmaps)
26568692172297647753b19567a180d52a6415193e3ddirk          {
26578692172297647753b19567a180d52a6415193e3ddirk            columns=DIV2(columns);
26588692172297647753b19567a180d52a6415193e3ddirk            rows=DIV2(rows);
26598692172297647753b19567a180d52a6415193e3ddirk            mipmaps++;
26608692172297647753b19567a180d52a6415193e3ddirk          }
26618692172297647753b19567a180d52a6415193e3ddirk        }
26628692172297647753b19567a180d52a6415193e3ddirk    }
26638692172297647753b19567a180d52a6415193e3ddirk
26648692172297647753b19567a180d52a6415193e3ddirk  WriteDDSInfo(image,pixelFormat,compression,mipmaps);
26658692172297647753b19567a180d52a6415193e3ddirk
26668692172297647753b19567a180d52a6415193e3ddirk  WriteImageData(image,pixelFormat,compression,clusterFit,weightByAlpha,
26678692172297647753b19567a180d52a6415193e3ddirk    exception);
26688692172297647753b19567a180d52a6415193e3ddirk
26698692172297647753b19567a180d52a6415193e3ddirk  if (mipmaps > 0 && WriteMipmaps(image,pixelFormat,compression,mipmaps,
26708692172297647753b19567a180d52a6415193e3ddirk        clusterFit,weightByAlpha,exception) == MagickFalse)
26718692172297647753b19567a180d52a6415193e3ddirk    return(MagickFalse);
26728692172297647753b19567a180d52a6415193e3ddirk
26738692172297647753b19567a180d52a6415193e3ddirk  (void) CloseBlob(image);
26748692172297647753b19567a180d52a6415193e3ddirk  return(MagickTrue);
26758692172297647753b19567a180d52a6415193e3ddirk}
26768692172297647753b19567a180d52a6415193e3ddirk
26778692172297647753b19567a180d52a6415193e3ddirkstatic void WriteDDSInfo(Image *image, const size_t pixelFormat,
26788692172297647753b19567a180d52a6415193e3ddirk  const size_t compression, const size_t mipmaps)
26798692172297647753b19567a180d52a6415193e3ddirk{
26808692172297647753b19567a180d52a6415193e3ddirk  char
2681151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    software[MagickPathExtent];
26828692172297647753b19567a180d52a6415193e3ddirk
26838692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
26848692172297647753b19567a180d52a6415193e3ddirk    i;
26858692172297647753b19567a180d52a6415193e3ddirk
26868692172297647753b19567a180d52a6415193e3ddirk  unsigned int
26878692172297647753b19567a180d52a6415193e3ddirk    format,
26888692172297647753b19567a180d52a6415193e3ddirk    caps,
26898692172297647753b19567a180d52a6415193e3ddirk    flags;
26908692172297647753b19567a180d52a6415193e3ddirk
26918692172297647753b19567a180d52a6415193e3ddirk  flags=(unsigned int) (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT |
26923e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd    DDSD_PIXELFORMAT);
26938692172297647753b19567a180d52a6415193e3ddirk  caps=(unsigned int) DDSCAPS_TEXTURE;
26948692172297647753b19567a180d52a6415193e3ddirk  format=(unsigned int) pixelFormat;
26958692172297647753b19567a180d52a6415193e3ddirk
26963e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd  if (format == DDPF_FOURCC)
26973e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd      flags=flags | DDSD_LINEARSIZE;
26983e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd  else
26993e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd      flags=flags | DDSD_PITCH;
27003e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd
27018692172297647753b19567a180d52a6415193e3ddirk  if (mipmaps > 0)
27028692172297647753b19567a180d52a6415193e3ddirk    {
27038692172297647753b19567a180d52a6415193e3ddirk      flags=flags | (unsigned int) DDSD_MIPMAPCOUNT;
27048692172297647753b19567a180d52a6415193e3ddirk      caps=caps | (unsigned int) (DDSCAPS_MIPMAP | DDSCAPS_COMPLEX);
27058692172297647753b19567a180d52a6415193e3ddirk    }
27068692172297647753b19567a180d52a6415193e3ddirk
270717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy  if (format != DDPF_FOURCC && image->alpha_trait != UndefinedPixelTrait)
27088692172297647753b19567a180d52a6415193e3ddirk    format=format | DDPF_ALPHAPIXELS;
27098692172297647753b19567a180d52a6415193e3ddirk
27108692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlob(image,4,(unsigned char *) "DDS ");
27118692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,124);
27128692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,flags);
2713a436849eb21b1901b8338cbb05f753c30035d4b9dirk  (void) WriteBlobLSBLong(image,(unsigned int) image->rows);
2714a436849eb21b1901b8338cbb05f753c30035d4b9dirk  (void) WriteBlobLSBLong(image,(unsigned int) image->columns);
27158692172297647753b19567a180d52a6415193e3ddirk
27167cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski  if (pixelFormat == DDPF_FOURCC)
27177cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski    {
27184fab20568447bd49152ddeca53b567e2893a0e8cdirk      /* Compressed DDS requires linear compressed size of first image */
27197cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski      if (compression == FOURCC_DXT1)
27204fab20568447bd49152ddeca53b567e2893a0e8cdirk        (void) WriteBlobLSBLong(image,(unsigned int) (MagickMax(1,
27214fab20568447bd49152ddeca53b567e2893a0e8cdirk          (image->columns+3)/4)*MagickMax(1,(image->rows+3)/4)*8));
27223e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd      else /* DXT5 */
27234fab20568447bd49152ddeca53b567e2893a0e8cdirk        (void) WriteBlobLSBLong(image,(unsigned int) (MagickMax(1,
27244fab20568447bd49152ddeca53b567e2893a0e8cdirk          (image->columns+3)/4)*MagickMax(1,(image->rows+3)/4)*16));
27257cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski    }
27268692172297647753b19567a180d52a6415193e3ddirk  else
27277cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski    {
27284fab20568447bd49152ddeca53b567e2893a0e8cdirk      /* Uncompressed DDS requires byte pitch of first image */
27297cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski      if (image->alpha_trait != UndefinedPixelTrait)
2730b22ff3cea82f953f1a40195b81b10aede77b3be4Hrnchamd        (void) WriteBlobLSBLong(image,(unsigned int) (image->columns * 4));
27317cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski      else
2732b22ff3cea82f953f1a40195b81b10aede77b3be4Hrnchamd        (void) WriteBlobLSBLong(image,(unsigned int) (image->columns * 3));
27337cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski    }
27348692172297647753b19567a180d52a6415193e3ddirk
27358692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,0x00);
27368692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,(unsigned int) mipmaps+1);
27378692172297647753b19567a180d52a6415193e3ddirk  (void) ResetMagickMemory(software,0,sizeof(software));
2738151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(software,"IMAGEMAGICK",MagickPathExtent);
27398692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlob(image,44,(unsigned char *) software);
27408692172297647753b19567a180d52a6415193e3ddirk
27418692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,32);
27428692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,format);
27438692172297647753b19567a180d52a6415193e3ddirk
27448692172297647753b19567a180d52a6415193e3ddirk  if (pixelFormat == DDPF_FOURCC)
27458692172297647753b19567a180d52a6415193e3ddirk    {
27468692172297647753b19567a180d52a6415193e3ddirk      (void) WriteBlobLSBLong(image,(unsigned int) compression);
27478692172297647753b19567a180d52a6415193e3ddirk      for(i=0;i < 5;i++) // bitcount / masks
27488692172297647753b19567a180d52a6415193e3ddirk        (void) WriteBlobLSBLong(image,0x00);
27498692172297647753b19567a180d52a6415193e3ddirk    }
27508692172297647753b19567a180d52a6415193e3ddirk  else
27518692172297647753b19567a180d52a6415193e3ddirk    {
27528692172297647753b19567a180d52a6415193e3ddirk      (void) WriteBlobLSBLong(image,0x00);
275317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
27548692172297647753b19567a180d52a6415193e3ddirk        {
27558692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,32);
27568692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,0xff0000);
27578692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,0xff00);
27588692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,0xff);
27598692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,0xff000000);
27608692172297647753b19567a180d52a6415193e3ddirk        }
27618692172297647753b19567a180d52a6415193e3ddirk      else
27628692172297647753b19567a180d52a6415193e3ddirk        {
27638692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,24);
27647cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski          (void) WriteBlobLSBLong(image,0xff0000);
27657cd5b950c64ead38f7733f76847ae3b459b52e53Dan Skorupski          (void) WriteBlobLSBLong(image,0xff00);
27668692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,0xff);
27678692172297647753b19567a180d52a6415193e3ddirk          (void) WriteBlobLSBLong(image,0x00);
27688692172297647753b19567a180d52a6415193e3ddirk        }
27698692172297647753b19567a180d52a6415193e3ddirk    }
27708692172297647753b19567a180d52a6415193e3ddirk
27718692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobLSBLong(image,caps);
27728692172297647753b19567a180d52a6415193e3ddirk  for(i=0;i < 4;i++) // ddscaps2 + reserved region
27738692172297647753b19567a180d52a6415193e3ddirk    (void) WriteBlobLSBLong(image,0x00);
27748692172297647753b19567a180d52a6415193e3ddirk}
27758692172297647753b19567a180d52a6415193e3ddirk
27768692172297647753b19567a180d52a6415193e3ddirkstatic void WriteFourCC(Image *image, const size_t compression,
27778692172297647753b19567a180d52a6415193e3ddirk  const MagickBooleanType clusterFit, const MagickBooleanType weightByAlpha,
27788692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
27798692172297647753b19567a180d52a6415193e3ddirk{
27808692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
27818692172297647753b19567a180d52a6415193e3ddirk    x;
27828692172297647753b19567a180d52a6415193e3ddirk
27838692172297647753b19567a180d52a6415193e3ddirk  ssize_t
27848692172297647753b19567a180d52a6415193e3ddirk    i,
27858692172297647753b19567a180d52a6415193e3ddirk    y,
27868692172297647753b19567a180d52a6415193e3ddirk    bx,
27878692172297647753b19567a180d52a6415193e3ddirk    by;
27888692172297647753b19567a180d52a6415193e3ddirk
27898692172297647753b19567a180d52a6415193e3ddirk  register const Quantum
27908692172297647753b19567a180d52a6415193e3ddirk    *p;
27918692172297647753b19567a180d52a6415193e3ddirk
27928692172297647753b19567a180d52a6415193e3ddirk  for (y=0; y < (ssize_t) image->rows; y+=4)
27938692172297647753b19567a180d52a6415193e3ddirk  {
27948692172297647753b19567a180d52a6415193e3ddirk    for (x=0; x < (ssize_t) image->columns; x+=4)
27958692172297647753b19567a180d52a6415193e3ddirk    {
27968692172297647753b19567a180d52a6415193e3ddirk      MagickBooleanType
27978692172297647753b19567a180d52a6415193e3ddirk        match;
27988692172297647753b19567a180d52a6415193e3ddirk
27998692172297647753b19567a180d52a6415193e3ddirk      DDSVector4
28008692172297647753b19567a180d52a6415193e3ddirk        point,
28018692172297647753b19567a180d52a6415193e3ddirk        points[16];
28028692172297647753b19567a180d52a6415193e3ddirk
28038692172297647753b19567a180d52a6415193e3ddirk      size_t
28048692172297647753b19567a180d52a6415193e3ddirk        count = 0,
28058692172297647753b19567a180d52a6415193e3ddirk        max5 = 0,
28068692172297647753b19567a180d52a6415193e3ddirk        max7 = 0,
28078692172297647753b19567a180d52a6415193e3ddirk        min5 = 255,
28088692172297647753b19567a180d52a6415193e3ddirk        min7 = 255,
28098692172297647753b19567a180d52a6415193e3ddirk        columns = 4,
28108692172297647753b19567a180d52a6415193e3ddirk        rows = 4;
28118692172297647753b19567a180d52a6415193e3ddirk
28128692172297647753b19567a180d52a6415193e3ddirk      ssize_t
28138692172297647753b19567a180d52a6415193e3ddirk        alphas[16],
28148692172297647753b19567a180d52a6415193e3ddirk        map[16];
28158692172297647753b19567a180d52a6415193e3ddirk
28168692172297647753b19567a180d52a6415193e3ddirk      unsigned char
28178692172297647753b19567a180d52a6415193e3ddirk        alpha;
28188692172297647753b19567a180d52a6415193e3ddirk
28198692172297647753b19567a180d52a6415193e3ddirk      if (x + columns >= image->columns)
28208692172297647753b19567a180d52a6415193e3ddirk        columns = image->columns - x;
28218692172297647753b19567a180d52a6415193e3ddirk
28228692172297647753b19567a180d52a6415193e3ddirk      if (y + rows >= image->rows)
28238692172297647753b19567a180d52a6415193e3ddirk        rows = image->rows - y;
28248692172297647753b19567a180d52a6415193e3ddirk
28258692172297647753b19567a180d52a6415193e3ddirk      p=GetVirtualPixels(image,x,y,columns,rows,exception);
28268692172297647753b19567a180d52a6415193e3ddirk      if (p == (const Quantum *) NULL)
28278692172297647753b19567a180d52a6415193e3ddirk        break;
28288692172297647753b19567a180d52a6415193e3ddirk
28298692172297647753b19567a180d52a6415193e3ddirk      for (i=0; i<16; i++)
28308692172297647753b19567a180d52a6415193e3ddirk      {
28318692172297647753b19567a180d52a6415193e3ddirk        map[i] = -1;
28328692172297647753b19567a180d52a6415193e3ddirk        alphas[i] = -1;
28338692172297647753b19567a180d52a6415193e3ddirk      }
28348692172297647753b19567a180d52a6415193e3ddirk
28353e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd      for (by=0; by < (ssize_t) rows; by++)
28368692172297647753b19567a180d52a6415193e3ddirk      {
28373e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd        for (bx=0; bx < (ssize_t) columns; bx++)
28388692172297647753b19567a180d52a6415193e3ddirk        {
28398692172297647753b19567a180d52a6415193e3ddirk          if (compression == FOURCC_DXT5)
28408692172297647753b19567a180d52a6415193e3ddirk            alpha = ScaleQuantumToChar(GetPixelAlpha(image,p));
28418692172297647753b19567a180d52a6415193e3ddirk          else
28428692172297647753b19567a180d52a6415193e3ddirk            alpha = 255;
28438692172297647753b19567a180d52a6415193e3ddirk
28443e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          if (compression == FOURCC_DXT5)
28453e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd            {
28463e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd              if (alpha < min7)
28473e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd                min7 = alpha;
28483e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd              if (alpha > max7)
28493e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd                max7 = alpha;
28503e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd              if (alpha != 0 && alpha < min5)
28513e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd                min5 = alpha;
28523e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd              if (alpha != 255 && alpha > max5)
28533e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd                max5 = alpha;
28543e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd            }
28553e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd
28568692172297647753b19567a180d52a6415193e3ddirk          alphas[4*by + bx] = (size_t)alpha;
28578692172297647753b19567a180d52a6415193e3ddirk
28588692172297647753b19567a180d52a6415193e3ddirk          point.x = (float)ScaleQuantumToChar(GetPixelRed(image,p)) / 255.0f;
28598692172297647753b19567a180d52a6415193e3ddirk          point.y = (float)ScaleQuantumToChar(GetPixelGreen(image,p)) / 255.0f;
28608692172297647753b19567a180d52a6415193e3ddirk          point.z = (float)ScaleQuantumToChar(GetPixelBlue(image,p)) / 255.0f;
28618692172297647753b19567a180d52a6415193e3ddirk          point.w = weightByAlpha ? (float)(alpha + 1) / 256.0f : 1.0f;
28628692172297647753b19567a180d52a6415193e3ddirk          p+=GetPixelChannels(image);
28638692172297647753b19567a180d52a6415193e3ddirk
28648692172297647753b19567a180d52a6415193e3ddirk          match = MagickFalse;
28653e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          for (i=0; i < (ssize_t) count; i++)
28668692172297647753b19567a180d52a6415193e3ddirk          {
28678692172297647753b19567a180d52a6415193e3ddirk            if ((points[i].x == point.x) &&
28688692172297647753b19567a180d52a6415193e3ddirk                (points[i].y == point.y) &&
28698692172297647753b19567a180d52a6415193e3ddirk                (points[i].z == point.z) &&
28708692172297647753b19567a180d52a6415193e3ddirk                (alpha       >= 128 || compression == FOURCC_DXT5))
28718692172297647753b19567a180d52a6415193e3ddirk              {
28728692172297647753b19567a180d52a6415193e3ddirk                points[i].w += point.w;
28738692172297647753b19567a180d52a6415193e3ddirk                map[4*by + bx] = i;
28748692172297647753b19567a180d52a6415193e3ddirk                match = MagickTrue;
28758692172297647753b19567a180d52a6415193e3ddirk                break;
28768692172297647753b19567a180d52a6415193e3ddirk              }
28773e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          }
28788692172297647753b19567a180d52a6415193e3ddirk
28793e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          if (match != MagickFalse)
28803e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd            continue;
28818692172297647753b19567a180d52a6415193e3ddirk
28823e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          points[count].x = point.x;
28833e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          points[count].y = point.y;
28843e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          points[count].z = point.z;
28853e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          points[count].w = point.w;
28863e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          map[4*by + bx] = count;
28873e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd          count++;
28888692172297647753b19567a180d52a6415193e3ddirk        }
28893e6952389f1e2f7bf91e1b3096b6feb9f6d5300eHrnchamd      }
28908692172297647753b19567a180d52a6415193e3ddirk
28918692172297647753b19567a180d52a6415193e3ddirk      for (i=0; i <  (ssize_t) count; i++)
28928692172297647753b19567a180d52a6415193e3ddirk        points[i].w = sqrt(points[i].w);
28938692172297647753b19567a180d52a6415193e3ddirk
28948692172297647753b19567a180d52a6415193e3ddirk      if (compression == FOURCC_DXT5)
28958692172297647753b19567a180d52a6415193e3ddirk        WriteAlphas(image,alphas,min5,max5,min7,max7);
28968692172297647753b19567a180d52a6415193e3ddirk
28978692172297647753b19567a180d52a6415193e3ddirk      if (count == 1)
28988692172297647753b19567a180d52a6415193e3ddirk        WriteSingleColorFit(image,points,map);
28998692172297647753b19567a180d52a6415193e3ddirk      else
29008692172297647753b19567a180d52a6415193e3ddirk        WriteCompressed(image,count,points,map,clusterFit);
29018692172297647753b19567a180d52a6415193e3ddirk    }
29028692172297647753b19567a180d52a6415193e3ddirk  }
29038692172297647753b19567a180d52a6415193e3ddirk}
29048692172297647753b19567a180d52a6415193e3ddirk
29058692172297647753b19567a180d52a6415193e3ddirkstatic void WriteImageData(Image *image, const size_t pixelFormat,
29068692172297647753b19567a180d52a6415193e3ddirk  const size_t compression,const MagickBooleanType clusterFit,
29078692172297647753b19567a180d52a6415193e3ddirk  const MagickBooleanType weightByAlpha, ExceptionInfo *exception)
29088692172297647753b19567a180d52a6415193e3ddirk{
29098692172297647753b19567a180d52a6415193e3ddirk  if (pixelFormat == DDPF_FOURCC)
29108692172297647753b19567a180d52a6415193e3ddirk    WriteFourCC(image,compression,clusterFit,weightByAlpha,exception);
29118692172297647753b19567a180d52a6415193e3ddirk  else
29128692172297647753b19567a180d52a6415193e3ddirk    WriteUncompressed(image,exception);
29138692172297647753b19567a180d52a6415193e3ddirk}
29148692172297647753b19567a180d52a6415193e3ddirk
29158692172297647753b19567a180d52a6415193e3ddirkstatic inline size_t ClampToLimit(const float value, const size_t limit)
29168692172297647753b19567a180d52a6415193e3ddirk{
29178692172297647753b19567a180d52a6415193e3ddirk  size_t
29188692172297647753b19567a180d52a6415193e3ddirk    result = (int) (value + 0.5f);
29198692172297647753b19567a180d52a6415193e3ddirk
29208692172297647753b19567a180d52a6415193e3ddirk  if (result < 0.0f)
29218692172297647753b19567a180d52a6415193e3ddirk    return(0);
29228692172297647753b19567a180d52a6415193e3ddirk  if (result > limit)
29238692172297647753b19567a180d52a6415193e3ddirk    return(limit);
29248692172297647753b19567a180d52a6415193e3ddirk  return result;
29258692172297647753b19567a180d52a6415193e3ddirk}
29268692172297647753b19567a180d52a6415193e3ddirk
29278692172297647753b19567a180d52a6415193e3ddirkstatic inline size_t ColorTo565(const DDSVector3 point)
29288692172297647753b19567a180d52a6415193e3ddirk{
29298692172297647753b19567a180d52a6415193e3ddirk  size_t r = ClampToLimit(31.0f*point.x,31);
29308692172297647753b19567a180d52a6415193e3ddirk  size_t g = ClampToLimit(63.0f*point.y,63);
29318692172297647753b19567a180d52a6415193e3ddirk  size_t b = ClampToLimit(31.0f*point.z,31);
29328692172297647753b19567a180d52a6415193e3ddirk
29338692172297647753b19567a180d52a6415193e3ddirk  return (r << 11) | (g << 5) | b;
29348692172297647753b19567a180d52a6415193e3ddirk}
29358692172297647753b19567a180d52a6415193e3ddirk
29368692172297647753b19567a180d52a6415193e3ddirkstatic void WriteIndices(Image *image, const DDSVector3 start,
29378692172297647753b19567a180d52a6415193e3ddirk  const DDSVector3 end, unsigned char *indices)
29388692172297647753b19567a180d52a6415193e3ddirk{
29398692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
29408692172297647753b19567a180d52a6415193e3ddirk    i;
29418692172297647753b19567a180d52a6415193e3ddirk
29428692172297647753b19567a180d52a6415193e3ddirk  size_t
29438692172297647753b19567a180d52a6415193e3ddirk    a,
29448692172297647753b19567a180d52a6415193e3ddirk    b;
29458692172297647753b19567a180d52a6415193e3ddirk
29468692172297647753b19567a180d52a6415193e3ddirk  unsigned char
29478692172297647753b19567a180d52a6415193e3ddirk    remapped[16];
29488692172297647753b19567a180d52a6415193e3ddirk
29498692172297647753b19567a180d52a6415193e3ddirk  const unsigned char
29508692172297647753b19567a180d52a6415193e3ddirk    *ind;
29518692172297647753b19567a180d52a6415193e3ddirk
29528692172297647753b19567a180d52a6415193e3ddirk  a = ColorTo565(start);
29538692172297647753b19567a180d52a6415193e3ddirk  b = ColorTo565(end);
29548692172297647753b19567a180d52a6415193e3ddirk
29558692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i<16; i++)
29568692172297647753b19567a180d52a6415193e3ddirk  {
29578692172297647753b19567a180d52a6415193e3ddirk    if( a < b )
29588692172297647753b19567a180d52a6415193e3ddirk      remapped[i] = (indices[i] ^ 0x1) & 0x3;
29598692172297647753b19567a180d52a6415193e3ddirk    else if( a == b )
29608692172297647753b19567a180d52a6415193e3ddirk      remapped[i] = 0;
29618692172297647753b19567a180d52a6415193e3ddirk    else
29628692172297647753b19567a180d52a6415193e3ddirk      remapped[i] = indices[i];
29638692172297647753b19567a180d52a6415193e3ddirk  }
29648692172297647753b19567a180d52a6415193e3ddirk
29658692172297647753b19567a180d52a6415193e3ddirk  if( a < b )
29668692172297647753b19567a180d52a6415193e3ddirk    Swap(a,b);
29678692172297647753b19567a180d52a6415193e3ddirk
29688692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobByte(image,(unsigned char) (a & 0xff));
29698692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobByte(image,(unsigned char) (a >> 8));
29708692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobByte(image,(unsigned char) (b & 0xff));
29718692172297647753b19567a180d52a6415193e3ddirk  (void) WriteBlobByte(image,(unsigned char) (b >> 8));
29728692172297647753b19567a180d52a6415193e3ddirk
29738692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i<4; i++)
29748692172297647753b19567a180d52a6415193e3ddirk  {
29758692172297647753b19567a180d52a6415193e3ddirk     ind = remapped + 4*i;
29768692172297647753b19567a180d52a6415193e3ddirk     (void) WriteBlobByte(image,ind[0] | (ind[1] << 2) | (ind[2] << 4) |
29778692172297647753b19567a180d52a6415193e3ddirk       (ind[3] << 6));
29788692172297647753b19567a180d52a6415193e3ddirk  }
29798692172297647753b19567a180d52a6415193e3ddirk}
29808692172297647753b19567a180d52a6415193e3ddirk
29818692172297647753b19567a180d52a6415193e3ddirkstatic MagickBooleanType WriteMipmaps(Image *image, const size_t pixelFormat,
29828692172297647753b19567a180d52a6415193e3ddirk  const size_t compression, const size_t mipmaps,
29838692172297647753b19567a180d52a6415193e3ddirk  const MagickBooleanType clusterFit, const MagickBooleanType weightByAlpha,
29848692172297647753b19567a180d52a6415193e3ddirk  ExceptionInfo *exception)
29858692172297647753b19567a180d52a6415193e3ddirk{
29868692172297647753b19567a180d52a6415193e3ddirk  Image*
29878692172297647753b19567a180d52a6415193e3ddirk    resize_image;
29888692172297647753b19567a180d52a6415193e3ddirk
29898692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
29908692172297647753b19567a180d52a6415193e3ddirk    i;
29918692172297647753b19567a180d52a6415193e3ddirk
29928692172297647753b19567a180d52a6415193e3ddirk  size_t
29938692172297647753b19567a180d52a6415193e3ddirk    columns,
29948692172297647753b19567a180d52a6415193e3ddirk    rows;
29958692172297647753b19567a180d52a6415193e3ddirk
29968692172297647753b19567a180d52a6415193e3ddirk  columns = image->columns;
29978692172297647753b19567a180d52a6415193e3ddirk  rows = image->rows;
29988692172297647753b19567a180d52a6415193e3ddirk
29998692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i< (ssize_t) mipmaps; i++)
30008692172297647753b19567a180d52a6415193e3ddirk  {
30018692172297647753b19567a180d52a6415193e3ddirk    resize_image = ResizeImage(image,columns/2,rows/2,TriangleFilter,
30028692172297647753b19567a180d52a6415193e3ddirk      exception);
30038692172297647753b19567a180d52a6415193e3ddirk
30048692172297647753b19567a180d52a6415193e3ddirk    if (resize_image == (Image *) NULL)
30058692172297647753b19567a180d52a6415193e3ddirk      return(MagickFalse);
30068692172297647753b19567a180d52a6415193e3ddirk
30078692172297647753b19567a180d52a6415193e3ddirk    DestroyBlob(resize_image);
30088692172297647753b19567a180d52a6415193e3ddirk    resize_image->blob=ReferenceBlob(image->blob);
30098692172297647753b19567a180d52a6415193e3ddirk
30108692172297647753b19567a180d52a6415193e3ddirk    WriteImageData(resize_image,pixelFormat,compression,weightByAlpha,
30118692172297647753b19567a180d52a6415193e3ddirk      clusterFit,exception);
30128692172297647753b19567a180d52a6415193e3ddirk
30138692172297647753b19567a180d52a6415193e3ddirk    resize_image=DestroyImage(resize_image);
30148692172297647753b19567a180d52a6415193e3ddirk
30158692172297647753b19567a180d52a6415193e3ddirk    columns = DIV2(columns);
30168692172297647753b19567a180d52a6415193e3ddirk    rows = DIV2(rows);
30178692172297647753b19567a180d52a6415193e3ddirk  }
30188692172297647753b19567a180d52a6415193e3ddirk
30198692172297647753b19567a180d52a6415193e3ddirk  return(MagickTrue);
30208692172297647753b19567a180d52a6415193e3ddirk}
30218692172297647753b19567a180d52a6415193e3ddirk
30228692172297647753b19567a180d52a6415193e3ddirkstatic void WriteSingleColorFit(Image *image, const DDSVector4 *points,
30238692172297647753b19567a180d52a6415193e3ddirk  const ssize_t *map)
30248692172297647753b19567a180d52a6415193e3ddirk{
30258692172297647753b19567a180d52a6415193e3ddirk  DDSVector3
30268692172297647753b19567a180d52a6415193e3ddirk    start,
30278692172297647753b19567a180d52a6415193e3ddirk    end;
30288692172297647753b19567a180d52a6415193e3ddirk
30298692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
30308692172297647753b19567a180d52a6415193e3ddirk    i;
30318692172297647753b19567a180d52a6415193e3ddirk
30328692172297647753b19567a180d52a6415193e3ddirk  unsigned char
30338692172297647753b19567a180d52a6415193e3ddirk    color[3],
30348692172297647753b19567a180d52a6415193e3ddirk    index,
30358692172297647753b19567a180d52a6415193e3ddirk    indexes[16],
30368692172297647753b19567a180d52a6415193e3ddirk    indices[16];
30378692172297647753b19567a180d52a6415193e3ddirk
30388692172297647753b19567a180d52a6415193e3ddirk  color[0] = (unsigned char) ClampToLimit(255.0f*points->x,255);
30398692172297647753b19567a180d52a6415193e3ddirk  color[1] = (unsigned char) ClampToLimit(255.0f*points->y,255);
30408692172297647753b19567a180d52a6415193e3ddirk  color[2] = (unsigned char) ClampToLimit(255.0f*points->z,255);
30418692172297647753b19567a180d52a6415193e3ddirk
30428692172297647753b19567a180d52a6415193e3ddirk  index=0;
30438692172297647753b19567a180d52a6415193e3ddirk  ComputeEndPoints(DDS_LOOKUP,color,&start,&end,&index);
30448692172297647753b19567a180d52a6415193e3ddirk
30458692172297647753b19567a180d52a6415193e3ddirk  for (i=0; i< 16; i++)
30468692172297647753b19567a180d52a6415193e3ddirk    indexes[i]=index;
30478692172297647753b19567a180d52a6415193e3ddirk  RemapIndices(map,indexes,indices);
30488692172297647753b19567a180d52a6415193e3ddirk  WriteIndices(image,start,end,indices);
30498692172297647753b19567a180d52a6415193e3ddirk}
30508692172297647753b19567a180d52a6415193e3ddirk
30518692172297647753b19567a180d52a6415193e3ddirkstatic void WriteUncompressed(Image *image, ExceptionInfo *exception)
30528692172297647753b19567a180d52a6415193e3ddirk{
30538692172297647753b19567a180d52a6415193e3ddirk  register const Quantum
30548692172297647753b19567a180d52a6415193e3ddirk    *p;
30558692172297647753b19567a180d52a6415193e3ddirk
30568692172297647753b19567a180d52a6415193e3ddirk  register ssize_t
30578692172297647753b19567a180d52a6415193e3ddirk    x;
30588692172297647753b19567a180d52a6415193e3ddirk
30598692172297647753b19567a180d52a6415193e3ddirk  ssize_t
30608692172297647753b19567a180d52a6415193e3ddirk    y;
30618692172297647753b19567a180d52a6415193e3ddirk
30628692172297647753b19567a180d52a6415193e3ddirk  for (y=0; y < (ssize_t) image->rows; y++)
30638692172297647753b19567a180d52a6415193e3ddirk  {
30648692172297647753b19567a180d52a6415193e3ddirk    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
30658692172297647753b19567a180d52a6415193e3ddirk    if (p == (const Quantum *) NULL)
30668692172297647753b19567a180d52a6415193e3ddirk      break;
30678692172297647753b19567a180d52a6415193e3ddirk
30688692172297647753b19567a180d52a6415193e3ddirk    for (x=0; x < (ssize_t) image->columns; x++)
30698692172297647753b19567a180d52a6415193e3ddirk    {
30708692172297647753b19567a180d52a6415193e3ddirk      (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelBlue(image,p)));
30718692172297647753b19567a180d52a6415193e3ddirk      (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelGreen(image,p)));
30728692172297647753b19567a180d52a6415193e3ddirk      (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelRed(image,p)));
307317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy      if (image->alpha_trait != UndefinedPixelTrait)
30748692172297647753b19567a180d52a6415193e3ddirk        (void) WriteBlobByte(image,ScaleQuantumToChar(GetPixelAlpha(image,p)));
30758692172297647753b19567a180d52a6415193e3ddirk      p+=GetPixelChannels(image);
30768692172297647753b19567a180d52a6415193e3ddirk    }
30778692172297647753b19567a180d52a6415193e3ddirk  }
30788692172297647753b19567a180d52a6415193e3ddirk}
3079