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    }