1 //*******************************************************************
2 //
3 // License:  See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts (gpotts@remotesensing.org)
6 // Description:
7 //
8 //*************************************************************************
9 // $Id: ossimHsiVector.cpp 11955 2007-10-31 16:10:22Z gpotts $
10 #include <ossim/base/ossimHsiVector.h>
11 #include <ossim/base/ossimRgbVector.h>
12 #include <ossim/base/ossimNormRgbVector.h>
13 #include <math.h>
14 #include <ossim/base/ossimCommon.h>
15 
16 // nonstandard versions that use operator>, so they behave differently
17 // than std:::min/max and ossim::min/max.  kept here for now for that
18 // reason.
19 #ifndef MAX
20 #  define MAX(x,y) ((x)>(y)?(x):(y))
21 #  define MIN(x,y) ((x)>(y)?(y):(x))
22 #endif
23 
ossimHsiVector(const ossimRgbVector & rgb)24 ossimHsiVector::ossimHsiVector(const ossimRgbVector& rgb)
25 {
26    setFromRgb(rgb.getR()/255.0, rgb.getG()/255.0, rgb.getB()/255.0);
27 }
28 
ossimHsiVector(const ossimNormRgbVector & rgb)29 ossimHsiVector::ossimHsiVector(const ossimNormRgbVector& rgb)
30 {
31    setFromRgb(rgb.getR(), rgb.getG(), rgb.getB());
32 }
33 
operator =(const ossimRgbVector & rgb)34 ossimHsiVector& ossimHsiVector::operator =(const ossimRgbVector& rgb)
35 {
36    setFromRgb(rgb.getR()/255.0, rgb.getG()/255.0, rgb.getB()/255.0);
37 
38    return *this;
39 
40 }
41 
operator =(const ossimNormRgbVector & rgb)42 ossimHsiVector& ossimHsiVector::operator =(const ossimNormRgbVector& rgb)
43 {
44    setFromRgb(rgb.getR(), rgb.getG(), rgb.getB());
45 
46    return *this;
47 
48 }
49 
setFromRgb(ossim_float64 r,ossim_float64 g,ossim_float64 b)50 void ossimHsiVector::setFromRgb(ossim_float64 r, ossim_float64 g, ossim_float64 b)
51 {
52    ossim_float64 sum = r + g + b;
53 
54    theBuf[2] =  sum/3;
55 
56    if(theBuf[2] > FLT_EPSILON)
57    {
58       double deltaI1I2 = r - g;
59       double root = deltaI1I2*deltaI1I2 +
60                     ((r-b)*(g-b));
61 
62       // compute Saturation from RGB
63       theBuf[1] = 1 - (3.0/sum)*(MIN(MIN(r,g),b));
64 
65       // compte Hue from Rgb.
66       if(root >= FLT_EPSILON)
67       {
68          theBuf[0] = acos((.5*((r-g)+(r-b)))/
69                           sqrt(root))*DEG_PER_RAD;
70 
71          if(b > g)
72          {
73             theBuf[0] = 360 - theBuf[0];
74          }
75       }
76       else
77       {
78          theBuf[0] = b;
79       }
80    }
81    else
82    {
83       theBuf[0] = 0;
84       theBuf[1] = 0;
85       theBuf[2] = 0;
86    }
87 
88    setH(theBuf[0]);
89    setS(theBuf[1]);
90    setI(theBuf[2]);
91 }
92