1 /* babl - dynamically extendable universal pixel fish library.
2 * Copyright (C) 2005, Øyvind Kolås.
3 *
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.
8 *
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.
13 *
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/>.
17 */
18
19 #include "config.h"
20 #include "babl-internal.h"
21 #ifdef HAVE_LCMS
22 #include "lcms2.h"
23 #endif
24
25
26 static Babl *
assert_conversion_find(const void * source,const void * destination)27 assert_conversion_find (const void *source,
28 const void *destination)
29 {
30 Babl *ret = babl_conversion_find (source, destination);
31
32 if (!ret)
33 babl_fatal ("failed finding conversion between %s and %s aborting",
34 babl_get_name (source), babl_get_name (destination));
35
36 return ret;
37 }
38
39 static int
create_name_internal(char * buf,size_t maxlen,const Babl * source,const Babl * destination,int is_reference)40 create_name_internal (char *buf,
41 size_t maxlen,
42 const Babl *source,
43 const Babl *destination,
44 int is_reference)
45 {
46 return snprintf (buf, maxlen, "%s %p %p",
47 is_reference ? "ref "
48 : "",
49 source, destination);
50 }
51
52 #ifdef HAVE_TLS
53
54 static __thread char buf[1024];
55
56 static char *
create_name(const Babl * source,const Babl * destination,int is_reference)57 create_name (const Babl *source,
58 const Babl *destination,
59 int is_reference)
60 {
61 int size = 0;
62
63 size = create_name_internal (buf, sizeof(buf), source, destination, is_reference);
64
65 if (size < 0)
66 return NULL;
67
68 return buf;
69 }
70
71
72 #else
73
74 static char *
create_name(const Babl * source,const Babl * destination,int is_reference)75 create_name (const Babl *source,
76 const Babl *destination,
77 int is_reference)
78 {
79 int size = 0;
80 char *buf = NULL;
81
82 size = create_name_internal (buf, size, source, destination, is_reference);
83
84 if (size < 0)
85 return NULL;
86
87 size++; /* For '\0' */
88 buf = malloc (size);
89 if (buf == NULL)
90 return NULL;
91
92 size = create_name_internal (buf, size, source, destination, is_reference);
93
94 if (size < 0)
95 {
96 free (buf);
97 return NULL;
98 }
99
100 return buf;
101 }
102
103 #endif
104
105 /* need an internal version that only ever does double,
106 * for use in path evaluation? and perhaps even self evaluation of float code path?
107 */
108 Babl *
babl_fish_reference(const Babl * source,const Babl * destination)109 babl_fish_reference (const Babl *source,
110 const Babl *destination)
111 {
112 Babl *babl = NULL;
113 char *name = create_name (source, destination, 1);
114
115 babl_assert (name);
116
117 babl = babl_db_exist_by_name (babl_fish_db (), name);
118 if (babl)
119 {
120 /* There is an instance already registered by the required name,
121 * returning the preexistent one instead.
122 */
123 #ifndef HAVE_TLS
124 free (name);
125 #endif
126 _babl_fish_rig_dispatch (babl);
127 return babl;
128 }
129
130 babl_assert (BABL_IS_BABL (source));
131 babl_assert (BABL_IS_BABL (destination));
132
133 babl_assert (source->class_type == BABL_FORMAT);
134 babl_assert (destination->class_type == BABL_FORMAT);
135
136 babl = babl_calloc (1, sizeof (BablFishReference) +
137 strlen (name) + 1);
138 babl->class_type = BABL_FISH_REFERENCE;
139 babl->instance.id = babl_fish_get_id (source, destination);
140 babl->instance.name = ((char *) babl) + sizeof (BablFishReference);
141 strcpy (babl->instance.name, name);
142 babl->fish.source = source;
143 babl->fish.destination = destination;
144
145 babl->fish.pixels = 0;
146 babl->fish.error = 0.0; /* assuming the provided reference conversions for types
147 and models are as exact as possible
148 */
149 _babl_fish_rig_dispatch (babl);
150
151 /* Since there is not an already registered instance by the required
152 * name, inserting newly created class into database.
153 */
154 babl_db_insert (babl_fish_db (), babl);
155 #ifndef HAVE_TLS
156 free (name);
157 #endif
158 return babl;
159 }
160
161
162 static void
convert_to_double(BablFormat * source_fmt,const char * source_buf,char * double_buf,int n)163 convert_to_double (BablFormat *source_fmt,
164 const char *source_buf,
165 char *double_buf,
166 int n)
167 {
168 int i;
169
170 BablImage *src_img;
171 BablImage *dst_img;
172
173 src_img = (BablImage *) babl_image_new (
174 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
175 dst_img = (BablImage *) babl_image_new (
176 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
177
178 dst_img->type[0] = (BablType *) babl_type_from_id (BABL_DOUBLE);
179 dst_img->pitch[0] =
180 (dst_img->type[0]->bits / 8) * source_fmt->model->components;
181 dst_img->stride[0] = 0;
182
183 src_img->type[0] = (BablType *) babl_type_from_id (BABL_DOUBLE);
184 src_img->pitch[0] = source_fmt->bytes_per_pixel;
185 src_img->stride[0] = 0;
186
187 {
188 /* i is dest position */
189 for (i = 0; i < source_fmt->model->components; i++)
190 {
191 int j;
192 int found = 0;
193
194 dst_img->data[0] =
195 double_buf + (dst_img->type[0]->bits / 8) * i;
196
197 src_img->data[0] = (char *)source_buf;
198
199 /* j is source position */
200 for (j = 0; j < source_fmt->components; j++)
201 {
202 src_img->type[0] = source_fmt->type[j];
203
204 if (source_fmt->component[j] ==
205 source_fmt->model->component[i])
206 {
207 babl_conversion_process (assert_conversion_find (src_img->type[0], dst_img->type[0]),
208 (void*)src_img, (void*)dst_img, n);
209 found = 1;
210 break;
211 }
212
213 src_img->data[0] += src_img->type[0]->bits / 8;
214 }
215
216 if (!found)
217 {
218 char *dst_ptr = dst_img->data[0];
219 double value;
220
221 value = source_fmt->model->component[i]->instance.id == BABL_ALPHA ? 1.0 : 0.0;
222
223 for (j = 0; j < n; j++)
224 {
225 double *dst_component = (double *) dst_ptr;
226
227 *dst_component = value;
228 dst_ptr += dst_img->pitch[0];
229 }
230 }
231 }
232 }
233 babl_free (src_img);
234 babl_free (dst_img);
235 }
236
237
238 static void
convert_from_double(BablFormat * source_fmt,BablFormat * destination_fmt,char * destination_double_buf,char * destination_buf,int n)239 convert_from_double (BablFormat *source_fmt,
240 BablFormat *destination_fmt,
241 char *destination_double_buf,
242 char *destination_buf,
243 int n)
244 {
245 int i;
246
247 BablImage *src_img;
248 BablImage *dst_img;
249
250 src_img = (BablImage *) babl_image_new (
251 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
252 dst_img = (BablImage *) babl_image_new (
253 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
254
255 src_img->type[0] = (BablType *) babl_type_from_id (BABL_DOUBLE);
256 src_img->pitch[0] = (src_img->type[0]->bits / 8) * destination_fmt->model->components;
257 src_img->stride[0] = 0;
258
259 dst_img->data[0] = destination_buf;
260 dst_img->pitch[0] = destination_fmt->bytes_per_pixel;
261 dst_img->stride[0] = 0;
262
263 for (i = 0; i < destination_fmt->components; i++)
264 {
265 int j;
266 int can_be_used = 1;
267
268 dst_img->type[0] = destination_fmt->type[i];
269
270 if (source_fmt->model == destination_fmt->model)
271 {
272 can_be_used = 0;
273 for (j = 0; j < source_fmt->components; j++)
274 {
275 if (destination_fmt->component[i] == source_fmt->component[j])
276 {
277 can_be_used = 1;
278 }
279 }
280 }
281 else
282 {
283 }
284 //fprintf (stderr, "%s %s %i\n", babl_get_name (source_fmt), babl_get_name (destination_fmt), can_be_used);
285
286 if (can_be_used)
287 for (j = 0; j < destination_fmt->model->components; j++)
288 {
289 if (destination_fmt->component[i] ==
290 destination_fmt->model->component[j])
291 {
292 src_img->data[0] =
293 destination_double_buf + (src_img->type[0]->bits / 8) * j;
294
295 babl_conversion_process (assert_conversion_find (src_img->type[0],
296 dst_img->type[0]),
297 (void*)src_img, (void*)dst_img, n);
298 break;
299 }
300 }
301
302 dst_img->data[0] += dst_img->type[0]->bits / 8;
303 }
304 babl_free (src_img);
305 babl_free (dst_img);
306 }
307
308
309 static void
ncomponent_convert_to_double(BablFormat * source_fmt,char * source_buf,char * source_double_buf,int n)310 ncomponent_convert_to_double (BablFormat *source_fmt,
311 char *source_buf,
312 char *source_double_buf,
313 int n)
314 {
315 BablImage *src_img;
316 BablImage *dst_img;
317
318 src_img = (BablImage *) babl_image_new (
319 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
320 dst_img = (BablImage *) babl_image_new (
321 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
322
323 dst_img->type[0] = (BablType *) babl_type_from_id (BABL_DOUBLE);
324 dst_img->pitch[0] = (dst_img->type[0]->bits / 8);
325 dst_img->stride[0] = 0;
326
327 src_img->data[0] = source_buf;
328 src_img->type[0] = source_fmt->type[0];
329 src_img->pitch[0] = source_fmt->type[0]->bits / 8;
330 src_img->stride[0] = 0;
331
332 dst_img->data[0] = source_double_buf;
333
334 babl_conversion_process (
335 assert_conversion_find (src_img->type[0], dst_img->type[0]),
336 (void*)src_img, (void*)dst_img,
337 n * source_fmt->components);
338 babl_free (src_img);
339 babl_free (dst_img);
340 }
341
342 static void
ncomponent_convert_from_double(BablFormat * destination_fmt,char * destination_double_buf,char * destination_buf,int n)343 ncomponent_convert_from_double (BablFormat *destination_fmt,
344 char *destination_double_buf,
345 char *destination_buf,
346 int n)
347 {
348 BablImage *src_img;
349 BablImage *dst_img;
350
351 src_img = (BablImage *) babl_image_new (
352 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
353 dst_img = (BablImage *) babl_image_new (
354 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
355
356 src_img->type[0] = (BablType *) babl_type_from_id (BABL_DOUBLE);
357 src_img->pitch[0] = (src_img->type[0]->bits / 8);
358 src_img->stride[0] = 0;
359
360 dst_img->data[0] = destination_buf;
361 dst_img->pitch[0] = destination_fmt->type[0]->bits/8;
362 dst_img->stride[0] = 0;
363
364 dst_img->type[0] = destination_fmt->type[0];
365 src_img->data[0] = destination_double_buf;
366
367 babl_conversion_process (
368 assert_conversion_find (src_img->type[0], dst_img->type[0]),
369 (void*)src_img, (void*)dst_img,
370 n * destination_fmt->components);
371
372 dst_img->data[0] += dst_img->type[0]->bits / 8;
373 babl_free (src_img);
374 babl_free (dst_img);
375 }
376
377
378 static int
process_to_n_component(const Babl * babl,const char * source,char * destination,long n)379 process_to_n_component (const Babl *babl,
380 const char *source,
381 char *destination,
382 long n)
383 {
384 void *double_buf;
385 #ifndef MAX
386 #define MAX(a, b) ((a) > (b) ? (a) : (b))
387 #endif
388 int components = MAX(BABL (babl->fish.source)->format.model->components,
389 BABL (babl->fish.source)->format.components);
390 components = MAX(components, BABL (babl->fish.destination)->format.components);
391 components = MAX(components, BABL (babl->fish.destination)->model.components);
392
393 double_buf = babl_malloc (sizeof (double) * n * components);
394 memset (double_buf, 0,sizeof (double) * n * components);
395
396 /* a single precision path could be added here*/
397 {
398 ncomponent_convert_to_double (
399 (BablFormat *) BABL (babl->fish.source),
400 (char *) source,
401 double_buf,
402 n
403 );
404
405 ncomponent_convert_from_double (
406 (BablFormat *) BABL (babl->fish.destination),
407 double_buf,
408 (char *) destination,
409 n
410 );
411 }
412
413 babl_free (double_buf);
414 return 0;
415 }
416
compatible_components(const BablFormat * a,const BablFormat * b)417 static int compatible_components (const BablFormat *a,
418 const BablFormat *b)
419 {
420 int i;
421 if (a->components != b->components)
422 return 0;
423 for (i = 0; i < a->components; i++)
424 if (a->component[i] != b->component[i])
425 return 0;
426 return 1;
427 }
428
429 static void
ncomponent_convert_to_float(BablFormat * source_fmt,char * source_buf,char * source_float_buf,int n)430 ncomponent_convert_to_float (BablFormat *source_fmt,
431 char *source_buf,
432 char *source_float_buf,
433 int n)
434 {
435 BablImage *src_img;
436 BablImage *dst_img;
437
438 src_img = (BablImage *) babl_image_new (
439 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
440 dst_img = (BablImage *) babl_image_new (
441 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
442
443 dst_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
444 dst_img->pitch[0] = (dst_img->type[0]->bits / 8);
445 dst_img->stride[0] = 0;
446
447 src_img->data[0] = source_buf;
448 src_img->type[0] = source_fmt->type[0];
449 src_img->pitch[0] = source_fmt->type[0]->bits / 8;
450 src_img->stride[0] = 0;
451
452 dst_img->data[0] = source_float_buf;
453
454 babl_conversion_process (
455 assert_conversion_find (src_img->type[0], dst_img->type[0]),
456 (void*)src_img, (void*)dst_img,
457 n * source_fmt->components);
458 babl_free (src_img);
459 babl_free (dst_img);
460 }
461
462 static void
ncomponent_convert_from_float(BablFormat * source_fmt,BablFormat * destination_fmt,char * destination_float_buf,char * destination_buf,int n)463 ncomponent_convert_from_float (BablFormat *source_fmt,
464 BablFormat *destination_fmt,
465 char *destination_float_buf,
466 char *destination_buf,
467 int n)
468 {
469 BablImage *src_img;
470 BablImage *dst_img;
471
472 src_img = (BablImage *) babl_image_new (
473 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
474 dst_img = (BablImage *) babl_image_new (
475 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
476
477 src_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
478 src_img->pitch[0] = (src_img->type[0]->bits / 8);
479 src_img->stride[0] = 0;
480
481 dst_img->data[0] = destination_buf;
482 dst_img->pitch[0] = destination_fmt->type[0]->bits/8;
483 dst_img->stride[0] = 0;
484
485 dst_img->type[0] = destination_fmt->type[0];
486 src_img->data[0] = destination_float_buf;
487
488 babl_conversion_process (
489 assert_conversion_find (src_img->type[0], dst_img->type[0]),
490 (void*)src_img, (void*)dst_img,
491 n * destination_fmt->components);
492
493 dst_img->data[0] += dst_img->type[0]->bits / 8;
494 babl_free (src_img);
495 babl_free (dst_img);
496 }
497
498 static void
convert_to_float(BablFormat * source_fmt,const char * source_buf,char * float_buf,int n)499 convert_to_float (BablFormat *source_fmt,
500 const char *source_buf,
501 char *float_buf,
502 int n)
503 {
504 int i;
505
506 BablImage *src_img;
507 BablImage *dst_img;
508
509 src_img = (BablImage *) babl_image_new (
510 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
511 dst_img = (BablImage *) babl_image_new (
512 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
513
514 dst_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
515 dst_img->pitch[0] =
516 (dst_img->type[0]->bits / 8) * source_fmt->model->components;
517 dst_img->stride[0] = 0;
518
519 src_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
520 src_img->pitch[0] = source_fmt->bytes_per_pixel;
521 src_img->stride[0] = 0;
522
523 {
524 /* i is dest position */
525 for (i = 0; i < source_fmt->model->components; i++)
526 {
527 int j;
528 int found = 0;
529
530 dst_img->data[0] =
531 float_buf + (dst_img->type[0]->bits / 8) * i;
532
533 src_img->data[0] = (char *)source_buf;
534
535 /* j is source position */
536 for (j = 0; j < source_fmt->components; j++)
537 {
538 src_img->type[0] = source_fmt->type[j];
539
540 if (source_fmt->component[j] ==
541 source_fmt->model->component[i])
542 {
543 babl_conversion_process (assert_conversion_find (src_img->type[0], dst_img->type[0]),
544 (void*)src_img, (void*)dst_img, n);
545 found = 1;
546 break;
547 }
548
549 src_img->data[0] += src_img->type[0]->bits / 8;
550 }
551
552 if (!found)
553 {
554 char *dst_ptr = dst_img->data[0];
555 float value;
556
557 value = source_fmt->model->component[i]->instance.id == BABL_ALPHA ? 1.0 : 0.0;
558
559 for (j = 0; j < n; j++)
560 {
561 float *dst_component = (float *) dst_ptr;
562
563 *dst_component = value;
564 dst_ptr += dst_img->pitch[0];
565 }
566 }
567 }
568 }
569 babl_free (src_img);
570 babl_free (dst_img);
571 }
572
573
574 static void
convert_from_float(BablFormat * source_fmt,BablFormat * destination_fmt,char * destination_float_buf,char * destination_buf,int n)575 convert_from_float (BablFormat *source_fmt,
576 BablFormat *destination_fmt,
577 char *destination_float_buf,
578 char *destination_buf,
579 int n)
580 {
581 int i;
582
583 BablImage *src_img;
584 BablImage *dst_img;
585
586 src_img = (BablImage *) babl_image_new (
587 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
588 dst_img = (BablImage *) babl_image_new (
589 babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
590
591 src_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
592 src_img->pitch[0] = (src_img->type[0]->bits / 8) * destination_fmt->model->components;
593 src_img->stride[0] = 0;
594
595 dst_img->data[0] = destination_buf;
596 dst_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
597 dst_img->pitch[0] = destination_fmt->bytes_per_pixel;
598 dst_img->stride[0] = 0;
599
600 for (i = 0; i < destination_fmt->components; i++)
601 {
602 int j;
603 int can_be_used = 1;
604
605 dst_img->type[0] = destination_fmt->type[i];
606
607 if (source_fmt->model == destination_fmt->model)
608 {
609 can_be_used = 0;
610 for (j = 0; j < source_fmt->components; j++)
611 {
612 if (destination_fmt->component[i] == source_fmt->component[j])
613 {
614 can_be_used = 1;
615 }
616 }
617 }
618
619 if (can_be_used)
620 for (j = 0; j < destination_fmt->model->components; j++)
621 {
622 if (destination_fmt->component[i] ==
623 destination_fmt->model->component[j])
624 {
625 src_img->data[0] =
626 destination_float_buf + (src_img->type[0]->bits / 8) * j;
627
628 babl_conversion_process (assert_conversion_find (src_img->type[0],
629 dst_img->type[0]),
630 (void*)src_img, (void*)dst_img, n);
631 break;
632 }
633 }
634
635 dst_img->data[0] += dst_img->type[0]->bits / 8;
636 }
637 babl_free (src_img);
638 babl_free (dst_img);
639 }
640
641
642
643 static void
process_same_model(const Babl * babl,const char * source,char * destination,long n)644 process_same_model (const Babl *babl,
645 const char *source,
646 char *destination,
647 long n)
648 {
649 const void *type_float = babl_type_from_id (BABL_FLOAT);
650 #define MAX(a, b) ((a) > (b) ? (a) : (b))
651
652 if ((babl->fish.source->format.type[0]->bits < 32 ||
653 babl->fish.source->format.type[0] == type_float) &&
654 (babl->fish.destination->format.type[0]->bits < 32 ||
655 babl->fish.destination->format.type[0] == type_float))
656 {
657 void *float_buf = babl_malloc (sizeof (float) * n *
658 MAX (BABL (babl->fish.source)->format.model->components,
659 BABL (babl->fish.source)->format.components));
660 if (compatible_components ((void*)babl->fish.source,
661 (void*)babl->fish.destination))
662 {
663 ncomponent_convert_to_float (
664 (BablFormat *) BABL (babl->fish.source),
665 (char *) source,
666 float_buf,
667 n);
668 ncomponent_convert_from_float (
669 (BablFormat *) BABL (babl->fish.source),
670 (BablFormat *) BABL (babl->fish.destination),
671 float_buf,
672 (char *) destination,
673 n);
674 }
675 else
676 {
677 convert_to_float (
678 (BablFormat *) BABL (babl->fish.source),
679 (char *) source,
680 float_buf,
681 n);
682
683 convert_from_float (
684 (BablFormat *) BABL (babl->fish.source),
685 (BablFormat *) BABL (babl->fish.destination),
686 float_buf,
687 (char *) destination,
688 n);
689 }
690 babl_free (float_buf);
691 }
692 else
693 {
694 void *double_buf = babl_malloc (sizeof (double) * n *
695 MAX (BABL (babl->fish.source)->format.model->components,
696 BABL (babl->fish.source)->format.components));
697 #undef MAX
698 if (compatible_components ((void*)babl->fish.source,
699 (void*)babl->fish.destination))
700 {
701 ncomponent_convert_to_double (
702 (BablFormat *) BABL (babl->fish.source),
703 (char *) source,
704 double_buf,
705 n);
706 ncomponent_convert_from_double (
707 (BablFormat *) BABL (babl->fish.destination),
708 double_buf,
709 (char *) destination,
710 n);
711 }
712 else
713 {
714 convert_to_double (
715 (BablFormat *) BABL (babl->fish.source),
716 (char *) source,
717 double_buf,
718 n);
719
720 convert_from_double (
721 (BablFormat *) BABL (babl->fish.source),
722 (BablFormat *) BABL (babl->fish.destination),
723 double_buf,
724 (char *) destination,
725 n);
726 }
727 babl_free (double_buf);
728 }
729 }
730
731 typedef enum _Kind Kind;
732 enum _Kind { KIND_RGB, KIND_CMYK};
733
format_has_cmyk_model(const Babl * format)734 static int format_has_cmyk_model (const Babl *format)
735 {
736 return format->format.model->flags & BABL_MODEL_FLAG_CMYK;
737 }
738
739 static void
babl_fish_reference_process_double(const Babl * babl,const char * source,char * destination,long n,void * data)740 babl_fish_reference_process_double (const Babl *babl,
741 const char *source,
742 char *destination,
743 long n,
744 void *data)
745 {
746 Kind source_kind = KIND_RGB;
747 Kind destination_kind = KIND_RGB;
748 Babl *source_image = NULL;
749 Babl *rgba_image = NULL;
750 Babl *cmyka_image = NULL;
751 Babl *destination_image = NULL;
752
753
754
755 void *source_double_buf_alloc = NULL;
756 void *source_double_buf = NULL;
757 void *rgba_double_buf_alloc = NULL;
758 void *rgba_double_buf = NULL;
759 void *cmyka_double_buf_alloc = NULL;
760 void *cmyka_double_buf = NULL;
761 void *destination_double_buf_alloc = NULL;
762 void *destination_double_buf;
763 const void *type_double = babl_type_from_id (BABL_DOUBLE);
764
765 const Babl *source_space = BABL (BABL ((babl->fish.source))->format.space);
766 const Babl *destination_space = BABL (BABL ((babl->fish.destination))->format.space);
767
768 /* This is not the full/only condition XXX */
769
770 /* XXX : sometimes is_cmyk is neither 0 or 1 */
771
772 if (format_has_cmyk_model (babl->fish.source))
773 source_kind = KIND_CMYK;
774 if (format_has_cmyk_model (babl->fish.destination))
775 destination_kind = KIND_CMYK;
776
777 if (babl->fish.source->format.type[0] == type_double &&
778 BABL(babl->fish.source)->format.components ==
779 BABL(babl->fish.source)->format.model->components)
780 {
781 source_double_buf = (void*)source;
782 source_image = babl_image_from_linear (
783 source_double_buf, BABL (BABL ((babl->fish.source))->format.model));
784 }
785 else
786 {
787 source_double_buf =
788 source_double_buf_alloc = babl_malloc (sizeof (double) * n *
789 BABL (babl->fish.source)->format.model->components);
790
791 source_image = babl_image_from_linear (
792 source_double_buf, BABL (BABL ((babl->fish.source))->format.model));
793 convert_to_double (
794 (BablFormat *) BABL (babl->fish.source),
795 source,
796 source_double_buf,
797 n
798 );
799 }
800
801 babl_mutex_lock (babl_reference_mutex);
802 switch (source_kind)
803 {
804 case KIND_RGB:
805 {
806 Babl *conv = assert_conversion_find (
807 BABL (babl->fish.source)->format.model,
808 babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
809 source_space));
810
811 rgba_double_buf =
812 rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
813
814 rgba_image = babl_image_from_linear (
815 rgba_double_buf, babl_remodel_with_space (babl_model_from_id (BABL_RGBA), source_space));
816
817 if (conv->class_type == BABL_CONVERSION_PLANAR)
818 {
819 babl_conversion_process (conv,
820 (void*)source_image, (void*)rgba_image, n);
821 }
822 else if (conv->class_type == BABL_CONVERSION_LINEAR)
823 {
824 babl_conversion_process (conv, source_double_buf, rgba_double_buf, n);
825 }
826 else babl_fatal ("oops");
827 }
828 break;
829 case KIND_CMYK:
830 if (babl_model_is ((void*)babl->fish.source->format.model, "cmykA"))
831 {
832 cmyka_double_buf = source_double_buf;
833 cmyka_image = babl_image_from_linear (cmyka_double_buf,
834 (void*)babl->fish.source->format.model);
835 }
836 else
837 {
838 Babl *conv = assert_conversion_find (
839 BABL (babl->fish.source)->format.model,
840 babl_remodel_with_space (babl_model ("cmykA"),
841 source_space));
842
843 cmyka_double_buf =
844 cmyka_double_buf_alloc = babl_malloc (sizeof (double) * n * 5);
845
846 cmyka_image = babl_image_from_linear (
847 cmyka_double_buf, babl_remodel_with_space (babl_model ("cmykA"),
848 source_space));
849
850 if (conv->class_type == BABL_CONVERSION_PLANAR)
851 {
852 babl_conversion_process (conv,
853 (void*)source_image, (void*)cmyka_image, n);
854 }
855 else if (conv->class_type == BABL_CONVERSION_LINEAR)
856 {
857 babl_conversion_process (conv,source_double_buf, cmyka_double_buf, n);
858 }
859 else babl_fatal ("oops");
860 }
861 break;
862 }
863
864 if (source_kind == KIND_RGB &&
865 destination_kind == KIND_RGB)
866 {
867 if (source_space != destination_space)
868 {
869 double matrix[9];
870 double *rgba = rgba_double_buf;
871 babl_matrix_mul_matrix (
872 destination_space->space.XYZtoRGB,
873 source_space->space.RGBtoXYZ,
874 matrix);
875
876 babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n);
877 }
878 }
879 else if (source_kind == KIND_RGB &&
880 destination_kind == KIND_CMYK)
881 {
882 cmyka_double_buf =
883 cmyka_double_buf_alloc = babl_malloc (sizeof (double) * n * 5);
884 cmyka_image = babl_image_from_linear (
885 cmyka_double_buf, babl_remodel_with_space (babl_model ("cmykA"),
886 destination_space));
887
888 #if HAVE_LCMS
889 if (destination_space->space.cmyk.lcms_profile)
890 {
891 /* lcms expect floats with normalized range 0.0-100.0 for CMYK data,
892 we also do our inversion from profile here.
893 */
894 double *rgba=rgba_double_buf;
895 double *cmyka=cmyka_double_buf;
896 int i;
897 /* use lcms for doing conversion from RGBA */
898 cmsDoTransform (destination_space->space.cmyk.lcms_from_rgba,
899 rgba_double_buf, cmyka_double_buf, n);
900
901 for (i = 0; i < n; i++)
902 {
903 cmyka[i * 5 + 0] = 1.0-(cmyka[i * 5 + 0])/100.0;
904 cmyka[i * 5 + 1] = 1.0-(cmyka[i * 5 + 1])/100.0;
905 cmyka[i * 5 + 2] = 1.0-(cmyka[i * 5 + 2])/100.0;
906 cmyka[i * 5 + 3] = 1.0-(cmyka[i * 5 + 3])/100.0;
907 cmyka[i * 5 + 4] = rgba[i * 4 + 3];
908 }
909 }
910 else
911 #endif
912 {
913 double *rgba=rgba_double_buf;
914 double *cmyka=cmyka_double_buf;
915 int i;
916 for (i = 0; i < n; i++)
917 {
918 /* A very naive conversion - but it is usable */
919 double key=1.0;
920 cmyka[i * 5 + 0] = 1.0 - rgba[i * 4 + 0];
921 cmyka[i * 5 + 1] = 1.0 - rgba[i * 4 + 1];
922 cmyka[i * 5 + 2] = 1.0 - rgba[i * 4 + 2];
923
924 if (cmyka[i * 5 + 0] < key) key = cmyka[i*5+0];
925 if (cmyka[i * 5 + 1] < key) key = cmyka[i*5+1];
926 if (cmyka[i * 5 + 2] < key) key = cmyka[i*5+2];
927
928 key *= 1.0; // pullout - XXX tune default pullout?;
929
930 if (key < 1.0)
931 {
932 cmyka[i * 5 + 0] = (cmyka[i * 5 + 0] - key) / (1.0-key);
933 cmyka[i * 5 + 1] = (cmyka[i * 5 + 1] - key) / (1.0-key);
934 cmyka[i * 5 + 2] = (cmyka[i * 5 + 2] - key) / (1.0-key);
935 }
936 cmyka[i * 5 + 0] = 1.0-cmyka[i * 5 + 0];
937 cmyka[i * 5 + 1] = 1.0-cmyka[i * 5 + 1];
938 cmyka[i * 5 + 2] = 1.0-cmyka[i * 5 + 2];
939 cmyka[i * 5 + 3] = 1.0-key;
940 cmyka[i * 5 + 4] = rgba[i * 4 + 3];
941 }
942 }
943 }
944 else if (source_kind == KIND_CMYK &&
945 destination_kind == KIND_RGB)
946 {
947 /* */
948 rgba_double_buf_alloc = babl_malloc (sizeof (double) * n * 4);
949 rgba_double_buf = rgba_double_buf_alloc;
950 rgba_image = babl_image_from_linear (
951 rgba_double_buf, babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
952 destination_space));
953
954 #if HAVE_LCMS
955 if (source_space->space.cmyk.lcms_profile)
956 {
957 {
958 /* lcms expect floats with normalized range 0.0-100.0 for CMYK data,
959 we also do our inversion from profile here.
960 */
961 double *cmyka=cmyka_double_buf;
962 int i;
963 for (i = 0; i < n; i++)
964 {
965 cmyka[i * 5 + 0] = (1.0-cmyka[i * 5 + 0])*100.0;
966 cmyka[i * 5 + 1] = (1.0-cmyka[i * 5 + 1])*100.0;
967 cmyka[i * 5 + 2] = (1.0-cmyka[i * 5 + 2])*100.0;
968 cmyka[i * 5 + 3] = (1.0-cmyka[i * 5 + 3])*100.0;
969 }
970 }
971 /* use lcms for doing conversion to RGBA */
972 cmsDoTransform (source_space->space.cmyk.lcms_to_rgba,
973 cmyka_double_buf, rgba_double_buf, n);
974
975 {
976 double *rgba=rgba_double_buf;
977 double *cmyka=cmyka_double_buf;
978 int i;
979 for (i = 0; i < n; i++)
980 {
981 rgba[i * 4 + 3] = cmyka[i * 5 + 4];
982 }
983 }
984 }
985 else
986 #endif
987 {
988 double *rgba=rgba_double_buf;
989 double *cmyka=cmyka_double_buf;
990 int i;
991 for (i = 0; i < n; i++)
992 {
993 /* A very naive conversion - but it is usable */
994 rgba[i * 4 + 0] = cmyka[i * 5 + 0]*cmyka[i*5+3];
995 rgba[i * 4 + 1] = cmyka[i * 5 + 1]*cmyka[i*5+3];
996 rgba[i * 4 + 2] = cmyka[i * 5 + 2]*cmyka[i*5+3];
997 rgba[i * 4 + 3] = cmyka[i * 5 + 4];
998 }
999 }
1000
1001 /* color space conversions */
1002 if ((babl_space ("scRGB")!=
1003 ((babl->fish.destination)->format.space)))
1004 {
1005 double matrix[9];
1006 double *rgba = rgba_double_buf;
1007 babl_matrix_mul_matrix (
1008 (babl->fish.destination)->format.space->space.XYZtoRGB,
1009 babl_space("scRGB")->space.RGBtoXYZ,
1010 matrix);
1011
1012 babl_matrix_mul_vector_buf4 (matrix, rgba, rgba, n);
1013 }
1014 }
1015 else if (source_kind == KIND_CMYK &&
1016 destination_kind == KIND_CMYK)
1017 {
1018 if (source_space != destination_space
1019 #if HAVE_LCMS
1020 && source_space->space.cmyk.lcms_profile
1021 && destination_space->space.cmyk.lcms_profile
1022 #endif
1023 )
1024 {
1025 #if HAVE_LCMS
1026
1027 #define MAX_CMYK_CMYK 64
1028 static int cmyk_cmyk_count = 0;
1029 static const Babl *cmyk_cmyk_source[MAX_CMYK_CMYK];
1030 static const Babl *cmyk_cmyk_destination[MAX_CMYK_CMYK];
1031 static cmsHTRANSFORM cmyk_cmyk_transform[MAX_CMYK_CMYK];
1032
1033 int cmyk_cmyk_no;
1034 double *cmyka = cmyka_double_buf;
1035 for (cmyk_cmyk_no = 0; cmyk_cmyk_no < cmyk_cmyk_count; cmyk_cmyk_no++)
1036 {
1037 if (cmyk_cmyk_source[cmyk_cmyk_no] == source_space &&
1038 cmyk_cmyk_destination[cmyk_cmyk_no] == destination_space)
1039 break;
1040 }
1041
1042 /* these are not defined by lcms2.h we hope that following the existing pattern of pixel-format definitions work */
1043 #ifndef TYPE_CMYKA_DBL
1044 #define TYPE_CMYKA_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|EXTRA_SH(1)|CHANNELS_SH(4)|BYTES_SH(0))
1045 #endif
1046
1047 if (cmyk_cmyk_no >= cmyk_cmyk_count)
1048 {
1049 cmsHPROFILE src_profile = cmsOpenProfileFromMem(source_space->space.icc_profile, source_space->space.icc_length);
1050 cmsHPROFILE dst_profile = cmsOpenProfileFromMem(destination_space->space.icc_profile, source_space->space.icc_length);
1051
1052 cmyk_cmyk_source[cmyk_cmyk_no] = source_space;
1053 cmyk_cmyk_destination[cmyk_cmyk_no] = destination_space;
1054 cmyk_cmyk_transform[cmyk_cmyk_no] = cmsCreateTransform(src_profile, TYPE_CMYKA_DBL,
1055 dst_profile, TYPE_CMYKA_DBL,
1056 INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_BLACKPOINTCOMPENSATION);
1057 cmsCloseProfile (src_profile);
1058 cmsCloseProfile (dst_profile);
1059
1060 cmyk_cmyk_count ++;
1061 }
1062 for (int i = 0; i < n; i++)
1063 {
1064 cmyka[i * 5 + 0] = (1.0-cmyka[i * 5 + 0])*100.0;
1065 cmyka[i * 5 + 1] = (1.0-cmyka[i * 5 + 1])*100.0;
1066 cmyka[i * 5 + 2] = (1.0-cmyka[i * 5 + 2])*100.0;
1067 cmyka[i * 5 + 3] = (1.0-cmyka[i * 5 + 3])*100.0;
1068 }
1069
1070 cmsDoTransform (cmyk_cmyk_transform[cmyk_cmyk_no],
1071 cmyka_double_buf, cmyka_double_buf, n);
1072
1073 for (int i = 0; i < n; i++)
1074 {
1075 cmyka[i * 5 + 0] = 1.0-(cmyka[i * 5 + 0])/100.0;
1076 cmyka[i * 5 + 1] = 1.0-(cmyka[i * 5 + 1])/100.0;
1077 cmyka[i * 5 + 2] = 1.0-(cmyka[i * 5 + 2])/100.0;
1078 cmyka[i * 5 + 3] = 1.0-(cmyka[i * 5 + 3])/100.0;
1079 }
1080
1081 #endif
1082 }
1083 }
1084
1085
1086 switch (destination_kind) /* XXX: the cases can share logic */
1087 {
1088 case KIND_CMYK:
1089 {
1090 const Babl *destination_cmyka_format =
1091 babl_remodel_with_space (babl_model ("cmykA"), destination_space);
1092 if(BABL (babl->fish.destination)->format.model == (void*)destination_cmyka_format)
1093 {
1094 destination_double_buf = cmyka_double_buf;
1095 }
1096 else
1097 {
1098 Babl *conv =
1099 assert_conversion_find (destination_cmyka_format,
1100 BABL (babl->fish.destination)->format.model);
1101 destination_double_buf =
1102 destination_double_buf_alloc = babl_malloc (sizeof (double) * n *
1103 BABL (babl->fish.destination)->format.model->components);
1104 if (conv->class_type == BABL_CONVERSION_PLANAR)
1105 {
1106 destination_image = babl_image_from_linear (
1107 destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model));
1108 babl_conversion_process (conv,
1109 (void*)cmyka_image, (void*)destination_image, n);
1110 }
1111 else if (conv->class_type == BABL_CONVERSION_LINEAR)
1112 {
1113 babl_conversion_process (conv,
1114 cmyka_double_buf, destination_double_buf, n);
1115 }
1116 else
1117 {
1118 babl_fatal ("oops");
1119 }
1120 }
1121 }
1122 break;
1123 case KIND_RGB:
1124 {
1125 const Babl *destination_rgba_format =
1126 babl_remodel_with_space (babl_model_from_id (BABL_RGBA),
1127 destination_space);
1128
1129 if(BABL (babl->fish.destination)->format.model == (void*)destination_rgba_format)
1130 {
1131 destination_double_buf = rgba_double_buf;
1132 }
1133 else
1134 {
1135 Babl *conv =
1136 assert_conversion_find (destination_rgba_format,
1137 BABL (babl->fish.destination)->format.model);
1138 destination_double_buf_alloc = babl_malloc (sizeof (double) * n *
1139 BABL (babl->fish.destination)->format.model->components);
1140 destination_double_buf = destination_double_buf_alloc;
1141
1142 if (conv->class_type == BABL_CONVERSION_PLANAR)
1143 {
1144 destination_image = babl_image_from_linear (
1145 destination_double_buf, BABL (BABL ((babl->fish.destination))->format.model));
1146 babl_conversion_process (
1147 conv,
1148 (void*)rgba_image, (void*)destination_image,
1149 n);
1150 }
1151 else if (conv->class_type == BABL_CONVERSION_LINEAR)
1152 {
1153 babl_conversion_process (
1154 conv,
1155 rgba_double_buf, destination_double_buf,
1156 n);
1157 }
1158 else
1159 {
1160 babl_fatal ("oops");
1161 }
1162 }
1163 }
1164 break;
1165 }
1166 babl_mutex_unlock (babl_reference_mutex);
1167
1168 /* convert from double model backing target pixel format to final representation */
1169 convert_from_double (
1170 (BablFormat *) BABL (babl->fish.source),
1171 (BablFormat *) BABL (babl->fish.destination),
1172 destination_double_buf,
1173 destination,
1174 n
1175 );
1176
1177 if (destination_double_buf_alloc)
1178 babl_free (destination_double_buf_alloc);
1179 if (rgba_double_buf_alloc)
1180 babl_free (rgba_double_buf_alloc);
1181 if (cmyka_double_buf_alloc)
1182 babl_free (cmyka_double_buf_alloc);
1183 if (source_double_buf_alloc)
1184 babl_free (source_double_buf_alloc);
1185 if (source_image)
1186 babl_free (source_image);
1187 if (rgba_image)
1188 babl_free (rgba_image);
1189 if (cmyka_image)
1190 babl_free (cmyka_image);
1191 if (destination_image)
1192 babl_free (destination_image);
1193 }
1194
1195 static void
babl_fish_reference_process_float(const Babl * babl,const char * source,char * destination,long n,void * data)1196 babl_fish_reference_process_float (const Babl *babl,
1197 const char *source,
1198 char *destination,
1199 long n,
1200 void *data)
1201 {
1202 const void *type_float = babl_type_from_id (BABL_FLOAT);
1203 Babl *source_image = NULL;
1204 Babl *rgba_image = NULL;
1205 Babl *destination_image = NULL;
1206 void *source_float_buf_alloc = NULL;
1207 void *source_float_buf;
1208 void *rgba_float_buf_alloc = NULL;
1209 void *rgba_float_buf;
1210 void *destination_float_buf_alloc = NULL;
1211 void *destination_float_buf;
1212 const Babl *destination_float_format;
1213 Babl *conv_to_rgba;
1214 Babl *conv_from_rgba;
1215 char dst_name[256];
1216
1217
1218 {
1219 char src_name[256];
1220 sprintf (src_name, "%s float", babl_get_name((void*)babl->fish.source->format.model));
1221 conv_to_rgba =
1222 babl_conversion_find (
1223 babl_format_with_space (src_name,
1224 BABL (BABL ((babl->fish.source))->format.space)),
1225 babl_format_with_space ("RGBA float",
1226 BABL (BABL ((babl->fish.source))->format.space)));
1227 }
1228 {
1229 sprintf (dst_name, "%s float", babl_get_name((void*)babl->fish.destination->format.model));
1230 destination_float_format =
1231 babl_format_with_space (dst_name,
1232 BABL (BABL ((babl->fish.destination))->format.space));
1233 conv_from_rgba =
1234 babl_conversion_find (
1235 babl_format_with_space ("RGBA float",
1236 BABL (BABL ((babl->fish.destination))->format.space)),
1237 destination_float_format);
1238 }
1239
1240 if (!conv_to_rgba || !conv_from_rgba)
1241 {
1242 /* needed float conversions not found, using double code path instead */
1243 babl_fish_reference_process_double (babl, source, destination, n, data);
1244 return;
1245 }
1246
1247 babl_mutex_lock (babl_reference_mutex);
1248 if (babl->fish.source->format.type[0] == type_float &&
1249 BABL(babl->fish.source)->format.components ==
1250 BABL(babl->fish.source)->format.model->components && 0)
1251 {
1252 source_float_buf = (void*)source;
1253 source_image = babl_image_from_linear (
1254 source_float_buf,
1255 babl_format_with_model_as_type ((void*)((babl->fish.source))->format.model,
1256 type_float));
1257 }
1258 else
1259 {
1260 /* the +1 is to mask a valgrind 'invalid read of size 16' false positive */
1261 source_float_buf_alloc = babl_malloc (sizeof (float) * (n+1) *
1262 (BABL (babl->fish.source)->format.model->components));
1263
1264 source_float_buf = source_float_buf_alloc;
1265 source_image = babl_image_from_linear (
1266 source_float_buf,
1267 babl_format_with_model_as_type (BABL(BABL ((babl->fish.source))->format.model),
1268 type_float));
1269 convert_to_float (
1270 (BablFormat *) BABL (babl->fish.source),
1271 source,
1272 source_float_buf,
1273 n
1274 );
1275 }
1276
1277 if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA") && 0)
1278 {
1279 rgba_float_buf = source_float_buf;
1280 rgba_image = babl_image_from_linear (
1281 rgba_float_buf,
1282 (void*)babl->fish.source->format.model);
1283 }
1284 else
1285 {
1286 rgba_float_buf_alloc = babl_malloc (sizeof (float) * n * 4);
1287 rgba_float_buf = rgba_float_buf_alloc;
1288
1289 rgba_image = babl_image_from_linear (
1290 rgba_float_buf,
1291 babl_format_with_space ("RGBA float",
1292 BABL (BABL ((babl->fish.source))->format.space)));
1293
1294
1295 if (conv_to_rgba->class_type == BABL_CONVERSION_PLANAR)
1296 {
1297 babl_conversion_process (
1298 conv_to_rgba,
1299 (void*)source_image, (void*)rgba_image,
1300 n);
1301 }
1302 else if (conv_to_rgba->class_type == BABL_CONVERSION_LINEAR)
1303 {
1304 babl_conversion_process (
1305 conv_to_rgba,
1306 source_float_buf, rgba_float_buf,
1307 n);
1308 }
1309 }
1310 babl_mutex_unlock (babl_reference_mutex);
1311
1312 if (((babl->fish.source)->format.space !=
1313 ((babl->fish.destination)->format.space)))
1314 {
1315 float matrix[9];
1316 float *rgba = rgba_float_buf;
1317 babl_matrix_mul_matrixf (
1318 (babl->fish.destination)->format.space->space.XYZtoRGBf,
1319 (babl->fish.source)->format.space->space.RGBtoXYZf,
1320 matrix);
1321
1322 babl_matrix_mul_vectorff_buf4 (matrix, rgba, rgba, n);
1323 }
1324
1325 {
1326 if(babl_format_with_space ("RGBA float",
1327 BABL (BABL ((babl->fish.destination))->format.space)) ==
1328 babl_format_with_space (dst_name,
1329 BABL (BABL ((babl->fish.destination))->format.space)))
1330 {
1331 destination_float_buf = rgba_float_buf;
1332 }
1333 else
1334 {
1335 destination_float_buf_alloc = babl_malloc (sizeof (float) * n *
1336 BABL (babl->fish.destination)->format.model->components);
1337 destination_float_buf = destination_float_buf_alloc;
1338
1339 if (conv_from_rgba->class_type == BABL_CONVERSION_PLANAR)
1340 {
1341 destination_image = babl_image_from_linear (
1342 destination_float_buf, destination_float_format);
1343 babl_conversion_process (
1344 conv_from_rgba,
1345 (void*)rgba_image, (void*)destination_image,
1346 n);
1347 }
1348 else if (conv_from_rgba->class_type == BABL_CONVERSION_LINEAR)
1349 {
1350 babl_conversion_process (conv_from_rgba, rgba_float_buf,
1351 destination_float_buf, n);
1352 }
1353 }
1354 }
1355
1356 convert_from_float (
1357 (BablFormat *) BABL (babl->fish.source),
1358 (BablFormat *) BABL (babl->fish.destination),
1359 destination_float_buf,
1360 destination,
1361 n
1362 );
1363
1364 if (destination_float_buf_alloc)
1365 babl_free (destination_float_buf_alloc);
1366 if (rgba_float_buf_alloc)
1367 babl_free (rgba_float_buf_alloc);
1368 if (source_float_buf_alloc)
1369 babl_free (source_float_buf_alloc);
1370 if (source_image)
1371 babl_free (source_image);
1372 if (rgba_image)
1373 babl_free (rgba_image);
1374 if (destination_image)
1375 babl_free (destination_image);
1376 }
1377
1378 void
babl_fish_reference_process(const Babl * babl,const char * source,char * destination,long n,void * data)1379 babl_fish_reference_process (const Babl *babl,
1380 const char *source,
1381 char *destination,
1382 long n,
1383 void *data)
1384 {
1385 static const void *type_float = NULL;
1386 static int allow_float_reference = -1;
1387
1388 if (!type_float) type_float = babl_type_from_id (BABL_FLOAT);
1389
1390 /* same format in source/destination */
1391 if (BABL (babl->fish.source) == BABL (babl->fish.destination))
1392 {
1393 if (source == destination)
1394 {
1395 memcpy (destination, source, n * babl->fish.source->format.bytes_per_pixel);
1396 }
1397 return;
1398 }
1399
1400 /* same model and space, only convert type */
1401 if ((BABL (babl->fish.source)->format.model ==
1402 BABL (babl->fish.destination)->format.model) &&
1403 (BABL (babl->fish.source)->format.space ==
1404 BABL (babl->fish.destination)->format.space)
1405 )
1406 {
1407 process_same_model (babl, source, destination, n);
1408 return;
1409 }
1410
1411 /* we're converting to a n_component format - special case */
1412 if (babl_format_is_format_n (BABL (babl->fish.destination)))
1413 {
1414 process_to_n_component (babl, source, destination, n);
1415 return;
1416 }
1417
1418 if (format_has_cmyk_model (babl->fish.source) ||
1419 format_has_cmyk_model (babl->fish.destination))
1420 {
1421 babl_fish_reference_process_double (babl, source, destination, n, data);
1422 return;
1423 }
1424
1425 if (allow_float_reference == -1)
1426 allow_float_reference = getenv ("BABL_REFERENCE_NOFLOAT") ? 0 : 1;
1427
1428 /* both source and destination are either single precision float or <32bit component,
1429 we then do a similar to the double reference - using the first registered
1430 float conversions - note that this makes the first registered float conversion of
1431 a given type a reference, and we thus rely on the *first* float conversion regsitered
1432 to be correct, this will be the case if the code paths are duplicated and we register
1433 either a planar or linear conversion to and from "RGBA float" at the same time as
1434 registering conversions for double. When needed conversions do not exist, we defer
1435 to the double code paths
1436 */
1437 if (allow_float_reference &&
1438 (babl->fish.source->format.type[0]->bits < 32 ||
1439 babl->fish.source->format.type[0] == type_float) &&
1440 (babl->fish.destination->format.type[0]->bits < 32 ||
1441 babl->fish.destination->format.type[0] == type_float) &&
1442 !babl_format_is_palette (babl->fish.source) &&
1443 !babl_format_is_palette (babl->fish.destination))
1444 {
1445 babl_fish_reference_process_float (babl, source, destination, n, data);
1446 }
1447 else /* double */
1448 {
1449 babl_fish_reference_process_double (babl, source, destination, n, data);
1450 }
1451
1452 }
1453