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