1 package edu.iris.dmc.seedcodec;
2
3 import java.io.*;
4
5 /***
6 * This class acts as a container to hold encoded bytes processed
7 * by a Steim compression routine, as well as supporting information
8 * relating to the data processed.
9 * It also facilitates Steim notation and the formation
10 * of the data frames.
11 * This class stores the Steim encoding, but is ignorant of the encoding
12 * process itself...it's just for self-referencing.
13 * @author Robert Casey (IRIS DMC)
14 * @version 12/10/2001
15 */
16
17 public class SteimFrameBlock {
18
19
20
21 /***
22 * Create a new block of Steim frames for a particular version of Steim
23 * copression.
24 * Instantiate object with the number of 64-byte frames
25 * that this block will contain (should connect to data
26 * record header such that a proper power of 2 boundary is
27 * formed for the data record) AND the version of Steim
28 * compression used (1 and 2 currently)
29 * the number of frames remains static...frames that are
30 * not filled with data are simply full of nulls.
31 * @param numFrames the number of frames in this Steim record
32 * @param steimVersion which version of Steim compression is being used
33 * (1,2,3).
34 */
35 public SteimFrameBlock (int numFrames, int steimVersion) {
36 steimFrame = new SteimFrame[numFrames];
37 for (int i = 0; i < steimFrame.length; i++) {
38
39 steimFrame[i] = new SteimFrame();
40 }
41 this.numFrames = numFrames;
42 this.steimVersion = steimVersion;
43
44
45 currentFrame = 0;
46 addEncodingNibble(0);
47 this.steimFrame[currentFrame].pos++;
48 }
49
50
51
52
53 /***
54 * Return the number of data samples represented by this frame block
55 * @return integer value indicating number of samples
56 */
57 public int getNumSamples () {
58 return numSamples;
59 }
60
61 /***
62 * Return the version of Steim compression used
63 * @return integer value representing the Steim version (1,2,3)
64 */
65 public int getSteimVersion () {
66 return steimVersion;
67 }
68
69 /***
70 * Return the compressed byte representation of the data for inclusion
71 * in a data record.
72 * @return byte array containing the encoded, compressed data
73 * @throws IOException from called method(s)
74 */
75 public byte[] getEncodedData () throws IOException {
76
77 ByteArrayOutputStream encodedData =
78 new ByteArrayOutputStream(numFrames * 64);
79
80 DataOutputStream intSerializer =
81 new DataOutputStream(encodedData);
82 for (int i = 0; i < numFrames; i++) {
83 for (int j = 0; j < 16; j++) {
84
85 intSerializer.writeInt(steimFrame[i].word[j]);
86 }
87 }
88
89 return encodedData.toByteArray();
90 }
91
92 /***
93 * Return the number of frames in this frame block
94 * @return integer value indicating number of frames
95 */
96 public int getNumFrames () {
97 return numFrames;
98 }
99
100
101
102
103 /***
104 * Add a single 32-bit word to current frame.
105 * @param samples the number of sample differences in the word
106 * @param nibble a value of 0 to 3 that reflects the W0 encoding
107 * for this word
108 * @return boolean indicating true if the block is full (ie: the
109 * calling app should not add any more to this object)
110 */
111 protected boolean addEncodedWord (int word, int samples, int nibble) {
112 int pos = steimFrame[currentFrame].pos;
113 steimFrame[currentFrame].word[pos] = word;
114 addEncodingNibble (nibble);
115 numSamples += samples;
116 pos++;
117 if (pos > 15) {
118 currentFrame++;
119 if (currentFrame >= numFrames) {
120 return true;
121 }
122 addEncodingNibble(0);
123 }
124 steimFrame[currentFrame].pos++;
125 return false;
126 }
127
128 /***
129 * Set the reverse integration constant X(N) explicitly to the
130 * provided word value.
131 * This method is typically used to reset X(N) should the compressor
132 * fill the frame block before all samples have been read.
133 * @param word integer value to be placed in X(N)
134 */
135 protected void setXsubN (int word) {
136 steimFrame[0].word[2] = word;
137 return;
138 }
139
140 /***
141 * Add encoding nibble to W0.
142 * @param bitFlag a value 0 to 3 representing an encoding nibble
143 */
144 private void addEncodingNibble (int bitFlag) {
145 int offset = steimFrame[currentFrame].pos;
146 int shift = (15 - offset)*2;
147 steimFrame[currentFrame].word[0] |= (bitFlag << shift);
148 return;
149 }
150
151
152
153
154 /***
155 * This represents a single Steim compression frame. It stores values
156 * as an int array and keeps track of it's current position in the frame.
157 */
158 private class SteimFrame {
159 public int[] word = new int[16];
160 public int pos = 0;
161 }
162
163
164
165
166 private int numFrames = 0;
167 private int numSamples = 0;
168 private int steimVersion = 0;
169 private int currentFrame = 0;
170 private SteimFrame[] steimFrame = null;
171 }