From 25055ce2d9668798445f285eb798c050fcdef82f Mon Sep 17 00:00:00 2001
From: Turo Lamminen <turotl@gmail.com>
Date: Wed, 29 Apr 2015 14:02:44 +0000
Subject: [PATCH] Aaron Melcher's version
---
mojodds.h | 12 +++++
mojodds.c | 67 +++++++++++++++++++++++++++++++--
2 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/mojodds.c b/mojodds.c
index 7da86f0..5a321cc 100644
--- a/mojodds.c
+++ b/mojodds.c
@@ -22,6 +22,8 @@
typedef uint32_t uint32;
#endif
+#include "mojodds.h"
+
#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )
#define DDS_MAGIC 0x20534444 // 'DDS ' in littleendian.
@@ -40,6 +42,14 @@
#define DDSCAPS_COMPLEX 0x8
#define DDSCAPS_MIPMAP 0x400000
#define DDSCAPS_TEXTURE 0x1000
+#define DDSCAPS2_CUBEMAP 0x200
+#define DDSCAPS2_CUBEMAP_POSITIVEX 0x400
+#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x800
+#define DDSCAPS2_CUBEMAP_POSITIVEY 0x1000
+#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x2000
+#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x4000
+#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x8000
+#define DDSCAPS2_VOLUME 0x200000
#define DDPF_ALPHAPIXELS 0x1
#define DDPF_ALPHA 0x2
#define DDPF_FOURCC 0x4
@@ -59,6 +69,8 @@
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#define GL_BGR 0x80E0
#define GL_BGRA 0x80E1
+
+#define MAX( a, b ) ((a) > (b) ? (a) : (b))
typedef struct
{
@@ -108,13 +120,17 @@
} // readui32
static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len,
- unsigned int *_glfmt, unsigned int *_miplevels)
+ unsigned int *_glfmt, unsigned int *_miplevels,
+ unsigned int *_cubemapfacelen,
+ MOJODDS_textureType *_textureType)
{
const uint32 pitchAndLinear = (DDSD_PITCH | DDSD_LINEARSIZE);
uint32 width = 0;
uint32 height = 0;
uint32 calcSize = 0;
uint32 calcSizeFlag = DDSD_LINEARSIZE;
+ uint32 blockDim = 1;
+ uint32 blockSize = 0;
int i;
// Files start with magic value...
@@ -161,8 +177,6 @@
return 0;
else if ((header->dwCaps & DDSCAPS_TEXTURE) == 0)
return 0;
- else if (header->dwCaps2 != 0) // !!! FIXME (non-zero with other bits in dwCaps set)
- return 0;
else if ((header->dwFlags & pitchAndLinear) == pitchAndLinear)
return 0; // can't specify both.
@@ -176,16 +190,22 @@
*_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
calcSize = ((width ? ((width + 3) / 4) : 1) * 8) *
(height ? ((height + 3) / 4) : 1);
+ blockDim = 4;
+ blockSize = 8;
break;
case FOURCC_DXT3:
*_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
calcSize = ((width ? ((width + 3) / 4) : 1) * 16) *
(height ? ((height + 3) / 4) : 1);
+ blockDim = 4;
+ blockSize = 16;
break;
case FOURCC_DXT5:
*_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
calcSize = ((width ? ((width + 3) / 4) : 1) * 16) *
(height ? ((height + 3) / 4) : 1);
+ blockDim = 4;
+ blockSize = 16;
break;
// !!! FIXME: DX10 is an extended header, introduced by DirectX 10.
@@ -212,12 +232,14 @@
(header->ddspf.dwABitMask != 0xFF000000) )
return 0; // unsupported.
*_glfmt = GL_BGRA;
+ blockSize = 4;
} // if
else
{
if (header->ddspf.dwRGBBitCount != 24)
return 0; // unsupported.
*_glfmt = GL_BGR;
+ blockSize = 3;
} // else
calcSizeFlag = DDSD_PITCH;
@@ -245,6 +267,39 @@
header->dwFlags |= calcSizeFlag;
} // if
+ *_textureType = MOJODDS_TEXTURE_2D;
+ { // figure out texture type.
+ if (header->dwCaps & DDSCAPS_COMPLEX &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEY &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ &&
+ header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ)
+ {
+ *_textureType = MOJODDS_TEXTURE_CUBE;
+ }
+ else if (header->dwCaps2 & DDSCAPS2_VOLUME)
+ {
+ *_textureType = MOJODDS_TEXTURE_VOLUME;
+ }
+ }
+
+ // figure out how much memory makes up a single face mip chain.
+ if (*_textureType == MOJODDS_TEXTURE_CUBE)
+ {
+ uint32 wd = header->dwWidth;
+ uint32 ht = header->dwHeight;
+ *_cubemapfacelen = 0;
+ for (i = 0; i < (int)*_miplevels; i++)
+ {
+ *_cubemapfacelen += ((MAX( wd, blockDim ) / blockDim) * (MAX( ht, blockDim ) / blockDim)) * blockSize;
+ wd >>= 1;
+ ht >>= 1;
+ }
+ }
+
return 1;
} // parse_dds
@@ -260,12 +315,14 @@
int MOJODDS_getTexture(const void *_ptr, const unsigned long _len,
const void **_tex, unsigned long *_texlen,
unsigned int *_glfmt, unsigned int *_w,
- unsigned int *_h, unsigned int *_miplevels)
+ unsigned int *_h, unsigned int *_miplevels,
+ unsigned int *_cubemapfacelen,
+ MOJODDS_textureType *_textureType)
{
size_t len = (size_t) _len;
const uint8 *ptr = (const uint8 *) _ptr;
MOJODDS_Header header;
- if (!parse_dds(&header, &ptr, &len, _glfmt, _miplevels))
+ if (!parse_dds(&header, &ptr, &len, _glfmt, _miplevels, _cubemapfacelen, _textureType))
return 0;
*_tex = (const void *) ptr;
diff --git a/mojodds.h b/mojodds.h
index 63c848e..91f9177 100644
--- a/mojodds.h
+++ b/mojodds.h
@@ -6,11 +6,21 @@
extern "C" {
#endif
+typedef enum MOJODDS_textureType
+{
+ MOJODDS_TEXTURE_NONE,
+ MOJODDS_TEXTURE_2D,
+ MOJODDS_TEXTURE_CUBE,
+ MOJODDS_TEXTURE_VOLUME
+} MOJODDS_textureType;
+
int MOJODDS_isDDS(const void *_ptr, const unsigned long _len);
int MOJODDS_getTexture(const void *_ptr, const unsigned long _len,
const void **_tex, unsigned long *_texlen,
unsigned int *_glfmt, unsigned int *_w,
- unsigned int *_h, unsigned int *_miplevels);
+ unsigned int *_h, unsigned int *_miplevels,
+ unsigned int *_cubemapfacelen,
+ MOJODDS_textureType *_textureType);
#ifdef __cplusplus
}
--
Gitblit v1.9.3