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.FilterInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 import org.apache.commons.imaging.ImagingException;
24
25
26
27
28 final class BitInputStreamFlexible extends FilterInputStream {
29
30
31
32 private int cache;
33 private int cacheBitsRemaining;
34 private long bytesRead;
35
36 BitInputStreamFlexible(final InputStream is) {
37 super(is);
38 }
39
40 public void flushCache() {
41 cacheBitsRemaining = 0;
42 }
43
44 public long getBytesRead() {
45 return bytesRead;
46 }
47
48 @Override
49 public int read() throws IOException {
50 if (cacheBitsRemaining > 0) {
51 throw new ImagingException("BitInputStream: incomplete bit read");
52 }
53 return in.read();
54 }
55
56 public int readBits(int count) throws IOException {
57
58 if (count <= 32) {
59
60 int result = 0;
61
62
63 if (cacheBitsRemaining > 0) {
64 if (count >= cacheBitsRemaining) {
65 result = (1 << cacheBitsRemaining) - 1 & cache;
66 count -= cacheBitsRemaining;
67 cacheBitsRemaining = 0;
68 } else {
69
70 cacheBitsRemaining -= count;
71 result = (1 << count) - 1 & cache >> cacheBitsRemaining;
72 count = 0;
73 }
74 }
75 while (count >= 8) {
76 cache = in.read();
77 if (cache < 0) {
78 throw new ImagingException("Couldn't read bits");
79 }
80
81
82
83 bytesRead++;
84 result = result << 8 | 0xff & cache;
85 count -= 8;
86 }
87 if (count > 0) {
88 cache = in.read();
89 if (cache < 0) {
90 throw new ImagingException("Couldn't read bits");
91 }
92
93
94
95 bytesRead++;
96 cacheBitsRemaining = 8 - count;
97 result = result << count | (1 << count) - 1 & cache >> cacheBitsRemaining;
98 count = 0;
99 }
100
101 return result;
102 }
103
104 throw new ImagingException("BitInputStream: unknown error");
105
106 }
107 }