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