Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / codedid.cpp
blob7921e8298bdc2e2afb642e1d79190f4d9e38ff5b
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyright (C) 2000 Allen Akin All Rights Reserved.
4 //
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
12 // conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
16 // Software.
17 //
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.
26 //
27 // END_COPYRIGHT
31 // codedid.h: tool to map integer IDs into colors, and vice-versa
33 #include <algorithm>
34 #include <vector>
35 #include "codedid.h"
36 #include "image.h"
38 using namespace std;
40 namespace GLEAN {
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
48 gBits = min(8, g);
49 bBits = min(8, b);
50 nsRBits = 8 - rBits;
51 nsGBits = 8 - gBits;
52 nsBBits = 8 - bBits;
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 ///////////////////////////////////////////////////////////////////////////////
64 int
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 ///////////////////////////////////////////////////////////////////////////////
72 void
73 RGBCodedID::toRGB(int id, GLubyte& r, GLubyte& g, GLubyte& b) const {
74 b = (id & bMask) << nsBBits;
75 id >>= bBits;
76 g = (id & gMask) << nsGBits;
77 id >>= gBits;
78 r = (id & rMask) << nsRBits;
79 } // RGBCodedID::toRGB
81 ///////////////////////////////////////////////////////////////////////////////
82 // toID: Convert RGB triple to integer ID number
83 ///////////////////////////////////////////////////////////////////////////////
84 int
85 RGBCodedID::toID(GLubyte r, GLubyte g, GLubyte b) const {
86 int id = 0;
87 id |= (r >> nsRBits) & rMask;
88 id <<= gBits;
89 id |= (g >> nsGBits) & gMask;
90 id <<= bBits;
91 id |= (b >> nsBBits) & bMask;
92 return id;
93 } // RGBCodedID::toID
95 ///////////////////////////////////////////////////////////////////////////////
96 // histogram: Compute histogram of coded IDs in an UNSIGNED_BYTE RGB image
97 ///////////////////////////////////////////////////////////////////////////////
98 void
99 RGBCodedID::histogram(Image& img, vector<int>& hist) const {
100 if (img.format() != GL_RGB || img.type() != GL_UNSIGNED_BYTE) {
101 hist.resize(0);
102 return;
105 int max = maxID();
106 hist.resize(max + 1);
107 for (vector<int>::iterator p = hist.begin(); p != hist.end(); ++p)
108 *p = 0;
110 GLubyte* row = reinterpret_cast<GLubyte*>(img.pixels());
111 for (GLsizei r = 0; r < img.height(); ++r) {
112 GLubyte* pix = row;
113 for (GLsizei c = 0; c < img.width(); ++c) {
114 int id = toID(pix[0], pix[1], pix[2]);
115 if (id <= max)
116 ++hist[id];
117 pix += 3;
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 ///////////////////////////////////////////////////////////////////////////////
126 bool
127 RGBCodedID::allPresent(Image& img, int first, int last) const {
128 vector<int> hist;
129 histogram(img, hist);
130 if (hist.size() == 0)
131 return false;
132 if (first >= static_cast<int>(hist.size()))
133 return false;
134 if (last >= static_cast<int>(hist.size()))
135 return false;
136 if (first > last)
137 return false;
139 for (vector<int>::const_iterator p = hist.begin() + first;
140 p != hist.begin() + last + 1; ++p)
141 if (*p == 0)
142 return false;
143 return true;
144 } // RGBCodedID::allPresent
146 } // namespace GLEAN