diff -urN pngnq-0.4/neuquant32.c pngnq-0.41/neuquant32.c --- pngnq-0.4/neuquant32.c 2006-06-12 22:37:19.000000000 +1000 +++ pngnq-0.41/neuquant32.c 2006-06-17 09:25:04.000000000 +1000 @@ -381,7 +381,7 @@ register unsigned char *p; unsigned char *lim; - alphadec = 30 + ((samplefac-1)/3); + alphadec = 30 + ((samplefac-1)/4); /*Fixed sample factor bug 17/06/2006/ Stuart Coyle */ p = thepicture; lim = thepicture + lengthcount; samplepixels = lengthcount/(3*samplefac); diff -urN pngnq-0.4/neuquant32.c~ pngnq-0.41/neuquant32.c~ --- pngnq-0.4/neuquant32.c~ 1970-01-01 10:00:00.000000000 +1000 +++ pngnq-0.41/neuquant32.c~ 2006-06-17 09:24:20.000000000 +1000 @@ -0,0 +1,434 @@ +/* NeuQuant Neural-Net Quantization Algorithm + * ------------------------------------------ + * + * Copyright (c) 1994 Anthony Dekker + * + * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. + * See "Kohonen neural networks for optimal colour quantization" + * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. + * for a discussion of the algorithm. + * See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML + * + * Any party obtaining a copy of these files from the author, directly or + * indirectly, is granted, free of charge, a full and unrestricted irrevocable, + * world-wide, paid up, royalty-free, nonexclusive right and license to deal + * in this software and documentation files (the "Software"), including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons who receive + * copies from any such party to do so, with the only requirement being + * that this copyright notice remain intact. + * + * + * Modified to process 32bit RGBA images. + * Stuart Coyle 2004-2006 + */ + + +#include "neuquant32.h" + + +/* Network Definitions + ------------------- */ + +#define maxnetpos (MAXNETSIZE-1) +#define netbiasshift 4 /* bias for colour values */ +#define ncycles 100 /* no. of learning cycles */ + +/* defs for freq and bias */ +#define intbiasshift 16 /* bias for fractions */ +#define intbias (((int) 1)<>betashift) /* beta = 1/1024 */ +#define betagamma (intbias<<(gammashift-betashift)) + +/* defs for decreasing radius factor */ +#define initrad (MAXNETSIZE>>3) /* for 256 cols, radius starts */ +#define radiusbiasshift 6 /* at 32.0 biased by 6 bits */ +#define radiusbias (((int) 1)<>= netbiasshift; */ + /* Fix based on bug report by Juergen Weigert jw@suse.de */ + temp = (network[i][j] + (1 << (netbiasshift - 1))) >> netbiasshift; + if (temp > 255) temp = 255; + network[i][j] = temp; + } + network[i][4] = i; /* record colour no */ + } +} + + +/* Output colour map + ----------------- */ + +void writecolourmap(f) +FILE *f; +{ + int i,j; + + for (i=3; i>=0; i--) + for (j=0; j=0; i--){ + *map = network[j][i]; + map++; + } + } +} + + +/* Insertion sort of network and building of netindex[0..255] (to do after unbias) + ------------------------------------------------------------------------------- */ + +void inxbuild() +{ + register int i,j,smallpos,smallval; + register int *p,*q; + int previouscol,startpos; + + previouscol = 0; + startpos = 0; + for (i=0; i>1; + for (j=previouscol+1; j>1; + for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; /* really 256 */ +} + + +/* Search for ABGR values 0..255 (after net is unbiased) and return colour index + ---------------------------------------------------------------------------- */ +int inxsearch(al,b,g,r) + register int al,b,g,r; +{ + register int i,j,dist,a,bestd; + register int *p; + int best; + + bestd = 1000; /* biggest possible dist is 256*3 */ + best = -1; + i = netindex[g]; /* index on g */ + j = i-1; /* start at netindex[g] and work outwards */ + + while ((i=0)) { + if (i= bestd) i = netsize; /* stop iter */ + else { + i++; + if (dist<0) dist = -dist; + a = p[1] - b; if (a<0) a = -a; + dist += a; + if (dist=0) { + p = network[j]; + dist = g - p[2]; /* inx key - reverse dif */ + if (dist >= bestd) j = -1; /* stop iter */ + else { + j--; + if (dist<0) dist = -dist; + a = p[1] - b; if (a<0) a = -a; + dist += a; + if (dist>(intbiasshift-netbiasshift)); + if (biasdist> betashift); + *f++ -= betafreq; + *p++ += (betafreq<netsize) hi=netsize; + + j = i+1; + k = i-1; + q = radpower; + while ((jlo)) { + a = (*(++q)); + if (jlo) { + p = network[k]; + *p -= (a*(*p - al)) / alpharadbias; + p++; + *p -= (a*(*p - b)) / alpharadbias; + p++; + *p -= (a*(*p - g)) / alpharadbias; + p++; + *p -= (a*(*p - r)) / alpharadbias; + k--; + } + } +} + + +/* Main Learning Loop + ------------------ */ + +void learn(int verbose) /* Stu: N.B. added parameter so that main() could control verbosity. */ +{ + register int i,j,al,b,g,r; + int radius,rad,alpha,step,delta,samplepixels; + register unsigned char *p; + unsigned char *lim; + + alphadec = 30 + ((samplefac-1)/3); + p = thepicture; + lim = thepicture + lengthcount; + samplepixels = lengthcount/(3*samplefac); + delta = samplepixels/ncycles; /* here's a problem with small images: samplepixels < ncycles => delta = 0 */ + if(delta==0) delta = 1; /* kludge to fix */ + alpha = initalpha; + radius = initradius; + + rad = radius >> radiusbiasshift; + if (rad <= 1) rad = 0; + for (i=0; i= lim) p -= lengthcount; + + i++; + if (i%delta == 0) { /* FPE here if delta=0*/ + alpha -= alpha / alphadec; + radius -= radius / radiusdec; + rad = radius >> radiusbiasshift; + if (rad <= 1) rad = 0; + for (j=0; j