4 * Last changed in libpng 1.6.0 [February 14, 2013]
6 * COPYRIGHT: Written by John Cunningham Bowler, 2013.
7 * To the extent possible under law, the author has waived all copyright and
8 * related or neighboring rights to this work. This work is published from:
11 * Convert 8-bit sRGB or 16-bit linear values to another format.
13 #define _ISOC99_SOURCE 1
25 usage(const char *prog
)
28 "%s: usage: %s [-linear|-sRGB] [-gray|-color] component{1,4}\n",
34 component(const char *prog
, const char *arg
, int issRGB
)
37 unsigned long c
= strtoul(arg
, &ep
, 0);
39 if (ep
<= arg
|| *ep
|| c
> 65535 || (issRGB
&& c
> 255))
41 fprintf(stderr
, "%s: %s: invalid component value (%lu)\n", prog
, arg
, c
);
49 main(int argc
, const char **argv
)
51 const char *prog
= *argv
++;
52 int to_linear
= 0, to_gray
= 0, to_color
= 0;
56 /* FE_TONEAREST is the IEEE754 round to nearest, preferring even, mode; i.e.
57 * everything rounds to the nearest value except that '.5' rounds to the
60 fesetround(FE_TONEAREST
);
62 c
[3] = c
[2] = c
[1] = c
[0] = 0;
64 while (--argc
> 0 && **argv
== '-')
66 const char *arg
= 1+*argv
++;
68 if (strcmp(arg
, "sRGB") == 0)
71 else if (strcmp(arg
, "linear") == 0)
74 else if (strcmp(arg
, "gray") == 0)
75 to_gray
= 1, to_color
= 0;
77 else if (strcmp(arg
, "color") == 0)
78 to_gray
= 0, to_color
= 1;
91 c
[3] = component(prog
, argv
[3], to_linear
);
94 c
[2] = component(prog
, argv
[2], to_linear
);
97 c
[1] = component(prog
, argv
[1], to_linear
);
100 c
[0] = component(prog
, argv
[0], to_linear
);
108 int components
= channels
;
110 if ((components
& 1) == 0)
113 for (i
=0; i
<components
; ++i
) c
[i
] = linear_from_sRGB(c
[i
] / 255);
114 if (components
< channels
)
115 c
[components
] = c
[components
] / 255;
121 for (i
=0; i
<4; ++i
) c
[i
] /= 65535;
123 if ((channels
& 1) == 0)
125 double alpha
= c
[channels
-1];
128 for (i
=0; i
<channels
-1; ++i
) c
[i
] /= alpha
;
130 for (i
=0; i
<channels
-1; ++i
) c
[i
] = 1;
138 fprintf(stderr
, "%s: too few channels (%d) for -gray\n",
143 c
[0] = YfromRGB(c
[0], c
[1], c
[2]);
151 fprintf(stderr
, "%s: too many channels (%d) for -color\n",
156 c
[3] = c
[1]; /* alpha, if present */
163 if ((channels
& 1) == 0)
165 double alpha
= c
[channels
-1];
166 for (i
=0; i
<channels
-1; ++i
) c
[i
] *= alpha
;
169 for (i
=0; i
<channels
; ++i
) c
[i
] = nearbyint(c
[i
] * 65535);
174 int i
= (channels
+1)&~1;
176 c
[i
] = sRGB_from_linear(c
[i
]);
178 for (i
=0; i
<channels
; ++i
) c
[i
] = nearbyint(c
[i
] * 255);
183 for (i
=0; i
<channels
; ++i
) printf(" %g", c
[i
]);