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