40package com.jogamp.opengl.util.texture.spi;
44import java.nio.channels.*;
46import com.jogamp.opengl.*;
47import com.jogamp.common.util.IOUtil;
74 private final Header header;
77 private ByteBuffer data;
117 private final int tgaType;
120 private int idLength;
121 private int colorMapType;
122 private int imageType;
125 private int firstEntryIndex;
126 private int colorMapLength;
127 private byte colorMapEntrySize;
134 private byte pixelDepth;
135 private byte imageDescriptor;
137 private byte[] imageIDbuf;
138 private String imageID;
149 idLength = in.readUnsignedByte();
150 colorMapType = in.readUnsignedByte();
151 imageType = in.readUnsignedByte();
154 firstEntryIndex = in.readUnsignedShort();
155 colorMapLength = in.readUnsignedShort();
156 colorMapEntrySize = in.readByte();
159 xOrigin = in.readUnsignedShort();
160 yOrigin = in.readUnsignedShort();
161 width = in.readUnsignedShort();
162 height = in.readUnsignedShort();
163 pixelDepth = in.readByte();
164 imageDescriptor = in.readByte();
167 imageIDbuf =
new byte[idLength];
168 in.read(imageIDbuf, 0, idLength);
169 imageID =
new String(imageIDbuf,
"US-ASCII");
204 return "TGA Header " +
205 " id length: " + idLength +
206 " color map type: "+ colorMapType +
207 " image type: "+ imageType +
208 " first entry index: " + firstEntryIndex +
209 " color map length: " + colorMapLength +
210 " color map entry size: " + colorMapEntrySize +
211 " x Origin: " + xOrigin +
212 " y Origin: " + yOrigin +
214 " height: "+ height +
215 " pixel depth: "+ pixelDepth +
216 " image descriptor: "+ imageDescriptor +
217 (imageIDbuf ==
null ?
"" : (
" ID String: " + imageID));
220 public int size() {
return 18 + idLength; }
223 private void write(
final ByteBuffer buf) {
224 buf.put((
byte) idLength);
225 buf.put((
byte) colorMapType);
226 buf.put((
byte) imageType);
227 buf.putShort((
short) firstEntryIndex);
228 buf.putShort((
short) colorMapLength);
229 buf.put(colorMapEntrySize);
230 buf.putShort((
short) xOrigin);
231 buf.putShort((
short) yOrigin);
232 buf.putShort((
short) width);
233 buf.putShort((
short) height);
235 buf.put(imageDescriptor);
238 final byte[] chars = imageID.getBytes(
"US-ASCII");
240 }
catch (
final UnsupportedEncodingException e) {
241 throw new RuntimeException(e);
253 private void decodeImage(
final GLProfile glp,
final LEDataInputStream dIn)
throws IOException {
254 switch (header.imageType()) {
255 case Header.UCOLORMAPPED:
256 throw new IOException(
"TGADecoder Uncompressed Colormapped images not supported");
258 case Header.UTRUECOLOR:
259 switch (header.pixelDepth) {
261 throw new IOException(
"TGADecoder Compressed 16-bit True Color images not supported");
265 decodeRGBImageU24_32(glp, dIn);
270 case Header.UBLACKWHITE:
271 throw new IOException(
"TGADecoder Uncompressed Grayscale images not supported");
273 case Header.COLORMAPPED:
274 throw new IOException(
"TGADecoder Compressed Colormapped images not supported");
276 case Header.TRUECOLOR:
277 switch (header.pixelDepth) {
279 throw new IOException(
"TGADecoder Compressed 16-bit True Color images not supported");
283 decodeRGBImageRLE24_32(glp, dIn);
288 case Header.BLACKWHITE:
289 throw new IOException(
"TGADecoder Compressed Grayscale images not supported");
297 private void decodeRGBImageU24_32(
final GLProfile glp,
final LEDataInputStream dIn)
throws IOException {
298 setupImage24_32(glp);
302 final int rawWidth = header.width() * bpp;
303 final byte[] rawBuf =
new byte[rawWidth];
304 final byte[] tmpData =
new byte[rawWidth * header.height()];
306 for (i = 0; i < header.height(); ++i) {
307 dIn.readFully(rawBuf, 0, rawWidth);
310 y = header.height - i - 1;
314 System.arraycopy(rawBuf, 0, tmpData, y * rawWidth, rawBuf.length);
318 swapBGR(tmpData, rawWidth, header.height(), bpp);
319 data = ByteBuffer.wrap(tmpData);
326 private void decodeRGBImageRLE24_32(
final GLProfile glp,
final LEDataInputStream dIn)
throws IOException {
327 setupImage24_32(glp);
329 final byte[] pixel =
new byte[bpp];
330 final int rawWidth = header.width() * bpp;
331 final byte[] tmpData =
new byte[rawWidth * header.height()];
334 while (i < tmpData.length) {
335 packet = dIn.readUnsignedByte();
336 len = (packet & 0x7F) + 1;
337 if ((packet & 0x80) != 0) {
339 for (j = 0; j < len; ++j)
340 System.arraycopy(pixel, 0, tmpData, i + j * bpp, bpp);
342 dIn.read(tmpData, i, len * bpp);
347 swapBGR(tmpData, rawWidth, header.height(), bpp);
348 data = ByteBuffer.wrap(tmpData);
351 private void setupImage24_32(
final GLProfile glp) {
352 bpp = header.pixelDepth / 8;
353 switch (header.pixelDepth) {
363 format = useBGRA ? GL.GL_BGRA :
GL.
GL_RGBA;
370 private static void swapBGR(
final byte[] data,
final int bWidth,
final int height,
final int bpp) {
373 for(
int i=0; i<height; ++i) {
374 for(
int j=0; j<bWidth; j+=bpp) {
402 return read(glp,
new FileInputStream(filename));
411 res.decodeImage(glp, dIn);
416 public void write(
final String filename)
throws IOException {
417 write(
new File(filename));
421 public void write(
final File file)
throws IOException {
422 final FileOutputStream stream = IOUtil.getFileOutputStream(file,
true);
423 final FileChannel chan = stream.getChannel();
424 final ByteBuffer buf = ByteBuffer.allocate(header.
size());
425 buf.order(ByteOrder.LITTLE_ENDIAN);
442 final boolean hasAlpha,
443 final boolean topToBottom,
444 final ByteBuffer data) {
447 header.width = width;
448 header.height = height;
449 header.pixelDepth = (byte) (hasAlpha ? 32 : 24);
Abstraction for an OpenGL rendering context.
static GLContext getCurrent()
Returns this thread current context.
boolean isTextureFormatBGRA8888Available()
Specifies the the OpenGL profile.
final boolean isGL2GL3()
Indicates whether this profile is capable of GL2GL3.
Little Endian Data Input Stream.
Targa image reader and writer adapted from sources of the Jimi image I/O class library.
int getWidth()
Returns the width of the image.
ByteBuffer getData()
Returns the raw data for this texture in the correct (bottom-to-top) order for calls to glTexImage2D.
static TGAImage read(final GLProfile glp, final InputStream in)
Reads a Targa image from the specified InputStream.
void write(final File file)
Writes the image in Targa format to the specified file.
void write(final String filename)
Writes the image in Targa format to the specified file name.
static TGAImage createFromData(final int width, final int height, final boolean hasAlpha, final boolean topToBottom, final ByteBuffer data)
Creates a TGAImage from data supplied by the end user.
int getHeight()
Returns the height of the image.
int getBytesPerPixel()
Returns the bytes per pixel.
int getGLFormat()
Returns the OpenGL format for this texture; e.g.
static TGAImage read(final GLProfile glp, final String filename)
Reads a Targa image from the specified file.
static final int GL_RGB
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_RGB" with expression ...
static final int GL_RGBA
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_RGBA" with expression...