001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2015
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
029package edu.wisc.ssec.mcidasv.data;
030
031import edu.wisc.ssec.mcidasv.data.McIdasXInfo;
032import edu.wisc.ssec.mcidasv.data.McIdasXFrameInfo;
033
034import java.util.List;
035import java.util.StringTokenizer;
036
037import java.awt.Image;
038
039import ucar.unidata.util.ColorTable;
040
041/**
042 * Class to hold McIdas-X frame datasets
043 */
044public 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} 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}