1 /********************************************************************************
2 *                                                                               *
3 *                          D D S   I n p u t / O u t p u t                      *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 1998,2021 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify          *
9 * it under the terms of the GNU Lesser General Public License as published by   *
10 * the Free Software Foundation; either version 3 of the License, or             *
11 * (at your option) any later version.                                           *
12 *                                                                               *
13 * This library is distributed in the hope that it will be useful,               *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of                *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 *
16 * GNU Lesser General Public License for more details.                           *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser General Public License      *
19 * along with this program.  If not, see <http://www.gnu.org/licenses/>          *
20 ********************************************************************************/
21 #include "xincs.h"
22 #include "fxver.h"
23 #include "fxdefs.h"
24 #include "fxmath.h"
25 #include "FXArray.h"
26 #include "FXHash.h"
27 #include "FXhalf.h"
28 #include "FXElement.h"
29 #include "FXStream.h"
30 
31 /*
32   Notes:
33   - For cubic environment maps, one or more faces of a cube are written to the file, using either uncompressed or
34     compressed formats, and all faces must be the same size. Each face can have mipmaps defined, although all faces
35     must have the same number of mipmap levels. If a file contains a cube map, DDSCAPS_COMPLEX, DDSCAPS2_CUBEMAP,
36     and one or more of DSCAPS2_CUBEMAP_POSITIVEX/Y/Z and/or DDSCAPS2_CUBEMAP_NEGATIVEX/Y/Z should be set.
37     The faces are written in the order: positive x, negative x, positive y, negative y, positive z, negative z,
38     with any missing faces omitted. Each face is written with its main image, followed by any mipmap levels.
39   - For a volume texture, use the DDSCAPS_COMPLEX, DDSCAPS2_VOLUME, DDSD_DEPTH, flags and set and dwDepth.
40     A volume texture is an extension of a standard texture for Direct3D 9; a volume texture is can be defined with
41     or without mipmaps.  For volumes without mipmaps, each depth slice is written to the file in order.
42     If mipmaps are included, all depth slices for a given mipmap level are written together, with each level
43     containing half as many slices as the previous level with a minimum of 1.
44   - Volume textures do not support compression in Direct3D 9.
45   - For an uncompressed texture, use the DDSD_PITCH and DDPF_RGB flags; for a compressed texture,
46     use the DDSD_LINEARSIZE and DDPF_FOURCC flags.
47   - For a mipmapped texture, use the DDSD_MIPMAPCOUNT, DDSCAPS_MIPMAP, and DDSCAPS_COMPLEX flags also as
48     well as the mipmap count member. If mipmaps are generated, all levels down to 1-by-1 are usually written.
49 */
50 
51 
52 
53 // Magic file header constant
54 #define DDSD_MAGIC                   0x20534444
55 
56 // DDSHeader flags
57 #define DDSD_CAPS                    0x00000001
58 #define DDSD_HEIGHT                  0x00000002
59 #define DDSD_WIDTH                   0x00000004
60 #define DDSD_PITCH                   0x00000008
61 #define DDSD_PIXELFORMAT	     0x00001000
62 #define DDSD_MIPMAPCOUNT	     0x00020000
63 #define DDSD_LINEARSIZE   	     0x00080000
64 #define DDSD_DEPTH      	     0x00800000
65 
66 // DDSPixelFormat flags
67 #define DDPF_ALPHAPIXELS	     0x00000001
68 #define DDPF_ALPHA                   0x00000002
69 #define DDPF_FOURCC                  0x00000004
70 #define DDPF_PALETTEINDEXED4         0x00000008
71 #define DDPF_PALETTEINDEXED8         0x00000020
72 #define DDPF_RGB                     0x00000040
73 #define DDPF_COMPRESSED              0x00000080
74 #define DDPF_RGBTOYUV                0x00000100
75 #define DDPF_YUV                     0x00000200
76 #define DDPF_ZBUFFER                 0x00000400
77 #define DDPF_PALETTEINDEXED1         0x00000800
78 #define DDPF_PALETTEINDEXED2         0x00001000
79 #define DDPF_ZPIXELS                 0x00002000
80 #define DDPF_STENCILBUFFER           0x00004000
81 #define DDPF_ALPHAPREMULT            0x00008000
82 #define DDPF_LUMINANCE               0x00020000
83 #define DDPF_BUMPLUMINANCE           0x00040000
84 #define DDPF_NORMAL                  0x80000000
85 
86 // DDSHeader CAPS field
87 #define DDSCAPS_COMPLEX              0x00000008
88 #define DDSCAPS_TEXTURE              0x00001000
89 #define DDSCAPS_MIPMAP               0x00400000
90 
91 // DDSHeader CAPS2 field
92 #define DDSCAPS2_CUBEMAP             0x00000200
93 #define DDSCAPS2_VOLUME              0x00200000
94 
95 // DDSHeader Cube maps
96 #define DDSCAPS2_CUBEMAP_POSITIVEX   0x00000400
97 #define DDSCAPS2_CUBEMAP_NEGATIVEX   0x00000800
98 #define DDSCAPS2_CUBEMAP_POSITIVEY   0x00001000
99 #define DDSCAPS2_CUBEMAP_NEGATIVEY   0x00002000
100 #define DDSCAPS2_CUBEMAP_POSITIVEZ   0x00004000
101 #define DDSCAPS2_CUBEMAP_NEGATIVEZ   0x00008000
102 
103 
104 // DDSPixelFormat FOURCC constants (Compressed texture formats)
105 #define D3DFMT_DXT1                  0x31545844         // DXT1
106 #define D3DFMT_DXT2                  0x32545844         // DXT2
107 #define D3DFMT_DXT3                  0x33545844         // DXT3
108 #define D3DFMT_DXT4                  0x34545844         // DXT4
109 #define D3DFMT_DXT5                  0x35545844         // DXT5
110 
111 // DDSPixelFormat FOURCC constants (Nonstandard formats)
112 #define D3DFMT_DX10                  0x30315844         // DX10
113 #define D3DFMT_RXGB                  0x42475852         // RXGB (AKA DOOM III)
114 #define D3DFMT_ATI1                  0x31495441         // ATI1
115 #define D3DFMT_ATI2                  0x32495441         // ATI2 (AKA 3Dc)
116 #define D3DFMT_A2XY                  0x59583241         // A2XY
117 #define D3DFMT_UYVY                  0x59565955         // UYVY format
118 #define D3DFMT_YUY2                  0x32595559         // YUY2 format
119 #define D3DFMT_R8G8_B8G8             0x47424752         // Pairs of pixels, [RG][BG] consecutive pixels share R and G (G0R0,G1B0, G2R2,G3B2) etc.
120 #define D3DFMT_G8R8_G8B8             0x42475247         // Pairs of pixels, [GR][GB] consecutive pixels share R and B (R0G0,B0G1, R2G2,B2G3) etc.
121 
122 // DDSPixelFormat FOURCC constants (Floating point)
123 #define D3DFMT_R16F                  111                // 16-bit float format using 16 bits for the red channel.
124 #define D3DFMT_G16R16F               112                // 32-bit float format using 16 bits for the red channel and 16 bits for the green channel.
125 #define D3DFMT_A16B16G16R16F         113                // 64-bit float format using 16 bits for the each channel (alpha, blue, green, red).
126 #define D3DFMT_R32F                  114                // 32-bit float format using 32 bits for the red channel.
127 #define D3DFMT_G32R32F               115                // 64-bit float format using 32 bits for the red channel and 32 bits for the green channel.
128 #define D3DFMT_A32B32G32R32F         116                // 128-bit float format using 32 bits for the each channel (alpha, blue, green, red).
129 
130 // DDSPixelFormat FOURCC constants (Signed integer formats)
131 #define D3DFMT_V8U8                  60                 // 16-bit bump-map format using 8 bits each for u and v data.
132 #define D3DFMT_L6V5U5                61                 // 16-bit bump-map format with luminance using 6 bits for luminance, and 5 bits each for v and u.
133 #define D3DFMT_X8L8V8U8              62                 // 32-bit bump-map format with luminance using 8 bits for each channel.
134 #define D3DFMT_Q8W8V8U8              63                 // 32-bit bump-map format using 8 bits for each channel.
135 #define D3DFMT_V16U16                64                 // 32-bit bump-map format using 16 bits for each channel.
136 #define D3DFMT_A2W10V10U10           67                 // 32-bit bump-map format using 2 bits for alpha and 10 bits each for w, v, and u.
137 #define D3DFMT_Q16W16V16U16          110                // 64-bit bump-map format using 16 bits for each component.
138 #define D3DFMT_CxV8U8                117                // 16-bit normal compression format. The texture sampler computes the C channel from: C = sqrt(1 - U2 - V2).
139 
140 // DDSPixelFormat FOURCC constants (Unsigned integer formats)
141 #define D3DFMT_R8G8B8                20                 // 24-bit RGB pixel format with 8 bits per channel.
142 #define D3DFMT_A8R8G8B8              21                 // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
143 #define D3DFMT_X8R8G8B8              22                 // 32-bit RGB pixel format, where 8 bits are reserved for each color.
144 #define D3DFMT_R5G6B5                23                 // 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.
145 #define D3DFMT_X1R5G5B5              24                 // 16-bit pixel format where 5 bits are reserved for each color.
146 #define D3DFMT_A1R5G5B5              25                 // 16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha.
147 #define D3DFMT_A4R4G4B4              26                 // 16-bit ARGB pixel format with 4 bits for each channel.
148 #define D3DFMT_R3G3B2                27                 // 8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue.
149 #define D3DFMT_A8                    28                 // 8-bit alpha only.
150 #define D3DFMT_A8R3G3B2              29                 // 16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and green, and 2 bits for blue.
151 #define D3DFMT_X4R4G4B4              30                 // 16-bit RGB pixel format using 4 bits for each color.
152 #define D3DFMT_A2B10G10R10           31                 // 32-bit pixel format using 10 bits for each color and 2 bits for alpha.
153 #define D3DFMT_A8B8G8R8              32                 // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
154 #define D3DFMT_X8B8G8R8              33                 // 32-bit RGB pixel format, where 8 bits are reserved for each color.
155 #define D3DFMT_G16R16                34                 // 32-bit pixel format using 16 bits each for green and red.
156 #define D3DFMT_A2R10G10B10           35                 // 32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for alpha.
157 #define D3DFMT_A16B16G16R16          36                 // 64-bit pixel format using 16 bits for each component.
158 #define D3DFMT_A8P8                  40                 // 8-bit color indexed with 8 bits of alpha.
159 #define D3DFMT_P8                    41                 // 8-bit color indexed.
160 #define D3DFMT_L8                    50                 // 8-bit luminance only.
161 #define D3DFMT_A8L8                  51                 // 16-bit using 8 bits each for alpha and luminance.
162 #define D3DFMT_A4L4                  52                 // 8-bit using 4 bits each for alpha and luminance.
163 #define D3DFMT_L16                   81                 // 16-bit luminance only.
164 #define D3DFMT_A1                    118                // 1-bit monochrome.
165 #define D3DFMT_A2B10G10R10_XR_BIAS   119                // 2.8-biased fixed point.
166 #define D3DFMT_BINARYBUFFER          199                // Binary format indicating that the data has no inherent type.
167 
168 // DDSPixelFormat FOURCC constants (Buffer formats)
169 #define D3DFMT_D16_LOCKABLE          70                 // 16-bit z-buffer bit depth.
170 #define D3DFMT_D32                   71                 // 32-bit z-buffer bit depth.
171 #define D3DFMT_D15S1                 73                 // 16-bit z-buffer bit depth where 15 bits are reserved for the depth channel and 1 bit is reserved for the stencil channel.
172 #define D3DFMT_D24S8                 75                 // 32-bit z-buffer bit depth using 24 bits for the depth channel and 8 bits for the stencil channel.
173 #define D3DFMT_D24X8                 77                 // 32-bit z-buffer bit depth using 24 bits for the depth channel.
174 #define D3DFMT_D24X4S4               79                 // 32-bit z-buffer bit depth using 24 bits for the depth channel and 4 bits for the stencil channel.
175 #define D3DFMT_D16                   80                 // 16-bit z-buffer bit depth.
176 #define D3DFMT_D32F_LOCKABLE         82                 // A lockable format where the depth value is represented as a standard IEEE floating-point number.
177 #define D3DFMT_D24FS8                83                 // A non-lockable format that contains 24 bits of depth (in a 24-bit floating point format - 20e4) and 8 bits of stencil.
178 #define D3DFMT_D32_LOCKABLE          84                 // A lockable 32-bit depth buffer.
179 #define D3DFMT_S8_LOCKABLE           85                 // A lockable 8-bit stencil buffer.
180 #define D3DFMT_VERTEXDATA            100                // Describes a vertex buffer surface.
181 #define D3DFMT_INDEX16               101                // 16-bit index buffer bit depth.
182 #define D3DFMT_INDEX32               102                // 32-bit index buffer bit depth.
183 
184 // DDSXHeader Resource dimension
185 #define D3D10_RESOURCE_DIMENSION_UNKNOWN        0               // Resource is of unknown type.
186 #define D3D10_RESOURCE_DIMENSION_BUFFER         1               // Resource is a buffer.
187 #define D3D10_RESOURCE_DIMENSION_TEXTURE1D      2               // Resource is a 1D texture.
188 #define D3D10_RESOURCE_DIMENSION_TEXTURE2D      3               // Resource is a 2D texture.
189 #define D3D10_RESOURCE_DIMENSION_TEXTURE3D      4               // Resource is a 3D texture.
190 
191 // DDSXHeader Miscellaneous flag
192 #define D3D10_RESOURCE_MISC_GENERATE_MIPS       0x1             // Enable mipmap generation
193 #define D3D10_RESOURCE_MISC_SHARED              0x2             // Enable share
194 #define D3D10_RESOURCE_MISC_TEXTURECUBE         0x4             // Enable cube map
195 #define D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX   0x10
196 #define D3D10_RESOURCE_MISC_GDI_COMPATIBLE      0x20
197 
198 // DDSXHeader Formats
199 #define DXGI_FORMAT_UNKNOWN                     0               // The format is not known.
200 
201 #define DXGI_FORMAT_R32G32B32A32_TYPELESS       1               // A four-component, 128-bit typeless format.
202 #define DXGI_FORMAT_R32G32B32A32_FLOAT          2               // A four-component, 128-bit floating-point format
203 #define DXGI_FORMAT_R32G32B32A32_UINT           3               // A four-component, 128-bit unsigned-integer format
204 #define DXGI_FORMAT_R32G32B32A32_SINT           4               // A four-component, 128-bit signed-integer format.
205 
206 #define DXGI_FORMAT_R32G32B32_TYPELESS          5               // A three-component, 96-bit typeless format.
207 #define DXGI_FORMAT_R32G32B32_FLOAT             6               // A three-component, 96-bit floating-point format.
208 #define DXGI_FORMAT_R32G32B32_UINT              7               // A three-component, 96-bit unsigned-integer format.
209 #define DXGI_FORMAT_R32G32B32_SINT              8               // A three-component, 96-bit signed-integer format.
210 
211 #define DXGI_FORMAT_R16G16B16A16_TYPELESS       9               // A four-component, 64-bit typeless format.
212 #define DXGI_FORMAT_R16G16B16A16_FLOAT          10              // A four-component, 64-bit floating-point format.
213 #define DXGI_FORMAT_R16G16B16A16_UNORM          11              // A four-component, 64-bit unsigned-integer format.
214 #define DXGI_FORMAT_R16G16B16A16_UINT           12              // A four-component, 64-bit unsigned-integer format.
215 #define DXGI_FORMAT_R16G16B16A16_SNORM          13              // A four-component, 64-bit signed-integer format.
216 #define DXGI_FORMAT_R16G16B16A16_SINT           14              // A four-component, 64-bit signed-integer format.
217 
218 #define DXGI_FORMAT_R32G32_TYPELESS             15              // A two-component, 64-bit typeless format.
219 #define DXGI_FORMAT_R32G32_FLOAT                16              // A two-component, 64-bit floating-point format.
220 #define DXGI_FORMAT_R32G32_UINT                 17              // A two-component, 64-bit unsigned-integer format.
221 #define DXGI_FORMAT_R32G32_SINT                 18              // A two-component, 64-bit signed-integer format.
222 
223 #define DXGI_FORMAT_R32G8X24_TYPELESS           19              // A two-component, 64-bit typeless format.
224 #define DXGI_FORMAT_D32_FLOAT_S8X24_UINT        20              // A 32-bit floating-point component, and two unsigned-integer components (with an additional 32 bits).
225 #define DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS    21              // A 32-bit floating-point component, and two typeless components (with an additional 32 bits).
226 #define DXGI_FORMAT_X32_TYPELESS_G8X24_UINT     22              // A 32-bit typeless component, and two unsigned-integer components (with an additional 32 bits).
227 
228 #define DXGI_FORMAT_R10G10B10A2_TYPELESS        23              // A four-component, 32-bit typeless format.
229 #define DXGI_FORMAT_R10G10B10A2_UNORM           24              // A four-component, 32-bit unsigned-integer format.
230 #define DXGI_FORMAT_R10G10B10A2_UINT            25              // A four-component, 32-bit unsigned-integer format.
231 
232 #define DXGI_FORMAT_R11G11B10_FLOAT             26              // A three-component, 32-bit floating-point format.
233 
234 #define DXGI_FORMAT_R8G8B8A8_TYPELESS           27              // A three-component, 32-bit typeless format.
235 #define DXGI_FORMAT_R8G8B8A8_UNORM              28              // A four-component, 32-bit unsigned-integer format.
236 #define DXGI_FORMAT_R8G8B8A8_UNORM_SRGB         29              // A four-component, 32-bit unsigned-normalized integer sRGB format.
237 #define DXGI_FORMAT_R8G8B8A8_UINT               30              // A four-component, 32-bit unsigned-integer format.
238 #define DXGI_FORMAT_R8G8B8A8_SNORM              31              // A three-component, 32-bit signed-integer format.
239 #define DXGI_FORMAT_R8G8B8A8_SINT               32              // A three-component, 32-bit signed-integer format.
240 
241 #define DXGI_FORMAT_R16G16_TYPELESS             33              // A two-component, 32-bit typeless format.
242 #define DXGI_FORMAT_R16G16_FLOAT                34              // A two-component, 32-bit floating-point format.
243 #define DXGI_FORMAT_R16G16_UNORM                35              // A two-component, 32-bit unsigned-integer format.
244 #define DXGI_FORMAT_R16G16_UINT                 36              // A two-component, 32-bit unsigned-integer format.
245 #define DXGI_FORMAT_R16G16_SNORM                37              // A two-component, 32-bit signed-integer format.
246 #define DXGI_FORMAT_R16G16_SINT                 38              // A two-component, 32-bit signed-integer format.
247 
248 #define DXGI_FORMAT_R32_TYPELESS                39              // A single-component, 32-bit typeless format.
249 #define DXGI_FORMAT_D32_FLOAT                   40              // A single-component, 32-bit floating-point format.
250 #define DXGI_FORMAT_R32_FLOAT                   41              // A single-component, 32-bit floating-point format.
251 #define DXGI_FORMAT_R32_UINT                    42              // A single-component, 32-bit unsigned-integer format.
252 #define DXGI_FORMAT_R32_SINT                    43              // A single-component, 32-bit signed-integer format.
253 
254 #define DXGI_FORMAT_R24G8_TYPELESS              44              // A two-component, 32-bit typeless format.
255 #define DXGI_FORMAT_D24_UNORM_S8_UINT           45              // A 32-bit z-buffer format that uses 24 bits for the depth channel and 8 bits for the stencil channel.
256 #define DXGI_FORMAT_R24_UNORM_X8_TYPELESS       46              // A 32-bit format, that contains a 24 bit, single-component, unsigned-normalized integer, with an additional typeless 8 bits.
257 #define DXGI_FORMAT_X24_TYPELESS_G8_UINT        47              // A 32-bit format, that contains a 24 bit, single-component, typeless format, with an additional 8 bit unsigned integer component.
258 
259 #define DXGI_FORMAT_R8G8_TYPELESS               48              // A two-component, 16-bit typeless format.
260 #define DXGI_FORMAT_R8G8_UNORM                  49              // A two-component, 16-bit unsigned-integer format.
261 #define DXGI_FORMAT_R8G8_UINT                   50              // A two-component, 16-bit unsigned-integer format.
262 #define DXGI_FORMAT_R8G8_SNORM                  51              // A two-component, 16-bit signed-integer format.
263 #define DXGI_FORMAT_R8G8_SINT                   52              // A two-component, 16-bit signed-integer format.
264 
265 #define DXGI_FORMAT_R16_TYPELESS                53              // A single-component, 16-bit typeless format.
266 #define DXGI_FORMAT_R16_FLOAT                   54              // A single-component, 16-bit floating-point format.
267 #define DXGI_FORMAT_D16_UNORM                   55              // A single-component, 16-bit unsigned-normalized integer format.
268 #define DXGI_FORMAT_R16_UNORM                   56              // A single-component, 16-bit unsigned-integer format.
269 #define DXGI_FORMAT_R16_UINT                    57              // A single-component, 16-bit unsigned-integer format.
270 #define DXGI_FORMAT_R16_SNORM                   58              // A single-component, 16-bit signed-integer format.
271 #define DXGI_FORMAT_R16_SINT                    59              // A single-component, 16-bit signed-integer format.
272 
273 #define DXGI_FORMAT_R8_TYPELESS                 60              // A single-component, 8-bit typeless format.
274 #define DXGI_FORMAT_R8_UNORM                    61              // A single-component, 8-bit unsigned-integer format.
275 #define DXGI_FORMAT_R8_UINT                     62              // A single-component, 8-bit unsigned-integer format.
276 #define DXGI_FORMAT_R8_SNORM                    63              // A single-component, 8-bit signed-integer format.
277 #define DXGI_FORMAT_R8_SINT                     64              // A single-component, 8-bit signed-integer format.
278 #define DXGI_FORMAT_A8_UNORM                    65              // A single-component, 8-bit unsigned-integer format.
279 
280 #define DXGI_FORMAT_R1_UNORM                    66              // A single-component, 1-bit unsigned-normalized integer format.
281 
282 #define DXGI_FORMAT_R9G9B9E5_SHAREDEXP          67              // A four-component, 32-bit floating-point format.
283 
284 #define DXGI_FORMAT_R8G8_B8G8_UNORM             68              // A four-component, 32-bit unsigned-normalized integer format.
285 #define DXGI_FORMAT_G8R8_G8B8_UNORM             69              // A four-component, 32-bit unsigned-normalized integer format.
286 
287 #define DXGI_FORMAT_BC1_TYPELESS                70              // 4-channel typeless block-compression format.
288 #define DXGI_FORMAT_BC1_UNORM                   71              // 4-channel block-compression format.
289 #define DXGI_FORMAT_BC1_UNORM_SRGB              72              // 4-channel block-compression format for sRGB data.
290 
291 #define DXGI_FORMAT_BC2_TYPELESS                73              // 4-channel typeless block-compression format.
292 #define DXGI_FORMAT_BC2_UNORM                   74              // 4-channel block-compression format.
293 #define DXGI_FORMAT_BC2_UNORM_SRGB              75              // 4-channel block-compression format for sRGB data.
294 
295 #define DXGI_FORMAT_BC3_TYPELESS                76              // 4-channel typeless block-compression format.
296 #define DXGI_FORMAT_BC3_UNORM                   77              // 4-channel block-compression format.
297 #define DXGI_FORMAT_BC3_UNORM_SRGB              78              // 4-channel block-compression format for sRGB data.
298 
299 #define DXGI_FORMAT_BC4_TYPELESS                79              // 1-channel typeless block-compression format.
300 #define DXGI_FORMAT_BC4_UNORM                   80              // 1-channel block-compression format.
301 #define DXGI_FORMAT_BC4_SNORM                   81              // 1-channel block-compression format.
302 
303 #define DXGI_FORMAT_BC5_TYPELESS                82              // 2-channel typeless block-compression format.
304 #define DXGI_FORMAT_BC5_UNORM                   83              // 2-channel block-compression format.
305 #define DXGI_FORMAT_BC5_SNORM                   84              // 2-channel block-compression format.
306 
307 #define DXGI_FORMAT_B5G6R5_UNORM                85              // A three-component, 16-bit unsigned-normalized integer format.
308 #define DXGI_FORMAT_B5G5R5A1_UNORM              86              // A four-component, 16-bit unsigned-normalized integer format that supports 1-bit alpha.
309 #define DXGI_FORMAT_B8G8R8A8_UNORM              87              // A four-component, 16-bit unsigned-normalized integer format that supports 8-bit alpha.
310 #define DXGI_FORMAT_B8G8R8X8_UNORM              88              // A four-component, 16-bit unsigned-normalized integer format.
311 #define DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM  89              // A four-component, 32-bit format that supports 2-bit alpha.
312 #define DXGI_FORMAT_B8G8R8A8_TYPELESS           90              // A four-component, 32-bit typeless format that supports 8-bit alpha.
313 #define DXGI_FORMAT_B8G8R8A8_UNORM_SRGB         91              // A four-component, 32-bit unsigned-normalized standard RGB format that supports 8-bit alpha.
314 #define DXGI_FORMAT_B8G8R8X8_TYPELESS           92              // A four-component, 32-bit typeless format.
315 #define DXGI_FORMAT_B8G8R8X8_UNORM_SRGB         93              // A four-component, 32-bit unsigned-normalized standard RGB format.
316 #define DXGI_FORMAT_BC6H_TYPELESS               94              // A typeless block-compression format
317 #define DXGI_FORMAT_BC6H_UF16                   95              // A block-compression format.
318 #define DXGI_FORMAT_BC6H_SF16                   96              // A block-compression format.
319 #define DXGI_FORMAT_BC7_TYPELESS                97              // A typeless block-compression format.
320 #define DXGI_FORMAT_BC7_UNORM                   98              // A block-compression format.
321 #define DXGI_FORMAT_BC7_UNORM_SRGB              99              // A block-compression format.
322 
323 #define DXGI_FORMAT_AYUV                        100             // Most common YUV 4:4:4 video resource format
324 #define DXGI_FORMAT_Y410                        101             // 10-bit per channel packed YUV 4:4:4 video resource format
325 #define DXGI_FORMAT_Y416                        102             // 16-bit per channel packed YUV 4:4:4 video resource format
326 #define DXGI_FORMAT_NV12                        103             // Most common YUV 4:2:0 video resource format
327 #define DXGI_FORMAT_P010                        104             // 10-bit per channel planar YUV 4:2:0 video resource format
328 #define DXGI_FORMAT_P016                        105             // 16-bit per channel planar YUV 4:2:0 video resource format
329 #define DXGI_FORMAT_420_OPAQUE                  106             // 8-bit per channel planar YUV 4:2:0 video resource format
330 #define DXGI_FORMAT_YUY2                        107             // Most common YUV 4:2:2 video resource format
331 #define DXGI_FORMAT_Y210                        108             // 10-bit per channel packed YUV 4:2:2 video resource format
332 #define DXGI_FORMAT_Y216                        109             // 16-bit per channel packed YUV 4:2:2 video resource format.
333 #define DXGI_FORMAT_NV11                        110             // Most common planar YUV 4:1:1 video resource format
334 #define DXGI_FORMAT_AI44                        111             // 4-bit palletized YUV format that is commonly used for DVD subpicture
335 #define DXGI_FORMAT_IA44                        112             // 4-bit palletized YUV format that is commonly used for DVD subpicture
336 #define DXGI_FORMAT_P8                          113             // 88-bit palletized format that is used for palletized RGB data when the processor processes ISDB-T data and for palletized YUV data when the processor processes BluRay data
337 #define DXGI_FORMAT_A8P8                        114             // 8-bit palletized format with 8 bits of alpha that is used for palletized YUV data when the processor processes BluRay data
338 #define DXGI_FORMAT_B4G4R4A4_UNORM              115             // A four-component, 16-bit unsigned-normalized integer format that supports 4 bits for each channel including alpha
339 
340 
341 // Internal codes
342 #define CODE_NONE       0
343 #define CODE_DXT1       1
344 #define CODE_DXT2       2
345 #define CODE_DXT3       3
346 #define CODE_DXT4       4
347 #define CODE_DXT5       5
348 
349 using namespace FX;
350 
351 /*******************************************************************************/
352 
353 namespace FX {
354 
355 #ifndef FXLOADDDS
356 extern FXAPI FXbool fxcheckDDS(FXStream& store);
357 extern FXAPI FXbool fxloadDDS(FXStream& store,FXColor*& data,FXint& width,FXint& height,FXint& depth);
358 extern FXAPI FXbool fxsaveDDS(FXStream& store,FXColor* data,FXint width,FXint height,FXint depth);
359 #endif
360 
361 
362 // Pixel format
363 struct DDSPixelFormat {
364   FXuint         dwSize;
365   FXuint         dwFlags;
366   FXuint         dwFourCC;
367   FXuint         dwRGBBitCount;
368   FXuint         dwRBitMask;
369   FXuint         dwGBitMask;
370   FXuint         dwBBitMask;
371   FXuint         dwABitMask;
372   };
373 
374 
375 // DDS Header
376 struct DDSHeader {
377   FXuint         dwSize;
378   FXuint         dwFlags;
379   FXuint         dwHeight;
380   FXuint         dwWidth;
381   FXuint         dwLinearSize;
382   FXuint         dwDepth;
383   FXuint         dwMipMapCount;
384   FXuint         dwReserved1[11];
385   DDSPixelFormat ddpf;
386   FXuint         dwCaps;
387   FXuint         dwCaps2;
388   FXuint         dwCaps3;
389   FXuint         dwCaps4;
390   FXuint         dwReserved2;
391   };
392 
393 
394 // DX10 extra header structure
395 struct DDSXHeader {
396   FXuint         dxgiFormat;
397   FXuint         resourceDimension;
398   FXuint         miscFlag;
399   FXuint         arraySize;
400   FXuint         reserved;
401   };
402 
403 
404 // DDS Image
405 struct DDSImage {
406   FXuint         magic;
407   DDSHeader      header;
408   DDSXHeader     xheader;
409   FXuint         size;
410   FXuchar       *data;
411   };
412 
413 
414 // Fast integer square root
isqrt(FXuint val)415 static FXuint isqrt(FXuint val){
416   FXuint temp,g=0,b=0x8000,bshft=15;
417   do{if(val>=(temp=(((g<<1)+b)<<bshft--))){g+=b;val-=temp;}}while(b>>=1);
418   return g;
419   }
420 
421 
422 // Undo premultiplied alpha
423 // The math: 255*X = (255*R * 255*A)/255, so 255*R = 255*X*255 / 255*A
dds_correct_color(FXuchar * image,FXuint size)424 static void dds_correct_color(FXuchar *image,FXuint size){
425   FXuint i,a;
426   for(i=0; i<size; i+=4){
427     if((a=image[i+3])>0){
428       image[i+0]=(image[i+0]*255)/a;
429       image[i+1]=(image[i+1]*255)/a;
430       image[i+2]=(image[i+2]*255)/a;
431       }
432     }
433   }
434 
435 
436 // Swizzle red and alpha for RXGB
dds_correct_swizzle(FXuchar * image,FXuint size)437 static void dds_correct_swizzle(FXuchar *image,FXuint size){
438   FXuint i;
439   for(i=0; i<size; i+=4){
440     image[i+2]^=image[i+3];
441     image[i+3]^=image[i+2];
442     image[i+2]^=image[i+3];
443     }
444   }
445 
446 
447 // Decompress DXT1/BC1 image
dds_decompress_DXT1(const DDSImage & dds,FXuchar * image)448 static FXbool dds_decompress_DXT1(const DDSImage& dds,FXuchar *image){
449   const FXuchar *temp=dds.data;
450   FXuint x,y,z,i,j,select,bitmask,offset;
451   FXuchar r0,g0,b0,r1,g1,b1;
452   FXushort c0,c1;
453   FXuchar colors[4][4];
454 
455   FXTRACE((100,"dds_decompress_DXT1\n"));
456 
457   // Loop over 4x4 blocks
458   for(z=0; z<dds.header.dwDepth; z+=1){
459     for(y=0; y<dds.header.dwHeight; y+=4){
460       for(x=0; x<dds.header.dwWidth; x+=4){
461 
462         // Grab two 5,6,5 colors
463         c0=(((FXushort)temp[1])<<8) | (FXushort)temp[0];
464         c1=(((FXushort)temp[3])<<8) | (FXushort)temp[2];
465 
466         r0=(c0>>11)&0x1f;
467         g0=(c0>>5)&0x3f;
468         b0=c0&0x1f;
469 
470         r1=(c1>>11)&0x1f;
471         g1=(c1>>5)&0x3f;
472         b1=c1&0x1f;
473 
474         colors[0][0]=(b0<<3)|(b0>>2);     // Convert from 5,6,5 to 8,8,8 color #0
475         colors[0][1]=(g0<<2)|(g0>>4);
476         colors[0][2]=(r0<<3)|(r0>>2);
477         colors[0][3]=0xFF;
478 
479         colors[1][0]=(b1<<3)|(b1>>2);     // Convert from 5,6,5 to 8,8,8 color #1
480         colors[1][1]=(g1<<2)|(g1>>4);
481         colors[1][2]=(r1<<3)|(r1>>2);
482         colors[1][3]=0xFF;
483 
484         // Four color block: 00=color #0, 01=color #1, 10=color #2, 11=color #3
485         if(c0>c1){
486           colors[2][0]=(2*colors[0][0]+colors[1][0]+1)/3;
487           colors[2][1]=(2*colors[0][1]+colors[1][1]+1)/3;
488           colors[2][2]=(2*colors[0][2]+colors[1][2]+1)/3;
489           colors[2][3]=255;
490           colors[3][0]=(colors[0][0]+2*colors[1][0]+1)/3;
491           colors[3][1]=(colors[0][1]+2*colors[1][1]+1)/3;
492           colors[3][2]=(colors[0][2]+2*colors[1][2]+1)/3;
493           colors[3][3]=255;
494           }
495 
496         // Three color block: 00=color #0, 01=color #1, 10=color #2, 11=transparent
497         else{
498           colors[2][0]=(colors[0][0]+colors[1][0])/2;
499           colors[2][1]=(colors[0][1]+colors[1][1])/2;
500           colors[2][2]=(colors[0][2]+colors[1][2])/2;
501           colors[2][3]=255;
502           colors[3][0]=0;
503           colors[3][1]=0;
504           colors[3][2]=0;
505           colors[3][3]=0;
506           }
507 
508         // Get index bits all at once
509         bitmask=(((FXuint)temp[7])<<24)|(((FXuint)temp[6])<<16)|(((FXuint)temp[5])<<8)|((FXuint)temp[4]);
510 
511         // Decode the bits
512         for(j=0; j<4; ++j){
513           for(i=0; i<4; ++i){
514             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
515               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
516               select=bitmask&3;
517               image[offset+0]=colors[select][0];
518               image[offset+1]=colors[select][1];
519               image[offset+2]=colors[select][2];
520               image[offset+3]=colors[select][3];
521               }
522             bitmask>>=2;
523             }
524           }
525         temp+=8;
526         }
527       }
528     }
529   return true;
530   }
531 
532 
533 // Decompress DXT3/BC2 image
dds_decompress_DXT3(const DDSImage & dds,FXuchar * image)534 static FXbool dds_decompress_DXT3(const DDSImage& dds,FXuchar *image){
535   FXuchar *temp=dds.data;
536   FXuint x,y,z,i,j,select,bitmask,offset;
537   FXuchar r0,g0,b0,r1,g1,b1;
538   FXushort c0,c1;
539   FXuchar colors[4][4];
540   FXuchar alpha[4][4];
541 
542   FXTRACE((100,"dds_decompress_DXT3\n"));
543 
544   // Loop over 4x4 blocks
545   for(z=0; z<dds.header.dwDepth; z+=1){
546     for(y=0; y<dds.header.dwHeight; y+=4){
547       for(x=0; x<dds.header.dwWidth; x+=4){
548 
549         // Grab 16 4-bit alpha values and convert them to 8-bit ones
550         alpha[0][0]=(temp[0]&15)*17;
551         alpha[0][1]=(temp[0]>>4)*17;
552         alpha[0][2]=(temp[1]&15)*17;
553         alpha[0][3]=(temp[1]>>4)*17;
554 
555         alpha[1][0]=(temp[2]&15)*17;
556         alpha[1][1]=(temp[2]>>4)*17;
557         alpha[1][2]=(temp[3]&15)*17;
558         alpha[1][3]=(temp[3]>>4)*17;
559 
560         alpha[2][0]=(temp[4]&15)*17;
561         alpha[2][1]=(temp[4]>>4)*17;
562         alpha[2][2]=(temp[5]&15)*17;
563         alpha[2][3]=(temp[5]>>4)*17;
564 
565         alpha[3][0]=(temp[6]&15)*17;
566         alpha[3][1]=(temp[6]>>4)*17;
567         alpha[3][2]=(temp[7]&15)*17;
568         alpha[3][3]=(temp[7]>>4)*17;
569 
570         // Grab two 5,6,5 colors
571         c0=(((FXushort)temp[9])<<8) | (FXushort)temp[8];
572         c1=(((FXushort)temp[11])<<8) | (FXushort)temp[10];
573 
574         r0=(c0>>11)&0x1f;
575         g0=(c0>>5)&0x3f;
576         b0=c0&0x1f;
577 
578         r1=(c1>>11)&0x1f;
579         g1=(c1>>5)&0x3f;
580         b1=c1&0x1f;
581 
582         colors[0][0]=(b0<<3)|(b0>>2);     // Convert from 5,6,5 to 8,8,8 color #0
583         colors[0][1]=(g0<<2)|(g0>>4);
584         colors[0][2]=(r0<<3)|(r0>>2);
585         colors[0][3]=0xFF;
586 
587         colors[1][0]=(b1<<3)|(b1>>2);     // Convert from 5,6,5 to 8,8,8 color #1
588         colors[1][1]=(g1<<2)|(g1>>4);
589         colors[1][2]=(r1<<3)|(r1>>2);
590         colors[1][3]=0xFF;
591 
592         // Four color block: 00=color #0, 01=color #1, 10=color #2, 11=color #3
593         colors[2][0]=(2*colors[0][0]+colors[1][0]+1)/3;
594         colors[2][1]=(2*colors[0][1]+colors[1][1]+1)/3;
595         colors[2][2]=(2*colors[0][2]+colors[1][2]+1)/3;
596         colors[2][3]=0xFF;
597 
598         colors[3][0]=(colors[0][0]+2*colors[1][0]+1)/3;
599         colors[3][1]=(colors[0][1]+2*colors[1][1]+1)/3;
600         colors[3][2]=(colors[0][2]+2*colors[1][2]+1)/3;
601         colors[3][3]=0xFF;
602 
603         // Get index bits all at once
604         bitmask=(((FXuint)temp[15])<<24)|(((FXuint)temp[14])<<16)|(((FXuint)temp[13])<<8)|((FXuint)temp[12]);
605 
606         // Decode the bits
607         for(j=0; j<4; ++j){
608           for(i=0; i<4; ++i){
609             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
610               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
611               select=bitmask&3;
612               image[offset+0]=colors[select][0];
613               image[offset+1]=colors[select][1];
614               image[offset+2]=colors[select][2];
615               image[offset+3]=alpha[j][i];
616               }
617             bitmask>>=2;
618             }
619           }
620         temp+=16;
621         }
622       }
623     }
624   return true;
625   }
626 
627 
628 // Decompress DXT2 image; has premultiplied alpha
dds_decompress_DXT2(const DDSImage & dds,FXuchar * image)629 static FXbool dds_decompress_DXT2(const DDSImage& dds,FXuchar *image){
630   if(dds_decompress_DXT3(dds,image)){
631     dds_correct_color(image,dds.header.dwWidth*dds.header.dwHeight*dds.header.dwDepth*4);
632     return true;
633     }
634   return false;
635   }
636 
637 
638 // Decompress DXT5/BC3 image
dds_decompress_DXT5(const DDSImage & dds,FXuchar * image)639 static FXbool dds_decompress_DXT5(const DDSImage& dds,FXuchar *image){
640   FXuchar *temp=dds.data;
641   FXuint x,y,z,i,j,select,bitmask,bits,offset;
642   FXuchar r0,g0,b0,r1,g1,b1;
643   FXushort c0,c1;
644   FXuchar colors[4][4];
645   FXuchar levels[8];
646   FXuchar alpha[4][4];
647 
648   FXTRACE((150,"dds_decompress_DXT5\n"));
649 
650   // Loop over 4x4 blocks
651   for(z=0; z<dds.header.dwDepth; z+=1){
652     for(y=0; y<dds.header.dwHeight; y+=4){
653       for(x=0; x<dds.header.dwWidth; x+=4){
654 
655         // Grab two 8-bit alphas
656         levels[0]=temp[0];
657         levels[1]=temp[1];
658 
659         // Six interpolated alpha levels
660         if(levels[0]>levels[1]){
661           levels[2]=(6*levels[0]+1*levels[1]+3)/7;                // bit code 010
662           levels[3]=(5*levels[0]+2*levels[1]+3)/7;                // bit code 011
663           levels[4]=(4*levels[0]+3*levels[1]+3)/7;                // bit code 100
664           levels[5]=(3*levels[0]+4*levels[1]+3)/7;                // bit code 101
665           levels[6]=(2*levels[0]+5*levels[1]+3)/7;                // bit code 110
666           levels[7]=(1*levels[0]+6*levels[1]+3)/7;                // bit code 111
667           }
668 
669         // 4 interpolated alpha levels
670         else{
671           levels[2]=(4*levels[0]+1*levels[1]+2)/5;                // Bit code 010
672           levels[3]=(3*levels[0]+2*levels[1]+2)/5;                // Bit code 011
673           levels[4]=(2*levels[0]+3*levels[1]+2)/5;                // Bit code 100
674           levels[5]=(1*levels[0]+4*levels[1]+2)/5;                // Bit code 101
675           levels[6]=0x00;                                         // Bit code 110
676           levels[7]=0xFF;                                         // Bit code 111
677           }
678 
679         // First three bytes
680         bits=(((FXuint)temp[4])<<16)|(((FXuint)temp[3])<<8)|((FXuint)temp[2]);
681         for(j=0; j<2; ++j){
682           for(i=0; i<4; ++i){
683             alpha[j][i]=levels[bits&7];
684             bits>>=3;
685             }
686           }
687 
688         // Last three bytes
689         bits=(((FXuint)temp[7])<<16)|(((FXuint)temp[6])<<8)|((FXuint)temp[5]);
690         for(j=2; j<4; ++j){
691           for(i=0; i<4; ++i){
692             alpha[j][i]=levels[bits&7];
693             bits>>=3;
694             }
695           }
696 
697         // Grab two 5,6,5 colors
698         c0=(((FXushort)temp[9])<<8) | (FXushort)temp[8];
699         c1=(((FXushort)temp[11])<<8) | (FXushort)temp[10];
700 
701         r0=(c0>>11)&0x1f;
702         g0=(c0>>5)&0x3f;
703         b0=c0&0x1f;
704 
705         r1=(c1>>11)&0x1f;
706         g1=(c1>>5)&0x3f;
707         b1=c1&0x1f;
708 
709         colors[0][0]=(b0<<3)|(b0>>2);     // Convert from 5,6,5 to 8,8,8 color #0
710         colors[0][1]=(g0<<2)|(g0>>4);
711         colors[0][2]=(r0<<3)|(r0>>2);
712         colors[0][3]=0xFF;
713 
714         colors[1][0]=(b1<<3)|(b1>>2);     // Convert from 5,6,5 to 8,8,8 color #1
715         colors[1][1]=(g1<<2)|(g1>>4);
716         colors[1][2]=(r1<<3)|(r1>>2);
717         colors[1][3]=0xFF;
718 
719         // Four color block: 00=color #0, 01=color #1, 10=color #2, 11=color #3
720         colors[2][0]=(2*colors[0][0]+colors[1][0]+1)/3;
721         colors[2][1]=(2*colors[0][1]+colors[1][1]+1)/3;
722         colors[2][2]=(2*colors[0][2]+colors[1][2]+1)/3;
723         colors[2][3]=0xFF;
724 
725         colors[3][0]=(colors[0][0]+2*colors[1][0]+1)/3;
726         colors[3][1]=(colors[0][1]+2*colors[1][1]+1)/3;
727         colors[3][2]=(colors[0][2]+2*colors[1][2]+1)/3;
728         colors[3][3]=0xFF;
729 
730         // Get index bits all at once
731         bitmask=(((FXuint)temp[15])<<24)|(((FXuint)temp[14])<<16)|(((FXuint)temp[13])<<8)|((FXuint)temp[12]);
732 
733         // Decode the bits
734         for(j=0; j<4; ++j){
735           for(i=0; i<4; ++i){
736             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
737               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
738               select=bitmask&3;
739               image[offset+0]=colors[select][0];
740               image[offset+1]=colors[select][1];
741               image[offset+2]=colors[select][2];
742               image[offset+3]=alpha[j][i];
743               }
744             bitmask>>=2;
745             }
746           }
747         temp+=16;
748         }
749       }
750     }
751   return true;
752   }
753 
754 
755 // Decompress DXT4 image; has premultiplied alpha
dds_decompress_DXT4(const DDSImage & dds,FXuchar * image)756 static FXbool dds_decompress_DXT4(const DDSImage& dds,FXuchar *image){
757   if(dds_decompress_DXT5(dds,image)){
758     dds_correct_color(image,dds.header.dwWidth*dds.header.dwHeight*dds.header.dwDepth*4);
759     return true;
760     }
761   return false;
762   }
763 
764 
765 // Decompress RXGB image
dds_decompress_RXGB(const DDSImage & dds,FXuchar * image)766 static FXbool dds_decompress_RXGB(const DDSImage& dds,FXuchar *image){
767   if(dds_decompress_DXT5(dds,image)){
768     dds_correct_swizzle(image,dds.header.dwWidth*dds.header.dwHeight*dds.header.dwDepth*4);
769     return true;
770     }
771   return false;
772   }
773 
774 
775 // Decompress BC4 (ATI1) image
dds_decompress_BC4(const DDSImage & dds,FXuchar * image)776 static FXbool dds_decompress_BC4(const DDSImage& dds,FXuchar *image){
777   FXuchar *temp=dds.data;
778   FXuint x,y,z,i,j,bits,offset;
779   FXuchar levels[8];
780 
781   FXTRACE((150,"dds_decompress_BC4\n"));
782 
783   // Loop over 4x4 blocks
784   for(z=0; z<dds.header.dwDepth; z+=1){
785     for(y=0; y<dds.header.dwHeight; y+=4){
786       for(x=0; x<dds.header.dwWidth; x+=4){
787 
788         // Grab two 8-bit grey levels
789         levels[0]=temp[0];
790         levels[1]=temp[1];
791 
792         // Six interpolated grey levels
793         if(levels[0]>levels[1]){
794           levels[2]=(6*levels[0]+1*levels[1]+3)/7;
795           levels[3]=(5*levels[0]+2*levels[1]+3)/7;
796           levels[4]=(4*levels[0]+3*levels[1]+3)/7;
797           levels[5]=(3*levels[0]+4*levels[1]+3)/7;
798           levels[6]=(2*levels[0]+5*levels[1]+3)/7;
799           levels[7]=(1*levels[0]+6*levels[1]+3)/7;
800           }
801 
802         // 4 interpolated grey levels
803         else{
804           levels[2]=(4*levels[0]+1*levels[1]+2)/5;
805           levels[3]=(3*levels[0]+2*levels[1]+2)/5;
806           levels[4]=(2*levels[0]+3*levels[1]+2)/5;
807           levels[5]=(1*levels[0]+4*levels[1]+2)/5;
808           levels[6]=0;
809           levels[7]=255;
810           }
811 
812         // First three bytes
813         bits=(((FXuint)temp[4])<<16)|(((FXuint)temp[3])<<8)|((FXuint)temp[2]);
814         for(j=0; j<2; ++j){
815           for(i=0; i<4; ++i){
816             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
817               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
818               image[offset+0]=image[offset+1]=image[offset+2]=image[offset+3]=levels[bits&7];
819               }
820             bits>>=3;
821             }
822           }
823 
824         // Last three bytes
825         bits=(((FXuint)temp[7])<<16)|(((FXuint)temp[6])<<8)|((FXuint)temp[5]);
826         for(j=2; j<4; ++j){
827           for(i=0; i<4; ++i){
828             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
829               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
830               image[offset+0]=image[offset+1]=image[offset+2]=image[offset+3]=levels[bits&7];
831               }
832             bits>>=3;
833             }
834           }
835         temp+=8;
836         }
837       }
838     }
839   return true;
840   }
841 
842 
843 // Decompress 3DC (ATI2) image
dds_decompress_3DC(const DDSImage & dds,FXuchar * image)844 static FXbool dds_decompress_3DC(const DDSImage& dds,FXuchar *image){
845   FXuchar *temp=dds.data;
846   FXuint x,y,z,i,j,redbits,grnbits,offset;
847   FXint tx,ty,t;
848   FXuchar red[8];
849   FXuchar grn[8];
850 
851   FXTRACE((150,"dds_decompress_3DC\n"));
852 
853   // Loop over 4x4 blocks
854   for(z=0; z<dds.header.dwDepth; z+=1){
855     for(y=0; y<dds.header.dwHeight; y+=4){
856       for(x=0; x<dds.header.dwWidth; x+=4){
857 
858         // Grab two reds
859         red[0]=temp[0];
860         red[1]=temp[1];
861 
862         // Six interpolated values
863         if(red[0]>red[1]){
864           red[2]=(6*red[0]+1*red[1]+3)/7;
865           red[3]=(5*red[0]+2*red[1]+3)/7;
866           red[4]=(4*red[0]+3*red[1]+3)/7;
867           red[5]=(3*red[0]+4*red[1]+3)/7;
868           red[6]=(2*red[0]+5*red[1]+3)/7;
869           red[7]=(1*red[0]+6*red[1]+3)/7;
870           }
871 
872         // Four interpolated values
873         else{
874           red[2]=(4*red[0]+1*red[1]+2)/5;
875           red[3]=(3*red[0]+2*red[1]+2)/5;
876           red[4]=(2*red[0]+3*red[1]+2)/5;
877           red[5]=(1*red[0]+4*red[1]+2)/5;
878           red[6]=0;
879           red[7]=255;
880           }
881 
882         // Grab two greens
883         grn[0]=temp[8];
884         grn[1]=temp[9];
885 
886         // Six interpolated values
887         if(grn[0]>grn[1]){
888           grn[2]=(6*grn[0]+1*grn[1]+3)/7;
889           grn[3]=(5*grn[0]+2*grn[1]+3)/7;
890           grn[4]=(4*grn[0]+3*grn[1]+3)/7;
891           grn[5]=(3*grn[0]+4*grn[1]+3)/7;
892           grn[6]=(2*grn[0]+5*grn[1]+3)/7;
893           grn[7]=(1*grn[0]+6*grn[1]+3)/7;
894           }
895 
896         // Four interpolated values
897         else{
898           grn[2]=(4*grn[0]+1*grn[1]+2)/5;
899           grn[3]=(3*grn[0]+2*grn[1]+2)/5;
900           grn[4]=(2*grn[0]+3*grn[1]+2)/5;
901           grn[5]=(1*grn[0]+4*grn[1]+2)/5;
902           grn[6]=0;
903           grn[7]=255;
904           }
905 
906         // Decode the first 3 bytes
907         redbits=(((FXuint)temp[4])<<16)|(((FXuint)temp[3])<<8)|((FXuint)temp[2]);
908         grnbits=(((FXuint)temp[12])<<16)|(((FXuint)temp[11])<<8)|((FXuint)temp[10]);
909         for(j=0; j<2; ++j){
910           for(i=0; i<4; ++i){
911             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
912               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
913               image[offset+1]=ty=grn[grnbits&7];
914               image[offset+2]=tx=red[redbits&7];
915               t=127*128-(tx-127)*(tx-128)-(ty-127)*(ty-128);
916               if(t>0){
917                 image[offset+0]=(FXuchar)(isqrt(t)+128);
918                 }
919               else{
920                 image[offset+0]=127;
921                 }
922               image[offset+3]=255;
923               }
924             redbits>>=3;
925             grnbits>>=3;
926             }
927           }
928 
929         // Decode the last 3 bytes
930         redbits=(((FXuint)temp[7])<<16)|(((FXuint)temp[6])<<8)|((FXuint)temp[5]);
931         grnbits=(((FXuint)temp[15])<<16)|(((FXuint)temp[14])<<8)|((FXuint)temp[13]);
932         for(j=2; j<4; ++j){
933           for(i=0; i<4; ++i){
934             if(((x+i)<dds.header.dwWidth) && ((y+j)<dds.header.dwHeight)){
935               offset=((z*dds.header.dwHeight+y+j)*dds.header.dwWidth+x+i)<<2;
936               image[offset+2]=tx=red[redbits&7];
937               image[offset+1]=ty=grn[grnbits&7];
938               t=127*128-(tx-127)*(tx-128)-(ty-127)*(ty-128);
939               if(t>0){
940                 image[offset+0]=(FXuchar)(isqrt(t)+128);
941                 }
942               else{
943                 image[offset+0]=127;
944                 }
945               image[offset+3]=255;
946               }
947             redbits>>=3;
948             grnbits>>=3;
949             }
950           }
951         temp+=16;
952         }
953       }
954     }
955   return true;
956   }
957 
958 
959 // Compute shifts
getShifts(FXuint mask,FXuint & shift,FXuint & mul,FXuint & sc)960 static void getShifts(FXuint mask,FXuint& shift,FXuint& mul,FXuint& sc){
961   FXuint bits=0;
962   shift=0;
963   mul=1;
964   sc=0;
965   while(!(mask&1)){
966     mask>>=1;
967     shift++;
968     }
969   while(mask&(1<<bits)) bits++;
970   while((mask*mul)<255){
971     mul=(mul<<bits)+1;
972     }
973   mask*=mul;
974   while((mask&~0xff)!=0){
975     mask>>=1;
976     sc++;
977     }
978   }
979 
980 
981 // General decompress integer pixel
dds_decompress_RGB(const DDSImage & dds,FXuchar * image,FXuint bmask,FXuint gmask,FXuint rmask,FXuint s)982 static FXbool dds_decompress_RGB(const DDSImage& dds,FXuchar *image,FXuint bmask,FXuint gmask,FXuint rmask,FXuint s){
983   FXuint rshift=0,gshift=0,bshift=0,rmul=0,gmul=0,bmul=0,rs=0,gs=0,bs=0;
984   FXuint x,y,z,offset,pix,t;
985   FXuchar *temp=dds.data;
986   FXTRACE((150,"dds_decompress_RGBA\n"));
987   if(rmask){ getShifts(rmask,rshift,rmul,rs); }
988   if(gmask){ getShifts(gmask,gshift,gmul,gs); }
989   if(bmask){ getShifts(bmask,bshift,bmul,bs); }
990   FXTRACE((150,"rmask=0x%08x rshift=%2d rmul=%3d rs=%3d\n",rmask,rshift,rmul,rs));
991   FXTRACE((150,"gmask=0x%08x gshift=%2d gmul=%3d gs=%3d\n",gmask,gshift,gmul,gs));
992   FXTRACE((150,"bmask=0x%08x bshift=%2d bmul=%3d bs=%3d\n",bmask,bshift,bmul,bs));
993   for(z=offset=0; z<dds.header.dwDepth; ++z){
994     for(y=0; y<dds.header.dwHeight; ++y){
995       for(x=0; x<dds.header.dwWidth; ++x){
996         pix=(((FXuint)temp[3])<<24)|(((FXuint)temp[2])<<16)|(((FXuint)temp[1])<<8)|((FXuint)temp[0]);
997         t=(pix&bmask)>>bshift; image[offset+0]=(t*bmul)>>bs;
998         t=(pix&gmask)>>gshift; image[offset+1]=(t*gmul)>>gs;
999         t=(pix&rmask)>>rshift; image[offset+2]=(t*rmul)>>rs;
1000         image[offset+3]=255;
1001         offset+=4;
1002         temp+=s;
1003         }
1004       }
1005     }
1006   return true;
1007   }
1008 
1009 
1010 // General decompress integer pixel with alpha
dds_decompress_RGBA(const DDSImage & dds,FXuchar * image,FXuint bmask,FXuint gmask,FXuint rmask,FXuint amask,FXuint s)1011 static FXbool dds_decompress_RGBA(const DDSImage& dds,FXuchar *image,FXuint bmask,FXuint gmask,FXuint rmask,FXuint amask,FXuint s){
1012   FXuint rshift=0,gshift=0,bshift=0,ashift=0,rmul=0,gmul=0,bmul=0,amul=0,rs=0,gs=0,bs=0,as=0;
1013   FXuint x,y,z,offset,pix,t;
1014   FXuchar *temp=dds.data;
1015   FXTRACE((150,"dds_decompress_RGBA\n"));
1016   if(rmask){ getShifts(rmask,rshift,rmul,rs); }
1017   if(gmask){ getShifts(gmask,gshift,gmul,gs); }
1018   if(bmask){ getShifts(bmask,bshift,bmul,bs); }
1019   if(amask){ getShifts(amask,ashift,amul,as); }
1020   FXTRACE((150,"rmask=0x%08x rshift=%2d rmul=%3d rs=%3d\n",rmask,rshift,rmul,rs));
1021   FXTRACE((150,"gmask=0x%08x gshift=%2d gmul=%3d gs=%3d\n",gmask,gshift,gmul,gs));
1022   FXTRACE((150,"bmask=0x%08x bshift=%2d bmul=%3d bs=%3d\n",bmask,bshift,bmul,bs));
1023   FXTRACE((150,"amask=0x%08x ashift=%2d amul=%3d as=%3d\n",amask,ashift,amul,as));
1024   for(z=offset=0; z<dds.header.dwDepth; ++z){
1025     for(y=0; y<dds.header.dwHeight; ++y){
1026       for(x=0; x<dds.header.dwWidth; ++x){
1027         pix=(((FXuint)temp[3])<<24)|(((FXuint)temp[2])<<16)|(((FXuint)temp[1])<<8)|((FXuint)temp[0]);
1028         t=(pix&bmask)>>bshift; image[offset+0]=(t*bmul)>>bs;
1029         t=(pix&gmask)>>gshift; image[offset+1]=(t*gmul)>>gs;
1030         t=(pix&rmask)>>rshift; image[offset+2]=(t*rmul)>>rs;
1031         t=(pix&amask)>>ashift; image[offset+3]=(t*amul)>>as;
1032         offset+=4;
1033         temp+=s;
1034         }
1035       }
1036     }
1037   return true;
1038   }
1039 
1040 
1041 // Decompress Luminance
dds_decompress_LUM(const DDSImage & dds,FXuchar * image,FXuint cmask,FXuint s)1042 static FXbool dds_decompress_LUM(const DDSImage& dds,FXuchar *image,FXuint cmask,FXuint s){
1043   FXuint cshift=0,cmul=0,cs=0;
1044   FXuint x,y,z,offset,pix,t;
1045   FXuchar *temp=dds.data;
1046   FXTRACE((150,"dds_decompress_LUM\n"));
1047   if(cmask){ getShifts(cmask,cshift,cmul,cs); }
1048   FXTRACE((150,"cmask=0x%08x cshift=%2d cmul=%3d cs=%3d\n",cmask,cshift,cmul,cs));
1049   for(z=offset=0; z<dds.header.dwDepth; ++z){
1050     for(y=0; y<dds.header.dwHeight; ++y){
1051       for(x=0; x<dds.header.dwWidth; ++x){
1052         pix=(((FXuint)temp[3])<<24)|(((FXuint)temp[2])<<16)|(((FXuint)temp[1])<<8)|((FXuint)temp[0]);
1053         t=(pix&cmask)>>cshift; image[offset+0]=image[offset+1]=image[offset+2]=(t*cmul)>>cs; image[offset+3]=255;
1054         offset+=4;
1055         temp+=s;
1056         }
1057       }
1058     }
1059   return true;
1060   }
1061 
1062 
1063 // Decompress Luminance and alpha
dds_decompress_LUMA(const DDSImage & dds,FXuchar * image,FXuint cmask,FXuint amask,FXuint s)1064 static FXbool dds_decompress_LUMA(const DDSImage& dds,FXuchar *image,FXuint cmask,FXuint amask,FXuint s){
1065   FXuint cshift=0,ashift=0,cmul=0,amul=0,cs=0,as=0;
1066   FXuint x,y,z,offset,pix,t;
1067   FXuchar *temp=dds.data;
1068   FXTRACE((150,"dds_decompress_LUMA\n"));
1069   if(cmask){ getShifts(cmask,cshift,cmul,cs); }
1070   if(amask){ getShifts(amask,ashift,amul,as); }
1071   FXTRACE((150,"cmask=0x%08x cshift=%2d cmul=%3d cs=%3d\n",cmask,cshift,cmul,cs));
1072   FXTRACE((150,"amask=0x%08x ashift=%2d amul=%3d as=%3d\n",amask,ashift,amul,as));
1073   for(z=offset=0; z<dds.header.dwDepth; ++z){
1074     for(y=0; y<dds.header.dwHeight; ++y){
1075       for(x=0; x<dds.header.dwWidth; ++x){
1076         pix=(((FXuint)temp[3])<<24)|(((FXuint)temp[2])<<16)|(((FXuint)temp[1])<<8)|((FXuint)temp[0]);
1077         t=(pix&cmask)>>cshift; image[offset+0]=image[offset+1]=image[offset+2]=(t*cmul)>>cs;
1078         t=(pix&amask)>>ashift; image[offset+3]=(t*amul)>>as;
1079         offset+=4;
1080         temp+=s;
1081         }
1082       }
1083     }
1084   return true;
1085   }
1086 
1087 
1088 // Decompress R16F
dds_decompress_R16F(const DDSImage & dds,FXuchar * image)1089 static FXbool dds_decompress_R16F(const DDSImage& dds,FXuchar *image){
1090   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1091   FXhalf *temp=(FXhalf*)dds.data;
1092   FXuint p=0;
1093   FXTRACE((150,"dds_decompress_R16F\n"));
1094   while(p<count){
1095     image[p+0]=0;
1096     image[p+1]=0;
1097     image[p+2]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1098     image[p+3]=255;
1099     p+=4;
1100     }
1101   return true;
1102   }
1103 
1104 
1105 // Decompress G16R16F
dds_decompress_G16R16F(const DDSImage & dds,FXuchar * image)1106 static FXbool dds_decompress_G16R16F(const DDSImage& dds,FXuchar *image){
1107   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1108   FXhalf *temp=(FXhalf*)dds.data;
1109   FXuint p=0;
1110   FXTRACE((150,"dds_decompress_G16R16F\n"));
1111   while(p<count){
1112     image[p+0]=0;
1113     image[p+2]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1114     image[p+1]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1115     image[p+3]=255;
1116     p+=4;
1117     }
1118   return true;
1119   }
1120 
1121 
1122 // Decompress A16B16G16R16F
dds_decompress_A16B16G16R16F(const DDSImage & dds,FXuchar * image)1123 static FXbool dds_decompress_A16B16G16R16F(const DDSImage& dds,FXuchar *image){
1124   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1125   FXhalf *temp=(FXhalf*)dds.data;
1126   FXuint p=0;
1127   FXTRACE((150,"dds_decompress_A16B16G16R16F\n"));
1128   while(p<count){
1129     image[p+2]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1130     image[p+1]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1131     image[p+0]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1132     image[p+3]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1133     p+=4;
1134     }
1135   return true;
1136   }
1137 
1138 
1139 // Decompress A16B16G16R16
dds_decompress_A16B16G16R16(const DDSImage & dds,FXuchar * image)1140 static FXbool dds_decompress_A16B16G16R16(const DDSImage& dds,FXuchar *image){
1141   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1142   FXushort *temp=(FXushort*)dds.data;
1143   FXuint p=0;
1144   FXTRACE((150,"dds_decompress_A16B16G16R16\n"));
1145   while(p<count){
1146     image[p+2]=(FXuchar)(*temp++ / 257);
1147     image[p+1]=(FXuchar)(*temp++ / 257);
1148     image[p+0]=(FXuchar)(*temp++ / 257);
1149     image[p+3]=(FXuchar)(*temp++ / 257);
1150     p+=4;
1151     }
1152   return true;
1153   }
1154 
1155 
1156 // Decompress R32F
dds_decompress_R32F(const DDSImage & dds,FXuchar * image)1157 static FXbool dds_decompress_R32F(const DDSImage& dds,FXuchar *image){
1158   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1159   FXfloat *temp=(FXfloat*)dds.data;
1160   FXuint p=0;
1161   FXTRACE((150,"dds_decompress_R32F\n"));
1162   while(p<count){
1163     image[p+0]=0;
1164     image[p+1]=0;
1165     image[p+2]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1166     image[p+3]=255;
1167     p+=4;
1168     }
1169   return true;
1170   }
1171 
1172 
1173 // Decompress G32R32F
dds_decompress_G32R32F(const DDSImage & dds,FXuchar * image)1174 static FXbool dds_decompress_G32R32F(const DDSImage& dds,FXuchar *image){
1175   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1176   FXfloat *temp=(FXfloat*)dds.data;
1177   FXuint p=0;
1178   FXTRACE((150,"dds_decompress_G32R32F\n"));
1179   while(p<count){
1180     image[p+2]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1181     image[p+1]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1182     image[p+0]=0;
1183     image[p+3]=255;
1184     p+=4;
1185     }
1186   return true;
1187   }
1188 
1189 
1190 // Decompress A32B32G32R32F
dds_decompress_A32B32G32R32F(const DDSImage & dds,FXuchar * image)1191 static FXbool dds_decompress_A32B32G32R32F(const DDSImage& dds,FXuchar *image){
1192   FXuint count=dds.header.dwDepth*dds.header.dwHeight*dds.header.dwWidth*4;
1193   FXfloat *temp=(FXfloat*)dds.data;
1194   FXuint p=0;
1195   FXTRACE((150,"dds_decompress_A32B32G32R32F\n"));
1196   while(p<count){
1197     image[p+2]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1198     image[p+1]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1199     image[p+0]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1200     image[p+3]=(FXuchar)(*temp++ * 255.0f + 0.5f);
1201     p+=4;
1202     }
1203   return true;
1204   }
1205 
1206 
1207 // Decompress R8G8_B8G8
dds_decompress_RGBG(const DDSImage & dds,FXuchar * image)1208 static FXbool dds_decompress_RGBG(const DDSImage& dds,FXuchar *image){
1209   FXuint x,y,z,offset;
1210   FXuchar *temp=dds.data;
1211   FXTRACE((150,"dds_decompress_RGBG\n"));
1212   for(z=offset=0; z<dds.header.dwDepth; z+=1){
1213     for(y=0; y<dds.header.dwHeight; y+=1){
1214       for(x=0; x<dds.header.dwWidth; x+=2){
1215         image[offset+0]=temp[3];
1216         image[offset+1]=temp[0];
1217         image[offset+2]=temp[1];
1218         image[offset+3]=255;
1219         image[offset+4]=temp[3];
1220         image[offset+5]=temp[2];
1221         image[offset+6]=temp[1];
1222         image[offset+7]=255;
1223         offset+=8;
1224         temp+=4;
1225         }
1226       }
1227     }
1228   return true;
1229   }
1230 
1231 
1232 // Decompress G8R8_G8B8
dds_decompress_GRGB(const DDSImage & dds,FXuchar * image)1233 static FXbool dds_decompress_GRGB(const DDSImage& dds,FXuchar *image){
1234   FXuint x,y,z,offset;
1235   FXuchar *temp=dds.data;
1236   FXTRACE((150,"dds_decompress_GRGB\n"));
1237   for(z=offset=0; z<dds.header.dwDepth; z+=1){
1238     for(y=0; y<dds.header.dwHeight; y+=1){
1239       for(x=0; x<dds.header.dwWidth; x+=2){
1240         image[offset+0]=temp[2];
1241         image[offset+1]=temp[1];
1242         image[offset+2]=temp[0];
1243         image[offset+3]=255;
1244         image[offset+4]=temp[2];
1245         image[offset+5]=temp[3];
1246         image[offset+6]=temp[0];
1247         image[offset+7]=255;
1248         offset+=8;
1249         temp+=4;
1250         }
1251       }
1252     }
1253   return true;
1254   }
1255 
1256 
1257 // Check if stream contains a BMP
fxcheckDDS(FXStream & store)1258 FXbool fxcheckDDS(FXStream& store){
1259   FXuchar signature[4];
1260   store.load(signature,4);
1261   store.position(-4,FXFromCurrent);
1262   return signature[0]=='D' && signature[1]=='D' && signature[2]=='S' && signature[3]==' ';
1263   }
1264 
1265 
1266 // Load image from stream
fxloadDDS(FXStream & store,FXColor * & data,FXint & width,FXint & height,FXint & depth)1267 FXbool fxloadDDS(FXStream& store,FXColor*& data,FXint& width,FXint& height,FXint& depth){
1268   FXbool swap=store.swapBytes();
1269   FXbool ok=false;
1270   DDSImage dds;
1271 
1272   // Null out
1273   data=NULL;
1274   width=0;
1275   height=0;
1276   depth=0;
1277 
1278   // Bitmaps are little-endian
1279   store.setBigEndian(false);
1280 
1281   // Check header
1282   store >> dds.magic;
1283   if(dds.magic==DDSD_MAGIC){
1284     store >> dds.header.dwSize;
1285     if(dds.header.dwSize!=124) goto x;                  // Unexpected size; bail!
1286     store >> dds.header.dwFlags;
1287     store >> dds.header.dwHeight;
1288     store >> dds.header.dwWidth;
1289     store >> dds.header.dwLinearSize;
1290     store >> dds.header.dwDepth;
1291     store >> dds.header.dwMipMapCount;
1292     store.load(dds.header.dwReserved1,11);
1293     store >> dds.header.ddpf.dwSize;
1294     store >> dds.header.ddpf.dwFlags;
1295     store >> dds.header.ddpf.dwFourCC;
1296     store >> dds.header.ddpf.dwRGBBitCount;
1297     store >> dds.header.ddpf.dwRBitMask;
1298     store >> dds.header.ddpf.dwGBitMask;
1299     store >> dds.header.ddpf.dwBBitMask;
1300     store >> dds.header.ddpf.dwABitMask;
1301     store >> dds.header.dwCaps;
1302     store >> dds.header.dwCaps2;
1303     store >> dds.header.dwCaps3;
1304     store >> dds.header.dwCaps4;
1305     store >> dds.header.dwReserved2;
1306 
1307     // Load DX10 Header if present
1308     if(dds.header.ddpf.dwFourCC==D3DFMT_DX10){          // Parse over DX10 header
1309       store >> dds.xheader.dxgiFormat;
1310       store >> dds.xheader.resourceDimension;
1311       store >> dds.xheader.miscFlag;
1312       store >> dds.xheader.arraySize;
1313       store >> dds.xheader.reserved;
1314       }
1315     else{
1316       dds.xheader.dxgiFormat=DXGI_FORMAT_UNKNOWN;
1317       dds.xheader.resourceDimension=D3D10_RESOURCE_DIMENSION_UNKNOWN;
1318       dds.xheader.miscFlag=0;
1319       dds.xheader.arraySize=1;
1320       dds.xheader.reserved=0;
1321       }
1322 
1323     FXTRACE((150,"dds.magic=0x%08x\n",dds.magic));
1324     FXTRACE((150,"dds.header.dwSize=%d\n",dds.header.dwSize));
1325     FXTRACE((150,"dds.header.dwFlags=0x%08x: %s%s%s%s%s%s%s%s\n",dds.header.dwFlags,(dds.header.dwFlags&DDSD_CAPS)?"DDSD_CAPS ":"",(dds.header.dwFlags&DDSD_HEIGHT)?"DDSD_HEIGHT ":"",(dds.header.dwFlags&DDSD_WIDTH)?"DDSD_WIDTH ":"",(dds.header.dwFlags&DDSD_PITCH)?"DDSD_PITCH ":"",(dds.header.dwFlags&DDSD_PIXELFORMAT)?"DDSD_PIXELFORMAT ":"",(dds.header.dwFlags&DDSD_MIPMAPCOUNT)?"DDSD_MIPMAPCOUNT ":"",(dds.header.dwFlags&DDSD_LINEARSIZE)?"DDSD_LINEARSIZE ":"",(dds.header.dwFlags&DDSD_DEPTH)?"DDSD_DEPTH":""));
1326     FXTRACE((150,"dds.header.dwHeight=%d\n",dds.header.dwHeight));
1327     FXTRACE((150,"dds.header.dwWidth=%d\n",dds.header.dwWidth));
1328     FXTRACE((150,"dds.header.dwDepth=%d\n",dds.header.dwDepth));
1329     FXTRACE((150,"dds.header.dwLinearSize=%d\n",dds.header.dwLinearSize));
1330     FXTRACE((150,"dds.header.dwMipMapCount=%d\n",dds.header.dwMipMapCount));
1331     FXTRACE((150,"dds.header.ddpf.dwSize=%d\n",dds.header.ddpf.dwSize));
1332     FXTRACE((150,"dds.header.ddpf.dwFlags=0x%08x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",dds.header.ddpf.dwFlags,(dds.header.ddpf.dwFlags&DDPF_ALPHAPIXELS)?"DDPF_ALPHAPIXELS ":"",(dds.header.ddpf.dwFlags&DDPF_ALPHA)?"DDPF_ALPHA ":"",(dds.header.ddpf.dwFlags&DDPF_FOURCC)?"DDPF_FOURCC ":"",(dds.header.ddpf.dwFlags&DDPF_PALETTEINDEXED4)?"DDPF_PALETTEINDEXED4 ":"",(dds.header.ddpf.dwFlags&DDPF_PALETTEINDEXED8)?"DDPF_PALETTEINDEXED8 ":"",(dds.header.ddpf.dwFlags&DDPF_RGB)?"DDPF_RGB ":"",(dds.header.ddpf.dwFlags&DDPF_COMPRESSED)?"DDPF_COMPRESSED ":"",(dds.header.ddpf.dwFlags&DDPF_RGBTOYUV)?"DDPF_RGBTOYUV ":"",(dds.header.ddpf.dwFlags&DDPF_YUV)?"DDPF_YUV ":"",(dds.header.ddpf.dwFlags&DDPF_ZBUFFER)?"DDPF_ZBUFFER ":"",(dds.header.ddpf.dwFlags&DDPF_PALETTEINDEXED1)?"DDPF_PALETTEINDEXED1 ":"",(dds.header.ddpf.dwFlags&DDPF_PALETTEINDEXED2)?"DDPF_PALETTEINDEXED2 ":"",(dds.header.ddpf.dwFlags&DDPF_ZPIXELS)?"DDPF_ZPIXELS ":"",(dds.header.ddpf.dwFlags&DDPF_STENCILBUFFER)?"DDPF_STENCILBUFFER ":"",(dds.header.ddpf.dwFlags&DDPF_ALPHAPREMULT)?"DDPF_ALPHAPREMULT ":"",(dds.header.ddpf.dwFlags&DDPF_LUMINANCE)?"DDPF_LUMINANCE ":"",(dds.header.ddpf.dwFlags&DDPF_BUMPLUMINANCE)?"DDPF_BUMPLUMINANCE ":"",(dds.header.ddpf.dwFlags&DDPF_NORMAL)?"DDPF_NORMAL":""));
1333     FXTRACE((150,"dds.header.ddpf.dwFourCC=0x%08x (%d) (%c%c%c%c)\n",dds.header.ddpf.dwFourCC,dds.header.ddpf.dwFourCC,dds.header.ddpf.dwFourCC&255,(dds.header.ddpf.dwFourCC>>8)&255,(dds.header.ddpf.dwFourCC>>16)&255,(dds.header.ddpf.dwFourCC>>24)&255));
1334     FXTRACE((150,"dds.header.ddpf.dwRGBBitCount=%d\n",dds.header.ddpf.dwRGBBitCount));
1335     FXTRACE((150,"dds.header.ddpf.dwRBitMask=0x%08x\n",dds.header.ddpf.dwRBitMask));
1336     FXTRACE((150,"dds.header.ddpf.dwGBitMask=0x%08x\n",dds.header.ddpf.dwGBitMask));
1337     FXTRACE((150,"dds.header.ddpf.dwBBitMask=0x%08x\n",dds.header.ddpf.dwBBitMask));
1338     FXTRACE((150,"dds.header.ddpf.dwABitMask=0x%08x\n",dds.header.ddpf.dwABitMask));
1339 
1340     FXTRACE((150,"dds.header.dwCaps =0x%08x: %s%s%s\n",dds.header.dwCaps,(dds.header.dwCaps&DDSCAPS_COMPLEX)?"DDSCAPS_COMPLEX ":"",(dds.header.dwCaps&DDSCAPS_TEXTURE)?"DDSCAPS_TEXTURE ":"",(dds.header.dwCaps&DDSCAPS_MIPMAP)?"DDSCAPS_MIPMAP":""));
1341     FXTRACE((150,"dds.header.dwCaps2=0x%08x: %s%s%s%s%s%s%s%s\n",dds.header.dwCaps2,(dds.header.dwCaps2&DDSCAPS2_CUBEMAP)?"DDSCAPS2_CUBEMAP ":"",(dds.header.dwCaps2&DDSCAPS2_VOLUME)?"DDSCAPS2_VOLUME ":"",(dds.header.dwCaps2&DDSCAPS2_CUBEMAP_POSITIVEX)?"DDSCAPS2_CUBEMAP_POSITIVEX ":"",(dds.header.dwCaps2&DDSCAPS2_CUBEMAP_NEGATIVEX)?"DDSCAPS2_CUBEMAP_NEGATIVEX ":"",(dds.header.dwCaps2&DDSCAPS2_CUBEMAP_POSITIVEY)?"DDSCAPS2_CUBEMAP_POSITIVEY ":"",(dds.header.dwCaps2&DDSCAPS2_CUBEMAP_NEGATIVEY)?"DDSCAPS2_CUBEMAP_NEGATIVEY ":"",(dds.header.dwCaps2&DDSCAPS2_CUBEMAP_POSITIVEZ)?"DDSCAPS2_CUBEMAP_POSITIVEZ ":"",(dds.header.dwCaps2&DDSCAPS2_CUBEMAP_NEGATIVEZ)?"DDSCAPS2_CUBEMAP_NEGATIVEZ ":""));
1342     FXTRACE((150,"dds.header.dwCaps3=0x%08x\n",dds.header.dwCaps3));
1343     FXTRACE((150,"dds.header.dwCaps4=0x%08x\n",dds.header.dwCaps4));
1344 
1345     FXTRACE((150,"dds.xheader.dxgiFormat=%d\n",dds.xheader.dxgiFormat));
1346     FXTRACE((150,"dds.xheader.resourceDimension=%d\n",dds.xheader.resourceDimension));
1347     FXTRACE((150,"dds.xheader.miscFlag=%d\n",dds.xheader.miscFlag));
1348     FXTRACE((150,"dds.xheader.arraySize=%d\n",dds.xheader.arraySize));
1349 
1350     // Fix depth
1351     if(!(dds.header.dwFlags&DDSD_DEPTH) || (dds.header.dwDepth==0)) dds.header.dwDepth=1;
1352 
1353     // Fix mipmap count
1354     if(!(dds.header.dwFlags&DDSD_MIPMAPCOUNT) || (dds.header.dwMipMapCount==0)) dds.header.dwMipMapCount=1;
1355 
1356     // Set image size to return
1357     width=dds.header.dwWidth;
1358     height=dds.header.dwHeight;
1359     depth=dds.header.dwDepth;
1360 
1361     // Perhaps broken format; assume DDPF_FOURCC
1362     if(dds.header.ddpf.dwFlags==0 && dds.header.ddpf.dwFourCC!=0){
1363       dds.header.ddpf.dwFlags=DDPF_FOURCC;
1364       }
1365 
1366     // Figure out how much to allocate for compressed data
1367     if(dds.header.ddpf.dwFlags&DDPF_FOURCC){
1368       switch(dds.header.ddpf.dwFourCC){
1369         case D3DFMT_DXT1:
1370         case D3DFMT_ATI1:
1371           dds.size=((width+3)>>2)*((height+3)>>2)*depth*8;
1372           break;
1373         case D3DFMT_DXT2:
1374         case D3DFMT_DXT3:
1375         case D3DFMT_DXT4:
1376         case D3DFMT_DXT5:
1377         case D3DFMT_ATI2:
1378         case D3DFMT_RXGB:
1379           dds.size=((width+3)>>2)*((height+3)>>2)*depth*16;
1380           break;
1381         case D3DFMT_A1:
1382           dds.size=((width+7)>>3)*height*depth;
1383           break;
1384         case D3DFMT_A2XY:
1385         case D3DFMT_UYVY:
1386         case D3DFMT_YUY2:
1387           goto x;       // Unsupported compression code
1388         case D3DFMT_R16F:
1389         case D3DFMT_R5G6B5:
1390         case D3DFMT_X1R5G5B5:
1391         case D3DFMT_A1R5G5B5:
1392         case D3DFMT_A4R4G4B4:
1393         case D3DFMT_A8R3G3B2:
1394         case D3DFMT_X4R4G4B4:
1395         case D3DFMT_R8G8_B8G8:
1396         case D3DFMT_G8R8_G8B8:
1397         case D3DFMT_L16:
1398         case D3DFMT_A8P8:
1399         case D3DFMT_A8L8:
1400           dds.size=width*height*depth*2;
1401           break;
1402         case D3DFMT_G16R16F:
1403         case D3DFMT_A8R8G8B8:
1404         case D3DFMT_X8R8G8B8:
1405         case D3DFMT_A8B8G8R8:
1406         case D3DFMT_X8B8G8R8:
1407         case D3DFMT_G16R16:
1408         case D3DFMT_A2R10G10B10:
1409         case D3DFMT_R32F:
1410         case D3DFMT_A2B10G10R10:
1411         case D3DFMT_A2B10G10R10_XR_BIAS:
1412           dds.size=width*height*depth*4;
1413           break;
1414         case D3DFMT_A32B32G32R32F:
1415           dds.size=width*height*depth*16;
1416           break;
1417         case D3DFMT_R8G8B8:
1418           dds.size=width*height*depth*3;
1419           break;
1420         case D3DFMT_R3G3B2:
1421         case D3DFMT_A8:
1422         case D3DFMT_P8:
1423         case D3DFMT_L8:
1424         case D3DFMT_A4L4:
1425           dds.size=width*height*depth;
1426           break;
1427         case D3DFMT_A16B16G16R16F:
1428         case D3DFMT_G32R32F:
1429         case D3DFMT_A16B16G16R16:
1430           dds.size=width*height*depth*8;
1431           break;
1432         default:
1433           goto x;       // Unsupported compression code
1434         }
1435       }
1436 
1437     // Figure out how much to allocate for RGB
1438     else if(dds.header.ddpf.dwFlags&DDPF_RGB){
1439       dds.size=width*height*depth*dds.header.ddpf.dwRGBBitCount/8;
1440       }
1441 
1442     // Luminance
1443     else if(dds.header.ddpf.dwFlags&DDPF_LUMINANCE){
1444       dds.size=width*height*depth*dds.header.ddpf.dwRGBBitCount/8;
1445       }
1446 
1447     // Unsupported format
1448     else{
1449       goto x;           // Not supported
1450       }
1451 
1452     FXTRACE((150,"dds.size=%d\n",dds.size));
1453 
1454     // Allocate array for compressed data
1455     if(allocElms(dds.data,dds.size)){
1456 
1457       // Allocate output image
1458       if(allocElms(data,width*height*depth)){
1459 
1460         // Load temp array
1461         store.load(dds.data,dds.size);
1462 
1463         // FOURCC format
1464         if(dds.header.ddpf.dwFlags&DDPF_FOURCC){
1465           switch(dds.header.ddpf.dwFourCC){
1466             case D3DFMT_DXT1:
1467               ok=dds_decompress_DXT1(dds,(FXuchar*)data);
1468               break;
1469             case D3DFMT_DXT2:
1470               ok=dds_decompress_DXT2(dds,(FXuchar*)data);
1471               break;
1472             case D3DFMT_DXT3:
1473               ok=dds_decompress_DXT3(dds,(FXuchar*)data);
1474               break;
1475             case D3DFMT_DXT4:
1476               ok=dds_decompress_DXT4(dds,(FXuchar*)data);
1477               break;
1478             case D3DFMT_DXT5:
1479               ok=dds_decompress_DXT5(dds,(FXuchar*)data);
1480               break;
1481             case D3DFMT_ATI1:
1482               ok=dds_decompress_BC4(dds,(FXuchar*)data);
1483               break;
1484             case D3DFMT_ATI2:
1485               ok=dds_decompress_3DC(dds,(FXuchar*)data);
1486               break;
1487             case D3DFMT_RXGB:
1488               ok=dds_decompress_RXGB(dds,(FXuchar*)data);
1489               break;
1490             case D3DFMT_A2XY:
1491             case D3DFMT_UYVY:
1492             case D3DFMT_YUY2:
1493               break;
1494             case D3DFMT_R8G8_B8G8:
1495               ok=dds_decompress_RGBG(dds,(FXuchar*)data);
1496               break;
1497             case D3DFMT_G8R8_G8B8:
1498               ok=dds_decompress_GRGB(dds,(FXuchar*)data);
1499               break;
1500             case D3DFMT_R16F:
1501               ok=dds_decompress_R16F(dds,(FXuchar*)data);
1502               break;
1503             case D3DFMT_G16R16F:
1504               ok=dds_decompress_G16R16F(dds,(FXuchar*)data);
1505               break;
1506             case D3DFMT_A16B16G16R16F:
1507               ok=dds_decompress_A16B16G16R16F(dds,(FXuchar*)data);
1508               break;
1509             case D3DFMT_R32F:
1510               ok=dds_decompress_R32F(dds,(FXuchar*)data);
1511               break;
1512             case D3DFMT_G32R32F:
1513               ok=dds_decompress_G32R32F(dds,(FXuchar*)data);
1514               break;
1515             case D3DFMT_A32B32G32R32F:
1516               ok=dds_decompress_A32B32G32R32F(dds,(FXuchar*)data);
1517               break;
1518             case D3DFMT_R8G8B8:
1519               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x0000FF,0x00FF00,0xFF0000,3);
1520               break;
1521             case D3DFMT_A8R8G8B8:
1522               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x000000FF,0x0000FF00,0x00FF0000,0xFF000000,4);
1523               break;
1524             case D3DFMT_X8R8G8B8:
1525               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x0000FF,0x00FF00,0xFF0000,4);
1526               break;
1527             case D3DFMT_R5G6B5:
1528               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x001F,0x07E0,0xF800,2);
1529               break;
1530             case D3DFMT_X1R5G5B5:
1531               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x001F,0x03E0,0x7C00,2);
1532               break;
1533             case D3DFMT_A1R5G5B5:
1534               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x001F,0x03E0,0x7C00,0x8000,2);
1535               break;
1536             case D3DFMT_A4R4G4B4:
1537               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x000F,0x00F0,0x0F00,0xF000,2);
1538               break;
1539             case D3DFMT_R3G3B2:
1540               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x07,0x38,0xC0,1);
1541               break;
1542             case D3DFMT_A8:
1543               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x00,0x00,0x00,0xFF,1);
1544               break;
1545             case D3DFMT_A8R3G3B2:
1546               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x0003,0x001C,0x00E0,0xFF00,2);
1547               break;
1548             case D3DFMT_X4R4G4B4:
1549               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x000F,0x00F0,0x0F00,2);
1550               break;
1551             case D3DFMT_A8B8G8R8:
1552               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x00FF0000,0x0000FF00,0x000000FF,0xFF000000,4);
1553               break;
1554             case D3DFMT_X8B8G8R8:
1555               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x00FF0000,0x0000FF00,0x000000FF,4);
1556               break;
1557             case D3DFMT_G16R16:
1558               ok=dds_decompress_RGB(dds,(FXuchar*)data,0x00000000,0xFFFF0000,0x0000FFFF,4);
1559               break;
1560             case D3DFMT_A2R10G10B10:
1561               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x000003FF,0x000FFC00,0x3FF00000,0xC0000000,2);
1562               break;
1563             case D3DFMT_A16B16G16R16:
1564               ok=dds_decompress_A16B16G16R16(dds,(FXuchar*)data);
1565               break;
1566             case D3DFMT_P8:
1567             case D3DFMT_L8:
1568               ok=dds_decompress_LUM(dds,(FXuchar*)data,0xFF,1);
1569               break;
1570             case D3DFMT_A8P8:
1571             case D3DFMT_A8L8:
1572               ok=dds_decompress_LUMA(dds,(FXuchar*)data,0x00FF,0xFF00,2);
1573               break;
1574             case D3DFMT_A4L4:
1575               ok=dds_decompress_LUMA(dds,(FXuchar*)data,0x0F,0xF0,1);
1576               break;
1577             case D3DFMT_L16:
1578               ok=dds_decompress_LUM(dds,(FXuchar*)data,0xFFFF,2);
1579               break;
1580             case D3DFMT_A1:
1581               break;
1582             case D3DFMT_A2B10G10R10:
1583             case D3DFMT_A2B10G10R10_XR_BIAS:
1584               ok=dds_decompress_RGBA(dds,(FXuchar*)data,0x3FF00000,0x000FFC00,0x000003FF,0xC0000000,2);
1585               break;
1586             }
1587           }
1588 
1589         // RGB format
1590         else if(dds.header.ddpf.dwFlags&DDPF_RGB){
1591           if(dds.header.ddpf.dwFlags&DDPF_ALPHAPIXELS)
1592             ok=dds_decompress_RGBA(dds,(FXuchar*)data,dds.header.ddpf.dwBBitMask,dds.header.ddpf.dwGBitMask,dds.header.ddpf.dwRBitMask,dds.header.ddpf.dwABitMask,(dds.header.ddpf.dwRGBBitCount+7)>>3);
1593           else
1594             ok=dds_decompress_RGB(dds,(FXuchar*)data,dds.header.ddpf.dwBBitMask,dds.header.ddpf.dwGBitMask,dds.header.ddpf.dwRBitMask,(dds.header.ddpf.dwRGBBitCount+7)>>3);
1595           }
1596 
1597         // Lumimance format
1598         else if(dds.header.ddpf.dwFlags&DDPF_LUMINANCE){
1599           if(dds.header.ddpf.dwFlags&DDPF_ALPHAPIXELS)
1600             ok=dds_decompress_LUMA(dds,(FXuchar*)data,dds.header.ddpf.dwRBitMask,dds.header.ddpf.dwABitMask,(dds.header.ddpf.dwRGBBitCount+7)/8);
1601           else
1602             ok=dds_decompress_LUM(dds,(FXuchar*)data,dds.header.ddpf.dwRBitMask,(dds.header.ddpf.dwRGBBitCount+7)/8);
1603           }
1604         }
1605 
1606       // Free temp array of encoded pixels
1607       freeElms(dds.data);
1608       }
1609     }
1610 
1611   // Restore original byte orientation
1612 x:store.swapBytes(swap);
1613 
1614   // Done
1615   return ok;
1616   }
1617 
1618 
1619 // Save a dds file to a stream
fxsaveDDS(FXStream & store,FXColor * data,FXint width,FXint height,FXint depth)1620 FXbool fxsaveDDS(FXStream& store,FXColor* data,FXint width,FXint height,FXint depth){
1621   DDSImage dds;
1622   FXbool swap;
1623 
1624   // Must make sense
1625   if(!data || width<=0 || height<=0 || depth<=0) return false;
1626 
1627   // Switch byte order for the duration
1628   swap=store.swapBytes();
1629   store.setBigEndian(false);
1630 
1631   // Initialize header
1632   dds.magic=DDSD_MAGIC;
1633   dds.header.dwSize=sizeof(DDSHeader);
1634   dds.header.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_MIPMAPCOUNT|DDSD_LINEARSIZE;
1635   dds.header.dwHeight=height;
1636   dds.header.dwWidth=width;
1637   dds.header.dwLinearSize=width*height*depth*4;
1638   dds.header.dwDepth=depth;
1639   dds.header.dwMipMapCount=1;
1640   memset(dds.header.dwReserved1,0,sizeof(dds.header.dwReserved1));
1641   dds.header.ddpf.dwSize=sizeof(DDSPixelFormat);
1642   dds.header.ddpf.dwFlags=DDPF_RGB;
1643   dds.header.ddpf.dwFourCC=0;
1644   dds.header.ddpf.dwRGBBitCount=32;
1645   dds.header.ddpf.dwBBitMask=0x000000ff;
1646   dds.header.ddpf.dwGBitMask=0x0000ff00;
1647   dds.header.ddpf.dwRBitMask=0x00ff0000;
1648   dds.header.ddpf.dwABitMask=0xff000000;
1649   if(1<depth){
1650     dds.header.dwCaps=DDSCAPS_COMPLEX|DDSCAPS_TEXTURE;
1651     dds.header.dwCaps2=DDSCAPS2_VOLUME;
1652     }
1653   else{
1654     dds.header.dwCaps=DDSCAPS_TEXTURE;
1655     dds.header.dwCaps2=0;
1656     }
1657   dds.header.dwCaps3=0;
1658   dds.header.dwCaps4=0;
1659   dds.header.dwReserved2=0;
1660 
1661   // Start saving now
1662   store << dds.magic;
1663   store << dds.header.dwSize;
1664   store << dds.header.dwFlags;
1665   store << dds.header.dwHeight;
1666   store << dds.header.dwWidth;
1667   store << dds.header.dwLinearSize;
1668   store << dds.header.dwDepth;
1669   store << dds.header.dwMipMapCount;
1670   store.save(dds.header.dwReserved1,11);
1671   store << dds.header.ddpf.dwSize;
1672   store << dds.header.ddpf.dwFlags;
1673   store << dds.header.ddpf.dwFourCC;
1674   store << dds.header.ddpf.dwRGBBitCount;
1675   store << dds.header.ddpf.dwRBitMask;
1676   store << dds.header.ddpf.dwGBitMask;
1677   store << dds.header.ddpf.dwBBitMask;
1678   store << dds.header.ddpf.dwABitMask;
1679   store << dds.header.dwCaps;
1680   store << dds.header.dwCaps2;
1681   store << dds.header.dwCaps3;
1682   store << dds.header.dwCaps4;
1683   store << dds.header.dwReserved2;
1684 
1685   // Data array
1686   store.save(data,width*height*depth);
1687 
1688   store.swapBytes(swap);
1689   return true;
1690   }
1691 
1692 }
1693