Bug 982

Summary: TextureIO fails to load some Targa image files
Product: [JogAmp] Jogl Reporter: Julien Gouesse <gouessej>
Component: utilAssignee: Sven Gothel <sgothel>
Status: RESOLVED INVALID    
Severity: minor CC: gouessej, michael.esemplare
Priority: ---    
Version: 2   
Hardware: All   
OS: all   
Type: DEFECT SCM Refs:
9d7a7e55c95fcf29ce1ed0804fd7791c1c1147de
Workaround: ---
Attachments: Test case for targa image

Description Julien Gouesse 2014-02-23 10:06:11 CET
This Targa image file cannot be loaded by TextureIO:
https://github.com/Renanse/Ardor3D/blob/master/ardor3d-core/src/main/resources/com/ardor3d/renderer/state/notloaded.tga

I get the following stack trace when attempting to load it:
java.io.IOException: No suitable reader for given stream
        at com.jogamp.opengl.util.texture.TextureIO.newTextureDataImpl(TextureIO.java:888)
        at com.jogamp.opengl.util.texture.TextureIO.newTextureData(TextureIO.java:243)
        at com.ardor3d.image.util.jogl.JoglImageLoader.load(JoglImageLoader.java:105)
        at com.ardor3d.image.util.ImageLoaderUtil.loadImage(ImageLoaderUtil.java:77)
        at com.ardor3d.image.util.ImageLoaderUtil.loadImage(ImageLoaderUtil.java:54)
        at com.ardor3d.util.TextureManager.loadFromKey(TextureManager.java:207)
        at com.ardor3d.util.TextureManager.load(TextureManager.java:136)
        at com.ardor3d.util.TextureManager.load(TextureManager.java:110)
        at com.ardor3d.renderer.state.TextureState.loadDefaultTexture(TextureState.java:303)
        at com.ardor3d.renderer.state.TextureState.<init>(TextureState.java:91)
        at com.ardor3d.example.canvas.RotatingCubeGame.init(RotatingCubeGame.java:83)
        at com.ardor3d.example.canvas.JoglNewtAwtExample.main(JoglNewtAwtExample.java:130) 

You can reproduce this bug with the following example:
https://github.com/Renanse/Ardor3D/blob/master/ardor3d-examples/src/main/java/com/ardor3d/example/canvas/JoglNewtAwtExample.java

You can modify this existing JUnit test to give it a try:
https://github.com/sgothel/jogl/blob/master/src/test/com/jogamp/opengl/test/junit/jogl/util/texture/TestTGATextureFromFileNEWT.java
Comment 1 Michael 2014-03-09 08:57:08 CET
Looking at the TGAImage class and the tga file in question, it seems to be expected...

private void decodeImage(GLProfile glp, LEDataInputStream dIn) throws IOException {
        switch (header.imageType()) {
        case Header.UCOLORMAPPED:
            throw new IOException("TGADecoder Uncompressed Colormapped images not supported");

        case Header.UTRUECOLOR:    // pixelDepth 15, 16, 24 and 32
            switch (header.pixelDepth) {
            case 16:
                throw new IOException("TGADecoder Compressed 16-bit True Color images not supported");

            case 24:
            case 32:
                decodeRGBImageU24_32(glp, dIn);
                break;
            }
            break;

        case Header.UBLACKWHITE:
            throw new IOException("TGADecoder Uncompressed Grayscale images not supported");

        case Header.COLORMAPPED:
            throw new IOException("TGADecoder Compressed Colormapped images not supported");

        case Header.TRUECOLOR:
            throw new IOException("TGADecoder Compressed True Color images not supported");

        case Header.BLACKWHITE:
            throw new IOException("TGADecoder Compressed Grayscale images not supported");
        }
    }

The exception I am thrown is:

java.io.IOException: TGADecoder Compressed True Color images not supported
	at com.jogamp.opengl.util.texture.spi.TGAImage.decodeImage(TGAImage.java:276)
	at com.jogamp.opengl.util.texture.spi.TGAImage.read(TGAImage.java:373)
	at com.jogamp.opengl.util.texture.spi.TGAImage.read(TGAImage.java:364)
	at com.jogamp.opengl.test.junit.jogl.util.texture.TestBug982TGAImageCreateFromData.testImpl(TestBug982TGAImageCreateFromData.java:63)
	at com.jogamp.opengl.test.junit.jogl.util.texture.TestBug982TGAImageCreateFromData.test00_TGAImage_LoadFromFile(TestBug982TGAImageCreateFromData.java:69)
...
Comment 2 Julien Gouesse 2014-03-09 16:10:33 CET
(In reply to comment #1)
> Looking at the TGAImage class and the tga file in question, it seems to be
> expected...
> 
> private void decodeImage(GLProfile glp, LEDataInputStream dIn) throws
> IOException {
>         switch (header.imageType()) {
>         case Header.UCOLORMAPPED:
>             throw new IOException("TGADecoder Uncompressed Colormapped
> images not supported");
> 
>         case Header.UTRUECOLOR:    // pixelDepth 15, 16, 24 and 32
>             switch (header.pixelDepth) {
>             case 16:
>                 throw new IOException("TGADecoder Compressed 16-bit True
> Color images not supported");
> 
>             case 24:
>             case 32:
>                 decodeRGBImageU24_32(glp, dIn);
>                 break;
>             }
>             break;
> 
>         case Header.UBLACKWHITE:
>             throw new IOException("TGADecoder Uncompressed Grayscale images
> not supported");
> 
>         case Header.COLORMAPPED:
>             throw new IOException("TGADecoder Compressed Colormapped images
> not supported");
> 
>         case Header.TRUECOLOR:
>             throw new IOException("TGADecoder Compressed True Color images
> not supported");
> 
>         case Header.BLACKWHITE:
>             throw new IOException("TGADecoder Compressed Grayscale images
> not supported");
>         }
>     }
> 
> The exception I am thrown is:
> 
> java.io.IOException: TGADecoder Compressed True Color images not supported
> 	at
> com.jogamp.opengl.util.texture.spi.TGAImage.decodeImage(TGAImage.java:276)
> 	at com.jogamp.opengl.util.texture.spi.TGAImage.read(TGAImage.java:373)
> 	at com.jogamp.opengl.util.texture.spi.TGAImage.read(TGAImage.java:364)
> 	at
> com.jogamp.opengl.test.junit.jogl.util.texture.
> TestBug982TGAImageCreateFromData.testImpl(TestBug982TGAImageCreateFromData.
> java:63)
> 	at
> com.jogamp.opengl.test.junit.jogl.util.texture.
> TestBug982TGAImageCreateFromData.
> test00_TGAImage_LoadFromFile(TestBug982TGAImageCreateFromData.java:69)
> ...

Thank you for investigating. There is a lack to support for RLE compression in TGAImage, "truecolor" is already supported.
Comment 3 Julien Gouesse 2014-03-09 16:32:05 CET
(In reply to comment #1)

> 
>         case Header.COLORMAPPED:
>             throw new IOException("TGADecoder Compressed Colormapped images
> not supported");
> 
>         case Header.TRUECOLOR:
>             throw new IOException("TGADecoder Compressed True Color images
> not supported");
> 
>         case Header.BLACKWHITE:
>             throw new IOException("TGADecoder Compressed Grayscale images
> not supported");
>         }
>     }
> 
> The exception I am thrown is:
> 
> java.io.IOException: TGADecoder Compressed True Color images not supported
> 	at
> com.jogamp.opengl.util.texture.spi.TGAImage.decodeImage(TGAImage.java:276)
> 	at com.jogamp.opengl.util.texture.spi.TGAImage.read(TGAImage.java:373)
> 	at com.jogamp.opengl.util.texture.spi.TGAImage.read(TGAImage.java:364)
> 	at
> com.jogamp.opengl.test.junit.jogl.util.texture.
> TestBug982TGAImageCreateFromData.testImpl(TestBug982TGAImageCreateFromData.
> java:63)
> 	at
> com.jogamp.opengl.test.junit.jogl.util.texture.
> TestBug982TGAImageCreateFromData.
> test00_TGAImage_LoadFromFile(TestBug982TGAImageCreateFromData.java:69)
> ...
Which version of JOGL do you use? RLE support was added in 2013 in this class, only 16-bits compressed truecolor TGA files are still unsupported:
https://github.com/sgothel/jogl/blob/master/src/jogl/classes/com/jogamp/opengl/util/texture/spi/TGAImage.java#L279

The Gimp doesn't give me a lot of information about the image data :s
Comment 4 Julien Gouesse 2014-03-09 16:48:11 CET
"For 16 bits each colour component is stored as 5 bits and the remaining bit is a binary alpha value."
http://www.paulbourke.net/dataformats/tga/

It matches with this format:
http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/GL.html#GL_RGB5_A1
Comment 5 Michael 2014-03-09 23:30:06 CET
Created attachment 606 [details]
Test case for targa image

Thanks for pointing that out, I didn't realize I was using a much older version. 

The unit test passes against master and 2.1.4.

I have attached the test if you wish to run.
Comment 6 Sven Gothel 2014-07-10 14:05:19 CEST
9d7a7e55c95fcf29ce1ed0804fd7791c1c1147de:
  Added RLE32 tga file to be tested w/ pre-existing unit test TestTGATextureFromFileNEWT.

As mentioned above - not a bug, all works.
Comment 7 Julien Gouesse 2014-07-12 23:58:06 CEST
Sorry but it doesn't work with the image I mentioned in my very first post:
https://github.com/Renanse/Ardor3D/blob/master/ardor3d-core/src/main/resources/com/ardor3d/renderer/state/notloaded.tga

JFPSM still complains:
 [java] juil. 12, 2014 10:52:22 PM com.ardor3d.util.resource.ResourceLocatorTool locateResource
        [java] Avertissement: Unable to locate: file:/home/gouessej/Documents/programmation/java/workspace/tuer/md2/soldier.md2
        [java] juil. 12, 2014 10:52:22 PM com.ardor3d.util.TextureManager load
        [java] Avertissement: Could not load image...  source was null. defaultTexture used.
        [java] libEGL warning: failed to create a pipe screen for i965
        [java] juil. 12, 2014 10:52:29 PM com.ardor3d.image.util.ImageLoaderUtil loadImage
        [java] Avertissement: Could not load Image.
        [java] java.io.IOException: No suitable reader for given stream
        [java] 	at com.jogamp.opengl.util.texture.TextureIO.newTextureDataImpl(TextureIO.java:851)
        [java] 	at com.jogamp.opengl.util.texture.TextureIO.newTextureData(TextureIO.java:245)
        [java] 	at com.ardor3d.image.util.jogl.JoglImageLoader.load(JoglImageLoader.java:105)
        [java] 	at com.ardor3d.image.util.ImageLoaderUtil.loadImage(ImageLoaderUtil.java:77)
        [java] 	at com.ardor3d.image.util.ImageLoaderUtil.loadImage(ImageLoaderUtil.java:54)
        [java] 	at com.ardor3d.util.TextureManager.loadFromKey(TextureManager.java:207)
        [java] 	at com.ardor3d.util.TextureManager.load(TextureManager.java:136)
        [java] 	at com.ardor3d.util.TextureManager.load(TextureManager.java:110)
        [java] 	at com.ardor3d.renderer.state.TextureState.loadDefaultTexture(TextureState.java:303)
        [java] 	at com.ardor3d.renderer.state.TextureState.getDefaultTexture(TextureState.java:292)
        [java] 	at com.ardor3d.util.TextureManager.load(TextureManager.java:131)
        [java] 	at com.ardor3d.util.TextureManager.load(TextureManager.java:93)
        [java] 	at com.ardor3d.extension.model.md2.Md2Importer.loadTexture(Md2Importer.java:356)
        [java] 	at com.ardor3d.extension.model.md2.Md2Importer.load(Md2Importer.java:337)
        [java] 	at jfpsm.ModelConverterViewer$ModelConversionSwingWorker.doInBackground(ModelConverterViewer.java:371)
        [java] 	at jfpsm.ModelConverterViewer$ModelConversionSwingWorker.doInBackground(ModelConverterViewer.java:318)
        [java] 	at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
        [java] 	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        [java] 	at javax.swing.SwingWorker.run(SwingWorker.java:335)
        [java] 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        [java] 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        [java] 	at java.lang.Thread.run(Thread.java:744)
        [java] juil. 12, 2014 10:52:29 PM com.ardor3d.util.TextureManager loadFromKey
        [java] Avertissement: (image null) Could not load: URLResourceSource [url=jar:file:/home/gouessej/Documents/programmation/java/workspace/tuer/lib/ardor3d/ardor3d-core-1.0-SNAPSHOT.jar!/com/ardor3d/renderer/state/notloaded.tga, type=.tga]
Comment 8 Julien Gouesse 2014-07-14 15:51:20 CEST
I've just added the problematic image into the unit test:
https://github.com/sgothel/jogl/pull/78

It seems to work but I still get an exception. It probably exhibits another bug elsewhere.
Comment 9 Julien Gouesse 2014-07-31 21:27:48 CEST
In JoglImageLoader, I do this:
final TextureData textureData = TextureIO.newTextureData(_capsUtil.getProfile(), is, true, null);

It has no chance to work with TGA because of this test in TGATextureProvider:
if (TGA.equals(fileSuffix)) {

I don't know yet how I'll work around this limitation.
Comment 10 Julien Gouesse 2014-07-31 22:51:21 CEST
Feel free to close this bug as invalid. The image I provided in in true color 32 bits, the problem comes from Ardor3D except if we consider that JOGL should be able to guess which image type contains the passed input stream (with a file suffix set to null). I'll implement this mechanism in Ardor3D, maybe we should move it into JOGL itself, it should be the subject of a distinct bug report.
Comment 11 Julien Gouesse 2014-08-02 23:57:18 CEST
The real bug has been fixed in Ardor3D:
https://github.com/gouessej/Ardor3D/blob/master/ardor3d-jogl/src/main/java/com/ardor3d/image/util/jogl/JoglImageLoader.java#L148

Sven, please tell me whether this kind of thing should be moved into JOGL.

My bug report is invalid as JOGL's TGA loader was already able to load the default image used in Ardor3D since the very beginning. Ardor3D AWT image loader was the only loader able to "guess" the image format until I fixed that in com.ardor3d.image.util.jogl.JoglImageLoader.
Comment 12 Sven Gothel 2014-08-04 19:52:45 CEST
(In reply to comment #11)
> The real bug has been fixed in Ardor3D:
> https://github.com/gouessej/Ardor3D/blob/master/ardor3d-jogl/src/main/java/
> com/ardor3d/image/util/jogl/JoglImageLoader.java#L148
> 
> Sven, please tell me whether this kind of thing should be moved into JOGL.
> 
> My bug report is invalid as JOGL's TGA loader was already able to load the
> default image used in Ardor3D since the very beginning. Ardor3D AWT image
> loader was the only loader able to "guess" the image format until I fixed
> that in com.ardor3d.image.util.jogl.JoglImageLoader.

That would be _excellent_, i.e. the image format auto-detection!

IMHO it would be nice to have a static method returning the type,
as well as an overloaded 'load' texture method.

Nice!

I will cherry pick your lines and commit as you as author.
Comment 13 Sven Gothel 2014-08-04 19:55:25 CEST
(In reply to comment #12)
> 
> Nice!
> 
> I will cherry pick your lines and commit as you as author.

Bug 1042