aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Esemplare <[email protected]>2013-12-11 13:43:03 -0800
committerMichael Esemplare <[email protected]>2013-12-11 13:49:00 -0800
commit82d7bae212ad5a540a29003aaec8c7e026615f68 (patch)
tree239cb2557018df8e7661702216e6fb53aad4fecb
parent45525950b0ad41b10790515c8b6142d746cd24f5 (diff)
Fix Bug 362: calculated dimensions for MipMaps smaller than 16x16
Added method to calculate mipmap blocksize for uncompressed and DXTn images
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java33
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java98
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.ddsbin0 -> 1512 bytes
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.ddsbin0 -> 2896 bytes
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.ddsbin0 -> 8321 bytes
5 files changed, 130 insertions, 1 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
index d75bb3767..7311f20b3 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java
@@ -766,6 +766,8 @@ public class DDSImage {
// Now check the mipmaps against this size
int curSize = topmostMipmapSize;
+ int mipmapWidth = width;
+ int mipmapHeight = height;
int totalSize = 0;
for (int i = 0; i < mipmapData.length; i++) {
if (mipmapData[i].remaining() != curSize) {
@@ -773,7 +775,10 @@ public class DDSImage {
" didn't match expected data size (expected " + curSize + ", got " +
mipmapData[i].remaining() + ")");
}
- curSize /= 4;
+ // Compute next mipmap size
+ if (mipmapWidth > 1) mipmapWidth /= 2;
+ if (mipmapHeight > 1) mipmapHeight /= 2;
+ curSize = computeBlockSize(mipmapWidth, mipmapHeight, 1, d3dFormat);
totalSize += mipmapData[i].remaining();
}
@@ -852,6 +857,32 @@ public class DDSImage {
return blockSize;
}
+ private static int computeBlockSize(int width,
+ int height,
+ int depth,
+ int pixelFormat) {
+ int blocksize;
+ switch (pixelFormat) {
+ case D3DFMT_R8G8B8:
+ blocksize = width*height*3;
+ break;
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ blocksize = width*height*4;
+ break;
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ blocksize = computeCompressedBlockSize(width, height, 1, pixelFormat);
+ break;
+ default:
+ throw new IllegalArgumentException("d3dFormat must be one of the known formats");
+ }
+ return blocksize;
+ }
+
private int mipMapWidth(int map) {
int width = getWidth();
for (int i = 0; i < map; i++) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
new file mode 100644
index 000000000..4212abae7
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java
@@ -0,0 +1,98 @@
+package com.jogamp.opengl.test.junit.jogl.util.texture;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.ByteBuffer;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.jogamp.common.util.IOUtil;
+import com.jogamp.opengl.util.texture.spi.DDSImage;
+import com.jogamp.opengl.util.texture.spi.DDSImage.ImageInfo;
+
+/**
+ * This test uses the DDSImage class to read a dds image from file, extract the data,
+ * and use the class to create a new DDSImage from the extracted data
+ * <br></br>
+ * Bug Reference: https://jogamp.org/bugzilla/show_bug.cgi?id=362
+ * <br></br>
+ * The bug pertains to incorrect size calculation for checking validity of data. Compressed DXT1 has min of 8 bytes, DXT5 has min of 16 bytes.
+ * It exists in {@link DDSImage#createFromData(int, int, int, ByteBuffer[])}
+ * where an {@link IllegalArgumentException} is thrown for Mipmap level size mismatch.
+ * <br></br>
+ * <ul>The following cases are tested:
+ * <li>Uncompressed 64x32 RGB DDS Image with all mipmap levels (64x32 --> 1x1)</li>
+ * <li>DXT1 compressed 64x32 RGB DDS Image with all mipmap levels (64x32 --> 1x1)</li>
+ * <li>DXT5 compressed 64x32 RGB DDS Image with all mipmap levels (64x32 --> 1x1)</li>
+ * </ul>
+ *
+ * @author Michael Esemplare
+ *
+ */
+public class TestBug362DDSImageCreateFromData {
+
+ File testDDSImage01Uncompressed;
+ File testDDSImage02DXT1;
+ File testDDSImage03DXT5;
+
+ @Before
+ public void setup() throws Throwable {
+ testDDSImage01Uncompressed = initFile("test-64x32_uncompressed.dds");
+ testDDSImage02DXT1 = initFile("test-64x32_DXT1.dds");
+ testDDSImage03DXT5 = initFile("test-64x32_DXT5.dds");
+ }
+
+ @After
+ public void teardown() {
+ testDDSImage01Uncompressed = null;
+ testDDSImage02DXT1 = null;
+ testDDSImage03DXT5 = null;
+ }
+
+ private File initFile(String filename) throws URISyntaxException {
+ URLConnection connection = IOUtil.getResource(getClass(), filename);
+ Assert.assertNotNull(connection);
+ URL url = connection.getURL();
+ File file = new File(url.toURI());
+ Assert.assertTrue(file.exists());
+ return file;
+ }
+
+ private void testImpl(File file) throws IOException {
+ DDSImage ddsImage = DDSImage.read(file);
+ Assert.assertNotNull(ddsImage);
+ int numMipMaps = ddsImage.getNumMipMaps();
+ ByteBuffer[] mipMapArray = new ByteBuffer[numMipMaps];
+ for (int i=0;i<numMipMaps;i++){
+ ImageInfo info = ddsImage.getMipMap(i);
+ mipMapArray[i] = info.getData();
+ }
+ DDSImage newImage = DDSImage.createFromData(ddsImage.getPixelFormat(), ddsImage.getWidth(), ddsImage.getHeight(), mipMapArray);
+ Assert.assertNotNull(newImage);
+ }
+
+ @Test
+ public void test00_DDSImage_CreateFromData_Uncompressed_RGB () throws IOException {
+ testImpl(testDDSImage01Uncompressed);
+ }
+
+ @Test
+ public void test01_DDSImage_CreateFromData_DXT1_RGB () throws IOException {
+ testImpl(testDDSImage02DXT1);
+ }
+
+ @Test
+ public void test02_DDSImage_CreateFromData_DXT5_RGB () throws IOException {
+ testImpl(testDDSImage03DXT5);
+ }
+
+ public static void main(String[] args) {
+ org.junit.runner.JUnitCore.main(TestBug362DDSImageCreateFromData.class.getName());
+ }
+} \ No newline at end of file
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds
new file mode 100644
index 000000000..81ae64e33
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds
Binary files differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds
new file mode 100644
index 000000000..5b9e364e0
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds
Binary files differ
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds
new file mode 100644
index 000000000..034d2516c
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds
Binary files differ