home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / source / colorw.lha / hsl.c < prev    next >
C/C++ Source or Header  |  1987-10-12  |  4KB  |  158 lines

  1.  
  2. /* *** hsl.c ****************************************************************
  3.  *
  4.  * ColorWindow Routine  --  HSL Translation Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * HISTORY      NAME            DESCRIPTION
  15.  * -----------  --------------  --------------------------------------------
  16.  * 3 Jan 87     RJ >:-{)*       Clean-up for release      
  17.  * 27 Feb 86    =RJ Mical=      Modified these routines for Zaphod
  18.  * January 86   =RJ=            Modified the originals for Mandelbrot
  19.  * Late 85      =RJ=            Created the color window for Graphicraft
  20.  *
  21.  * *********************************************************************** */
  22.  
  23.  
  24. #include "color.h"
  25.  
  26.  
  27. SHORT HSLToRGB(hue, saturation, luminance)
  28. USHORT hue, saturation, luminance;
  29. /* This actually doesn't do true HSL to RGB conversion, but it works
  30.  * close enough.  Also, this code could be optimized quite a bit, but
  31.  * I've left it spread out like this so that several years from now 
  32.  * I will be able to figure out what the heck is going on.
  33.  */
  34. {
  35.    LONG red, green, blue;
  36.    LONG reddiff, greendiff, bluediff;
  37.    LONG sixth, rising, falling, invertsaturation;
  38.  
  39.    /* We're going to hold one color off, a second at full, and ramp  
  40.     * the third.  This allows us to visit all two-color combinations.
  41.     * By modifying saturation, all three-color combinations can be seen.
  42.     */
  43.    sixth = hue / 0x2AAB;
  44.    rising = (hue - (sixth * 0x2AAB)) * 6;
  45.    falling = 0xFFFF - rising;
  46.  
  47.    switch (sixth)
  48.       {
  49.       case 0:
  50.          red = 0xFFFF;
  51.          green = rising;
  52.          blue = 0;
  53.          break;
  54.       case 1:
  55.          red = falling;
  56.          green = 0xFFFF;
  57.          blue = 0;
  58.          break;
  59.       case 2:
  60.          red = 0;
  61.          green = 0xFFFF;
  62.          blue = rising;
  63.          break;
  64.       case 3:
  65.          red = 0;
  66.          green = falling;
  67.          blue = 0xFFFF;
  68.          break;
  69.       case 4:
  70.          red = rising;
  71.          green = 0;
  72.          blue = 0xFFFF;
  73.          break;
  74.       case 5:
  75.          red = 0xFFFF;
  76.          green = 0;
  77.          blue = falling;
  78.          break;
  79.       }
  80.  
  81.    red = (red * luminance) >> 16;
  82.    green = (green * luminance) >> 16;
  83.    blue = (blue * luminance) >> 16;
  84.  
  85.    /* The closer saturation is to zero, the closer red, green and blue should
  86.     * be to luminance.
  87.     */
  88.    invertsaturation = 0xFFFF - saturation;
  89.    reddiff = luminance - red;
  90.    red = red + ((reddiff * invertsaturation) >> 16);
  91.    greendiff = luminance - green;
  92.    green = green + ((greendiff * invertsaturation) >> 16);
  93.    bluediff = luminance - blue;
  94.    blue = blue + ((bluediff * invertsaturation) >> 16);
  95.  
  96.    red = (red >> 12) & 0xF;
  97.    green = (green >> 12) & 0xF;
  98.    blue = (blue >> 12) & 0xF;
  99.  
  100.    return( (SHORT)((red << 8) | (green << 4) | (blue)) );
  101. }
  102.  
  103.  
  104.  
  105. VOID RGBToHSL(rgb, returnhue, returnsat, returnlum)
  106. USHORT rgb;
  107. USHORT *returnhue, *returnsat, *returnlum;
  108. {
  109.    LONG min, max, hue, saturation, luminance, differential;
  110.    LONG redpart, greenpart, bluepart;
  111.    LONG workred, workgreen, workblue;
  112.  
  113.    workred = ((rgb >> 8) & 0xF) * 0x111;
  114.    workgreen = ((rgb >> 4) & 0xF) * 0x111;
  115.    workblue = (rgb & 0xF) * 0x111;
  116.  
  117.    if (workred < workgreen) min = workred;
  118.    else min = workgreen;
  119.    if (workblue < min) min = workblue;
  120.  
  121.    if (workred > workgreen) max = workred;
  122.    else max = workgreen;
  123.    if (workblue > max) max = workblue;
  124.  
  125.    luminance = max;
  126.    luminance <<= 4;
  127.    differential = max - min;
  128.  
  129.    if (max != 0)
  130.       {
  131.       saturation = (differential << 16) / max;
  132.       if (saturation > 0xFFFF) saturation = 0xFFFF;
  133.       }
  134.    else 
  135.       saturation = 0;
  136.  
  137.    if (saturation == 0)
  138.       hue = 0;
  139.    else
  140.       {
  141.       redpart = (((max - workred) << 16) / differential) >> 4;
  142.       greenpart = (((max - workgreen) << 16) / differential) >> 4;
  143.       bluepart = (((max - workblue) << 16) / differential) >> 4;
  144.  
  145.       if (workred == max) hue = bluepart - greenpart;
  146.       else if (workgreen == max) hue = 0x2000 + redpart - bluepart;
  147.       else if (workblue == max) hue = 0x4000 + greenpart - redpart;
  148.       if (hue < 0) hue += 0x6000;
  149.       hue = (hue * 2667) / 1000;
  150.       }
  151.  
  152.    *returnhue = hue;
  153.    *returnsat = saturation;
  154.    *returnlum = luminance;
  155. }
  156.  
  157.  
  158.