< prev index next >

src/java.desktop/share/native/liblcms/cmsalpha.c

Print this page

        

@@ -28,11 +28,11 @@
 // file:
 //
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2017 Marti Maria Saguer
+//  Copyright (c) 1998-2020 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,

@@ -55,10 +55,14 @@
 
 #include "lcms2_internal.h"
 
 // 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)
 {
        d += 0.5;
        if (d <= 0) return 0;

@@ -102,10 +106,17 @@
        cmsUInt8Number n = *(cmsUInt8Number*)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)
 {
        *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
 }
 

@@ -135,26 +146,54 @@
        cmsUInt16Number n = *(cmsUInt16Number*)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);
+}
+
+static
 void from16toFLT(void* dst, const void* src)
 {
        *(cmsFloat32Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
 }
 
+static
+void from16SEtoFLT(void* dst, const void* src)
+{
+    *(cmsFloat32Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
+}
+
+static
 void from16toDBL(void* dst, const void* src)
 {
        *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
 }
 
 static
+void from16SEtoDBL(void* dst, const void* src)
+{
+    *(cmsFloat64Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
+}
+
+static
 void from16toHLF(void* dst, const void* src)
 {
 #ifndef CMS_NO_HALF_SUPPORT
        cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f;
        *(cmsUInt16Number*)dst = _cmsFloat2Half(n);

@@ -162,10 +201,21 @@
     cmsUNUSED_PARAMETER(dst);
     cmsUNUSED_PARAMETER(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
 void fromFLTto8(void* dst, const void* src)
 {

@@ -179,10 +229,19 @@
        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));
 }
 

@@ -232,10 +291,23 @@
     cmsUNUSED_PARAMETER(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)
 {
 #ifndef CMS_NO_HALF_SUPPORT
        *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src);
 #else

@@ -269,10 +341,18 @@
        cmsFloat64Number n = *(cmsFloat64Number*)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)
 {
        cmsFloat64Number n = *(cmsFloat64Number*)src;
        *(cmsFloat32Number*)dst = (cmsFloat32Number) n;
 }

@@ -301,41 +381,46 @@
 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))
+    {
+        if (T_ENDIAN16(frm))
+            return 2; // 16SE
+        else
         return 1; // 16
+    }
     if (b == 1 && !T_FLOAT(frm))
         return 0; // 8
-
     return -1; // not recognized
 }
 
-// Obtains a alpha-to-alpha funmction formatter
+// Obtains an alpha-to-alpha function formatter
 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);
 
-        if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4) {
+        if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5) {
 
                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized alpha channel width");
                return NULL;
         }
 

@@ -513,10 +598,12 @@
     ComputeComponentIncrements(p->InputFormat, Stride->BytesPerPlaneIn, SourceStartingOrder, SourceIncrements);
     ComputeComponentIncrements(p->OutputFormat, Stride->BytesPerPlaneOut, DestStartingOrder, DestIncrements);
 
     // Check for conversions 8, 16, half, float, dbl
     copyValueFn = _cmsGetFormatterAlpha(p->ContextID, p->InputFormat, p->OutputFormat);
+    if (copyValueFn == NULL)
+        return;
 
     if (nExtra == 1) { // Optimized routine for copying a single extra channel quickly
 
         cmsUInt8Number* SourcePtr;
         cmsUInt8Number* DestPtr;
< prev index next >