1 /*
2  * This file was part of gggl, it implements a variety of pixel conversion
3  * functions that are usable with babl, the file needs more cleanup.
4  *
5  *    GGGL is free software; you can redistribute it and/or modify
6  *    it under the terms of the GNU General Public License as published by
7  *    the Free Software Foundation; either version 3 of the License, or
8  *    (at your option) any later version.
9  *
10  *    GGGL is distributed in the hope that it will be useful,
11  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *    GNU General Public License for more details.
14  *
15  *    You should have received a copy of the GNU General Public License
16  *    along with GGGL; if not, see <https://www.gnu.org/licenses/>.
17  *
18  *    Rights are granted to use this shared object in libraries covered by
19  *    LGPL. (exception added, during import into babl CVS.)
20  *
21  *  Copyright 2003, 2004, 2005 Øyvind Kolås <pippin@gimp.org>
22  */
23 
24 #define _POSIX_C_SOURCE 200112L
25 
26 #include "config.h"
27 #include <math.h>
28 #include <string.h>
29 #include <stdint.h>
30 
31 #include "babl.h"
32 #include "extensions/util.h"
33 
34 /*
35  * Implemented according to information read from:
36  *
37  * http://www.cinenet.net/~spitzak/conversion/sketches_0265.pdf
38  *
39  * due to ability to be able to relicence gggl under a different
40  * licence than GPL, I avoided the temptation to look at the
41  * source files in the same location, in case I was going to
42  * need this piece of code for projects where GPL compatibility
43  * was a must.
44  *
45  */
46 
47 /* lookup tables used in conversion */
48 
49 static float          table_8_F[1 << 8];
50 static float          table_16_F[1 << 16];
51 static unsigned char  table_F_8[1 << 16];
52 static unsigned short table_F_16[1 << 16];
53 
54 static uint32_t      *table_8_F_int = NULL;
55 
56 static int table_inited = 0;
57 
58 static void
table_init(void)59 table_init (void)
60 {
61   if (table_inited)
62     return;
63 
64   table_8_F_int = (void*)(table_8_F);
65 
66   table_inited = 1;
67 
68   /* fill tables for conversion from integer to float */
69   {
70     int i;
71     for (i = 0; i < 1 << 8; i++)
72       {
73         table_8_F[i] = (i * 1.0) / 255.0;
74       }
75     for (i = 0; i < 1 << 16; i++)
76       table_16_F[i] = (i * 1.0) / 65535.0;
77   }
78   /* fill tables for conversion from float to integer */
79   {
80     union
81     {
82       float          f;
83       unsigned short s[2];
84     } u;
85     u.f = 0.0;
86 
87     u.s[0] = 0x8000;
88 
89     for (u.s[1] = 0; u.s[1] < 65535; u.s[1] += 1)
90       {
91         unsigned char  c;
92         unsigned short s;
93 
94         if (u.f <= 0.0)
95           {
96             c = 0;
97             s = 0;
98           }
99         else if (u.f >= 1.0)
100           {
101             c = 255;
102             s = 65535;
103           }
104         else
105           {
106             c = u.f * 255 + 0.5f;
107             s = u.f * 65535 + 0.5f;
108           }
109 
110         /*fprintf (stderr, "%2.3f=%03i %05i ", f, c, (*hi));
111            / if (! ((*hi)%9))
112            /         fprintf (stderr, "\n"); */
113 
114         table_F_8[u.s[1]]  = c;
115         table_F_16[u.s[1]] = s;
116       }
117   }
118   /* patch tables to ensure 1:1 conversions back and forth */
119   if (0)
120     {                           /*FIXME: probably not the right way to do it,.. must sit down and scribble on paper */
121       int i;
122       for (i = 0; i < 256; i++)
123         {
124           float           f  = table_8_F[i];
125           unsigned short *hi = ((unsigned short *) (void *) &f);
126           unsigned short *lo = ((unsigned short *) (void *) &f);
127           *lo              = 0;
128           table_F_8[(*hi)] = i;
129         }
130     }
131 }
132 
133 /* function to find the index in table for a float */
134 static unsigned int
gggl_float_to_index16(float f)135 gggl_float_to_index16 (float f)
136 {
137   union
138   {
139     float          f;
140     unsigned short s[2];
141   } u;
142   u.f = f;
143   return u.s[1];
144 }
145 
146 static void
conv_F_8(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)147 conv_F_8 (const Babl    *conversion,
148           unsigned char *src,
149           unsigned char *dst,
150           long samples)
151 {
152   long n = samples;
153 
154   if (!table_inited)
155     table_init ();
156   while (n--)
157     {
158       register float f = (*(float *) src);
159       *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)];
160       dst                   += 1;
161       src                   += 4;
162     }
163 }
164 
165 
166 static void
conv_F_16(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)167 conv_F_16 (const Babl    *conversion,
168            unsigned char *src,
169            unsigned char *dst,
170            long samples)
171 {
172   long n = samples;
173 
174   if (!table_inited)
175     table_init ();
176   while (n--)
177     {
178       register float f = (*(float *) src);
179       *(unsigned short *) dst = table_F_16[gggl_float_to_index16 (f)];
180       dst                    += 2;
181       src                    += 4;
182     }
183 }
184 
185 static void
conv_8_F(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)186 conv_8_F (const Babl    *conversion,
187           unsigned char *src,
188           unsigned char *dst,
189           long samples)
190 {
191   long n = samples;
192 
193   if (!table_inited)
194     table_init ();
195   while (n--)
196     {
197       (*(uint32_t *) dst) = table_8_F_int[*(unsigned char *) src];
198       dst             += 4;
199       src             += 1;
200     }
201 }
202 
203 static void
conv_rgb8_rgbaF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)204 conv_rgb8_rgbaF (const Babl    *conversion,
205                  unsigned char *src,
206                  unsigned char *dst,
207                  long samples)
208 {
209   long n = samples;
210 
211   if (!table_inited)
212     table_init ();
213   while (n--)
214     {
215       (*(uint32_t *) dst) = table_8_F_int[*(unsigned char *) src];
216       dst             += 4;
217       src             += 1;
218       (*(uint32_t *) dst) = table_8_F_int[*(unsigned char *) src];
219       dst             += 4;
220       src             += 1;
221       (*(uint32_t *) dst) = table_8_F_int[*(unsigned char *) src];
222       dst             += 4;
223       src             += 1;
224       (*(float    *) dst) = 1.0;
225       dst             += 4;
226     }
227 }
228 
229 static void
conv_16_F(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)230 conv_16_F (const Babl    *conversion,
231            unsigned char *src,
232            unsigned char *dst,
233            long samples)
234 {
235   long n = samples;
236 
237   if (!table_inited)
238     table_init ();
239   while (n--)
240     {
241       (*(float *) dst) = table_16_F[*(unsigned short *) src];
242       dst             += 4;
243       src             += 2;
244     }
245 }
246 
247 static void
conv_rgbaF_rgb8(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)248 conv_rgbaF_rgb8 (const Babl    *conversion,
249                  unsigned char *src,
250                  unsigned char *dst,
251                  long samples)
252 {
253   long n = samples;
254 
255   while (n--)
256     {
257       register float f = (*(float *) src);
258       *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)];
259       src                   += 4;
260       dst                   += 1;
261 
262       f                      = (*(float *) src);
263       *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)];
264       src                   += 4;
265       dst                   += 1;
266 
267       f                      = (*(float *) src);
268       *(unsigned char *) dst = table_F_8[gggl_float_to_index16 (f)];
269       src                   += 4;
270       dst                   += 1;
271 
272       src += 4;
273     }
274 }
275 
276 
277 /*********/
278 static void
conv_rgbaF_rgba8(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)279 conv_rgbaF_rgba8 (const Babl    *conversion,
280                   unsigned char *src,
281                   unsigned char *dst,
282                   long samples)
283 {
284   conv_F_8 (conversion, src, dst, samples * 4);
285 }
286 
287 static void
conv_rgbF_rgb8(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)288 conv_rgbF_rgb8 (const Babl    *conversion,
289                 unsigned char *src,
290                 unsigned char *dst,
291                 long samples)
292 {
293   conv_F_8 (conversion, src, dst, samples * 3);
294 }
295 
296 static void
conv_gaF_ga8(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)297 conv_gaF_ga8 (const Babl    *conversion,
298               unsigned char *src,
299               unsigned char *dst,
300               long samples)
301 {
302   conv_F_8 (conversion, src, dst, samples * 2);
303 }
304 
305 #define conv_rgbAF_rgbA8    conv_rgbaF_rgba8
306 #define conv_gF_g8          conv_F_8
307 #define conv_gAF_gA8        conv_gaF_ga8
308 
309 static void
conv_rgbaF_rgba16(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)310 conv_rgbaF_rgba16 (const Babl    *conversion,
311                    unsigned char *src,
312                    unsigned char *dst,
313                    long samples)
314 {
315   conv_F_16 (conversion, src, dst, samples * 4);
316 }
317 
318 static void
conv_rgbF_rgb16(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)319 conv_rgbF_rgb16 (const Babl    *conversion,
320                  unsigned char *src,
321                  unsigned char *dst,
322                  long samples)
323 {
324   conv_F_16 (conversion, src, dst, samples * 3);
325 }
326 
327 static void
conv_gaF_ga16(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)328 conv_gaF_ga16 (const Babl    *conversion,
329                unsigned char *src,
330                unsigned char *dst,
331                long samples)
332 {
333   conv_F_16 (conversion, src, dst, samples * 2);
334 }
335 
336 #define conv_rgbAF_rgbA16    conv_rgbaF_rgba16
337 #define conv_gF_g16          conv_F_16
338 #define conv_gAF_gA16        conv_gaF_ga16
339 
340 static void
conv_rgba8_rgbaF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)341 conv_rgba8_rgbaF (const Babl    *conversion,
342                   unsigned char *src,
343                   unsigned char *dst,
344                   long samples)
345 {
346   conv_8_F (conversion, src, dst, samples * 4);
347 }
348 
349 
350 static void
conv_rgb8_rgbF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)351 conv_rgb8_rgbF (const Babl    *conversion,
352                 unsigned char *src,
353                 unsigned char *dst,
354                 long samples)
355 {
356   conv_8_F (conversion, src, dst, samples * 3);
357 }
358 
359 static void
conv_ga8_gaF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)360 conv_ga8_gaF (const Babl    *conversion,
361               unsigned char *src,
362               unsigned char *dst,
363               long samples)
364 {
365   conv_8_F (conversion, src, dst, samples * 2);
366 }
367 
368 #define conv_rgbA8_rgbAF    conv_rgba8_rgbaF
369 #define conv_gA8_gAF        conv_ga8_gaF
370 #define conv_g8_gF          conv_8_F
371 
372 static void
conv_rgba16_rgbaF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)373 conv_rgba16_rgbaF (const Babl    *conversion,
374                    unsigned char *src,
375                    unsigned char *dst,
376                    long samples)
377 {
378   conv_16_F (conversion, src, dst, samples * 4);
379 }
380 
381 static void
conv_rgb16_rgbF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)382 conv_rgb16_rgbF (const Babl    *conversion,
383                  unsigned char *src,
384                  unsigned char *dst,
385                  long samples)
386 {
387   conv_16_F (conversion, src, dst, samples * 3);
388 }
389 
390 static void
conv_ga16_gaF(const Babl * conversion,unsigned char * src,unsigned char * dst,long samples)391 conv_ga16_gaF (const Babl    *conversion,
392                unsigned char *src,
393                unsigned char *dst,
394                long samples)
395 {
396   conv_16_F (conversion, src, dst, samples * 2);
397 }
398 
399 #define conv_rgbA16_rgbAF    conv_rgba16_rgbaF
400 #define conv_gA16_gAF        conv_ga16_gaF
401 #define conv_g16_gF          conv_16_F
402 
403 int init (void);
404 
405 int
init(void)406 init (void)
407 {
408   const Babl *rgbaF = babl_format_new (
409     babl_model ("R'G'B'A"),
410     babl_type ("float"),
411     babl_component ("R'"),
412     babl_component ("G'"),
413     babl_component ("B'"),
414     babl_component ("A"),
415     NULL);
416   const Babl *rgba16 = babl_format_new (
417     babl_model ("R'G'B'A"),
418     babl_type ("u16"),
419     babl_component ("R'"),
420     babl_component ("G'"),
421     babl_component ("B'"),
422     babl_component ("A"),
423     NULL);
424   const Babl *rgba8 = babl_format_new (
425     babl_model ("R'G'B'A"),
426     babl_type ("u8"),
427     babl_component ("R'"),
428     babl_component ("G'"),
429     babl_component ("B'"),
430     babl_component ("A"),
431     NULL);
432   const Babl *rgbAF = babl_format_new (
433     babl_model ("R'aG'aB'aA"),
434     babl_type ("float"),
435     babl_component ("R'a"),
436     babl_component ("G'a"),
437     babl_component ("B'a"),
438     babl_component ("A"),
439     NULL);
440   const Babl *rgbA16 = babl_format_new (
441     babl_model ("R'aG'aB'aA"),
442     babl_type ("u16"),
443     babl_component ("R'a"),
444     babl_component ("G'a"),
445     babl_component ("B'a"),
446     babl_component ("A"),
447     NULL);
448   const Babl *rgbA8 = babl_format_new (
449     babl_model ("R'aG'aB'aA"),
450     babl_type ("u8"),
451     babl_component ("R'a"),
452     babl_component ("G'a"),
453     babl_component ("B'a"),
454     babl_component ("A"),
455     NULL);
456   const Babl *rgbF = babl_format_new (
457     babl_model ("R'G'B'"),
458     babl_type ("float"),
459     babl_component ("R'"),
460     babl_component ("G'"),
461     babl_component ("B'"),
462     NULL);
463   const Babl *rgb16 = babl_format_new (
464     babl_model ("R'G'B'"),
465     babl_type ("u16"),
466     babl_component ("R'"),
467     babl_component ("G'"),
468     babl_component ("B'"),
469     NULL);
470   const Babl *rgb8 = babl_format_new (
471     babl_model ("R'G'B'"),
472     babl_type ("u8"),
473     babl_component ("R'"),
474     babl_component ("G'"),
475     babl_component ("B'"),
476     NULL);
477   const Babl *gaF = babl_format_new (
478     babl_model ("Y'A"),
479     babl_type ("float"),
480     babl_component ("Y'"),
481     babl_component ("A"),
482     NULL);
483   const Babl *gAF = babl_format_new (
484     babl_model ("Y'aA"),
485     babl_type ("float"),
486     babl_component ("Y'a"),
487     babl_component ("A"),
488     NULL);
489   const Babl *gF = babl_format_new (
490     babl_model ("Y'"),
491     babl_type ("float"),
492     babl_component ("Y'"),
493     NULL);
494   const Babl *ga16 = babl_format_new (
495     babl_model ("Y'A"),
496     babl_type ("u16"),
497     babl_component ("Y'"),
498     babl_component ("A"),
499     NULL);
500   const Babl *gA16 = babl_format_new (
501     babl_model ("Y'aA"),
502     babl_type ("u16"),
503     babl_component ("Y'a"),
504     babl_component ("A"),
505     NULL);
506   const Babl *g16 = babl_format_new (
507     babl_model ("Y'"),
508     babl_type ("u16"),
509     babl_component ("Y'"),
510     NULL);
511   const Babl *ga8 = babl_format_new (
512     babl_model ("Y'A"),
513     babl_type ("u8"),
514     babl_component ("Y'"),
515     babl_component ("A"),
516     NULL);
517   const Babl *gA8 = babl_format_new (
518     babl_model ("Y'aA"),
519     babl_type ("u8"),
520     babl_component ("Y'a"),
521     babl_component ("A"),
522     NULL);
523   const Babl *g8 = babl_format_new (
524     babl_model ("Y'"),
525     babl_type ("u8"),
526     babl_component ("Y'"),
527     NULL);
528 
529 #define o(src, dst) \
530   babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)
531 
532   o (rgbaF, rgba8);
533   o (rgba8, rgbaF);
534   o (rgbaF, rgba16);
535   o (rgba16, rgbaF);
536   o (rgbAF, rgbA8);
537   o (rgbA8, rgbAF);
538   o (rgbAF, rgbA16);
539   o (rgbA16, rgbAF);
540   o (rgbF, rgb8);
541   o (rgb8, rgbF);
542   o (rgbF, rgb16);
543   o (rgb16, rgbF);
544   o (gaF, ga8);
545   o (gAF, gA8);
546   o (gF, g8);
547   o (ga8, gaF);
548   o (gA8, gAF);
549   o (g8, gF);
550   o (gaF, ga16);
551   o (gAF, gA16);
552   o (gF, g16);
553   o (ga16, gaF);
554   o (gA16, gAF);
555   o (g16, gF);
556   o (rgbaF, rgb8);
557   o (rgb8, rgbaF);
558 
559   if (!table_inited)
560     table_init ();
561 
562   return 0;
563 }
564