Back to index

radiance  4R0+20100331
Defines | Typedefs | Functions | Variables
neuclrtab.c File Reference
#include "copyright.h"
#include <string.h>
#include "standard.h"
#include "color.h"
#include "random.h"
#include "clrtab.h"

Go to the source code of this file.

Defines

#define DEFSMPFAC   3
#define MAXSKIP   (1<<24-1)
#define nskip(sp)   ((long)(sp)[0]<<16|(long)(sp)[1]<<8|(long)(sp)[2])
#define setskip(sp, n)   ((sp)[0]=(n)>>16,(sp)[1]=((n)>>8)&255,(sp)[2]=(n)&255)
#define thepicture   thesamples
#define lengthcount   (nsamples*3)
#define samplefac   1
#define bool   int
#define false   0
#define true   1
#define netsize   clrtabsiz /* number of colours - can change this */
#define maxnetpos   (netsize-1)
#define netbiasshift   4 /* bias for colour values */
#define ncycles   100 /* no. of learning cycles */
#define intbiasshift   16 /* bias for fractions */
#define intbias   (((int) 1)<<intbiasshift)
#define gammashift   10 /* gamma = 1024 */
#define gamma   (((int) 1)<<gammashift)
#define betashift   10
#define beta   (intbias>>betashift) /* beta = 1/1024 */
#define betagamma   (intbias<<(gammashift-betashift))
#define initrad   (256>>3) /* for 256 cols, radius starts */
#define radiusbiasshift   6 /* at 32.0 biased by 6 bits */
#define radiusbias   (((int) 1)<<radiusbiasshift)
#define initradius   (initrad*radiusbias) /* and decreases by a */
#define radiusdec   30 /* factor of 1/30 each cycle */
#define alphabiasshift   10 /* alpha starts at 1.0 */
#define initalpha   (((int) 1)<<alphabiasshift)
#define radbiasshift   8
#define radbias   (((int) 1)<<radbiasshift)
#define alpharadbshift   (alphabiasshift+radbiasshift)
#define alpharadbias   (((int) 1)<<alpharadbshift)
#define prime1   499
#define prime2   491
#define prime3   487
#define prime4   503

Typedefs

typedef int pixel [4]

Functions

static void initnet (void)
static void inxbuild (void)
static int inxsearch (int b, int g, int r)
static int contest (int b, int g, int r)
static void altersingle (int alpha, int i, int b, int g, int r)
static void alterneigh (int rad, int i, int b, int g, int r)
static void learn (void)
static void unbiasnet (void)
static void cpyclrtab (void)
int neu_init (long npixels)
void neu_pixel (register BYTE col[])
void neu_colrs (register COLR *cs, register int n)
int neu_clrtab (int ncolors)
int neu_map_pixel (register BYTE col[])
void neu_map_colrs (register BYTE *bs, register COLR *cs, register int n)
void neu_dith_colrs (register BYTE *bs, register COLR *cs, int n)
static int inxsearch (register int b, register int g, register int r)
static int contest (register int b, register int g, register int r)
static void altersingle (register int alpha, register int i, register int b, register int g, register int r)
static void alterneigh (int rad, int i, register int b, register int g, register int r)

Variables

static const char RCSid [] = "$Id: neuclrtab.c,v 2.13 2007/09/08 19:17:52 greg Exp $"
BYTE clrtab [256][3]
static int clrtabsiz
int samplefac = DEFSMPFAC
static BYTEthesamples
static int nsamples
static BYTEcursamp
static long skipcount
int alphadec
pixel network [256]
int netindex [256]
int bias [256]
int freq [256]
int radpower [initrad]

Define Documentation

#define alphabiasshift   10 /* alpha starts at 1.0 */

Definition at line 284 of file neuclrtab.c.

#define alpharadbias   (((int) 1)<<alpharadbshift)

Definition at line 292 of file neuclrtab.c.

Definition at line 291 of file neuclrtab.c.

#define beta   (intbias>>betashift) /* beta = 1/1024 */

Definition at line 273 of file neuclrtab.c.

Definition at line 274 of file neuclrtab.c.

#define betashift   10

Definition at line 272 of file neuclrtab.c.

#define bool   int

Definition at line 257 of file neuclrtab.c.

#define DEFSMPFAC   3

Definition at line 31 of file neuclrtab.c.

#define false   0

Definition at line 258 of file neuclrtab.c.

#define gamma   (((int) 1)<<gammashift)

Definition at line 271 of file neuclrtab.c.

#define gammashift   10 /* gamma = 1024 */

Definition at line 270 of file neuclrtab.c.

#define initalpha   (((int) 1)<<alphabiasshift)

Definition at line 285 of file neuclrtab.c.

#define initrad   (256>>3) /* for 256 cols, radius starts */

Definition at line 277 of file neuclrtab.c.

#define initradius   (initrad*radiusbias) /* and decreases by a */

Definition at line 280 of file neuclrtab.c.

#define intbias   (((int) 1)<<intbiasshift)

Definition at line 269 of file neuclrtab.c.

#define intbiasshift   16 /* bias for fractions */

Definition at line 268 of file neuclrtab.c.

#define lengthcount   (nsamples*3)

Definition at line 233 of file neuclrtab.c.

#define maxnetpos   (netsize-1)

Definition at line 263 of file neuclrtab.c.

#define MAXSKIP   (1<<24-1)

Definition at line 44 of file neuclrtab.c.

#define ncycles   100 /* no. of learning cycles */

Definition at line 265 of file neuclrtab.c.

#define netbiasshift   4 /* bias for colour values */

Definition at line 264 of file neuclrtab.c.

#define netsize   clrtabsiz /* number of colours - can change this */

Definition at line 262 of file neuclrtab.c.

#define nskip (   sp)    ((long)(sp)[0]<<16|(long)(sp)[1]<<8|(long)(sp)[2])

Definition at line 46 of file neuclrtab.c.

#define prime1   499

Definition at line 296 of file neuclrtab.c.

#define prime2   491

Definition at line 297 of file neuclrtab.c.

#define prime3   487

Definition at line 298 of file neuclrtab.c.

#define prime4   503

Definition at line 299 of file neuclrtab.c.

#define radbias   (((int) 1)<<radbiasshift)

Definition at line 290 of file neuclrtab.c.

#define radbiasshift   8

Definition at line 289 of file neuclrtab.c.

#define radiusbias   (((int) 1)<<radiusbiasshift)

Definition at line 279 of file neuclrtab.c.

#define radiusbiasshift   6 /* at 32.0 biased by 6 bits */

Definition at line 278 of file neuclrtab.c.

#define radiusdec   30 /* factor of 1/30 each cycle */

Definition at line 281 of file neuclrtab.c.

#define samplefac   1

Definition at line 234 of file neuclrtab.c.

#define setskip (   sp,
  n 
)    ((sp)[0]=(n)>>16,(sp)[1]=((n)>>8)&255,(sp)[2]=(n)&255)

Definition at line 48 of file neuclrtab.c.

#define thepicture   thesamples

Definition at line 232 of file neuclrtab.c.

#define true   1

Definition at line 259 of file neuclrtab.c.


Typedef Documentation

typedef int pixel[4]

Definition at line 301 of file neuclrtab.c.


Function Documentation

static void alterneigh ( int  rad,
int  i,
int  b,
int  g,
int  r 
) [static]

Here is the caller graph for this function:

static void alterneigh ( int  rad,
int  i,
register int  b,
register int  g,
register int  r 
) [static]

Definition at line 495 of file neuclrtab.c.

{
       register int j,k,lo,hi,a;
       register int *p, *q;

       lo = i-rad;   if (lo<-1) lo= -1;
       hi = i+rad;   if (hi>netsize) hi=netsize;

       j = i+1;
       k = i-1;
       q = radpower;
       while ((j<hi) || (k>lo)) {
              a = (*(++q));
              if (j<hi) {
                     p = network[j];
                     *p -= (a*(*p - b)) / alpharadbias;
                     p++;
                     *p -= (a*(*p - g)) / alpharadbias;
                     p++;
                     *p -= (a*(*p - r)) / alpharadbias;
                     j++;
              }
              if (k>lo) {
                     p = network[k];
                     *p -= (a*(*p - b)) / alpharadbias;
                     p++;
                     *p -= (a*(*p - g)) / alpharadbias;
                     p++;
                     *p -= (a*(*p - r)) / alpharadbias;
                     k--;
              }
       }
}
static void altersingle ( int  alpha,
int  i,
int  b,
int  g,
int  r 
) [static]

Here is the caller graph for this function:

static void altersingle ( register int  alpha,
register int  i,
register int  b,
register int  g,
register int  r 
) [static]

Definition at line 472 of file neuclrtab.c.

{
       register int *n;

       n = network[i];             /* alter hit neuron */
       *n -= (alpha*(*n - b)) / initalpha;
       n++;
       *n -= (alpha*(*n - g)) / initalpha;
       n++;
       *n -= (alpha*(*n - r)) / initalpha;
}
static int contest ( int  b,
int  g,
int  r 
) [static]

Here is the caller graph for this function:

static int contest ( register int  b,
register int  g,
register int  r 
) [static]

Definition at line 432 of file neuclrtab.c.

{
       register int i,dist,a,biasdist,betafreq;
       int bestpos,bestbiaspos,bestd,bestbiasd;
       register int *p,*f, *n;

       bestd = ~(((int) 1)<<31);
       bestbiasd = bestd;
       bestpos = -1;
       bestbiaspos = bestpos;
       p = bias;
       f = freq;

       for (i=0; i<netsize; i++) {
              n = network[i];
              dist = n[0] - b;   if (dist<0) dist = -dist;
              a = n[1] - g;   if (a<0) a = -a;
              dist += a;
              a = n[2] - r;   if (a<0) a = -a;
              dist += a;
              if (dist<bestd) {bestd=dist; bestpos=i;}
              biasdist = dist - ((*p)>>(intbiasshift-netbiasshift));
              if (biasdist<bestbiasd) {bestbiasd=biasdist; bestbiaspos=i;}
              betafreq = (*f >> betashift);
              *f++ -= betafreq;
              *p++ += (betafreq<<gammashift);
       }
       freq[bestpos] += beta;
       bias[bestpos] -= betagamma;
       return(bestbiaspos);
}

Here is the call graph for this function:

static void cpyclrtab ( void  ) [static]

Definition at line 611 of file neuclrtab.c.

{
       register int i,j,k;
       
       for (j=0; j<netsize; j++) {
              k = network[j][3];
              for (i = 0; i < 3; i++)
                     clrtab[k][i] = network[j][2-i];
       }
}

Here is the caller graph for this function:

static void initnet ( void  ) [static]

Definition at line 314 of file neuclrtab.c.

{
       register int i;
       register int *p;
       
       for (i=0; i<netsize; i++) {
              p = network[i];
              p[0] = p[1] = p[2] = (i << (netbiasshift+8))/netsize;
              freq[i] = intbias/netsize;  /* 1/netsize */
              bias[i] = 0;
       }
}

Here is the caller graph for this function:

static void inxbuild ( void  ) [static]

Definition at line 331 of file neuclrtab.c.

{
       register int i,j,smallpos,smallval;
       register int *p,*q;
       int previouscol,startpos;

       previouscol = 0;
       startpos = 0;
       for (i=0; i<netsize; i++) {
              p = network[i];
              smallpos = i;
              smallval = p[1];     /* index on g */
              /* find smallest in i..netsize-1 */
              for (j=i+1; j<netsize; j++) {
                     q = network[j];
                     if (q[1] < smallval) {      /* index on g */
                            smallpos = j;
                            smallval = q[1]; /* index on g */
                     }
              }
              q = network[smallpos];
              /* swap p (i) and q (smallpos) entries */
              if (i != smallpos) {
                     j = q[0];   q[0] = p[0];   p[0] = j;
                     j = q[1];   q[1] = p[1];   p[1] = j;
                     j = q[2];   q[2] = p[2];   p[2] = j;
                     j = q[3];   q[3] = p[3];   p[3] = j;
              }
              /* smallval entry is now in position i */
              if (smallval != previouscol) {
                     netindex[previouscol] = (startpos+i)>>1;
                     for (j=previouscol+1; j<smallval; j++) netindex[j] = i;
                     previouscol = smallval;
                     startpos = i;
              }
       }
       netindex[previouscol] = (startpos+maxnetpos)>>1;
       for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; /* really 256 */
}

Here is the caller graph for this function:

static int inxsearch ( int  b,
int  g,
int  r 
) [static]

Here is the caller graph for this function:

static int inxsearch ( register int  b,
register int  g,
register int  r 
) [static]

Definition at line 373 of file neuclrtab.c.

{
       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<netsize) || (j>=0)) {
              if (i<netsize) {
                     p = network[i];
                     dist = p[1] - g;     /* inx key */
                     if (dist >= bestd) i = netsize; /* stop iter */
                     else {
                            i++;
                            if (dist<0) dist = -dist;
                            a = p[0] - b;   if (a<0) a = -a;
                            dist += a;
                            if (dist<bestd) {
                                   a = p[2] - r;   if (a<0) a = -a;
                                   dist += a;
                                   if (dist<bestd) {bestd=dist; best=p[3];}
                            }
                     }
              }
              if (j>=0) {
                     p = network[j];
                     dist = g - p[1]; /* inx key - reverse dif */
                     if (dist >= bestd) j = -1; /* stop iter */
                     else {
                            j--;
                            if (dist<0) dist = -dist;
                            a = p[0] - b;   if (a<0) a = -a;
                            dist += a;
                            if (dist<bestd) {
                                   a = p[2] - r;   if (a<0) a = -a;
                                   dist += a;
                                   if (dist<bestd) {bestd=dist; best=p[3];}
                            }
                     }
              }
       }
       return(best);
}

Here is the call graph for this function:

static void learn ( void  ) [static]

Definition at line 537 of file neuclrtab.c.

{
       register int i,j,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;
       alpha = initalpha;
       radius = initradius;
       
       rad = radius >> radiusbiasshift;
       if (rad <= 1) rad = 0;
       for (i=0; i<rad; i++) 
              radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
       
       if ((lengthcount%prime1) != 0) step = 3*prime1;
       else {
              if ((lengthcount%prime2) !=0) step = 3*prime2;
              else {
                     if ((lengthcount%prime3) !=0) step = 3*prime3;
                     else step = 3*prime4;
              }
       }
       
       i = 0;
       while (i < samplepixels) {
              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 == 0) {  
                     alpha -= alpha / alphadec;
                     radius -= radius / radiusdec;
                     rad = radius >> radiusbiasshift;
                     if (rad <= 1) rad = 0;
                     for (j=0; j<rad; j++) 
                            radpower[j] = alpha*(((rad*rad - j*j)*radbias)/(rad*rad));
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int neu_clrtab ( int  ncolors)

Definition at line 137 of file neuclrtab.c.

{
       clrtabsiz = ncolors;
       if (clrtabsiz > 256) clrtabsiz = 256;
       initnet();
       learn();
       unbiasnet();
       cpyclrtab();
       inxbuild();
                            /* we're done with our samples */
       free((void *)thesamples);
                            /* reset dithering function */
       neu_dith_colrs((BYTE *)NULL, (COLR *)NULL, 0);
                            /* return new color table size */
       return(clrtabsiz);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void neu_colrs ( register COLR cs,
register int  n 
)

Definition at line 117 of file neuclrtab.c.

{
       while (n > skipcount) {
              cs += skipcount;
              n -= skipcount+1;
              skipcount = nskip(cursamp);
              cursamp[0] = cs[0][BLU];
              cursamp[1] = cs[0][GRN];
              cursamp[2] = cs[0][RED];
              cs++;
              cursamp += 3;
       }
       skipcount -= n;
}
void neu_dith_colrs ( register BYTE bs,
register COLR cs,
int  n 
)

Definition at line 181 of file neuclrtab.c.

{
       static short  (*cerr)[3] = NULL;
       static int    N = 0;
       int    err[3], errp[3];
       register int  x, i;

       if (n != N) {        /* get error propogation array */
              if (N) {
                     free((void *)cerr);
                     cerr = NULL;
              }
              if (n)
                     cerr = (short (*)[3])malloc(3*n*sizeof(short));
              if (cerr == NULL) {
                     N = 0;
                     map_colrs(bs, cs, n);
                     return;
              }
              N = n;
              memset((char *)cerr, '\0', 3*N*sizeof(short));
       }
       err[0] = err[1] = err[2] = 0;
       for (x = 0; x < n; x++) {
              for (i = 0; i < 3; i++) {   /* dither value */
                     errp[i] = err[i];
                     err[i] += cerr[x][i];
#ifdef MAXERR
                     if (err[i] > MAXERR) err[i] = MAXERR;
                     else if (err[i] < -MAXERR) err[i] = -MAXERR;
#endif
                     err[i] += cs[x][i];
                     if (err[i] < 0) err[i] = 0;
                     else if (err[i] > 255) err[i] = 255;
              }
              bs[x] = inxsearch(err[BLU],err[GRN],err[RED]);
              for (i = 0; i < 3; i++) {   /* propagate error */
                     err[i] -= clrtab[bs[x]][i];
                     err[i] /= 3;
                     cerr[x][i] = err[i] + errp[i];
              }
       }
}

Here is the call graph for this function:

int neu_init ( long  npixels)

Definition at line 62 of file neuclrtab.c.

{
       register int  nsleft;
       register long sv;
       double rval, cumprob;
       long   npleft;

       nsamples = npixels/samplefac;
       if (nsamples < 600)
              return(-1);
       thesamples = (BYTE *)malloc(nsamples*3);
       if (thesamples == NULL)
              return(-1);
       cursamp = thesamples;
       npleft = npixels;
       nsleft = nsamples;
       while (nsleft) {
              rval = frandom();    /* random distance to next sample */
              sv = 0;
              cumprob = 0.;
              while ((cumprob += (1.-cumprob)*nsleft/(npleft-sv)) < rval)
                     sv++;
              if (nsleft == nsamples)
                     skipcount = sv;
              else {
                     setskip(cursamp, sv);
                     cursamp += 3;
              }
              npleft -= sv+1;
              nsleft--;
       }
       setskip(cursamp, npleft);   /* tag on end to skip the rest */
       cursamp = thesamples;
       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void neu_map_colrs ( register BYTE bs,
register COLR cs,
register int  n 
)

Definition at line 167 of file neuclrtab.c.

{
       while (n-- > 0) {
              *bs++ = inxsearch(cs[0][BLU],cs[0][GRN],cs[0][RED]);
              cs++;
       }
}

Here is the call graph for this function:

int neu_map_pixel ( register BYTE  col[])

Definition at line 158 of file neuclrtab.c.

{
       return(inxsearch(col[BLU],col[GRN],col[RED]));
}

Here is the call graph for this function:

void neu_pixel ( register BYTE  col[])

Definition at line 102 of file neuclrtab.c.

{
       if (!skipcount--) {
              skipcount = nskip(cursamp);
              cursamp[0] = col[BLU];
              cursamp[1] = col[GRN];
              cursamp[2] = col[RED];
              cursamp += 3;
       }
}
static void unbiasnet ( void  ) [static]

Definition at line 596 of file neuclrtab.c.

{
       int i,j;

       for (i=0; i<netsize; i++) {
              for (j=0; j<3; j++)
                     network[i][j] >>= netbiasshift;
              network[i][3] = i; /* record colour no */
       }
}

Here is the caller graph for this function:


Variable Documentation

int alphadec

Definition at line 286 of file neuclrtab.c.

int bias[256]

Definition at line 306 of file neuclrtab.c.

BYTE clrtab[256][3]

Definition at line 26 of file ra_gif.c.

int clrtabsiz [static]

Definition at line 28 of file neuclrtab.c.

BYTE* cursamp [static]

Definition at line 41 of file neuclrtab.c.

int freq[256]

Definition at line 307 of file neuclrtab.c.

int netindex[256]

Definition at line 304 of file neuclrtab.c.

pixel network[256]

Definition at line 302 of file neuclrtab.c.

int nsamples [static]

Definition at line 40 of file neuclrtab.c.

Definition at line 308 of file neuclrtab.c.

const char RCSid[] = "$Id: neuclrtab.c,v 2.13 2007/09/08 19:17:52 greg Exp $" [static]

Definition at line 2 of file neuclrtab.c.

Definition at line 34 of file neuclrtab.c.

long skipcount [static]

Definition at line 42 of file neuclrtab.c.

BYTE* thesamples [static]

Definition at line 39 of file neuclrtab.c.