home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 February / CMCD0205.ISO / Linux / gimp-2.2.0.tar.gz / gimp-2.2.0.tar / gimp-2.2.0 / libgimpcolor / gimprgb.c < prev    next >
C/C++ Source or Header  |  2004-09-17  |  9KB  |  416 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Lesser General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Library General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this library; if not, write to the
  16.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  17.  * Boston, MA 02111-1307, USA.
  18.  */
  19.  
  20. #include "config.h"
  21.  
  22. #include <glib-object.h>
  23.  
  24. #include "libgimpmath/gimpmath.h"
  25.  
  26. #include "gimpcolortypes.h"
  27.  
  28. #include "gimprgb.h"
  29.  
  30.  
  31. /*  RGB type  */
  32.  
  33. static GimpRGB  * rgb_copy  (const GimpRGB *rgb);
  34.  
  35.  
  36. GType
  37. gimp_rgb_get_type (void)
  38. {
  39.   static GType rgb_type = 0;
  40.  
  41.   if (!rgb_type)
  42.     rgb_type = g_boxed_type_register_static ("GimpRGB",
  43.                                              (GBoxedCopyFunc) rgb_copy,
  44.                                              (GBoxedFreeFunc) g_free);
  45.  
  46.   return rgb_type;
  47. }
  48.  
  49. static GimpRGB *
  50. rgb_copy (const GimpRGB *rgb)
  51. {
  52.   return g_memdup (rgb, sizeof (GimpRGB));
  53. }
  54.  
  55.  
  56. /*  RGB functions  */
  57.  
  58. /**
  59.  * gimp_rgb_set:
  60.  * @rgb: a #GimpRGB struct
  61.  * @red:
  62.  * @green:
  63.  * @blue:
  64.  *
  65.  * Sets the red, green and blue components of @rgb and leaves the
  66.  * alpha component unchanged. The color values should be between 0.0
  67.  * and 1.0 but there is no check to enforce this and the values are
  68.  * set exactly as they are passed in.
  69.  **/
  70. void
  71. gimp_rgb_set (GimpRGB *rgb,
  72.           gdouble  r,
  73.           gdouble  g,
  74.           gdouble  b)
  75. {
  76.   g_return_if_fail (rgb != NULL);
  77.  
  78.   rgb->r = r;
  79.   rgb->g = g;
  80.   rgb->b = b;
  81. }
  82.  
  83. /**
  84.  * gimp_rgb_set_alpha:
  85.  * @rgb: a #GimpRGB struct
  86.  * @alpha:
  87.  *
  88.  * Sets the alpha component of @rgb and leaves the RGB components unchanged.
  89.  **/
  90. void
  91. gimp_rgb_set_alpha (GimpRGB *rgb,
  92.             gdouble  a)
  93. {
  94.   g_return_if_fail (rgb != NULL);
  95.  
  96.   rgb->a = a;
  97. }
  98.  
  99. /**
  100.  * gimp_rgb_set_uchar:
  101.  * @rgb: a #GimpRGB struct
  102.  * @red:
  103.  * @green:
  104.  * @blue:
  105.  *
  106.  * Sets the red, green and blue components of @rgb from 8bit values
  107.  * (0 to 255) and leaves the alpha component unchanged.
  108.  **/
  109. void
  110. gimp_rgb_set_uchar (GimpRGB *rgb,
  111.             guchar   r,
  112.             guchar   g,
  113.             guchar   b)
  114. {
  115.   g_return_if_fail (rgb != NULL);
  116.  
  117.   rgb->r = (gdouble) r / 255.0;
  118.   rgb->g = (gdouble) g / 255.0;
  119.   rgb->b = (gdouble) b / 255.0;
  120. }
  121.  
  122. void
  123. gimp_rgb_get_uchar (const GimpRGB *rgb,
  124.             guchar        *r,
  125.             guchar        *g,
  126.             guchar        *b)
  127. {
  128.   g_return_if_fail (rgb != NULL);
  129.  
  130.   if (r) *r = ROUND (CLAMP (rgb->r, 0.0, 1.0) * 255.0);
  131.   if (g) *g = ROUND (CLAMP (rgb->g, 0.0, 1.0) * 255.0);
  132.   if (b) *b = ROUND (CLAMP (rgb->b, 0.0, 1.0) * 255.0);
  133. }
  134.  
  135. void
  136. gimp_rgb_add (GimpRGB       *rgb1,
  137.           const GimpRGB *rgb2)
  138. {
  139.   g_return_if_fail (rgb1 != NULL);
  140.   g_return_if_fail (rgb2 != NULL);
  141.  
  142.   rgb1->r += rgb2->r;
  143.   rgb1->g += rgb2->g;
  144.   rgb1->b += rgb2->b;
  145. }
  146.  
  147. void
  148. gimp_rgb_subtract (GimpRGB       *rgb1,
  149.            const GimpRGB *rgb2)
  150. {
  151.   g_return_if_fail (rgb1 != NULL);
  152.   g_return_if_fail (rgb2 != NULL);
  153.  
  154.   rgb1->r -= rgb2->r;
  155.   rgb1->g -= rgb2->g;
  156.   rgb1->b -= rgb2->b;
  157. }
  158.  
  159. void
  160. gimp_rgb_multiply (GimpRGB *rgb,
  161.            gdouble  factor)
  162. {
  163.   g_return_if_fail (rgb != NULL);
  164.  
  165.   rgb->r *= factor;
  166.   rgb->g *= factor;
  167.   rgb->b *= factor;
  168. }
  169.  
  170. gdouble
  171. gimp_rgb_distance (const GimpRGB *rgb1,
  172.            const GimpRGB *rgb2)
  173. {
  174.   g_return_val_if_fail (rgb1 != NULL, 0.0);
  175.   g_return_val_if_fail (rgb2 != NULL, 0.0);
  176.  
  177.   return (fabs (rgb1->r - rgb2->r) +
  178.       fabs (rgb1->g - rgb2->g) +
  179.       fabs (rgb1->b - rgb2->b));
  180. }
  181.  
  182. gdouble
  183. gimp_rgb_max (const GimpRGB *rgb)
  184. {
  185.   g_return_val_if_fail (rgb != NULL, 0.0);
  186.  
  187.   if (rgb->r > rgb->g)
  188.      return (rgb->r > rgb->b) ? rgb->r : rgb->b;
  189.   return (rgb->g > rgb->b) ? rgb->g : rgb->b;
  190. }
  191.  
  192. gdouble
  193. gimp_rgb_min (const GimpRGB *rgb)
  194. {
  195.   g_return_val_if_fail (rgb != NULL, 0.0);
  196.  
  197.   if (rgb->r < rgb->g)
  198.      return (rgb->r < rgb->b) ? rgb->r : rgb->b;
  199.   return (rgb->g < rgb->b) ? rgb->g : rgb->b;
  200. }
  201.  
  202. void
  203. gimp_rgb_clamp (GimpRGB *rgb)
  204. {
  205.   g_return_if_fail (rgb != NULL);
  206.  
  207.   rgb->r = CLAMP (rgb->r, 0.0, 1.0);
  208.   rgb->g = CLAMP (rgb->g, 0.0, 1.0);
  209.   rgb->b = CLAMP (rgb->b, 0.0, 1.0);
  210.   rgb->a = CLAMP (rgb->a, 0.0, 1.0);
  211. }
  212.  
  213. void
  214. gimp_rgb_gamma (GimpRGB *rgb,
  215.         gdouble  gamma)
  216. {
  217.   gdouble ig;
  218.  
  219.   g_return_if_fail (rgb != NULL);
  220.  
  221.   if (gamma != 0.0)
  222.     ig = 1.0 / gamma;
  223.   else
  224.     ig = 0.0;
  225.  
  226.   rgb->r = pow (rgb->r, ig);
  227.   rgb->g = pow (rgb->g, ig);
  228.   rgb->b = pow (rgb->b, ig);
  229. }
  230.  
  231. gdouble
  232. gimp_rgb_intensity (const GimpRGB *rgb)
  233. {
  234.   gdouble intensity;
  235.  
  236.   g_return_val_if_fail (rgb != NULL, 0.0);
  237.  
  238.   intensity = GIMP_RGB_INTENSITY (rgb->r, rgb->g, rgb->b);
  239.  
  240.   return CLAMP (intensity, 0.0, 1.0);
  241. }
  242.  
  243. guchar
  244. gimp_rgb_intensity_uchar (const GimpRGB *rgb)
  245. {
  246.   g_return_val_if_fail (rgb != NULL, 0);
  247.  
  248.   return ROUND (gimp_rgb_intensity (rgb) * 255.0);
  249. }
  250.  
  251. void
  252. gimp_rgb_composite (GimpRGB              *color1,
  253.             const GimpRGB        *color2,
  254.             GimpRGBCompositeMode  mode)
  255. {
  256.   gdouble factor;
  257.  
  258.   g_return_if_fail (color1 != NULL);
  259.   g_return_if_fail (color2 != NULL);
  260.  
  261.   switch (mode)
  262.     {
  263.     case GIMP_RGB_COMPOSITE_NONE:
  264.       break;
  265.  
  266.     case GIMP_RGB_COMPOSITE_NORMAL:
  267.       /*  put color2 on top of color1  */
  268.       if (color2->a == 1.0)
  269.     {
  270.       *color1 = *color2;
  271.     }
  272.       else
  273.     {
  274.       factor = color1->a * (1.0 - color2->a);
  275.       color1->r = color1->r * factor + color2->r * color2->a;
  276.       color1->g = color1->g * factor + color2->g * color2->a;
  277.       color1->b = color1->b * factor + color2->b * color2->a;
  278.       color1->a = factor + color2->a;
  279.     }
  280.       break;
  281.  
  282.     case GIMP_RGB_COMPOSITE_BEHIND:
  283.       /*  put color2 below color1  */
  284.       if (color1->a < 1.0)
  285.     {
  286.       factor = color2->a * (1.0 - color1->a);
  287.       color1->r = color2->r * factor + color1->r * color1->a;
  288.       color1->g = color2->g * factor + color1->g * color1->a;
  289.       color1->b = color2->b * factor + color1->b * color1->a;
  290.       color1->a = factor + color1->a;
  291.     }
  292.       break;
  293.     }
  294. }
  295.  
  296. /*  RGBA functions  */
  297.  
  298. /**
  299.  * gimp_rgba_set:
  300.  * @rgba: a #GimpRGB struct
  301.  * @red:
  302.  * @green:
  303.  * @blue:
  304.  * @alpha:
  305.  *
  306.  * Sets the red, green, blue and alpha components of @rgb. The values
  307.  * should be between 0.0 and 1.0 but there is no check to enforce this
  308.  * and the values are set exactly as they are passed in.
  309.  **/
  310. void
  311. gimp_rgba_set (GimpRGB *rgba,
  312.            gdouble  r,
  313.            gdouble  g,
  314.            gdouble  b,
  315.            gdouble  a)
  316. {
  317.   g_return_if_fail (rgba != NULL);
  318.  
  319.   rgba->r = r;
  320.   rgba->g = g;
  321.   rgba->b = b;
  322.   rgba->a = a;
  323. }
  324.  
  325. /**
  326.  * gimp_rgba_set_uchar:
  327.  * @rgba: a #GimpRGB struct
  328.  * @red:
  329.  * @green:
  330.  * @blue:
  331.  * @alpha:
  332.  *
  333.  * Sets the red, green, blue and alpha components of @rgb from 8bit
  334.  * values (0 to 255).
  335.  **/
  336. void
  337. gimp_rgba_set_uchar (GimpRGB *rgba,
  338.              guchar   r,
  339.              guchar   g,
  340.              guchar   b,
  341.              guchar   a)
  342. {
  343.   g_return_if_fail (rgba != NULL);
  344.  
  345.   rgba->r = (gdouble) r / 255.0;
  346.   rgba->g = (gdouble) g / 255.0;
  347.   rgba->b = (gdouble) b / 255.0;
  348.   rgba->a = (gdouble) a / 255.0;
  349. }
  350.  
  351. void
  352. gimp_rgba_get_uchar (const GimpRGB *rgba,
  353.              guchar        *r,
  354.              guchar        *g,
  355.              guchar        *b,
  356.              guchar        *a)
  357. {
  358.   g_return_if_fail (rgba != NULL);
  359.  
  360.   if (r) *r = ROUND (CLAMP (rgba->r, 0.0, 1.0) * 255.0);
  361.   if (g) *g = ROUND (CLAMP (rgba->g, 0.0, 1.0) * 255.0);
  362.   if (b) *b = ROUND (CLAMP (rgba->b, 0.0, 1.0) * 255.0);
  363.   if (a) *a = ROUND (CLAMP (rgba->a, 0.0, 1.0) * 255.0);
  364. }
  365.  
  366. void
  367. gimp_rgba_add (GimpRGB       *rgba1,
  368.            const GimpRGB *rgba2)
  369. {
  370.   g_return_if_fail (rgba1 != NULL);
  371.   g_return_if_fail (rgba2 != NULL);
  372.  
  373.   rgba1->r += rgba2->r;
  374.   rgba1->g += rgba2->g;
  375.   rgba1->b += rgba2->b;
  376.   rgba1->a += rgba2->a;
  377. }
  378.  
  379. void
  380. gimp_rgba_subtract (GimpRGB       *rgba1,
  381.             const GimpRGB *rgba2)
  382. {
  383.   g_return_if_fail (rgba1 != NULL);
  384.   g_return_if_fail (rgba2 != NULL);
  385.  
  386.   rgba1->r -= rgba2->r;
  387.   rgba1->g -= rgba2->g;
  388.   rgba1->b -= rgba2->b;
  389.   rgba1->a -= rgba2->a;
  390. }
  391.  
  392. void
  393. gimp_rgba_multiply (GimpRGB *rgba,
  394.             gdouble  factor)
  395. {
  396.   g_return_if_fail (rgba != NULL);
  397.  
  398.   rgba->r *= factor;
  399.   rgba->g *= factor;
  400.   rgba->b *= factor;
  401.   rgba->a *= factor;
  402. }
  403.  
  404. gdouble
  405. gimp_rgba_distance (const GimpRGB *rgba1,
  406.             const GimpRGB *rgba2)
  407. {
  408.   g_return_val_if_fail (rgba1 != NULL, 0.0);
  409.   g_return_val_if_fail (rgba2 != NULL, 0.0);
  410.  
  411.   return (fabs (rgba1->r - rgba2->r) +
  412.           fabs (rgba1->g - rgba2->g) +
  413.           fabs (rgba1->b - rgba2->b) +
  414.           fabs (rgba1->a - rgba2->a));
  415. }
  416.