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