Gamma Correction
Before diving into the PNG-specific code, there are a couple of items in
the main program (front end) that are worth a quick look. The first has
to do with our old friend, gamma correction (see Chapter 10, "Gamma Correction and Precision Color"). As I noted
earlier, in general there is no way to know what the gamma value of the input
file is, so the output PNG file's gamma cannot be set automatically. But
we do know that if the input file looks OK when displayed on the user's
display system--which is presumed to be the one in use when the conversion
program is run--then the file gamma is roughly equal to the inverse of
the display system's exponent. So wpng calculates a default value
for the display-system exponent just as our two PNG-reading demo programs
did; the difference is that its calculated value is purely advisory. Here
is the code to calculate the default gamma value:
double default_gamma = 0.0;
#if defined(NeXT)
default_exponent = 1.0; /* 2.2/next_gamma for 3rd-party utils */
#elif defined(sgi)
default_exponent = 1.3; /* default == 2.2 / 1.7 */
/* there doesn't seem to be any documented function to get the
* "gamma" value, so we do it the hard way */
if (tmpfile = fopen("/etc/config/system.glGammaVal", "r")) {
double sgi_gamma;
fgets(fooline, 80, tmpfile);
fclose(tmpfile);
sgi_gamma = atof(fooline);
if (sgi_gamma > 0.0)
default_exponent = 2.2 / sgi_gamma;
}
#elif defined(Macintosh)
default_exponent = 1.5; /* default == (1.8/2.61) * 2.2 */
/*
if (mac_gamma = some_mac_function_that_returns_gamma())
default_exponent = (mac_gamma/2.61) * 2.2;
*/
#else
default_exponent = 2.2; /* assume std. CRT, no LUT: most PCs */
#endif
default_gamma = 1.0 / default_exponent;
if ((p = getenv("SCREEN_GAMMA")) != NULL) {
double exponent = atof(p);
if (exponent > 0.0)
default_gamma = 1.0 / atof(p);
}
The first section calculates a platform-dependent exponent for the display
system, which is then inverted to give a default file-gamma value. But it
is possible that the user has calibrated the display system more precisely
and has defined the SCREEN_GAMMA environment variable as suggested
by the libpng documentation. If so, this value is used instead.
Note that the Macintosh code is incomplete. The Macintosh macro,
presumed to be defined already, most likely would need to be set on the basis
of compiler-specific macros. For example, the following preprocessor code
would work for Metrowerks CodeWarrior and the Macintosh Programmer's Workbench,
although MPW is not terribly specific and might be defined on non-Macintosh
systems, too:
#if !defined(Macintosh)
# if defined(__MWERKS__) && defined(macintosh)
# define Macintosh
# elif defined(MPW) /* && defined(MCH_MACINTOSH) */
# define Macintosh
# endif
#endif
In any case, the calculated file gamma is presented as part of wpng's
usage screen but thereafter ignored.
|