/* * Copyright 2006-2017 ICEsoft Technologies Canada Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.icepdf.core.io; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * The class <code>BitStream</code> is designed to convert an input stream of * bytes into bits. A <code>BitStream</code> is primarily used when bit * manipulation of stream needed, such as when bit data is needed for encoding * a image. * * @since 1.0 */ public class BitStream { // Input stream InputStream in; // Output stream OutputStream out; // bits left in stream int bits; // number of bits left in a byte int bits_left; boolean readEOF; // making value private static final int masks[] = new int[32]; static { for (int i = 0; i < 32; i++) { masks[i] = ((1 << i) - 1); } } /** * Create a new instance of a <code>BitStream</code> from the given * input stream. * * @param i input stream to create a bit stream from. */ public BitStream(InputStream i) { in = i; bits = 0; bits_left = 0; readEOF = false; } /** * Create a new instance of a <code>BitStream</code> from the given * output stream. * * @param o output stream to create a bit stream from. */ public BitStream(OutputStream o) { out = o; bits = 0; bits_left = 0; readEOF = false; } /** * Close all streams data associated with this object * * @throws IOException error closing stream */ public void close() throws IOException { // clean up the streams. if (in != null) { in.close(); } if (out != null) { out.flush(); out.close(); } } /** * @param count * @return * @throws java.io.IOException */ public int getBits(int count) throws IOException { if (count < 32) { while (bits_left < count) { int r = in.read(); if (r < 0) { readEOF = true; break; } bits <<= 8; bits |= (r & 0xFF); bits_left += 8; } bits_left -= count; return (bits >> bits_left) & masks[count]; } else if (count == 32) { return (in.read() << 24) | (in.read() << 16) | (in.read() << 8) | in.read(); } return 0; } public boolean atEndOfFile() { return readEOF && (bits_left <= 0); } /** * @param i * @throws java.io.IOException */ public void putBit(int i) throws IOException { bits <<= 1; bits |= i; bits_left++; if (bits_left == 8) { out.write(bits); bits = 0; bits_left = 0; } } /** * @param i * @param len * @throws java.io.IOException */ public void putRunBits(int i, int len) throws IOException { for (int j = len - 1; j >= 0; ) { if (bits_left != 0 || j < 8) { putBit(i); j--; } else { if (i == 0) out.write(0x00); else out.write(0xFF); j -= 8; } } } /** * @return * @throws java.io.IOException */ public int available() throws IOException { if (bits_left == 0 && in.available() <= 0) return 0; return 1; } /** * @throws java.io.IOException */ public void skipByte() throws IOException { bits_left = 0; bits = 0; } }