Bug 584 - Texture binding fails if image width < alignment
Summary: Texture binding fails if image width < alignment
Status: RESOLVED INVALID
Alias: None
Product: Jogl
Classification: JogAmp
Component: util (show other bugs)
Version: 2
Hardware: All all
: --- normal
Assignee: Sven Gothel
URL:
Depends on:
Blocks:
 
Reported: 2012-05-23 18:47 CEST by Fabien Mars
Modified: 2012-05-24 12:30 CEST (History)
0 users

See Also:
Type: DEFECT
SCM Refs:
Workaround: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fabien Mars 2012-05-23 18:47:16 CEST
I'm trying to bind a .gif 2x2 texture in 4 colors, JOGL won't let me.

First loading it with BufferedImage sourceImage = ImageIO.read(url);
Then, using an appropriate Color Model: new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] { 8, 8, 8, 0 }, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
I'm creating a raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, 2, 2, 3, null) to hold the data
Prior to filling a new proper BufferedImage destImage = new BufferedImage(colorModel, raster, false, new Hashtable<Object, Object>());
Graphics g = destImage.getGraphics();
g.drawImage(sourceImage, 0, 0, null);
And getting the databuffer with raster.getDataBuffer().
I do the above with all my textures, no matter what they are, they will load properly. Except here:

This method is called:
      gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, 2, 2, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, textureBuffer);

And I get:
java.lang.IndexOutOfBoundsException: Required 14 remaining bytes in buffer, only had 12
	at com.jogamp.common.nio.Buffers.rangeCheckBytes(Buffers.java:853)
	at jogamp.opengl.gl4.GL4bcImpl.glTexImage2D(GL4bcImpl.java:25283)


That's because of what's in GLBuffers line 321: remainder won't be good if image width < alignment.

This works in C, should also in Java.
Comment 1 Fabien Mars 2012-05-24 07:33:07 CEST
Actually this very texture used to load in C and also with JOGL in 2005. I discovered this whilist dusting my code with the latest libs of everything.
Comment 2 Sven Gothel 2012-05-24 09:21:28 CEST
(In reply to comment #0)
> I'm trying to bind a .gif 2x2 texture in 4 colors, JOGL won't let me.

> 
> This method is called:
>       gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, 2, 2, 0, GL.GL_RGB,
> GL.GL_UNSIGNED_BYTE, textureBuffer);
> 
> And I get:
> java.lang.IndexOutOfBoundsException: Required 14 remaining bytes in buffer,
> only had 12
>     at com.jogamp.common.nio.Buffers.rangeCheckBytes(Buffers.java:853)
>     at jogamp.opengl.gl4.GL4bcImpl.glTexImage2D(GL4bcImpl.java:25283)
> 
> 
> That's because of what's in GLBuffers line 321: remainder won't be good if
> image width < alignment.
> 

Alignment should be 1 or 2 in your case 
(not 4, which is the default).
It's up to you to properly set it up.

In your example, you have probably kept alignment at 4,
hence the 1st row-length is assumed to be 8:
  2 * 3 =6, aligned -> 8
the 2nd row-length is not required to be aligned,
since only the beginning of a row requires alignment:
  8 + 6 = 14

So you are missing the 2 bytes of alignment.
Either add it to the buffer, or set alignment to 1.

> This works in C, should also in Java.

Well, if the native OpenGL driver allows you to ignore alignment
and does not post an error - this is one thing.
Please notice that in such case, the OpenGL driver may
copy more bytes than you offer from host memory to GPU memory.

JOGL likes to fail-fast and  does not allow to offer less bytes
than required.

(In reply to comment #1)
> Actually this very texture used to load in C and also with JOGL in 2005. I
> discovered this whilist dusting my code with the latest libs of everything.
In 2005 we might not had this pre-validation in place
or my latest update of this code refined the restrictions.

If my calculations and/or assumptions above are wrong,
please reopen the bug and clarify.

Thank you.
Comment 3 Fabien Mars 2012-05-24 12:30:26 CEST
Indeed, I'm blatantly stupid.