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.mcidasv.data.McIdasXFrameInfo;
033    
034    import java.util.List;
035    import java.util.StringTokenizer;
036    
037    import java.awt.Image;
038    
039    import ucar.unidata.util.ColorTable;
040    
041    /**
042     * Class to hold McIdas-X frame datasets
043     */
044    public class McIdasFrame {
045        
046        /** frame data */
047        private int myFrameNumber = 0;
048        private McIdasXFrameInfo myXFrameInfo;
049        
050        /** Keep local copies of everything so we dont have to go back over the bridge unless asked to refresh */
051        private int myLineSize = -1;
052        private int myElementSize = -1;
053        private FrameDirectory myFrameDirectory;
054        private ColorTable myColorTable;
055        private byte[] myImage;
056        private byte[] myGraphics;
057        
058        /**
059         *  Empty constructor for XML encoding
060         */
061        public McIdasFrame() {}
062    
063        /**
064         * Construct a new McIdasFrame from the given frame number
065         *
066         * @param frameNumber       frame number
067         */
068        public McIdasFrame(int frameNumber, McIdasXInfo xInfo) {
069    //      System.out.println("McIdasFrame constructor for frame: " + frameNumber);
070            this.myFrameNumber = frameNumber;
071            this.myXFrameInfo = new McIdasXFrameInfo(frameNumber, xInfo);
072        }
073        
074        /** Get frame number */
075        public int getFrameNumber() {
076    //      System.out.println("McIdasFrame getFrameNumber: " + this.myFrameNumber);
077            return this.myFrameNumber;
078        }
079        
080        /** Tell the XFrameInfo to refresh the cached data */
081        public void setRefreshData(boolean refresh) {
082    //              System.out.println("McIdasFrame setRefreshData(" + refresh + ")");
083            this.myXFrameInfo.setRefreshData(refresh);
084        }
085    
086        /** Get frame data */
087        public int getLineSize(boolean refresh) {
088    //              System.out.println("McIdasFrame getLineSize(" + refresh + ")");
089            if (this.myLineSize <0 || refresh) {
090                    this.myLineSize = this.myXFrameInfo.getLineSize();
091            }
092            return this.myLineSize;
093        }
094    
095        /** Get frame data */
096        public int getElementSize(boolean refresh) {
097    //              System.out.println("McIdasFrame getElementSize(" + refresh + ")");
098            if (this.myElementSize <0 || refresh) {
099                    this.myElementSize = this.myXFrameInfo.getElementSize();
100            }
101            return this.myElementSize;
102        }
103    
104        /** Get Frame Directory */
105            public FrameDirectory getFrameDirectory(boolean refresh) {
106    //              System.out.println("McIdasFrame getFrameDirectory(" + refresh + ")");
107                    if (this.myFrameDirectory == null || refresh) {
108                            this.myFrameDirectory = new FrameDirectory(this.myXFrameInfo.getFrameDirectory());
109                    }
110            return this.myFrameDirectory;
111        }
112    
113            /** Get Color Table */
114            public ColorTable getColorTable(boolean refresh) {
115    //              System.out.println("McIdasFrame getColorTable(" + refresh + ")");
116                    if (this.myColorTable == null || refresh) {
117                            this.myColorTable = new ColorTable("McIDAS-X",ColorTable.CATEGORY_BASIC,
118                                            this.myXFrameInfo.getEnhancementTable());
119                    }
120            return this.myColorTable;
121        }
122            
123        /** Get image data */
124        public byte[] getImageData(boolean refresh) {
125    //              System.out.println("McIdasFrame getImageData(" + refresh + ")");
126            if (this.myImage == null || refresh) {
127                    byte[] image = this.myXFrameInfo.getImage();
128                    int height = this.myLineSize;
129                    int width = this.myElementSize;
130                this.myImage = new byte[height*width];
131                    for (int i=0; i<height; i++) {
132                            for (int j=0; j<width; j++) {
133                                    this.myImage[i*width + j] = image[(height-i-1)*width + j];
134                            }
135                    }
136            }
137            return this.myImage;
138        }
139    
140        /** Get graphics data */
141            public byte[] getGraphicsData(boolean refresh) {
142    //              System.out.println("McIdasFrame getGraphicsData(" + refresh + ")");
143            if (this.myGraphics == null || refresh) {
144                List graphics = this.myXFrameInfo.getGraphics();
145                    int height = this.myLineSize;
146                    int width = this.myElementSize;
147                this.myGraphics = new byte[height*width];
148                    for (int i=0; i<this.myGraphics.length; i++) {
149                            this.myGraphics[i] = (byte)255;
150                    }
151                String line;
152                StringTokenizer tok;
153                int[] graphicsPt = new int[3];
154                for (int i=0; i<graphics.size(); i++) {
155                    line = (String)(graphics.get(i));
156                    tok = new StringTokenizer(line);
157                    for (int j=0; j<3; j++) {
158                        graphicsPt[j] = new Integer(tok.nextToken()).intValue();
159                    }
160                    int color = graphicsPt[2];
161                    int x = graphicsPt[1] - 1;
162                    int y = graphicsPt[0] - 1;
163                    if (((y<height)&&(y>0)) && ((x<width)&&(x>0))) {
164                        this.myGraphics[y*width + x] = (byte)color;
165                    }
166                }
167            }
168            return this.myGraphics;
169            }
170            
171        /** Get image data */
172        public Image getGIF() {
173            return this.myXFrameInfo.getGIF();
174        }
175            
176        /**
177         * See if this McIdasFrame is equal to the object in question
178         *
179         * @param o   object in question
180         * @return  true if <code>o</code> is a McIdasFrame and
181         *          they area equivalent
182         */
183        public boolean equals(Object o) {
184            if ( !(o instanceof McIdasFrame)) {
185                return false;
186            }
187            McIdasFrame that = (McIdasFrame) o;
188    //        System.out.println("McIdasFrame equals: " + this.toString() + " vs " + that.toString());
189            return (this.myFrameNumber == that.myFrameNumber);
190        }
191    
192        /**
193         * Get a String representation of this object
194         * 
195         * @return a string representation
196         */
197        public String toString() {
198            StringBuffer buf = new StringBuffer();
199            if (this.myFrameNumber > 0) {
200              buf.append("Frame " + this.myFrameNumber);
201            }
202    //      System.out.println("McIdasFrame toString: " + buf);
203            return buf.toString();
204        }
205      
206    }