TileMangler/src/tm/tilecodecs/PlanarTileCodec.java

126 lines
3.6 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.tilecodecs;
/**
*
* Planar, palette-indexed 8x8 tile codec. Max. 8 bitplanes.
* bitsPerPixel must be a power of 2. (1, 2, 4, 8) (why??)
* Planes for each row must be stored sequentially.
*
**/
public class PlanarTileCodec extends TileCodec {
protected int[] bpOffsets;
protected int[] bp;
protected static int[][][] bitsToPixelsLookup=null;
/**
*
* Constructor.
*
* @param bpOffsets Relative offsets for the bitplane values in a row (8 pixels) of encoded tile data. The length of this array is the number of bitplanes in a tile row, which is equal to the # of bits per pixel.
*
**/
public PlanarTileCodec(String id, int[] bpOffsets, String description) {
super(id, bpOffsets.length, description);
this.bpOffsets = bpOffsets;
bp = new int[8];
if (bitsToPixelsLookup == null) {
// Precalculate all bit patterns
bitsToPixelsLookup = new int[8][256][8];
for (int i=0; i<8; i++) {
// do one bitplane
for (int j=0; j<256; j++) {
// do one byte
for (int k=7; k>=0; k--) {
// do one pixel
bitsToPixelsLookup[i][j][7-k] = ((j >> k) & 1) << i;
}
}
}
}
}
/**
*
* Decodes a tile.
*
* @param bits An array of ints holding encoded tile data in each LSB
* @param ofs Where to start decoding from in the array
*
**/
public int[] decode(byte[] bits, int ofs, int stride) {
int pos=0;
stride++;
stride *= bytesPerRow;
for (int i=0; i<8; i++) {
// do one row of pixels
for (int j=0; j<bitsPerPixel; j++) {
// get bits for bitplane j
bp[j] = bits[ofs+bpOffsets[j]] & 0xFF;
}
for (int j=0; j<8; j++) {
// decode one pixel
int p = 0;
for (int k=0; k<bitsPerPixel; k++) {
// add bitplane k
p |= bitsToPixelsLookup[k][bp[k]][j];
}
pixels[pos++] = p;
}
ofs += stride;
}
return pixels;
}
/**
*
* Encodes a bitplaned tile.
*
**/
public void encode(int[] pixels, byte[] bits, int ofs, int stride) {
int pos=0;
stride++;
stride *= bytesPerRow;
for (int i=0; i<8; i++) {
// do one row
for (int j=0; j<bitsPerPixel; j++) {
// reset bits of bitplane j
bits[ofs+bpOffsets[j]] = 0;
}
for (int j=0; j<8; j++) {
// encode one pixel
int p = pixels[pos];
for (int k=0; k<bitsPerPixel; k++) {
// add bitplane k
bits[ofs+bpOffsets[k]] |= ((p >> k) & 0x01) << (7-j);
}
pos++;
}
ofs += stride;
}
}
}