You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2147 lines
60 KiB
2147 lines
60 KiB
// Little cms
|
|
// Copyright (C) 1998-2007 Marti Maria
|
|
//
|
|
// 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 "lcms.h"
|
|
|
|
// This module handles all formats supported by lcms
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// This macro return words stored as big endian
|
|
|
|
#define CHANGE_ENDIAN(w) (WORD) ((WORD) ((w)<<8)|((w)>>8))
|
|
|
|
// These macros handles reversing (negative)
|
|
|
|
#define REVERSE_FLAVOR_8(x) ((BYTE) (0xff-(x)))
|
|
#define REVERSE_FLAVOR_16(x) ((WORD)(0xffff-(x)))
|
|
|
|
// Supress waning about info never being used
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma warn -par
|
|
#endif
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable : 4100)
|
|
#endif
|
|
|
|
// -------------------------------------------------------- Unpacking routines.
|
|
|
|
|
|
static
|
|
LPBYTE UnrollAnyBytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
register int i;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
wIn[i] = RGB_8_TO_16(*accum); accum++;
|
|
}
|
|
|
|
return accum + T_EXTRA(info -> InputFormat);
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE Unroll4Bytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = RGB_8_TO_16(*accum); accum++; // C
|
|
wIn[1] = RGB_8_TO_16(*accum); accum++; // M
|
|
wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
|
|
wIn[3] = RGB_8_TO_16(*accum); accum++; // K
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll4BytesReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // C
|
|
wIn[1] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // M
|
|
wIn[2] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // Y
|
|
wIn[3] = RGB_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll4BytesSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
|
|
wIn[3] = RGB_8_TO_16(*accum); accum++; // K
|
|
wIn[0] = RGB_8_TO_16(*accum); accum++; // C
|
|
wIn[1] = RGB_8_TO_16(*accum); accum++; // M
|
|
wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
|
|
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
|
|
// KYMC
|
|
static
|
|
LPBYTE Unroll4BytesSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[3] = RGB_8_TO_16(*accum); accum++; // K
|
|
wIn[2] = RGB_8_TO_16(*accum); accum++; // Y
|
|
wIn[1] = RGB_8_TO_16(*accum); accum++; // M
|
|
wIn[0] = RGB_8_TO_16(*accum); accum++; // C
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll4BytesSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[2] = RGB_8_TO_16(*accum); accum++; // K
|
|
wIn[1] = RGB_8_TO_16(*accum); accum++; // Y
|
|
wIn[0] = RGB_8_TO_16(*accum); accum++; // M
|
|
wIn[3] = RGB_8_TO_16(*accum); accum++; // C
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE UnrollAnyWords(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
register int i;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
wIn[i] = *(LPWORD) accum; accum += 2;
|
|
}
|
|
|
|
return accum + T_EXTRA(info -> InputFormat) * sizeof(WORD);
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll4Words(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = *(LPWORD) accum; accum+= 2; // C
|
|
wIn[1] = *(LPWORD) accum; accum+= 2; // M
|
|
wIn[2] = *(LPWORD) accum; accum+= 2; // Y
|
|
wIn[3] = *(LPWORD) accum; accum+= 2; // K
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll4WordsReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // C
|
|
wIn[1] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // M
|
|
wIn[2] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // Y
|
|
wIn[3] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2; // K
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll4WordsSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[3] = *(LPWORD) accum; accum+= 2; // K
|
|
wIn[0] = *(LPWORD) accum; accum+= 2; // C
|
|
wIn[1] = *(LPWORD) accum; accum+= 2; // M
|
|
wIn[2] = *(LPWORD) accum; accum+= 2; // Y
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
// KYMC
|
|
static
|
|
LPBYTE Unroll4WordsSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[3] = *(LPWORD) accum; accum+= 2; // K
|
|
wIn[2] = *(LPWORD) accum; accum+= 2; // Y
|
|
wIn[1] = *(LPWORD) accum; accum+= 2; // M
|
|
wIn[0] = *(LPWORD) accum; accum+= 2; // C
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll4WordsSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[2] = *(LPWORD) accum; accum+= 2; // K
|
|
wIn[1] = *(LPWORD) accum; accum+= 2; // Y
|
|
wIn[0] = *(LPWORD) accum; accum+= 2; // M
|
|
wIn[3] = *(LPWORD) accum; accum+= 2; // C
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll4WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //C
|
|
wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //M
|
|
wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //Y
|
|
wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //K
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll4WordsBigEndianReverse(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //C
|
|
wIn[1] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //M
|
|
wIn[2] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //Y
|
|
wIn[3] = REVERSE_FLAVOR_16(CHANGE_ENDIAN(*(LPWORD) accum)); accum+= 2; //K
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
// KYMC
|
|
static
|
|
LPBYTE Unroll4WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //K
|
|
wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //Y
|
|
wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //M
|
|
wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2; //C
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll3Bytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
|
|
wIn[0] = RGB_8_TO_16(*accum); accum++; // R
|
|
wIn[1] = RGB_8_TO_16(*accum); accum++; // G
|
|
wIn[2] = RGB_8_TO_16(*accum); accum++; // B
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
// Lab8 encoding using v2 PCS
|
|
|
|
static
|
|
LPBYTE Unroll3BytesLab(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
|
|
wIn[0] = (WORD) ((*accum) << 8); accum++;
|
|
wIn[1] = (WORD) ((*accum) << 8); accum++;
|
|
wIn[2] = (WORD) ((*accum) << 8); accum++;
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
// BRG
|
|
|
|
static
|
|
LPBYTE Unroll3BytesSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
|
|
wIn[2] = RGB_8_TO_16(*accum); accum++; // B
|
|
wIn[1] = RGB_8_TO_16(*accum); accum++; // G
|
|
wIn[0] = RGB_8_TO_16(*accum); accum++; // R
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll3Words(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = *(LPWORD) accum; accum+= 2; // C R
|
|
wIn[1] = *(LPWORD) accum; accum+= 2; // M G
|
|
wIn[2] = *(LPWORD) accum; accum+= 2; // Y B
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll3WordsSwap(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[2] = *(LPWORD) accum; accum+= 2; // C R
|
|
wIn[1] = *(LPWORD) accum; accum+= 2; // M G
|
|
wIn[0] = *(LPWORD) accum; accum+= 2; // Y B
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll3WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll3WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
wIn[1] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
wIn[0] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
return accum;
|
|
}
|
|
|
|
|
|
|
|
// Monochrome duplicates L into RGB for null-transforms
|
|
|
|
static
|
|
LPBYTE Unroll1Byte(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll1ByteSkip2(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
|
|
accum += 2;
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll1ByteReversed(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(RGB_8_TO_16(*accum)); accum++; // L
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll1Word(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2; // L
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll1WordReversed(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(LPWORD) accum); accum+= 2;
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll1WordBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll1WordSkip3(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum;
|
|
|
|
accum += 8;
|
|
return accum;
|
|
}
|
|
|
|
|
|
// Monochrome + alpha. Alpha is lost
|
|
|
|
static
|
|
LPBYTE Unroll2Byte(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
|
|
wIn[3] = RGB_8_TO_16(*accum); accum++; // alpha
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll2ByteSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[3] = RGB_8_TO_16(*accum); accum++; // alpha
|
|
wIn[0] = wIn[1] = wIn[2] = RGB_8_TO_16(*accum); accum++; // L
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll2Word(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2; // L
|
|
wIn[3] = *(LPWORD) accum; accum += 2; // alpha
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Unroll2WordSwapFirst(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[3] = *(LPWORD) accum; accum += 2; // alpha
|
|
wIn[0] = wIn[1] = wIn[2] = *(LPWORD) accum; accum+= 2; // L
|
|
|
|
return accum;
|
|
}
|
|
|
|
static
|
|
LPBYTE Unroll2WordBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
wIn[0] = wIn[1] = wIn[2] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
wIn[3] = CHANGE_ENDIAN(*(LPWORD) accum); accum+= 2;
|
|
|
|
return accum;
|
|
}
|
|
|
|
|
|
|
|
|
|
static
|
|
LPBYTE UnrollPlanarBytes(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
register int i;
|
|
LPBYTE Init = accum;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
wIn[i] = RGB_8_TO_16(*accum);
|
|
accum += info -> StrideIn;
|
|
}
|
|
|
|
return (Init + 1);
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE UnrollPlanarWords(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
register int i;
|
|
LPBYTE Init = accum;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
wIn[i] = *(LPWORD) accum;
|
|
accum += (info -> StrideIn * sizeof(WORD));
|
|
}
|
|
|
|
return (Init + sizeof(WORD));
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE UnrollPlanarWordsBigEndian(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
register int i;
|
|
LPBYTE Init = accum;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
wIn[i] = CHANGE_ENDIAN(*(LPWORD) accum);
|
|
accum += (info -> StrideIn * sizeof(WORD));
|
|
}
|
|
|
|
return (Init + sizeof(WORD));
|
|
}
|
|
|
|
|
|
// floating point
|
|
static
|
|
LPBYTE UnrollLabDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
|
|
if (T_PLANAR(info -> InputFormat)) {
|
|
|
|
double* Pt = (double*) accum;
|
|
|
|
cmsCIELab Lab;
|
|
|
|
Lab.L = Pt[0];
|
|
Lab.a = Pt[info->StrideIn];
|
|
Lab.b = Pt[info->StrideIn*2];
|
|
|
|
if (info ->lInputV4Lab)
|
|
cmsFloat2LabEncoded4(wIn, &Lab);
|
|
else
|
|
cmsFloat2LabEncoded(wIn, &Lab);
|
|
|
|
return accum + sizeof(double);
|
|
}
|
|
else {
|
|
|
|
if (info ->lInputV4Lab)
|
|
cmsFloat2LabEncoded4(wIn, (LPcmsCIELab) accum);
|
|
else
|
|
cmsFloat2LabEncoded(wIn, (LPcmsCIELab) accum);
|
|
|
|
accum += sizeof(cmsCIELab);
|
|
|
|
return accum;
|
|
}
|
|
}
|
|
|
|
static
|
|
LPBYTE UnrollXYZDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
if (T_PLANAR(info -> InputFormat)) {
|
|
|
|
double* Pt = (double*) accum;
|
|
cmsCIEXYZ XYZ;
|
|
|
|
XYZ.X = Pt[0];
|
|
XYZ.Y = Pt[info->StrideIn];
|
|
XYZ.Z = Pt[info->StrideIn*2];
|
|
cmsFloat2XYZEncoded(wIn, &XYZ);
|
|
|
|
return accum + sizeof(double);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
cmsFloat2XYZEncoded(wIn, (LPcmsCIEXYZ) accum);
|
|
accum += sizeof(cmsCIEXYZ);
|
|
|
|
return accum;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Inks does come in percentage
|
|
static
|
|
LPBYTE UnrollInkDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
double* Inks = (double*) accum;
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
int Planar = T_PLANAR(info -> InputFormat);
|
|
int i;
|
|
double v;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
if (Planar)
|
|
|
|
v = Inks[i * info ->StrideIn];
|
|
else
|
|
v = Inks[i];
|
|
|
|
v = floor(v * 655.35 + 0.5);
|
|
|
|
if (v > 65535.0) v = 65535.0;
|
|
if (v < 0) v = 0;
|
|
|
|
wIn[i] = (WORD) v;
|
|
}
|
|
|
|
if (T_PLANAR(info -> InputFormat))
|
|
return accum + sizeof(double);
|
|
else
|
|
return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(double);
|
|
}
|
|
|
|
|
|
// Remaining cases are between 0..1.0
|
|
static
|
|
LPBYTE UnrollDouble(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
double* Inks = (double*) accum;
|
|
int nChan = T_CHANNELS(info -> InputFormat);
|
|
int Planar = T_PLANAR(info -> InputFormat);
|
|
int i;
|
|
double v;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
if (Planar)
|
|
|
|
v = Inks[i * info ->StrideIn];
|
|
else
|
|
v = Inks[i];
|
|
|
|
v = floor(v * 65535.0 + 0.5);
|
|
|
|
if (v > 65535.0) v = 65535.0;
|
|
if (v < 0) v = 0;
|
|
|
|
wIn[i] = (WORD) v;
|
|
}
|
|
|
|
if (T_PLANAR(info -> InputFormat))
|
|
return accum + sizeof(double);
|
|
else
|
|
return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(double);
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE UnrollDouble1Chan(register _LPcmsTRANSFORM info, register WORD wIn[], register LPBYTE accum)
|
|
{
|
|
double* Inks = (double*) accum;
|
|
double v;
|
|
|
|
|
|
v = floor(Inks[0] * 65535.0 + 0.5);
|
|
|
|
if (v > 65535.0) v = 65535.0;
|
|
if (v < 0) v = 0;
|
|
|
|
|
|
wIn[0] = wIn[1] = wIn[2] = (WORD) v;
|
|
|
|
return accum + sizeof(double);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------- Packing routines
|
|
|
|
|
|
// Generic N-bytes plus dither 16-to-8 conversion. Currently is just a quick hack
|
|
|
|
static int err[MAXCHANNELS];
|
|
|
|
static
|
|
LPBYTE PackNBytesDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
unsigned int n, pe, pf;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
n = wOut[i] + err[i]; // Value
|
|
|
|
pe = (n / 257); // Whole part
|
|
pf = (n % 257); // Fractional part
|
|
|
|
err[i] = pf; // Store it for next pixel
|
|
|
|
*output++ = (BYTE) pe;
|
|
}
|
|
|
|
return output + T_EXTRA(info ->OutputFormat);
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE PackNBytesSwapDither(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
unsigned int n, pe, pf;
|
|
|
|
for (i=nChan-1; i >= 0; --i) {
|
|
|
|
n = wOut[i] + err[i]; // Value
|
|
|
|
pe = (n / 257); // Whole part
|
|
pf = (n % 257); // Fractional part
|
|
|
|
err[i] = pf; // Store it for next pixel
|
|
|
|
*output++ = (BYTE) pe;
|
|
}
|
|
|
|
|
|
return output + T_EXTRA(info ->OutputFormat);
|
|
}
|
|
|
|
|
|
|
|
// Generic chunky for byte
|
|
|
|
static
|
|
LPBYTE PackNBytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
|
|
for (i=0; i < nChan; i++)
|
|
*output++ = RGB_16_TO_8(wOut[i]);
|
|
|
|
return output + T_EXTRA(info ->OutputFormat);
|
|
}
|
|
|
|
// Chunky reversed order bytes
|
|
|
|
static
|
|
LPBYTE PackNBytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
|
|
for (i=nChan-1; i >= 0; --i)
|
|
*output++ = RGB_16_TO_8(wOut[i]);
|
|
|
|
return output + T_EXTRA(info ->OutputFormat);
|
|
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE PackNWords(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
*(LPWORD) output = wOut[i];
|
|
output += sizeof(WORD);
|
|
}
|
|
|
|
return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
|
|
}
|
|
|
|
static
|
|
LPBYTE PackNWordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
|
|
for (i=nChan-1; i >= 0; --i) {
|
|
*(LPWORD) output = wOut[i];
|
|
output += sizeof(WORD);
|
|
}
|
|
|
|
return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE PackNWordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[i]);
|
|
output += sizeof(WORD);
|
|
}
|
|
|
|
return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE PackNWordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
|
|
for (i=nChan-1; i >= 0; --i) {
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[i]);
|
|
output += sizeof(WORD);
|
|
}
|
|
|
|
return output + T_EXTRA(info ->OutputFormat) * sizeof(WORD);
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE PackPlanarBytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
LPBYTE Init = output;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
*(LPBYTE) output = RGB_16_TO_8(wOut[i]);
|
|
output += info -> StrideOut;
|
|
}
|
|
|
|
return (Init + 1);
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE PackPlanarWords(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
int nChan = T_CHANNELS(info -> OutputFormat);
|
|
register int i;
|
|
LPBYTE Init = output;
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
*(LPWORD) output = wOut[i];
|
|
output += (info -> StrideOut * sizeof(WORD));
|
|
}
|
|
|
|
return (Init + 2);
|
|
}
|
|
|
|
|
|
// CMYKcm (unrolled for speed)
|
|
|
|
static
|
|
LPBYTE Pack6Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[3]);
|
|
*output++ = RGB_16_TO_8(wOut[4]);
|
|
*output++ = RGB_16_TO_8(wOut[5]);
|
|
|
|
return output;
|
|
}
|
|
|
|
// KCMYcm
|
|
|
|
static
|
|
LPBYTE Pack6BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[3]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[4]);
|
|
*output++ = RGB_16_TO_8(wOut[5]);
|
|
|
|
return output;
|
|
}
|
|
|
|
// CMYKcm
|
|
static
|
|
LPBYTE Pack6Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[3];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[4];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[5];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
// KCMYcm
|
|
static
|
|
LPBYTE Pack6WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[3];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[4];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[5];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
// CMYKcm
|
|
static
|
|
LPBYTE Pack6WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[4]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[5]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
// KCMYcm
|
|
static
|
|
LPBYTE Pack6WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[4]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[5]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack4Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[3]);
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack4BytesReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[0]));
|
|
*output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[1]));
|
|
*output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[2]));
|
|
*output++ = REVERSE_FLAVOR_8(RGB_16_TO_8(wOut[3]));
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack4BytesSwapFirst(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[3]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
// ABGR
|
|
|
|
static
|
|
LPBYTE Pack4BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[3]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack4BytesSwapSwapFirst(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[3]);
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack4Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[3];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack4WordsReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = REVERSE_FLAVOR_16(wOut[0]);
|
|
output+= 2;
|
|
*(LPWORD) output = REVERSE_FLAVOR_16(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = REVERSE_FLAVOR_16(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = REVERSE_FLAVOR_16(wOut[3]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
// ABGR
|
|
|
|
static
|
|
LPBYTE Pack4WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[3];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
// CMYK
|
|
static
|
|
LPBYTE Pack4WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack4WordsBigEndianReverse(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[0]));
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[1]));
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[2]));
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(REVERSE_FLAVOR_16(wOut[3]));
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
// KYMC
|
|
|
|
static
|
|
LPBYTE Pack4WordsSwapBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[3]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack3Bytes(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack3BytesLab(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = (BYTE) (wOut[0] >> 8);
|
|
*output++ = (BYTE) (wOut[1] >> 8);
|
|
*output++ = (BYTE) (wOut[2] >> 8);
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3BytesSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3Words(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack3WordsSwap(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack3WordsBigEndian(register _LPcmsTRANSFORM info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3WordsSwapBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3BytesAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
output++;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3BytesAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
output++;
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack3BytesAndSkip1Swap(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
output++;
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3BytesAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[2]);
|
|
*output++ = RGB_16_TO_8(wOut[1]);
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
output++;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3WordsAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack3WordsAndSkip1Swap(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3WordsAndSkip1SwapSwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[2];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[1];
|
|
output+= 2;
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
output+= 2;
|
|
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3WordsAndSkip1BigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack3WordsAndSkip1SwapBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[2]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[1]);
|
|
output+= 2;
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE Pack1Byte(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack1ByteAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
output++;
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack1ByteAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
output++;
|
|
*output++ = RGB_16_TO_8(wOut[0]);
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack1Word(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack1WordBigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack1WordAndSkip1(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 4;
|
|
|
|
return output;
|
|
}
|
|
|
|
static
|
|
LPBYTE Pack1WordAndSkip1SwapFirst(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
output += 2;
|
|
*(LPWORD) output = wOut[0];
|
|
output+= 2;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE Pack1WordAndSkip1BigEndian(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
*(LPWORD) output = CHANGE_ENDIAN(wOut[0]);
|
|
output+= 4;
|
|
|
|
return output;
|
|
}
|
|
|
|
|
|
// Unencoded Float values -- don't try optimize speed
|
|
|
|
static
|
|
LPBYTE PackLabDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
|
|
if (T_PLANAR(Info -> OutputFormat)) {
|
|
|
|
cmsCIELab Lab;
|
|
double* Out = (double*) output;
|
|
cmsLabEncoded2Float(&Lab, wOut);
|
|
|
|
Out[0] = Lab.L;
|
|
Out[Info ->StrideOut] = Lab.a;
|
|
Out[Info ->StrideOut*2] = Lab.b;
|
|
|
|
return output + sizeof(double);
|
|
|
|
}
|
|
else {
|
|
|
|
if (Info ->lOutputV4Lab)
|
|
cmsLabEncoded2Float4((LPcmsCIELab) output, wOut);
|
|
else
|
|
cmsLabEncoded2Float((LPcmsCIELab) output, wOut);
|
|
|
|
return output + (sizeof(cmsCIELab) + T_EXTRA(Info ->OutputFormat) * sizeof(double));
|
|
}
|
|
|
|
}
|
|
|
|
static
|
|
LPBYTE PackXYZDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
|
|
if (T_PLANAR(Info -> OutputFormat)) {
|
|
|
|
cmsCIEXYZ XYZ;
|
|
double* Out = (double*) output;
|
|
cmsXYZEncoded2Float(&XYZ, wOut);
|
|
|
|
Out[0] = XYZ.X;
|
|
Out[Info ->StrideOut] = XYZ.Y;
|
|
Out[Info ->StrideOut*2] = XYZ.Z;
|
|
|
|
return output + sizeof(double);
|
|
|
|
}
|
|
else {
|
|
|
|
cmsXYZEncoded2Float((LPcmsCIEXYZ) output, wOut);
|
|
|
|
return output + (sizeof(cmsCIEXYZ) + T_EXTRA(Info ->OutputFormat) * sizeof(double));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static
|
|
LPBYTE PackInkDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
double* Inks = (double*) output;
|
|
int nChan = T_CHANNELS(Info -> OutputFormat);
|
|
int i;
|
|
|
|
if (T_PLANAR(Info -> OutputFormat)) {
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
Inks[i*Info ->StrideOut] = wOut[i] / 655.35;
|
|
}
|
|
|
|
return output + sizeof(double);
|
|
}
|
|
else {
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
Inks[i] = wOut[i] / 655.35;
|
|
}
|
|
|
|
|
|
return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(double);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static
|
|
LPBYTE PackDouble(register _LPcmsTRANSFORM Info, register WORD wOut[], register LPBYTE output)
|
|
{
|
|
double* Inks = (double*) output;
|
|
int nChan = T_CHANNELS(Info -> OutputFormat);
|
|
int i;
|
|
|
|
|
|
if (T_PLANAR(Info -> OutputFormat)) {
|
|
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
Inks[i*Info ->StrideOut] = wOut[i] / 65535.0;
|
|
}
|
|
|
|
return output + sizeof(double);
|
|
|
|
}
|
|
else {
|
|
for (i=0; i < nChan; i++) {
|
|
|
|
Inks[i] = wOut[i] / 65535.0;
|
|
}
|
|
|
|
return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(double);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// choose routine from Input identifier
|
|
|
|
_cmsFIXFN _cmsIdentifyInputFormat(_LPcmsTRANSFORM xform, DWORD dwInput)
|
|
{
|
|
_cmsFIXFN FromInput = NULL;
|
|
|
|
|
|
// Check Named Color
|
|
|
|
if (xform) {
|
|
|
|
if (xform ->InputProfile) {
|
|
|
|
if (cmsGetDeviceClass(xform ->InputProfile) == icSigNamedColorClass) {
|
|
|
|
if (dwInput != TYPE_NAMED_COLOR_INDEX) {
|
|
cmsSignalError(LCMS_ERRC_ABORTED, "Named color needs TYPE_NAMED_COLOR_INDEX");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// Unencoded modes
|
|
|
|
if (T_BYTES(dwInput) == 0) {
|
|
|
|
switch (T_COLORSPACE(dwInput)) {
|
|
|
|
case PT_Lab:
|
|
FromInput = UnrollLabDouble;
|
|
break;
|
|
case PT_XYZ:
|
|
FromInput = UnrollXYZDouble;
|
|
break;
|
|
|
|
// 0.0 .. 1.0 range
|
|
|
|
case PT_GRAY:
|
|
case PT_RGB:
|
|
case PT_YCbCr:
|
|
case PT_YUV:
|
|
case PT_YUVK:
|
|
case PT_HSV:
|
|
case PT_HLS:
|
|
case PT_Yxy:
|
|
if (T_CHANNELS(dwInput) == 1)
|
|
FromInput = UnrollDouble1Chan;
|
|
else
|
|
FromInput = UnrollDouble;
|
|
break;
|
|
|
|
// Inks (%) 0.0 .. 100.0
|
|
|
|
default:
|
|
FromInput = UnrollInkDouble;
|
|
break;
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
if (T_PLANAR(dwInput)) {
|
|
|
|
switch (T_BYTES(dwInput)) {
|
|
|
|
case 1:
|
|
FromInput = UnrollPlanarBytes;
|
|
break;
|
|
|
|
case 2:
|
|
if (T_ENDIAN16(dwInput))
|
|
FromInput = UnrollPlanarWordsBigEndian;
|
|
else
|
|
FromInput = UnrollPlanarWords;
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
}
|
|
else {
|
|
|
|
switch (T_BYTES(dwInput)) {
|
|
|
|
case 1: // 1 byte per channel
|
|
|
|
switch (T_CHANNELS(dwInput) + T_EXTRA(dwInput)) {
|
|
|
|
case 1: if (T_FLAVOR(dwInput))
|
|
FromInput = Unroll1ByteReversed;
|
|
else
|
|
FromInput = Unroll1Byte;
|
|
break;
|
|
|
|
case 2: if (T_SWAPFIRST(dwInput))
|
|
FromInput = Unroll2ByteSwapFirst;
|
|
else
|
|
FromInput = Unroll2Byte;
|
|
break;
|
|
|
|
case 3: if (T_DOSWAP(dwInput))
|
|
FromInput = Unroll3BytesSwap;
|
|
else {
|
|
if (T_EXTRA(dwInput) == 2)
|
|
FromInput = Unroll1ByteSkip2;
|
|
else
|
|
if (T_COLORSPACE(dwInput) == PT_Lab)
|
|
FromInput = Unroll3BytesLab;
|
|
else
|
|
FromInput = Unroll3Bytes;
|
|
}
|
|
break;
|
|
case 4:
|
|
// TODO: ALab8 must be fixed to match v2 encoding
|
|
|
|
if (T_DOSWAP(dwInput)) {
|
|
if (T_SWAPFIRST(dwInput))
|
|
|
|
FromInput = Unroll4BytesSwapSwapFirst;
|
|
else
|
|
FromInput = Unroll4BytesSwap;
|
|
}
|
|
else {
|
|
if (T_SWAPFIRST(dwInput))
|
|
FromInput = Unroll4BytesSwapFirst;
|
|
else {
|
|
if (T_FLAVOR(dwInput))
|
|
FromInput = Unroll4BytesReverse;
|
|
else
|
|
FromInput = Unroll4Bytes;
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
if (!T_DOSWAP(dwInput) && !T_SWAPFIRST(dwInput))
|
|
FromInput = UnrollAnyBytes;
|
|
break;
|
|
|
|
|
|
default:;
|
|
}
|
|
break;
|
|
|
|
|
|
case 2: // 1 word per channel
|
|
|
|
switch (T_CHANNELS(dwInput) + T_EXTRA(dwInput))
|
|
{
|
|
case 1: if (T_ENDIAN16(dwInput))
|
|
FromInput = Unroll1WordBigEndian;
|
|
else
|
|
if (T_FLAVOR(dwInput))
|
|
FromInput = Unroll1WordReversed;
|
|
else
|
|
FromInput = Unroll1Word;
|
|
break;
|
|
|
|
case 2: if (T_ENDIAN16(dwInput))
|
|
FromInput = Unroll2WordBigEndian;
|
|
else {
|
|
if (T_SWAPFIRST(dwInput))
|
|
FromInput = Unroll2WordSwapFirst;
|
|
else
|
|
FromInput = Unroll2Word;
|
|
}
|
|
break;
|
|
|
|
case 3: if (T_DOSWAP(dwInput)) {
|
|
if (T_ENDIAN16(dwInput))
|
|
FromInput = Unroll3WordsSwapBigEndian;
|
|
else
|
|
FromInput = Unroll3WordsSwap;
|
|
}
|
|
else {
|
|
if (T_ENDIAN16(dwInput))
|
|
FromInput = Unroll3WordsBigEndian;
|
|
else
|
|
FromInput = Unroll3Words;
|
|
}
|
|
break;
|
|
|
|
case 4: if (T_DOSWAP(dwInput)) {
|
|
|
|
if (T_ENDIAN16(dwInput))
|
|
FromInput = Unroll4WordsSwapBigEndian;
|
|
else {
|
|
|
|
if (T_SWAPFIRST(dwInput))
|
|
FromInput = Unroll4WordsSwapSwapFirst;
|
|
else
|
|
FromInput = Unroll4WordsSwap;
|
|
|
|
}
|
|
|
|
}
|
|
else {
|
|
|
|
if (T_EXTRA(dwInput) == 3)
|
|
FromInput = Unroll1WordSkip3;
|
|
else
|
|
|
|
if (T_ENDIAN16(dwInput)) {
|
|
|
|
if (T_FLAVOR(dwInput))
|
|
FromInput = Unroll4WordsBigEndianReverse;
|
|
else
|
|
FromInput = Unroll4WordsBigEndian;
|
|
}
|
|
else {
|
|
if (T_SWAPFIRST(dwInput))
|
|
FromInput = Unroll4WordsSwapFirst;
|
|
else {
|
|
if (T_FLAVOR(dwInput))
|
|
FromInput = Unroll4WordsReverse;
|
|
else
|
|
FromInput = Unroll4Words;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
if (!T_DOSWAP(dwInput) && !T_SWAPFIRST(dwInput))
|
|
FromInput = UnrollAnyWords;
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (!FromInput)
|
|
cmsSignalError(LCMS_ERRC_ABORTED, "Unknown input format");
|
|
|
|
return FromInput;
|
|
}
|
|
|
|
// choose routine from Input identifier
|
|
|
|
_cmsFIXFN _cmsIdentifyOutputFormat(_LPcmsTRANSFORM xform, DWORD dwOutput)
|
|
{
|
|
_cmsFIXFN ToOutput = NULL;
|
|
|
|
|
|
if (T_BYTES(dwOutput) == 0) {
|
|
|
|
switch (T_COLORSPACE(dwOutput)) {
|
|
|
|
case PT_Lab:
|
|
ToOutput = PackLabDouble;
|
|
break;
|
|
case PT_XYZ:
|
|
ToOutput = PackXYZDouble;
|
|
break;
|
|
|
|
// 0.0 .. 1.0 range
|
|
case PT_GRAY:
|
|
case PT_RGB:
|
|
case PT_YCbCr:
|
|
case PT_YUV:
|
|
case PT_YUVK:
|
|
case PT_HSV:
|
|
case PT_HLS:
|
|
case PT_Yxy:
|
|
ToOutput = PackDouble;
|
|
break;
|
|
|
|
// Inks (%) 0.0 .. 100.0
|
|
|
|
default:
|
|
ToOutput = PackInkDouble;
|
|
break;
|
|
}
|
|
|
|
}
|
|
else
|
|
|
|
if (T_PLANAR(dwOutput)) {
|
|
|
|
switch (T_BYTES(dwOutput)) {
|
|
|
|
case 1: ToOutput = PackPlanarBytes;
|
|
break;
|
|
|
|
case 2:if (!T_ENDIAN16(dwOutput))
|
|
ToOutput = PackPlanarWords;
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
}
|
|
else {
|
|
|
|
switch (T_BYTES(dwOutput)) {
|
|
|
|
case 1:
|
|
switch (T_CHANNELS(dwOutput))
|
|
{
|
|
case 1:
|
|
if (T_DITHER(dwOutput))
|
|
ToOutput = PackNBytesDither;
|
|
else
|
|
ToOutput = Pack1Byte;
|
|
if (T_EXTRA(dwOutput) == 1) {
|
|
if (T_SWAPFIRST(dwOutput))
|
|
ToOutput = Pack1ByteAndSkip1SwapFirst;
|
|
else
|
|
ToOutput = Pack1ByteAndSkip1;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
switch (T_EXTRA(dwOutput)) {
|
|
|
|
case 0: if (T_DOSWAP(dwOutput))
|
|
ToOutput = Pack3BytesSwap;
|
|
else
|
|
if (T_COLORSPACE(dwOutput) == PT_Lab)
|
|
ToOutput = Pack3BytesLab;
|
|
else {
|
|
if (T_DITHER(dwOutput))
|
|
ToOutput = PackNBytesDither;
|
|
else
|
|
ToOutput = Pack3Bytes;
|
|
}
|
|
break;
|
|
|
|
case 1: // TODO: ALab8 should be handled here
|
|
|
|
if (T_DOSWAP(dwOutput)) {
|
|
|
|
if (T_SWAPFIRST(dwOutput))
|
|
ToOutput = Pack3BytesAndSkip1SwapSwapFirst;
|
|
else
|
|
ToOutput = Pack3BytesAndSkip1Swap;
|
|
}
|
|
else {
|
|
if (T_SWAPFIRST(dwOutput))
|
|
ToOutput = Pack3BytesAndSkip1SwapFirst;
|
|
else
|
|
ToOutput = Pack3BytesAndSkip1;
|
|
}
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
break;
|
|
|
|
case 4: if (T_EXTRA(dwOutput) == 0) {
|
|
|
|
|
|
if (T_DOSWAP(dwOutput)) {
|
|
|
|
|
|
if (T_SWAPFIRST(dwOutput)) {
|
|
ToOutput = Pack4BytesSwapSwapFirst;
|
|
}
|
|
else {
|
|
|
|
if (T_DITHER(dwOutput)) {
|
|
ToOutput = PackNBytesSwapDither;
|
|
}
|
|
else {
|
|
ToOutput = Pack4BytesSwap;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (T_SWAPFIRST(dwOutput))
|
|
ToOutput = Pack4BytesSwapFirst;
|
|
else {
|
|
|
|
if (T_FLAVOR(dwOutput))
|
|
ToOutput = Pack4BytesReverse;
|
|
else {
|
|
if (T_DITHER(dwOutput))
|
|
ToOutput = PackNBytesDither;
|
|
else
|
|
ToOutput = Pack4Bytes;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
|
|
ToOutput = PackNBytes;
|
|
}
|
|
break;
|
|
|
|
// Hexachrome separations.
|
|
case 6: if (T_EXTRA(dwOutput) == 0) {
|
|
|
|
if( T_DOSWAP(dwOutput))
|
|
ToOutput = Pack6BytesSwap;
|
|
else
|
|
ToOutput = Pack6Bytes;
|
|
}
|
|
else {
|
|
if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
|
|
ToOutput = PackNBytes;
|
|
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
case 5:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
case 14:
|
|
case 15:
|
|
|
|
if ((T_EXTRA(dwOutput) == 0) && (T_SWAPFIRST(dwOutput) == 0))
|
|
{
|
|
if (T_DOSWAP(dwOutput))
|
|
ToOutput = PackNBytesSwap;
|
|
else {
|
|
|
|
if (T_DITHER(dwOutput))
|
|
ToOutput = PackNBytesDither;
|
|
else
|
|
ToOutput = PackNBytes;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
switch (T_CHANNELS(dwOutput)) {
|
|
|
|
case 1:
|
|
if (T_ENDIAN16(dwOutput))
|
|
|
|
ToOutput = Pack1WordBigEndian;
|
|
else
|
|
ToOutput = Pack1Word;
|
|
|
|
if (T_EXTRA(dwOutput) == 1) {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
|
|
ToOutput = Pack1WordAndSkip1BigEndian;
|
|
else {
|
|
if (T_SWAPFIRST(dwOutput))
|
|
ToOutput = Pack1WordAndSkip1SwapFirst;
|
|
else
|
|
ToOutput = Pack1WordAndSkip1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
|
|
switch (T_EXTRA(dwOutput)) {
|
|
|
|
case 0:
|
|
if (T_DOSWAP(dwOutput)) {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
|
|
ToOutput = Pack3WordsSwapBigEndian;
|
|
else
|
|
ToOutput = Pack3WordsSwap;
|
|
}
|
|
else {
|
|
if (T_ENDIAN16(dwOutput))
|
|
|
|
ToOutput = Pack3WordsBigEndian;
|
|
else
|
|
ToOutput = Pack3Words;
|
|
}
|
|
break;
|
|
|
|
case 1: if (T_DOSWAP(dwOutput)) {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
|
|
ToOutput = Pack3WordsAndSkip1SwapBigEndian;
|
|
else {
|
|
if (T_SWAPFIRST(dwOutput))
|
|
ToOutput = Pack3WordsAndSkip1SwapSwapFirst;
|
|
else
|
|
ToOutput = Pack3WordsAndSkip1Swap;
|
|
}
|
|
}
|
|
else {
|
|
if (T_ENDIAN16(dwOutput))
|
|
ToOutput = Pack3WordsAndSkip1BigEndian;
|
|
else
|
|
ToOutput = Pack3WordsAndSkip1;
|
|
}
|
|
default:;
|
|
}
|
|
break;
|
|
|
|
case 4: if (T_EXTRA(dwOutput) == 0) {
|
|
|
|
if (T_DOSWAP(dwOutput)) {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
ToOutput = Pack4WordsSwapBigEndian;
|
|
else
|
|
ToOutput = Pack4WordsSwap;
|
|
}
|
|
else {
|
|
|
|
if (T_ENDIAN16(dwOutput)) {
|
|
|
|
if (T_FLAVOR(dwOutput))
|
|
ToOutput = Pack4WordsBigEndianReverse;
|
|
else
|
|
ToOutput = Pack4WordsBigEndian;
|
|
}
|
|
else {
|
|
if (T_FLAVOR(dwOutput))
|
|
ToOutput = Pack4WordsReverse;
|
|
else
|
|
ToOutput = Pack4Words;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
|
|
ToOutput = PackNWords;
|
|
}
|
|
break;
|
|
|
|
case 6: if (T_EXTRA(dwOutput) == 0) {
|
|
|
|
if (T_DOSWAP(dwOutput)) {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
ToOutput = Pack6WordsSwapBigEndian;
|
|
else
|
|
ToOutput = Pack6WordsSwap;
|
|
}
|
|
else {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
ToOutput = Pack6WordsBigEndian;
|
|
else
|
|
ToOutput = Pack6Words;
|
|
}
|
|
}
|
|
else {
|
|
if (!T_DOSWAP(dwOutput) && !T_SWAPFIRST(dwOutput))
|
|
ToOutput = PackNWords;
|
|
}
|
|
break;
|
|
|
|
|
|
case 2:
|
|
case 5:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
case 14:
|
|
case 15: if ((T_EXTRA(dwOutput) == 0) && (T_SWAPFIRST(dwOutput) == 0)) {
|
|
|
|
if (T_DOSWAP(dwOutput)) {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
ToOutput = PackNWordsSwapBigEndian;
|
|
else
|
|
ToOutput = PackNWordsSwap;
|
|
}
|
|
else {
|
|
|
|
if (T_ENDIAN16(dwOutput))
|
|
ToOutput = PackNWordsBigEndian;
|
|
else
|
|
ToOutput = PackNWords;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
break;
|
|
|
|
default:;
|
|
}
|
|
}
|
|
|
|
if (!ToOutput)
|
|
cmsSignalError(LCMS_ERRC_ABORTED, "Unknown output format");
|
|
|
|
return ToOutput;
|
|
}
|
|
|
|
// User formatters for (weird) cases not already included
|
|
|
|
void LCMSEXPORT cmsSetUserFormatters(cmsHTRANSFORM hTransform, DWORD dwInput, cmsFORMATTER Input,
|
|
DWORD dwOutput, cmsFORMATTER Output)
|
|
{
|
|
_LPcmsTRANSFORM xform = (_LPcmsTRANSFORM) (LPSTR) hTransform;
|
|
|
|
if (Input != NULL) {
|
|
xform ->FromInput = (_cmsFIXFN) Input;
|
|
xform ->InputFormat = dwInput;
|
|
}
|
|
|
|
if (Output != NULL) {
|
|
xform ->ToOutput = (_cmsFIXFN) Output;
|
|
xform ->OutputFormat = dwOutput;
|
|
}
|
|
|
|
}
|
|
|
|
void LCMSEXPORT cmsGetUserFormatters(cmsHTRANSFORM hTransform,
|
|
LPDWORD InputFormat, cmsFORMATTER* Input,
|
|
LPDWORD OutputFormat, cmsFORMATTER* Output)
|
|
{
|
|
_LPcmsTRANSFORM xform = (_LPcmsTRANSFORM) (LPSTR) hTransform;
|
|
|
|
if (Input) *Input = (cmsFORMATTER) xform ->FromInput;
|
|
if (InputFormat) *InputFormat = xform -> InputFormat;
|
|
if (Output) *Output = (cmsFORMATTER) xform ->ToOutput;
|
|
if (OutputFormat) *OutputFormat = xform -> OutputFormat;
|
|
}
|
|
|
|
|
|
// Change format of yet existing transform. No colorspace checking is performed
|
|
|
|
void LCMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
|
|
DWORD dwInputFormat,
|
|
DWORD dwOutputFormat)
|
|
{
|
|
|
|
cmsSetUserFormatters(hTransform,
|
|
dwInputFormat,
|
|
(cmsFORMATTER) _cmsIdentifyInputFormat((_LPcmsTRANSFORM) hTransform, dwInputFormat),
|
|
dwOutputFormat,
|
|
(cmsFORMATTER) _cmsIdentifyOutputFormat((_LPcmsTRANSFORM) hTransform, dwOutputFormat));
|
|
}
|