home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / COMMON / COLROPS.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  5KB  |  231 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)colrops.c 2.4 10/2/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Integer operations on COLR scanlines
  9.  */
  10.  
  11. #include "color.h"
  12.  
  13. #define NULL        0
  14.  
  15. extern char    *bmalloc();
  16.  
  17. #define MAXGSHIFT    31        /* maximum shift for gamma table */
  18.  
  19. static BYTE    *g_mant = NULL, *g_nexp = NULL;
  20.  
  21. static BYTE    (*g_bval)[256] = NULL;
  22.  
  23. #ifndef pow
  24. extern double    pow();
  25. #endif
  26.  
  27.  
  28. setcolrcor(f, a2)        /* set brightness correction */
  29. double    (*f)();
  30. double    a2;
  31. {
  32.     double    mult;
  33.     register int    i, j;
  34.                     /* allocate tables */
  35.     if (g_bval == NULL && (g_bval =
  36.             (BYTE (*)[256])bmalloc((MAXGSHIFT+1)*256)) == NULL)
  37.         return(-1);
  38.                     /* compute colr -> gamb mapping */
  39.     mult = 1.0/256.0;
  40.     for (i = 0; i <= MAXGSHIFT; i++) {
  41.         for (j = 0; j < 256; j++)
  42.             g_bval[i][j] = 256.0 * (*f)((j+.5)*mult, a2);
  43.         mult *= 0.5;
  44.     }
  45.     return(0);
  46. }
  47.  
  48.  
  49. setcolrinv(f, a2)        /* set inverse brightness correction */
  50. double    (*f)();
  51. double    a2;
  52. {
  53.     double    mult;
  54.     register int    i, j;
  55.                     /* allocate tables */
  56.     if (g_mant == NULL && (g_mant = (BYTE *)bmalloc(256)) == NULL)
  57.         return(-1);
  58.     if (g_nexp == NULL && (g_nexp = (BYTE *)bmalloc(256)) == NULL)
  59.         return(-1);
  60.                     /* compute gamb -> colr mapping */
  61.     i = 0;
  62.     mult = 256.0;
  63.     for (j = 255; j > 0; j--) {
  64.         while ((g_mant[j] = mult * (*f)(j/256.0, a2)) < 128) {
  65.             i++;
  66.             mult *= 2.0;
  67.         }
  68.         g_nexp[j] = i;
  69.     }
  70.     g_mant[0] = 0;
  71.     g_nexp[0] = COLXS;
  72.     return(0);
  73. }
  74.  
  75.  
  76. setcolrgam(g)            /* set gamma conversion */
  77. double    g;
  78. {
  79.     if (setcolrcor(pow, 1.0/g) < 0)
  80.         return(-1);
  81.     return(setcolrinv(pow, g));
  82. }
  83.  
  84.  
  85. colrs_gambs(scan, len)        /* convert scanline of colrs to gamma bytes */
  86. register COLR    *scan;
  87. int    len;
  88. {
  89.     register int    i, expo;
  90.  
  91.     if (g_bval == NULL)
  92.         return(-1);
  93.     while (len-- > 0) {
  94.         expo = scan[0][EXP] - COLXS;
  95.         if (expo < -MAXGSHIFT) {
  96.             if (expo < -MAXGSHIFT-8) {
  97.                 scan[0][RED] =
  98.                 scan[0][GRN] =
  99.                 scan[0][BLU] = 0;
  100.             } else {
  101.                 i = (-MAXGSHIFT-1) - expo;
  102.                 scan[0][RED] = 
  103.                 g_bval[MAXGSHIFT][((scan[0][RED]>>i)+1)>>1];
  104.                 scan[0][GRN] =
  105.                 g_bval[MAXGSHIFT][((scan[0][GRN]>>i)+1)>>1];
  106.                 scan[0][BLU] =
  107.                 g_bval[MAXGSHIFT][((scan[0][BLU]>>i)+1)>>1];
  108.             }
  109.         } else if (expo > 0) {
  110.             if (expo > 8) {
  111.                 scan[0][RED] =
  112.                 scan[0][GRN] =
  113.                 scan[0][BLU] = 255;
  114.             } else {
  115.                 i = (scan[0][RED]<<1 | 1) << (expo-1);
  116.                 scan[0][RED] = i > 255 ? 255 : g_bval[0][i];
  117.                 i = (scan[0][GRN]<<1 | 1) << (expo-1);
  118.                 scan[0][GRN] = i > 255 ? 255 : g_bval[0][i];
  119.                 i = (scan[0][BLU]<<1 | 1) << (expo-1);
  120.                 scan[0][BLU] = i > 255 ? 255 : g_bval[0][i];
  121.             }
  122.         } else {
  123.             scan[0][RED] = g_bval[-expo][scan[0][RED]];
  124.             scan[0][GRN] = g_bval[-expo][scan[0][GRN]];
  125.             scan[0][BLU] = g_bval[-expo][scan[0][BLU]];
  126.         }
  127.         scan[0][EXP] = COLXS;
  128.         scan++;
  129.     }
  130.     return(0);
  131. }
  132.  
  133.  
  134. gambs_colrs(scan, len)        /* convert gamma bytes to colr scanline */
  135. register COLR    *scan;
  136. int    len;
  137. {
  138.     register int    nexpo;
  139.  
  140.     if (g_mant == NULL | g_nexp == NULL)
  141.         return(-1);
  142.     while (len-- > 0) {
  143.         nexpo = g_nexp[scan[0][RED]];
  144.         if (g_nexp[scan[0][GRN]] < nexpo)
  145.             nexpo = g_nexp[scan[0][GRN]];
  146.         if (g_nexp[scan[0][BLU]] < nexpo)
  147.             nexpo = g_nexp[scan[0][BLU]];
  148.         if (nexpo < g_nexp[scan[0][RED]])
  149.             scan[0][RED] = g_mant[scan[0][RED]]
  150.                     >> (g_nexp[scan[0][RED]]-nexpo);
  151.         else
  152.             scan[0][RED] = g_mant[scan[0][RED]];
  153.         if (nexpo < g_nexp[scan[0][GRN]])
  154.             scan[0][GRN] = g_mant[scan[0][GRN]]
  155.                     >> (g_nexp[scan[0][GRN]]-nexpo);
  156.         else
  157.             scan[0][GRN] = g_mant[scan[0][GRN]];
  158.         if (nexpo < g_nexp[scan[0][BLU]])
  159.             scan[0][BLU] = g_mant[scan[0][BLU]]
  160.                     >> (g_nexp[scan[0][BLU]]-nexpo);
  161.         else
  162.             scan[0][BLU] = g_mant[scan[0][BLU]];
  163.         scan[0][EXP] = COLXS - nexpo;
  164.         scan++;
  165.     }
  166.     return(0);
  167. }
  168.  
  169.  
  170. shiftcolrs(scan, len, adjust)    /* shift a scanline of colors by 2^adjust */
  171. register COLR    *scan;
  172. register int    len;
  173. register int    adjust;
  174. {
  175.     int    minexp;
  176.  
  177.     if (adjust == 0)
  178.         return;
  179.     minexp = adjust < 0 ? -adjust : 0;
  180.     while (len-- > 0) {
  181.         if (scan[0][EXP] <= minexp)
  182.             scan[0][RED] = scan[0][GRN] = scan[0][BLU] =
  183.             scan[0][EXP] = 0;
  184.         else
  185.             scan[0][EXP] += adjust;
  186.         scan++;
  187.     }
  188. }
  189.  
  190.  
  191. normcolrs(scan, len, adjust)    /* normalize a scanline of colrs */
  192. register COLR  *scan;
  193. int  len;
  194. int  adjust;
  195. {
  196.     register int  c;
  197.     register int  shift;
  198.  
  199.     while (len-- > 0) {
  200.         shift = scan[0][EXP] + adjust - COLXS;
  201.         if (shift > 0) {
  202.             if (shift > 8) {
  203.                 scan[0][RED] =
  204.                 scan[0][GRN] =
  205.                 scan[0][BLU] = 255;
  206.             } else {
  207.                 shift--;
  208.                 c = (scan[0][RED]<<1 | 1) << shift;
  209.                 scan[0][RED] = c > 255 ? 255 : c;
  210.                 c = (scan[0][GRN]<<1 | 1) << shift;
  211.                 scan[0][GRN] = c > 255 ? 255 : c;
  212.                 c = (scan[0][BLU]<<1 | 1) << shift;
  213.                 scan[0][BLU] = c > 255 ? 255 : c;
  214.             }
  215.         } else if (shift < 0) {
  216.             if (shift < -8) {
  217.                 scan[0][RED] =
  218.                 scan[0][GRN] =
  219.                 scan[0][BLU] = 0;
  220.             } else {
  221.                 shift = -1-shift;
  222.                 scan[0][RED] = ((scan[0][RED]>>shift)+1)>>1;
  223.                 scan[0][GRN] = ((scan[0][GRN]>>shift)+1)>>1;
  224.                 scan[0][BLU] = ((scan[0][BLU]>>shift)+1)>>1;
  225.             }
  226.         }
  227.         scan[0][EXP] = COLXS - adjust;
  228.         scan++;
  229.     }
  230. }
  231.