WoW Model Viewer
Your premiere tool for viewing, equipping and animating World of Warcraft models.
Loading...
Searching...
No Matches
ddslib.cpp
Go to the documentation of this file.
1/* -----------------------------------------------------------------------------
2DDS Library
3
4Based on code from Nvidia's DDS example:
5http://www.nvidia.com/object/dxtc_decompression_code.html
6
7Copyright (c) 2003 Randy Reddig
8All rights reserved.
9
10Redistribution and use in source and binary forms, with or without modification,
11are permitted provided that the following conditions are met:
12
13Redistributions of source code must retain the above copyright notice, this list
14of conditions and the following disclaimer.
15
16Redistributions in binary form must reproduce the above copyright notice, this
17list of conditions and the following disclaimer in the documentation and/or
18other materials provided with the distribution.
19
20Neither the names of the copyright holders nor the names of its contributors may
21be used to endorse or promote products derived from this software without
22specific prior written permission.
23
24THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35Modified by: John Steele November 2005
36----------------------------------------------------------------------------- */
37/* marker */
38#define DDSLIB_C
39
40/* dependencies */
41#include "ddslib.h"
42
43/* endian tomfoolery */
44typedef union
45{
46 float f;
47 char c[4];
48}
50
51#ifndef __BIG_ENDIAN__
52#ifdef _SGI_SOURCE
53 #define __BIG_ENDIAN__
54#endif
55#endif
56
57#ifdef __BIG_ENDIAN__
58
59 int DDSBigLong( int src ) { return src; }
60 short DDSBigShort( short src ) { return src; }
61 float DDSBigFloat( float src ) { return src; }
62
63 int DDSLittleLong( int src )
64 {
65 return ((src & 0xFF000000) >> 24) |
66 ((src & 0x00FF0000) >> 8) |
67 ((src & 0x0000FF00) << 8) |
68 ((src & 0x000000FF) << 24);
69 }
70
71 short DDSLittleShort( short src )
72 {
73 return ((src & 0xFF00) >> 8) |
74 ((src & 0x00FF) << 8);
75 }
76
77 float DDSLittleFloat( float src )
78 {
79 floatSwapUnion in,out;
80 in.f = src;
81 out.c[ 0 ] = in.c[ 3 ];
82 out.c[ 1 ] = in.c[ 2 ];
83 out.c[ 2 ] = in.c[ 1 ];
84 out.c[ 3 ] = in.c[ 0 ];
85 return out.f;
86 }
87
88#else /*__BIG_ENDIAN__*/
89
90int DDSLittleLong(int src) { return src; }
91short DDSLittleShort(short src) { return src; }
92float DDSLittleFloat(float src) { return src; }
93
94int DDSBigLong(int src)
95{
96 return ((src & 0xFF000000) >> 24) |
97 ((src & 0x00FF0000) >> 8) |
98 ((src & 0x0000FF00) << 8) |
99 ((src & 0x000000FF) << 24);
100}
101
102short DDSBigShort(short src)
103{
104 return ((src & 0xFF00) >> 8) |
105 ((src & 0x00FF) << 8);
106}
107
108float DDSBigFloat(float src)
109{
110 floatSwapUnion in, out{};
111 in.f = src;
112 out.c[0] = in.c[3];
113 out.c[1] = in.c[2];
114 out.c[2] = in.c[1];
115 out.c[3] = in.c[0];
116 return out.f;
117}
118
119#endif /*__BIG_ENDIAN__*/
120
122//DDSDecodePixelFormat()
123//determines which pixel format the dds texture is in
124//*/
125//
126//static void DDSDecodePixelFormat( ddsBuffer_t *dds, ddsPF_t *pf )
127//{
128// unsigned int fourCC;
129//
130// /* dummy check */
131// if( dds == NULL || pf == NULL )
132// return;
133//
134// /* extract fourCC */
135// fourCC = dds->pixelFormat.fourCC;
136//
137// /* test it */
138// if( fourCC == 0 )
139// *pf = DDS_PF_ARGB8888;
140// else if( fourCC == *((unsigned int*) "DXT1") )
141// *pf = DDS_PF_DXT1;
142// else if( fourCC == *((unsigned int*) "DXT2") )
143// *pf = DDS_PF_DXT2;
144// else if( fourCC == *((unsigned int*) "DXT3") )
145// *pf = DDS_PF_DXT3;
146// else if( fourCC == *((unsigned int*) "DXT4") )
147// *pf = DDS_PF_DXT4;
148// else if( fourCC == *((unsigned int*) "DXT5") )
149// *pf = DDS_PF_DXT5;
150// else
151// *pf = DDS_PF_UNKNOWN;
152//}
154//DDSGetInfo()
155//extracts relevant info from a dds texture, returns 0 on success
156//*/
157//int DDSGetInfo( ddsBuffer_t *dds, int *width, int *height, ddsPF_t *pf )
158//{
159// /* dummy test */
160// if( dds == NULL )
161// return -1;
162//
163// /* test dds header */
164// if( *((int*) dds->magic) != *((int*) "DDS ") )
165// return -1;
166// if( DDSLittleLong( dds->size ) != 124 )
167// return -1;
168//
169// /* extract width and height */
170// if( width != NULL )
171// *width = DDSLittleLong( dds->width );
172// if( height != NULL )
173// *height = DDSLittleLong( dds->height );
174//
175// /* get pixel format */
176// DDSDecodePixelFormat( dds, pf );
177//
178// /* return ok */
179// return 0;
180//}
181
182/*
183DDSGetColorBlockColors()
184extracts colors from a dds color block
185*/
186
188{
189 /* color 0 */
190 unsigned short word = DDSLittleShort(block->colors[0]);
191 colors[0].a = 0xff;
192
193 /* extract rgb bits */
194 colors[0].b = static_cast<unsigned char>(word & 0xFF);
195 colors[0].b <<= 3;
196 colors[0].b |= (colors[0].b >> 5);
197 word >>= 5;
198 colors[0].g = static_cast<unsigned char>(word & 0xFF);
199 colors[0].g <<= 2;
200 colors[0].g |= (colors[0].g >> 5);
201 word >>= 6;
202 colors[0].r = static_cast<unsigned char>(word & 0xFF);
203 colors[0].r <<= 3;
204 colors[0].r |= (colors[0].r >> 5);
205
206 /* same for color 1 */
207 word = DDSLittleShort(block->colors[1]);
208 colors[1].a = 0xff;
209
210 /* extract rgb bits */
211 colors[1].b = static_cast<unsigned char>(word & 0xFF);
212 colors[1].b <<= 3;
213 colors[1].b |= (colors[1].b >> 5);
214 word >>= 5;
215 colors[1].g = static_cast<unsigned char>(word & 0xFF);
216 colors[1].g <<= 2;
217 colors[1].g |= (colors[1].g >> 5);
218 word >>= 6;
219 colors[1].r = static_cast<unsigned char>(word & 0xFF);
220 colors[1].r <<= 3;
221 colors[1].r |= (colors[1].r >> 5);
222
223 /* use this for all but the super-freak math method */
224 if (block->colors[0] > block->colors[1])
225 {
226 /* four-color block: derive the other two colors.
227 00 = color 0, 01 = color 1, 10 = color 2, 11 = color 3
228 these two bit codes correspond to the 2-bit fields
229 stored in the 64-bit block. */
230
231 word = (static_cast<unsigned short>(colors[0].r) * 2 + static_cast<unsigned short>(colors[1].r)) / 3;
232 /* no +1 for rounding */
233 /* as bits have been shifted to 888 */
234 colors[2].r = static_cast<unsigned char>(word);
235 word = (static_cast<unsigned short>(colors[0].g) * 2 + static_cast<unsigned short>(colors[1].g)) / 3;
236 colors[2].g = static_cast<unsigned char>(word);
237 word = (static_cast<unsigned short>(colors[0].b) * 2 + static_cast<unsigned short>(colors[1].b)) / 3;
238 colors[2].b = static_cast<unsigned char>(word);
239 colors[2].a = 0xff;
240
241 word = (static_cast<unsigned short>(colors[0].r) + static_cast<unsigned short>(colors[1].r) * 2) / 3;
242 colors[3].r = static_cast<unsigned char>(word);
243 word = (static_cast<unsigned short>(colors[0].g) + static_cast<unsigned short>(colors[1].g) * 2) / 3;
244 colors[3].g = static_cast<unsigned char>(word);
245 word = (static_cast<unsigned short>(colors[0].b) + static_cast<unsigned short>(colors[1].b) * 2) / 3;
246 colors[3].b = static_cast<unsigned char>(word);
247 colors[3].a = 0xff;
248 }
249 else
250 {
251 /* three-color block: derive the other color.
252 00 = color 0, 01 = color 1, 10 = color 2,
253 11 = transparent.
254 These two bit codes correspond to the 2-bit fields
255 stored in the 64-bit block */
256
257 word = (static_cast<unsigned short>(colors[0].r) + static_cast<unsigned short>(colors[1].r)) / 2;
258 colors[2].r = static_cast<unsigned char>(word & 0xFF);
259 word = (static_cast<unsigned short>(colors[0].g) + static_cast<unsigned short>(colors[1].g)) / 2;
260 colors[2].g = static_cast<unsigned char>(word & 0xFF);
261 word = (static_cast<unsigned short>(colors[0].b) + static_cast<unsigned short>(colors[1].b)) / 2;
262 colors[2].b = static_cast<unsigned char>(word & 0xFF);
263 colors[2].a = 0xff;
264
265 /* random color to indicate alpha */
266 colors[3].r = 0x00;
267 colors[3].g = 0xff;
268 colors[3].b = 0xff;
269 colors[3].a = 0x00;
270 }
271}
272
273/*
274DDSDecodeColorBlock()
275decodes a dds color block
276fixme: make endian-safe
277*/
278static void DDSDecodeColorBlock(unsigned int* pixel, ddsColorBlock_t* block, int width, unsigned int colors[4])
279{
280 const unsigned int masks[] = {3, 12, 3 << 4, 3 << 6}; /* bit masks = 00000011, 00001100, 00110000, 11000000 */
281 const int shift[] = {0, 2, 4, 6};
282
283 /* r steps through lines in y */
284 for (int r = 0; r < 4; r++, pixel += (width - 4)) /* no width * 4 as unsigned int ptr inc will * 4 */
285 {
286 /* width * 4 bytes per pixel per line, each j dxtc row is 4 lines of pixels */
287 /* n steps through pixels */
288 for (int n = 0; n < 4; n++)
289 {
290 unsigned int bits = block->row[r] & masks[n];
291 bits >>= shift[n];
292
293 switch (bits)
294 {
295 case 0:
296 *pixel = colors[0];
297 pixel++;
298 break;
299
300 case 1:
301 *pixel = colors[1];
302 pixel++;
303 break;
304
305 case 2:
306 *pixel = colors[2];
307 pixel++;
308 break;
309
310 case 3:
311 *pixel = colors[3];
312 pixel++;
313 break;
314
315 default:
316 /* invalid */
317 pixel++;
318 break;
319 }
320 }
321 }
322}
323
324/*
325DDSDecodeAlphaExplicit()
326decodes a dds explicit alpha block
327*/
328static void DDSDecodeAlphaExplicit(unsigned int* pixel, ddsAlphaBlockExplicit_t* alphaBlock, int width,
329 unsigned int alphaZero)
330{
331 ddsColor_t color{};
332
333 /* clear color */
334 color.r = 0;
335 color.g = 0;
336 color.b = 0;
337
338 /* walk rows */
339 for (int row = 0; row < 4; row++, pixel += (width - 4))
340 {
341 unsigned short word = DDSLittleShort(alphaBlock->row[row]);
342
343 /* walk pixels */
344 for (int pix = 0; pix < 4; pix++)
345 {
346 /* zero the alpha bits of image pixel */
347 *pixel &= alphaZero;
348 color.a = static_cast<unsigned char>(word & 0x000F);
349 color.a = color.a | (color.a << 4);
350 // Avoid strict aliasing violation by constructing the uint32_t manually
351 unsigned int colorValue = (static_cast<unsigned int>(color.a) << 24) |
352 (static_cast<unsigned int>(color.r) << 16) |
353 (static_cast<unsigned int>(color.g) << 8) |
354 (static_cast<unsigned int>(color.b));
355 *pixel |= colorValue;
356 word >>= 4; /* move next bits to lowest 4 */
357 pixel++; /* move to next pixel in the row */
358 }
359 }
360}
361
362/*
363DDSDecodeAlpha3BitLinear()
364decodes interpolated alpha block
365*/
366static void DDSDecodeAlpha3BitLinear(unsigned int* pixel, ddsAlphaBlock3BitLinear_t* alphaBlock, int width,
367 unsigned int alphaZero)
368{
369 int row, pix;
370 unsigned char bits[4][4]{};
371 unsigned short alphas[8]{};
372 ddsColor_t aColors[4][4]{};
373
374 /* get initial alphas */
375 alphas[0] = alphaBlock->alpha0;
376 alphas[1] = alphaBlock->alpha1;
377
378 /* 8-alpha block */
379 if (alphas[0] > alphas[1])
380 {
381 /* 000 = alpha_0, 001 = alpha_1, others are interpolated */
382 alphas[2] = (6 * alphas[0] + alphas[1]) / 7; /* bit code 010 */
383 alphas[3] = (5 * alphas[0] + 2 * alphas[1]) / 7; /* bit code 011 */
384 alphas[4] = (4 * alphas[0] + 3 * alphas[1]) / 7; /* bit code 100 */
385 alphas[5] = (3 * alphas[0] + 4 * alphas[1]) / 7; /* bit code 101 */
386 alphas[6] = (2 * alphas[0] + 5 * alphas[1]) / 7; /* bit code 110 */
387 alphas[7] = (alphas[0] + 6 * alphas[1]) / 7; /* bit code 111 */
388 }
389
390 /* 6-alpha block */
391 else
392 {
393 /* 000 = alpha_0, 001 = alpha_1, others are interpolated */
394 alphas[2] = (4 * alphas[0] + alphas[1]) / 5; /* bit code 010 */
395 alphas[3] = (3 * alphas[0] + 2 * alphas[1]) / 5; /* bit code 011 */
396 alphas[4] = (2 * alphas[0] + 3 * alphas[1]) / 5; /* bit code 100 */
397 alphas[5] = (alphas[0] + 4 * alphas[1]) / 5; /* bit code 101 */
398 alphas[6] = 0; /* bit code 110 */
399 alphas[7] = 255; /* bit code 111 */
400 }
401
402 /* decode 3-bit fields into array of 16 bytes with same value */
403
404 /* first two rows of 4 pixels each */
405 unsigned int stuff = *((unsigned char*)&(alphaBlock->stuff[0]));
406
407 bits[0][0] = static_cast<unsigned char>(stuff & 0x00000007);
408 stuff >>= 3;
409 bits[0][1] = static_cast<unsigned char>(stuff & 0x00000007);
410 stuff >>= 3;
411 bits[0][2] = static_cast<unsigned char>(stuff & 0x00000007);
412 stuff >>= 3;
413 bits[0][3] = static_cast<unsigned char>(stuff & 0x00000007);
414 stuff >>= 3;
415 bits[1][0] = static_cast<unsigned char>(stuff & 0x00000007);
416 stuff >>= 3;
417 bits[1][1] = static_cast<unsigned char>(stuff & 0x00000007);
418 stuff >>= 3;
419 bits[1][2] = static_cast<unsigned char>(stuff & 0x00000007);
420 stuff >>= 3;
421 bits[1][3] = static_cast<unsigned char>(stuff & 0x00000007);
422
423 /* last two rows */
424 stuff = *((unsigned char*)&(alphaBlock->stuff[3])); /* last 3 bytes */
425
426 bits[2][0] = static_cast<unsigned char>(stuff & 0x00000007);
427 stuff >>= 3;
428 bits[2][1] = static_cast<unsigned char>(stuff & 0x00000007);
429 stuff >>= 3;
430 bits[2][2] = static_cast<unsigned char>(stuff & 0x00000007);
431 stuff >>= 3;
432 bits[2][3] = static_cast<unsigned char>(stuff & 0x00000007);
433 stuff >>= 3;
434 bits[3][0] = static_cast<unsigned char>(stuff & 0x00000007);
435 stuff >>= 3;
436 bits[3][1] = static_cast<unsigned char>(stuff & 0x00000007);
437 stuff >>= 3;
438 bits[3][2] = static_cast<unsigned char>(stuff & 0x00000007);
439 stuff >>= 3;
440 bits[3][3] = static_cast<unsigned char>(stuff & 0x00000007);
441
442 /* decode the codes into alpha values */
443 for (row = 0; row < 4; row++)
444 {
445 for (pix = 0; pix < 4; pix++)
446 {
447 aColors[row][pix].r = 0;
448 aColors[row][pix].g = 0;
449 aColors[row][pix].b = 0;
450 aColors[row][pix].a = static_cast<unsigned char>(alphas[bits[row][pix]]);
451 }
452 }
453
454 /* write out alpha values to the image bits */
455 for (row = 0; row < 4; row++, pixel += width - 4)
456 {
457 for (pix = 0; pix < 4; pix++)
458 {
459 /* zero the alpha bits of image pixel */
460 *pixel &= alphaZero;
461
462 /* manually construct the uint32_t value to avoid strict aliasing violation */
463 const ddsColor_t& c = aColors[row][pix];
464 unsigned int colorValue = (static_cast<unsigned int>(c.a) << 24) |
465 (static_cast<unsigned int>(c.r) << 16) |
466 (static_cast<unsigned int>(c.g) << 8) |
467 (static_cast<unsigned int>(c.b));
468 *pixel |= colorValue;
469 pixel++;
470 }
471 }
472}
473
474/*
475DDSDecompressDXT1()
476decompresses a dxt1 format texture
477*/
478
479int DDSDecompressDXT1(unsigned char* src, int width, int height, unsigned char* dest)
480{
481 ddsColor_t colors[4];
482
483 /* setup */
484 const int xBlocks = width / 4;
485 const int yBlocks = height / 4;
486
487 /* walk y */
488 for (int y = 0; y < yBlocks; y++)
489 {
490 /* 8 bytes per block */
491 ddsColorBlock_t* block = reinterpret_cast<ddsColorBlock_t*>(src + y * xBlocks * 8);
492
493 /* walk x */
494 for (int x = 0; x < xBlocks; x++, block++)
495 {
496 DDSGetColorBlockColors(block, colors);
497 // Avoid strict aliasing violation by copying color bytes to a uint32_t array
498 unsigned int colorInts[4];
499 for (int i = 0; i < 4; ++i)
500 {
501 colorInts[i] = (static_cast<unsigned int>(colors[i].a) << 24) |
502 (static_cast<unsigned int>(colors[i].r) << 16) |
503 (static_cast<unsigned int>(colors[i].g) << 8) |
504 (static_cast<unsigned int>(colors[i].b));
505 }
506 unsigned int* pixel = reinterpret_cast<unsigned int*>(dest + x * 16 + (y * 4) * width * 4);
507 DDSDecodeColorBlock(pixel, block, width, colorInts);
508 }
509 }
510
511 /* return ok */
512 return 0;
513}
514
515/*
516DDSDecompressDXT3()
517decompresses a dxt3 format texture
518*/
519int DDSDecompressDXT3(unsigned char* src, int width, int height, unsigned char* dest)
520{
521 ddsColor_t colors[4]{};
522
523 /* setup */
524 const int xBlocks = width / 4;
525 const int yBlocks = height / 4;
526
527 /* create zero alpha */
528 colors[0].a = 0;
529 colors[0].r = 0xFF;
530 colors[0].g = 0xFF;
531 colors[0].b = 0xFF;
532 const unsigned int alphaZero = *reinterpret_cast<unsigned int*>(&colors[0]);
533
534 /* walk y */
535 for (int y = 0; y < yBlocks; y++)
536 {
537 /* 8 bytes per block, 1 block for alpha, 1 block for color */
538 ddsColorBlock_t* block = reinterpret_cast<ddsColorBlock_t*>(src + y * xBlocks * 16);
539
540 /* walk x */
541 for (int x = 0; x < xBlocks; x++, block++)
542 {
543 /* get alpha block */
544 ddsAlphaBlockExplicit_t* alphaBlock = reinterpret_cast<ddsAlphaBlockExplicit_t*>(block);
545
546 /* get color block */
547 block++;
548 DDSGetColorBlockColors(block, colors);
549
550 /* decode color block */
551 unsigned int* pixel = reinterpret_cast<unsigned int*>(dest + x * 16 + (y * 4) * width * 4);
552 DDSDecodeColorBlock(pixel, block, width, reinterpret_cast<unsigned int*>(colors));
553
554 /* overwrite alpha bits with alpha block */
555 DDSDecodeAlphaExplicit(pixel, alphaBlock, width, alphaZero);
556 }
557 }
558 /* return ok */
559 return 0;
560}
561
562/*
563DDSDecompressDXT5()
564decompresses a dxt5 format texture
565*/
566int DDSDecompressDXT5(unsigned char* src, int width, int height, unsigned char* dest)
567{
568 ddsColor_t colors[4]{};
569
570 /* setup */
571 const int xBlocks = width / 4;
572 const int yBlocks = height / 4;
573
574 /* create zero alpha */
575 colors[0].a = 0;
576 colors[0].r = 0xFF;
577 colors[0].g = 0xFF;
578 colors[0].b = 0xFF;
579 const unsigned int alphaZero = *reinterpret_cast<unsigned int*>(&colors[0]);
580
581 /* walk y */
582 for (int y = 0; y < yBlocks; y++)
583 {
584 /* 8 bytes per block, 1 block for alpha, 1 block for color */
585 ddsColorBlock_t* block = reinterpret_cast<ddsColorBlock_t*>(src + y * xBlocks * 16);
586
587 /* walk x */
588 for (int x = 0; x < xBlocks; x++, block++)
589 {
590 /* get alpha block */
591 ddsAlphaBlock3BitLinear_t* alphaBlock = reinterpret_cast<ddsAlphaBlock3BitLinear_t*>(block);
592
593 /* get color block */
594 block++;
595 DDSGetColorBlockColors(block, colors);
596
597 /* decode color block */
598 unsigned int* pixel = reinterpret_cast<unsigned int*>(dest + x * 16 + (y * 4) * width * 4);
599 DDSDecodeColorBlock(pixel, block, width, reinterpret_cast<unsigned int*>(colors));
600
601 /* overwrite alpha bits with alpha block */
602 DDSDecodeAlpha3BitLinear(pixel, alphaBlock, width, alphaZero);
603 }
604 }
605 /* return ok */
606 return 0;
607}
608
609/*
610DDSDecompressDXT2()
611decompresses a dxt2 format texture (fixme: un-premultiply alpha)
612*/
613/*
614static int DDSDecompressDXT2( ddsBuffer_t *dds, int width, int height, unsigned char *pixels )
615{
616 int r;
617
618
619 // decompress dxt3 first //
620 r = DDSDecompressDXT3( dds, width, height, pixels );
621
622 // return to sender //
623 return r;
624}
625*/
626
627
628/*
629DDSDecompressDXT4()
630decompresses a dxt4 format texture (fixme: un-premultiply alpha)
631*/
632
633/*
634static int DDSDecompressDXT4( ddsBuffer_t *dds, int width, int height, unsigned char *pixels )
635{
636 int r;
637
638 // decompress dxt5 first
639 r = DDSDecompressDXT5( dds, width, height, pixels );
640
641 // return to sender
642 return r;
643}
644*/
645/*
646DDSDecompressARGB8888()
647decompresses an argb 8888 format texture
648*/
649#if 0
650static int DDSDecompressARGB8888( ddsBuffer_t *dds, int width, int height, unsigned char *pixels )
651{
652 int x, y;
653 unsigned char *in, *out;
654
655
656 /* setup */
657 in = dds->data;
658 out = pixels;
659
660 /* walk y */
661 for( y = 0; y < height; y++ )
662 {
663 /* walk x */
664 for( x = 0; x < width; x++ )
665 {
666 *out++ = *in++;
667 *out++ = *in++;
668 *out++ = *in++;
669 *out++ = *in++;
670 }
671 }
672
673 /* return ok */
674 return 0;
675}
676#endif
678//DDSDecompress()
679//decompresses a dds texture into an rgba image buffer, returns 0 on success
680//*/
681//
682//int DDSDecompress( ddsBuffer_t *dds, unsigned char *pixels )
683//{
684// int width, height, r;
685// ddsPF_t pf;
686//
687//
688// /* get dds info */
689// r = DDSGetInfo( dds, &width, &height, &pf );
690// if( r )
691// return r;
692//
693// /* decompress */
694// switch( pf )
695// {
696// case DDS_PF_ARGB8888:
697// /* fixme: support other [a]rgb formats */
698// r = DDSDecompressARGB8888( dds, width, height, pixels );
699// break;
700// /*
701// case DDS_PF_DXT1:
702// r = DDSDecompressDXT1( dds, width, height, pixels );
703// break;
704// */
705// /*
706// case DDS_PF_DXT2:
707// r = DDSDecompressDXT2( dds, width, height, pixels );
708// break;
709// */
710// /*
711// case DDS_PF_DXT3:
712// r = DDSDecompressDXT3( dds, width, height, pixels );
713// break;
714// */
715//
716// case DDS_PF_DXT4:
717// r = DDSDecompressDXT4( dds, width, height, pixels );
718// break;
719//
720// case DDS_PF_DXT5:
721// r = DDSDecompressDXT5( dds, width, height, pixels );
722// break;
723//
724// default:
725// case DDS_PF_UNKNOWN:
726// memset( pixels, 0xFF, width * height * 4 );
727// r = -1;
728// break;
729// }
730//
731// /* return to sender */
732// return r;
733//}
float DDSLittleFloat(float src)
Definition ddslib.cpp:92
short DDSLittleShort(short src)
Definition ddslib.cpp:91
static void DDSGetColorBlockColors(ddsColorBlock_t *block, ddsColor_t colors[4])
Definition ddslib.cpp:187
int DDSDecompressDXT1(unsigned char *src, int width, int height, unsigned char *dest)
Decompress a DXT1 (BC1) compressed texture into raw RGBA pixels.
Definition ddslib.cpp:479
short DDSBigShort(short src)
Definition ddslib.cpp:102
int DDSBigLong(int src)
Definition ddslib.cpp:94
float DDSBigFloat(float src)
Definition ddslib.cpp:108
static void DDSDecodeAlpha3BitLinear(unsigned int *pixel, ddsAlphaBlock3BitLinear_t *alphaBlock, int width, unsigned int alphaZero)
Definition ddslib.cpp:366
int DDSLittleLong(int src)
Definition ddslib.cpp:90
int DDSDecompressDXT3(unsigned char *src, int width, int height, unsigned char *dest)
Decompress a DXT3 (BC2) compressed texture into raw RGBA pixels.
Definition ddslib.cpp:519
static void DDSDecodeAlphaExplicit(unsigned int *pixel, ddsAlphaBlockExplicit_t *alphaBlock, int width, unsigned int alphaZero)
Definition ddslib.cpp:328
static void DDSDecodeColorBlock(unsigned int *pixel, ddsColorBlock_t *block, int width, unsigned int colors[4])
Definition ddslib.cpp:278
int DDSDecompressDXT5(unsigned char *src, int width, int height, unsigned char *dest)
Decompress a DXT5 (BC3) compressed texture into raw RGBA pixels.
Definition ddslib.cpp:566
float height() noexcept
Title bar height in logical pixels (call after begin()).
unsigned char alpha1
Definition ddslib.h:213
unsigned char stuff[6]
Definition ddslib.h:214
unsigned char alpha0
Definition ddslib.h:212
unsigned short row[4]
Definition ddslib.h:206
unsigned char data[4]
Definition ddslib.h:193
unsigned char row[4]
Definition ddslib.h:200
unsigned short colors[2]
Definition ddslib.h:199
unsigned char a
Definition ddslib.h:220
unsigned char g
Definition ddslib.h:220
unsigned char b
Definition ddslib.h:220
unsigned char r
Definition ddslib.h:220
char c[4]
Definition ddslib.cpp:47