Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
479 lines
14 KiB
Java
479 lines
14 KiB
Java
package com.realityinteractive.imageio.tga;
|
|
|
|
/*
|
|
* TGAHeader.java
|
|
* Copyright (c) 2003 Reality Interactive, Inc.
|
|
* See bottom of file for license and warranty information.
|
|
* Created on Sep 26, 2003
|
|
*/
|
|
|
|
import java.io.IOException;
|
|
|
|
import javax.imageio.stream.ImageInputStream;
|
|
|
|
/**
|
|
* <p>The header to a TGA image file.</p>
|
|
*
|
|
* <p>See <a href="http://organicbit.com/closecombat/formats/tga.html">format</a>,
|
|
* <a href="http://www.opennet.ru/docs/formats/targa.pdf">format</a> or
|
|
* <a href="http://netghost.narod.ru/gff/graphics/summary/tga.htm">format</a>
|
|
* for header information.</p>
|
|
*
|
|
* @author Rob Grzywinski <a href="mailto:rgrzywinski@realityinteractive.com">rgrzywinski@realityinteractive.com</a>
|
|
* @version $Id: TGAHeader.java,v 1.1 2005/04/12 11:23:53 ornedan Exp $
|
|
* @since 1.0
|
|
*/
|
|
public class TGAHeader
|
|
{
|
|
/**
|
|
* <p>The length of the TGA identifier. This is a <code>byte</code> in
|
|
* length.</p>
|
|
*/
|
|
private int idLength;
|
|
|
|
/**
|
|
* <p>The image identifier with length <code>idLength</code>.</p>
|
|
*/
|
|
private byte[] id;
|
|
|
|
/**
|
|
* <p>Does this TGA have an associated color map? <code>1</code> indicates
|
|
* that there is a color map. <code>0</code> indicates no color map.</p>
|
|
*/
|
|
private boolean hasColorMap;
|
|
|
|
/**
|
|
* <p>The type of image. See the image type constants in {@link com.realityinteractive.imageio.tga.TGAConstants}
|
|
* for allowed values.</p>
|
|
*/
|
|
private int imageType;
|
|
|
|
/**
|
|
* <p>An image is compressed if its image type is {@link TGAConstants#RLE_COLOR_MAP},
|
|
* {@link TGAConstants#RLE_TRUE_COLOR}, or {@link TGAConstants#RLE_MONO}.</p>
|
|
*/
|
|
private boolean isCompressed;
|
|
|
|
/**
|
|
* <p>The index of the first color map entry.</p>
|
|
*/
|
|
private int firstColorMapEntryIndex;
|
|
|
|
/**
|
|
* <p>The total number of color map entries.</p>
|
|
*/
|
|
private int numberColorMapEntries;
|
|
|
|
/**
|
|
* <p>The number of bits per color map entry.</p>
|
|
*/
|
|
private int bitsPerColorMapEntry;
|
|
|
|
/**
|
|
* <p>The computed size of a color map entry in <code>byte</code>s.</p>
|
|
*/
|
|
private int colorMapEntrySize;
|
|
|
|
/**
|
|
* <p>The computed size of the color map field in <code>byte</code>s. This
|
|
* is determined from the <code>numberColorMapEntries</code> and
|
|
* <code>colorMapEntrySize</code>.</p>
|
|
*/
|
|
private int colorMapSize;
|
|
|
|
/**
|
|
* <p>The horizontal coordinate for the lower-left corner of the image.</p>
|
|
*/
|
|
private int xOrigin;
|
|
|
|
/**
|
|
* <p>The vertical coordinate for the lower-left corner of the image.</p>
|
|
*/
|
|
private int yOrigin;
|
|
|
|
/**
|
|
* <p>The width of the image in pixels.</p>
|
|
*/
|
|
private int width;
|
|
|
|
/**
|
|
* <p>The height of the image in pixels.</p>
|
|
*/
|
|
private int height;
|
|
|
|
/**
|
|
* <p>The number of bits per pixel.</p>
|
|
*/
|
|
private int bitsPerPixel;
|
|
|
|
/**
|
|
* <p>The number of attribute bits per pixel.</p>
|
|
*/
|
|
private int imageDescriptor;
|
|
|
|
/**
|
|
* <p>The horizontal ordering of the pixels as determined from the image
|
|
* descriptor. By default the order is left to right.</p>
|
|
*/
|
|
// NOTE: true -> left-to-right; false -> right-to-left
|
|
private boolean leftToRight;
|
|
|
|
/**
|
|
* <p>The horizontal ordering of the pixels as determined from the image
|
|
* descriptor. By default the order is left to right.</p>
|
|
*/
|
|
// NOTE: true -> bottom-to-top; false -> top-to-bottom
|
|
private boolean bottomToTop;
|
|
|
|
/**
|
|
* <p>The offset to the color map data. This value is not defined if there
|
|
* is no color map (see <code>hasColorMap</code>).</p>
|
|
*/
|
|
private int colorMapDataOffset;
|
|
|
|
/**
|
|
* <p>The offset to the pixel data.</p>
|
|
*/
|
|
private int pixelDataOffset;
|
|
|
|
// =========================================================================
|
|
/**
|
|
* <p>Constructs a TGA header that will be populated by setters or directly
|
|
* (via a static "factory" method).</p>
|
|
*/
|
|
public TGAHeader() {}
|
|
|
|
/**
|
|
* <p>Constructs and populates a TGA header from the specified {@link javax.imageio.stream.ImageInputStream}.</p>
|
|
*
|
|
* @param inputStream the <code>ImageInputStream</code> from which the
|
|
* header data is read
|
|
* @throws IOException if there was an I/O error while reading the header
|
|
* data
|
|
*/
|
|
public TGAHeader(final ImageInputStream inputStream)
|
|
throws IOException
|
|
{
|
|
// read the data
|
|
readHeader(inputStream);
|
|
}
|
|
|
|
/**
|
|
* <p>Reads and populates the header from the specifed {@link javax.imageio.stream.ImageInputStream}.
|
|
* Any existing values will be over written.</p>
|
|
*
|
|
* <p>The <code>ImageInputStream</code> will be changed as a result of this
|
|
* operation (the offset will be moved).</p>
|
|
*
|
|
* @param inputStream the <code>ImageInputStream</code> from which the
|
|
* header data is read
|
|
* @throws IOException if there was an I/O error while reading the header
|
|
* data
|
|
*/
|
|
public void readHeader(final ImageInputStream inputStream)
|
|
throws IOException
|
|
{
|
|
// read in the header as per the spec
|
|
idLength = inputStream.readUnsignedByte();
|
|
|
|
hasColorMap = (inputStream.readUnsignedByte() == 1); // 1 == true, 0 == false
|
|
imageType = inputStream.readUnsignedByte();
|
|
|
|
firstColorMapEntryIndex = inputStream.readUnsignedShort();
|
|
numberColorMapEntries = inputStream.readUnsignedShort();
|
|
bitsPerColorMapEntry = inputStream.readByte();
|
|
|
|
xOrigin = inputStream.readUnsignedShort();
|
|
yOrigin = inputStream.readUnsignedShort();
|
|
width = inputStream.readUnsignedShort();
|
|
height = inputStream.readUnsignedShort();
|
|
|
|
bitsPerPixel = inputStream.readByte();
|
|
imageDescriptor = inputStream.readByte();
|
|
|
|
// determine if the image is compressed
|
|
isCompressed = ( (imageType == TGAConstants.RLE_COLOR_MAP) ||
|
|
(imageType == TGAConstants.RLE_TRUE_COLOR) ||
|
|
(imageType == TGAConstants.RLE_MONO) );
|
|
|
|
// compute the size of the color map field in bytes
|
|
switch(bitsPerColorMapEntry)
|
|
{
|
|
case 8:
|
|
default:
|
|
colorMapEntrySize = 1;
|
|
break;
|
|
case 15:
|
|
case 16:
|
|
colorMapEntrySize = 2;
|
|
break;
|
|
case 24:
|
|
case 32:
|
|
colorMapEntrySize = 3;
|
|
break;
|
|
}
|
|
colorMapSize = colorMapEntrySize * numberColorMapEntries; // in bytes
|
|
|
|
// set the pixel ordering from the imageDescriptor bit mask
|
|
// (bit set indicates false)
|
|
leftToRight = ((imageDescriptor & TGAConstants.LEFT_RIGHT_BIT) == 0);
|
|
bottomToTop = ((imageDescriptor & TGAConstants.BOTTOM_TOP_BIT) == 0);
|
|
|
|
// read the image id based whose length is idLength
|
|
if(idLength > 0)
|
|
{
|
|
// allocate the space for the id
|
|
id = new byte[idLength];
|
|
|
|
// read the id
|
|
inputStream.read(id, 0, idLength);
|
|
} /* else -- the idLength was not positive */
|
|
|
|
// compute the color map and pixel data offsets. The color map data
|
|
// offset is the current offset.
|
|
// NOTE: the conversion to int is OK since the maximum size of the
|
|
// color map data is 65536 bytes.
|
|
final long currentOffset = inputStream.getStreamPosition();
|
|
colorMapDataOffset = (int)currentOffset;
|
|
if(hasColorMap)
|
|
{
|
|
// there is a color map so the pixel data offset is the current
|
|
// offset + the size of the color map data
|
|
pixelDataOffset = colorMapDataOffset + colorMapSize;
|
|
} else /* there is no color map */
|
|
{
|
|
// there is no color map so the pixel data offset is the current
|
|
// offset
|
|
pixelDataOffset = (int)currentOffset;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>The length of the TGA identifier. This is a <code>byte</code> in
|
|
* length.</p>
|
|
*/
|
|
public int getIdLength()
|
|
{
|
|
return idLength;
|
|
}
|
|
|
|
/**
|
|
* <p>Does this TGA have an associated color map?</p>
|
|
*/
|
|
public boolean hasColorMap()
|
|
{
|
|
return hasColorMap;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the type of image. See the image type constants in {@link com.realityinteractive.imageio.tga.TGAConstants}
|
|
* for allowed values.</p>
|
|
*/
|
|
public int getImageType()
|
|
{
|
|
return imageType;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves a string that represents the image type.</p>
|
|
*/
|
|
public String getImageTypeString()
|
|
{
|
|
switch(imageType)
|
|
{
|
|
case TGAConstants.NO_IMAGE:
|
|
return "NO IMAGE";
|
|
|
|
case TGAConstants.COLOR_MAP:
|
|
return "COLOR MAP";
|
|
|
|
case TGAConstants.TRUE_COLOR:
|
|
return "TRUE COLOR";
|
|
|
|
case TGAConstants.MONO:
|
|
return "MONOCHROME";
|
|
|
|
case TGAConstants.RLE_COLOR_MAP:
|
|
return "RLE COMPRESSED COLOR MAP";
|
|
|
|
case TGAConstants.RLE_TRUE_COLOR:
|
|
return "RLE COMPRESSED TRUE COLOR";
|
|
|
|
case TGAConstants.RLE_MONO:
|
|
return "RLE COMPRESSED MONOCHROME";
|
|
|
|
default:
|
|
return "UNKNOWN";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves if this image is compressed. If the image type is
|
|
* {@link TGAConstants#RLE_COLOR_MAP}, {@link TGAConstants#RLE_TRUE_COLOR},
|
|
* or {@link TGAConstants#RLE_MONO} then the image is compressed.</p>
|
|
*/
|
|
public boolean isCompressed()
|
|
{
|
|
return isCompressed;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the index of the first color map entry.</p>
|
|
*/
|
|
public int getFirstColorMapEntryIndex()
|
|
{
|
|
return firstColorMapEntryIndex;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves ttotal number of color map entries.</p>
|
|
*/
|
|
public int getColorMapLength()
|
|
{
|
|
return numberColorMapEntries;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the number of bits per color map entry.</p>
|
|
*/
|
|
public int getBitsPerColorMapEntry()
|
|
{
|
|
return bitsPerColorMapEntry;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the horizontal coordinate for the lower-left corner of the
|
|
* image.</p>
|
|
*/
|
|
public int getXOrigin()
|
|
{
|
|
return xOrigin;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the vertical coordinate for the lower-left corner of the image.</p>
|
|
*/
|
|
public int getYOrigin()
|
|
{
|
|
return yOrigin;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the width of the image in pixels.</p>
|
|
*/
|
|
public int getWidth()
|
|
{
|
|
return width;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the height of the image in pixels.</p>
|
|
*/
|
|
public int getHeight()
|
|
{
|
|
return height;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the number of bits per pixel.</p>
|
|
*/
|
|
public int getBitsPerPixel()
|
|
{
|
|
return bitsPerPixel;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the number of samples per pixel.</p>
|
|
*/
|
|
public int getSamplesPerPixel()
|
|
{
|
|
// FIXME: this is overly simplistic but it is accurate
|
|
return (bitsPerPixel == 32) ? 4 : 3;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the number of attribute bits per pixel.</p>
|
|
*/
|
|
public int getImageDescriptor()
|
|
{
|
|
return imageDescriptor;
|
|
}
|
|
|
|
/**
|
|
* <p>Returns if this image is left-to-right (<code>true</code>) or right-
|
|
* to-left (<code>false</code>).</p>
|
|
*/
|
|
public boolean isLeftToRight()
|
|
{
|
|
return leftToRight;
|
|
}
|
|
|
|
/**
|
|
* <p>Returns if this image is bottom-to-top (<code>true</code>) or top-to-
|
|
* bottom (<code>false</code>).</p>
|
|
*/
|
|
public boolean isBottomToTop()
|
|
{
|
|
return bottomToTop;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the offset to the color map data. If there is no color
|
|
* map ({@link #hasColorMap()} returns <code>false</code>) then this is
|
|
* undefined.</p>
|
|
*/
|
|
public int getColorMapDataOffset()
|
|
{
|
|
return colorMapDataOffset;
|
|
}
|
|
|
|
/**
|
|
* <p>Retrieves the offset to the pixel data.</p>
|
|
*/
|
|
public int getPixelDataOffset()
|
|
{
|
|
return pixelDataOffset;
|
|
}
|
|
|
|
// =========================================================================
|
|
/**
|
|
* <p>Retrieves a string useful for debugging.</p>
|
|
*
|
|
* @return a string useful for debugging
|
|
*/
|
|
public String debugString()
|
|
{
|
|
return "TGAHeader[" +
|
|
"type=" + getImageTypeString() + ", " +
|
|
(hasColorMap ?
|
|
("firstColorMapEntryIndex=" + firstColorMapEntryIndex + ", " +
|
|
"numberColorMapEntries=" + numberColorMapEntries + ", " +
|
|
"bitsPerColorMapEntry=" + bitsPerColorMapEntry + ", " +
|
|
"totalColorMapEntrySize=" + colorMapSize + ", " ) :
|
|
"") +
|
|
"isCompressed=" + isCompressed + ", " +
|
|
"xOrigin=" + xOrigin + ", " +
|
|
"yOrigin=" + yOrigin + ", " +
|
|
"width=" + width + ", " +
|
|
"height=" + height + ", " +
|
|
"bitsPerPixel=" + bitsPerPixel + ", " +
|
|
"samplesPerPixel=" + getSamplesPerPixel() +
|
|
"]";
|
|
}
|
|
}
|
|
// =============================================================================
|
|
/*
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/ |