library of assembled shared sources

http://lass.cocamware.com

color_rgba.cpp

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 #include "prim_common.h"
00045 #include "color_rgba.h"
00046 #include "vector_3d.h"
00047 
00048 // for this translation unit, we don't want any warnings on numerical conversions.
00049 #if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
00050 #   pragma warning(disable: 4305 4244)
00051 #endif
00052 
00053 namespace lass
00054 {
00055 namespace prim
00056 {
00057 
00058 
00059 
00060 // --- public --------------------------------------------------------------------------------------
00061 
00062 /** construct an unexisting color (black with zero alpha)
00063  */
00064 ColorRGBA::ColorRGBA():
00065     r(TNumTraits::zero),
00066     g(TNumTraits::zero),
00067     b(TNumTraits::zero),
00068     a(TNumTraits::zero)
00069 {
00070     LASS_ASSERT(isZero());
00071 }
00072 
00073 
00074 
00075 /** construct a color with values for all channels
00076  */
00077 ColorRGBA::ColorRGBA(TParam iRed, TParam iGreen, TParam iBlue, TParam iAlpha):
00078     r(iRed),
00079     g(iGreen),
00080     b(iBlue),
00081     a(iAlpha)
00082 {
00083 }
00084 
00085 
00086 
00087 /** construct a color in white range (r == g == b),  with an alpha value
00088  */
00089 ColorRGBA::ColorRGBA(TParam iWhite, TParam iAlpha):
00090     r(iWhite),
00091     g(iWhite),
00092     b(iWhite),
00093     a(iAlpha)
00094 {
00095 }
00096 
00097 
00098 
00099 /** construct a color from a raw vector
00100  */
00101 ColorRGBA::ColorRGBA(const TVector& iVector):
00102     r(iVector.x),
00103     g(iVector.y),
00104     b(iVector.z),
00105     a(iVector.w)
00106 {
00107 }
00108 
00109 
00110 
00111 /** @e raw addition of @a iOther to this color, including alpha channel
00112  */
00113 ColorRGBA& ColorRGBA::operator+=(const ColorRGBA& iOther)
00114 {
00115     r += iOther.r;
00116     g += iOther.g;
00117     b += iOther.b;
00118     a += iOther.a;
00119     return *this;
00120 }
00121 
00122 
00123 
00124 /** @e raw subtraction @a iOther from this color, including alpha channel
00125  */
00126 ColorRGBA& ColorRGBA::operator-=(const ColorRGBA& iOther)
00127 {
00128     r -= iOther.r;
00129     g -= iOther.g;
00130     b -= iOther.b;
00131     a -= iOther.a;
00132     return *this;
00133 }
00134 
00135 
00136 
00137 /** @e raw multiplication of @a iOther with this color, including alpha channel
00138  */
00139 ColorRGBA& ColorRGBA::operator*=(const ColorRGBA& iOther)
00140 {
00141     r *= iOther.r;
00142     g *= iOther.g;
00143     b *= iOther.b;
00144     a *= iOther.a;
00145     return *this;
00146 }
00147 
00148 
00149 
00150 /** @e raw division of this color by @a iOther, including alpha channel
00151  */
00152 ColorRGBA& ColorRGBA::operator/=(const ColorRGBA& iOther)
00153 {
00154     r /= iOther.r;
00155     g /= iOther.g;
00156     b /= iOther.b;
00157     a /= iOther.a;
00158     return *this;
00159 }
00160 
00161 
00162 
00163 /** @e raw addition of @a iWhite to this color, including alpha channel
00164  */
00165 ColorRGBA& ColorRGBA::operator+=(TParam iWhite)
00166 {
00167     r += iWhite;
00168     g += iWhite;
00169     b += iWhite;
00170     a += iWhite;
00171     return *this;
00172 }
00173 
00174 
00175 
00176 /** @e raw subtraction @a iWhite from this color, including alpha channel
00177  */
00178 ColorRGBA& ColorRGBA::operator-=(TParam iWhite)
00179 {
00180     r -= iWhite;
00181     g -= iWhite;
00182     b -= iWhite;
00183     a -= iWhite;
00184     return *this;
00185 }
00186 
00187 
00188 
00189 /** @e raw multiplication of @a iWhite with this color, including alpha channel
00190  */
00191 ColorRGBA& ColorRGBA::operator*=(TParam iWhite)
00192 {
00193     r *= iWhite;
00194     g *= iWhite;
00195     b *= iWhite;
00196     a *= iWhite;
00197     return *this;
00198 }
00199 
00200 
00201 
00202 /** @e raw division of this color by @a iWhite, including alpha channel
00203  */
00204 ColorRGBA& ColorRGBA::operator/=(TParam iWhite)
00205 {
00206     const TValue invWhite = TNumTraits::one / iWhite;
00207     r *= invWhite;
00208     g *= invWhite;
00209     b *= invWhite;
00210     a *= invWhite;
00211     return *this;
00212 }
00213 
00214 
00215 
00216 const ColorRGBA::TValue ColorRGBA::brightness() const
00217 {
00218     return (r + g + b) / 3;
00219 }
00220 
00221 
00222 
00223 /** return true if all color components are zero
00224  */
00225 const bool ColorRGBA::isBlack() const
00226 {
00227     return r == TNumTraits::zero && g == TNumTraits::zero && b == TNumTraits::zero;
00228 }
00229 
00230 
00231 
00232 /** return true if all components are zero
00233  */
00234 const bool ColorRGBA::isZero() const
00235 {
00236     return r == TNumTraits::zero && g == TNumTraits::zero && b == TNumTraits::zero &&
00237         a == TNumTraits::zero;
00238 }
00239 
00240 
00241 
00242 /** Return true if at least one of the components is NaN
00243  */
00244 const bool ColorRGBA::isNaN() const
00245 {
00246     return num::isNaN(r) || num::isNaN(g) || num::isNaN(b) || num::isNaN(a);
00247 }
00248 
00249 
00250 
00251 /** return darkened colour without changing the opaqueness.
00252  *
00253  *  @pre @a *this are considered non-premultiplied
00254  *
00255  *  @code
00256  *  alphaR = alphaA.
00257  *  ColorR = ColorA * darkenFactor.
00258  *  @endcode
00259  *
00260  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00261  */
00262 const ColorRGBA ColorRGBA::darkened(ColorRGBA::TParam iFactor) const
00263 {
00264     ColorRGBA result(*this);
00265     result *= iFactor;
00266     result.a = a;
00267     return result;
00268 }
00269 
00270 
00271 
00272 /** return color with dissolved opaqueness
00273  *
00274  *  @pre @a iA and @a iB are considered non-premultiplied
00275  *
00276  *  @code
00277  *  alphaR = alphaA * dissolveFactor.
00278  *  ColorR = ColorA.
00279  *  @endcode
00280  *
00281  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00282  */
00283 const ColorRGBA ColorRGBA::dissolved(TParam iFactor) const
00284 {
00285     ColorRGBA result(*this);
00286     result.a *= iFactor;
00287     return result;
00288 }
00289 
00290 
00291 
00292 /** return gamma corrected color.
00293  *
00294  *  corrects gamma of all channels, except alpha.
00295  *
00296  *  @pre @a iA and @a iB are considered non-premultiplied
00297  *
00298  *  @code
00299  *  alphaR = alphaA.
00300  *  ColorR = ColorA ** (1 / gamma).
00301  *  @endcode
00302  */
00303 const ColorRGBA ColorRGBA::gammaCorrected(TParam iGammaExponent) const
00304 {
00305     const TValue invGamma = num::inv(iGammaExponent);
00306     return ColorRGBA(num::pow(r, invGamma), num::pow(g, invGamma), num::pow(b, invGamma), a);
00307 }
00308 
00309 
00310 
00311 /** return exposed color.
00312  *
00313  *  apply exposure function to color and clamp alpha channel
00314  *
00315  *  @pre @a iA and @a iB are considered non-premultiplied
00316  *  @post: all channel values ar in the range [0, 1].
00317  *
00318  *  @code
00319  *  alphaR = alphaA.
00320  *  ColorR = 1 - exp(-time * ColorA).
00321  *  @endcode
00322  */
00323 const ColorRGBA ColorRGBA::exposed(TParam iExposureTime) const
00324 {
00325     const TValue f = -iExposureTime;
00326     return ColorRGBA(
00327         num::clamp(TNumTraits::one - num::exp(f * r), TNumTraits::zero, TNumTraits::one),
00328         num::clamp(TNumTraits::one - num::exp(f * g), TNumTraits::zero, TNumTraits::one),
00329         num::clamp(TNumTraits::one - num::exp(f * b), TNumTraits::zero, TNumTraits::one),
00330         num::clamp(a, TNumTraits::zero, TNumTraits::one));
00331 }
00332 
00333 
00334 
00335 /** return result of inverse exposure function
00336  *
00337  *  apply inverse of exposure function to color and clamp alpha channel
00338  *
00339  *  @pre @a iA and @a iB are considered non-premultiplied
00340  *  @post: all channel values ar in the range [0, 1].
00341  *
00342  *  @code
00343  *  alphaR = alphaA.
00344  *  ColorR = log(1 - colorA) / -time
00345  *  @endcode
00346  */
00347 const ColorRGBA ColorRGBA::invExposed(TParam iExposureTime) const
00348 {
00349     const TValue f =  num::inv(-iExposureTime);
00350     return ColorRGBA(
00351         f * num::log(num::clamp(TNumTraits::one - r, TNumTraits::minStrictPositive, TNumTraits::one)),
00352         f * num::log(num::clamp(TNumTraits::one - g, TNumTraits::minStrictPositive, TNumTraits::one)),
00353         f * num::log(num::clamp(TNumTraits::one - b, TNumTraits::minStrictPositive, TNumTraits::one)),
00354         a);
00355 }
00356 
00357 
00358 
00359 /** clamp all channels (including alpha channel) to the range [0, 1].
00360  *  @post: all channel values ar in the range [0, 1].
00361  */
00362 const ColorRGBA ColorRGBA::clamped() const
00363 {
00364     return ColorRGBA(
00365         num::clamp(r, TNumTraits::zero, TNumTraits::one),
00366         num::clamp(g, TNumTraits::zero, TNumTraits::one),
00367         num::clamp(b, TNumTraits::zero, TNumTraits::one),
00368         num::clamp(a, TNumTraits::zero, TNumTraits::one));
00369 }
00370 
00371 
00372 
00373 /** convert a value in range [0, 1] to a color like in colormap 'autumn' of matlab.
00374  */
00375 const ColorRGBA ColorRGBA::mapAutumn(TParam iValue)
00376 {
00377     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00378     return ColorRGBA(TNumTraits::one, iValue, TNumTraits::zero);
00379 }
00380 
00381 
00382 
00383 /** convert a value in range [0, 1] to a color like in colormap 'bone' of matlab.
00384  */
00385 const ColorRGBA ColorRGBA::mapBone(TParam iValue)
00386 {
00387     const static ColorRGBA keys[] =
00388     {
00389         ColorRGBA(0.    , 0.    , 0.    ),
00390         ColorRGBA(0.3194, 0.3194, 0.4444),
00391         ColorRGBA(0.6528, 0.7778, 0.7778),
00392         ColorRGBA(1.    , 1.    , 1.    )
00393     };
00394     return doMap(iValue, keys, 4);
00395 }
00396 
00397 
00398 
00399 /** convert a value in range [0, 1] to a color like in colormap 'cool' of matlab.
00400  */
00401 const ColorRGBA ColorRGBA::mapCool(TParam iValue)
00402 {
00403     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00404     return ColorRGBA(iValue, TNumTraits::one - iValue, TNumTraits::one);
00405 }
00406 
00407 
00408 
00409 /** convert a value in range [0, 1] to a color like in colormap 'copper' of matlab.
00410  */
00411 const ColorRGBA ColorRGBA::mapCopper(TParam iValue)
00412 {
00413     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00414     return ColorRGBA(iValue < .8 ? iValue / .8 : 1., .8 * iValue, .5 * iValue);
00415 }
00416 
00417 
00418 
00419 /** convert a value in range [0, 1] to a color like in colormap 'gray' of matlab.
00420  */
00421 const ColorRGBA ColorRGBA::mapGray(TParam iValue)
00422 {
00423     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00424     return ColorRGBA(iValue);
00425 }
00426 
00427 
00428 
00429 /** convert a value in range [0, 1] to a color like in colormap 'hot' of matlab.
00430  */
00431 const ColorRGBA ColorRGBA::mapHot(TParam iValue)
00432 {
00433     const static ColorRGBA keys[] =
00434     {
00435         ColorRGBA(0.     , 0.     , 0.),
00436         ColorRGBA(1. / 3., 0.     , 0.),
00437         ColorRGBA(2. / 3., 0.     , 0.),
00438         ColorRGBA(1.     , 0.     , 0.),
00439         ColorRGBA(1.     , 1. / 3., 0.),
00440         ColorRGBA(1.     , 2. / 3., 0.),
00441         ColorRGBA(1.     , 1.     , 0.),
00442         ColorRGBA(1.     , 1.     , .5),
00443         ColorRGBA(1.     , 1.     , 1.)
00444     };
00445     return doMap(iValue, keys, 9);
00446 }
00447 
00448 
00449 
00450 /** convert a value to a color like in colormap 'hsv' of matlab.
00451  */
00452 const ColorRGBA ColorRGBA::mapHsv(TParam iValue)
00453 {
00454     const static ColorRGBA keys[] =
00455     {
00456         ColorRGBA(1., 0., 0.),
00457         ColorRGBA(1., 1., 0.),
00458         ColorRGBA(0., 1., 0.),
00459         ColorRGBA(0., 1., 1.),
00460         ColorRGBA(0., 0., 1.),
00461         ColorRGBA(1., 0., 1.),
00462         ColorRGBA(1., 0., 0.)
00463     };
00464     return doMap(iValue - num::floor(iValue), keys, 7);
00465 }
00466 
00467 
00468 
00469 /** convert a value in range [0, 1] to a color like in colormap 'jet' of matlab.
00470  */
00471 const ColorRGBA ColorRGBA::mapJet(TParam iValue)
00472 {
00473     const static ColorRGBA keys[] =
00474     {
00475         ColorRGBA(0., 0., .5), // 240
00476         ColorRGBA(0., 0., 1.), // 240
00477         ColorRGBA(0., .5, 1.), // 210
00478         ColorRGBA(0., 1., 1.), // 180
00479         ColorRGBA(.5, 1., .5), // 90
00480         ColorRGBA(1., 1., 0.), // 60
00481         ColorRGBA(1., .5, 0.), // 30
00482         ColorRGBA(1., .0, 0.), // 0
00483         ColorRGBA(.5, .0, 0.)  // 0
00484     };
00485 
00486     return doMap(iValue, keys, 9);
00487 }
00488 
00489 
00490 
00491 /** convert a value in range [0, 1] to a color like in colormap 'pink' of matlab.
00492  */
00493 const ColorRGBA ColorRGBA::mapPink(TParam iValue)
00494 {
00495     const static ColorRGBA keys[] =
00496     {
00497         ColorRGBA(0.    , 0.    , 0.    ),
00498         ColorRGBA(0.2955, 0.1782, 0.1782),
00499         ColorRGBA(0.4303, 0.2722, 0.2722),
00500         ColorRGBA(0.5320, 0.3412, 0.3412),
00501         ColorRGBA(0.6172, 0.3984, 0.3984),
00502         ColorRGBA(0.6920, 0.4484, 0.4484),
00503         ColorRGBA(0.7594, 0.4933, 0.4933),
00504         ColorRGBA(0.7868, 0.5842, 0.5345),
00505         ColorRGBA(0.8133, 0.6627, 0.5727),
00506         ColorRGBA(0.8389, 0.7328, 0.6086),
00507         ColorRGBA(0.8637, 0.7968, 0.6424),
00508         ColorRGBA(0.8879, 0.8560, 0.6746),
00509         ColorRGBA(0.9114, 0.9114, 0.7052),
00510         ColorRGBA(0.9344, 0.9344, 0.7893),
00511         ColorRGBA(0.9567, 0.9567, 0.8653),
00512         ColorRGBA(0.9786, 0.9786, 0.9351),
00513         ColorRGBA(1.    , 1.    , 1.    ),
00514     };
00515     return doMap(iValue, keys, 17);
00516 }
00517 
00518 
00519 
00520 /** convert a value in range [0, 1] to a color like in colormap 'spring' of matlab.
00521  */
00522 const ColorRGBA ColorRGBA::mapSpring(TParam iValue)
00523 {
00524     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00525     return ColorRGBA(TNumTraits::one, iValue, TNumTraits::one - iValue);
00526 }
00527 
00528 
00529 
00530 /** convert a value in range [0, 1] to a color like in colormap 'summer' of matlab.
00531  */
00532 const ColorRGBA ColorRGBA::mapSummer(TParam iValue)
00533 {
00534     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00535     return ColorRGBA(iValue, (TNumTraits::one + iValue) / 2, 0.4 * TNumTraits::one);
00536 }
00537 
00538 
00539 
00540 /** convert a value in range [0, 1] to a color like in colormap 'winter' of matlab.
00541  */
00542 const ColorRGBA ColorRGBA::mapWinter(TParam iValue)
00543 {
00544     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00545     return ColorRGBA(0, TNumTraits::one - iValue, TNumTraits::one / 2);
00546 }
00547 
00548 
00549 
00550 /** convert a value in range [0, 1] to a color from a custom color map.
00551  */
00552 const ColorRGBA ColorRGBA::mapCustom(TParam iValue, const std::vector<ColorRGBA>& iColorMap)
00553 {
00554     LASS_ASSERT(static_cast<int>(iColorMap.size()) >= 0);
00555     return doMap(iValue, &iColorMap[0], static_cast<int>(iColorMap.size()));
00556 }
00557 
00558 
00559 
00560 // --- protected -----------------------------------------------------------------------------------
00561 
00562 
00563 
00564 // --- private -------------------------------------------------------------------------------------
00565 
00566 const ColorRGBA ColorRGBA::doMap(TParam iValue, const ColorRGBA* iMap, int iMapSize)
00567 {
00568     LASS_ASSERT(iMapSize > 1);
00569 
00570     num::inpclamp(iValue, TNumTraits::zero, TNumTraits::one);
00571     const TValue x = iValue * (iMapSize - 1);
00572     const TValue x0 = num::floor(x);
00573 
00574     const int i = static_cast<int>(x0);
00575     LASS_ASSERT(i >= 0 && i < iMapSize);
00576 
00577     if (i == iMapSize - 1)
00578     {
00579         return iMap[i];
00580     }
00581 
00582     const TValue dx = x - x0;
00583     return iMap[i] * (TNumTraits::one - dx) + iMap[i + 1] * dx;
00584 }
00585 
00586 // --- free ----------------------------------------------------------------------------------------
00587 
00588 /** raw addition of @a iA and @a iB, including alpha channels
00589  *  @relates lass::prim::ColorRGBA
00590  */
00591 ColorRGBA operator+(const ColorRGBA& iA, const ColorRGBA& iB)
00592 {
00593     ColorRGBA result(iA);
00594     result += iB;
00595     return result;
00596 }
00597 
00598 
00599 
00600 /** raw subtraction of @a iA and @a iB, including alpha channels
00601  *  @relates lass::prim::ColorRGBA
00602  */
00603 ColorRGBA operator-(const ColorRGBA& iA, const ColorRGBA& iB)
00604 {
00605     ColorRGBA result(iA);
00606     result -= iB;
00607     return result;
00608 }
00609 
00610 
00611 
00612 /** raw addition of @a iA and @a iB, including alpha channels
00613  *  @relates lass::prim::ColorRGBA
00614  */
00615 ColorRGBA operator*(const ColorRGBA& iA, const ColorRGBA& iB)
00616 {
00617     ColorRGBA result(iA);
00618     result *= iB;
00619     return result;
00620 }
00621 
00622 
00623 
00624 /** raw addition of @a iA and @a iB, including alpha channels
00625  *  @relates lass::prim::ColorRGBA
00626  */
00627 ColorRGBA operator/(const ColorRGBA& iA, const ColorRGBA& iB)
00628 {
00629     ColorRGBA result(iA);
00630     result /= iB;
00631     return result;
00632 }
00633 
00634 
00635 
00636 /** raw addition of @a iA and @a iB, including alpha channels
00637  *  @relates lass::prim::ColorRGBA
00638  */
00639 ColorRGBA operator+(ColorRGBA::TParam iA, const ColorRGBA& iB)
00640 {
00641     ColorRGBA result(iB);
00642     result += iA;
00643     return result;
00644 }
00645 
00646 
00647 
00648 /** raw subtraction of @a iA and @a iB, including alpha channels
00649  *  @relates lass::prim::ColorRGBA
00650  */
00651 ColorRGBA operator-(ColorRGBA::TParam iA, const ColorRGBA& iB)
00652 {
00653     ColorRGBA result(iA);
00654     result -= iB;
00655     return result;
00656 }
00657 
00658 
00659 
00660 /** raw addition of @a iA and @a iB, including alpha channels
00661  *  @relates lass::prim::ColorRGBA
00662  */
00663 ColorRGBA operator*(ColorRGBA::TParam iA, const ColorRGBA& iB)
00664 {
00665     ColorRGBA result(iB);
00666     result *= iA;
00667     return result;
00668 }
00669 
00670 
00671 
00672 /** raw addition of @a iA and @a iB, including alpha channels
00673  *  @relates lass::prim::ColorRGBA
00674  */
00675 ColorRGBA operator/(ColorRGBA::TParam iA, const ColorRGBA& iB)
00676 {
00677     ColorRGBA result(iA);
00678     result /= iB;
00679     return result;
00680 }
00681 
00682 
00683 
00684 /** raw addition of @a iA and @a iB, including alpha channels
00685  *  @relates lass::prim::ColorRGBA
00686  */
00687 ColorRGBA operator+(const ColorRGBA& iA, ColorRGBA::TParam iB)
00688 {
00689     ColorRGBA result(iA);
00690     result += iB;
00691     return result;
00692 }
00693 
00694 
00695 
00696 /** raw subtraction of @a iA and @a iB, including alpha channels
00697  *  @relates lass::prim::ColorRGBA
00698  */
00699 ColorRGBA operator-(const ColorRGBA& iA, ColorRGBA::TParam iB)
00700 {
00701     ColorRGBA result(iA);
00702     result -= iB;
00703     return result;
00704 }
00705 
00706 
00707 
00708 /** raw addition of @a iA and @a iB, including alpha channels
00709  *  @relates lass::prim::ColorRGBA
00710  */
00711 ColorRGBA operator*(const ColorRGBA& iA, ColorRGBA::TParam iB)
00712 {
00713     ColorRGBA result(iA);
00714     result *= iB;
00715     return result;
00716 }
00717 
00718 
00719 
00720 /** raw addition of @a iA and @a iB, including alpha channels
00721  *  @relates lass::prim::ColorRGBA
00722  */
00723 ColorRGBA operator/(const ColorRGBA& iA, ColorRGBA::TParam iB)
00724 {
00725     ColorRGBA result(iA);
00726     result /= iB;
00727     return result;
00728 }
00729 
00730 
00731 
00732 /** placement of foreground @a iA in front of background @a iB.
00733  *
00734  *  @a iA is painted over @a iB and leaves only a that part of @a iB visible that isn't painted 
00735  *  over: 1 - alphaA.
00736  *
00737  *  @pre @a iA and @a iB are considered non-premultiplied
00738  *
00739  *  @code
00740  *  alphaR = alphaA + (1 - alphaA) * alphaB.
00741  *  ColorR * alphaR = ColorA * alphaA + ColorB * alphaB * (1 - alphaA).
00742  *  @endcode
00743  *
00744  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00745  *  @arg http://en.wikipedia.org/wiki/Alpha_channel
00746  */
00747 ColorRGBA over(const ColorRGBA& iA, const ColorRGBA& iB)
00748 {
00749     const ColorRGBA::TValue unfilteredB = (ColorRGBA::TNumTraits::one - iA.a) * iB.a;
00750     const ColorRGBA::TValue alphaR = iA.a + unfilteredB;
00751     ColorRGBA result(iB);
00752     result *= unfilteredB;
00753     result *= iA * iA.a;
00754     result /= alphaR;
00755     result.a = alphaR;
00756     return result;
00757 }
00758 
00759 
00760 
00761 /** part of @a iA inside @a iB.
00762  *
00763  *  @a iA is only painted where @a iB is present, and @a iB is not painted at all.
00764  *  This is the equivalent of only drawing @iA clipped by the alpha channel of @a iB
00765  *
00766  *  @pre @a iA and @a iB are considered non-premultiplied
00767  *
00768  *  @code
00769  *  alphaR = alphaA * alphaB.
00770  *  ColorR = ColorA.
00771  *  @endcode
00772  *
00773  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00774  *  @arg http://en.wikipedia.org/wiki/Alpha_channel
00775  */
00776 ColorRGBA in(const ColorRGBA& iA, const ColorRGBA& iB)
00777 {
00778     ColorRGBA result(iA);
00779     result.a *= iB.a;
00780     return result;
00781 }
00782 
00783 
00784 
00785 /** @a iA held out by @a iB, part of @a iA outside @a iB.
00786  *
00787  *  @a iA is only painted where @a iB is not present, and @a iB is not painted at all.
00788  *  This is the equivalent of only drawing @iA clipped by the inverse alpha channel of @a iB.
00789  *
00790  *  @pre @a iA and @a iB are considered non-premultiplied
00791  *
00792  *  @code
00793  *  alphaR = alphaA * (1 - alphaB).
00794  *  ColorR = ColorA.
00795  *  @endcode
00796  *
00797  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00798  *  @arg http://en.wikipedia.org/wiki/Alpha_channel
00799  */
00800 ColorRGBA out(const ColorRGBA& iA, const ColorRGBA& iB)
00801 {
00802     ColorRGBA result(iA);
00803     result.a *= (ColorRGBA::TNumTraits::one - iB.a);
00804     return result;
00805 }
00806 
00807 
00808 
00809 /** union of @a iA in @a iB and @a iB out @a iA.
00810  *
00811  *  @a iA atop @a iB includes @a iA where it's on top of @a iB, otherwise it's @a iB.  But nothing 
00812  *  outside @a iB is included.
00813  *
00814  *  @pre @a iA and @a iB are considered non-premultiplied
00815  *
00816  *  @code
00817  *  alphaR = alphaB.
00818  *  ColorR = ColorA * alphaA + ColorB * (1 - alphaA).
00819  *  @endcode
00820  *
00821  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00822  *  @arg http://en.wikipedia.org/wiki/Alpha_channel
00823  */
00824 ColorRGBA atop(const ColorRGBA& iA, const ColorRGBA& iB)
00825 {
00826     ColorRGBA result(iA);
00827     result *= iA.a;
00828     result += iB * (ColorRGBA::TNumTraits::one - iA.a);
00829     result.a = iB.a;
00830     return result;
00831 }
00832 
00833 
00834 
00835 /** @pre @a iA and @a iB are considered non-premultiplied
00836  *
00837  *  @code
00838  *  alphaR = alphaA + alphaB
00839  *  colorR * alphaR = colorA * alphaA + colorB * alphaB.
00840  *  @endcode
00841  *
00842  *  @arg T. Porter, T. Duff. Compositing Digital Images, Comp. Graphics, 18(3):253-259, July 1984.
00843  *  @arg http://en.wikipedia.org/wiki/Alpha_channel
00844  */
00845 ColorRGBA plus(const ColorRGBA& iA, const ColorRGBA& iB)
00846 {
00847     ColorRGBA result(iA);
00848     result *= iA;
00849     result += iB * iB.a;
00850     result /= iA.a + iB.a;
00851     result.a = iA.a + iB.a;
00852     return result;
00853 }
00854 
00855 
00856 
00857 /** @a iA seen through color filter @a iB.
00858  *
00859  *  @pre @a iA and @a iB are considered non-premultiplied
00860  *
00861  *  @code
00862  *  alphaR = alphaA.
00863  *  colorR = colorA * (1 - alphaB) + colorA * colorB * alphaB.
00864  *  @endcode
00865  */
00866 ColorRGBA through(const ColorRGBA& iA, const ColorRGBA& iB)
00867 {
00868     ColorRGBA result(iA);
00869     result *= iB;
00870     result *= iB.a;
00871     result += iA * (ColorRGBA::TNumTraits::one - iA.b);
00872     result.a = iA.a;
00873     return result;
00874 }
00875 
00876 
00877 
00878 /** distance between non-non-premultiplied colours as 3D points (alpha channel is disregarded).
00879  *  @return num::sqrt(dR ** 2 + dG ** 2 + dB ** 2)
00880  */
00881 ColorRGBA::TValue distance(const ColorRGBA& iA, const ColorRGBA& iB)
00882 {
00883     ColorRGBA delta(iA);
00884     delta -= iB;
00885     return num::sqrt(num::sqr(delta.r) + num::sqr(delta.g) + num::sqr(delta.a));
00886 }
00887 
00888 }
00889 
00890 }
00891 
00892 // EOF

Generated on Mon Nov 10 14:20:01 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo