1 /* 2 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.cmm.lcms; 27 28 import java.awt.color.ICC_Profile; 29 import java.util.Arrays; 30 import java.util.HashMap; 31 import sun.java2d.cmm.ColorTransform; 32 import sun.java2d.cmm.PCMM; 33 34 public class LCMS implements PCMM { 35 36 /* methods invoked from ICC_Profile */ 37 @Override 38 public long loadProfile(byte[] data) { 39 long id = loadProfileNative(data); 40 41 if (id != 0L) { 42 if (profiles == null) { 43 profiles = new HashMap<>(); 44 } 45 profiles.put(id, new TagCache(id)); 46 } 47 return id; 48 } 49 50 private native long loadProfileNative(byte[] data); 51 52 @Override 53 public void freeProfile(long profileID) { 54 TagCache c = profiles.remove(profileID); 55 if (c != null) { 56 c.clear(); 57 } 58 if (profiles.isEmpty()) { 59 profiles = null; 60 } 61 freeProfileNative(profileID); 62 } 63 64 private native void freeProfileNative(long profileID); 65 66 public native synchronized int getProfileSize(long profileID); 67 68 public native synchronized void getProfileData(long profileID, byte[] data); 69 70 @Override 71 public synchronized int getTagSize(long profileID, int tagSignature) { 72 TagCache cache = profiles.get(profileID); 73 74 if (cache == null) { 75 cache = new TagCache(profileID); 76 profiles.put(profileID, cache); 77 } 78 79 TagData t = cache.getTag(tagSignature); 80 return t == null ? 0 : t.getSize(); 81 } 82 83 private static native byte[] getTagNative(long profileID, int signature); 84 85 @Override 86 public synchronized void getTagData(long profileID, int tagSignature, 87 byte[] data) 88 { 89 TagCache cache = profiles.get(profileID); 90 91 if (cache == null) { 92 cache = new TagCache(profileID); 93 profiles.put(profileID, cache); 94 } 95 96 TagData t = cache.getTag(tagSignature); 97 if (t != null) { 98 t.copyDataTo(data); 99 } 100 } 101 102 @Override 103 public synchronized void setTagData(long profileID, int tagSignature, byte[] data) { 104 TagCache cache = profiles.get(profileID); 105 106 if (cache != null) { 107 cache.clear(); 108 } 109 setTagDataNative(profileID, tagSignature, data); 110 } 111 112 private native synchronized void setTagDataNative(long profileID, int tagSignature, 113 byte[] data); 114 115 public static native long getProfileID(ICC_Profile profile); 116 117 public static native long createNativeTransform( 118 long[] profileIDs, int renderType, 119 int inFormatter, boolean isInIntPacked, 120 int outFormatter, boolean isOutIntPacked, 121 Object disposerRef); 122 123 /** 124 * Constructs ColorTransform object corresponding to an ICC_profile 125 */ 126 public ColorTransform createTransform(ICC_Profile profile, 127 int renderType, 128 int transformType) 129 { 130 return new LCMSTransform(profile, renderType, renderType); 131 } 132 133 /** 134 * Constructs an ColorTransform object from a list of ColorTransform 135 * objects 136 */ 137 public synchronized ColorTransform createTransform( 138 ColorTransform[] transforms) 139 { 140 return new LCMSTransform(transforms); 141 } 142 143 /* methods invoked from LCMSTransform */ 144 public static native void colorConvert(LCMSTransform trans, 145 LCMSImageLayout src, 146 LCMSImageLayout dest); 147 public static native void freeTransform(long ID); 148 149 public static native void initLCMS(Class Trans, Class IL, Class Pf); 150 151 /* the class initializer which loads the CMM */ 152 static { 153 java.security.AccessController.doPrivileged( 154 new java.security.PrivilegedAction() { 155 public Object run() { 156 /* We need to load awt here because of usage trace and 157 * disposer frameworks 158 */ 159 System.loadLibrary("awt"); 160 System.loadLibrary("lcms"); 161 return null; 162 } 163 } 164 ); 165 166 initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class); 167 } 168 169 private static class TagData { 170 private int signature; 171 private byte[] data; 172 173 TagData(int sig, byte[] data) { 174 this.signature = sig; 175 this.data = data; 176 } 177 178 int getSize() { 179 return data.length; 180 } 181 182 byte[] getData() { 183 return Arrays.copyOf(data, data.length); 184 } 185 186 void copyDataTo(byte[] dst) { 187 System.arraycopy(data, 0, dst, 0, data.length); 188 } 189 190 int getSignature() { 191 return signature; 192 } 193 } 194 195 private static class TagCache { 196 private long profileID; 197 private HashMap<Integer, TagData> tags; 198 199 TagCache(long id) { 200 profileID = id; 201 202 tags = new HashMap<>(); 203 } 204 205 TagData getTag(int sig) { 206 TagData t = tags.get(sig); 207 if (t == null) { 208 byte[] tagData = getTagNative(profileID, sig); 209 if (tagData != null) { 210 t = new TagData(sig, tagData); 211 tags.put(sig, t); 212 } 213 } 214 return t; 215 } 216 217 void clear() { 218 tags.clear(); 219 } 220 } 221 222 private static HashMap<Long, TagCache> profiles; 223 } --- EOF ---