Skip to content

Commit

Permalink
Initial bit of code I scratched out. Not nearly complete, no real API…
Browse files Browse the repository at this point in the history
… yet.
  • Loading branch information
icculus committed May 7, 2011
0 parents commit 5f561a6
Showing 1 changed file with 202 additions and 0 deletions.
202 changes: 202 additions & 0 deletions mojodds.c
@@ -0,0 +1,202 @@
/**
* MojoDDS; tools for dealing with DDS files.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/

// Specs on DDS format: http://msdn.microsoft.com/en-us/library/bb943991.aspx/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef _MSC_VER
typedef unsigned __int8 uint8;
typedef unsigned __int32 uint32;
#else
#include <stdint.h>
typedef uint8_t uint8;
typedef uint32_t uint32;
#endif

#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )


#define DDS_MAGIC 0x20534444 // 'DDS ' in littleendian.
#define DDS_HEADERSIZE 124
#define DDS_PIXFMTSIZE 32
#define DDSD_CAPS 0x1
#define DDSD_HEIGHT 0x2
#define DDSD_WIDTH 0x4
#define DDSD_PITCH 0x8
#define DDSD_FMT 0x1000
#define DDSD_MIPMAPCOUNT 0x20000
#define DDSD_LINEARSIZE 0x80000
#define DDSD_DEPTH 0x800000
#define DDSD_REQ (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_FMT)
#define DDSCAPS_COMPLEX 0x8
#define DDSCAPS_MIPMAP 0x400000
#define DDSCAPS_TEXTURE 0x1000
#define DDPF_ALPHAPIXELS 0x1
#define DDPF_ALPHA 0x2
#define DDPF_FOURCC 0x4
#define DDPF_RGB 0x40
#define DDPF_YUV 0x200
#define DDPF_LUMINANCE 0x20000

#define FOURCC_DXT1 0x31545844
#define FOURCC_DXT2 0x32545844
#define FOURCC_DXT3 0x33545844
#define FOURCC_DXT4 0x34545844
#define FOURCC_DXT5 0x35545844
#define FOURCC_DX10 0x30315844

typedef struct
{
uint32 dwSize;
uint32 dwFlags;
uint32 dwFourCC;
uint32 dwRGBBitCount;
uint32 dwRBitMask;
uint32 dwGBitMask;
uint32 dwBBitMask;
uint32 dwABitMask;
} MOJODDS_PixelFormat;

typedef struct
{
uint32 dwSize;
uint32 dwFlags;
uint32 dwHeight;
uint32 dwWidth;
uint32 dwPitchOrLinearSize;
uint32 dwDepth;
uint32 dwMipMapCount;
uint32 dwReserved1[11];
MOJODDS_PixelFormat ddspf;
uint32 dwCaps;
uint32 dwCaps2;
uint32 dwCaps3;
uint32 dwCaps4;
uint32 dwReserved2;
} MOJODDS_Header;


static uint32 readui32(const uint8 **_ptr, size_t *_len)
{
uint32 retval = 0;
if (*_len < sizeof (retval))
*_len = 0;
else
{
const uint8 *ptr = *_ptr;
retval = (((uint32) ptr[0]) << 0) | (((uint32) ptr[1]) << 8) |
(((uint32) ptr[2]) << 16) | (((uint32) ptr[3]) << 24) ;
*_ptr += sizeof (retval);
*_len -= sizeof (retval);
} // else
return retval;
} // readui32

static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len)
{
int i;

// Files start with magic value...
if (readui32(ptr, len) != DDS_MAGIC)
return 0; // not a DDS file.

// Then comes the DDS header...
if (*len < DDS_HEADERSIZE)
return 0;

header->dwSize = readui32(ptr, len);
header->dwFlags = readui32(ptr, len);
header->dwHeight = readui32(ptr, len);
header->dwWidth = readui32(ptr, len);
header->dwPitchOrLinearSize = readui32(ptr, len);
header->dwDepth = readui32(ptr, len);
header->dwMipMapCount = readui32(ptr, len);
for (i = 0; i < STATICARRAYLEN(header->dwReserved1); i++)
header->dwReserved1[i] = readui32(ptr, len);
header->ddspf.dwSize = readui32(ptr, len);
header->ddspf.dwFlags = readui32(ptr, len);
header->ddspf.dwFourCC = readui32(ptr, len);
header->ddspf.dwRGBBitCount = readui32(ptr, len);
header->ddspf.dwRBitMask = readui32(ptr, len);
header->ddspf.dwGBitMask = readui32(ptr, len);
header->ddspf.dwBBitMask = readui32(ptr, len);
header->ddspf.dwABitMask = readui32(ptr, len);
header->dwCaps = readui32(ptr, len);
header->dwCaps2 = readui32(ptr, len);
header->dwCaps3 = readui32(ptr, len);
header->dwCaps4 = readui32(ptr, len);
header->dwReserved2 = readui32(ptr, len);

if (header->dwSize != DDS_HEADERSIZE) // header size must be 124.
return 0;
else if (header->ddspf.dwSize != DDS_PIXFMTSIZE) // size must be 32.
return 0;
else if ((header->dwFlags & DDSD_REQ) != DDSD_REQ) // must have these bits.
return 0;
else if (header->dwCaps != DDSCAPS_TEXTURE) // !!! FIXME
return 0;
else if (header->dwCaps2 != 0) // !!! FIXME (non-zero with other bits in dwCaps set)
return 0;

if ((header->ddspf.dwFlags & DDPF_FOURCC) == 0) // !!! FIXME
return 0;
if ((header->dwFlags & DDSD_LINEARSIZE) == 0) // !!! FIXME
return 0;

if (header->ddspf.dwFlags & DDPF_FOURCC)
{
switch (header->ddspf.dwFourCC)
{
case FOURCC_DXT1:
case FOURCC_DXT2:
case FOURCC_DXT3:
case FOURCC_DXT4:
case FOURCC_DXT5:
// !!! FIXME: DX10 is an extended header, introduced by DirectX 10.
//case FOURCC_DX10:
break;
default:
return 0; // unsupported data format.
} // switch
} // if

return 1;
} // parse_dds


// !!! FIXME: improve the crap out of this API later.
int MOJODDS_getTexture(const void *_ptr, const long _len,
const void **_tex, long *_texlen, int *_dxtver)
{
size_t len = (size_t) _len;
const uint8 *ptr = (const uint8 *) _ptr;
MOJODDS_Header header;
if (!parse_dds(&header, &ptr, &len))
return 0;

*_tex = (const void *) ptr;
*_texlen = (long) header.dwPitchOrLinearSize;

switch (header.ddspf.dwFourCC)
{
case FOURCC_DXT1: *_dxtver = 1; break;
case FOURCC_DXT2: *_dxtver = 2; break;
case FOURCC_DXT3: *_dxtver = 3; break;
case FOURCC_DXT4: *_dxtver = 4; break;
case FOURCC_DXT5: *_dxtver = 5; break;
default: *_dxtver = 0; return 0;
} // switch

return 1;
} // MOJODDS_getTexture

// end of mojodds.c ...

0 comments on commit 5f561a6

Please sign in to comment.