mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[libpng15] Updated contrib/sRGBtables code
This commit is contained in:
parent
ae41dc55a2
commit
76b0459fdd
181
contrib/sRGBtables/cvtcolor.c
Normal file
181
contrib/sRGBtables/cvtcolor.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/*-
|
||||||
|
* convert.c
|
||||||
|
*
|
||||||
|
* Convert 8-bit sRGB or 16-bit linear values to another format.
|
||||||
|
*/
|
||||||
|
#define _ISOC99_SOURCE 1
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <fenv.h>
|
||||||
|
|
||||||
|
#include "sRGB.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage(const char *prog)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: usage: %s [-linear|-sRGB] [-gray|-color] component{1,4}\n",
|
||||||
|
prog, prog);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
component(const char *prog, const char *arg, int issRGB)
|
||||||
|
{
|
||||||
|
char *ep;
|
||||||
|
unsigned long c = strtoul(arg, &ep, 0);
|
||||||
|
|
||||||
|
if (ep <= arg || *ep || c > 65535 || (issRGB && c > 255))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: %s: invalid component value (%lu)\n", prog, arg, c);
|
||||||
|
usage(prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
const char *prog = *argv++;
|
||||||
|
int to_linear = 0, to_gray = 0, to_color = 0;
|
||||||
|
int channels = 0;
|
||||||
|
double c[4];
|
||||||
|
|
||||||
|
/* FE_TONEAREST is the IEEE754 round to nearest, preferring even, mode; i.e.
|
||||||
|
* everything rounds to the nearest value except that '.5' rounds to the
|
||||||
|
* nearest even value.
|
||||||
|
*/
|
||||||
|
fesetround(FE_TONEAREST);
|
||||||
|
|
||||||
|
c[3] = c[2] = c[1] = c[0] = 0;
|
||||||
|
|
||||||
|
while (--argc > 0 && **argv == '-')
|
||||||
|
{
|
||||||
|
const char *arg = 1+*argv++;
|
||||||
|
|
||||||
|
if (strcmp(arg, "sRGB") == 0)
|
||||||
|
to_linear = 0;
|
||||||
|
|
||||||
|
else if (strcmp(arg, "linear") == 0)
|
||||||
|
to_linear = 1;
|
||||||
|
|
||||||
|
else if (strcmp(arg, "gray") == 0)
|
||||||
|
to_gray = 1, to_color = 0;
|
||||||
|
|
||||||
|
else if (strcmp(arg, "color") == 0)
|
||||||
|
to_gray = 0, to_color = 1;
|
||||||
|
|
||||||
|
else
|
||||||
|
usage(prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (argc)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
usage(prog);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
c[3] = component(prog, argv[3], to_linear);
|
||||||
|
++channels;
|
||||||
|
case 3:
|
||||||
|
c[2] = component(prog, argv[2], to_linear);
|
||||||
|
++channels;
|
||||||
|
case 2:
|
||||||
|
c[1] = component(prog, argv[1], to_linear);
|
||||||
|
++channels;
|
||||||
|
case 1:
|
||||||
|
c[0] = component(prog, argv[0], to_linear);
|
||||||
|
++channels;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_linear)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int components = channels;
|
||||||
|
|
||||||
|
if ((components & 1) == 0)
|
||||||
|
--components;
|
||||||
|
|
||||||
|
for (i=0; i<components; ++i) c[i] = linear_from_sRGB(c[i] / 255);
|
||||||
|
if (components < channels)
|
||||||
|
c[components] = c[components] / 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<4; ++i) c[i] /= 65535;
|
||||||
|
|
||||||
|
if ((channels & 1) == 0)
|
||||||
|
{
|
||||||
|
double alpha = c[channels-1];
|
||||||
|
|
||||||
|
if (alpha > 0)
|
||||||
|
for (i=0; i<channels-1; ++i) c[i] /= alpha;
|
||||||
|
else
|
||||||
|
for (i=0; i<channels-1; ++i) c[i] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_gray)
|
||||||
|
{
|
||||||
|
if (channels < 3)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: too few channels (%d) for -gray\n",
|
||||||
|
prog, channels);
|
||||||
|
usage(prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
c[0] = YfromRGB(c[0], c[1], c[2]);
|
||||||
|
channels -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_color)
|
||||||
|
{
|
||||||
|
if (channels > 2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: too many channels (%d) for -color\n",
|
||||||
|
prog, channels);
|
||||||
|
usage(prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
c[3] = c[1]; /* alpha, if present */
|
||||||
|
c[2] = c[1] = c[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (to_linear)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if ((channels & 1) == 0)
|
||||||
|
{
|
||||||
|
double alpha = c[channels-1];
|
||||||
|
for (i=0; i<channels-1; ++i) c[i] *= alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<channels; ++i) c[i] = nearbyint(c[i] * 65535);
|
||||||
|
}
|
||||||
|
|
||||||
|
else /* to sRGB */
|
||||||
|
{
|
||||||
|
int i = (channels+1)&~1;
|
||||||
|
while (--i >= 0)
|
||||||
|
c[i] = sRGB_from_linear(c[i]);
|
||||||
|
|
||||||
|
for (i=0; i<channels; ++i) c[i] = nearbyint(c[i] * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<channels; ++i) printf(" %g", c[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -23,37 +23,9 @@
|
|||||||
/* pngpriv.h includes the definition of 'PNG_sRGB_FROM_LINEAR' which is required
|
/* pngpriv.h includes the definition of 'PNG_sRGB_FROM_LINEAR' which is required
|
||||||
* to verify the actual code.
|
* to verify the actual code.
|
||||||
*/
|
*/
|
||||||
#include "../pngpriv.h"
|
#include "../../pngpriv.h"
|
||||||
|
|
||||||
/*
|
#include "sRGB.h"
|
||||||
* Utility sRGB calculation functions.
|
|
||||||
*
|
|
||||||
* Both routines take and return a floating point value in the range
|
|
||||||
* 0 to 1.0, doing a calculation according to the sRGB specification.
|
|
||||||
* (In fact the source of the numbers is the wikipedia article at
|
|
||||||
* http://en.wikipedia.org/wiki/SRGB .)
|
|
||||||
*/
|
|
||||||
double
|
|
||||||
sRGB_from_linear(double l)
|
|
||||||
{
|
|
||||||
if (l <= 0.0031308)
|
|
||||||
l *= 12.92;
|
|
||||||
|
|
||||||
else
|
|
||||||
l = 1.055 * pow(l, 1/2.4) - 0.055;
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
linear_from_sRGB(double s)
|
|
||||||
{
|
|
||||||
if (s <= 0.04045)
|
|
||||||
return s / 12.92;
|
|
||||||
|
|
||||||
else
|
|
||||||
return pow((s+0.055)/1.055, 2.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The tables are declared 'const' in pngpriv.h, so this redefines the tables to
|
/* The tables are declared 'const' in pngpriv.h, so this redefines the tables to
|
||||||
* be used.
|
* be used.
|
||||||
|
|||||||
@ -4,9 +4,10 @@
|
|||||||
* Utility file; not actually a header, this contains definitions of sRGB
|
* Utility file; not actually a header, this contains definitions of sRGB
|
||||||
* calculation functions for inclusion in those test programs that need them.
|
* calculation functions for inclusion in those test programs that need them.
|
||||||
*
|
*
|
||||||
* All routines take and return a floating point value in the range 0 to 1.0,
|
* All routines take and return a floating point value in the range
|
||||||
* doing a calculation according to the sRGB specification. (In fact the source
|
* 0 to 1.0, doing a calculation according to the sRGB specification
|
||||||
* of the numbers is the wikipedia article.)
|
* (in fact the source of the numbers is the wikipedia article at
|
||||||
|
* http://en.wikipedia.org/wiki/SRGB).
|
||||||
*/
|
*/
|
||||||
static double
|
static double
|
||||||
sRGB_from_linear(double l)
|
sRGB_from_linear(double l)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user