提交 b94ff94d 编写于 作者: C chegar

Merge

...@@ -85,45 +85,72 @@ class LCMSImageLayout { ...@@ -85,45 +85,72 @@ class LCMSImageLayout {
private boolean imageAtOnce = false; private boolean imageAtOnce = false;
Object dataArray; 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; this.pixelType = pixelType;
width = np; width = np;
height = 1; height = 1;
nextRowOffset = np * pixelSize; nextRowOffset = safeMult(pixelSize, np);
offset = 0; offset = 0;
} }
private LCMSImageLayout(int width, int height, int pixelType, private LCMSImageLayout(int width, int height, int pixelType,
int pixelSize) { int pixelSize)
throws ImageLayoutException
{
this.pixelType = pixelType; this.pixelType = pixelType;
this.width = width; this.width = width;
this.height = height; this.height = height;
nextRowOffset = width * pixelSize; nextRowOffset = safeMult(pixelSize, width);
offset = 0; 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); this(np, pixelType, pixelSize);
dataType = DT_BYTE; dataType = DT_BYTE;
dataArray = data; 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); this(np, pixelType, pixelSize);
dataType = DT_SHORT; dataType = DT_SHORT;
dataArray = data; 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); this(np, pixelType, pixelSize);
dataType = DT_INT; dataType = DT_INT;
dataArray = data; 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); this(np, pixelType, pixelSize);
dataType = DT_DOUBLE; dataType = DT_DOUBLE;
dataArray = data; dataArray = data;
dataArrayLength = 8 * data.length;
verify();
} }
private LCMSImageLayout() { private LCMSImageLayout() {
...@@ -132,7 +159,7 @@ class LCMSImageLayout { ...@@ -132,7 +159,7 @@ class LCMSImageLayout {
/* This method creates a layout object for given image. /* This method creates a layout object for given image.
* Returns null if the image is not supported by current implementation. * 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(); LCMSImageLayout l = new LCMSImageLayout();
switch (image.getType()) { switch (image.getType()) {
...@@ -193,9 +220,10 @@ class LCMSImageLayout { ...@@ -193,9 +220,10 @@ class LCMSImageLayout {
do { do {
IntegerComponentRaster intRaster = (IntegerComponentRaster) IntegerComponentRaster intRaster = (IntegerComponentRaster)
image.getRaster(); image.getRaster();
l.nextRowOffset = intRaster.getScanlineStride() * 4; l.nextRowOffset = safeMult(4, intRaster.getScanlineStride());
l.offset = intRaster.getDataOffset(0) * 4; l.offset = safeMult(4, intRaster.getDataOffset(0));
l.dataArray = intRaster.getDataStorage(); l.dataArray = intRaster.getDataStorage();
l.dataArrayLength = 4 * intRaster.getDataStorage().length;
l.dataType = DT_INT; l.dataType = DT_INT;
if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) { if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
...@@ -213,6 +241,7 @@ class LCMSImageLayout { ...@@ -213,6 +241,7 @@ class LCMSImageLayout {
int firstBand = image.getSampleModel().getNumBands() - 1; int firstBand = image.getSampleModel().getNumBands() - 1;
l.offset = byteRaster.getDataOffset(firstBand); l.offset = byteRaster.getDataOffset(firstBand);
l.dataArray = byteRaster.getDataStorage(); l.dataArray = byteRaster.getDataStorage();
l.dataArrayLength = byteRaster.getDataStorage().length;
l.dataType = DT_BYTE; l.dataType = DT_BYTE;
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) { if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
l.imageAtOnce = true; l.imageAtOnce = true;
...@@ -225,6 +254,7 @@ class LCMSImageLayout { ...@@ -225,6 +254,7 @@ class LCMSImageLayout {
ByteComponentRaster byteRaster = (ByteComponentRaster) ByteComponentRaster byteRaster = (ByteComponentRaster)
image.getRaster(); image.getRaster();
l.nextRowOffset = byteRaster.getScanlineStride(); l.nextRowOffset = byteRaster.getScanlineStride();
l.dataArrayLength = byteRaster.getDataStorage().length;
l.offset = byteRaster.getDataOffset(0); l.offset = byteRaster.getDataOffset(0);
l.dataArray = byteRaster.getDataStorage(); l.dataArray = byteRaster.getDataStorage();
l.dataType = DT_BYTE; l.dataType = DT_BYTE;
...@@ -239,9 +269,10 @@ class LCMSImageLayout { ...@@ -239,9 +269,10 @@ class LCMSImageLayout {
do { do {
ShortComponentRaster shortRaster = (ShortComponentRaster) ShortComponentRaster shortRaster = (ShortComponentRaster)
image.getRaster(); image.getRaster();
l.nextRowOffset = shortRaster.getScanlineStride() * 2; l.nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
l.offset = shortRaster.getDataOffset(0) * 2; l.offset = safeMult(2, shortRaster.getDataOffset(0));
l.dataArray = shortRaster.getDataStorage(); l.dataArray = shortRaster.getDataStorage();
l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
l.dataType = DT_SHORT; l.dataType = DT_SHORT;
if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) { if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
...@@ -252,6 +283,7 @@ class LCMSImageLayout { ...@@ -252,6 +283,7 @@ class LCMSImageLayout {
default: default:
return null; return null;
} }
l.verify();
return l; return l;
} }
...@@ -293,6 +325,46 @@ class LCMSImageLayout { ...@@ -293,6 +325,46 @@ class LCMSImageLayout {
} }
} }
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) { public static LCMSImageLayout createImageLayout(Raster r) {
LCMSImageLayout l = new LCMSImageLayout(); LCMSImageLayout l = new LCMSImageLayout();
if (r instanceof ByteComponentRaster) { if (r instanceof ByteComponentRaster) {
......
...@@ -51,6 +51,7 @@ import java.awt.image.SinglePixelPackedSampleModel; ...@@ -51,6 +51,7 @@ import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.ComponentSampleModel; import java.awt.image.ComponentSampleModel;
import sun.java2d.cmm.*; import sun.java2d.cmm.*;
import sun.java2d.cmm.lcms.*; import sun.java2d.cmm.lcms.*;
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
public class LCMSTransform implements ColorTransform { public class LCMSTransform implements ColorTransform {
...@@ -162,15 +163,19 @@ public class LCMSTransform implements ColorTransform { ...@@ -162,15 +163,19 @@ public class LCMSTransform implements ColorTransform {
public void colorConvert(BufferedImage src, BufferedImage dst) { public void colorConvert(BufferedImage src, BufferedImage dst) {
LCMSImageLayout srcIL, dstIL; LCMSImageLayout srcIL, dstIL;
try {
dstIL = LCMSImageLayout.createImageLayout(dst); dstIL = LCMSImageLayout.createImageLayout(dst);
if (dstIL != null) { if (dstIL != null) {
srcIL = LCMSImageLayout.createImageLayout(src); srcIL = LCMSImageLayout.createImageLayout(src);
if (srcIL != null) { if (srcIL != null) {
doTransform(srcIL, dstIL); doTransform(srcIL, dstIL);
return; return;
}
} }
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
} }
Raster srcRas = src.getRaster(); Raster srcRas = src.getRaster();
...@@ -228,14 +233,18 @@ public class LCMSTransform implements ColorTransform { ...@@ -228,14 +233,18 @@ public class LCMSTransform implements ColorTransform {
} }
int idx; int idx;
// TODO check for src npixels = dst npixels // TODO check for src npixels = dst npixels
srcIL = new LCMSImageLayout( try {
srcLine, srcLine.length/getNumInComponents(), srcIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.BYTES_SH(1), getNumInComponents()); LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
dstIL = new LCMSImageLayout( LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstLine, dstLine.length/getNumOutComponents(), dstIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
// convert src scanline // convert src scanline
...@@ -284,16 +293,19 @@ public class LCMSTransform implements ColorTransform { ...@@ -284,16 +293,19 @@ public class LCMSTransform implements ColorTransform {
alpha = new float[w]; alpha = new float[w];
} }
int idx; int idx;
srcIL = new LCMSImageLayout( try {
srcLine, srcLine.length/getNumInComponents(), srcIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(), dstIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
// convert src scanline // convert src scanline
...@@ -402,16 +414,19 @@ public class LCMSTransform implements ColorTransform { ...@@ -402,16 +414,19 @@ public class LCMSTransform implements ColorTransform {
short[] srcLine = new short[w * srcNumBands]; short[] srcLine = new short[w * srcNumBands];
short[] dstLine = new short[w * dstNumBands]; short[] dstLine = new short[w * dstNumBands];
int idx; int idx;
srcIL = new LCMSImageLayout( try {
srcLine, srcLine.length/getNumInComponents(), srcIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); 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 // process each scanline
for (int y = 0; y < h; y++, ys++, yd++) { for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline // get src scanline
...@@ -502,15 +517,18 @@ public class LCMSTransform implements ColorTransform { ...@@ -502,15 +517,18 @@ public class LCMSTransform implements ColorTransform {
byte[] dstLine = new byte[w * dstNumBands]; byte[] dstLine = new byte[w * dstNumBands];
int idx; int idx;
// TODO check for src npixels = dst npixels // TODO check for src npixels = dst npixels
srcIL = new LCMSImageLayout( try {
srcLine, srcLine.length/getNumInComponents(), srcIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.BYTES_SH(1), getNumInComponents()); LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
dstIL = new LCMSImageLayout( LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstLine, dstLine.length/getNumOutComponents(), dstIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.BYTES_SH(1), getNumOutComponents()); LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++, ys++, yd++) { for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline // get src scanline
...@@ -542,16 +560,20 @@ public class LCMSTransform implements ColorTransform { ...@@ -542,16 +560,20 @@ public class LCMSTransform implements ColorTransform {
short[] srcLine = new short[w * srcNumBands]; short[] srcLine = new short[w * srcNumBands];
short[] dstLine = new short[w * dstNumBands]; short[] dstLine = new short[w * dstNumBands];
int idx; int idx;
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);
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);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline // process each scanline
for (int y = 0; y < h; y++, ys++, yd++) { for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline // get src scanline
...@@ -592,19 +614,23 @@ public class LCMSTransform implements ColorTransform { ...@@ -592,19 +614,23 @@ public class LCMSTransform implements ColorTransform {
dst = new short [(src.length/getNumInComponents())*getNumOutComponents()]; dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
} }
LCMSImageLayout srcIL = new LCMSImageLayout( try {
src, src.length/getNumInComponents(), LCMSImageLayout srcIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | src, src.length/getNumInComponents(),
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2); LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
LCMSImageLayout dstIL = new LCMSImageLayout( LCMSImageLayout dstIL = new LCMSImageLayout(
dst, dst.length/getNumOutComponents(), dst, dst.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2); 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) { public byte[] colorConvert(byte[] src, byte[] dst) {
...@@ -612,18 +638,22 @@ public class LCMSTransform implements ColorTransform { ...@@ -612,18 +638,22 @@ public class LCMSTransform implements ColorTransform {
dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()]; dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
} }
LCMSImageLayout srcIL = new LCMSImageLayout( try {
src, src.length/getNumInComponents(), LCMSImageLayout srcIL = new LCMSImageLayout(
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) | src, src.length/getNumInComponents(),
LCMSImageLayout.BYTES_SH(1), getNumInComponents()); LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
LCMSImageLayout dstIL = new LCMSImageLayout( LCMSImageLayout dstIL = new LCMSImageLayout(
dst, dst.length/getNumOutComponents(), dst, dst.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) | LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), 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");
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册