Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
Functions | Variables
inv_cmap.c File Reference
#include <math.h>
#include <stdio.h>
Include dependency graph for inv_cmap.c:

Go to the source code of this file.

Functions

static void maxfill ()
 
static int redloop ()
 
static int greenloop ()
 
static int blueloop ()
 
void inv_cmap (int colors, colormap, int bits, unsigned long *dist_buf,*rgbmap)
 
static int greenloop (int restart)
 
static int blueloop (int restart)
 
static void maxfill (unsigned long *buffer, long side)
 

Variables

static int bcenter
 
static int gcenter
 
static int rcenter
 
static long gdist
 
static long rdist
 
static long cdist
 
static long cbinc
 
static long cginc
 
static long crinc
 
static unsigned long * gdp
 
static unsigned long * rdp
 
static unsigned long * cdp
 
static unsigned char * grgbp
 
static unsigned char * rrgbp
 
static unsigned char * crgbp
 
static long gstride
 
static long rstride
 
static long x
 
static long xsqr
 
static long colormax
 
static int cindex
 

Function Documentation

static int blueloop ( )
static
static int blueloop ( int  restart)
static

Definition at line 480 of file inv_cmap.c.

482 {
483  int detect;
484  register unsigned long *dp;
485  register unsigned char *rgbp;
486  register long bdist, bxx;
487  register int b, i = cindex;
488  register long txsqr = xsqr + xsqr;
489  register int lim;
490  static int here, min, max;
491 #ifdef MINMAX_TRACK
492  static int prevmin, prevmax;
493  int thismin, thismax;
494 #ifdef DMIN_DMAX_TRACK
495  static int dmin, dmax;
496 #endif /* DMIN_DMAX_TRACK */
497 #endif /* MINMAX_TRACK */
498  static long binc;
499 #ifdef DEBUG
500  long dist, tdist;
501 #endif
502 
503  if ( restart )
504  {
505  here = bcenter;
506  min = 0;
507  max = colormax - 1;
508  binc = cbinc;
509 #ifdef MINMAX_TRACK
510  prevmin = colormax;
511  prevmax = 0;
512 #ifdef DMIN_DMAX_TRACK
513  dmin = 0;
514  dmax = 0;
515 #endif /* DMIN_DMAX_TRACK */
516 #endif /* MINMAX_TRACK */
517  }
518 
519  detect = 0;
520 #ifdef MINMAX_TRACK
521  thismin = min;
522  thismax = max;
523 #endif
524 #ifdef DEBUG
525  tdist = cred - red * x - x/2;
526  dist = tdist*tdist;
527  tdist = cgreen - green * x - x/2;
528  dist += tdist*tdist;
529  tdist = cblue - here * x - x/2;
530  dist += tdist*tdist;
531  if ( gdist != dist )
532  fprintf( stderr, "*** At %d,%d,%d; dist = %ld != gdist = %ld\n",
533  red, green, here, dist, gdist );
534  if ( grgbp != zrgbp + red*rstride + green*gstride + here )
535  fprintf( stderr, "*** At %d,%d,%d: buffer pointer is at %d,%d,%d\n",
536  red, green, here,
537  (grgbp - zrgbp) / rstride,
538  ((grgbp - zrgbp) % rstride) / gstride,
539  (grgbp - zrgbp) % gstride );
540 #endif /* DEBUG */
541 
542  /* Basic loop up. */
543  /* First loop just finds first applicable cell. */
544  for ( b = here, bdist = gdist, bxx = binc, dp = gdp, rgbp = grgbp, lim = max;
545  b <= lim;
546  b++, dp++, rgbp++,
547  bdist += bxx, bxx += txsqr )
548  {
549 #ifdef INSTRUMENT_IT
550  outercount++;
551 #endif
552  if ( *dp > bdist )
553  {
554  /* Remember new 'here' and associated data! */
555  if ( b > here )
556  {
557  here = b;
558  gdp = dp;
559  grgbp = rgbp;
560  gdist = bdist;
561  binc = bxx;
562 #ifdef MINMAX_TRACK
563  thismin = here;
564 #endif
565 #ifdef DEBUG
566  fprintf( stderr, "===Adjusting blue here up at %d,%d,%d\n",
567  red, green, here );
568 
569  tdist = cred - red * x - x/2;
570  dist = tdist*tdist;
571  tdist = cgreen - green * x - x/2;
572  dist += tdist*tdist;
573  tdist = cblue - here * x - x/2;
574  dist += tdist*tdist;
575  if ( gdist != dist )
576  fprintf( stderr,
577  "*** Adjusting here up at %d,%d,%d; dist = %ld != gdist = %ld\n",
578  red, green, here, dist, gdist );
579 #endif /* DEBUG */
580  }
581  detect = 1;
582 #ifdef INSTRUMENT_IT
583  outercount--;
584 #endif
585  break;
586  }
587  }
588  /* Second loop fills in a run of closer cells. */
589  for ( ;
590  b <= lim;
591  b++, dp++, rgbp++,
592  bdist += bxx, bxx += txsqr )
593  {
594 #ifdef INSTRUMENT_IT
595  outercount++;
596 #endif
597  if ( *dp > bdist )
598  {
599 #ifdef INSTRUMENT_IT
600  innercount++;
601 #endif
602  *dp = bdist;
603  *rgbp = i;
604  }
605  else
606  {
607 #ifdef MINMAX_TRACK
608  thismax = b - 1;
609 #endif
610  break;
611  }
612  }
613 #ifdef DEBUG
614  tdist = cred - red * x - x/2;
615  dist = tdist*tdist;
616  tdist = cgreen - green * x - x/2;
617  dist += tdist*tdist;
618  tdist = cblue - b * x - x/2;
619  dist += tdist*tdist;
620  if ( bdist != dist )
621  fprintf( stderr,
622  "*** After up loop at %d,%d,%d; dist = %ld != bdist = %ld\n",
623  red, green, b, dist, bdist );
624 #endif /* DEBUG */
625 
626  /* Basic loop down. */
627  /* Do initializations here, since the 'find' loop might not get
628  * executed.
629  */
630  lim = min;
631  b = here - 1;
632  bxx = binc - txsqr;
633  bdist = gdist - bxx;
634  dp = gdp - 1;
635  rgbp = grgbp - 1;
636  /* The 'find' loop is executed only if we didn't already find
637  * something.
638  */
639  if ( !detect )
640  for ( ;
641  b >= lim;
642  b--, dp--, rgbp--,
643  bxx -= txsqr, bdist -= bxx )
644  {
645 #ifdef INSTRUMENT_IT
646  outercount++;
647 #endif
648  if ( *dp > bdist )
649  {
650  /* Remember here! */
651  /* No test for b against here necessary because b <
652  * here by definition.
653  */
654  here = b;
655  gdp = dp;
656  grgbp = rgbp;
657  gdist = bdist;
658  binc = bxx;
659 #ifdef MINMAX_TRACK
660  thismax = here;
661 #endif
662  detect = 1;
663 #ifdef DEBUG
664  fprintf( stderr, "===Adjusting blue here down at %d,%d,%d\n",
665  red, green, here );
666  tdist = cred - red * x - x/2;
667  dist = tdist*tdist;
668  tdist = cgreen - green * x - x/2;
669  dist += tdist*tdist;
670  tdist = cblue - here * x - x/2;
671  dist += tdist*tdist;
672  if ( gdist != dist )
673  fprintf( stderr,
674  "*** Adjusting here down at %d,%d,%d; dist = %ld != gdist = %ld\n",
675  red, green, here, dist, gdist );
676 #endif /* DEBUG */
677 #ifdef INSTRUMENT_IT
678  outercount--;
679 #endif
680  break;
681  }
682  }
683  /* The 'update' loop. */
684  for ( ;
685  b >= lim;
686  b--, dp--, rgbp--,
687  bxx -= txsqr, bdist -= bxx )
688  {
689 #ifdef INSTRUMENT_IT
690  outercount++;
691 #endif
692  if ( *dp > bdist )
693  {
694 #ifdef INSTRUMENT_IT
695  innercount++;
696 #endif
697  *dp = bdist;
698  *rgbp = i;
699  }
700  else
701  {
702 #ifdef MINMAX_TRACK
703  thismin = b + 1;
704 #endif
705  break;
706  }
707  }
708 
709 #ifdef DEBUG
710  tdist = cred - red * x - x/2;
711  dist = tdist*tdist;
712  tdist = cgreen - green * x - x/2;
713  dist += tdist*tdist;
714  tdist = cblue - b * x - x/2;
715  dist += tdist*tdist;
716  if ( bdist != dist )
717  fprintf( stderr,
718  "*** After down loop at %d,%d,%d; dist = %ld != bdist = %ld\n",
719  red, green, b, dist, bdist );
720 #endif /* DEBUG */
721 
722  /* If we saw something, update the edge trackers. */
723 #ifdef MINMAX_TRACK
724  if ( detect )
725  {
726 #ifdef DMIN_DMAX_TRACK
727  /* Predictively track. Not clear this is a win. */
728  /* If there was a previous line, update the dmin/dmax values. */
729  if ( prevmax >= prevmin )
730  {
731  if ( thismin > 0 )
732  dmin = thismin - prevmin - 1;
733  else
734  dmin = 0;
735  if ( thismax < colormax - 1 )
736  dmax = thismax - prevmax + 1;
737  else
738  dmax = 0;
739  /* Update the min and max values by the differences. */
740  max = thismax + dmax;
741  if ( max >= colormax )
742  max = colormax - 1;
743  min = thismin + dmin;
744  if ( min < 0 )
745  min = 0;
746  }
747 #else /* !DMIN_DMAX_TRACK */
748  /* Only tracks edges that are "shrinking" (min increasing, max
749  * decreasing.
750  */
751  if ( thismax < prevmax )
752  max = thismax;
753 
754  if ( thismin > prevmin )
755  min = thismin;
756 #endif /* DMIN_DMAX_TRACK */
757 
758  /* Remember the min and max values. */
759  prevmax = thismax;
760  prevmin = thismin;
761  }
762 #endif /* MINMAX_TRACK */
763 
764  return detect;
765 }
static int bcenter
Definition: inv_cmap.c:40
static long cbinc
Definition: inv_cmap.c:42
static long x
Definition: inv_cmap.c:46
static unsigned long * gdp
Definition: inv_cmap.c:43
#define bdist(a, b)
Definition: getami.c:42
static long gdist
Definition: inv_cmap.c:41
static unsigned char b
Definition: getami.c:692
static long rstride
Definition: inv_cmap.c:45
static long colormax
Definition: inv_cmap.c:46
static unsigned char green[256]
Definition: rastorle.c:71
static unsigned char * grgbp
Definition: inv_cmap.c:44
#define min(a, b)
Definition: dvirle.h:51
int i
Definition: rletorla.c:82
static int cindex
Definition: inv_cmap.c:47
static long gstride
Definition: inv_cmap.c:45
static unsigned char red[256]
Definition: rastorle.c:71
static long xsqr
Definition: inv_cmap.c:46
static int greenloop ( )
static
static int greenloop ( int  restart)
static

Definition at line 339 of file inv_cmap.c.

Referenced by redloop().

341 {
342  int detect;
343  int g;
344  int first;
345  long txsqr = xsqr + xsqr;
346  static int here, min, max;
347 #ifdef MINMAX_TRACK
348  static int prevmax, prevmin;
349  int thismax, thismin;
350 #endif
351  static long ginc, gxx, gcdist; /* "gc" variables maintain correct */
352  static unsigned long *gcdp; /* values for bcenter position, */
353  static unsigned char *gcrgbp; /* despite modifications by blueloop */
354  /* to gdist, gdp, grgbp. */
355 
356  if ( restart )
357  {
358  here = gcenter;
359  min = 0;
360  max = colormax - 1;
361  ginc = cginc;
362 #ifdef MINMAX_TRACK
363  prevmax = 0;
364  prevmin = colormax;
365 #endif
366  }
367 
368 #ifdef MINMAX_TRACK
369  thismin = min;
370  thismax = max;
371 #endif
372  detect = 0;
373 
374  /* Basic loop up. */
375  for ( g = here, gcdist = gdist = rdist, gxx = ginc,
376  gcdp = gdp = rdp, gcrgbp = grgbp = rrgbp, first = 1;
377  g <= max;
378  g++, gdp += gstride, gcdp += gstride, grgbp += gstride, gcrgbp += gstride,
379  gdist += gxx, gcdist += gxx, gxx += txsqr, first = 0 )
380  {
381 #ifdef DEBUG
382  green = g;
383 #endif
384  if ( blueloop( first ) )
385  {
386  if ( !detect )
387  {
388  /* Remember here and associated data! */
389  if ( g > here )
390  {
391  here = g;
392  rdp = gcdp;
393  rrgbp = gcrgbp;
394  rdist = gcdist;
395  ginc = gxx;
396 #ifdef MINMAX_TRACK
397  thismin = here;
398 #endif
399 #ifdef DEBUG
400  fprintf( stderr, "===Adjusting green here up at %d,%d\n",
401  red, here );
402 #endif
403  }
404  detect = 1;
405  }
406  }
407  else if ( detect )
408  {
409 #ifdef MINMAX_TRACK
410  thismax = g - 1;
411 #endif
412  break;
413  }
414  }
415 
416  /* Basic loop down. */
417  for ( g = here - 1, gxx = ginc - txsqr, gcdist = gdist = rdist - gxx,
418  gcdp = gdp = rdp - gstride, gcrgbp = grgbp = rrgbp - gstride,
419  first = 1;
420  g >= min;
421  g--, gdp -= gstride, gcdp -= gstride, grgbp -= gstride, gcrgbp -= gstride,
422  gxx -= txsqr, gdist -= gxx, gcdist -= gxx, first = 0 )
423  {
424 #ifdef DEBUG
425  green = g;
426 #endif
427  if ( blueloop( first ) )
428  {
429  if ( !detect )
430  {
431  /* Remember here! */
432  here = g;
433  rdp = gcdp;
434  rrgbp = gcrgbp;
435  rdist = gcdist;
436  ginc = gxx;
437 #ifdef MINMAX_TRACK
438  thismax = here;
439 #endif
440 #ifdef DEBUG
441  fprintf( stderr, "===Adjusting green here down at %d,%d\n",
442  red, here );
443 #endif
444  detect = 1;
445  }
446  }
447  else if ( detect )
448  {
449 #ifdef MINMAX_TRACK
450  thismin = g + 1;
451 #endif
452  break;
453  }
454  }
455 
456 #ifdef MINMAX_TRACK
457  /* If we saw something, update the edge trackers. For now, only
458  * tracks edges that are "shrinking" (min increasing, max
459  * decreasing.
460  */
461  if ( detect )
462  {
463  if ( thismax < prevmax )
464  max = thismax;
465 
466  prevmax = thismax;
467 
468  if ( thismin > prevmin )
469  min = thismin;
470 
471  prevmin = thismin;
472  }
473 #endif
474 
475  return detect;
476 }
static unsigned char g
Definition: getami.c:692
static int blueloop()
static unsigned char * rrgbp
Definition: inv_cmap.c:44
static unsigned long * gdp
Definition: inv_cmap.c:43
static long gdist
Definition: inv_cmap.c:41
static long rdist
Definition: inv_cmap.c:41
static int gcenter
Definition: inv_cmap.c:40
static long colormax
Definition: inv_cmap.c:46
static unsigned char green[256]
Definition: rastorle.c:71
static unsigned char * grgbp
Definition: inv_cmap.c:44
#define min(a, b)
Definition: dvirle.h:51
static long cginc
Definition: inv_cmap.c:42
static unsigned long * rdp
Definition: inv_cmap.c:43
static long gstride
Definition: inv_cmap.c:45
static unsigned char red[256]
Definition: rastorle.c:71
static long xsqr
Definition: inv_cmap.c:46

Here is the caller graph for this function:

void inv_cmap ( int  colors,
colormap  ,
int  bits,
unsigned long *  dist_buf,
rgbmap 
)

Definition at line 214 of file inv_cmap.c.

218 {
219  int nbits = 8 - bits;
220 
221  colormax = 1 << bits;
222  x = 1 << nbits;
223  xsqr = 1 << (2 * nbits);
224 
225  /* Compute "strides" for accessing the arrays. */
226  gstride = colormax;
228 
229 #ifdef INSTRUMENT_IT
230  outercount = 0;
231  innercount = 0;
232 #endif
233  maxfill( dist_buf, colormax );
234 
235  for ( cindex = 0; cindex < colors; cindex++ )
236  {
237  /*
238  * Distance formula is
239  * (red - map[0])^2 + (green - map[1])^2 + (blue - map[2])^2
240  *
241  * Because of quantization, we will measure from the center of
242  * each quantized "cube", so blue distance is
243  * (blue + x/2 - map[2])^2,
244  * where x = 2^(8 - bits).
245  * The step size is x, so the blue increment is
246  * 2*x*blue - 2*x*map[2] + 2*x^2
247  *
248  * Now, b in the code below is actually blue/x, so our
249  * increment will be 2*(b*x^2 + x^2 - x*map[2]). For
250  * efficiency, we will maintain this quantity in a separate variable
251  * that will be updated incrementally by adding 2*x^2 each time.
252  */
253  /* The initial position is the cell containing the colormap
254  * entry. We get this by quantizing the colormap values.
255  */
256  rcenter = colormap[0][cindex] >> nbits;
257  gcenter = colormap[1][cindex] >> nbits;
258  bcenter = colormap[2][cindex] >> nbits;
259 #ifdef DEBUG
260  cred = colormap[0][cindex];
261  cgreen = colormap[1][cindex];
262  cblue = colormap[2][cindex];
263  fprintf( stderr, "---Starting %d: %d,%d,%d -> %d,%d,%d\n",
264  cindex, cred, cgreen, cblue,
265  rcenter, gcenter, bcenter );
266  zrgbp = rgbmap;
267 #endif
268 
269  rdist = colormap[0][cindex] - (rcenter * x + x/2);
270  gdist = colormap[1][cindex] - (gcenter * x + x/2);
271  cdist = colormap[2][cindex] - (bcenter * x + x/2);
272  cdist = rdist*rdist + gdist*gdist + cdist*cdist;
273 
274  crinc = 2 * ((rcenter + 1) * xsqr - (colormap[0][cindex] * x));
275  cginc = 2 * ((gcenter + 1) * xsqr - (colormap[1][cindex] * x));
276  cbinc = 2 * ((bcenter + 1) * xsqr - (colormap[2][cindex] * x));
277 
278  /* Array starting points. */
279  cdp = dist_buf + rcenter * rstride + gcenter * gstride + bcenter;
280  crgbp = rgbmap + rcenter * rstride + gcenter * gstride + bcenter;
281 
282  (void)redloop();
283  }
284 #ifdef INSTRUMENT_IT
285  fprintf( stderr, "K = %d, N = %d, outer count = %ld, inner count = %ld\n",
286  colors, colormax, outercount, innercount );
287 #endif
288 }
static int bcenter
Definition: inv_cmap.c:40
static long cbinc
Definition: inv_cmap.c:42
static void maxfill()
static long crinc
Definition: inv_cmap.c:42
static long x
Definition: inv_cmap.c:46
static unsigned char nbits[256]
Definition: dvirle2.c:656
static int rcenter
Definition: inv_cmap.c:40
static long cdist
Definition: inv_cmap.c:41
rle_map * colormap
Definition: rletoppm.c:56
static long gdist
Definition: inv_cmap.c:41
static long rdist
Definition: inv_cmap.c:41
static int gcenter
Definition: inv_cmap.c:40
static int redloop()
Definition: inv_cmap.c:292
static long rstride
Definition: inv_cmap.c:45
static long colormax
Definition: inv_cmap.c:46
static long cginc
Definition: inv_cmap.c:42
static unsigned long * cdp
Definition: inv_cmap.c:43
static int cindex
Definition: inv_cmap.c:47
static long gstride
Definition: inv_cmap.c:45
static long xsqr
Definition: inv_cmap.c:46
static unsigned char * crgbp
Definition: inv_cmap.c:44
static void maxfill ( )
static
static void maxfill ( unsigned long *  buffer,
long  side 
)
static

Definition at line 768 of file inv_cmap.c.

771 {
772  register unsigned long maxv = ~0L;
773  register long i;
774  register unsigned long *bp;
775 
776  for ( i = colormax * colormax * colormax, bp = buffer;
777  i > 0;
778  i--, bp++ )
779  *bp = maxv;
780 }
static long colormax
Definition: inv_cmap.c:46
int i
Definition: rletorla.c:82
unsigned char * buffer
Definition: getsun.c:87
static int redloop ( )
static

Definition at line 292 of file inv_cmap.c.

References cdist, cdp, colormax, crgbp, crinc, greenloop(), rcenter, rdist, rdp, rrgbp, rstride, and xsqr.

293 {
294  int detect;
295  int r;
296  int first;
297  long txsqr = xsqr + xsqr;
298  static long rxx;
299 
300  detect = 0;
301 
302  /* Basic loop up. */
303  for ( r = rcenter, rdist = cdist, rxx = crinc,
304  rdp = cdp, rrgbp = crgbp, first = 1;
305  r < colormax;
306  r++, rdp += rstride, rrgbp += rstride,
307  rdist += rxx, rxx += txsqr, first = 0 )
308  {
309 #ifdef DEBUG
310  red = r;
311 #endif
312  if ( greenloop( first ) )
313  detect = 1;
314  else if ( detect )
315  break;
316  }
317 
318  /* Basic loop down. */
319  for ( r = rcenter - 1, rxx = crinc - txsqr, rdist = cdist - rxx,
320  rdp = cdp - rstride, rrgbp = crgbp - rstride, first = 1;
321  r >= 0;
322  r--, rdp -= rstride, rrgbp -= rstride,
323  rxx -= txsqr, rdist -= rxx, first = 0 )
324  {
325 #ifdef DEBUG
326  red = r;
327 #endif
328  if ( greenloop( first ) )
329  detect = 1;
330  else if ( detect )
331  break;
332  }
333 
334  return detect;
335 }
static long crinc
Definition: inv_cmap.c:42
static int rcenter
Definition: inv_cmap.c:40
static unsigned char r
Definition: getami.c:692
static unsigned char * rrgbp
Definition: inv_cmap.c:44
static long cdist
Definition: inv_cmap.c:41
static long rdist
Definition: inv_cmap.c:41
static long rstride
Definition: inv_cmap.c:45
static long colormax
Definition: inv_cmap.c:46
static unsigned long * cdp
Definition: inv_cmap.c:43
static unsigned long * rdp
Definition: inv_cmap.c:43
static unsigned char red[256]
Definition: rastorle.c:71
static int greenloop()
static long xsqr
Definition: inv_cmap.c:46
static unsigned char * crgbp
Definition: inv_cmap.c:44

Here is the call graph for this function:

Variable Documentation

int bcenter
static

Definition at line 40 of file inv_cmap.c.

long cbinc
static

Definition at line 42 of file inv_cmap.c.

long cdist
static

Definition at line 41 of file inv_cmap.c.

Referenced by redloop().

unsigned long * cdp
static

Definition at line 43 of file inv_cmap.c.

Referenced by redloop().

long cginc
static

Definition at line 42 of file inv_cmap.c.

int cindex
static

Definition at line 47 of file inv_cmap.c.

long colormax
static

Definition at line 46 of file inv_cmap.c.

Referenced by redloop().

unsigned char * crgbp
static

Definition at line 44 of file inv_cmap.c.

Referenced by redloop().

long crinc
static

Definition at line 42 of file inv_cmap.c.

Referenced by redloop().

int gcenter
static

Definition at line 40 of file inv_cmap.c.

long gdist
static

Definition at line 41 of file inv_cmap.c.

unsigned long* gdp
static

Definition at line 43 of file inv_cmap.c.

unsigned char* grgbp
static

Definition at line 44 of file inv_cmap.c.

long gstride
static

Definition at line 45 of file inv_cmap.c.

int rcenter
static

Definition at line 40 of file inv_cmap.c.

Referenced by redloop().

long rdist
static

Definition at line 41 of file inv_cmap.c.

Referenced by redloop().

unsigned long * rdp
static

Definition at line 43 of file inv_cmap.c.

Referenced by redloop().

unsigned char * rrgbp
static

Definition at line 44 of file inv_cmap.c.

Referenced by redloop().

long rstride
static

Definition at line 45 of file inv_cmap.c.

Referenced by redloop().

long x
static

Definition at line 46 of file inv_cmap.c.

long xsqr
static

Definition at line 46 of file inv_cmap.c.

Referenced by redloop().