The netpbm-1mar1994 release of ppmquant suffers from an overflow bug. (The "distance" between colors is computed as a long, but it won't fit in a 32-bit long if maxval is 65535.) You can test for this bug by running ppmmake red 10 10 | ppmquant 256 | ppmhist If you get this output: r g b lum count --- --- --- --- ----- 0 0 0 0 100 then you've got the bug. The fixed version will produce the correct output (all red): r g b lum count --- --- --- --- ----- 65535 0 0 19595 100 - Darrell Kindred (dkindred@cmu.edu), 15 March 1997 --- ppm/ppmquant.c.orig Mon Oct 4 05:12:30 1993 +++ ppm/ppmquant.c Sat Mar 15 15:39:54 1997 @@ -247,20 +247,22 @@ ind = ppm_lookupcolor( cht, pP ); if ( ind == -1 ) { /* No; search colormap for closest match. */ - register int i, r1, g1, b1, r2, g2, b2; - register long dist, newdist; + int i; + pixval r1, g1, b1, r2, g2, b2; + double dist, newdist; r1 = PPM_GETR( *pP ); g1 = PPM_GETG( *pP ); b1 = PPM_GETB( *pP ); - dist = 2000000000; + /* 3 * maxval^2 is the largest distance possible */ + dist = (double) maxval * maxval * 4; for ( i = 0; i < newcolors; ++i ) { r2 = PPM_GETR( colormap[i].color ); g2 = PPM_GETG( colormap[i].color ); b2 = PPM_GETB( colormap[i].color ); - newdist = ( r1 - r2 ) * ( r1 - r2 ) + - ( g1 - g2 ) * ( g1 - g2 ) + - ( b1 - b2 ) * ( b1 - b2 ); + newdist = (double) ( r1 - r2 ) * ( r1 - r2 ) + + (double) ( g1 - g2 ) * ( g1 - g2 ) + + (double) ( b1 - b2 ) * ( b1 - b2 ); if ( newdist < dist ) { ind = i;