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