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