1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18 * @author Oleg V. Khaschansky 19 * @version $Revision$ 20 */ 21package org.apache.harmony.awt.gl.color; 22 23import java.awt.color.ICC_Profile; 24 25import org.apache.harmony.awt.gl.color.NativeCMM; 26 27/** 28 * This class encapsulates native ICC transform object, is responsible for its 29 * creation, destruction and passing its handle to the native CMM. 30 */ 31public class ICC_Transform { 32 private long transformHandle; 33 private int numInputChannels; 34 private int numOutputChannels; 35 private ICC_Profile src; 36 private ICC_Profile dst; 37 38 39 /** 40 * @return Returns the number of input channels. 41 */ 42 public int getNumInputChannels() { 43 return numInputChannels; 44 } 45 46 /** 47 * @return Returns the number of output channels. 48 */ 49 public int getNumOutputChannels() { 50 return numOutputChannels; 51 } 52 53 /** 54 * @return Returns the dst. 55 */ 56 public ICC_Profile getDst() { 57 return dst; 58 } 59 60 /** 61 * @return Returns the src. 62 */ 63 public ICC_Profile getSrc() { 64 return src; 65 } 66 67 /** 68 * Constructs a multiprofile ICC transform 69 * @param profiles - list of ICC profiles 70 * @param renderIntents - only hints for CMM 71 */ 72 public ICC_Transform(ICC_Profile[] profiles, int[] renderIntents) { 73 int numProfiles = profiles.length; 74 75 long[] profileHandles = new long[numProfiles]; 76 for (int i=0; i<numProfiles; i++) { 77 profileHandles[i] = NativeCMM.getHandle(profiles[i]); 78 } 79 80 transformHandle = NativeCMM.cmmCreateMultiprofileTransform( 81 profileHandles, 82 renderIntents); 83 84 src = profiles[0]; 85 dst = profiles[numProfiles-1]; 86 numInputChannels = src.getNumComponents(); 87 numOutputChannels = dst.getNumComponents(); 88 } 89 90 /** 91 * This constructor is able to set intents by default 92 * @param profiles - list of ICC profiles 93 */ 94 public ICC_Transform(ICC_Profile[] profiles) { 95 int numProfiles = profiles.length; 96 int[] renderingIntents = new int[numProfiles]; 97 98 // Default is perceptual 99 int currRenderingIntent = ICC_Profile.icPerceptual; 100 101 // render as colorimetric for output device 102 if (profiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) { 103 currRenderingIntent = ICC_Profile.icRelativeColorimetric; 104 } 105 106 // get the transforms from each profile 107 for (int i = 0; i < numProfiles; i++) { 108 // first or last profile cannot be abstract 109 // if profile is abstract, the only possible way is 110 // use AToB0Tag (perceptual), see ICC spec 111 if (i != 0 && 112 i != numProfiles - 1 && 113 profiles[i].getProfileClass() == ICC_Profile.CLASS_ABSTRACT 114 ) { 115 currRenderingIntent = ICC_Profile.icPerceptual; 116 } 117 118 renderingIntents[i] = currRenderingIntent; 119 // use current rendering intent 120 // to select LUT from the next profile (chaining) 121 currRenderingIntent = 122 ICC_ProfileHelper.getRenderingIntent(profiles[i]); 123 } 124 125 // Get the profile handles and go ahead 126 long[] profileHandles = new long[numProfiles]; 127 for (int i=0; i<numProfiles; i++) { 128 profileHandles[i] = NativeCMM.getHandle(profiles[i]); 129 } 130 131 transformHandle = NativeCMM.cmmCreateMultiprofileTransform( 132 profileHandles, 133 renderingIntents); 134 135 src = profiles[0]; 136 dst = profiles[numProfiles-1]; 137 numInputChannels = src.getNumComponents(); 138 numOutputChannels = dst.getNumComponents(); 139 } 140 141 @Override 142 protected void finalize() { 143 if (transformHandle != 0) { 144 NativeCMM.cmmDeleteTransform(transformHandle); 145 } 146 } 147 148 /** 149 * Invokes native color conversion 150 * @param src - source image format 151 * @param dst - destination image format 152 */ 153 public void translateColors(NativeImageFormat src, NativeImageFormat dst) { 154 NativeCMM.cmmTranslateColors(transformHandle, src, dst); 155 } 156}