awpaeth@watcgl.waterloo.edu (Alan Wm Paeth) (12/07/88)
>The particular problem I have in mind is that of a StaticGray display with N >equally spaced intensities arranged in a ramp with black at 0 and white at >N-1...Two different expressions for computing the appropriate pixel value... > >(a) floor((.299r + .587g + .114b)(n - 1) + 0.5) (a) > >(b) floor((.299r + .587g + .114b)(n)) (b) > >..where maxColor is dependent upon which of (a) or (b) is chosen: > float maxColor = (float) (0xFFFF); /* (a) */ > float maxColor = (float) (0x10000); /* (b) */ Your question is not so much on luminance _per se_ (else I would have asked you questions about monitor calibration, gamma, etc.) but about integer representation schemes for pixels. I am adamant advocate of the interval [0.0..1.0] (a doubly-closed interval) to represent [black..white]. This interval allows closure for both multiplication (image blending) and complementation (1-x image reversal). This design topic is covered at length in "The IM Raster Toolkit -- Design, Implementation and Use" (U-of-W tech report CS-86-65), see also "PROCEEDINGS, Graphics Interface '86 (Vancouver), pg. 93. I can think of no reason to justify the common practice of 0=black, 256=white in which 256 (and hence, white) is not a symbol in the representation scheme. (I'm dealing with the 8-bit integer intensity case as it is so familiar). This approach treats the domain as the semi-open interval [0..1) which allows the integer intensity to be viewed as a binary fraction (0.ffffffff). This in turn means that mapping, say, a four-bit gray scale or 0.ffff onto an 8-bit scale can be done with bit shifting. But this has obvious problems. A one-bit gray scale yields the two symbols {0, 1} which as fractions are .0 and .1, so that bit-shifting into higher precisions only gives a half-intensity value, that is, the value .10000000 and not .11111111 By way of comparison, setting 0=black and 255=white means that white of the form 2^m-1 (m the number of bits, eight in this case) is always present in the representation scheme. Moreover, the upward mapping of a domain of lower precision to a higher one remains simple -- it is merely an integer multiply to go from n to m bits, if n divides m. For many machines the cost of the integer multiply is on par with the multi-bit left shift (which is really just a multiply by 2^(m-n)). For instance, 4-bit gray [0..15] with 15 representing white (1.0) can be mapped onto 12-bit gray [0..4095] by multiplying the 4-bit sample by 273. A "proof" to show that an integer factor exists (as 4 divides 12) is illustrated below: 4095 (12-bit white) = 15 (4-bit white) * 273 (integer scale factor) 1 1 1 1 1 1 1 1 1 1 1 1 = 1 1 1 1 * 0 0 0 1 0 0 0 1 0 0 0 1 For other mappings an exact integer scale factor may not exist, but the domains (typically 12 bits are less) are small enough that table look-up is easily implemented, which in almost all cases is faster than either bit-shift-style multiplies or the garden variety integer kind. So in short, there are no advantages to using the [0..2^m) representation, just liabilites -- so I choose your varient (a), which implies: [0..2^m-1]. /Alan Paeth PS - Copies of the IM Raster toolkit technical report are available from the University of Waterloo, as is a magnetic tape distribution of over four dozen machine-independent raster-based tools. For more information: IM Raster Toolkit c/o Computer Graphics Laboratory University of Waterloo Waterloo, Ont. N2L 3G1 CANADA ph: 519-888-4534