
Prefer not to have edgy references to child sexual assault in our tools. Consider that victims of such violence may well grow up to become ROM hackers just as often as the rest of us. Let's not be rude to them!
186 lines
No EOL
4.2 KiB
Java
186 lines
No EOL
4.2 KiB
Java
/*
|
|
*
|
|
* Copyright (C) 2003 Kent Hansen.
|
|
*
|
|
* This file is part of Tile Mangler.
|
|
*
|
|
* Tile Mangler is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Tile Mangler 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 General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
package tm.colorcodecs;
|
|
|
|
/**
|
|
*
|
|
* Abstract superclass for color codecs.
|
|
* A "color codec" defines how values of a particular format are translated
|
|
* to 32-bit ARGB pixel values (decoded), and back again (encoded).
|
|
*
|
|
**/
|
|
|
|
public abstract class ColorCodec {
|
|
|
|
public static final int LITTLE_ENDIAN=1;
|
|
public static final int BIG_ENDIAN=2;
|
|
public static final int MIDDLE_ENDIAN=3;
|
|
|
|
protected int bitsPerPixel;
|
|
protected int bytesPerPixel;
|
|
protected String id;
|
|
protected String description;
|
|
|
|
private static int endianness;
|
|
private int startShift;
|
|
private int shiftStep;
|
|
|
|
/**
|
|
*
|
|
* Creates a ColorCodec with the given id, bits per pixel and description.
|
|
*
|
|
**/
|
|
|
|
public ColorCodec(String id, int bitsPerPixel, String description) {
|
|
this.id = id;
|
|
this.bitsPerPixel = bitsPerPixel;
|
|
this.description = description;
|
|
bytesPerPixel = getBytesRequired(bitsPerPixel);
|
|
setEndianness(LITTLE_ENDIAN); // default
|
|
}
|
|
|
|
/**
|
|
* Sets the endianness.
|
|
* It determines the byte order related to methods toBytes() and fromBytes().
|
|
**/
|
|
|
|
public void setEndianness(int endianness) {
|
|
this.endianness = endianness;
|
|
if (endianness == LITTLE_ENDIAN) {
|
|
startShift = 0;
|
|
shiftStep = 8;
|
|
}
|
|
else {
|
|
// BIG_ENDIAN
|
|
startShift = (bytesPerPixel-1) * 8;
|
|
shiftStep = -8;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the ID.
|
|
*
|
|
**/
|
|
|
|
public String getID() {
|
|
return id;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the number of bits per pixel.
|
|
*
|
|
**/
|
|
|
|
public int getBitsPerPixel() {
|
|
return bitsPerPixel;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the number of bytes required to hold one pixel.
|
|
*
|
|
**/
|
|
|
|
public int getBytesPerPixel() {
|
|
return bytesPerPixel;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the description.
|
|
*
|
|
**/
|
|
|
|
public String getDescription() {
|
|
return description;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* This method takes a value assumed to be in the color codec's native format
|
|
* and returns the equivalent 32-bit ARGB value.
|
|
*
|
|
**/
|
|
|
|
public abstract int decode(int value);
|
|
|
|
/**
|
|
*
|
|
* This method takes a value assumed to be in 32-bit ARGB format and returns
|
|
* the equivalent native format value.
|
|
*
|
|
**/
|
|
|
|
public abstract int encode(int argb);
|
|
|
|
/**
|
|
*
|
|
* Converts given value to a series of bytes, according to current endianness.
|
|
* @param bytes Array to store resulting bytes in
|
|
* @param offset Starting offset in array
|
|
*
|
|
**/
|
|
|
|
public byte[] toBytes(int value, byte[] bytes, int offset) {
|
|
int shift = startShift;
|
|
for (int i=0; i<bytesPerPixel; i++) {
|
|
bytes[offset+i] = (byte)(value >> shift);
|
|
shift += shiftStep;
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Converts bytes from given array to a value, according to current endianness.
|
|
* @param offset Where to start reading the bytes that make up the value.
|
|
*
|
|
**/
|
|
|
|
public int fromBytes(byte[] bytes, int offset) {
|
|
int shift = startShift;
|
|
int value = 0;
|
|
for (int i=0; i<bytesPerPixel; i++) {
|
|
value |= (bytes[offset+i] & 0xFF) << shift;
|
|
shift += shiftStep;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Gets the least number of whole bytes that are required to store
|
|
* <code>bits</code> bits of information.
|
|
*
|
|
**/
|
|
|
|
private static int getBytesRequired(int bits) {
|
|
int bytes = bits / 8;
|
|
int extrabits = bits % 8;
|
|
if (extrabits != 0) bytes++;
|
|
return bytes;
|
|
}
|
|
|
|
public String toString() {
|
|
return description;
|
|
}
|
|
|
|
} |