Apply second half of [#21590] .dds textures: fix for DXT1n format + sync with upstrea...
[blender.git] / source / blender / imbuf / intern / dds / DirectDrawSurface.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributors: Amorilia (amorilia@users.sourceforge.net)
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/imbuf/intern/dds/DirectDrawSurface.cpp
26  *  \ingroup imbdds
27  */
28
29
30 /*
31  * This file is based on a similar file from the NVIDIA texture tools
32  * (http://nvidia-texture-tools.googlecode.com/)
33  *
34  * Original license from NVIDIA follows.
35  */
36
37 // Copyright NVIDIA Corporation 2007 -- Ignacio Castano <icastano@nvidia.com>
38 // 
39 // Permission is hereby granted, free of charge, to any person
40 // obtaining a copy of this software and associated documentation
41 // files (the "Software"), to deal in the Software without
42 // restriction, including without limitation the rights to use,
43 // copy, modify, merge, publish, distribute, sublicense, and/or sell
44 // copies of the Software, and to permit persons to whom the
45 // Software is furnished to do so, subject to the following
46 // conditions:
47 // 
48 // The above copyright notice and this permission notice shall be
49 // included in all copies or substantial portions of the Software.
50 // 
51 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
52 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
53 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
54 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
55 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
56 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
57 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
58 // OTHER DEALINGS IN THE SOFTWARE.
59
60 #include <DirectDrawSurface.h>
61 #include <BlockDXT.h>
62 #include <PixelFormat.h>
63
64 #include <stdio.h> // printf
65 #include <math.h>  // sqrt
66 #include <sys/types.h>
67
68 /*** declarations ***/
69
70 #if !defined(MAKEFOURCC)
71 #       define MAKEFOURCC(ch0, ch1, ch2, ch3) \
72     (uint(uint8(ch0)) | (uint(uint8(ch1)) << 8) | \
73     (uint(uint8(ch2)) << 16) | (uint(uint8(ch3)) << 24 ))
74 #endif
75
76 static const uint FOURCC_NVTT = MAKEFOURCC('N', 'V', 'T', 'T');
77 static const uint FOURCC_DDS = MAKEFOURCC('D', 'D', 'S', ' ');
78 static const uint FOURCC_DXT1 = MAKEFOURCC('D', 'X', 'T', '1');
79 static const uint FOURCC_DXT2 = MAKEFOURCC('D', 'X', 'T', '2');
80 static const uint FOURCC_DXT3 = MAKEFOURCC('D', 'X', 'T', '3');
81 static const uint FOURCC_DXT4 = MAKEFOURCC('D', 'X', 'T', '4');
82 static const uint FOURCC_DXT5 = MAKEFOURCC('D', 'X', 'T', '5');
83 static const uint FOURCC_RXGB = MAKEFOURCC('R', 'X', 'G', 'B');
84 static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1');
85 static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
86
87 static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y');
88         
89 static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0');
90
91 static const uint FOURCC_UVER = MAKEFOURCC('U', 'V', 'E', 'R');
92
93 // 32 bit RGB formats.
94 static const uint D3DFMT_R8G8B8 = 20;
95 static const uint D3DFMT_A8R8G8B8 = 21;
96 static const uint D3DFMT_X8R8G8B8 = 22;
97 static const uint D3DFMT_R5G6B5 = 23;
98 static const uint D3DFMT_X1R5G5B5 = 24;
99 static const uint D3DFMT_A1R5G5B5 = 25;
100 static const uint D3DFMT_A4R4G4B4 = 26;
101 static const uint D3DFMT_R3G3B2 = 27;
102 static const uint D3DFMT_A8 = 28;
103 static const uint D3DFMT_A8R3G3B2 = 29;
104 static const uint D3DFMT_X4R4G4B4 = 30;
105 static const uint D3DFMT_A2B10G10R10 = 31;
106 static const uint D3DFMT_A8B8G8R8 = 32;
107 static const uint D3DFMT_X8B8G8R8 = 33;
108 static const uint D3DFMT_G16R16 = 34;
109 static const uint D3DFMT_A2R10G10B10 = 35;
110
111 static const uint D3DFMT_A16B16G16R16 = 36;
112
113 // Palette formats.
114 static const uint D3DFMT_A8P8 = 40;
115 static const uint D3DFMT_P8 = 41;
116         
117 // Luminance formats.
118 static const uint D3DFMT_L8 = 50;
119 static const uint D3DFMT_A8L8 = 51;
120 static const uint D3DFMT_A4L4 = 52;
121 static const uint D3DFMT_L16 = 81;
122
123 // Floating point formats
124 static const uint D3DFMT_R16F = 111;
125 static const uint D3DFMT_G16R16F = 112;
126 static const uint D3DFMT_A16B16G16R16F = 113;
127 static const uint D3DFMT_R32F = 114;
128 static const uint D3DFMT_G32R32F = 115;
129 static const uint D3DFMT_A32B32G32R32F = 116;
130         
131 static const uint DDSD_CAPS = 0x00000001U;
132 static const uint DDSD_PIXELFORMAT = 0x00001000U;
133 static const uint DDSD_WIDTH = 0x00000004U;
134 static const uint DDSD_HEIGHT = 0x00000002U;
135 static const uint DDSD_PITCH = 0x00000008U;
136 static const uint DDSD_MIPMAPCOUNT = 0x00020000U;
137 static const uint DDSD_LINEARSIZE = 0x00080000U;
138 static const uint DDSD_DEPTH = 0x00800000U;
139         
140 static const uint DDSCAPS_COMPLEX = 0x00000008U;
141 static const uint DDSCAPS_TEXTURE = 0x00001000U;
142 static const uint DDSCAPS_MIPMAP = 0x00400000U;
143 static const uint DDSCAPS2_VOLUME = 0x00200000U;
144 static const uint DDSCAPS2_CUBEMAP = 0x00000200U;
145
146 static const uint DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400U;
147 static const uint DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800U;
148 static const uint DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000U;
149 static const uint DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000U;
150 static const uint DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000U;
151 static const uint DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000U;
152 static const uint DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000FC00U;
153
154 static const uint DDPF_ALPHAPIXELS = 0x00000001U;
155 static const uint DDPF_ALPHA = 0x00000002U;
156 static const uint DDPF_FOURCC = 0x00000004U;
157 static const uint DDPF_RGB = 0x00000040U;
158 static const uint DDPF_PALETTEINDEXED1 = 0x00000800U;
159 static const uint DDPF_PALETTEINDEXED2 = 0x00001000U;
160 static const uint DDPF_PALETTEINDEXED4 = 0x00000008U;
161 static const uint DDPF_PALETTEINDEXED8 = 0x00000020U;
162 static const uint DDPF_LUMINANCE = 0x00020000U;
163 static const uint DDPF_ALPHAPREMULT = 0x00008000U;
164
165 // Custom NVTT flags.
166 static const uint DDPF_NORMAL = 0x80000000U;  
167 static const uint DDPF_SRGB = 0x40000000U;
168
169         // DX10 formats.
170         enum DXGI_FORMAT
171         {
172                 DXGI_FORMAT_UNKNOWN = 0,
173                 
174                 DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
175                 DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
176                 DXGI_FORMAT_R32G32B32A32_UINT = 3,
177                 DXGI_FORMAT_R32G32B32A32_SINT = 4,
178                 
179                 DXGI_FORMAT_R32G32B32_TYPELESS = 5,
180                 DXGI_FORMAT_R32G32B32_FLOAT = 6,
181                 DXGI_FORMAT_R32G32B32_UINT = 7,
182                 DXGI_FORMAT_R32G32B32_SINT = 8,
183                 
184                 DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
185                 DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
186                 DXGI_FORMAT_R16G16B16A16_UNORM = 11,
187                 DXGI_FORMAT_R16G16B16A16_UINT = 12,
188                 DXGI_FORMAT_R16G16B16A16_SNORM = 13,
189                 DXGI_FORMAT_R16G16B16A16_SINT = 14,
190                 
191                 DXGI_FORMAT_R32G32_TYPELESS = 15,
192                 DXGI_FORMAT_R32G32_FLOAT = 16,
193                 DXGI_FORMAT_R32G32_UINT = 17,
194                 DXGI_FORMAT_R32G32_SINT = 18,
195                 
196                 DXGI_FORMAT_R32G8X24_TYPELESS = 19,
197                 DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
198                 DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
199                 DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
200                 
201                 DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
202                 DXGI_FORMAT_R10G10B10A2_UNORM = 24,
203                 DXGI_FORMAT_R10G10B10A2_UINT = 25,
204                 
205                 DXGI_FORMAT_R11G11B10_FLOAT = 26,
206                 
207                 DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
208                 DXGI_FORMAT_R8G8B8A8_UNORM = 28,
209                 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
210                 DXGI_FORMAT_R8G8B8A8_UINT = 30,
211                 DXGI_FORMAT_R8G8B8A8_SNORM = 31,
212                 DXGI_FORMAT_R8G8B8A8_SINT = 32,
213                 
214                 DXGI_FORMAT_R16G16_TYPELESS = 33,
215                 DXGI_FORMAT_R16G16_FLOAT = 34,
216                 DXGI_FORMAT_R16G16_UNORM = 35,
217                 DXGI_FORMAT_R16G16_UINT = 36,
218                 DXGI_FORMAT_R16G16_SNORM = 37,
219                 DXGI_FORMAT_R16G16_SINT = 38,
220                 
221                 DXGI_FORMAT_R32_TYPELESS = 39,
222                 DXGI_FORMAT_D32_FLOAT = 40,
223                 DXGI_FORMAT_R32_FLOAT = 41,
224                 DXGI_FORMAT_R32_UINT = 42,
225                 DXGI_FORMAT_R32_SINT = 43,
226                 
227                 DXGI_FORMAT_R24G8_TYPELESS = 44,
228                 DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
229                 DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
230                 DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
231                 
232                 DXGI_FORMAT_R8G8_TYPELESS = 48,
233                 DXGI_FORMAT_R8G8_UNORM = 49,
234                 DXGI_FORMAT_R8G8_UINT = 50,
235                 DXGI_FORMAT_R8G8_SNORM = 51,
236                 DXGI_FORMAT_R8G8_SINT = 52,
237                 
238                 DXGI_FORMAT_R16_TYPELESS = 53,
239                 DXGI_FORMAT_R16_FLOAT = 54,
240                 DXGI_FORMAT_D16_UNORM = 55,
241                 DXGI_FORMAT_R16_UNORM = 56,
242                 DXGI_FORMAT_R16_UINT = 57,
243                 DXGI_FORMAT_R16_SNORM = 58,
244                 DXGI_FORMAT_R16_SINT = 59,
245                 
246                 DXGI_FORMAT_R8_TYPELESS = 60,
247                 DXGI_FORMAT_R8_UNORM = 61,
248                 DXGI_FORMAT_R8_UINT = 62,
249                 DXGI_FORMAT_R8_SNORM = 63,
250                 DXGI_FORMAT_R8_SINT = 64,
251                 DXGI_FORMAT_A8_UNORM = 65,
252                 
253                 DXGI_FORMAT_R1_UNORM = 66,
254                 
255                 DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
256                 
257                 DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
258                 DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
259                 
260                 DXGI_FORMAT_BC1_TYPELESS = 70,
261                 DXGI_FORMAT_BC1_UNORM = 71,
262                 DXGI_FORMAT_BC1_UNORM_SRGB = 72,
263                 
264                 DXGI_FORMAT_BC2_TYPELESS = 73,
265                 DXGI_FORMAT_BC2_UNORM = 74,
266                 DXGI_FORMAT_BC2_UNORM_SRGB = 75,
267                 
268                 DXGI_FORMAT_BC3_TYPELESS = 76,
269                 DXGI_FORMAT_BC3_UNORM = 77,
270                 DXGI_FORMAT_BC3_UNORM_SRGB = 78,
271                 
272                 DXGI_FORMAT_BC4_TYPELESS = 79,
273                 DXGI_FORMAT_BC4_UNORM = 80,
274                 DXGI_FORMAT_BC4_SNORM = 81,
275                 
276                 DXGI_FORMAT_BC5_TYPELESS = 82,
277                 DXGI_FORMAT_BC5_UNORM = 83,
278                 DXGI_FORMAT_BC5_SNORM = 84,
279                 
280                 DXGI_FORMAT_B5G6R5_UNORM = 85,
281                 DXGI_FORMAT_B5G5R5A1_UNORM = 86,
282                 DXGI_FORMAT_B8G8R8A8_UNORM = 87,
283                 DXGI_FORMAT_B8G8R8X8_UNORM = 88,
284
285         DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
286         DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
287         DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
288         DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
289         DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
290
291         DXGI_FORMAT_BC6H_TYPELESS = 94,
292         DXGI_FORMAT_BC6H_UF16 = 95,
293         DXGI_FORMAT_BC6H_SF16 = 96,
294
295         DXGI_FORMAT_BC7_TYPELESS = 97,
296         DXGI_FORMAT_BC7_UNORM = 98,
297         DXGI_FORMAT_BC7_UNORM_SRGB = 99,
298         };
299
300         enum D3D10_RESOURCE_DIMENSION
301         {
302                 D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
303                 D3D10_RESOURCE_DIMENSION_BUFFER = 1,
304                 D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
305                 D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
306                 D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
307         };
308
309
310         const char * getDxgiFormatString(DXGI_FORMAT dxgiFormat)
311         {
312 #define CASE(format) case DXGI_FORMAT_##format: return #format
313                 switch(dxgiFormat)
314                 {
315                         CASE(UNKNOWN);
316                         
317                         CASE(R32G32B32A32_TYPELESS);
318                         CASE(R32G32B32A32_FLOAT);
319                         CASE(R32G32B32A32_UINT);
320                         CASE(R32G32B32A32_SINT);
321                         
322                         CASE(R32G32B32_TYPELESS);
323                         CASE(R32G32B32_FLOAT);
324                         CASE(R32G32B32_UINT);
325                         CASE(R32G32B32_SINT);
326                         
327                         CASE(R16G16B16A16_TYPELESS);
328                         CASE(R16G16B16A16_FLOAT);
329                         CASE(R16G16B16A16_UNORM);
330                         CASE(R16G16B16A16_UINT);
331                         CASE(R16G16B16A16_SNORM);
332                         CASE(R16G16B16A16_SINT);
333                         
334                         CASE(R32G32_TYPELESS);
335                         CASE(R32G32_FLOAT);
336                         CASE(R32G32_UINT);
337                         CASE(R32G32_SINT);
338                         
339                         CASE(R32G8X24_TYPELESS);
340                         CASE(D32_FLOAT_S8X24_UINT);
341                         CASE(R32_FLOAT_X8X24_TYPELESS);
342                         CASE(X32_TYPELESS_G8X24_UINT);
343                         
344                         CASE(R10G10B10A2_TYPELESS);
345                         CASE(R10G10B10A2_UNORM);
346                         CASE(R10G10B10A2_UINT);
347                         
348                         CASE(R11G11B10_FLOAT);
349                         
350                         CASE(R8G8B8A8_TYPELESS);
351                         CASE(R8G8B8A8_UNORM);
352                         CASE(R8G8B8A8_UNORM_SRGB);
353                         CASE(R8G8B8A8_UINT);
354                         CASE(R8G8B8A8_SNORM);
355                         CASE(R8G8B8A8_SINT);
356                         
357                         CASE(R16G16_TYPELESS);
358                         CASE(R16G16_FLOAT);
359                         CASE(R16G16_UNORM);
360                         CASE(R16G16_UINT);
361                         CASE(R16G16_SNORM);
362                         CASE(R16G16_SINT);
363                         
364                         CASE(R32_TYPELESS);
365                         CASE(D32_FLOAT);
366                         CASE(R32_FLOAT);
367                         CASE(R32_UINT);
368                         CASE(R32_SINT);
369                         
370                         CASE(R24G8_TYPELESS);
371                         CASE(D24_UNORM_S8_UINT);
372                         CASE(R24_UNORM_X8_TYPELESS);
373                         CASE(X24_TYPELESS_G8_UINT);
374                         
375                         CASE(R8G8_TYPELESS);
376                         CASE(R8G8_UNORM);
377                         CASE(R8G8_UINT);
378                         CASE(R8G8_SNORM);
379                         CASE(R8G8_SINT);
380                         
381                         CASE(R16_TYPELESS);
382                         CASE(R16_FLOAT);
383                         CASE(D16_UNORM);
384                         CASE(R16_UNORM);
385                         CASE(R16_UINT);
386                         CASE(R16_SNORM);
387                         CASE(R16_SINT);
388                         
389                         CASE(R8_TYPELESS);
390                         CASE(R8_UNORM);
391                         CASE(R8_UINT);
392                         CASE(R8_SNORM);
393                         CASE(R8_SINT);
394                         CASE(A8_UNORM);
395
396                         CASE(R1_UNORM);
397                 
398                         CASE(R9G9B9E5_SHAREDEXP);
399                         
400                         CASE(R8G8_B8G8_UNORM);
401                         CASE(G8R8_G8B8_UNORM);
402
403                         CASE(BC1_TYPELESS);
404                         CASE(BC1_UNORM);
405                         CASE(BC1_UNORM_SRGB);
406                 
407                         CASE(BC2_TYPELESS);
408                         CASE(BC2_UNORM);
409                         CASE(BC2_UNORM_SRGB);
410                 
411                         CASE(BC3_TYPELESS);
412                         CASE(BC3_UNORM);
413                         CASE(BC3_UNORM_SRGB);
414                 
415                         CASE(BC4_TYPELESS);
416                         CASE(BC4_UNORM);
417                         CASE(BC4_SNORM);
418                 
419                         CASE(BC5_TYPELESS);
420                         CASE(BC5_UNORM);
421                         CASE(BC5_SNORM);
422
423                         CASE(B5G6R5_UNORM);
424                         CASE(B5G5R5A1_UNORM);
425                         CASE(B8G8R8A8_UNORM);
426                         CASE(B8G8R8X8_UNORM);
427
428                         default: 
429                                 return "UNKNOWN";
430                 }
431 #undef CASE
432         }
433         
434         const char * getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension)
435         {
436                 switch(resourceDimension)
437                 {
438                         default:
439                         case D3D10_RESOURCE_DIMENSION_UNKNOWN: return "UNKNOWN";
440                         case D3D10_RESOURCE_DIMENSION_BUFFER: return "BUFFER";
441                         case D3D10_RESOURCE_DIMENSION_TEXTURE1D: return "TEXTURE1D";
442                         case D3D10_RESOURCE_DIMENSION_TEXTURE2D: return "TEXTURE2D";
443                         case D3D10_RESOURCE_DIMENSION_TEXTURE3D: return "TEXTURE3D";
444                 }
445         }
446
447 /*** implementation ***/
448
449 void mem_read(Stream & mem, DDSPixelFormat & pf)
450 {
451         mem_read(mem, pf.size);
452         mem_read(mem, pf.flags);
453         mem_read(mem, pf.fourcc);
454         mem_read(mem, pf.bitcount);
455         mem_read(mem, pf.rmask);
456         mem_read(mem, pf.gmask);
457         mem_read(mem, pf.bmask);
458         mem_read(mem, pf.amask);
459 }
460
461 void mem_read(Stream & mem, DDSCaps & caps)
462 {
463         mem_read(mem, caps.caps1);
464         mem_read(mem, caps.caps2);
465         mem_read(mem, caps.caps3);
466         mem_read(mem, caps.caps4);
467 }
468
469 void mem_read(Stream & mem, DDSHeader10 & header)
470 {
471         mem_read(mem, header.dxgiFormat);
472         mem_read(mem, header.resourceDimension);
473         mem_read(mem, header.miscFlag);
474         mem_read(mem, header.arraySize);
475         mem_read(mem, header.reserved);
476 }
477
478 void mem_read(Stream & mem, DDSHeader & header)
479 {
480         mem_read(mem, header.fourcc);
481         mem_read(mem, header.size);
482         mem_read(mem, header.flags);
483         mem_read(mem, header.height);
484         mem_read(mem, header.width);
485         mem_read(mem, header.pitch);
486         mem_read(mem, header.depth);
487         mem_read(mem, header.mipmapcount);
488         for (uint i = 0; i < 11; i++) mem_read(mem, header.reserved[i]);
489         mem_read(mem, header.pf);
490         mem_read(mem, header.caps);
491         mem_read(mem, header.notused);
492
493         if (header.hasDX10Header())
494         {
495                 mem_read(mem, header.header10);
496         }
497 }
498
499 namespace
500 {
501     struct FormatDescriptor
502     {
503         uint format;
504         uint bitcount;
505         uint rmask;
506         uint gmask;
507         uint bmask;
508         uint amask;
509     };
510
511     static const FormatDescriptor s_d3dFormats[] =
512     {
513         { D3DFMT_R8G8B8,                24, 0xFF0000,   0xFF00,     0xFF,       0 },
514         { D3DFMT_A8R8G8B8,              32, 0xFF0000,   0xFF00,     0xFF,       0xFF000000 },  // DXGI_FORMAT_B8G8R8A8_UNORM
515         { D3DFMT_X8R8G8B8,              32, 0xFF0000,   0xFF00,     0xFF,       0 },           // DXGI_FORMAT_B8G8R8X8_UNORM
516         { D3DFMT_R5G6B5,                16,     0xF800,     0x7E0,      0x1F,       0 },           // DXGI_FORMAT_B5G6R5_UNORM
517         { D3DFMT_X1R5G5B5,              16, 0x7C00,     0x3E0,      0x1F,       0 },
518         { D3DFMT_A1R5G5B5,              16, 0x7C00,     0x3E0,      0x1F,       0x8000 },      // DXGI_FORMAT_B5G5R5A1_UNORM
519         { D3DFMT_A4R4G4B4,              16, 0xF00,      0xF0,       0xF,        0xF000 },
520         { D3DFMT_R3G3B2,                8,  0xE0,       0x1C,       0x3,            0 },
521         { D3DFMT_A8,                    8,  0,          0,          0,              8 },           // DXGI_FORMAT_A8_UNORM
522         { D3DFMT_A8R3G3B2,              16, 0xE0,       0x1C,       0x3,        0xFF00 },
523         { D3DFMT_X4R4G4B4,              16, 0xF00,      0xF0,       0xF,        0 },
524         { D3DFMT_A2B10G10R10,   32, 0x3FF,      0xFFC00,    0x3FF00000, 0xC0000000 },  // DXGI_FORMAT_R10G10B10A2
525         { D3DFMT_A8B8G8R8,              32, 0xFF,       0xFF00,     0xFF0000,   0xFF000000 },  // DXGI_FORMAT_R8G8B8A8_UNORM
526         { D3DFMT_X8B8G8R8,              32, 0xFF,       0xFF00,     0xFF0000,   0 },
527         { D3DFMT_G16R16,                32, 0xFFFF,     0xFFFF0000, 0,          0 },           // DXGI_FORMAT_R16G16_UNORM
528         { D3DFMT_A2R10G10B10,   32, 0x3FF00000, 0xFFC00,    0x3FF,      0xC0000000 },
529         { D3DFMT_A2B10G10R10,   32, 0x3FF,      0xFFC00,    0x3FF00000, 0xC0000000 },
530
531         { D3DFMT_L8,                    8,  8,          0,          0,          0 },           // DXGI_FORMAT_R8_UNORM 
532         { D3DFMT_L16,                   16, 16,         0,          0,          0 },           // DXGI_FORMAT_R16_UNORM
533     };
534
535     static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]);
536
537 } // namespace
538
539 uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
540 {
541     for (int i = 0; i < s_d3dFormatCount; i++)
542         {
543             if (s_d3dFormats[i].bitcount == bitcount &&
544                 s_d3dFormats[i].rmask == rmask &&
545                 s_d3dFormats[i].gmask == gmask &&
546                 s_d3dFormats[i].bmask == bmask &&
547                 s_d3dFormats[i].amask == amask)
548             {
549                 return s_d3dFormats[i].format;
550             }
551         }
552
553         return 0;
554     }
555
556
557
558 DDSHeader::DDSHeader()
559 {
560         this->fourcc = FOURCC_DDS;
561         this->size = 124;
562         this->flags  = (DDSD_CAPS|DDSD_PIXELFORMAT);
563         this->height = 0;
564         this->width = 0;
565         this->pitch = 0;
566         this->depth = 0;
567         this->mipmapcount = 0;
568         for (uint i = 0; i < 11; i++) this->reserved[i] = 0;
569
570         // Store version information on the reserved header attributes.
571     this->reserved[9] = FOURCC_NVTT;
572         this->reserved[10] = (2 << 16) | (1 << 8) | (0);        // major.minor.revision
573
574         this->pf.size = 32;
575         this->pf.flags = 0;
576         this->pf.fourcc = 0;
577         this->pf.bitcount = 0;
578         this->pf.rmask = 0;
579         this->pf.gmask = 0;
580         this->pf.bmask = 0;
581         this->pf.amask = 0;
582         this->caps.caps1 = DDSCAPS_TEXTURE;
583         this->caps.caps2 = 0;
584         this->caps.caps3 = 0;
585         this->caps.caps4 = 0;
586         this->notused = 0;
587
588         this->header10.dxgiFormat = DXGI_FORMAT_UNKNOWN;
589         this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN;
590         this->header10.miscFlag = 0;
591         this->header10.arraySize = 0;
592         this->header10.reserved = 0;
593 }
594
595 void DDSHeader::setWidth(uint w)
596 {
597         this->flags |= DDSD_WIDTH;
598         this->width = w;
599 }
600
601 void DDSHeader::setHeight(uint h)
602 {
603         this->flags |= DDSD_HEIGHT;
604         this->height = h;
605 }
606
607 void DDSHeader::setDepth(uint d)
608 {
609         this->flags |= DDSD_DEPTH;
610         this->depth = d;
611 }
612
613 void DDSHeader::setMipmapCount(uint count)
614 {
615         if (count == 0 || count == 1)
616         {
617                 this->flags &= ~DDSD_MIPMAPCOUNT;
618         this->mipmapcount = 1;
619
620                 if (this->caps.caps2 == 0) {
621                         this->caps.caps1 = DDSCAPS_TEXTURE;
622                 }
623                 else {
624                         this->caps.caps1 = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
625                 }
626         }
627         else
628         {
629                 this->flags |= DDSD_MIPMAPCOUNT;
630                 this->mipmapcount = count;
631
632                 this->caps.caps1 |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
633         }
634 }
635
636 void DDSHeader::setTexture2D()
637 {
638         this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
639         this->header10.arraySize = 1;
640 }
641
642 void DDSHeader::setTexture3D()
643 {
644         this->caps.caps2 = DDSCAPS2_VOLUME;
645
646         this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
647         this->header10.arraySize = 1;
648 }
649
650 void DDSHeader::setTextureCube()
651 {
652         this->caps.caps1 |= DDSCAPS_COMPLEX;
653         this->caps.caps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALL_FACES;
654
655         this->header10.resourceDimension = D3D10_RESOURCE_DIMENSION_TEXTURE2D;
656         this->header10.arraySize = 6;
657 }
658
659 void DDSHeader::setLinearSize(uint size)
660 {
661         this->flags &= ~DDSD_PITCH;
662         this->flags |= DDSD_LINEARSIZE;
663         this->pitch = size;
664 }
665
666 void DDSHeader::setPitch(uint pitch)
667 {
668         this->flags &= ~DDSD_LINEARSIZE;
669         this->flags |= DDSD_PITCH;
670         this->pitch = pitch;
671 }
672
673 void DDSHeader::setFourCC(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
674 {
675         // set fourcc pixel format.
676         this->pf.flags = DDPF_FOURCC;
677         this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
678
679         this->pf.bitcount = 0;
680         this->pf.rmask = 0;
681         this->pf.gmask = 0;
682         this->pf.bmask = 0;
683         this->pf.amask = 0;
684 }
685
686 void DDSHeader::setFormatCode(uint32 code)
687 {
688         // set fourcc pixel format.
689         this->pf.flags = DDPF_FOURCC;
690         this->pf.fourcc = code;
691         
692         this->pf.bitcount = 0;
693         this->pf.rmask = 0;
694         this->pf.gmask = 0;
695         this->pf.bmask = 0;
696         this->pf.amask = 0;
697 }
698
699 void DDSHeader::setSwizzleCode(uint8 c0, uint8 c1, uint8 c2, uint8 c3)
700 {
701         this->pf.bitcount = MAKEFOURCC(c0, c1, c2, c3);
702 }
703
704
705 void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask)
706 {
707         // Make sure the masks are correct.
708         if ((rmask & gmask) || \
709                 (rmask & bmask) || \
710                 (rmask & amask) || \
711                 (gmask & bmask) || \
712                 (gmask & amask) || \
713                 (bmask & amask)) {
714                 printf("DDS: bad RGBA masks, pixel format not set\n");
715                 return;
716         }
717
718         if (rmask != 0 || gmask != 0 || bmask != 0)
719         {
720         if (gmask == 0 && bmask == 0)
721         {
722             this->pf.flags = DDPF_LUMINANCE;
723         }
724         else
725         {
726                     this->pf.flags = DDPF_RGB;
727         }
728
729                 if (amask != 0) {
730                         this->pf.flags |= DDPF_ALPHAPIXELS;
731                 }
732         }
733         else if (amask != 0)
734         {
735                 this->pf.flags |= DDPF_ALPHA;
736         }
737
738         if (bitcount == 0)
739         {
740                 // Compute bit count from the masks.
741                 uint total = rmask | gmask | bmask | amask;
742                 while(total != 0) {
743                         bitcount++;
744                         total >>= 1;
745                 }
746         }
747
748     // D3DX functions do not like this:
749         this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask);
750     /*if (this->pf.fourcc) {
751         this->pf.flags |= DDPF_FOURCC;
752     }*/
753
754         if (!(bitcount > 0 && bitcount <= 32)) {
755                 printf("DDS: bad bit count, pixel format not set\n");
756                 return;
757         }
758         this->pf.bitcount = bitcount;
759         this->pf.rmask = rmask;
760         this->pf.gmask = gmask;
761         this->pf.bmask = bmask;
762         this->pf.amask = amask;
763 }
764
765 void DDSHeader::setDX10Format(uint format)
766 {
767         //this->pf.flags = 0;
768         this->pf.fourcc = FOURCC_DX10;
769         this->header10.dxgiFormat = format;
770 }
771
772 void DDSHeader::setNormalFlag(bool b)
773 {
774         if (b) this->pf.flags |= DDPF_NORMAL;
775         else this->pf.flags &= ~DDPF_NORMAL;
776 }
777
778 void DDSHeader::setSrgbFlag(bool b)
779 {
780     if (b) this->pf.flags |= DDPF_SRGB;
781     else this->pf.flags &= ~DDPF_SRGB;
782 }
783
784 void DDSHeader::setHasAlphaFlag(bool b)
785 {
786         if (b) this->pf.flags |= DDPF_ALPHAPIXELS;
787         else this->pf.flags &= ~DDPF_ALPHAPIXELS;
788 }
789
790 void DDSHeader::setUserVersion(int version)
791 {
792     this->reserved[7] = FOURCC_UVER;
793     this->reserved[8] = version;
794 }
795
796 /*
797 void DDSHeader::swapBytes()
798 {
799         this->fourcc = POSH_LittleU32(this->fourcc);
800         this->size = POSH_LittleU32(this->size);
801         this->flags = POSH_LittleU32(this->flags);
802         this->height = POSH_LittleU32(this->height);
803         this->width = POSH_LittleU32(this->width);
804         this->pitch = POSH_LittleU32(this->pitch);
805         this->depth = POSH_LittleU32(this->depth);
806         this->mipmapcount = POSH_LittleU32(this->mipmapcount);
807         
808         for(int i = 0; i < 11; i++) {
809                 this->reserved[i] = POSH_LittleU32(this->reserved[i]);
810         }
811
812         this->pf.size = POSH_LittleU32(this->pf.size);
813         this->pf.flags = POSH_LittleU32(this->pf.flags);
814         this->pf.fourcc = POSH_LittleU32(this->pf.fourcc);
815         this->pf.bitcount = POSH_LittleU32(this->pf.bitcount);
816         this->pf.rmask = POSH_LittleU32(this->pf.rmask);
817         this->pf.gmask = POSH_LittleU32(this->pf.gmask);
818         this->pf.bmask = POSH_LittleU32(this->pf.bmask);
819         this->pf.amask = POSH_LittleU32(this->pf.amask);
820         this->caps.caps1 = POSH_LittleU32(this->caps.caps1);
821         this->caps.caps2 = POSH_LittleU32(this->caps.caps2);
822         this->caps.caps3 = POSH_LittleU32(this->caps.caps3);
823         this->caps.caps4 = POSH_LittleU32(this->caps.caps4);
824         this->notused = POSH_LittleU32(this->notused);
825
826         this->header10.dxgiFormat = POSH_LittleU32(this->header10.dxgiFormat);
827         this->header10.resourceDimension = POSH_LittleU32(this->header10.resourceDimension);
828         this->header10.miscFlag = POSH_LittleU32(this->header10.miscFlag);
829         this->header10.arraySize = POSH_LittleU32(this->header10.arraySize);
830         this->header10.reserved = POSH_LittleU32(this->header10.reserved);
831 }
832 */
833
834 bool DDSHeader::hasDX10Header() const
835 {
836         return this->pf.fourcc == FOURCC_DX10;
837 }
838
839 uint DDSHeader::signature() const
840 {
841     return this->reserved[9];
842 }
843
844 uint DDSHeader::toolVersion() const
845 {
846     return this->reserved[10];
847 }
848
849 uint DDSHeader::userVersion() const
850 {
851     if (this->reserved[7] == FOURCC_UVER) {
852         return this->reserved[8];
853     }
854     return 0;
855 }
856
857 bool DDSHeader::isNormalMap() const
858 {
859     return (pf.flags & DDPF_NORMAL) != 0;
860 }
861
862 bool DDSHeader::isSrgb() const
863 {
864     return (pf.flags & DDPF_SRGB) != 0;
865 }
866
867 bool DDSHeader::hasAlpha() const
868 {
869     return (pf.flags & DDPF_ALPHAPIXELS) != 0;
870 }
871
872 uint DDSHeader::d3d9Format() const
873 {
874     if (pf.flags & DDPF_FOURCC) {
875         return pf.fourcc;
876     }
877     else {
878         return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
879     }
880 }
881
882 DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
883 {
884         mem_read(stream, header);
885
886         // some ATI2 compressed normal maps do not have their
887         // normal flag set, so force it here (the original nvtt don't do
888         // this, but the decompressor has a -forcenormal flag)
889         if (header.pf.fourcc == FOURCC_ATI2) header.setNormalFlag(true);
890 }
891
892 DirectDrawSurface::~DirectDrawSurface()
893 {
894 }
895
896 bool DirectDrawSurface::isValid() const
897 {
898         if (header.fourcc != FOURCC_DDS || header.size != 124)
899         {
900                 return false;
901         }
902         
903         const uint required = (DDSD_WIDTH|DDSD_HEIGHT/*|DDSD_CAPS|DDSD_PIXELFORMAT*/);
904         if( (header.flags & required) != required ) {
905                 return false;
906         }
907         
908         if (header.pf.size != 32) {
909                 return false;
910         }
911
912         /* in some files DDSCAPS_TEXTURE is missing: silently ignore */
913         /*
914         if( !(header.caps.caps1 & DDSCAPS_TEXTURE) ) {
915                 return false;
916         }
917         */
918
919         return true;
920 }
921
922 bool DirectDrawSurface::isSupported() const
923 {
924         if (header.hasDX10Header())
925         {
926                 if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
927                         header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
928                         header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM ||
929                         header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM ||
930                         header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM)
931                 {
932                         return true;
933                 }
934
935                 return false;
936         }
937         else
938         {
939                 if (header.pf.flags & DDPF_FOURCC)
940                 {
941                         if (header.pf.fourcc != FOURCC_DXT1 &&
942                             header.pf.fourcc != FOURCC_DXT2 &&
943                             header.pf.fourcc != FOURCC_DXT3 &&
944                             header.pf.fourcc != FOURCC_DXT4 &&
945                             header.pf.fourcc != FOURCC_DXT5 &&
946                             header.pf.fourcc != FOURCC_RXGB &&
947                             header.pf.fourcc != FOURCC_ATI1 &&
948                             header.pf.fourcc != FOURCC_ATI2)
949                         {
950                                 // Unknown fourcc code.
951                                 return false;
952                         }
953                 }
954         else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE))
955         {
956             // All RGB and luminance formats are supported now.
957                 }
958                 else
959                 {
960                         return false;
961                 }
962                 
963                 if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES)
964                 {
965                         // Cubemaps must contain all faces.
966                         return false;
967                 }
968         
969                 if (isTexture3D())
970                 {
971                         // @@ 3D textures not supported yet.
972                         return false;
973                 }
974         }
975         
976         return true;
977 }
978
979 bool DirectDrawSurface::hasAlpha() const
980 {
981         if (header.hasDX10Header())
982         {
983 #pragma NV_MESSAGE("TODO: Update hasAlpha to handle all DX10 formats.")
984                 return 
985                         header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM ||
986                         header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
987                         header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
988         }
989         else
990         {
991                 if (header.pf.flags & DDPF_RGB) 
992                 {
993                         return header.pf.amask != 0;
994                 }
995                 else if (header.pf.flags & DDPF_FOURCC)
996                 {
997                         if (header.pf.fourcc == FOURCC_RXGB ||
998                                 header.pf.fourcc == FOURCC_ATI1 ||
999                                 header.pf.fourcc == FOURCC_ATI2 ||
1000                                 header.pf.flags & DDPF_NORMAL)
1001                         {
1002                                 return false;
1003                         }
1004                         else
1005                         {
1006                 // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
1007                                 return true;
1008                         }
1009                 }
1010
1011                 return false;
1012         }
1013 }
1014
1015 uint DirectDrawSurface::mipmapCount() const
1016 {
1017         if (header.flags & DDSD_MIPMAPCOUNT) return header.mipmapcount;
1018         else return 1;
1019 }
1020
1021
1022 uint DirectDrawSurface::width() const
1023 {
1024         if (header.flags & DDSD_WIDTH) return header.width;
1025         else return 1;
1026 }
1027
1028 uint DirectDrawSurface::height() const
1029 {
1030         if (header.flags & DDSD_HEIGHT) return header.height;
1031         else return 1;
1032 }
1033
1034 uint DirectDrawSurface::depth() const
1035 {
1036         if (header.flags & DDSD_DEPTH) return header.depth;
1037         else return 1;
1038 }
1039
1040 bool DirectDrawSurface::isTexture1D() const
1041 {
1042         if (header.hasDX10Header())
1043         {
1044                 return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D;
1045         }
1046         return false;
1047 }
1048
1049 bool DirectDrawSurface::isTexture2D() const
1050 {
1051         if (header.hasDX10Header())
1052         {
1053                 return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D;
1054         }
1055         else
1056         {
1057                 return !isTexture3D() && !isTextureCube();
1058         }
1059 }
1060
1061 bool DirectDrawSurface::isTexture3D() const
1062 {
1063         if (header.hasDX10Header())
1064         {
1065                 return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D;
1066         }
1067         else
1068         {
1069         return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
1070         }
1071 }
1072
1073 bool DirectDrawSurface::isTextureCube() const
1074 {
1075         return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
1076 }
1077
1078 void DirectDrawSurface::setNormalFlag(bool b)
1079 {
1080         header.setNormalFlag(b);
1081 }
1082
1083 void DirectDrawSurface::setHasAlphaFlag(bool b)
1084 {
1085         header.setHasAlphaFlag(b);
1086 }
1087
1088 void DirectDrawSurface::setUserVersion(int version)
1089 {
1090     header.setUserVersion(version);
1091 }
1092
1093 void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
1094 {
1095         stream.seek(offset(face, mipmap));
1096         
1097         uint w = width();
1098         uint h = height();
1099         
1100         // Compute width and height.
1101         for (uint m = 0; m < mipmap; m++)
1102         {
1103                 w = max(1U, w / 2);
1104                 h = max(1U, h / 2);
1105         }
1106         
1107         img->allocate(w, h);
1108         
1109         if (hasAlpha())
1110         {
1111                 img->setFormat(Image::Format_ARGB);
1112         }
1113         else
1114         {
1115                 img->setFormat(Image::Format_RGB);
1116         }
1117
1118         if (header.hasDX10Header())
1119         {
1120                 // So far only block formats supported.
1121                 readBlockImage(img);
1122         }
1123         else
1124         {
1125                 if (header.pf.flags & DDPF_RGB) 
1126                 {
1127                         readLinearImage(img);
1128                 }
1129                 else if (header.pf.flags & DDPF_FOURCC)
1130                 {
1131                         readBlockImage(img);
1132                 }
1133         }
1134 }
1135
1136 void DirectDrawSurface::readLinearImage(Image * img)
1137 {
1138         
1139         const uint w = img->width();
1140         const uint h = img->height();
1141         
1142         uint rshift, rsize;
1143         PixelFormat::maskShiftAndSize(header.pf.rmask, &rshift, &rsize);
1144         
1145         uint gshift, gsize;
1146         PixelFormat::maskShiftAndSize(header.pf.gmask, &gshift, &gsize);
1147         
1148         uint bshift, bsize;
1149         PixelFormat::maskShiftAndSize(header.pf.bmask, &bshift, &bsize);
1150         
1151         uint ashift, asize;
1152         PixelFormat::maskShiftAndSize(header.pf.amask, &ashift, &asize);
1153
1154         uint byteCount = (header.pf.bitcount + 7) / 8;
1155
1156         if (byteCount > 4)
1157         {
1158                 /* just in case... we could have segfaults later on if byteCount > 4 */
1159                 printf("DDS: bitcount too large");
1160                 return;
1161         }
1162
1163         // Read linear RGB images.
1164         for (uint y = 0; y < h; y++)
1165         {
1166                 for (uint x = 0; x < w; x++)
1167                 {
1168                         uint c = 0;
1169                         mem_read(stream, (unsigned char *)(&c), byteCount);
1170
1171                         Color32 pixel(0, 0, 0, 0xFF);
1172                         pixel.r = PixelFormat::convert((c & header.pf.rmask) >> rshift, rsize, 8);
1173                         pixel.g = PixelFormat::convert((c & header.pf.gmask) >> gshift, gsize, 8);
1174                         pixel.b = PixelFormat::convert((c & header.pf.bmask) >> bshift, bsize, 8);
1175                         pixel.a = PixelFormat::convert((c & header.pf.amask) >> ashift, asize, 8);
1176
1177                         img->pixel(x, y) = pixel;
1178                 }
1179         }
1180 }
1181
1182 void DirectDrawSurface::readBlockImage(Image * img)
1183 {
1184
1185         const uint w = img->width();
1186         const uint h = img->height();
1187         
1188         const uint bw = (w + 3) / 4;
1189         const uint bh = (h + 3) / 4;
1190         
1191         for (uint by = 0; by < bh; by++)
1192         {
1193                 for (uint bx = 0; bx < bw; bx++)
1194                 {
1195                         ColorBlock block;
1196                         
1197                         // Read color block.
1198                         readBlock(&block);
1199                         
1200                         // Write color block.
1201                         for (uint y = 0; y < min(4U, h-4*by); y++)
1202                         {
1203                                 for (uint x = 0; x < min(4U, w-4*bx); x++)
1204                                 {
1205                                         img->pixel(4*bx+x, 4*by+y) = block.color(x, y);
1206                                 }
1207                         }
1208                 }
1209         }
1210 }
1211
1212 static Color32 buildNormal(uint8 x, uint8 y)
1213 {
1214         float nx = 2 * (x / 255.0f) - 1;
1215         float ny = 2 * (y / 255.0f) - 1;
1216         float nz = 0.0f;
1217         if (1 - nx*nx - ny*ny > 0) nz = sqrt(1 - nx*nx - ny*ny);
1218         uint8 z = clamp(int(255.0f * (nz + 1) / 2.0f), 0, 255);
1219         
1220         return Color32(x, y, z);
1221 }
1222
1223
1224 void DirectDrawSurface::readBlock(ColorBlock * rgba)
1225 {
1226         uint fourcc = header.pf.fourcc;
1227
1228         // Map DX10 block formats to fourcc codes.
1229         if (header.hasDX10Header())
1230         {
1231                 if (header.header10.dxgiFormat == DXGI_FORMAT_BC1_UNORM) fourcc = FOURCC_DXT1;
1232                 if (header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM) fourcc = FOURCC_DXT3;
1233                 if (header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM) fourcc = FOURCC_DXT5;
1234                 if (header.header10.dxgiFormat == DXGI_FORMAT_BC4_UNORM) fourcc = FOURCC_ATI1;
1235                 if (header.header10.dxgiFormat == DXGI_FORMAT_BC5_UNORM) fourcc = FOURCC_ATI2;
1236         }
1237
1238
1239         if (fourcc == FOURCC_DXT1)
1240         {
1241                 BlockDXT1 block;
1242                 mem_read(stream, block);
1243                 block.decodeBlock(rgba);
1244         }
1245         else if (fourcc == FOURCC_DXT2 ||
1246             header.pf.fourcc == FOURCC_DXT3)
1247         {
1248                 BlockDXT3 block;
1249                 mem_read(stream, block);
1250                 block.decodeBlock(rgba);
1251         }
1252         else if (fourcc == FOURCC_DXT4 ||
1253             header.pf.fourcc == FOURCC_DXT5 ||
1254             header.pf.fourcc == FOURCC_RXGB)
1255         {
1256                 BlockDXT5 block;
1257                 mem_read(stream, block);
1258                 block.decodeBlock(rgba);
1259                 
1260                 if (fourcc == FOURCC_RXGB)
1261                 {
1262                         // Swap R & A.
1263                         for (int i = 0; i < 16; i++)
1264                         {
1265                                 Color32 & c = rgba->color(i);
1266                                 uint tmp = c.r;
1267                                 c.r = c.a;
1268                                 c.a = tmp;
1269                         }
1270                 }
1271         }
1272         else if (fourcc == FOURCC_ATI1)
1273         {
1274                 BlockATI1 block;
1275                 mem_read(stream, block);
1276                 block.decodeBlock(rgba);
1277         }
1278         else if (fourcc == FOURCC_ATI2)
1279         {
1280                 BlockATI2 block;
1281                 mem_read(stream, block);
1282                 block.decodeBlock(rgba);
1283         }
1284         
1285         // If normal flag set, convert to normal.
1286         if (header.pf.flags & DDPF_NORMAL)
1287         {
1288                 if (fourcc == FOURCC_ATI2)
1289                 {
1290                         for (int i = 0; i < 16; i++)
1291                         {
1292                                 Color32 & c = rgba->color(i);
1293                                 c = buildNormal(c.r, c.g);
1294                         }
1295                 }
1296                 else if (fourcc == FOURCC_DXT5)
1297                 {
1298                         for (int i = 0; i < 16; i++)
1299                         {
1300                                 Color32 & c = rgba->color(i);
1301                                 c = buildNormal(c.a, c.g);
1302                         }
1303                 }
1304         }
1305 }
1306
1307
1308 uint DirectDrawSurface::blockSize() const
1309 {
1310         switch(header.pf.fourcc)
1311         {
1312                 case FOURCC_DXT1:
1313                 case FOURCC_ATI1:
1314                         return 8;
1315                 case FOURCC_DXT2:
1316                 case FOURCC_DXT3:
1317                 case FOURCC_DXT4:
1318                 case FOURCC_DXT5:
1319                 case FOURCC_RXGB:
1320                 case FOURCC_ATI2:
1321                         return 16;
1322                 case FOURCC_DX10:
1323                         switch(header.header10.dxgiFormat)
1324                         {
1325                                 case DXGI_FORMAT_BC1_TYPELESS:
1326                                 case DXGI_FORMAT_BC1_UNORM:
1327                                 case DXGI_FORMAT_BC1_UNORM_SRGB:
1328                                 case DXGI_FORMAT_BC4_TYPELESS:
1329                                 case DXGI_FORMAT_BC4_UNORM:
1330                                 case DXGI_FORMAT_BC4_SNORM:
1331                                         return 8;
1332                                 case DXGI_FORMAT_BC2_TYPELESS:
1333                                 case DXGI_FORMAT_BC2_UNORM:
1334                                 case DXGI_FORMAT_BC2_UNORM_SRGB:
1335                                 case DXGI_FORMAT_BC3_TYPELESS:
1336                                 case DXGI_FORMAT_BC3_UNORM:
1337                                 case DXGI_FORMAT_BC3_UNORM_SRGB:
1338                                 case DXGI_FORMAT_BC5_TYPELESS:
1339                                 case DXGI_FORMAT_BC5_UNORM:
1340                                 case DXGI_FORMAT_BC5_SNORM:
1341                                         return 16;
1342                         };
1343         };
1344
1345         // Not a block image.
1346         return 0;
1347 }
1348
1349 uint DirectDrawSurface::mipmapSize(uint mipmap) const
1350 {
1351         uint w = width();
1352         uint h = height();
1353         uint d = depth();
1354         
1355         for (uint m = 0; m < mipmap; m++)
1356         {
1357                 w = max(1U, w / 2);
1358                 h = max(1U, h / 2);
1359                 d = max(1U, d / 2);
1360         }
1361
1362         if (header.pf.flags & DDPF_FOURCC)
1363         {
1364                 // @@ How are 3D textures aligned?
1365                 w = (w + 3) / 4;
1366                 h = (h + 3) / 4;
1367                 return blockSize() * w * h;
1368         }
1369         else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE))
1370         {
1371         uint pitch = computePitch(w, header.pf.bitcount, 8); // Asuming 8 bit alignment, which is the same D3DX expects.
1372         
1373                 return pitch * h * d;
1374         }
1375         else {
1376                 printf("DDS: mipmap format not supported\n");
1377                 return(0);
1378         };
1379 }
1380
1381 uint DirectDrawSurface::faceSize() const
1382 {
1383         const uint count = mipmapCount();
1384         uint size = 0;
1385         
1386         for (uint m = 0; m < count; m++)
1387         {
1388                 size += mipmapSize(m);
1389         }
1390         
1391         return size;
1392 }
1393
1394 uint DirectDrawSurface::offset(const uint face, const uint mipmap)
1395 {
1396         uint size = 128; // sizeof(DDSHeader);
1397         
1398         if (header.hasDX10Header())
1399         {
1400                 size += 20; // sizeof(DDSHeader10);
1401         }
1402
1403         if (face != 0)
1404         {
1405                 size += face * faceSize();
1406         }
1407         
1408         for (uint m = 0; m < mipmap; m++)
1409         {
1410                 size += mipmapSize(m);
1411         }
1412         
1413         return size;
1414 }
1415
1416
1417 void DirectDrawSurface::printInfo() const
1418 {
1419         printf("Flags: 0x%.8X\n", header.flags);
1420         if (header.flags & DDSD_CAPS) printf("\tDDSD_CAPS\n");
1421         if (header.flags & DDSD_PIXELFORMAT) printf("\tDDSD_PIXELFORMAT\n");
1422         if (header.flags & DDSD_WIDTH) printf("\tDDSD_WIDTH\n");
1423         if (header.flags & DDSD_HEIGHT) printf("\tDDSD_HEIGHT\n");
1424         if (header.flags & DDSD_DEPTH) printf("\tDDSD_DEPTH\n");
1425         if (header.flags & DDSD_PITCH) printf("\tDDSD_PITCH\n");
1426         if (header.flags & DDSD_LINEARSIZE) printf("\tDDSD_LINEARSIZE\n");
1427         if (header.flags & DDSD_MIPMAPCOUNT) printf("\tDDSD_MIPMAPCOUNT\n");
1428
1429         printf("Height: %d\n", header.height);
1430         printf("Width: %d\n", header.width);
1431         printf("Depth: %d\n", header.depth);
1432         if (header.flags & DDSD_PITCH) printf("Pitch: %d\n", header.pitch);
1433         else if (header.flags & DDSD_LINEARSIZE) printf("Linear size: %d\n", header.pitch);
1434         printf("Mipmap count: %d\n", header.mipmapcount);
1435         
1436         printf("Pixel Format:\n");
1437         printf("\tFlags: 0x%.8X\n", header.pf.flags);
1438         if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n");
1439     if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n");
1440         if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n");
1441         if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n");
1442         if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n");
1443         if (header.pf.flags & DDPF_PALETTEINDEXED1) printf("\t\tDDPF_PALETTEINDEXED1\n");
1444         if (header.pf.flags & DDPF_PALETTEINDEXED2) printf("\t\tDDPF_PALETTEINDEXED2\n");
1445         if (header.pf.flags & DDPF_PALETTEINDEXED4) printf("\t\tDDPF_PALETTEINDEXED4\n");
1446         if (header.pf.flags & DDPF_PALETTEINDEXED8) printf("\t\tDDPF_PALETTEINDEXED8\n");
1447         if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
1448         if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
1449         
1450     if (header.pf.fourcc != 0) { 
1451         // Display fourcc code even when DDPF_FOURCC flag not set.
1452         printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n",
1453                         ((header.pf.fourcc >> 0) & 0xFF),
1454                         ((header.pf.fourcc >> 8) & 0xFF),
1455                         ((header.pf.fourcc >> 16) & 0xFF),
1456             ((header.pf.fourcc >> 24) & 0xFF), 
1457             header.pf.fourcc);
1458     }
1459
1460     if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0))
1461         {
1462         printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n", 
1463                         (header.pf.bitcount >> 0) & 0xFF,
1464                         (header.pf.bitcount >> 8) & 0xFF,
1465                         (header.pf.bitcount >> 16) & 0xFF,
1466             (header.pf.bitcount >> 24) & 0xFF,
1467             header.pf.bitcount);
1468         }
1469         else
1470         {
1471                 printf("\tBit count: %d\n", header.pf.bitcount);
1472         }
1473
1474         printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
1475         printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
1476         printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
1477         printf("\tAlpha mask: 0x%.8X\n", header.pf.amask);
1478
1479         printf("Caps:\n");
1480         printf("\tCaps 1: 0x%.8X\n", header.caps.caps1);
1481         if (header.caps.caps1 & DDSCAPS_COMPLEX) printf("\t\tDDSCAPS_COMPLEX\n");
1482         if (header.caps.caps1 & DDSCAPS_TEXTURE) printf("\t\tDDSCAPS_TEXTURE\n");
1483         if (header.caps.caps1 & DDSCAPS_MIPMAP) printf("\t\tDDSCAPS_MIPMAP\n");
1484
1485         printf("\tCaps 2: 0x%.8X\n", header.caps.caps2);
1486         if (header.caps.caps2 & DDSCAPS2_VOLUME) printf("\t\tDDSCAPS2_VOLUME\n");
1487         else if (header.caps.caps2 & DDSCAPS2_CUBEMAP)
1488         {
1489                 printf("\t\tDDSCAPS2_CUBEMAP\n");
1490                 if ((header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) == DDSCAPS2_CUBEMAP_ALL_FACES) printf("\t\tDDSCAPS2_CUBEMAP_ALL_FACES\n");
1491                 else {
1492                         if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEX\n");
1493                         if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEX\n");
1494                         if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEY\n");
1495                         if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEY\n");
1496                         if (header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_POSITIVEZ\n");
1497                         if (header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) printf("\t\tDDSCAPS2_CUBEMAP_NEGATIVEZ\n");
1498                 }
1499         }
1500
1501         printf("\tCaps 3: 0x%.8X\n", header.caps.caps3);
1502         printf("\tCaps 4: 0x%.8X\n", header.caps.caps4);
1503
1504         if (header.hasDX10Header())
1505         {
1506                 printf("DX10 Header:\n");
1507                 printf("\tDXGI Format: %u (%s)\n", header.header10.dxgiFormat, getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat));
1508                 printf("\tResource dimension: %u (%s)\n", header.header10.resourceDimension, getD3d10ResourceDimensionString((D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension));
1509                 printf("\tMisc flag: %u\n", header.header10.miscFlag);
1510                 printf("\tArray size: %u\n", header.header10.arraySize);
1511         }
1512         
1513     if (header.reserved[9] == FOURCC_NVTT)
1514         {
1515                 int major = (header.reserved[10] >> 16) & 0xFF;
1516                 int minor = (header.reserved[10] >> 8) & 0xFF;
1517                 int revision= header.reserved[10] & 0xFF;
1518                 
1519                 printf("Version:\n");
1520                 printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision);
1521         }
1522
1523     if (header.reserved[7] == FOURCC_UVER)
1524     {
1525         printf("User Version: %d\n", header.reserved[8]);
1526     }
1527 }
1528