1 package nom.tam.fits.compression.algorithm.rice;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 import java.nio.ByteBuffer;
35
36
37
38
39
40
41
42
43 @SuppressWarnings("javadoc")
44 public class BitBuffer {
45
46 private static final int BITS_OF_4_BYTES = 32;
47
48 private static final int BYTE_MASK = 0xFF;
49
50 private static final long INTEGER_MASK = 0xFFFFFFFFL;
51
52 private static final int BITS_OF_1_BYTE = 8;
53
54 private static final int BITS_OF_2_BYTES = 16;
55
56 private static final int BITS_OF_3_BYTES = 24;
57
58 private static final int BYTE_1_OF_INT = 0x000000FF;
59
60 private static final int BYTE_2_OF_INT = 0x0000FF00;
61
62 private static final int BYTE_3_OF_INT = 0x00FF0000;
63
64 private static final int BYTE_4_OF_INT = 0xFF000000;
65
66 private final ByteBuffer buffer;
67
68 private long position;
69
70 public BitBuffer(ByteBuffer writeBuffer) {
71 buffer = writeBuffer;
72 }
73
74 public int bitbuffer() {
75 return buffer.get((int) (position / BITS_OF_1_BYTE));
76 }
77
78 void close() {
79 if (position % BITS_OF_1_BYTE != 0) {
80 putByte((byte) 0, (int) (BITS_OF_1_BYTE - position % BITS_OF_1_BYTE));
81 }
82 buffer.position((int) (position / BITS_OF_1_BYTE));
83 }
84
85 public int missingBitsInCurrentByte() {
86 return (int) (BITS_OF_1_BYTE - position % BITS_OF_1_BYTE);
87 }
88
89 public void movePosition(int i) {
90 position += i;
91 }
92
93 public void putByte(byte byteToAdd) {
94 final int bytePosition = (int) (position / BITS_OF_1_BYTE);
95 final int positionInByte = (int) (position % BITS_OF_1_BYTE);
96 final byte old = (byte) (buffer.get(bytePosition) & (byte) ~(BYTE_MASK >>> positionInByte));
97 final int byteAsInt = byteToAdd & BYTE_MASK;
98 buffer.put(bytePosition, (byte) (old | (byte) (byteAsInt >>> positionInByte)));
99 if (positionInByte > 0) {
100 buffer.put(bytePosition + 1, (byte) (byteAsInt << BITS_OF_1_BYTE - positionInByte));
101 }
102 position += BITS_OF_1_BYTE;
103 }
104
105 public void putByte(byte byteToAdd, int bits) {
106 final int bytePosition = (int) (position / BITS_OF_1_BYTE);
107 final int positionInByte = (int) (position % BITS_OF_1_BYTE);
108 final byte old = buffer.get(bytePosition);
109 final int byteAsInt = BYTE_MASK & (byteToAdd & BYTE_MASK >>> BITS_OF_1_BYTE - bits) << BITS_OF_1_BYTE - bits;
110 buffer.put(bytePosition, (byte) (BYTE_MASK &
111 (old & BYTE_MASK << BITS_OF_1_BYTE - positionInByte | byteAsInt >>> positionInByte)));
112 if (BITS_OF_1_BYTE - positionInByte < bits) {
113 buffer.put(bytePosition + 1, (byte) (BYTE_MASK & byteAsInt << BITS_OF_1_BYTE - positionInByte));
114 }
115 position += bits;
116 }
117
118
119
120
121
122
123 public void putInt(int i) {
124 putByte((byte) ((i & BYTE_4_OF_INT) >>> BITS_OF_3_BYTES));
125 putByte((byte) ((i & BYTE_3_OF_INT) >>> BITS_OF_2_BYTES));
126 putByte((byte) ((i & BYTE_2_OF_INT) >>> BITS_OF_1_BYTE));
127 putByte((byte) (i & BYTE_1_OF_INT));
128 }
129
130 public void putInt(int i, int bits) {
131 if (bits == 0) {
132 return;
133 }
134 do {
135 if (bits >= BITS_OF_1_BYTE) {
136 putByte((byte) ((i & BYTE_MASK << bits - BITS_OF_1_BYTE) >>> bits - BITS_OF_1_BYTE & BYTE_MASK));
137 bits -= BITS_OF_1_BYTE;
138 } else {
139 putByte((byte) (i & BYTE_MASK >> -(bits - BITS_OF_1_BYTE)), bits);
140 bits = 0;
141 }
142 } while (bits > 0);
143 }
144
145 public void putLong(long l, int bits) {
146 if (bits == 0) {
147 return;
148 }
149 do {
150 if (bits >= BITS_OF_4_BYTES) {
151 putInt((int) ((l & INTEGER_MASK << bits - BITS_OF_4_BYTES) >>> bits - BITS_OF_4_BYTES));
152 bits -= BITS_OF_4_BYTES;
153 } else {
154 putInt((int) (l & INTEGER_MASK >> -(bits - BITS_OF_4_BYTES)), bits);
155 bits = 0;
156 }
157 } while (bits > 0);
158 }
159
160 }