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    }