blob: 955687c69f51880a850f86277979af7effcad7de [file] [log] [blame] [edit]
//---------------------------------------------------------------------------------
//
// Little Color Management System
// Copyright (c) 1998-2022 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"
// This module handles all formats supported by lcms. There are two flavors, 16 bits and
// floating point. Floating point is supported only in a subset, those formats holding
// cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component
// as special case)
// ---------------------------------------------------------------------------
// This macro return words stored as big endian
#define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
// These macros handles reversing (negative)
#define REVERSE_FLAVOR_8(x) ((cmsUInt8Number) (0xff-(x)))
#define REVERSE_FLAVOR_16(x) ((cmsUInt16Number)(0xffff-(x)))
// * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x)
{
int a = (x << 8 | x) >> 8; // * 257 / 256
if ( a > 0xffff) return 0xffff;
return (cmsUInt16Number) a;
}
// * 0xf00 / 0xffff = * 256 / 257
cmsINLINE cmsUInt16Number FomLabV4ToLabV2(cmsUInt16Number x)
{
return (cmsUInt16Number) (((x << 8) + 0x80) / 257);
}
typedef struct {
cmsUInt32Number Type;
cmsUInt32Number Mask;
cmsFormatter16 Frm;
} cmsFormatters16;
typedef struct {
cmsUInt32Number Type;
cmsUInt32Number Mask;
cmsFormatterFloat Frm;
} cmsFormattersFloat;
#define ANYSPACE COLORSPACE_SH(31)
#define ANYCHANNELS CHANNELS_SH(15)
#define ANYEXTRA EXTRA_SH(7)
#define ANYPLANAR PLANAR_SH(1)
#define ANYENDIAN ENDIAN16_SH(1)
#define ANYSWAP DOSWAP_SH(1)
#define ANYSWAPFIRST SWAPFIRST_SH(1)
#define ANYFLAVOR FLAVOR_SH(1)
#define ANYPREMUL PREMUL_SH(1)
// Suppress waning about info never being used
#ifdef _MSC_VER
#pragma warning(disable : 4100)
#endif
// Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
// Does almost everything but is slow
static
cmsUInt8Number* UnrollChunkyBytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number v;
cmsUInt32Number i;
cmsUInt32Number alpha_factor = 1;
if (ExtraFirst) {
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[0]));
accum += Extra;
}
else
{
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[nChan]));
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = FROM_8_TO_16(*accum);
v = Reverse ? REVERSE_FLAVOR_16(v) : v;
if (Premul && alpha_factor > 0)
{
v = ((cmsUInt32Number)((cmsUInt32Number)v << 16) / alpha_factor);
if (v > 0xffff) v = 0xffff;
}
wIn[index] = (cmsUInt16Number) v;
accum++;
}
if (!ExtraFirst) {
accum += Extra;
}
if (Extra == 0 && SwapFirst) {
cmsUInt16Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
wIn[nChan-1] = tmp;
}
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// Extra channels are just ignored because come in the next planes
static
cmsUInt8Number* UnrollPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
cmsUInt32Number i;
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
cmsUInt8Number* Init = accum;
cmsUInt32Number alpha_factor = 1;
if (ExtraFirst) {
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[0]));
accum += Extra * Stride;
}
else
{
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(accum[(nChan) * Stride]));
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt32Number v = FROM_8_TO_16(*accum);
v = Reverse ? REVERSE_FLAVOR_16(v) : v;
if (Premul && alpha_factor > 0)
{
v = ((cmsUInt32Number)((cmsUInt32Number)v << 16) / alpha_factor);
if (v > 0xffff) v = 0xffff;
}
wIn[index] = (cmsUInt16Number) v;
accum += Stride;
}
return (Init + 1);
}
// Special cases, provided for performance
static
cmsUInt8Number* Unroll4Bytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = FROM_8_TO_16(*accum); accum++; // C
wIn[1] = FROM_8_TO_16(*accum); accum++; // M
wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
wIn[3] = FROM_8_TO_16(*accum); accum++; // K
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll4BytesReverse(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
wIn[1] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
wIn[2] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[3] = FROM_8_TO_16(*accum); accum++; // K
wIn[0] = FROM_8_TO_16(*accum); accum++; // C
wIn[1] = FROM_8_TO_16(*accum); accum++; // M
wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// KYMC
static
cmsUInt8Number* Unroll4BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[3] = FROM_8_TO_16(*accum); accum++; // K
wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
wIn[1] = FROM_8_TO_16(*accum); accum++; // M
wIn[0] = FROM_8_TO_16(*accum); accum++; // C
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[2] = FROM_8_TO_16(*accum); accum++; // K
wIn[1] = FROM_8_TO_16(*accum); accum++; // Y
wIn[0] = FROM_8_TO_16(*accum); accum++; // M
wIn[3] = FROM_8_TO_16(*accum); accum++; // C
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3Bytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
wIn[1] = FROM_8_TO_16(*accum); accum++; // G
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3BytesSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
accum++; // A
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
wIn[1] = FROM_8_TO_16(*accum); accum++; // G
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3BytesSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
wIn[1] = FROM_8_TO_16(*accum); accum++; // G
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
accum++; // A
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3BytesSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
accum++; // A
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
wIn[1] = FROM_8_TO_16(*accum); accum++; // G
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// BRG
static
cmsUInt8Number* Unroll3BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
wIn[1] = FROM_8_TO_16(*accum); accum++; // G
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollLabV2_8(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollALabV2_8(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
accum++; // A
wIn[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
wIn[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollLabV2_16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
wIn[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// for duplex
static
cmsUInt8Number* Unroll2Bytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// Monochrome duplicates L into RGB for null-transforms
static
cmsUInt8Number* Unroll1Byte(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
accum += 1;
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll1ByteSkip2(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
accum += 2;
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll1ByteReversed(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollAnyWords(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number i;
if (ExtraFirst) {
accum += Extra * sizeof(cmsUInt16Number);
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt16Number v = *(cmsUInt16Number*) accum;
if (SwapEndian)
v = CHANGE_ENDIAN(v);
wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
accum += sizeof(cmsUInt16Number);
}
if (!ExtraFirst) {
accum += Extra * sizeof(cmsUInt16Number);
}
if (Extra == 0 && SwapFirst) {
cmsUInt16Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
wIn[nChan-1] = tmp;
}
return accum;
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollAnyWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number i;
cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[nChan - 1]);
cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha));
if (ExtraFirst) {
accum += sizeof(cmsUInt16Number);
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt32Number v = *(cmsUInt16Number*) accum;
if (SwapEndian)
v = CHANGE_ENDIAN(v);
v = (v << 16) / alpha_factor;
if (v > 0xffff) v = 0xffff;
wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
accum += sizeof(cmsUInt16Number);
}
if (!ExtraFirst) {
accum += sizeof(cmsUInt16Number);
}
return accum;
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollPlanarWords(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
cmsUInt32Number i;
cmsUInt8Number* Init = accum;
if (DoSwap) {
accum += T_EXTRA(info -> InputFormat) * Stride;
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt16Number v = *(cmsUInt16Number*) accum;
if (SwapEndian)
v = CHANGE_ENDIAN(v);
wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v;
accum += Stride;
}
return (Init + sizeof(cmsUInt16Number));
}
static
cmsUInt8Number* UnrollPlanarWordsPremul(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat);
cmsUInt32Number i;
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt8Number* Init = accum;
cmsUInt16Number alpha = (ExtraFirst ? accum[0] : accum[(nChan - 1) * Stride]);
cmsUInt32Number alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(alpha));
if (ExtraFirst) {
accum += Stride;
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt32Number v = (cmsUInt32Number) *(cmsUInt16Number*) accum;
if (SwapEndian)
v = CHANGE_ENDIAN(v);
v = (v << 16) / alpha_factor;
if (v > 0xffff) v = 0xffff;
wIn[index] = (cmsUInt16Number) (Reverse ? REVERSE_FLAVOR_16(v) : v);
accum += Stride;
}
return (Init + sizeof(cmsUInt16Number));
}
static
cmsUInt8Number* Unroll4Words(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll4WordsReverse(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // C
wIn[1] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // M
wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // Y
wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll4WordsSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// KYMC
static
cmsUInt8Number* Unroll4WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll4WordsSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // K
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // Y
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // M
wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3Words(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3WordsSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
accum += 2; // A
wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // R
wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll3WordsSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
accum += 2; // A
wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // R
wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // G
wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll1Word(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll1WordReversed(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll1WordSkip3(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
accum += 8;
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll2Words(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// This is a conversion of Lab double to 16 bits
static
cmsUInt8Number* UnrollLabDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
if (T_PLANAR(info -> InputFormat)) {
cmsCIELab Lab;
cmsUInt8Number* pos_L;
cmsUInt8Number* pos_a;
cmsUInt8Number* pos_b;
pos_L = accum;
pos_a = accum + Stride;
pos_b = accum + Stride * 2;
Lab.L = *(cmsFloat64Number*) pos_L;
Lab.a = *(cmsFloat64Number*) pos_a;
Lab.b = *(cmsFloat64Number*) pos_b;
cmsFloat2LabEncoded(wIn, &Lab);
return accum + sizeof(cmsFloat64Number);
}
else {
cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
return accum;
}
}
// This is a conversion of Lab float to 16 bits
static
cmsUInt8Number* UnrollLabFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsCIELab Lab;
if (T_PLANAR(info -> InputFormat)) {
cmsUInt8Number* pos_L;
cmsUInt8Number* pos_a;
cmsUInt8Number* pos_b;
pos_L = accum;
pos_a = accum + Stride;
pos_b = accum + Stride * 2;
Lab.L = *(cmsFloat32Number*)pos_L;
Lab.a = *(cmsFloat32Number*)pos_a;
Lab.b = *(cmsFloat32Number*)pos_b;
cmsFloat2LabEncoded(wIn, &Lab);
return accum + sizeof(cmsFloat32Number);
}
else {
Lab.L = ((cmsFloat32Number*) accum)[0];
Lab.a = ((cmsFloat32Number*) accum)[1];
Lab.b = ((cmsFloat32Number*) accum)[2];
cmsFloat2LabEncoded(wIn, &Lab);
accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
return accum;
}
}
// This is a conversion of XYZ double to 16 bits
static
cmsUInt8Number* UnrollXYZDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
if (T_PLANAR(info -> InputFormat)) {
cmsCIEXYZ XYZ;
cmsUInt8Number* pos_X;
cmsUInt8Number* pos_Y;
cmsUInt8Number* pos_Z;
pos_X = accum;
pos_Y = accum + Stride;
pos_Z = accum + Stride * 2;
XYZ.X = *(cmsFloat64Number*)pos_X;
XYZ.Y = *(cmsFloat64Number*)pos_Y;
XYZ.Z = *(cmsFloat64Number*)pos_Z;
cmsFloat2XYZEncoded(wIn, &XYZ);
return accum + sizeof(cmsFloat64Number);
}
else {
cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
return accum;
}
}
// This is a conversion of XYZ float to 16 bits
static
cmsUInt8Number* UnrollXYZFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
if (T_PLANAR(info -> InputFormat)) {
cmsCIEXYZ XYZ;
cmsUInt8Number* pos_X;
cmsUInt8Number* pos_Y;
cmsUInt8Number* pos_Z;
pos_X = accum;
pos_Y = accum + Stride;
pos_Z = accum + Stride * 2;
XYZ.X = *(cmsFloat32Number*)pos_X;
XYZ.Y = *(cmsFloat32Number*)pos_Y;
XYZ.Z = *(cmsFloat32Number*)pos_Z;
cmsFloat2XYZEncoded(wIn, &XYZ);
return accum + sizeof(cmsFloat32Number);
}
else {
cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
cmsCIEXYZ XYZ;
XYZ.X = Pt[0];
XYZ.Y = Pt[1];
XYZ.Z = Pt[2];
cmsFloat2XYZEncoded(wIn, &XYZ);
accum += 3 * sizeof(cmsFloat32Number) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat32Number);
return accum;
}
}
// Check if space is marked as ink
cmsINLINE cmsBool IsInkSpace(cmsUInt32Number Type)
{
switch (T_COLORSPACE(Type)) {
case PT_CMY:
case PT_CMYK:
case PT_MCH5:
case PT_MCH6:
case PT_MCH7:
case PT_MCH8:
case PT_MCH9:
case PT_MCH10:
case PT_MCH11:
case PT_MCH12:
case PT_MCH13:
case PT_MCH14:
case PT_MCH15: return TRUE;
default: return FALSE;
}
}
// Return the size in bytes of a given formatter
static
cmsUInt32Number PixelSize(cmsUInt32Number Format)
{
cmsUInt32Number fmt_bytes = T_BYTES(Format);
// For double, the T_BYTES field is zero
if (fmt_bytes == 0)
return sizeof(cmsUInt64Number);
// Otherwise, it is already correct for all formats
return fmt_bytes;
}
// Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
static
cmsUInt8Number* UnrollDoubleTo16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat64Number v;
cmsUInt16Number vi;
cmsUInt32Number i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
else
v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
vi = _cmsQuickSaturateWord(v * maximum);
if (Reverse)
vi = REVERSE_FLAVOR_16(vi);
wIn[index] = vi;
}
if (Extra == 0 && SwapFirst) {
cmsUInt16Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat64Number);
else
return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
}
static
cmsUInt8Number* UnrollFloatTo16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat);
cmsUInt32Number Extra = T_EXTRA(info -> InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Planar = T_PLANAR(info -> InputFormat);
cmsFloat32Number v;
cmsUInt16Number vi;
cmsUInt32Number i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
else
v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
vi = _cmsQuickSaturateWord(v * maximum);
if (Reverse)
vi = REVERSE_FLAVOR_16(vi);
wIn[index] = vi;
}
if (Extra == 0 && SwapFirst) {
cmsUInt16Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat32Number);
else
return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
}
// For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
static
cmsUInt8Number* UnrollDouble1Chan(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
return accum + sizeof(cmsFloat64Number);
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
//-------------------------------------------------------------------------------------------------------------------
// For anything going from cmsUInt8Number
static
cmsUInt8Number* Unroll8ToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
cmsFloat32Number v;
cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst)
start = Extra;
for (i = 0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
v = (cmsFloat32Number) ((cmsUInt8Number *)accum)[(i + start) * Stride];
else
v = (cmsFloat32Number) ((cmsUInt8Number *)accum)[i + start];
v /= 255.0F;
wIn[index] = Reverse ? 1 - v : v;
}
if (Extra == 0 && SwapFirst) {
cmsFloat32Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan - 1) * sizeof(cmsFloat32Number));
wIn[nChan - 1] = tmp;
}
if (T_PLANAR(info->InputFormat))
return accum + sizeof(cmsUInt8Number);
else
return accum + (nChan + Extra) * sizeof(cmsUInt8Number);
}
// For anything going from cmsUInt16Number
static
cmsUInt8Number* Unroll16ToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
cmsFloat32Number v;
cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->InputFormat);
if (ExtraFirst)
start = Extra;
for (i = 0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
v = (cmsFloat32Number)((cmsUInt16Number*)accum)[(i + start) * Stride];
else
v = (cmsFloat32Number)((cmsUInt16Number*)accum)[i + start];
v /= 65535.0F;
wIn[index] = Reverse ? 1 - v : v;
}
if (Extra == 0 && SwapFirst) {
cmsFloat32Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan - 1) * sizeof(cmsFloat32Number));
wIn[nChan - 1] = tmp;
}
if (T_PLANAR(info->InputFormat))
return accum + sizeof(cmsUInt16Number);
else
return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
}
// For anything going from cmsFloat32Number
static
cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
cmsFloat32Number v;
cmsUInt32Number i, start = 0;
cmsFloat32Number maximum = IsInkSpace(info->InputFormat) ? 100.0F : 1.0F;
cmsFloat32Number alpha_factor = 1.0f;
cmsFloat32Number* ptr = (cmsFloat32Number*)accum;
Stride /= PixelSize(info->InputFormat);
if (Premul && Extra)
{
if (Planar)
alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan * Stride]) / maximum;
else
alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum;
}
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
v = ptr[(i + start) * Stride];
else
v = ptr[i + start];
if (Premul && alpha_factor > 0)
v /= alpha_factor;
v /= maximum;
wIn[index] = Reverse ? 1 - v : v;
}
if (Extra == 0 && SwapFirst) {
cmsFloat32Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat32Number);
else
return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
}
// For anything going from double
static
cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->InputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->InputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->InputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->InputFormat);
cmsUInt32Number Extra = T_EXTRA(info->InputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Planar = T_PLANAR(info->InputFormat);
cmsUInt32Number Premul = T_PREMUL(info->InputFormat);
cmsFloat64Number v;
cmsUInt32Number i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
cmsFloat64Number alpha_factor = 1.0;
cmsFloat64Number* ptr = (cmsFloat64Number*)accum;
Stride /= PixelSize(info->InputFormat);
if (Premul && Extra)
{
if (Planar)
alpha_factor = (ExtraFirst ? ptr[0] : ptr[(nChan) * Stride]) / maximum;
else
alpha_factor = (ExtraFirst ? ptr[0] : ptr[nChan]) / maximum;
}
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
else
v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
if (Premul && alpha_factor > 0)
v /= alpha_factor;
v /= maximum;
wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
}
if (Extra == 0 && SwapFirst) {
cmsFloat32Number tmp = wIn[0];
memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat64Number);
else
return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
}
// From Lab double to cmsFloat32Number
static
cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
return accum + sizeof(cmsFloat64Number);
}
else {
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
// From Lab double to cmsFloat32Number
static
cmsUInt8Number* UnrollLabFloatToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
return accum + sizeof(cmsFloat32Number);
}
else {
wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
// 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
static
cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsFloat64Number* Pt = (cmsFloat64Number*) accum;
if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
return accum + sizeof(cmsFloat64Number);
}
else {
wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
static
cmsUInt8Number* UnrollXYZFloatToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
if (T_PLANAR(info -> InputFormat)) {
Stride /= PixelSize(info->InputFormat);
wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ);
return accum + sizeof(cmsFloat32Number);
}
else {
wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ);
wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
cmsINLINE void lab4toFloat(cmsFloat32Number wIn[], cmsUInt16Number lab4[3])
{
cmsFloat32Number L = (cmsFloat32Number) lab4[0] / 655.35F;
cmsFloat32Number a = ((cmsFloat32Number) lab4[1] / 257.0F) - 128.0F;
cmsFloat32Number b = ((cmsFloat32Number) lab4[2] / 257.0F) - 128.0F;
wIn[0] = (L / 100.0F); // from 0..100 to 0..1
wIn[1] = ((a + 128.0F) / 255.0F); // form -128..+127 to 0..1
wIn[2] = ((b + 128.0F) / 255.0F);
}
static
cmsUInt8Number* UnrollLabV2_8ToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt16Number lab4[3];
lab4[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
lab4[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
lab4[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
lab4toFloat(wIn, lab4);
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollALabV2_8ToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt16Number lab4[3];
accum++; // A
lab4[0] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // L
lab4[1] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // a
lab4[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
lab4toFloat(wIn, lab4);
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* UnrollLabV2_16ToFloat(_cmsTRANSFORM* info,
cmsFloat32Number wIn[],
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
cmsUInt16Number lab4[3];
lab4[0] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // L
lab4[1] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // a
lab4[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
lab4toFloat(wIn, lab4);
return accum;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// Packing routines -----------------------------------------------------------------------------------------------------------
// Generic chunky for byte
static
cmsUInt8Number* PackChunkyBytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt8Number* swap1;
cmsUInt16Number v = 0;
cmsUInt32Number i;
cmsUInt32Number alpha_factor = 0;
swap1 = output;
if (ExtraFirst) {
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[0]));
output += Extra;
}
else
{
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[nChan]));
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index];
if (Reverse)
v = REVERSE_FLAVOR_16(v);
if (Premul && alpha_factor != 0)
{
v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
}
*output++ = FROM_16_TO_8(v);
}
if (!ExtraFirst) {
output += Extra;
}
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, nChan-1);
*swap1 = FROM_16_TO_8(v);
}
return output;
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* PackChunkyWords(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
cmsUInt32Number SwapEndian = T_ENDIAN16(info->OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt16Number* swap1;
cmsUInt16Number v = 0;
cmsUInt32Number i;
cmsUInt32Number alpha_factor = 0;
swap1 = (cmsUInt16Number*) output;
if (ExtraFirst) {
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(*(cmsUInt16Number*) output);
output += Extra * sizeof(cmsUInt16Number);
}
else
{
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*) output)[nChan]);
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index];
if (SwapEndian)
v = CHANGE_ENDIAN(v);
if (Reverse)
v = REVERSE_FLAVOR_16(v);
if (Premul && alpha_factor != 0)
{
v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
}
*(cmsUInt16Number*) output = v;
output += sizeof(cmsUInt16Number);
}
if (!ExtraFirst) {
output += Extra * sizeof(cmsUInt16Number);
}
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
*swap1 = v;
}
return output;
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* PackPlanarBytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
cmsUInt32Number i;
cmsUInt8Number* Init = output;
cmsUInt32Number alpha_factor = 0;
if (ExtraFirst) {
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[0]));
output += Extra * Stride;
}
else
{
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(FROM_8_TO_16(output[nChan * Stride]));
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
cmsUInt16Number v = wOut[index];
if (Reverse)
v = REVERSE_FLAVOR_16(v);
if (Premul && alpha_factor != 0)
{
v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
}
*(cmsUInt8Number*)output = FROM_16_TO_8(v);
output += Stride;
}
return (Init + 1);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* PackPlanarWords(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt32Number Premul = T_PREMUL(info->OutputFormat);
cmsUInt32Number SwapEndian = T_ENDIAN16(info->OutputFormat);
cmsUInt32Number i;
cmsUInt8Number* Init = output;
cmsUInt16Number v;
cmsUInt32Number alpha_factor = 0;
if (ExtraFirst) {
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*) output)[0]);
output += Extra * Stride;
}
else
{
if (Premul && Extra)
alpha_factor = _cmsToFixedDomain(((cmsUInt16Number*)output)[nChan * Stride]);
}
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index];
if (SwapEndian)
v = CHANGE_ENDIAN(v);
if (Reverse)
v = REVERSE_FLAVOR_16(v);
if (Premul && alpha_factor != 0)
{
v = (cmsUInt16Number)((cmsUInt32Number)((cmsUInt32Number)v * alpha_factor + 0x8000) >> 16);
}
*(cmsUInt16Number*) output = v;
output += Stride;
}
return (Init + sizeof(cmsUInt16Number));
}
// CMYKcm (unrolled for speed)
static
cmsUInt8Number* Pack6Bytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[3]);
*output++ = FROM_16_TO_8(wOut[4]);
*output++ = FROM_16_TO_8(wOut[5]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// KCMYcm
static
cmsUInt8Number* Pack6BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[5]);
*output++ = FROM_16_TO_8(wOut[4]);
*output++ = FROM_16_TO_8(wOut[3]);
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[0]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// CMYKcm
static
cmsUInt8Number* Pack6Words(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[3];
output+= 2;
*(cmsUInt16Number*) output = wOut[4];
output+= 2;
*(cmsUInt16Number*) output = wOut[5];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// KCMYcm
static
cmsUInt8Number* Pack6WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[5];
output+= 2;
*(cmsUInt16Number*) output = wOut[4];
output+= 2;
*(cmsUInt16Number*) output = wOut[3];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack4Bytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[3]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack4BytesReverse(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[0]));
*output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[1]));
*output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[2]));
*output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack4BytesSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[3]);
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[2]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// ABGR
static
cmsUInt8Number* Pack4BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[3]);
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[0]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack4BytesSwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[3]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack4Words(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[3];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack4WordsReverse(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
output+= 2;
*(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[1]);
output+= 2;
*(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[2]);
output+= 2;
*(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[3]);
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// ABGR
static
cmsUInt8Number* Pack4WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[3];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// CMYK
static
cmsUInt8Number* Pack4WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
output+= 2;
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
output+= 2;
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
output+= 2;
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[3]);
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* PackLabV2_8(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* PackALabV2_8(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output++;
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[0]));
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[1]));
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* PackLabV2_16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[0]);
output += 2;
*(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[1]);
output += 2;
*(cmsUInt16Number*) output = FomLabV4ToLabV2(wOut[2]);
output += 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3Bytes(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[2]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesOptimized(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = (wOut[0] & 0xFFU);
*output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[2] & 0xFFU);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[0]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesSwapOptimized(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = (wOut[2] & 0xFFU);
*output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[0] & 0xFFU);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3Words(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3WordsSwap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3WordsBigEndian(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
output+= 2;
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[1]);
output+= 2;
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[2]);
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[2]);
output++;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1Optimized(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = (wOut[0] & 0xFFU);
*output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[2] & 0xFFU);
output++;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output++;
*output++ = FROM_16_TO_8(wOut[0]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[2]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output++;
*output++ = (wOut[0] & 0xFFU);
*output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[2] & 0xFFU);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output++;
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[0]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output++;
*output++ = (wOut[2] & 0xFFU);
*output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[0] & 0xFFU);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[2]);
*output++ = FROM_16_TO_8(wOut[1]);
*output++ = FROM_16_TO_8(wOut[0]);
output++;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = (wOut[2] & 0xFFU);
*output++ = (wOut[1] & 0xFFU);
*output++ = (wOut[0] & 0xFFU);
output++;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3WordsAndSkip1(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3WordsAndSkip1Swap(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output+= 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[2];
output+= 2;
*(cmsUInt16Number*) output = wOut[1];
output+= 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1Byte(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1ByteReversed(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1ByteSkip1(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
output++;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1ByteSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output++;
*output++ = FROM_16_TO_8(wOut[0]);
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1Word(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1WordReversed(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = REVERSE_FLAVOR_16(wOut[0]);
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1WordBigEndian(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = CHANGE_ENDIAN(wOut[0]);
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1WordSkip1(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
*(cmsUInt16Number*) output = wOut[0];
output+= 4;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Pack1WordSkip1SwapFirst(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
output += 2;
*(cmsUInt16Number*) output = wOut[0];
output+= 2;
return output;
cmsUNUSED_PARAMETER(info);
cmsUNUSED_PARAMETER(Stride);
}
// Unencoded Float values -- don't try optimize speed
static
cmsUInt8Number* PackLabDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
if (T_PLANAR(info -> OutputFormat)) {
cmsCIELab Lab;
cmsFloat64Number* Out = (cmsFloat64Number*) output;
cmsLabEncoded2Float(&Lab, wOut);
Out[0] = Lab.L;
Out[Stride] = Lab.a;
Out[Stride*2] = Lab.b;
return output + sizeof(cmsFloat64Number);
}
else {
cmsLabEncoded2Float((cmsCIELab*) output, wOut);
return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
}
}
static
cmsUInt8Number* PackLabFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsCIELab Lab;
cmsLabEncoded2Float(&Lab, wOut);
if (T_PLANAR(info -> OutputFormat)) {
cmsFloat32Number* Out = (cmsFloat32Number*) output;
Stride /= PixelSize(info->OutputFormat);
Out[0] = (cmsFloat32Number)Lab.L;
Out[Stride] = (cmsFloat32Number)Lab.a;
Out[Stride*2] = (cmsFloat32Number)Lab.b;
return output + sizeof(cmsFloat32Number);
}
else {
((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
}
}
static
cmsUInt8Number* PackXYZDoubleFrom16(CMSREGISTER _cmsTRANSFORM* Info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
if (T_PLANAR(Info -> OutputFormat)) {
cmsCIEXYZ XYZ;
cmsFloat64Number* Out = (cmsFloat64Number*) output;
cmsXYZEncoded2Float(&XYZ, wOut);
Stride /= PixelSize(Info->OutputFormat);
Out[0] = XYZ.X;
Out[Stride] = XYZ.Y;
Out[Stride*2] = XYZ.Z;
return output + sizeof(cmsFloat64Number);
}
else {
cmsXYZEncoded2Float((cmsCIEXYZ*) output, wOut);
return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
}
}
static
cmsUInt8Number* PackXYZFloatFrom16(CMSREGISTER _cmsTRANSFORM* Info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
if (T_PLANAR(Info -> OutputFormat)) {
cmsCIEXYZ XYZ;
cmsFloat32Number* Out = (cmsFloat32Number*) output;
cmsXYZEncoded2Float(&XYZ, wOut);
Stride /= PixelSize(Info->OutputFormat);
Out[0] = (cmsFloat32Number) XYZ.X;
Out[Stride] = (cmsFloat32Number) XYZ.Y;
Out[Stride*2] = (cmsFloat32Number) XYZ.Z;
return output + sizeof(cmsFloat32Number);
}
else {
cmsCIEXYZ XYZ;
cmsFloat32Number* Out = (cmsFloat32Number*) output;
cmsXYZEncoded2Float(&XYZ, wOut);
Out[0] = (cmsFloat32Number) XYZ.X;
Out[1] = (cmsFloat32Number) XYZ.Y;
Out[2] = (cmsFloat32Number) XYZ.Z;
return output + (3 * sizeof(cmsFloat32Number) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat32Number));
}
}
static
cmsUInt8Number* PackDoubleFrom16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat);
cmsUInt32Number Planar = T_PLANAR(info -> OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
cmsFloat64Number v = 0;
cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst)
start = Extra;
for (i=0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = (cmsFloat64Number) wOut[index] / maximum;
if (Reverse)
v = maximum - v;
if (Planar)
((cmsFloat64Number*) output)[(i + start) * Stride]= v;
else
((cmsFloat64Number*) output)[i + start] = v;
}
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
*swap1 = v;
}
if (T_PLANAR(info -> OutputFormat))
return output + sizeof(cmsFloat64Number);
else
return output + (nChan + Extra) * sizeof(cmsFloat64Number);
}
static
cmsUInt8Number* PackFloatFrom16(CMSREGISTER _cmsTRANSFORM* info,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0;
cmsFloat64Number v = 0;
cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst)
start = Extra;
for (i = 0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = (cmsFloat64Number)wOut[index] / maximum;
if (Reverse)
v = maximum - v;
if (Planar)
((cmsFloat32Number*)output)[(i + start) * Stride] = (cmsFloat32Number)v;
else
((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
}
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
*swap1 = (cmsFloat32Number)v;
}
if (T_PLANAR(info->OutputFormat))
return output + sizeof(cmsFloat32Number);
else
return output + (nChan + Extra) * sizeof(cmsFloat32Number);
}
// --------------------------------------------------------------------------------------------------------
static
cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
cmsFloat32Number wOut[],
cmsUInt8Number* output,
cmsUInt32Number Stride)
{
cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat);
cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat);
cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat);
cmsUInt32Number Extra = T_EXTRA(info->OutputFormat);
cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat);
cmsUInt32Number Planar = T_PLANAR(info->OutputFormat);
cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0;
cmsFloat32Number* swap1 = (cmsFloat32Number*)output;
cmsFloat64Number v = 0;
cmsUInt32Number i, start = 0;
Stride /= PixelSize(info->OutputFormat);
if (ExtraFirst)
start = Extra;
for (i = 0; i < nChan; i++) {
cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i;
v = wOut[index] * maximum;
if (Reverse)
v = maximum - v;
if (Planar)
((cmsFloat32Number*)output)[(i + start)* Stride] = (cmsFloat32Number)v;
else
((cmsFloat32Number*)output)[i + start] = (cmsFloat32Number)v;
}
if (Extra == 0 && SwapFirst) {
memmove(swap1 + 1, swap1, (nChan - 1)* sizeof(cmsFloat32Number));
*swap1 = (cmsFloat32Number)v;
}
if (T_PLANAR(info->OutputFormat))
return output + sizeof(cmsFloat32Number);
else
return output + (nChan + Extra) * sizeof(cmsFloat32Number);