1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimp-babl.c
5 * Copyright (C) 2012 Michael Natterer <mitch@gimp.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <cairo.h>
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 #include <gegl.h>
26
27 #include "libgimpcolor/gimpcolor.h"
28
29 #include "gimp-gegl-types.h"
30
31 #include "gimp-babl.h"
32
33 #include "gimp-intl.h"
34
35
36 void
gimp_babl_init(void)37 gimp_babl_init (void)
38 {
39 babl_format_new ("name", "R u8",
40 babl_model ("RGBA"),
41 babl_type ("u8"),
42 babl_component ("R"),
43 NULL);
44 babl_format_new ("name", "R' u8",
45 babl_model ("R'G'B'A"),
46 babl_type ("u8"),
47 babl_component ("R'"),
48 NULL);
49 babl_format_new ("name", "G u8",
50 babl_model ("RGBA"),
51 babl_type ("u8"),
52 babl_component ("G"),
53 NULL);
54 babl_format_new ("name", "G' u8",
55 babl_model ("R'G'B'A"),
56 babl_type ("u8"),
57 babl_component ("G'"),
58 NULL);
59 babl_format_new ("name", "B u8",
60 babl_model ("RGBA"),
61 babl_type ("u8"),
62 babl_component ("B"),
63 NULL);
64 babl_format_new ("name", "B' u8",
65 babl_model ("R'G'B'A"),
66 babl_type ("u8"),
67 babl_component ("B'"),
68 NULL);
69 babl_format_new ("name", "A u8",
70 babl_model ("RGBA"),
71 babl_type ("u8"),
72 babl_component ("A"),
73 NULL);
74
75 babl_format_new ("name", "R u16",
76 babl_model ("RGBA"),
77 babl_type ("u16"),
78 babl_component ("R"),
79 NULL);
80 babl_format_new ("name", "R' u16",
81 babl_model ("R'G'B'A"),
82 babl_type ("u16"),
83 babl_component ("R'"),
84 NULL);
85 babl_format_new ("name", "G u16",
86 babl_model ("RGBA"),
87 babl_type ("u16"),
88 babl_component ("G"),
89 NULL);
90 babl_format_new ("name", "G' u16",
91 babl_model ("R'G'B'A"),
92 babl_type ("u16"),
93 babl_component ("G'"),
94 NULL);
95 babl_format_new ("name", "B u16",
96 babl_model ("RGBA"),
97 babl_type ("u16"),
98 babl_component ("B"),
99 NULL);
100 babl_format_new ("name", "B' u16",
101 babl_model ("R'G'B'A"),
102 babl_type ("u16"),
103 babl_component ("B'"),
104 NULL);
105 babl_format_new ("name", "A u16",
106 babl_model ("RGBA"),
107 babl_type ("u16"),
108 babl_component ("A"),
109 NULL);
110
111 babl_format_new ("name", "R u32",
112 babl_model ("RGBA"),
113 babl_type ("u32"),
114 babl_component ("R"),
115 NULL);
116 babl_format_new ("name", "R' u32",
117 babl_model ("R'G'B'A"),
118 babl_type ("u32"),
119 babl_component ("R'"),
120 NULL);
121 babl_format_new ("name", "G u32",
122 babl_model ("RGBA"),
123 babl_type ("u32"),
124 babl_component ("G"),
125 NULL);
126 babl_format_new ("name", "G' u32",
127 babl_model ("R'G'B'A"),
128 babl_type ("u32"),
129 babl_component ("G'"),
130 NULL);
131 babl_format_new ("name", "B u32",
132 babl_model ("RGBA"),
133 babl_type ("u32"),
134 babl_component ("B"),
135 NULL);
136 babl_format_new ("name", "B' u32",
137 babl_model ("R'G'B'A"),
138 babl_type ("u32"),
139 babl_component ("B'"),
140 NULL);
141 babl_format_new ("name", "A u32",
142 babl_model ("RGBA"),
143 babl_type ("u32"),
144 babl_component ("A"),
145 NULL);
146
147 babl_format_new ("name", "R half",
148 babl_model ("RGBA"),
149 babl_type ("half"),
150 babl_component ("R"),
151 NULL);
152 babl_format_new ("name", "R' half",
153 babl_model ("R'G'B'A"),
154 babl_type ("half"),
155 babl_component ("R'"),
156 NULL);
157 babl_format_new ("name", "G half",
158 babl_model ("RGBA"),
159 babl_type ("half"),
160 babl_component ("G"),
161 NULL);
162 babl_format_new ("name", "G' half",
163 babl_model ("R'G'B'A"),
164 babl_type ("half"),
165 babl_component ("G'"),
166 NULL);
167 babl_format_new ("name", "B half",
168 babl_model ("RGBA"),
169 babl_type ("half"),
170 babl_component ("B"),
171 NULL);
172 babl_format_new ("name", "B' half",
173 babl_model ("R'G'B'A"),
174 babl_type ("half"),
175 babl_component ("B'"),
176 NULL);
177 babl_format_new ("name", "A half",
178 babl_model ("RGBA"),
179 babl_type ("half"),
180 babl_component ("A"),
181 NULL);
182
183 babl_format_new ("name", "R float",
184 babl_model ("RGBA"),
185 babl_type ("float"),
186 babl_component ("R"),
187 NULL);
188 babl_format_new ("name", "R' float",
189 babl_model ("R'G'B'A"),
190 babl_type ("float"),
191 babl_component ("R'"),
192 NULL);
193 babl_format_new ("name", "G float",
194 babl_model ("RGBA"),
195 babl_type ("float"),
196 babl_component ("G"),
197 NULL);
198 babl_format_new ("name", "G' float",
199 babl_model ("R'G'B'A"),
200 babl_type ("float"),
201 babl_component ("G'"),
202 NULL);
203 babl_format_new ("name", "B float",
204 babl_model ("RGBA"),
205 babl_type ("float"),
206 babl_component ("B"),
207 NULL);
208 babl_format_new ("name", "B' float",
209 babl_model ("R'G'B'A"),
210 babl_type ("float"),
211 babl_component ("B'"),
212 NULL);
213 babl_format_new ("name", "A float",
214 babl_model ("RGBA"),
215 babl_type ("float"),
216 babl_component ("A"),
217 NULL);
218
219 babl_format_new ("name", "R double",
220 babl_model ("RGBA"),
221 babl_type ("double"),
222 babl_component ("R"),
223 NULL);
224 babl_format_new ("name", "R' double",
225 babl_model ("R'G'B'A"),
226 babl_type ("double"),
227 babl_component ("R'"),
228 NULL);
229 babl_format_new ("name", "G double",
230 babl_model ("RGBA"),
231 babl_type ("double"),
232 babl_component ("G"),
233 NULL);
234 babl_format_new ("name", "G' double",
235 babl_model ("R'G'B'A"),
236 babl_type ("double"),
237 babl_component ("G'"),
238 NULL);
239 babl_format_new ("name", "B double",
240 babl_model ("RGBA"),
241 babl_type ("double"),
242 babl_component ("B"),
243 NULL);
244 babl_format_new ("name", "B' double",
245 babl_model ("R'G'B'A"),
246 babl_type ("double"),
247 babl_component ("B'"),
248 NULL);
249 babl_format_new ("name", "A double",
250 babl_model ("RGBA"),
251 babl_type ("double"),
252 babl_component ("A"),
253 NULL);
254 }
255
256 void
gimp_babl_init_fishes(GimpInitStatusFunc status_callback)257 gimp_babl_init_fishes (GimpInitStatusFunc status_callback)
258 {
259 /* create a bunch of fishes - to decrease the initial lazy
260 * initialization cost for some interactions
261 */
262 static const struct
263 {
264 const gchar *from_format;
265 const gchar *to_format;
266 }
267 fishes[] =
268 {
269 { "Y' u8", "RaGaBaA float" },
270 { "Y u8", "RaGaBaA float" },
271 { "R'G'B'A u8", "RaGaBaA float" },
272 { "R'G'B'A float", "R'G'B'A u8" },
273 { "R'G'B'A float", "R'G'B' u8" },
274 { "R'G'B'A u8", "RGBA float" },
275 { "RGBA float", "R'G'B'A u8" },
276 { "RGBA float", "R'G'B'A u8" },
277 { "RGBA float", "R'G'B'A float" },
278 { "Y' u8", "R'G'B' u8" },
279 { "Y u8", "Y float" },
280 { "R'G'B' u8", "cairo-RGB24" },
281 { "R'G'B' u8", "R'G'B'A float" },
282 { "R'G'B' u8", "R'G'B'A u8" },
283 { "R'G'B'A u8", "R'G'B'A float" },
284 { "R'G'B'A u8", "cairo-ARGB32" },
285 { "R'G'B'A double", "RGBA float" },
286 { "R'G'B'A float", "RGBA double" },
287 { "R'G'B' u8", "RGB float" },
288 { "RGB float", "R'G'B'A float" },
289 { "R'G'B' u8", "RGBA float" },
290 { "RaGaBaA float", "R'G'B'A float" },
291 { "RaGaBaA float", "RGBA float" },
292 { "RGBA float", "RaGaBaA float" },
293 { "R'G'B' u8", "RaGaBaA float" },
294 { "cairo-ARGB32", "R'G'B'A u8" }
295 };
296
297 gint i;
298
299 for (i = 0; i < G_N_ELEMENTS (fishes); i++)
300 {
301 status_callback (NULL, NULL,
302 (gdouble) (i + 1) /
303 (gdouble) G_N_ELEMENTS (fishes) * 0.8);
304
305 babl_fish (babl_format (fishes[i].from_format),
306 babl_format (fishes[i].to_format));
307 }
308 }
309
310 static const struct
311 {
312 const gchar *name;
313 const gchar *description;
314 }
315 babl_descriptions[] =
316 {
317 { "RGB u8", N_("RGB") },
318 { "R'G'B' u8", N_("RGB") },
319 { "RGB u16", N_("RGB") },
320 { "R'G'B' u16", N_("RGB") },
321 { "RGB u32", N_("RGB") },
322 { "R'G'B' u32", N_("RGB") },
323 { "RGB half", N_("RGB") },
324 { "R'G'B' half", N_("RGB") },
325 { "RGB float", N_("RGB") },
326 { "R'G'B' float", N_("RGB") },
327 { "RGB double", N_("RGB") },
328 { "R'G'B' double", N_("RGB") },
329
330 { "RGBA u8", N_("RGB-alpha") },
331 { "R'G'B'A u8", N_("RGB-alpha") },
332 { "RGBA u16", N_("RGB-alpha") },
333 { "R'G'B'A u16", N_("RGB-alpha") },
334 { "RGBA u32", N_("RGB-alpha") },
335 { "R'G'B'A u32", N_("RGB-alpha") },
336 { "RGBA half", N_("RGB-alpha") },
337 { "R'G'B'A half", N_("RGB-alpha") },
338 { "RGBA float", N_("RGB-alpha") },
339 { "R'G'B'A float", N_("RGB-alpha") },
340 { "RGBA double", N_("RGB-alpha") },
341 { "R'G'B'A double", N_("RGB-alpha") },
342
343 { "Y u8", N_("Grayscale") },
344 { "Y' u8", N_("Grayscale") },
345 { "Y u16", N_("Grayscale") },
346 { "Y' u16", N_("Grayscale") },
347 { "Y u32", N_("Grayscale") },
348 { "Y' u32", N_("Grayscale") },
349 { "Y half", N_("Grayscale") },
350 { "Y' half", N_("Grayscale") },
351 { "Y float", N_("Grayscale") },
352 { "Y' float", N_("Grayscale") },
353 { "Y double", N_("Grayscale") },
354 { "Y' double", N_("Grayscale") },
355
356 { "YA u8", N_("Grayscale-alpha") },
357 { "Y'A u8", N_("Grayscale-alpha") },
358 { "YA u16", N_("Grayscale-alpha") },
359 { "Y'A u16", N_("Grayscale-alpha") },
360 { "YA u32", N_("Grayscale-alpha") },
361 { "Y'A u32", N_("Grayscale-alpha") },
362 { "YA half", N_("Grayscale-alpha") },
363 { "Y'A half", N_("Grayscale-alpha") },
364 { "YA float", N_("Grayscale-alpha") },
365 { "Y'A float", N_("Grayscale-alpha") },
366 { "YA double", N_("Grayscale-alpha") },
367 { "Y'A double", N_("Grayscale-alpha") },
368
369 { "R u8", N_("Red component") },
370 { "R' u8", N_("Red component") },
371 { "R u16", N_("Red component") },
372 { "R' u16", N_("Red component") },
373 { "R u32", N_("Red component") },
374 { "R' u32", N_("Red component") },
375 { "R half", N_("Red component") },
376 { "R' half", N_("Red component") },
377 { "R float", N_("Red component") },
378 { "R' float", N_("Red component") },
379 { "R double", N_("Red component") },
380 { "R' double", N_("Red component") },
381
382 { "G u8", N_("Green component") },
383 { "G' u8", N_("Green component") },
384 { "G u16", N_("Green component") },
385 { "G' u16", N_("Green component") },
386 { "G u32", N_("Green component") },
387 { "G' u32", N_("Green component") },
388 { "G half", N_("Green component") },
389 { "G' half", N_("Green component") },
390 { "G float", N_("Green component") },
391 { "G' float", N_("Green component") },
392 { "G double", N_("Green component") },
393 { "G' double", N_("Green component") },
394
395 { "B u8", N_("Blue component") },
396 { "B' u8", N_("Blue component") },
397 { "B u16", N_("Blue component") },
398 { "B' u16", N_("Blue component") },
399 { "B u32", N_("Blue component") },
400 { "B' u32", N_("Blue component") },
401 { "B half", N_("Blue component") },
402 { "B' half", N_("Blue component") },
403 { "B float", N_("Blue component") },
404 { "B' float", N_("Blue component") },
405 { "B double", N_("Blue component") },
406 { "B' double", N_("Blue component") },
407
408 { "A u8", N_("Alpha component") },
409 { "A u16", N_("Alpha component") },
410 { "A u32", N_("Alpha component") },
411 { "A half", N_("Alpha component") },
412 { "A float", N_("Alpha component") },
413 { "A double", N_("Alpha component") }
414 };
415
416 static GHashTable *babl_description_hash = NULL;
417
418 const gchar *
gimp_babl_format_get_description(const Babl * babl)419 gimp_babl_format_get_description (const Babl *babl)
420 {
421 const gchar *description;
422
423 g_return_val_if_fail (babl != NULL, NULL);
424
425 if (G_UNLIKELY (! babl_description_hash))
426 {
427 gint i;
428
429 babl_description_hash = g_hash_table_new (g_str_hash,
430 g_str_equal);
431
432 for (i = 0; i < G_N_ELEMENTS (babl_descriptions); i++)
433 g_hash_table_insert (babl_description_hash,
434 (gpointer) babl_descriptions[i].name,
435 gettext (babl_descriptions[i].description));
436 }
437
438 if (babl_format_is_palette (babl))
439 {
440 if (babl_format_has_alpha (babl))
441 return _("Indexed-alpha");
442 else
443 return _("Indexed");
444 }
445
446 description = g_hash_table_lookup (babl_description_hash,
447 babl_get_name (babl));
448
449 if (description)
450 return description;
451
452 return g_strconcat ("ERROR: unknown Babl format ",
453 babl_get_name (babl), NULL);
454 }
455
456 GimpColorProfile *
gimp_babl_format_get_color_profile(const Babl * format)457 gimp_babl_format_get_color_profile (const Babl *format)
458 {
459 static GimpColorProfile *srgb_profile = NULL;
460 static GimpColorProfile *linear_rgb_profile = NULL;
461 static GimpColorProfile *gray_profile = NULL;
462 static GimpColorProfile *linear_gray_profile = NULL;
463
464 g_return_val_if_fail (format != NULL, NULL);
465
466 if (gimp_babl_format_get_base_type (format) == GIMP_GRAY)
467 {
468 if (gimp_babl_format_get_linear (format))
469 {
470 if (! linear_gray_profile)
471 {
472 linear_gray_profile = gimp_color_profile_new_d65_gray_linear ();
473 g_object_add_weak_pointer (G_OBJECT (linear_gray_profile),
474 (gpointer) &linear_gray_profile);
475 }
476
477 return linear_gray_profile;
478 }
479 else
480 {
481 if (! gray_profile)
482 {
483 gray_profile = gimp_color_profile_new_d65_gray_srgb_trc ();
484 g_object_add_weak_pointer (G_OBJECT (gray_profile),
485 (gpointer) &gray_profile);
486 }
487
488 return gray_profile;
489 }
490 }
491 else
492 {
493 if (gimp_babl_format_get_linear (format))
494 {
495 if (! linear_rgb_profile)
496 {
497 linear_rgb_profile = gimp_color_profile_new_rgb_srgb_linear ();
498 g_object_add_weak_pointer (G_OBJECT (linear_rgb_profile),
499 (gpointer) &linear_rgb_profile);
500 }
501
502 return linear_rgb_profile;
503 }
504 else
505 {
506 if (! srgb_profile)
507 {
508 srgb_profile = gimp_color_profile_new_rgb_srgb ();
509 g_object_add_weak_pointer (G_OBJECT (srgb_profile),
510 (gpointer) &srgb_profile);
511 }
512
513 return srgb_profile;
514 }
515 }
516 }
517
518 GimpImageBaseType
gimp_babl_format_get_base_type(const Babl * format)519 gimp_babl_format_get_base_type (const Babl *format)
520 {
521 const Babl *model;
522
523 g_return_val_if_fail (format != NULL, -1);
524
525 model = babl_format_get_model (format);
526
527 if (model == babl_model ("Y") ||
528 model == babl_model ("Y'") ||
529 model == babl_model ("YA") ||
530 model == babl_model ("Y'A"))
531 {
532 return GIMP_GRAY;
533 }
534 else if (model == babl_model ("RGB") ||
535 model == babl_model ("R'G'B'") ||
536 model == babl_model ("RGBA") ||
537 model == babl_model ("R'G'B'A") ||
538 model == babl_model ("RaGaBaA") ||
539 model == babl_model ("R'aG'aB'aA"))
540 {
541 return GIMP_RGB;
542 }
543 else if (babl_format_is_palette (format))
544 {
545 return GIMP_INDEXED;
546 }
547
548 g_return_val_if_reached (-1);
549 }
550
551 GimpComponentType
gimp_babl_format_get_component_type(const Babl * format)552 gimp_babl_format_get_component_type (const Babl *format)
553 {
554 const Babl *type;
555
556 g_return_val_if_fail (format != NULL, -1);
557
558 type = babl_format_get_type (format, 0);
559
560 if (type == babl_type ("u8"))
561 return GIMP_COMPONENT_TYPE_U8;
562 else if (type == babl_type ("u16"))
563 return GIMP_COMPONENT_TYPE_U16;
564 else if (type == babl_type ("u32"))
565 return GIMP_COMPONENT_TYPE_U32;
566 else if (type == babl_type ("half"))
567 return GIMP_COMPONENT_TYPE_HALF;
568 else if (type == babl_type ("float"))
569 return GIMP_COMPONENT_TYPE_FLOAT;
570 else if (type == babl_type ("double"))
571 return GIMP_COMPONENT_TYPE_DOUBLE;
572
573 g_return_val_if_reached (-1);
574 }
575
576 GimpPrecision
gimp_babl_format_get_precision(const Babl * format)577 gimp_babl_format_get_precision (const Babl *format)
578 {
579 const Babl *type;
580
581 g_return_val_if_fail (format != NULL, -1);
582
583 type = babl_format_get_type (format, 0);
584
585 if (gimp_babl_format_get_linear (format))
586 {
587 if (type == babl_type ("u8"))
588 return GIMP_PRECISION_U8_LINEAR;
589 else if (type == babl_type ("u16"))
590 return GIMP_PRECISION_U16_LINEAR;
591 else if (type == babl_type ("u32"))
592 return GIMP_PRECISION_U32_LINEAR;
593 else if (type == babl_type ("half"))
594 return GIMP_PRECISION_HALF_LINEAR;
595 else if (type == babl_type ("float"))
596 return GIMP_PRECISION_FLOAT_LINEAR;
597 else if (type == babl_type ("double"))
598 return GIMP_PRECISION_DOUBLE_LINEAR;
599 }
600 else
601 {
602 if (type == babl_type ("u8"))
603 return GIMP_PRECISION_U8_GAMMA;
604 else if (type == babl_type ("u16"))
605 return GIMP_PRECISION_U16_GAMMA;
606 else if (type == babl_type ("u32"))
607 return GIMP_PRECISION_U32_GAMMA;
608 else if (type == babl_type ("half"))
609 return GIMP_PRECISION_HALF_GAMMA;
610 else if (type == babl_type ("float"))
611 return GIMP_PRECISION_FLOAT_GAMMA;
612 else if (type == babl_type ("double"))
613 return GIMP_PRECISION_DOUBLE_GAMMA;
614 }
615
616 g_return_val_if_reached (-1);
617 }
618
619 gboolean
gimp_babl_format_get_linear(const Babl * format)620 gimp_babl_format_get_linear (const Babl *format)
621 {
622 const Babl *model;
623
624 g_return_val_if_fail (format != NULL, FALSE);
625
626 model = babl_format_get_model (format);
627
628 if (model == babl_model ("Y") ||
629 model == babl_model ("YA") ||
630 model == babl_model ("RGB") ||
631 model == babl_model ("RGBA") ||
632 model == babl_model ("RaGaBaA"))
633 {
634 return TRUE;
635 }
636 else if (model == babl_model ("Y'") ||
637 model == babl_model ("Y'A") ||
638 model == babl_model ("R'G'B'") ||
639 model == babl_model ("R'G'B'A") ||
640 model == babl_model ("R'aG'aB'aA"))
641 {
642 return FALSE;
643 }
644 else if (babl_format_is_palette (format))
645 {
646 return FALSE;
647 }
648
649 g_return_val_if_reached (FALSE);
650 }
651
652 GimpComponentType
gimp_babl_component_type(GimpPrecision precision)653 gimp_babl_component_type (GimpPrecision precision)
654 {
655 switch (precision)
656 {
657 case GIMP_PRECISION_U8_LINEAR:
658 case GIMP_PRECISION_U8_GAMMA:
659 return GIMP_COMPONENT_TYPE_U8;
660
661 case GIMP_PRECISION_U16_LINEAR:
662 case GIMP_PRECISION_U16_GAMMA:
663 return GIMP_COMPONENT_TYPE_U16;
664
665 case GIMP_PRECISION_U32_LINEAR:
666 case GIMP_PRECISION_U32_GAMMA:
667 return GIMP_COMPONENT_TYPE_U32;
668
669 case GIMP_PRECISION_HALF_LINEAR:
670 case GIMP_PRECISION_HALF_GAMMA:
671 return GIMP_COMPONENT_TYPE_HALF;
672
673 case GIMP_PRECISION_FLOAT_LINEAR:
674 case GIMP_PRECISION_FLOAT_GAMMA:
675 return GIMP_COMPONENT_TYPE_FLOAT;
676
677 case GIMP_PRECISION_DOUBLE_LINEAR:
678 case GIMP_PRECISION_DOUBLE_GAMMA:
679 return GIMP_COMPONENT_TYPE_DOUBLE;
680 }
681
682 g_return_val_if_reached (-1);
683 }
684
685 gboolean
gimp_babl_linear(GimpPrecision precision)686 gimp_babl_linear (GimpPrecision precision)
687 {
688 switch (precision)
689 {
690 case GIMP_PRECISION_U8_LINEAR:
691 case GIMP_PRECISION_U16_LINEAR:
692 case GIMP_PRECISION_U32_LINEAR:
693 case GIMP_PRECISION_HALF_LINEAR:
694 case GIMP_PRECISION_FLOAT_LINEAR:
695 case GIMP_PRECISION_DOUBLE_LINEAR:
696 return TRUE;
697
698 case GIMP_PRECISION_U8_GAMMA:
699 case GIMP_PRECISION_U16_GAMMA:
700 case GIMP_PRECISION_U32_GAMMA:
701 case GIMP_PRECISION_HALF_GAMMA:
702 case GIMP_PRECISION_FLOAT_GAMMA:
703 case GIMP_PRECISION_DOUBLE_GAMMA:
704 return FALSE;
705 }
706
707 g_return_val_if_reached (FALSE);
708 }
709
710 GimpPrecision
gimp_babl_precision(GimpComponentType component,gboolean linear)711 gimp_babl_precision (GimpComponentType component,
712 gboolean linear)
713 {
714 switch (component)
715 {
716 case GIMP_COMPONENT_TYPE_U8:
717 if (linear)
718 return GIMP_PRECISION_U8_LINEAR;
719 else
720 return GIMP_PRECISION_U8_GAMMA;
721
722 case GIMP_COMPONENT_TYPE_U16:
723 if (linear)
724 return GIMP_PRECISION_U16_LINEAR;
725 else
726 return GIMP_PRECISION_U16_GAMMA;
727
728 case GIMP_COMPONENT_TYPE_U32:
729 if (linear)
730 return GIMP_PRECISION_U32_LINEAR;
731 else
732 return GIMP_PRECISION_U32_GAMMA;
733
734 case GIMP_COMPONENT_TYPE_HALF:
735 if (linear)
736 return GIMP_PRECISION_HALF_LINEAR;
737 else
738 return GIMP_PRECISION_HALF_GAMMA;
739
740 case GIMP_COMPONENT_TYPE_FLOAT:
741 if (linear)
742 return GIMP_PRECISION_FLOAT_LINEAR;
743 else
744 return GIMP_PRECISION_FLOAT_GAMMA;
745
746 case GIMP_COMPONENT_TYPE_DOUBLE:
747 if (linear)
748 return GIMP_PRECISION_DOUBLE_LINEAR;
749 else
750 return GIMP_PRECISION_DOUBLE_GAMMA;
751
752 default:
753 break;
754 }
755
756 g_return_val_if_reached (-1);
757 }
758
759 gboolean
gimp_babl_is_valid(GimpImageBaseType base_type,GimpPrecision precision)760 gimp_babl_is_valid (GimpImageBaseType base_type,
761 GimpPrecision precision)
762 {
763 switch (base_type)
764 {
765 case GIMP_RGB:
766 case GIMP_GRAY:
767 return TRUE;
768
769 case GIMP_INDEXED:
770 switch (precision)
771 {
772 case GIMP_PRECISION_U8_GAMMA:
773 return TRUE;
774
775 default:
776 return FALSE;
777 }
778 }
779
780 g_return_val_if_reached (FALSE);
781 }
782
783 GimpComponentType
gimp_babl_is_bounded(GimpPrecision precision)784 gimp_babl_is_bounded (GimpPrecision precision)
785 {
786 switch (gimp_babl_component_type (precision))
787 {
788 case GIMP_COMPONENT_TYPE_U8:
789 case GIMP_COMPONENT_TYPE_U16:
790 case GIMP_COMPONENT_TYPE_U32:
791 return TRUE;
792
793 case GIMP_COMPONENT_TYPE_HALF:
794 case GIMP_COMPONENT_TYPE_FLOAT:
795 case GIMP_COMPONENT_TYPE_DOUBLE:
796 return FALSE;
797 }
798
799 g_return_val_if_reached (FALSE);
800 }
801
802 const Babl *
gimp_babl_format(GimpImageBaseType base_type,GimpPrecision precision,gboolean with_alpha)803 gimp_babl_format (GimpImageBaseType base_type,
804 GimpPrecision precision,
805 gboolean with_alpha)
806 {
807 switch (base_type)
808 {
809 case GIMP_RGB:
810 switch (precision)
811 {
812 case GIMP_PRECISION_U8_LINEAR:
813 if (with_alpha)
814 return babl_format ("RGBA u8");
815 else
816 return babl_format ("RGB u8");
817
818 case GIMP_PRECISION_U8_GAMMA:
819 if (with_alpha)
820 return babl_format ("R'G'B'A u8");
821 else
822 return babl_format ("R'G'B' u8");
823
824 case GIMP_PRECISION_U16_LINEAR:
825 if (with_alpha)
826 return babl_format ("RGBA u16");
827 else
828 return babl_format ("RGB u16");
829
830 case GIMP_PRECISION_U16_GAMMA:
831 if (with_alpha)
832 return babl_format ("R'G'B'A u16");
833 else
834 return babl_format ("R'G'B' u16");
835
836 case GIMP_PRECISION_U32_LINEAR:
837 if (with_alpha)
838 return babl_format ("RGBA u32");
839 else
840 return babl_format ("RGB u32");
841
842 case GIMP_PRECISION_U32_GAMMA:
843 if (with_alpha)
844 return babl_format ("R'G'B'A u32");
845 else
846 return babl_format ("R'G'B' u32");
847
848 case GIMP_PRECISION_HALF_LINEAR:
849 if (with_alpha)
850 return babl_format ("RGBA half");
851 else
852 return babl_format ("RGB half");
853
854 case GIMP_PRECISION_HALF_GAMMA:
855 if (with_alpha)
856 return babl_format ("R'G'B'A half");
857 else
858 return babl_format ("R'G'B' half");
859
860 case GIMP_PRECISION_FLOAT_LINEAR:
861 if (with_alpha)
862 return babl_format ("RGBA float");
863 else
864 return babl_format ("RGB float");
865
866 case GIMP_PRECISION_FLOAT_GAMMA:
867 if (with_alpha)
868 return babl_format ("R'G'B'A float");
869 else
870 return babl_format ("R'G'B' float");
871
872 case GIMP_PRECISION_DOUBLE_LINEAR:
873 if (with_alpha)
874 return babl_format ("RGBA double");
875 else
876 return babl_format ("RGB double");
877
878 case GIMP_PRECISION_DOUBLE_GAMMA:
879 if (with_alpha)
880 return babl_format ("R'G'B'A double");
881 else
882 return babl_format ("R'G'B' double");
883
884 default:
885 break;
886 }
887 break;
888
889 case GIMP_GRAY:
890 switch (precision)
891 {
892 case GIMP_PRECISION_U8_LINEAR:
893 if (with_alpha)
894 return babl_format ("YA u8");
895 else
896 return babl_format ("Y u8");
897
898 case GIMP_PRECISION_U8_GAMMA:
899 if (with_alpha)
900 return babl_format ("Y'A u8");
901 else
902 return babl_format ("Y' u8");
903
904 case GIMP_PRECISION_U16_LINEAR:
905 if (with_alpha)
906 return babl_format ("YA u16");
907 else
908 return babl_format ("Y u16");
909
910 case GIMP_PRECISION_U16_GAMMA:
911 if (with_alpha)
912 return babl_format ("Y'A u16");
913 else
914 return babl_format ("Y' u16");
915
916 case GIMP_PRECISION_U32_LINEAR:
917 if (with_alpha)
918 return babl_format ("YA u32");
919 else
920 return babl_format ("Y u32");
921
922 case GIMP_PRECISION_U32_GAMMA:
923 if (with_alpha)
924 return babl_format ("Y'A u32");
925 else
926 return babl_format ("Y' u32");
927
928 case GIMP_PRECISION_HALF_LINEAR:
929 if (with_alpha)
930 return babl_format ("YA half");
931 else
932 return babl_format ("Y half");
933
934 case GIMP_PRECISION_HALF_GAMMA:
935 if (with_alpha)
936 return babl_format ("Y'A half");
937 else
938 return babl_format ("Y' half");
939
940 case GIMP_PRECISION_FLOAT_LINEAR:
941 if (with_alpha)
942 return babl_format ("YA float");
943 else
944 return babl_format ("Y float");
945
946 case GIMP_PRECISION_FLOAT_GAMMA:
947 if (with_alpha)
948 return babl_format ("Y'A float");
949 else
950 return babl_format ("Y' float");
951
952 case GIMP_PRECISION_DOUBLE_LINEAR:
953 if (with_alpha)
954 return babl_format ("YA double");
955 else
956 return babl_format ("Y double");
957
958 case GIMP_PRECISION_DOUBLE_GAMMA:
959 if (with_alpha)
960 return babl_format ("Y'A double");
961 else
962 return babl_format ("Y' double");
963
964 default:
965 break;
966 }
967 break;
968
969 case GIMP_INDEXED:
970 /* need to use the image's api for this */
971 break;
972 }
973
974 g_return_val_if_reached (NULL);
975 }
976
977 const Babl *
gimp_babl_mask_format(GimpPrecision precision)978 gimp_babl_mask_format (GimpPrecision precision)
979 {
980 switch (gimp_babl_component_type (precision))
981 {
982 case GIMP_COMPONENT_TYPE_U8: return babl_format ("Y u8");
983 case GIMP_COMPONENT_TYPE_U16: return babl_format ("Y u16");
984 case GIMP_COMPONENT_TYPE_U32: return babl_format ("Y u32");
985 case GIMP_COMPONENT_TYPE_HALF: return babl_format ("Y half");
986 case GIMP_COMPONENT_TYPE_FLOAT: return babl_format ("Y float");
987 case GIMP_COMPONENT_TYPE_DOUBLE: return babl_format ("Y double");
988 }
989
990 g_return_val_if_reached (NULL);
991 }
992
993 const Babl *
gimp_babl_component_format(GimpImageBaseType base_type,GimpPrecision precision,gint index)994 gimp_babl_component_format (GimpImageBaseType base_type,
995 GimpPrecision precision,
996 gint index)
997 {
998 switch (base_type)
999 {
1000 case GIMP_RGB:
1001 switch (precision)
1002 {
1003 case GIMP_PRECISION_U8_LINEAR:
1004 switch (index)
1005 {
1006 case 0: return babl_format ("R u8");
1007 case 1: return babl_format ("G u8");
1008 case 2: return babl_format ("B u8");
1009 case 3: return babl_format ("A u8");
1010 default:
1011 break;
1012 }
1013 break;
1014
1015 case GIMP_PRECISION_U8_GAMMA:
1016 switch (index)
1017 {
1018 case 0: return babl_format ("R' u8");
1019 case 1: return babl_format ("G' u8");
1020 case 2: return babl_format ("B' u8");
1021 case 3: return babl_format ("A u8");
1022 default:
1023 break;
1024 }
1025 break;
1026
1027 case GIMP_PRECISION_U16_LINEAR:
1028 switch (index)
1029 {
1030 case 0: return babl_format ("R u16");
1031 case 1: return babl_format ("G u16");
1032 case 2: return babl_format ("B u16");
1033 case 3: return babl_format ("A u16");
1034 default:
1035 break;
1036 }
1037 break;
1038
1039 case GIMP_PRECISION_U16_GAMMA:
1040 switch (index)
1041 {
1042 case 0: return babl_format ("R' u16");
1043 case 1: return babl_format ("G' u16");
1044 case 2: return babl_format ("B' u16");
1045 case 3: return babl_format ("A u16");
1046 default:
1047 break;
1048 }
1049 break;
1050
1051 case GIMP_PRECISION_U32_LINEAR:
1052 switch (index)
1053 {
1054 case 0: return babl_format ("R u32");
1055 case 1: return babl_format ("G u32");
1056 case 2: return babl_format ("B u32");
1057 case 3: return babl_format ("A u32");
1058 default:
1059 break;
1060 }
1061 break;
1062
1063 case GIMP_PRECISION_U32_GAMMA:
1064 switch (index)
1065 {
1066 case 0: return babl_format ("R' u32");
1067 case 1: return babl_format ("G' u32");
1068 case 2: return babl_format ("B' u32");
1069 case 3: return babl_format ("A u32");
1070 default:
1071 break;
1072 }
1073 break;
1074
1075 case GIMP_PRECISION_HALF_LINEAR:
1076 switch (index)
1077 {
1078 case 0: return babl_format ("R half");
1079 case 1: return babl_format ("G half");
1080 case 2: return babl_format ("B half");
1081 case 3: return babl_format ("A half");
1082 default:
1083 break;
1084 }
1085 break;
1086
1087 case GIMP_PRECISION_HALF_GAMMA:
1088 switch (index)
1089 {
1090 case 0: return babl_format ("R' half");
1091 case 1: return babl_format ("G' half");
1092 case 2: return babl_format ("B' half");
1093 case 3: return babl_format ("A half");
1094 default:
1095 break;
1096 }
1097 break;
1098
1099 case GIMP_PRECISION_FLOAT_LINEAR:
1100 switch (index)
1101 {
1102 case 0: return babl_format ("R float");
1103 case 1: return babl_format ("G float");
1104 case 2: return babl_format ("B float");
1105 case 3: return babl_format ("A float");
1106 default:
1107 break;
1108 }
1109 break;
1110
1111 case GIMP_PRECISION_FLOAT_GAMMA:
1112 switch (index)
1113 {
1114 case 0: return babl_format ("R' float");
1115 case 1: return babl_format ("G' float");
1116 case 2: return babl_format ("B' float");
1117 case 3: return babl_format ("A float");
1118 default:
1119 break;
1120 }
1121 break;
1122
1123 case GIMP_PRECISION_DOUBLE_LINEAR:
1124 switch (index)
1125 {
1126 case 0: return babl_format ("R double");
1127 case 1: return babl_format ("G double");
1128 case 2: return babl_format ("B double");
1129 case 3: return babl_format ("A double");
1130 default:
1131 break;
1132 }
1133 break;
1134
1135 case GIMP_PRECISION_DOUBLE_GAMMA:
1136 switch (index)
1137 {
1138 case 0: return babl_format ("R' double");
1139 case 1: return babl_format ("G' double");
1140 case 2: return babl_format ("B' double");
1141 case 3: return babl_format ("A double");
1142 default:
1143 break;
1144 }
1145 break;
1146
1147 default:
1148 break;
1149 }
1150 break;
1151
1152 case GIMP_GRAY:
1153 switch (precision)
1154 {
1155 case GIMP_PRECISION_U8_LINEAR:
1156 switch (index)
1157 {
1158 case 0: return babl_format ("Y u8");
1159 case 1: return babl_format ("A u8");
1160 default:
1161 break;
1162 }
1163 break;
1164
1165 case GIMP_PRECISION_U8_GAMMA:
1166 switch (index)
1167 {
1168 case 0: return babl_format ("Y' u8");
1169 case 1: return babl_format ("A u8");
1170 default:
1171 break;
1172 }
1173 break;
1174
1175 case GIMP_PRECISION_U16_LINEAR:
1176 switch (index)
1177 {
1178 case 0: return babl_format ("Y u16");
1179 case 1: return babl_format ("A u16");
1180 default:
1181 break;
1182 }
1183 break;
1184
1185 case GIMP_PRECISION_U16_GAMMA:
1186 switch (index)
1187 {
1188 case 0: return babl_format ("Y' u16");
1189 case 1: return babl_format ("A u16");
1190 default:
1191 break;
1192 }
1193 break;
1194
1195 case GIMP_PRECISION_U32_LINEAR:
1196 switch (index)
1197 {
1198 case 0: return babl_format ("Y u32");
1199 case 1: return babl_format ("A u32");
1200 default:
1201 break;
1202 }
1203 break;
1204
1205 case GIMP_PRECISION_U32_GAMMA:
1206 switch (index)
1207 {
1208 case 0: return babl_format ("Y' u32");
1209 case 1: return babl_format ("A u32");
1210 default:
1211 break;
1212 }
1213 break;
1214
1215 case GIMP_PRECISION_HALF_LINEAR:
1216 switch (index)
1217 {
1218 case 0: return babl_format ("Y half");
1219 case 1: return babl_format ("A half");
1220 default:
1221 break;
1222 }
1223 break;
1224
1225 case GIMP_PRECISION_HALF_GAMMA:
1226 switch (index)
1227 {
1228 case 0: return babl_format ("Y' half");
1229 case 1: return babl_format ("A half");
1230 default:
1231 break;
1232 }
1233 break;
1234
1235 case GIMP_PRECISION_FLOAT_LINEAR:
1236 switch (index)
1237 {
1238 case 0: return babl_format ("Y float");
1239 case 1: return babl_format ("A float");
1240 default:
1241 break;
1242 }
1243 break;
1244
1245 case GIMP_PRECISION_FLOAT_GAMMA:
1246 switch (index)
1247 {
1248 case 0: return babl_format ("Y' float");
1249 case 1: return babl_format ("A float");
1250 default:
1251 break;
1252 }
1253 break;
1254
1255 case GIMP_PRECISION_DOUBLE_LINEAR:
1256 switch (index)
1257 {
1258 case 0: return babl_format ("Y double");
1259 case 1: return babl_format ("A double");
1260 default:
1261 break;
1262 }
1263 break;
1264
1265 case GIMP_PRECISION_DOUBLE_GAMMA:
1266 switch (index)
1267 {
1268 case 0: return babl_format ("Y' double");
1269 case 1: return babl_format ("A double");
1270 default:
1271 break;
1272 }
1273 break;
1274
1275 default:
1276 break;
1277 }
1278 break;
1279
1280 case GIMP_INDEXED:
1281 /* need to use the image's api for this */
1282 break;
1283 }
1284
1285 g_return_val_if_reached (NULL);
1286 }
1287
1288 const Babl *
gimp_babl_format_change_component_type(const Babl * format,GimpComponentType component)1289 gimp_babl_format_change_component_type (const Babl *format,
1290 GimpComponentType component)
1291 {
1292 g_return_val_if_fail (format != NULL, NULL);
1293
1294 return gimp_babl_format (gimp_babl_format_get_base_type (format),
1295 gimp_babl_precision (
1296 component,
1297 gimp_babl_format_get_linear (format)),
1298 babl_format_has_alpha (format));
1299 }
1300
1301 const Babl *
gimp_babl_format_change_linear(const Babl * format,gboolean linear)1302 gimp_babl_format_change_linear (const Babl *format,
1303 gboolean linear)
1304 {
1305 g_return_val_if_fail (format != NULL, NULL);
1306
1307 return gimp_babl_format (gimp_babl_format_get_base_type (format),
1308 gimp_babl_precision (
1309 gimp_babl_format_get_component_type (format),
1310 linear),
1311 babl_format_has_alpha (format));
1312 }
1313
1314 gchar **
gimp_babl_print_pixel(const Babl * format,gpointer pixel)1315 gimp_babl_print_pixel (const Babl *format,
1316 gpointer pixel)
1317 {
1318 GimpPrecision precision;
1319 gint n_components;
1320 guchar tmp_pixel[32];
1321 gchar **strings;
1322
1323 g_return_val_if_fail (format != NULL, NULL);
1324 g_return_val_if_fail (pixel != NULL, NULL);
1325
1326 precision = gimp_babl_format_get_precision (format);
1327
1328 if (babl_format_is_palette (format))
1329 {
1330 const Babl *f = gimp_babl_format (GIMP_RGB, precision,
1331 babl_format_has_alpha (format));
1332
1333 babl_process (babl_fish (format, f), pixel, tmp_pixel, 1);
1334
1335 format = f;
1336 pixel = tmp_pixel;
1337 }
1338
1339 n_components = babl_format_get_n_components (format);
1340
1341 strings = g_new0 (gchar *, n_components + 1);
1342
1343 switch (gimp_babl_format_get_component_type (format))
1344 {
1345 case GIMP_COMPONENT_TYPE_U8:
1346 {
1347 guchar *color = pixel;
1348 gint i;
1349
1350 for (i = 0; i < n_components; i++)
1351 strings[i] = g_strdup_printf ("%d", color[i]);
1352 }
1353 break;
1354
1355 case GIMP_COMPONENT_TYPE_U16:
1356 {
1357 guint16 *color = pixel;
1358 gint i;
1359
1360 for (i = 0; i < n_components; i++)
1361 strings[i] = g_strdup_printf ("%u", color[i]);
1362 }
1363 break;
1364
1365 case GIMP_COMPONENT_TYPE_U32:
1366 {
1367 guint32 *color = pixel;
1368 gint i;
1369
1370 for (i = 0; i < n_components; i++)
1371 strings[i] = g_strdup_printf ("%u", color[i]);
1372 }
1373 break;
1374
1375 case GIMP_COMPONENT_TYPE_HALF:
1376 {
1377 GimpPrecision p;
1378 const Babl *f;
1379
1380 p = gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT,
1381 gimp_babl_format_get_linear (format));
1382
1383 f = gimp_babl_format (gimp_babl_format_get_base_type (format),
1384 p,
1385 babl_format_has_alpha (format));
1386
1387 babl_process (babl_fish (format, f), pixel, tmp_pixel, 1);
1388
1389 pixel = tmp_pixel;
1390 }
1391 /* fall through */
1392
1393 case GIMP_COMPONENT_TYPE_FLOAT:
1394 {
1395 gfloat *color = pixel;
1396 gint i;
1397
1398 for (i = 0; i < n_components; i++)
1399 strings[i] = g_strdup_printf ("%0.6f", color[i]);
1400 }
1401 break;
1402
1403 case GIMP_COMPONENT_TYPE_DOUBLE:
1404 {
1405 gdouble *color = pixel;
1406 gint i;
1407
1408 for (i = 0; i < n_components; i++)
1409 strings[i] = g_strdup_printf ("%0.6f", color[i]);
1410 }
1411 break;
1412 }
1413
1414 return strings;
1415 }
1416