[GRASS-dev] cause for bad colors in output from png driver

Glynn,

I finally isolated the cause of the color issue I’m having with the PNG driver.

It is the GRASS_TRUECOLOR setting.

If this is set to false, then the PNG looks fine, except that it uses a limited color pallet. If it is set to true, the PNG has black where it should be white and other issues.

GRASS_PNG_AUTO_WRITE=TRUE
export GRASS_PNG_AUTO_WRITE
GRASS_RENDER_IMMEDIATE=TRUE
export GRASS_RENDER_IMMEDIATE
GRASS_TRUECOLOR=TRUE
export GRASS_TRUECOLOR
GRASS_PNGFILE=map.png
export GRASS_PNGFILE

GRASS 6.3.cvs (spearfish60_test):~ > d.barscale tcolor=green
PNG: GRASS_TRUECOLOR status: TRUE
PNG: collecting to file: /Users/cmbarton/map.png,
GRASS_WIDTH=640, GRASS_HEIGHT=480
WARNING: Color: can’t set color -256

This gives a black background to the barscale

GRASS 6.3.cvs (spearfish60_test):~ > d.legend elevation.10m
PNG: GRASS_TRUECOLOR status: TRUE
PNG: collecting to file: /Users/cmbarton/map.png,
GRASS_WIDTH=640, GRASS_HEIGHT=480
WARNING: Color: can’t set color -256
WARNING: Color: can’t set color -16843264
WARNING: Color: can’t set color -33686272
WARNING: Color: can’t set color -50529280
WARNING: Color: can’t set color -50529280

A lot more of these errors. This is what is locking up the wxPython overlay routine

If I set GRASS_TRUECOLOR=FALSE, I get no errors, d.barscale is correct, but of course the FP colors in d.legend do not display properly.

Michael


Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Michael Barton wrote:

I finally isolated the cause of the color issue I¹m having with the PNG
driver.

It is the GRASS_TRUECOLOR setting.

If this is set to false, then the PNG looks fine, except that it uses a
limited color pallet. If it is set to true, the PNG has black where it
should be white and other issues.

GRASS_PNG_AUTO_WRITE=TRUE
export GRASS_PNG_AUTO_WRITE
GRASS_RENDER_IMMEDIATE=TRUE
export GRASS_RENDER_IMMEDIATE
GRASS_TRUECOLOR=TRUE
export GRASS_TRUECOLOR
GRASS_PNGFILE=map.png
export GRASS_PNGFILE

GRASS 6.3.cvs (spearfish60_test):~ > d.barscale tcolor=green
PNG: GRASS_TRUECOLOR status: TRUE
PNG: collecting to file: /Users/cmbarton/map.png,
GRASS_WIDTH=640, GRASS_HEIGHT=480
WARNING: Color: can't set color -256

This gives a black background to the barscale

GRASS 6.3.cvs (spearfish60_test):~ > d.legend elevation.10m
PNG: GRASS_TRUECOLOR status: TRUE
PNG: collecting to file: /Users/cmbarton/map.png,
GRASS_WIDTH=640, GRASS_HEIGHT=480
WARNING: Color: can't set color -256
WARNING: Color: can't set color -16843264
WARNING: Color: can't set color -33686272
WARNING: Color: can't set color -50529280
WARNING: Color: can't set color -50529280
...
A lot more of these errors. This is what is locking up the wxPython overlay
routine

Duh; this is related to the changes to support mmap()d files.

The framebuffer is always stored as B,G,R,A (the format used by 32-bpp
BMP files). This corresponds to 0xAARRGGBB on a little-endian system
and 0xBBGGRRAA on a big-endian system (e.g. Mac).

Externally (DRV_color, DRV_lookup_color), the alpha value is always
zero (0 = opaque, 255 = transparent), resulting in 0x00RRGGBB on x86
and 0xBBGGRR00 on Mac. But the valid range of colors is always 0 to
0x00FFFFFF inclusive.

Hence the error on Mac, and why I couldn't reproduce it on x86.

I'll change it to always use 0x00RRGGBB externally.

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

Thanks. This was a really baffling one.

Michael

On 5/9/07 2:33 PM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Michael Barton wrote:

I finally isolated the cause of the color issue I¹m having with the PNG
driver.

It is the GRASS_TRUECOLOR setting.

If this is set to false, then the PNG looks fine, except that it uses a
limited color pallet. If it is set to true, the PNG has black where it
should be white and other issues.

GRASS_PNG_AUTO_WRITE=TRUE
export GRASS_PNG_AUTO_WRITE
GRASS_RENDER_IMMEDIATE=TRUE
export GRASS_RENDER_IMMEDIATE
GRASS_TRUECOLOR=TRUE
export GRASS_TRUECOLOR
GRASS_PNGFILE=map.png
export GRASS_PNGFILE

GRASS 6.3.cvs (spearfish60_test):~ > d.barscale tcolor=green
PNG: GRASS_TRUECOLOR status: TRUE
PNG: collecting to file: /Users/cmbarton/map.png,
GRASS_WIDTH=640, GRASS_HEIGHT=480
WARNING: Color: can't set color -256

This gives a black background to the barscale

GRASS 6.3.cvs (spearfish60_test):~ > d.legend elevation.10m
PNG: GRASS_TRUECOLOR status: TRUE
PNG: collecting to file: /Users/cmbarton/map.png,
GRASS_WIDTH=640, GRASS_HEIGHT=480
WARNING: Color: can't set color -256
WARNING: Color: can't set color -16843264
WARNING: Color: can't set color -33686272
WARNING: Color: can't set color -50529280
WARNING: Color: can't set color -50529280
...
A lot more of these errors. This is what is locking up the wxPython overlay
routine

Duh; this is related to the changes to support mmap()d files.

The framebuffer is always stored as B,G,R,A (the format used by 32-bpp
BMP files). This corresponds to 0xAARRGGBB on a little-endian system
and 0xBBGGRRAA on a big-endian system (e.g. Mac).

Externally (DRV_color, DRV_lookup_color), the alpha value is always
zero (0 = opaque, 255 = transparent), resulting in 0x00RRGGBB on x86
and 0xBBGGRR00 on Mac. But the valid range of colors is always 0 to
0x00FFFFFF inclusive.

Hence the error on Mac, and why I couldn't reproduce it on x86.

I'll change it to always use 0x00RRGGBB externally.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Glynn,

Just compiled the newest version from the CVS and this is solved. Thanks
very much for responding so quickly.

Michael

On 5/9/07 2:33 PM, "Glynn Clements" <glynn@gclements.plus.com> wrote:

Duh; this is related to the changes to support mmap()d files.

The framebuffer is always stored as B,G,R,A (the format used by 32-bpp
BMP files). This corresponds to 0xAARRGGBB on a little-endian system
and 0xBBGGRRAA on a big-endian system (e.g. Mac).

Externally (DRV_color, DRV_lookup_color), the alpha value is always
zero (0 = opaque, 255 = transparent), resulting in 0x00RRGGBB on x86
and 0xBBGGRR00 on Mac. But the valid range of colors is always 0 to
0x00FFFFFF inclusive.

Hence the error on Mac, and why I couldn't reproduce it on x86.

I'll change it to always use 0x00RRGGBB externally.

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

Glynn Clements wrote:

The framebuffer is always stored as B,G,R,A (the format used by 32-bpp
BMP files).

(answers my earlier r.what.color question)

This corresponds to 0xAARRGGBB on a little-endian system and
0xBBGGRRAA on a big-endian system (e.g. Mac).

dumb question: are Intel Macs now little endian?

Externally (DRV_color, DRV_lookup_color), the alpha value is always
zero (0 = opaque, 255 = transparent),

in gis.h I used:

typedef struct
{
    unsigned char r, g, b, a; /* red, green, blue, and alpha */
} RGBA_Color ;

typedef RGBA_Color RGB_Color;

/* RGBA_Color alpha presets */
#define RGBA_COLOR_OPAQUE 255
#define RGBA_COLOR_TRANSPARENT 0
#define RGBA_COLOR_NONE 0

Are the above alpha OPAQUE and TRANSPARENT values backwards? I had
pictured alpha as opacity, with OPAQUE being 100% and TRANSPARENT as 0%.
COLOR_NONE is used to indicate that the RGB array hasn't been filled.
(d.vect color=none)

Hamish

On May 9, 2007, at 8:11 PM, Hamish wrote:

This corresponds to 0xAARRGGBB on a little-endian system and
0xBBGGRRAA on a big-endian system (e.g. Mac).

dumb question: are Intel Macs now little endian?

Intel Macs have always been little-endian. Only the PPC Macs are big-endian. So, giving "Mac" as an example of big-endian is now not sufficient. You need to say PPC Macs and Intel Macs (big/little).

:slight_smile:

-----
William Kyngesburye <kyngchaos*at*kyngchaos*dot*com>
http://www.kyngchaos.com/

[Trillian] What are you supposed to do WITH a maniacally depressed robot?

[Marvin] You think you have problems? What are you supposed to do if you ARE a maniacally depressed robot? No, don't try and answer, I'm 50,000 times more intelligent than you and even I don't know the answer...

- HitchHiker's Guide to the Galaxy

Hamish:

dumb question: are Intel Macs now little endian?

Yup : Intel. Older PPC Macs were big endian.

Daniel.

--
-- Daniel Calvelo Aros

Hamish wrote:

> The framebuffer is always stored as B,G,R,A (the format used by 32-bpp
> BMP files).

(answers my earlier r.what.color question)

> This corresponds to 0xAARRGGBB on a little-endian system and
> 0xBBGGRRAA on a big-endian system (e.g. Mac).

dumb question: are Intel Macs now little endian?

Yes; the x86 is always little-endian; if you want to read big-endian
values, you have to do it in software.

> Externally (DRV_color, DRV_lookup_color), the alpha value is always
> zero (0 = opaque, 255 = transparent),

in gis.h I used:

typedef struct
{
    unsigned char r, g, b, a; /* red, green, blue, and alpha */
} RGBA_Color ;

typedef RGBA_Color RGB_Color;

/* RGBA_Color alpha presets */
#define RGBA_COLOR_OPAQUE 255
#define RGBA_COLOR_TRANSPARENT 0
#define RGBA_COLOR_NONE 0

Are the above alpha OPAQUE and TRANSPARENT values backwards? I had
pictured alpha as opacity, with OPAQUE being 100% and TRANSPARENT as 0%.
COLOR_NONE is used to indicate that the RGB array hasn't been filled.
(d.vect color=none)

There's no "right" answer; "alpha" can represent either opacity (0 =
transparent, 255 = opaque) or transparency (0 = opaque, 255 =
transparent).

The PNG driver uses transparency because all externally-specified
colours are opaque, and at that time, the integer colour number was
stored directly in the framebuffer. Transparent pixels can only arise
from erasing the framebuffer when GRASS_TRANSPARENT=TRUE, and (more
recently) with R_bitmap(). Note that R_bitmap() uses opacity.

When writing PPM/PGM files, the PGM file contains opacity values
(255-alpha). When writing PNG files, it calls png_set_invert_alpha(),
which causes the opacity values to be returned when reading.

I'm not sure which sense the 32-bit BMP format uses; the only
application I tested (gqview) simply ignores the alpha channel. If it
turns out that it's meant to be opacity, I'll need to invert the
internal format.

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