[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PNG pictures have gamma correction twice applied

From: David Kastrup
Subject: Re: PNG pictures have gamma correction twice applied
Date: Mon, 11 Nov 2002 18:30:59 +0100

"Stefan Monnier" <monnier+gnu/address@hidden> writes:

> > Now x_alloc_nearest_color is defined in src/xterm.c.  It first calls
> > gamma_correct on the function in question (which does the gamma
> > correction with a very expensive floating point operation), then
> > calls x_alloc_nearest_color_1, which does a costly operation of
> > figuring out a closest color.
> Have you checked whether this "costly operation" is actually done
> in your case ?  It should only happen if the XAllocColor fails, which
> should never be the case in a 16bpp (or more) display.

Correction: which should not be the case when there is no palette
involved of any kind.  If there is, XAllocColor will allocate the
next free color slot.  Since the Emacs display code never deallocates
a color again, the color palette will run out of colors eventually.
Whatever colors happen to be in the palette at that time, get used
for the "closest" color.  If you have, for example, a color diagram
as an image, the red top will allocate all the colors away, and blue,
green and white will be all represented by shades of red.

For that reason it would be more prudent to allocate a fixed palette,
even if it has just 4x4x4 colors, and use that.  Just making use of
whatever happens to be present in the current palette is an emergency
measure.  And asking for the current palette again for every new
pixel is not going to be reducing the X traffic...

> The reason for the "closest color" code is to deal with the situation
> where the aren't enough color slots available.  There might very well
> not be 64 slots available.
> I think this part of the code is OK, especially since I believe it is only
> triggered in the very rare cases where it is needed.

Always when you are having a palette and using images with a large
number of colors, since Emacs does never free colors it allocates.

> But I also remember that some of that code was done to try and reduce the
> amount of X traffic (there were many calls to XAllocColor or XLookupColor
> or something like that).

Well, since the X server gets asked for the entire palette every time
a pixel color is not found in the hash, when you are having images
with just few different colors, it will significantly reduce the
traffic.  And the hash probably is not amiss where _text_ colors are
concerned, since those happen to be few, usually (even though never
freeing color slots can lead to problems there, too).  But for
_images_ it does not make sense to treat every pixel as a new
surprise, and do all the lookup including fetching the current color
palette new for every pixel.

> I think the caching could be improved (to reduce X traffic), tho.

I think that for most purposes one should rather aim to obliterate
rather than improve it.  The closest match stuff should really be
only used when Emacs does not get a chance to allocate the standard
4x4x4 palette which should only be the case when some other color
hogger on an 8bit system is actively interfering.

> And bypassing this code for PNG would be a good idea since libpng
> should do a good enough (better) job already.

libpng has nothing to do with the actual color management.  It can
cater for the gamma correction, true, but that is the smallest
problem of the current code base.

Gamma correction should probably done by table lookup, anyway, when
libpng does not already cater for it.

And the image format conversions should be done by batching them,
instead of working on every single pixel.

If the Emacs code base can't with a good conscience make use of
toolkit parts with color management (such as gdk), one might cobble
some code together from such sources in order to manage this sort of
thing more amicably.  It really sounds quite like reinvention of the

David Kastrup, Kriemhildstr. 15, 44793 Bochum

reply via email to

[Prev in Thread] Current Thread [Next in Thread]