package org.jcodec.codecs.common.biari; import org.jcodec.platform.BaseOutputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * This class is part of JCodec ( www.jcodec.org ) This software is distributed * under FreeBSD License * * All the IO routines related to bits * * @author The JCodec project * */ public class BitIO { public static interface InputBits { public int getBit() throws IOException; } public static interface OutputBits { public void putBit(int symbol) throws IOException; public void flush() throws IOException; } public static InputBits inputFromStream(InputStream is) { return new StreamInputBits(is); } public static OutputBits outputFromStream(OutputStream out) { return new StreamOutputBits(out); } public static InputBits inputFromArray(byte[] bytes) { return new StreamInputBits(new ByteArrayInputStream(bytes)); } public static OutputBits outputFromArray(final byte[] bytes) { return new StreamOutputBits(new BaseOutputStream() { int ptr; protected void writeByte(int b) throws IOException { if (ptr >= bytes.length) throw new IOException("Buffer is full"); bytes[ptr++] = (byte) b; } }); } public static byte[] compressBits(int[] decompressed) { byte[] compressed = new byte[(decompressed.length >> 3) + 1]; OutputBits out = outputFromArray(compressed); try { for (int i = 0; i < decompressed.length; i++) { int bit = decompressed[i]; out.putBit(bit); } } catch (IOException e) { } return compressed; } public static int[] decompressBits(byte[] compressed) { int[] decompressed = new int[compressed.length << 3]; InputBits inputFromArray = inputFromArray(compressed); int read; try { for (int i = 0; (read = inputFromArray.getBit()) != -1; i++) { decompressed[i] = read; } } catch (IOException e) { } return decompressed; } public static class StreamInputBits implements InputBits { private InputStream _in; private int cur; private int bit; public StreamInputBits(InputStream _in) { this._in = _in; this.bit = 8; } public int getBit() throws IOException { if (bit > 7) { cur = _in.read(); if (cur == -1) return -1; bit = 0; } return (cur >> (7 - bit++)) & 0x1; } } public static class StreamOutputBits implements OutputBits { private OutputStream out; private int cur; private int bit; public StreamOutputBits(OutputStream out) { this.out = out; } public void putBit(int symbol) throws IOException { if (bit > 7) { out.write(cur); cur = 0; bit = 0; } cur |= (symbol & 0x1) << (7 - bit++); } public void flush() throws IOException { if (bit > 0) out.write(cur); } } }