8162488: JDK should be updated to use LittleCMS 2.8
Reviewed-by: serb, psadhukhan
This commit is contained in:
parent
a8ce73f840
commit
eae21ed09c
547
jdk/src/java.desktop/share/native/liblcms/cmsalpha.c
Normal file
547
jdk/src/java.desktop/share/native/liblcms/cmsalpha.c
Normal file
@ -0,0 +1,547 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 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-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"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
|
||||||
|
// Alpha copy ------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Floor to byte, taking care of saturation
|
||||||
|
cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d)
|
||||||
|
{
|
||||||
|
d += 0.5;
|
||||||
|
if (d <= 0) return 0;
|
||||||
|
if (d >= 255.0) return 255;
|
||||||
|
|
||||||
|
return (cmsUInt8Number) _cmsQuickFloorWord(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return the size in bytes of a given formatter
|
||||||
|
static
|
||||||
|
int trueBytesSize(cmsUInt32Number Format)
|
||||||
|
{
|
||||||
|
int fmt_bytes = T_BYTES(Format);
|
||||||
|
|
||||||
|
// For double, the T_BYTES field returns zero
|
||||||
|
if (fmt_bytes == 0)
|
||||||
|
return sizeof(double);
|
||||||
|
|
||||||
|
// Otherwise, it is already correct for all formats
|
||||||
|
return fmt_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Several format converters
|
||||||
|
|
||||||
|
typedef void(*cmsFormatterAlphaFn)(void* dst, const void* src);
|
||||||
|
|
||||||
|
|
||||||
|
// From 8
|
||||||
|
|
||||||
|
static
|
||||||
|
void copy8(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
memmove(dst, src, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void from8to16(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsUInt8Number n = *(cmsUInt8Number*)src;
|
||||||
|
*(cmsUInt16Number*) dst = FROM_8_TO_16(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void from8toFLT(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
*(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void from8toDBL(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
*(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void from8toHLF(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f;
|
||||||
|
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From 16
|
||||||
|
|
||||||
|
static
|
||||||
|
void from16to8(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsUInt16Number n = *(cmsUInt16Number*)src;
|
||||||
|
*(cmsUInt8Number*) dst = FROM_16_TO_8(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void copy16(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
memmove(dst, src, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void from16toFLT(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
*(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void from16toDBL(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
*(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void from16toHLF(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
|
||||||
|
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From Float
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromFLTto8(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = *(cmsFloat32Number*)src;
|
||||||
|
*(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromFLTto16(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = *(cmsFloat32Number*)src;
|
||||||
|
*(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void copy32(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
memmove(dst, src, sizeof(cmsFloat32Number));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromFLTtoDBL(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = *(cmsFloat32Number*)src;
|
||||||
|
*(cmsFloat64Number*)dst = (cmsFloat64Number)n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromFLTtoHLF(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = *(cmsFloat32Number*)src;
|
||||||
|
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// From HALF
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromHLFto8(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||||
|
*(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromHLFto16(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||||
|
*(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromHLFtoFLT(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
*(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromHLFtoDBL(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
*(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src);
|
||||||
|
}
|
||||||
|
|
||||||
|
// From double
|
||||||
|
static
|
||||||
|
void fromDBLto8(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat64Number n = *(cmsFloat64Number*)src;
|
||||||
|
*(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromDBLto16(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat64Number n = *(cmsFloat64Number*)src;
|
||||||
|
*(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromDBLtoFLT(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat64Number n = *(cmsFloat64Number*)src;
|
||||||
|
*(cmsFloat32Number*)dst = (cmsFloat32Number) n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void fromDBLtoHLF(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src;
|
||||||
|
*(cmsUInt16Number*)dst = _cmsFloat2Half(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void copy64(void* dst, const void* src)
|
||||||
|
{
|
||||||
|
memmove(dst, src, sizeof(cmsFloat64Number));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the position (x or y) of the formatter in the table of functions
|
||||||
|
static
|
||||||
|
int FormatterPos(cmsUInt32Number frm)
|
||||||
|
{
|
||||||
|
int b = T_BYTES(frm);
|
||||||
|
|
||||||
|
if (b == 0 && T_FLOAT(frm))
|
||||||
|
return 4; // DBL
|
||||||
|
if (b == 2 && T_FLOAT(frm))
|
||||||
|
return 2; // HLF
|
||||||
|
if (b == 4 && T_FLOAT(frm))
|
||||||
|
return 3; // FLT
|
||||||
|
if (b == 2 && !T_FLOAT(frm))
|
||||||
|
return 1; // 16
|
||||||
|
if (b == 1 && !T_FLOAT(frm))
|
||||||
|
return 0; // 8
|
||||||
|
|
||||||
|
return -1; // not recognized
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtains a alpha-to-alpha funmction formatter
|
||||||
|
static
|
||||||
|
cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out)
|
||||||
|
{
|
||||||
|
static cmsFormatterAlphaFn FormattersAlpha[5][5] = {
|
||||||
|
|
||||||
|
/* from 8 */ { copy8, from8to16, from8toHLF, from8toFLT, from8toDBL },
|
||||||
|
/* from 16*/ { from16to8, copy16, from16toHLF, from16toFLT, from16toDBL },
|
||||||
|
/* from HLF*/ { fromHLFto8, fromHLFto16, copy16, fromHLFtoFLT, fromHLFtoDBL },
|
||||||
|
/* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTtoHLF, copy32, fromFLTtoDBL },
|
||||||
|
/* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLtoHLF, fromDBLtoFLT, copy64 }};
|
||||||
|
|
||||||
|
int in_n = FormatterPos(in);
|
||||||
|
int out_n = FormatterPos(out);
|
||||||
|
|
||||||
|
if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4) {
|
||||||
|
|
||||||
|
cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FormattersAlpha[in_n][out_n];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This function computes the distance from each component to the next one in bytes.
|
||||||
|
static
|
||||||
|
void ComputeIncrementsForChunky(cmsUInt32Number Format,
|
||||||
|
cmsUInt32Number ComponentStartingOrder[],
|
||||||
|
cmsUInt32Number ComponentPointerIncrements[])
|
||||||
|
{
|
||||||
|
cmsUInt32Number channels[cmsMAXCHANNELS];
|
||||||
|
int extra = T_EXTRA(Format);
|
||||||
|
int nchannels = T_CHANNELS(Format);
|
||||||
|
int total_chans = nchannels + extra;
|
||||||
|
int i;
|
||||||
|
int channelSize = trueBytesSize(Format);
|
||||||
|
int pixelSize = channelSize * total_chans;
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(channels, 0, sizeof(channels));
|
||||||
|
|
||||||
|
// Separation is independent of starting point and only depends on channel size
|
||||||
|
for (i = 0; i < extra; i++)
|
||||||
|
ComponentPointerIncrements[i] = pixelSize;
|
||||||
|
|
||||||
|
// Handle do swap
|
||||||
|
for (i = 0; i < total_chans; i++)
|
||||||
|
{
|
||||||
|
if (T_DOSWAP(Format)) {
|
||||||
|
channels[i] = total_chans - i - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
channels[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
|
||||||
|
if (T_SWAPFIRST(Format) && total_chans > 1) {
|
||||||
|
|
||||||
|
cmsUInt32Number tmp = channels[0];
|
||||||
|
for (i = 0; i < total_chans-1; i++)
|
||||||
|
channels[i] = channels[i + 1];
|
||||||
|
|
||||||
|
channels[total_chans - 1] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle size
|
||||||
|
if (channelSize > 1)
|
||||||
|
for (i = 0; i < total_chans; i++) {
|
||||||
|
channels[i] *= channelSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < extra; i++)
|
||||||
|
ComponentStartingOrder[i] = channels[i + nchannels];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// On planar configurations, the distance is the stride added to any non-negative
|
||||||
|
static
|
||||||
|
void ComputeIncrementsForPlanar(cmsUInt32Number Format,
|
||||||
|
cmsUInt32Number BytesPerPlane,
|
||||||
|
cmsUInt32Number ComponentStartingOrder[],
|
||||||
|
cmsUInt32Number ComponentPointerIncrements[])
|
||||||
|
{
|
||||||
|
cmsUInt32Number channels[cmsMAXCHANNELS];
|
||||||
|
int extra = T_EXTRA(Format);
|
||||||
|
int nchannels = T_CHANNELS(Format);
|
||||||
|
int total_chans = nchannels + extra;
|
||||||
|
int i;
|
||||||
|
int channelSize = trueBytesSize(Format);
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset(channels, 0, sizeof(channels));
|
||||||
|
|
||||||
|
// Separation is independent of starting point and only depends on channel size
|
||||||
|
for (i = 0; i < extra; i++)
|
||||||
|
ComponentPointerIncrements[i] = channelSize;
|
||||||
|
|
||||||
|
// Handle do swap
|
||||||
|
for (i = 0; i < total_chans; i++)
|
||||||
|
{
|
||||||
|
if (T_DOSWAP(Format)) {
|
||||||
|
channels[i] = total_chans - i - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
channels[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle swap first (ROL of positions), example CMYK -> KCMY | 0123 -> 3012
|
||||||
|
if (T_SWAPFIRST(Format) && total_chans > 0) {
|
||||||
|
|
||||||
|
cmsUInt32Number tmp = channels[0];
|
||||||
|
for (i = 0; i < total_chans - 1; i++)
|
||||||
|
channels[i] = channels[i + 1];
|
||||||
|
|
||||||
|
channels[total_chans - 1] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle size
|
||||||
|
for (i = 0; i < total_chans; i++) {
|
||||||
|
channels[i] *= BytesPerPlane;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < extra; i++)
|
||||||
|
ComponentStartingOrder[i] = channels[i + nchannels];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Dispatcher por chunky and planar RGB
|
||||||
|
static
|
||||||
|
void ComputeComponentIncrements(cmsUInt32Number Format,
|
||||||
|
cmsUInt32Number BytesPerPlane,
|
||||||
|
cmsUInt32Number ComponentStartingOrder[],
|
||||||
|
cmsUInt32Number ComponentPointerIncrements[])
|
||||||
|
{
|
||||||
|
if (T_PLANAR(Format)) {
|
||||||
|
|
||||||
|
ComputeIncrementsForPlanar(Format, BytesPerPlane, ComponentStartingOrder, ComponentPointerIncrements);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ComputeIncrementsForChunky(Format, ComponentStartingOrder, ComponentPointerIncrements);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Handles extra channels copying alpha if requested by the flags
|
||||||
|
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
|
||||||
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
|
{
|
||||||
|
cmsUInt32Number i, j, k;
|
||||||
|
cmsUInt32Number nExtra;
|
||||||
|
cmsUInt32Number SourceStartingOrder[cmsMAXCHANNELS];
|
||||||
|
cmsUInt32Number SourceIncrements[cmsMAXCHANNELS];
|
||||||
|
cmsUInt32Number DestStartingOrder[cmsMAXCHANNELS];
|
||||||
|
cmsUInt32Number DestIncrements[cmsMAXCHANNELS];
|
||||||
|
|
||||||
|
cmsFormatterAlphaFn copyValueFn;
|
||||||
|
|
||||||
|
// Make sure we need some copy
|
||||||
|
if (!(p->dwOriginalFlags & cmsFLAGS_COPY_ALPHA))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Exit early if in-place color-management is occurring - no need to copy extra channels to themselves.
|
||||||
|
if (p->InputFormat == p->OutputFormat && in == out)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Make sure we have same number of alpha channels. If not, just return as this should be checked at transform creation time.
|
||||||
|
nExtra = T_EXTRA(p->InputFormat);
|
||||||
|
if (nExtra != T_EXTRA(p->OutputFormat))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Anything to do?
|
||||||
|
if (nExtra == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Compute the increments
|
||||||
|
ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
|
||||||
|
ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
|
||||||
|
|
||||||
|
// Check for conversions 8, 16, half, float, dbl
|
||||||
|
copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
|
||||||
|
|
||||||
|
if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
|
||||||
|
|
||||||
|
cmsUInt8Number* SourcePtr;
|
||||||
|
cmsUInt8Number* DestPtr;
|
||||||
|
|
||||||
|
cmsUInt32Number SourceStrideIncrement = 0;
|
||||||
|
cmsUInt32Number DestStrideIncrement = 0;
|
||||||
|
|
||||||
|
// The loop itself
|
||||||
|
for (i = 0; i < LineCount; i++) {
|
||||||
|
|
||||||
|
// Prepare pointers for the loop
|
||||||
|
SourcePtr = (cmsUInt8Number*)in + SourceStartingOrder[0] + SourceStrideIncrement;
|
||||||
|
DestPtr = (cmsUInt8Number*)out + DestStartingOrder[0] + DestStrideIncrement;
|
||||||
|
|
||||||
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
|
|
||||||
|
copyValueFn(DestPtr, SourcePtr);
|
||||||
|
|
||||||
|
SourcePtr += SourceIncrements[0];
|
||||||
|
DestPtr += DestIncrements[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceStrideIncrement += Stride->BytesPerLineIn;
|
||||||
|
DestStrideIncrement += Stride->BytesPerLineOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else { // General case with more than one extra channel
|
||||||
|
|
||||||
|
cmsUInt8Number* SourcePtr[cmsMAXCHANNELS];
|
||||||
|
cmsUInt8Number* DestPtr[cmsMAXCHANNELS];
|
||||||
|
|
||||||
|
cmsUInt32Number SourceStrideIncrements[cmsMAXCHANNELS];
|
||||||
|
cmsUInt32Number DestStrideIncrements[cmsMAXCHANNELS];
|
||||||
|
|
||||||
|
memset(SourceStrideIncrements, 0, sizeof(SourceStrideIncrements));
|
||||||
|
memset(DestStrideIncrements, 0, sizeof(DestStrideIncrements));
|
||||||
|
|
||||||
|
// The loop itself
|
||||||
|
for (i = 0; i < LineCount; i++) {
|
||||||
|
|
||||||
|
// Prepare pointers for the loop
|
||||||
|
for (j = 0; j < nExtra; j++) {
|
||||||
|
|
||||||
|
SourcePtr[j] = (cmsUInt8Number*)in + SourceStartingOrder[j] + SourceStrideIncrements[j];
|
||||||
|
DestPtr[j] = (cmsUInt8Number*)out + DestStartingOrder[j] + DestStrideIncrements[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
|
|
||||||
|
for (k = 0; k < nExtra; k++) {
|
||||||
|
|
||||||
|
copyValueFn(DestPtr[k], SourcePtr[k]);
|
||||||
|
|
||||||
|
SourcePtr[k] += SourceIncrements[k];
|
||||||
|
DestPtr[k] += DestIncrements[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < nExtra; j++) {
|
||||||
|
|
||||||
|
SourceStrideIncrements[j] += Stride->BytesPerLineIn;
|
||||||
|
DestStrideIncrements[j] += Stride->BytesPerLineOut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -625,7 +625,7 @@ void ReadReal(cmsIT8* it8, int inum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parses a float number
|
// Parses a float number
|
||||||
// This can not call directly atof because it uses locale dependant
|
// This can not call directly atof because it uses locale dependent
|
||||||
// parsing, while CCMX files always use . as decimal separator
|
// parsing, while CCMX files always use . as decimal separator
|
||||||
static
|
static
|
||||||
cmsFloat64Number ParseFloatNumber(const char *Buffer)
|
cmsFloat64Number ParseFloatNumber(const char *Buffer)
|
||||||
@ -830,11 +830,11 @@ void InSymbol(cmsIT8* it8)
|
|||||||
|
|
||||||
if (it8 ->sy == SINUM) {
|
if (it8 ->sy == SINUM) {
|
||||||
|
|
||||||
sprintf(it8->id, "%d", it8->inum);
|
snprintf(it8->id, 127, "%d", it8->inum);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
sprintf(it8->id, it8 ->DoubleFormatter, it8->dnum);
|
snprintf(it8->id, 127, it8 ->DoubleFormatter, it8->dnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
k = (int) strlen(it8 ->id);
|
k = (int) strlen(it8 ->id);
|
||||||
@ -1392,7 +1392,7 @@ cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFlo
|
|||||||
cmsIT8* it8 = (cmsIT8*) hIT8;
|
cmsIT8* it8 = (cmsIT8*) hIT8;
|
||||||
char Buffer[1024];
|
char Buffer[1024];
|
||||||
|
|
||||||
sprintf(Buffer, it8->DoubleFormatter, Val);
|
snprintf(Buffer, 1023, it8->DoubleFormatter, Val);
|
||||||
|
|
||||||
return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
|
return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
|
||||||
}
|
}
|
||||||
@ -1402,7 +1402,7 @@ cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUIn
|
|||||||
cmsIT8* it8 = (cmsIT8*) hIT8;
|
cmsIT8* it8 = (cmsIT8*) hIT8;
|
||||||
char Buffer[1024];
|
char Buffer[1024];
|
||||||
|
|
||||||
sprintf(Buffer, "%u", Val);
|
snprintf(Buffer, 1023, "%u", Val);
|
||||||
|
|
||||||
return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
|
return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
|
||||||
}
|
}
|
||||||
@ -1846,7 +1846,7 @@ cmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number*
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------- Higer level parsing
|
// -------------------------------------------------------------- Higher level parsing
|
||||||
|
|
||||||
static
|
static
|
||||||
cmsBool DataFormatSection(cmsIT8* it8)
|
cmsBool DataFormatSection(cmsIT8* it8)
|
||||||
@ -2149,7 +2149,7 @@ cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Init usefull pointers
|
// Init useful pointers
|
||||||
|
|
||||||
static
|
static
|
||||||
void CookPointers(cmsIT8* it8)
|
void CookPointers(cmsIT8* it8)
|
||||||
@ -2546,9 +2546,9 @@ int LocateSample(cmsIT8* it8, const char* cSample)
|
|||||||
|
|
||||||
fld = GetDataFormat(it8, i);
|
fld = GetDataFormat(it8, i);
|
||||||
if (fld != NULL) {
|
if (fld != NULL) {
|
||||||
if (cmsstrcasecmp(fld, cSample) == 0)
|
if (cmsstrcasecmp(fld, cSample) == 0)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -2606,7 +2606,7 @@ cmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFl
|
|||||||
|
|
||||||
_cmsAssert(hIT8 != NULL);
|
_cmsAssert(hIT8 != NULL);
|
||||||
|
|
||||||
sprintf(Buff, it8->DoubleFormatter, Val);
|
snprintf(Buff, 255, it8->DoubleFormatter, Val);
|
||||||
|
|
||||||
return SetData(it8, row, col, Buff);
|
return SetData(it8, row, col, Buff);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -136,7 +136,7 @@ static cmsIntentsList DefaultIntents[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// A pointer to the begining of the list
|
// A pointer to the beginning of the list
|
||||||
_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL };
|
_cmsIntentsPluginChunkType _cmsIntentsPluginChunk = { NULL };
|
||||||
|
|
||||||
// Duplicates the zone of memory used by the plug-in in the new context
|
// Duplicates the zone of memory used by the plug-in in the new context
|
||||||
@ -299,6 +299,7 @@ cmsBool ComputeAbsoluteIntent(cmsFloat64Number AdaptationState,
|
|||||||
cmsMAT3 Scale, m1, m2, m3, m4;
|
cmsMAT3 Scale, m1, m2, m3, m4;
|
||||||
|
|
||||||
// TODO: Follow Marc Mahy's recommendation to check if CHAD is same by using M1*M2 == M2*M1. If so, do nothing.
|
// TODO: Follow Marc Mahy's recommendation to check if CHAD is same by using M1*M2 == M2*M1. If so, do nothing.
|
||||||
|
// TODO: Add support for ArgyllArts tag
|
||||||
|
|
||||||
// Adaptation state
|
// Adaptation state
|
||||||
if (AdaptationState == 1.0) {
|
if (AdaptationState == 1.0) {
|
||||||
@ -917,7 +918,7 @@ int BlackPreservingSampler(register const cmsUInt16Number In[], register cmsUInt
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure to pass thru K (which now is fixed)
|
// Make sure to pass through K (which now is fixed)
|
||||||
Outf[3] = LabK[3];
|
Outf[3] = LabK[3];
|
||||||
|
|
||||||
// Apply TAC if needed
|
// Apply TAC if needed
|
||||||
@ -985,7 +986,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
|
|||||||
memset(&bp, 0, sizeof(bp));
|
memset(&bp, 0, sizeof(bp));
|
||||||
|
|
||||||
// We need the input LUT of the last profile, assuming this one is responsible of
|
// We need the input LUT of the last profile, assuming this one is responsible of
|
||||||
// black generation. This LUT will be seached in inverse order.
|
// black generation. This LUT will be searched in inverse order.
|
||||||
bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
|
bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
|
||||||
if (bp.LabK2cmyk == NULL) goto Cleanup;
|
if (bp.LabK2cmyk == NULL) goto Cleanup;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2015 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -227,7 +227,7 @@ void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, const struct _cmsCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliar to fill memory management functions from plugin (or context 0 defaults)
|
// Auxiliary to fill memory management functions from plugin (or context 0 defaults)
|
||||||
void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
|
void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr)
|
||||||
{
|
{
|
||||||
if (Plugin == NULL) {
|
if (Plugin == NULL) {
|
||||||
@ -459,14 +459,14 @@ void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size
|
|||||||
|
|
||||||
// Error logging ******************************************************************
|
// Error logging ******************************************************************
|
||||||
|
|
||||||
// There is no error handling at all. When a funtion fails, it returns proper value.
|
// There is no error handling at all. When a function fails, it returns proper value.
|
||||||
// For example, all create functions does return NULL on failure. Other return FALSE
|
// For example, all create functions does return NULL on failure. Other return FALSE
|
||||||
// It may be interesting, for the developer, to know why the function is failing.
|
// It may be interesting, for the developer, to know why the function is failing.
|
||||||
// for that reason, lcms2 does offer a logging function. This function does recive
|
// for that reason, lcms2 does offer a logging function. This function does recive
|
||||||
// a ENGLISH string with some clues on what is going wrong. You can show this
|
// a ENGLISH string with some clues on what is going wrong. You can show this
|
||||||
// info to the end user, or just create some sort of log.
|
// info to the end user, or just create some sort of log.
|
||||||
// The logging function should NOT terminate the program, as this obviously can leave
|
// The logging function should NOT terminate the program, as this obviously can leave
|
||||||
// resources. It is the programmer's responsability to check each function return code
|
// resources. It is the programmer's responsibility to check each function return code
|
||||||
// to make sure it didn't fail.
|
// to make sure it didn't fail.
|
||||||
|
|
||||||
// Error messages are limited to MAX_ERROR_MESSAGE_LEN
|
// Error messages are limited to MAX_ERROR_MESSAGE_LEN
|
||||||
|
@ -596,7 +596,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
|
|||||||
return Val;
|
return Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate a segmented funtion for a single value. Return -1 if no valid segment found .
|
// Evaluate a segmented function for a single value. Return -1 if no valid segment found .
|
||||||
// If fn type is 0, perform an interpolation on the table
|
// If fn type is 0, perform an interpolation on the table
|
||||||
static
|
static
|
||||||
cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
|
cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R)
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -56,7 +56,7 @@
|
|||||||
#include "lcms2_internal.h"
|
#include "lcms2_internal.h"
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar: append a Lab identity after the given sequence of profiles
|
// Auxiliary: append a Lab identity after the given sequence of profiles
|
||||||
// and return the transform. Lab profile is closed, rest of profiles are kept open.
|
// and return the transform. Lab profile is closed, rest of profiles are kept open.
|
||||||
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
||||||
cmsUInt32Number nProfiles,
|
cmsUInt32Number nProfiles,
|
||||||
@ -201,7 +201,7 @@ cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
|
// Build the relationship. This effectively limits the maximum accuracy to 16 bits, but
|
||||||
// since this is used on black-preserving LUTs, we are not loosing accuracy in any case
|
// since this is used on black-preserving LUTs, we are not losing accuracy in any case
|
||||||
KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
|
KTone = cmsJoinToneCurve(ContextID, in, out, nPoints);
|
||||||
|
|
||||||
// Get rid of components
|
// Get rid of components
|
||||||
@ -307,7 +307,7 @@ int GamutSampler(register const cmsUInt16Number In[], register cmsUInt16Number O
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
|
// Does compute a gamut LUT going back and forth across pcs -> relativ. colorimetric intent -> pcs
|
||||||
// the dE obtained is then annotated on the LUT. Values truely out of gamut are clipped to dE = 0xFFFE
|
// the dE obtained is then annotated on the LUT. Values truly out of gamut are clipped to dE = 0xFFFE
|
||||||
// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
|
// and values changed are supposed to be handled by any gamut remapping, so, are out of gamut as well.
|
||||||
//
|
//
|
||||||
// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,
|
// **WARNING: This algorithm does assume that gamut remapping algorithms does NOT move in-gamut colors,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -185,7 +185,7 @@ cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int
|
|||||||
int i;
|
int i;
|
||||||
cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
|
cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS];
|
||||||
|
|
||||||
// Fill the auxiliar array
|
// Fill the auxiliary array
|
||||||
for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
|
for (i=0; i < MAX_INPUT_DIMENSIONS; i++)
|
||||||
Samples[i] = nSamples;
|
Samples[i] = nSamples;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -353,7 +353,7 @@ cmsUInt32Number FileRead(cmsIOHANDLER* iohandler, void *Buffer, cmsUInt32Number
|
|||||||
return nReaded;
|
return nReaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Postion file pointer in the file
|
// Position file pointer in the file
|
||||||
static
|
static
|
||||||
cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
|
cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
|
||||||
{
|
{
|
||||||
@ -397,6 +397,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
|||||||
{
|
{
|
||||||
cmsIOHANDLER* iohandler = NULL;
|
cmsIOHANDLER* iohandler = NULL;
|
||||||
FILE* fm = NULL;
|
FILE* fm = NULL;
|
||||||
|
cmsInt32Number fileLen;
|
||||||
|
|
||||||
_cmsAssert(FileName != NULL);
|
_cmsAssert(FileName != NULL);
|
||||||
_cmsAssert(AccessMode != NULL);
|
_cmsAssert(AccessMode != NULL);
|
||||||
@ -413,7 +414,16 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
|||||||
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
|
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(fm);
|
fileLen = cmsfilelength(fm);
|
||||||
|
if (fileLen < 0)
|
||||||
|
{
|
||||||
|
fclose(fm);
|
||||||
|
_cmsFree(ContextID, iohandler);
|
||||||
|
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w':
|
case 'w':
|
||||||
@ -453,6 +463,14 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
|
|||||||
cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream)
|
cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream)
|
||||||
{
|
{
|
||||||
cmsIOHANDLER* iohandler = NULL;
|
cmsIOHANDLER* iohandler = NULL;
|
||||||
|
cmsInt32Number fileSize;
|
||||||
|
|
||||||
|
fileSize = cmsfilelength(Stream);
|
||||||
|
if (fileSize < 0)
|
||||||
|
{
|
||||||
|
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
|
iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
|
||||||
if (iohandler == NULL) return NULL;
|
if (iohandler == NULL) return NULL;
|
||||||
@ -460,7 +478,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* S
|
|||||||
iohandler -> ContextID = ContextID;
|
iohandler -> ContextID = ContextID;
|
||||||
iohandler -> stream = (void*) Stream;
|
iohandler -> stream = (void*) Stream;
|
||||||
iohandler -> UsedSpace = 0;
|
iohandler -> UsedSpace = 0;
|
||||||
iohandler -> ReportedSize = (cmsUInt32Number) cmsfilelength(Stream);
|
iohandler -> ReportedSize = (cmsUInt32Number) fileSize;
|
||||||
iohandler -> PhysicalFile[0] = 0;
|
iohandler -> PhysicalFile[0] = 0;
|
||||||
|
|
||||||
iohandler ->Read = FileRead;
|
iohandler ->Read = FileRead;
|
||||||
@ -652,7 +670,7 @@ cmsBool _cmsNewTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, int* NewPos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check existance
|
// Check existence
|
||||||
cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
||||||
{
|
{
|
||||||
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) (void*) hProfile;
|
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) (void*) hProfile;
|
||||||
@ -708,7 +726,7 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust endianess of the used parameters
|
// Adjust endianness of the used parameters
|
||||||
Icc -> DeviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass);
|
Icc -> DeviceClass = (cmsProfileClassSignature) _cmsAdjustEndianess32(Header.deviceClass);
|
||||||
Icc -> ColorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.colorSpace);
|
Icc -> ColorSpace = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.colorSpace);
|
||||||
Icc -> PCS = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.pcs);
|
Icc -> PCS = (cmsColorSpaceSignature) _cmsAdjustEndianess32(Header.pcs);
|
||||||
@ -826,7 +844,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
|||||||
|
|
||||||
memset(&Header.reserved, 0, sizeof(Header.reserved));
|
memset(&Header.reserved, 0, sizeof(Header.reserved));
|
||||||
|
|
||||||
// Set profile ID. Endianess is always big endian
|
// Set profile ID. Endianness is always big endian
|
||||||
memmove(&Header.profileID, &Icc ->ProfileID, 16);
|
memmove(&Header.profileID, &Icc ->ProfileID, 16);
|
||||||
|
|
||||||
// Dump the header
|
// Dump the header
|
||||||
@ -836,7 +854,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
|||||||
|
|
||||||
// Get true count
|
// Get true count
|
||||||
for (i=0; i < Icc -> TagCount; i++) {
|
for (i=0; i < Icc -> TagCount; i++) {
|
||||||
if (Icc ->TagNames[i] != 0)
|
if (Icc ->TagNames[i] != (cmsTagSignature) 0)
|
||||||
Count++;
|
Count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,7 +863,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
|
|||||||
|
|
||||||
for (i=0; i < Icc -> TagCount; i++) {
|
for (i=0; i < Icc -> TagCount; i++) {
|
||||||
|
|
||||||
if (Icc ->TagNames[i] == 0) continue; // It is just a placeholder
|
if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder
|
||||||
|
|
||||||
Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]);
|
Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]);
|
||||||
Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]);
|
Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]);
|
||||||
@ -1195,7 +1213,7 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig)
|
|||||||
|
|
||||||
for (i=0; i < Icc -> TagCount; i++) {
|
for (i=0; i < Icc -> TagCount; i++) {
|
||||||
|
|
||||||
if (Icc ->TagNames[i] == 0) continue;
|
if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue;
|
||||||
|
|
||||||
// Linked tags are not written
|
// Linked tags are not written
|
||||||
if (Icc ->TagLinked[i] != (cmsTagSignature) 0) continue;
|
if (Icc ->TagLinked[i] != (cmsTagSignature) 0) continue;
|
||||||
@ -1329,11 +1347,15 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
|
|||||||
|
|
||||||
_cmsAssert(hProfile != NULL);
|
_cmsAssert(hProfile != NULL);
|
||||||
|
|
||||||
|
if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return 0;
|
||||||
memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
|
memmove(&Keep, Icc, sizeof(_cmsICCPROFILE));
|
||||||
|
|
||||||
ContextID = cmsGetProfileContextID(hProfile);
|
ContextID = cmsGetProfileContextID(hProfile);
|
||||||
PrevIO = Icc ->IOhandler = cmsOpenIOhandlerFromNULL(ContextID);
|
PrevIO = Icc ->IOhandler = cmsOpenIOhandlerFromNULL(ContextID);
|
||||||
if (PrevIO == NULL) return 0;
|
if (PrevIO == NULL) {
|
||||||
|
_cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Pass #1 does compute offsets
|
// Pass #1 does compute offsets
|
||||||
|
|
||||||
@ -1353,7 +1375,10 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
|
|||||||
}
|
}
|
||||||
|
|
||||||
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
||||||
if (!cmsCloseIOhandler(PrevIO)) return 0;
|
if (!cmsCloseIOhandler(PrevIO))
|
||||||
|
UsedSpace = 0; // As a error marker
|
||||||
|
|
||||||
|
_cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
|
||||||
|
|
||||||
return UsedSpace;
|
return UsedSpace;
|
||||||
|
|
||||||
@ -1361,6 +1386,8 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
|
|||||||
Error:
|
Error:
|
||||||
cmsCloseIOhandler(PrevIO);
|
cmsCloseIOhandler(PrevIO);
|
||||||
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
memmove(Icc, &Keep, sizeof(_cmsICCPROFILE));
|
||||||
|
_cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1564,7 +1591,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
|
|||||||
LocalTypeHandler.ICCVersion = Icc ->Version;
|
LocalTypeHandler.ICCVersion = Icc ->Version;
|
||||||
Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
|
Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
|
||||||
|
|
||||||
// The tag type is supported, but something wrong happend and we cannot read the tag.
|
// The tag type is supported, but something wrong happened and we cannot read the tag.
|
||||||
// let know the user about this (although it is just a warning)
|
// let know the user about this (although it is just a warning)
|
||||||
if (Icc -> TagPtrs[n] == NULL) {
|
if (Icc -> TagPtrs[n] == NULL) {
|
||||||
|
|
||||||
@ -1883,7 +1910,7 @@ cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, cons
|
|||||||
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
|
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
|
||||||
|
|
||||||
if (Icc->TagPtrs[i] == NULL) {
|
if (Icc->TagPtrs[i] == NULL) {
|
||||||
Icc->TagNames[i] = 0;
|
Icc->TagNames[i] = (cmsTagSignature) 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -157,7 +157,7 @@ cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper
|
// Auxiliary, read colorants as a MAT3 structure. Used by any function that needs a matrix-shaper
|
||||||
static
|
static
|
||||||
cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile)
|
cmsBool ReadICCMatrixRGB2XYZ(cmsMAT3* r, cmsHPROFILE hProfile)
|
||||||
{
|
{
|
||||||
@ -343,7 +343,7 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
|||||||
cmsTagSignature tagFloat;
|
cmsTagSignature tagFloat;
|
||||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||||
|
|
||||||
// On named color, take the appropiate tag
|
// On named color, take the appropriate tag
|
||||||
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
|
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
|
||||||
|
|
||||||
cmsPipeline* Lut;
|
cmsPipeline* Lut;
|
||||||
@ -365,9 +365,9 @@ cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
|
|||||||
return Lut;
|
return Lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an attempt to reuse this funtion to retrieve the matrix-shaper as pipeline no
|
// This is an attempt to reuse this function to retrieve the matrix-shaper as pipeline no
|
||||||
// matter other LUT are present and have precedence. Intent = -1 means just this.
|
// matter other LUT are present and have precedence. Intent = -1 means just this.
|
||||||
if (Intent != -1) {
|
if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
|
||||||
|
|
||||||
tag16 = Device2PCS16[Intent];
|
tag16 = Device2PCS16[Intent];
|
||||||
tagFloat = Device2PCSFloat[Intent];
|
tagFloat = Device2PCSFloat[Intent];
|
||||||
@ -423,7 +423,7 @@ Error:
|
|||||||
// Check if this is a grayscale profile.
|
// Check if this is a grayscale profile.
|
||||||
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
||||||
|
|
||||||
// if so, build appropiate conversion tables.
|
// if so, build appropriate conversion tables.
|
||||||
// The tables are the PCS iluminant, scaled across GrayTRC
|
// The tables are the PCS iluminant, scaled across GrayTRC
|
||||||
return BuildGrayInputMatrixPipeline(hProfile);
|
return BuildGrayInputMatrixPipeline(hProfile);
|
||||||
}
|
}
|
||||||
@ -578,7 +578,7 @@ cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFlo
|
|||||||
if (Lut == NULL) return NULL;
|
if (Lut == NULL) return NULL;
|
||||||
|
|
||||||
// If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
|
// If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
|
||||||
// and since the formatter has already accomodated to 0..1.0, we should undo this change
|
// and since the formatter has already accommodated to 0..1.0, we should undo this change
|
||||||
if ( PCS == cmsSigLabData)
|
if ( PCS == cmsSigLabData)
|
||||||
{
|
{
|
||||||
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
|
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID)))
|
||||||
@ -619,7 +619,7 @@ cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
|
|||||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||||
|
|
||||||
|
|
||||||
if (Intent != -1) {
|
if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) {
|
||||||
|
|
||||||
tag16 = PCS2Device16[Intent];
|
tag16 = PCS2Device16[Intent];
|
||||||
tagFloat = PCS2DeviceFloat[Intent];
|
tagFloat = PCS2DeviceFloat[Intent];
|
||||||
@ -680,7 +680,7 @@ Error:
|
|||||||
// Check if this is a grayscale profile.
|
// Check if this is a grayscale profile.
|
||||||
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
if (cmsGetColorSpace(hProfile) == cmsSigGrayData) {
|
||||||
|
|
||||||
// if so, build appropiate conversion tables.
|
// if so, build appropriate conversion tables.
|
||||||
// The tables are the PCS iluminant, scaled across GrayTRC
|
// The tables are the PCS iluminant, scaled across GrayTRC
|
||||||
return BuildGrayOutputPipeline(hProfile);
|
return BuildGrayOutputPipeline(hProfile);
|
||||||
}
|
}
|
||||||
@ -738,15 +738,21 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
|||||||
{
|
{
|
||||||
cmsPipeline* Lut;
|
cmsPipeline* Lut;
|
||||||
cmsTagTypeSignature OriginalType;
|
cmsTagTypeSignature OriginalType;
|
||||||
cmsTagSignature tag16 = Device2PCS16[Intent];
|
cmsTagSignature tag16;
|
||||||
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
|
cmsTagSignature tagFloat;
|
||||||
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
cmsContext ContextID = cmsGetProfileContextID(hProfile);
|
||||||
|
|
||||||
|
|
||||||
// On named color, take the appropiate tag
|
if (Intent < INTENT_PERCEPTUAL || Intent > INTENT_ABSOLUTE_COLORIMETRIC)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
tag16 = Device2PCS16[Intent];
|
||||||
|
tagFloat = Device2PCSFloat[Intent];
|
||||||
|
|
||||||
|
// On named color, take the appropriate tag
|
||||||
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
|
if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
|
||||||
|
|
||||||
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
|
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*)cmsReadTag(hProfile, cmsSigNamedColor2Tag);
|
||||||
|
|
||||||
if (nc == NULL) return NULL;
|
if (nc == NULL) return NULL;
|
||||||
|
|
||||||
@ -762,12 +768,13 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
|
|||||||
goto Error;
|
goto Error;
|
||||||
|
|
||||||
return Lut;
|
return Lut;
|
||||||
Error:
|
Error:
|
||||||
cmsPipelineFree(Lut);
|
cmsPipelineFree(Lut);
|
||||||
cmsFreeNamedColorList(nc);
|
cmsFreeNamedColorList(nc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
|
||||||
|
|
||||||
// Floating point LUT are always V
|
// Floating point LUT are always V
|
||||||
@ -777,19 +784,19 @@ Error:
|
|||||||
tagFloat = Device2PCSFloat[0];
|
tagFloat = Device2PCSFloat[0];
|
||||||
if (cmsIsTag(hProfile, tagFloat)) {
|
if (cmsIsTag(hProfile, tagFloat)) {
|
||||||
|
|
||||||
return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
|
return cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
if (!cmsIsTag(hProfile, tag16)) { // Is there any LUT-Based table?
|
||||||
|
|
||||||
tag16 = Device2PCS16[0];
|
tag16 = Device2PCS16[0];
|
||||||
if (!cmsIsTag(hProfile, tag16)) return NULL;
|
if (!cmsIsTag(hProfile, tag16)) return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check profile version and LUT type. Do the necessary adjustments if needed
|
// Check profile version and LUT type. Do the necessary adjustments if needed
|
||||||
|
|
||||||
// Read the tag
|
// Read the tag
|
||||||
Lut = (cmsPipeline*) cmsReadTag(hProfile, tag16);
|
Lut = (cmsPipeline*)cmsReadTag(hProfile, tag16);
|
||||||
if (Lut == NULL) return NULL;
|
if (Lut == NULL) return NULL;
|
||||||
|
|
||||||
// The profile owns the Lut, so we need to copy it
|
// The profile owns the Lut, so we need to copy it
|
||||||
@ -802,7 +809,7 @@ Error:
|
|||||||
ChangeInterpolationToTrilinear(Lut);
|
ChangeInterpolationToTrilinear(Lut);
|
||||||
|
|
||||||
// After reading it, we have info about the original type
|
// After reading it, we have info about the original type
|
||||||
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
|
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
|
||||||
|
|
||||||
// We need to adjust data for Lab16 on output
|
// We need to adjust data for Lab16 on output
|
||||||
if (OriginalType != cmsSigLut16Type) return Lut;
|
if (OriginalType != cmsSigLut16Type) return Lut;
|
||||||
@ -810,12 +817,12 @@ Error:
|
|||||||
// Here it is possible to get Lab on both sides
|
// Here it is possible to get Lab on both sides
|
||||||
|
|
||||||
if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
|
if (cmsGetColorSpace(hProfile) == cmsSigLabData) {
|
||||||
if(!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
|
if (!cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID)))
|
||||||
goto Error2;
|
goto Error2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
if (cmsGetPCS(hProfile) == cmsSigLabData) {
|
||||||
if(!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
|
if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID)))
|
||||||
goto Error2;
|
goto Error2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,7 +957,7 @@ cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar, read and duplicate a MLU if found.
|
// Auxiliary, read and duplicate a MLU if found.
|
||||||
static
|
static
|
||||||
cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
|
cmsMLU* GetMLUFromProfile(cmsHPROFILE h, cmsTagSignature sig)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -534,7 +534,7 @@ void* CLUTElemDup(cmsStage* mpe)
|
|||||||
goto Error;
|
goto Error;
|
||||||
} else {
|
} else {
|
||||||
NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number));
|
NewElem ->Tab.T = (cmsUInt16Number*) _cmsDupMem(mpe ->ContextID, Data ->Tab.T, Data ->nEntries * sizeof (cmsUInt16Number));
|
||||||
if (NewElem ->Tab.TFloat == NULL)
|
if (NewElem ->Tab.T == NULL)
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1482,7 +1482,8 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut)
|
|||||||
First = FALSE;
|
First = FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Anterior ->Next = NewMPE;
|
if (Anterior != NULL)
|
||||||
|
Anterior ->Next = NewMPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Anterior = NewMPE;
|
Anterior = NewMPE;
|
||||||
@ -1836,3 +1837,5 @@ cmsBool CMSEXPORT cmsPipelineEvalReverseFloat(cmsFloat32Number Target[],
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -67,7 +67,7 @@ void CMSEXPORT _cmsVEC3init(cmsVEC3* r, cmsFloat64Number x, cmsFloat64Number y,
|
|||||||
r -> n[VZ] = z;
|
r -> n[VZ] = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector substraction
|
// Vector subtraction
|
||||||
void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b)
|
void CMSEXPORT _cmsVEC3minus(cmsVEC3* r, const cmsVEC3* a, const cmsVEC3* b)
|
||||||
{
|
{
|
||||||
r -> n[VX] = a -> n[VX] - b -> n[VX];
|
r -> n[VX] = a -> n[VX] - b -> n[VX];
|
||||||
@ -201,3 +201,5 @@ void CMSEXPORT _cmsMAT3eval(cmsVEC3* r, const cmsMAT3* a, const cmsVEC3* v)
|
|||||||
r->n[VY] = a->v[1].n[VX]*v->n[VX] + a->v[1].n[VY]*v->n[VY] + a->v[1].n[VZ]*v->n[VZ];
|
r->n[VY] = a->v[1].n[VX]*v->n[VX] + a->v[1].n[VY]*v->n[VY] + a->v[1].n[VZ]*v->n[VZ];
|
||||||
r->n[VZ] = a->v[2].n[VX]*v->n[VX] + a->v[2].n[VY]*v->n[VY] + a->v[2].n[VZ]*v->n[VZ];
|
r->n[VZ] = a->v[2].n[VX]*v->n[VX] + a->v[2].n[VY]*v->n[VY] + a->v[2].n[VZ]*v->n[VZ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2012 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -121,7 +121,7 @@ cmsBool GrowMLUpool(cmsMLU* mlu)
|
|||||||
static
|
static
|
||||||
cmsBool GrowMLUtable(cmsMLU* mlu)
|
cmsBool GrowMLUtable(cmsMLU* mlu)
|
||||||
{
|
{
|
||||||
int AllocatedEntries;
|
cmsUInt32Number AllocatedEntries;
|
||||||
_cmsMLUentry *NewPtr;
|
_cmsMLUentry *NewPtr;
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
@ -147,7 +147,7 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
|
|||||||
static
|
static
|
||||||
int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
|
int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
|
||||||
{
|
{
|
||||||
int i;
|
cmsUInt32Number i;
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (mlu == NULL) return -1;
|
if (mlu == NULL) return -1;
|
||||||
@ -207,15 +207,42 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert from a 3-char code to a cmsUInt16Number. It is done inthis way because some
|
||||||
|
// compilers don't properly align beginning of strings
|
||||||
|
|
||||||
// Add an ASCII entry.
|
static
|
||||||
|
cmsUInt16Number strTo16(const char str[3])
|
||||||
|
{
|
||||||
|
cmsUInt16Number n = ((cmsUInt16Number) str[0] << 8) | str[1];
|
||||||
|
|
||||||
|
return n; // Always big endian in this case
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void strFrom16(char str[3], cmsUInt16Number n)
|
||||||
|
{
|
||||||
|
// Assiming this would be aligned
|
||||||
|
union {
|
||||||
|
|
||||||
|
cmsUInt16Number n;
|
||||||
|
char str[2];
|
||||||
|
|
||||||
|
} c;
|
||||||
|
|
||||||
|
c.n = n; // Always big endian in this case
|
||||||
|
|
||||||
|
str[0] = c.str[0]; str[1] = c.str[1]; str[2] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
|
||||||
cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
|
cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
|
||||||
{
|
{
|
||||||
cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1;
|
cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
|
||||||
wchar_t* WStr;
|
wchar_t* WStr;
|
||||||
cmsBool rc;
|
cmsBool rc;
|
||||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
cmsUInt16Number Lang = strTo16(LanguageCode);
|
||||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
cmsUInt16Number Cntry = strTo16(CountryCode);
|
||||||
|
|
||||||
if (mlu == NULL) return FALSE;
|
if (mlu == NULL) return FALSE;
|
||||||
|
|
||||||
@ -245,18 +272,17 @@ cmsUInt32Number mywcslen(const wchar_t *s)
|
|||||||
return (cmsUInt32Number)(p - s);
|
return (cmsUInt32Number)(p - s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a wide entry. Do not add any \0 terminator (ICC1v43_2010-12.pdf page 61)
|
||||||
// Add a wide entry
|
|
||||||
cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
|
cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
|
||||||
{
|
{
|
||||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language);
|
cmsUInt16Number Lang = strTo16(Language);
|
||||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country);
|
cmsUInt16Number Cntry = strTo16(Country);
|
||||||
cmsUInt32Number len;
|
cmsUInt32Number len;
|
||||||
|
|
||||||
if (mlu == NULL) return FALSE;
|
if (mlu == NULL) return FALSE;
|
||||||
if (WideString == NULL) return FALSE;
|
if (WideString == NULL) return FALSE;
|
||||||
|
|
||||||
len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t);
|
len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t);
|
||||||
return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
|
return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,8 +353,8 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
|
|||||||
cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
|
cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
|
||||||
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
|
cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
|
||||||
{
|
{
|
||||||
int i;
|
cmsUInt32Number i;
|
||||||
int Best = -1;
|
cmsInt32Number Best = -1;
|
||||||
_cmsMLUentry* v;
|
_cmsMLUentry* v;
|
||||||
|
|
||||||
if (mlu == NULL) return NULL;
|
if (mlu == NULL) return NULL;
|
||||||
@ -379,8 +405,8 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
|
|||||||
cmsUInt32Number StrLen = 0;
|
cmsUInt32Number StrLen = 0;
|
||||||
cmsUInt32Number ASCIIlen, i;
|
cmsUInt32Number ASCIIlen, i;
|
||||||
|
|
||||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
cmsUInt16Number Lang = strTo16(LanguageCode);
|
||||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
cmsUInt16Number Cntry = strTo16(CountryCode);
|
||||||
|
|
||||||
// Sanitize
|
// Sanitize
|
||||||
if (mlu == NULL) return 0;
|
if (mlu == NULL) return 0;
|
||||||
@ -423,8 +449,8 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
|
|||||||
const wchar_t *Wide;
|
const wchar_t *Wide;
|
||||||
cmsUInt32Number StrLen = 0;
|
cmsUInt32Number StrLen = 0;
|
||||||
|
|
||||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
cmsUInt16Number Lang = strTo16(LanguageCode);
|
||||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
cmsUInt16Number Cntry = strTo16(CountryCode);
|
||||||
|
|
||||||
// Sanitize
|
// Sanitize
|
||||||
if (mlu == NULL) return 0;
|
if (mlu == NULL) return 0;
|
||||||
@ -456,8 +482,8 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
|
|||||||
{
|
{
|
||||||
const wchar_t *Wide;
|
const wchar_t *Wide;
|
||||||
|
|
||||||
cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
|
cmsUInt16Number Lang = strTo16(LanguageCode);
|
||||||
cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
|
cmsUInt16Number Cntry = strTo16(CountryCode);
|
||||||
cmsUInt16Number ObtLang, ObtCode;
|
cmsUInt16Number ObtLang, ObtCode;
|
||||||
|
|
||||||
// Sanitize
|
// Sanitize
|
||||||
@ -467,10 +493,9 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
|
|||||||
if (Wide == NULL) return FALSE;
|
if (Wide == NULL) return FALSE;
|
||||||
|
|
||||||
// Get used language and code
|
// Get used language and code
|
||||||
*(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang);
|
strFrom16(ObtainedLanguage, ObtLang);
|
||||||
*(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode);
|
strFrom16(ObtainedCountry, ObtCode);
|
||||||
|
|
||||||
ObtainedLanguage[2] = ObtainedCountry[2] = 0;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,12 +518,12 @@ cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu,
|
|||||||
|
|
||||||
if (mlu == NULL) return FALSE;
|
if (mlu == NULL) return FALSE;
|
||||||
|
|
||||||
if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE;
|
if (idx >= mlu->UsedEntries) return FALSE;
|
||||||
|
|
||||||
entry = &mlu->Entries[idx];
|
entry = &mlu->Entries[idx];
|
||||||
|
|
||||||
*(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language);
|
strFrom16(LanguageCode, entry->Language);
|
||||||
*(cmsUInt16Number *)CountryCode = _cmsAdjustEndianess16(entry->Country);
|
strFrom16(CountryCode, entry->Country);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,10 @@
|
|||||||
// However, the following notice accompanied the original version of this
|
// However, the following notice accompanied the original version of this
|
||||||
// file:
|
// file:
|
||||||
//
|
//
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2011 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -258,11 +257,10 @@ cmsBool _MultiplyMatrix(cmsPipeline* Lut)
|
|||||||
|
|
||||||
// We can not get rid of full matrix
|
// We can not get rid of full matrix
|
||||||
cmsStage* Multmat = cmsStageAllocMatrix(Lut->ContextID, 3, 3, (const cmsFloat64Number*) &res, NULL);
|
cmsStage* Multmat = cmsStageAllocMatrix(Lut->ContextID, 3, 3, (const cmsFloat64Number*) &res, NULL);
|
||||||
|
if (Multmat == NULL) return FALSE; // Should never happen
|
||||||
|
|
||||||
// Recover the chain
|
// Recover the chain
|
||||||
if (Multmat != NULL) {
|
Multmat->Next = chain;
|
||||||
Multmat->Next = chain;
|
|
||||||
}
|
|
||||||
*pt1 = Multmat;
|
*pt1 = Multmat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -560,7 +558,7 @@ cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[],
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliar, to see if two values are equal or very different
|
// Auxiliary, to see if two values are equal or very different
|
||||||
static
|
static
|
||||||
cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
|
cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
|
||||||
{
|
{
|
||||||
@ -568,7 +566,7 @@ cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[]
|
|||||||
|
|
||||||
for (i=0; i < n; i++) {
|
for (i=0; i < n; i++) {
|
||||||
|
|
||||||
if (abs(White1[i] - White2[i]) > 0xf000) return TRUE; // Values are so extremly different that the fixup should be avoided
|
if (abs(White1[i] - White2[i]) > 0xf000) return TRUE; // Values are so extremely different that the fixup should be avoided
|
||||||
if (White1[i] != White2[i]) return FALSE;
|
if (White1[i] != White2[i]) return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -706,7 +704,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
|||||||
cmsStage* PreLin = cmsPipelineGetPtrToFirstStage(Src);
|
cmsStage* PreLin = cmsPipelineGetPtrToFirstStage(Src);
|
||||||
|
|
||||||
// Check if suitable
|
// Check if suitable
|
||||||
if (PreLin ->Type == cmsSigCurveSetElemType) {
|
if (PreLin && PreLin ->Type == cmsSigCurveSetElemType) {
|
||||||
|
|
||||||
// Maybe this is a linear tram, so we can avoid the whole stuff
|
// Maybe this is a linear tram, so we can avoid the whole stuff
|
||||||
if (!AllCurvesAreLinear(PreLin)) {
|
if (!AllCurvesAreLinear(PreLin)) {
|
||||||
@ -739,7 +737,7 @@ cmsBool OptimizeByResampling(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt3
|
|||||||
cmsStage* PostLin = cmsPipelineGetPtrToLastStage(Src);
|
cmsStage* PostLin = cmsPipelineGetPtrToLastStage(Src);
|
||||||
|
|
||||||
// Check if suitable
|
// Check if suitable
|
||||||
if (cmsStageType(PostLin) == cmsSigCurveSetElemType) {
|
if (PostLin && cmsStageType(PostLin) == cmsSigCurveSetElemType) {
|
||||||
|
|
||||||
// Maybe this is a linear tram, so we can avoid the whole stuff
|
// Maybe this is a linear tram, so we can avoid the whole stuff
|
||||||
if (!AllCurvesAreLinear(PostLin)) {
|
if (!AllCurvesAreLinear(PostLin)) {
|
||||||
@ -1041,8 +1039,8 @@ cmsBool IsDegenerated(const cmsToneCurve* g)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Zeros == 1 && Poles == 1) return FALSE; // For linear tables
|
if (Zeros == 1 && Poles == 1) return FALSE; // For linear tables
|
||||||
if (Zeros > (nEntries / 4)) return TRUE; // Degenerated, mostly zeros
|
if (Zeros > (nEntries / 20)) return TRUE; // Degenerated, many zeros
|
||||||
if (Poles > (nEntries / 4)) return TRUE; // Degenerated, mostly poles
|
if (Poles > (nEntries / 20)) return TRUE; // Degenerated, many poles
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -1064,17 +1062,19 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
|
|||||||
cmsColorSpaceSignature ColorSpace, OutputColorSpace;
|
cmsColorSpaceSignature ColorSpace, OutputColorSpace;
|
||||||
cmsStage* OptimizedPrelinMpe;
|
cmsStage* OptimizedPrelinMpe;
|
||||||
cmsStage* mpe;
|
cmsStage* mpe;
|
||||||
cmsToneCurve** OptimizedPrelinCurves;
|
cmsToneCurve** OptimizedPrelinCurves;
|
||||||
_cmsStageCLutData* OptimizedPrelinCLUT;
|
_cmsStageCLutData* OptimizedPrelinCLUT;
|
||||||
|
|
||||||
|
|
||||||
// This is a loosy optimization! does not apply in floating-point cases
|
// This is a loosy optimization! does not apply in floating-point cases
|
||||||
if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE;
|
if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE;
|
||||||
|
|
||||||
// Only on RGB
|
// Only on chunky RGB
|
||||||
if (T_COLORSPACE(*InputFormat) != PT_RGB) return FALSE;
|
if (T_COLORSPACE(*InputFormat) != PT_RGB) return FALSE;
|
||||||
if (T_COLORSPACE(*OutputFormat) != PT_RGB) return FALSE;
|
if (T_PLANAR(*InputFormat)) return FALSE;
|
||||||
|
|
||||||
|
if (T_COLORSPACE(*OutputFormat) != PT_RGB) return FALSE;
|
||||||
|
if (T_PLANAR(*OutputFormat)) return FALSE;
|
||||||
|
|
||||||
// On 16 bits, user has to specify the feature
|
// On 16 bits, user has to specify the feature
|
||||||
if (!_cmsFormatterIs8bit(*InputFormat)) {
|
if (!_cmsFormatterIs8bit(*InputFormat)) {
|
||||||
@ -1098,6 +1098,22 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
|
|||||||
memset(Trans, 0, sizeof(Trans));
|
memset(Trans, 0, sizeof(Trans));
|
||||||
memset(TransReverse, 0, sizeof(TransReverse));
|
memset(TransReverse, 0, sizeof(TransReverse));
|
||||||
|
|
||||||
|
// If the last stage of the original lut are curves, and those curves are
|
||||||
|
// degenerated, it is likely the transform is squeezing and clipping
|
||||||
|
// the output from previous CLUT. We cannot optimize this case
|
||||||
|
{
|
||||||
|
cmsStage* last = cmsPipelineGetPtrToLastStage(OriginalLut);
|
||||||
|
|
||||||
|
if (cmsStageType(last) == cmsSigCurveSetElemType) {
|
||||||
|
|
||||||
|
_cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*)cmsStageData(last);
|
||||||
|
for (i = 0; i < Data->nCurves; i++) {
|
||||||
|
if (IsDegenerated(Data->TheCurves[i]))
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (t = 0; t < OriginalLut ->InputChannels; t++) {
|
for (t = 0; t < OriginalLut ->InputChannels; t++) {
|
||||||
Trans[t] = cmsBuildTabulatedToneCurve16(OriginalLut ->ContextID, PRELINEARIZATION_POINTS, NULL);
|
Trans[t] = cmsBuildTabulatedToneCurve16(OriginalLut ->ContextID, PRELINEARIZATION_POINTS, NULL);
|
||||||
if (Trans[t] == NULL) goto Error;
|
if (Trans[t] == NULL) goto Error;
|
||||||
@ -1431,7 +1447,10 @@ cmsBool OptimizeByJoiningCurves(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUI
|
|||||||
GammaTables[i] = NULL;
|
GammaTables[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GammaTables != NULL) _cmsFree(Src ->ContextID, GammaTables);
|
if (GammaTables != NULL) {
|
||||||
|
_cmsFree(Src->ContextID, GammaTables);
|
||||||
|
GammaTables = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Maybe the curves are linear at the end
|
// Maybe the curves are linear at the end
|
||||||
if (!AllCurvesAreLinear(ObtainedCurves)) {
|
if (!AllCurvesAreLinear(ObtainedCurves)) {
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -110,7 +110,7 @@ typedef struct {
|
|||||||
#define ANYFLAVOR FLAVOR_SH(1)
|
#define ANYFLAVOR FLAVOR_SH(1)
|
||||||
|
|
||||||
|
|
||||||
// Supress waning about info never being used
|
// Suppress waning about info never being used
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable : 4100)
|
#pragma warning(disable : 4100)
|
||||||
@ -3188,6 +3188,8 @@ cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Numbe
|
|||||||
cmsUInt32Number i;
|
cmsUInt32Number i;
|
||||||
cmsFormatter fr;
|
cmsFormatter fr;
|
||||||
|
|
||||||
|
// Optimization is only a hint
|
||||||
|
dwInput &= ~OPTIMIZED_SH(1);
|
||||||
|
|
||||||
switch (dwFlags)
|
switch (dwFlags)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -337,7 +337,7 @@ void CMSEXPORT cmsFloat2LabEncoded(cmsUInt16Number wLab[3], const cmsCIELab* fLa
|
|||||||
wLab[2] = ab2Fix4(Lab.b);
|
wLab[2] = ab2Fix4(Lab.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliar: convert to Radians
|
// Auxiliary: convert to Radians
|
||||||
static
|
static
|
||||||
cmsFloat64Number RADIANS(cmsFloat64Number deg)
|
cmsFloat64Number RADIANS(cmsFloat64Number deg)
|
||||||
{
|
{
|
||||||
@ -345,7 +345,7 @@ cmsFloat64Number RADIANS(cmsFloat64Number deg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar: atan2 but operating in degrees and returning 0 if a==b==0
|
// Auxiliary: atan2 but operating in degrees and returning 0 if a==b==0
|
||||||
static
|
static
|
||||||
cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
|
cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
|
||||||
{
|
{
|
||||||
@ -368,7 +368,7 @@ cmsFloat64Number atan2deg(cmsFloat64Number a, cmsFloat64Number b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar: Square
|
// Auxiliary: Square
|
||||||
static
|
static
|
||||||
cmsFloat64Number Sqr(cmsFloat64Number v)
|
cmsFloat64Number Sqr(cmsFloat64Number v)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2010 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -136,7 +136,7 @@ void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number*
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliar -- read 8, 16 and 32-bit numbers
|
// Auxiliary -- read 8, 16 and 32-bit numbers
|
||||||
cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
|
cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
|
||||||
{
|
{
|
||||||
cmsUInt8Number tmp;
|
cmsUInt8Number tmp;
|
||||||
@ -201,13 +201,13 @@ cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
|
|||||||
|
|
||||||
_cmsAssert(io != NULL);
|
_cmsAssert(io != NULL);
|
||||||
|
|
||||||
if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
|
if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (n != NULL) {
|
if (n != NULL) {
|
||||||
|
|
||||||
tmp = _cmsAdjustEndianess32(tmp);
|
tmp = _cmsAdjustEndianess32(tmp);
|
||||||
*n = *(cmsFloat32Number*) &tmp;
|
*n = *(cmsFloat32Number*) (void*) &tmp;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -244,22 +244,6 @@ cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
|
cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
|
||||||
{
|
{
|
||||||
cmsEncodedXYZNumber xyz;
|
cmsEncodedXYZNumber xyz;
|
||||||
@ -273,8 +257,6 @@ cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
|
|||||||
XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
|
XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
|
||||||
XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
|
XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
|
||||||
XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
|
XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
|
||||||
|
|
||||||
NormalizeXYZ(XYZ);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -336,7 +318,7 @@ cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
|
|||||||
|
|
||||||
_cmsAssert(io != NULL);
|
_cmsAssert(io != NULL);
|
||||||
|
|
||||||
tmp = *(cmsUInt32Number*) &n;
|
tmp = *(cmsUInt32Number*) (void*) &n;
|
||||||
tmp = _cmsAdjustEndianess32(tmp);
|
tmp = _cmsAdjustEndianess32(tmp);
|
||||||
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -532,7 +514,10 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
|
|||||||
va_start(args, frm);
|
va_start(args, frm);
|
||||||
|
|
||||||
len = vsnprintf((char*) Buffer, 2047, frm, args);
|
len = vsnprintf((char*) Buffer, 2047, frm, args);
|
||||||
if (len < 0) return FALSE; // Truncated, which is a fatal error for us
|
if (len < 0) {
|
||||||
|
va_end(args);
|
||||||
|
return FALSE; // Truncated, which is a fatal error for us
|
||||||
|
}
|
||||||
|
|
||||||
rc = io ->Write(io, len, Buffer);
|
rc = io ->Write(io, len, Buffer);
|
||||||
|
|
||||||
@ -554,6 +539,7 @@ void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
|
|||||||
if (ContextID == NULL) {
|
if (ContextID == NULL) {
|
||||||
|
|
||||||
ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
|
ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
|
||||||
|
if (ctx->MemPool == NULL) return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
|
cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
|
||||||
@ -989,3 +975,5 @@ void* CMSEXPORT cmsGetContextUserData(cmsContext ContextID)
|
|||||||
{
|
{
|
||||||
return _cmsContextGetClientChunk(ContextID, UserPtr);
|
return _cmsContextGetClientChunk(ContextID, UserPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2011 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -608,7 +608,7 @@ void EmitNGamma(cmsIOHANDLER* m, int n, cmsToneCurve* g[])
|
|||||||
//
|
//
|
||||||
// Each row contains Pipeline values for all but first component. So, I
|
// Each row contains Pipeline values for all but first component. So, I
|
||||||
// detect row changing by keeping a copy of last value of first
|
// detect row changing by keeping a copy of last value of first
|
||||||
// component. -1 is used to mark begining of whole block.
|
// component. -1 is used to mark beginning of whole block.
|
||||||
|
|
||||||
static
|
static
|
||||||
int OutputValueSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
|
int OutputValueSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
|
||||||
@ -1422,14 +1422,15 @@ void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[])
|
|||||||
if (nColorant > cmsMAXCHANNELS)
|
if (nColorant > cmsMAXCHANNELS)
|
||||||
nColorant = cmsMAXCHANNELS;
|
nColorant = cmsMAXCHANNELS;
|
||||||
|
|
||||||
for (j=0; j < nColorant; j++) {
|
for (j = 0; j < nColorant; j++) {
|
||||||
|
|
||||||
sprintf(Buff, "%.3f", Out[j] / 65535.0);
|
snprintf(Buff, 31, "%.3f", Out[j] / 65535.0);
|
||||||
strcat(Colorant, Buff);
|
Buff[31] = 0;
|
||||||
if (j < nColorant -1)
|
strcat(Colorant, Buff);
|
||||||
strcat(Colorant, " ");
|
if (j < nColorant - 1)
|
||||||
|
strcat(Colorant, " ");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2011 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -247,7 +247,8 @@ cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2
|
|||||||
{
|
{
|
||||||
cmsFloat64Number a, b, c, d, e, D;
|
cmsFloat64Number a, b, c, d, e, D;
|
||||||
cmsFloat64Number sc, sN, sD;
|
cmsFloat64Number sc, sN, sD;
|
||||||
cmsFloat64Number tc, tN, tD;
|
//cmsFloat64Number tc; // left for future use
|
||||||
|
cmsFloat64Number tN, tD;
|
||||||
cmsVEC3 w0;
|
cmsVEC3 w0;
|
||||||
|
|
||||||
_cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
|
_cmsVEC3minus(&w0, &line1 ->a, &line2 ->a);
|
||||||
@ -315,7 +316,7 @@ cmsBool ClosestLineToLine(cmsVEC3* r, const cmsLine* line1, const cmsLine* line2
|
|||||||
}
|
}
|
||||||
// finally do the division to get sc and tc
|
// finally do the division to get sc and tc
|
||||||
sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
|
sc = (fabs(sN) < MATRIX_DET_TOLERANCE ? 0.0 : sN / sD);
|
||||||
tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD);
|
//tc = (fabs(tN) < MATRIX_DET_TOLERANCE ? 0.0 : tN / tD); // left for future use.
|
||||||
|
|
||||||
GetPointOfLine(r, line1, sc);
|
GetPointOfLine(r, line1, sc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -346,7 +347,7 @@ void CMSEXPORT cmsGBDFree(cmsHANDLE hGBD)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar to retrieve a pointer to the segmentr containing the Lab value
|
// Auxiliary to retrieve a pointer to the segmentr containing the Lab value
|
||||||
static
|
static
|
||||||
cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
||||||
{
|
{
|
||||||
@ -358,7 +359,7 @@ cmsGDBPoint* GetPoint(cmsGDB* gbd, const cmsCIELab* Lab, cmsSpherical* sp)
|
|||||||
_cmsAssert(Lab != NULL);
|
_cmsAssert(Lab != NULL);
|
||||||
_cmsAssert(sp != NULL);
|
_cmsAssert(sp != NULL);
|
||||||
|
|
||||||
// Center L* by substracting half of its domain, that's 50
|
// Center L* by subtracting half of its domain, that's 50
|
||||||
_cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
|
_cmsVEC3init(&v, Lab ->L - 50.0, Lab ->a, Lab ->b);
|
||||||
|
|
||||||
// Convert to spherical coordinates
|
// Convert to spherical coordinates
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -59,7 +59,7 @@
|
|||||||
// This file implements every single tag and tag type as described in the ICC spec. Some types
|
// This file implements every single tag and tag type as described in the ICC spec. Some types
|
||||||
// have been deprecated, like ncl and Data. There is no implementation for those types as there
|
// have been deprecated, like ncl and Data. There is no implementation for those types as there
|
||||||
// are no profiles holding them. The programmer can also extend this list by defining his own types
|
// are no profiles holding them. The programmer can also extend this list by defining his own types
|
||||||
// by using the appropiate plug-in. There are three types of plug ins regarding that. First type
|
// by using the appropriate plug-in. There are three types of plug ins regarding that. First type
|
||||||
// allows to define new tags using any existing type. Next plug-in type allows to define new types
|
// allows to define new tags using any existing type. Next plug-in type allows to define new types
|
||||||
// and the third one is very specific: allows to extend the number of elements in the multiprocessing
|
// and the third one is very specific: allows to extend the number of elements in the multiprocessing
|
||||||
// elements special type.
|
// elements special type.
|
||||||
@ -142,7 +142,7 @@ cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* Pl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar to convert UTF-32 to UTF-16 in some cases
|
// Auxiliary to convert UTF-32 to UTF-16 in some cases
|
||||||
static
|
static
|
||||||
cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
|
cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
|
||||||
{
|
{
|
||||||
@ -158,7 +158,7 @@ cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t*
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliar to read an array of wchar_t
|
// Auxiliary to read an array of wchar_t
|
||||||
static
|
static
|
||||||
cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
|
cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
|
||||||
{
|
{
|
||||||
@ -189,7 +189,7 @@ typedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self,
|
|||||||
cmsUInt32Number n,
|
cmsUInt32Number n,
|
||||||
cmsUInt32Number SizeOfTag);
|
cmsUInt32Number SizeOfTag);
|
||||||
|
|
||||||
// Helper function to deal with position tables as decribed in ICC spec 4.3
|
// Helper function to deal with position tables as described in ICC spec 4.3
|
||||||
// A table of n elements is readed, where first comes n records containing offsets and sizes and
|
// A table of n elements is readed, where first comes n records containing offsets and sizes and
|
||||||
// then a block containing the data itself. This allows to reuse same data in more than one entry
|
// then a block containing the data itself. This allows to reuse same data in more than one entry
|
||||||
static
|
static
|
||||||
@ -980,7 +980,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
|
|||||||
cmsMLU* mlu = (cmsMLU*) Ptr;
|
cmsMLU* mlu = (cmsMLU*) Ptr;
|
||||||
char *Text = NULL;
|
char *Text = NULL;
|
||||||
wchar_t *Wide = NULL;
|
wchar_t *Wide = NULL;
|
||||||
cmsUInt32Number len, len_aligned, len_filler_alignment;
|
cmsUInt32Number len, len_text, len_tag_requirement, len_aligned;
|
||||||
cmsBool rc = FALSE;
|
cmsBool rc = FALSE;
|
||||||
char Filler[68];
|
char Filler[68];
|
||||||
|
|
||||||
@ -990,17 +990,18 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
|
|||||||
// Get the len of string
|
// Get the len of string
|
||||||
len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
|
len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
|
||||||
|
|
||||||
// From ICC3.4: It has been found that textDescriptionType can contain misaligned data
|
// Specification ICC.1:2001-04 (v2.4.0): It has been found that textDescriptionType can contain misaligned data
|
||||||
//(see clause 4.1 for the definition of “aligned”). Because the Unicode language
|
//(see clause 4.1 for the definition of “aligned”). Because the Unicode language
|
||||||
// code and Unicode count immediately follow the ASCII description, their
|
// code and Unicode count immediately follow the ASCII description, their
|
||||||
// alignment is not correct if the ASCII count is not a multiple of four. The
|
// alignment is not correct if the ASCII count is not a multiple of four. The
|
||||||
// ScriptCode code is misaligned when the ASCII count is odd. Profile reading and
|
// ScriptCode code is misaligned when the ASCII count is odd. Profile reading and
|
||||||
// writing software must be written carefully in order to handle these alignment
|
// writing software must be written carefully in order to handle these alignment
|
||||||
// problems.
|
// problems.
|
||||||
|
//
|
||||||
// Compute an aligned size
|
// The above last sentence suggest to handle alignment issues in the
|
||||||
len_aligned = _cmsALIGNLONG(len);
|
// parser. The provided example (Table 69 on Page 60) makes this clear.
|
||||||
len_filler_alignment = len_aligned - len;
|
// The padding only in the ASCII count is not sufficient for a aligned tag
|
||||||
|
// size, with the same text size in ASCII and Unicode.
|
||||||
|
|
||||||
// Null strings
|
// Null strings
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
@ -1021,6 +1022,12 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
|
|||||||
cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t));
|
cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tell the real text len including the null terminator and padding
|
||||||
|
len_text = (cmsUInt32Number) strlen(Text) + 1;
|
||||||
|
// Compute an total tag size requirement
|
||||||
|
len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67);
|
||||||
|
len_aligned = _cmsALIGNLONG(len_tag_requirement);
|
||||||
|
|
||||||
// * cmsUInt32Number count; * Description length
|
// * cmsUInt32Number count; * Description length
|
||||||
// * cmsInt8Number desc[count] * NULL terminated ascii string
|
// * cmsInt8Number desc[count] * NULL terminated ascii string
|
||||||
// * cmsUInt32Number ucLangCode; * UniCode language code
|
// * cmsUInt32Number ucLangCode; * UniCode language code
|
||||||
@ -1030,20 +1037,14 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
|
|||||||
// * cmsUInt8Number scCount; * ScriptCode count
|
// * cmsUInt8Number scCount; * ScriptCode count
|
||||||
// * cmsInt8Number scDesc[67]; * ScriptCode Description
|
// * cmsInt8Number scDesc[67]; * ScriptCode Description
|
||||||
|
|
||||||
if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error;
|
if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
|
||||||
if (!io ->Write(io, len, Text)) goto Error;
|
if (!io ->Write(io, len_text, Text)) goto Error;
|
||||||
if (!io ->Write(io, len_filler_alignment, Filler)) goto Error;
|
|
||||||
|
|
||||||
if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode
|
if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode
|
||||||
|
|
||||||
// This part is tricky: we need an aligned tag size, and the ScriptCode part
|
if (!_cmsWriteUInt32Number(io, len_text)) goto Error;
|
||||||
// takes 70 bytes, so we need 2 extra bytes to do the alignment
|
|
||||||
|
|
||||||
if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error;
|
|
||||||
|
|
||||||
// Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t)
|
// Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t)
|
||||||
if (!_cmsWriteWCharArray(io, len, Wide)) goto Error;
|
if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error;
|
||||||
if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error;
|
|
||||||
|
|
||||||
// ScriptCode Code & count (unused)
|
// ScriptCode Code & count (unused)
|
||||||
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
|
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
|
||||||
@ -1051,6 +1052,10 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO
|
|||||||
|
|
||||||
if (!io ->Write(io, 67, Filler)) goto Error;
|
if (!io ->Write(io, 67, Filler)) goto Error;
|
||||||
|
|
||||||
|
// possibly add pad at the end of tag
|
||||||
|
if(len_aligned - len_tag_requirement > 0)
|
||||||
|
if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error;
|
||||||
|
|
||||||
rc = TRUE;
|
rc = TRUE;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
@ -1498,7 +1503,7 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU
|
|||||||
LargestPosition = EndOfThisString;
|
LargestPosition = EndOfThisString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now read the remaining of tag and fill all strings. Substract the directory
|
// Now read the remaining of tag and fill all strings. Subtract the directory
|
||||||
SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
|
SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
|
||||||
if (SizeOfTag == 0)
|
if (SizeOfTag == 0)
|
||||||
{
|
{
|
||||||
@ -1532,7 +1537,7 @@ cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
|
|||||||
cmsMLU* mlu =(cmsMLU*) Ptr;
|
cmsMLU* mlu =(cmsMLU*) Ptr;
|
||||||
cmsUInt32Number HeaderSize;
|
cmsUInt32Number HeaderSize;
|
||||||
cmsUInt32Number Len, Offset;
|
cmsUInt32Number Len, Offset;
|
||||||
int i;
|
cmsUInt32Number i;
|
||||||
|
|
||||||
if (Ptr == NULL) {
|
if (Ptr == NULL) {
|
||||||
|
|
||||||
@ -3133,6 +3138,8 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i
|
|||||||
|
|
||||||
memset(Colorant, 0, sizeof(Colorant));
|
memset(Colorant, 0, sizeof(Colorant));
|
||||||
if (io -> Read(io, Root, 32, 1) != 1) return NULL;
|
if (io -> Read(io, Root, 32, 1) != 1) return NULL;
|
||||||
|
Root[32] = 0; // To prevent exploits
|
||||||
|
|
||||||
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
|
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
|
||||||
if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error;
|
if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error;
|
||||||
|
|
||||||
@ -3155,8 +3162,8 @@ static
|
|||||||
cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||||
{
|
{
|
||||||
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
|
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
|
||||||
char prefix[32]; // Prefix for each color name
|
char prefix[33]; // Prefix for each color name
|
||||||
char suffix[32]; // Suffix for each color name
|
char suffix[33]; // Suffix for each color name
|
||||||
int i, nColors;
|
int i, nColors;
|
||||||
|
|
||||||
nColors = cmsNamedColorCount(NamedColorList);
|
nColors = cmsNamedColorCount(NamedColorList);
|
||||||
@ -3168,7 +3175,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
|
|||||||
strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
|
strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
|
||||||
strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
|
strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
|
||||||
|
|
||||||
suffix[31] = prefix[31] = 0;
|
suffix[32] = prefix[32] = 0;
|
||||||
|
|
||||||
if (!io ->Write(io, 32, prefix)) return FALSE;
|
if (!io ->Write(io, 32, prefix)) return FALSE;
|
||||||
if (!io ->Write(io, 32, suffix)) return FALSE;
|
if (!io ->Write(io, 32, suffix)) return FALSE;
|
||||||
@ -3180,6 +3187,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER
|
|||||||
char Root[33];
|
char Root[33];
|
||||||
|
|
||||||
if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
|
if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
|
||||||
|
Root[32] = 0;
|
||||||
if (!io ->Write(io, 32 , Root)) return FALSE;
|
if (!io ->Write(io, 32 , Root)) return FALSE;
|
||||||
if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE;
|
if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE;
|
||||||
if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE;
|
if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE;
|
||||||
@ -3630,7 +3638,7 @@ country varies for each element:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Auxiliar, read an string specified as count + string
|
// Auxiliary, read an string specified as count + string
|
||||||
static
|
static
|
||||||
cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
|
cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
|
||||||
{
|
{
|
||||||
@ -3879,7 +3887,7 @@ cmsBool Type_ViewingConditions_Write(struct _cms_typehandler_struct* self, cmsIO
|
|||||||
static
|
static
|
||||||
void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
|
void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
|
||||||
{
|
{
|
||||||
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening));
|
return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions));
|
||||||
|
|
||||||
cmsUNUSED_PARAMETER(n);
|
cmsUNUSED_PARAMETER(n);
|
||||||
}
|
}
|
||||||
@ -4333,13 +4341,13 @@ Error:
|
|||||||
static
|
static
|
||||||
cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
|
||||||
{
|
{
|
||||||
cmsUInt8Number Dimensions8[16];
|
cmsUInt8Number Dimensions8[16]; // 16 because the spec says 16 and not max number of channels
|
||||||
cmsUInt32Number i;
|
cmsUInt32Number i;
|
||||||
cmsStage* mpe = (cmsStage*) Ptr;
|
cmsStage* mpe = (cmsStage*) Ptr;
|
||||||
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data;
|
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data;
|
||||||
|
|
||||||
// Check for maximum number of channels
|
// Check for maximum number of channels supported by lcms
|
||||||
if (mpe -> InputChannels > 15) return FALSE;
|
if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE;
|
||||||
|
|
||||||
// Only floats are supported in MPE
|
// Only floats are supported in MPE
|
||||||
if (clut ->HasFloatValues == FALSE) return FALSE;
|
if (clut ->HasFloatValues == FALSE) return FALSE;
|
||||||
@ -5477,8 +5485,9 @@ static _cmsTagLinkedList SupportedTags[] = {
|
|||||||
{ cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]},
|
{ cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]},
|
||||||
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
|
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
|
||||||
{ cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
|
{ cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
|
||||||
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
|
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
|
||||||
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL}
|
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]},
|
||||||
|
{ cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -1167,15 +1167,20 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
|
|||||||
// If no way, then force CLUT that for sure can be written
|
// If no way, then force CLUT that for sure can be written
|
||||||
if (AllowedLUT == NULL) {
|
if (AllowedLUT == NULL) {
|
||||||
|
|
||||||
|
cmsStage* FirstStage;
|
||||||
|
cmsStage* LastStage;
|
||||||
|
|
||||||
dwFlags |= cmsFLAGS_FORCE_CLUT;
|
dwFlags |= cmsFLAGS_FORCE_CLUT;
|
||||||
_cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
|
_cmsOptimizePipeline(ContextID, &LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
|
||||||
|
|
||||||
// Put identity curves if needed
|
// Put identity curves if needed
|
||||||
if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
|
FirstStage = cmsPipelineGetPtrToFirstStage(LUT);
|
||||||
|
if (FirstStage != NULL && FirstStage ->Type != cmsSigCurveSetElemType)
|
||||||
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)))
|
if (!cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn)))
|
||||||
goto Error;
|
goto Error;
|
||||||
|
|
||||||
if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType)
|
LastStage = cmsPipelineGetPtrToLastStage(LUT);
|
||||||
|
if (LastStage != NULL && LastStage ->Type != cmsSigCurveSetElemType)
|
||||||
if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut)))
|
if (!cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut)))
|
||||||
goto Error;
|
goto Error;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -376,3 +376,5 @@ cmsBool CMSEXPORT cmsAdaptToIlluminant(cmsCIEXYZ* Result,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -208,12 +208,18 @@ void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
|
|||||||
|
|
||||||
{
|
{
|
||||||
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
|
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
|
||||||
|
cmsStride stride;
|
||||||
|
|
||||||
p -> xform(p, InputBuffer, OutputBuffer, Size, Size);
|
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,
|
void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
|
||||||
const void* InputBuffer,
|
const void* InputBuffer,
|
||||||
void* OutputBuffer,
|
void* OutputBuffer,
|
||||||
@ -221,10 +227,40 @@ void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
|
|||||||
|
|
||||||
{
|
{
|
||||||
_cmsTRANSFORM* p = (_cmsTRANSFORM*) 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 ----------------------------------------------------------------------------------------------------------
|
// Transform routines ----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -233,49 +269,64 @@ void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
|
|||||||
static
|
static
|
||||||
void FloatXFORM(_cmsTRANSFORM* p,
|
void FloatXFORM(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
{
|
{
|
||||||
cmsUInt8Number* accum;
|
cmsUInt8Number* accum;
|
||||||
cmsUInt8Number* output;
|
cmsUInt8Number* output;
|
||||||
cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
|
cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS];
|
||||||
cmsFloat32Number OutOfGamut;
|
cmsFloat32Number OutOfGamut;
|
||||||
cmsUInt32Number i, j;
|
cmsUInt32Number i, j, c, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
|
|
||||||
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?
|
accum = (cmsUInt8Number*)in + strideIn;
|
||||||
if (p ->GamutCheck != NULL) {
|
output = (cmsUInt8Number*)out + strideOut;
|
||||||
|
|
||||||
// Evaluate gamut marker.
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
cmsPipelineEvalFloat( fIn, &OutOfGamut, p ->GamutCheck);
|
|
||||||
|
|
||||||
// Is current color out of gamut?
|
accum = p->FromInputFloat(p, fIn, accum, Stride->BytesPerPlaneIn);
|
||||||
if (OutOfGamut > 0.0) {
|
|
||||||
|
|
||||||
// Certainly, out of gamut
|
// Any gamut chack to do?
|
||||||
for (j=0; j < cmsMAXCHANNELS; j++)
|
if (p->GamutCheck != NULL) {
|
||||||
fOut[j] = -1.0;
|
|
||||||
|
|
||||||
|
// 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 {
|
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
|
strideIn += Stride->BytesPerLineIn;
|
||||||
output = p -> ToOutputFloat(p, fOut, output, Stride);
|
strideOut += Stride->BytesPerLineOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,22 +334,34 @@ static
|
|||||||
void NullFloatXFORM(_cmsTRANSFORM* p,
|
void NullFloatXFORM(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out,
|
void* out,
|
||||||
cmsUInt32Number Size,
|
cmsUInt32Number PixelsPerLine,
|
||||||
cmsUInt32Number Stride)
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
|
|
||||||
{
|
{
|
||||||
cmsUInt8Number* accum;
|
cmsUInt8Number* accum;
|
||||||
cmsUInt8Number* output;
|
cmsUInt8Number* output;
|
||||||
cmsFloat32Number fIn[cmsMAXCHANNELS];
|
cmsFloat32Number fIn[cmsMAXCHANNELS];
|
||||||
cmsUInt32Number i, n;
|
cmsUInt32Number i, j, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
n = Size;
|
|
||||||
|
|
||||||
for (i=0; i < n; i++) {
|
strideIn = 0;
|
||||||
|
strideOut = 0;
|
||||||
|
|
||||||
accum = p -> FromInputFloat(p, fIn, accum, Stride);
|
for (i = 0; i < LineCount; i++) {
|
||||||
output = p -> ToOutputFloat(p, fIn, output, Stride);
|
|
||||||
|
accum = (cmsUInt8Number*) in + strideIn;
|
||||||
|
output = (cmsUInt8Number*) out + strideOut;
|
||||||
|
|
||||||
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
|
|
||||||
|
accum = p->FromInputFloat(p, fIn, accum, Stride ->BytesPerPlaneIn);
|
||||||
|
output = p->ToOutputFloat(p, fIn, output, Stride->BytesPerPlaneOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
strideIn += Stride->BytesPerLineIn;
|
||||||
|
strideOut += Stride->BytesPerLineOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,23 +371,36 @@ void NullFloatXFORM(_cmsTRANSFORM* p,
|
|||||||
static
|
static
|
||||||
void NullXFORM(_cmsTRANSFORM* p,
|
void NullXFORM(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out, cmsUInt32Number Size,
|
void* out,
|
||||||
cmsUInt32Number Stride)
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
{
|
{
|
||||||
cmsUInt8Number* accum;
|
cmsUInt8Number* accum;
|
||||||
cmsUInt8Number* output;
|
cmsUInt8Number* output;
|
||||||
cmsUInt16Number wIn[cmsMAXCHANNELS];
|
cmsUInt16Number wIn[cmsMAXCHANNELS];
|
||||||
cmsUInt32Number i, n;
|
cmsUInt32Number i, j, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
n = Size; // Buffer len
|
|
||||||
|
|
||||||
for (i=0; i < n; i++) {
|
strideIn = 0;
|
||||||
|
strideOut = 0;
|
||||||
|
|
||||||
accum = p -> FromInput(p, wIn, accum, Stride);
|
for (i = 0; i < LineCount; i++) {
|
||||||
output = p -> ToOutput(p, wIn, output, Stride);
|
|
||||||
|
accum = (cmsUInt8Number*)in + strideIn;
|
||||||
|
output = (cmsUInt8Number*)out + strideOut;
|
||||||
|
|
||||||
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
|
|
||||||
|
accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
|
||||||
|
output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strideIn += Stride->BytesPerLineIn;
|
||||||
|
strideOut += Stride->BytesPerLineOut;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -332,27 +408,41 @@ void NullXFORM(_cmsTRANSFORM* p,
|
|||||||
static
|
static
|
||||||
void PrecalculatedXFORM(_cmsTRANSFORM* p,
|
void PrecalculatedXFORM(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
{
|
{
|
||||||
register cmsUInt8Number* accum;
|
register cmsUInt8Number* accum;
|
||||||
register cmsUInt8Number* output;
|
register cmsUInt8Number* output;
|
||||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||||
cmsUInt32Number i, n;
|
cmsUInt32Number i, j, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
n = Size;
|
|
||||||
|
|
||||||
for (i=0; i < n; i++) {
|
strideIn = 0;
|
||||||
|
strideOut = 0;
|
||||||
|
|
||||||
accum = p -> FromInput(p, wIn, accum, Stride);
|
for (i = 0; i < LineCount; i++) {
|
||||||
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
|
|
||||||
output = p -> ToOutput(p, wOut, output, Stride);
|
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
|
static
|
||||||
void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
|
void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
|
||||||
const cmsUInt16Number wIn[],
|
const cmsUInt16Number wIn[],
|
||||||
@ -379,22 +469,35 @@ void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
|
|||||||
static
|
static
|
||||||
void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
|
void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
{
|
{
|
||||||
cmsUInt8Number* accum;
|
cmsUInt8Number* accum;
|
||||||
cmsUInt8Number* output;
|
cmsUInt8Number* output;
|
||||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||||
cmsUInt32Number i, n;
|
cmsUInt32Number i, j, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
n = Size; // Buffer len
|
|
||||||
|
|
||||||
for (i=0; i < n; i++) {
|
strideIn = 0;
|
||||||
|
strideOut = 0;
|
||||||
|
|
||||||
accum = p -> FromInput(p, wIn, accum, Stride);
|
for (i = 0; i < LineCount; i++) {
|
||||||
TransformOnePixelWithGamutCheck(p, wIn, wOut);
|
|
||||||
output = p -> ToOutput(p, wOut, output, Stride);
|
accum = (cmsUInt8Number*)in + strideIn;
|
||||||
|
output = (cmsUInt8Number*)out + strideOut;
|
||||||
|
|
||||||
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,94 +506,120 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
|
|||||||
static
|
static
|
||||||
void CachedXFORM(_cmsTRANSFORM* p,
|
void CachedXFORM(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
{
|
{
|
||||||
cmsUInt8Number* accum;
|
cmsUInt8Number* accum;
|
||||||
cmsUInt8Number* output;
|
cmsUInt8Number* output;
|
||||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||||
cmsUInt32Number i, n;
|
|
||||||
_cmsCACHE Cache;
|
_cmsCACHE Cache;
|
||||||
|
cmsUInt32Number i, j, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
n = Size; // Buffer len
|
|
||||||
|
|
||||||
// Empty buffers for quick memcmp
|
// Empty buffers for quick memcmp
|
||||||
memset(wIn, 0, sizeof(wIn));
|
memset(wIn, 0, sizeof(wIn));
|
||||||
memset(wOut, 0, sizeof(wOut));
|
memset(wOut, 0, sizeof(wOut));
|
||||||
|
|
||||||
// Get copy of zero cache
|
// 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));
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
|
accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
|
||||||
|
|
||||||
memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
|
if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
|
||||||
memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
|
|
||||||
|
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
|
// All those nice features together
|
||||||
static
|
static
|
||||||
void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
|
void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
|
||||||
const void* in,
|
const void* in,
|
||||||
void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride)
|
||||||
{
|
{
|
||||||
cmsUInt8Number* accum;
|
cmsUInt8Number* accum;
|
||||||
cmsUInt8Number* output;
|
cmsUInt8Number* output;
|
||||||
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
|
||||||
cmsUInt32Number i, n;
|
_cmsCACHE Cache;
|
||||||
_cmsCACHE Cache;
|
cmsUInt32Number i, j, strideIn, strideOut;
|
||||||
|
|
||||||
accum = (cmsUInt8Number*) in;
|
_cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride);
|
||||||
output = (cmsUInt8Number*) out;
|
|
||||||
n = Size; // Buffer len
|
|
||||||
|
|
||||||
// Empty buffers for quick memcmp
|
// Empty buffers for quick memcmp
|
||||||
memset(wIn, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
memset(wIn, 0, sizeof(wIn));
|
||||||
memset(wOut, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
|
memset(wOut, 0, sizeof(wOut));
|
||||||
|
|
||||||
// Get copy of zero cache
|
// 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++) {
|
||||||
|
|
||||||
|
accum = (cmsUInt8Number*)in + strideIn;
|
||||||
|
output = (cmsUInt8Number*)out + strideOut;
|
||||||
|
|
||||||
|
for (j = 0; j < PixelsPerLine; j++) {
|
||||||
|
|
||||||
|
accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn);
|
||||||
|
|
||||||
if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
|
if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
|
||||||
memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
|
|
||||||
|
memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TransformOnePixelWithGamutCheck(p, wIn, wOut);
|
TransformOnePixelWithGamutCheck(p, wIn, wOut);
|
||||||
memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
|
|
||||||
memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
|
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
|
// List of used-defined transform factories
|
||||||
typedef struct _cmsTransformCollection_st {
|
typedef struct _cmsTransformCollection_st {
|
||||||
|
|
||||||
_cmsTransformFactory Factory;
|
_cmsTransform2Factory Factory;
|
||||||
|
cmsBool OldXform; // Factory returns xform function in the old style
|
||||||
|
|
||||||
struct _cmsTransformCollection_st *Next;
|
struct _cmsTransformCollection_st *Next;
|
||||||
|
|
||||||
} _cmsTransformCollection;
|
} _cmsTransformCollection;
|
||||||
@ -533,6 +662,7 @@ void DupPluginTransformList(struct _cmsContext_struct* ctx,
|
|||||||
ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
|
ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocates memory for transform plugin factory
|
||||||
void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
|
void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
|
||||||
const struct _cmsContext_struct* src)
|
const struct _cmsContext_struct* src)
|
||||||
{
|
{
|
||||||
@ -547,6 +677,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
|
// Register new ways to transform
|
||||||
@ -564,14 +723,22 @@ cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Factory callback is required
|
// Factory callback is required
|
||||||
if (Plugin ->Factory == NULL) return FALSE;
|
if (Plugin->factories.xform == NULL) return FALSE;
|
||||||
|
|
||||||
|
|
||||||
fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
|
fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection));
|
||||||
if (fl == NULL) return FALSE;
|
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
|
// Copy the parameters
|
||||||
fl ->Factory = Plugin ->Factory;
|
fl->Factory = Plugin->factories.xform;
|
||||||
|
|
||||||
// Keep linked list
|
// Keep linked list
|
||||||
fl ->Next = ctx->TransformCollection;
|
fl ->Next = ctx->TransformCollection;
|
||||||
@ -656,6 +823,12 @@ _cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
|
|||||||
p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
|
p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
|
||||||
p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, 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;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -816,6 +989,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
|
static
|
||||||
void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
|
void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
|
||||||
{
|
{
|
||||||
@ -828,6 +1017,8 @@ void SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src)
|
|||||||
wtPt ->X = src->X;
|
wtPt ->X = src->X;
|
||||||
wtPt ->Y = src->Y;
|
wtPt ->Y = src->Y;
|
||||||
wtPt ->Z = src->Z;
|
wtPt ->Z = src->Z;
|
||||||
|
|
||||||
|
NormalizeXYZ(wtPt);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1138,7 +1329,6 @@ cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
|
|||||||
cmsUInt32Number InputFormat,
|
cmsUInt32Number InputFormat,
|
||||||
cmsUInt32Number OutputFormat)
|
cmsUInt32Number OutputFormat)
|
||||||
{
|
{
|
||||||
|
|
||||||
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
_cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
|
||||||
cmsFormatter16 FromInput, ToOutput;
|
cmsFormatter16 FromInput, ToOutput;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -52,7 +52,7 @@
|
|||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Version 2.7
|
// Version 2.8
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _lcms2_H
|
#ifndef _lcms2_H
|
||||||
@ -104,7 +104,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Version/release
|
// Version/release
|
||||||
#define LCMS_VERSION 2070
|
#define LCMS_VERSION 2080
|
||||||
|
|
||||||
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
|
||||||
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
|
||||||
@ -202,43 +202,44 @@ typedef int cmsBool;
|
|||||||
# define CMS_IS_WINDOWS_ 1
|
# define CMS_IS_WINDOWS_ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try to detect big endian platforms. This list can be endless, so only some checks are performed over here.
|
// Try to detect big endian platforms. This list can be endless, so primarily rely on the configure script
|
||||||
// you can pass this toggle to the compiler by using -DCMS_USE_BIG_ENDIAN or something similar
|
// on Unix-like systems, and allow it to be set on the compiler command line using
|
||||||
|
// -DCMS_USE_BIG_ENDIAN or something similar
|
||||||
|
#ifdef CMS_USE_BIG_ENDIAN // set at compiler command line takes overall precedence
|
||||||
|
|
||||||
#if defined(__sgi__) || defined(__sgi) || defined(sparc)
|
# if CMS_USE_BIG_ENDIAN == 0
|
||||||
# define CMS_USE_BIG_ENDIAN 1
|
# undef CMS_USE_BIG_ENDIAN
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#if defined(__s390__) || defined(__s390x__)
|
#else // CMS_USE_BIG_ENDIAN
|
||||||
# define CMS_USE_BIG_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
# ifdef WORDS_BIGENDIAN // set by configure (or explicitly on compiler command line)
|
||||||
|
# define CMS_USE_BIG_ENDIAN 1
|
||||||
|
# else // WORDS_BIGENDIAN
|
||||||
|
// Fall back to platform/compiler specific tests
|
||||||
|
# if defined(__sgi__) || defined(__sgi) || defined(sparc)
|
||||||
|
# define CMS_USE_BIG_ENDIAN 1
|
||||||
|
# endif
|
||||||
|
|
||||||
#if defined(__powerpc__) || defined(__ppc__) || defined(TARGET_CPU_PPC)
|
# if defined(__s390__) || defined(__s390x__)
|
||||||
# if __powerpc__ || __ppc__ || TARGET_CPU_PPC
|
# define CMS_USE_BIG_ENDIAN 1
|
||||||
# define CMS_USE_BIG_ENDIAN 1
|
# endif
|
||||||
# if defined (__GNUC__) && defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
|
|
||||||
# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
|
||||||
// Don't use big endian for PowerPC little endian mode
|
|
||||||
# undef CMS_USE_BIG_ENDIAN
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef macintosh
|
# ifdef macintosh
|
||||||
# ifdef __BIG_ENDIAN__
|
# ifdef __BIG_ENDIAN__
|
||||||
# define CMS_USE_BIG_ENDIAN 1
|
# define CMS_USE_BIG_ENDIAN 1
|
||||||
# endif
|
# endif
|
||||||
# ifdef __LITTLE_ENDIAN__
|
# ifdef __LITTLE_ENDIAN__
|
||||||
# undef CMS_USE_BIG_ENDIAN
|
# undef CMS_USE_BIG_ENDIAN
|
||||||
# endif
|
# endif
|
||||||
#endif
|
# endif
|
||||||
|
# endif // WORDS_BIGENDIAN
|
||||||
|
|
||||||
// WORDS_BIGENDIAN takes precedence
|
# if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
|
||||||
#if defined(_HOST_BIG_ENDIAN) || defined(__BIG_ENDIAN__) || defined(WORDS_BIGENDIAN)
|
# define CMS_USE_BIG_ENDIAN 1
|
||||||
# define CMS_USE_BIG_ENDIAN 1
|
# endif
|
||||||
#endif
|
|
||||||
|
#endif // CMS_USE_BIG_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
// Calling convention -- this is hardly platform and compiler dependent
|
// Calling convention -- this is hardly platform and compiler dependent
|
||||||
@ -248,7 +249,7 @@ typedef int cmsBool;
|
|||||||
# define CMSEXPORT __stdcall _export
|
# define CMSEXPORT __stdcall _export
|
||||||
# define CMSAPI
|
# define CMSAPI
|
||||||
# else
|
# else
|
||||||
# define CMSEXPORT _stdcall
|
# define CMSEXPORT __stdcall
|
||||||
# ifdef CMS_DLL_BUILD
|
# ifdef CMS_DLL_BUILD
|
||||||
# define CMSAPI __declspec(dllexport)
|
# define CMSAPI __declspec(dllexport)
|
||||||
# else
|
# else
|
||||||
@ -410,7 +411,8 @@ typedef enum {
|
|||||||
cmsSigViewingCondDescTag = 0x76756564, // 'vued'
|
cmsSigViewingCondDescTag = 0x76756564, // 'vued'
|
||||||
cmsSigViewingConditionsTag = 0x76696577, // 'view'
|
cmsSigViewingConditionsTag = 0x76696577, // 'view'
|
||||||
cmsSigVcgtTag = 0x76636774, // 'vcgt'
|
cmsSigVcgtTag = 0x76636774, // 'vcgt'
|
||||||
cmsSigMetaTag = 0x6D657461 // 'meta'
|
cmsSigMetaTag = 0x6D657461, // 'meta'
|
||||||
|
cmsSigArgyllArtsTag = 0x61727473 // 'arts'
|
||||||
|
|
||||||
} cmsTagSignature;
|
} cmsTagSignature;
|
||||||
|
|
||||||
@ -683,7 +685,7 @@ typedef void* cmsHTRANSFORM;
|
|||||||
// T: Pixeltype
|
// T: Pixeltype
|
||||||
// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
|
// F: Flavor 0=MinIsBlack(Chocolate) 1=MinIsWhite(Vanilla)
|
||||||
// P: Planar? 0=Chunky, 1=Planar
|
// P: Planar? 0=Chunky, 1=Planar
|
||||||
// X: swap 16 bps endianess?
|
// X: swap 16 bps endianness?
|
||||||
// S: Do swap? ie, BGR, KYMC
|
// S: Do swap? ie, BGR, KYMC
|
||||||
// E: Extra samples
|
// E: Extra samples
|
||||||
// C: Channels (Samples per pixel)
|
// C: Channels (Samples per pixel)
|
||||||
@ -926,7 +928,7 @@ typedef void* cmsHTRANSFORM;
|
|||||||
#define TYPE_ARGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1))
|
#define TYPE_ARGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1))
|
||||||
#define TYPE_BGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
|
#define TYPE_BGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
|
||||||
#define TYPE_BGRA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
#define TYPE_BGRA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
|
||||||
#define TYPE_ABGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
|
#define TYPE_ABGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
|
||||||
|
|
||||||
#define TYPE_CMYK_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4))
|
#define TYPE_CMYK_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4))
|
||||||
|
|
||||||
@ -1043,7 +1045,7 @@ CMSAPI long int CMSEXPORT cmsfilelength(FILE* f);
|
|||||||
// Context handling --------------------------------------------------------------------------------------------------------
|
// Context handling --------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
|
// Each context holds its owns globals and its own plug-ins. There is a global context with the id = 0 for lecacy compatibility
|
||||||
// though using the global context is not recomended. Proper context handling makes lcms more thread-safe.
|
// though using the global context is not recommended. Proper context handling makes lcms more thread-safe.
|
||||||
|
|
||||||
typedef struct _cmsContext_struct* cmsContext;
|
typedef struct _cmsContext_struct* cmsContext;
|
||||||
|
|
||||||
@ -1412,7 +1414,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
cmsUInt32Number n;
|
cmsUInt32Number n;
|
||||||
cmsContext ContextID;
|
cmsContext ContextID;
|
||||||
cmsPSEQDESC* seq;
|
cmsPSEQDESC* seq;
|
||||||
|
|
||||||
} cmsSEQ;
|
} cmsSEQ;
|
||||||
@ -1679,6 +1681,8 @@ CMSAPI cmsUInt32Number CMSEXPORT cmsGetSupportedIntentsTHR(cmsContext ContextID
|
|||||||
// Specific to unbounded mode
|
// Specific to unbounded mode
|
||||||
#define cmsFLAGS_NONEGATIVES 0x8000 // Prevent negative numbers in floating point transforms
|
#define cmsFLAGS_NONEGATIVES 0x8000 // Prevent negative numbers in floating point transforms
|
||||||
|
|
||||||
|
// Copy alpha channels when transforming
|
||||||
|
#define cmsFLAGS_COPY_ALPHA 0x04000000 // Alpha channels are copied on cmsDoTransform()
|
||||||
|
|
||||||
// Fine-tune control over number of gridpoints
|
// Fine-tune control over number of gridpoints
|
||||||
#define cmsFLAGS_GRIDPOINTS(n) (((n) & 0xFF) << 16)
|
#define cmsFLAGS_GRIDPOINTS(n) (((n) & 0xFF) << 16)
|
||||||
@ -1757,12 +1761,22 @@ CMSAPI void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
|
|||||||
void * OutputBuffer,
|
void * OutputBuffer,
|
||||||
cmsUInt32Number Size);
|
cmsUInt32Number Size);
|
||||||
|
|
||||||
CMSAPI void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
|
CMSAPI void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform, // Deprecated
|
||||||
const void * InputBuffer,
|
const void * InputBuffer,
|
||||||
void * OutputBuffer,
|
void * OutputBuffer,
|
||||||
cmsUInt32Number Size,
|
cmsUInt32Number Size,
|
||||||
cmsUInt32Number Stride);
|
cmsUInt32Number Stride);
|
||||||
|
|
||||||
|
CMSAPI void CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM Transform,
|
||||||
|
const void* InputBuffer,
|
||||||
|
void* OutputBuffer,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
cmsUInt32Number BytesPerLineIn,
|
||||||
|
cmsUInt32Number BytesPerLineOut,
|
||||||
|
cmsUInt32Number BytesPerPlaneIn,
|
||||||
|
cmsUInt32Number BytesPerPlaneOut);
|
||||||
|
|
||||||
|
|
||||||
CMSAPI void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
CMSAPI void CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
||||||
CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// 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
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -86,7 +86,15 @@
|
|||||||
#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
|
#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
|
||||||
|
|
||||||
// Alignment to memory pointer
|
// Alignment to memory pointer
|
||||||
#define _cmsALIGNMEM(x) (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
|
|
||||||
|
// (Ultra)SPARC with gcc requires ptr alignment of 8 bytes
|
||||||
|
// even though sizeof(void *) is only four: for greatest flexibility
|
||||||
|
// allow the build to specify ptr alignment.
|
||||||
|
#ifndef CMS_PTR_ALIGNMENT
|
||||||
|
# define CMS_PTR_ALIGNMENT sizeof(void *)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
|
||||||
|
|
||||||
// Maximum encodeable values in floating point
|
// Maximum encodeable values in floating point
|
||||||
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
|
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
|
||||||
@ -122,7 +130,7 @@
|
|||||||
|
|
||||||
// A fast way to convert from/to 16 <-> 8 bits
|
// A fast way to convert from/to 16 <-> 8 bits
|
||||||
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
|
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
|
||||||
#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
|
#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
|
||||||
|
|
||||||
// Code analysis is broken on asserts
|
// Code analysis is broken on asserts
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -691,8 +699,8 @@ struct _cms_MLU_struct {
|
|||||||
cmsContext ContextID;
|
cmsContext ContextID;
|
||||||
|
|
||||||
// The directory
|
// The directory
|
||||||
int AllocatedEntries;
|
cmsUInt32Number AllocatedEntries;
|
||||||
int UsedEntries;
|
cmsUInt32Number UsedEntries;
|
||||||
_cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
|
_cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
|
||||||
|
|
||||||
// The Pool
|
// The Pool
|
||||||
@ -760,7 +768,7 @@ typedef struct _cms_iccprofile_struct {
|
|||||||
// Dictionary
|
// Dictionary
|
||||||
cmsUInt32Number TagCount;
|
cmsUInt32Number TagCount;
|
||||||
cmsTagSignature TagNames[MAX_TABLE_TAG];
|
cmsTagSignature TagNames[MAX_TABLE_TAG];
|
||||||
cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none)
|
cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none)
|
||||||
cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
|
cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
|
||||||
cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
|
cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
|
||||||
cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
|
cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
|
||||||
@ -988,7 +996,7 @@ typedef struct _cmstransform_struct {
|
|||||||
cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
|
cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
|
||||||
|
|
||||||
// Points to transform code
|
// Points to transform code
|
||||||
_cmsTransformFn xform;
|
_cmsTransform2Fn xform;
|
||||||
|
|
||||||
// Formatters, cannot be embedded into LUT because cache
|
// Formatters, cannot be embedded into LUT because cache
|
||||||
cmsFormatter16 FromInput;
|
cmsFormatter16 FromInput;
|
||||||
@ -1034,9 +1042,20 @@ typedef struct _cmstransform_struct {
|
|||||||
void* UserData;
|
void* UserData;
|
||||||
_cmsFreeUserDataFn FreeUserData;
|
_cmsFreeUserDataFn FreeUserData;
|
||||||
|
|
||||||
|
// A way to provide backwards compatibility with full xform plugins
|
||||||
|
_cmsTransformFn OldXform;
|
||||||
|
|
||||||
} _cmsTRANSFORM;
|
} _cmsTRANSFORM;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
// Copies extra channels from input to output if the original flags in the transform structure
|
||||||
|
// instructs to do so. This function is called on all standard transform functions.
|
||||||
|
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
|
||||||
|
void* out,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
||||||
cmsUInt32Number nProfiles,
|
cmsUInt32Number nProfiles,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Little Color Management System
|
// Little Color Management System
|
||||||
// Copyright (c) 1998-2011 Marti Maria Saguer
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
// a copy of this software and associated documentation files (the "Software"),
|
// a copy of this software and associated documentation files (the "Software"),
|
||||||
@ -157,7 +157,7 @@ struct _cms_io_handler {
|
|||||||
const void* Buffer);
|
const void* Buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Endianess adjust functions
|
// Endianness adjust functions
|
||||||
CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word);
|
CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word);
|
||||||
CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value);
|
CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value);
|
||||||
CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord);
|
CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord);
|
||||||
@ -371,8 +371,8 @@ struct _cmstransform_struct;
|
|||||||
|
|
||||||
typedef cmsUInt8Number* (* cmsFormatter16)(register struct _cmstransform_struct* CMMcargo,
|
typedef cmsUInt8Number* (* cmsFormatter16)(register struct _cmstransform_struct* CMMcargo,
|
||||||
register cmsUInt16Number Values[],
|
register cmsUInt16Number Values[],
|
||||||
register cmsUInt8Number* Buffer,
|
register cmsUInt8Number* Buffer,
|
||||||
register cmsUInt32Number Stride);
|
register cmsUInt32Number Stride);
|
||||||
|
|
||||||
typedef cmsUInt8Number* (* cmsFormatterFloat)(struct _cmstransform_struct* CMMcargo,
|
typedef cmsUInt8Number* (* cmsFormatterFloat)(struct _cmstransform_struct* CMMcargo,
|
||||||
cmsFloat32Number Values[],
|
cmsFloat32Number Values[],
|
||||||
@ -600,11 +600,28 @@ typedef struct {
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------
|
||||||
// Full xform
|
// Full xform
|
||||||
typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo,
|
|
||||||
|
typedef struct {
|
||||||
|
cmsUInt32Number BytesPerLineIn;
|
||||||
|
cmsUInt32Number BytesPerLineOut;
|
||||||
|
cmsUInt32Number BytesPerPlaneIn;
|
||||||
|
cmsUInt32Number BytesPerPlaneOut;
|
||||||
|
|
||||||
|
} cmsStride;
|
||||||
|
|
||||||
|
typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo, // Legacy function, handles just ONE scanline.
|
||||||
const void* InputBuffer,
|
const void* InputBuffer,
|
||||||
void* OutputBuffer,
|
void* OutputBuffer,
|
||||||
cmsUInt32Number Size,
|
cmsUInt32Number Size,
|
||||||
cmsUInt32Number Stride);
|
cmsUInt32Number Stride); // Stride in bytes to the next plana in planar formats
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*_cmsTransform2Fn)(struct _cmstransform_struct *CMMcargo,
|
||||||
|
const void* InputBuffer,
|
||||||
|
void* OutputBuffer,
|
||||||
|
cmsUInt32Number PixelsPerLine,
|
||||||
|
cmsUInt32Number LineCount,
|
||||||
|
const cmsStride* Stride);
|
||||||
|
|
||||||
typedef cmsBool (* _cmsTransformFactory)(_cmsTransformFn* xform,
|
typedef cmsBool (* _cmsTransformFactory)(_cmsTransformFn* xform,
|
||||||
void** UserData,
|
void** UserData,
|
||||||
@ -614,6 +631,14 @@ typedef cmsBool (* _cmsTransformFactory)(_cmsTransformFn* xform,
|
|||||||
cmsUInt32Number* OutputFormat,
|
cmsUInt32Number* OutputFormat,
|
||||||
cmsUInt32Number* dwFlags);
|
cmsUInt32Number* dwFlags);
|
||||||
|
|
||||||
|
typedef cmsBool (* _cmsTransform2Factory)(_cmsTransform2Fn* xform,
|
||||||
|
void** UserData,
|
||||||
|
_cmsFreeUserDataFn* FreePrivateDataFn,
|
||||||
|
cmsPipeline** Lut,
|
||||||
|
cmsUInt32Number* InputFormat,
|
||||||
|
cmsUInt32Number* OutputFormat,
|
||||||
|
cmsUInt32Number* dwFlags);
|
||||||
|
|
||||||
|
|
||||||
// Retrieve user data as specified by the factory
|
// Retrieve user data as specified by the factory
|
||||||
CMSAPI void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn);
|
CMSAPI void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn);
|
||||||
@ -628,7 +653,10 @@ typedef struct {
|
|||||||
cmsPluginBase base;
|
cmsPluginBase base;
|
||||||
|
|
||||||
// Transform entry point
|
// Transform entry point
|
||||||
_cmsTransformFactory Factory;
|
union {
|
||||||
|
_cmsTransformFactory legacy_xform;
|
||||||
|
_cmsTransform2Factory xform;
|
||||||
|
} factories;
|
||||||
|
|
||||||
} cmsPluginTransform;
|
} cmsPluginTransform;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user