Merge
authorchegar
Thu, 04 Apr 2013 17:34:07 +0100
changeset 16900 5e0400ee2917
parent 16898 b321dfd1163f (current diff)
parent 16899 666a37b19844 (diff)
child 16901 d98c53659845
Merge
jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java	Fri Mar 01 04:45:12 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java	Thu Apr 04 17:34:07 2013 +0100
@@ -85,45 +85,72 @@
     private boolean imageAtOnce = false;
     Object dataArray;
 
-    private LCMSImageLayout(int np, int pixelType, int pixelSize) {
+    private int dataArrayLength; /* in bytes */
+
+    private LCMSImageLayout(int np, int pixelType, int pixelSize)
+            throws ImageLayoutException
+    {
         this.pixelType = pixelType;
         width = np;
         height = 1;
-        nextRowOffset = np * pixelSize;
+        nextRowOffset = safeMult(pixelSize, np);
         offset = 0;
     }
 
     private LCMSImageLayout(int width, int height, int pixelType,
-            int pixelSize) {
+                            int pixelSize)
+            throws ImageLayoutException
+    {
         this.pixelType = pixelType;
         this.width = width;
         this.height = height;
-        nextRowOffset = width * pixelSize;
+        nextRowOffset = safeMult(pixelSize, width);
         offset = 0;
     }
 
-    public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
+
+    public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
+            throws ImageLayoutException
+    {
         this(np, pixelType, pixelSize);
         dataType = DT_BYTE;
         dataArray = data;
+        dataArrayLength = data.length;
+
+        verify();
     }
 
-    public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
+    public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
+            throws ImageLayoutException
+    {
         this(np, pixelType, pixelSize);
         dataType = DT_SHORT;
         dataArray = data;
+        dataArrayLength = 2 * data.length;
+
+        verify();
     }
 
-    public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
+    public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
+            throws ImageLayoutException
+    {
         this(np, pixelType, pixelSize);
         dataType = DT_INT;
         dataArray = data;
+        dataArrayLength = 4 * data.length;
+
+        verify();
     }
 
-    public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) {
+    public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
+            throws ImageLayoutException
+    {
         this(np, pixelType, pixelSize);
         dataType = DT_DOUBLE;
         dataArray = data;
+        dataArrayLength = 8 * data.length;
+
+        verify();
     }
 
     private LCMSImageLayout() {
@@ -132,7 +159,7 @@
     /* This method creates a layout object for given image.
      * Returns null if the image is not supported by current implementation.
      */
-    public static LCMSImageLayout createImageLayout(BufferedImage image) {
+    public static LCMSImageLayout createImageLayout(BufferedImage image) throws ImageLayoutException {
         LCMSImageLayout l = new LCMSImageLayout();
 
         switch (image.getType()) {
@@ -193,9 +220,10 @@
                 do {
                     IntegerComponentRaster intRaster = (IntegerComponentRaster)
                             image.getRaster();
-                    l.nextRowOffset = intRaster.getScanlineStride() * 4;
-                    l.offset = intRaster.getDataOffset(0) * 4;
+                    l.nextRowOffset = safeMult(4, intRaster.getScanlineStride());
+                    l.offset = safeMult(4, intRaster.getDataOffset(0));
                     l.dataArray = intRaster.getDataStorage();
+                    l.dataArrayLength = 4 * intRaster.getDataStorage().length;
                     l.dataType = DT_INT;
 
                     if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
@@ -213,6 +241,7 @@
                     int firstBand = image.getSampleModel().getNumBands() - 1;
                     l.offset = byteRaster.getDataOffset(firstBand);
                     l.dataArray = byteRaster.getDataStorage();
+                    l.dataArrayLength = byteRaster.getDataStorage().length;
                     l.dataType = DT_BYTE;
                     if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
                         l.imageAtOnce = true;
@@ -225,6 +254,7 @@
                     ByteComponentRaster byteRaster = (ByteComponentRaster)
                             image.getRaster();
                     l.nextRowOffset = byteRaster.getScanlineStride();
+                    l.dataArrayLength = byteRaster.getDataStorage().length;
                     l.offset = byteRaster.getDataOffset(0);
                     l.dataArray = byteRaster.getDataStorage();
                     l.dataType = DT_BYTE;
@@ -239,9 +269,10 @@
                 do {
                     ShortComponentRaster shortRaster = (ShortComponentRaster)
                             image.getRaster();
-                    l.nextRowOffset = shortRaster.getScanlineStride() * 2;
-                    l.offset = shortRaster.getDataOffset(0) * 2;
+                    l.nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
+                    l.offset = safeMult(2, shortRaster.getDataOffset(0));
                     l.dataArray = shortRaster.getDataStorage();
+                    l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
                     l.dataType = DT_SHORT;
 
                     if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
@@ -252,6 +283,7 @@
             default:
                 return null;
         }
+        l.verify();
         return l;
     }
 
@@ -293,6 +325,46 @@
         }
     }
 
+    private void verify() throws ImageLayoutException {
+
+        if (offset < 0 || offset >= dataArrayLength) {
+            throw new ImageLayoutException("Invalid image layout");
+        }
+
+        int lastPixelOffset = safeMult(nextRowOffset, (height - 1));
+
+        lastPixelOffset = safeAdd(lastPixelOffset, (width - 1));
+
+        int off = safeAdd(offset, lastPixelOffset);
+
+        if (off < 0 || off >= dataArrayLength) {
+            throw new ImageLayoutException("Invalid image layout");
+        }
+    }
+
+    static int safeAdd(int a, int b) throws ImageLayoutException {
+        long res = a;
+        res += b;
+        if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
+            throw new ImageLayoutException("Invalid image layout");
+        }
+        return (int)res;
+    }
+
+    static int safeMult(int a, int b) throws ImageLayoutException {
+        long res = a;
+        res *= b;
+        if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
+            throw new ImageLayoutException("Invalid image layout");
+        }
+        return (int)res;
+    }
+
+    public static class ImageLayoutException extends Exception {
+        public ImageLayoutException(String message) {
+            super(message);
+        }
+    }
     public static LCMSImageLayout createImageLayout(Raster r) {
         LCMSImageLayout l = new LCMSImageLayout();
         if (r instanceof ByteComponentRaster) {
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java	Fri Mar 01 04:45:12 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java	Thu Apr 04 17:34:07 2013 +0100
@@ -51,6 +51,7 @@
 import java.awt.image.ComponentSampleModel;
 import sun.java2d.cmm.*;
 import sun.java2d.cmm.lcms.*;
+import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
 
 
 public class LCMSTransform implements ColorTransform {
@@ -162,15 +163,19 @@
 
     public void colorConvert(BufferedImage src, BufferedImage dst) {
         LCMSImageLayout srcIL, dstIL;
+        try {
 
-        dstIL = LCMSImageLayout.createImageLayout(dst);
+            dstIL = LCMSImageLayout.createImageLayout(dst);
 
-        if (dstIL != null) {
-            srcIL = LCMSImageLayout.createImageLayout(src);
-            if (srcIL != null) {
-                doTransform(srcIL, dstIL);
-                return;
+            if (dstIL != null) {
+                srcIL = LCMSImageLayout.createImageLayout(src);
+                if (srcIL != null) {
+                    doTransform(srcIL, dstIL);
+                    return;
+                }
             }
+        }  catch (ImageLayoutException e) {
+            throw new CMMException("Unable to convert images");
         }
 
         Raster srcRas = src.getRaster();
@@ -228,14 +233,18 @@
             }
             int idx;
             // TODO check for src npixels = dst npixels
-            srcIL = new LCMSImageLayout(
-                srcLine, srcLine.length/getNumInComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-                LCMSImageLayout.BYTES_SH(1), getNumInComponents());
-            dstIL = new LCMSImageLayout(
-                dstLine, dstLine.length/getNumOutComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-                LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
+            try {
+                srcIL = new LCMSImageLayout(
+                        srcLine, srcLine.length/getNumInComponents(),
+                        LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                        LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+                dstIL = new LCMSImageLayout(
+                        dstLine, dstLine.length/getNumOutComponents(),
+                        LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                        LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
+            } catch (ImageLayoutException e) {
+                throw new CMMException("Unable to convert images");
+            }
             // process each scanline
             for (int y = 0; y < h; y++) {
                 // convert src scanline
@@ -284,16 +293,19 @@
                 alpha = new float[w];
             }
             int idx;
-            srcIL = new LCMSImageLayout(
-                srcLine, srcLine.length/getNumInComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-                LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+            try {
+                srcIL = new LCMSImageLayout(
+                    srcLine, srcLine.length/getNumInComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                    LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
 
-            dstIL = new LCMSImageLayout(
-                dstLine, dstLine.length/getNumOutComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-                LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
-
+                dstIL = new LCMSImageLayout(
+                    dstLine, dstLine.length/getNumOutComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                    LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+            } catch (ImageLayoutException e) {
+                throw new CMMException("Unable to convert images");
+            }
             // process each scanline
             for (int y = 0; y < h; y++) {
                 // convert src scanline
@@ -402,16 +414,19 @@
         short[] srcLine = new short[w * srcNumBands];
         short[] dstLine = new short[w * dstNumBands];
         int idx;
-        srcIL = new LCMSImageLayout(
-            srcLine, srcLine.length/getNumInComponents(),
-            LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-            LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+        try {
+            srcIL = new LCMSImageLayout(
+                    srcLine, srcLine.length/getNumInComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                    LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
 
-        dstIL = new LCMSImageLayout(
-            dstLine, dstLine.length/getNumOutComponents(),
-            LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-            LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
-
+            dstIL = new LCMSImageLayout(
+                    dstLine, dstLine.length/getNumOutComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                    LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+        } catch (ImageLayoutException e) {
+            throw new CMMException("Unable to convert rasters");
+        }
         // process each scanline
         for (int y = 0; y < h; y++, ys++, yd++) {
             // get src scanline
@@ -502,15 +517,18 @@
             byte[] dstLine = new byte[w * dstNumBands];
             int idx;
             // TODO check for src npixels = dst npixels
-            srcIL = new LCMSImageLayout(
-                srcLine, srcLine.length/getNumInComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-                LCMSImageLayout.BYTES_SH(1), getNumInComponents());
-            dstIL = new LCMSImageLayout(
-                dstLine, dstLine.length/getNumOutComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-                LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
-
+            try {
+                srcIL = new LCMSImageLayout(
+                        srcLine, srcLine.length/getNumInComponents(),
+                        LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                        LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+                dstIL = new LCMSImageLayout(
+                        dstLine, dstLine.length/getNumOutComponents(),
+                        LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                        LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
+            } catch (ImageLayoutException e) {
+                throw new CMMException("Unable to convert rasters");
+            }
             // process each scanline
             for (int y = 0; y < h; y++, ys++, yd++) {
                 // get src scanline
@@ -542,16 +560,20 @@
             short[] srcLine = new short[w * srcNumBands];
             short[] dstLine = new short[w * dstNumBands];
             int idx;
-            srcIL = new LCMSImageLayout(
-                srcLine, srcLine.length/getNumInComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-                LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+
+            try {
+                srcIL = new LCMSImageLayout(
+                        srcLine, srcLine.length/getNumInComponents(),
+                        LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                        LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
 
-            dstIL = new LCMSImageLayout(
-                dstLine, dstLine.length/getNumOutComponents(),
-                LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-                LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
-
+                dstIL = new LCMSImageLayout(
+                        dstLine, dstLine.length/getNumOutComponents(),
+                        LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                        LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+            } catch (ImageLayoutException e) {
+                throw new CMMException("Unable to convert rasters");
+            }
             // process each scanline
             for (int y = 0; y < h; y++, ys++, yd++) {
                 // get src scanline
@@ -592,19 +614,23 @@
             dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
         }
 
-        LCMSImageLayout srcIL = new LCMSImageLayout(
-            src, src.length/getNumInComponents(),
-            LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-            LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+        try {
+            LCMSImageLayout srcIL = new LCMSImageLayout(
+                    src, src.length/getNumInComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                    LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
 
-        LCMSImageLayout dstIL = new LCMSImageLayout(
-            dst, dst.length/getNumOutComponents(),
-            LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-            LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+            LCMSImageLayout dstIL = new LCMSImageLayout(
+                    dst, dst.length/getNumOutComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                    LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
 
-        doTransform(srcIL, dstIL);
+            doTransform(srcIL, dstIL);
 
-        return dst;
+            return dst;
+        } catch (ImageLayoutException e) {
+            throw new CMMException("Unable to convert data");
+        }
     }
 
     public byte[] colorConvert(byte[] src, byte[] dst) {
@@ -612,18 +638,22 @@
             dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
         }
 
-        LCMSImageLayout srcIL = new LCMSImageLayout(
-            src, src.length/getNumInComponents(),
-            LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
-            LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+        try {
+            LCMSImageLayout srcIL = new LCMSImageLayout(
+                    src, src.length/getNumInComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                    LCMSImageLayout.BYTES_SH(1), getNumInComponents());
 
-        LCMSImageLayout dstIL = new LCMSImageLayout(
-            dst, dst.length/getNumOutComponents(),
-            LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
-            LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
+            LCMSImageLayout dstIL = new LCMSImageLayout(
+                    dst, dst.length/getNumOutComponents(),
+                    LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                    LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
 
-        doTransform(srcIL, dstIL);
+            doTransform(srcIL, dstIL);
 
-        return dst;
+            return dst;
+        } catch (ImageLayoutException e) {
+            throw new CMMException("Unable to convert data");
+        }
     }
 }