diff options
Diffstat (limited to 'src/javax/media/j3d/ImageComponentRetained.java')
-rw-r--r-- | src/javax/media/j3d/ImageComponentRetained.java | 2653 |
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; - - } - } - } -} |