1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.mylzw;
18
19 import java.io.FilterOutputStream;
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.nio.ByteOrder;
23
24 final class MyBitOutputStream extends FilterOutputStream {
25
26 private final ByteOrder byteOrder;
27 private int bitsInCache;
28 private int bitCache;
29 private int bytesWritten;
30
31 MyBitOutputStream(final OutputStream os, final ByteOrder byteOrder) {
32 super(os);
33 this.byteOrder = byteOrder;
34 }
35
36 private void actualWrite(final int value) throws IOException {
37 out.write(value);
38 bytesWritten++;
39 }
40
41 public void flushCache() throws IOException {
42 if (bitsInCache > 0) {
43 final int bitMask = (1 << bitsInCache) - 1;
44 int b = bitMask & bitCache;
45
46 if (byteOrder == ByteOrder.BIG_ENDIAN) {
47
48 b <<= 8 - bitsInCache;
49 }
50 out.write(b);
51 }
52
53 bitsInCache = 0;
54 bitCache = 0;
55 }
56
57 public int getBytesWritten() {
58 return bytesWritten + (bitsInCache > 0 ? 1 : 0);
59 }
60
61 @Override
62 public void write(final int value) throws IOException {
63 writeBits(value, 8);
64 }
65
66
67
68 public void writeBits(int value, final int sampleBits) throws IOException {
69 final int sampleMask = (1 << sampleBits) - 1;
70 value &= sampleMask;
71
72 if (byteOrder == ByteOrder.BIG_ENDIAN) {
73
74 bitCache = bitCache << sampleBits | value;
75 } else {
76
77 bitCache |= value << bitsInCache;
78 }
79 bitsInCache += sampleBits;
80
81 while (bitsInCache >= 8) {
82 if (byteOrder == ByteOrder.BIG_ENDIAN) {
83
84 final int b = 0xff & bitCache >> bitsInCache - 8;
85 actualWrite(b);
86 } else {
87
88 final int b = 0xff & bitCache;
89 actualWrite(b);
90
91 bitCache >>= 8;
92 }
93 bitsInCache -= 8;
94 final int remainderMask = (1 << bitsInCache) - 1;
95 bitCache &= remainderMask;
96 }
97
98 }
99
100 }