ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/neuclrtab.c
(Generate patch)

Comparing ray/src/px/neuclrtab.c (file contents):
Revision 2.5 by greg, Tue Aug 2 13:22:08 1994 UTC vs.
Revision 2.13 by greg, Sat Sep 8 19:17:52 2007 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1994 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Neural-Net quantization algorithm based on work of Anthony Dekker
6   */
7  
8 < #include "standard.h"
8 > #include "copyright.h"
9  
10 < #include "color.h"
10 > #include <string.h>
11  
12 + #include "standard.h"
13 + #include "color.h"
14   #include "random.h"
15 + #include "clrtab.h"
16  
17   #ifdef COMPAT_MODE
18   #define neu_init        new_histo
# Line 28 | Line 28 | extern BYTE    clrtab[256][3];
28   static int      clrtabsiz;
29  
30   #ifndef DEFSMPFAC
31 < #ifdef SPEED
32 < #define DEFSMPFAC       (240/SPEED+3)
33 < #else
34 < #define DEFSMPFAC       30
31 > #define DEFSMPFAC       3
32   #endif
36 #endif
33  
34   int     samplefac = DEFSMPFAC;  /* sampling factor */
35  
# Line 51 | Line 47 | static long    skipcount;
47  
48   #define setskip(sp,n)   ((sp)[0]=(n)>>16,(sp)[1]=((n)>>8)&255,(sp)[2]=(n)&255)
49  
50 + static void initnet(void);
51 + static void inxbuild(void);
52 + static int inxsearch(int b, int g, int r);
53 + static int contest(int b, int g, int r);
54 + static void altersingle(int alpha, int i, int b, int g, int r);
55 + static void alterneigh(int rad, int i, int b, int g, int r);
56 + static void learn(void);
57 + static void unbiasnet(void);
58 + static void cpyclrtab(void);
59  
60 < neu_init(npixels)               /* initialize our sample array */
61 < long    npixels;
60 >
61 > extern int
62 > neu_init(               /* initialize our sample array */
63 >        long    npixels
64 > )
65   {
66          register int    nsleft;
67          register long   sv;
# Line 90 | Line 98 | long   npixels;
98   }
99  
100  
101 < neu_pixel(col)                  /* add pixel to our samples */
102 < register BYTE   col[];
101 > extern void
102 > neu_pixel(                      /* add pixel to our samples */
103 >        register BYTE   col[]
104 > )
105   {
106          if (!skipcount--) {
107                  skipcount = nskip(cursamp);
# Line 103 | Line 113 | register BYTE  col[];
113   }
114  
115  
116 < neu_colrs(cs, n)                /* add a scanline to our samples */
117 < register COLR   *cs;
118 < register int    n;
116 > extern void
117 > neu_colrs(              /* add a scanline to our samples */
118 >        register COLR   *cs,
119 >        register int    n
120 > )
121   {
122          while (n > skipcount) {
123                  cs += skipcount;
# Line 121 | Line 133 | register int   n;
133   }
134  
135  
136 < neu_clrtab(ncolors)             /* make new color table using ncolors */
137 < int     ncolors;
136 > extern int
137 > neu_clrtab(             /* make new color table using ncolors */
138 >        int     ncolors
139 > )
140   {
141          clrtabsiz = ncolors;
142          if (clrtabsiz > 256) clrtabsiz = 256;
# Line 132 | Line 146 | int    ncolors;
146          cpyclrtab();
147          inxbuild();
148                                  /* we're done with our samples */
149 <        free((char *)thesamples);
149 >        free((void *)thesamples);
150                                  /* reset dithering function */
151          neu_dith_colrs((BYTE *)NULL, (COLR *)NULL, 0);
152                                  /* return new color table size */
# Line 140 | Line 154 | int    ncolors;
154   }
155  
156  
157 < int
158 < neu_map_pixel(col)              /* get pixel for color */
159 < register BYTE   col[];
157 > extern int
158 > neu_map_pixel(          /* get pixel for color */
159 >        register BYTE   col[]
160 > )
161   {
162          return(inxsearch(col[BLU],col[GRN],col[RED]));
163   }
164  
165  
166 < neu_map_colrs(bs, cs, n)        /* convert a scanline to color index values */
167 < register BYTE   *bs;
168 < register COLR   *cs;
169 < register int    n;
166 > extern void
167 > neu_map_colrs(  /* convert a scanline to color index values */
168 >        register BYTE   *bs,
169 >        register COLR   *cs,
170 >        register int    n
171 > )
172   {
173          while (n-- > 0) {
174                  *bs++ = inxsearch(cs[0][BLU],cs[0][GRN],cs[0][RED]);
# Line 160 | Line 177 | register int   n;
177   }
178  
179  
180 < neu_dith_colrs(bs, cs, n)       /* convert scanline to dithered index values */
181 < register BYTE   *bs;
182 < register COLR   *cs;
183 < int     n;
180 > extern void
181 > neu_dith_colrs( /* convert scanline to dithered index values */
182 >        register BYTE   *bs,
183 >        register COLR   *cs,
184 >        int     n
185 > )
186   {
187          static short    (*cerr)[3] = NULL;
188          static int      N = 0;
# Line 172 | Line 191 | int    n;
191  
192          if (n != N) {           /* get error propogation array */
193                  if (N) {
194 <                        free((char *)cerr);
194 >                        free((void *)cerr);
195                          cerr = NULL;
196                  }
197                  if (n)
# Line 183 | Line 202 | int    n;
202                          return;
203                  }
204                  N = n;
205 <                bzero((char *)cerr, 3*N*sizeof(short));
205 >                memset((char *)cerr, '\0', 3*N*sizeof(short));
206          }
207          err[0] = err[1] = err[2] = 0;
208          for (x = 0; x < n; x++) {
# Line 208 | Line 227 | int    n;
227   }
228  
229   /* The following was adapted and modified from the original (GW)        */
211 /*----------------------------------------------------------------------*/
212 /*                                                                      */
213 /*                              NeuQuant                                */
214 /*                              --------                                */
215 /*                                                                      */
216 /*              Copyright: Anthony Dekker, June 1994                    */
217 /*                                                                      */
218 /* This program performs colour quantization of graphics images (SUN    */
219 /* raster files).  It uses a Kohonen Neural Network.  It produces       */
220 /* better results than existing methods and runs faster, using minimal  */
221 /* space (8kB plus the image itself).  The algorithm is described in    */
222 /* the paper "Kohonen Neural Networks for Optimal Colour Quantization"  */
223 /* to appear in the journal "Network: Computation in Neural Systems".   */
224 /* It is a significant improvement of an earlier algorithm.             */
225 /*                                                                      */
226 /* This program is distributed free for academic use or for evaluation  */
227 /* by commercial organizations.                                         */
228 /*                                                                      */
229 /*      Usage:  NeuQuant -n inputfile > outputfile                      */
230 /*                                                                      */
231 /* where n is a sampling factor for neural learning.                    */
232 /*                                                                      */
233 /* Program performance compared with other methods is as follows:       */
234 /*                                                                      */
235 /*      Algorithm               |  Av. CPU Time |  Quantization Error   */
236 /*      -------------------------------------------------------------   */
237 /*      NeuQuant -3             |  314          |  5.55                 */
238 /*      NeuQuant -10            |  119          |  5.97                 */
239 /*      NeuQuant -30            |  65           |  6.53                 */
240 /*      Oct-Trees               |  141          |  8.96                 */
241 /*      Median Cut (XV -best)   |  420          |  9.28                 */
242 /*      Median Cut (XV -slow)   |  72           |  12.15                */
243 /*                                                                      */
244 /* Author's address:    Dept of ISCS, National University of Singapore  */
245 /*                      Kent Ridge, Singapore 0511                      */
246 /* Email:       [email protected]                                     */
247 /*----------------------------------------------------------------------*/
230  
231 < #define bool    int
232 < #define false   0
233 < #define true    1
231 > /* cheater definitions (GW) */
232 > #define thepicture      thesamples
233 > #define lengthcount     (nsamples*3)
234 > #define samplefac       1
235  
236 < #define initrad                 32
237 < #define radiusdec               30
238 < #define alphadec                30
236 > /* NeuQuant Neural-Net Quantization Algorithm Interface
237 > * ----------------------------------------------------
238 > *
239 > * Copyright (c) 1994 Anthony Dekker
240 > *
241 > * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
242 > * See "Kohonen neural networks for optimal colour quantization"
243 > * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
244 > * for a discussion of the algorithm.
245 > * See also  http://members.ozemail.com.au/~dekker/NEUQUANT.HTML
246 > *
247 > * Any party obtaining a copy of these files from the author, directly or
248 > * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
249 > * world-wide, paid up, royalty-free, nonexclusive right and license to deal
250 > * in this software and documentation files (the "Software"), including without
251 > * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
252 > * and/or sell copies of the Software, and to permit persons who receive
253 > * copies from any such party to do so, with the only requirement being
254 > * that this copyright notice remain intact.
255 > */
256  
257 + #define bool            int
258 + #define false           0
259 + #define true            1
260 +
261 + /* network defs */
262 + #define netsize         clrtabsiz               /* number of colours - can change this */
263 + #define maxnetpos       (netsize-1)
264 + #define netbiasshift    4                       /* bias for colour values */
265 + #define ncycles         100                     /* no. of learning cycles */
266 +
267   /* defs for freq and bias */
268 < #define gammashift      10
269 < #define betashift       gammashift
270 < #define intbiasshift    16
271 < #define intbias         (1<<intbiasshift)
272 < #define gamma           (1<<gammashift)
273 < #define beta            (intbias>>betashift)
268 > #define intbiasshift    16                      /* bias for fractions */
269 > #define intbias         (((int) 1)<<intbiasshift)
270 > #define gammashift      10                      /* gamma = 1024 */
271 > #define gamma           (((int) 1)<<gammashift)
272 > #define betashift       10
273 > #define beta            (intbias>>betashift)    /* beta = 1/1024 */
274   #define betagamma       (intbias<<(gammashift-betashift))
265 #define gammaphi        (intbias<<(gammashift-8))
275  
276 < /* defs for rad and alpha */
277 < #define maxrad          (initrad+1)
278 < #define radiusbiasshift 6
279 < #define radiusbias      (1<<radiusbiasshift)
280 < #define initradius      ((int) (initrad*radiusbias))
281 < #define alphabiasshift  10
282 < #define initalpha       (1<<alphabiasshift)
276 > /* defs for decreasing radius factor */
277 > #define initrad         (256>>3)                /* for 256 cols, radius starts */
278 > #define radiusbiasshift 6                       /* at 32.0 biased by 6 bits */
279 > #define radiusbias      (((int) 1)<<radiusbiasshift)
280 > #define initradius      (initrad*radiusbias)    /* and decreases by a */
281 > #define radiusdec       30                      /* factor of 1/30 each cycle */
282 >
283 > /* defs for decreasing alpha factor */
284 > #define alphabiasshift  10                      /* alpha starts at 1.0 */
285 > #define initalpha       (((int) 1)<<alphabiasshift)
286 > int alphadec;                                   /* biased by 10 bits */
287 >
288 > /* radbias and alpharadbias used for radpower calculation */
289   #define radbiasshift    8
290 < #define radbias         (1<<radbiasshift)
290 > #define radbias         (((int) 1)<<radbiasshift)
291   #define alpharadbshift  (alphabiasshift+radbiasshift)
292 < #define alpharadbias    (1<<alpharadbshift)
292 > #define alpharadbias    (((int) 1)<<alpharadbshift)
293  
294 < /* other defs */
295 < #define netbiasshift    4
296 < #define funnyshift      (intbiasshift-netbiasshift)
297 < #define maxnetval       ((256<<netbiasshift)-1)
298 < #define ncycles         100
299 < #define jump1           499     /* prime */
285 < #define jump2           491     /* prime */
286 < #define jump3           487     /* any pic whose size was divisible by all */
287 < #define jump4           503     /* four primes would be simply enormous */
294 > /* four primes near 500 - assume no image has a length so large */
295 > /* that it is divisible by all four primes */
296 > #define prime1          499
297 > #define prime2          491
298 > #define prime3          487
299 > #define prime4          503
300  
289 /* cheater definitions (GW) */
290 #define thepicture      thesamples
291 #define lengthcount     (nsamples*3)
292 #define samplefac       1
293
301   typedef int pixel[4];  /* BGRc */
302 + pixel network[256];
303  
304 < static pixel network[256];
304 > int netindex[256];      /* for network lookup - really 256 */
305  
306 < static int netindex[256];
306 > int bias [256];         /* bias and freq arrays for learning */
307 > int freq [256];
308 > int radpower[initrad];  /* radpower for precomputation */
309  
300 static int bias [256];
301 static int freq [256];
302 static int radpower[256];       /* actually need only go up to maxrad */
310  
311 < /* fixed space overhead 256*4+256+256+256+256 words = 256*8 = 8kB */
311 > /* initialise network in range (0,0,0) to (255,255,255) */
312  
313 <
314 < static
308 < initnet()
313 > static void
314 > initnet(void)  
315   {
316          register int i;
317          register int *p;
318          
319 <        for (i=0; i<clrtabsiz; i++) {
319 >        for (i=0; i<netsize; i++) {
320                  p = network[i];
321 <                p[0] =
322 <                p[1] =
317 <                p[2] = (i<<(netbiasshift+8))/clrtabsiz;
318 <                freq[i] = intbias/clrtabsiz;  /* 1/256 */
321 >                p[0] = p[1] = p[2] = (i << (netbiasshift+8))/netsize;
322 >                freq[i] = intbias/netsize;  /* 1/netsize */
323                  bias[i] = 0;
324          }
325   }
326  
327  
328 < static
329 < inxbuild()
328 > /* do after unbias - insertion sort of network and build netindex[0..255] */
329 >
330 > static void
331 > inxbuild(void)
332   {
333          register int i,j,smallpos,smallval;
334          register int *p,*q;
335 <        int start,previous;
335 >        int previouscol,startpos;
336  
337 <        previous = 0;
338 <        start = 0;
339 <        for (i=0; i<clrtabsiz; i++) {
337 >        previouscol = 0;
338 >        startpos = 0;
339 >        for (i=0; i<netsize; i++) {
340                  p = network[i];
341                  smallpos = i;
342                  smallval = p[1];        /* index on g */
343 <                /* find smallest in i+1..clrtabsiz-1 */
344 <                for (j=i+1; j<clrtabsiz; j++) {
343 >                /* find smallest in i..netsize-1 */
344 >                for (j=i+1; j<netsize; j++) {
345                          q = network[j];
346                          if (q[1] < smallval) {  /* index on g */
347                                  smallpos = j;
# Line 343 | Line 349 | inxbuild()
349                          }
350                  }
351                  q = network[smallpos];
352 +                /* swap p (i) and q (smallpos) entries */
353                  if (i != smallpos) {
354                          j = q[0];   q[0] = p[0];   p[0] = j;
355                          j = q[1];   q[1] = p[1];   p[1] = j;
# Line 350 | Line 357 | inxbuild()
357                          j = q[3];   q[3] = p[3];   p[3] = j;
358                  }
359                  /* smallval entry is now in position i */
360 <                if (smallval != previous) {
361 <                        netindex[previous] = (start+i)>>1;
362 <                        for (j=previous+1; j<smallval; j++) netindex[j] = i;
363 <                        previous = smallval;
364 <                        start = i;
360 >                if (smallval != previouscol) {
361 >                        netindex[previouscol] = (startpos+i)>>1;
362 >                        for (j=previouscol+1; j<smallval; j++) netindex[j] = i;
363 >                        previouscol = smallval;
364 >                        startpos = i;
365                  }
366          }
367 <        netindex[previous] = (start+255)>>1;
368 <        for (j=previous+1; j<256; j++) netindex[j] = 255;
367 >        netindex[previouscol] = (startpos+maxnetpos)>>1;
368 >        for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; /* really 256 */
369   }
370  
371  
372   static int
373 < inxsearch(b,g,r)  /* accepts real BGR values after net is unbiased */
374 < register int b,g,r;
373 > inxsearch(  /* accepts real BGR values after net is unbiased */
374 >        register int b,
375 >        register int g,
376 >        register int r
377 > )
378   {
379 <        register int i,j,best,x,y,bestd;
379 >        register int i,j,dist,a,bestd;
380          register int *p;
381 +        int best;
382  
383          bestd = 1000;   /* biggest possible dist is 256*3 */
384          best = -1;
385          i = netindex[g]; /* index on g */
386 <        j = i-1;
386 >        j = i-1;         /* start at netindex[g] and work outwards */
387  
388 <        while ((i<clrtabsiz) || (j>=0)) {
389 <                if (i<clrtabsiz) {
388 >        while ((i<netsize) || (j>=0)) {
389 >                if (i<netsize) {
390                          p = network[i];
391 <                        x = p[1] - g;   /* inx key */
392 <                        if (x >= bestd) i = clrtabsiz; /* stop iter */
391 >                        dist = p[1] - g;        /* inx key */
392 >                        if (dist >= bestd) i = netsize; /* stop iter */
393                          else {
394                                  i++;
395 <                                if (x<0) x = -x;
396 <                                y = p[0] - b;
397 <                                if (y<0) y = -y;
398 <                                x += y;
399 <                                if (x<bestd) {
400 <                                        y = p[2] - r;  
401 <                                        if (y<0) y = -y;
391 <                                        x += y; /* x holds distance */
392 <                                        if (x<bestd) {bestd=x; best=p[3];}
395 >                                if (dist<0) dist = -dist;
396 >                                a = p[0] - b;   if (a<0) a = -a;
397 >                                dist += a;
398 >                                if (dist<bestd) {
399 >                                        a = p[2] - r;   if (a<0) a = -a;
400 >                                        dist += a;
401 >                                        if (dist<bestd) {bestd=dist; best=p[3];}
402                                  }
403                          }
404                  }
405                  if (j>=0) {
406                          p = network[j];
407 <                        x = g - p[1]; /* inx key - reverse dif */
408 <                        if (x >= bestd) j = -1; /* stop iter */
407 >                        dist = g - p[1]; /* inx key - reverse dif */
408 >                        if (dist >= bestd) j = -1; /* stop iter */
409                          else {
410                                  j--;
411 <                                if (x<0) x = -x;
412 <                                y = p[0] - b;
413 <                                if (y<0) y = -y;
414 <                                x += y;
415 <                                if (x<bestd) {
416 <                                        y = p[2] - r;  
417 <                                        if (y<0) y = -y;
409 <                                        x += y; /* x holds distance */
410 <                                        if (x<bestd) {bestd=x; best=p[3];}
411 >                                if (dist<0) dist = -dist;
412 >                                a = p[0] - b;   if (a<0) a = -a;
413 >                                dist += a;
414 >                                if (dist<bestd) {
415 >                                        a = p[2] - r;   if (a<0) a = -a;
416 >                                        dist += a;
417 >                                        if (dist<bestd) {bestd=dist; best=p[3];}
418                                  }
419                          }
420                  }
# Line 416 | Line 423 | register int b,g,r;
423   }
424  
425  
426 + /* finds closest neuron (min dist) and updates freq */
427 + /* finds best neuron (min dist-bias) and returns position */
428 + /* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
429 + /* bias[i] = gamma*((1/netsize)-freq[i]) */
430 +
431   static int
432 < contest(b,g,r)  /* accepts biased BGR values */
433 < register int b,g,r;
432 > contest(        /* accepts biased BGR values */
433 >        register int b,
434 >        register int g,
435 >        register int r
436 > )
437   {
438 <        register int i,best,bestbias,x,y,bestd,bestbiasd;
439 <        register int *p,*q, *pp;
438 >        register int i,dist,a,biasdist,betafreq;
439 >        int bestpos,bestbiaspos,bestd,bestbiasd;
440 >        register int *p,*f, *n;
441  
442 <        bestd = ~(1<<31);
442 >        bestd = ~(((int) 1)<<31);
443          bestbiasd = bestd;
444 <        best = -1;
445 <        bestbias = best;
446 <        q = bias;
447 <        p = freq;
448 <        for (i=0; i<clrtabsiz; i++) {
449 <                pp = network[i];
450 <                x = pp[0] - b;
451 <                if (x<0) x = -x;
452 <                y = pp[1] - g;
453 <                if (y<0) y = -y;
454 <                x += y;
455 <                y = pp[2] - r;  
456 <                if (y<0) y = -y;
457 <                x += y; /* x holds distance */
458 <                        /* >> netbiasshift not needed if funnyshift used */
459 <                if (x<bestd) {bestd=x; best=i;}
460 <                y = x - ((*q)>>funnyshift);  /* y holds biasd */
461 <                if (y<bestbiasd) {bestbiasd=y; bestbias=i;}
446 <                y = (*p >> betashift);       /* y holds beta*freq */
447 <                *p -= y;
448 <                *q += (y<<gammashift);
449 <                p++;
450 <                q++;
444 >        bestpos = -1;
445 >        bestbiaspos = bestpos;
446 >        p = bias;
447 >        f = freq;
448 >
449 >        for (i=0; i<netsize; i++) {
450 >                n = network[i];
451 >                dist = n[0] - b;   if (dist<0) dist = -dist;
452 >                a = n[1] - g;   if (a<0) a = -a;
453 >                dist += a;
454 >                a = n[2] - r;   if (a<0) a = -a;
455 >                dist += a;
456 >                if (dist<bestd) {bestd=dist; bestpos=i;}
457 >                biasdist = dist - ((*p)>>(intbiasshift-netbiasshift));
458 >                if (biasdist<bestbiasd) {bestbiasd=biasdist; bestbiaspos=i;}
459 >                betafreq = (*f >> betashift);
460 >                *f++ -= betafreq;
461 >                *p++ += (betafreq<<gammashift);
462          }
463 <        freq[best] += beta;
464 <        bias[best] -= betagamma;
465 <        return(bestbias);
463 >        freq[bestpos] += beta;
464 >        bias[bestpos] -= betagamma;
465 >        return(bestbiaspos);
466   }
467  
468  
469 < static
470 < alterneigh(rad,i,b,g,r) /* accepts biased BGR values */
471 < int rad,i;
472 < register int b,g,r;
469 > /* move neuron i towards (b,g,r) by factor alpha */
470 >
471 > static void
472 > altersingle(    /* accepts biased BGR values */
473 >        register int alpha,
474 >        register int i,
475 >        register int b,
476 >        register int g,
477 >        register int r
478 > )
479   {
480 +        register int *n;
481 +
482 +        n = network[i];         /* alter hit neuron */
483 +        *n -= (alpha*(*n - b)) / initalpha;
484 +        n++;
485 +        *n -= (alpha*(*n - g)) / initalpha;
486 +        n++;
487 +        *n -= (alpha*(*n - r)) / initalpha;
488 + }
489 +
490 +
491 + /* move neurons adjacent to i towards (b,g,r) by factor */
492 + /* alpha*(1-((i-j)^2/[r]^2)) precomputed as radpower[|i-j|]*/
493 +
494 + static void
495 + alterneigh(     /* accents biased BGR values */
496 +        int rad,
497 +        int i,
498 +        register int b,
499 +        register int g,
500 +        register int r
501 + )
502 + {
503          register int j,k,lo,hi,a;
504          register int *p, *q;
505  
506 <        lo = i-rad;
507 <        if (lo<-1) lo= -1;
468 <        hi = i+rad;
469 <        if (hi>clrtabsiz) hi=clrtabsiz;
506 >        lo = i-rad;   if (lo<-1) lo= -1;
507 >        hi = i+rad;   if (hi>netsize) hi=netsize;
508  
509          j = i+1;
510          k = i-1;
# Line 495 | Line 533 | register int b,g,r;
533   }
534  
535  
536 < static
537 < altersingle(alpha,j,b,g,r)      /* accepts biased BGR values */
500 < register int alpha,j,b,g,r;
536 > static void
537 > learn(void)
538   {
502        register int *q;
503
504        q = network[j];         /* alter hit neuron */
505        *q -= (alpha*(*q - b)) / initalpha;
506        q++;
507        *q -= (alpha*(*q - g)) / initalpha;
508        q++;
509        *q -= (alpha*(*q - r)) / initalpha;
510 }
511
512
513 static
514 learn()
515 {
539          register int i,j,b,g,r;
540 <        int radius,rad,alpha,step,delta,upto;
540 >        int radius,rad,alpha,step,delta,samplepixels;
541          register unsigned char *p;
542          unsigned char *lim;
543  
544 <        upto = lengthcount/(3*samplefac);
522 <        delta = upto/ncycles;
523 <        lim = thepicture + lengthcount;
544 >        alphadec = 30 + ((samplefac-1)/3);
545          p = thepicture;
546 +        lim = thepicture + lengthcount;
547 +        samplepixels = lengthcount/(3*samplefac);
548 +        delta = samplepixels/ncycles;
549          alpha = initalpha;
550          radius = initradius;
551 +        
552          rad = radius >> radiusbiasshift;
553          if (rad <= 1) rad = 0;
554          for (i=0; i<rad; i++)
555                  radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
556 <
557 <        if ((lengthcount%jump1) != 0) step = 3*jump1;
556 >        
557 >        if ((lengthcount%prime1) != 0) step = 3*prime1;
558          else {
559 <                if ((lengthcount%jump2) !=0) step = 3*jump2;
559 >                if ((lengthcount%prime2) !=0) step = 3*prime2;
560                  else {
561 <                        if ((lengthcount%jump3) !=0) step = 3*jump3;
562 <                        else step = 3*jump4;
561 >                        if ((lengthcount%prime3) !=0) step = 3*prime3;
562 >                        else step = 3*prime4;
563                  }
564          }
565 +        
566          i = 0;
567 <        while (i < upto) {
567 >        while (i < samplepixels) {
568                  b = p[0] << netbiasshift;
569                  g = p[1] << netbiasshift;
570                  r = p[2] << netbiasshift;
571                  j = contest(b,g,r);
572  
573                  altersingle(alpha,j,b,g,r);
574 <                if (rad) alterneigh(rad,j,b,g,r);
549 <                                                /* alter neighbours */
574 >                if (rad) alterneigh(rad,j,b,g,r);   /* alter neighbours */
575  
576                  p += step;
577                  if (p >= lim) p -= lengthcount;
# Line 563 | Line 588 | learn()
588          }
589   }
590          
591 < static
592 < unbiasnet()
591 > /* unbias network to give 0..255 entries */
592 > /* which can then be used for colour map */
593 > /* and record position i to prepare for sort */
594 >
595 > static void
596 > unbiasnet(void)
597   {
598          int i,j;
599  
600 <        for (i=0; i<clrtabsiz; i++) {
600 >        for (i=0; i<netsize; i++) {
601                  for (j=0; j<3; j++)
602                          network[i][j] >>= netbiasshift;
603                  network[i][3] = i; /* record colour no */
604          }
605   }
606  
607 < /* Don't do this until the network has been unbiased */
607 >
608 > /* Don't do this until the network has been unbiased (GW) */
609                  
610 < static
611 < cpyclrtab()
610 > static void
611 > cpyclrtab(void)
612   {
613          register int i,j,k;
614          
615 <        for (j=0; j<clrtabsiz; j++) {
615 >        for (j=0; j<netsize; j++) {
616                  k = network[j][3];
617                  for (i = 0; i < 3; i++)
618                          clrtab[k][i] = network[j][2-i];

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines