/*
* This file is a part of the Jop-UI
* Copyright (C) 2009, Stefan Resch (e0425306@student.tuwien.ac.at)
* Stefan Rottensteiner (e0425058@student.tuwien.ac.at)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jopdesign.jopui.core;
import com.jopdesign.jopui.helper.Transformation;
/**
* Image objects holding graphical data.
*/
public class Image {
protected int [] data; //holding 4 pixel per integer.
protected int colorKey;
protected int width;
protected int height;
protected Image(int width, int height) {
this.width = width;
this.height = height;
this.data = new int [((width * height)>>2)+1];
}
protected Image(Image copy) {
this.width = copy.width;
this.height = copy.height;
this.data = new int [((width * height)>>2)+1];
System.arraycopy(copy.data, 0, data, 0, copy.data.length);
this.colorKey = copy.colorKey;
}
/**
* Creates a new image with a given width and height <p>
* Returns null if width or height <= 0
* @param width image width in pixel
* @param height image height in pixel
* @return a new Image object or null if an error occurred
*/
public static Image createImage(int width, int height) {
if(width <= 0 || height <= 0)
return null;
return new Image(width, height);
}
/**
* Creates a new image from an other one <p>
* Returns null if source is null
* @param source image to be copied
* @return a new Image object or null if an error occurred
*/
public static Image createImage(Image source) {
if(source == null)
return null;
return new Image(source);
}
/**
* Creates a new image from a specified region of a source image, with the given transformation.<p>
* Conditions: <br>
* if source == null, null will be returned <br>
* if x or y < 0, null will be returned <br>
* if width or height <= 0, null will be returned <br>
* if x+width > source image width, null will be returned <br>
* if y+height > source image height, null will be returned <br>
* if transformation is unknown, null will be returned
* @param source source image to be copied
* @param x x-coordinate of the upper left corner of the region to be copied
* @param y y-coordinate of the upper left corner of the region to be copied
* @param width width of the region to be copied
* @param height height of the region to be copied
* @param transform transformation for the region
* @return a new Image object or null if an error occurred
*/
public static Image createImage(Image source, int x, int y, int width, int height, int transform) {
if(source == null)
return null;
if((x < 0) || (y < 0) || (width <= 0) || (height <= 0))
return null;
if((x+width > source.getWidth()) || (y+height > source.getHeight()))
return null;
int [] data = new int[width * height];
source.getRGB(data, 0, source.width, x, y, width, height);
Image tmp = Image.createRGBImage(data, width, height);
switch(transform) {
case Transformation.TRANS_NONE: return tmp;
case Transformation.TRANS_ROT90: return Transformation.rotate90(tmp);
case Transformation.TRANS_ROT180: return Transformation.rotate180(tmp);
case Transformation.TRANS_ROT270: return Transformation.rotate270(tmp);
case Transformation.TRANS_MIRROR: return Transformation.mirror(tmp);
case Transformation.TRANS_MIRROR_ROT90: return Transformation.mirrorRotate90(tmp);
case Transformation.TRANS_MIRROR_ROT180: return Transformation.mirrorRotate180(tmp);
case Transformation.TRANS_MIRROR_ROT270: return Transformation.mirrorRotate270(tmp);
default: return null;
}
}
/**
* Creates a new image from an array.
* @param rgb array holding pixeldata for the image. one pixel per int
* @param width image width in pixel
* @param height image height in pixel
* @return a new Image object or null if an error occurred
*/
public static Image createRGBImage(int[] rgb, int width, int height) {
if(rgb == null)
return null;
if(width <= 0 || height <= 0)
return null;
if((width * height) != rgb.length)
return null;
Image tmp = new Image(width, height);
int absolute_adr=0;
for(int i=0; i<rgb.length; i+=4) {
//save 4 pixel per integer
tmp.data[absolute_adr++]= rgb[i]<<24 | rgb[i+1]<<16 | rgb[i+2]<<8 | rgb[i+3];
}
return tmp;
}
/**
* Stores images pixel data to the rgbData array.<p>
* Conditions: <br>
* if rgbData == null, no action will be performed <br>
* if x or y or offset < 0, no action will be performed <br>
* if width or height <= 0, no action will be performed <br>
* if scanlength < width, no action will be performed <br>
* if x + width > current image width, no action will be performed <br>
* if y + height > current image height, no action will be performed <br>
* if width * height + offset > length of rgbData, no action will be performed
*
* @param rgbData pixeldata stored to this array. one pixel per integer
* @param offset the starting index where pixeldata will be stored in the rgbData array.
* @param scanlength
* @param x x-coordinate of the upper left corner of the region to be copied
* @param y y-coordinate of the upper left corner of the region to be copied
* @param width width of the region to be copied
* @param height width of the region to be copied
*/
public void getRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height) {
if(rgbData == null)
return;
if(x < 0 || y < 0 || width <= 0 || height <= 0 || offset < 0 || scanlength < width)
return;
if((x + width > this.width) || (y + height > this.height))
return;
if((width*height + offset) > rgbData.length)
return;
for(int j=y; j<height; ++j) {
for(int i=x; i<width; ++i) {
int adr = (i+j*width);
int absolute_adr = adr>>2;
int adroffset = 8*(adr & 0x03);
rgbData[offset + (i-x) + (j-y)*scanlength] = 0xFF & (data[absolute_adr] >> adroffset);
}
}
}
/**
* Creates a new Graphics object for the current image
* @return a new Graphics object for this image
*/
public Graphics getGraphics() {
return new Graphics(this);
}
/**
* Returns the height of the current image in pixel.
* @return height in pixel
*/
public int getHeight() {
return height;
}
/**
* Returns the width of the current image in pixel.
* @return width in pixel
*/
public int getWidth() {
return width;
}
/**
* Returns the pixel data of the image with 4 pixel per integer
* @return pixel data
*/
public int [] getData() {
return data;
}
/**
* Sets the colorkey to the color c
* @param c colorvalue
*/
public void setColorKey(int c) {
this.colorKey = c;
}
/**
* Returns the colorkey value
* @return colorkey color
*/
public int getColorKey() {
return this.colorKey;
}
}