1 // BEGIN_COPYRIGHT -*- glean -*-
3 // Copyright (C) 2000 Allen Akin All Rights Reserved.
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
31 // codedid.h: tool to map integer IDs into colors, and vice-versa
42 ///////////////////////////////////////////////////////////////////////////////
43 // RGBCodedID: Create an object that maps integer identification numbers
44 // to RGB triples, and vice-versa
45 ///////////////////////////////////////////////////////////////////////////////
46 RGBCodedID::RGBCodedID(int r
, int g
, int b
) {
47 rBits
= min(8, r
); // 8 because we use GLubyte color values
53 rMask
= (1 << rBits
) - 1;
54 gMask
= (1 << gBits
) - 1;
55 bMask
= (1 << bBits
) - 1;
56 } // RGBCodedID::RGBCodedID
58 RGBCodedID::~RGBCodedID() {
59 } // RGBCodedID::~RGBCodedID
61 ///////////////////////////////////////////////////////////////////////////////
62 // maxID: Return the maximum allowable integer ID number
63 ///////////////////////////////////////////////////////////////////////////////
65 RGBCodedID::maxID() const {
66 return (1 << (rBits
+ gBits
+ bBits
)) - 1;
67 } // RGBCodedID::maxID
69 ///////////////////////////////////////////////////////////////////////////////
70 // toRGB: Convert integer ID number to RGB triple
71 ///////////////////////////////////////////////////////////////////////////////
73 RGBCodedID::toRGB(int id
, GLubyte
& r
, GLubyte
& g
, GLubyte
& b
) const {
74 b
= (id
& bMask
) << nsBBits
;
76 g
= (id
& gMask
) << nsGBits
;
78 r
= (id
& rMask
) << nsRBits
;
79 } // RGBCodedID::toRGB
81 ///////////////////////////////////////////////////////////////////////////////
82 // toID: Convert RGB triple to integer ID number
83 ///////////////////////////////////////////////////////////////////////////////
85 RGBCodedID::toID(GLubyte r
, GLubyte g
, GLubyte b
) const {
87 id
|= (r
>> nsRBits
) & rMask
;
89 id
|= (g
>> nsGBits
) & gMask
;
91 id
|= (b
>> nsBBits
) & bMask
;
95 ///////////////////////////////////////////////////////////////////////////////
96 // histogram: Compute histogram of coded IDs in an UNSIGNED_BYTE RGB image
97 ///////////////////////////////////////////////////////////////////////////////
99 RGBCodedID::histogram(Image
& img
, vector
<int>& hist
) const {
100 if (img
.format() != GL_RGB
|| img
.type() != GL_UNSIGNED_BYTE
) {
106 hist
.resize(max
+ 1);
107 for (vector
<int>::iterator p
= hist
.begin(); p
!= hist
.end(); ++p
)
110 GLubyte
* row
= reinterpret_cast<GLubyte
*>(img
.pixels());
111 for (GLsizei r
= 0; r
< img
.height(); ++r
) {
113 for (GLsizei c
= 0; c
< img
.width(); ++c
) {
114 int id
= toID(pix
[0], pix
[1], pix
[2]);
119 row
+= img
.rowSizeInBytes();
121 } // RGBCodedID::histogram
123 ///////////////////////////////////////////////////////////////////////////////
124 // allPresent: See if all of a range of IDs are present in a given RGB image
125 ///////////////////////////////////////////////////////////////////////////////
127 RGBCodedID::allPresent(Image
& img
, int first
, int last
) const {
129 histogram(img
, hist
);
130 if (hist
.size() == 0)
132 if (first
>= static_cast<int>(hist
.size()))
134 if (last
>= static_cast<int>(hist
.size()))
139 for (vector
<int>::const_iterator p
= hist
.begin() + first
;
140 p
!= hist
.begin() + last
+ 1; ++p
)
144 } // RGBCodedID::allPresent