From 30e8719c18baf8e88de537c8c5e5b009029c3392 Mon Sep 17 00:00:00 2001 From: Marti Maria Date: Wed, 2 May 2018 18:01:01 +0200 Subject: add swapped-endian formats in alpha handling fixes #159 --- src/cmsalpha.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/cmsalpha.c b/src/cmsalpha.c index 6dae644..ae9f3d9 100644 --- a/src/cmsalpha.c +++ b/src/cmsalpha.c @@ -28,6 +28,10 @@ // Alpha copy ------------------------------------------------------------------------------------------------------------------ +// This macro return words stored as big endian +#define CHANGE_ENDIAN(w) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8)) + + // Floor to byte, taking care of saturation cmsINLINE cmsUInt8Number _cmsQuickSaturateByte(cmsFloat64Number d) { @@ -74,6 +78,13 @@ void from8to16(void* dst, const void* src) *(cmsUInt16Number*) dst = FROM_8_TO_16(n); } +static +void from8to16SE(void* dst, const void* src) +{ + cmsUInt8Number n = *(cmsUInt8Number*)src; + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(FROM_8_TO_16(n)); +} + static void from8toFLT(void* dst, const void* src) { @@ -107,22 +118,46 @@ void from16to8(void* dst, const void* src) *(cmsUInt8Number*) dst = FROM_16_TO_8(n); } +static +void from16SEto8(void* dst, const void* src) +{ + cmsUInt16Number n = *(cmsUInt16Number*)src; + *(cmsUInt8Number*)dst = FROM_16_TO_8(CHANGE_ENDIAN(n)); +} + static void copy16(void* dst, const void* src) { memmove(dst, src, 2); } +static +void from16to16(void* dst, const void* src) +{ + cmsUInt16Number n = *(cmsUInt16Number*)src; + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(n); +} + void from16toFLT(void* dst, const void* src) { *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f; } +void from16SEtoFLT(void* dst, const void* src) +{ + *(cmsFloat32Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f; +} + void from16toDBL(void* dst, const void* src) { *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f; } +void from16SEtoDBL(void* dst, const void* src) +{ + *(cmsFloat64Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f; +} + static void from16toHLF(void* dst, const void* src) { @@ -135,33 +170,53 @@ void from16toHLF(void* dst, const void* src) #endif } +static +void from16SEtoHLF(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f; + *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} // From Float -static +static void fromFLTto8(void* dst, const void* src) { - cmsFloat32Number n = *(cmsFloat32Number*)src; - *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f); + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f); } static void fromFLTto16(void* dst, const void* src) { - cmsFloat32Number n = *(cmsFloat32Number*)src; - *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f); + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f); +} + +static +void fromFLTto16SE(void* dst, const void* src) +{ + cmsFloat32Number n = *(cmsFloat32Number*)src; + cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0f); + + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); } static void copy32(void* dst, const void* src) { - memmove(dst, src, sizeof(cmsFloat32Number)); + memmove(dst, src, sizeof(cmsFloat32Number)); } static void fromFLTtoDBL(void* dst, const void* src) { - cmsFloat32Number n = *(cmsFloat32Number*)src; - *(cmsFloat64Number*)dst = (cmsFloat64Number)n; + cmsFloat32Number n = *(cmsFloat32Number*)src; + *(cmsFloat64Number*)dst = (cmsFloat64Number)n; } static @@ -204,6 +259,18 @@ void fromHLFto16(void* dst, const void* src) #endif } +static +void fromHLFto16SE(void* dst, const void* src) +{ +#ifndef CMS_NO_HALF_SUPPORT + cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); + cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0f); + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif +} static void fromHLFtoFLT(void* dst, const void* src) { @@ -241,6 +308,13 @@ void fromDBLto16(void* dst, const void* src) *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f); } +static +void fromDBLto16SE(void* dst, const void* src) +{ + cmsFloat64Number n = *(cmsFloat64Number*)src; + cmsUInt16Number i = _cmsQuickSaturateWord(n * 65535.0f); + *(cmsUInt16Number*)dst = CHANGE_ENDIAN(i); +} static void fromDBLtoFLT(void* dst, const void* src) { @@ -274,18 +348,19 @@ int FormatterPos(cmsUInt32Number frm) cmsUInt32Number b = T_BYTES(frm); if (b == 0 && T_FLOAT(frm)) - return 4; // DBL + return 5; // DBL #ifndef CMS_NO_HALF_SUPPORT if (b == 2 && T_FLOAT(frm)) - return 2; // HLF + return 3; // HLF #endif if (b == 4 && T_FLOAT(frm)) - return 3; // FLT + return 4; // FLT if (b == 2 && !T_FLOAT(frm)) return 1; // 16 if (b == 1 && !T_FLOAT(frm)) return 0; // 8 - + if (b == 2 && T_ENDIAN16(frm)) + return 3; return -1; // not recognized } @@ -293,13 +368,14 @@ int FormatterPos(cmsUInt32Number frm) static cmsFormatterAlphaFn _cmsGetFormatterAlpha(cmsContext id, cmsUInt32Number in, cmsUInt32Number out) { -static cmsFormatterAlphaFn FormattersAlpha[5][5] = { +static cmsFormatterAlphaFn FormattersAlpha[6][6] = { - /* from 8 */ { copy8, from8to16, from8toHLF, from8toFLT, from8toDBL }, - /* from 16*/ { from16to8, copy16, from16toHLF, from16toFLT, from16toDBL }, - /* from HLF*/ { fromHLFto8, fromHLFto16, copy16, fromHLFtoFLT, fromHLFtoDBL }, - /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTtoHLF, copy32, fromFLTtoDBL }, - /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLtoHLF, fromDBLtoFLT, copy64 }}; + /* from 8 */ { copy8, from8to16, from8to16SE, from8toHLF, from8toFLT, from8toDBL }, + /* from 16*/ { from16to8, copy16, from16to16, from16toHLF, from16toFLT, from16toDBL }, + /* from 16SE*/{ from16SEto8, from16to16, copy16, from16SEtoHLF,from16SEtoFLT, from16SEtoDBL }, + /* from HLF*/ { fromHLFto8, fromHLFto16, fromHLFto16SE, copy16, fromHLFtoFLT, fromHLFtoDBL }, + /* from FLT*/ { fromFLTto8, fromFLTto16, fromFLTto16SE, fromFLTtoHLF, copy32, fromFLTtoDBL }, + /* from DBL*/ { fromDBLto8, fromDBLto16, fromDBLto16SE, fromDBLtoHLF, fromDBLtoFLT, copy64 }}; int in_n = FormatterPos(in); int out_n = FormatterPos(out); -- cgit v1.2.1