/[projet1]/public/pc/shared_libraries/freeimage/v3.12.0/Source/FreeImage/PluginDDS.cpp
Defence Force logotype

Contents of /public/pc/shared_libraries/freeimage/v3.12.0/Source/FreeImage/PluginDDS.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 126 - (show annotations)
Mon Jul 13 12:20:10 2009 UTC (10 years, 7 months ago) by dbug
File size: 18969 byte(s)
Added some shared libraries (UnitTest++, and FreeImage) to avoid having every single project brings its own libraries.
Ideally people should add them in a way we can upgrade versions without breaking things:
-> public/pc/shared_libraries/library_name/library_version/actuall_content
1 // ==========================================================
2 // DDS Loader
3 //
4 // Design and implementation by
5 // - Volker Gärtner (volkerg@gmx.at)
6 // - Sherman Wilcox
7 //
8 // This file is part of FreeImage 3
9 //
10 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
11 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
12 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
13 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
14 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
15 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
16 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
17 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
18 // THIS DISCLAIMER.
19 //
20 // Use at your own risk!
21 // ==========================================================
22
23 #include "FreeImage.h"
24 #include "Utilities.h"
25
26 // ----------------------------------------------------------
27 // Definitions for the DDS format
28 // ----------------------------------------------------------
29
30 #ifdef _WIN32
31 #pragma pack(push, 1)
32 #else
33 #pragma pack(1)
34 #endif
35
36 typedef struct tagDDPIXELFORMAT {
37 DWORD dwSize; // size of this structure (must be 32)
38 DWORD dwFlags; // see DDPF_*
39 DWORD dwFourCC;
40 DWORD dwRGBBitCount; // Total number of bits for RGB formats
41 DWORD dwRBitMask;
42 DWORD dwGBitMask;
43 DWORD dwBBitMask;
44 DWORD dwRGBAlphaBitMask;
45 } DDPIXELFORMAT;
46
47 // DIRECTDRAW PIXELFORMAT FLAGS
48 enum {
49 DDPF_ALPHAPIXELS = 0x00000001l, // surface has alpha channel
50 DDPF_ALPHA = 0x00000002l, // alpha only
51 DDPF_FOURCC = 0x00000004l, // FOURCC available
52 DDPF_RGB = 0x00000040l // RGB(A) bitmap
53 };
54
55 typedef struct tagDDCAPS2 {
56 DWORD dwCaps1; // Zero or more of the DDSCAPS_* members
57 DWORD dwCaps2; // Zero or more of the DDSCAPS2_* members
58 DWORD dwReserved[2];
59 } DDCAPS2;
60
61 // DIRECTDRAWSURFACE CAPABILITY FLAGS
62 enum {
63 DDSCAPS_ALPHA = 0x00000002l, // alpha only surface
64 DDSCAPS_COMPLEX = 0x00000008l, // complex surface structure
65 DDSCAPS_TEXTURE = 0x00001000l, // used as texture (should always be set)
66 DDSCAPS_MIPMAP = 0x00400000l // Mipmap present
67 };
68
69 enum {
70 DDSCAPS2_CUBEMAP = 0x00000200L,
71 DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400L,
72 DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800L,
73 DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000L,
74 DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000L,
75 DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000L,
76 DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000L,
77 DDSCAPS2_VOLUME = 0x00200000L
78 };
79
80 typedef struct tagDDSURFACEDESC2 {
81 DWORD dwSize; // size of this structure (must be 124)
82 DWORD dwFlags; // combination of the DDSS_* flags
83 DWORD dwHeight;
84 DWORD dwWidth;
85 DWORD dwPitchOrLinearSize;
86 DWORD dwDepth; // Depth of a volume texture
87 DWORD dwMipMapCount;
88 DWORD dwReserved1[11];
89 DDPIXELFORMAT ddpfPixelFormat;
90 DDCAPS2 ddsCaps;
91 DWORD dwReserved2;
92 } DDSURFACEDESC2;
93
94 enum {
95 DDSD_CAPS = 0x00000001l,
96 DDSD_HEIGHT = 0x00000002l,
97 DDSD_WITH = 0x00000004l,
98 DDSD_PITCH = 0x00000008l,
99 DDSD_ALPHABITDEPTH = 0x00000080l,
100 DDSD_PIXELFORMAT = 0x00001000l,
101 DDSD_MIPMAPCOUNT = 0x00020000l,
102 DDSD_LINEARSIZE = 0x00080000l,
103 DDSD_DEPTH = 0x00800000l
104 };
105
106 typedef struct tagDDSHEADER {
107 DWORD dwMagic; // FOURCC: "DDS "
108 DDSURFACEDESC2 surfaceDesc;
109 } DDSHEADER;
110
111 #define MAKEFOURCC(ch0, ch1, ch2, ch3) \
112 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
113 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
114
115 #define FOURCC_DXT1 MAKEFOURCC('D','X','T','1')
116 #define FOURCC_DXT2 MAKEFOURCC('D','X','T','2')
117 #define FOURCC_DXT3 MAKEFOURCC('D','X','T','3')
118 #define FOURCC_DXT4 MAKEFOURCC('D','X','T','4')
119 #define FOURCC_DXT5 MAKEFOURCC('D','X','T','5')
120
121 // ----------------------------------------------------------
122 // Structures used by DXT textures
123 // ----------------------------------------------------------
124
125 typedef struct tagColor8888 {
126 BYTE b;
127 BYTE g;
128 BYTE r;
129 BYTE a;
130 } Color8888;
131
132 typedef struct tagColor565 {
133 WORD b : 5;
134 WORD g : 6;
135 WORD r : 5;
136 } Color565;
137
138 typedef struct tagDXTColBlock {
139 Color565 colors[2];
140 BYTE row[4];
141 } DXTColBlock;
142
143 typedef struct tagDXTAlphaBlockExplicit {
144 WORD row[4];
145 } DXTAlphaBlockExplicit;
146
147 typedef struct tagDXTAlphaBlock3BitLinear {
148 BYTE alpha[2];
149 BYTE data[6];
150 } DXTAlphaBlock3BitLinear;
151
152 typedef struct tagDXT1Block
153 {
154 DXTColBlock color;
155 } DXT1Block;
156
157 typedef struct tagDXT3Block { // also used by dxt2
158 DXTAlphaBlockExplicit alpha;
159 DXTColBlock color;
160 } DXT3Block;
161
162 typedef struct tagDXT5Block { // also used by dxt4
163 DXTAlphaBlock3BitLinear alpha;
164 DXTColBlock color;
165 } DXT5Block;
166
167 #ifdef _WIN32
168 # pragma pack(pop)
169 #else
170 # pragma pack()
171 #endif
172
173 // ----------------------------------------------------------
174 // Internal functions
175 // ----------------------------------------------------------
176 #ifdef FREEIMAGE_BIGENDIAN
177 static void
178 SwapHeader(DDSHEADER *header) {
179 SwapLong(&header->dwMagic);
180 SwapLong(&header->surfaceDesc.dwSize);
181 SwapLong(&header->surfaceDesc.dwFlags);
182 SwapLong(&header->surfaceDesc.dwHeight);
183 SwapLong(&header->surfaceDesc.dwWidth);
184 SwapLong(&header->surfaceDesc.dwPitchOrLinearSize);
185 SwapLong(&header->surfaceDesc.dwDepth);
186 SwapLong(&header->surfaceDesc.dwMipMapCount);
187 for(int i=0; i<11; i++) {
188 SwapLong(&header->surfaceDesc.dwReserved1[i]);
189 }
190 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwSize);
191 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwFlags);
192 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwFourCC);
193 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwRGBBitCount);
194 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwRBitMask);
195 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwGBitMask);
196 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwBBitMask);
197 SwapLong(&header->surfaceDesc.ddpfPixelFormat.dwRGBAlphaBitMask);
198 SwapLong(&header->surfaceDesc.ddsCaps.dwCaps1);
199 SwapLong(&header->surfaceDesc.ddsCaps.dwCaps2);
200 SwapLong(&header->surfaceDesc.ddsCaps.dwReserved[0]);
201 SwapLong(&header->surfaceDesc.ddsCaps.dwReserved[1]);
202 SwapLong(&header->surfaceDesc.dwReserved2);
203 }
204 #endif
205
206 // ==========================================================
207
208 // Get the 4 possible colors for a block
209 //
210 static void
211 GetBlockColors (const DXTColBlock &block, Color8888 colors[4], bool isDXT1) {
212 int i;
213 // expand from 565 to 888
214 for (i = 0; i < 2; i++) {
215 colors[i].a = 0xff;
216 /*
217 colors[i].r = (BYTE)(block.colors[i].r * 0xff / 0x1f);
218 colors[i].g = (BYTE)(block.colors[i].g * 0xff / 0x3f);
219 colors[i].b = (BYTE)(block.colors[i].b * 0xff / 0x1f);
220 */
221 colors[i].r = (BYTE)((block.colors[i].r << 3U) | (block.colors[i].r >> 2U));
222 colors[i].g = (BYTE)((block.colors[i].g << 2U) | (block.colors[i].g >> 4U));
223 colors[i].b = (BYTE)((block.colors[i].b << 3U) | (block.colors[i].b >> 2U));
224 }
225
226 WORD *wCol = (WORD *)block.colors;
227 if (wCol[0] > wCol[1] || !isDXT1) {
228 // 4 color block
229 for (i = 0; i < 2; i++) {
230 colors[i + 2].a = 0xff;
231 colors[i + 2].r = (BYTE)((WORD (colors[0].r) * (2 - i) + WORD (colors[1].r) * (1 + i)) / 3);
232 colors[i + 2].g = (BYTE)((WORD (colors[0].g) * (2 - i) + WORD (colors[1].g) * (1 + i)) / 3);
233 colors[i + 2].b = (BYTE)((WORD (colors[0].b) * (2 - i) + WORD (colors[1].b) * (1 + i)) / 3);
234 }
235 }
236 else {
237 // 3 color block, number 4 is transparent
238 colors[2].a = 0xff;
239 colors[2].r = (BYTE)((WORD (colors[0].r) + WORD (colors[1].r)) / 2);
240 colors[2].g = (BYTE)((WORD (colors[0].g) + WORD (colors[1].g)) / 2);
241 colors[2].b = (BYTE)((WORD (colors[0].b) + WORD (colors[1].b)) / 2);
242
243 colors[3].a = 0x00;
244 colors[3].g = 0x00;
245 colors[3].b = 0x00;
246 colors[3].r = 0x00;
247 }
248 }
249
250 struct DXT_INFO_1 {
251 typedef DXT1Block Block;
252 enum {
253 isDXT1 = 1,
254 bytesPerBlock = 8
255 };
256 };
257
258 struct DXT_INFO_3 {
259 typedef DXT3Block Block;
260 enum {
261 isDXT1 = 1,
262 bytesPerBlock = 16
263 };
264 };
265
266 struct DXT_INFO_5 {
267 typedef DXT5Block Block;
268 enum
269 {
270 isDXT1 = 1,
271 bytesPerBlock = 16
272 };
273 };
274
275 template <class INFO> class DXT_BLOCKDECODER_BASE {
276 protected:
277 Color8888 m_colors[4];
278 const typename INFO::Block *m_pBlock;
279 unsigned m_colorRow;
280
281 public:
282 void Setup (const BYTE *pBlock) {
283 m_pBlock = (const typename INFO::Block *)pBlock;
284 GetBlockColors (m_pBlock->color, m_colors, INFO::isDXT1);
285 }
286
287 void SetY (int y) {
288 m_colorRow = m_pBlock->color.row[y];
289 }
290
291 void GetColor (int x, int y, Color8888 &color) {
292 unsigned bits = (m_colorRow >> (x * 2)) & 3;
293 color = m_colors[bits];
294 }
295 };
296
297 class DXT_BLOCKDECODER_1 : public DXT_BLOCKDECODER_BASE <DXT_INFO_1> {
298 public:
299 typedef DXT_INFO_1 INFO;
300 };
301
302 class DXT_BLOCKDECODER_3 : public DXT_BLOCKDECODER_BASE <DXT_INFO_3> {
303 public:
304 typedef DXT_BLOCKDECODER_BASE <DXT_INFO_3> base;
305 typedef DXT_INFO_3 INFO;
306
307 protected:
308 unsigned m_alphaRow;
309
310 public:
311 void SetY (int y) {
312 base::SetY (y);
313 m_alphaRow = m_pBlock->alpha.row[y];
314 }
315
316 void GetColor (int x, int y, Color8888 &color) {
317 base::GetColor (x, y, color);
318 const unsigned bits = (m_alphaRow >> (x * 4)) & 0xF;
319 color.a = (BYTE)((bits * 0xFF) / 0xF);
320 }
321 };
322
323 class DXT_BLOCKDECODER_5 : public DXT_BLOCKDECODER_BASE <DXT_INFO_5> {
324 public:
325 typedef DXT_BLOCKDECODER_BASE <DXT_INFO_5> base;
326 typedef DXT_INFO_5 INFO;
327
328 protected:
329 unsigned m_alphas[8];
330 unsigned m_alphaBits;
331 int m_offset;
332
333 public:
334 void Setup (const BYTE *pBlock) {
335 base::Setup (pBlock);
336
337 const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha;
338 m_alphas[0] = block.alpha[0];
339 m_alphas[1] = block.alpha[1];
340 if (m_alphas[0] > m_alphas[1]) {
341 // 8 alpha block
342 for (int i = 0; i < 6; i++) {
343 m_alphas[i + 2] = ((6 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 3) / 7;
344 }
345 }
346 else {
347 // 6 alpha block
348 for (int i = 0; i < 4; i++) {
349 m_alphas[i + 2] = ((4 - i) * m_alphas[0] + (1 + i) * m_alphas[1] + 2) / 5;
350 }
351 m_alphas[6] = 0;
352 m_alphas[7] = 0xFF;
353 }
354
355 }
356
357 void SetY (int y) {
358 base::SetY (y);
359 int i = y / 2;
360 const DXTAlphaBlock3BitLinear &block = m_pBlock->alpha;
361 m_alphaBits = unsigned(block.data[0 + i * 3]) | (unsigned(block.data[1 + i * 3]) << 8)
362 | (unsigned(block.data[2 + i * 3]) << 16);
363 m_offset = (y & 1) * 12;
364 }
365
366 void GetColor (int x, int y, Color8888 &color) {
367 base::GetColor (x, y, color);
368 unsigned bits = (m_alphaBits >> (x * 3 + m_offset)) & 7;
369 color.a = (BYTE)m_alphas[bits];
370 }
371 };
372
373 template <class DECODER> void DecodeDXTBlock (BYTE *dstData, const BYTE *srcBlock, long dstPitch, int bw, int bh) {
374 DECODER decoder;
375 decoder.Setup (srcBlock);
376 for (int y = 0; y < bh; y++) {
377 BYTE *dst = dstData - y * dstPitch;
378 decoder.SetY (y);
379 for (int x = 0; x < bw; x++) {
380 decoder.GetColor (x, y, (Color8888 &)*dst);
381 dst += 4;
382 }
383 }
384 }
385
386 // ==========================================================
387 // Plugin Interface
388 // ==========================================================
389
390 static int s_format_id;
391
392 // ==========================================================
393 // Internal functions
394 // ==========================================================
395
396 static FIBITMAP *
397 LoadRGB (DDSURFACEDESC2 &desc, FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
398 int width = (int)desc.dwWidth & ~3;
399 int height = (int)desc.dwHeight & ~3;
400 int bpp = (int)desc.ddpfPixelFormat.dwRGBBitCount;
401
402 // allocate a new dib
403 FIBITMAP *dib = FreeImage_Allocate (width, height, bpp, desc.ddpfPixelFormat.dwRBitMask,
404 desc.ddpfPixelFormat.dwGBitMask, desc.ddpfPixelFormat.dwBBitMask);
405 if (dib == NULL)
406 return NULL;
407
408 #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
409 // Calculate the number of bytes per pixel (3 for 24-bit or 4 for 32-bit)
410 int bytespp = FreeImage_GetLine(dib) / FreeImage_GetWidth(dib);
411 #endif
412
413 // read the file
414 int line = CalculateLine(width, bpp);
415 int filePitch = (desc.dwFlags & DDSD_PITCH) ? (int)desc.dwPitchOrLinearSize : line;
416 long delta = (long)filePitch - (long)line;
417 for (int i = 0; i < height; i++) {
418 BYTE *pixels = FreeImage_GetScanLine(dib, height - i - 1);
419 io->read_proc (pixels, 1, line, handle);
420 io->seek_proc (handle, delta, SEEK_CUR);
421 #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
422 for(int x = 0; x < width; x++) {
423 INPLACESWAP(pixels[FI_RGBA_RED],pixels[FI_RGBA_BLUE]);
424 pixels += bytespp;
425 }
426 #endif
427 }
428
429 // enable transparency
430 FreeImage_SetTransparent (dib, (desc.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) ? TRUE : FALSE);
431
432 if (!(desc.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && bpp == 32) {
433 // no transparency: convert to 24-bit
434 FIBITMAP *old = dib;
435 dib = FreeImage_ConvertTo24Bits (old);
436 FreeImage_Unload (old);
437 }
438 return dib;
439 }
440
441 template <class DECODER> static void
442 LoadDXT_Helper (FreeImageIO *io, fi_handle handle, int page, int flags, void *data, FIBITMAP *dib, int width, int height, int line) {
443 typedef typename DECODER::INFO INFO;
444 typedef typename INFO::Block Block;
445
446 Block *input_buffer = new Block[(width + 3) / 4];
447 int widthRest = (int) width & 3;
448 int heightRest = (int) height & 3;
449 int inputLine = (width + 3) / 4;
450 int y = 0;
451
452 if (height >= 4) {
453 for (; y < height; y += 4) {
454 io->read_proc (input_buffer, sizeof (typename INFO::Block), inputLine, handle);
455 // TODO: probably need some endian work here
456 BYTE *pbSrc = (BYTE *)input_buffer;
457 BYTE *pbDst = FreeImage_GetScanLine (dib, height - y - 1);
458
459 if (width >= 4) {
460 for (int x = 0; x < width; x += 4) {
461 DecodeDXTBlock <DECODER> (pbDst, pbSrc, line, 4, 4);
462 pbSrc += INFO::bytesPerBlock;
463 pbDst += 4 * 4;
464 }
465 }
466 if (widthRest) {
467 DecodeDXTBlock <DECODER> (pbDst, pbSrc, line, widthRest, 4);
468 }
469 }
470 }
471 if (heightRest) {
472 io->read_proc (input_buffer, sizeof (typename INFO::Block), inputLine, handle);
473 // TODO: probably need some endian work here
474 BYTE *pbSrc = (BYTE *)input_buffer;
475 BYTE *pbDst = FreeImage_GetScanLine (dib, height - y - 1);
476
477 if (width >= 4) {
478 for (int x = 0; x < width; x += 4) {
479 DecodeDXTBlock <DECODER> (pbDst, pbSrc, line, 4, heightRest);
480 pbSrc += INFO::bytesPerBlock;
481 pbDst += 4 * 4;
482 }
483 }
484 if (widthRest) {
485 DecodeDXTBlock <DECODER> (pbDst, pbSrc, line, widthRest, heightRest);
486 }
487
488 }
489
490 delete [] input_buffer;
491 }
492
493 static FIBITMAP *
494 LoadDXT (int type, DDSURFACEDESC2 &desc, FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
495 int width = (int)desc.dwWidth & ~3;
496 int height = (int)desc.dwHeight & ~3;
497
498 // allocate a 32-bit dib
499 FIBITMAP *dib = FreeImage_Allocate (width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
500 if (dib == NULL)
501 return NULL;
502
503 int bpp = FreeImage_GetBPP (dib);
504 int line = CalculateLine (width, bpp);
505 BYTE *bits = FreeImage_GetBits (dib);
506
507 // select the right decoder
508 switch (type) {
509 case 1:
510 LoadDXT_Helper <DXT_BLOCKDECODER_1> (io, handle, page, flags, data, dib, width, height, line);
511 break;
512 case 3:
513 LoadDXT_Helper <DXT_BLOCKDECODER_3> (io, handle, page, flags, data, dib, width, height, line);
514 break;
515 case 5:
516 LoadDXT_Helper <DXT_BLOCKDECODER_5> (io, handle, page, flags, data, dib, width, height, line);
517 break;
518 }
519
520 return dib;
521 }
522 // ==========================================================
523 // Plugin Implementation
524 // ==========================================================
525
526 static const char * DLL_CALLCONV
527 Format() {
528 return "DDS";
529 }
530
531 static const char * DLL_CALLCONV
532 Description() {
533 return "DirectX Surface";
534 }
535
536 static const char * DLL_CALLCONV
537 Extension() {
538 return "dds";
539 }
540
541 static const char * DLL_CALLCONV
542 RegExpr() {
543 return NULL;
544 }
545
546 static const char * DLL_CALLCONV
547 MimeType() {
548 return "image/freeimage-dds";
549 }
550
551 static BOOL DLL_CALLCONV
552 Validate(FreeImageIO *io, fi_handle handle) {
553 DDSHEADER header;
554 memset(&header, 0, sizeof(header));
555 io->read_proc(&header, 1, sizeof(header), handle);
556 #ifdef FREEIMAGE_BIGENDIAN
557 SwapHeader(&header);
558 #endif
559 if (header.dwMagic != MAKEFOURCC ('D','D','S',' '))
560 return FALSE;
561 if (header.surfaceDesc.dwSize != sizeof (header.surfaceDesc) ||
562 header.surfaceDesc.ddpfPixelFormat.dwSize != sizeof (header.surfaceDesc.ddpfPixelFormat))
563 return FALSE;
564 return TRUE;
565 }
566
567 static BOOL DLL_CALLCONV
568 SupportsExportDepth(int depth) {
569 return FALSE;
570 }
571
572 static BOOL DLL_CALLCONV
573 SupportsExportType(FREE_IMAGE_TYPE type) {
574 return (type == FIT_BITMAP) ? TRUE : FALSE;
575 }
576
577 // ----------------------------------------------------------
578
579 static void * DLL_CALLCONV
580 Open(FreeImageIO *io, fi_handle handle, BOOL read) {
581 return NULL;
582 }
583
584 static void DLL_CALLCONV
585 Close(FreeImageIO *io, fi_handle handle, void *data) {
586 }
587
588 // ----------------------------------------------------------
589
590 static FIBITMAP * DLL_CALLCONV
591 Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
592 DDSHEADER header;
593 FIBITMAP *dib = NULL;
594
595 memset(&header, 0, sizeof(header));
596 io->read_proc(&header, 1, sizeof(header), handle);
597 #ifdef FREEIMAGE_BIGENDIAN
598 SwapHeader(&header);
599 #endif
600 if (header.surfaceDesc.ddpfPixelFormat.dwFlags & DDPF_RGB) {
601 dib = LoadRGB (header.surfaceDesc, io, handle, page, flags, data);
602 }
603 else if (header.surfaceDesc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) {
604 switch (header.surfaceDesc.ddpfPixelFormat.dwFourCC) {
605 case FOURCC_DXT1:
606 dib = LoadDXT (1, header.surfaceDesc, io, handle, page, flags, data);
607 break;
608 case FOURCC_DXT3:
609 dib = LoadDXT (3, header.surfaceDesc, io, handle, page, flags, data);
610 break;
611 case FOURCC_DXT5:
612 dib = LoadDXT (5, header.surfaceDesc, io, handle, page, flags, data);
613 break;
614 }
615 }
616 return dib;
617 }
618
619 /*
620 static BOOL DLL_CALLCONV
621 Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void *data) {
622 return FALSE;
623 }
624 */
625
626 // ==========================================================
627 // Init
628 // ==========================================================
629
630 void DLL_CALLCONV
631 InitDDS(Plugin *plugin, int format_id) {
632 s_format_id = format_id;
633
634 plugin->format_proc = Format;
635 plugin->description_proc = Description;
636 plugin->extension_proc = Extension;
637 plugin->regexpr_proc = RegExpr;
638 plugin->open_proc = Open;
639 plugin->close_proc = Close;
640 plugin->pagecount_proc = NULL;
641 plugin->pagecapability_proc = NULL;
642 plugin->load_proc = Load;
643 plugin->save_proc = NULL; //Save; // not implemented (yet?)
644 plugin->validate_proc = Validate;
645 plugin->mime_proc = MimeType;
646 plugin->supports_export_bpp_proc = SupportsExportDepth;
647 plugin->supports_export_type_proc = SupportsExportType;
648 plugin->supports_icc_profiles_proc = NULL;
649 }

  ViewVC Help
Powered by ViewVC 1.1.26