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_Helpers.cpp
14 // ------------------------------------------------------------------
15 #include "stdafx.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <assert.h>
19 #include <limits.h>
20 #include "ddraw.h"
21 #include "d3d9types.h"
22 #include "DDS.h"
23 #include "DDS_Helpers.h"
24 #include "resource.h"
25 
26 namespace DDSReader
27 {
IsD3D10Format(const GX2Surface * pSurface)28 bool IsD3D10Format(const GX2Surface* pSurface)
29 {
30     assert(pSurface);
31 
32     if(!pSurface)
33         return false;
34 
35     switch (pSurface->format)
36     {
37     case GX2_SURFACE_FORMAT_T_BC1_UNORM:
38     case GX2_SURFACE_FORMAT_T_BC2_UNORM:
39     case GX2_SURFACE_FORMAT_T_BC3_UNORM:
40     case GX2_SURFACE_FORMAT_T_BC4_UNORM:
41     case GX2_SURFACE_FORMAT_T_BC4_SNORM:
42     case GX2_SURFACE_FORMAT_T_BC5_UNORM:
43     case GX2_SURFACE_FORMAT_T_BC5_SNORM:
44         return true;
45     }
46 
47     return false;
48 }
49 
GetGX2TextureInfo(const DDSD2 * pDDSD,GX2Surface * pSurface,ChannelFormat channelFormat,TextureDataType textureDataType,MS_CubeFace * pCubeFaceMask)50 bool GetGX2TextureInfo(const DDSD2* pDDSD, GX2Surface* pSurface, ChannelFormat channelFormat,
51                        TextureDataType textureDataType,MS_CubeFace* pCubeFaceMask)
52 {
53     u32 cubeFaceMask = 0;
54     HMODULE   hTexUtilDLL = LoadLibrary(LIB_DLL_TEXUTILS);
55     if ( !hTexUtilDLL )
56     {
57         printf("Failed to load DLL %s. Exiting.", LIB_DLL_TEXUTILS);
58         FreeLibrary(hTexUtilDLL);
59         exit(1);
60     }
61     PTC2GetSourceSurfaceSize fpTC2GetSourceSurfaceSize    = reinterpret_cast<PTC2GetSourceSurfaceSize>(GetProcAddress(hTexUtilDLL, "TC2GetSourceSurfaceSize"));
62 
63     if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
64     {
65         pSurface->depth = 0;
66         pSurface->dim = GX2_SURFACE_DIM_CUBE;
67         cubeFaceMask = MS_CF_None;
68 
69         if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX)
70         {
71             pSurface->depth++;
72             cubeFaceMask |= MS_CF_PositiveX;
73         }
74         if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEY)
75         {
76             pSurface->depth++;
77             cubeFaceMask |= MS_CF_PositiveY;
78         }
79         if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ)
80         {
81             pSurface->depth++;
82             cubeFaceMask |= MS_CF_PositiveZ;
83         }
84         if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX)
85         {
86             pSurface->depth++;
87             cubeFaceMask |= MS_CF_NegativeX;
88         }
89         if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY)
90         {
91             pSurface->depth++;
92             cubeFaceMask |= MS_CF_NegativeY;
93         }
94         if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ)
95         {
96             pSurface->depth++;
97             cubeFaceMask |= MS_CF_NegativeZ;
98         }
99     }
100     else if(pDDSD->ddsCaps.dwCaps2 & DDSCAPS2_VOLUME && pDDSD->dwFlags & DDSD_DEPTH)
101     {
102         pSurface->depth = pDDSD->dwDepth;
103         pSurface->dim = GX2_SURFACE_DIM_3D;
104     }
105     else if(pDDSD->dwFlags & DDSD_DEPTH)
106     {
107         pSurface->depth = pDDSD->dwDepth;
108         pSurface->dim = GX2_SURFACE_DIM_2D_ARRAY;
109     }
110 	else
111     {
112         pSurface->depth = 1;
113         pSurface->dim = GX2_SURFACE_DIM_2D;
114     }
115 
116     if(pDDSD->dwFlags & DDSD_MIPMAPCOUNT)
117     {
118         pSurface->numMips = pDDSD->dwMipMapCount;
119     }
120     else
121     {
122         pSurface->numMips = pDDSD->dwMipMapCount;
123     }
124 
125     if(pSurface->numMips < 1)
126     {
127         pSurface->numMips = 1;
128     }
129 
130     pSurface->width     = pDDSD->dwWidth;
131     pSurface->height    = pDDSD->dwHeight;
132     pSurface->tileMode  = GX2_TILE_MODE_LINEAR_SPECIAL;
133     pSurface->use       = GX2_SURFACE_USE_TEXTURE;
134     pSurface->alignment = 1;
135 
136     switch (channelFormat)
137     {
138     case CF_Compressed:
139         if (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('D', 'X', 'T', '1') &&
140             (textureDataType == TDT_XRGB || textureDataType == TDT_ARGB))
141         {
142             pSurface->format = GX2_SURFACE_FORMAT_T_BC1_UNORM;
143             break;
144         }
145         else if (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('D', 'X', 'T', '3') &&
146             (textureDataType == TDT_XRGB || textureDataType == TDT_ARGB))
147         {
148             pSurface->format = GX2_SURFACE_FORMAT_T_BC2_UNORM;
149             break;
150         }
151         else if (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('D', 'X', 'T', '5') &&
152             (textureDataType == TDT_XRGB || textureDataType == TDT_ARGB))
153         {
154             pSurface->format = GX2_SURFACE_FORMAT_T_BC3_UNORM;
155             break;
156         }
157         else if ( (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('A', 'T', 'I', '1') ||
158                    pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('B', 'C', '4', 'U' ) ) &&
159             textureDataType == TDT_R)
160         {
161             pSurface->format = GX2_SURFACE_FORMAT_T_BC4_UNORM;
162             break;
163         }
164         else if ( (pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('A', 'T', 'I', '2') ||
165                    pDDSD->ddpfPixelFormat.dwFourCC == MAKEFOURCC('B', 'C', '5', 'U' ) ) &&
166             textureDataType == TDT_RG)
167         {
168             pSurface->format = GX2_SURFACE_FORMAT_T_BC5_UNORM;
169             break;
170         }
171         else if((pDDSD->ddpfPixelFormat.dwLuminanceBitCount == 8) &&
172                 (pDDSD->ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) &&
173                 (pDDSD->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS))
174         {
175             pSurface->format = GX2_SURFACE_FORMAT_T_R4_G4_UNORM;
176             break;
177         }
178         else if((pDDSD->ddpfPixelFormat.dwLuminanceBitCount == 16) &&
179                 (pDDSD->ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) &&
180                 (pDDSD->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS))
181         {
182             pSurface->format = GX2_SURFACE_FORMAT_TC_R8_G8_UNORM;
183             break;
184         }
185         else if((pDDSD->ddpfPixelFormat.dwLuminanceBitCount == 16) &&
186                 (pDDSD->ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) &&
187                 ((pDDSD->ddpfPixelFormat.dwFlags | DDPF_LUMINANCE) == DDPF_LUMINANCE))
188         {
189             pSurface->format = GX2_SURFACE_FORMAT_TCD_R16_UNORM;
190             break;
191         }
192         else if((pDDSD->ddpfPixelFormat.dwLuminanceBitCount == 8) &&
193                 (pDDSD->ddpfPixelFormat.dwFlags & DDPF_LUMINANCE) &&
194                 ((pDDSD->ddpfPixelFormat.dwFlags | DDPF_LUMINANCE) == DDPF_LUMINANCE))
195         {
196             pSurface->format = GX2_SURFACE_FORMAT_TC_R8_UNORM;
197             break;
198         }
199         else
200         {
201             printf("Unsupported texture data type");
202             FreeLibrary(hTexUtilDLL);
203             return false;
204         }
205         break;
206     case CF_8bit:
207         switch (textureDataType)
208         {
209         case TDT_XRGB:
210         case TDT_ARGB:
211             pSurface->format = GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM;
212             break;
213         case TDT_R:
214             pSurface->format = GX2_SURFACE_FORMAT_TC_R8_UNORM;
215         case TDT_RG:
216             pSurface->format = GX2_SURFACE_FORMAT_TC_R8_G8_UNORM;
217             break;
218         case TDT_RGB:
219             if (pDDSD->ddpfPixelFormat.dwRBitMask == 0x0000f800 && pDDSD->ddpfPixelFormat.dwGBitMask == 0x000007e0 && pDDSD->ddpfPixelFormat.dwBBitMask == 0x0000001f)
220             {
221                 // Loader will flip RGB/BGR order
222                 pSurface->format = GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM;
223             }
224             else
225             {
226                 assert(!"Unsupported texture data type");
227                 FreeLibrary(hTexUtilDLL);
228                 return false;
229             }
230             break;
231         default:
232             assert(!"Unsupported texture data type");
233             FreeLibrary(hTexUtilDLL);
234             return false;
235         }
236         break;
237     case CF_Float16:
238         switch (textureDataType)
239         {
240         case TDT_XRGB:
241         case TDT_ARGB:
242             pSurface->format = GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT;
243             break;
244         case TDT_R:
245             pSurface->format = GX2_SURFACE_FORMAT_TC_R16_FLOAT;
246             break;
247         case TDT_RG:
248             pSurface->format = GX2_SURFACE_FORMAT_TC_R16_G16_FLOAT;
249             break;
250         default:
251             assert(!"Unsupported texture data type");
252             FreeLibrary(hTexUtilDLL);
253             return false;
254         }
255         break;
256     case CF_Float32:
257         switch (textureDataType)
258         {
259         case TDT_R:
260             pSurface->format = GX2_SURFACE_FORMAT_TCD_R32_FLOAT;
261             break;
262         case TDT_RG:
263             pSurface->format = GX2_SURFACE_FORMAT_TC_R32_G32_FLOAT;
264             break;
265         case TDT_XRGB:
266         case TDT_ARGB:
267             pSurface->format = GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT;
268             break;
269         default:
270             assert(!"Unsupported texture data type");
271             FreeLibrary(hTexUtilDLL);
272             return false;
273         }
274         break;
275     case CF_16bit:
276         switch (textureDataType)
277         {
278         case TDT_XRGB:
279         case TDT_ARGB:
280             pSurface->format = GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM;
281             break;
282         case TDT_RG:
283             pSurface->format = GX2_SURFACE_FORMAT_TC_R16_G16_UNORM;
284             break;
285         default:
286             assert(!"Unsupported texture data type");
287             FreeLibrary(hTexUtilDLL);
288             return false;
289         }
290         break;
291     case CF_32bit:
292         switch (textureDataType)
293         {
294         case TDT_XRGB:
295         case TDT_ARGB:
296             pSurface->format = GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_UINT;
297             break;
298         default:
299             assert(!"Unsupported texture data type");
300             FreeLibrary(hTexUtilDLL);
301             return false;
302         }
303         break;
304     case CF_1555:
305         if (pDDSD->ddpfPixelFormat.dwRBitMask==0x00007c00) {
306             // Loader will flip RGB/BGR order
307             pSurface->format = GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM;
308         } else {
309             assert(!"Unsupported texture data type");
310             FreeLibrary(hTexUtilDLL);
311             return false;
312         }
313         break;
314     case CF_4444:
315         pSurface->format = GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM;
316         break;
317     case CF_2101010:
318         switch (textureDataType)
319         {
320         case TDT_XRGB:
321         case TDT_ARGB:
322             if (pDDSD->ddpfPixelFormat.dwRBitMask==0x000003ff)
323             {
324                 pSurface->format = GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM;
325             }
326             else if (pDDSD->ddpfPixelFormat.dwRBitMask==0x3ff00000)
327             {
328                 // Loader will flip RGB/BGR order
329                 pSurface->format = GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM;
330             }
331             else
332             {
333                 pSurface->format = GX2_SURFACE_FORMAT_TCS_A2_B10_G10_R10_UNORM;
334             }
335             break;
336         default:
337             assert(!"Unsupported texture data type");
338             FreeLibrary(hTexUtilDLL);
339             return false;
340         }
341         break;
342     default:
343         assert(!"Unsupported channel format");
344         FreeLibrary(hTexUtilDLL);
345         return false;
346     }
347 
348     if (!fpTC2GetSourceSurfaceSize(pSurface))
349     {
350         FreeLibrary(hTexUtilDLL);
351         return false;
352     }
353 
354     FreeLibrary(hTexUtilDLL);
355     return true;
356 }
357 
GenericLoadFunction(FILE * & pFile,DDSD2 * & pDDSD,GX2Surface * & pSurface,void * & extra,ChannelFormat channelFormat,TextureDataType textureDataType,PreLoopFunction fnPreLoop,LoopFunction fnLoop,PostLoopFunction fnPostLoop)358 TU_Error GenericLoadFunction(FILE*& pFile, DDSD2*& pDDSD, GX2Surface*& pSurface, void*& extra, ChannelFormat channelFormat,
359                              TextureDataType textureDataType, PreLoopFunction fnPreLoop, LoopFunction fnLoop, PostLoopFunction fnPostLoop)
360 {
361     u32 dwWidth, dwHeight;
362     TU_Error err;
363     MS_CubeFace cubeFaceMask = MS_CF_None;
364 
365     memset(pSurface, 0, sizeof(*pSurface));
366     if (!GetGX2TextureInfo(pDDSD, pSurface, channelFormat, textureDataType, &cubeFaceMask))
367     {
368         return PE_Unknown;
369     }
370 
371     pSurface->imagePtr = malloc(pSurface->imageSize + pSurface->mipSize);
372 
373     if (pSurface->mipSize)
374     {
375         pSurface->mipPtr = (void*)((u8*)pSurface->imagePtr + pSurface->imageSize);
376     }
377 
378     err = fnPreLoop(pFile, pDDSD, pSurface, extra);
379     if(err != PE_OK)
380     {
381         return err;
382     }
383 
384         if(pSurface->dim == GX2_SURFACE_DIM_2D || pSurface->dim == GX2_SURFACE_DIM_CUBE)
385         {
386             for(u32 nFace = 0; nFace < pSurface->depth; nFace++)
387             {
388                 dwWidth = pDDSD->dwWidth;
389                 dwHeight = pDDSD->dwHeight;
390                 for(u32 nMipLevel = 0; nMipLevel < pSurface->numMips; nMipLevel++)
391                 {
392                     err = fnLoop(pFile, pDDSD, pSurface, extra, nMipLevel, nFace, dwWidth, dwHeight);
393                     if(err != PE_OK)
394                         return err;
395                     dwWidth = (dwWidth>1) ? (dwWidth>>1) : 1;
396                     dwHeight = (dwHeight>1) ? (dwHeight>>1) : 1;
397                 }
398             }
399         }
400         else if(pSurface->dim == GX2_SURFACE_DIM_3D)
401         {
402             dwWidth = pDDSD->dwWidth;
403             dwHeight = pDDSD->dwHeight;
404             for(u32 nMipLevel = 0; nMipLevel < pSurface->numMips; nMipLevel++)
405             {
406                 int nMaxSlices = MaxFacesOrSlices(pSurface, nMipLevel);
407                 for(int nSlice=0; nSlice<nMaxSlices; nSlice++)
408                 {
409                     err = fnLoop(pFile, pDDSD, pSurface, extra, nMipLevel, nSlice, dwWidth, dwHeight);
410                     if(err != PE_OK)
411                         return err;
412                 }
413                 dwWidth = dwWidth>1 ? dwWidth>>1 : 1;
414                 dwHeight = dwHeight>1 ? dwHeight>>1 : 1;
415             }
416         }
417 		else if(pSurface->dim == GX2_SURFACE_DIM_2D_ARRAY)
418         {
419             dwWidth = pDDSD->dwWidth;
420             dwHeight = pDDSD->dwHeight;
421             int nMaxSlices = pDDSD->dwDepth;
422 			for(u32 nMipLevel = 0; nMipLevel < pSurface->numMips; nMipLevel++)
423             {
424                 for(int nSlice=0; nSlice<nMaxSlices; nSlice++)
425                 {
426                     err = fnLoop(pFile, pDDSD, pSurface, extra, nMipLevel, nSlice, dwWidth, dwHeight);
427                     if(err != PE_OK)
428                         return err;
429                 }
430                 dwWidth = dwWidth>1 ? dwWidth>>1 : 1;
431                 dwHeight = dwHeight>1 ? dwHeight>>1 : 1;
432             }
433         }
434         else
435         {
436             ASSERT(0);
437             return PE_Unknown;
438         }
439 
440     return fnPostLoop(pFile, pDDSD, pSurface, extra);
441 }
442 
GenericFreeFunction(GX2Surface * & pSurface)443 TU_Error GenericFreeFunction(GX2Surface*& pSurface)
444 {
445     if(pSurface == NULL)
446     {
447         assert(pSurface);
448         return PE_Unknown;
449     }
450 
451     if(pSurface->imagePtr != NULL)
452     {
453             free(pSurface->imagePtr);
454             pSurface->imagePtr = NULL;
455             pSurface->mipPtr = NULL;
456     }
457     return PE_OK;
458 }
459 
460 
PreLoopDefault(FILE * &,DDSD2 * &,GX2Surface * &,void * &)461 TU_Error PreLoopDefault(FILE*&, DDSD2*&, GX2Surface*&, void*&)
462 {
463     return PE_OK;
464 }
465 
LoopDefault(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * & extra,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)466 TU_Error LoopDefault(FILE*& pFile, DDSD2*&, GX2Surface*& pSurface, void*& extra,
467                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
468 {
469     MipLevel mipLevel;
470 
471     ChannelFormat channelFormat = *reinterpret_cast<ChannelFormat*>(extra);
472     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
473     {
474         return PE_Unknown;
475     }
476 
477     if(fread(mipLevel.pData, GetMipSize(pSurface, nMipLevel, nFaceOrSlice), 1, pFile) != 1)
478         return PE_Unknown;
479 
480     return PE_OK;
481 }
482 
PostLoopDefault(FILE * &,DDSD2 * &,GX2Surface * &,void * &)483 TU_Error PostLoopDefault(FILE*&, DDSD2*&, GX2Surface*&, void*&)
484 {
485     return PE_OK;
486 }
487 
PreLoopFourCC(FILE * & pFile,DDSD2 * & pDDSD,GX2Surface * & pSurface,void * & extra)488 TU_Error PreLoopFourCC(FILE*& pFile, DDSD2*& pDDSD, GX2Surface*& pSurface, void*& extra)
489 {
490     u32 dwWidth;
491     u32 dwHeight;
492     u32 dwDepth;
493     u32 dwPixels = 0;
494     switch(pSurface->dim)
495     {
496     case GX2_SURFACE_DIM_2D:
497     case GX2_SURFACE_DIM_CUBE:
498         dwWidth = pSurface->width;
499         dwHeight = pSurface->height;
500         for(u32 i = 0; i < pSurface->numMips; i++)
501         {
502             dwPixels += dwWidth * dwHeight * pSurface->depth;
503             dwWidth = dwWidth>1 ? dwWidth>>1 : 1;
504             dwHeight = dwHeight>1 ? dwHeight>>1 : 1;
505         }
506         break;
507     case GX2_SURFACE_DIM_2D_ARRAY:
508 	case GX2_SURFACE_DIM_3D:
509         dwWidth = pSurface->width;
510         dwHeight = pSurface->height;
511         dwDepth = pSurface->depth;
512         for(u32 i = 0; i < pSurface->numMips; i++)
513         {
514             dwPixels += dwWidth * dwHeight * dwDepth;
515             dwWidth = dwWidth>1 ? dwWidth>>1 : 1;
516             dwHeight = dwHeight>1 ? dwHeight>>1 : 1;
517             dwDepth = dwDepth>1 ? dwDepth>>1 : 1;
518         }
519         break;
520     default:
521         assert(0);
522         fclose(pFile);
523         return PE_Unknown;
524     }
525 
526     extra = NULL;
527 
528     return PE_OK;
529 }
530 
LoopFourCC(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)531 TU_Error LoopFourCC(FILE*& pFile, DDSD2*&, GX2Surface*& pSurface, void*& /*extra*/,
532                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
533 {
534     MipLevel mipLevel;
535 
536     if(!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
537     {
538         return PE_Unknown;
539     }
540 
541     //read in the data....
542 	if(fread(mipLevel.pData, mipLevel.byteSize, 1, pFile) != 1)
543     {
544         return PE_Unknown;
545     }
546     return PE_OK;
547 }
548 
PostLoopFourCC(FILE * &,DDSD2 * &,GX2Surface * &,void * &)549 TU_Error PostLoopFourCC(FILE*&, DDSD2*&, GX2Surface*&, void*&)
550 {
551     return PE_OK;
552 }
553 
PreLoopRGB565(FILE * &,DDSD2 * & pDDSD,GX2Surface * & pSurface,void * & extra)554 TU_Error PreLoopRGB565(FILE*&, DDSD2*& pDDSD, GX2Surface*& pSurface, void*& extra)
555 {
556     return PE_OK;
557 }
558 
LoopRGB565(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * & extra,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)559 TU_Error LoopRGB565(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*& extra, u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
560 {
561     // Allocate the permanent buffer and unpack the bitmap data into it
562     MipLevel mipLevel;
563     u32 size = (dwWidth * dwHeight) * 2;
564     u16* pData = NULL;
565     u32 count = 0;
566     u16 value;
567 
568     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
569     {
570         return PE_Unknown;
571     }
572 
573     if(fread(mipLevel.pData, size, 1, pFile) != 1)
574     {
575         return PE_Unknown;
576     }
577 
578     pData = (u16*)mipLevel.pData;
579 
580     for (count = 0; count < (size / 2); count++)
581     {
582         value = *(pData + count);
583         *(pData + count) = ((value & 0xf800) >> 11) | (value & 0x07e0) | ((value & 0x1f) << 11);
584     }
585 
586     return PE_OK;
587 }
588 
PostLoopRGB565(FILE * &,DDSD2 * &,GX2Surface * &,void * & extra)589 TU_Error PostLoopRGB565(FILE*&, DDSD2*&, GX2Surface*&, void*& extra)
590 {
591     return PE_OK;
592 }
593 
PreLoopRGB888(FILE * &,DDSD2 * & pDDSD,GX2Surface * & pSurface,void * & extra)594 TU_Error PreLoopRGB888(FILE*&, DDSD2*& pDDSD, GX2Surface*& pSurface, void*& extra)
595 {
596     // Allocate a temporary buffer and read the bitmap data into it
597     u32 dwTempSize = pDDSD->dwWidth * pDDSD->dwHeight * 3;
598     extra = malloc(dwTempSize);
599     return extra ? PE_OK : PE_Unknown;
600 }
601 
LoopRGB888(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * & extra,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)602 TU_Error LoopRGB888(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*& extra,
603                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
604 {
605     MipLevel mipLevel;
606 
607     if(fread(extra, dwWidth * dwHeight * 3, 1, pFile) != 1)
608     {
609         free(extra);
610         return PE_Unknown;
611     }
612 
613     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
614     {
615         free(extra);
616         return PE_Unknown;
617     }
618 
619     // Allocate the permanent buffer and unpack the bitmap data into it
620     if(!mipLevel.pData)
621     {
622         free(extra);
623         return PE_Unknown;
624     }
625 
626     u32* pData = (u32*)mipLevel.pData;
627     u8* pTempPtr = (u8*)extra;
628     u8* pEnd = (u8*)pTempPtr + (dwWidth * dwHeight * 3);
629     u8 red, green, blue;
630     while(pTempPtr < pEnd)
631     {
632         blue = *pTempPtr++;
633         green = *pTempPtr++;
634         red = *pTempPtr++;
635 
636        *pData++ = (0xff << 24) | (blue << 16) | (green << 8) | red;
637     }
638 
639     return PE_OK;
640 }
641 
PostLoopRGB888(FILE * &,DDSD2 * &,GX2Surface * &,void * & extra)642 TU_Error PostLoopRGB888(FILE*&, DDSD2*&, GX2Surface*&, void*& extra)
643 {
644     free(extra);
645     return PE_OK;
646 }
647 
PreLoopRGB8888(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)648 TU_Error PreLoopRGB8888(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
649 {
650     return PE_OK;
651 }
652 
LoopRGB8888(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * & extra,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)653 TU_Error LoopRGB8888(FILE*& pFile, DDSD2*&, GX2Surface*& pSurface, void*& extra,
654                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
655 {
656     u32 size = (dwWidth * dwHeight * 4);
657     MipLevel mipLevel;
658 
659     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
660     {
661         return PE_Unknown;
662     }
663 
664     ARGB8888Struct* pARGB8888Struct = reinterpret_cast<ARGB8888Struct*>(extra);
665     if(!(pARGB8888Struct->nFlags & EF_UseBitMasks))
666     {   //not using bitmasks
667         if(fread(mipLevel.pData, size, 1, pFile) != 1)
668         {
669             return PE_Unknown;
670         }
671     }
672     else
673     {   //using bitmasks
674         if(fread(pARGB8888Struct->pMemory, size, 1, pFile) != 1)
675         {
676             return PE_Unknown;
677         }
678         u8* pData = mipLevel.pData;
679         u32* pTempPtr = (u32*)pARGB8888Struct->pMemory;
680         u32* pEnd = (u32*)pARGB8888Struct->pMemory + (size / 4);
681         while(pTempPtr < pEnd)
682         {
683             *(pData + 0) = static_cast<s8> ((*pTempPtr & pARGB8888Struct->nRMask) >> pARGB8888Struct->nRShift);
684             *(pData + 1) = static_cast<s8> ((*pTempPtr & pARGB8888Struct->nGMask) >> pARGB8888Struct->nGShift);
685             *(pData + 2) = static_cast<s8> ((*pTempPtr & pARGB8888Struct->nBMask) >> pARGB8888Struct->nBShift);
686             *(pData + 3) = static_cast<s8> ((*pTempPtr & 0xFF000000) >> 24);    //take alpha whether or not its used
687             pData += 4;
688             pTempPtr++;
689         }
690     }
691     return PE_OK;
692 }
693 
PostLoopRGB8888(FILE * &,DDSD2 * &,GX2Surface * &,void * &)694 TU_Error PostLoopRGB8888(FILE*&, DDSD2*&, GX2Surface*&, void*&)
695 {
696     return PE_OK;
697 }
698 
699 
PreLoopABGR32F(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)700 TU_Error PreLoopABGR32F(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
701 {
702    return PE_OK;
703 }
704 
LoopABGR32F(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)705 TU_Error LoopABGR32F(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
706                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
707 {
708     u32 size = dwWidth * dwHeight * 16;
709     MipLevel mipLevel;
710 
711     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
712     {
713         return PE_Unknown;
714     }
715 
716     if(fread(mipLevel.pData, size, 1, pFile) != 1)
717     {
718         return PE_Unknown;
719     }
720 
721     return PE_OK;
722 }
723 
LoopR32F(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)724 TU_Error LoopR32F(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
725                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
726 {
727     u32 size = dwWidth * dwHeight * 4;
728     MipLevel mipLevel;
729 
730     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
731     {
732         return PE_Unknown;
733     }
734 
735     if(fread(mipLevel.pData, size, 1, pFile) != 1)
736     {
737         return PE_Unknown;
738     }
739 
740     return PE_OK;
741 }
742 
LoopGR32F(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)743 TU_Error LoopGR32F(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
744                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
745 {
746     u32 size = dwWidth * dwHeight * 8;
747     MipLevel mipLevel;
748     //u64 value;
749     //u32 count;
750     //u64 *pData = NULL;
751 
752     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
753     {
754         return PE_Unknown;
755     }
756 
757     if(fread(mipLevel.pData, size, 1, pFile) != 1)
758     {
759         return PE_Unknown;
760     }
761 
762     /*pData = (u64*)mipLevel.pData;
763 
764     for (count = 0; count < size / 8; count++)
765     {
766         value = *(pData + count);
767         *(pData + count) = ((value & 0x00000000ffffffff) << 32) | ((value & 0xffffffff00000000) >> 32);
768     }*/
769 
770     return PE_OK;
771 }
772 
PostLoopABGR32F(FILE * &,DDSD2 * &,GX2Surface * &,void * &)773 TU_Error PostLoopABGR32F(FILE*&, DDSD2*&, GX2Surface*&, void*&)
774 {
775     return PE_OK;
776 }
777 
PreLoopABGR16F(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)778 TU_Error PreLoopABGR16F(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
779 {
780     return PE_OK;
781 }
782 
LoopABGR16F(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)783 TU_Error LoopABGR16F(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
784                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
785 {
786     MipLevel mipLevel;
787 
788     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
789     {
790         return PE_Unknown;
791     }
792 
793     u32 size = dwWidth * dwHeight * 8;
794 
795     if(fread(mipLevel.pData, size, 1, pFile) != 1)
796         return PE_Unknown;
797 
798     return PE_OK;
799 }
800 
LoopGR16F(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)801 TU_Error LoopGR16F(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
802                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
803 {
804     MipLevel mipLevel;
805 
806     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
807     {
808         return PE_Unknown;
809     }
810 
811     u32 size = dwWidth * dwHeight * 4;
812 
813     if(fread(mipLevel.pData, size, 1, pFile) != 1)
814         return PE_Unknown;
815 
816     return PE_OK;
817 }
818 
LoopR16F(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)819 TU_Error LoopR16F(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
820                            u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
821 {
822     MipLevel mipLevel;
823 
824     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
825     {
826         return PE_Unknown;
827     }
828 
829     u32 size = dwWidth * dwHeight * 2;
830 
831     if(fread(mipLevel.pData, size, 1, pFile) != 1)
832         return PE_Unknown;
833 
834     return PE_OK;
835 }
836 
PostLoopABGR16F(FILE * &,DDSD2 * &,GX2Surface * &,void * &)837 TU_Error PostLoopABGR16F(FILE*&, DDSD2*&, GX2Surface*&, void*&)
838 {
839     return PE_OK;
840 }
841 
PreLoopG8(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)842 TU_Error PreLoopG8(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
843 {
844     return PE_OK;
845 }
846 
LoopG8(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)847 TU_Error LoopG8(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
848                       u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
849 {
850     MipLevel mipLevel;
851 
852     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
853     {
854         return PE_Unknown;
855     }
856 
857     u32 size = dwWidth * dwHeight;// + 0x3) & ~0x3;
858     // Allocate the permanent buffer and unpack the bitmap data into it
859 
860     if(fread(mipLevel.pData, size, 1, pFile) != 1)
861     {
862         return PE_Unknown;
863     }
864 
865     return PE_OK;
866 }
867 
PostLoopG8(FILE * &,DDSD2 * &,GX2Surface * &,void * &)868 TU_Error PostLoopG8(FILE*&, DDSD2*&, GX2Surface*&, void*&)
869 {
870     return PE_OK;
871 }
872 
PreLoopA4L4(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)873 TU_Error PreLoopA4L4(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
874 {
875     return PE_OK;
876 }
877 
PreLoopA8L8(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)878 TU_Error PreLoopA8L8(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
879 {
880     return PE_OK;
881 }
882 
LoopA4L4(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)883 TU_Error LoopA4L4(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
884                       u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
885 {
886     MipLevel mipLevel;
887 
888     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
889     {
890         return PE_Unknown;
891     }
892 
893     u32 size = ((dwWidth * dwHeight) + 0x3) & ~0x3;
894     // Allocate the permanent buffer and unpack the bitmap data into it
895 
896     if(fread(mipLevel.pData, size, 1, pFile) != 1)
897     {
898         return PE_Unknown;
899     }
900 
901     return PE_OK;
902 }
903 
LoopA8L8(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)904 TU_Error LoopA8L8(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
905                       u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
906 {
907     MipLevel mipLevel;
908 
909     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
910     {
911         return PE_Unknown;
912     }
913 
914     u32 size = (dwWidth * dwHeight) * 2;
915     // Allocate the permanent buffer and unpack the bitmap data into it
916 
917     if(fread(mipLevel.pData, size, 1, pFile) != 1)
918     {
919         return PE_Unknown;
920     }
921 
922     return PE_OK;
923 }
924 
PostLoopA4L4(FILE * &,DDSD2 * &,GX2Surface * &,void * &)925 TU_Error PostLoopA4L4(FILE*&, DDSD2*&, GX2Surface*&, void*&)
926 {
927     return PE_OK;
928 }
929 
PostLoopA8L8(FILE * &,DDSD2 * &,GX2Surface * &,void * &)930 TU_Error PostLoopA8L8(FILE*&, DDSD2*&, GX2Surface*&, void*&)
931 {
932     return PE_OK;
933 }
934 
PreLoopAG8(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)935 TU_Error PreLoopAG8(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
936 {
937     return PE_OK;
938 }
939 
LoopAG8(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)940 TU_Error LoopAG8(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
941                        u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
942 {
943     MipLevel mipLevel;
944 
945     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
946     {
947         return PE_Unknown;
948     }
949 
950     u32 size = (((dwWidth * dwHeight) + 0x3) & ~0x3) * 2;
951 
952     if(fread(mipLevel.pData, size, 1, pFile) != 1)
953     {
954         return PE_Unknown;
955     }
956 
957     return PE_OK;
958 }
959 
PostLoopAG8(FILE * &,DDSD2 * &,GX2Surface * &,void * &)960 TU_Error PostLoopAG8(FILE*&, DDSD2*&, GX2Surface*&, void*&)
961 {
962     return PE_OK;
963 }
964 
PreLoopG16(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)965 TU_Error PreLoopG16(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
966 {
967     return PE_OK;
968 }
969 
LoopG16(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)970 TU_Error LoopG16(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
971                        u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
972 {
973     MipLevel mipLevel;
974 
975     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
976     {
977         return PE_Unknown;
978     }
979 
980     u32 size = (((dwWidth * dwHeight) + 0x3) & ~0x3) * 2;
981 
982     if(fread(mipLevel.pData, size, 1, pFile) != 1)
983         return PE_Unknown;
984 
985     return PE_OK;
986 }
987 
PostLoopG16(FILE * &,DDSD2 * &,GX2Surface * &,void * &)988 TU_Error PostLoopG16(FILE*&, DDSD2*&, GX2Surface*&, void*&)
989 {
990     return PE_OK;
991 }
992 
PreLoopA8(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)993 TU_Error PreLoopA8(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
994 {
995     return PE_OK;
996 }
997 
LoopA8(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)998 TU_Error LoopA8(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
999                       u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1000 {
1001     MipLevel mipLevel;
1002 
1003     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
1004     {
1005         return PE_Unknown;
1006     }
1007 
1008     u32 size = ((dwWidth * dwHeight) + 0x3) & ~0x3;
1009 
1010     if (fread(mipLevel.pData, size, 1, pFile) != 1)
1011     {
1012         return PE_Unknown;
1013     }
1014 
1015     return PE_OK;
1016 }
1017 
PostLoopA8(FILE * &,DDSD2 * &,GX2Surface * &,void * &)1018 TU_Error PostLoopA8(FILE*&, DDSD2*&, GX2Surface*&, void*&)
1019 {
1020     return PE_OK;
1021 }
1022 
PreLoopABGR16(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)1023 TU_Error PreLoopABGR16(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
1024 {
1025     return PE_OK;
1026 }
1027 
LoopABGR16(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1028 TU_Error LoopABGR16(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1029                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1030 {
1031     MipLevel mipLevel;
1032 
1033     if (!GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel))
1034     {
1035         return PE_Unknown;
1036     }
1037 
1038     u32 size = dwWidth * dwHeight * 8;
1039     if(fread((void*)mipLevel.pData, size, 1, pFile) != 1)
1040     {
1041         return PE_Unknown;
1042     }
1043 
1044     return PE_OK;
1045 }
1046 
PostLoopABGR16(FILE * &,DDSD2 * &,GX2Surface * &,void * &)1047 TU_Error PostLoopABGR16(FILE*&, DDSD2*&, GX2Surface*&, void*&)
1048 {
1049     return PE_OK;
1050 }
1051 
PreLoopG16R16(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)1052 TU_Error PreLoopG16R16(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
1053 {
1054     return PE_OK;
1055 }
1056 
PreLoopARGB1555(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)1057 TU_Error PreLoopARGB1555(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
1058 {
1059     return PE_OK;
1060 }
1061 
PreLoopARGB4444(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)1062 TU_Error PreLoopARGB4444(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
1063 {
1064     return PE_OK;
1065 }
1066 
LoopG16R16(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1067 TU_Error LoopG16R16(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1068                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1069 {
1070     MipLevel mipLevel;
1071     u32 size = dwWidth * dwHeight * 4;
1072     //u32 value, count;
1073     //u32* pData;
1074 
1075     GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1076 
1077     if(fread(mipLevel.pData, size, 1, pFile) != 1)
1078     {
1079         return PE_Unknown;
1080     }
1081 
1082     /*pData = (u32*)mipLevel.pData;
1083 
1084     for (count = 0; count < size / 4; count++)
1085     {
1086         value = *(pData + count);
1087         *(pData + count) = ((value & 0x0000ffff) << 16) | ((value & 0xffff0000) >> 16);
1088     }*/
1089 
1090     return PE_OK;
1091 }
1092 
LoopARGB1555(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1093 TU_Error LoopARGB1555(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1094                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1095 {
1096     MipLevel mipLevel;
1097     u32 size = dwWidth * dwHeight * 2;
1098     u16* pData = NULL;
1099     u32 count = 0;
1100     u16 value;
1101 
1102     GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1103 
1104     if(fread(mipLevel.pData, size, 1, pFile) != 1)
1105     {
1106         return PE_Unknown;
1107     }
1108 
1109     pData = (u16*)mipLevel.pData;
1110 
1111     for (count = 0; count < size/2; count++)
1112     {
1113         value = *(pData + count);
1114         // [MSB] ARGB [LSB] to ABGR
1115         *(pData + count) = ((value & 0x8000)) | ((value & 0x7c00) >> 10) | ((value & 0x001f) << 10) | (value & 0x03e0);
1116     }
1117 
1118     return PE_OK;
1119 }
1120 
LoopARGB4444(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1121 TU_Error LoopARGB4444(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1122                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1123 {
1124     MipLevel mipLevel;
1125     u32 count;
1126     u32 size = dwWidth * dwHeight * 2;
1127     u16* pData = NULL;
1128     u16 value;
1129 
1130     GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1131 
1132     if(fread(mipLevel.pData, size, 1, pFile) != 1)
1133     {
1134         return PE_Unknown;
1135     }
1136 
1137     pData = (u16*)mipLevel.pData;
1138     for (count = 0; count < (size / 2); count++)
1139     {
1140         value = *(pData + count);
1141         //ARGB ABGR
1142         *(pData + count) = (value & 0xf000) | ((value & 0x0f00) >> 8) | (value & 0x00f0) | ((value & 0x000f) << 8);
1143     }
1144 
1145     return PE_OK;
1146 }
1147 
PostLoopG16R16(FILE * &,DDSD2 * &,GX2Surface * &,void * &)1148 TU_Error PostLoopG16R16(FILE*&, DDSD2*&, GX2Surface*&, void*&)
1149 {
1150     return PE_OK;
1151 }
1152 
PostLoopARGB1555(FILE * &,DDSD2 * &,GX2Surface * &,void * &)1153 TU_Error PostLoopARGB1555(FILE*&, DDSD2*&, GX2Surface*&, void*&)
1154 {
1155     return PE_OK;
1156 }
1157 
PostLoopARGB4444(FILE * &,DDSD2 * &,GX2Surface * &,void * &)1158 TU_Error PostLoopARGB4444(FILE*&, DDSD2*&, GX2Surface*&, void*&)
1159 {
1160     return PE_OK;
1161 }
1162 
SetupDDSD(DDSD2 & ddsd2,const GX2Surface * pSurface,bool bCompressed)1163 bool SetupDDSD(DDSD2& ddsd2, const GX2Surface* pSurface, bool bCompressed)
1164 {
1165     memset(&ddsd2, 0, sizeof(DDSD2));
1166     ddsd2.dwSize = sizeof(DDSD2);
1167 
1168     ASSERT(pSurface);
1169     if(pSurface == NULL)
1170     {
1171         return false;
1172     }
1173 
1174     ddsd2.dwWidth = pSurface->width;
1175     ddsd2.dwHeight = pSurface->height;
1176     ddsd2.dwMipMapCount = pSurface->numMips;
1177     ddsd2.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_MIPMAPCOUNT;
1178     if(bCompressed)
1179     {
1180         ddsd2.dwFlags |= DDSD_LINEARSIZE;
1181         ddsd2.dwLinearSize = pSurface->imageSize + pSurface->mipSize;
1182     }
1183     else
1184         ddsd2.dwFlags |= DDSD_PITCH;
1185 
1186     ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
1187     ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_COMPLEX|DDSCAPS_MIPMAP;
1188 
1189     if(pSurface->dim == GX2_SURFACE_DIM_CUBE)
1190     {
1191         ddsd2.ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1192     }
1193     else if(pSurface->dim == GX2_SURFACE_DIM_3D)
1194     {
1195         ddsd2.dwFlags |= DDSD_DEPTH;
1196         ddsd2.dwDepth = pSurface->depth;
1197         ddsd2.ddsCaps.dwCaps2 |= DDSCAPS2_VOLUME;
1198     }
1199     else if(pSurface->dim == GX2_SURFACE_DIM_2D_ARRAY)
1200     {
1201         ddsd2.dwFlags |= DDSD_DEPTH;
1202         ddsd2.dwDepth = pSurface->depth;
1203 	}
1204 
1205     return true;
1206 }
1207 
SetupDDSD_DDS10(DDSD2 & ddsd2,const GX2Surface * pSurface,bool bCompressed)1208 bool SetupDDSD_DDS10(DDSD2& ddsd2, const GX2Surface* pSurface, bool bCompressed)
1209 {
1210     memset(&ddsd2, 0, sizeof(DDSD2));
1211     ddsd2.dwSize = sizeof(DDSD2);
1212 
1213     ASSERT(pSurface);
1214     if(pSurface == NULL)
1215         return false;
1216 
1217     ddsd2.dwWidth = pSurface->width;
1218     ddsd2.dwHeight = pSurface->height;
1219     ddsd2.dwMipMapCount = pSurface->numMips;
1220     ddsd2.dwFlags = DDSD_WIDTH|DDSD_HEIGHT;
1221 
1222     ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
1223     ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1224 
1225     if(pSurface->dim == GX2_SURFACE_DIM_CUBE)
1226     {
1227         ddsd2.ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1228     }
1229     else if(pSurface->dim == GX2_SURFACE_DIM_3D)
1230     {
1231         ddsd2.dwFlags |= DDSD_DEPTH;
1232         ddsd2.dwDepth = pSurface->depth;
1233         ddsd2.ddsCaps.dwCaps2 |= DDSCAPS2_VOLUME;
1234     }
1235     else if(pSurface->dim == GX2_SURFACE_DIM_2D_ARRAY)
1236     {
1237         ddsd2.dwFlags |= DDSD_DEPTH;
1238         ddsd2.dwDepth = pSurface->depth;
1239 	}
1240 
1241     if(pSurface->numMips > 1)
1242     {
1243         ddsd2.dwFlags |= DDSD_MIPMAPCOUNT;
1244         ddsd2.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;
1245     }
1246 
1247     return true;
1248 }
1249 
PreLoopABGR32(FILE * &,DDSD2 * &,GX2Surface * & pSurface,void * &)1250 TU_Error PreLoopABGR32(FILE*&, DDSD2*&, GX2Surface*& pSurface, void*&)
1251 {
1252     return PE_OK;
1253 }
1254 
LoopABGR32(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1255 TU_Error LoopABGR32(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1256                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1257 {
1258     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1259 
1260     if(fread(mipLevel.pData, GetMipSize(pSurface, nMipLevel, nFaceOrSlice), 1, pFile) != 1)
1261         return PE_Unknown;
1262 
1263     return PE_OK;
1264 }
1265 
PostLoopABGR32(FILE * &,DDSD2 * &,GX2Surface * &,void * &)1266 TU_Error PostLoopABGR32(FILE*&, DDSD2*&, GX2Surface*&, void*&)
1267 {
1268     return PE_OK;
1269 }
1270 
LoopR32(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1271 TU_Error LoopR32(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&, u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1272 {
1273     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1274     u32 dwSize = GetMipSize(pSurface, nMipLevel, nFaceOrSlice) / 4;
1275     s8* pTempData = (s8*) malloc(dwSize);
1276     assert(pTempData);
1277     if(!pTempData)
1278         return PE_Unknown;
1279 
1280     u32 dws8sRead = (u32)fread(pTempData, 1, dwSize, pFile);
1281     if(dws8sRead != dwSize)
1282     {
1283         free(pTempData);
1284         return PE_Unknown;
1285     }
1286 
1287     u32* pSrc = (u32*) pTempData;
1288     u32* pEnd = (u32*) (pTempData + dwSize);
1289     u32* pDest = (u32*) mipLevel.pData;
1290     while(pSrc < pEnd)
1291     {
1292         *pDest++ = *pSrc++;
1293         *pDest++ = 0;
1294         *pDest++ = 0;
1295         *pDest++ = _UI32_MAX;
1296     }
1297 
1298     free(pTempData);
1299 
1300     return PE_OK;
1301 }
1302 
LoopR8G8(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1303 TU_Error LoopR8G8(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1304                         u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1305 {
1306     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1307 
1308     u32 dwSize = GetMipSize(pSurface, nMipLevel, nFaceOrSlice) / 2;
1309     s8* pTempData = (s8*) malloc(dwSize);
1310     assert(pTempData);
1311     if(!pTempData)
1312         return PE_Unknown;
1313 
1314     if(fread(pTempData, dwSize, 1, pFile) != 1)
1315     {
1316         free(pTempData);
1317         return PE_Unknown;
1318     }
1319 
1320     u8* pSrc = (u8*)pTempData;
1321     u8* pEnd = (u8*)(pTempData + dwSize);
1322     u8* pDest = mipLevel.pData;
1323     while(pSrc < pEnd)
1324     {
1325         *pDest++ = 0;
1326         u8 bRed = *pSrc++;
1327         *pDest++ = *pSrc++;
1328         *pDest++ = bRed;
1329         *pDest++ = (u8)0xff;
1330     }
1331 
1332     free(pTempData);
1333 
1334     return PE_OK;
1335 }
1336 
LoopR32G32(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1337 TU_Error LoopR32G32(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1338                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1339 {
1340     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1341     u32 dwSize = GetMipSize(pSurface, nMipLevel, nFaceOrSlice) / 2;
1342     u32* pTempData = (u32*) malloc(dwSize);
1343     assert(pTempData);
1344     if(!pTempData)
1345         return PE_Unknown;
1346 
1347     if(fread(pTempData, dwSize, 1, pFile) != 1)
1348     {
1349         free(pTempData);
1350         return PE_Unknown;
1351     }
1352 
1353     u32* pSrc = pTempData;
1354     u32* pEnd = (pTempData + (dwSize / sizeof(u32)));
1355     u32* pDest = (u32*)mipLevel.pData;
1356     while(pSrc < pEnd)
1357     {
1358         *pDest++ = *pSrc++;
1359         *pDest++ = *pSrc++;
1360         *pDest++ = 0;
1361         *pDest++ = 0;
1362     }
1363 
1364     free(pTempData);
1365 
1366     return PE_OK;
1367 }
1368 
LoopA2R10G10B10(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1369 TU_Error LoopA2R10G10B10(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1370                                u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1371 {
1372     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1373 	u32 dwSize = mipLevel.byteSize;
1374     u32* pTempData = (u32*) malloc(dwSize);
1375     assert(pTempData);
1376     if(!pTempData)
1377         return PE_Unknown;
1378 
1379     if(fread(pTempData, dwSize, 1, pFile) != 1)
1380     {
1381         free(pTempData);
1382         return PE_Unknown;
1383     }
1384 
1385     u32* pSrc = pTempData;
1386     u32* pEnd = (pTempData + (dwSize / sizeof(u32)));
1387     u32* pDest = (u32*)mipLevel.pData;
1388     while(pSrc < pEnd)
1389     {
1390         u32 dwSrc = *pSrc++;
1391         // ARGB to ABGR
1392         u32 dwDest = (dwSrc & 0xc0000000) | ((dwSrc & 0x3ff00000) >> 20) | (dwSrc & 0x000ffc00) | ((dwSrc & 0x000003ff) << 20);
1393         *pDest++ = dwDest;
1394     }
1395 
1396     free(pTempData);
1397 
1398     return PE_OK;
1399 }
1400 
LoopR16G16(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1401 TU_Error LoopR16G16(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1402                           u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1403 {
1404     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1405     u32 dwSize = GetMipSize(pSurface, nMipLevel, nFaceOrSlice) / 2;
1406     WORD* pTempData = (WORD*) malloc(dwSize);
1407     assert(pTempData);
1408     if(!pTempData)
1409         return PE_Unknown;
1410 
1411     if(fread(pTempData, dwSize, 1, pFile) != 1)
1412     {
1413         free(pTempData);
1414         return PE_Unknown;
1415     }
1416 
1417     WORD* pSrc = pTempData;
1418     WORD* pEnd = (pTempData + (dwSize / sizeof(WORD)));
1419     WORD* pDest = (WORD*)mipLevel.pData;
1420     while(pSrc < pEnd)
1421     {
1422         *pDest++ = *pSrc++;
1423         *pDest++ = *pSrc++;
1424         *pDest++ = 0;
1425         *pDest++ = 0;
1426     }
1427 
1428     free(pTempData);
1429 
1430     return PE_OK;
1431 }
1432 
LoopR16(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1433 TU_Error LoopR16(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1434                        u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1435 {
1436     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1437     u32 dwSize = GetMipSize(pSurface, nMipLevel, nFaceOrSlice) / 4;
1438     s8* pTempData = (s8*) malloc(dwSize);
1439     assert(pTempData);
1440     if(!pTempData)
1441         return PE_Unknown;
1442 
1443     u32 dws8sRead = (u32)fread(pTempData, 1, dwSize, pFile);
1444     if(dws8sRead != dwSize)
1445     {
1446         free(pTempData);
1447         return PE_Unknown;
1448     }
1449 
1450     WORD* pSrc = (WORD*) pTempData;
1451     WORD* pEnd = (WORD*) (pTempData + dwSize);
1452     WORD* pDest = (WORD*)mipLevel.pData;
1453     while(pSrc < pEnd)
1454     {
1455         *pDest++ = *pSrc++;
1456         *pDest++ = 0;
1457         *pDest++ = 0;
1458         *pDest++ = _UI16_MAX;
1459     }
1460 
1461     free(pTempData);
1462 
1463     return PE_OK;
1464 }
1465 
LoopR8(FILE * & pFile,DDSD2 * &,GX2Surface * & pSurface,void * &,u32 nMipLevel,u32 nFaceOrSlice,u32 dwWidth,u32 dwHeight)1466 TU_Error LoopR8(FILE*& pFile, DDSD2*& , GX2Surface*& pSurface, void*&,
1467                       u32 nMipLevel, u32 nFaceOrSlice, u32 dwWidth, u32 dwHeight)
1468 {
1469     MipLevel mipLevel;GetMipLevel(pSurface, nMipLevel, nFaceOrSlice, &mipLevel);
1470     u32 dwSize = GetMipSize(pSurface, nMipLevel, nFaceOrSlice) / 4;
1471     s8* pTempData = (s8*) malloc(dwSize);
1472     assert(pTempData);
1473     if(!pTempData)
1474         return PE_Unknown;
1475 
1476     if(fread(pTempData, dwSize, 1, pFile) != 1)
1477     {
1478         free(pTempData);
1479         return PE_Unknown;
1480     }
1481 
1482     u8* pSrc = (u8*)pTempData;
1483     u8* pEnd = (u8*)(pTempData + dwSize);
1484     u8* pDest = mipLevel.pData;
1485     while(pSrc < pEnd)
1486     {
1487         *pDest++ = 0;
1488         *pDest++ = 0;
1489         *pDest++ = *pSrc++;
1490         *pDest++ = (u8)0xff;
1491     }
1492 
1493     free(pTempData);
1494 
1495     return PE_OK;
1496 }
1497 }   //namespace DDSReader
1498