Path: blob/master/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java
66647 views
/*1* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.cmm.lcms;2627import java.awt.color.CMMException;28import java.awt.color.ICC_Profile;29import java.util.concurrent.locks.StampedLock;3031import sun.java2d.cmm.ColorTransform;32import sun.java2d.cmm.PCMM;33import sun.java2d.cmm.Profile;3435final class LCMS implements PCMM {3637/**38* Prevent changing profiles data during transform creation.39*/40private static final StampedLock lock = new StampedLock();4142/* methods invoked from ICC_Profile */43@Override44public Profile loadProfile(byte[] data) {45final Object disposerRef = new Object();4647final long ptr = loadProfileNative(data, disposerRef);4849if (ptr != 0L) {50return new LCMSProfile(ptr, disposerRef);51}52return null;53}5455private static LCMSProfile getLcmsProfile(Profile p) {56if (p instanceof LCMSProfile) {57return (LCMSProfile)p;58}59throw new CMMException("Invalid profile: " + p);60}6162/**63* Writes supplied data as a tag into the profile.64* Destroys old profile, if new one was successfully65* created.66*67* Returns valid pointer to new profile.68*69* Throws CMMException if operation fails, preserve old profile from70* destruction.71*/72static native void setTagDataNative(long ptr, int tagSignature, byte[] data);73static native byte[] getProfileDataNative(long ptr);74static native byte[] getTagNative(long profileID, int signature);75private static native long loadProfileNative(byte[] data, Object ref);7677@Override78public byte[] getProfileData(Profile p) {79return getLcmsProfile(p).getProfileData();80}8182@Override83public byte[] getTagData(Profile p, int tagSignature) {84return getLcmsProfile(p).getTag(tagSignature);85}8687@Override88public void setTagData(Profile p, int tagSignature, byte[] data) {89long stamp = lock.writeLock();90try {91getLcmsProfile(p).setTag(tagSignature, data);92} finally {93lock.unlockWrite(stamp);94}95}9697static synchronized native LCMSProfile getProfileID(ICC_Profile profile);9899/* Helper method used from LCMSColorTransfrom */100static long createTransform(101LCMSProfile[] profiles, int renderType,102int inFormatter, boolean isInIntPacked,103int outFormatter, boolean isOutIntPacked,104Object disposerRef)105{106long[] ptrs = new long[profiles.length];107long stamp = lock.readLock();108try {109for (int i = 0; i < profiles.length; i++) {110if (profiles[i] == null) {111throw new CMMException("Unknown profile ID");112}113ptrs[i] = profiles[i].getLcmsPtr();114}115116return createNativeTransform(ptrs, renderType, inFormatter,117isInIntPacked, outFormatter, isOutIntPacked, disposerRef);118} finally {119lock.unlockRead(stamp);120}121}122123private static native long createNativeTransform(124long[] profileIDs, int renderType,125int inFormatter, boolean isInIntPacked,126int outFormatter, boolean isOutIntPacked,127Object disposerRef);128129/**130* Constructs ColorTransform object corresponding to an ICC_profile131*/132public ColorTransform createTransform(ICC_Profile profile,133int renderType,134int transformType)135{136return new LCMSTransform(profile, renderType, renderType);137}138139/**140* Constructs an ColorTransform object from a list of ColorTransform141* objects142*/143public synchronized ColorTransform createTransform(144ColorTransform[] transforms)145{146return new LCMSTransform(transforms);147}148149/* methods invoked from LCMSTransform */150public static native void colorConvert(long trans,151LCMSImageLayout src,152LCMSImageLayout dest);153154public static native void initLCMS(Class<?> Trans, Class<?> IL, Class<?> Pf);155156private LCMS() {};157158private static LCMS theLcms = null;159160@SuppressWarnings("removal")161static synchronized PCMM getModule() {162if (theLcms != null) {163return theLcms;164}165166java.security.AccessController.doPrivileged(167new java.security.PrivilegedAction<Object>() {168public Object run() {169/* We need to load awt here because of usage trace and170* disposer frameworks171*/172System.loadLibrary("awt");173System.loadLibrary("lcms");174return null;175}176});177178initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class);179180theLcms = new LCMS();181182return theLcms;183}184}185186187