package org.lateralgm.file.iconio; import java.io.IOException; import org.lateralgm.file.StreamDecoder; import org.lateralgm.file.StreamEncoder; /** * <p> * Bitmap with 16 color palette (4 bits per sample). * </p> * * @author © Christian Treber, ct@ctreber.com */ public class BitmapIndexed4BPP extends AbstractBitmapIndexed { /** * Create a 4 BPP bitmap. * * @param pDescriptor */ public BitmapIndexed4BPP(final BitmapDescriptor pDescriptor) { super(pDescriptor); } void readBitmap(final StreamDecoder pDec) throws IOException { // One byte contains 2 samples. final int lWt = getBytesPerScanLine(getWidth(),4); for (int lRowNo = 0; lRowNo < getHeight(); lRowNo++) { final byte[] lRow = new byte[lWt]; pDec.read(lRow); int lRowByte = 0; boolean lUpperNibbleP = true; int lOutputPos = (getHeight() - lRowNo - 1) * getWidth(); for (int lColNo = 0; lColNo < getWidth(); lColNo++) { int lValue; if (lUpperNibbleP) { lValue = (lRow[lRowByte] & 0xF0) >> 4; } else { lValue = lRow[lRowByte] & 0x0F; lRowByte++; } pixels[lOutputPos++] = lValue & 0xFF; lUpperNibbleP = !lUpperNibbleP; } } } private void writeNibs(StreamEncoder out, int offset, int count) throws IOException { if (count == 2) out.write(pixels[offset] << 4 | pixels[offset + 1]); else if (count == 1) out.write(pixels[offset] << 4); else throw new IllegalArgumentException("Can't write anything other than 1 or 2 nibbles"); } void writeBitmap(StreamEncoder out) throws IOException { int width = getWidth(); int padding = getPaddingPerScanLine(width,4); for (int row = getHeight() - 1; row >= 0; row--) { int offset = row * width; for (int x = 0; x < width; x += 2) writeNibs(out,offset + x,Math.min(width - x,2)); int i = padding; while (i-- > 0) out.write(0); } } }