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 }