Package de.lessvoid.nifty.renderer.lwjgl.render.io

Source Code of de.lessvoid.nifty.renderer.lwjgl.render.io.TGAImageData

package de.lessvoid.nifty.renderer.lwjgl.render.io;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import org.lwjgl.BufferUtils;

/**
* A utility to load TGAs. Note: NOT THREAD SAFE
*
* Fresh cut of code but largely influeneced by the TGA loading class
* provided as part of the Java Monkey Engine (JME). Why not check out
* what they're doing over at http://www.jmonkeyengine.com. kudos to
* Mark Powell.
*
* @author Kevin Glass
*/
public class TGAImageData implements ImageData {
  /** The width of the texture that needs to be generated */
  private int texWidth;
  /** The height of the texture that needs to be generated */
  private int texHeight;
  /** The width of the TGA image */
  private int width;
  /** The height of the TGA image */
  private int height;
  /** The bit depth of the image */
  private short pixelDepth;

  /**
   * Create a new TGA Loader
   */
  public TGAImageData() {
  }

  /**
   * Flip the endian-ness of the short
   *
   * @param signedShort The short to flip
   * @return The flipped short
   */
  private short flipEndian(short signedShort) {
    int input = signedShort & 0xFFFF;
    return (short) (input << 8 | (input & 0xFF00) >>> 8);
  }
 
  /**
   * @see org.newdawn.slick.opengl.ImageData#getDepth()
   */
  public int getDepth() {
    return pixelDepth;
  }
 
  /**
   * @see org.newdawn.slick.opengl.ImageData#getWidth()
   */
  public int getWidth() {
    return width;
  }

  /**
   * @see org.newdawn.slick.opengl.ImageData#getHeight()
   */
  public int getHeight() {
    return height;
  }

  /**
   * @see org.newdawn.slick.opengl.ImageData#getTexWidth()
   */
  public int getTexWidth() {
    return texWidth;
  }

  /**
   * @see org.newdawn.slick.opengl.ImageData#getTexHeight()
   */
  public int getTexHeight() {
    return texHeight;
  }
 
  public ByteBuffer loadImage(InputStream fis) throws IOException {
    return loadImage(fis, false, null);
  }
 
  public ByteBuffer loadImage(InputStream fis, boolean flipped, int[] transparent) throws IOException {
    return loadImage(fis, flipped, true, transparent);
  }
 
  public ByteBuffer loadImage(InputStream fis, boolean flipped, boolean forceAlpha, int[] transparent) throws IOException {
    return loadImageInternal(fis, flipped, forceAlpha, transparent, true, false);
  }

  public ByteBuffer loadMouseCursorImage(InputStream fis) throws IOException {
    return loadImageInternal(fis, true, false, null, false, true);
  }

  private ByteBuffer loadImageInternal(InputStream fis, boolean flipped, boolean forceAlpha, int[] transparent, boolean forceNonePowerOfTwo, boolean modeARGB) throws IOException {
    if (transparent != null) {
      forceAlpha = true;
    }
    byte red = 0;
    byte green = 0;
    byte blue = 0;
    byte alpha = 0;
   
    BufferedInputStream bis = new BufferedInputStream(fis, 100000);
    DataInputStream dis = new DataInputStream(bis);
   
    // Read in the Header
    short idLength = (short) dis.read();
    short colorMapType = (short) dis.read();
    short imageType = (short) dis.read();
    short cMapStart = flipEndian(dis.readShort());
    short cMapLength = flipEndian(dis.readShort());
    short cMapDepth = (short) dis.read();
    short xOffset = flipEndian(dis.readShort());
    short yOffset = flipEndian(dis.readShort());
   
    width = flipEndian(dis.readShort());
    height = flipEndian(dis.readShort());
    pixelDepth = (short) dis.read();
    if (pixelDepth == 32) {
      forceAlpha = false;
    }

    texWidth = width;
    texHeight = height;
    if (forceNonePowerOfTwo) {
      texWidth = get2Fold(width);
      texHeight = get2Fold(height);
    }
   
    short imageDescriptor = (short) dis.read();
    if ((imageDescriptor & 0x0020) == 0) {
       flipped = !flipped;
    }
   
    // Skip image ID
    if (idLength > 0) {
      bis.skip(idLength);
    }
   
    byte[] rawData = null;
    if ((pixelDepth == 32) || (forceAlpha)) {
      pixelDepth = 32;
      rawData = new byte[texWidth * texHeight * 4];
    } else if (pixelDepth == 24) {
      rawData = new byte[texWidth * texHeight * 3];
    } else {
      throw new RuntimeException("Only 24 and 32 bit TGAs are supported");
    }
   
    if (pixelDepth == 24) {
      if (flipped) {
        for (int i = height-1; i >= 0; i--) {
          for (int j = 0; j < width; j++) {
            blue = dis.readByte();
            green = dis.readByte();
            red = dis.readByte();
           
            int ofs = ((j + (i * texWidth)) * 3);
            rawData[ofs] = red;
            rawData[ofs + 1] = green;
            rawData[ofs + 2] = blue;
          }
        }
      } else {
        for (int i = 0; i < height; i++) {
          for (int j = 0; j < width; j++) {
            blue = dis.readByte();
            green = dis.readByte();
            red = dis.readByte();
           
            int ofs = ((j + (i * texWidth)) * 3);
            rawData[ofs] = red;
            rawData[ofs + 1] = green;
            rawData[ofs + 2] = blue;
          }
        }
      }
    } else if (pixelDepth == 32) {
      if (flipped) {
        for (int i = height-1; i >= 0; i--) {
          for (int j = 0; j < width; j++) {
            blue = dis.readByte();
            green = dis.readByte();
            red = dis.readByte();
            if (forceAlpha) {
              alpha = (byte) 255;
            } else {
              alpha = dis.readByte();
            }
           
            int ofs = ((j + (i * texWidth)) * 4);
           
            rawData[ofs] = red;
            rawData[ofs + 1] = green;
            rawData[ofs + 2] = blue;
            rawData[ofs + 3] = alpha;
           
            if (alpha == 0) {
              rawData[ofs + 2] = (byte) 0;
              rawData[ofs + 1] = (byte) 0;
              rawData[ofs] = (byte) 0;
            }
          }
        }
      } else {
        for (int i = 0; i < height; i++) {
          for (int j = 0; j < width; j++) {
            blue = dis.readByte();
            green = dis.readByte();
            red = dis.readByte();
            if (forceAlpha) {
              alpha = (byte) 255;
            } else {
              alpha = dis.readByte();
            }
           
            int ofs = ((j + (i * texWidth)) * 4);
           
            if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
              rawData[ofs] = red;
              rawData[ofs + 1] = green;
              rawData[ofs + 2] = blue;
              rawData[ofs + 3] = alpha;
            } else {
              rawData[ofs] = red;
              rawData[ofs + 1] = green;
              rawData[ofs + 2] = blue;
              rawData[ofs + 3] = alpha;
            }
           
            if (alpha == 0) {
              rawData[ofs + 2] = 0;
              rawData[ofs + 1] = 0;
              rawData[ofs] = 0;
            }
          }
        }
      }
    }
    fis.close();
   
    if (transparent != null) {
          for (int i=0;i<rawData.length;i+=4) {
            boolean match = true;
            for (int c=0;c<3;c++) {
              if (rawData[i+c] != transparent[c]) {
                match = false;
              }
            }
   
            if (match) {
              rawData[i+3] = 0;
               }
          }
        }
   
    // Get a pointer to the image memory
    ByteBuffer scratch = BufferUtils.createByteBuffer(rawData.length);
    scratch.put(rawData);
   
    int perPixel = pixelDepth / 8;
    if (height < texHeight-1) {
      int topOffset = (texHeight-1) * (texWidth*perPixel);
      int bottomOffset = (height-1) * (texWidth*perPixel);
      for (int x=0;x<texWidth*perPixel;x++) {
        scratch.put(topOffset+x, scratch.get(x));
        scratch.put(bottomOffset+(texWidth*perPixel)+x, scratch.get((texWidth*perPixel)+x));
      }
    }
    if (width < texWidth-1) {
      for (int y=0;y<texHeight;y++) {
        for (int i=0;i<perPixel;i++) {
          scratch.put(((y+1)*(texWidth*perPixel))-perPixel+i, scratch.get(y*(texWidth*perPixel)+i));
          scratch.put((y*(texWidth*perPixel))+(width*perPixel)+i, scratch.get((y*(texWidth*perPixel))+((width-1)*perPixel)+i));
        }
      }
    }

    scratch.flip();

    return scratch;
  }

    /**
     * Get the closest greater power of 2 to the fold number
     *
     * @param fold The target number
     * @return The power of 2
     */
    private int get2Fold(int fold) {
        int ret = 2;
        while (ret < fold) {
            ret *= 2;
        }
        return ret;
    }

  /**
   * @see org.newdawn.slick.opengl.ImageData#getImageBufferData()
   */
  public ByteBuffer getImageBufferData() {
    throw new RuntimeException("TGAImageData doesn't store it's image.");
  }
 
  /**
   * @see org.newdawn.slick.opengl.LoadableImageData#configureEdging(boolean)
   */
  public void configureEdging(boolean edging) {
  }
}
TOP

Related Classes of de.lessvoid.nifty.renderer.lwjgl.render.io.TGAImageData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.