babl: fix some annotation to make the function usable in bindings.
[babl.git] / extensions / float.c
blobcbe042cde96e8cb8fc02dff1427c7e0b7cc8a4e3
1 /* babl - dynamically extendable universal pixel conversion library.
2 * Copyright (C) 2012, Øyvind Kolås
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 3 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, see
16 * <https://www.gnu.org/licenses/>.
19 #include "config.h"
21 #include <stdint.h>
22 #include <stdlib.h>
24 #include "babl-internal.h"
25 #include "babl-cpuaccel.h"
26 #include "extensions/util.h"
27 #include "base/util.h"
29 static const Babl *trc_srgb = NULL;
32 static void
33 conv_yaF_linear_yAF_linear (const Babl *conversion,
34 unsigned char *__restrict__ src,
35 unsigned char *__restrict__ dst,
36 long samples)
38 float *fsrc = (float *) src;
39 float *fdst = (float *) dst;
40 int n = samples;
42 while (n--)
44 float alpha = fsrc[1];
45 float used_alpha = babl_epsilon_for_zero_float (alpha);
46 *fdst++ = (*fsrc++) * used_alpha;
47 *fdst++ = alpha;
48 fsrc++;
53 static void
54 conv_yAF_linear_yaF_linear (const Babl *conversion,
55 unsigned char *__restrict__ src,
56 unsigned char *__restrict__ dst,
57 long samples)
59 float *fsrc = (float *) src;
60 float *fdst = (float *) dst;
61 int n = samples;
63 while (n--)
65 float alpha = fsrc[1];
66 float alpha_reciprocal = 1.0f/babl_epsilon_for_zero_float (alpha);
67 *fdst++ = (*fsrc++) * alpha_reciprocal;
68 *fdst++ = alpha;
69 fsrc++;
74 static void
75 conv_yaF_linear_yAF_nonlinear (const Babl *conversion,
76 unsigned char *__restrict__ src,
77 unsigned char *__restrict__ dst,
78 long samples)
80 const Babl *space = babl_conversion_get_destination_space (conversion);
81 const Babl **trc = (void*)space->space.trc;
83 float *fsrc = (float *) src;
84 float *fdst = (float *) dst;
85 int n = samples;
87 while (n--)
89 float alpha = fsrc[1];
90 float used_alpha = babl_epsilon_for_zero_float (alpha);
91 *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * used_alpha;
92 *fdst++ = alpha;
93 fsrc++;
97 static void
98 conv_rgbaF_linear_rgbAF_nonlinear (const Babl *conversion,
99 unsigned char *__restrict__ src,
100 unsigned char *__restrict__ dst,
101 long samples)
103 const Babl *space = babl_conversion_get_destination_space (conversion);
104 const Babl **trc = (void*)space->space.trc;
106 float *fsrc = (float *) src;
107 float *fdst = (float *) dst;
108 int n = samples;
110 while (n--)
112 float alpha = fsrc[3];
113 float used_alpha = babl_epsilon_for_zero_float (alpha);
114 *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * used_alpha;
115 *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * used_alpha;
116 *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * used_alpha;
117 *fdst++ = alpha;
118 fsrc++;
122 static void
123 conv_rgbaF_linear_rgbAF_perceptual (const Babl *conversion,
124 unsigned char *__restrict__ src,
125 unsigned char *__restrict__ dst,
126 long samples)
128 float *fsrc = (float *) src;
129 float *fdst = (float *) dst;
130 int n = samples;
132 while (n--)
134 float alpha = fsrc[3];
135 float used_alpha = babl_epsilon_for_zero (alpha);
136 *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * used_alpha;
137 *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * used_alpha;
138 *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * used_alpha;
139 *fdst++ = alpha;
140 fsrc++;
145 static void
146 conv_rgbAF_linear_rgbAF_nonlinear (const Babl *conversion,
147 unsigned char *__restrict__ src,
148 unsigned char *__restrict__ dst,
149 long samples)
151 const Babl *space = babl_conversion_get_destination_space (conversion);
152 const Babl **trc = (void*)space->space.trc;
154 float *fsrc = (float *) src;
155 float *fdst = (float *) dst;
156 int n = samples;
158 while (n--)
160 float alpha = fsrc[3];
161 if (alpha == 0)
163 *fdst++ = 0.0;
164 *fdst++ = 0.0;
165 *fdst++ = 0.0;
166 *fdst++ = 0.0;
167 fsrc+=4;
169 else
171 float alpha_recip = 1.0f / alpha;
172 *fdst++ = babl_trc_from_linear (trc[0], *fsrc++ * alpha_recip) * alpha;
173 *fdst++ = babl_trc_from_linear (trc[1], *fsrc++ * alpha_recip) * alpha;
174 *fdst++ = babl_trc_from_linear (trc[2], *fsrc++ * alpha_recip) * alpha;
175 *fdst++ = *fsrc++;
181 static void
182 conv_yAF_linear_yAF_nonlinear (const Babl *conversion,
183 unsigned char *__restrict__ src,
184 unsigned char *__restrict__ dst,
185 long samples)
187 const Babl *space = babl_conversion_get_destination_space (conversion);
188 const Babl **trc = (void*)space->space.trc;
190 float *fsrc = (float *) src;
191 float *fdst = (float *) dst;
192 int n = samples;
194 while (n--)
196 float alpha = fsrc[1];
197 if (alpha == 0)
199 *fdst++ = 0.0;
200 *fdst++ = 0.0;
201 *fdst++ = 0.0;
202 *fdst++ = 0.0;
203 fsrc+=4;
205 else
207 float alpha_recip = 1.0f / alpha;
208 *fdst++ = babl_trc_from_linear (trc[0], *fsrc++ * alpha_recip) * alpha;
209 *fdst++ = *fsrc++;
216 static void
217 conv_rgbAF_linear_rgbAF_perceptual (const Babl *conversion,
218 unsigned char *__restrict__ src,
219 unsigned char *__restrict__ dst,
220 long samples)
223 float *fsrc = (float *) src;
224 float *fdst = (float *) dst;
225 int n = samples;
227 while (n--)
229 float alpha = fsrc[3];
230 if (alpha == 0.0f)
232 *fdst++ = 0.0f;
233 *fdst++ = 0.0f;
234 *fdst++ = 0.0f;
235 *fdst++ = 0.0f;
236 fsrc+=4;
238 else
240 float alpha_recip = 1.0f / alpha;
241 *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha;
242 *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha;
243 *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha;
244 *fdst++ = *fsrc++;
250 static void
251 conv_yaF_linear_yaF_nonlinear (const Babl *conversion,
252 unsigned char *__restrict__ src,
253 unsigned char *__restrict__ dst,
254 long samples)
256 const Babl *space = babl_conversion_get_destination_space (conversion);
257 const Babl **trc = (void*)space->space.trc;
259 float *fsrc = (float *) src;
260 float *fdst = (float *) dst;
261 babl_trc_from_linear_buf (trc[0], fsrc, fdst, 2, 2, 1, samples);
264 static void
265 conv_rgbaF_linear_rgbaF_nonlinear (const Babl *conversion,
266 unsigned char *__restrict__ src,
267 unsigned char *__restrict__ dst,
268 long samples)
270 const Babl *space = babl_conversion_get_destination_space (conversion);
271 const Babl **trc = (void*)space->space.trc;
273 float *fsrc = (float *) src;
274 float *fdst = (float *) dst;
275 int n = samples;
277 while (n--)
279 *fdst++ = babl_trc_from_linear (trc[0], *fsrc++);
280 *fdst++ = babl_trc_from_linear (trc[1], *fsrc++);
281 *fdst++ = babl_trc_from_linear (trc[2], *fsrc++);
282 *fdst++ = *fsrc++;
286 static void
287 conv_rgbaF_linear_rgbaF_perceptual (const Babl *conversion,
288 unsigned char *__restrict__ src,
289 unsigned char *__restrict__ dst,
290 long samples)
292 float *fsrc = (float *) src;
293 float *fdst = (float *) dst;
294 babl_trc_from_linear_buf (trc_srgb, fsrc, fdst, 4, 4, 3, samples);
297 static void
298 conv_yF_linear_yF_nonlinear (const Babl *conversion,
299 unsigned char *__restrict__ src,
300 unsigned char *__restrict__ dst,
301 long samples)
303 const Babl *space = babl_conversion_get_destination_space (conversion);
304 const Babl **trc = (void*)space->space.trc;
305 float *fsrc = (float *) src;
306 float *fdst = (float *) dst;
307 babl_trc_from_linear_buf (trc[0], fsrc, fdst, 1, 1, 1, samples);
311 static void
312 conv_rgbF_linear_rgbF_nonlinear (const Babl *conversion,
313 unsigned char *__restrict__ src,
314 unsigned char *__restrict__ dst,
315 long samples)
317 const Babl *space = babl_conversion_get_destination_space (conversion);
318 const Babl **trc = (void*)space->space.trc;
319 float *fsrc = (float *) src;
320 float *fdst = (float *) dst;
321 int n = samples;
323 while (n--)
325 *fdst++ = babl_trc_from_linear (trc[0], *fsrc++);
326 *fdst++ = babl_trc_from_linear (trc[1], *fsrc++);
327 *fdst++ = babl_trc_from_linear (trc[2], *fsrc++);
331 static void
332 conv_rgbF_linear_rgbF_perceptual (const Babl *conversion,
333 unsigned char *__restrict__ src,
334 unsigned char *__restrict__ dst,
335 long samples)
337 float *fsrc = (float *) src;
338 float *fdst = (float *) dst;
339 babl_trc_from_linear_buf (trc_srgb, fsrc, fdst, 3, 3, 3, samples);
342 static void
343 conv_rgbaF_nonlinear_rgbaF_linear (const Babl *conversion,
344 unsigned char *__restrict__ src,
345 unsigned char *__restrict__ dst,
346 long samples)
348 const Babl *space = babl_conversion_get_destination_space (conversion);
349 const Babl **trc = (void*)space->space.trc;
350 float *fsrc = (float *) src;
351 float *fdst = (float *) dst;
352 int n = samples;
354 while (n--)
356 *fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
357 *fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
358 *fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
359 *fdst++ = *fsrc++;
364 static void
365 conv_yaF_nonlinear_yaF_linear (const Babl *conversion,
366 unsigned char *__restrict__ src,
367 unsigned char *__restrict__ dst,
368 long samples)
370 const Babl *space = babl_conversion_get_destination_space (conversion);
371 const Babl **trc = (void*)space->space.trc;
372 float *fsrc = (float *) src;
373 float *fdst = (float *) dst;
374 babl_trc_to_linear_buf (trc[0], fsrc, fdst, 2, 2, 1, samples);
378 static void
379 conv_rgbaF_perceptual_rgbaF_linear (const Babl *conversion,
380 unsigned char *__restrict__ src,
381 unsigned char *__restrict__ dst,
382 long samples)
384 float *fsrc = (float *) src;
385 float *fdst = (float *) dst;
386 babl_trc_to_linear_buf (trc_srgb, fsrc, fdst, 4, 4, 3, samples);
390 static void
391 conv_rgbF_nonlinear_rgbF_linear (const Babl *conversion,
392 unsigned char *__restrict__ src,
393 unsigned char *__restrict__ dst,
394 long samples)
396 const Babl *space = babl_conversion_get_destination_space (conversion);
397 const Babl **trc = (void*)space->space.trc;
398 float *fsrc = (float *) src;
399 float *fdst = (float *) dst;
400 int n = samples;
402 while (n--)
404 *fdst++ = babl_trc_to_linear (trc[0], *fsrc++);
405 *fdst++ = babl_trc_to_linear (trc[1], *fsrc++);
406 *fdst++ = babl_trc_to_linear (trc[2], *fsrc++);
411 static void
412 conv_yF_nonlinear_yF_linear (const Babl *conversion,
413 unsigned char *__restrict__ src,
414 unsigned char *__restrict__ dst,
415 long samples)
417 const Babl *space = babl_conversion_get_destination_space (conversion);
418 const Babl **trc = (void*)space->space.trc;
419 float *fsrc = (float *) src;
420 float *fdst = (float *) dst;
422 babl_trc_to_linear_buf (trc[0], fsrc, fdst, 1, 1, 1, samples);
425 static void
426 conv_rgbF_perceptual_rgbF_linear (const Babl *conversion,
427 unsigned char *__restrict__ src,
428 unsigned char *__restrict__ dst,
429 long samples)
431 float *fsrc = (float *) src;
432 float *fdst = (float *) dst;
433 babl_trc_to_linear_buf (trc_srgb, fsrc, fdst, 3, 3, 3, samples);
437 #define o(src, dst) \
438 babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)
440 int init (void);
441 #include "babl-verify-cpu.inc"
444 init (void)
446 BABL_VERIFY_CPU();
448 const Babl *yaF_linear = babl_format_new (
449 babl_model ("YA"),
450 babl_type ("float"),
451 babl_component ("Y"),
452 babl_component ("A"),
453 NULL);
454 const Babl *yAF_linear = babl_format_new (
455 babl_model ("YaA"),
456 babl_type ("float"),
457 babl_component ("Ya"),
458 babl_component ("A"),
459 NULL);
460 const Babl *yaF_nonlinear = babl_format_new (
461 babl_model ("Y'A"),
462 babl_type ("float"),
463 babl_component ("Y'"),
464 babl_component ("A"),
465 NULL);
466 const Babl *rgbaF_linear = babl_format_new (
467 babl_model ("RGBA"),
468 babl_type ("float"),
469 babl_component ("R"),
470 babl_component ("G"),
471 babl_component ("B"),
472 babl_component ("A"),
473 NULL);
474 const Babl *rgbAF_linear = babl_format_new (
475 babl_model ("RaGaBaA"),
476 babl_type ("float"),
477 babl_component ("Ra"),
478 babl_component ("Ga"),
479 babl_component ("Ba"),
480 babl_component ("A"),
481 NULL);
482 const Babl *rgbaF_nonlinear = babl_format_new (
483 babl_model ("R'G'B'A"),
484 babl_type ("float"),
485 babl_component ("R'"),
486 babl_component ("G'"),
487 babl_component ("B'"),
488 babl_component ("A"),
489 NULL);
490 const Babl *rgbaF_perceptual = babl_format_new (
491 babl_model ("R~G~B~A"),
492 babl_type ("float"),
493 babl_component ("R~"),
494 babl_component ("G~"),
495 babl_component ("B~"),
496 babl_component ("A"),
497 NULL);
498 const Babl *yAF_nonlinear = babl_format_new (
499 babl_model ("Y'aA"),
500 babl_type ("float"),
501 babl_component ("Y'a"),
502 babl_component ("A"),
503 NULL);
504 const Babl *rgbAF_nonlinear = babl_format_new (
505 babl_model ("R'aG'aB'aA"),
506 babl_type ("float"),
507 babl_component ("R'a"),
508 babl_component ("G'a"),
509 babl_component ("B'a"),
510 babl_component ("A"),
511 NULL);
512 const Babl *rgbAF_perceptual = babl_format_new (
513 babl_model ("R~aG~aB~aA"),
514 babl_type ("float"),
515 babl_component ("R~a"),
516 babl_component ("G~a"),
517 babl_component ("B~a"),
518 babl_component ("A"),
519 NULL);
520 const Babl *yF_linear = babl_format_new (
521 babl_model ("Y"),
522 babl_type ("float"),
523 babl_component ("Y"),
524 NULL);
525 const Babl *yF_nonlinear = babl_format_new (
526 babl_model ("Y'"),
527 babl_type ("float"),
528 babl_component ("Y'"),
529 NULL);
530 const Babl *rgbF_linear = babl_format_new (
531 babl_model ("RGB"),
532 babl_type ("float"),
533 babl_component ("R"),
534 babl_component ("G"),
535 babl_component ("B"),
536 NULL);
537 const Babl *rgbF_nonlinear = babl_format_new (
538 babl_model ("R'G'B'"),
539 babl_type ("float"),
540 babl_component ("R'"),
541 babl_component ("G'"),
542 babl_component ("B'"),
543 NULL);
544 const Babl *rgbF_perceptual = babl_format_new (
545 babl_model ("R~G~B~"),
546 babl_type ("float"),
547 babl_component ("R~"),
548 babl_component ("G~"),
549 babl_component ("B~"),
550 NULL);
551 trc_srgb = babl_trc("sRGB");
553 o (rgbAF_linear, rgbAF_nonlinear);
554 o (rgbaF_linear, rgbAF_nonlinear);
555 o (rgbaF_linear, rgbaF_nonlinear);
556 o (rgbaF_nonlinear, rgbaF_linear);
557 o (rgbF_linear, rgbF_nonlinear);
558 o (rgbF_nonlinear, rgbF_linear);
561 o (yaF_linear, yAF_linear);
562 o (yAF_linear, yaF_linear);
563 o (yAF_linear, yAF_nonlinear);
564 o (yaF_linear, yAF_nonlinear);
565 o (yaF_linear, yaF_nonlinear);
566 o (yaF_nonlinear, yaF_linear);
567 o (yF_linear, yF_nonlinear);
568 o (yF_nonlinear, yF_linear);
570 o (rgbAF_linear, rgbAF_perceptual);
571 o (rgbaF_linear, rgbAF_perceptual);
572 o (rgbaF_linear, rgbaF_perceptual);
573 o (rgbaF_perceptual, rgbaF_linear);
574 o (rgbF_linear, rgbF_perceptual);
575 o (rgbF_perceptual, rgbF_linear);
577 return 0;