| /* |
| * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /********************************************************************** |
| ********************************************************************** |
| ********************************************************************** |
| *** COPYRIGHT (c) Eastman Kodak Company, 1997 *** |
| *** As an unpublished work pursuant to Title 17 of the United *** |
| *** States Code. All rights reserved. *** |
| ********************************************************************** |
| ********************************************************************** |
| **********************************************************************/ |
| |
| package sun.java2d.cmm.lcms; |
| |
| import java.awt.color.ICC_Profile; |
| import java.awt.color.ProfileDataException; |
| import java.awt.color.CMMException; |
| import java.awt.color.ColorSpace; |
| import java.awt.image.BufferedImage; |
| import java.awt.image.Raster; |
| import java.awt.image.WritableRaster; |
| import java.awt.image.ColorModel; |
| import java.awt.image.DirectColorModel; |
| import java.awt.image.ComponentColorModel; |
| import java.awt.image.SampleModel; |
| import java.awt.image.DataBuffer; |
| import java.awt.image.SinglePixelPackedSampleModel; |
| 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 { |
| long ID; |
| private int inFormatter = 0; |
| private boolean isInIntPacked = false; |
| private int outFormatter = 0; |
| private boolean isOutIntPacked = false; |
| |
| ICC_Profile[] profiles; |
| LCMSProfile[] lcmsProfiles; |
| int renderType; |
| int transformType; |
| |
| private int numInComponents = -1; |
| private int numOutComponents = -1; |
| |
| private Object disposerReferent = new Object(); |
| |
| /* the class initializer */ |
| static { |
| if (ProfileDeferralMgr.deferring) { |
| ProfileDeferralMgr.activateProfiles(); |
| } |
| } |
| |
| public LCMSTransform(ICC_Profile profile, int renderType, |
| int transformType) |
| { |
| /* Actually, it is not a complete transform but just part of it */ |
| profiles = new ICC_Profile[1]; |
| profiles[0] = profile; |
| lcmsProfiles = new LCMSProfile[1]; |
| lcmsProfiles[0] = LCMS.getProfileID(profile); |
| this.renderType = (renderType == ColorTransform.Any)? |
| ICC_Profile.icPerceptual : renderType; |
| this.transformType = transformType; |
| |
| /* Note that ICC_Profile.getNumComponents() is quite expensive |
| * (it may results in a reading of the profile header). |
| * So, here we cache the number of components of input and |
| * output profiles for further usage. |
| */ |
| numInComponents = profiles[0].getNumComponents(); |
| numOutComponents = profiles[profiles.length - 1].getNumComponents(); |
| } |
| |
| public LCMSTransform (ColorTransform[] transforms) { |
| int size = 0; |
| for (int i=0; i < transforms.length; i++) { |
| size+=((LCMSTransform)transforms[i]).profiles.length; |
| } |
| profiles = new ICC_Profile[size]; |
| lcmsProfiles = new LCMSProfile[size]; |
| int j = 0; |
| for (int i=0; i < transforms.length; i++) { |
| LCMSTransform curTrans = (LCMSTransform)transforms[i]; |
| System.arraycopy(curTrans.profiles, 0, profiles, j, |
| curTrans.profiles.length); |
| System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j, |
| curTrans.lcmsProfiles.length); |
| j += curTrans.profiles.length; |
| } |
| renderType = ((LCMSTransform)transforms[0]).renderType; |
| |
| /* Note that ICC_Profile.getNumComponents() is quite expensive |
| * (it may results in a reading of the profile header). |
| * So, here we cache the number of components of input and |
| * output profiles for further usage. |
| */ |
| numInComponents = profiles[0].getNumComponents(); |
| numOutComponents = profiles[profiles.length - 1].getNumComponents(); |
| } |
| |
| public int getNumInComponents() { |
| return numInComponents; |
| } |
| |
| public int getNumOutComponents() { |
| return numOutComponents; |
| } |
| |
| private synchronized void doTransform(LCMSImageLayout in, |
| LCMSImageLayout out) { |
| // update native transfrom if needed |
| if (ID == 0L || |
| inFormatter != in.pixelType || isInIntPacked != in.isIntPacked || |
| outFormatter != out.pixelType || isOutIntPacked != out.isIntPacked) |
| { |
| |
| if (ID != 0L) { |
| // Disposer will destroy forgotten transform |
| disposerReferent = new Object(); |
| } |
| inFormatter = in.pixelType; |
| isInIntPacked = in.isIntPacked; |
| |
| outFormatter = out.pixelType; |
| isOutIntPacked = out.isIntPacked; |
| |
| ID = LCMS.createTransform(lcmsProfiles, renderType, |
| inFormatter, isInIntPacked, |
| outFormatter, isOutIntPacked, |
| disposerReferent); |
| } |
| |
| LCMS.colorConvert(this, in, out); |
| } |
| |
| public void colorConvert(BufferedImage src, BufferedImage dst) { |
| LCMSImageLayout srcIL, dstIL; |
| try { |
| if (!dst.getColorModel().hasAlpha()) { |
| dstIL = LCMSImageLayout.createImageLayout(dst); |
| |
| 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(); |
| WritableRaster dstRas = dst.getRaster(); |
| ColorModel srcCM = src.getColorModel(); |
| ColorModel dstCM = dst.getColorModel(); |
| int w = src.getWidth(); |
| int h = src.getHeight(); |
| int srcNumComp = srcCM.getNumColorComponents(); |
| int dstNumComp = dstCM.getNumColorComponents(); |
| int precision = 8; |
| float maxNum = 255.0f; |
| for (int i = 0; i < srcNumComp; i++) { |
| if (srcCM.getComponentSize(i) > 8) { |
| precision = 16; |
| maxNum = 65535.0f; |
| } |
| } |
| for (int i = 0; i < dstNumComp; i++) { |
| if (dstCM.getComponentSize(i) > 8) { |
| precision = 16; |
| maxNum = 65535.0f; |
| } |
| } |
| float[] srcMinVal = new float[srcNumComp]; |
| float[] srcInvDiffMinMax = new float[srcNumComp]; |
| ColorSpace cs = srcCM.getColorSpace(); |
| for (int i = 0; i < srcNumComp; i++) { |
| srcMinVal[i] = cs.getMinValue(i); |
| srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]); |
| } |
| cs = dstCM.getColorSpace(); |
| float[] dstMinVal = new float[dstNumComp]; |
| float[] dstDiffMinMax = new float[dstNumComp]; |
| for (int i = 0; i < dstNumComp; i++) { |
| dstMinVal[i] = cs.getMinValue(i); |
| dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum; |
| } |
| boolean dstHasAlpha = dstCM.hasAlpha(); |
| boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha; |
| float[] dstColor; |
| if (dstHasAlpha) { |
| dstColor = new float[dstNumComp + 1]; |
| } else { |
| dstColor = new float[dstNumComp]; |
| } |
| if (precision == 8) { |
| byte[] srcLine = new byte[w * srcNumComp]; |
| byte[] dstLine = new byte[w * dstNumComp]; |
| Object pixel; |
| float[] color; |
| float[] alpha = null; |
| if (needSrcAlpha) { |
| alpha = new float[w]; |
| } |
| int idx; |
| // TODO check for src npixels = dst npixels |
| 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 |
| pixel = null; |
| color = null; |
| idx = 0; |
| for (int x = 0; x < w; x++) { |
| pixel = srcRas.getDataElements(x, y, pixel); |
| color = srcCM.getNormalizedComponents(pixel, color, 0); |
| for (int i = 0; i < srcNumComp; i++) { |
| srcLine[idx++] = (byte) |
| ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] + |
| 0.5f); |
| } |
| if (needSrcAlpha) { |
| alpha[x] = color[srcNumComp]; |
| } |
| } |
| // color convert srcLine to dstLine |
| doTransform(srcIL, dstIL); |
| |
| // convert dst scanline |
| pixel = null; |
| idx = 0; |
| for (int x = 0; x < w; x++) { |
| for (int i = 0; i < dstNumComp; i++) { |
| dstColor[i] = ((float) (dstLine[idx++] & 0xff)) * |
| dstDiffMinMax[i] + dstMinVal[i]; |
| } |
| if (needSrcAlpha) { |
| dstColor[dstNumComp] = alpha[x]; |
| } else if (dstHasAlpha) { |
| dstColor[dstNumComp] = 1.0f; |
| } |
| pixel = dstCM.getDataElements(dstColor, 0, pixel); |
| dstRas.setDataElements(x, y, pixel); |
| } |
| } |
| } else { |
| short[] srcLine = new short[w * srcNumComp]; |
| short[] dstLine = new short[w * dstNumComp]; |
| Object pixel; |
| float[] color; |
| float[] alpha = null; |
| if (needSrcAlpha) { |
| alpha = new float[w]; |
| } |
| int idx; |
| 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 images"); |
| } |
| // process each scanline |
| for (int y = 0; y < h; y++) { |
| // convert src scanline |
| pixel = null; |
| color = null; |
| idx = 0; |
| for (int x = 0; x < w; x++) { |
| pixel = srcRas.getDataElements(x, y, pixel); |
| color = srcCM.getNormalizedComponents(pixel, color, 0); |
| for (int i = 0; i < srcNumComp; i++) { |
| srcLine[idx++] = (short) |
| ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] + |
| 0.5f); |
| } |
| if (needSrcAlpha) { |
| alpha[x] = color[srcNumComp]; |
| } |
| } |
| // color convert srcLine to dstLine |
| doTransform(srcIL, dstIL); |
| |
| // convert dst scanline |
| pixel = null; |
| idx = 0; |
| for (int x = 0; x < w; x++) { |
| for (int i = 0; i < dstNumComp; i++) { |
| dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) * |
| dstDiffMinMax[i] + dstMinVal[i]; |
| } |
| if (needSrcAlpha) { |
| dstColor[dstNumComp] = alpha[x]; |
| } else if (dstHasAlpha) { |
| dstColor[dstNumComp] = 1.0f; |
| } |
| pixel = dstCM.getDataElements(dstColor, 0, pixel); |
| dstRas.setDataElements(x, y, pixel); |
| } |
| } |
| } |
| } |
| |
| public void colorConvert(Raster src, WritableRaster dst, |
| float[] srcMinVal, float[]srcMaxVal, |
| float[] dstMinVal, float[]dstMaxVal) { |
| LCMSImageLayout srcIL, dstIL; |
| |
| // Can't pass src and dst directly to CMM, so process per scanline |
| SampleModel srcSM = src.getSampleModel(); |
| SampleModel dstSM = dst.getSampleModel(); |
| int srcTransferType = src.getTransferType(); |
| int dstTransferType = dst.getTransferType(); |
| boolean srcIsFloat, dstIsFloat; |
| if ((srcTransferType == DataBuffer.TYPE_FLOAT) || |
| (srcTransferType == DataBuffer.TYPE_DOUBLE)) { |
| srcIsFloat = true; |
| } else { |
| srcIsFloat = false; |
| } |
| if ((dstTransferType == DataBuffer.TYPE_FLOAT) || |
| (dstTransferType == DataBuffer.TYPE_DOUBLE)) { |
| dstIsFloat = true; |
| } else { |
| dstIsFloat = false; |
| } |
| int w = src.getWidth(); |
| int h = src.getHeight(); |
| int srcNumBands = src.getNumBands(); |
| int dstNumBands = dst.getNumBands(); |
| float[] srcScaleFactor = new float[srcNumBands]; |
| float[] dstScaleFactor = new float[dstNumBands]; |
| float[] srcUseMinVal = new float[srcNumBands]; |
| float[] dstUseMinVal = new float[dstNumBands]; |
| for (int i = 0; i < srcNumBands; i++) { |
| if (srcIsFloat) { |
| srcScaleFactor[i] = 65535.0f / (srcMaxVal[i] - srcMinVal[i]); |
| srcUseMinVal[i] = srcMinVal[i]; |
| } else { |
| if (srcTransferType == DataBuffer.TYPE_SHORT) { |
| srcScaleFactor[i] = 65535.0f / 32767.0f; |
| } else { |
| srcScaleFactor[i] = 65535.0f / |
| ((float) ((1 << srcSM.getSampleSize(i)) - 1)); |
| } |
| srcUseMinVal[i] = 0.0f; |
| } |
| } |
| for (int i = 0; i < dstNumBands; i++) { |
| if (dstIsFloat) { |
| dstScaleFactor[i] = (dstMaxVal[i] - dstMinVal[i]) / 65535.0f; |
| dstUseMinVal[i] = dstMinVal[i]; |
| } else { |
| if (dstTransferType == DataBuffer.TYPE_SHORT) { |
| dstScaleFactor[i] = 32767.0f / 65535.0f; |
| } else { |
| dstScaleFactor[i] = |
| ((float) ((1 << dstSM.getSampleSize(i)) - 1)) / |
| 65535.0f; |
| } |
| dstUseMinVal[i] = 0.0f; |
| } |
| } |
| int ys = src.getMinY(); |
| int yd = dst.getMinY(); |
| int xs, xd; |
| float sample; |
| short[] srcLine = new short[w * srcNumBands]; |
| short[] dstLine = new short[w * dstNumBands]; |
| int idx; |
| 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 |
| for (int y = 0; y < h; y++, ys++, yd++) { |
| // get src scanline |
| xs = src.getMinX(); |
| idx = 0; |
| for (int x = 0; x < w; x++, xs++) { |
| for (int i = 0; i < srcNumBands; i++) { |
| sample = src.getSampleFloat(xs, ys, i); |
| srcLine[idx++] = (short) |
| ((sample - srcUseMinVal[i]) * srcScaleFactor[i] + 0.5f); |
| } |
| } |
| |
| // color convert srcLine to dstLine |
| doTransform(srcIL, dstIL); |
| |
| // store dst scanline |
| xd = dst.getMinX(); |
| idx = 0; |
| for (int x = 0; x < w; x++, xd++) { |
| for (int i = 0; i < dstNumBands; i++) { |
| sample = ((dstLine[idx++] & 0xffff) * dstScaleFactor[i]) + |
| dstUseMinVal[i]; |
| dst.setSample(xd, yd, i, sample); |
| } |
| } |
| } |
| } |
| |
| public void colorConvert(Raster src, WritableRaster dst) { |
| |
| LCMSImageLayout srcIL, dstIL; |
| dstIL = LCMSImageLayout.createImageLayout(dst); |
| if (dstIL != null) { |
| srcIL = LCMSImageLayout.createImageLayout(src); |
| if (srcIL != null) { |
| doTransform(srcIL, dstIL); |
| return; |
| } |
| } |
| // Can't pass src and dst directly to CMM, so process per scanline |
| SampleModel srcSM = src.getSampleModel(); |
| SampleModel dstSM = dst.getSampleModel(); |
| int srcTransferType = src.getTransferType(); |
| int dstTransferType = dst.getTransferType(); |
| int w = src.getWidth(); |
| int h = src.getHeight(); |
| int srcNumBands = src.getNumBands(); |
| int dstNumBands = dst.getNumBands(); |
| int precision = 8; |
| float maxNum = 255.0f; |
| for (int i = 0; i < srcNumBands; i++) { |
| if (srcSM.getSampleSize(i) > 8) { |
| precision = 16; |
| maxNum = 65535.0f; |
| } |
| } |
| for (int i = 0; i < dstNumBands; i++) { |
| if (dstSM.getSampleSize(i) > 8) { |
| precision = 16; |
| maxNum = 65535.0f; |
| } |
| } |
| float[] srcScaleFactor = new float[srcNumBands]; |
| float[] dstScaleFactor = new float[dstNumBands]; |
| for (int i = 0; i < srcNumBands; i++) { |
| if (srcTransferType == DataBuffer.TYPE_SHORT) { |
| srcScaleFactor[i] = maxNum / 32767.0f; |
| } else { |
| srcScaleFactor[i] = maxNum / |
| ((float) ((1 << srcSM.getSampleSize(i)) - 1)); |
| } |
| } |
| for (int i = 0; i < dstNumBands; i++) { |
| if (dstTransferType == DataBuffer.TYPE_SHORT) { |
| dstScaleFactor[i] = 32767.0f / maxNum; |
| } else { |
| dstScaleFactor[i] = |
| ((float) ((1 << dstSM.getSampleSize(i)) - 1)) / maxNum; |
| } |
| } |
| int ys = src.getMinY(); |
| int yd = dst.getMinY(); |
| int xs, xd; |
| int sample; |
| if (precision == 8) { |
| byte[] srcLine = new byte[w * srcNumBands]; |
| byte[] dstLine = new byte[w * dstNumBands]; |
| int idx; |
| // TODO check for src npixels = dst npixels |
| 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 |
| xs = src.getMinX(); |
| idx = 0; |
| for (int x = 0; x < w; x++, xs++) { |
| for (int i = 0; i < srcNumBands; i++) { |
| sample = src.getSample(xs, ys, i); |
| srcLine[idx++] = (byte) |
| ((sample * srcScaleFactor[i]) + 0.5f); |
| } |
| } |
| |
| // color convert srcLine to dstLine |
| doTransform(srcIL, dstIL); |
| |
| // store dst scanline |
| xd = dst.getMinX(); |
| idx = 0; |
| for (int x = 0; x < w; x++, xd++) { |
| for (int i = 0; i < dstNumBands; i++) { |
| sample = (int) (((dstLine[idx++] & 0xff) * |
| dstScaleFactor[i]) + 0.5f); |
| dst.setSample(xd, yd, i, sample); |
| } |
| } |
| } |
| } else { |
| short[] srcLine = new short[w * srcNumBands]; |
| short[] dstLine = new short[w * dstNumBands]; |
| int idx; |
| |
| 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 |
| for (int y = 0; y < h; y++, ys++, yd++) { |
| // get src scanline |
| xs = src.getMinX(); |
| idx = 0; |
| for (int x = 0; x < w; x++, xs++) { |
| for (int i = 0; i < srcNumBands; i++) { |
| sample = src.getSample(xs, ys, i); |
| srcLine[idx++] = (short) |
| ((sample * srcScaleFactor[i]) + 0.5f); |
| } |
| } |
| |
| // color convert srcLine to dstLine |
| doTransform(srcIL, dstIL); |
| |
| // store dst scanline |
| xd = dst.getMinX(); |
| idx = 0; |
| for (int x = 0; x < w; x++, xd++) { |
| for (int i = 0; i < dstNumBands; i++) { |
| sample = (int) (((dstLine[idx++] & 0xffff) * |
| dstScaleFactor[i]) + 0.5f); |
| dst.setSample(xd, yd, i, sample); |
| } |
| } |
| } |
| } |
| } |
| |
| /* convert an array of colors in short format */ |
| /* each color is a contiguous set of array elements */ |
| /* the number of colors is (size of the array) / (number of input/output |
| components */ |
| public short[] colorConvert(short[] src, short[] dst) { |
| |
| if (dst == null) { |
| dst = new short [(src.length/getNumInComponents())*getNumOutComponents()]; |
| } |
| |
| 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); |
| |
| doTransform(srcIL, dstIL); |
| |
| return dst; |
| } catch (ImageLayoutException e) { |
| throw new CMMException("Unable to convert data"); |
| } |
| } |
| |
| public byte[] colorConvert(byte[] src, byte[] dst) { |
| if (dst == null) { |
| dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()]; |
| } |
| |
| 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()); |
| |
| doTransform(srcIL, dstIL); |
| |
| return dst; |
| } catch (ImageLayoutException e) { |
| throw new CMMException("Unable to convert data"); |
| } |
| } |
| } |