aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/ImageComponentRetained.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/javax/media/j3d/ImageComponentRetained.java')
-rw-r--r--src/javax/media/j3d/ImageComponentRetained.java2653
1 files changed, 0 insertions, 2653 deletions
diff --git a/src/javax/media/j3d/ImageComponentRetained.java b/src/javax/media/j3d/ImageComponentRetained.java
deleted file mode 100644
index 8fb9697..0000000
--- a/src/javax/media/j3d/ImageComponentRetained.java
+++ /dev/null
@@ -1,2653 +0,0 @@
-/*
- * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-package javax.media.j3d;
-
-import java.awt.color.ColorSpace;
-import java.awt.geom.AffineTransform;
-import java.awt.image.AffineTransformOp;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferInt;
-import java.awt.image.PixelInterleavedSampleModel;
-import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.logging.Level;
-
-
-/**
- * Abstract class that is used to define 2D or 3D ImageComponent classes
- * used in a Java 3D scene graph.
- * This is used for texture images, background images and raster components
- * of Shape3D nodes.
- */
-
-abstract class ImageComponentRetained extends NodeComponentRetained {
-
- // change flag
- static final int IMAGE_CHANGED = 0x01;
- static final int SUBIMAGE_CHANGED = 0x02;
-
- static final int TYPE_BYTE_BGR = 0x1;
- static final int TYPE_BYTE_RGB = 0x2;
- static final int TYPE_BYTE_ABGR = 0x4;
- static final int TYPE_BYTE_RGBA = 0x8;
- static final int TYPE_BYTE_LA = 0x10;
- static final int TYPE_BYTE_GRAY = 0x20;
- static final int TYPE_USHORT_GRAY = 0x40;
- static final int TYPE_INT_BGR = 0x80;
- static final int TYPE_INT_RGB = 0x100;
- static final int TYPE_INT_ARGB = 0x200;
-
- static final int IMAGE_SIZE_512X512 = 262144;
-
- enum ImageFormatType {
- TYPE_UNKNOWN,
- TYPE_BYTE_BGR,
- TYPE_BYTE_RGB,
- TYPE_BYTE_ABGR,
- TYPE_BYTE_RGBA,
- TYPE_BYTE_LA,
- TYPE_BYTE_GRAY,
- TYPE_USHORT_GRAY,
- TYPE_INT_BGR,
- TYPE_INT_RGB,
- TYPE_INT_ARGB
- }
-
- static final int IMAGE_DATA_TYPE_BYTE_ARRAY = 0x1000;
- static final int IMAGE_DATA_TYPE_INT_ARRAY = 0x2000;
- static final int IMAGE_DATA_TYPE_BYTE_BUFFER = 0x4000;
- static final int IMAGE_DATA_TYPE_INT_BUFFER = 0x8000;
-
- enum ImageDataType {
- TYPE_NULL,
- TYPE_BYTE_ARRAY,
- TYPE_INT_ARRAY,
- TYPE_BYTE_BUFFER,
- TYPE_INT_BUFFER
- }
-
- private int apiFormat; // The format set by user.
- int width; // Width of PixelArray
- int height; // Height of PixelArray
- int depth; // Depth of PixelArray
- boolean byReference = false; // Is the imageComponent by reference
- boolean yUp = false;
- boolean imageTypeIsSupported;
- boolean abgrSupported = true;
- boolean npotSupported = true;
- private int unitsPerPixel;
- private int numberOfComponents;
-
- // Note : This is unuse for NioImageBuffer.
- // The image type of the input image. Using the constant in BufferedImage
- private int imageType;
-
- private ImageFormatType imageFormatType = ImageFormatType.TYPE_UNKNOWN;
- ImageData imageData;
- private ImageComponent.ImageClass imageClass = ImageComponent.ImageClass.BUFFERED_IMAGE;
-
- // To support Non power of 2 (NPOT) image
- // if enforceNonPowerOfTwoSupport is true (for examples Raster and Background)
- // and imageData is a non power of 2 image
- // and graphics driver doesn't support NPOT extension.
- private ImageData imageDataPowerOfTwo;
- private AffineTransformOp powerOfTwoATOp;
- // The following flag means that if the image is non-power-of-two and the
- // card doesn't support NPOT texture, we will scale the image to a power
- // of two.
- private boolean enforceNonPowerOfTwoSupport = false;
- private boolean usedByOffScreenCanvas = false;
-
- // This will store the referenced Images for reference case.
- // private RenderedImage refImage[] = null;
- private Object refImage[] = null;
-
- // Issue 366: Lock for evaluateExtensions
- Object evaluateExtLock = new Object();
-
- // Lock used in the "by ref case"
- GeometryLock geomLock = new GeometryLock();
-
- int tilew = 0;
- int tileh = 0;
- int numXTiles = 0;
- int numYTiles = 0;
-
-// lists of Node Components that are referencing this ImageComponent
-// object. This list is used to notify the referencing node components
-// of any changes of this ImageComponent.
-private ArrayList<NodeComponentRetained> userList = new ArrayList<NodeComponentRetained>();
-
- /**
- * Retrieves the width of this image component object.
- * @return the width of this image component object
- */
- int getWidth() {
- return width;
- }
-
- /**
- * Retrieves the height of this image component object.
- * @return the height of this image component object
- */
- int getHeight() {
- return height;
- }
-
- /**
- * Retrieves the apiFormat of this image component object.
- *
- * @return the apiFormat of this image component object
- */
- int getFormat() {
- return apiFormat;
- }
-
- void setFormat(int format) {
- this.apiFormat = format;
- }
-
- void setByReference(boolean byReference) {
- this.byReference = byReference;
- }
-
- boolean isByReference() {
- return byReference;
- }
-
- void setYUp( boolean yUp) {
- this.yUp = yUp;
- }
-
- boolean isYUp() {
- return yUp;
- }
-
- int getUnitsPerPixel() {
- return unitsPerPixel;
- }
-
- void setUnitsPerPixel(int ipp) {
- unitsPerPixel = ipp;
- }
-
- ImageComponent.ImageClass getImageClass() {
- return imageClass;
- }
-
- void setImageClass(RenderedImage image) {
- if(image instanceof BufferedImage) {
- imageClass = ImageComponent.ImageClass.BUFFERED_IMAGE;
- } else {
- imageClass = ImageComponent.ImageClass.RENDERED_IMAGE;
- }
- }
-
- void setImageClass(NioImageBuffer image) {
- imageClass = ImageComponent.ImageClass.NIO_IMAGE_BUFFER;
- }
-
- void setEnforceNonPowerOfTwoSupport(boolean npot) {
- this.enforceNonPowerOfTwoSupport = npot;
- }
-
- void setUsedByOffScreen(boolean used) {
- usedByOffScreenCanvas = used;
- }
-
- boolean getUsedByOffScreen() {
- return usedByOffScreenCanvas;
- }
-
- int getNumberOfComponents() {
- return numberOfComponents;
- }
-
- void setNumberOfComponents(int numberOfComponents) {
- this.numberOfComponents = numberOfComponents;
- }
-
- int getImageDataTypeIntValue() {
- int idtValue = -1;
- switch(imageData.imageDataType) {
- case TYPE_BYTE_ARRAY:
- idtValue = IMAGE_DATA_TYPE_BYTE_ARRAY;
- break;
- case TYPE_INT_ARRAY:
- idtValue = IMAGE_DATA_TYPE_INT_ARRAY;
- break;
- case TYPE_BYTE_BUFFER:
- idtValue = IMAGE_DATA_TYPE_BYTE_BUFFER;
- break;
- case TYPE_INT_BUFFER:
- idtValue = IMAGE_DATA_TYPE_INT_BUFFER;
- break;
- default :
- assert false;
- }
- return idtValue;
-
- }
-
- int getImageFormatTypeIntValue(boolean powerOfTwoData) {
- int iftValue = -1;
- switch(imageFormatType) {
- case TYPE_BYTE_BGR:
- iftValue = TYPE_BYTE_BGR;
- break;
- case TYPE_BYTE_RGB:
- iftValue = TYPE_BYTE_RGB;
- break;
- case TYPE_BYTE_ABGR:
- iftValue = TYPE_BYTE_ABGR;
- break;
- case TYPE_BYTE_RGBA:
- if((imageDataPowerOfTwo != null) && (powerOfTwoData)) {
- iftValue = TYPE_BYTE_ABGR;
- }
- else {
- iftValue = TYPE_BYTE_RGBA;
- }
- break;
- case TYPE_BYTE_LA:
- iftValue = TYPE_BYTE_LA;
- break;
- case TYPE_BYTE_GRAY:
- iftValue = TYPE_BYTE_GRAY;
- break;
- case TYPE_USHORT_GRAY:
- iftValue = TYPE_USHORT_GRAY;
- break;
- case TYPE_INT_BGR:
- iftValue = TYPE_INT_BGR;
- break;
- case TYPE_INT_RGB:
- iftValue = TYPE_INT_RGB;
- break;
- case TYPE_INT_ARGB:
- iftValue = TYPE_INT_ARGB;
- break;
- default:
- throw new AssertionError();
- }
- return iftValue;
- }
-
- // Note: This method for RenderedImage, can't be used by NioImageBuffer.
- int getImageType() {
- return imageType;
- }
-
- void setImageFormatType(ImageFormatType ift) {
- this.imageFormatType = ift;
- }
-
- ImageFormatType getImageFormatType() {
- return this.imageFormatType;
- }
-
- void setRefImage(Object image, int index) {
- this.refImage[index] = image;
- }
-
- Object getRefImage(int index) {
- return this.refImage[index];
- }
-
- ImageData getImageData(boolean npotSupportNeeded) {
- if(npotSupportNeeded) {
- assert enforceNonPowerOfTwoSupport;
- if(imageDataPowerOfTwo != null) {
- return imageDataPowerOfTwo;
- }
- }
- return imageData;
- }
-
- boolean useBilinearFilter() {
- if(imageDataPowerOfTwo != null) {
- return true;
- }
-
- return false;
- }
-
- boolean isImageTypeSupported() {
- return imageTypeIsSupported;
- }
-
- /**
- * Check if ImageComponent parameters have valid values.
- */
- void processParams(int format, int width, int height, int depth) {
- if (width < 1)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained0"));
-
- if (height < 1)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained1"));
-
- if (depth < 1)
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained2"));
-
- // If the format is 8bit per component, we may send it down
- // to OpenGL directly if its by ref case
- switch (format) {
- case ImageComponent.FORMAT_RGB:// same as ImageComponent.FORMAT_RGB8
- case ImageComponent.FORMAT_RGB4: // Need to be Deprecated
- case ImageComponent.FORMAT_RGB5: // Need to be Deprecated
- case ImageComponent.FORMAT_R3_G3_B2: // Need to be Deprecated
- numberOfComponents = 3;
- break;
- case ImageComponent.FORMAT_RGBA:// same as ImageComponent.FORMAT_RGBA8
- case ImageComponent.FORMAT_RGB5_A1: // Need to be Deprecated
- case ImageComponent.FORMAT_RGBA4: // Need to be Deprecated
- numberOfComponents = 4;
- break;
- case ImageComponent.FORMAT_LUM4_ALPHA4: // Need to be Deprecated
- case ImageComponent.FORMAT_LUM8_ALPHA8:
- numberOfComponents = 2;
- break;
- case ImageComponent.FORMAT_CHANNEL8:
- numberOfComponents = 1;
- break;
- default:
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponentRetained3"));
- }
-
- this.setFormat(format);
- this.width = width;
- this.height = height;
- this.depth = depth;
- refImage = new Object[depth];
- }
-
- int evaluateImageType(RenderedImage ri) {
- int imageType = BufferedImage.TYPE_CUSTOM;
-
- if (ri instanceof BufferedImage) {
- imageType = ((BufferedImage)ri).getType();
-
- if(imageType != BufferedImage.TYPE_CUSTOM) {
- return imageType;
- }
- }
- else {
- // Fix to Issue 412. Force copy for RenderedImage of type not equal to BufferedImage.
- return imageType;
- }
-
- // System.err.println("This is a RenderedImage or BufferedImage with TYPE_CUSTOM. It imageType classification may not be correct.");
- ColorModel cm = ri.getColorModel();
- ColorSpace cs = cm.getColorSpace();
- SampleModel sm = ri.getSampleModel();
-
- int csType = cs.getType();
- boolean isAlphaPre = cm.isAlphaPremultiplied();
-
-
- if (csType == ColorSpace.TYPE_GRAY && cm instanceof ComponentColorModel) {
- if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
- imageType = BufferedImage.TYPE_BYTE_GRAY;
- } else if (sm.getDataType() == DataBuffer.TYPE_USHORT) {
- imageType = BufferedImage.TYPE_USHORT_GRAY;
- }
- }
-
- // RGB , only interested in BYTE ABGR and BGR for now
- // all others will be copied to a buffered image
- else if(csType == ColorSpace.TYPE_RGB) {
- int comparedBit = 0;
- int smDataType = sm.getDataType();
- if(smDataType == DataBuffer.TYPE_BYTE) {
- comparedBit = 8;
- } else if(smDataType == DataBuffer.TYPE_INT) {
- comparedBit = 32;
- }
-
- if(comparedBit != 0) {
- int numBands = sm.getNumBands();
- if (cm instanceof ComponentColorModel &&
- sm instanceof PixelInterleavedSampleModel) {
- PixelInterleavedSampleModel csm =
- (PixelInterleavedSampleModel) sm;
- int[] offs = csm.getBandOffsets();
- ComponentColorModel ccm = (ComponentColorModel)cm;
- int[] nBits = ccm.getComponentSize();
- boolean isNBit = true;
- for (int i=0; i < numBands; i++) {
- if (nBits[i] != comparedBit) {
- isNBit = false;
- break;
- }
- }
-
- // Handle TYPE_BYTE
- if( comparedBit == 8) {
- if (isNBit &&
- offs[0] == numBands-1 &&
- offs[1] == numBands-2 &&
- offs[2] == numBands-3) {
- if (numBands == 3) {
- imageType = BufferedImage.TYPE_3BYTE_BGR;
- } else if (offs[3] == 0) {
- imageType = (isAlphaPre
- ? BufferedImage.TYPE_4BYTE_ABGR_PRE
- : BufferedImage.TYPE_4BYTE_ABGR);
- }
- }
- }
- //Handle TYPE_INT
- else {
- if (isNBit) {
- if (numBands == 3) {
- if(offs[0] == numBands-1 &&
- offs[1] == numBands-2 &&
- offs[2] == numBands-3) {
- imageType = BufferedImage.TYPE_INT_BGR;
- } else if(offs[0] == 0 &&
- offs[1] == 1 &&
- offs[2] == 2) {
- imageType = BufferedImage.TYPE_INT_RGB;
- }
- } else if(offs[0] == 3 &&
- offs[1] == 0 &&
- offs[2] == 1 &&
- offs[3] == 2) {
- imageType = (isAlphaPre
- ? BufferedImage.TYPE_INT_ARGB_PRE
- : BufferedImage.TYPE_INT_ARGB);
- }
- }
- }
- }
- }
- }
-
- return imageType;
- }
-
- // Assume ri's imageType is BufferedImage.TYPE_CUSTOM
- boolean is3ByteRGB(RenderedImage ri) {
- boolean value = false;
- int i;
- ColorModel cm = ri.getColorModel();
- ColorSpace cs = cm.getColorSpace();
- SampleModel sm = ri.getSampleModel();
- boolean isAlphaPre = cm.isAlphaPremultiplied();
- int csType = cs.getType();
- if ( csType == ColorSpace.TYPE_RGB) {
- int numBands = sm.getNumBands();
- if ((numBands == 3) && (sm.getDataType() == DataBuffer.TYPE_BYTE)) {
- if (cm instanceof ComponentColorModel &&
- sm instanceof PixelInterleavedSampleModel) {
- PixelInterleavedSampleModel csm =
- (PixelInterleavedSampleModel) sm;
- int[] offs = csm.getBandOffsets();
- ComponentColorModel ccm = (ComponentColorModel)cm;
- int[] nBits = ccm.getComponentSize();
- boolean is8Bit = true;
- for (i=0; i < numBands; i++) {
- if (nBits[i] != 8) {
- is8Bit = false;
- break;
- }
- }
- if (is8Bit &&
- offs[0] == 0 &&
- offs[1] == 1 &&
- offs[2] == 2) {
- value = true;
- }
- }
- }
- }
- return value;
- }
-
- // Assume ri's imageType is BufferedImage.TYPE_CUSTOM
- boolean is4ByteRGBA(RenderedImage ri) {
- boolean value = false;
- int i;
- ColorModel cm = ri.getColorModel();
- ColorSpace cs = cm.getColorSpace();
- SampleModel sm = ri.getSampleModel();
- boolean isAlphaPre = cm.isAlphaPremultiplied();
- int csType = cs.getType();
- if ( csType == ColorSpace.TYPE_RGB) {
- int numBands = sm.getNumBands();
- if ((numBands == 4) && (sm.getDataType() == DataBuffer.TYPE_BYTE)) {
- if (cm instanceof ComponentColorModel &&
- sm instanceof PixelInterleavedSampleModel) {
- PixelInterleavedSampleModel csm =
- (PixelInterleavedSampleModel) sm;
- int[] offs = csm.getBandOffsets();
- ComponentColorModel ccm = (ComponentColorModel)cm;
- int[] nBits = ccm.getComponentSize();
- boolean is8Bit = true;
- for (i=0; i < numBands; i++) {
- if (nBits[i] != 8) {
- is8Bit = false;
- break;
- }
- }
- if (is8Bit &&
- offs[0] == 0 &&
- offs[1] == 1 &&
- offs[2] == 2 &&
- offs[3] == 3 && !isAlphaPre) {
- value = true;
- }
- }
- }
- }
- return value;
- }
-
- // Note: This method for RenderedImage, can't be used by NioImageBuffer.
- /* Check if sub-image type matches image type */
- boolean isSubImageTypeEqual(RenderedImage ri) {
- int subImageType = evaluateImageType(ri);
-
- // This test is likely too loose, but the specification isn't clear either.
- // Assuming TYPE_CUSTOM of sub-image == the TYPE_CUSTOM of existing image.
- if(imageType == subImageType) {
- return true;
- } else {
- return false;
- }
-
- }
-
- // This method only support caller of offScreenBuffer and readRaster.
- void createBlankImageData() {
-
- assert (imageData == null);
-
- switch(numberOfComponents) {
- case 4:
- imageType = BufferedImage.TYPE_INT_ARGB;
- imageFormatType = ImageFormatType.TYPE_INT_ARGB;
- unitsPerPixel = 1;
- break;
-
- case 3:
- imageType = BufferedImage.TYPE_INT_RGB;
- imageFormatType = ImageFormatType.TYPE_INT_RGB;
- unitsPerPixel = 1;
- break;
- default:
- // Only valid for 3 and 4 channel case. ( Read back from framebuffer )
- assert false;
- }
-
- imageTypeIsSupported = true;
- imageData = createRenderedImageDataObject(null);
-
- }
-
- // This method will set imageType, imageFormatType, and unitsPerPixel
- // as it evaluates NioImageBuffer is supported. It will also reset
- // abgrSupported.
- boolean isImageTypeSupported(NioImageBuffer nioImgBuf) {
-
- boolean isSupported = true;
- NioImageBuffer.ImageType nioImageType = nioImgBuf.getImageType();
-
- switch(numberOfComponents) {
- case 4:
- switch(nioImageType) {
- case TYPE_4BYTE_ABGR:
- // TODO : This approach will lead to a very slow path
- // for unsupported case.
- if(abgrSupported) {
- imageFormatType = ImageFormatType.TYPE_BYTE_ABGR;
- } else {
- // Unsupported format on HW, switch to slow copy.
- imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
- isSupported = false;
- }
- unitsPerPixel = 4;
- break;
- case TYPE_4BYTE_RGBA:
- imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
- unitsPerPixel = 4;
- break;
- case TYPE_INT_ARGB:
- imageFormatType = ImageFormatType.TYPE_INT_ARGB;
- unitsPerPixel = 1;
- break;
- default:
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent5"));
-
- }
- break;
- case 3:
- switch(nioImageType) {
- case TYPE_3BYTE_BGR:
- imageFormatType = ImageFormatType.TYPE_BYTE_BGR;
- unitsPerPixel = 3;
- break;
- case TYPE_3BYTE_RGB:
- imageFormatType = ImageFormatType.TYPE_BYTE_RGB;
- unitsPerPixel = 3;
- break;
- case TYPE_INT_BGR:
- imageFormatType = ImageFormatType.TYPE_INT_BGR;
- unitsPerPixel = 1;
- break;
- case TYPE_INT_RGB:
- imageFormatType = ImageFormatType.TYPE_INT_RGB;
- unitsPerPixel = 1;
- break;
- default:
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent5"));
- }
- break;
-
- case 2:
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent5"));
- case 1:
- if(nioImageType == NioImageBuffer.ImageType.TYPE_BYTE_GRAY) {
- imageFormatType = ImageFormatType.TYPE_BYTE_GRAY;
- unitsPerPixel = 1;
- } else {
- throw new IllegalArgumentException(J3dI18N.getString("ImageComponent5"));
- }
- break;
-
- default:
- throw new AssertionError();
- }
-
- return isSupported;
- }
-
- // This method will set imageType, imageFormatType, and unitsPerPixel
- // as it evaluates RenderedImage is supported. It will also reset
- // abgrSupported.
- boolean isImageTypeSupported(RenderedImage ri) {
-
- boolean isSupported = true;
- imageType = evaluateImageType(ri);
-
- switch(numberOfComponents) {
- case 4:
- if(imageType == BufferedImage.TYPE_4BYTE_ABGR) {
-
- // TODO : This approach will lead to a very slow path
- // for unsupported case.
- if(abgrSupported) {
- imageFormatType = ImageFormatType.TYPE_BYTE_ABGR;
- } else {
- // Unsupported format on HW, switch to slow copy.
- imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
- isSupported = false;
- }
- unitsPerPixel = 4;
- } else if(imageType == BufferedImage.TYPE_INT_ARGB) {
- imageFormatType = ImageFormatType.TYPE_INT_ARGB;
- unitsPerPixel = 1;
- } else if(is4ByteRGBA(ri)) {
- imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
- unitsPerPixel = 4;
- } else {
- // System.err.println("Image format is unsupported --- Case 4");
- // Convert unsupported format to TYPE_BYTE_RGBA.
- imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
- isSupported = false;
- unitsPerPixel = 4;
- }
- break;
-
- case 3:
- if(imageType == BufferedImage.TYPE_3BYTE_BGR) {
- imageFormatType = ImageFormatType.TYPE_BYTE_BGR;
- unitsPerPixel = 3;
- } else if(imageType == BufferedImage.TYPE_INT_BGR) {
- imageFormatType = ImageFormatType.TYPE_INT_BGR;
- unitsPerPixel = 1;
- } else if(imageType == BufferedImage.TYPE_INT_RGB) {
- imageFormatType = ImageFormatType.TYPE_INT_RGB;
- unitsPerPixel = 1;
- } else if(is3ByteRGB(ri)) {
- imageFormatType = ImageFormatType.TYPE_BYTE_RGB;
- unitsPerPixel = 3;
- } else {
- // System.err.println("Image format is unsupported --- Case 3");
- // Convert unsupported format to TYPE_BYTE_RGB.
- imageFormatType = ImageFormatType.TYPE_BYTE_RGB;
- isSupported = false;
- unitsPerPixel = 3;
- }
- break;
-
- case 2:
- // System.err.println("Image format is unsupported --- Case 2");
- // Convert unsupported format to TYPE_BYTE_LA.
- imageFormatType = ImageFormatType.TYPE_BYTE_LA;
- isSupported = false;
- unitsPerPixel = 2;
- break;
-
- case 1:
- if(imageType == BufferedImage.TYPE_BYTE_GRAY) {
- imageFormatType = ImageFormatType.TYPE_BYTE_GRAY;
- unitsPerPixel = 1;
- } else {
- // System.err.println("Image format is unsupported --- Case 1");
- // Convert unsupported format to TYPE_BYTE_GRAY.
- imageFormatType = ImageFormatType.TYPE_BYTE_GRAY;
- isSupported = false;
- unitsPerPixel = 1;
- }
- break;
-
- default:
- throw new AssertionError();
- }
-
- return isSupported;
- }
-
- /*
- * This method assume that the following members have been initialized :
- * width, height, depth, imageFormatType, and unitsPerPixel.
- */
- ImageData createNioImageBufferDataObject(NioImageBuffer nioImageBuffer) {
-
- switch(imageFormatType) {
- case TYPE_BYTE_GRAY:
- case TYPE_BYTE_LA:
- case TYPE_BYTE_RGB:
- case TYPE_BYTE_BGR:
- case TYPE_BYTE_RGBA:
- case TYPE_BYTE_ABGR:
- if(nioImageBuffer != null) {
- return new ImageData(ImageDataType.TYPE_BYTE_BUFFER,
- width * height * depth * unitsPerPixel,
- width, height, nioImageBuffer);
- } else {
- // This is needed only if abgr is unsupported.
- return new ImageData(ImageDataType.TYPE_BYTE_BUFFER,
- width * height * depth * unitsPerPixel,
- width, height);
- }
- case TYPE_INT_RGB:
- case TYPE_INT_BGR:
- case TYPE_INT_ARGB:
- return new ImageData(ImageDataType.TYPE_INT_BUFFER,
- width * height * depth * unitsPerPixel,
- width, height, nioImageBuffer);
- default:
- throw new AssertionError();
- }
- }
-
- /*
- * This method assume that the following members have been initialized :
- * depth, imageType, imageFormatType, and unitsPerPixel.
- */
- ImageData createRenderedImageDataObject(RenderedImage byRefImage, int dataWidth, int dataHeight) {
- switch(imageFormatType) {
- case TYPE_BYTE_GRAY:
- case TYPE_BYTE_LA:
- case TYPE_BYTE_RGB:
- case TYPE_BYTE_BGR:
- case TYPE_BYTE_RGBA:
- case TYPE_BYTE_ABGR:
- if(byRefImage != null) {
- return new ImageData(ImageDataType.TYPE_BYTE_ARRAY,
- dataWidth * dataHeight * depth * unitsPerPixel,
- dataWidth, dataHeight, byRefImage);
- } else {
- return new ImageData(ImageDataType.TYPE_BYTE_ARRAY,
- dataWidth * dataHeight * depth * unitsPerPixel,
- dataWidth, dataHeight);
- }
- case TYPE_INT_RGB:
- case TYPE_INT_BGR:
- case TYPE_INT_ARGB:
- if(byRefImage != null) {
- return new ImageData(ImageDataType.TYPE_INT_ARRAY,
- dataWidth * dataHeight * depth * unitsPerPixel,
- dataWidth, dataHeight, byRefImage);
- } else {
- return new ImageData(ImageDataType.TYPE_INT_ARRAY,
- dataWidth * dataHeight * depth * unitsPerPixel,
- dataWidth, dataHeight);
- }
- default:
- throw new AssertionError();
- }
- }
-
- private void updateImageDataPowerOfTwo(int depthIndex) {
- assert enforceNonPowerOfTwoSupport;
- BufferedImage bufImage = imageData.createBufferedImage(depthIndex);
- BufferedImage scaledImg = powerOfTwoATOp.filter(bufImage, null);
- copySupportedImageToImageData(scaledImg, 0, imageDataPowerOfTwo);
- }
-
- /*
- * This method assume that the following members have been initialized :
- * width, height, depth, imageType, imageFormatType, and bytesPerPixel.
- */
- ImageData createRenderedImageDataObject(RenderedImage byRefImage) {
-
- return createRenderedImageDataObject(byRefImage, width, height);
-
- }
-
-
- /**
- * Copy specified region of image data from RenderedImage to
- * ImageComponent's imageData object
- */
- void copySupportedImageToImageData(RenderedImage ri, int srcX, int srcY,
- int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
-
- assert (data != null);
-
- ColorModel cm = ri.getColorModel();
-
- int xoff = ri.getTileGridXOffset(); // tile origin x offset
- int yoff = ri.getTileGridYOffset(); // tile origin y offset
- int minTileX = ri.getMinTileX(); // min tile x index
- int minTileY = ri.getMinTileY(); // min tile y index
- tilew = ri.getTileWidth(); // tile width in pixels
- tileh = ri.getTileHeight(); // tile height in pixels
-
- // determine the first tile of the image
- float mt;
-
- mt = (float)(srcX - xoff) / (float)tilew;
- if (mt < 0) {
- minTileX = (int)(mt - 1);
- } else {
- minTileX = (int)mt;
- }
-
- mt = (float)(srcY - yoff) / (float)tileh;
- if (mt < 0) {
- minTileY = (int)(mt - 1);
- } else {
- minTileY = (int)mt;
- }
-
- // determine the pixel offset of the upper-left corner of the
- // first tile
- int startXTile = minTileX * tilew + xoff;
- int startYTile = minTileY * tileh + yoff;
-
- // image dimension in the first tile
- int curw = (startXTile + tilew - srcX);
- int curh = (startYTile + tileh - srcY);
-
- // check if the to-be-copied region is less than the tile image
- // if so, update the to-be-copied dimension of this tile
- if (curw > copyWidth) {
- curw = copyWidth;
- }
-
- if (curh > copyHeight) {
- curh = copyHeight;
- }
-
- // save the to-be-copied width of the left most tile
- int startw = curw;
-
- // temporary variable for dimension of the to-be-copied region
- int tmpw = copyWidth;
- int tmph = copyHeight;
-
- // offset of the first pixel of the tile to be copied; offset is
- // relative to the upper left corner of the title
- int x = srcX - startXTile;
- int y = srcY - startYTile;
-
- // determine the number of tiles in each direction that the
- // image spans
- numXTiles = (copyWidth + x) / tilew;
- numYTiles = (copyHeight + y) / tileh;
-
- if (((float)(copyWidth + x ) % (float)tilew) > 0) {
- numXTiles += 1;
- }
-
- if (((float)(copyHeight + y ) % (float)tileh) > 0) {
- numYTiles += 1;
- }
-
- int offset;
- int w, h, i, j, m, n;
- int dstBegin;
- Object pixel = null;
- java.awt.image.Raster ras;
- int lineUnits; // nbytes per line in dst image buffer
- int sign; // -1 for going down
- int dstLineUnits; // sign * lineUnits
- int tileStart; // destination buffer offset
- // at the next left most tile
-
- byte[] dstByteBuffer = null;
- int[] dstIntBuffer = null;
-
- switch(data.getType()) {
- case TYPE_BYTE_ARRAY:
- dstByteBuffer = data.getAsByteArray();
- break;
- case TYPE_INT_ARRAY:
- dstIntBuffer = data.getAsIntArray();
- break;
- default:
- assert false;
- }
-
- int dataWidth = data.dataWidth;
- int dataHeight = data.dataHeight;
-
- lineUnits = dataWidth * unitsPerPixel;
- if (yUp) {
- // destination buffer offset
- tileStart = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
- sign = 1;
- dstLineUnits = lineUnits;
- } else {
- // destination buffer offset
- tileStart = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
- sign = -1;
- dstLineUnits = -lineUnits;
- }
-
-/*
- System.err.println("tileStart= " + tileStart + " dstLineUnits= " + dstLineUnits);
- System.err.println("startw= " + startw);
- */
-
- // allocate memory for a pixel
- ras = ri.getTile(minTileX,minTileY);
- pixel = getDataElementBuffer(ras);
-
- int srcOffset, dstOffset;
- int tileLineUnits = tilew * unitsPerPixel;
- int copyUnits;
-
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copyWidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- srcOffset = (y * tilew + x) * unitsPerPixel;
- dstOffset = dstBegin;
-
- copyUnits = curw * unitsPerPixel;
-
- //System.err.println("curh = "+curh+" curw = "+curw);
- //System.err.println("x = "+x+" y = "+y);
-
- switch(data.getType()) {
- case TYPE_BYTE_ARRAY:
- byte[] srcByteBuffer = ((DataBufferByte)ras.getDataBuffer()).getData();
- for (h = 0; h < curh; h++) {
- System.arraycopy(srcByteBuffer, srcOffset, dstByteBuffer, dstOffset,
- copyUnits);
- srcOffset += tileLineUnits;
- dstOffset += dstLineUnits;
- }
- break;
- case TYPE_INT_ARRAY:
- int[] srcIntBuffer = ((DataBufferInt)ras.getDataBuffer()).getData();
- for (h = 0; h < curh; h++) {
- System.arraycopy(srcIntBuffer, srcOffset, dstIntBuffer, dstOffset,
- copyUnits);
- srcOffset += tileLineUnits;
- dstOffset += dstLineUnits;
- }
- break;
- default:
- assert false;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * unitsPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
- tileStart += dataWidth * unitsPerPixel * curh * sign;
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
-
- if((imageData == data) && (imageDataPowerOfTwo != null)) {
- updateImageDataPowerOfTwo(depthIndex);
- }
- }
-
- // Quick line by line copy
- void copyImageLineByLine(BufferedImage bi, int srcX, int srcY,
- int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
-
- assert (data != null);
-
- int h;
- int rowBegin, // src begin row index
- srcBegin, // src begin offset
- dstBegin; // dst begin offset
-
- int dataWidth = data.dataWidth;
- int dataHeight = data.dataHeight;
- int dstUnitsPerRow = dataWidth * unitsPerPixel; // bytes per row in dst image
- rowBegin = srcY;
-
- if (yUp) {
- dstBegin = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
- } else {
- dstBegin = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
- dstUnitsPerRow = - 1 * dstUnitsPerRow;
- }
-
- int copyUnits = copyWidth * unitsPerPixel;
- int srcWidth = bi.getWidth();
- int srcUnitsPerRow = srcWidth * unitsPerPixel;
- srcBegin = (rowBegin * srcWidth + srcX) * unitsPerPixel;
-
- switch(data.getType()) {
- case TYPE_BYTE_ARRAY:
- byte[] srcByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- byte[] dstByteBuffer = data.getAsByteArray();
- for (h = 0; h < copyHeight; h++) {
- System.arraycopy(srcByteBuffer, srcBegin, dstByteBuffer, dstBegin, copyUnits);
- dstBegin += dstUnitsPerRow;
- srcBegin += srcUnitsPerRow;
- }
- break;
-
- case TYPE_INT_ARRAY:
- int[] srcIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- int[] dstIntBuffer = data.getAsIntArray();
- for (h = 0; h < copyHeight; h++) {
- System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, dstBegin, copyUnits);
- dstBegin += dstUnitsPerRow;
- srcBegin += srcUnitsPerRow;
- }
- break;
- default:
- assert false;
- }
-
- if((imageData == data) && (imageDataPowerOfTwo != null)) {
- updateImageDataPowerOfTwo(depthIndex);
- }
- }
-
- // Quick block copy for yUp image
- void copyImageByBlock(BufferedImage bi, int depthIndex, ImageData data) {
-
- assert ((data != null) && yUp);
-
- int dataWidth = data.dataWidth;
- int dataHeight = data.dataHeight;
-
- int dstBegin; // dst begin offset
- dstBegin = depthIndex * dataWidth * dataHeight * unitsPerPixel;
-
- switch(imageData.getType()) {
- case TYPE_BYTE_ARRAY:
- byte[] srcByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- byte[] dstByteBuffer = data.getAsByteArray();
- System.arraycopy(srcByteBuffer, 0, dstByteBuffer, dstBegin, (dataWidth * dataHeight * unitsPerPixel));
- break;
- case TYPE_INT_ARRAY:
- int[] srcIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- int[] dstIntBuffer = data.getAsIntArray();
- System.arraycopy(srcIntBuffer, 0, dstIntBuffer, dstBegin, (dataWidth * dataHeight * unitsPerPixel));
- break;
- default:
- assert false;
- }
-
- if((imageData == data) && (imageDataPowerOfTwo != null)) {
- updateImageDataPowerOfTwo(depthIndex);
- }
-
- }
-
- /**
- * copy complete region of a RenderedImage to ImageComponent's imageData object.
- */
- void copySupportedImageToImageData(RenderedImage ri, int depthIndex, ImageData data) {
-
- if (ri instanceof BufferedImage) {
- if(yUp) {
- /* Use quick block copy when ( format is OK, Yup is true, and byRef is false). */
- // System.err.println("ImageComponentRetained.copySupportedImageToImageData() : (imageTypeSupported && !byReference && yUp) --- (2 BI)");
- copyImageByBlock((BufferedImage)ri, depthIndex, data);
- } else {
- /* Use quick inverse line by line copy when (format is OK and Yup is false). */
- // System.err.println("ImageComponentRetained.copySupportedImageToImageData() : (imageTypeSupported && !yUp) --- (3 BI)");
- copyImageLineByLine((BufferedImage)ri, 0, 0, 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
- }
- } else {
- // System.err.println("ImageComponentRetained.copySupportedImageToImageData() : (imageTypeSupported && !byReference ) --- (2 RI)");
- copySupportedImageToImageData(ri, ri.getMinX(), ri.getMinY(), 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
-
- /*
- * An alternative approach.
- *
- // Create a buffered image from renderImage
- ColorModel cm = ri.getColorModel();
- WritableRaster wRaster = ri.copyData(null);
- BufferedImage bi = new BufferedImage(cm,
- wRaster,
- cm.isAlphaPremultiplied()
- ,null);
-
- copySupportedImageToImageData((BufferedImage)ri, 0, 0, 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
-
- *
- *
- */
- }
- }
-
- /*
- * copy the complete unsupported NioImageBuffer into a supported BYTE_BUFFER format
- */
- void copyUnsupportedNioImageToImageData(NioImageBuffer nioImage, int srcX, int srcY,
- int dstX, int dstY, int copyWidth, int copyHeight, ImageData iData) {
-
- if (MasterControl.isDevLoggable(Level.INFO)) {
- MasterControl.getDevLogger().info("ImageComponent - Copying Unsupported NioImage, use a different image type");
- }
-
- assert (iData.getType() == ImageDataType.TYPE_BYTE_BUFFER);
- assert (getImageFormatType() == ImageFormatType.TYPE_BYTE_RGBA);
-
- int length = copyWidth * copyHeight;
- ByteBuffer srcBuffer = (ByteBuffer) nioImage.getDataBuffer();
- srcBuffer.rewind();
- ByteBuffer dstBuffer = iData.getAsByteBuffer();
- dstBuffer.rewind();
-
- // Do copy and swap.
- for(int i = 0; i < length; i +=4) {
- dstBuffer.put(i, srcBuffer.get(i+3));
- dstBuffer.put(i+1, srcBuffer.get(i+2));
- dstBuffer.put(i+2, srcBuffer.get(i+1));
- dstBuffer.put(i+3, srcBuffer.get(i));
- }
- }
-
- /*
- * copy the complete unsupported image into a supported BYTE_ARRAY format
- */
- void copyUnsupportedImageToImageData(RenderedImage ri, int depthIndex, ImageData data) {
-
- assert (data.getType() == ImageDataType.TYPE_BYTE_ARRAY);
-
- if (MasterControl.isDevLoggable(Level.INFO)) {
- MasterControl.getDevLogger().info("ImageComponent - Copying Unsupported Image, use a different image type");
- }
-
- if (ri instanceof BufferedImage) {
- copyUnsupportedImageToImageData((BufferedImage)ri, 0, 0, 0, 0,
- depthIndex, data.dataWidth, data.dataHeight, data);
- } else {
- copyUnsupportedImageToImageData(ri, ri.getMinX(), ri.getMinY(),
- 0, 0, depthIndex, data.dataWidth, data.dataHeight, data);
- }
- }
-
- void copyUnsupportedImageToImageData(BufferedImage bi, int srcX, int srcY,
- int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
-
- int w, h, i, j;
- int rowBegin, // src begin row index
- srcBegin, // src begin offset
- dstBegin, // dst begin offset
- rowInc, // row increment
- // -1 --- ydown
- // 1 --- yup
- row;
-
- rowBegin = srcY;
- rowInc = 1;
-
- assert (data != null);
-
- int dataWidth = data.dataWidth;
- int dataHeight = data.dataHeight;
- int dstBytesPerRow = dataWidth * unitsPerPixel; // bytes per row in dst image
-
- if (yUp) {
- dstBegin = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
- } else {
- dstBegin = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
- dstBytesPerRow = - 1 * dstBytesPerRow;
- }
-
- WritableRaster ras = bi.getRaster();
- ColorModel cm = bi.getColorModel();
- Object pixel = getDataElementBuffer(ras);
-
- byte[] dstBuffer = data.getAsByteArray();
-
- switch(numberOfComponents) {
- case 4: {
- for (row = rowBegin, h = 0;
- h < copyHeight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copyWidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- dstBuffer[j++] = (byte)cm.getGreen(pixel);
- dstBuffer[j++] = (byte)cm.getBlue(pixel);
- dstBuffer[j++] = (byte)cm.getAlpha(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
- }
- break;
-
- case 3: {
- for (row = rowBegin, h = 0;
- h < copyHeight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copyWidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- dstBuffer[j++] = (byte)cm.getGreen(pixel);
- dstBuffer[j++] = (byte)cm.getBlue(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
- }
- break;
-
- case 2: {
- for (row = rowBegin, h = 0;
- h < copyHeight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copyWidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- dstBuffer[j++] = (byte)cm.getAlpha(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
- }
- break;
-
- case 1: {
- for (row = rowBegin, h = 0;
- h < copyHeight; h++, row += rowInc) {
- j = dstBegin;
- for (w = srcX; w < (copyWidth + srcX); w++) {
- ras.getDataElements(w, row, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- }
- dstBegin += dstBytesPerRow;
- }
- }
- break;
- default:
- assert false;
- }
-
- if((imageData == data) && (imageDataPowerOfTwo != null)) {
- updateImageDataPowerOfTwo(depthIndex);
- }
- }
-
- void copyUnsupportedImageToImageData(RenderedImage ri, int srcX, int srcY,
- int dstX, int dstY, int depthIndex, int copyWidth, int copyHeight, ImageData data) {
-
- int w, h, i, j, m, n;
- int dstBegin;
- Object pixel = null;
- java.awt.image.Raster ras;
- // dst image buffer
- int sign; // -1 for going down
- int dstLineBytes; // sign * lineBytes
- int tileStart; // destination buffer offset
- // at the next left most tile
-
- int offset;
-
- ColorModel cm = ri.getColorModel();
-
- int xoff = ri.getTileGridXOffset(); // tile origin x offset
- int yoff = ri.getTileGridYOffset(); // tile origin y offset
- int minTileX = ri.getMinTileX(); // min tile x index
- int minTileY = ri.getMinTileY(); // min tile y index
- tilew = ri.getTileWidth(); // tile width in pixels
- tileh = ri.getTileHeight(); // tile height in pixels
-
- // determine the first tile of the image
-
- float mt;
-
- mt = (float)(srcX - xoff) / (float)tilew;
- if (mt < 0) {
- minTileX = (int)(mt - 1);
- } else {
- minTileX = (int)mt;
- }
-
- mt = (float)(srcY - yoff) / (float)tileh;
- if (mt < 0) {
- minTileY = (int)(mt - 1);
- } else {
- minTileY = (int)mt;
- }
-
- // determine the pixel offset of the upper-left corner of the
- // first tile
- int startXTile = minTileX * tilew + xoff;
- int startYTile = minTileY * tileh + yoff;
-
-
- // image dimension in the first tile
- int curw = (startXTile + tilew - srcX);
- int curh = (startYTile + tileh - srcY);
-
- // check if the to-be-copied region is less than the tile image
- // if so, update the to-be-copied dimension of this tile
- if (curw > copyWidth) {
- curw = copyWidth;
- }
-
- if (curh > copyHeight) {
- curh = copyHeight;
- }
-
- // save the to-be-copied width of the left most tile
- int startw = curw;
-
-
- // temporary variable for dimension of the to-be-copied region
- int tmpw = copyWidth;
- int tmph = copyHeight;
-
-
- // offset of the first pixel of the tile to be copied; offset is
- // relative to the upper left corner of the title
- int x = srcX - startXTile;
- int y = srcY - startYTile;
-
-
- // determine the number of tiles in each direction that the
- // image spans
-
- numXTiles = (copyWidth + x) / tilew;
- numYTiles = (copyHeight + y) / tileh;
-
- if (((float)(copyWidth + x ) % (float)tilew) > 0) {
- numXTiles += 1;
- }
-
- if (((float)(copyHeight + y ) % (float)tileh) > 0) {
- numYTiles += 1;
- }
-
- assert (data != null);
- int dataWidth = data.dataWidth;
- int dataHeight = data.dataHeight;
- int lineBytes = dataWidth * unitsPerPixel; // nbytes per line in
-
- if (yUp) {
- // destination buffer offset
- tileStart = (depthIndex * dataWidth * dataHeight + dstY * dataWidth + dstX) * unitsPerPixel;
- sign = 1;
- dstLineBytes = lineBytes;
- } else {
- // destination buffer offset
- tileStart = (depthIndex * dataWidth * dataHeight + (dataHeight - dstY - 1) * dataWidth + dstX) * unitsPerPixel;
- sign = -1;
- dstLineBytes = -lineBytes;
- }
-
-/*
- System.err.println("tileStart= " + tileStart + " dstLineBytes= " + dstLineBytes);
- System.err.println("startw= " + startw);
- */
-
- // allocate memory for a pixel
- ras = ri.getTile(minTileX,minTileY);
- pixel = getDataElementBuffer(ras);
- byte[] dstBuffer = imageData.getAsByteArray();
-
- switch(numberOfComponents) {
- case 4: {
- // System.err.println("Case 1: byReference = "+byReference);
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copyWidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.err.println("curh = "+curh+" curw = "+curw);
- //System.err.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.err.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- dstBuffer[j++] = (byte)cm.getGreen(pixel);
- dstBuffer[j++] = (byte)cm.getBlue(pixel);
- dstBuffer[j++] = (byte)cm.getAlpha(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * unitsPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += dataWidth * unitsPerPixel * curh * sign;
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- case 3: {
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copyWidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.err.println("curh = "+curh+" curw = "+curw);
- //System.err.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.err.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- dstBuffer[j++] = (byte)cm.getGreen(pixel);
- dstBuffer[j++] = (byte)cm.getBlue(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * unitsPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += dataWidth * unitsPerPixel * curh * sign;
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- case 2: {
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copyWidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.err.println("curh = "+curh+" curw = "+curw);
- //System.err.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.err.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- dstBuffer[j++] = (byte)cm.getAlpha(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * unitsPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
-
- tileStart += dataWidth * unitsPerPixel * curh * sign;
-
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
- case 1: {
- for (n = minTileY; n < minTileY+numYTiles; n++) {
-
- dstBegin = tileStart; // destination buffer offset
- tmpw = copyWidth; // reset the width to be copied
- curw = startw; // reset the width to be copied of
- // the left most tile
- x = srcX - startXTile; // reset the starting x offset of
- // the left most tile
-
- for (m = minTileX; m < minTileX+numXTiles; m++) {
-
- // retrieve the raster for the next tile
- ras = ri.getTile(m,n);
-
- j = dstBegin;
- offset = 0;
-
- //System.err.println("curh = "+curh+" curw = "+curw);
- //System.err.println("x = "+x+" y = "+y);
-
- for (h = y; h < (y + curh); h++) {
- // System.err.println("j = "+j);
- for (w = x; w < (x + curw); w++) {
- ras.getDataElements(w, h, pixel);
- dstBuffer[j++] = (byte)cm.getRed(pixel);
- }
- offset += dstLineBytes;
- j = dstBegin + offset;
- }
-
- // advance the destination buffer offset
- dstBegin += curw * unitsPerPixel;
-
- // move to the next tile in x direction
- x = 0;
-
- // determine the width of copy region of the next tile
-
- tmpw -= curw;
- if (tmpw < tilew) {
- curw = tmpw;
- } else {
- curw = tilew;
- }
- }
-
- // we are done copying an array of tiles in the x direction
- // advance the tileStart offset
- tileStart += dataWidth * unitsPerPixel * curh * sign;
-
- // move to the next set of tiles in y direction
- y = 0;
-
- // determine the height of copy region for the next set
- // of tiles
- tmph -= curh;
- if (tmph < tileh) {
- curh = tmph;
- } else {
- curh = tileh;
- }
- }
- }
- break;
-
- default:
- assert false;
- }
-
- if((imageData == data) && (imageDataPowerOfTwo != null)) {
- updateImageDataPowerOfTwo(depthIndex);
- }
- }
-
-
- void evaluateExtensions(Canvas3D canvas) {
- // Issue 366: need to synchronize since it could be called concurrently
- // from multiple renderers (and maybe the renderer(s) and renderbin)
- synchronized (evaluateExtLock) {
- // For performance reason the ordering of the following 2 statements is intentional.
- // So that we only need to do format conversion for imageData only
- evaluateExtABGR(canvas.extensionsSupported);
- evaluateExtNonPowerOfTwo(canvas.textureExtendedFeatures);
- }
-
- }
-
-
- void evaluateExtABGR(int ext) {
-
-
- // If abgrSupported is false, a copy has been created so
- // we don't have to check again.
- if(!abgrSupported) {
- return;
- }
-
- if(getImageFormatType() != ImageFormatType.TYPE_BYTE_ABGR) {
- return;
- }
-
- if((ext & Canvas3D.EXT_ABGR) != 0) {
- return;
- }
-
- // ABGR is unsupported, set flag to false.
- abgrSupported = false;
- convertImageDataFromABGRToRGBA();
-
- }
-
- private int getClosestPowerOf2(int value) {
-
- if (value < 1)
- return value;
-
- int powerValue = 1;
- for (;;) {
- powerValue *= 2;
- if (value < powerValue) {
- // Found max bound of power, determine which is closest
- int minBound = powerValue/2;
- if ((powerValue - value) >
- (value - minBound))
- return minBound;
- else
- return powerValue;
- }
- }
- }
-
- private int getCeilPowerOf2(int value) {
-
- if (value < 1)
- return value;
-
- int powerValue = 1;
- for (;;) {
- powerValue *= 2;
- if (value <= powerValue) {
- // Found max bound of power
- return powerValue;
- }
- }
- }
-
- void evaluateExtNonPowerOfTwo(int ext) {
- // Only need to enforce for Raster or Background.
- if(!enforceNonPowerOfTwoSupport) {
- return;
- }
-
- // If npotSupported is false, a copy power of two image has been created
- // so we don't have to check again.
- if(!npotSupported) {
- return;
- }
-
- if (imageData == null && !isByReference()) {
- return;
- }
-
- if((ext & Canvas3D.TEXTURE_NON_POWER_OF_TWO) != 0) {
- return;
- }
-
- // NPOT is unsupported, set flag to false.
- npotSupported = false;
-
- int npotWidth;
- int npotHeight;
- // Always scale up if image size is smaller 512*512.
- if((width * height) < IMAGE_SIZE_512X512) {
- npotWidth = getCeilPowerOf2(width);
- npotHeight = getCeilPowerOf2(height);
- } else {
- npotWidth = getClosestPowerOf2(width);
- npotHeight = getClosestPowerOf2(height);
- }
-
- // System.err.println("width " + width + " height " + height + " npotWidth " + npotWidth + " npotHeight " + npotHeight);
-
- float xScale = (float)npotWidth/(float)width;
- float yScale = (float)npotHeight/(float)height;
-
- // scale if scales aren't 1.0
- if (!(xScale == 1.0f && yScale == 1.0f)) {
-
- if (imageData == null) {
- // This is a byRef, support format and is a RenderedImage case.
- // See ImageComponent2DRetained.set(RenderedImage image)
- RenderedImage ri = (RenderedImage) getRefImage(0);
-
- assert !(ri instanceof BufferedImage);
-
- // Create a buffered image from renderImage
- ColorModel cm = ri.getColorModel();
- WritableRaster wRaster = ri.copyData(null);
- ri = new BufferedImage(cm,
- wRaster,
- cm.isAlphaPremultiplied()
- ,null);
-
-
- // Create image data object with buffer for image. */
- imageData = createRenderedImageDataObject(null);
- copySupportedImageToImageData(ri, 0, imageData);
-
- }
-
- assert imageData != null;
-
- // Create a supported BufferedImage type.
- BufferedImage bi = imageData.createBufferedImage(0);
-
- int imageType = bi.getType();
- BufferedImage scaledImg = new BufferedImage(npotWidth, npotHeight, imageType);
-
- AffineTransform at = AffineTransform.getScaleInstance(xScale,
- yScale);
-
- powerOfTwoATOp = new AffineTransformOp(at,
- AffineTransformOp.TYPE_BILINEAR);
-
- powerOfTwoATOp.filter(bi, scaledImg);
-
- // System.err.println("bi " + bi.getColorModel());
- // System.err.println("scaledImg " + scaledImg.getColorModel());
-
- imageDataPowerOfTwo = createRenderedImageDataObject(null, npotWidth, npotHeight);
- // Since bi is created from imageData, it's imageType is supported.
- copySupportedImageToImageData(scaledImg, 0, imageDataPowerOfTwo);
-
- } else {
- imageDataPowerOfTwo = null;
- }
- }
-
- void convertImageDataFromABGRToRGBA() {
-
- // Unsupported format on HW, switch to slow copy.
- imageFormatType = ImageFormatType.TYPE_BYTE_RGBA;
- imageTypeIsSupported = false;
-
- // Only need to convert imageData
- imageData.convertFromABGRToRGBA();
-
- }
-
- /**
- * Copy supported ImageType from ImageData to the user defined bufferedImage
- */
- void copyToRefImage(int depth) {
- int h;
- int rowBegin, // src begin row index
- srcBegin, // src begin offset
- dstBegin; // dst begin offset
-
- // refImage has to be a BufferedImage for off screen and read raster
- assert refImage[depth] != null;
- assert (refImage[depth] instanceof BufferedImage);
-
- BufferedImage bi = (BufferedImage)refImage[depth];
- int dstUnitsPerRow = width * unitsPerPixel; // bytes per row in dst image
- rowBegin = 0;
-
- if (yUp) {
- dstBegin = (depth * width * height) * unitsPerPixel;
- } else {
- dstBegin = (depth * width * height + (height - 1) * width ) * unitsPerPixel;
- dstUnitsPerRow = - 1 * dstUnitsPerRow;
- }
-
- int scanline = width * unitsPerPixel;
- srcBegin = (rowBegin * width ) * unitsPerPixel;
-
- switch(imageData.getType()) {
- case TYPE_BYTE_ARRAY:
- byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- byte[] srcByteBuffer = imageData.getAsByteArray();
- for (h = 0; h < height; h++) {
- System.arraycopy(srcByteBuffer, srcBegin, dstByteBuffer, dstBegin, scanline);
- dstBegin += dstUnitsPerRow;
- srcBegin += scanline;
- }
- break;
-
- case TYPE_INT_ARRAY:
- int[] dstIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- int[] srcIntBuffer = imageData.getAsIntArray();
- for (h = 0; h < height; h++) {
- System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, dstBegin, scanline);
- dstBegin += dstUnitsPerRow;
- srcBegin += scanline;
- }
- break;
- default:
- assert false;
- }
-
- }
-
- /**
- * Copy image to the user defined bufferedImage ( 3 or 4 components only )
- */
- void copyToRefImageWithFormatConversion(int depth) {
- int w, h, i, j;
- int dstBegin, dstInc, dstIndex, dstIndexInc;
- // refImage has to be a BufferedImage for off screen and read raster
- assert refImage[depth] != null;
- assert (refImage[depth] instanceof BufferedImage);
-
- BufferedImage bi = (BufferedImage)refImage[depth];
- int biType = bi.getType();
- byte[] buf = imageData.getAsByteArray();
-
- // convert from Ydown to Yup for texture
- if (!yUp) {
- dstInc = -1 * width;
- dstBegin = (height - 1) * width;
- dstIndex = height -1;
- dstIndexInc = -1;
- } else {
- dstInc = width;
- dstBegin = 0;
- dstIndex = 0;
- dstIndexInc = 1;
- }
-
- switch (biType) {
- case BufferedImage.TYPE_INT_ARGB:
- int[] intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
- switch (imageFormatType) {
- case TYPE_BYTE_RGBA:
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = (((buf[j+3] &0xff) << 24) | // a
- ((buf[j] &0xff) << 16) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)); // b
- }
- }
- break;
- case TYPE_BYTE_RGB:
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=3, i++) {
- intData[i] = (0xff000000 | // a
- ((buf[j] &0xff) << 16) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)); // b
- }
- }
- break;
- default:
- assert false;
- }
- break;
-
- case BufferedImage.TYPE_INT_RGB:
- intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = (0xff000000 | // a
- ((buf[j] &0xff) << 16) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)); // b
- }
- }
- break;
-
- case BufferedImage.TYPE_4BYTE_ABGR:
- byte[] byteData =
- ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
-
- //Issue 381: dstBegin contains pixel count, but we are looping over byte count. In case of YDown, it contains a count that is decremented and if we do not multiply, we have an AIOOB thrown at 25% of the copy.
- dstBegin <<= 2;
-
- switch (imageFormatType) {
- case TYPE_BYTE_RGBA:
- for(h = 0; h < height; h++, dstBegin += (dstInc << 2)) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4) {
- byteData[i++] = buf[j+3]; // a
- byteData[i++] = buf[j+2]; // b
- byteData[i++] = buf[j+1];// g
- byteData[i++] = buf[j]; // r
- }
- }
- break;
- case TYPE_BYTE_RGB:
- for(h = 0; h < height; h++, dstBegin += (dstInc << 2)) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=3) {
- byteData[i++] = (byte) 0xff; // a
- byteData[i++] = buf[j+2]; // b
- byteData[i++] = buf[j+1];// g
- byteData[i++] = buf[j]; // r
- }
- }
- break;
- default:
- assert false;
- }
- break;
-
- case BufferedImage.TYPE_INT_BGR:
- intData =
- ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- // Multiply by 4 to get the byte incr and start point
- j = 0;
-
- for(h = 0; h < height; h++, dstBegin += dstInc) {
- i = dstBegin;
- for (w = 0; w < width; w++, j+=4, i++) {
- intData[i] = (0xff000000 | // a
- ((buf[j] &0xff) ) | // r
- ((buf[j+1] &0xff) << 8) | // g
- (buf[j+2] & 0xff)<< 16); // b
- }
- }
- break;
- default:
- assert false;
- }
-
- }
-
- // Add a user to the userList
- synchronized void addUser(NodeComponentRetained node) {
- userList.add(node);
- }
-
- // Add a user to the userList
- synchronized void removeUser(NodeComponentRetained node) {
- int i = userList.indexOf(node);
- if (i >= 0) {
- userList.remove(i);
- }
- }
-
- /*
- *
- * @exception IllegalSharingException if this image is
- * being used by a Canvas3D as an off-screen buffer.
- */
- @Override
- void setLive(boolean inBackgroundGroup, int refCount) {
- // Do illegalSharing check.
- if(getUsedByOffScreen()) {
- throw new IllegalSharingException(J3dI18N.getString("ImageComponent3"));
- }
- super.setLive(inBackgroundGroup, refCount);
- }
-
- /**
- * ImageComponent object doesn't really have mirror object.
- * But it's using the updateMirrorObject interface to propagate
- * the changes to the users
- */
- @Override
- synchronized void updateMirrorObject(int component, Object value) {
- // System.err.println("ImageComponent.updateMirrorObject");
- if ((component & IMAGE_CHANGED) == 0 &&
- (component & SUBIMAGE_CHANGED) == 0)
- return;
-
- for (int i = userList.size() - 1; i >= 0; i--) {
- NodeComponentRetained user = userList.get(i);
- if (user == null)
- continue;
-
- if (user instanceof TextureRetained) {
- ((TextureRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
- }
- else if (user instanceof RasterRetained) {
- ((RasterRetained)user).notifyImageComponentImageChanged(this, (ImageComponentUpdateInfo)value);
- }
- }
- }
-
- final void sendMessage(int attrMask, Object attr) {
-
- J3dMessage createMessage = new J3dMessage();
- createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES |
- J3dThread.UPDATE_RENDER;
- createMessage.type = J3dMessage.IMAGE_COMPONENT_CHANGED;
- createMessage.universe = null;
- createMessage.args[0] = this;
- createMessage.args[1]= new Integer(attrMask);
- createMessage.args[2] = attr;
- createMessage.args[3] = new Integer(changedFrequent);
- VirtualUniverse.mc.processMessage(createMessage);
- }
-
- @Override
- void handleFrequencyChange(int bit) {
- if (bit == ImageComponent.ALLOW_IMAGE_WRITE) {
- setFrequencyChangeMask(ImageComponent.ALLOW_IMAGE_WRITE, 0x1);
- }
- }
-
- static Object getDataElementBuffer(java.awt.image.Raster ras) {
- int nc = ras.getNumDataElements();
-
- switch (ras.getTransferType()) {
- case DataBuffer.TYPE_INT:
- return new int[nc];
- case DataBuffer.TYPE_BYTE:
- return new byte[nc];
- case DataBuffer.TYPE_USHORT:
- case DataBuffer.TYPE_SHORT:
- return new short[nc];
- case DataBuffer.TYPE_FLOAT:
- return new float[nc];
- case DataBuffer.TYPE_DOUBLE:
- return new double[nc];
- }
- // Should not happen
- return null;
- }
-
- /**
- * Wrapper class for image data.
- * Currently supports byte array and int array.
- * Will eventually support NIO ByteBuffer and IntBuffer.
- */
- class ImageData {
-
- private Object data = null;
- private ImageDataType imageDataType = ImageDataType.TYPE_NULL;
- private int length = 0;
- private boolean dataIsByRef = false;
- private int dataWidth, dataHeight;
-
- /**
- * Constructs a new ImageData buffer of the specified type with the
- * specified length.
- */
- ImageData(ImageDataType imageDataType, int length, int dataWidth, int dataHeight) {
- this.imageDataType = imageDataType;
- this.length = length;
- this.dataWidth = dataWidth;
- this.dataHeight = dataHeight;
- this.dataIsByRef = false;
-
- switch (imageDataType) {
- case TYPE_BYTE_ARRAY:
- data = new byte[length];
- break;
- case TYPE_INT_ARRAY:
- data = new int[length];
- break;
- case TYPE_BYTE_BUFFER:
- ByteOrder order = ByteOrder.nativeOrder();
- data = ByteBuffer.allocateDirect(length).order(order);
- break;
- case TYPE_INT_BUFFER:
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Constructs a new ImageData buffer of the specified type with the
- * specified length and the specified byRefImage as data.
- */
- ImageData(ImageDataType imageDataType, int length, int dataWidth, int dataHeight,
- Object byRefImage) {
- BufferedImage bi;
- NioImageBuffer nio;
-
- this.imageDataType = imageDataType;
- this.length = length;
- this.dataWidth = dataWidth;
- this.dataHeight = dataHeight;
- this.dataIsByRef = true;
-
- switch (imageDataType) {
- case TYPE_BYTE_ARRAY:
- bi = (BufferedImage) byRefImage;
- data = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- break;
- case TYPE_INT_ARRAY:
- bi = (BufferedImage) byRefImage;
- data = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- break;
- case TYPE_BYTE_BUFFER:
- case TYPE_INT_BUFFER:
- nio = (NioImageBuffer) byRefImage;
- data = nio.getDataBuffer();
- break;
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Constructs a new ImageData buffer from the specified
- * object. This object stores a reference to the input image data.
- */
- ImageData(Object data, boolean isByRef) {
- this.data = data;
- dataIsByRef = isByRef;
- dataWidth = ((ImageData) data).dataWidth;
- dataHeight = ((ImageData) data).dataHeight;
-
- if (data == null) {
- imageDataType = ImageDataType.TYPE_NULL;
- length = 0;
- } else if (data instanceof byte[]) {
- imageDataType = ImageDataType.TYPE_BYTE_ARRAY;
- length = ((byte[]) data).length;
- } else if (data instanceof int[]) {
- imageDataType = ImageDataType.TYPE_INT_ARRAY;
- length = ((int[]) data).length;
- } else if (data instanceof ByteBuffer) {
- imageDataType = ImageDataType.TYPE_BYTE_BUFFER;
- length = ((ByteBuffer) data).limit();
- } else if (data instanceof IntBuffer) {
- imageDataType = ImageDataType.TYPE_INT_BUFFER;
- length = ((IntBuffer) data).limit();
- } else {
- assert false;
- }
- }
-
- /**
- * Returns the type of this DataBuffer.
- */
- ImageDataType getType() {
- return imageDataType;
- }
-
- /**
- * Returns the number of elements in this DataBuffer.
- */
- int length() {
- return length;
- }
-
- /**
- * Returns the width of this DataBuffer.
- */
- int getWidth() {
- return dataWidth;
- }
-
- /**
- * Returns the height of this DataBuffer.
- */
- int getHeight() {
- return dataHeight;
- }
-
- /**
- * Returns this DataBuffer as an Object.
- */
- Object get() {
- return data;
- }
-
- /**
- * Returns is this data is byRef. No internal data is made.
- */
- boolean isDataByRef() {
- return dataIsByRef;
- }
-
-
- /**
- * Returns this DataBuffer as a byte array.
- */
- byte[] getAsByteArray() {
- return (byte[]) data;
- }
-
- /**
- * Returns this DataBuffer as an int array.
- */
- int[] getAsIntArray() {
- return (int[]) data;
- }
-
- /**
- * Returns this DataBuffer as an nio ByteBuffer.
- */
- ByteBuffer getAsByteBuffer() {
- return (ByteBuffer) data;
- }
-
- /**
- * Returns this DataBuffer as an nio IntBuffer.
- */
- IntBuffer getAsIntBuffer() {
- return (IntBuffer) data;
- }
-
- // Handle TYPE_BYTE_LA only
- void copyByLineAndExpand(BufferedImage bi, int depthIndex) {
- int h;
- int srcBegin, // src begin offset
- dstBegin; // dst begin offset
-
- assert (imageData.getType() == ImageDataType.TYPE_BYTE_ARRAY);
- assert (imageFormatType == ImageFormatType.TYPE_BYTE_LA);
-
- int unitsPerRow = width * unitsPerPixel; // bytes per row
- int scanline = unitsPerRow;
- if (yUp) {
- srcBegin = (depthIndex * width * height) * unitsPerPixel;
- } else {
- srcBegin = (depthIndex * width * height + (height - 1) * width) * unitsPerPixel;
- unitsPerRow = - 1 * unitsPerRow;
- }
-
- dstBegin = 0;
- // ABGR is 4 bytes per pixel
- int dstUnitsPerRow = width * 4;
-
- byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- byte[] srcByteBuffer = imageData.getAsByteArray();
- for (h = 0; h < height; h++) {
- for( int v = 0, w = 0; w < scanline; w += unitsPerPixel, v += 4) {
- dstByteBuffer[dstBegin+v] = srcByteBuffer[srcBegin+w+1]; // Alpha
- dstByteBuffer[dstBegin+v+1] = 0;
- dstByteBuffer[dstBegin+v+2] = 0;
- dstByteBuffer[dstBegin+v+3] = srcByteBuffer[srcBegin+w]; // Red
- }
-
- dstBegin += dstUnitsPerRow;
- srcBegin += unitsPerRow;
- }
-
- }
-
- // Quick line by line copy
- void copyByLine(BufferedImage bi, int depthIndex, boolean swapNeeded) {
-
- int h;
- int srcBegin, // src begin offset
- dstBegin; // dst begin offset
-
- int unitsPerRow = width * unitsPerPixel; // bytes per row
- int copyUnits = unitsPerRow;
- if (yUp) {
- srcBegin = (depthIndex * width * height) * unitsPerPixel;
- } else {
- srcBegin = (depthIndex * width * height + (height - 1) * width) * unitsPerPixel;
- unitsPerRow = - 1 * unitsPerRow;
- }
-
- dstBegin = 0;
-
- switch(imageData.getType()) {
- case TYPE_BYTE_ARRAY:
- byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- byte[] srcByteBuffer = imageData.getAsByteArray();
- for (h = 0; h < height; h++) {
- if(!swapNeeded) {
- System.arraycopy(srcByteBuffer, srcBegin,
- dstByteBuffer, dstBegin, copyUnits);
- } else {
- if(imageFormatType == ImageFormatType.TYPE_BYTE_RGB) {
- assert (unitsPerPixel == 3);
- for(int w = 0; w < copyUnits; w += unitsPerPixel) {
- dstByteBuffer[dstBegin+w] = srcByteBuffer[srcBegin+w+2];
- dstByteBuffer[dstBegin+w+1] = srcByteBuffer[srcBegin+w+1];
- dstByteBuffer[dstBegin+w+2] = srcByteBuffer[srcBegin+w];
- }
- } else if(imageFormatType == ImageFormatType.TYPE_BYTE_RGBA) {
- assert (unitsPerPixel == 4);
- for(int w = 0; w < copyUnits; w += unitsPerPixel) {
- dstByteBuffer[dstBegin+w] = srcByteBuffer[srcBegin+w+3];
- dstByteBuffer[dstBegin+w+1] = srcByteBuffer[srcBegin+w+2];
- dstByteBuffer[dstBegin+w+2] = srcByteBuffer[srcBegin+w+1];
- dstByteBuffer[dstBegin+w+3] = srcByteBuffer[srcBegin+w];
- }
- } else {
- assert false;
- }
- }
- dstBegin += copyUnits;
- srcBegin += unitsPerRow;
- }
- break;
-
- // INT case doesn't required to handle swapNeeded
- case TYPE_INT_ARRAY:
- assert (!swapNeeded);
- int[] dstIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- int[] srcIntBuffer = imageData.getAsIntArray();
- for (h = 0; h < height; h++) {
- System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, dstBegin, copyUnits);
- dstBegin += copyUnits;
- srcBegin += unitsPerRow;
- }
- break;
- default:
- assert false;
- }
- }
-
- void copyByBlock(BufferedImage bi, int depthIndex) {
- // src begin offset
- int srcBegin = depthIndex * width * height * unitsPerPixel;
-
- switch(imageData.getType()) {
- case TYPE_BYTE_ARRAY:
- byte[] dstByteBuffer = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- byte[] srcByteBuffer = imageData.getAsByteArray();
- System.arraycopy(srcByteBuffer, srcBegin, dstByteBuffer, 0, (height * width * unitsPerPixel));
- break;
- case TYPE_INT_ARRAY:
- int[] dstIntBuffer = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
- int[] srcIntBuffer = imageData.getAsIntArray();
- System.arraycopy(srcIntBuffer, srcBegin, dstIntBuffer, 0, (height * width * unitsPerPixel));
- break;
- default:
- assert false;
- }
- }
-
- // Need to check for imageData is null. if it is null return null.
- BufferedImage createBufferedImage(int depthIndex) {
- if(data != null) {
- int bufferType = BufferedImage.TYPE_CUSTOM;
- boolean swapNeeded = false;
-
- switch(imageFormatType) {
- case TYPE_BYTE_BGR:
- bufferType = BufferedImage.TYPE_3BYTE_BGR;
- break;
- case TYPE_BYTE_RGB:
- bufferType = BufferedImage.TYPE_3BYTE_BGR;
- swapNeeded = true;
- break;
- case TYPE_BYTE_ABGR:
- bufferType = BufferedImage.TYPE_4BYTE_ABGR;
- break;
- case TYPE_BYTE_RGBA:
- bufferType = BufferedImage.TYPE_4BYTE_ABGR;
- swapNeeded = true;
- break;
- // This is a special case. Need to handle separately.
- case TYPE_BYTE_LA:
- bufferType = BufferedImage.TYPE_4BYTE_ABGR;
- break;
- case TYPE_BYTE_GRAY:
- bufferType = BufferedImage.TYPE_BYTE_GRAY;
- break;
- case TYPE_INT_BGR:
- bufferType = BufferedImage.TYPE_INT_BGR;
- break;
- case TYPE_INT_RGB:
- bufferType = BufferedImage.TYPE_INT_RGB;
- break;
- case TYPE_INT_ARGB:
- bufferType = BufferedImage.TYPE_INT_ARGB;
- break;
- // Unsupported case, so shouldn't be here.
- case TYPE_USHORT_GRAY:
- bufferType = BufferedImage.TYPE_USHORT_GRAY;
- default:
- assert false;
-
- }
-
- BufferedImage bi = new BufferedImage(width, height, bufferType);
- if((!swapNeeded) && (imageFormatType != ImageFormatType.TYPE_BYTE_LA)) {
- if(yUp) {
- copyByBlock(bi, depthIndex);
- } else {
- copyByLine(bi, depthIndex, false);
- }
- } else if(swapNeeded) {
- copyByLine(bi, depthIndex, swapNeeded);
- } else if(imageFormatType == ImageFormatType.TYPE_BYTE_LA) {
- copyByLineAndExpand(bi, depthIndex);
- } else {
- assert false;
- }
-
- return bi;
-
- }
- return null;
- }
-
- void convertFromABGRToRGBA() {
- int i;
-
- if(imageDataType == ImageComponentRetained.ImageDataType.TYPE_BYTE_ARRAY) {
- // Note : Highly inefficient for depth > 0 case.
- // This method doesn't take into account of depth, it is assuming that
- // depth == 0, which is true for ImageComponent2D.
- byte[] srcBuffer, dstBuffer;
- srcBuffer = getAsByteArray();
-
- if(dataIsByRef) {
- dstBuffer = new byte[length];
- // Do copy and swap.
- for(i = 0; i < length; i +=4) {
- dstBuffer[i] = srcBuffer[i+3];
- dstBuffer[i+1] = srcBuffer[i+2];
- dstBuffer[i+2] = srcBuffer[i+1];
- dstBuffer[i+3] = srcBuffer[i];
- }
- data = dstBuffer;
- dataIsByRef = false;
-
- } else {
- byte a, b;
- // Do swap in place.
- for(i = 0; i < length; i +=4) {
- a = srcBuffer[i];
- b = srcBuffer[i+1];
- srcBuffer[i] = srcBuffer[i+3];
- srcBuffer[i+1] = srcBuffer[i+2];
- srcBuffer[i+2] = b;
- srcBuffer[i+3] = a;
- }
- }
- }
- else if(imageDataType == ImageComponentRetained.ImageDataType.TYPE_BYTE_BUFFER) {
-
- assert dataIsByRef;
- ByteBuffer srcBuffer, dstBuffer;
-
- srcBuffer = getAsByteBuffer();
- srcBuffer.rewind();
-
- ByteOrder order = ByteOrder.nativeOrder();
- dstBuffer = ByteBuffer.allocateDirect(length).order(order);
- dstBuffer.rewind();
-
- // Do copy and swap.
- for(i = 0; i < length; i +=4) {
- dstBuffer.put(i, srcBuffer.get(i+3));
- dstBuffer.put(i+1, srcBuffer.get(i+2));
- dstBuffer.put(i+2, srcBuffer.get(i+1));
- dstBuffer.put(i+3, srcBuffer.get(i));
- }
-
- dataIsByRef = false;
-
- }
- }
- }
-}