color scaling

As long as I'm sending lengthy ramblings to the list, I thought I'd
bring up another issue as well.

VisAD's autoscaling support works very simply, by mapping the lowest
sample value to min, and the highest sample value to max. This is the
most "honest" way to do autoscaling. But other ways may sometimes
produce more desirable results, depending on circumstances.

For example, I have a FITS file that has one tiny spot with values
somewhere in the 40,000 range, while the rest of the samples range from
0 to 100ish. The current autoscaling produces an image that is
completely black, with one tiny white spot. Cases like this occur often
with microscopy images.

To produce a better initial image in the above case, one could compute
the sampling mean and standard deviation, then use those values to
create an intelligent color mapping that emphasizes sampling differences
without being overly influenced by outliers.

Even in the case of spatial mappings, it may occasionally make sense to
do things this way. With the above FITS file, mapping the image range
RealType to Display.ZAxis would produce a nice surface, except for the
spike where the outliers are. Instead, the resultant display is
essentially flat with a single spike. If the autoscaling used some kind
of statistical approach, we'd see the relevant surface instead.

My idea is to expand the autoscaling logic to account for more than one
autoscaling strategy. For example, there could be a method of ScalarMap
and/or GraphicsModeControl such as:
  public void setScalingStrategy(int strategy)
where strategy can be MINMAX_STRATEGY (the default, as it is now),
STDDEV_STRATEGY, or possibly other alternative scaling techniques.

To implement this, the loop that computes min and max values would need
to also compute some basic statistical information such as mean,
standard deviation, and possibly other values such as median and mode.
But such changes wouldn't affect efficiency.

Of course, I could code this statistical color scaling logic in VisBio,
and just use ScalarMap.setRange() to implement it. But the functionality
seems generally useful enough that it might make sense for it to be part
of core VisAD.