/* * Copyright (c) 2007, 2022, 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.
*/
(*javaVM)->AttachCurrentThread(javaVM, (void**)&env, NULL); if (!(*env)->ExceptionCheck(env)) { // errorHandler may throw it before
JNU_ThrowByName(env, "java/awt/color/CMMException", errMsg);
}
}
void LCMS_freeProfile(JNIEnv *env, jlong ptr) {
lcmsProfile_p p = (lcmsProfile_p)jlong_to_ptr(ptr);
if (p != NULL) { if (p->pf != NULL) {
cmsCloseProfile(p->pf);
}
free(p);
}
}
void LCMS_freeTransform(JNIEnv *env, jlong ID)
{
cmsHTRANSFORM sTrans = jlong_to_ptr(ID); /* Passed ID is always valid native ref so there is no check for zero */
cmsDeleteTransform(sTrans);
}
/* * Throw an IllegalArgumentException and init the cause.
*/ staticvoid ThrowIllegalArgumentException(JNIEnv *env, constchar *msg) {
jthrowable cause = (*env)->ExceptionOccurred(env); if (cause != NULL) {
(*env)->ExceptionClear(env);
}
jstring str = JNU_NewStringPlatform(env, msg); if (str != NULL) {
jobject iae = JNU_NewObjectByName(env, "java/lang/IllegalArgumentException", "(Ljava/lang/String;Ljava/lang/Throwable;)V",
str, cause); if (iae != NULL) {
(*env)->Throw(env, iae);
}
}
}
size = (*env)->GetArrayLength (env, profileIDs);
ids = (*env)->GetLongArrayElements(env, profileIDs, 0); if (ids == NULL) { // An exception should have already been thrown. return 0L;
}
#ifdef _LITTLE_ENDIAN /* Reversing data packed into int for LE archs */ if (isInIntPacked) {
inFormatter ^= DOSWAP_SH(1);
} if (isOutIntPacked) {
outFormatter ^= DOSWAP_SH(1);
} #endif
if (DF_ICC_BUF_SIZE < size*2) {
iccArray = (cmsHPROFILE*) malloc(
size*2*sizeof(cmsHPROFILE)); if (iccArray == NULL) {
(*env)->ReleaseLongArrayElements(env, profileIDs, ids, 0);
// determine actual profile size if (!cmsSaveProfileToMem(sProf->pf, NULL, &pfSize)) { if (!(*env)->ExceptionCheck(env)) { // errorHandler may throw it
JNU_ThrowByName(env, "java/awt/color/CMMException", "Can not access specified profile.");
} return NULL;
}
jbyteArray data = (*env)->NewByteArray(env, pfSize); if (data == NULL) { // An exception should have already been thrown. return NULL;
}
jbyte* dataArray = (*env)->GetByteArrayElements(env, data, 0); if (dataArray == NULL) { // An exception should have already been thrown. return NULL;
}
cmsBool status = cmsSaveProfileToMem(sProf->pf, dataArray, &pfSize);
if (!status) { if (!(*env)->ExceptionCheck(env)) { // errorHandler may throw it
JNU_ThrowByName(env, "java/awt/color/CMMException", "Can not access specified profile.");
} return NULL;
} return data;
}
if (!status) { if (!(*env)->ExceptionCheck(env)) { // errorHandler may throw it
JNU_ThrowByName(env, "java/awt/color/CMMException", "ICC Profile header not found");
} return NULL;
}
return data;
}
if (cmsIsTag(sProf->pf, sig.cms)) {
tagSize = cmsReadRawTag(sProf->pf, sig.cms, NULL, 0);
} else { if (!(*env)->ExceptionCheck(env)) { // errorHandler may throw it
JNU_ThrowByName(env, "java/awt/color/CMMException", "ICC profile tag not found");
} return NULL;
}
// allocate java array
data = (*env)->NewByteArray(env, tagSize); if (data == NULL) { // An exception should have already been thrown. return NULL;
}
if (bufSize != tagSize) { if (!(*env)->ExceptionCheck(env)) { // errorHandler may throw it
JNU_ThrowByName(env, "java/awt/color/CMMException", "Can not get tag data.");
} return NULL;
} return data;
}
if (dataArray == NULL) { // An exception should have already been thrown. return;
}
if (tagSig == SigHead) {
status = _setHeaderInfo(sProf->pf, dataArray, tagSize);
} else { /* * New strategy for generic tags: create a place holder, * dump all existing tags there, dump externally supplied * tag, and return the new profile to the java.
*/
pfReplace = _writeCookedTag(sProf->pf, sig.cms, dataArray, tagSize);
status = (pfReplace != NULL);
}
if (sTrans == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "LCMS_colorConvert: transform == NULL");
JNU_ThrowByName(env, "java/awt/color/CMMException", "Cannot get color transform"); return;
}
void *inputBuffer = getILData(env, srcData, srcDType); if (inputBuffer == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, ""); // An exception should have already been thrown. return;
}
void *outputBuffer = getILData(env, dstData, dstDType); if (outputBuffer == NULL) {
releaseILData(env, inputBuffer, srcDType, srcData, JNI_ABORT); // An exception should have already been thrown. return;
}
pfBuffer = malloc(pfSize); if (pfBuffer == NULL) { returnFALSE;
}
// load raw profile data into the buffer if (cmsSaveProfileToMem(pf, pfBuffer, &pfSize)) {
memcpy(pBuffer, pfBuffer, sizeof(cmsICCHeader));
status = TRUE;
}
free(pfBuffer); return status;
}
// now set header fields, which we can access using the lcms2 public API
cmsSetHeaderFlags(pf, _cmsAdjustEndianess32(pfHeader.flags));
cmsSetHeaderManufacturer(pf, _cmsAdjustEndianess32(pfHeader.manufacturer));
cmsSetHeaderModel(pf, _cmsAdjustEndianess32(pfHeader.model));
cmsUInt64Number attributes;
_cmsAdjustEndianess64(&attributes, &pfHeader.attributes);
cmsSetHeaderAttributes(pf, attributes);
cmsSetHeaderProfileID(pf, (cmsUInt8Number*)&(pfHeader.profileID));
cmsSetHeaderRenderingIntent(pf, _cmsAdjustEndianess32(pfHeader.renderingIntent));
cmsSetPCS(pf, _cmsAdjustEndianess32(pfHeader.pcs));
cmsSetColorSpace(pf, _cmsAdjustEndianess32(pfHeader.colorSpace));
cmsSetDeviceClass(pf, _cmsAdjustEndianess32(pfHeader.deviceClass));
cmsSetEncodedICCversion(pf, _cmsAdjustEndianess32(pfHeader.version));
returnTRUE;
}
/* Returns new profile handler, if it was created successfully, NULL otherwise.
*/ static cmsHPROFILE _writeCookedTag(const cmsHPROFILE pfTarget, const cmsTagSignature sig,
jbyte *pData, jint size)
{
cmsUInt32Number pfSize = 0; const cmsInt32Number tagCount = cmsGetTagCount(pfTarget);
cmsInt32Number i;
cmsHPROFILE pfSanity = NULL;
cmsICCHeader hdr;
cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
// now write the user supplied tag if (size <= 0 || !cmsWriteRawTag(p, sig, pData, size)) {
cmsCloseProfile(p); return NULL;
}
// copy tags from the original profile for (i = 0; i < tagCount; i++) {
cmsBool isTagReady = FALSE; const cmsTagSignature s = cmsGetTagSignature(pfTarget, i); const cmsUInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0);
if (s == sig) { // skip the user supplied tag continue;
}
// read raw tag from the original profile if (tagSize > 0) {
cmsUInt8Number* buf = (cmsUInt8Number*)malloc(tagSize); if (buf != NULL) { if (tagSize == cmsReadRawTag(pfTarget, s, buf, tagSize)) { // now we are ready to write the tag
isTagReady = cmsWriteRawTag(p, s, buf, tagSize);
}
free(buf);
}
}
if (!isTagReady) {
cmsCloseProfile(p); return NULL;
}
}
// now we have all tags moved to the new profile. // do some sanity checks: write it to a memory buffer and read again. void* buf = NULL; if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
buf = malloc(pfSize); if (buf != NULL) { // load raw profile data into the buffer if (cmsSaveProfileToMem(p, buf, &pfSize)) {
pfSanity = cmsOpenProfileFromMem(buf, pfSize);
}
}
}
cmsCloseProfile(p); // No longer needed.
if (pfSanity == NULL) { // for some reason, we failed to save and read the updated profile // It likely indicates that the profile is not correct, so we report // a failure here.
free(buf); return NULL;
} else { // do final check whether we can read and handle the target tag. constvoid* pTag = cmsReadTag(pfSanity, sig); if (pTag == NULL) { // the tag can not be cooked
free(buf);
cmsCloseProfile(pfSanity); return NULL;
} // The profile we used for sanity checking needs to be returned // since the one we updated is raw - not cooked. // Except we want to re-open it since the call to cmsReadTag() // means we may not get back the same bytes as we set. // Whilst this may change later anyway, we can at least prevent // it from happening immediately.
cmsCloseProfile(pfSanity);
pfSanity = cmsOpenProfileFromMem(buf, pfSize);
free(buf); return pfSanity;
}
}
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.