OSDN Git Service

merge from jme10694
authorkobayasi <kobayasi@pscnet.co.jp>
Sat, 6 Jul 2013 21:35:10 +0000 (06:35 +0900)
committerkobayasi <kobayasi@pscnet.co.jp>
Sat, 6 Jul 2013 21:35:10 +0000 (06:35 +0900)
engine/src/core/com/jme3/texture/Texture2D.java
engine/src/core/com/jme3/texture/Texture3D.java
engine/src/core/com/jme3/texture/TextureArray.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/TextureCubeMap.java
engine/src/core/com/jme3/texture/TextureProcessor.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/image/BitMaskImageCodec.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/image/ByteAlignedImageCodec.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/image/ByteOffsetImageCodec.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/image/DefaultImageRaster.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/image/ImageCodec.java [new file with mode: 0644]
engine/src/core/com/jme3/texture/image/ImageRaster.java [new file with mode: 0644]

index cb0a733..2533d2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2010 jMonkeyEngine
+ * Copyright (c) 2009-2012 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 package com.jme3.texture;
 
+import com.jme3.export.InputCapsule;
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
-import com.jme3.export.InputCapsule;
 import com.jme3.export.OutputCapsule;
 import java.io.IOException;
 
index 90333b5..106351e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2010 jMonkeyEngine
+ * Copyright (c) 2009-2012 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,9 @@
  */
 package com.jme3.texture;
 
+import com.jme3.export.InputCapsule;
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
-import com.jme3.export.InputCapsule;
 import com.jme3.export.OutputCapsule;
 import java.io.IOException;
 
diff --git a/engine/src/core/com/jme3/texture/TextureArray.java b/engine/src/core/com/jme3/texture/TextureArray.java
new file mode 100644 (file)
index 0000000..32cf376
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2009-2012 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.texture;
+
+import com.jme3.texture.Image.Format;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements a Texture array
+ * warning, this feature is only supported on opengl 3.0 version.
+ * To check if a hardware supports TextureArray check : 
+ * renderManager.getRenderer().getCaps().contains(Caps.TextureArray)
+ * @author phate666
+ */
+public class TextureArray extends Texture {
+
+    private WrapMode wrapS = WrapMode.EdgeClamp;
+    private WrapMode wrapT = WrapMode.EdgeClamp;
+
+    /**
+     * Construct a TextureArray
+     * warning, this feature is only supported on opengl 3.0 version.
+     * To check if a hardware supports TextureArray check : 
+     * renderManager.getRenderer().getCaps().contains(Caps.TextureArray)
+     */
+    public TextureArray() {
+        super();
+    }
+
+    /**
+     * Construct a TextureArray from the given list of images.
+     * To check if a hardware supports TextureArray check : 
+     * renderManager.getRenderer().getCaps().contains(Caps.TextureArray)
+     * @param images 
+     */
+    public TextureArray(List<Image> images) {
+        super();
+        
+        int width = images.get(0).getWidth();
+        int height = images.get(0).getHeight();
+        Format format = images.get(0).getFormat();
+        Image arrayImage = new Image(format, width, height, null);
+
+        for (Image img : images) {
+            if (img.getHeight() != height || img.getWidth() != width) {
+                throw new IllegalArgumentException("Images in texture array must have same dimensions");
+            }
+            if (img.getFormat() != format) {
+                throw new IllegalArgumentException("Images in texture array must have same format");
+            }
+            
+            arrayImage.addData(img.getData(0));
+        }
+        setImage(arrayImage);
+    }
+
+    @Override
+    public Texture createSimpleClone() {
+        TextureArray clone = new TextureArray();
+        createSimpleClone(clone);
+        return clone;
+    }
+
+    @Override
+    public Texture createSimpleClone(Texture rVal) {
+        rVal.setWrap(WrapAxis.S, wrapS);
+        rVal.setWrap(WrapAxis.T, wrapT);
+        return super.createSimpleClone(rVal);
+    }
+
+    @Override
+    public Type getType() {
+        return Type.TwoDimensionalArray;
+    }
+
+    @Override
+    public WrapMode getWrap(WrapAxis axis) {
+        switch (axis) {
+            case S:
+                return wrapS;
+            case T:
+                return wrapT;
+            default:
+                throw new IllegalArgumentException("invalid WrapAxis: " + axis);
+        }
+    }
+
+    @Override
+    public void setWrap(WrapAxis axis, WrapMode mode) {
+        if (mode == null) {
+            throw new IllegalArgumentException("mode can not be null.");
+        } else if (axis == null) {
+            throw new IllegalArgumentException("axis can not be null.");
+        }
+        switch (axis) {
+            case S:
+                this.wrapS = mode;
+                break;
+            case T:
+                this.wrapT = mode;
+                break;
+            default:
+                throw new IllegalArgumentException("Not applicable for 2D textures");
+        }
+    }
+
+    @Override
+    public void setWrap(WrapMode mode) {
+        if (mode == null) {
+            throw new IllegalArgumentException("mode can not be null.");
+        }
+        this.wrapS = mode;
+        this.wrapT = mode;
+    }
+}
\ No newline at end of file
index 9b256d6..22debee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2010 jMonkeyEngine
+ * Copyright (c) 2009-2012 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 package com.jme3.texture;
 
+import com.jme3.export.InputCapsule;
 import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
-import com.jme3.export.InputCapsule;
 import com.jme3.export.OutputCapsule;
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 /**
  * Describes a cubemap texture.
@@ -63,9 +64,10 @@ public class TextureCubeMap extends Texture {
      * Face of the Cubemap as described by its directional offset from the
      * origin.
      */
-//    public enum Face {
-//        PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ;
-//    }
+    public enum Face {
+
+        PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ;
+    }
 
     public TextureCubeMap(){
         super();
@@ -75,6 +77,20 @@ public class TextureCubeMap extends Texture {
         super();
         setImage(img);
     }
+    
+    public TextureCubeMap(int width, int height, Image.Format format){
+        this(createEmptyLayeredImage(width, height, 6, format));
+    }
+
+    private static Image createEmptyLayeredImage(int width, int height,
+            int layerCount, Image.Format format) {
+        ArrayList<ByteBuffer> layers = new ArrayList<ByteBuffer>();
+        for(int i = 0; i < layerCount; i++) {
+            layers.add(null);
+        }
+        Image image = new Image(format, width, height, 0, layers);
+        return image;
+    }
 
     public Texture createSimpleClone() {
         return createSimpleClone(new TextureCubeMap());
diff --git a/engine/src/core/com/jme3/texture/TextureProcessor.java b/engine/src/core/com/jme3/texture/TextureProcessor.java
new file mode 100644 (file)
index 0000000..0ade0f7
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture;\r
+\r
+import com.jme3.asset.AssetKey;\r
+import com.jme3.asset.AssetProcessor;\r
+import com.jme3.asset.TextureKey;\r
+import java.nio.ByteBuffer;\r
+\r
+public class TextureProcessor implements AssetProcessor {\r
+\r
+    public Object postProcess(AssetKey key, Object obj) {\r
+        TextureKey texKey = (TextureKey) key;\r
+        Image img = (Image) obj;\r
+        if (img == null) {\r
+            return null;\r
+        }\r
+\r
+        Texture tex;\r
+        if (texKey.isAsCube()) {\r
+            if (texKey.isFlipY()) {\r
+                // also flip -y and +y image in cubemap\r
+                ByteBuffer pos_y = img.getData(2);\r
+                img.setData(2, img.getData(3));\r
+                img.setData(3, pos_y);\r
+            }\r
+            tex = new TextureCubeMap();\r
+        } else if (texKey.isAsTexture3D()) {\r
+            tex = new Texture3D();\r
+        } else {\r
+            tex = new Texture2D();\r
+        }\r
+\r
+        // enable mipmaps if image has them\r
+        // or generate them if requested by user\r
+        if (img.hasMipmaps() || texKey.isGenerateMips()) {\r
+            tex.setMinFilter(Texture.MinFilter.Trilinear);\r
+        }\r
+\r
+        tex.setAnisotropicFilter(texKey.getAnisotropy());\r
+        tex.setName(texKey.getName());\r
+        tex.setImage(img);\r
+        return tex;\r
+    }\r
+\r
+    public Object createClone(Object obj) {\r
+        Texture tex = (Texture) obj;\r
+        return tex.clone();\r
+    }\r
+    \r
+}\r
diff --git a/engine/src/core/com/jme3/texture/image/BitMaskImageCodec.java b/engine/src/core/com/jme3/texture/image/BitMaskImageCodec.java
new file mode 100644 (file)
index 0000000..a888dfa
--- /dev/null
@@ -0,0 +1,118 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture.image;\r
+\r
+import java.nio.ByteBuffer;\r
+\r
+class BitMaskImageCodec extends ImageCodec {\r
+    \r
+    // Shifts\r
+    final int as, rs, gs, bs;\r
+    boolean be = false;\r
+    \r
+    public BitMaskImageCodec(int bpp, int flags, int ac, int rc, int gc, int bc, int as, int rs, int gs, int bs) {\r
+        super(bpp, flags,\r
+                (int) (((long) 1 << ac) - 1),\r
+                (int) (((long) 1 << rc) - 1),\r
+                (int) (((long) 1 << gc) - 1),\r
+                (int) (((long) 1 << bc) - 1));\r
+\r
+        if (bpp > 4) {\r
+            throw new UnsupportedOperationException("Use ByteAlignedImageCodec for codecs with pixel sizes larger than 4 bytes");\r
+        }\r
+        \r
+        this.as = as;\r
+        this.rs = rs;\r
+        this.gs = gs;\r
+        this.bs = bs;\r
+    }\r
+    \r
+    private static int readPixelRaw(ByteBuffer buf, int idx, int bpp) {\r
+        //idx += bpp;\r
+        //int original = buf.get(--idx) & 0xff;\r
+        //while ((--bpp) > 0) {\r
+        //    original = (original << 8) | (buf.get(--idx) & 0xff);\r
+        //}\r
+        //return original;\r
+        //return buf.getInt(idx) & (0xFFFFFFFF >>> (32 - bpp));\r
+        int pixel = 0;\r
+        buf.position(idx);\r
+        for (int i = 0; i < bpp; i++) {\r
+            pixel = pixel | (buf.get() & 0xff) << (i * 8);\r
+        }\r
+        return pixel;\r
+    }\r
+    \r
+    private void writePixelRaw(ByteBuffer buf, int idx, int pixel, int bpp){\r
+//        buf.position(idx);\r
+//        if (!be){\r
+        // This works:\r
+//            while ((--bpp) >= 0){\r
+//                byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff);\r
+//                buf.put(idx + bpp, bt);\r
+//            }\r
+        // ==\r
+//        } else {\r
+//            for (int i = bpp - 1; i >= 0; i--) {\r
+//                byte bt = (byte) ((pixel >> (i * 8)) & 0xff);\r
+//                buf.put(idx + i, bt);\r
+//            }\r
+//        }\r
+        \r
+        buf.position(idx);\r
+        for (int i = 0; i < bpp; i++) {\r
+            buf.put( (byte)((pixel >> (8 * i)) & 0xff) );\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void readComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp) {\r
+        int inputPixel = readPixelRaw(buf, (x + y * width) * bpp, bpp);\r
+        components[0] = (inputPixel >> as) & maxAlpha;\r
+        components[1] = (inputPixel >> rs) & maxRed;\r
+        components[2] = (inputPixel >> gs) & maxGreen;\r
+        components[3] = (inputPixel >> bs) & maxBlue;\r
+    }\r
+\r
+    public void writeComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp) {\r
+        // Shift components then mask them\r
+        // Map all components into a single bitspace\r
+        int outputPixel = ((components[0] & maxAlpha) << as)\r
+                        | ((components[1] & maxRed) << rs)\r
+                        | ((components[2] & maxGreen) << gs)\r
+                        | ((components[3] & maxBlue) << bs);\r
+        \r
+        // Find index in image where to write pixel.\r
+        // Write the resultant bitspace into the pixel.\r
+        writePixelRaw(buf, (x + y * width) * bpp, outputPixel, bpp);\r
+    }\r
+}\r
diff --git a/engine/src/core/com/jme3/texture/image/ByteAlignedImageCodec.java b/engine/src/core/com/jme3/texture/image/ByteAlignedImageCodec.java
new file mode 100644 (file)
index 0000000..490a440
--- /dev/null
@@ -0,0 +1,127 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture.image;\r
+\r
+import java.nio.ByteBuffer;\r
+\r
+class ByteAlignedImageCodec extends ImageCodec {\r
+    \r
+    private final int ap, az, rp, rz, gp, gz, bp, bz;\r
+    boolean be;\r
+    \r
+    public ByteAlignedImageCodec(int bpp, int flags, int az, int rz, int gz, int bz, int ap, int rp, int gp, int bp) {\r
+        // Cast to long to compute max vals, since some components could be as high as 32 bits.\r
+        super(bpp, flags, \r
+                (int)(((long)1 << (az << 3)) - 1), \r
+                (int)(((long)1 << (rz << 3)) - 1), \r
+                (int)(((long)1 << (gz << 3)) - 1), \r
+                (int)(((long)1 << (bz << 3)) - 1));\r
+\r
+        this.ap = ap;\r
+        this.az = az;\r
+        this.rp = rp;\r
+        this.rz = rz;\r
+\r
+        this.gp = gp;\r
+        this.gz = gz;\r
+        this.bp = bp;\r
+        this.bz = bz;\r
+    }\r
+    \r
+    private static void readPixelRaw(ByteBuffer buf, int idx, int bpp, byte[] result) {\r
+        buf.position(idx);\r
+        buf.get(result, 0, bpp);\r
+    }\r
+    \r
+    private static void writePixelRaw(ByteBuffer buf, int idx, byte[] pixel, int bpp) {\r
+//        try {\r
+        buf.position(idx);\r
+        buf.put(pixel, 0, bpp);\r
+//        } catch (IndexOutOfBoundsException ex) {\r
+//            System.out.println("!");\r
+//        }\r
+    }\r
+    \r
+    private static int readComponent(byte[] encoded, int position, int size) {\r
+//        int component = encoded[position] & 0xff;\r
+//        while ((--size) > 0){\r
+//            component = (component << 8) | (encoded[++position] & 0xff);\r
+//        }\r
+//        return component;\r
+        try {\r
+            int component = 0;\r
+            for (int i = size - 1; i >= 0; i--) {\r
+                component = (component << 8) | (encoded[position + i] & 0xff);\r
+            }\r
+            return component;\r
+//        position += size - 1;\r
+//        \r
+//        while ((--size) >= 0) {\r
+//            component = (component << 8) | (encoded[position--] & 0xff);\r
+//        }\r
+//        return component;\r
+        } catch (ArrayIndexOutOfBoundsException ex){\r
+            ex.printStackTrace();\r
+            return 0;\r
+        }\r
+    }\r
+    \r
+    private void writeComponent(int component, int position, int size, byte[] result) {\r
+//        if (!be) {\r
+//            while ((--size) >= 0){\r
+//                byte bt = (byte) ((component >> (size * 8)) & 0xff);\r
+//                result[position++] = bt;\r
+//            }\r
+//        } else {\r
+            for (int i = 0; i < size; i++) {\r
+                byte bt = (byte) ((component >> (i * 8)) & 0xff);\r
+                result[position++] = bt;\r
+            }\r
+//        }\r
+    }\r
+    \r
+    public void readComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp) {\r
+        readPixelRaw(buf, (x + y * width) * bpp, bpp, tmp);\r
+        components[0] = readComponent(tmp, ap, az);\r
+        components[1] = readComponent(tmp, rp, rz);\r
+        components[2] = readComponent(tmp, gp, gz);\r
+        components[3] = readComponent(tmp, bp, bz);\r
+    }\r
+    \r
+    public void writeComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp) {\r
+        writeComponent(components[0], ap, az, tmp);\r
+        writeComponent(components[1], rp, rz, tmp);\r
+        writeComponent(components[2], gp, gz, tmp);\r
+        writeComponent(components[3], bp, bz, tmp);\r
+        writePixelRaw(buf, (x + y * width) * bpp, tmp, bpp);\r
+    }\r
+}\r
diff --git a/engine/src/core/com/jme3/texture/image/ByteOffsetImageCodec.java b/engine/src/core/com/jme3/texture/image/ByteOffsetImageCodec.java
new file mode 100644 (file)
index 0000000..908bcdf
--- /dev/null
@@ -0,0 +1,89 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture.image;\r
+\r
+import java.nio.ByteBuffer;\r
+\r
+public class ByteOffsetImageCodec extends ImageCodec {\r
+\r
+    private int redPos, greenPos, bluePos, alphaPos;\r
+    \r
+    public ByteOffsetImageCodec(int bpp, int flags,  int alphaPos, int redPos, int greenPos, int bluePos) {\r
+        super(bpp, flags, alphaPos != -1 ? 255 : 0,\r
+                          redPos != -1 ? 255 : 0,\r
+                          greenPos != -1 ? 255 : 0,\r
+                          bluePos != -1 ? 255 : 0);\r
+        this.alphaPos = alphaPos;\r
+        this.redPos = redPos;\r
+        this.greenPos = greenPos;\r
+        this.bluePos = bluePos;\r
+    }\r
+    \r
+    @Override\r
+    public void readComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp) {\r
+        int i = (y * width + x) * bpp;\r
+        buf.position(i);\r
+        buf.get(tmp, 0, bpp);\r
+        if (alphaPos != -1) {\r
+            components[0] = tmp[alphaPos] & 0xff;\r
+        }\r
+        if (redPos != -1) {\r
+            components[1] = tmp[redPos] & 0xff;\r
+        }\r
+        if (greenPos != -1) {\r
+            components[2] = tmp[greenPos] & 0xff;\r
+        }\r
+        if (bluePos != -1) {\r
+            components[3] = tmp[bluePos] & 0xff;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void writeComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp) {\r
+        int i = (y * width + x) * bpp;\r
+        if (alphaPos != -1) {\r
+            tmp[alphaPos] = (byte) components[0];\r
+        }\r
+        if (redPos != -1) {\r
+            tmp[redPos] = (byte) components[1];\r
+        }\r
+        if (greenPos != -1) {\r
+            tmp[greenPos] = (byte) components[2];\r
+        }\r
+        if (bluePos != -1) {\r
+            tmp[bluePos] = (byte) components[3];\r
+        }\r
+        buf.position(i);\r
+        buf.put(tmp, 0, bpp);\r
+    }\r
+    \r
+}\r
diff --git a/engine/src/core/com/jme3/texture/image/DefaultImageRaster.java b/engine/src/core/com/jme3/texture/image/DefaultImageRaster.java
new file mode 100644 (file)
index 0000000..32fc99e
--- /dev/null
@@ -0,0 +1,169 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture.image;\r
+\r
+import com.jme3.math.ColorRGBA;\r
+import com.jme3.math.FastMath;\r
+import com.jme3.texture.Image;\r
+import java.nio.ByteBuffer;\r
+\r
+public class DefaultImageRaster extends ImageRaster {\r
+    \r
+    private final int[] components = new int[4];\r
+    private ByteBuffer buffer;\r
+    private final Image image;\r
+    private final ImageCodec codec;\r
+    private final int width;\r
+    private final int height;\r
+    private final byte[] temp;\r
+    private int slice;\r
+    \r
+    private void rangeCheck(int x, int y) {\r
+        if (x < 0 || y < 0 || x >= width || y >= height) {\r
+            throw new IllegalArgumentException("x and y must be inside the image dimensions");\r
+        }\r
+    }\r
+    \r
+    public DefaultImageRaster(Image image, int slice) {\r
+        this.image = image;\r
+        this.slice = slice;\r
+        this.buffer = image.getData(slice);\r
+        this.codec = ImageCodec.lookup(image.getFormat());\r
+        this.width = image.getWidth();\r
+        this.height = image.getHeight();\r
+        if (codec instanceof ByteAlignedImageCodec || codec instanceof ByteOffsetImageCodec) {\r
+            this.temp = new byte[codec.bpp];\r
+        } else {\r
+            this.temp = null;\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public int getWidth() {\r
+        return width;\r
+    }\r
+\r
+    @Override\r
+    public int getHeight() {\r
+        return height;\r
+    }\r
+    \r
+    @Override\r
+    public void setPixel(int x, int y, ColorRGBA color) {\r
+        rangeCheck(x, y);\r
+        \r
+        // Check flags for grayscale\r
+        if (codec.isGray) {\r
+            float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;\r
+            color = new ColorRGBA(gray, gray, gray, color.a);\r
+        }\r
+\r
+        switch (codec.type) {\r
+            case ImageCodec.FLAG_F16:\r
+                components[0] = (int) FastMath.convertFloatToHalf(color.a);\r
+                components[1] = (int) FastMath.convertFloatToHalf(color.r);\r
+                components[2] = (int) FastMath.convertFloatToHalf(color.g);\r
+                components[3] = (int) FastMath.convertFloatToHalf(color.b);\r
+                break;\r
+            case ImageCodec.FLAG_F32:\r
+                components[0] = (int) Float.floatToIntBits(color.a);\r
+                components[1] = (int) Float.floatToIntBits(color.r);\r
+                components[2] = (int) Float.floatToIntBits(color.g);\r
+                components[3] = (int) Float.floatToIntBits(color.b);\r
+                break;\r
+            case 0:\r
+                // Convert color to bits by multiplying by size\r
+                components[0] = Math.min( (int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);\r
+                components[1] = Math.min( (int) (color.r * codec.maxRed + 0.5f), codec.maxRed);\r
+                components[2] = Math.min( (int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);\r
+                components[3] = Math.min( (int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);\r
+                break;\r
+        }     \r
+        codec.writeComponents(getBuffer(), x, y, width, components, temp);\r
+        image.setUpdateNeeded();\r
+    }\r
+    \r
+    private ByteBuffer getBuffer(){\r
+        if(buffer == null){\r
+            this.buffer = image.getData(slice);\r
+        }\r
+        return buffer;\r
+    }\r
+    \r
+    @Override\r
+    public ColorRGBA getPixel(int x, int y, ColorRGBA store) {\r
+        rangeCheck(x, y);\r
+        \r
+        codec.readComponents(getBuffer(), x, y, width, components, temp);\r
+        if (store == null) {\r
+            store = new ColorRGBA();\r
+        }\r
+        switch (codec.type) {\r
+            case ImageCodec.FLAG_F16:\r
+                store.set(FastMath.convertHalfToFloat((short)components[1]),\r
+                          FastMath.convertHalfToFloat((short)components[2]),\r
+                          FastMath.convertHalfToFloat((short)components[3]),\r
+                          FastMath.convertHalfToFloat((short)components[0]));\r
+                break;\r
+            case ImageCodec.FLAG_F32:\r
+                store.set(Float.intBitsToFloat((int)components[1]),\r
+                          Float.intBitsToFloat((int)components[2]),\r
+                          Float.intBitsToFloat((int)components[3]),\r
+                          Float.intBitsToFloat((int)components[0]));\r
+                break;\r
+            case 0:\r
+                // Convert to float and divide by bitsize to get into range 0.0 - 1.0.\r
+                store.set((float)components[1] / codec.maxRed,\r
+                          (float)components[2] / codec.maxGreen,\r
+                          (float)components[3] / codec.maxBlue,\r
+                          (float)components[0] / codec.maxAlpha);\r
+                break;\r
+        }\r
+        if (codec.isGray) {\r
+            store.g = store.b = store.r;\r
+        } else {\r
+            if (codec.maxRed == 0) {\r
+                store.r = 1;\r
+            }\r
+            if (codec.maxGreen == 0) {\r
+                store.g = 1;\r
+            }\r
+            if (codec.maxBlue == 0) {\r
+                store.b = 1;\r
+            }\r
+            if (codec.maxAlpha == 0) {\r
+                store.a = 1;\r
+            }\r
+        }\r
+        return store;\r
+    }\r
+}\r
diff --git a/engine/src/core/com/jme3/texture/image/ImageCodec.java b/engine/src/core/com/jme3/texture/image/ImageCodec.java
new file mode 100644 (file)
index 0000000..504e2be
--- /dev/null
@@ -0,0 +1,187 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture.image;\r
+\r
+import com.jme3.texture.Image;\r
+import com.jme3.texture.Image.Format;\r
+import java.nio.ByteBuffer;\r
+import java.util.EnumMap;\r
+\r
+abstract class ImageCodec {\r
+    \r
+    public static final int FLAG_F16 = 1, FLAG_F32 = 2, FLAG_GRAY = 4; //, FLAG_ALPHAONLY = 8, FLAG_SHAREDEXP = 16;\r
+    private static final EnumMap<Image.Format, ImageCodec> params = new EnumMap<Image.Format, ImageCodec>(Image.Format.class);\r
+    \r
+    protected final int bpp, type, maxAlpha, maxRed, maxGreen, maxBlue;\r
+    protected final boolean isGray;\r
+\r
+    public ImageCodec(int bpp, int flags, int maxAlpha, int maxRed, int maxGreen, int maxBlue) {\r
+        this.bpp = bpp;\r
+        this.isGray = (flags & FLAG_GRAY) != 0;\r
+        this.type = flags & ~FLAG_GRAY;\r
+        this.maxAlpha = maxAlpha;\r
+        this.maxRed = maxRed;\r
+        this.maxGreen = maxGreen;\r
+        this.maxBlue = maxBlue;\r
+    }\r
+\r
+    static {       \r
+        // == ALPHA ==\r
+//        params.put(Format.Alpha8,   new BitMaskImageCodec(1, 0, 8, 0, 0, 0,\r
+//                                                                0, 0, 0, 0));\r
+        \r
+        params.put(Format.Alpha8,   new ByteOffsetImageCodec(1, 0, 0, -1, -1, -1));\r
+        \r
+        params.put(Format.Alpha16,  new BitMaskImageCodec(2, 0, 16, 0, 0, 0,\r
+                                                                0,  0, 0, 0));\r
+        \r
+        // == LUMINANCE ==\r
+//        params.put(Format.Luminance8, new BitMaskImageCodec(1, FLAG_GRAY, 0, 8, 0, 0,\r
+//                                                                          0, 0, 0, 0));\r
+        \r
+        params.put(Format.Luminance8, new ByteOffsetImageCodec(1, FLAG_GRAY, -1, 0, -1, -1));\r
+        \r
+        params.put(Format.Luminance16, new BitMaskImageCodec(2, FLAG_GRAY, 0, 16, 0, 0,\r
+                                                                           0, 0, 0, 0));\r
+        params.put(Format.Luminance16F, new BitMaskImageCodec(2, FLAG_GRAY | FLAG_F16, 0, 16, 0, 0,\r
+                                                                                        0, 0, 0, 0));\r
+        params.put(Format.Luminance32F, new BitMaskImageCodec(4, FLAG_GRAY | FLAG_F32, 0, 32, 0, 0,\r
+                                                                                        0, 0, 0, 0));\r
+        \r
+        // == INTENSITY ==\r
+        // ??\r
+        \r
+        // == LUMINANCA ALPHA ==\r
+//        params.put(Format.Luminance8Alpha8, new BitMaskImageCodec(2, FLAG_GRAY, \r
+//                                                                  8, 8, 0, 0,\r
+//                                                                  8, 0, 0, 0));\r
+        \r
+        params.put(Format.Luminance8Alpha8, new ByteOffsetImageCodec(2, FLAG_GRAY, 1, 0, -1, -1));\r
+        \r
+        params.put(Format.Luminance16Alpha16, new BitMaskImageCodec(4, FLAG_GRAY, \r
+                                                                  16, 16, 0, 0,\r
+                                                                  16, 0, 0, 0));\r
+        \r
+        params.put(Format.Luminance16FAlpha16F, new BitMaskImageCodec(4, FLAG_GRAY | FLAG_F16, \r
+                                                                   16, 16, 0, 0,\r
+                                                                   16, 0, 0, 0));\r
+        \r
+        // == RGB ==\r
+//        params.put(Format.BGR8,     new BitMaskImageCodec(3, 0, \r
+//                                                          0, 8,  8,  8,\r
+//                                                          0, 16, 8,  0));\r
+//        \r
+        params.put(Format.BGR8,     new ByteOffsetImageCodec(3, 0, -1, 2, 1, 0));\r
+        \r
+        params.put(Format.RGB565,       new BitMaskImageCodec(2, 0,\r
+                                                            0, 5,  6, 5,\r
+                                                            0, 11, 5, 0));\r
+//        \r
+//        params.put(Format.RGB8,         new BitMaskImageCodec(3, 0,\r
+//                                                            0, 8, 8, 8,\r
+//                                                            0, 0, 8, 16));\r
+        \r
+        params.put(Format.RGB8,     new ByteOffsetImageCodec(3, 0, -1, 0, 1, 2));\r
+        \r
+        params.put(Format.RGB16,        new ByteAlignedImageCodec(6, 0,\r
+                                                                  0, 2, 2, 2,\r
+                                                                  0, 0, 2, 4));\r
+       \r
+        params.put(Format.RGB32F,        new ByteAlignedImageCodec(12, FLAG_F32,\r
+                                                                   0,  4, 4, 4,\r
+                                                                   0,  0, 4, 8));\r
+        \r
+        ByteAlignedImageCodec rgb16f = new ByteAlignedImageCodec(6, FLAG_F16,\r
+                                                            0, 2, 2, 2,\r
+                                                            0, 0, 2, 4); \r
+        params.put(Format.RGB16F, rgb16f);\r
+        params.put(Format.RGB16F_to_RGB111110F, rgb16f);\r
+        params.put(Format.RGB16F_to_RGB9E5, rgb16f);\r
+        \r
+        // == RGBA ==\r
+//        params.put(Format.ABGR8,    new BitMaskImageCodec(4, 0,\r
+//                                                          0, 8, 8, 8,\r
+//                                                          0, 24, 16, 8));\r
+        \r
+        params.put(Format.ABGR8, new ByteOffsetImageCodec(4, 0, 0, 3, 2, 1));\r
+        \r
+        params.put(Format.ARGB4444, new BitMaskImageCodec(2, 0,\r
+                                                          4, 4, 4, 4,\r
+                                                          12, 0, 4, 8));\r
+\r
+        params.put(Format.RGB5A1,   new BitMaskImageCodec(2, 0, \r
+                                                          1, 5, 5, 5,\r
+                                                          0, 11, 6, 1));\r
+        ((BitMaskImageCodec)params.get(Format.RGB5A1)).be = true;\r
+       \r
+//        params.put(Format.RGBA8,    new ByteAlignedImageCodec(4, 0,\r
+//                                                              0, 1, 1, 1,\r
+//                                                              0, 0, 1, 2));\r
+                \r
+                //new BitMaskImageCodec(4, 0,\r
+                                    //                      8,  8, 8, 8,\r
+                                    //                      24,  0, 8, 16));\r
+        \r
+        params.put(Format.RGBA8, new ByteOffsetImageCodec(4, 0, 3, 0, 1, 2));\r
+        \r
+        params.put(Format.RGBA16,        new ByteAlignedImageCodec(8, 0,\r
+                                                                   2, 2, 2, 2,\r
+                                                                   6, 0, 2, 4));\r
+        \r
+        params.put(Format.RGBA16F,        new ByteAlignedImageCodec(8, FLAG_F16,\r
+                                                            2, 2, 2,  2,\r
+                                                            6, 0, 2,  4));\r
+        \r
+        params.put(Format.RGBA32F,        new ByteAlignedImageCodec(16, FLAG_F32,\r
+                                                            4, 4, 4, 4,\r
+                                                            12, 0, 4, 8));\r
+    }\r
+    \r
+    public abstract void readComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp);\r
+    \r
+    public abstract void writeComponents(ByteBuffer buf, int x, int y, int width, int[] components, byte[] tmp);\r
+    \r
+    /**\r
+     * Looks up the format in the codec registry.\r
+     * The codec will be able to decode the given format.\r
+     * \r
+     * @param format The format to lookup.\r
+     * @return The codec capable of decoding it, or null if not found.\r
+     */\r
+    public static ImageCodec lookup(Format format) {\r
+        ImageCodec codec = params.get(format);\r
+        if (codec == null) {\r
+            throw new UnsupportedOperationException("The format " + format + " is not supported");\r
+        }\r
+        return codec;\r
+    }\r
+}\r
diff --git a/engine/src/core/com/jme3/texture/image/ImageRaster.java b/engine/src/core/com/jme3/texture/image/ImageRaster.java
new file mode 100644 (file)
index 0000000..123316a
--- /dev/null
@@ -0,0 +1,185 @@
+/*\r
+ * Copyright (c) 2009-2012 jMonkeyEngine\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
+ *\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
+ *\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+package com.jme3.texture.image;\r
+\r
+import com.jme3.math.ColorRGBA;\r
+import com.jme3.system.JmeSystem;\r
+import com.jme3.texture.Image;\r
+\r
+/**\r
+ * Utility class for reading and writing from jME3 {@link Image images}.\r
+ * <br>\r
+ * Allows directly manipulating pixels of the image by writing and \r
+ * reading {@link ColorRGBA colors} at any coordinate, without\r
+ * regard to the underlying {@link Image.Format format} of the image.\r
+ * NOTE: compressed and depth formats are <strong>not supported</strong>.\r
+ * Special RGB formats like RGB111110F and RGB9E5 are not supported\r
+ * at the moment, but may be added later on. For now \r
+ * use RGB16F_to_RGB111110F and RGB16F_to_RGB9E5 to handle\r
+ * the conversion on the GPU.\r
+ * <p>\r
+ * If direct manipulations are done to the image, such as replacing\r
+ * the image data, or changing the width, height, or format, then\r
+ * all current instances of <code>ImageReadWrite</code> become invalid, and\r
+ * new instances must be created in order to properly access\r
+ * the image data.\r
+ * \r
+ * Usage example:<br>\r
+ * <code>\r
+ * Image myImage = ...\r
+ * ImageRaster raster = ImageRaster.create(myImage);\r
+ * raster.setPixel(1, 5, ColorRGBA.Green);\r
+ * System.out.println( raster.getPixel(1, 5) ); // Will print [0.0, 1.0, 0.0, 1.0].\r
+ * </code>\r
+ * \r
+ * @author Kirill Vainer\r
+ */\r
+public abstract class ImageRaster {\r
+\r
+    /**\r
+     * Create new image reader / writer.\r
+     *\r
+     * @param image The image to read / write to.\r
+     * @param slice Which slice to use. Only applies to 3D images, 2D image\r
+     * arrays or cubemaps.\r
+     */\r
+    public static ImageRaster create(Image image, int slices) {\r
+        // TODO: need implement JmeSystem::createImageRaster\r
+        return new DefaultImageRaster(image, slices); //JmeSystem.createImageRaster(image, slices);\r
+    }\r
+    \r
+    /**\r
+     * Create new image reader / writer for 2D images.\r
+     * \r
+     * @param image The image to read / write to.\r
+     */\r
+    public static ImageRaster create(Image image) {\r
+        if (image.getData().size() > 1) {\r
+            throw new IllegalStateException("Use constructor that takes slices argument to read from multislice image");\r
+        }\r
+        // TODO: need implement JmeSystem::createImageRaster\r
+        return new DefaultImageRaster(image, 0);//JmeSystem.createImageRaster(image, 0);\r
+    }\r
+    \r
+    public ImageRaster() {\r
+    }\r
+    \r
+    /**\r
+     * Returns the pixel width of the underlying image.\r
+     * \r
+     * @return the pixel width of the underlying image.\r
+     */\r
+    public abstract int getWidth();\r
+    \r
+    /**\r
+     * Returns the pixel height of the underlying image.\r
+     * \r
+     * @return the pixel height of the underlying image.\r
+     */\r
+    public abstract int getHeight();\r
+    \r
+    /**\r
+     * Sets the pixel at the given coordinate to the given color.\r
+     * <p>\r
+     * For all integer based formats (those not ending in "F"), the \r
+     * color is first clamped to 0.0 - 1.0 before converting it to\r
+     * an integer to avoid overflow. For floating point based formats, \r
+     * components larger than 1.0 can be represented, but components\r
+     * lower than 0.0 are still not allowed (as all formats are unsigned).\r
+     * <p>\r
+     * If the underlying format is grayscale (e.g. one of the luminance formats,\r
+     * such as {@link Image.Format#Luminance8}) then a color to grayscale\r
+     * conversion is done first, before writing the result into the image.\r
+     * <p>\r
+     * If the image does not have some of the components in the color (such\r
+     * as alpha, or any of the color components), then these components\r
+     * will be ignored. The only exception to this is luminance formats\r
+     * for which the color is converted to luminance first (see above).\r
+     * <p>\r
+     * After writing the color, the image shall be marked as requiring an\r
+     * update. The next time it is used for rendering, all pixel changes\r
+     * will be reflected when the image is rendered.\r
+     * \r
+     * @param x The x coordinate, from 0 to width - 1.\r
+     * @param y The y coordinate, from 0 to height - 1.\r
+     * @param color The color to write. \r
+     * @throws IllegalArgumentException If x or y are outside the image dimensions.\r
+     */\r
+    public abstract void setPixel(int x, int y, ColorRGBA color);\r
+    \r
+    /**\r
+     * Retrieve the color at the given coordinate.\r
+     * <p>\r
+     * Any components that are not defined in the image format\r
+     * will be set to 1.0 in the returned color. For example,\r
+     * reading from an {@link Image.Format#Alpha8} format will\r
+     * return a ColorRGBA with the R, G, and B components set to 1.0, and\r
+     * the A component set to the alpha in the image.\r
+     * <p>\r
+     * For grayscale or luminance formats, the luminance value is replicated\r
+     * in the R, G, and B components. \r
+     * <p>\r
+     * Integer formats are converted to the range 0.0 - 1.0, based\r
+     * on the maximum possible integer value that can be represented\r
+     * by the number of bits the component has.\r
+     * For example, the {@link Image.Format#RGB5A1} format can\r
+     * contain the integer values 0 - 31, a conversion to floating point\r
+     * is done by diving the integer value by 31 (done with floating point\r
+     * precision).\r
+     * \r
+     * @param x The x coordinate, from 0 to width - 1.\r
+     * @param y The y coordinate, from 0 to height - 1.\r
+     * @param store Storage location for the read color, if <code>null</code>, \r
+     * then a new ColorRGBA is created and returned with the read color.\r
+     * @return The store parameter, if it is null, then a new ColorRGBA\r
+     * with the read color.\r
+     * @throws IllegalArgumentException If x or y are outside the image dimensions.\r
+     */\r
+    public abstract ColorRGBA getPixel(int x, int y, ColorRGBA store);\r
+    \r
+    /**\r
+     * Retrieve the color at the given coordinate.\r
+     * <p>\r
+     * Convenience method that does not take a store argument. Equivalent\r
+     * to calling getPixel(x, y, null). \r
+     * See {@link #getPixel(int, int, com.jme3.math.ColorRGBA) } for\r
+     * more information.\r
+     * \r
+     * @param x The x coordinate, from 0 to width - 1.\r
+     * @param y The y coordinate, from 0 to height - 1.\r
+     * @return A new ColorRGBA with the read color.\r
+     * @throws IllegalArgumentException If x or y are outside the image dimensions\r
+     */\r
+    public ColorRGBA getPixel(int x, int y) { \r
+        return getPixel(x, y, null);\r
+    }\r
+}\r