home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 May / PCO_5_97.ISO / FilesBBS / OS2 / WWWCNT15.ARJ / WWWCNT15 / WWWCNT15.ZIP / combine / rgbtran.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-09  |  7.8 KB  |  308 lines

  1. #include "combine.h"
  2. #include "defines.h"
  3.  
  4. /*
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. %                                                                             %
  7. %                                                                             %
  8. %     R G B T r a n s f o r m I m a g e                                       %
  9. %                                                                             %
  10. %                                                                             %
  11. %                                                                             %
  12. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  13. %
  14. %  Procedure RGBTransformImage converts the reference image from RGB to
  15. %  an alternate colorspace.
  16. %
  17. %  The format of the RGBTransformImage routine is:
  18. %
  19. %      RGBTransformImage(image,colorspace)
  20. %
  21. %  A description of each parameter follows:
  22. %
  23. %    o image: The address of a structure of type Image;  returned from
  24. %      ReadImage.
  25. %
  26. %    o colorspace: An unsigned integer value that indicates which colorspace
  27. %      to transform the image.
  28. %
  29. %
  30. */
  31. void RGBTransformImage(image,colorspace)
  32. Image
  33.   *image;
  34.  
  35. unsigned int
  36.   colorspace;
  37. {
  38. #define X 0
  39. #define Y (MaxRGB+1)
  40. #define Z (MaxRGB+1)*2
  41.  
  42.   long
  43.     tx,
  44.     ty,
  45.     tz,
  46.     *x,
  47.     *y,
  48.     *z;
  49.  
  50.   register int
  51.     blue,
  52.     green,
  53.     i,
  54.     red;
  55.  
  56.   register Runlength
  57.     *p;
  58.  
  59.   register unsigned char
  60.     *range_limit;
  61.  
  62.   unsigned char
  63.     *range_table;
  64. fprintf (stderr, "RGBTran: colorspace: %d\n",colorspace);
  65.  
  66.   if (colorspace == RGBColorspace)
  67.     return;
  68.   /*
  69.     Allocate the tables.
  70.   */
  71.   x=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
  72.   y=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
  73.   z=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
  74.   range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
  75.   if ((x == (long *) NULL) || (y == (long *) NULL) ||
  76.       (z == (long *) NULL) || (range_table == (unsigned char *) NULL))
  77.     {
  78.       (void) fprintf (stderr,
  79.         "Unable to transform color space,Memory allocation failed\n");
  80.       return;
  81.     }
  82.   /*
  83.     Pre-compute conversion tables.
  84.   */
  85.   for (i=0; i <= MaxRGB; i++)
  86.   {
  87.     range_table[i]=0;
  88.     range_table[i+(MaxRGB+1)]=(unsigned char) i;
  89.     range_table[i+(MaxRGB+1)*2]=MaxRGB;
  90.   }
  91.   range_limit=range_table+(MaxRGB+1);
  92.   tx=0;
  93.   ty=0;
  94.   tz=0;
  95.   switch (colorspace)
  96.   {
  97.     case GRAYColorspace:
  98.     {
  99.       /*
  100.         Initialize GRAY tables:
  101.  
  102.           G = 0.29900*R+0.58700*G+0.11400*B
  103.       */
  104.       for (i=0; i <= MaxRGB; i++)
  105.       {
  106.         x[i+X]=UpShifted(0.29900)*i;
  107.         y[i+X]=UpShifted(0.58700)*i;
  108.         z[i+X]=UpShifted(0.11400)*i;
  109.         x[i+Y]=UpShifted(0.29900)*i;
  110.         y[i+Y]=UpShifted(0.58700)*i;
  111.         z[i+Y]=UpShifted(0.11400)*i;
  112.         x[i+Z]=UpShifted(0.29900)*i;
  113.         y[i+Z]=UpShifted(0.58700)*i;
  114.         z[i+Z]=UpShifted(0.11400)*i;
  115.       }
  116.       break;
  117.     }
  118.     case OHTAColorspace:
  119.     {
  120.       /*
  121.         Initialize OHTA tables:
  122.  
  123.           I1 = 0.33333*R+0.33334*G+0.33333*B
  124.           I2 = 0.50000*R+0.00000*G-0.50000*B
  125.           I3 =-0.25000*R+0.50000*G-0.25000*B
  126.  
  127.         I and Q, normally -0.5 through 0.5, are normalized to the range 0
  128.         through MaxRGB.
  129.       */
  130.       ty=UpShifted((MaxRGB+1) >> 1);
  131.       tz=UpShifted((MaxRGB+1) >> 1);
  132.       for (i=0; i <= MaxRGB; i++)
  133.       {
  134.         x[i+X]=UpShifted(0.33333)*i;
  135.         y[i+X]=UpShifted(0.33334)*i;
  136.         z[i+X]=UpShifted(0.33333)*i;
  137.         x[i+Y]=UpShifted(0.50000)*i;
  138.         y[i+Y]=0;
  139.         z[i+Y]=(-UpShifted(0.50000))*i;
  140.         x[i+Z]=(-UpShifted(0.25000))*i;
  141.         y[i+Z]=UpShifted(0.50000)*i;
  142.         z[i+Z]=(-UpShifted(0.25000))*i;
  143.       }
  144.       break;
  145.     }
  146.  
  147.     case YCbCrColorspace:
  148.     {
  149.       /*
  150.         Initialize YCbCr tables:
  151.  
  152.           Y =  0.29900*R+0.58700*G+0.11400*B
  153.           Cb= -0.16864*R-0.33126*G+0.50000*B
  154.           Cr=  0.50000*R-0.41869*G-0.08131*B
  155.  
  156.         Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
  157.         through MaxRGB.
  158.       */
  159.       ty=UpShifted((MaxRGB+1) >> 1);
  160.       tz=UpShifted((MaxRGB+1) >> 1);
  161.       for (i=0; i <= MaxRGB; i++)
  162.       {
  163.         x[i+X]=UpShifted(0.29900)*i;
  164.         y[i+X]=UpShifted(0.58700)*i;
  165.         z[i+X]=UpShifted(0.11400)*i;
  166.         x[i+Y]=(-UpShifted(0.16874))*i;
  167.         y[i+Y]=(-UpShifted(0.33126))*i;
  168.         z[i+Y]=UpShifted(0.50000)*i;
  169.         x[i+Z]=UpShifted(0.50000)*i;
  170.         y[i+Z]=(-UpShifted(0.41869))*i;
  171.         z[i+Z]=(-UpShifted(0.08131))*i;
  172.       }
  173.       break;
  174.     }
  175.     case YIQColorspace:
  176.     {
  177.       /*
  178.         Initialize YIQ tables:
  179.  
  180.           Y = 0.29900*R+0.58700*G+0.11400*B
  181.           I = 0.59600*R-0.27400*G-0.32200*B
  182.           Q = 0.21100*R-0.52300*G+0.31200*B
  183.  
  184.         I and Q, normally -0.5 through 0.5, are normalized to the range 0
  185.         through MaxRGB.
  186.       */
  187.       ty=UpShifted((MaxRGB+1) >> 1);
  188.       tz=UpShifted((MaxRGB+1) >> 1);
  189.       for (i=0; i <= MaxRGB; i++)
  190.       {
  191.         x[i+X]=UpShifted(0.29900)*i;
  192.         y[i+X]=UpShifted(0.58700)*i;
  193.         z[i+X]=UpShifted(0.11400)*i;
  194.         x[i+Y]=UpShifted(0.59600)*i;
  195.         y[i+Y]=(-UpShifted(0.27400))*i;
  196.         z[i+Y]=(-UpShifted(0.32200))*i;
  197.         x[i+Z]=UpShifted(0.21100)*i;
  198.         y[i+Z]=(-UpShifted(0.52300))*i;
  199.         z[i+Z]=UpShifted(0.31200)*i;
  200.       }
  201.       break;
  202.     }
  203.     case YUVColorspace:
  204.     default:
  205.     {
  206.       /*
  207.         Initialize YUV tables:
  208.  
  209.           Y =  0.29900*R+0.58700*G+0.11400*B
  210.           U = -0.14740*R-0.28950*G+0.43690*B
  211.           V =  0.61500*R-0.51500*G-0.10000*B
  212.  
  213.         U and V, normally -0.5 through 0.5, are normalized to the range 0
  214.         through MaxRGB.
  215.       */
  216.       ty=UpShifted((MaxRGB+1) >> 1);
  217.       tz=UpShifted((MaxRGB+1) >> 1);
  218.       for (i=0; i <= MaxRGB; i++)
  219.       {
  220.         x[i+X]=UpShifted(0.29900)*i;
  221.         y[i+X]=UpShifted(0.58700)*i;
  222.         z[i+X]=UpShifted(0.11400)*i;
  223.         x[i+Y]=(-UpShifted(0.14740))*i;
  224.         y[i+Y]=(-UpShifted(0.28950))*i;
  225.         z[i+Y]=UpShifted(0.43690)*i;
  226.         x[i+Z]=UpShifted(0.61500)*i;
  227.         y[i+Z]=(-UpShifted(0.51500))*i;
  228.         z[i+Z]=(-UpShifted(0.10000))*i;
  229.       }
  230.       break;
  231.     }
  232.     case XYZColorspace:
  233.     {
  234.       /*
  235.         Initialize XYZ tables:
  236.  
  237.           X = 0.49000*R+0.31000*G+0.20000*B
  238.           Y = 0.17700*R+0.81300*G+0.01100*B
  239.           Z = 0.00000*R+0.01000*G+0.99000*B
  240.       */
  241.       for (i=0; i <= MaxRGB; i++)
  242.       {
  243.         x[i+X]=UpShifted(0.49000)*i;
  244.         y[i+X]=UpShifted(0.31000)*i;
  245.         z[i+X]=UpShifted(0.20000)*i;
  246.         x[i+Y]=UpShifted(0.17700)*i;
  247.         y[i+Y]=UpShifted(0.81300)*i;
  248.         z[i+Y]=UpShifted(0.01100)*i;
  249.         x[i+Z]=0;
  250.         y[i+Z]=UpShifted(0.01000)*i;
  251.         z[i+Z]=UpShifted(0.99000)*i;
  252.       }
  253.       break;
  254.     }
  255.   }
  256.   /*
  257.     Convert from RGB.
  258.   */
  259.   switch (image->class)
  260.   {
  261.     case DirectClass:
  262.     {
  263.       /*
  264.         Convert DirectClass image.
  265.       */
  266.       p=image->pixels;
  267.       for (i=0; i < image->packets; i++)
  268.       {
  269.         red=p->red;
  270.         green=p->green;
  271.         blue=p->blue;
  272.         p->red=range_limit[DownShift(x[red+X]+y[green+X]+z[blue+X]+tx)];
  273.         p->green=range_limit[DownShift(x[red+Y]+y[green+Y]+z[blue+Y]+ty)];
  274.         p->blue=range_limit[DownShift(x[red+Z]+y[green+Z]+z[blue+Z]+tz)];
  275.         p++;
  276.       }
  277.       break;
  278.     }
  279.     case PseudoClass:
  280.     {
  281.       /*
  282.         Convert PseudoClass image.
  283.       */
  284.       for (i=0; i < image->colors; i++)
  285.       {
  286.         red=image->colormap[i].red;
  287.         green=image->colormap[i].green;
  288.         blue=image->colormap[i].blue;
  289.         image->colormap[i].red=
  290.           range_limit[DownShift(x[red+X]+y[green+X]+z[blue+X]+tx)];
  291.         image->colormap[i].green=
  292.           range_limit[DownShift(x[red+Y]+y[green+Y]+z[blue+Y]+ty)];
  293.         image->colormap[i].blue=
  294.           range_limit[DownShift(x[red+Z]+y[green+Z]+z[blue+Z]+tz)];
  295.       }
  296.       SyncImage(image);
  297.       break;
  298.     }
  299.   }
  300.   /*
  301.     Free allocated memory.
  302.   */
  303.   (void) free((char *) range_table);
  304.   (void) free((char *) z);
  305.   (void) free((char *) y);
  306.   (void) free((char *) x);
  307. }
  308.