// several changes (mainly x86 and quality optimizations) by wili/hybrid 1996 /* 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. * * 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. */ #include "neuquant.h" #include extern void check_abort(); /* Network Definitions ------------------- */ #define maxnetpos (netsize-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 (netsize>>3) /* for 256 cols, radius starts */ #define radiusbiasshift 6 /* at 32.0 biased by 6 bits */ #define radiusbias (((int) 1)<>= netbiasshift; network[i][3] = i; /* record colour no */ } } /* Output colour map ----------------- */ void copy_colourmap( char *dest) { int i,j; for (i=2; i>=0; i--) for (j=0; j>1; for (j=previouscol+1; j=0)) { if (i= bestd) i = netsize; /* stop iter */ else { i++; dist=abs(dist)+abs(p[2]-r); // 0 b if (dist=0) { p = network[j]; dist = (g - p[1]); /* inx key - reverse dif */ if (dist >= bestd) j = -1; /* stop iter */ else { j--; dist=abs(dist)+abs(p[2]-r); // 0 b if (dist>(intbiasshift-netbiasshift)); if (biasdist> betashift); *f++ -= betafreq; *p++ += (betafreq<netsize) hi=netsize; j = i+1; k = i-1; q = radpower; while ((jlo)) { mul = (float)(*(++q))/alpharadbias; if (jlo) { p = network[k]; p[0] -= FTOI ((p[0]-b)*mul); p[1] -= FTOI ((p[1]-g)*mul); p[2] -= FTOI ((p[2]-r)*mul); k--; } } } /* Main Learning Loop ------------------ */ void learn() { int i,j,b,g,r; int radius,rad,alpha,step,delta,samplepixels,r2; unsigned char *p; unsigned char *lim; int percadd,perc; alphadec = 30 + ((samplefac-1)/3); p = thepicture; lim = thepicture + lengthcount; samplepixels = lengthcount/(3*samplefac); delta = samplepixels/ncycles; alpha = initalpha; radius = initradius; rad = radius >> radiusbiasshift; if (rad <= 1) rad = 0; for (i=0; iperc) { check_abort(); printf("%cLearning (%d%%)",13,(i*100)/samplepixels); perc = i+percadd; fflush(stdout); } b = p[0] << netbiasshift; g = p[1] << netbiasshift; r = p[2] << netbiasshift; j = contest(b,g,r); altersingle(alpha,j,b,g,r); if (rad) alterneigh(rad,j,b,g,r); /* alter neighbours */ p += step; if (p >= lim) p -= lengthcount; i++; if (!(i%delta)) { alpha -= alpha / alphadec; radius -= radius / radiusdec; rad = radius >> radiusbiasshift; if (rad <= 1) rad = 0; r2 = rad*rad; for (j=0; j