com.jme3.texture.image.ImageRaster Maven / Gradle / Ivy
Show all versions of jme3-core Show documentation
/*
* Copyright (c) 2009-2019 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.texture.image;
import com.jme3.math.ColorRGBA;
import com.jme3.texture.Image;
/**
* Utility class for reading and writing from jME3 {@link Image images}.
*
* Allows directly manipulating pixels of the image by writing and
* reading {@link ColorRGBA colors} at any coordinate, without
* regard to the underlying {@link com.jme3.texture.Image.Format format} of the image.
* NOTE: compressed and depth formats are not supported.
* Special RGB formats like RGB111110F and RGB9E5 are not supported
* at the moment, but may be added later on. For now
* use RGB16F_to_RGB111110F and RGB16F_to_RGB9E5 to handle
* the conversion on the GPU.
*
* If direct manipulations are done to the image, such as replacing
* the image data, or changing the width, height, or format, then
* all current instances of ImageReadWrite
become invalid, and
* new instances must be created in order to properly access
* the image data.
*
* Usage example:
*
* Image myImage = ...
* ImageRaster raster = ImageRaster.create(myImage);
* raster.setPixel(1, 5, ColorRGBA.Green);
* System.out.println(raster.getPixel(1, 5)); // Will print [0.0, 1.0, 0.0, 1.0].
*
*
* @author Kirill Vainer
*/
public abstract class ImageRaster {
/**
* Create new image reader / writer.
*
* @param image The image to read / write to.
* @param slice Which slice to use. Only applies to 3D images, 2D image
* arrays or cubemaps.
* @param mipMapLevel The mipmap level to read / write to. To access levels
* other than 0, the image must have
* {@link Image#setMipMapSizes(int[]) mipmap sizes} set.
* @param convertToLinear If true, the application expects read or written
* colors to be in linear color space (ImageRaster
will
* automatically perform a conversion as needed). If false, the application expects
* colors to be in the image's native {@link Image#getColorSpace() color space}.
* @return An ImageRaster to read / write to the image.
*/
public static ImageRaster create(Image image, int slice, int mipMapLevel, boolean convertToLinear) {
return new DefaultImageRaster(image, slice, mipMapLevel, convertToLinear);
}
/**
* Create new image reader / writer.
*
* @param image The image to read / write to.
* @param slice Which slice to use. Only applies to 3D images, 2D image
* arrays or cubemaps.
* @return An ImageRaster to read / write to the image.
*/
public static ImageRaster create(Image image, int slice) {
return create(image, slice, 0, false);
}
/**
* Create new image reader / writer for 2D images.
*
* @param image The image to read / write to.
* @return An ImageRaster to read / write to the image.
*/
public static ImageRaster create(Image image) {
if (image.getData().size() > 1) {
throw new IllegalStateException("Use constructor that takes slices argument to read from multislice image");
}
return create(image, 0, 0, false);
}
public ImageRaster() {
}
/**
* Returns the pixel width of the underlying image.
*
* @return the pixel width of the underlying image.
*/
public abstract int getWidth();
/**
* Returns the pixel height of the underlying image.
*
* @return the pixel height of the underlying image.
*/
public abstract int getHeight();
/**
* Sets the pixel at the given coordinate to the given color.
*
* For all integer based formats (those not ending in "F"), the
* color is first clamped to 0.0 - 1.0 before converting it to
* an integer to avoid overflow. For floating point based formats,
* components larger than 1.0 can be represented, but components
* lower than 0.0 are still not allowed (as all formats are unsigned).
*
* If the underlying format is grayscale (e.g. one of the luminance formats,
* such as {@link com.jme3.texture.Image.Format#Luminance8}) then a color to grayscale
* conversion is done first, before writing the result into the image.
*
* If the image lacks some components (such
* as alpha, or any of the color components), then these components
* will be ignored. The only exception to this is luminance formats
* for which the color is converted to luminance first (see above).
*
* After writing the color, the image shall be marked as requiring an
* update. The next time it is used for rendering, all pixel changes
* will be reflected when the image is rendered.
*
* @param x The x coordinate, from 0 to width - 1.
* @param y The y coordinate, from 0 to height - 1.
* @param color The color to write.
* @throws IllegalArgumentException If x or y are outside the image dimensions.
*/
public abstract void setPixel(int x, int y, ColorRGBA color);
/**
* Retrieve the color at the given coordinate.
*
* Any components that are not defined in the image format
* will be set to 1.0 in the returned color. For example,
* reading from an {@link com.jme3.texture.Image.Format#Alpha8} format will
* return a ColorRGBA with the R, G, and B components set to 1.0, and
* the A component set to the alpha in the image.
*
* For grayscale or luminance formats, the luminance value is replicated
* in the R, G, and B components.
*
* Integer formats are converted to the range 0.0 - 1.0, based
* on the maximum possible integer value that can be represented
* by the number of bits the component has.
* For example, the {@link com.jme3.texture.Image.Format#RGB5A1} format can
* contain the integer values 0 - 31, a conversion to floating point
* is done by diving the integer value by 31 (done with floating point
* precision).
*
* @param x The x coordinate, from 0 to width - 1.
* @param y The y coordinate, from 0 to height - 1.
* @param store Storage location for the read color, if null
,
* then a new ColorRGBA is created and returned with the read color.
* @return The store parameter, if it is null, then a new ColorRGBA
* with the read color.
* @throws IllegalArgumentException If x or y are outside the image dimensions.
*/
public abstract ColorRGBA getPixel(int x, int y, ColorRGBA store);
/**
* Retrieve the color at the given coordinate.
*
* Convenience method that does not take a store argument. Equivalent
* to calling getPixel(x, y, null).
* See {@link #getPixel(int, int, com.jme3.math.ColorRGBA) } for
* more information.
*
* @param x The x coordinate, from 0 to width - 1.
* @param y The y coordinate, from 0 to height - 1.
* @return A new ColorRGBA with the read color.
* @throws IllegalArgumentException If x or y are outside the image dimensions
*/
public ColorRGBA getPixel(int x, int y) {
return getPixel(x, y, null);
}
}