diff options
author | Sven Gothel <[email protected]> | 2013-12-15 08:06:01 -0800 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-12-15 08:06:01 -0800 |
commit | 82927b0e75a2a93f3728d158295a6ae25dddeecf (patch) | |
tree | 7dba5f547db114f697659d214d06ad7acfa79d6a | |
parent | ccfc9b529b1dbd6003a62cb4215e2cdaeb8c37fd (diff) | |
parent | 82d7bae212ad5a540a29003aaec8c7e026615f68 (diff) |
Merge pull request #76 from esemplare/master
Fix Bug 362: calculated dimensions for MipMaps smaller than 16x16
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/texture/spi/DDSImage.java | 33 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestBug362DDSImageCreateFromData.java | 98 | ||||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds | bin | 0 -> 1512 bytes | |||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds | bin | 0 -> 2896 bytes | |||
-rw-r--r-- | src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds | bin | 0 -> 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 Binary files differnew file mode 100644 index 000000000..81ae64e33 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT1.dds 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 Binary files differnew file mode 100644 index 000000000..5b9e364e0 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_DXT5.dds 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 Binary files differnew file mode 100644 index 000000000..034d2516c --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/test-64x32_uncompressed.dds |