summaryrefslogtreecommitdiff
path: root/native/lib/dds.c
diff options
context:
space:
mode:
Diffstat (limited to 'native/lib/dds.c')
-rw-r--r--native/lib/dds.c122
1 files changed, 74 insertions, 48 deletions
diff --git a/native/lib/dds.c b/native/lib/dds.c
index 0afba5e..5ae4c26 100644
--- a/native/lib/dds.c
+++ b/native/lib/dds.c
@@ -42,35 +42,37 @@
#define DDS_MAGIC 0x20534444
// DDS_header.dwFlags
-#define DDSD_CAPS 0x00000001
-#define DDSD_HEIGHT 0x00000002
-#define DDSD_WIDTH 0x00000004
-#define DDSD_PITCH 0x00000008
-#define DDSD_PIXELFORMAT 0x00001000
-#define DDSD_MIPMAPCOUNT 0x00020000
-#define DDSD_LINEARSIZE 0x00080000
-#define DDSD_DEPTH 0x00800000
+#define DDSD_CAPS 0x00000001
+#define DDSD_HEIGHT 0x00000002
+#define DDSD_WIDTH 0x00000004
+#define DDSD_PITCH 0x00000008
+#define DDSD_PIXELFORMAT 0x00001000
+#define DDSD_MIPMAPCOUNT 0x00020000
+#define DDSD_LINEARSIZE 0x00080000
+#define DDSD_DEPTH 0x00800000
// DDS_header.sPixelFormat.dwFlags
-#define DDPF_ALPHAPIXELS 0x00000001
-#define DDPF_FOURCC 0x00000004
-#define DDPF_INDEXED 0x00000020
-#define DDPF_RGB 0x00000040
+#define DDPF_ALPHAPIXELS 0x00000001
+#define DDPF_ALPHA 0x00000002
+#define DDPF_FOURCC 0x00000004
+#define DDPF_INDEXED 0x00000020
+#define DDPF_RGB 0x00000040
+#define DDPF_LUMINANCE 0x00020000
// DDS_header.sCaps.dwCaps1
-#define DDSCAPS_COMPLEX 0x00000008
-#define DDSCAPS_TEXTURE 0x00001000
-#define DDSCAPS_MIPMAP 0x00400000
+#define DDSCAPS_COMPLEX 0x00000008
+#define DDSCAPS_TEXTURE 0x00001000
+#define DDSCAPS_MIPMAP 0x00400000
// DDS_header.sCaps.dwCaps2
-#define DDSCAPS2_CUBEMAP 0x00000200
-#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
-#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
-#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
-#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
-#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
-#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
-#define DDSCAPS2_VOLUME 0x00200000
+#define DDSCAPS2_CUBEMAP 0x00000200
+#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400
+#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800
+#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000
+#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000
+#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000
+#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000
+#define DDSCAPS2_VOLUME 0x00200000
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
(uint32_t)( \
@@ -79,11 +81,11 @@
(((uint32_t)(uint8_t)(ch1) << 8) & 0x0000FF00) | \
((uint32_t)(uint8_t)(ch0) & 0x000000FF) )
-#define D3DFMT_DXT1 MAKEFOURCC('D','X','T','1') // DXT1 compression texture format
-#define D3DFMT_DXT2 MAKEFOURCC('D','X','T','2') // DXT2 compression texture format
-#define D3DFMT_DXT3 MAKEFOURCC('D','X','T','3') // DXT3 compression texture format
-#define D3DFMT_DXT4 MAKEFOURCC('D','X','T','4') // DXT4 compression texture format
-#define D3DFMT_DXT5 MAKEFOURCC('D','X','T','5') // DXT5 compression texture format
+#define D3DFMT_DXT1 MAKEFOURCC('D','X','T','1') // DXT1 compression texture format
+#define D3DFMT_DXT2 MAKEFOURCC('D','X','T','2') // DXT2 compression texture format
+#define D3DFMT_DXT3 MAKEFOURCC('D','X','T','3') // DXT3 compression texture format
+#define D3DFMT_DXT4 MAKEFOURCC('D','X','T','4') // DXT4 compression texture format
+#define D3DFMT_DXT5 MAKEFOURCC('D','X','T','5') // DXT5 compression texture format
#define D3DFMT_ETC1 MAKEFOURCC('E','T','C','1') // Custom (Ericcson Texture Compression)
struct _DDS_pixelformat {
@@ -128,6 +130,7 @@ typedef struct _DdsLoadInfo {
bool compressed;
unsigned int divSize;
unsigned int blockBytes;
+ uint32_t flags;
int bitcount;
uint32_t rmask;
uint32_t gmask;
@@ -136,16 +139,19 @@ typedef struct _DdsLoadInfo {
} DdsLoadInfo;
static DdsLoadInfo loadInfo[] = {
- [FMT_A8R8G8B8] = {false, 1, 4, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
- [FMT_X8R8G8B8] = {false, 1, 4, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
- [FMT_R8G8B8] = {false, 1, 3, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
- [FMT_A1R5G5B5] = {false, 1, 2, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000},
- [FMT_X1R5G5B5] = {false, 1, 2, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00000000},
- [FMT_R5G6B5] = {false, 1, 2, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000},
- [FMT_DXT1] = {true, 4, 8, 0, D3DFMT_DXT1},
- [FMT_DXT3] = {true, 4, 16, 0, D3DFMT_DXT3},
- [FMT_DXT5] = {true, 4, 16, 0, D3DFMT_DXT5},
- [FMT_ETC1] = {true, 4, 8, 0, D3DFMT_ETC1}
+ [FMT_A8R8G8B8] = {false, 1, 4, DDPF_RGB, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},
+ [FMT_X8R8G8B8] = {false, 1, 4, DDPF_RGB, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
+ [FMT_R8G8B8] = {false, 1, 3, DDPF_RGB, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
+ [FMT_A1R5G5B5] = {false, 1, 2, DDPF_RGB, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000},
+ [FMT_X1R5G5B5] = {false, 1, 2, DDPF_RGB, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00000000},
+ [FMT_R5G6B5] = {false, 1, 2, DDPF_RGB, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000},
+ [FMT_A8] = {false, 1, 1, DDPF_ALPHA, 8, 0x00000000, 0, 0, 0x000000ff},
+ [FMT_L8] = {false, 1, 1, DDPF_LUMINANCE, 8, 0x000000ff, 0, 0, 0x00000000},
+ [FMT_A8L8] = {false, 1, 2, DDPF_LUMINANCE, 16, 0x000000ff, 0, 0, 0x0000ff00},
+ [FMT_DXT1] = {true, 4, 8, DDPF_FOURCC, 0, D3DFMT_DXT1},
+ [FMT_DXT3] = {true, 4, 16, DDPF_FOURCC, 0, D3DFMT_DXT3},
+ [FMT_DXT5] = {true, 4, 16, DDPF_FOURCC, 0, D3DFMT_DXT5},
+ [FMT_ETC1] = {true, 4, 8, DDPF_FOURCC, 0, D3DFMT_ETC1}
};
#define NUM_FORMATS (sizeof(loadInfo) / sizeof(DdsLoadInfo))
@@ -160,20 +166,40 @@ static int find_fmt(struct _DDS_pixelformat *pf)
DdsLoadInfo *li = &loadInfo[fmt];
if(pf->dwFlags & DDPF_FOURCC)
{
- if(li->bitcount == 0 && li->rmask == pf->dwFourCC)
+ if(li->flags == DDPF_FOURCC && li->bitcount == 0 && li->rmask == pf->dwFourCC)
{
return fmt;
}
}
else if(pf->dwFlags & DDPF_RGB)
{
- if((li->bitcount == pf->dwRGBBitCount) &&
- (li->rmask == pf->dwRBitMask) && (li->gmask == pf->dwGBitMask) &&
+ if((li->flags == DDPF_RGB) &&
+ (li->bitcount == pf->dwRGBBitCount) &&
+ (li->rmask == pf->dwRBitMask) && (li->gmask == pf->dwGBitMask) &&
(li->bmask == pf->dwBBitMask) && (li->amask == ((pf->dwFlags & DDPF_ALPHAPIXELS)?pf->dwAlphaBitMask:0)))
{
return fmt;
}
}
+ else if(pf->dwFlags & DDPF_LUMINANCE)
+ {
+ bool formatHasAlpha = pf->dwAlphaBitMask != 0;
+ bool ddsHasAlpha = (pf->dwFlags & DDPF_ALPHAPIXELS) != 0;
+ if(li->flags == DDPF_LUMINANCE &&
+ li->bitcount == pf->dwRGBBitCount &&
+ formatHasAlpha == ddsHasAlpha)
+ {
+ return fmt;
+ }
+ }
+ else if(pf->dwFlags & DDPF_ALPHA)
+ {
+ if(li->flags == DDPF_ALPHA &&
+ li->bitcount == pf->dwRGBBitCount)
+ {
+ return fmt;
+ }
+ }
}
return -1;
}
@@ -209,7 +235,7 @@ bool dds_load_file(FILE *f, dds_texture **out)
}
DdsLoadInfo *li = &loadInfo[fmt];
dds_texture *rv = (dds_texture*)malloc(sizeof(dds_texture));
- if(!rv)
+ if(!rv)
goto failure;
//fixme: do cube maps later
@@ -232,7 +258,7 @@ bool dds_load_file(FILE *f, dds_texture **out)
}
if((hdr.dwFlags & DDSD_PITCH) && (hdr.dwPitchOrLinearSize != x*li->blockBytes))
goto failure;
-
+
rv->fmt = fmt;
rv->num_slices = 1;
rv->num_mipmaps = mipMapCount;
@@ -246,7 +272,7 @@ bool dds_load_file(FILE *f, dds_texture **out)
/* compute offsets */
size_t offset = 0;
- for(unsigned int ix = 0; ix < mipMapCount; ++ix)
+ for(unsigned int ix = 0; ix < mipMapCount; ++ix)
{
dds_mipmap *mip = &rv->slices[0][ix];
mip->width = x;
@@ -255,7 +281,7 @@ bool dds_load_file(FILE *f, dds_texture **out)
mip->offset = offset;
mip->size = size;
#ifdef DEBUG
- printf("%08x Loading mipmap %i: %ix%i (%i) stride=%i\n",
+ printf("%08x Loading mipmap %i: %ix%i (%i) stride=%i\n",
(int)mip->offset, ix, (int)mip->width, (int)mip->height, (int)mip->size,
(int)mip->stride);
#endif
@@ -266,10 +292,10 @@ bool dds_load_file(FILE *f, dds_texture **out)
}
rv->data = malloc(offset);
rv->size = offset;
- if(!rv->data)
+ if(!rv->data)
goto failure;
fread(rv->data, rv->size, 1, f);
- for(unsigned int ix = 0; ix < mipMapCount; ++ix)
+ for(unsigned int ix = 0; ix < mipMapCount; ++ix)
{
rv->slices[0][ix].data = (void*)((size_t)rv->data + rv->slices[0][ix].offset);
}
@@ -283,7 +309,7 @@ failure:
bool dds_load(const char *filename, dds_texture **out)
{
FILE *f = fopen(filename, "rb");
- if(f == NULL)
+ if(f == NULL)
{
#ifdef DEBUG
printf("Cannot open texture file\n");