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