[Image-SIG] bug in getcolors()

Richard Oudkerk r.oudkerk at tiscali.co.uk
Tue Feb 15 00:20:21 CET 2005


Sometimes (depending on the setting of the parameter maxcolors) the
last colour in the list returned by im.getcolors() is reported as
having a zero pixel count, and that colour will have appeared earlier
in the list.

For example if we do

. >>> import Image
. >>> im = Image.open("Images/lena.ppm")
. >>> A = im.quantize(3).convert("RGB")

then we get

. >>> A.getcolors(maxcolors=8)
. [(3236, (227, 183, 147)), (6851, (208, 143, 112)), (0, (227, 183, 147))]

(which is wrong) but get

. >>> A.getcolors(maxcolors=16)
. [(6851, (208, 143, 112)), (6297, (143, 84, 81)), (3236, (227, 183, 147))]

(which is right).

This seems to be caused by a bug at the end of getcolors32() in
GetBBox.c when table[] is being packed.

It looks as though the packing only works correctly if table[0] is
unoccupied (or the image has only one colour).  Otherwise table[0]
will get overwritten and lost.

I think this patch fixes things.


*** GetBBox.c   Mon Feb 14 01:04:58 2005
--- libImaging/GetBBox.c        Mon Feb 14 01:12:44 2005
***************
*** 307,315 ****

   overflow:

       /* pack the table */
!     for (x = y = 0; x < (int) code_size; x++)
!         if (table[x].count && x != y)
               table[y++] = table[x];
       table[y].count = 0; /* mark end of table */

--- 307,320 ----

   overflow:

+     /* find first unoccupied position in table */
+     for (y = 0; y < (int) code_size; y++)
+         if (!table[y].count)
+             break;
+
       /* pack the table */
!     for (x = y; x < (int) code_size; x++)
!         if (table[x].count)
               table[y++] = table[x];
       table[y].count = 0; /* mark end of table */


More information about the Image-SIG mailing list