001 /*
002 * $Id: McIdasXFrameInfo.java,v 1.9 2012/02/19 17:35:45 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.data;
032
033 import edu.wisc.ssec.mcidasv.data.McIdasXInfo;
034 import edu.wisc.ssec.mcidas.AREAnav;
035
036 import java.io.*;
037 import java.util.ArrayList;
038 import java.util.List;
039
040 import java.awt.Image;
041 import java.awt.Toolkit;
042
043 import ucar.unidata.util.Misc;
044
045 public class McIdasXFrameInfo {
046
047 private int myFrameNumber;
048 private McIdasXInfo myXInfo;
049
050 private int width = 0;
051 private int height = 0;
052 private int[] stretchTable = new int[256];
053 private int[] colorTable = new int[256];
054 private int[] graphicsTable = new int[256];
055
056 private byte myImage[];
057
058 private boolean isLoaded = false;
059
060 /**
061 * Constructor
062 */
063 public McIdasXFrameInfo() {
064 this.myFrameNumber = 0;
065 this.myXInfo = new McIdasXInfo();
066 this.isLoaded = false;
067 }
068
069 /**
070 * Copy constructor
071 *
072 * @param that The McIdasXFrameInfo to copy
073 *
074 */
075 public McIdasXFrameInfo(McIdasXFrameInfo that) {
076 this.myFrameNumber = that.myFrameNumber;
077 this.myXInfo = that.myXInfo;
078 this.isLoaded = false;
079 }
080
081 /**
082 * Copy constructor
083 *
084 * @param that The McIdasXFrameInfo to copy
085 *
086 */
087 public McIdasXFrameInfo(int frameNumber, McIdasXInfo xInfo) {
088 // System.out.println("McIdasXFrameInfo constructor: frame " + frameNumber + ", xInfo " + xInfo.toString());
089 this.myFrameNumber = frameNumber;
090 this.myXInfo = xInfo;
091 this.isLoaded = false;
092 }
093
094 public void setRefreshData(boolean refresh) {
095 if (refresh) this.isLoaded = false;
096 }
097
098 private int setFrameData() {
099 // System.out.println(" <=> setFrameData frame " + this.myFrameNumber);
100 int ret = -1;
101 DataInputStream inputStream = myXInfo.getDataInputStream(this.myFrameNumber);
102 try {
103 this.width = inputStream.readInt();
104 this.height = inputStream.readInt();
105 } catch (Exception e) {
106 System.out.println("getFrameData exception: " + e);
107 return ret;
108 }
109
110 if (!getTable(inputStream, stretchTable)) return ret;
111 if (!getTable(inputStream, colorTable)) return ret;
112 if (!getTable(inputStream, graphicsTable)) return ret;
113
114 int havebytes = 0;
115 int needbytes = this.width * this.height;
116 byte[] image = new byte[needbytes];
117 int count = 0;
118 int num = 0;
119 int indx = 0;
120 try {
121 while (needbytes > 0) {
122 num = inputStream.read(image, indx, needbytes);
123 indx += num;
124 havebytes += num;
125 needbytes -= num;
126 count++;
127 Misc.sleep(10);
128 if (count > 100) return ret;
129 }
130 } catch (Exception e) {
131 System.out.println("getFrameData exception: " + e);
132 return ret;
133 }
134 this.isLoaded = true;
135 this.myImage = image;
136 ret = 0;
137 return ret;
138 }
139
140 public List getGraphics() {
141 // System.out.println(" <=> getGraphics frame " + this.myFrameNumber);
142 DataInputStream inputStream = myXInfo.getGraphicsInputStream(this.myFrameNumber);
143 List graphics = new ArrayList();
144 int pixels = 0;
145 try {
146 BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
147 String lineOut = br.readLine();
148 while (lineOut != null) {
149 // System.out.println("getGraphics adding pixel: " + lineOut);
150 graphics.add(lineOut);
151 pixels++;
152 lineOut = br.readLine();
153 }
154 } catch (Exception e) {
155 System.out.println("getGraphics exception: " + e);
156 try { inputStream.close(); }
157 catch (Exception ee) {}
158 return graphics;
159 }
160 // System.out.println("getGraphics: " + pixels);
161 return graphics;
162 }
163
164 public int[] getFrameDirectory() {
165 // System.out.println(" <=> getFrameDirectory frame " + this.myFrameNumber);
166 String filename = "Frame" + this.myFrameNumber + ".0";
167 DataInputStream inputStream = myXInfo.getFileInputStream(filename);
168
169 int dirLength = 64;
170 int[] dir = getInts(inputStream, dirLength);
171
172 // The next byte tells us what type of nav we have...
173 // it also needs to be the first byte of the nav array
174 int navLength;
175 int[] navType = getInts(inputStream, 1);
176 if (navType[0] == AREAnav.LALO) navLength = 128;
177 else navLength = 640;
178 int[] navRest = getInts(inputStream, navLength - 1);
179 int[] nav = new int[navLength];
180 System.arraycopy(navType, 0, nav, 0, 1);
181 System.arraycopy(navRest, 0, nav, 1, navLength - 1);
182
183 int auxLength = 0;
184 int rows = 0;
185 int cols = 0;
186 int begLat= 0;
187 int begLon =0;
188 if (navLength == 128) {
189 rows = nav[65];
190 cols = nav[66];
191 begLat = nav[78]/4;
192 begLon = nav[79]/4;
193 auxLength = begLon + (rows*cols);
194 }
195 int[] aux = getInts(inputStream, auxLength);
196
197 int[] frmdir = new int[dirLength + navLength + auxLength];
198 System.arraycopy(dir, 0, frmdir, 0, dirLength);
199 System.arraycopy(nav, 0, frmdir, dirLength, navLength);
200 if (auxLength > 0)
201 System.arraycopy(aux, 0, frmdir, dirLength+navLength, auxLength);
202
203 try { inputStream.close(); }
204 catch (Exception ee) {}
205
206 return frmdir;
207 }
208
209 private boolean getTable(DataInputStream inputStream, int[] tbl) {
210 try {
211 for (int i=0; i<256; i++) {
212 tbl[i] = inputStream.readInt();
213 }
214 } catch (Exception e) {
215 System.out.println("getTable exception: " + e);
216 return false;
217 }
218 return true;
219 }
220
221 private int[] getInts(DataInputStream stream, int count) {
222 int[] buf = new int[count];
223 if (count < 1) return buf;
224
225 int havebytes=0;
226 int needbytes=count;
227
228 try {
229 while (havebytes<needbytes) {
230 buf[havebytes] = stream.readInt();
231 havebytes++;
232 }
233 } catch (Exception e) {
234 System.out.println("getInts exception: " + e);
235 return buf;
236 }
237
238 return buf;
239 }
240
241 public int getFrameNumber() {
242 return this.myFrameNumber;
243 }
244
245 public int getLineSize() {
246 if (!this.isLoaded) {
247 if (setFrameData() < 0) this.height = -1;
248 }
249 return this.height;
250 }
251
252 public int getElementSize() {
253 if (!this.isLoaded) {
254 if (setFrameData() < 0) this.width = -1;
255 }
256 return this.width;
257 }
258
259 public int[] getStretchTable() {
260 if (!this.isLoaded) {
261 if (setFrameData() < 0) this.stretchTable = new int[256];
262 }
263 return this.stretchTable;
264 }
265
266 public int[] getColorTable() {
267 if (!this.isLoaded) {
268 if (setFrameData() < 0) this.colorTable = new int[256];
269 }
270 return this.colorTable;
271 }
272
273 public int[] getGraphicsTable() {
274 if (!this.isLoaded) {
275 if (setFrameData() < 0) this.graphicsTable = new int[256];
276 }
277 return this.graphicsTable;
278 }
279
280 public float[][] getEnhancementTable() {
281 float[][] enhancementTable = new float[3][256];
282 if (!this.isLoaded) {
283 if (setFrameData() < 0) return enhancementTable;
284 }
285 for (int i=1; i<18; i++) {
286 enhancementTable[0][i] = (float)((this.colorTable[i]/0x10000)&0xff);
287 enhancementTable[1][i] = (float)((this.colorTable[i]/0x100)&0xff);
288 enhancementTable[2][i] = (float)(this.colorTable[i]&0xff);
289 }
290 for (int i=18; i<256; i++) {
291 enhancementTable[0][i] = (float)((this.colorTable[this.stretchTable[i]]/0x10000)&0xff);
292 enhancementTable[1][i] = (float)((this.colorTable[this.stretchTable[i]]/0x100)&0xff);
293 enhancementTable[2][i] = (float)(this.colorTable[this.stretchTable[i]]&0xff);
294 }
295 for (int i=0; i<256; i++) {
296 enhancementTable[0][i] /= 0xff;
297 enhancementTable[1][i] /= 0xff;
298 enhancementTable[2][i] /= 0xff;
299 }
300 return enhancementTable;
301 }
302
303 public byte[] getImage() {
304 if (!this.isLoaded) {
305 if (setFrameData() < 0) this.myImage = new byte[0];
306 }
307 return this.myImage;
308 }
309
310 public Image getGIF() {
311 int MAX_BYTES = 1048576;
312 byte[] imagebytes = new byte[MAX_BYTES];
313 DataInputStream inputStream = this.myXInfo.getGIFInputStream(this.myFrameNumber);
314 int n = 0;
315 int i = 0;
316 for (n=0; n<MAX_BYTES; n++) {
317 try {
318 i = inputStream.read();
319 } catch (Exception ee) { }
320 if (i < 0) break;
321 imagebytes[n] = (byte)i;
322 }
323 byte[] gifbytes = new byte[n];
324 System.arraycopy(imagebytes, 0, gifbytes, 0, n);
325 Image imageGIF = Toolkit.getDefaultToolkit().createImage(gifbytes);
326 imagebytes = null;
327 try { inputStream.close(); }
328 catch (Exception ee) {}
329 return imageGIF;
330 }
331
332 }