--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Tue Mar 05 17:18:55 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Tue Feb 19 12:06:28 2013 +0400
@@ -99,50 +99,75 @@
int offset;
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)
+ throws ImageLayoutException
{
this(np, pixelType, pixelSize);
dataType = DT_DOUBLE;
dataArray = data;
+ dataArrayLength = 8 * data.length;
+
+ verify();
}
- public LCMSImageLayout(BufferedImage image) {
+ public LCMSImageLayout(BufferedImage image) throws ImageLayoutException {
ShortComponentRaster shortRaster;
IntegerComponentRaster intRaster;
ByteComponentRaster byteRaster;
@@ -186,9 +211,13 @@
case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_BGR:
intRaster = (IntegerComponentRaster)image.getRaster();
- nextRowOffset = intRaster.getScanlineStride()*4;
- offset = intRaster.getDataOffset(0)*4;
+
+ nextRowOffset = safeMult(4, intRaster.getScanlineStride());
+
+ offset = safeMult(4, intRaster.getDataOffset(0));
+
dataArray = intRaster.getDataStorage();
+ dataArrayLength = 4 * intRaster.getDataStorage().length;
dataType = DT_INT;
break;
@@ -199,6 +228,7 @@
int firstBand = image.getSampleModel().getNumBands() - 1;
offset = byteRaster.getDataOffset(firstBand);
dataArray = byteRaster.getDataStorage();
+ dataArrayLength = byteRaster.getDataStorage().length;
dataType = DT_BYTE;
break;
@@ -207,17 +237,20 @@
nextRowOffset = byteRaster.getScanlineStride();
offset = byteRaster.getDataOffset(0);
dataArray = byteRaster.getDataStorage();
+ dataArrayLength = byteRaster.getDataStorage().length;
dataType = DT_BYTE;
break;
case BufferedImage.TYPE_USHORT_GRAY:
shortRaster = (ShortComponentRaster)image.getRaster();
- nextRowOffset = shortRaster.getScanlineStride()*2;
- offset = shortRaster.getDataOffset(0) * 2;
+ nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
+ offset = safeMult(2, shortRaster.getDataOffset(0));
dataArray = shortRaster.getDataStorage();
+ dataArrayLength = 2 * shortRaster.getDataStorage().length;
dataType = DT_SHORT;
break;
}
+ verify();
}
public static boolean isSupported(BufferedImage image) {
@@ -233,4 +266,45 @@
}
return false;
}
+
+ 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);
+ }
+ }
}
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Tue Mar 05 17:18:55 2013 +0400
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Tue Feb 19 12:06:28 2013 +0400
@@ -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 {
@@ -164,8 +165,12 @@
if (LCMSImageLayout.isSupported(src) &&
LCMSImageLayout.isSupported(dst))
{
- doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst));
- return;
+ try {
+ doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst));
+ return;
+ } catch (ImageLayoutException e) {
+ throw new CMMException("Unable to convert images");
+ }
}
LCMSImageLayout srcIL, dstIL;
Raster srcRas = src.getRaster();
@@ -223,14 +228,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
@@ -279,16 +288,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
@@ -397,16 +409,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
@@ -489,15 +504,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
@@ -529,16 +547,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
@@ -579,19 +601,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) {
@@ -599,18 +625,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");
+ }
}
}