summaryrefslogtreecommitdiff
path: root/third_party/lcms/src/cmsxform.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/lcms/src/cmsxform.c')
-rw-r--r--third_party/lcms/src/cmsxform.c518
1 files changed, 356 insertions, 162 deletions
diff --git a/third_party/lcms/src/cmsxform.c b/third_party/lcms/src/cmsxform.c
index dffe6b2fb7..b3802f0d57 100644
--- a/third_party/lcms/src/cmsxform.c
+++ b/third_party/lcms/src/cmsxform.c
@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2014 Marti Maria Saguer
+// Copyright (c) 1998-2016 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"),
@@ -179,12 +179,18 @@ void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
{
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
-
- p -> xform(p, InputBuffer, OutputBuffer, Size, Size);
+ cmsStride stride;
+
+ stride.BytesPerLineIn = 0; // Not used
+ stride.BytesPerLineOut = 0;
+ stride.BytesPerPlaneIn = Size;
+ stride.BytesPerPlaneOut = Size;
+
+ p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride);
}
-// Apply transform.
+// This is a legacy stride for planar
void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
const void* InputBuffer,
void* OutputBuffer,
@@ -192,10 +198,40 @@ void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
{
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+ cmsStride stride;
- p -> xform(p, InputBuffer, OutputBuffer, Size, Stride);
+ stride.BytesPerLineIn = 0;
+ stride.BytesPerLineOut = 0;
+ stride.BytesPerPlaneIn = Stride;
+ stride.BytesPerPlaneOut = Stride;
+
+ p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride);
}
+// This is the "fast" function for plugins
+void CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM Transform,
+ const void* InputBuffer,
+ void* OutputBuffer,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ cmsUInt32Number BytesPerLineIn,
+ cmsUInt32Number BytesPerLineOut,
+ cmsUInt32Number BytesPerPlaneIn,
+ cmsUInt32Number BytesPerPlaneOut)
+
+{
+ _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+ cmsStride stride;
+
+ stride.BytesPerLineIn = BytesPerLineIn;
+ stride.BytesPerLineOut = BytesPerLineOut;
+ stride.BytesPerPlaneIn = BytesPerPlaneIn;
+ stride.BytesPerPlaneOut = BytesPerPlaneOut;
+
+ p->xform(p, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, &stride);
+}
+
+
// Transform routines ----------------------------------------------------------------------------------------------------------
@@ -204,49 +240,64 @@ void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
static
void FloatXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
cmsFloat32Number OutOfGamut;
- cmsUInt32Number i, j;
+ cmsUInt32Number i, j, c, strideIn, strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
- for (i=0; i < Size; i++) {
+ strideIn = 0;
+ strideOut = 0;
- accum = p -> FromInputFloat(p, fIn, accum, Stride);
+ for (i = 0; i < LineCount; i++) {
- // Any gamut chack to do?
- if (p ->GamutCheck != NULL) {
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- // Evaluate gamut marker.
- cmsPipelineEvalFloat( fIn, &OutOfGamut, p ->GamutCheck);
+ for (j = 0; j < PixelsPerLine; j++) {
- // Is current color out of gamut?
- if (OutOfGamut > 0.0) {
+ accum = p->FromInputFloat(p, fIn, accum, Stride->BytesPerPlaneIn);
- // Certainly, out of gamut
- for (j=0; j < cmsMAXCHANNELS; j++)
- fOut[j] = -1.0;
+ // Any gamut chack to do?
+ if (p->GamutCheck != NULL) {
+ // Evaluate gamut marker.
+ cmsPipelineEvalFloat(fIn, &OutOfGamut, p->GamutCheck);
+
+ // Is current color out of gamut?
+ if (OutOfGamut > 0.0) {
+
+ // Certainly, out of gamut
+ for (c = 0; c < cmsMAXCHANNELS; c++)
+ fOut[c] = -1.0;
+
+ }
+ else {
+ // No, proceed normally
+ cmsPipelineEvalFloat(fIn, fOut, p->Lut);
+ }
}
else {
- // No, proceed normally
- cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
+
+ // No gamut check at all
+ cmsPipelineEvalFloat(fIn, fOut, p->Lut);
}
- }
- else {
- // No gamut check at all
- cmsPipelineEvalFloat(fIn, fOut, p -> Lut);
+
+ output = p->ToOutputFloat(p, fOut, output, Stride->BytesPerPlaneOut);
}
- // Back to asked representation
- output = p -> ToOutputFloat(p, fOut, output, Stride);
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
+
}
@@ -254,47 +305,73 @@ static
void NullFloatXFORM(_cmsTRANSFORM* p,
const void* in,
void* out,
- cmsUInt32Number Size,
- cmsUInt32Number Stride)
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
+
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsFloat32Number fIn[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
+
+ accum = (cmsUInt8Number*) in + strideIn;
+ output = (cmsUInt8Number*) out + strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size;
+ for (j = 0; j < PixelsPerLine; j++) {
- for (i=0; i < n; i++) {
+ accum = p->FromInputFloat(p, fIn, accum, Stride ->BytesPerPlaneIn);
+ output = p->ToOutputFloat(p, fIn, output, Stride->BytesPerPlaneOut);
+ }
- accum = p -> FromInputFloat(p, fIn, accum, Stride);
- output = p -> ToOutputFloat(p, fIn, output, Stride);
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
}
// 16 bit precision -----------------------------------------------------------------------------------------------------------
-// Null transformation, only applies formatters. No cach?static
+// Null transformation, only applies formatters. No cache
+static
void NullXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size,
- cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- for (i=0; i < n; i++) {
+ for (j = 0; j < PixelsPerLine; j++) {
- accum = p -> FromInput(p, wIn, accum, Stride);
- output = p -> ToOutput(p, wIn, output, Stride);
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+ output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut);
}
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
+ }
+
}
@@ -302,27 +379,41 @@ void NullXFORM(_cmsTRANSFORM* p,
static
void PrecalculatedXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
register cmsUInt8Number* accum;
register cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size;
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
- for (i=0; i < n; i++) {
+ strideIn = 0;
+ strideOut = 0;
- accum = p -> FromInput(p, wIn, accum, Stride);
- p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
- output = p -> ToOutput(p, wOut, output, Stride);
+ for (i = 0; i < LineCount; i++) {
+
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
+
+ for (j = 0; j < PixelsPerLine; j++) {
+
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+ p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data);
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+ }
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
+
}
-// Auxiliar: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
+// Auxiliary: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical.
static
void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
const cmsUInt16Number wIn[],
@@ -345,122 +436,161 @@ void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
}
-// Gamut check, No cach? 16 bits.
+// Gamut check, No cache, 16 bits.
static
void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- for (i=0; i < n; i++) {
+ for (j = 0; j < PixelsPerLine; j++) {
- accum = p -> FromInput(p, wIn, accum, Stride);
- TransformOnePixelWithGamutCheck(p, wIn, wOut);
- output = p -> ToOutput(p, wOut, output, Stride);
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
+ TransformOnePixelWithGamutCheck(p, wIn, wOut);
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+ }
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
}
-// No gamut check, Cach? 16 bits,
+// No gamut check, Cache, 16 bits,
static
void CachedXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
_cmsCACHE Cache;
+ cmsUInt32Number i, j, strideIn, strideOut;
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
// Empty buffers for quick memcmp
- memset(wIn, 0, sizeof(wIn));
+ memset(wIn, 0, sizeof(wIn));
memset(wOut, 0, sizeof(wOut));
// Get copy of zero cache
- memcpy(&Cache, &p ->Cache, sizeof(Cache));
+ memcpy(&Cache, &p->Cache, sizeof(Cache));
- for (i=0; i < n; i++) {
+ strideIn = 0;
+ strideOut = 0;
- accum = p -> FromInput(p, wIn, accum, Stride);
+ for (i = 0; i < LineCount; i++) {
- if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
- }
- else {
+ for (j = 0; j < PixelsPerLine; j++) {
- p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
- memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
- memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+ if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
+
+ memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
+ }
+ else {
+ p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data);
+
+ memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+ memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+ }
+
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
}
- output = p -> ToOutput(p, wOut, output, Stride);
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
}
-
}
-
// All those nice features together
static
void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
+ void* out,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
{
- cmsUInt8Number* accum;
- cmsUInt8Number* output;
- cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
- cmsUInt32Number i, n;
- _cmsCACHE Cache;
+ cmsUInt8Number* accum;
+ cmsUInt8Number* output;
+ cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
+ _cmsCACHE Cache;
+ cmsUInt32Number i, j, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
+
+ // Empty buffers for quick memcmp
+ memset(wIn, 0, sizeof(wIn));
+ memset(wOut, 0, sizeof(wOut));
+
+ // Get copy of zero cache
+ memcpy(&Cache, &p->Cache, sizeof(Cache));
- accum = (cmsUInt8Number*) in;
- output = (cmsUInt8Number*) out;
- n = Size; // Buffer len
+ strideIn = 0;
+ strideOut = 0;
- // Empty buffers for quick memcmp
- memset(wIn, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- memset(wOut, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
+ for (i = 0; i < LineCount; i++) {
- // Get copy of zero cache
- memcpy(&Cache, &p ->Cache, sizeof(Cache));
+ accum = (cmsUInt8Number*)in + strideIn;
+ output = (cmsUInt8Number*)out + strideOut;
- for (i=0; i < n; i++) {
+ for (j = 0; j < PixelsPerLine; j++) {
- accum = p -> FromInput(p, wIn, accum, Stride);
+ accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
- memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
+
+ memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
}
else {
- TransformOnePixelWithGamutCheck(p, wIn, wOut);
- memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
- memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
+ TransformOnePixelWithGamutCheck(p, wIn, wOut);
+
+ memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+ memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
}
- output = p -> ToOutput(p, wOut, output, Stride);
- }
+ output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut);
+ }
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
+ }
}
-// -------------------------------------------------------------------------------------------------------------
+// Transform plug-ins ----------------------------------------------------------------------------------------------------
// List of used-defined transform factories
typedef struct _cmsTransformCollection_st {
- _cmsTransformFactory Factory;
+ _cmsTransform2Factory Factory;
+ cmsBool OldXform; // Factory returns xform function in the old style
+
struct _cmsTransformCollection_st *Next;
} _cmsTransformCollection;
@@ -503,6 +633,7 @@ void DupPluginTransformList(struct _cmsContext_struct* ctx,
ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
}
+// Allocates memory for transform plugin factory
void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src)
{
@@ -517,6 +648,35 @@ void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
}
}
+// Adaptor for old versions of plug-in
+static
+void _cmsTransform2toTransformAdaptor(struct _cmstransform_struct *CMMcargo,
+ const void* InputBuffer,
+ void* OutputBuffer,
+ cmsUInt32Number PixelsPerLine,
+ cmsUInt32Number LineCount,
+ const cmsStride* Stride)
+{
+
+ cmsUInt32Number i, strideIn, strideOut;
+
+ _cmsHandleExtraChannels(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride);
+
+ strideIn = 0;
+ strideOut = 0;
+
+ for (i = 0; i < LineCount; i++) {
+
+ void *accum = (cmsUInt8Number*)InputBuffer + strideIn;
+ void *output = (cmsUInt8Number*)OutputBuffer + strideOut;
+
+ CMMcargo->OldXform(CMMcargo, accum, output, PixelsPerLine, Stride->BytesPerPlaneIn);
+
+ strideIn += Stride->BytesPerLineIn;
+ strideOut += Stride->BytesPerLineOut;
+ }
+}
+
// Register new ways to transform
@@ -534,14 +694,22 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data)
}
// Factory callback is required
- if (Plugin ->Factory == NULL) return FALSE;
+ if (Plugin->factories.xform == NULL) return FALSE;
fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
if (fl == NULL) return FALSE;
+ // Check for full xform plug-ins previous to 2.8, we would need an adapter in that case
+ if (Plugin->base.ExpectedVersion < 2080) {
+
+ fl->OldXform = TRUE;
+ }
+ else
+ fl->OldXform = FALSE;
+
// Copy the parameters
- fl ->Factory = Plugin ->Factory;
+ fl->Factory = Plugin->factories.xform;
// Keep linked list
fl ->Next = ctx->TransformCollection;
@@ -591,49 +759,57 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
_cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin);
_cmsTransformCollection* Plugin;
- // Allocate needed memory
- _cmsTRANSFORM* p = (_cmsTRANSFORM*) _cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
- if (!p) {
- cmsPipelineFree(lut);
- return NULL;
- }
-
- // Store the proposed pipeline
- p ->Lut = lut;
-
- // Let's see if any plug-in want to do the transform by itself
- for (Plugin = ctx ->TransformCollection;
- Plugin != NULL;
- Plugin = Plugin ->Next) {
-
- 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 ->ContextID = ContextID;
- 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 ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
- p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
-
- return p;
- }
- }
-
- // Not suitable for the transform plug-in, let's check the pipeline plug-in
- if (p ->Lut != NULL)
- _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+ // Allocate needed memory
+ _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
+ if (!p) {
+ cmsPipelineFree(lut);
+ return NULL;
+ }
+
+ // Store the proposed pipeline
+ p->Lut = lut;
+
+ // Let's see if any plug-in want to do the transform by itself
+ if (p->Lut != NULL) {
+
+ for (Plugin = ctx->TransformCollection;
+ Plugin != NULL;
+ Plugin = Plugin->Next) {
+
+ 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->ContextID = ContextID;
+ 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->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+
+ // Save the day?
+ if (Plugin->OldXform) {
+ p->OldXform = (_cmsTransformFn) p->xform;
+ p->xform = _cmsTransform2toTransformAdaptor;
+ }
+
+ return p;
+ }
+ }
+
+ // Not suitable for the transform plug-in, let's check the pipeline plug-in
+ _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+ }
// Check whatever this is a true floating point transform
if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) {
@@ -655,7 +831,7 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
p ->xform = NullFloatXFORM;
}
else {
- // Float transforms don't use cach? always are non-NULL
+ // Float transforms don't use cache, always are non-NULL
p ->xform = FloatXFORM;
}
@@ -694,16 +870,17 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
if (*dwFlags & cmsFLAGS_NOCACHE) {
if (*dwFlags & cmsFLAGS_GAMUTCHECK)
- p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cach?
+ p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cache
else
- p ->xform = PrecalculatedXFORM; // No cach? no gamut check
+ p ->xform = PrecalculatedXFORM; // No cache, no gamut check
}
else {
if (*dwFlags & cmsFLAGS_GAMUTCHECK)
- p ->xform = CachedXFORMGamutCheck; // Gamut check, cach?
+ p ->xform = CachedXFORMGamutCheck; // Gamut check, cache
else
- p ->xform = CachedXFORM; // No gamut check, cach?
+ p ->xform = CachedXFORM; // No gamut check, cache
+
}
}
}
@@ -786,6 +963,22 @@ cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwForm
// ----------------------------------------------------------------------------------------------------------------
+// Jun-21-2000: Some profiles (those that comes with W2K) comes
+// with the media white (media black?) x 100. Add a sanity check
+
+static
+void NormalizeXYZ(cmsCIEXYZ* Dest)
+{
+ while (Dest -> X > 2. &&
+ Dest -> Y > 2. &&
+ Dest -> Z > 2.) {
+
+ Dest -> X /= 10.;
+ Dest -> Y /= 10.;
+ Dest -> Z /= 10.;
+ }
+}
+
static
void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
{
@@ -798,6 +991,8 @@ void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
wtPt ->X = src->X;
wtPt ->Y = src->Y;
wtPt ->Z = src->Z;
+
+ NormalizeXYZ(wtPt);
}
}
@@ -1108,7 +1303,6 @@ cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
cmsUInt32Number InputFormat,
cmsUInt32Number OutputFormat)
{
-
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
cmsFormatter16 FromInput, ToOutput;