[GRASSLIST:428] Re: Maximum number of colors in rasters

Glynn Clements glynn at gclements.plus.com
Mon Mar 27 13:29:12 EST 2006


Hamish wrote:

> For some reason I don't understand, floating point maps don't do smooth
> color transitions.

If you look at G_get_color_range() in lib/gis/color_range.c, for FP
maps, it returns +/- 255^3 for the min/max values.

Moving on to lib/display/raster2.c, D_set_colors() calls
D_check_colormap_size(), which checks whether the number of colours
supported by the driver is sufficient for the range returned by
G_get_color_range().

If there are sufficient colours, it uploads a colour table to the
driver such that each category has its own colour table entry.

For an FP map, it wants 2 * 255^3 + 4 = 33162754 colours, which is
more than the 16777216 colours provided by a 24-bit display. In this
case, it uploads a colour cube which fits within the number of colours
provided by the driver, clamped to a maximum of 32 levels per
component (i.e. 32768 colours, or 15-bpp).

IOW, the colour handling in libdisplay was designed for colour-mapped
displays and integer maps. Support for FP maps and true-colour
hardware has largely been bolted on as an afterthought.

OTOH, it's constrained by the fact that uploading a 16777216-entry
(24-bpp) colour table to the driver isn't particularly practical (for
a start, it will cause the driver to consume an extra 64MB of RAM, as
well as being rather slow).

[If you want to test this case, create an integer map with just under
2^24 categories (e.g. using "r.composite ... levels=256", but ensure
that it doesn't actually use #FFFFFF, as the +4 in
D_check_colormap_size() will take it over the limit), then display it
with d.rast. Note the time taken and the memory used by the driver.]

One solution would be for libdisplay to use D_draw_raster_RGB() if the
driver supports >=32768 colours (i.e. it's using true-color). This
eliminates the need to upload a large colour table; instead, you
upload separate R/G/B translation tables, each of which would have 256
entries (256 * 3 is much smaller than 256 ^ 3), and send the raster as
separate R/G/B components rather than a composite index.

Another option would be to sample the map's colour table rather than
using a colour cube. A colour table is a piecewise-linear curve in a
3-dimensional space. Unless it's a space-filling curve (Sierpinski,
Hilbert etc), and it probably isn't, a colour cube is a very
sub-optimal choice.

The latter is more work, but would also provide improvements on
colour-mapped displays. OTOH, are colour-mapped displays still
relevant nowadays? Removing support for them would make the display
architecture (libdisplay, libraster, monitor drivers) so much simpler.

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-user mailing list