java - Writing bits for huffman coding -
i'm pretty new programming , trying compress using method, have right sequence of 0s , 1s , need write bit bit i'm using class called bitoutputstream , bitinputstream write it(which didn't do), thing read file that's been written not same sequence had, here's code used write:
public void writecompressed() throws ioexception{ bitoutputstream fop2 = new bitoutputstream( new objectoutputstream( new fileoutputstream( "c:\\users\\david\\documents\\davidcompress.dabc"))); (int = 0; < secuenciafinal.length(); i++) { if (secuenciafinal.charat(i) == '1') { fop2.write1bit();//lee la cadena y si contiene 1 escribe in 1 bit en mi archivo1 } else if (secuenciafinal.charat(i) == '0') { fop2.write0bit();//si la cadena contiene 0 bits escribe 0 bits } else { //fop2.missingbits(); } } fop2.close(); } where "secuenciafinal" sequence want save, when read different sequence:
public void writedecompressed(string path) throws ioexception{ inputstream = new fileinputstream(path); bitinputstream bis = new bitinputstream(is); string textbits = "", originaltext =""; while(bis.available()>0) textbits += bis.readbit() +""; treenode node = root; (int = 0; < textbits.length(); i++) { if(!node.isleaf()){ if(integer.parseint(textbits.charat(i)+"") == 0) {node = node.getleftson();} else if(integer.parseint(textbits.charat(i)+"") == 1) {node = node.getrightson();} else system.out.println("no se encontrĂ³ 1 ni 0"); }else{ originaltext += node.getdata(); node = root; } } bis.close(); } i've been stuck @ several hours , don't know do, doing wrong? or malfunction of classes bitoutputstream , bitinputstream? in advance. classes pretty big had erase comments fit w/o making mess here's bitinputstream:
public class bitinputstream extends inputstream { private static final int default_buffer_size = 4096; private byte[] buf; private int bufsize; private int pos; private int bits; private int bitsize; private int unreadsize; private inputstream in; private boolean fillbytebuffer() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if ((bufsize = in.read(buf, 0, buf.length)) == -1) { pos = -1; unreadsize = 0; return false; } pos = 0; return true; } public bitinputstream(inputstream in, int size) { if (in == null) { throw new nullpointerexception("the stream in null"); } if (size <= 0) { throw new illegalargumentexception("a buffer size of " + size + " illegal!"); } buf = new byte[size]; this.in = in; } public bitinputstream(inputstream in) { this(in, default_buffer_size); } public bitinputstream(string filename, int size) throws filenotfoundexception { this(new fileinputstream(filename), size); } public bitinputstream(string filename) throws filenotfoundexception { this(new fileinputstream(filename)); } public static bitinputstream fromfile(string filename) throws filenotfoundexception { return new bitinputstream(new fileinputstream(filename)); } public static bitinputstream frombytearray(byte[] b) { if (b == null) { throw new nullpointerexception("the byte array b null!"); } int size = default_buffer_size; if (b.length < size) { size = b.length; } return new bitinputstream(new bytearrayinputstream(b), size); } @override public int available() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } return bitsize + 8 * (bufsize - pos + in.available()); } @override public int read() throws ioexception { unreadsize = 8; // maximal number of bits unread if (bitsize < 8) // bit buffer needs more bits { if (pos >= bufsize) // byte array need refill? { if (fillbytebuffer() == false) { return -1; } } bits <<= 8; // makes room 8 new bits bits |= (buf[pos++] & 0xff); // byte (8 bits) added return (bits >> bitsize) & 0xff; // 8 bits returned } // end of if (bitsize < 8) bitsize -= 8; return (bits >> bitsize) & 0xff; // 8 bits returned } public int readbit() throws ioexception { unreadsize = 1; if (bitsize <= 0) // bit buffer empty { if (pos >= bufsize) // byte array need refill? { if (fillbytebuffer() == false) { return -1; } } bits = (buf[pos++] & 0xff); // 8 bits added bitsize = 8; // bitsize updated } // if (bitsize <= 0) bitsize--; return (bits >> bitsize) & 1; } public int readbits(int numberofbits) throws ioexception { if (numberofbits < 0) { throw new illegalargumentexception("cannot read " + numberofbits + " bits!"); } // / 1. numberofbits <= 25, common case ///////// if (numberofbits <= 25) { while (bitsize < numberofbits) // not create overflow { if (pos >= bufsize) // byte array need refill? { if (fillbytebuffer() == false) { return -1; } } bits <<= 8; // makes room 8 new bits bits |= (buf[pos++] & 0xff); // byte (8 bits) added bitsize += 8; // bitsize updated } // end while bitsize -= numberofbits; // bitsize updated unreadsize = numberofbits; // unreadsize updated return (bits >> bitsize) & ~(-1 << numberofbits); } // / 2. numberofbits > 25 ///////////////////// while (bitsize < 25) // not create overflow { if (pos >= bufsize) // byte array need refill? { if (fillbytebuffer() == false) { return -1; } } bits <<= 8; // makes room 8 new bits bits |= (buf[pos++] & 0xff); // byte (8 bits) added bitsize += 8; // bitsize updated } // end while // / 3. numberofbits < bitsize ///////////////////// if (numberofbits < bitsize) // enough bits in buffer! { bitsize -= numberofbits; // bitsize updated unreadsize = numberofbits; // unreadsize updated return (bits >> bitsize) & ~(-1 << numberofbits); } // / 4. numberofbits == bitsize ///////////////////// if (numberofbits == bitsize) { // continue need sure numberofbits not // out of range, i.e. not equal 32 or greater. if (numberofbits > 31) { throw new illegalargumentexception("cannot read " + numberofbits + " bits!"); } bitsize = 0; // bitsize updated unreadsize = numberofbits; // unreadsize updated return bits & ~(-1 << numberofbits); } // / 5. numberofbits > bitsize ///////////////////// int copy = bits & ~(-1 << bitsize); // bit buffer copy if (pos >= bufsize) // byte array need refill? { if (fillbytebuffer() == false) { return -1; } } bits <<= 8; // makes room 8 new bits bits |= (buf[pos++] & 0xff); // byte (8 bits) added int diff = numberofbits - bitsize; bitsize = 8 - diff; // bitsize updated unreadsize = diff + 24; // unreadsize updated return (copy << diff) | ((bits >> bitsize) & ~(-1 << diff)); } public int skip() throws ioexception { unreadsize = 0; // no unread subsequent skip if (bitsize < 8) // more bits bit buffer { if (pos >= bufsize) // byte array need refill? { if (fillbytebuffer() == false) { int skipsize = bitsize; bitsize = 0; return skipsize; // equal number of bits skipped } } bits <<= 8; // make room 8 bits bits |= (buf[pos++] & 0xff); // byte (8 bits) added return 8; // 8 bits skipped } // end of if (bitsize < 8) bitsize -= 8; return 8; // 8 bits skipped } @override public long skip(long n) throws ioexception { throw new unsupportedoperationexception(); } public void unreadbit() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if (unreadsize <= 0) { throw new illegalstateexception("no bits unread!"); } unreadsize--; bitsize++; } public void unreadbits() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } bitsize += unreadsize; unreadsize = 0; } public void unreadbits(int numberofbits) throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if (numberofbits < 0 || numberofbits > unreadsize) { throw new illegalargumentexception("illegal number of bits!"); } unreadsize -= numberofbits; bitsize += numberofbits; } public int unreadsize() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } return unreadsize; } public void insertbit(int bit) throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if (bitsize == 32) { throw new illegalstateexception("no bits can inserted!"); } bits = ((bits & (-1 << bitsize)) << 1) | ((bit & 1) << bitsize) | (bits & ((1 << bitsize) - 1)); if (unreadsize > 0) { unreadsize--; } bitsize++; } public void insert0bit() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if (bitsize == 32) { throw new illegalstateexception("no bits can inserted!"); } bits = ((bits & (-1 << bitsize)) << 1) | (bits & ((1 << bitsize) - 1)); if (unreadsize > 0) { unreadsize--; } bitsize++; } public void insert1bit() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if (bitsize == 32) { throw new illegalstateexception("no bits can inserted!"); } bits = ((bits & (-1 << bitsize)) << 1) | (1 << bitsize) | (bits & ((1 << bitsize) - 1)); if (unreadsize > 0) { unreadsize--; } bitsize++; } public void insertbits(int value, int numberofbits) throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } if (numberofbits < 0 || numberofbits > insertsize()) { throw new illegalargumentexception("numberofbits large!"); } if (numberofbits == 32) // bitsize = 0 { bits = value; } else { bits = (bits & ((1 << bitsize) - 1)) | ((bits & (~((1 << bitsize) - 1))) << numberofbits) | ((value & ((1 << numberofbits) - 1)) << bitsize); } unreadsize -= numberofbits; if (unreadsize < 0) { unreadsize = 0; } bitsize += numberofbits; } public int insertsize() throws ioexception { if (in == null) { throw new ioexception("the stream closed!"); } return 32 - bitsize; } @override protected void finalize() throws throwable { super.finalize(); if (in != null) { close(); } } @override public void close() throws ioexception { // second call close have no effect if (in == null) { return; } in.close(); in = null; buf = null; pos = -1; bufsize = -1; bitsize = -1; } } and here's bitoutputstream:
public class bitoutputstream extends outputstream { private static final int default_buffer_size = 4096; private byte buf[]; private int bufsize; private int pos; private int bits; private int bitsize; private outputstream out; public bitoutputstream(outputstream out, int size) { if (out == null) { throw new nullpointerexception("the stream out null"); } if (size <= 0) { throw new illegalargumentexception("the size(" + size + ") <= 0"); } buf = new byte[bufsize = size]; this.out = out; } public bitoutputstream(outputstream out) { this(out, default_buffer_size); } public bitoutputstream(string filename, int size) throws filenotfoundexception { this(new fileoutputstream(filename), size); } public bitoutputstream(string filename) throws filenotfoundexception { this(new fileoutputstream(filename), default_buffer_size); } public static bitoutputstream tofile(string filename) throws filenotfoundexception { return new bitoutputstream(new fileoutputstream(filename)); } public static bitoutputstream tofile(string filename, boolean append) throws filenotfoundexception { return new bitoutputstream(new fileoutputstream(filename, append)); } private void flushbuffer() throws ioexception { if (out == null) { throw new ioexception("the stream closed!"); } if (pos > 0) { out.write(buf, 0, pos); pos = 0; } } // end flushbuffer public void writebit(int bit) throws ioexception { bits <<= 1; // bit can added bits |= (bit & 1); // last bit of parameter bit added bitsize++; // bitsize updated if (bitsize >= 8) // byte can moved byte buffer { bitsize = 0; // byte buffer flushed if full if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) bits; // byte moved } } // end writebit public void write0bit() throws ioexception { bits <<= 1; // adds 0-bit bitsize++; // bitsize updated if (bitsize >= 8) // byte can moved byte buffer { bitsize = 0; // byte buffer flushed if full if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) bits; // byte moved } } // end write0bit public void write1bit() throws ioexception { bits <<= 1; // bit can added bits |= 1; // adds 1-bit bitsize++; // bitsize updated if (bitsize >= 8) // byte can moved byte buffer { bitsize = 0; // byte buffer flushed if full if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) bits; // byte moved } } // end write1bit @override public void write(int b) throws ioexception { bits <<= 8; // 8 bits can added bits |= (b & 0xff); // adds 8 rightmost bits of b // byte buffer flushed if full if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); // byte moved } // end write public void writebits(int value, int numberofbits) throws ioexception { if (numberofbits < 0) { throw new illegalargumentexception("cannot write " + numberofbits + " bits!"); } if (numberofbits <= 25) // common case { bits <<= numberofbits; // not create overflow bits |= (value & ((1 << numberofbits) - 1)); // bits added bitsize += numberofbits; // bitsize updated while (bitsize >= 8) { bitsize -= 8; // byte buffer flushed if full if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); // byte moved } } else if (numberofbits <= 32) { int k = numberofbits - 25; // 1 <= k <= 7 bits <<= 25; // 25 bits can added bits |= (value >> k) & 0x1ffffff; // 25 bits added bitsize += 25; // bitsize updated // bit buffer contains @ least 25 bits, // 24 of them moved byte buffer bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); bits <<= k; // k bits can added bits |= (value & ((1 << k) - 1)); // rightmost k bits of value bitsize += k; // bitsize updated if (bitsize >= 8) // 2 <= bitsize <= 15 { bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); // byte moved } } else { throw new illegalargumentexception("cannot write " + numberofbits + " bits!"); } } // end writebits public void writebits(int value) throws ioexception { // must find number of significant bits of value int signifcantbits = 31, v = value; if (v >>> 16 == 0) { signifcantbits -= 16; v <<= 16; } if (v >>> 24 == 0) { signifcantbits -= 8; v <<= 8; } if (v >>> 28 == 0) { signifcantbits -= 4; v <<= 4; } if (v >>> 30 == 0) { signifcantbits -= 2; v <<= 2; } signifcantbits += v >>> 31; bitsize += signifcantbits; if (bitsize <= 32) { bits <<= signifcantbits; // not create overflow bits |= value; // signifcantbits added while (bitsize >= 8) { bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); } } else { int k = bitsize - 32; bits <<= signifcantbits - k; bits |= value >>> k; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> 24); if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> 16); if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> 8); if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) bits; bits = value; bitsize = k; } } // end writebits public void writeleftbits(int value, int numberofbits) throws ioexception { if (numberofbits < 0) { throw new illegalargumentexception("cannot write negative (" + numberofbits + ") number of bits!"); } if (numberofbits <= 25) // common case { bits <<= numberofbits; // not create overflow bits |= (value >>> (32 - numberofbits)); // bits added bitsize += numberofbits; // bitsize updated while (bitsize >= 8) { bitsize -= 8; // byte buffer flushed if full if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); // byte moved } } else if (numberofbits <= 32) { bits <<= 25; // 25 bits can added bits |= (value >>> 7); // 25 bits added bitsize += 25; // bitsize updated // bit buffer contains @ least 25 bits, // 24 of them moved byte buffer bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); int k = numberofbits - 25; // 1 <= k <= 7 bits <<= k; // missing k bits can added bits |= ((value >>> (32 - numberofbits)) & ((1 << k) - 1)); bitsize += k; // bitsize updated if (bitsize >= 8) // 2 <= bitsize <= 15 { bitsize -= 8; if (pos >= bufsize) { flushbuffer(); } buf[pos++] = (byte) (bits >> bitsize); // byte moved } } else { throw new illegalargumentexception("cannot write " + numberofbits + " bits!"); } } // end writebits public void writeleftbits(int value) throws ioexception { writeleftbits(value, 32 - integer.numberoftrailingzeros(value)); } // end writebits @override public void flush() throws ioexception { if (bitsize > 0) { // byte buffer written ouput stream if full if (pos >= bufsize) { flushbuffer(); } // 0-bits added create full byte buf[pos++] = (byte) (bits <<= (8 - bitsize)); bitsize = 0; } flushbuffer(); out.flush(); } // end flush() public int missingbits() throws ioexception { if (out == null) { throw new ioexception("the stream closed!"); } return bitsize == 0 ? 0 : 8 - bitsize; } @override protected void finalize() throws throwable { super.finalize(); if (out != null) { close(); } } @override public void close() throws ioexception { // second call close have no effect if (out == null) { return; } flush(); out.close(); out = null; buf = null; pos = bufsize = -1; bitsize = 8; } // end close() public static string tobitstring(byte[] b) { stringbuilder s = new stringbuilder(); string[] fourbits = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; (int c : b) { s.append(fourbits[(c & 255) >> 4]); s.append(fourbits[c & 15]); s.append(' '); } return s.tostring(); } } // end class bitoutputstream
i found https://github.com/nayuki/huffman-coding/tree/master/src/nayuki/huffmancoding related huffman coding. might useful.
if can provide bitinputstream / bitoutputstream classes, think problem there, better answer based on codes can suggested.
Comments
Post a Comment