#include "fast_float_internal.h"
cmsINLINE cmsUInt16Number From16To15(cmsUInt16Number x16)
{
cmsUInt64Number r64 = (((cmsUInt64Number)x16 << 15)) / 0xFFFFL;
return (cmsUInt16Number)r64;
}
cmsINLINE cmsUInt16Number From15To16(cmsUInt16Number x15)
{
cmsUInt64Number r64 = ((cmsUInt64Number) x15 * 0xFFFF + 0x4000L) >> 15;
return (cmsUInt16Number)r64;
}
static
cmsUInt8Number* Unroll15bitsGray(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
Values[0] = From15To16(*(cmsUInt16Number*)Buffer);
return Buffer + 2;
}
static
cmsUInt8Number* Pack15bitsGray(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
*(cmsUInt16Number*)Buffer = From16To15(Values[0]);
return Buffer + 2;
}
static
cmsUInt8Number* Unroll15bitsRGB(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
Values[0] = From15To16(*(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[1] = From15To16(*(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[2] = From15To16(*(cmsUInt16Number*)Buffer);
return Buffer + 2;
}
static
cmsUInt8Number* Pack15bitsRGB(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
*(cmsUInt16Number*)Buffer = From16To15(Values[0]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = From16To15(Values[1]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = From16To15(Values[2]);
return Buffer + 2;
}
static
cmsUInt8Number* Unroll15bitsRGBA(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
Values[0] = From15To16(*(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[1] = From15To16(*(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[2] = From15To16(*(cmsUInt16Number*)Buffer);
return Buffer + 4;
}
static
cmsUInt8Number* Pack15bitsRGBA(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
*(cmsUInt16Number*)Buffer = From16To15(Values[0]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = From16To15(Values[1]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = From16To15(Values[2]);
return Buffer + 4;
}
static
cmsUInt8Number* Unroll15bitsBGR(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
Values[2] = From15To16(*(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[1] = From15To16(*(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[0] = From15To16(*(cmsUInt16Number*)Buffer);
return Buffer + 2;
}
static
cmsUInt8Number* Pack15bitsBGR(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
*(cmsUInt16Number*)Buffer = From16To15(Values[2]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = From16To15(Values[1]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = From16To15(Values[0]);
return Buffer+2;
}
static
cmsUInt8Number* Unroll15bitsCMYK(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
Values[0] = From15To16(0x8000 - *(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[1] = From15To16(0x8000 - *(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[2] = From15To16(0x8000 - *(cmsUInt16Number*)Buffer);
Buffer += 2;
Values[3] = From15To16(0x8000 - *(cmsUInt16Number*)Buffer);
return Buffer + 2;
}
static
cmsUInt8Number* Pack15bitsCMYK(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
UNUSED_PARAMETER(CMMcargo);
UNUSED_PARAMETER(Stride);
*(cmsUInt16Number*)Buffer = 0x8000U - From16To15(Values[0]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = 0x8000U - From16To15(Values[1]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = 0x8000U - From16To15(Values[2]);
Buffer += 2;
*(cmsUInt16Number*)Buffer = 0x8000U - From16To15(Values[3]);
return Buffer + 2;
}
cmsINLINE cmsUInt16Number UnrollOne(cmsUInt16Number x, cmsBool Reverse, cmsBool SwapEndian)
{
if (SwapEndian)
x = (x << 8) | (x >> 8);
if (Reverse)
x = 0xffff - x;
return From15To16(x);
}
cmsINLINE cmsUInt16Number PackOne(cmsUInt16Number x, cmsBool Reverse, cmsBool SwapEndian)
{
x = From16To15(x);
if (Reverse)
x = 0xffff - x;
if (SwapEndian)
x = (x << 8) | (x >> 8);
return x;
}
static
cmsUInt8Number* Unroll15bitsPlanar(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number wIn[],
CMSREGISTER cmsUInt8Number* accum,
CMSREGISTER cmsUInt32Number Stride)
{
_xform_head* head = (_xform_head*) CMMcargo;
int nChan = T_CHANNELS(head->InputFormat);
int DoSwap = T_DOSWAP(head->InputFormat);
int Reverse = T_FLAVOR(head->InputFormat);
int SwapEndian = T_ENDIAN16(head->InputFormat);
int i;
cmsUInt8Number* Init = accum;
UNUSED_PARAMETER(Stride);
if (DoSwap) {
accum += T_EXTRA(head->InputFormat) * Stride * 2;
}
for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
wIn[index] = UnrollOne(*(cmsUInt16Number*)accum, Reverse, SwapEndian);
accum += Stride * 2;
}
return (Init + 2);
}
static
cmsUInt8Number* Pack15bitsPlanar(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number wOut[],
CMSREGISTER cmsUInt8Number* output,
CMSREGISTER cmsUInt32Number Stride)
{
_xform_head* head = (_xform_head*)CMMcargo;
int nChan = T_CHANNELS(head->OutputFormat);
int DoSwap = T_DOSWAP(head->OutputFormat);
int Reverse = T_FLAVOR(head->OutputFormat);
int SwapEndian = T_ENDIAN16(head->OutputFormat);
CMSREGISTER int i;
cmsUInt8Number* Init = output;
if (DoSwap) {
output += T_EXTRA(head->OutputFormat) * Stride * 2;
}
for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
*(cmsUInt16Number*)output = PackOne(wOut[index], Reverse, SwapEndian);
output += (Stride * sizeof(cmsUInt16Number));
}
return (Init + sizeof(cmsUInt16Number));
}
static
cmsUInt8Number* Unroll15bitsChunky(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
_xform_head* head = (_xform_head*) CMMcargo;
int nChan = T_CHANNELS(head->InputFormat);
int DoSwap = T_DOSWAP(head->InputFormat);
int Reverse = T_FLAVOR(head->InputFormat);
int SwapEndian = T_ENDIAN16(head->InputFormat);
CMSREGISTER int i;
UNUSED_PARAMETER(Stride);
if (DoSwap) {
Buffer += T_EXTRA(head->OutputFormat) * 2;
}
for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
Values[index] = UnrollOne(*(cmsUInt16Number*)Buffer, Reverse, SwapEndian);
Buffer += 2;
}
return Buffer;
}
static
cmsUInt8Number* Pack15bitsChunky(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
_xform_head* head = (_xform_head*)CMMcargo;
int nChan = T_CHANNELS(head->OutputFormat);
int DoSwap = T_DOSWAP(head->OutputFormat);
int Reverse = T_FLAVOR(head->OutputFormat);
int SwapEndian = T_ENDIAN16(head->OutputFormat);
CMSREGISTER int i;
UNUSED_PARAMETER(Stride);
if (DoSwap) {
Buffer += T_EXTRA(head->OutputFormat) * 2;
}
for (i = 0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
*(cmsUInt16Number*)Buffer = PackOne(Values[index], Reverse, SwapEndian);
Buffer += 2;
}
return Buffer;
}
static int err[cmsMAXCHANNELS];
static
cmsUInt8Number* PackNBytesDither(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
_xform_head* info = (_xform_head*)CMMcargo;
int nChan = T_CHANNELS(info->OutputFormat);
CMSREGISTER int i;
unsigned int n, pe, pf;
UNUSED_PARAMETER(Stride);
for (i = 0; i < nChan; i++) {
n = Values[i] + err[i];
pe = (n / 257); pf = (n % 257);
err[i] = pf;
*Buffer++ = (cmsUInt8Number) pe;
}
return Buffer + T_EXTRA(info->OutputFormat);
}
static
cmsUInt8Number* PackNBytesSwapDither(CMSREGISTER struct _cmstransform_struct* CMMcargo,
CMSREGISTER cmsUInt16Number Values[],
CMSREGISTER cmsUInt8Number* Buffer,
CMSREGISTER cmsUInt32Number Stride)
{
_xform_head* info = (_xform_head*)CMMcargo;
int nChan = T_CHANNELS(info->OutputFormat);
CMSREGISTER int i;
unsigned int n, pe, pf;
UNUSED_PARAMETER(Stride);
for (i = nChan - 1; i >= 0; --i) {
n = Values[i] + err[i];
pe = (n / 257); pf = (n % 257);
err[i] = pf;
*Buffer++ = (cmsUInt8Number)pe;
}
return Buffer + T_EXTRA(info->OutputFormat);
}
CMSCHECKPOINT cmsFormatter CMSEXPORT Formatter_15Bit_Factory(cmsUInt32Number Type,
cmsFormatterDirection Dir,
cmsUInt32Number dwFlags)
{
cmsFormatter Result = { NULL };
UNUSED_PARAMETER(dwFlags);
switch (Type) {
case TYPE_GRAY_15:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsGray : Pack15bitsGray;
break;
case TYPE_CMY_15:
case TYPE_RGB_15:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsRGB : Pack15bitsRGB;
break;
case TYPE_YMC_15:
case TYPE_BGR_15:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsBGR : Pack15bitsBGR;
break;
case TYPE_RGBA_15:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsRGBA : Pack15bitsRGBA;
break;
case TYPE_CMYK_15:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsCMYK : Pack15bitsCMYK;
break;
case TYPE_GRAYA_15_PLANAR:
case TYPE_RGB_15_PLANAR:
case TYPE_BGR_15_PLANAR:
case TYPE_RGBA_15_PLANAR:
case TYPE_ABGR_15_PLANAR:
case TYPE_CMY_15_PLANAR:
case TYPE_CMYK_15_PLANAR:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsPlanar : Pack15bitsPlanar;
break;
case TYPE_GRAY_15_REV:
case TYPE_GRAY_15_SE:
case TYPE_GRAYA_15:
case TYPE_GRAYA_15_SE:
case TYPE_RGB_15_SE:
case TYPE_BGR_15_SE:
case TYPE_RGBA_15_SE:
case TYPE_ARGB_15:
case TYPE_ABGR_15:
case TYPE_ABGR_15_SE:
case TYPE_BGRA_15:
case TYPE_BGRA_15_SE:
case TYPE_CMY_15_SE:
case TYPE_CMYK_15_REV:
case TYPE_CMYK_15_SE:
case TYPE_KYMC_15:
case TYPE_KYMC_15_SE:
case TYPE_KCMY_15:
case TYPE_KCMY_15_REV:
case TYPE_KCMY_15_SE:
Result.Fmt16 = (Dir == cmsFormatterInput) ? Unroll15bitsChunky : Pack15bitsChunky;
break;
case TYPE_GRAY_8_DITHER:
case TYPE_RGB_8_DITHER:
case TYPE_RGBA_8_DITHER:
case TYPE_CMYK_8_DITHER:
if (Dir == cmsFormatterOutput) {
Result.Fmt16 = PackNBytesDither;
}
break;
case TYPE_ABGR_8_DITHER:
case TYPE_BGR_8_DITHER:
case TYPE_KYMC_8_DITHER:
if (Dir == cmsFormatterOutput) {
Result.Fmt16 = PackNBytesSwapDither;
}
break;
default:;
}
return Result;
}