001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 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 029package edu.wisc.ssec.mcidasv.data; 030 031import edu.wisc.ssec.mcidas.AREAnav; 032 033import java.io.*; 034import java.util.ArrayList; 035import java.util.List; 036 037import java.awt.Image; 038import java.awt.Toolkit; 039 040import ucar.unidata.util.Misc; 041 042public class McIdasXFrameInfo { 043 044 private int myFrameNumber; 045 private McIdasXInfo myXInfo; 046 047 private int width = 0; 048 private int height = 0; 049 private int[] stretchTable = new int[256]; 050 private int[] colorTable = new int[256]; 051 private int[] graphicsTable = new int[256]; 052 053 private byte myImage[]; 054 055 private boolean isLoaded = false; 056 057 /** 058 * Constructor 059 */ 060 public McIdasXFrameInfo() { 061 this.myFrameNumber = 0; 062 this.myXInfo = new McIdasXInfo(); 063 this.isLoaded = false; 064 } 065 066 /** 067 * Copy constructor 068 * 069 * @param that The McIdasXFrameInfo to copy 070 * 071 */ 072 public McIdasXFrameInfo(McIdasXFrameInfo that) { 073 this.myFrameNumber = that.myFrameNumber; 074 this.myXInfo = that.myXInfo; 075 this.isLoaded = false; 076 } 077 078 /** 079 * Create a new McIDAS-X frame using the given frame number and 080 * {@literal "info"} object. 081 * 082 * @param frameNumber Frame number. 083 * @param xInfo McIDAS-X {@literal "info"} object. Cannot be {@code null}. 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}