From 06ba8994749ac515399eb3489b4018b342fcdc91 Mon Sep 17 00:00:00 2001
From: Turo Lamminen <turotl@gmail.com>
Date: Sat, 09 May 2015 14:47:08 +0000
Subject: [PATCH] Calculate miplevels from size if header says zero
---
mojodds.c | 25 +++++++++++++++++++++++++
1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/mojodds.c b/mojodds.c
index c5e8124..6d69be5 100644
--- a/mojodds.c
+++ b/mojodds.c
@@ -104,6 +104,25 @@
} MOJODDS_Header;
+//http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
+static const uint32_t MultiplyDeBruijnBitPosition[32] =
+{
+ 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
+ 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
+};
+
+
+static uint32_t uintLog2(uint32_t v) {
+ v |= v >> 1; // first round down to one less than a power of 2
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+
+ return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
+}
+
+
static uint32 readui32(const uint8 **_ptr, size_t *_len)
{
uint32 retval = 0;
@@ -194,12 +213,18 @@
*_miplevels = (header->dwCaps & DDSCAPS_MIPMAP) ? header->dwMipMapCount : 1;
+ unsigned int calculatedMipLevels = uintLog2(MAX(width, height)) + 1;
if (*_miplevels > 32)
{
// too many mip levels, width and height would be larger than 32-bit int
// file is corrupted
return 0;
}
+ else if (*_miplevels == 0)
+ {
+ // invalid, calculate it ourselves from size
+ *_miplevels = calculatedMipLevels;
+ }
if (header->ddspf.dwFlags & DDPF_FOURCC)
{
--
Gitblit v1.9.3