/*
* Open Source Physics software is free software as described near the bottom of this code file.
*
* For additional information and documentation on Open Source Physics please see:
* <http://www.opensourcephysics.org/>
*/
package org.opensourcephysics.display2d;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BandedSampleModel;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import org.opensourcephysics.display.Dimensioned;
import org.opensourcephysics.display.DrawingPanel;
import org.opensourcephysics.display.MeasuredImage;
/**
* A IntegerRaster contains an array of integers where each integer represents an image pixel.
*
* Because the image created by a IntegerRaster cannot be resized, the image dimensions
* are the same as the dimensions of the integer array.
*
* @author Wolfgang Christian
* @created February 11, 2003
* @version 1.0
*/
public class IntegerRaster extends MeasuredImage implements Dimensioned {
public static int WHITE = 0xFFFFFF;
WritableRaster raster;
byte[][] rgbData;
int nrow, ncol;
boolean visible = true;
Dimension dimension;
protected double scaleFactor = 1;
/**
* Constructs IntegerRaster with the given size.
* @param _nrow the number of rows
* @param _ncol the number of columns
*/
public IntegerRaster(int _nrow, int _ncol) {
nrow = _nrow;
ncol = _ncol;
dimension = new Dimension(ncol, nrow);
int size = nrow*ncol;
ComponentColorModel ccm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8, 8, 8}, false, // hasAlpha
false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
BandedSampleModel csm = new BandedSampleModel(DataBuffer.TYPE_BYTE, ncol, nrow, ncol, new int[] {0, 1, 2}, new int[] {0, 0, 0});
rgbData = new byte[3][size];
DataBuffer databuffer = new DataBufferByte(rgbData, size);
WritableRaster raster = Raster.createWritableRaster(csm, databuffer, new Point(0, 0));
image = new BufferedImage(ccm, raster, false, null);
// col in x direction, row in y direction
xmin = 0;
xmax = ncol;
ymin = nrow;
ymax = 0; // zero is on top
}
/**
* Sets a block of lattice cells to new values.
*
* @param row_offset
* @param col_offset
* @param val
*/
public void setBlock(int row_offset, int col_offset, int val[][]) {
if((row_offset<0)||(row_offset+val.length>nrow)) {
throw new IllegalArgumentException("Row index out of range in integer raster setBlock."); //$NON-NLS-1$
}
if((col_offset<0)||(col_offset+val[0].length>ncol)) {
throw new IllegalArgumentException("Column index out of range in integer raster setBlock."); //$NON-NLS-1$
}
for(int rindex = row_offset, nr = val.length+row_offset; rindex<nr; rindex++) {
for(int cindex = col_offset, nc = val[0].length+col_offset; cindex<nc; cindex++) {
int index = rindex*ncol+cindex;
int pixval = val[rindex-row_offset][cindex-col_offset];
rgbData[0][index] = (byte) ((pixval>>16)&0xFF); // red
rgbData[1][index] = (byte) ((pixval>>8)&0xFF); // green
rgbData[2][index] = (byte) ((pixval>>0)&0xFF); // blue
}
}
}
/**
* Sets a row of lattice cells to new values.
*
* @param row
* @param col_offset
* @param val
*/
public void setRow(int row, int col_offset, int val[]) {
if((row<0)||(row>=nrow)) {
throw new IllegalArgumentException("Row index out of range in integer raster setBlock."); //$NON-NLS-1$
}
if((col_offset<0)||(col_offset+val.length>ncol)) {
throw new IllegalArgumentException("Column index out of range in integer raster setBlock."); //$NON-NLS-1$
}
for(int cindex = col_offset, nc = val.length+col_offset; cindex<nc; cindex++) {
int index = row*ncol+cindex;
int pixval = val[cindex-col_offset];
rgbData[0][index] = (byte) ((pixval>>16)&0xFF); // red
rgbData[1][index] = (byte) ((pixval>>8)&0xFF); // green
rgbData[2][index] = (byte) ((pixval>>0)&0xFF); // blue
}
}
/**
* Sets a column of lattice cells to new values.
*
* @param row_offset
* @param col
* @param val
*/
public void setCol(int row_offset, int col, int val[]) {
if((row_offset<0)||(row_offset+val.length>nrow)) {
throw new IllegalArgumentException("Row index out of range in integer raster setBlock."); //$NON-NLS-1$
}
if((col<0)||(col>=ncol)) {
throw new IllegalArgumentException("Column index out of range in integer raster setBlock."); //$NON-NLS-1$
}
for(int rindex = row_offset, nr = val.length+row_offset; rindex<nr; rindex++) {
int index = rindex*ncol+col;
int pixval = val[rindex-row_offset];
rgbData[0][index] = (byte) ((pixval>>16)&0xFF); // red
rgbData[1][index] = (byte) ((pixval>>8)&0xFF); // green
rgbData[2][index] = (byte) ((pixval>>0)&0xFF); // blue
}
}
/**
* Sets a lattice cell to a new value.
*/
public void setCell(int _row, int _col, int val) {
int index = _row*ncol+_col;
rgbData[0][index] = (byte) ((val>>16)&0xFF); // red
rgbData[1][index] = (byte) ((val>>8)&0xFF); // green
rgbData[2][index] = (byte) ((val>>0)&0xFF); // blue
}
/**
* Gets a lattice cell value.
*
* @return the cell value.
*/
public int getCell(int _row, int _col) {
int index = _row*ncol+_col;
return((rgbData[0][index]&0xFF)<<16)|((rgbData[1][index]&0xFF)<<8)|((rgbData[2][index]&0xFF)<<0);
}
/**
* Gets the dimension of the lattice in pixel units.
*
* @param panel
* @return the dimension
*/
public Dimension getInterior(DrawingPanel panel) {
float availableWidth = panel.getWidth()-panel.getLeftGutter()-panel.getRightGutter()-1;
float availableHeight = panel.getHeight()-panel.getTopGutter()-panel.getBottomGutter()-1;
scaleFactor = Math.min(availableWidth/dimension.width, availableHeight/dimension.height);
if(scaleFactor>1) {
scaleFactor = 1;
return dimension;
}
return new Dimension((int) (scaleFactor*ncol), (int) (scaleFactor*nrow));
}
/**
* Draws the image and the grid.
* @param panel
* @param g
*/
public void draw(DrawingPanel panel, Graphics g) {
if(scaleFactor<1) {
g.drawImage(image.getScaledInstance((int) (scaleFactor*image.getWidth()), (int) (scaleFactor*image.getHeight()), java.awt.Image.SCALE_REPLICATE), panel.getLeftGutter(), panel.getTopGutter(), panel);
} else {
//g.drawImage(image, 1+panel.xToPix(xmin), 1+panel.yToPix(ymax), panel);
g.drawImage(image, panel.getLeftGutter(), panel.getTopGutter(), panel);
}
}
}
/*
* Open Source Physics software is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License (GPL) as
* published by the Free Software Foundation; either version 2 of the License,
* or(at your option) any later version.
* Code that uses any portion of the code in the org.opensourcephysics package
* or any subpackage (subdirectory) of this package must must also be be released
* under the GNU GPL license.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
* or view the license online at http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2007 The Open Source Physics project
* http://www.opensourcephysics.org
*/