[Geoserver-devel] semi-transparent png8 images

Hello raster experts,

out of an issue raised in gwc land, I wonder whether we can support semi transparent 8 bit png images (I assume we just don’t so far?).

A little investigation (as I was trying to reject the proposal of using the pngquant external program to achieve this) suggests that what we need is to use the NeuQuant quantization algorithm[1], and surprisingly it looks like JAI actually supports it: <http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html>

So question is has this even been considered, is known to (not)work? and if yes, do you think we could add support for it in GeoServer?

Yeah the algorithm is known to be slower than the default median cut, a price that the admin may be able to pay in exchange for higher quality png8 output?

TIA,
Gabriel

[1]<http://members.ozemail.com.au/~dekker/NEUQUANT.HTML>


Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On Thu, Oct 20, 2011 at 7:18 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Hello raster experts,
out of an issue raised in gwc land, I wonder whether we can support semi
transparent 8 bit png images (I assume we just don't so far?).
A little investigation (as I was trying to reject the proposal of using the
pngquant external program to achieve this) suggests that what we need is to
use the NeuQuant quantization algorithm[1], and surprisingly it looks like
JAI actually supports it:
<http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html&gt;
So question is has this even been considered, is known to (not)work? and if
yes, do you think we could add support for it in GeoServer?

It's sometihng that has been in my wish list for a while. The neuquant
algorithm in
JAI does not support translucency and it's, afaik, quite slow, so it's
really useless.
See here:
http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html
"This operation generates an optimal lookup table (LUT) based on the
provided 3-band RGB source image by executing a color quantization
algorithm."
The op won't work on RGBA images as far as I know.

We can extend the current mediant cut, and I've put eyes on another
fast C implementation
that does support translucency that would need to be ported over to
Java/JAI. but so far
I haven't had time to work on it. It would require a few days of work
to do the port and
test it over the various input types, the pre-cooked palettes and so on.

Cheers
Andrea

--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------

On Thu, Oct 20, 2011 at 3:08 PM, Andrea Aime <andrea.aime@anonymised.com> wrote:

On Thu, Oct 20, 2011 at 7:18 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

Hello raster experts,
out of an issue raised in gwc land, I wonder whether we can support semi
transparent 8 bit png images (I assume we just don’t so far?).
A little investigation (as I was trying to reject the proposal of using the
pngquant external program to achieve this) suggests that what we need is to
use the NeuQuant quantization algorithm[1], and surprisingly it looks like
JAI actually supports it:
<http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html>
So question is has this even been considered, is known to (not)work? and if
yes, do you think we could add support for it in GeoServer?

It’s sometihng that has been in my wish list for a while. The neuquant
algorithm in
JAI does not support translucency and it’s, afaik, quite slow, so it’s
really useless.
See here:
http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html
“This operation generates an optimal lookup table (LUT) based on the
provided 3-band RGB source image by executing a color quantization
algorithm.”
The op won’t work on RGBA images as far as I know.

We can extend the current mediant cut, and I’ve put eyes on another
fast C implementation
that does support translucency that would need to be ported over to
Java/JAI. but so far
I haven’t had time to work on it. It would require a few days of work
to do the port and
test it over the various input types, the pre-cooked palettes and so on.

disappointing on the JAI side. Still, the following page[1] points to a java implementation that claims to support semi transparent: <http://members.ozemail.com.au/~dekker/NeuQuant.java>

may that be a good starting point?

[1]http://members.ozemail.com.au/~dekker/NEUQUANT.HTML

Cheers
Andrea

On Thu, Oct 20, 2011 at 8:22 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

On Thu, Oct 20, 2011 at 3:08 PM, Andrea Aime <andrea.aime@anonymised.com>
wrote:

On Thu, Oct 20, 2011 at 7:18 PM, Gabriel Roldan <groldan@anonymised.com>
wrote:
> Hello raster experts,
> out of an issue raised in gwc land, I wonder whether we can support semi
> transparent 8 bit png images (I assume we just don't so far?).
> A little investigation (as I was trying to reject the proposal of using
> the
> pngquant external program to achieve this) suggests that what we need is
> to
> use the NeuQuant quantization algorithm[1], and surprisingly it looks
> like
> JAI actually supports it:
>
> <http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html&gt;
> So question is has this even been considered, is known to (not)work? and
> if
> yes, do you think we could add support for it in GeoServer?

It's sometihng that has been in my wish list for a while. The neuquant
algorithm in
JAI does not support translucency and it's, afaik, quite slow, so it's
really useless.
See here:

http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html
"This operation generates an optimal lookup table (LUT) based on the
provided 3-band RGB source image by executing a color quantization
algorithm."
The op won't work on RGBA images as far as I know.

We can extend the current mediant cut, and I've put eyes on another
fast C implementation
that does support translucency that would need to be ported over to
Java/JAI. but so far
I haven't had time to work on it. It would require a few days of work
to do the port and
test it over the various input types, the pre-cooked palettes and so on.

disappointing on the JAI side. Still, the following page[1] points to a java
implementation that claims to support semi
transparent: <http://members.ozemail.com.au/~dekker/NeuQuant.java&gt;
may that be a good starting point?
[1]http://members.ozemail.com.au/~dekker/NEUQUANT.HTML

The code mentions a "alpha" variable, but it never actually uses the alpha
values from the pixels, so I'm inclined to believe it still just works for RGB
images.

There are two interesting C implementations around that can do RGBA,
one, pngnq, uses neuquant, the other, pngquant, uses a median cut.
When faced with a RGBA input image the difference in output seems small,
to the naked eye, negligible, but the performance one is staggering.

Let's take a image that GeoServer will still allow to generate, since these
algorithms work particularly bad on screen sized images:

http://demo1.geo-solutions.it/playground/wms?LAYERS=boulder&STYLES=&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A2876&BBOX=3058543.3075541,1247612.764777,3064807.4077617,1251136.3211438&WIDTH=1600&HEIGHT=900&transparent=true

and then translate it with the two tools:

time pngnq boulder.png

real 0m3.568s
user 0m3.560s
sys 0m0.000s

time pngquant 256 boulder.png

real 0m0.743s
user 0m0.730s
sys 0m0.010s

Consider that both had to pay the same price to decode the input and
re-encode the output, and that takes some time too. As a reference:

time gdal_translate -of PNG boulder.png boulder2.png
Input file size is 1600, 900
0...10...20...30...40...50...60...70...80...90...100 - done.

real 0m0.378s
user 0m0.370s
sys 0m0.010s

It looks like pngquant is 10 times faster and still able to produce good
looking output.
Also, its source code is small and relatively easy to understand, at least
compared to a neuquant implementation.

I understand that you're hitting for png8 for tile cache and so the
interest in large images may not be there, but consider that once
you add that output format it can be used for WMS as well, and we
allow relatively large request, if the png8 implementation is not careful
it can be easily used as a way to mount a DOS attack on the server
slamming its cpus to death.

If we go for a very slow implementation we should also be conscious
and allow the administrator to turn it off somehow

Cheers
Andrea

--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------

I understand and yes, as I'm looking for support for tiles ovreall
image size is going to be smaller.
One thing I've read on those pages though is that the neuquant
algorithm can use a pixel interleave other than 1, they recommend like
10.
Not that I'm pushing for it, just may be worth mentioning.
Hope any of us has the time/funding to look further into it in the near term.

Cheers,
Gabriel

On Fri, Oct 21, 2011 at 3:26 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Thu, Oct 20, 2011 at 8:22 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

On Thu, Oct 20, 2011 at 3:08 PM, Andrea Aime <andrea.aime@anonymised.com>
wrote:

On Thu, Oct 20, 2011 at 7:18 PM, Gabriel Roldan <groldan@anonymised.com>
wrote:
> Hello raster experts,
> out of an issue raised in gwc land, I wonder whether we can support semi
> transparent 8 bit png images (I assume we just don't so far?).
> A little investigation (as I was trying to reject the proposal of using
> the
> pngquant external program to achieve this) suggests that what we need is
> to
> use the NeuQuant quantization algorithm[1], and surprisingly it looks
> like
> JAI actually supports it:
>
> <http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html&gt;
> So question is has this even been considered, is known to (not)work? and
> if
> yes, do you think we could add support for it in GeoServer?

It's sometihng that has been in my wish list for a while. The neuquant
algorithm in
JAI does not support translucency and it's, afaik, quite slow, so it's
really useless.
See here:

http://download.oracle.com/docs/cd/E17802_01/products/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ColorQuantizerDescriptor.html
"This operation generates an optimal lookup table (LUT) based on the
provided 3-band RGB source image by executing a color quantization
algorithm."
The op won't work on RGBA images as far as I know.

We can extend the current mediant cut, and I've put eyes on another
fast C implementation
that does support translucency that would need to be ported over to
Java/JAI. but so far
I haven't had time to work on it. It would require a few days of work
to do the port and
test it over the various input types, the pre-cooked palettes and so on.

disappointing on the JAI side. Still, the following page[1] points to a java
implementation that claims to support semi
transparent: <http://members.ozemail.com.au/~dekker/NeuQuant.java&gt;
may that be a good starting point?
[1]http://members.ozemail.com.au/~dekker/NEUQUANT.HTML

The code mentions a "alpha" variable, but it never actually uses the alpha
values from the pixels, so I'm inclined to believe it still just works for RGB
images.

There are two interesting C implementations around that can do RGBA,
one, pngnq, uses neuquant, the other, pngquant, uses a median cut.
When faced with a RGBA input image the difference in output seems small,
to the naked eye, negligible, but the performance one is staggering.

Let's take a image that GeoServer will still allow to generate, since these
algorithms work particularly bad on screen sized images:

http://demo1.geo-solutions.it/playground/wms?LAYERS=boulder&STYLES=&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A2876&BBOX=3058543.3075541,1247612.764777,3064807.4077617,1251136.3211438&WIDTH=1600&HEIGHT=900&transparent=true

and then translate it with the two tools:

time pngnq boulder.png

real 0m3.568s
user 0m3.560s
sys 0m0.000s

time pngquant 256 boulder.png

real 0m0.743s
user 0m0.730s
sys 0m0.010s

Consider that both had to pay the same price to decode the input and
re-encode the output, and that takes some time too. As a reference:

time gdal_translate -of PNG boulder.png boulder2.png
Input file size is 1600, 900
0...10...20...30...40...50...60...70...80...90...100 - done.

real 0m0.378s
user 0m0.370s
sys 0m0.010s

It looks like pngquant is 10 times faster and still able to produce good
looking output.
Also, its source code is small and relatively easy to understand, at least
compared to a neuquant implementation.

I understand that you're hitting for png8 for tile cache and so the
interest in large images may not be there, but consider that once
you add that output format it can be used for WMS as well, and we
allow relatively large request, if the png8 implementation is not careful
it can be easily used as a way to mount a DOS attack on the server
slamming its cpus to death.

If we go for a very slow implementation we should also be conscious
and allow the administrator to turn it off somehow

Cheers
Andrea

--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.

On Fri, Oct 21, 2011 at 3:23 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

I understand and yes, as I'm looking for support for tiles ovreall
image size is going to be smaller.
One thing I've read on those pages though is that the neuquant
algorithm can use a pixel interleave other than 1, they recommend like
10.
Not that I'm pushing for it, just may be worth mentioning.

Yeah, I played with that a few times, it works if the image you're trying
to compress is raster, with little/no regularity.
But if you are trying to display a road network with roads crossing at a right
angle (very common in roman cities) there is a very good chance that the
sampling will make the code skip important values.

When I first discovered neuquant I was all fired up and wanted to
include it in GeoServer right away, a deeper analysis of its shortcomings
and a weekend spent looking at the code made me change my mind :wink:

That's why I'm now backing more pngquant, seems to have all the markings
for a real world solution that actually works (simple, efficient, good output)

Cheers
Andrea

--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------

On Fri, Oct 21, 2011 at 11:02 AM, Andrea Aime
<andrea.aime@anonymised.com> wrote:

On Fri, Oct 21, 2011 at 3:23 PM, Gabriel Roldan <groldan@anonymised.com> wrote:

I understand and yes, as I'm looking for support for tiles ovreall
image size is going to be smaller.
One thing I've read on those pages though is that the neuquant
algorithm can use a pixel interleave other than 1, they recommend like
10.
Not that I'm pushing for it, just may be worth mentioning.

Yeah, I played with that a few times, it works if the image you're trying
to compress is raster, with little/no regularity.
But if you are trying to display a road network with roads crossing at a right
angle (very common in roman cities) there is a very good chance that the
sampling will make the code skip important values.

When I first discovered neuquant I was all fired up and wanted to
include it in GeoServer right away, a deeper analysis of its shortcomings
and a weekend spent looking at the code made me change my mind :wink:

That's why I'm now backing more pngquant, seems to have all the markings
for a real world solution that actually works (simple, efficient, good output)

excellent, thanks for sharing all these insights.
Gabriel

Cheers
Andrea

--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------

--
Gabriel Roldan
OpenGeo - http://opengeo.org
Expert service straight from the developers.