The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly.

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);
        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;
    default_exponent = 2.2;   /* assume std. CRT, no LUT:  most PCs */

    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

In any case, the calculated file gamma is presented as part of wpng's usage screen but thereafter ignored.

Last Update: 2010-Nov-26