Opened 20 years ago

Closed 20 years ago

Last modified 18 years ago

#684 closed defect (wontfix)

Trouble tricking Mapserver colors in 8-bit mode

Reported by: bartvde@… Owned by: sdlime
Priority: high Milestone:
Component: MapServer C Library Version: 4.2
Severity: normal Keywords:
Cc:

Description

Following an advice from Frank Warmerdam I tried to trick Mapserver into using
the right color for my raster file. The raster file is a TIFF file and with
24-bits output I have no color problems. But when using 8 bit png output I get
the wrong colors.

The message from Frank which I refer to is:
http://mapserver.gis.umn.edu/data2/wilma/mapserver-users/0312/msg00163.html

I have created a testset illustrating the problem with the raster and a
shapefile I am using to trick the colors. I tried to put the shapefile layer at
the top or the bottom of the MAP file, no difference.

The URL I test with is:
http://localhost/cgi-bin/mapserv.exe?map=/ms4w/apps/general/map/geostreets_color.map&request=GetMap&version=1.1.1&bbox=100000,350000,300000,550000&width=500&height=500&layers=Gemeentes,layer_6&format=image/png&service=WMS

and (switching the layers sequence):
http://www.vz.geodan.nl:1112/cgi-bin/mapserv.exe?map=/ms4w/apps/general/map/geostreets_color.map&request=GetMap&version=1.1.1&bbox=100000,350000,300000,550000&width=500&height=500&layers=layer_6,Gemeentes&format=image/png&service=WMS

Will attach the testset after this.

Attachments (1)

ms4w.tgz (471.9 KB ) - added by bartvde@… 20 years ago.
Testcase in tgz format.

Download all attachments as: .zip

Change History (5)

by bartvde@…, 20 years ago

Attachment: ms4w.tgz added

Testcase in tgz format.

comment:1 by bartvde@…, 20 years ago

Cc: warmerdam@… added
Added Frank to the cc.

comment:2 by fwarmerdam, 20 years ago

Resolution: wontfix
Status: newclosed
Bart,

I finally followed through and dug through this.  I mostly looked at the grey
color that should be a background more or less (232 232 208).  

You are correct that adding this color in the other Gemeentes layer didn't
help when rendering the 24bit layer to 8bit; however, after some thought it
makes sense to me.  

When MapServer renders 24bit images to 8bit, it does it using a color cube - 
normally of 175 colors (5x7x5).  Any given 24bit colors is assigned to the
nearest color in the color cube.  But this isn't done by searching the color
cube, but rather by "division and indexing".  So, predeclaring specific colors
you want to see won't *normally* help you reproduce an exact desired color
since that color won't be allocated as part of the color cube unless it is 
very close to a desired color during color cube allocation. 

When pre-defining a color could help is when there aren't enough colors left
free when the color cube is allocated.  In this case, ensuring that specific
important colors are available will make sure that key entries in the color
cube are populated with reasonable colors. 

So, the gist of it is, it can be very hard to preserve colors from 24bit images
excactly when rendering to 8bit, no matter what you do.  

One solution would be to include a 24->8 bit conversion mode that actually
always searched the color table for the closest matching color instead of doing
it by the current "divide and index" method.  However, this could potentially
make raster rendering quite a bit slower.  There are some other methods that
could be applied that would be more memory intensive but still quite fast. 

However, I am hesitant to add all that complication.  I think I would prefer to
encourage people to pre-process 24bit images externally.  For instance, the 
rgb2pct.py script in GDAL can convert a 24bit image to 8bit with "optimal"
color map selection and dithering.  

So, after all this, my intent for now is to do nothing unless we agree that 
improved 24bit to 8bit conversion is a priority within MapServer.

Thanks for providing a good testcase to demonstrate the problem.

comment:3 by bartvde@…, 20 years ago

Hi Frank,

thanks for looking into this, and I agree with you it is best to advise people 
to preprocess their rasters. I followed this advice and put my rasters to 8 
bit. Only problem I had was that the newly created geotiff file does not have 
the extents from the corresponding TFW file, so I ended up just leaving my TFW 
files in the directory. Also, is it a different level of compression as the new 
geotiff files are sometimes more than 10 times larger than the original ones?

This is URL for a map of the whole of the Netherlands with the 24 bit tiff 
rasters:
http://www.vz.geodan.nl:1111/cgi-bin/mapserv.exe?
map=/ms4w/apps/general/map/geostreets.map&request=GetMap&format=image/png&bbox=1
00000,350000,300000,650000&width=500&height=500&srs=EPSG:28992&version=1.1.1&lay
ers=layer_3,layer_4,layer_5,Layer_6

And this is the new URL with the 8 bit tiff rasters:
http://www.vz.geodan.nl:1111/cgi-bin/mapserv.exe?
map=/ms4w/apps/general/map/geostreets8bit.map&request=GetMap&format=image/png&bb
ox=100000,350000,300000,650000&width=500&height=500&srs=EPSG:28992&version=1.1.1
&layers=layer_3,layer_4,layer_5,Layer_6

As you can see, the result is as expected and great :).

Examples of a deeper level:

8 bit tiff rasters:
http://www.vz.geodan.nl:1111/cgi-bin/mapserv.exe?
map=/ms4w/apps/general/map/geostreets8bit.map&request=GetMap&format=image/png&bb
ox=252439,526413,266550,536291&width=800&height=560&srs=EPSG:28992&version=1.1.1
&layers=layer_3,layer_4,layer_5,Layer_6

24 bit tiff rasters:
http://www.vz.geodan.nl:1111/cgi-bin/mapserv.exe?
map=/ms4w/apps/general/map/geostreets.map&request=GetMap&format=image/png&bbox=2
52439,526413,266550,536291&width=800&height=560&srs=EPSG:28992&version=1.1.1&lay
ers=layer_3,layer_4,layer_5,Layer_6

Thanks a lot! I will summarize this to the mapserver user list if anybody will 
run into this in the future.

Bart

comment:4 by woodbri@…, 18 years ago

I have copied the following from my post to the mapserver list. It seems
relivant to this issue and that it will become a larger issue in the future with
more ka-map sctivity and the need for better looking images:

I have mapserver configured to work with ka-map and things are working
fine except we have noticed color shifts in tiles. We are using:

  OUTPUTFORMAT
    NAME PNG8
    DRIVER "GD/PNG"
    EXTENSION "png"
    MIMETYPE "image/png"
    IMAGEMODE RGBA
    TRANSPARENT OFF
    FORMATOPTION "QUANTIZE_FORCE=ON"
    FORMATOPTION "QUANTIZE_DITHER=OFF"
    FORMATOPTION "QUANTIZE_COLORS=256"
  END

in our mapfile and my hypotheses is that the GD QUANTIZE process is
selecting different colors based on the colors available in the various
meta-tiles. The mapserver source code calls the following function for this
process and from the GD manual:

> void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int
> colorsWanted) gdImagePtr gdImageCreatePaletteFromTrueColor(gdImagePtr
> im, int ditherFlag, int colorsWanted) (FUNCTION)
>
> gdImageCreatePaletteFromTrueColor returns a new image.
> gdImageTrueColorToPalette permanently converts the existing image.
> The two functions are otherwise identical.
>
> The function converts a truecolor image to a palette-based image,
> using a high-quality two-pass quantization routine. If ditherFlag is
> set, the image will be dithered to approximate colors better, at the
> expense of some obvious "speckling." colorsWanted can be anything up
> to 256. If the original source image includes photographic
> information or anything that came out of a JPEG, 256 is strongly
> recommended. 100% transparency of a single transparent color in the
> original truecolor image will be preserved. There is no other support
> for preservation of alpha channel or transparency in the destination
> image.
>
> For best results, don't use this function -- write real truecolor
> PNGs and JPEGs. The disk space gain of conversion to palette is not
> great (for small images it can be negative) and the quality loss is
> ugly. However, the version of this function included in version
> 2.0.12 and later does do a better job than the version included prior
> to 2.0.12.

So, a few questions:

1) Has anyone looked into the impact of using PNG24 images on
  a) image sizes
  b) ka-map tile-cache sizing
  c) compatibility with browsers
  d) impact on browser memory usage or performance
2) I thought Paul Spencer said to use DITHERED=OFF, is this correct
3) Has anyone looked at the GD routine? Would it be possible to add a palette of
say 32 colors that would be "sticky" and priority over other colors?

Note: See TracTickets for help on using tickets.