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