1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) 2010-2011 Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 // ------------------------------------------------------------------
13 // DDS.cpp
14 // ------------------------------------------------------------------
15 #include "stdafx.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <assert.h>
19 #include "ddraw.h"
20 #include "d3d9types.h"
21 #include "DDS.h"
22 #include "DDS_10.h"
23 #include "DDS_Helpers.h"
24 #include "resource.h"
25 #include "cafe/gx2/gx2Enum.h"
26 #include "texUtils.h"
27 
28 namespace DDSReader
29 {
30 #define MAX_FORMAT_LENGTH 160
31 #define MAX_ERROR_LENGTH 240
32 
33 static const u32 DDS_HEADER = MAKEFOURCC('D', 'D', 'S', ' ');
34 
35 TU_Error LoadDDS_ABGR32F(FILE* pFile, DDSD2* pDDSD,GX2Surface* pSurface);
36 TU_Error LoadDDS_ABGR16F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
37 TU_Error LoadDDS_GR32F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
38 TU_Error LoadDDS_R32F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
39 TU_Error LoadDDS_R16F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
40 TU_Error LoadDDS_G16R16F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
41 TU_Error LoadDDS_FourCC(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
42 TU_Error LoadDDS_RGB565(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
43 TU_Error LoadDDS_RGB888(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
44 TU_Error LoadDDS_RGB8888(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface, bool bAlpha);
45 TU_Error LoadDDS_ABGR2101010(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
46 TU_Error LoadDDS_ABGR16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
47 TU_Error LoadDDS_G16R16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
48 TU_Error LoadDDS_R16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
49 TU_Error LoadDDS_ARGB1555(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
50 TU_Error LoadDDS_ARGB4444(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
51 TU_Error LoadDDS_G8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
52 TU_Error LoadDDS_A4L4(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
53 TU_Error LoadDDS_A8L8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
54 TU_Error LoadDDS_G16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
55 TU_Error LoadDDS_AG8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
56 TU_Error LoadDDS_A8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface);
57 
58 TU_Error SaveDDS_ABGR32F(FILE* pFile, const GX2Surface* pSurface);
59 TU_Error SaveDDS_RG32F(FILE* pFile, const GX2Surface* pSurface);
60 TU_Error SaveDDS_R32F(FILE* pFile, const GX2Surface* pSurface);
61 TU_Error SaveDDS_ABGR16F(FILE* pFile, const GX2Surface* pSurface);
62 TU_Error SaveDDS_RG16F(FILE* pFile, const GX2Surface* pSurface);
63 TU_Error SaveDDS_R16F(FILE* pFile, const GX2Surface* pSurface);
64 TU_Error SaveDDS_ARGB8888(FILE* pFile, const GX2Surface* pSurface);
65 TU_Error SaveDDS_ABGR2101010(FILE* pFile, const GX2Surface* pSurface);
66 TU_Error SaveDDS_ABGR16(FILE* pFile, const GX2Surface* pSurface);
67 TU_Error SaveDDS_R16(FILE* pFile, const GX2Surface* pSurface);
68 TU_Error SaveDDS_RG16(FILE* pFile, const GX2Surface* pSurface);
69 TU_Error SaveDDS_RGB888(FILE* pFile, const GX2Surface* pSurface);
70 TU_Error SaveDDS_FourCC(FILE* pFile, const GX2Surface* pSurface);
71 TU_Error SaveDDS_G8(FILE* pFile, const GX2Surface* pSurface);
72 TU_Error SaveDDS_A8(FILE* pFile, const GX2Surface* pSurface);
73 TU_Error SaveDDS_A8L8(FILE* pFile, const GX2Surface* pSurface);
74 TU_Error SaveDDS_RGB565(FILE* pFile, const GX2Surface* pSurface);
75 TU_Error SaveDDS_ARGB4444(FILE* pFile, const GX2Surface* pSurface);
76 TU_Error SaveDDS_ARGB1555(FILE* pFile, const GX2Surface* pSurface);
77 
DDSLoadFile(const TCHAR * pszFilename,GX2Surface * pSurface)78 bool DDSLoadFile(const TCHAR* pszFilename, GX2Surface* pSurface)
79 {
80     FILE* pFile = NULL;
81 
82     if(_tfopen_s(&pFile, pszFilename, _T("rb")))
83     {
84         return false;
85     }
86 
87     u32 dwFileHeader;
88     fread(&dwFileHeader ,sizeof(u32), 1, pFile);
89     if(dwFileHeader != DDS_HEADER)
90     {
91         fclose(pFile);
92         return false;
93     }
94 
95     DDSD2 ddsd;
96     if(fread(&ddsd, sizeof(DDSD2), 1, pFile) != 1)
97     {
98         fclose(pFile);
99         return false;
100     }
101 
102     if(!(ddsd.dwFlags & DDSD_MIPMAPCOUNT))
103         ddsd.dwMipMapCount = 1;
104     else if(ddsd.dwMipMapCount == 0)
105     {
106         ddsd.dwMipMapCount = 1;
107     }
108 
109     if(ddsd.ddpfPixelFormat.dwFourCC == MAKEFOURCC('D', 'X', '1', '0'))
110         return LoadDDS10(pFile, &ddsd, pSurface) == PE_OK;
111     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_A32B32G32R32F)
112         return LoadDDS_ABGR32F(pFile, &ddsd, pSurface) == PE_OK;
113     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_A16B16G16R16F)
114         return LoadDDS_ABGR16F(pFile, &ddsd, pSurface) == PE_OK;
115     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_G32R32F)
116         return LoadDDS_GR32F(pFile, &ddsd, pSurface) == PE_OK;
117     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_R32F)
118         return LoadDDS_R32F(pFile, &ddsd, pSurface) == PE_OK;
119     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_R16F)
120         return LoadDDS_R16F(pFile, &ddsd, pSurface) == PE_OK;
121     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_G16R16F)
122         return LoadDDS_G16R16F(pFile, &ddsd, pSurface) == PE_OK;
123     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_A16B16G16R16)
124         return LoadDDS_ABGR16(pFile, &ddsd, pSurface) == PE_OK;
125     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_Q16W16V16U16)
126         return LoadDDS_ABGR16(pFile, &ddsd, pSurface) == PE_OK;
127     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_G16R16)
128         return LoadDDS_G16R16(pFile, &ddsd, pSurface) == PE_OK;
129     else if(ddsd.ddpfPixelFormat.dwFourCC == D3DFMT_L16)
130         return LoadDDS_R16(pFile, &ddsd, pSurface) == PE_OK;
131     else if(ddsd.ddpfPixelFormat.dwFourCC)
132         return LoadDDS_FourCC(pFile, &ddsd, pSurface) == PE_OK;
133     else if(ddsd.ddpfPixelFormat.dwLuminanceBitCount==8 && (ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) && (ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS))
134         return LoadDDS_A4L4(pFile, &ddsd, pSurface) == PE_OK;
135     else if(ddsd.ddpfPixelFormat.dwLuminanceBitCount==8 && (ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE))
136         return LoadDDS_G8(pFile, &ddsd, pSurface) == PE_OK;
137     else if(ddsd.ddpfPixelFormat.dwLuminanceBitCount==16 && (ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) && (ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS))
138         return LoadDDS_A8L8(pFile, &ddsd, pSurface) == PE_OK;
139     else if(ddsd.ddpfPixelFormat.dwLuminanceBitCount==16 && (ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) && (ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS))
140         return LoadDDS_AG8(pFile, &ddsd, pSurface) == PE_OK;
141     else if(ddsd.ddpfPixelFormat.dwLuminanceBitCount==16 && (ddsd.ddpfPixelFormat.dwFlags & DDPF_LUMINANCE))
142         return LoadDDS_G16(pFile, &ddsd, pSurface) == PE_OK;
143     else if(ddsd.ddpfPixelFormat.dwAlphaBitDepth==8 && (ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHA))
144         return LoadDDS_A8(pFile, &ddsd, pSurface) == PE_OK;
145     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==16 && ddsd.ddpfPixelFormat.dwRBitMask==0x7c00 && ddsd.ddpfPixelFormat.dwGBitMask==0x3e0&&ddsd.ddpfPixelFormat.dwBBitMask==0x1f)
146         return LoadDDS_ARGB1555(pFile, &ddsd, pSurface) == PE_OK;
147     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==16 && ddsd.ddpfPixelFormat.dwRBitMask==0xf00 && ddsd.ddpfPixelFormat.dwGBitMask==0xf0&&ddsd.ddpfPixelFormat.dwBBitMask==0xf)
148         return LoadDDS_ARGB4444(pFile, &ddsd, pSurface) == PE_OK;
149     else if((ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB) && !(ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && (ddsd.ddpfPixelFormat.dwRGBBitCount==16))
150         return LoadDDS_RGB565(pFile, &ddsd, pSurface) == PE_OK;
151     else if((ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB) && !(ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) && (ddsd.ddpfPixelFormat.dwRGBBitCount==24))
152         return LoadDDS_RGB888(pFile, &ddsd, pSurface) == PE_OK;
153     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==32 && (ddsd.ddpfPixelFormat.dwRBitMask==0x3ff || ddsd.ddpfPixelFormat.dwRBitMask==0x3ff00000))
154         return LoadDDS_ABGR2101010(pFile, &ddsd, pSurface) == PE_OK;
155     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==32 && ddsd.ddpfPixelFormat.dwRBitMask==0xffff && ddsd.ddpfPixelFormat.dwGBitMask==0xffff0000)
156         return LoadDDS_G16R16(pFile, &ddsd, pSurface) == PE_OK;
157     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==16 && ddsd.ddpfPixelFormat.dwRBitMask==0xffff)
158         return LoadDDS_R16(pFile, &ddsd, pSurface) == PE_OK;
159     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==32)
160         return LoadDDS_RGB8888(pFile, &ddsd, pSurface, (ddsd.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) ? true : false) == PE_OK;
161     else if(ddsd.ddpfPixelFormat.dwRGBBitCount==16 && ddsd.ddpfPixelFormat.dwRBitMask==0x7c00 && ddsd.ddpfPixelFormat.dwGBitMask==0x3e0&&ddsd.ddpfPixelFormat.dwBBitMask==0x1f && ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0x8000)
162         return LoadDDS_ARGB1555(pFile, &ddsd, pSurface) == PE_OK; // This case is never executed (the above one supercedes it) ***
163 
164     return false;
165 }
166 
DDSFree(GX2Surface * pSurface)167 bool DDSFree(GX2Surface* pSurface)
168 {
169     return GenericFreeFunction(pSurface) == PE_OK;
170 }
171 
DDSConvertMipsToCubeFormat(const GX2Surface * pSurface,u8 * pWrite)172 void DDSConvertMipsToCubeFormat( const GX2Surface* pSurface, u8* pWrite )
173 {
174     int minMipSize;
175     if( pSurface->format == GX2_SURFACE_FORMAT_T_BC1_UNORM ||
176         pSurface->format == GX2_SURFACE_FORMAT_T_BC1_SRGB )
177     {
178         minMipSize = 8;
179     }
180     else if( pSurface->format >= GX2_SURFACE_FORMAT_T_BC2_UNORM &&
181         pSurface->format <= GX2_SURFACE_FORMAT_T_BC5_SNORM )
182     {
183         minMipSize = 16;
184     }
185     else
186     {
187         minMipSize = 1;
188     }
189 
190     const u8* pReadImg = (u8*)pSurface->imagePtr;
191     const u8* pReadMip = (u8*)pSurface->mipPtr;
192     for( u32 i = 0; i < 6; ++i )
193     {
194         int faceSize = pSurface->imageSize/6;
195         memcpy( pWrite, pReadImg + (faceSize*i), faceSize );
196         pWrite += faceSize;
197 
198         int mipOffset = 0;
199         for( u32 j = 0; j < pSurface->numMips-1; ++j )
200         {
201             int mipSize = faceSize >> ((j+1)*2);
202             mipSize = max( mipSize, minMipSize );
203 
204             memcpy( pWrite, pReadMip + mipOffset + (mipSize*i), mipSize );
205             pWrite += mipSize;
206             mipOffset += mipSize * 6;
207         }
208         assert( mipOffset == pSurface->mipSize );
209     }
210 }
211 
DDSSaveFile(const TCHAR * pszFilename,const GX2Surface * pSurface)212 bool DDSSaveFile(const TCHAR* pszFilename, const GX2Surface* pSurface)
213 {
214     assert(pszFilename);
215     assert(pSurface);
216 
217     FILE* pFile = NULL;
218     if(_tfopen_s(&pFile, pszFilename, _T("wb")))
219     {
220         return false;
221     }
222 
223     fwrite(&DDS_HEADER ,sizeof(u32), 1, pFile);
224 
225     // Cube-maps are stored differently than normal textures.
226     // Rather than have mip levels offset from the main image data,
227     // mips for a particular face directly follow that face in memory.
228 
229     void* pTempImg = NULL, *pTempMip = NULL;
230     u8* pTempData = NULL;
231     if( pSurface->dim == GX2_SURFACE_DIM_CUBE && pSurface->numMips > 1 )
232     {
233         // Store image data.
234         pTempImg = malloc( pSurface->imageSize );
235         pTempMip = malloc( pSurface->mipSize );
236         memcpy( pTempImg, pSurface->imagePtr, pSurface->imageSize );
237         memcpy( pTempMip, pSurface->mipPtr  , pSurface->mipSize );
238 
239         assert((pSurface->imageSize%6) == 0);
240         pTempData = (u8*)malloc( pSurface->imageSize + pSurface->mipSize );
241 
242         DDSConvertMipsToCubeFormat( pSurface, pTempData );
243 
244         memcpy( pSurface->imagePtr, pTempData, pSurface->imageSize );
245         memcpy( pSurface->mipPtr, pTempData + pSurface->imageSize, pSurface->mipSize );
246     }
247 
248     bool ret = false;
249     if(pSurface->format == GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM)
250         ret = SaveDDS_ABGR16(pFile, pSurface) == PE_OK;
251     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT)
252         ret = SaveDDS_ABGR16F(pFile, pSurface) == PE_OK;
253     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT)
254         ret = SaveDDS_ABGR32F(pFile, pSurface) == PE_OK;
255     else if(pSurface->format == GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM)
256         ret = SaveDDS_ABGR2101010(pFile, pSurface) == PE_OK;
257 
258     else if(pSurface->format == GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM)
259         ret = SaveDDS_RGB565(pFile, pSurface) == PE_OK;
260     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM)
261         ret = SaveDDS_ARGB1555(pFile, pSurface) == PE_OK;
262     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM)
263         ret = SaveDDS_ARGB4444(pFile, pSurface) == PE_OK;
264 
265     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R8_UNORM)
266         ret = SaveDDS_G8(pFile, pSurface) == PE_OK;
267     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R8_G8_UNORM)
268         ret = SaveDDS_A8L8(pFile, pSurface) == PE_OK;
269     else if(pSurface->format == GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM)
270         ret = SaveDDS_ARGB8888(pFile, pSurface) == PE_OK;
271     else if(pSurface->format == GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB)
272         ret = SaveDDS_ARGB8888(pFile, pSurface) == PE_OK;
273 
274     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC1_UNORM)
275         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
276     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC2_UNORM)
277         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
278     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC3_UNORM)
279         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
280     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC4_UNORM)
281         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
282     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC4_SNORM)
283         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
284     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC5_UNORM)
285         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
286     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC5_SNORM)
287         ret = SaveDDS_FourCC(pFile, pSurface) == PE_OK;
288 
289     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC1_SRGB)
290         ret = SaveDDS10(pFile, pSurface) == PE_OK;
291     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC2_SRGB)
292         ret = SaveDDS10(pFile, pSurface) == PE_OK;
293     else if(pSurface->format == GX2_SURFACE_FORMAT_T_BC3_SRGB)
294         ret = SaveDDS10(pFile, pSurface) == PE_OK;
295     else if(pSurface->format == GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT)
296         ret = SaveDDS10(pFile, pSurface) == PE_OK;
297 
298     // Restore image data.
299     if( pTempData )
300     {
301         memcpy( pSurface->imagePtr, pTempImg, pSurface->imageSize );
302         memcpy( pSurface->mipPtr, pTempMip, pSurface->mipSize );
303 
304         free( pTempImg );
305         free( pTempMip );
306         free( pTempData );
307 
308         pTempImg = NULL;
309         pTempMip = NULL;
310         pTempData = NULL;
311     }
312 
313     return ret;
314 }
315 
LoadDDS_FourCC(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)316 TU_Error LoadDDS_FourCC(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
317 {
318     void* extra;
319     TextureDataType tdt = TDT_XRGB;
320 
321     if (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('A', 'T', 'I', '1') ||
322         pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('B', 'C', '4', 'U'))
323     {
324         tdt = TDT_R;
325     }
326     else if (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('A', 'T', 'I', '2') ||
327              pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('B', 'C', '5', 'U'))
328     {
329         tdt = TDT_RG;
330     }
331 
332     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, tdt, PreLoopFourCC, LoopFourCC, PostLoopFourCC);
333     fclose(pFile);
334     return err;
335 }
336 
LoadDDS_RGB565(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)337 TU_Error LoadDDS_RGB565(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
338 {
339     void* extra;
340     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_8bit, TDT_RGB, PreLoopRGB565, LoopRGB565, PostLoopRGB565);
341     fclose(pFile);
342 
343     return err;
344 }
345 
LoadDDS_RGB888(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)346 TU_Error LoadDDS_RGB888(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
347 {
348     void* extra;
349     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_8bit, TDT_XRGB,
350         PreLoopRGB888, LoopRGB888, PostLoopRGB888);
351     fclose(pFile);
352 
353     return err;
354 }
355 
LoadDDS_RGB8888(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface,bool bAlpha)356 TU_Error LoadDDS_RGB8888(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface, bool bAlpha)
357 {
358     ARGB8888Struct* pARGB8888Struct = (ARGB8888Struct*)calloc(sizeof(ARGB8888Struct), 1);
359     void* extra = pARGB8888Struct;
360 
361     pARGB8888Struct->nFlags |= EF_UseBitMasks;
362 
363     if(pARGB8888Struct->nFlags & EF_UseBitMasks)
364     {    //using bitmasks
365         pARGB8888Struct->pMemory = malloc(4 * pDDSD->dwWidth * pDDSD->dwHeight);
366         pARGB8888Struct->nRMask = pDDSD->ddpfPixelFormat.dwRBitMask;
367         pARGB8888Struct->nGMask = pDDSD->ddpfPixelFormat.dwGBitMask;
368         pARGB8888Struct->nBMask = pDDSD->ddpfPixelFormat.dwBBitMask;
369 
370         int shift = 0;
371         int tempMask = pARGB8888Struct->nRMask;
372         while(!(tempMask & 0xFF) && tempMask)
373         {
374             shift += 8;
375             tempMask >>= 8;
376         }
377         pARGB8888Struct->nRShift = shift;
378 
379         shift = 0;
380         tempMask = pARGB8888Struct->nGMask;
381         while(!(tempMask & 0xFF) && tempMask)
382         {
383             shift += 8;
384             tempMask >>= 8;
385         }
386         pARGB8888Struct->nGShift = shift;
387 
388         shift = 0;
389         tempMask = pARGB8888Struct->nBMask;
390         while(!(tempMask & 0xFF) && tempMask)
391         {
392             shift += 8;
393             tempMask >>= 8;
394         }
395         pARGB8888Struct->nBShift = shift;
396     }
397 
398     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_8bit, bAlpha ? TDT_ARGB : TDT_XRGB,
399         PreLoopRGB8888, LoopRGB8888, PostLoopRGB8888);
400 
401     fclose(pFile);
402     return err;
403 }
404 
LoadDDS_ABGR2101010(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)405 TU_Error LoadDDS_ABGR2101010(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
406 {
407     TU_Error err = PE_Unknown;
408     ChannelFormat channelFormat = CF_2101010;
409     void* pChannelFormat = &channelFormat;
410 
411     if (pDDSD->ddpfPixelFormat.dwRBitMask==0x000003ff)
412     {
413         err = GenericLoadFunction(pFile, pDDSD, pSurface, pChannelFormat, channelFormat, TDT_ARGB,
414             PreLoopDefault, LoopA2R10G10B10, PostLoopDefault);
415     }
416     else if (pDDSD->ddpfPixelFormat.dwRBitMask==0x3ff00000)
417     {
418         err = GenericLoadFunction(pFile, pDDSD, pSurface, pChannelFormat, channelFormat, TDT_ARGB,
419             PreLoopDefault, LoopDefault, PostLoopDefault);
420     }
421     else
422     {
423         // read R10G10B10A2
424         err = GenericLoadFunction(pFile, pDDSD, pSurface, pChannelFormat, channelFormat, TDT_ARGB,
425             PreLoopDefault, LoopDefault /*LoopR10G10B10A2*/, PostLoopDefault);
426     }
427 
428     fclose(pFile);
429     return err;
430 }
431 
LoadDDS_ABGR32F(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)432 TU_Error LoadDDS_ABGR32F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
433 {
434     void* extra;
435     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Float32, TDT_ARGB,
436         PreLoopABGR32F, LoopABGR32F, PostLoopABGR32F);
437     fclose(pFile);
438     return err;
439 }
440 
LoadDDS_GR32F(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)441 TU_Error LoadDDS_GR32F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
442 {
443     void* extra;
444     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Float32, TDT_RG,
445         PreLoopABGR32F, LoopGR32F, PostLoopABGR32F);
446     fclose(pFile);
447 
448     return err;
449 }
450 
LoadDDS_R32F(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)451 TU_Error LoadDDS_R32F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
452 {
453     void* extra;
454     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Float32, TDT_R,
455         PreLoopABGR32F, LoopR32F, PostLoopABGR32F);
456     fclose(pFile);
457     return err;
458 }
459 
LoadDDS_R16F(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)460 TU_Error LoadDDS_R16F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
461 {
462     void* extra;
463     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Float16, TDT_R,
464         PreLoopABGR16F, LoopR16F, PostLoopABGR16F);
465     fclose(pFile);
466 
467     return err;
468 }
469 
LoadDDS_G16R16F(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)470 TU_Error LoadDDS_G16R16F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
471 {
472     void* extra;
473     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Float16, TDT_RG,
474         PreLoopABGR16F, LoopG16R16, PostLoopABGR16F);
475     fclose(pFile);
476 
477     return err;
478 }
479 
LoadDDS_ABGR16F(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)480 TU_Error LoadDDS_ABGR16F(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
481 {
482     void* extra;
483     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Float16, TDT_ARGB,
484         PreLoopABGR16, LoopABGR16, PostLoopABGR16);
485     fclose(pFile);
486 
487     return err;
488 }
489 
LoadDDS_A4L4(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)490 TU_Error LoadDDS_A4L4(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
491 {
492     void* extra;
493     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, TDT_RG,
494         PreLoopA4L4, LoopA4L4, PostLoopA4L4);
495 
496     fclose(pFile);
497     return err;
498 }
499 
LoadDDS_A8L8(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)500 TU_Error LoadDDS_A8L8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
501 {
502     void* extra;
503     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, TDT_RG,
504         PreLoopA8L8, LoopA8L8, PostLoopA8L8);
505 
506     fclose(pFile);
507     return err;
508 }
509 
LoadDDS_G8(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)510 TU_Error LoadDDS_G8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
511 {
512     void* extra;
513     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, TDT_XRGB,
514         PreLoopG8, LoopG8, PostLoopG8);
515     fclose(pFile);
516     return err;
517 }
518 
LoadDDS_AG8(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)519 TU_Error LoadDDS_AG8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
520 {
521     void* extra;
522     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, TDT_ARGB,
523         PreLoopAG8, LoopAG8, PostLoopAG8);
524     fclose(pFile);
525     return err;
526 }
527 
LoadDDS_G16(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)528 TU_Error LoadDDS_G16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
529 {
530     void* extra;
531     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, TDT_XRGB,
532         PreLoopG16, LoopG16, PostLoopG16);
533     fclose(pFile);
534     return err;
535 }
536 
LoadDDS_A8(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)537 TU_Error LoadDDS_A8(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
538 {
539     void* extra;
540     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_Compressed, TDT_ARGB,
541         PreLoopA8, LoopA8, PostLoopA8);
542     fclose(pFile);
543     return err;
544 }
545 
LoadDDS_ABGR16(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)546 TU_Error LoadDDS_ABGR16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
547 {
548     void* extra;
549     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_16bit, TDT_ARGB,
550         PreLoopABGR16, LoopABGR16, PostLoopABGR16);
551 
552     fclose(pFile);
553     return err;
554 }
555 
LoadDDS_G16R16(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)556 TU_Error LoadDDS_G16R16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
557 {
558     void* extra;
559     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_16bit, TDT_RG,
560         PreLoopG16R16, LoopG16R16, PostLoopG16R16);
561     fclose(pFile);
562 
563     return err;
564 }
565 
LoadDDS_ARGB1555(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)566 TU_Error LoadDDS_ARGB1555(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
567 {
568     void* extra;
569     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_1555, TDT_ARGB,
570         PreLoopARGB1555, LoopARGB1555, PostLoopARGB1555);
571     fclose(pFile);
572     return err;
573 }
574 
LoadDDS_ARGB4444(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)575 TU_Error LoadDDS_ARGB4444(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
576 {
577     void* extra;
578     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_4444, TDT_ARGB,
579         PreLoopARGB4444, LoopARGB4444, PostLoopARGB4444);
580     fclose(pFile);
581     return err;
582 }
583 
LoadDDS_R16(FILE * pFile,DDSD2 * pDDSD,GX2Surface * pSurface)584 TU_Error LoadDDS_R16(FILE* pFile, DDSD2* pDDSD, GX2Surface* pSurface)
585 {
586     void* extra;
587     TU_Error err = GenericLoadFunction(pFile, pDDSD, pSurface, extra, CF_16bit, TDT_R,
588         PreLoopG16R16, LoopABGR16, PostLoopG16R16);
589     fclose(pFile);
590     return err;
591 }
592 
593 ///////////////////////////////////////////////////
594 /// SAVE FUNCTIONS
595 //////////////////////////////////////////////////
596 
SaveDDS_RGB565(FILE * pFile,const GX2Surface * pSurface)597 TU_Error SaveDDS_RGB565(FILE* pFile, const GX2Surface* pSurface)
598 {
599     assert(pFile);
600     assert(pSurface);
601 
602     // Initialise surface descriptor
603     DDSD2 ddsd2;
604     SetupDDSD(ddsd2, pSurface, false);
605 
606     ddsd2.lPitch = pSurface->width * 2;
607     ddsd2.ddpfPixelFormat.dwRGBBitCount = 16;
608     ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB;
609 
610     // Write the data
611     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
612 
613     if(pSurface->imageSize > 0)
614     {
615         u16 value;
616         for (u32 count = 0; count < (pSurface->imageSize / 2); count++)
617         {
618             value = *((u16*)pSurface->imagePtr + count);
619             *((u16*)pSurface->imagePtr + count) = ((value & 0xf800) >> 11) | (value & 0x07e0) | ((value & 0x1f) << 11);
620         }
621         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
622     }
623 
624     if(pSurface->mipSize > 0)
625     {
626         u16 value;
627         for (u32 count = 0; count < (pSurface->mipSize / 2); count++)
628         {
629             value = *((u16*)pSurface->mipPtr + count);
630             *((u16*)pSurface->mipPtr + count) = ((value & 0xf800) >> 11) | (value & 0x07e0) | ((value & 0x1f) << 11);
631         }
632         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
633     }
634 
635     fclose(pFile);
636 
637     return PE_OK;
638 }
639 
SaveDDS_ARGB4444(FILE * pFile,const GX2Surface * pSurface)640 TU_Error SaveDDS_ARGB4444(FILE* pFile, const GX2Surface* pSurface)
641 {
642     assert(pFile);
643     assert(pSurface);
644 
645     // Initialise surface descriptor
646     DDSD2 ddsd2;
647     SetupDDSD(ddsd2, pSurface, false);
648 
649     ddsd2.ddpfPixelFormat.dwRBitMask = 0xf00;
650     ddsd2.ddpfPixelFormat.dwGBitMask = 0xf0;
651     ddsd2.ddpfPixelFormat.dwBBitMask = 0xf;
652 
653     ddsd2.lPitch = pSurface->width * 2;
654     ddsd2.ddpfPixelFormat.dwRGBBitCount = 16;
655     ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_ALPHAPIXELS;
656 
657     // Write the data
658     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
659 
660     if(pSurface->imageSize > 0)
661     {
662         u16 value;
663         for (u32 count = 0; count < (pSurface->imageSize / 2); count++)
664         {
665             value = *((u16*)pSurface->imagePtr + count);
666             //ARGB ABGR
667             *((u16*)pSurface->imagePtr + count) = (value & 0xf000) | ((value & 0x0f00) >> 8) | (value & 0x00f0) | ((value & 0x000f) << 8);
668         }
669         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
670     }
671 
672     if(pSurface->mipSize > 0)
673     {
674         u16 value;
675         for (u32 count = 0; count < (pSurface->mipSize / 2); count++)
676         {
677             value = *((u16*)pSurface->mipPtr + count);
678             //ARGB ABGR
679             *((u16*)pSurface->mipPtr + count) = (value & 0xf000) | ((value & 0x0f00) >> 8) | (value & 0x00f0) | ((value & 0x000f) << 8);
680         }
681         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
682     }
683 
684     fclose(pFile);
685 
686     return PE_OK;
687 }
688 
SaveDDS_ARGB1555(FILE * pFile,const GX2Surface * pSurface)689 TU_Error SaveDDS_ARGB1555(FILE* pFile, const GX2Surface* pSurface)
690 {
691     assert(pFile);
692     assert(pSurface);
693 
694     // Initialise surface descriptor
695     DDSD2 ddsd2;
696     SetupDDSD(ddsd2, pSurface, false);
697 
698     ddsd2.ddpfPixelFormat.dwRBitMask = 0x7c00;
699     ddsd2.ddpfPixelFormat.dwGBitMask = 0x3e0;
700     ddsd2.ddpfPixelFormat.dwBBitMask = 0x1f;
701     ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000;
702 
703     ddsd2.lPitch = pSurface->width * 2;
704     ddsd2.ddpfPixelFormat.dwRGBBitCount = 16;
705     ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_ALPHAPIXELS;
706 
707     // Write the data
708     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
709 
710     if(pSurface->imageSize > 0)
711     {
712         u16 value;
713         for (u32 count = 0; count < pSurface->imageSize/2; count++)
714         {
715             value = *((u16*)pSurface->imagePtr + count);
716             // [MSB] ARGB [LSB] to ABGR
717             *((u16*)pSurface->imagePtr + count) = ((value & 0x8000)) | ((value & 0x7c00) >> 10) | ((value & 0x001f) << 10) | (value & 0x03e0);
718         }
719         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
720     }
721 
722     if(pSurface->mipSize > 0)
723     {
724         u16 value;
725         for (u32 count = 0; count < pSurface->mipSize/2; count++)
726         {
727             value = *((u16*)pSurface->mipPtr + count);
728             // [MSB] ARGB [LSB] to ABGR
729             *((u16*)pSurface->mipPtr + count) = ((value & 0x8000)) | ((value & 0x7c00) >> 10) | ((value & 0x001f) << 10) | (value & 0x03e0);
730         }
731         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
732     }
733 
734     fclose(pFile);
735 
736     return PE_OK;
737 }
738 
SaveDDS_ARGB8888(FILE * pFile,const GX2Surface * pSurface)739 TU_Error SaveDDS_ARGB8888(FILE* pFile, const GX2Surface* pSurface)
740 {
741     assert(pFile);
742     assert(pSurface);
743 
744     // Initialise surface descriptor
745     DDSD2 ddsd2;
746     SetupDDSD(ddsd2, pSurface, false);
747 
748     ddsd2.ddpfPixelFormat.dwRBitMask = 0x000000ff;
749     ddsd2.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
750     ddsd2.ddpfPixelFormat.dwBBitMask = 0x00ff0000;
751     ddsd2.lPitch = pSurface->width * 4;
752     ddsd2.ddpfPixelFormat.dwRGBBitCount = 32;
753     ddsd2.ddpfPixelFormat.dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS;
754     ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x00000000;
755 
756     // Write the data
757     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
758 
759     if(pSurface->imageSize > 0)
760         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
761 
762     if(pSurface->mipSize > 0)
763         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
764 
765     fclose(pFile);
766     return PE_OK;
767 }
768 
SaveDDS_ABGR2101010(FILE * pFile,const GX2Surface * pSurface)769 TU_Error SaveDDS_ABGR2101010(FILE* pFile, const GX2Surface* pSurface)
770 {
771     assert(pFile);
772     assert(pSurface);
773 
774     // Initialise surface descriptor
775     DDSD2 ddsd2;
776     SetupDDSD(ddsd2, pSurface, false);
777 
778     ddsd2.ddpfPixelFormat.dwRBitMask = 0x3ff00000;
779     ddsd2.ddpfPixelFormat.dwGBitMask = 0x000ffc00;
780     ddsd2.ddpfPixelFormat.dwBBitMask = 0x000003ff;
781     ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0xc0000000;
782     ddsd2.lPitch = pSurface->width * 4;
783     ddsd2.ddpfPixelFormat.dwRGBBitCount = 32;
784     ddsd2.ddpfPixelFormat.dwFlags=DDPF_ALPHAPIXELS|DDPF_RGB;
785 
786     // Write the data
787     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
788 
789     if(pSurface->imageSize > 0)
790         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
791 
792     if(pSurface->mipSize > 0)
793         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
794 
795     fclose(pFile);
796 
797     return PE_OK;
798 }
799 
SaveDDS_ABGR16(FILE * pFile,const GX2Surface * pSurface)800 TU_Error SaveDDS_ABGR16(FILE* pFile, const GX2Surface* pSurface)
801 {
802     assert(pFile);
803     assert(pSurface);
804 
805     // Initialise surface descriptor
806     DDSD2 ddsd2;
807     SetupDDSD(ddsd2, pSurface, false);
808 
809     ddsd2.lPitch = pSurface->width * 8;
810     ddsd2.ddpfPixelFormat.dwFlags = DDPF_FOURCC|DDPF_ALPHAPIXELS;
811     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_A16B16G16R16;
812 
813     // Write the data
814     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
815 
816     if(pSurface->imageSize > 0)
817         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
818 
819     if(pSurface->mipSize > 0)
820         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
821 
822     fclose(pFile);
823 
824     return PE_OK;
825 }
826 
SaveDDS_R16(FILE * pFile,const GX2Surface * pSurface)827 TU_Error SaveDDS_R16(FILE* pFile, const GX2Surface* pSurface)
828 {
829     assert(pFile);
830     assert(pSurface);
831 
832     // Initialise surface descriptor
833     DDSD2 ddsd2;
834     SetupDDSD(ddsd2, pSurface, false);
835 
836     ddsd2.lPitch = pSurface->width * 2;
837     ddsd2.ddpfPixelFormat.dwFlags = DDPF_FOURCC|DDPF_ALPHAPIXELS;
838     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_L16;
839 
840     // Write the data
841     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
842 
843     if(pSurface->imageSize > 0)
844         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
845 
846     if(pSurface->mipSize > 0)
847         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
848 
849     fclose(pFile);
850     return PE_OK;
851 }
852 
SaveDDS_RG16(FILE * pFile,const GX2Surface * pSurface)853 TU_Error SaveDDS_RG16(FILE* pFile, const GX2Surface* pSurface)
854 {
855     assert(pFile);
856     assert(pSurface);
857 
858     // Initialise surface descriptor
859     DDSD2 ddsd2;
860     SetupDDSD(ddsd2, pSurface, false);
861 
862     ddsd2.lPitch = pSurface->width * 4;
863     ddsd2.ddpfPixelFormat.dwFlags = DDPF_FOURCC|DDPF_ALPHAPIXELS;
864     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_G16R16;
865 
866     // Write the data
867     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
868 
869     if(pSurface->imageSize > 0)
870         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
871 
872     if(pSurface->mipSize > 0)
873         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
874 
875     fclose(pFile);
876 
877     return PE_OK;
878 }
879 
SaveDDS_ABGR16F(FILE * pFile,const GX2Surface * pSurface)880 TU_Error SaveDDS_ABGR16F(FILE* pFile, const GX2Surface* pSurface)
881 {
882     assert(pFile);
883     assert(pSurface);
884 
885     // Initialise surface descriptor
886     DDSD2 ddsd2;
887     SetupDDSD(ddsd2, pSurface, false);
888 
889     ddsd2.lPitch = pSurface->width * 8;
890     ddsd2.ddpfPixelFormat.dwFlags = DDPF_FOURCC|DDPF_ALPHAPIXELS;
891     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_A16B16G16R16F;
892 
893     // Write the data
894     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
895 
896     if(pSurface->imageSize > 0)
897         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
898 
899     if(pSurface->mipSize > 0)
900         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
901 
902     fclose(pFile);
903 
904     return PE_OK;
905 }
906 
SaveDDS_R16F(FILE * pFile,const GX2Surface * pSurface)907 TU_Error SaveDDS_R16F(FILE* pFile, const GX2Surface* pSurface)
908 {
909     assert(pFile);
910     assert(pSurface);
911 
912     // Initialise surface descriptor
913     DDSD2 ddsd2;
914     SetupDDSD(ddsd2, pSurface, false);
915 
916     ddsd2.lPitch = pSurface->width * 2;
917     ddsd2.ddpfPixelFormat.dwFlags = DDPF_FOURCC|DDPF_ALPHAPIXELS;
918     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_R16F;
919 
920     // Write the data
921     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
922 
923     if(pSurface->imageSize > 0)
924         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
925 
926     if(pSurface->mipSize > 0)
927         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
928 
929     fclose(pFile);
930     return PE_OK;
931 }
932 
SaveDDS_RG16F(FILE * pFile,const GX2Surface * pSurface)933 TU_Error SaveDDS_RG16F(FILE* pFile, const GX2Surface* pSurface)
934 {
935     assert(pFile);
936     assert(pSurface);
937 
938     // Initialise surface descriptor
939     DDSD2 ddsd2;
940     SetupDDSD(ddsd2, pSurface, false);
941 
942     ddsd2.lPitch = pSurface->width * 4;
943     ddsd2.ddpfPixelFormat.dwFlags = DDPF_FOURCC|DDPF_ALPHAPIXELS;
944     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_G16R16F;
945 
946     // Write the data
947     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
948 
949     if(pSurface->imageSize > 0)
950         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
951 
952     if(pSurface->mipSize > 0)
953         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
954 
955     fclose(pFile);
956 
957     return PE_OK;
958 }
959 
SaveDDS_ABGR32F(FILE * pFile,const GX2Surface * pSurface)960 TU_Error SaveDDS_ABGR32F(FILE* pFile, const GX2Surface* pSurface)
961 {
962     assert(pFile);
963     assert(pSurface);
964 
965     // Initialise surface descriptor
966     DDSD2 ddsd2;
967     SetupDDSD(ddsd2, pSurface, false);
968 
969     ddsd2.lPitch = pSurface->width * 16;
970     ddsd2.ddpfPixelFormat.dwFlags=DDPF_FOURCC|DDPF_ALPHAPIXELS;
971     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_A32B32G32R32F;
972 
973     // Write the data
974     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
975 
976     if(pSurface->imageSize > 0)
977         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
978 
979     if(pSurface->mipSize > 0)
980         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
981 
982     fclose(pFile);
983 
984     return PE_OK;
985 }
986 
SaveDDS_R32F(FILE * pFile,const GX2Surface * pSurface)987 TU_Error SaveDDS_R32F(FILE* pFile, const GX2Surface* pSurface)
988 {
989     assert(pFile);
990     assert(pSurface);
991 
992     // Initialise surface descriptor
993     DDSD2 ddsd2;
994     SetupDDSD(ddsd2, pSurface, false);
995 
996     ddsd2.lPitch = pSurface->width * 4;
997     ddsd2.ddpfPixelFormat.dwFlags=DDPF_FOURCC|DDPF_ALPHAPIXELS;
998     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_R32F;
999 
1000     // Write the data
1001     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
1002 
1003     if(pSurface->imageSize > 0)
1004         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
1005 
1006     if(pSurface->mipSize > 0)
1007         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
1008 
1009     fclose(pFile);
1010 
1011     return PE_OK;
1012 }
1013 
SaveDDS_RG32F(FILE * pFile,const GX2Surface * pSurface)1014 TU_Error SaveDDS_RG32F(FILE* pFile, const GX2Surface* pSurface)
1015 {
1016     assert(pFile);
1017     assert(pSurface);
1018 
1019     // Initialise surface descriptor
1020     DDSD2 ddsd2;
1021     SetupDDSD(ddsd2, pSurface, false);
1022 
1023     ddsd2.lPitch = pSurface->width * 8;
1024     ddsd2.ddpfPixelFormat.dwFlags=DDPF_FOURCC|DDPF_ALPHAPIXELS;
1025     ddsd2.ddpfPixelFormat.dwFourCC = D3DFMT_G32R32F;
1026 
1027     // Write the data
1028     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
1029 
1030     if(pSurface->imageSize > 0)
1031         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
1032 
1033     if(pSurface->mipSize > 0)
1034         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
1035 
1036     fclose(pFile);
1037 
1038     return PE_OK;
1039 }
1040 
SaveDDS_FourCC(FILE * pFile,const GX2Surface * pSurface)1041 TU_Error SaveDDS_FourCC(FILE* pFile, const GX2Surface* pSurface)
1042 {
1043     assert(pFile);
1044     assert(pSurface);
1045 
1046     DDSD2 ddsd2;
1047     SetupDDSD(ddsd2, pSurface, true);
1048 
1049     if (pSurface->format == GX2_SURFACE_FORMAT_T_BC1_UNORM)
1050     {
1051         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('D', 'X', 'T', '1');
1052     }
1053     else if (pSurface->format == GX2_SURFACE_FORMAT_T_BC2_UNORM)
1054     {
1055         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('D', 'X', 'T', '3');
1056     }
1057     else if (pSurface->format == GX2_SURFACE_FORMAT_T_BC3_UNORM)
1058     {
1059         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('D', 'X', 'T', '5');
1060     }
1061     else if (pSurface->format == GX2_SURFACE_FORMAT_T_BC4_UNORM)
1062     {
1063         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('A', 'T', 'I', '1');
1064     }
1065     else if (pSurface->format == GX2_SURFACE_FORMAT_T_BC4_SNORM)
1066     {
1067         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('A', 'T', 'I', '1');
1068     }
1069     else if (pSurface->format == GX2_SURFACE_FORMAT_T_BC5_UNORM)
1070     {
1071         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('A', 'T', 'I', '2');
1072     }
1073     else if (pSurface->format == GX2_SURFACE_FORMAT_T_BC5_SNORM)
1074     {
1075         ddsd2.ddpfPixelFormat.dwFourCC = MAKEFOURCC('A', 'T', 'I', '2');
1076     }
1077     else
1078     {
1079         return  PE_Unknown;
1080     }
1081 
1082     ddsd2.ddpfPixelFormat.dwFlags=DDPF_FOURCC;
1083 
1084     /*
1085     if(pMipSet->m_TextureDataType == TDT_ARGB)
1086         ddsd2.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS;
1087     if(pMipSet->m_Flags & MS_AlphaPremult)
1088         ddsd2.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPREMULT;
1089     ddsd2.ddpfPixelFormat.dwPrivateFormatBitCount = pMipSet->m_dwFourCC2;
1090     */
1091 
1092     // Write the data
1093     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
1094 
1095     if(pSurface->imageSize > 0)
1096         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
1097 
1098     if(pSurface->mipSize > 0)
1099         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
1100 
1101     fclose(pFile);
1102 
1103     return PE_OK;
1104 }
1105 
SaveDDS_G8(FILE * pFile,const GX2Surface * pSurface)1106 TU_Error SaveDDS_G8(FILE* pFile, const GX2Surface* pSurface)
1107 {
1108     assert(pFile);
1109     assert(pSurface);
1110 
1111     DDSD2 ddsd2;
1112     SetupDDSD(ddsd2, pSurface, false);
1113 
1114     ddsd2.lPitch = pSurface->width * 8;
1115     ddsd2.ddpfPixelFormat.dwFlags=DDPF_LUMINANCE;
1116     ddsd2.ddpfPixelFormat.dwLuminanceBitCount = 8;
1117     ddsd2.ddpfPixelFormat.dwLuminanceBitMask = 0xff;
1118 
1119     // Write the data
1120     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
1121 
1122     if(pSurface->imageSize > 0)
1123         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
1124 
1125     if(pSurface->mipSize > 0)
1126         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
1127 
1128     fclose(pFile);
1129 
1130     return PE_OK;
1131 }
1132 
SaveDDS_A8(FILE * pFile,const GX2Surface * pSurface)1133 TU_Error SaveDDS_A8(FILE* pFile, const GX2Surface* pSurface)
1134 {
1135     assert(pFile);
1136     assert(pSurface);
1137 
1138 
1139     DDSD2 ddsd2;
1140     SetupDDSD(ddsd2, pSurface, false);
1141 
1142     ddsd2.lPitch = pSurface->width * 8;
1143     ddsd2.ddpfPixelFormat.dwFlags=DDPF_ALPHA;
1144     ddsd2.ddpfPixelFormat.dwAlphaBitDepth = 8;
1145     ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff;
1146 
1147     // Write the data
1148     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
1149 
1150     if(pSurface->imageSize > 0)
1151         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
1152 
1153     if(pSurface->mipSize > 0)
1154         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
1155 
1156     fclose(pFile);
1157 
1158     return PE_OK;
1159 }
1160 
SaveDDS_A8L8(FILE * pFile,const GX2Surface * pSurface)1161 TU_Error SaveDDS_A8L8(FILE* pFile, const GX2Surface* pSurface)
1162 {
1163     assert(pFile);
1164     assert(pSurface);
1165 
1166 
1167     DDSD2 ddsd2;
1168     SetupDDSD(ddsd2, pSurface, false);
1169 
1170     ddsd2.ddpfPixelFormat.dwLuminanceBitCount=16;
1171     ddsd2.ddpfPixelFormat.dwFlags = DDPF_LUMINANCE|DDPF_ALPHAPIXELS;
1172 
1173     ddsd2.lPitch = pSurface->width * 8;
1174     ddsd2.ddpfPixelFormat.dwRBitMask        = 0x000000ff;
1175     ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x0000ff00;
1176 
1177     // Write the data
1178     fwrite(&ddsd2, sizeof(DDSD2), 1, pFile);
1179 
1180     if(pSurface->imageSize > 0)
1181         fwrite(pSurface->imagePtr, 1, pSurface->imageSize, pFile);
1182 
1183     if(pSurface->mipSize > 0)
1184         fwrite(pSurface->mipPtr, 1, pSurface->mipSize, pFile);
1185 
1186     fclose(pFile);
1187 
1188     return PE_OK;
1189 }
1190 
1191 }   //namespace DDSReader
1192