3030//---------------------------------------------------------------------------------
3131//
3232// Little Color Management System
33- // Copyright (c) 1998-2017 Marti Maria Saguer
33+ // Copyright (c) 1998-2020 Marti Maria Saguer
3434//
3535// Permission is hereby granted, free of charge, to any person obtaining
3636// a copy of this software and associated documentation files (the "Software"),
5757
5858// Alpha copy ------------------------------------------------------------------------------------------------------------------
5959
60+ // This macro return words stored as big endian
61+ #define CHANGE_ENDIAN (w ) (cmsUInt16Number) ((cmsUInt16Number) ((w)<<8)|((w)>>8))
62+
63+
6064// Floor to byte, taking care of saturation
6165cmsINLINE cmsUInt8Number _cmsQuickSaturateByte (cmsFloat64Number d )
6266{
@@ -103,6 +107,13 @@ void from8to16(void* dst, const void* src)
103107 * (cmsUInt16Number * ) dst = FROM_8_TO_16 (n );
104108}
105109
110+ static
111+ void from8to16SE (void * dst , const void * src )
112+ {
113+ cmsUInt8Number n = * (cmsUInt8Number * )src ;
114+ * (cmsUInt16Number * )dst = CHANGE_ENDIAN (FROM_8_TO_16 (n ));
115+ }
116+
106117static
107118void from8toFLT (void * dst , const void * src )
108119{
@@ -136,22 +147,50 @@ void from16to8(void* dst, const void* src)
136147 * (cmsUInt8Number * ) dst = FROM_16_TO_8 (n );
137148}
138149
150+ static
151+ void from16SEto8 (void * dst , const void * src )
152+ {
153+ cmsUInt16Number n = * (cmsUInt16Number * )src ;
154+ * (cmsUInt8Number * )dst = FROM_16_TO_8 (CHANGE_ENDIAN (n ));
155+ }
156+
139157static
140158void copy16 (void * dst , const void * src )
141159{
142160 memmove (dst , src , 2 );
143161}
144162
163+ static
164+ void from16to16 (void * dst , const void * src )
165+ {
166+ cmsUInt16Number n = * (cmsUInt16Number * )src ;
167+ * (cmsUInt16Number * )dst = CHANGE_ENDIAN (n );
168+ }
169+
170+ static
145171void from16toFLT (void * dst , const void * src )
146172{
147173 * (cmsFloat32Number * )dst = (* (cmsUInt16Number * )src ) / 65535.0f ;
148174}
149175
176+ static
177+ void from16SEtoFLT (void * dst , const void * src )
178+ {
179+ * (cmsFloat32Number * )dst = (CHANGE_ENDIAN (* (cmsUInt16Number * )src )) / 65535.0f ;
180+ }
181+
182+ static
150183void from16toDBL (void * dst , const void * src )
151184{
152185 * (cmsFloat64Number * )dst = (* (cmsUInt16Number * )src ) / 65535.0f ;
153186}
154187
188+ static
189+ void from16SEtoDBL (void * dst , const void * src )
190+ {
191+ * (cmsFloat64Number * )dst = (CHANGE_ENDIAN (* (cmsUInt16Number * )src )) / 65535.0f ;
192+ }
193+
155194static
156195void from16toHLF (void * dst , const void * src )
157196{
@@ -164,33 +203,53 @@ void from16toHLF(void* dst, const void* src)
164203#endif
165204}
166205
206+ static
207+ void from16SEtoHLF (void * dst , const void * src )
208+ {
209+ #ifndef CMS_NO_HALF_SUPPORT
210+ cmsFloat32Number n = (CHANGE_ENDIAN (* (cmsUInt16Number * )src )) / 65535.0f ;
211+ * (cmsUInt16Number * )dst = _cmsFloat2Half (n );
212+ #else
213+ cmsUNUSED_PARAMETER (dst );
214+ cmsUNUSED_PARAMETER (src );
215+ #endif
216+ }
167217// From Float
168218
169219static
170220void fromFLTto8 (void * dst , const void * src )
171221{
172- cmsFloat32Number n = * (cmsFloat32Number * )src ;
173- * (cmsUInt8Number * )dst = _cmsQuickSaturateByte (n * 255.0f );
222+ cmsFloat32Number n = * (cmsFloat32Number * )src ;
223+ * (cmsUInt8Number * )dst = _cmsQuickSaturateByte (n * 255.0f );
174224}
175225
176226static
177227void fromFLTto16 (void * dst , const void * src )
178228{
179- cmsFloat32Number n = * (cmsFloat32Number * )src ;
180- * (cmsUInt16Number * )dst = _cmsQuickSaturateWord (n * 65535.0f );
229+ cmsFloat32Number n = * (cmsFloat32Number * )src ;
230+ * (cmsUInt16Number * )dst = _cmsQuickSaturateWord (n * 65535.0f );
231+ }
232+
233+ static
234+ void fromFLTto16SE (void * dst , const void * src )
235+ {
236+ cmsFloat32Number n = * (cmsFloat32Number * )src ;
237+ cmsUInt16Number i = _cmsQuickSaturateWord (n * 65535.0f );
238+
239+ * (cmsUInt16Number * )dst = CHANGE_ENDIAN (i );
181240}
182241
183242static
184243void copy32 (void * dst , const void * src )
185244{
186- memmove (dst , src , sizeof (cmsFloat32Number ));
245+ memmove (dst , src , sizeof (cmsFloat32Number ));
187246}
188247
189248static
190249void fromFLTtoDBL (void * dst , const void * src )
191250{
192- cmsFloat32Number n = * (cmsFloat32Number * )src ;
193- * (cmsFloat64Number * )dst = (cmsFloat64Number )n ;
251+ cmsFloat32Number n = * (cmsFloat32Number * )src ;
252+ * (cmsFloat64Number * )dst = (cmsFloat64Number )n ;
194253}
195254
196255static
@@ -233,6 +292,19 @@ void fromHLFto16(void* dst, const void* src)
233292#endif
234293}
235294
295+ static
296+ void fromHLFto16SE (void * dst , const void * src )
297+ {
298+ #ifndef CMS_NO_HALF_SUPPORT
299+ cmsFloat32Number n = _cmsHalf2Float (* (cmsUInt16Number * )src );
300+ cmsUInt16Number i = _cmsQuickSaturateWord (n * 65535.0f );
301+ * (cmsUInt16Number * )dst = CHANGE_ENDIAN (i );
302+ #else
303+ cmsUNUSED_PARAMETER (dst );
304+ cmsUNUSED_PARAMETER (src );
305+ #endif
306+ }
307+
236308static
237309void fromHLFtoFLT (void * dst , const void * src )
238310{
@@ -270,6 +342,14 @@ void fromDBLto16(void* dst, const void* src)
270342 * (cmsUInt16Number * )dst = _cmsQuickSaturateWord (n * 65535.0f );
271343}
272344
345+ static
346+ void fromDBLto16SE (void * dst , const void * src )
347+ {
348+ cmsFloat64Number n = * (cmsFloat64Number * )src ;
349+ cmsUInt16Number i = _cmsQuickSaturateWord (n * 65535.0f );
350+ * (cmsUInt16Number * )dst = CHANGE_ENDIAN (i );
351+ }
352+
273353static
274354void fromDBLtoFLT (void * dst , const void * src )
275355{
@@ -303,37 +383,42 @@ int FormatterPos(cmsUInt32Number frm)
303383 cmsUInt32Number b = T_BYTES (frm );
304384
305385 if (b == 0 && T_FLOAT (frm ))
306- return 4 ; // DBL
386+ return 5 ; // DBL
307387#ifndef CMS_NO_HALF_SUPPORT
308388 if (b == 2 && T_FLOAT (frm ))
309- return 2 ; // HLF
389+ return 3 ; // HLF
310390#endif
311391 if (b == 4 && T_FLOAT (frm ))
312- return 3 ; // FLT
392+ return 4 ; // FLT
313393 if (b == 2 && !T_FLOAT (frm ))
314- return 1 ; // 16
394+ {
395+ if (T_ENDIAN16 (frm ))
396+ return 2 ; // 16SE
397+ else
398+ return 1 ; // 16
399+ }
315400 if (b == 1 && !T_FLOAT (frm ))
316401 return 0 ; // 8
317-
318402 return -1 ; // not recognized
319403}
320404
321- // Obtains a alpha-to-alpha funmction formatter
405+ // Obtains an alpha-to-alpha function formatter
322406static
323407cmsFormatterAlphaFn _cmsGetFormatterAlpha (cmsContext id , cmsUInt32Number in , cmsUInt32Number out )
324408{
325- static cmsFormatterAlphaFn FormattersAlpha [5 ][ 5 ] = {
409+ static cmsFormatterAlphaFn FormattersAlpha [6 ][ 6 ] = {
326410
327- /* from 8 */ { copy8 , from8to16 , from8toHLF , from8toFLT , from8toDBL },
328- /* from 16*/ { from16to8 , copy16 , from16toHLF , from16toFLT , from16toDBL },
329- /* from HLF*/ { fromHLFto8 , fromHLFto16 , copy16 , fromHLFtoFLT , fromHLFtoDBL },
330- /* from FLT*/ { fromFLTto8 , fromFLTto16 , fromFLTtoHLF , copy32 , fromFLTtoDBL },
331- /* from DBL*/ { fromDBLto8 , fromDBLto16 , fromDBLtoHLF , fromDBLtoFLT , copy64 }};
411+ /* from 8 */ { copy8 , from8to16 , from8to16SE , from8toHLF , from8toFLT , from8toDBL },
412+ /* from 16*/ { from16to8 , copy16 , from16to16 , from16toHLF , from16toFLT , from16toDBL },
413+ /* from 16SE*/ { from16SEto8 , from16to16 , copy16 , from16SEtoHLF ,from16SEtoFLT , from16SEtoDBL },
414+ /* from HLF*/ { fromHLFto8 , fromHLFto16 , fromHLFto16SE , copy16 , fromHLFtoFLT , fromHLFtoDBL },
415+ /* from FLT*/ { fromFLTto8 , fromFLTto16 , fromFLTto16SE , fromFLTtoHLF , copy32 , fromFLTtoDBL },
416+ /* from DBL*/ { fromDBLto8 , fromDBLto16 , fromDBLto16SE , fromDBLtoHLF , fromDBLtoFLT , copy64 }};
332417
333418 int in_n = FormatterPos (in );
334419 int out_n = FormatterPos (out );
335420
336- if (in_n < 0 || out_n < 0 || in_n > 4 || out_n > 4 ) {
421+ if (in_n < 0 || out_n < 0 || in_n > 5 || out_n > 5 ) {
337422
338423 cmsSignalError (id , cmsERROR_UNKNOWN_EXTENSION , "Unrecognized alpha channel width" );
339424 return NULL ;
@@ -515,6 +600,8 @@ void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
515600
516601 // Check for conversions 8, 16, half, float, dbl
517602 copyValueFn = _cmsGetFormatterAlpha (p -> ContextID , p -> InputFormat , p -> OutputFormat );
603+ if (copyValueFn == NULL )
604+ return ;
518605
519606 if (nExtra == 1 ) { // Optimized routine for copying a single extra channel quickly
520607
0 commit comments