// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.resource.graphics;
import java.awt.Image;
import java.io.InputStream;
import java.nio.ByteBuffer;
import org.infinity.resource.key.ResourceEntry;
import org.infinity.util.io.StreamUtils;
/**
* Common base class for handling MOS resources.
*/
public abstract class MosDecoder
{
/** Recognized MOS resource types */
public enum Type { INVALID, MOSC, MOSV1, MOSV2 }
private final ResourceEntry mosEntry;
private Type type;
/**
* Returns whether the specified resource entry points to a valid MOS resource.
*/
public static boolean isValid(ResourceEntry mosEntry)
{
return (getType(mosEntry) != Type.INVALID);
}
/**
* Returns the type of the specified resource entry.
* @return One of the MOS {@code Type}s.
*/
public static Type getType(ResourceEntry mosEntry)
{
Type retVal = Type.INVALID;
if (mosEntry != null) {
try {
InputStream is = mosEntry.getResourceDataAsStream();
if (is != null) {
String signature = StreamUtils.readString(is, 4);
String version = StreamUtils.readString(is, 4);
is.close();
if ("MOSC".equals(signature)) {
retVal = Type.MOSC;
} else if ("MOS ".equals(signature)) {
if ("V1 ".equals(version)) {
retVal = Type.MOSV1;
} else if ("V2 ".equals(version)) {
retVal = Type.MOSV2;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return retVal;
}
/**
* Returns a new MosDecoder object based on the specified MOS resource entry.
* @param mosEntry The MOS resource entry.
* @return Either {@code MosV1Decoder} or {@code MosV2Decoder}, depending on the
* BAM resource type. Returns {@code null} if the resource doesn't contain valid
* BAM data.
*/
public static MosDecoder loadMos(ResourceEntry mosEntry)
{
Type type = getType(mosEntry);
switch (type) {
case MOSC:
case MOSV1:
return new MosV1Decoder(mosEntry);
case MOSV2:
return new MosV2Decoder(mosEntry);
default:
return null;
}
}
/**
* Returns the ResourceEntry object of the MOS resource.
*/
public ResourceEntry getResourceEntry()
{
return mosEntry;
}
/**
* Returns the type of the TIS resource.
*/
public Type getType()
{
return type;
}
/** Removes all data from the decoder. Use this to free up memory. */
public abstract void close();
/** Clears existing data and reloads the current MOS resource entry. */
public abstract void reload();
/** Returns the raw data of the MOS resource. */
public abstract ByteBuffer getResourceBuffer();
/** Returns the width of the MOS resource. */
public abstract int getWidth();
/** Returns the height of the MOS resource. */
public abstract int getHeight();
/** Returns the MOS as image object. */
public abstract Image getImage();
/** Paints the MOS onto the canvas. Returns the success state. */
public abstract boolean getImage(Image canvas);
/** Returns an int array containing the decoded MOS data. (Format: ARGB) */
public abstract int[] getImageData();
/** Writes the decoded MOS data into the buffer. Returns the success state. */
public abstract boolean getImageData(int[] buffer);
/** Returns the number of data blocks this MOS resource consists of. */
public abstract int getBlockCount();
/** Returns the width of the specified MOS data block */
public abstract int getBlockWidth(int blockIdx);
/** Returns the height of the specified MOS data block */
public abstract int getBlockHeight(int blockIdx);
/** Returns the specified block as image object. */
public abstract Image getBlock(int blockIdx);
/** Paints the specified block onto the canvas. Returns the success state. */
public abstract boolean getBlock(int blockIdx, Image canvas);
/** Returns the specified blocks as int array. (Format: ARGB) */
public abstract int[] getBlockData(int blockIdx);
/** Writes the specified blocks into the buffer. Returns the success state. */
public abstract boolean getBlockData(int blockIdx, int[] buffer);
/** Does basic initializations */
protected MosDecoder(ResourceEntry mosEntry)
{
this.mosEntry = mosEntry;
this.type = Type.INVALID;
}
protected void setType(Type type)
{
this.type = type;
}
}