Commits

Michael Ludwig committed 16771d7

Create new com.ferox.util package and move texture loading and converting there. Reorganize other packages too.

  • Participants
  • Parent commits ff3fcfc

Comments (0)

Files changed (51)

File src/com/ferox/resource/texture/converter/PackedInt8888Converter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.math.Color;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.TextureFormat;
-import com.ferox.resource.texture.converter.TextureConverter.DataBlock;
-import com.ferox.resource.texture.converter.TextureConverter.Decoder;
-import com.ferox.resource.texture.converter.TextureConverter.Encoder;
-
-/** Provides an implementation of Decoder and Encoder for
- * the packed formats RGBA_8888, BGRA_8888, ARGB_8888, and ABGR_8888;
- * assuming that the type is UNSIGNED_INT.
- * 
- * @author Michael Ludwig
- *
- */
-public class PackedInt8888Converter implements Decoder, Encoder {
-	private static final long C1_MASK = 0xff000000;
-	private static final int C2_MASK = 0x00ff0000;
-	private static final int C3_MASK = 0x0000ff00;
-	private static final int C4_MASK = 0x000000ff;
-	
-	private static final float MAX_VALUE = 255;
-	
-	@Override
-	public boolean canDecode(DataType type, TextureFormat format) {
-		return this.canEncode(type, format);
-	}
-
-	@Override
-	public boolean canEncode(DataType type, TextureFormat format) {
-		return type == DataType.UNSIGNED_INT && (format == TextureFormat.ABGR_8888 || 
-											     format == TextureFormat.BGRA_8888 || 
-											     format == TextureFormat.ARGB_8888 ||
-											     format == TextureFormat.RGBA_8888);
-	}
-	
-	@Override
-	public void getColor(DataBlock data, float u, float v, float w, Color store) {
-		int x = (int) u * data.getWidth();
-		int y = (int) v * data.getHeight();
-		int z = (int) w * data.getDepth();
-		
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		int val = ((int[]) data.getData().getData())[index];
-		
-		switch(data.getFormat()) {
-		case ABGR_4444:
-			store.set(((val & C4_MASK) >> 0) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 16) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 24) / MAX_VALUE);
-			break;
-		case ARGB_4444:
-			store.set(((val & C2_MASK) >> 16) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C4_MASK) >> 0) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 24) / MAX_VALUE);
-			break;	
-		case BGRA_4444:
-			store.set(((val & C3_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 16) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 24) / MAX_VALUE, 
-					  ((val & C4_MASK) >> 0) / MAX_VALUE);
-			break;
-		case RGBA_4444:
-			store.set(((val & C1_MASK) >> 24) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 16) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C4_MASK) >> 0) / MAX_VALUE);
-			break;
-		}
-	}
-
-	@Override
-	public void setColor(DataBlock data, int x, int y, int z, Color color) {
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		
-		int red = (int) (color.getRed() * MAX_VALUE);
-		int green = (int) (color.getGreen() * MAX_VALUE);
-		int blue = (int) (color.getBlue() * MAX_VALUE);
-		int alpha = (int) (color.getAlpha() * MAX_VALUE);
-		
-		int val = 0;
-		
-		// pack the color into a int
-		switch(data.getFormat()) {
-		case ABGR_4444:
-			val = (int) (((red   << 0)  & C4_MASK) | 
-						   ((green << 8)  & C3_MASK) | 
-				           ((blue  << 16) & C2_MASK) | 
-				           ((alpha << 24) & C1_MASK));
-			break;
-		case ARGB_4444:
-			val = (int) (((red   << 16) & C2_MASK) | 
-					   	   ((green << 8)  & C3_MASK) | 
-					   	   ((blue  << 0)  & C4_MASK) | 
-					   	   ((alpha << 24) & C1_MASK));
-			break;
-		case BGRA_4444:
-			val = (int) (((red   << 8)  & C3_MASK) | 
-					       ((green << 16) & C2_MASK) | 
-					       ((blue  << 24) & C1_MASK) | 
-					       ((alpha << 0)  & C4_MASK));
-			break;
-		case RGBA_4444:
-			val = (int) (((red   << 24) & C1_MASK) | 
-				           ((green << 16) & C2_MASK) | 
-				           ((blue  << 8)  & C3_MASK) | 
-				           ((alpha << 0)  & C4_MASK));
-			break;
-		}
-		
-		// write the packed color back into the array
-		((int[]) data.getData().getData())[index] = val;
-	}
-}

File src/com/ferox/resource/texture/converter/PackedShort4444Converter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.math.Color;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.TextureFormat;
-import com.ferox.resource.texture.converter.TextureConverter.DataBlock;
-import com.ferox.resource.texture.converter.TextureConverter.Decoder;
-import com.ferox.resource.texture.converter.TextureConverter.Encoder;
-
-/** Provides an implementation of Decoder and Encoder for
- * the packed formats RGBA_4444, BGRA_4444, ARGB_4444, and ABGR_4444;
- * assuming that the type is UNSIGNED_SHORT.
- * 
- * @author Michael Ludwig
- *
- */
-public class PackedShort4444Converter implements Decoder, Encoder {
-	private static final int C1_MASK = 0xf000;
-	private static final int C2_MASK = 0x0f00;
-	private static final int C3_MASK = 0x00f0;
-	private static final int C4_MASK = 0x000f;
-	
-	private static final float MAX_VALUE = 15;
-	
-	@Override
-	public boolean canDecode(DataType type, TextureFormat format) {
-		return this.canEncode(type, format);
-	}
-
-	@Override
-	public boolean canEncode(DataType type, TextureFormat format) {
-		return type == DataType.UNSIGNED_SHORT && (format == TextureFormat.ABGR_4444 || 
-												   format == TextureFormat.BGRA_4444 || 
-												   format == TextureFormat.ARGB_4444 ||
-												   format == TextureFormat.RGBA_4444);
-	}
-	
-	@Override
-	public void getColor(DataBlock data, float u, float v, float w, Color store) {
-		int x = (int) u * data.getWidth();
-		int y = (int) v * data.getHeight();
-		int z = (int) w * data.getDepth();
-		
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		short val = ((short[]) data.getData().getData())[index];
-		
-		switch(data.getFormat()) {
-		case ABGR_4444:
-			store.set(((val & C4_MASK) >> 0) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 4) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 12) / MAX_VALUE);
-			break;
-		case ARGB_4444:
-			store.set(((val & C2_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 4) / MAX_VALUE, 
-					  ((val & C4_MASK) >> 0) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 12) / MAX_VALUE);
-			break;	
-		case BGRA_4444:
-			store.set(((val & C3_MASK) >> 4) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 12) / MAX_VALUE, 
-					  ((val & C4_MASK) >> 0) / MAX_VALUE);
-			break;
-		case RGBA_4444:
-			store.set(((val & C1_MASK) >> 12) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 8) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 4) / MAX_VALUE, 
-					  ((val & C4_MASK) >> 0) / MAX_VALUE);
-			break;
-		}
-	}
-
-	@Override
-	public void setColor(DataBlock data, int x, int y, int z, Color color) {
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		
-		int red = (int) (color.getRed() * MAX_VALUE);
-		int green = (int) (color.getGreen() * MAX_VALUE);
-		int blue = (int) (color.getBlue() * MAX_VALUE);
-		int alpha = (int) (color.getAlpha() * MAX_VALUE);
-		
-		short val = 0;
-		
-		// pack the color into a short
-		switch(data.getFormat()) {
-		case ABGR_4444:
-			val = (short) (((red   << 0)  & C4_MASK) | 
-						   ((green << 4)  & C3_MASK) | 
-				           ((blue  << 8)  & C2_MASK) | 
-				           ((alpha << 12) & C1_MASK));
-			break;
-		case ARGB_4444:
-			val = (short) (((red   << 8)  & C2_MASK) | 
-					   	   ((green << 4)  & C3_MASK) | 
-					   	   ((blue  << 0)  & C4_MASK) | 
-					   	   ((alpha << 12) & C1_MASK));
-			break;
-		case BGRA_4444:
-			val = (short) (((red   << 4)  & C3_MASK) | 
-					       ((green << 8)  & C2_MASK) | 
-					       ((blue  << 12) & C1_MASK) | 
-					       ((alpha << 0)  & C4_MASK));
-			break;
-		case RGBA_4444:
-			val = (short) (((red   << 12) & C1_MASK) | 
-				           ((green << 8)  & C2_MASK) | 
-				           ((blue  << 4)  & C3_MASK) | 
-				           ((alpha << 0)  & C4_MASK));
-			break;
-		}
-		
-		// write the packed color back into the array
-		((short[]) data.getData().getData())[index] = val;
-	}
-}

File src/com/ferox/resource/texture/converter/PackedShort5551Converter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.math.Color;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.TextureFormat;
-import com.ferox.resource.texture.converter.TextureConverter.DataBlock;
-import com.ferox.resource.texture.converter.TextureConverter.Decoder;
-import com.ferox.resource.texture.converter.TextureConverter.Encoder;
-
-/** Provides an implementation of Decoder and Encoder for
- * the packed formats RGBA_5551, BGRA_5551, ARGB_1555, and ABGR_1555;
- * assuming that the type is UNSIGNED_SHORT.
- * 
- * @author Michael Ludwig
- *
- */
-public class PackedShort5551Converter implements Decoder, Encoder {
-	// used for RGBA and BGRA
-	private static final int C1_MASK = 0xf800;
-	private static final int C2_MASK = 0x07c0;
-	private static final int C3_MASK = 0x003e;
-	private static final int C4_MASK = 0x0001;
-	
-	// used for ARGB and ABGR
-	private static final int C1_REV_MASK = 0x8000;
-	private static final int C2_REV_MASK = 0x7c00;
-	private static final int C3_REV_MASK = 0x03e0;
-	private static final int C4_REV_MASK = 0x001f;
-	
-	private static final float MAX_VALUE = 31;
-	
-	@Override
-	public boolean canDecode(DataType type, TextureFormat format) {
-		return this.canEncode(type, format);
-	}
-
-	@Override
-	public boolean canEncode(DataType type, TextureFormat format) {
-		return type == DataType.UNSIGNED_SHORT && (format == TextureFormat.ABGR_1555 || 
-												   format == TextureFormat.BGRA_5551 || 
-												   format == TextureFormat.ARGB_1555 ||
-												   format == TextureFormat.RGBA_5551);
-	}
-	
-	@Override
-	public void getColor(DataBlock data, float u, float v, float w, Color store) {
-		int x = (int) u * data.getWidth();
-		int y = (int) v * data.getHeight();
-		int z = (int) w * data.getDepth();
-		
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		short val = ((short[]) data.getData().getData())[index];
-		
-		switch(data.getFormat()) {
-		case ABGR_1555:
-			store.set(((val & C4_REV_MASK) >> 0) / MAX_VALUE, 
-					  ((val & C3_REV_MASK) >> 5) / MAX_VALUE, 
-					  ((val & C2_REV_MASK) >> 10) / MAX_VALUE, 
-					   (val & C1_REV_MASK) != 0 ? 1f : 0f);
-			break;
-		case ARGB_1555:
-			store.set(((val & C2_REV_MASK) >> 10) / MAX_VALUE, 
-					  ((val & C3_REV_MASK) >> 5) / MAX_VALUE, 
-					  ((val & C4_REV_MASK) >> 0) / MAX_VALUE, 
-					   (val & C1_REV_MASK) != 0 ? 1f : 0f);
-			break;	
-		case BGRA_5551:
-			store.set(((val & C3_MASK) >> 1) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 6) / MAX_VALUE, 
-					  ((val & C1_MASK) >> 11) / MAX_VALUE, 
-					   (val & C4_MASK) != 0 ? 1f : 0f);
-			break;
-		case RGBA_5551:
-			store.set(((val & C1_MASK) >> 11) / MAX_VALUE, 
-					  ((val & C2_MASK) >> 6) / MAX_VALUE, 
-					  ((val & C3_MASK) >> 1) / MAX_VALUE, 
-					   (val & C4_MASK) != 0 ? 1f : 0f);
-			break;
-		}
-	}
-
-	@Override
-	public void setColor(DataBlock data, int x, int y, int z, Color color) {
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		
-		int red = (int) (color.getRed() * MAX_VALUE);
-		int green = (int) (color.getGreen() * MAX_VALUE);
-		int blue = (int) (color.getBlue() * MAX_VALUE);
-		int alpha = color.getAlpha() > 0f ? 1 : 0;
-		
-		short val = 0;
-		
-		// pack the color into a short
-		switch(data.getFormat()) {
-		case ABGR_1555:
-			val = (short) (((red   << 0)  & C4_REV_MASK) | 
-						   ((green << 5)  & C3_REV_MASK) | 
-				           ((blue  << 10) & C2_REV_MASK) | 
-				           ((alpha << 15) & C1_REV_MASK));
-			break;
-		case ARGB_1555:
-			val = (short) (((red   << 10) & C2_REV_MASK) | 
-					   	   ((green << 5)  & C3_REV_MASK) | 
-					   	   ((blue  << 0)  & C4_REV_MASK) | 
-					   	   ((alpha << 15) & C1_REV_MASK));
-			break;
-		case BGRA_5551:
-			val = (short) (((red   << 1)  & C3_MASK) | 
-					       ((green << 6)  & C2_MASK) | 
-					       ((blue  << 11) & C1_MASK) | 
-					       ((alpha << 0)  & C4_MASK));
-			break;
-		case RGBA_5551:
-			val = (short) (((red   << 11) & C1_MASK) | 
-				           ((green << 6)  & C2_MASK) | 
-				           ((blue  << 1)  & C3_MASK) | 
-				           ((alpha << 0)  & C4_MASK));
-			break;
-		}
-		
-		// write the packed color back into the array
-		((short[]) data.getData().getData())[index] = val;
-	}
-}

File src/com/ferox/resource/texture/converter/PackedShort565Converter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.math.Color;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.TextureFormat;
-import com.ferox.resource.texture.converter.TextureConverter.DataBlock;
-import com.ferox.resource.texture.converter.TextureConverter.Decoder;
-import com.ferox.resource.texture.converter.TextureConverter.Encoder;
-
-public class PackedShort565Converter implements Decoder, Encoder {
-	private static final int C1_MASK = 0xF800;
-	private static final int C2_MASK = 0x07E0;
-	private static final int C3_MASK = 0x001F;
-	
-	private static final float MAX_RB = 31;
-	private static final float MAX_G = 63;
-	
-	@Override
-	public boolean canDecode(DataType type, TextureFormat format) {
-		return this.canEncode(type, format);
-	}
-	
-	@Override
-	public boolean canEncode(DataType type, TextureFormat format) {
-		return type == DataType.UNSIGNED_SHORT && (format == TextureFormat.BGR_565 || format == TextureFormat.RGB_565);
-	}
-	
-	@Override
-	public void getColor(DataBlock data, float u, float v, float w, Color store) {
-		int x = (int) u * data.getWidth();
-		int y = (int) v * data.getHeight();
-		int z = (int) w * data.getDepth();
-		
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		short val = ((short[]) data.getData().getData())[index];
-		
-		switch(data.getFormat()) {
-		case BGR_565:
-			store.set(((val & C3_MASK) >> 0) / MAX_RB, 
-					  ((val & C2_MASK) >> 5) / MAX_G, 
-					  ((val & C1_MASK) >> 11) / MAX_RB, 
-					   1f);
-			break;
-		case RGB_565:
-			store.set(((val & C1_MASK) >> 11) / MAX_RB, 
-					  ((val & C2_MASK) >> 5) / MAX_G, 
-					  ((val & C3_MASK) >> 0) / MAX_RB, 
-					   1f);
-			break;	
-		}
-	}
-	
-	@Override
-	public void setColor(DataBlock data, int x, int y, int z, Color color) {
-		int index = x + y * data.getWidth() + z * data.getWidth() * data.getHeight();
-		
-		float alpha = color.getAlpha();
-		
-		int red = (int) (color.getRed() * alpha * MAX_RB);
-		int green = (int) (color.getGreen() * alpha * MAX_G);
-		int blue = (int) (color.getBlue() * alpha * MAX_RB);
-		
-		short val = 0;
-		
-		// pack the color into a short
-		switch(data.getFormat()) {
-		case BGR_565:
-			val = (short) (((red   << 0)  & C3_MASK) | 
-						   ((green << 5)  & C2_MASK) | 
-				           ((blue  << 11) & C1_MASK));
-			break;
-		case RGB_565:
-			val = (short) (((red   << 11) & C1_MASK) | 
-					       ((green << 5)  & C2_MASK) | 
-			               ((blue  << 0)  & C3_MASK));
-			break;
-		}
-		
-		// write the packed color back into the array
-		((short[]) data.getData().getData())[index] = val;
-	}
-}

File src/com/ferox/resource/texture/converter/TextureConverter.java

-package com.ferox.resource.texture.converter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.ferox.math.Color;
-import com.ferox.resource.BufferData;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.TextureFormat;
-
-/** TextureConverter provides utilities to register decoders and
- * encoders of texture data, as well as provide a utility methods
- * that will convert formats and scale dimensions.
- * 
- * There are default encoders and decoders supported all TextureFormats (with
- * valid types) except for the DXT_x formats, that have already been 
- * registered.
- * 
- * This utility is not intended to be an efficient imaging processor,
- * but is instead meant to be flexible, allowing for many formats to
- * be converted and scaled.
- * 
- * @author Michael Ludwig
- *
- */
-public class TextureConverter {
-	/** A DataBlock is a TextureImage agnostic way of handling
-	 * a single layer in an image.  It has three dimensions, but height
-	 * and depth may be 1. */
-	public static class DataBlock {
-		private int width, height, depth;
-		private BufferData data;
-		private TextureFormat format;
-		
-		protected DataBlock(BufferData data, int width, int height, int depth, TextureFormat format) {
-			this.data = data;
-			this.width = width;
-			this.height = height;
-			this.depth = depth;
-		}
-
-		/** Get the width, in texels of the data block. 
-		 * It will be >= 1. */
-		public int getWidth() {
-			return this.width;
-		}
-
-		/** Get the height, in texels of the data block.
-		 * It will be >= 1. */
-		public int getHeight() {
-			return this.height;
-		}
-
-		/** Get the depth, in texels of the data block. 
-		 * It will be >= 1. */
-		public int getDepth() {
-			return this.depth;
-		}
-
-		/** Get the BufferData that is the texture data for this
-		 * DataBlock. This will not be null, and its array won't be either. */
-		public BufferData getData() {
-			return this.data;
-		}
-
-		/** Get the TextureFormat for this data block.  It will
-		 * be compatible with the type of the BufferData. */
-		public TextureFormat getFormat() {
-			return this.format;
-		}
-	}
-	
-	/** An Encoder provides functionality to set the color at
-	 * specific texel locations for a DataBlock of certain types
-	 * and formats. */
-	public static interface Encoder {
-		/** Set the given color on the data block at the texel <x,y,z>.
-		 * It can be assumed that x, y, and z are within the dimensions
-		 * of the data block.  The data block and color will not be null.
-		 * 
-		 * If the Encoder doesn't support an alpha channel, the stored
-		 * color components should be pre-multiplied by the alpha of color.
-		 * If the Encoder represents a non-standard format, it must
-		 * provide a reasonable implementation of extracting those values 
-		 * from the RGBA color. */
-		public void setColor(DataBlock data, int x, int y, int z, Color color);
-		
-		/** Determine if this encoder can convert the given type and format.
-		 * It can be assumed that the combination will be valid and not null. */
-		public boolean canEncode(DataType type, TextureFormat format);
-	}
-	
-	/** An Decoder provides functionality to get the color at
-	 * specific texel locations for a DataBlock of certain types
-	 * and formats. */
-	public static interface Decoder {
-		/** Get the given color on the data block at the point <u,v,w>.
-		 * It can be assumed that u, v, and w are in [0, 1], representing
-		 * normalized texture coordinates across the valid dimensions.
-		 * The data block and store will not be null. store must hold the color result.
-		 * 
-		 * If the Decoder's format doesn't support an alpha channel, the stored
-		 * alpha value should be set 1.  The decoder can decide how to compute the
-		 * final color, either using some form of filtering or just nearest-neighbor.
-		 * 
-		 * If the Decoder represents a non-standard format, it must
-		 * provide a reasonable implementation for determining rgba colors.
-		 * For example, luminance and depth may store that value in the RGB
-		 * components. */
-		public void getColor(DataBlock data, float u, float v, float w, Color store);
-		
-		/** Determine if this decoder can convert the given type and format.
-		 * It can be assumed that the combination will be valid and not null. */
-		public boolean canDecode(DataType type, TextureFormat format);
-	}
-	
-	private static List<Encoder> encoders = new ArrayList<Encoder>();
-	private static List<Decoder> decoders = new ArrayList<Decoder>();
-	
-	/** This method will re-scale and change the data type and format of a single
-	 * mipmap layer of a texture image.  This image can be 2d or 3d (if it's 2d, the depth
-	 * should be 1).
-	 * 
-	 * If the result BufferData is null, doesn't match newType, or doesn't have the correct size,
-	 * a new BufferData is used.  Otherwise, its data array is used to store the converted image
-	 * (which may have to be allocated if it is null), and result will be returned.
-	 * 
-	 * If the backing array behind result is null, then a new one is created.  If a data's backing
-	 * array is null, an empty BufferData is created with an array sized appropriately for the
-	 * requested type, format and dimensions.
-	 * 
-	 * Returns the BufferData holding the converted image.
-	 * 
-	 * Throws an exception if data, oldFormat, oldWidth, oldHeight and oldDepth are incompatible:
-	 * 	- dimensions are negative or don't match the size of the buffer data's capacity
-	 *  - the format doesn't match the buffer data's type
-	 *  - the buffer data or format are null.
-	 *  
-	 * Throws an exception if the new format, new type and new dimensions are incompatible:
-	 * 	- as above, except format and newType must match (if result's type doesn't match, a 
-	 * 	  new buffer data is used instead).
-	 *  - newType cannot be null, either. 
-	 *  
-	 * Throws an exception if there's no registered decoder for the combination of oldFormat
-	 * and data's type.  Also fails if there's no encoder for the newFormat and newType. */
-	public static BufferData convert(BufferData data, TextureFormat oldFormat, int oldWidth, int oldHeight, int oldDepth, 
-									 BufferData result, TextureFormat newFormat, DataType newType, 
-									 int newWidth, int newHeight, int newDepth) throws NullPointerException, IllegalArgumentException {
-		// validate input parameters that involve the source data
-		if (data == null || oldFormat == null)
-			throw new NullPointerException("data and oldFormat cannot be null: " + data + " " + oldFormat);
-		if (!oldFormat.isTypeValid(data.getType()))
-			throw new IllegalArgumentException("data's type must be supported for the given oldFormat: " + data.getType() + " " + oldFormat);
-		if (oldFormat.getBufferSize(oldWidth, oldHeight, oldDepth) != data.getCapacity())
-			throw new IllegalArgumentException("data's capacity doesn't match expected size, based on old dimensions");
-		
-		// validate input parameters for the dst data
-		if (newFormat == null || newType == null)
-			throw new NullPointerException("newFormat and newType cannot be null: " + newFormat + " " + newType);
-		if (!newFormat.isTypeValid(newType))
-			throw new IllegalArgumentException("newType is not supported by newFormat: " + newType + " " + newFormat);
-		
-		int newCapacity = newFormat.getBufferSize(newWidth, newHeight, newDepth);
-		if (newCapacity < 0)
-			throw new IllegalArgumentException("new dimensions are invalid for newFormat: " + newWidth + "x" + newHeight + "x" + newDepth + " " + newFormat);
-		
-		// make a new BufferData if needed
-		if (result == null || result.getCapacity() != newCapacity || result.getType() != newType) {
-			result = new BufferData(newCapacity, newType);
-		}
-		// make sure its data array is not null
-		if (result.getData() == null) {
-			Object array = newArray(newCapacity, newType);
-			result.setData(array);
-		}
-		
-		if (data.getData() != null) {
-			// actually convert the old image data
-			Decoder decoder = getDecoder(data.getType(), oldFormat);
-			if (decoder == null)
-				throw new IllegalArgumentException("There is no registered Decoder supporting " + data.getType() + " and " + oldFormat);
-			DataBlock src = new DataBlock(data, oldWidth, oldHeight, oldDepth, oldFormat);
-			
-			Encoder encoder = getEncoder(newType, newFormat);
-			if (encoder == null)
-				throw new IllegalArgumentException("There is no registered Encoder supporting " + newType + " and " + newFormat);
-			DataBlock dst = new DataBlock(result, newWidth, newHeight, newDepth, newFormat);
-			
-			float uScale = 1f / newWidth;
-			float vScale = 1f / newHeight;
-			float wScale = 1f / newDepth;
-			
-			Color store = new Color();
-			int x, y, z;
-			float u, v, w;
-			for (z = 0; z < newDepth; z++) {
-				w = z * wScale;
-				for (y = 0; y < newHeight; y++) {
-					v = y * vScale;
-					for (x = 0; x < newWidth; x++) {
-						u = x * uScale;
-						
-						// read the color, based on normalized coords
-						decoder.getColor(src, u, v, w, store);
-						// store the color, based on actual pixel coords
-						encoder.setColor(dst, x, y, z, store);
-					}
-				}
-			}
-			
-			// we've finished converting the image layer
-		}
-		
-		return result;
-	}
-	
-	/** Register the given encoder, so that it can be used in subsequent 
-	 * convert() calls.  If multiple registered encoders return true
-	 * from canEncode(), the newest added encoder is used.
-	 * 
-	 * Does nothing if e is null.  If e has already been registered,
-	 * then e becomes the "newest" with regards to resolving conflicts. */
-	public static void registerEncoder(Encoder e) {
-		synchronized(encoders) {
-			if (e != null) {
-				int index = encoders.indexOf(e);
-				if (index >= 0)
-					encoders.remove(index);
-				encoders.add(e);
-			}
-		}
-	}
-	
-	/** Remove the given encoder.  Does nothing if it's
-	 * null or was never registered.  After a call to this method,
-	 * that encoder instance will not be used in calls to convert(). */
-	public static void unregisterEncoder(Encoder e) {
-		synchronized(encoders) {
-			if (e != null)
-				encoders.remove(e);
-		}
-	}
-	
-	/** Register the given decoder, so that it can be used in subsequent 
-	 * convert() calls.  If multiple registered decoders return true
-	 * from canDecode(), the newest added decoder is used.
-	 * 
-	 * Does nothing if d is null.  If d has already been registered,
-	 * then d becomes the "newest" with regards to resolving conflicts. */
-	public static void registerDecoder(Decoder d) {
-		synchronized(decoders) {
-			if (d != null) {
-				int index = decoders.indexOf(d);
-				if (index >= 0)
-					decoders.remove(index);
-				decoders.add(d);
-			}
-		}
-	}
-	
-	/** Remove the given decoder.  Does nothing if it's
-	 * null or was never registered.  After a call to this method,
-	 * that decoder instance will not be used in calls to convert(). */
-	public static void unregisterDecoder(Decoder d) {
-		synchronized(decoders) {
-			if (d != null)
-				decoders.remove(d);
-		}
-	}
-	
-	/* Return an Encoder that's been registered that can encode the
-	 * given type and format.  Returns the newest Encoder that returns
-	 * true in its canEncode() method. */
-	private static Encoder getEncoder(DataType type, TextureFormat format) {
-		Encoder e = null;
-		synchronized(encoders) {
-			for (int i = encoders.size() - 1; i >= 0; i--) {
-				if (encoders.get(i).canEncode(type, format)) {
-					e = encoders.get(i);
-					break;
-				}
-			}
-		}
-		
-		return e;
-	}
-	
-	/* Return a Decoder that's been registered that can decode the
-	 * given type and format.  Returns the newest Decoder that returns
-	 * true in its canDecode() method. */
-	private static Decoder getDecoder(DataType type, TextureFormat format) {
-		Decoder d = null;
-		synchronized(decoders) {
-			for (int i = decoders.size() - 1; i >= 0; i--) {
-				if (decoders.get(i).canDecode(type, format)) {
-					d = decoders.get(i);
-					break;
-				}
-			}
-		}
-		
-		return d;
-	}
-	
-	/* Create a new array with the given length and type. */
-	private static Object newArray(int newCapacity, DataType newType) {
-		Object array = null;
-		switch(newType) {
-		case BYTE: case UNSIGNED_BYTE:
-			array = new byte[newCapacity];
-			break;
-		case INT: case UNSIGNED_INT:
-			array = new int[newCapacity];
-			break;
-		case SHORT: case UNSIGNED_SHORT:
-			array = new short[newCapacity];
-			break;
-		case FLOAT:
-			array = new float[newCapacity];
-			break;
-		}
-		
-		return array;
-	}
-	
-	static {
-		// unpacked types
-		registerEncoder(new UnpackedFloatConverter());
-		registerDecoder(new UnpackedFloatConverter());
-		registerEncoder(new UnpackedIntConverter());
-		registerDecoder(new UnpackedIntConverter());
-		registerEncoder(new UnpackedShortConverter());
-		registerDecoder(new UnpackedShortConverter());
-		registerEncoder(new UnpackedByteConverter());
-		registerDecoder(new UnpackedByteConverter());
-		
-		// packed types
-		registerEncoder(new PackedInt8888Converter());
-		registerDecoder(new PackedInt8888Converter());
-		registerEncoder(new PackedShort4444Converter());
-		registerDecoder(new PackedShort4444Converter());
-		registerEncoder(new PackedShort5551Converter());
-		registerDecoder(new PackedShort5551Converter());
-		registerEncoder(new PackedShort565Converter());
-		registerDecoder(new PackedShort565Converter());
-	}
-}

File src/com/ferox/resource/texture/converter/UnpackedByteConverter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.resource.BufferData.DataType;
-
-/** An encoder and decoder that works with all uncompressed
- * and unpacked texture formats that have a data type of 
- * UNSIGNED_BYTE.
- * 
- * @author Michael Ludwig
- *
- */
-public class UnpackedByteConverter extends UnpackedFormatConverter {
-	private static final int MASK = 0xff;
-	private static final float MAX_VALUE = (float) Byte.MAX_VALUE - (float) Byte.MIN_VALUE;
-	
-	public UnpackedByteConverter() {
-		super(DataType.UNSIGNED_BYTE);
-	}
-
-	@Override
-	protected float get(Object array, int index) {
-		byte signed = ((byte[]) array)[index];
-		return ((signed & MASK) / MAX_VALUE);
-	}
-
-	@Override
-	protected void set(Object array, int index, float value) {
-		((byte[]) array)[index] = (byte) (value * MAX_VALUE);
-	}
-}

File src/com/ferox/resource/texture/converter/UnpackedFloatConverter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.resource.BufferData.DataType;
-
-/** An encoder and decoder that works with all uncompressed
- * and unpacked texture formats (including _FLOAT) that
- * have a data type of FLOAT.
- * 
- * @author Michael Ludwig
- *
- */
-public class UnpackedFloatConverter extends UnpackedFormatConverter {
-	public UnpackedFloatConverter() {
-		super(DataType.FLOAT);
-	}
-
-	@Override
-	protected final float get(Object array, int index) {
-		return ((float[]) array)[index];
-	}
-
-	@Override
-	protected final void set(Object array, int index, float value) {
-		((float[]) array)[index] = value;
-	}
-	
-}

File src/com/ferox/resource/texture/converter/UnpackedFormatConverter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.math.Color;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.TextureFormat;
-import com.ferox.resource.texture.converter.TextureConverter.DataBlock;
-import com.ferox.resource.texture.converter.TextureConverter.Decoder;
-import com.ferox.resource.texture.converter.TextureConverter.Encoder;
-
-/** Implements the majority of the work necessary for a Decoder and
- * Encoder involving formats that don't pack their data or compress
- * it in any other way.
- * 
- * @author Michael Ludwig
- *
- */
-public abstract class UnpackedFormatConverter implements Decoder, Encoder {
-	private DataType validType;
-	
-	/** SupportedType is the single type that this decoder and
-	 * encoder knows how to read.  It determines the type of
-	 * array passed into get() and set(). */
-	protected UnpackedFormatConverter(DataType supportedType) {
-		this.validType = supportedType;
-	}
-	
-	@Override
-	public boolean canDecode(DataType type, TextureFormat format) {
-		return this.supported(type, format);
-	}
-
-	@Override
-	public void getColor(DataBlock data, float u, float v, float w, Color store) {
-		int x = (int) u * data.getWidth();
-		int y = (int) v * data.getHeight();
-		int z = (int) w * data.getDepth();
-		
-		int numC = data.getFormat().getPrimitivesPerColor();
-		// first index of the color 
-		int index = numC * (x + y * data.getWidth() + z * data.getHeight() * data.getWidth());
-		Object array = data.getData().getData();
-		
-		switch(data.getFormat()) {
-		case BGRA: 
-			store.set(this.get(array, index + 2), 
-					  this.get(array, index + 1),
-					  this.get(array, index + 0),
-					  this.get(array, index + 3));
-			break;
-		case BGR:
-			store.set(this.get(array, index + 2), 
-					  this.get(array, index + 1),
-					  this.get(array, index + 0),
-					  1f);
-			break;
-		case RGBA: case RGBA_FLOAT:
-			store.set(this.get(array, index + 0), 
-					  this.get(array, index + 1),
-					  this.get(array, index + 2),
-					  this.get(array, index + 3));
-			break;
-		case RGB: case RGB_FLOAT:
-			store.set(this.get(array, index + 0), 
-					  this.get(array, index + 1),
-					  this.get(array, index + 2),
-					  1f);
-			break;
-		case ALPHA: case ALPHA_FLOAT:
-			store.set(0f, 0f, 0f, this.get(array, index));
-			break;	
-		case LUMINANCE_ALPHA: case LUMINANCE_ALPHA_FLOAT: {
-			float l = this.get(array, index);
-			store.set(l, l, l, this.get(array, index + 1));
-			break; }
-		case DEPTH: case LUMINANCE: case LUMINANCE_FLOAT: {
-			float ld = this.get(array, index);
-			store.set(ld, ld, ld, 1);
-			break; }
-		}
-	}
-
-	@Override
-	public boolean canEncode(DataType type, TextureFormat format) {
-		return this.supported(type, format);
-	}
-
-	@Override
-	public void setColor(DataBlock data, int x, int y, int z, Color color) {
-		int numC = data.getFormat().getPrimitivesPerColor();
-		// first index of the color 
-		int index = numC * (x + y * data.getWidth() + z * data.getHeight() * data.getWidth());
-		Object array = data.getData().getData();
-		
-		switch(data.getFormat()) {
-		case BGRA: 
-			this.set(array, index + 2, color.getRed());
-			this.set(array, index + 1, color.getGreen());
-			this.set(array, index + 0, color.getBlue());
-			this.set(array, index + 3, color.getAlpha());
-			break;
-		case BGR: {
-			float a = color.getAlpha();
-			this.set(array, index + 2, color.getRed() * a);
-			this.set(array, index + 1, color.getGreen() * a);
-			this.set(array, index + 0, color.getBlue() * a);
-			break; }
-		case RGBA: case RGBA_FLOAT:
-			this.set(array, index + 0, color.getRed());
-			this.set(array, index + 1, color.getGreen());
-			this.set(array, index + 2, color.getBlue());
-			this.set(array, index + 3, color.getAlpha());
-			break;
-		case RGB: case RGB_FLOAT: {
-			float a = color.getAlpha();
-			this.set(array, index + 0, color.getRed() * a);
-			this.set(array, index + 1, color.getGreen() * a);
-			this.set(array, index + 2, color.getBlue() * a);
-			break; }
-		case ALPHA: case ALPHA_FLOAT:
-			this.set(array, index, color.getAlpha());
-			break;	
-		case LUMINANCE_ALPHA: case LUMINANCE_ALPHA_FLOAT: {
-			this.set(array, index, (color.getRed() + color.getGreen() + color.getBlue()) / 3f);
-			this.set(array, index + 1, color.getAlpha());
-			break; }
-		case DEPTH: case LUMINANCE: case LUMINANCE_FLOAT: {
-			this.set(array, index, (color.getRed() + color.getGreen() + color.getBlue()) / 3f);
-			break; }
-		}
-	}
-	
-	/** Set the given array value at index to the floating
-	 * point value. This will likely involve scaling and
-	 * casting the value.  This value will be between
-	 * 0 and 1. */
-	protected abstract void set(Object array, int index, float value);
-	
-	/** Return a floating point value that represents the
-	 * final color value, as if it were converted into a
-	 * texture in the graphics card. */
-	protected abstract float get(Object array, int index);
-	
-	private boolean supported(DataType type, TextureFormat format) {
-		return type == this.validType && !format.isCompressed() && !format.isPackedFormat();
-	}
-
-}

File src/com/ferox/resource/texture/converter/UnpackedIntConverter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.resource.BufferData.DataType;
-
-/** An encoder and decoder that works with all uncompressed
- * and unpacked texture formats that have a data type of 
- * UNSIGNED_INT.
- * 
- * @author Michael Ludwig
- *
- */
-public class UnpackedIntConverter extends UnpackedFormatConverter {
-	private static final long MASK = 0xffffffffL;
-	private static final double MAX_VALUE = (double) Integer.MAX_VALUE - (double) Integer.MIN_VALUE;
-	
-	public UnpackedIntConverter() {
-		super(DataType.UNSIGNED_INT);
-	}
-
-	@Override
-	protected float get(Object array, int index) {
-		int signed = ((int[]) array)[index];
-		return (float) ((signed & MASK) / MAX_VALUE);
-	}
-
-	@Override
-	protected void set(Object array, int index, float value) {
-		// double cast is necessary for large values
-		((int[]) array)[index] = (int) ((long) (value * MAX_VALUE));
-	}
-}

File src/com/ferox/resource/texture/converter/UnpackedShortConverter.java

-package com.ferox.resource.texture.converter;
-
-import com.ferox.resource.BufferData.DataType;
-
-/** An encoder and decoder that works with all uncompressed
- * and unpacked texture formats that have a data type of 
- * UNSIGNED_SHORT.
- * 
- * @author Michael Ludwig
- *
- */
-public class UnpackedShortConverter extends UnpackedFormatConverter {
-	private static final int MASK = 0xffff;
-	private static final float MAX_VALUE = (float) Short.MAX_VALUE - (float) Short.MIN_VALUE;
-	
-	public UnpackedShortConverter() {
-		super(DataType.UNSIGNED_SHORT);
-	}
-
-	@Override
-	protected float get(Object array, int index) {
-		int signed = ((short[]) array)[index];
-		return ((signed & MASK) / MAX_VALUE);
-	}
-
-	@Override
-	protected void set(Object array, int index, float value) {
-		((short[]) array)[index] = (short) (value * MAX_VALUE);
-	}
-}

File src/com/ferox/resource/texture/loader/DDSImageFileLoader.java

-package com.ferox.resource.texture.loader;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.ferox.resource.texture.TextureImage;
-
-/** An implementation of ImageFileLoader that
- * relies on DDSTexture to load .dds files.
- * 
- * @author Michael Ludwig
- *
- */
-public class DDSImageFileLoader implements ImageFileLoader {
-	@Override
-	public TextureImage readImage(InputStream stream) throws IOException {
-		if (DDSTexture.isDDSTexture(stream))
-			return DDSTexture.readTexture(stream);
-		else
-			return null;
-	}
-}

File src/com/ferox/resource/texture/loader/DDSTexture.java

-package com.ferox.resource.texture.loader;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.ferox.resource.BufferData;
-import com.ferox.resource.BufferData.DataType;
-import com.ferox.resource.texture.Texture2D;
-import com.ferox.resource.texture.Texture3D;
-import com.ferox.resource.texture.TextureCubeMap;
-import com.ferox.resource.texture.TextureFormat;
-import com.ferox.resource.texture.TextureImage;
-import com.ferox.resource.texture.TextureImage.TextureTarget;
-
-/**
- * DDSTexture is a utility class that can be used to read
- * in cube maps, 3d textures and 2d textures from an input stream.
- * 
- * It is recommended to use TextureIO for input however, since it
- * will delegate to DDSTexture when needed.
- * 
- * @author Michael Ludwig
- *
- */
-@SuppressWarnings("unused")
-public class DDSTexture {
-	// dds header read in from the input stream
-	private DDSHeader header;
-	
-	// representation of the dds texture
-	private DataType type;
-	private TextureFormat format;
-	private TextureTarget target;
-	
-	private int mipmapCount; // at least 1
-	private int width, height, depth; // depth may be unused for cube maps and 2d textures (in which case it's set to 1)
-	private BufferData[][] data; // accessed [face][mipmap]
-	
-	/** Read in and create a new TextureImage from the given stream.  This image will be
-	 * a Texture2D, Texture3D, or TextureCubeMap.  An IOException will be thrown if the
-	 * stream doesn't represent a valid DDS texture or if its header can't be identified
-	 * to a supported TextureFormat, etc.
-	 * 
-	 * It assumes that the stream starts at the first byte of the header section for the
-	 * DDS texture.  The stream will not be closed. */
-	public static TextureImage readTexture(InputStream stream) throws IOException {
-		if (stream == null)
-			throw new IOException("Cannot read a texture from a null stream");
-		
-		DDSTexture texture = new DDSTexture(stream);
-		switch(texture.target) {
-		case T_2D:
-			return new Texture2D(texture.data[0], texture.width, texture.height, texture.format, texture.type);
-		case T_3D:
-			return new Texture3D(texture.data[0], texture.width, texture.height, texture.depth, texture.format, texture.type);
-		case T_CUBEMAP:
-			return new TextureCubeMap(texture.data[0], texture.data[2], texture.data[4], texture.data[1], texture.data[3], texture.data[5],
-									  texture.width, texture.format, texture.type);
-		default:
-			throw new IOException("Unsupported texture target type: " + texture.target);
-		}
-	}
-	
-	/** Determine if the given stream represents the start of a valid
-	 * DDS file.  All it checks is the header portion of the given stream.
-	 * As such, it is possible that it appears as a DDS file, but the rest
-	 * of the file is not valid.
-	 * 
-	 * The stream will mark and then read the 124 bytes of the header.
-	 * If an IOException occurs while reading or parsing the header, then
-	 * false is returned. When finished, the stream will be reset back to the mark.
-	 * 
-	 * The stream will not be closed.
-	 * 
-	 * Throws an exception if the stream is null. */
-	public static boolean isDDSTexture(InputStream stream) throws NullPointerException {
-		if (stream == null)
-			throw new NullPointerException("Cannot test a null stream");
-		
-		if (!(stream instanceof BufferedInputStream))
-			stream = new BufferedInputStream(stream); // this way marking is supported
-		try {
-			DDSHeader header;
-			try {
-				// mark the stream and read the header
-				stream.mark(124);
-				header = readHeader(stream);
-			} finally {
-				// must make sure the stream is reset at all times
-				stream.reset();
-			}
-		
-			validateHeader(header);
-			// if we've gotten here, we're valid
-			return true;
-		} catch (IOException ioe) {
-			// something didn't work - either serious IO, or thrown from validateHeader()
-			return false;
-		}
-	}
-	
-	/** Construct a DDSTexture that immediately reads its data in from the 
-	 * given InputStream.  Throws an IOException if the input stream doesn't
-	 * represent a DDS texture file, if the DDS texture isn't formatted correctly,
-	 * or if the DDS texture type isn't supported.
-	 * 
-	 * Assumes that the first byte returned by this input stream is the first byte
-	 * of the DDS header in the file. If the dds header represents a valid and
-	 * supported dds texture, the entire file will be read within this constructor. */
-	private DDSTexture(InputStream in) throws IOException {
-    	this.header = readHeader(in);
-    	
-    	// validate and interpret the header
-    	validateHeader(this.header);
-    	this.identifyBuildParams();
-    	this.identifyTextureFormat();
-    	
-    	this.readData(in);
-    }
-
-	/*
-	 * Structs to hold the DDS file header.
-	 * DDS constants and maps between DDS formats and OpenGL texture format/types.
-	 */
-	
-	// Stores a DDS header (equivalent for DX9 and DX10, DX10 may have non-null DDSHeader_DX10 header, too)
-	private static class DDSHeader {
-		// DDS_HEADER or DDSURFACEDESC2
-		int magic;
-		int size;
-		int flags;
-		int height;
-		int width;
-		int linearSize;
-		int depth;
-		int mipmapCount;
-		int[] reserved1 = new int[11];
-		
-		DDSPixelFormat pixelFormat;
-		
-		// DDS_CAPS2 (embedded in DDS_HEADER, not DDSURFACEDESC2)
-		int caps1;
-		int caps2;
-		int caps3;
-		int caps4;
-		
-		int reserved2;
-		
-		// Not really part of the header, but it follows immediately
-		// Not null if this is a DX10 dds texture
-		DDSHeader_DX10 headerDX10;
-	}
-	
-	// Stores the pixel format information for the dds texture
-	// If the fourCC is valid and set to 'DX10', then the pixel
-	// format is stored in a DXGIPixelFormat enum instead.
-	private static class DDSPixelFormat {
-		// PIXELFORMAT
-		int size;
-		int flags;
-		int fourCC;
-		int rgbBitCount;
-		int rBitMask;
-		int gBitMask;
-		int bBitMask;
-		int rgbAlphaBitMask;
-		
-		public String toString() {
-			String first = "RGB (" + isFlagSet(this.flags, DDPF_RGB) + "), LUM (" + isFlagSet(this.flags, DDPF_LUMINANCE) + 
-							"), ALPHA (" + isFlagSet(this.flags, DDPF_ALPHA) + "), FourCC (" + isFlagSet(this.flags, DDPF_FOURCC) + ")";
-			String second;
-			if (isFlagSet(this.flags, DDPF_FOURCC))
-				second = "FourCC = " + unmakeFourCC(this.fourCC);
-			else 
-				second = "Total bits = " + this.rgbBitCount + ", has alpha = " + isFlagSet(this.flags, DDPF_ALPHAPIXELS) +
-						 " Bit masks: r/l = " + Integer.toHexString(this.rBitMask) + ", g = " + Integer.toHexString(this.gBitMask) + 
-						 ", b = " + Integer.toHexString(this.bBitMask) + ", a = " + Integer.toHexString(this.rgbAlphaBitMask);
-			return first + "\n" + second;
-		}
-	}
-	
-	// Only present if header.pixelFormat.fourCC == 'DX10'
-	private static class DDSHeader_DX10 {
-		DXGIPixelFormat dxgiFormat;
-		int resourceDimension;
-		
-		int miscFlag;
-		int arraySize;
-		int reserved;
-	}
-	
-	/* DX10 pixel formats.  Default constructor implies not supported by this DDS reader.
-	 * If the valid boolean is set, the DXGIPixelFormat contains a valid map between DX10 pixel
-	 * formats and openGL source, dest, and type enums for a texture.
-	 * 
-	 * Also keeps track of byte size of the glType primitive and the number of primitives 
-	 * required to store a color element. */
-	private static enum DXGIPixelFormat {
-		DXGI_FORMAT_UNKNOWN,
-	    DXGI_FORMAT_R32G32B32A32_TYPELESS,
-	    DXGI_FORMAT_R32G32B32A32_FLOAT(DataType.FLOAT, TextureFormat.RGBA_FLOAT),
-	    DXGI_FORMAT_R32G32B32A32_UINT,
-	    DXGI_FORMAT_R32G32B32A32_SINT,
-	    DXGI_FORMAT_R32G32B32_TYPELESS,
-	    DXGI_FORMAT_R32G32B32_FLOAT(DataType.FLOAT, TextureFormat.RGB_FLOAT),
-	    DXGI_FORMAT_R32G32B32_UINT,
-	    DXGI_FORMAT_R32G32B32_SINT,
-	    DXGI_FORMAT_R16G16B16A16_TYPELESS,
-	    DXGI_FORMAT_R16G16B16A16_FLOAT,
-	    DXGI_FORMAT_R16G16B16A16_UNORM(DataType.UNSIGNED_SHORT, TextureFormat.RGBA),
-	    DXGI_FORMAT_R16G16B16A16_UINT,
-	    DXGI_FORMAT_R16G16B16A16_SNORM,
-	    DXGI_FORMAT_R16G16B16A16_SINT,
-	    DXGI_FORMAT_R32G32_TYPELESS,
-	    DXGI_FORMAT_R32G32_FLOAT(DataType.FLOAT, TextureFormat.LUMINANCE_ALPHA_FLOAT),
-	    DXGI_FORMAT_R32G32_UINT,
-	    DXGI_FORMAT_R32G32_SINT,
-	    DXGI_FORMAT_R32G8X24_TYPELESS,
-	    DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
-	    DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
-	    DXGI_FORMAT_X32_TYPELESS_G8X24_UINT,
-	    DXGI_FORMAT_R10G10B10A2_TYPELESS,
-	    DXGI_FORMAT_R10G10B10A2_UNORM,
-	    DXGI_FORMAT_R10G10B10A2_UINT,
-	    DXGI_FORMAT_R11G11B10_FLOAT,
-	    DXGI_FORMAT_R8G8B8A8_TYPELESS,
-	    DXGI_FORMAT_R8G8B8A8_UNORM(DataType.UNSIGNED_INT, TextureFormat.RGBA_8888),
-	    DXGI_FORMAT_R8G8B8A8_UNORM_SRGB(DataType.UNSIGNED_INT, TextureFormat.RGBA_8888),
-	    DXGI_FORMAT_R8G8B8A8_UINT,
-	    DXGI_FORMAT_R8G8B8A8_SNORM,
-	    DXGI_FORMAT_R8G8B8A8_SINT,
-	    DXGI_FORMAT_R16G16_TYPELESS,
-	    DXGI_FORMAT_R16G16_FLOAT,
-	    DXGI_FORMAT_R16G16_UNORM(DataType.UNSIGNED_SHORT, TextureFormat.LUMINANCE_ALPHA),
-	    DXGI_FORMAT_R16G16_UINT,
-	    DXGI_FORMAT_R16G16_SNORM,
-	    DXGI_FORMAT_R16G16_SINT,
-	    DXGI_FORMAT_R32_TYPELESS,
-	    DXGI_FORMAT_D32_FLOAT(DataType.FLOAT, TextureFormat.DEPTH),
-	    DXGI_FORMAT_R32_FLOAT(DataType.FLOAT, TextureFormat.LUMINANCE_FLOAT), // not the best mapping, but it works
-	    DXGI_FORMAT_R32_UINT,
-	    DXGI_FORMAT_R32_SINT,
-	    DXGI_FORMAT_R24G8_TYPELESS,
-	    DXGI_FORMAT_D24_UNORM_S8_UINT,
-	    DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
-	    DXGI_FORMAT_X24_TYPELESS_G8_UINT,
-	    DXGI_FORMAT_R8G8_TYPELESS,
-	    DXGI_FORMAT_R8G8_UNORM(DataType.UNSIGNED_BYTE, TextureFormat.LUMINANCE_ALPHA), // not the best mapping, but it works
-	    DXGI_FORMAT_R8G8_UINT,
-	    DXGI_FORMAT_R8G8_SNORM,
-	    DXGI_FORMAT_R8G8_SINT,
-	    DXGI_FORMAT_R16_TYPELESS,
-	    DXGI_FORMAT_R16_FLOAT,
-	    DXGI_FORMAT_D16_UNORM(DataType.UNSIGNED_SHORT, TextureFormat.DEPTH),
-	    DXGI_FORMAT_R16_UNORM(DataType.UNSIGNED_SHORT, TextureFormat.LUMINANCE),
-	    DXGI_FORMAT_R16_UINT,
-	    DXGI_FORMAT_R16_SNORM,
-	    DXGI_FORMAT_R16_SINT,
-	    DXGI_FORMAT_R8_TYPELESS,
-	    DXGI_FORMAT_R8_UNORM(DataType.UNSIGNED_BYTE, TextureFormat.LUMINANCE),
-	    DXGI_FORMAT_R8_UINT,
-	    DXGI_FORMAT_R8_SNORM,
-	    DXGI_FORMAT_R8_SINT,
-	    DXGI_FORMAT_A8_UNORM(DataType.UNSIGNED_BYTE, TextureFormat.ALPHA),
-	    DXGI_FORMAT_R1_UNORM,
-	    DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
-	    DXGI_FORMAT_R8G8_B8G8_UNORM,
-	    DXGI_FORMAT_G8R8_G8B8_UNORM,
-	    DXGI_FORMAT_BC1_TYPELESS,
-	    DXGI_FORMAT_BC1_UNORM(DataType.UNSIGNED_BYTE, TextureFormat.RGB_DXT1),
-	    DXGI_FORMAT_BC1_UNORM_SRGB(DataType.UNSIGNED_BYTE, TextureFormat.RGBA_DXT1),
-	    DXGI_FORMAT_BC2_TYPELESS,
-	    DXGI_FORMAT_BC2_UNORM(DataType.UNSIGNED_BYTE, TextureFormat.RGBA_DXT3),
-	    DXGI_FORMAT_BC2_UNORM_SRGB(DataType.UNSIGNED_BYTE, TextureFormat.RGBA_DXT3),
-	    DXGI_FORMAT_BC3_TYPELESS,
-	    DXGI_FORMAT_BC3_UNORM(DataType.UNSIGNED_BYTE, TextureFormat.RGBA_DXT5),
-	    DXGI_FORMAT_BC3_UNORM_SRGB(DataType.UNSIGNED_BYTE, TextureFormat.RGBA_DXT5),
-	    DXGI_FORMAT_BC4_TYPELESS,
-	    DXGI_FORMAT_BC4_UNORM,
-	    DXGI_FORMAT_BC4_SNORM,
-	    DXGI_FORMAT_BC5_TYPELESS,
-	    DXGI_FORMAT_BC5_UNORM,
-	    DXGI_FORMAT_BC5_SNORM,
-	    DXGI_FORMAT_B5G6R5_UNORM(DataType.UNSIGNED_SHORT, TextureFormat.BGR_565),
-	    DXGI_FORMAT_B5G5R5A1_UNORM(DataType.UNSIGNED_SHORT, TextureFormat.BGRA_5551),
-	    DXGI_FORMAT_B8G8R8A8_UNORM(DataType.UNSIGNED_INT, TextureFormat.BGRA_8888),
-	    DXGI_FORMAT_B8G8R8X8_UNORM;
-	    
-	    boolean supported;
-	    DataType type;
-	    TextureFormat format;
-	    
-	    int typeByteSize; // number of bytes of each primitive element for glType
-		int typePrimitiveSize; // number of primitives needed to store the color data for glSrcFormat
-		
-	    private DXGIPixelFormat() {
-	    	this(null, null);
-	    	this.supported = false;
-	    }
-	    
-		private DXGIPixelFormat(DataType type, TextureFormat format) {
-			this.supported = true;
-			this.format = format;
-			this.type = type;
-		}
-	}
-
-	/** A mapping between color component masks to openGL source, dest and type enums.
-	 * 
-	 * It also keeps track of the byte size of the glType primitive, as well as
-	 * the number of primitives required to store a color element. */
-	private static class DDPFMap {
-		int bitCount;
-		int rMask;
-		int gMask;
-		int bMask;
-		int aMask;
-		
-		TextureFormat format;
-		DataType type;
-		
-		public DDPFMap(int bitCount, int rMask, int gMask, int bMask, int aMask, DataType type, TextureFormat format) {
-			this.bitCount = bitCount;
-			this.rMask = rMask;
-			this.gMask = gMask;
-			this.bMask = bMask;
-			this.aMask = aMask;
-			
-			this.type = type;
-			this.format = format;
-		}
-		
-		public boolean equals(DDSPixelFormat pf) {
-			return this.equals(pf.rgbBitCount, pf.rBitMask, pf.gBitMask, pf.bBitMask, pf.rgbAlphaBitMask);
-		}
-		
-		public boolean equals(int bitCount, int rMask, int gMask, int bMask, int aMask) {
-			return (this.bitCount == bitCount &&
-					this.rMask == rMask &&
-					this.gMask == gMask &&
-					this.bMask == bMask &&
-					this.aMask == aMask);
-		}
-	}
-	
-	/*
-	 * Only 5 general types of pre-DX10 pixel format: RGB, RGBA, L, LA, and A
-	 * Each defined by bit masks for the component types.
-	 */
-	
-	// Supported RGB types
-	private static final DDPFMap[] pfRGB = new DDPFMap[] {
-		new DDPFMap(24, 0xff0000, 0xff00, 0xff, 0, DataType.UNSIGNED_BYTE, TextureFormat.RGB),
-		new DDPFMap(24, 0xff, 0xff00, 0xff0000, 0, DataType.UNSIGNED_BYTE, TextureFormat.BGR),
-		new DDPFMap(16, 0xf800, 0x7e0, 0x1f, 0, DataType.UNSIGNED_BYTE, TextureFormat.RGB_565),
-		new DDPFMap(16, 0x1f, 0x7e0, 0xf800, 0,  DataType.UNSIGNED_BYTE, TextureFormat.BGR_565),
-	};
-	
-	// Supported RGBA types
-	private static final DDPFMap[] pfRGBA = new DDPFMap[] {
-		new DDPFMap(32, 0xff0000, 0xff00, 0xff, 0xff000000,  DataType.UNSIGNED_INT, TextureFormat.ARGB_8888),
-		new DDPFMap(32, 0xff000000, 0xff0000, 0xff00, 0x000000ff,  DataType.UNSIGNED_INT, TextureFormat.RGBA_8888),
-		new DDPFMap(32, 0xff, 0xff00, 0xff0000, 0xff000000,  DataType.UNSIGNED_INT, TextureFormat.ABGR_8888),
-		new DDPFMap(32, 0xff00, 0xff0000, 0xff000000, 0xff,  DataType.UNSIGNED_INT, TextureFormat.BGRA_8888),
-	};
-
-	// Supported Luminance types
-	private static final DDPFMap[] pfL = new DDPFMap[] {
-		new DDPFMap(8, 0xff, 0, 0, 0,  DataType.UNSIGNED_BYTE, TextureFormat.LUMINANCE)
-	};
-	
-	// Supported Luminance/Alpha types
-	private static final DDPFMap[] pfLA = new DDPFMap[] {
-		new DDPFMap(16, 0xff, 0, 0, 0xff00,  DataType.UNSIGNED_BYTE, TextureFormat.LUMINANCE_ALPHA)
-	};
-	
-	// Supported Alpha types
-	private static final DDPFMap[] pfA = new DDPFMap[] {
-		new DDPFMap(8, 0, 0, 0, 0xff,  DataType.UNSIGNED_BYTE, TextureFormat.ALPHA)
-	};
-	
-	/*
-	 * More constants for the DDS header
-	 */
-	
-	// Selected bits in DDSHeader flags
-	private static final int DDSD_CAPS            = 0x00000001; // Capacities are valid
-	private static final int DDSD_HEIGHT          = 0x00000002; // Height is valid
-	private static final int DDSD_WIDTH           = 0x00000004; // Width is valid
-	private static final int DDSD_PITCH           = 0x00000008; // Pitch is valid
-	private static final int DDSD_PIXELFORMAT     = 0x00001000; // ddpfPixelFormat is valid
-	private static final int DDSD_MIPMAPCOUNT     = 0x00020000; // Mip map count is valid
-	private static final int DDSD_LINEARSIZE      = 0x00080000; // dwLinearSize is valid
-	private static final int DDSD_DEPTH           = 0x00800000; // dwDepth is valid
-
-	// Selected bits in DDSPixelFormat flags
-	private static final int DDPF_ALPHAPIXELS     = 0x00000001; // Alpha channel is present
-	private static final int DDPF_ALPHA           = 0x00000002; // Only contains alpha information
-	private static final int DDPF_LUMINANCE 	  = 0x00020000; // luminance data
-	private static final int DDPF_FOURCC          = 0x00000004; // FourCC code is valid
-	private static final int DDPF_RGB             = 0x00000040; // RGB data is present
-	
-	// Selected bits in DDS capabilities flags
-	private static final int DDSCAPS_TEXTURE      = 0x00001000; // Can be used as a texture
-	private static final int DDSCAPS_MIPMAP       = 0x00400000; // Is one level of a mip-map
-	private static final int DDSCAPS_COMPLEX      = 0x00000008; // Complex surface structure, such as a cube map
-
-	// Selected bits in DDS capabilities 2 flags
-	private static final int DDSCAPS2_CUBEMAP           = 0x00000200;
-	private static final int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400;
-	private static final int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800;
-	private static final int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000;
-	private static final int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000;
-	private static final int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000;
-	private static final int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000;
-	private static final int DDSCAPS2_CUBEMAP_ALL_FACES = 0x0000fc00;
-	private static final int DDSCAPS2_VOLUME 		   = 0x00200000;
-	
-	// Selected bits in DDSHeader_DX10 misc flags
-	private static final int D3D10_MISC_RESOURCE_GENERATE_MIPS = 0x1;
-	private static final int D3D10_MISC_RESOURCE_SHARED = 0x2;
-	private static final int D3D10_MISC_RESOURCE_TEXTURECUBE = 0x4;
-		
-	// D3D10 Resource Dimension enum
-	private static final int D3D10_RESOURCE_DIMENSION_UNKNOWN = 0;
-	private static final int D3D10_RESOURCE_DIMENSION_BUFFER = 1;
-	private static final int D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2;
-	private static final int D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3;
-	private static final int D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4;
-    
-	// FourCC codes
-	private static final int FOURCC_DDS = makeFourCC("DDS ");
-	private static final int FOURCC_DX10 = makeFourCC("DX10");
-	private static final int FOURCC_DXT1 = makeFourCC("DXT1");
-	private static final int FOURCC_DXT3 = makeFourCC("DXT3");
-	private static final int FOURCC_DXT5 = makeFourCC("DXT5");
-	
-	/*
-	 * Methods to interpret the DDS header and convert it to OpenGL specific enums 
-	 */
-	
-	/** Makes sure that the DDSHeader read in has the minimal correct
-	 * values identifying it as a valid DDS texture. */
-	private static void validateHeader(DDSHeader h) throws IOException {
-		// Must have the magic number 'DDS '
-		// Size must be 124, although devIL reports that some files have 'DDS ' in the
-		// size var as well, so we'll support that.
-		if (h.magic != FOURCC_DDS || (h.size != 124 && h.size != FOURCC_DDS))
-			throw new IOException("DDS header is invalid");
-		if (h.pixelFormat.size != 32)
-			throw new IOException("DDS pixel format header is invalid");
-
-		// Give me some valid assumptions
-		if (h.size == FOURCC_DDS)
-			h.size = 124;
-		if (h.mipmapCount == 0)
-			h.mipmapCount = 1;
-		if (h.depth == 0)
-			h.depth = 1;
-
-		// Header flags will be further validated as the header is interpreted in identifyX() methods
-	}
-	
-	/** Validates and looks at the DDSHeader for dimensions and texture target. */
-	private void identifyBuildParams() throws IOException {
-		if (!isFlagSet(this.header.flags, DDSD_CAPS))
-			throw new IOException("DDS header is missing required flag DDSD_CAPS");
-		
-		// check 2d dimensions, must be present for any texture type
-		if (isFlagSet(this.header.flags, DDSD_WIDTH))
-			this.width = this.header.width;
-		else
-			throw new IOException("DDS header is missing required flag DDSD_WIDTH");
-		
-		if (isFlagSet(this.header.flags, DDSD_HEIGHT))
-			this.height = this.header.height;
-		else
-			throw new IOException("DDS header is missing required flag DDSD_HEIGHT");
-		
-		if (!isFlagSet(this.header.caps1, DDSCAPS_TEXTURE))
-			throw new IOException("DDS surface capabilities missing required flag DDSCAPS_TEXTURE");
-		
-		// We won't check for DDSCAPS_COMPLEX, since some files seem to ignore it when creating cube maps or 3d textures
-		if (isFlagSet(this.header.caps2, DDSCAPS2_VOLUME))
-			this.target = TextureTarget.T_3D;
-		else if (isFlagSet(this.header.caps2, DDSCAPS2_CUBEMAP))
-			this.target = TextureTarget.T_CUBEMAP;
-		else 
-			this.target = TextureTarget.T_2D;
-		
-		this.depth = 1;
-		// further validate the dimensions
-		if (this.target == TextureTarget.T_3D) {
-			if (isFlagSet(this.header.flags, DDSD_DEPTH))
-				this.depth = this.header.depth;
-			else
-				throw new IOException("DDSD header is missing required flag DDSD_DEPTH for a volume texture");
-		} else if (this.target == TextureTarget.T_CUBEMAP) {
-			if (!isFlagSet(this.header.caps2, DDSCAPS2_CUBEMAP_ALL_FACES))
-				throw new IOException("Cube map must have 6 faces present");
-			if (this.width != this.height)
-				throw new IOException("Cube map must have square faces");
-		}
-		
-		// validate the DX10 header as well
-		if (this.header.headerDX10 != null) {
-			if (this.target == TextureTarget.T_2D) {
-				if (this.header.headerDX10.resourceDimension != D3D10_RESOURCE_DIMENSION_TEXTURE2D)
-					throw new IOException("DX10 header and surface caps are inconsistent");
-				if (this.header.headerDX10.arraySize > 1)
-					throw new IOException("Texture arrays aren't supported");
-			} else if (this.target == TextureTarget.T_3D) {
-				if (this.header.headerDX10.resourceDimension != D3D10_RESOURCE_DIMENSION_TEXTURE3D)
-					throw new IOException("DX10 header and surface caps are inconsistent");
-				if (this.header.headerDX10.arraySize > 1)
-					throw new IOException("Texture arrays aren't supported");
-			} else if (this.target == TextureTarget.T_CUBEMAP) {
-				if (this.header.headerDX10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D) {
-					// nvidia sets the dx10 header to be a 2d tex, with arraySize = 6 for cubemaps
-					if (this.header.headerDX10.arraySize != 6)
-						throw new IOException("Cube map must have 6 faces present");
-				} else 
-					throw new IOException("DX10 header and surface caps are inconsistent");
-			}
-		}
-		
-		// check for a mipmap count
-		if (isFlagSet(this.header.flags, DDSD_MIPMAPCOUNT)) {
-			this.mipmapCount = this.header.mipmapCount;
-			if (this.mipmapCount > 1) {
-				if (!isFlagSet(this.header.caps1, DDSCAPS_MIPMAP) || !isFlagSet(this.header.caps1, DDSCAPS_COMPLEX))
-					throw new IOException("DDS surface capabilities are invalid for a mipmapped texture");
-			}
-			// make sure all the mipmaps are present
-			int expected = (int)(Math.log(Math.max(this.width, Math.max(this.height, this.depth))) / Math.log(2) + 1); 
-			if (this.mipmapCount != expected)
-				throw new IOException("Expected " + expected + " but got " + this.mipmapCount + " mipmaps instead");
-		} else
-			this.mipmapCount = 1;
-	}
-	
-	/** Further validates the dds header, and tries to identify a supported opengl texture format. */
-	private void identifyTextureFormat() throws IOException {
-		if (!isFlagSet(this.header.flags, DDSD_PIXELFORMAT))
-			throw new IOException("DDSD header is missing required flag DDSD_PIXELFORMAT");
-		
-		if (this.header.headerDX10 != null) {
-			// the pixel format is stored in the dxgiFormat
-			if (!this.header.headerDX10.dxgiFormat.supported)
-				throw new IOException("Unsupported dxgi pixel format: " + this.header.headerDX10.dxgiFormat);
-			else {
-				this.format = this.header.headerDX10.dxgiFormat.format;
-				this.type = this.header.headerDX10.dxgiFormat.type;
-			}
-		} else {
-			if (isFlagSet(this.header.pixelFormat.flags, DDPF_FOURCC)) {
-				// interpret the FOURCC flag.  Currently only supports DXT1, DXT3, and DXT5
-				this.type = DataType.UNSIGNED_BYTE;
-				this.format = null;
-						
-				if (this.header.pixelFormat.fourCC == FOURCC_DXT1) {
-					if (isFlagSet(this.header.pixelFormat.flags, DDPF_ALPHAPIXELS))
-						this.format = TextureFormat.RGBA_DXT1;
-					else
-						this.format = TextureFormat.RGB_DXT1;
-				} else if (this.header.pixelFormat.fourCC == FOURCC_DXT3) 
-					this.format = TextureFormat.RGBA_DXT3;
-				else if (this.header.pixelFormat.fourCC == FOURCC_DXT5) 
-					this.format = TextureFormat.RGBA_DXT5;
-				else
-					throw new IOException("Unrecognized fourCC value in pixel format: " + unmakeFourCC(this.header.pixelFormat.fourCC));
-			} else {
-				// choose the correct DDPFMap array
-				DDPFMap[] supported = null;
-				if (isFlagSet(this.header.pixelFormat.flags, DDPF_LUMINANCE)) {
-					if (isFlagSet(this.header.pixelFormat.flags, DDPF_ALPHAPIXELS)) 
-						supported = pfLA;
-					else 
-						supported = pfL;
-				} else if (isFlagSet(this.header.pixelFormat.flags, DDPF_RGB)) {
-					if (isFlagSet(this.header.pixelFormat.flags, DDPF_ALPHAPIXELS)) 
-						supported = pfRGBA;
-					else
-						supported = pfRGB;	
-				} else if (isFlagSet(this.header.pixelFormat.flags, DDPF_ALPHA)) {
-					if (isFlagSet(this.header.pixelFormat.flags, DDPF_ALPHAPIXELS)) {
-						supported = pfA;
-					} else
-						throw new IOException("Invalid pixel format header");
-				} else
-					throw new IOException("Invalid pixel format header");
-				
-				for (int i = 0; i < supported.length; i++) {
-					if (supported[i].equals(this.header.pixelFormat)) {
-						this.format = supported[i].format;
-						this.type = supported[i].type;
-						return;
-					}
-				}
-
-				// if we've gotten to here, we didn't find a supported DDPF
-				throw new IOException("Unsupported pixel format: " + this.header.pixelFormat);
-			}
-		}
-		
-		if (this.format.getPrimitivesPerColor() < 0 && this.target == TextureTarget.T_3D)
-			throw new IOException("Compressed textures are only allowed to have targets of T_CUBEMAP or T_2D");
-	}
-	
-	/*
-	 * Methods to read in a DDS file from an input stream.
-	 */
-	
-	/** Create a new DDSHeader and fill its values based on the input stream. */
-	private static DDSHeader readHeader(InputStream in) throws IOException {
-		DDSHeader h = new DDSHeader();
-
-		h.magic = readLEInt(in);
-		h.size = readLEInt(in);
-		h.flags = readLEInt(in);
-		h.height = readLEInt(in);
-		h.width = readLEInt(in);
-		h.linearSize = readLEInt(in);
-		h.depth = readLEInt(in);
-		h.mipmapCount = readLEInt(in);
-		for (int i = 0; i < h.reserved1.length; i++)
-			h.reserved1[i] = readLEInt(in);
-
-		h.pixelFormat = new DDSPixelFormat();
-		h.pixelFormat.size = readLEInt(in);
-		h.pixelFormat.flags = readLEInt(in);
-		h.pixelFormat.fourCC = readLEInt(in);
-		h.pixelFormat.rgbBitCount = readLEInt(in);
-		h.pixelFormat.rBitMask = readLEInt(in);
-		h.pixelFormat.gBitMask = readLEInt(in);
-		h.pixelFormat.bBitMask = readLEInt(in);
-		h.pixelFormat.rgbAlphaBitMask = readLEInt(in);
-
-		h.caps1 = readLEInt(in);
-		h.caps2 = readLEInt(in);
-		h.caps3 = readLEInt(in);
-		h.caps4 = readLEInt(in);
-
-		h.reserved2 = readLEInt(in);
-
-		if (h.pixelFormat.fourCC == FOURCC_DX10) { // According to AMD, this is how we know if it's present
-			h.headerDX10 = new DDSHeader_DX10();
-			int dxgi = readLEInt(in);
-			h.headerDX10.dxgiFormat = (dxgi < 0 || dxgi >= DXGIPixelFormat.values().length ? DXGIPixelFormat.values()[0] : DXGIPixelFormat.values()[dxgi]);
-			h.headerDX10.resourceDimension = readLEInt(in);
-			h.headerDX10.miscFlag = readLEInt(in);
-			h.headerDX10.arraySize = readLEInt(in);
-			h.headerDX10.reserved = readLEInt(in);
-		} else 
-			h.headerDX10 = null;
-
-		return h;
-	}
-
-	/** Read the data from the input stream, assuming that it is a fully valid DDS file,
-	 * where the next byte read is the first byte in the texture data (header already read from stream). */
-	private void readData(InputStream in) throws IOException {