1 /* babl - dynamically extendable universal pixel conversion library.
2 * Copyright (C) 2015 Daniel Sabo
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 3 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see
17 * <https://www.gnu.org/licenses/>.
20 /* Copyright: (c) 2009 by James Tursa, All Rights Reserved
22 * This code uses the BSD License:
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions are
28 * * Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * * Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in
32 * the documentation and/or other materials provided with the distribution
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
35 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
38 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44 * POSSIBILITY OF SUCH DAMAGE.
46 * halfprecision converts the input argument to/from a half precision floating
47 * point bit pattern corresponding to IEEE 754r. The bit pattern is stored in a
48 * uint16 class variable. Please note that halfprecision is *not* a class. That
49 * is, you cannot do any arithmetic with the half precision bit patterns.
50 * halfprecision is simply a function that converts the IEEE 754r half precision
51 * bit pattern to/from other numeric MATLAB variables. You can, however, take
52 * the half precision bit patterns, convert them to single or double, do the
53 * operation, and then convert the result back manually.
56 * 5 bits exponent, biased by 15
57 * 10 bits mantissa, hidden leading bit, normalized to 1.0
59 * Special floating point bit patterns recognized and supported:
61 * All exponent bits zero:
62 * - If all mantissa bits are zero, then number is zero (possibly signed)
63 * - Otherwise, number is a denormalized bit pattern
65 * All exponent bits set to 1:
66 * - If all mantissa bits are zero, then number is +Infinity or -Infinity
67 * - Otherwise, number is NaN (Not a Number)
76 #include "extensions/util.h"
79 halfp2singles_fun(void *target
,
83 uint16_t *hp
= (uint16_t *) source
; // Type pun input as an unsigned 16-bit int
84 uint32_t *xp
= (uint32_t *) target
; // Type pun output as an unsigned 32-bit int
85 uint16_t h
, hs
, he
, hm
;
90 if( source
== NULL
|| target
== NULL
) // Nothing to convert (e.g., imag part of pure real)
94 if( (h
& 0x7FFFu
) == 0 ) { // Signed zero
95 *xp
++ = ((uint32_t) h
) << 16; // Return the signed zero
97 hs
= h
& 0x8000u
; // Pick off sign bit
98 he
= h
& 0x7C00u
; // Pick off exponent bits
99 hm
= h
& 0x03FFu
; // Pick off mantissa bits
100 if( he
== 0 ) { // Denormal will convert to normalized
101 e
= -1; // The following loop figures out how much extra to adjust the exponent
105 } while( (hm
& 0x0400u
) == 0 ); // Shift until leading bit overflows into exponent bit
106 xs
= ((uint32_t) hs
) << 16; // Sign bit
107 xes
= ((int32_t) (he
>> 10)) - 15 + 127 - e
; // Exponent unbias the halfp, then bias the single
108 xe
= (uint32_t) (xes
<< 23); // Exponent
109 xm
= ((uint32_t) (hm
& 0x03FFu
)) << 13; // Mantissa
110 *xp
++ = (xs
| xe
| xm
); // Combine sign bit, exponent bits, and mantissa bits
111 } else if( he
== 0x7C00u
) { // Inf or NaN (all the exponent bits are set)
112 if( hm
== 0 ) { // If mantissa is zero ...
113 *xp
++ = (((uint32_t) hs
) << 16) | ((uint32_t) 0x7F800000u
); // Signed Inf
115 *xp
++ = (uint32_t) 0xFFC00000u
; // NaN, only 1st mantissa bit set
117 } else { // Normalized number
118 xs
= ((uint32_t) hs
) << 16; // Sign bit
119 xes
= ((int32_t) (he
>> 10)) - 15 + 127; // Exponent unbias the halfp, then bias the single
120 xe
= (uint32_t) (xes
<< 23); // Exponent
121 xm
= ((uint32_t) hm
) << 13; // Mantissa
122 *xp
++ = (xs
| xe
| xm
); // Combine sign bit, exponent bits, and mantissa bits
128 static float half_float_table
[65536];
131 halfp2singles(void *target
,
135 uint16_t *src
= (uint16_t *) source
;
136 float *dst
= (float *) target
;
138 for (i
= 0; i
< numel
; i
++)
140 dst
[i
] = half_float_table
[src
[i
]];
144 /* from table based approach from qcms/blink/webkit */
146 const unsigned short half_float_base_table
[512] = {
147 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
148 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
149 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
150 0,0,0,0,0,0,0,1,2,4,8,16,32,64,128,256,
151 512,1024,2048,3072,4096,5120,6144,7168,8192,9216,10240,11264,12288,13312,14336,15360,
152 16384,17408,18432,19456,20480,21504,22528,23552,24576,25600,26624,27648,28672,29696,30720,31744,
153 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
154 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
155 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
156 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
157 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
158 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
159 31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,31744,
160 32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,
161 32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,
162 32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,
163 32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,
164 32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,
165 32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,
166 32768,32768,32768,32768,32768,32768,32768,32769,32770,32772,32776,32784,32800,32832,32896,33024,
167 33280,33792,34816,35840,36864,37888,38912,39936,40960,41984,43008,44032,45056,46080,47104,48128,
168 49152,50176,51200,52224,53248,54272,55296,56320,57344,58368,59392,60416,61440,62464,63488,64512,
169 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,
170 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,
171 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,
172 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,
173 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,
174 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,
175 64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512,64512
178 const unsigned char half_float_shift_table
[512] = {
179 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
180 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
181 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
182 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
183 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
184 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
185 24,24,24,24,24,24,24,23,22,21,20,19,18,17,16,15,
186 14,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
187 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,24,
188 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
189 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
190 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
191 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
192 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
193 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
194 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,13,
195 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
196 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
197 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
198 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
199 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
200 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
201 24,24,24,24,24,24,24,23,22,21,20,19,18,17,16,15,
202 14,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
203 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,24,
204 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
205 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
206 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
207 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
208 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
209 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
210 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,13
213 static inline unsigned short
214 float_to_half_float(float f
)
216 // See Blink::Source/platform/graphics/gpu/WebGLImageConversion.cpp::convertFloatToHalfFloat() and http://crbug.com/491784
222 unsigned int signexp
;
225 signexp
= (temp
>> 23) & 0x1ff;
226 return half_float_base_table
[signexp
] + ((temp
& 0x007fffff) >> half_float_shift_table
[signexp
]);
230 singles2halfp(void *target
,
234 const float *src
= source
;
235 uint16_t *dst
= target
;
237 for (i
= 0; i
< numel
; i
++)
238 dst
[i
] = float_to_half_float (src
[i
]);
242 conv_yHalf_yF (const Babl
*conversion
,
247 halfp2singles(dst
, src
, samples
);
251 conv_yaHalf_yaF (const Babl
*conversion
,
256 conv_yHalf_yF (conversion
, src
, dst
, samples
* 2);
260 conv_rgbHalf_rgbF (const Babl
*conversion
,
265 conv_yHalf_yF (conversion
, src
, dst
, samples
* 3);
269 conv_rgbaHalf_rgbaF (const Babl
*conversion
,
274 conv_yHalf_yF (conversion
, src
, dst
, samples
* 4);
277 #define conv_rgbAHalf_rgbAF conv_rgbaHalf_rgbaF
280 conv_yF_yHalf (const Babl
*conversion
,
285 singles2halfp (dst
, src
, samples
);
289 conv_yaF_yaHalf (const Babl
*conversion
,
294 conv_yF_yHalf (conversion
, src
, dst
, samples
* 2);
298 conv_rgbF_rgbHalf (const Babl
*conversion
,
303 conv_yF_yHalf (conversion
, src
, dst
, samples
* 3);
307 conv_rgbaF_rgbaHalf (const Babl
*conversion
,
312 conv_yF_yHalf (conversion
, src
, dst
, samples
* 4);
315 #define conv_rgbAF_rgbAHalf conv_rgbaF_rgbaHalf
318 singles2halfp2(void *target
,
322 uint16_t *hp
= (uint16_t *) target
; // Type pun output as an unsigned 16-bit int
323 uint32_t *xp
= (uint32_t *) source
; // Type pun input as an unsigned 32-bit int
325 uint32_t x
, xs
, xe
, xm
;
328 if( source
== NULL
|| target
== NULL
) { // Nothing to convert (e.g., imag part of pure real)
333 if( (x
& 0x7FFFFFFFu
) == 0 ) { // Signed zero
334 *hp
++ = (uint16_t) (x
>> 16); // Return the signed zero
336 xs
= x
& 0x80000000u
; // Pick off sign bit
337 xe
= x
& 0x7F800000u
; // Pick off exponent bits
338 xm
= x
& 0x007FFFFFu
; // Pick off mantissa bits
339 if( xe
== 0 ) { // Denormal will underflow, return a signed zero
340 *hp
++ = (uint16_t) (xs
>> 16);
341 } else if( xe
== 0x7F800000u
) { // Inf or NaN (all the exponent bits are set)
342 if( xm
== 0 ) { // If mantissa is zero ...
343 *hp
++ = (uint16_t) ((xs
>> 16) | 0x7C00u
); // Signed Inf
345 *hp
++ = (uint16_t) 0xFE00u
; // NaN, only 1st mantissa bit set
347 } else { // Normalized number
348 hs
= (uint16_t) (xs
>> 16); // Sign bit
349 hes
= ((int)(xe
>> 23)) - 127 + 15; // Exponent unbias the single, then bias the halfp
350 if( hes
>= 0x1F ) { // Overflow
351 *hp
++ = (uint16_t) ((xs
>> 16) | 0x7C00u
); // Signed Inf
352 } else if( hes
<= 0 ) { // Underflow
353 if( (14 - hes
) > 24 ) { // Mantissa shifted all the way off & no rounding possibility
354 hm
= (uint16_t) 0u; // Set mantissa to zero
356 xm
|= 0x00800000u
; // Add the hidden leading bit
357 hm
= (uint16_t) (xm
>> (14 - hes
)); // Mantissa
358 if( (xm
>> (13 - hes
)) & 0x00000001u
) // Check for rounding
359 hm
+= (uint16_t) 1u; // Round, might overflow into exp bit, but this is OK
361 *hp
++ = (hs
| hm
); // Combine sign bit and mantissa bits, biased exponent is zero
363 he
= (uint16_t) (hes
<< 10); // Exponent
364 hm
= (uint16_t) (xm
>> 13); // Mantissa
365 if( xm
& 0x00001000u
) // Check for rounding
366 *hp
++ = (hs
| he
| hm
) + (uint16_t) 1u; // Round, might overflow to inf, this is OK
368 *hp
++ = (hs
| he
| hm
); // No rounding
376 conv2_yF_yHalf (const Babl
*conversion
,
381 singles2halfp2 (dst
, src
, samples
);
385 conv2_yaF_yaHalf (const Babl
*conversion
,
390 conv2_yF_yHalf (conversion
, src
, dst
, samples
* 2);
394 conv2_rgbF_rgbHalf (const Babl
*conversion
,
399 conv2_yF_yHalf (conversion
, src
, dst
, samples
* 3);
403 conv2_rgbaF_rgbaHalf (const Babl
*conversion
,
408 conv2_yF_yHalf (conversion
, src
, dst
, samples
* 4);
411 #define conv_yAF_yAHalf conv_yaF_yaHalf
412 #define conv_yAHalf_yAF conv_yaHalf_yaF
415 #include "babl-verify-cpu.inc"
423 const Babl
*rgbaF_linear
= babl_format_new (
426 babl_component ("R"),
427 babl_component ("G"),
428 babl_component ("B"),
429 babl_component ("A"),
431 const Babl
*rgbAF_linear
= babl_format_new (
432 babl_model ("RaGaBaA"),
434 babl_component ("Ra"),
435 babl_component ("Ga"),
436 babl_component ("Ba"),
437 babl_component ("A"),
439 const Babl
*rgbAHalf_linear
= babl_format_new (
440 babl_model ("RaGaBaA"),
442 babl_component ("Ra"),
443 babl_component ("Ga"),
444 babl_component ("Ba"),
445 babl_component ("A"),
447 const Babl
*rgbAF_gamma
= babl_format_new (
448 babl_model ("R'aG'aB'aA"),
450 babl_component ("R'a"),
451 babl_component ("G'a"),
452 babl_component ("B'a"),
453 babl_component ("A"),
455 const Babl
*rgbAHalf_gamma
= babl_format_new (
456 babl_model ("R'aG'aB'aA"),
458 babl_component ("R'a"),
459 babl_component ("G'a"),
460 babl_component ("B'a"),
461 babl_component ("A"),
464 const Babl
*rgbaHalf_linear
= babl_format_new (
467 babl_component ("R"),
468 babl_component ("G"),
469 babl_component ("B"),
470 babl_component ("A"),
472 const Babl
*rgbaF_gamma
= babl_format_new (
473 babl_model ("R'G'B'A"),
475 babl_component ("R'"),
476 babl_component ("G'"),
477 babl_component ("B'"),
478 babl_component ("A"),
480 const Babl
*rgbaHalf_gamma
= babl_format_new (
481 babl_model ("R'G'B'A"),
483 babl_component ("R'"),
484 babl_component ("G'"),
485 babl_component ("B'"),
486 babl_component ("A"),
488 const Babl
*rgbF_linear
= babl_format_new (
491 babl_component ("R"),
492 babl_component ("G"),
493 babl_component ("B"),
495 const Babl
*rgbHalf_linear
= babl_format_new (
498 babl_component ("R"),
499 babl_component ("G"),
500 babl_component ("B"),
502 const Babl
*rgbF_gamma
= babl_format_new (
503 babl_model ("R'G'B'"),
505 babl_component ("R'"),
506 babl_component ("G'"),
507 babl_component ("B'"),
509 const Babl
*rgbHalf_gamma
= babl_format_new (
510 babl_model ("R'G'B'"),
512 babl_component ("R'"),
513 babl_component ("G'"),
514 babl_component ("B'"),
516 const Babl
*yaF_linear
= babl_format_new (
519 babl_component ("Y"),
520 babl_component ("A"),
522 const Babl
*yAF_linear
= babl_format_new (
525 babl_component ("Ya"),
526 babl_component ("A"),
528 const Babl
*yaHalf_linear
= babl_format_new (
531 babl_component ("Y"),
532 babl_component ("A"),
534 const Babl
*yAHalf_linear
= babl_format_new (
537 babl_component ("Ya"),
538 babl_component ("A"),
540 const Babl
*yaF_gamma
= babl_format_new (
543 babl_component ("Y'"),
544 babl_component ("A"),
546 const Babl
*yAF_gamma
= babl_format_new (
549 babl_component ("Y'a"),
550 babl_component ("A"),
552 const Babl
*yaHalf_gamma
= babl_format_new (
555 babl_component ("Y'"),
556 babl_component ("A"),
558 const Babl
*yAHalf_gamma
= babl_format_new (
561 babl_component ("Y'a"),
562 babl_component ("A"),
564 const Babl
*yF_linear
= babl_format_new (
567 babl_component ("Y"),
569 const Babl
*yHalf_linear
= babl_format_new (
572 babl_component ("Y"),
574 const Babl
*yF_gamma
= babl_format_new (
577 babl_component ("Y'"),
579 const Babl
*yHalf_gamma
= babl_format_new (
582 babl_component ("Y'"),
585 for (i
= 0; i
< 65536; i
++)
587 uint16_t buf
[2] = {i
, i
};
589 halfp2singles_fun(fbuf
, buf
, 1);
590 half_float_table
[i
] = fbuf
[0];
593 #define CONV(src, dst) \
595 babl_conversion_new (src ## _linear, dst ## _linear, "linear", conv_ ## src ## _ ## dst, NULL); \
596 babl_conversion_new (src ## _gamma, dst ## _gamma, "linear", conv_ ## src ## _ ## dst, NULL); \
598 #define CONV2(src, dst) \
600 babl_conversion_new (src ## _linear, dst ## _linear, "linear", conv2_ ## src ## _ ## dst, NULL); \
601 babl_conversion_new (src ## _gamma, dst ## _gamma, "linear", conv2_ ## src ## _ ## dst, NULL); \
604 CONV(rgbAHalf
, rgbAF
);
605 CONV(rgbAF
, rgbAHalf
);
606 CONV(rgbaHalf
, rgbaF
);
610 CONV(rgbaF
, rgbaHalf
);
618 CONV2(rgbaF
, rgbaHalf
);
619 CONV2(rgbF
, rgbHalf
);