home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Web / Utilities / wwwcount-2.3 / combine / tranrgb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-02  |  7.1 KB  |  293 lines

  1. /*
  2.  *    TransformRGBImage()    - Converts the reference image from an alternate
  3.  *                          colorspace.
  4.  *
  5.  *    RCS:
  6.  *        $Revision: 2.3 $
  7.  *        $Date: 1996/05/03 02:21:34 $
  8.  *
  9.  *    Security:
  10.  *        Unclassified
  11.  *
  12.  *    Description:
  13.  *        Adapted from ImageMacgick 3.0
  14.  *
  15.  *    Input Parameters:
  16.  *        type    identifier    description
  17.  *
  18.  *        text
  19.  *
  20.  *    Output Parameters:
  21.  *        type    identifier    description
  22.  *
  23.  *        text
  24.  *
  25.  *    Return Values:
  26.  *        value    description
  27.  *
  28.  *    Side Effects:
  29.  *        text
  30.  *
  31.  *    Limitations and Comments:
  32.  *        text
  33.  *
  34.  *    Development History:
  35.  *        when    who        why
  36.  *    4/30/94        mm        first cut
  37.  */
  38.  
  39. #include "combine.h"
  40. #include "defines.h"
  41.  
  42.  
  43. void TransformRGBImage(image,colorspace)
  44. Image
  45.   *image;
  46.  
  47. unsigned int
  48.   colorspace;
  49. {
  50. #define R 0
  51. #define G (MaxRGB+1)
  52. #define B (MaxRGB+1)*2
  53.  
  54.   long
  55.     *blue,
  56.     *green,
  57.     *red;
  58.  
  59.   register int
  60.     i,
  61.     x,
  62.     y,
  63.     z;
  64.  
  65.   register Runlength
  66.     *p;
  67.  
  68.   register unsigned char
  69.     *range_limit;
  70.  
  71.   unsigned char
  72.     *range_table;
  73.  
  74.   if ((colorspace == RGBColorspace) || (colorspace == GRAYColorspace))
  75.     return;
  76.   /*
  77.     Allocate the tables.
  78.   */
  79.   red=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
  80.   green=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
  81.   blue=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
  82.   range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
  83.   if ((red == (long *) NULL) || (green == (long *) NULL) ||
  84.       (blue == (long *) NULL) || (range_table == (unsigned char *) NULL))
  85.     {
  86.       (void) fprintf (stderr,
  87.         "Unable to transform color space,Memory allocation failed\n");
  88.       return;
  89.     }
  90.   /*
  91.     Initialize tables.
  92.   */
  93.   for (i=0; i <= MaxRGB; i++)
  94.   {
  95.     range_table[i]=0;
  96.     range_table[i+(MaxRGB+1)]=(unsigned char) i;
  97.     range_table[i+(MaxRGB+1)*2]=MaxRGB;
  98.   }
  99.   range_limit=range_table+(MaxRGB+1);
  100.   switch (colorspace)
  101.   {
  102.     case OHTAColorspace:
  103.     {
  104.       /*
  105.         Initialize OHTA tables:
  106.  
  107.           R = I1+1.00000*I2-0.66668*I3
  108.           G = I1+0.00000*I2+1.33333*I3
  109.           B = I1-1.00000*I2-0.66668*I3
  110.  
  111.         I and Q, normally -0.5 through 0.5, must be normalized to the range 0
  112.         through MaxRGB.
  113.       */
  114.       for (i=0; i <= MaxRGB; i++)
  115.       {
  116.         red[i+R]=UpShifted(1.00000)*i;
  117.         green[i+R]=UpShifted(1.0000*0.5)*((i << 1)-MaxRGB);
  118.         blue[i+R]=(-UpShifted(0.66668*0.5))*((i << 1)-MaxRGB);
  119.         red[i+G]=UpShifted(1.00000)*i;
  120.         green[i+G]=0;
  121.         blue[i+G]=UpShifted(1.33333*0.5)*((i << 1)-MaxRGB);
  122.         red[i+B]=UpShifted(1.00000)*i;
  123.         green[i+B]=(-UpShifted(1.00000*0.5))*((i << 1)-MaxRGB);
  124.         blue[i+B]=(-UpShifted(0.66668*0.5))*((i << 1)-MaxRGB);
  125.       }
  126.       break;
  127.     }
  128.     case XYZColorspace:
  129.     {
  130.       /*
  131.         Initialize XYZ tables:
  132.  
  133.           R =  1.87597*X-0.53294*Y-0.34303*Z
  134.           G = -0.96670*X+1.99806*Y+0.03136*Z
  135.           B =  0.05735*X-0.11853*Y+1.06118*Z
  136.       */
  137.       for (i=0; i <= MaxRGB; i++)
  138.       {
  139.         red[i+R]=UpShifted(1.87597)*i;
  140.         green[i+R]=(-UpShifted(0.53294))*i;
  141.         blue[i+R]=(-UpShifted(0.34303))*i;
  142.         red[i+G]=(-UpShifted(0.96670))*i;
  143.         green[i+G]=UpShifted(1.99806)*i;
  144.         blue[i+G]=UpShifted(0.03136)*i;
  145.         red[i+B]=UpShifted(0.05735)*i;
  146.         green[i+B]=(-UpShifted(0.11853))*i;
  147.         blue[i+B]=UpShifted(1.06118)*i;
  148.       }
  149.       break;
  150.     }
  151.     case YCbCrColorspace:
  152.     {
  153.       /*
  154.         Initialize YCbCr tables:
  155.  
  156.           R = Y           +1.40200*Cr
  157.           G = Y-0.34414*Cb-0.71414*Cr
  158.           B = Y+1.77200*Cb
  159.  
  160.         Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
  161.         through MaxRGB.
  162.       */
  163.       for (i=0; i <= MaxRGB; i++)
  164.       {
  165.         red[i+R]=UpShifted(1.00000)*i;
  166.         green[i+R]=0;
  167.         blue[i+R]=UpShifted(1.40200*0.5)*((i << 1)-MaxRGB);
  168.         red[i+G]=UpShifted(1.00000)*i;
  169.         green[i+G]=(-UpShifted(0.34414*0.5))*((i << 1)-MaxRGB);
  170.         blue[i+G]=(-UpShifted(0.71414*0.5))*((i << 1)-MaxRGB);
  171.         red[i+B]=UpShifted(1.00000)*i;
  172.         green[i+B]=UpShifted(1.77200*0.5)*((i << 1)-MaxRGB);
  173.         blue[i+B]=0;
  174.       }
  175.       break;
  176.     }
  177.     case YIQColorspace:
  178.     {
  179.       /*
  180.         Initialize YIQ tables:
  181.  
  182.           R = 0.97087*Y+1.17782*I+0.59800*Q
  183.           G = 0.97087*Y-0.28626*I-0.72851*Q
  184.           B = 0.97087*Y-1.27870*I+1.72801*Q
  185.  
  186.         I and Q, normally -0.5 through 0.5, must be normalized to the range 0
  187.         through MaxRGB.
  188.       */
  189.       for (i=0; i <= MaxRGB; i++)
  190.       {
  191.         red[i+R]=UpShifted(0.97087)*i;
  192.         green[i+R]=UpShifted(1.17782*0.5)*((i << 1)-MaxRGB);
  193.         blue[i+R]=UpShifted(0.59800*0.5)*((i << 1)-MaxRGB);
  194.         red[i+G]=UpShifted(0.97087)*i;
  195.         green[i+G]=(-UpShifted(0.28626*0.5))*((i << 1)-MaxRGB);
  196.         blue[i+G]=(-UpShifted(0.72851*0.5))*((i << 1)-MaxRGB);
  197.         red[i+B]=UpShifted(0.97087)*i;
  198.         green[i+B]=(-UpShifted(1.27870*0.5))*((i << 1)-MaxRGB);
  199.         blue[i+B]=UpShifted(1.72801*0.5)*((i << 1)-MaxRGB);
  200.       }
  201.       break;
  202.     }
  203.     case YUVColorspace:
  204.     default:
  205.     {
  206.       /*
  207.         Initialize YUV tables:
  208.  
  209.           R = Y          +1.13980*V
  210.           G = Y-0.39380*U-0.58050*V
  211.           B = Y+2.02790*U
  212.  
  213.         U and V, normally -0.5 through 0.5, must be normalized to the range 0
  214.         through MaxRGB.
  215.       */
  216.       for (i=0; i <= MaxRGB; i++)
  217.       {
  218.         red[i+R]=UpShifted(1.00000)*i;
  219.         green[i+R]=0;
  220.         blue[i+R]=UpShifted(1.13980*0.5)*((i << 1)-MaxRGB);
  221.         red[i+G]=UpShifted(1.00000)*i;
  222.         green[i+G]=(-UpShifted(0.39380*0.5))*((i << 1)-MaxRGB);
  223.         blue[i+G]=(-UpShifted(0.58050*0.5))*((i << 1)-MaxRGB);
  224.         red[i+B]=UpShifted(1.00000)*i;
  225.         green[i+B]=UpShifted(2.02790*0.5)*((i << 1)-MaxRGB);
  226.         blue[i+B]=0;
  227.       }
  228.       break;
  229.     }
  230.   }
  231.   /*
  232.     Convert to RGB.
  233.   */
  234.   switch (image->class)
  235.   {
  236.     case DirectClass:
  237.     {
  238.       /*
  239.         Convert DirectClass image.
  240.       */
  241.       p=image->pixels;
  242.       for (i=0; i < image->packets; i++)
  243.       {
  244.         x=p->red;
  245.         y=p->green;
  246.         z=p->blue;
  247.         p->red=range_limit[DownShift(red[x+R]+green[y+R]+blue[z+R])];
  248.         p->green=range_limit[DownShift(red[x+G]+green[y+G]+blue[z+G])];
  249.         p->blue=range_limit[DownShift(red[x+B]+green[y+B]+blue[z+B])];
  250.         p++;
  251.       }
  252.       break;
  253.     }
  254.     case PseudoClass:
  255.     {
  256.       /*
  257.         Convert PseudoClass image.
  258.       */
  259.       for (i=0; i < image->colors; i++)
  260.       {
  261.         x=image->colormap[i].red;
  262.         y=image->colormap[i].green;
  263.         z=image->colormap[i].blue;
  264.         image->colormap[i].red=
  265.           range_limit[DownShift(red[x+R]+green[y+R]+blue[z+R])];
  266.         image->colormap[i].green=
  267.           range_limit[DownShift(red[x+G]+green[y+G]+blue[z+G])];
  268.         image->colormap[i].blue=
  269.           range_limit[DownShift(red[x+B]+green[y+B]+blue[z+B])];
  270.       }
  271.       p=image->pixels;
  272.       for (i=0; i < image->packets; i++)
  273.       {
  274.         x=p->red;
  275.         y=p->green;
  276.         z=p->blue;
  277.         p->red=range_limit[DownShift(red[x+R]+green[y+R]+blue[z+R])];
  278.         p->green=range_limit[DownShift(red[x+G]+green[y+G]+blue[z+G])];
  279.         p->blue=range_limit[DownShift(red[x+B]+green[y+B]+blue[z+B])];
  280.         p++;
  281.       }
  282.       break;
  283.     }
  284.   }
  285.   /*
  286.     Free allocated memory.
  287.   */
  288.   (void) free((char *) range_table);
  289.   (void) free((char *) blue);
  290.   (void) free((char *) green);
  291.   (void) free((char *) red);
  292. }
  293.