1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.tiff.itu_t4;
18
19 import java.io.OutputStream;
20 import java.util.Arrays;
21
22 import org.apache.commons.imaging.common.Allocator;
23
24
25
26
27 final class BitArrayOutputStream extends OutputStream {
28 private byte[] buffer;
29 private int bytesWritten;
30 private int cache;
31 private int cacheMask = 0x80;
32
33 BitArrayOutputStream() {
34 buffer = new byte[16];
35 }
36
37 BitArrayOutputStream(final int size) {
38 buffer = Allocator.byteArray(size);
39 }
40
41 @Override
42 public void close() {
43 flush();
44 }
45
46 @Override
47 public void flush() {
48 if (cacheMask != 0x80) {
49 writeByte(cache);
50 cache = 0;
51 cacheMask = 0x80;
52 }
53 }
54
55 public int getBitsAvailableInCurrentByte() {
56 int count = 0;
57 for (int mask = cacheMask; mask != 0; mask >>>= 1) {
58 ++count;
59 }
60 return count;
61 }
62
63 public int size() {
64 return bytesWritten;
65 }
66
67 public byte[] toByteArray() {
68 flush();
69 if (bytesWritten == buffer.length) {
70 return buffer;
71 }
72 return Arrays.copyOf(buffer, bytesWritten);
73 }
74
75 @Override
76 public void write(final int b) {
77 flush();
78 writeByte(b);
79 }
80
81 public void writeBit(final int bit) {
82 if (bit != 0) {
83 cache |= cacheMask;
84 }
85 cacheMask >>>= 1;
86 if (cacheMask == 0) {
87 flush();
88 }
89 }
90
91 private void writeByte(final int b) {
92 if (bytesWritten >= buffer.length) {
93 final byte[] bigger = Allocator.byteArray(buffer.length * 2);
94 System.arraycopy(buffer, 0, bigger, 0, bytesWritten);
95 buffer = bigger;
96 }
97 buffer[bytesWritten++] = (byte) b;
98 }
99 }