/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
// This file is available under and governed by the GNU General Public
// License version 2 only, as published by the Free Software Foundation.
// However, the following notice accompanied the original version of this
// file:
//
//---------------------------------------------------------------------------------
//
// Little Color Management System
// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//---------------------------------------------------------------------------------
//
#include "lcms2_internal.h"
// Transformations stuff
// -----------------------------------------------------------------------
// Alarm codes for 16-bit transformations, because the fixed range of containers there are
// no values left to mark out of gamut. volatile is C99 per 6.2.5
static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS] = { 0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine
{
if (d >= 0)
return OldVal;
}
// Alarm codes are always global
{
int i;
for (i=0; i < cmsMAXCHANNELS; i++)
}
// You can get the codes cas well
{
int i;
for (i=0; i < cmsMAXCHANNELS; i++)
}
// Get rid of transform resources
{
_cmsAssert(p != NULL);
if (p -> GamutCheck)
cmsPipelineFree(p -> GamutCheck);
if (p -> Lut)
cmsPipelineFree(p -> Lut);
if (p ->InputColorant)
if (p -> OutputColorant)
if (p ->Sequence)
if (p ->UserData)
}
// Apply transform.
const void* InputBuffer,
void* OutputBuffer,
{
}
// Apply transform.
const void* InputBuffer,
void* OutputBuffer,
{
}
// Transform routines ----------------------------------------------------------------------------------------------------------
// Float xform converts floats. Since there are no performance issues, one routine does all job, including gamut check.
// Note that because extended range, we can use a -1.0 value for out of gamut in this case.
static
const void* in,
{
cmsUInt32Number i, j;
for (i=0; i < Size; i++) {
// Any gamut chack to do?
if (p ->GamutCheck != NULL) {
// Evaluate gamut marker.
// Is current color out of gamut?
if (OutOfGamut > 0.0) {
// Certainly, out of gamut
for (j=0; j < cmsMAXCHANNELS; j++)
fOut[j] = -1.0;
}
else {
// No, proceed normally
}
}
else {
// No gamut check at all
}
// Back to asked representation
}
}
// 16 bit precision -----------------------------------------------------------------------------------------------------------
// Null transformation, only applies formatters. No cach�
static
const void* in,
{
cmsUInt32Number i, n;
n = Size; // Buffer len
for (i=0; i < n; i++) {
}
}
// No gamut check, no cache, 16 bits
static
const void* in,
{
cmsUInt32Number i, n;
n = Size;
for (i=0; i < n; i++) {
}
}
// Auxiliar: Handle precalculated gamut check
static
const cmsUInt16Number wIn[],
{
if (wOutOfGamut >= 1) {
for (i=0; i < p ->Lut->OutputChannels; i++)
}
else
}
// Gamut check, No cach�, 16 bits.
static
const void* in,
{
cmsUInt32Number i, n;
n = Size; // Buffer len
for (i=0; i < n; i++) {
}
}
// No gamut check, Cach�, 16 bits,
static
const void* in,
{
cmsUInt32Number i, n;
n = Size; // Buffer len
// Empty buffers for quick memcmp
// Get copy of zero cache
for (i=0; i < n; i++) {
}
else {
}
}
}
// All those nice features together
static
const void* in,
{
cmsUInt32Number i, n;
n = Size; // Buffer len
// Empty buffers for quick memcmp
// Get copy of zero cache
for (i=0; i < n; i++) {
}
else {
}
}
}
// -------------------------------------------------------------------------------------------------------------
// List of used-defined transform factories
typedef struct _cmsTransformCollection_st {
// The linked list head
// Register new ways to transform
{
// Free the chain. Memory is safely freed at exit
return TRUE;
}
// Factory callback is required
// Copy the parameters
// Keep linked list
// All is ok
return TRUE;
}
void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn)
{
}
// returns the pointer defined by the plug-in to store private data
{
}
// returns the current formatters
void CMSEXPORT _cmsGetTransformFormatters16(struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput)
{
}
void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput)
{
}
// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper
// for separated transforms. If this is the case,
static
cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
{
// Allocate needed memory
if (!p) return NULL;
// Store the proposed pipeline
// Let's see if any plug-in want to do the transform by itself
for (Plugin = TransformCollection;
if (Plugin ->Factory(&p->xform, &p->UserData, &p ->FreeUserData, &p ->Lut, InputFormat, OutputFormat, dwFlags)) {
// Last plugin in the declaration order takes control. We just keep
// the original parameters as a logging.
// Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default
// an optimized transform is not reusable. The plug-in can, however, change
// the flags and make it suitable.
p ->InputFormat = *InputFormat;
p ->OutputFormat = *OutputFormat;
p ->dwOriginalFlags = *dwFlags;
// Fill the formatters just in case the optimized routine is interested.
// No error is thrown if the formatter doesn't exist. It is up to the optimization
// factory to decide what to do in those cases.
p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
return p;
}
}
// Not suitable for the transform plug-in, let's check the pipeline plug-in
// Check whatever this is a true floating point transform
// Get formatter function always return a valid union, but the contents of this union may be NULL.
p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
return NULL;
}
// Float transforms don't use cach�, always are non-NULL
p ->xform = FloatXFORM;
}
else {
if (*InputFormat == 0 && *OutputFormat == 0) {
}
else {
int BytesPerPixelInput;
return NULL;
}
}
if (*dwFlags & cmsFLAGS_NULLTRANSFORM) {
}
else {
if (*dwFlags & cmsFLAGS_NOCACHE) {
if (*dwFlags & cmsFLAGS_GAMUTCHECK)
else
}
else {
if (*dwFlags & cmsFLAGS_GAMUTCHECK)
else
}
}
}
p ->InputFormat = *InputFormat;
p ->OutputFormat = *OutputFormat;
p ->dwOriginalFlags = *dwFlags;
return p;
}
static
cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output)
{
int i;
for (i=0; i < nProfiles; i++) {
(PostColorSpace != cmsSigLabData);
if (cls == cmsSigNamedColorClass) {
}
else
}
else
{
}
if (i==0)
*Input = ColorSpaceIn;
}
*Output = PostColorSpace;
return TRUE;
}
// Check colorspace
static
{
return FALSE;
}
// ----------------------------------------------------------------------------------------------------------------
// New to lcms 2.0 -- have all parameters available.
{
// If it is a fake transform
if (dwFlags & cmsFLAGS_NULLTRANSFORM)
{
return AllocEmptyTransform(ContextID, NULL, INTENT_PERCEPTUAL, &InputFormat, &OutputFormat, &dwFlags);
}
// If gamut check is requested, make sure we have a gamut profile
if (dwFlags & cmsFLAGS_GAMUTCHECK) {
}
// On floating point transforms, inhibit optimizations
return NULL;
}
// Check if proper colorspaces
return NULL;
}
return NULL;
}
// Create a pipeline with all transformations
return NULL;
}
// Check channel count
cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted");
return NULL;
}
// All seems ok
return NULL;
}
// Keep values
// Create a gamut check LUT if requested
// Try to read input and output colorant table
// Input table can only come in this way.
xform ->InputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[0], cmsSigColorantTableTag));
}
// Output is a little bit more complex.
// This tag may exist only on devicelink profiles.
// It may be NULL if error
xform ->OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag));
}
} else {
xform -> OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableTag));
}
}
// Store the sequence of profiles
if (dwFlags & cmsFLAGS_KEEP_SEQUENCE) {
}
else
// If this is a cached transform, init first value, which is zero (16 bits only)
if (!(dwFlags & cmsFLAGS_NOCACHE)) {
}
else {
}
}
return (cmsHTRANSFORM) xform;
}
// Multiprofile transforms: Gamut check is not available here, as it is unclear from which profile the gamut comes.
{
cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles);
return NULL;
}
for (i=0; i < nProfiles; i++) {
}
return cmsCreateExtendedTransform(ContextID, nProfiles, hProfiles, BPC, Intents, AdaptationStates, NULL, 0, InputFormat, OutputFormat, dwFlags);
}
{
cmsSignalError(NULL, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles);
return NULL;
}
dwFlags);
}
{
return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1 : 2, InputFormat, OutputFormat, Intent, dwFlags);
}
{
return cmsCreateTransformTHR(cmsGetProfileContextID(Input), Input, InputFormat, Output, OutputFormat, Intent, dwFlags);
}
{
hArray[0] = InputProfile; hArray[1] = ProofingProfile; hArray[2] = ProofingProfile; hArray[3] = OutputProfile;
Intents[0] = nIntent; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = ProofingIntent;
return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags);
}
{
dwFlags);
}
// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
{
}
{
return xform->InputFormat;
}
{
return xform->OutputFormat;
}
// For backwards compatibility
{
// We only can afford to change formatters if previous transform is at least 16 bits
cmsSignalError(xform ->ContextID, cmsERROR_NOT_SUITABLE, "cmsChangeBuffersFormat works only on transforms created originally with at least 16 bits of precision");
return FALSE;
}
return FALSE;
}
return TRUE;
}