3 // Copyright (C) 1999 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.
32 // Data packing utilities. Note that these map component values per
33 // the usual OpenGL conversions. Also, see comments in unpack.cpp.
39 #define SCALE (static_cast<double>(num) / static_cast<double>(denom))
40 #define BIAS (static_cast<double>(bias) / static_cast<double>(denom))
42 // The original implementation of packing functions (using function
43 // templates) wouldn't compile under VC6, but this slight variant
44 // using static member functions in a class template will compile.
46 template<class component
, int num
, unsigned int denom
, int bias
>
51 static void pack_l(GLsizei n
, char* dst
, double* rgba
)
53 component
* out
= reinterpret_cast<component
*>(dst
);
54 double* end
= rgba
+ 4 * n
;
55 for (; rgba
!= end
; rgba
+= 4) {
57 out
[0] = static_cast<component
>(SCALE
* rgba
[0] - BIAS
);
59 out
[0] = static_cast<component
>(SCALE
* rgba
[0]);
65 static void pack_la(GLsizei n
, char* dst
, double* rgba
)
67 component
* out
= reinterpret_cast<component
*>(dst
);
68 double* end
= rgba
+ 4 * n
;
69 for (; rgba
!= end
; rgba
+= 4) {
71 out
[0] = static_cast<component
>(SCALE
* rgba
[0] - BIAS
);
72 out
[1] = static_cast<component
>(SCALE
* rgba
[3] - BIAS
);
74 out
[0] = static_cast<component
>(SCALE
* rgba
[0]);
75 out
[1] = static_cast<component
>(SCALE
* rgba
[3]);
82 static void pack_rgb(GLsizei n
, char* dst
, double* rgba
)
84 component
* out
= reinterpret_cast<component
*>(dst
);
85 double* end
= rgba
+ 4 * n
;
86 for (; rgba
!= end
; rgba
+= 4) {
88 out
[0] = static_cast<component
>(SCALE
* rgba
[0] - BIAS
);
89 out
[1] = static_cast<component
>(SCALE
* rgba
[1] - BIAS
);
90 out
[2] = static_cast<component
>(SCALE
* rgba
[2] - BIAS
);
92 out
[0] = static_cast<component
>(SCALE
* rgba
[0]);
93 out
[1] = static_cast<component
>(SCALE
* rgba
[1]);
94 out
[2] = static_cast<component
>(SCALE
* rgba
[2]);
101 static void pack_rgba(GLsizei n
, char* dst
, double* rgba
)
103 component
* out
= reinterpret_cast<component
*>(dst
);
104 double* end
= rgba
+ 4 * n
;
105 for (; rgba
!= end
; rgba
+= 4) {
107 out
[0] = static_cast<component
>(SCALE
* rgba
[0] - BIAS
);
108 out
[1] = static_cast<component
>(SCALE
* rgba
[1] - BIAS
);
109 out
[2] = static_cast<component
>(SCALE
* rgba
[2] - BIAS
);
110 out
[3] = static_cast<component
>(SCALE
* rgba
[3] - BIAS
);
112 out
[0] = static_cast<component
>(SCALE
* rgba
[0]);
113 out
[1] = static_cast<component
>(SCALE
* rgba
[1]);
114 out
[2] = static_cast<component
>(SCALE
* rgba
[2]);
115 out
[3] = static_cast<component
>(SCALE
* rgba
[3]);
126 }; // anonymous namespace
131 ///////////////////////////////////////////////////////////////////////////////
133 ///////////////////////////////////////////////////////////////////////////////
135 Image::pack(GLsizei n
, char* nextPixel
, double* rgba
) {
136 (*(valid(vbPacker
)? _packer
: validatePacker())) (n
, nextPixel
, rgba
);
139 ///////////////////////////////////////////////////////////////////////////////
140 // validatePacker - select appropriate pixel-packing utility
141 ///////////////////////////////////////////////////////////////////////////////
144 Image::validatePacker() {
149 _packer
= Pack
<GLbyte
, 255, 2, 1>::pack_l
;
151 case GL_UNSIGNED_BYTE
:
152 _packer
= Pack
<GLubyte
, 255, 1, 0>::pack_l
;
155 _packer
= Pack
<GLshort
, 65535, 2, 1>::pack_l
;
157 case GL_UNSIGNED_SHORT
:
158 _packer
= Pack
<GLushort
, 65535, 1, 0>::pack_l
;
161 _packer
= Pack
<GLint
, 4294967295U, 2, 1>::pack_l
;
163 case GL_UNSIGNED_INT
:
164 _packer
= Pack
<GLuint
, 4294967295U, 1, 0>::pack_l
;
167 _packer
= Pack
<GLfloat
, 1, 1, 0>::pack_l
;
170 throw BadType(type());
173 case GL_LUMINANCE_ALPHA
:
176 _packer
= Pack
<GLbyte
, 255, 2, 1>::pack_la
;
178 case GL_UNSIGNED_BYTE
:
179 _packer
= Pack
<GLubyte
, 255, 1, 0>::pack_la
;
182 _packer
= Pack
<GLshort
, 65535, 2, 1>::pack_la
;
184 case GL_UNSIGNED_SHORT
:
185 _packer
= Pack
<GLushort
, 65535, 1, 0>::pack_la
;
188 _packer
= Pack
<GLint
, 4294967295U, 2, 1>::pack_la
;
190 case GL_UNSIGNED_INT
:
191 _packer
= Pack
<GLuint
, 4294967295U, 1, 0>::pack_la
;
194 _packer
= Pack
<GLfloat
, 1, 1, 0>::pack_la
;
197 throw BadType(type());
203 _packer
= Pack
<GLbyte
, 255, 2, 1>::pack_rgb
;
205 case GL_UNSIGNED_BYTE
:
206 _packer
= Pack
<GLubyte
, 255, 1, 0>::pack_rgb
;
209 _packer
= Pack
<GLshort
, 65535, 2, 1>::pack_rgb
;
211 case GL_UNSIGNED_SHORT
:
212 _packer
= Pack
<GLushort
, 65535, 1, 0>::pack_rgb
;
215 _packer
= Pack
<GLint
, 4294967295U, 2, 1>::pack_rgb
;
217 case GL_UNSIGNED_INT
:
218 _packer
= Pack
<GLuint
, 4294967295U, 1, 0>::pack_rgb
;
221 _packer
= Pack
<GLfloat
, 1, 1, 0>::pack_rgb
;
224 throw BadType(type());
230 _packer
= Pack
<GLbyte
, 255, 2, 1>::pack_rgba
;
232 case GL_UNSIGNED_BYTE
:
233 _packer
= Pack
<GLubyte
, 255, 1, 0>::pack_rgba
;
236 _packer
= Pack
<GLshort
, 65535, 2, 1>::pack_rgba
;
238 case GL_UNSIGNED_SHORT
:
239 _packer
= Pack
<GLushort
, 65535, 1, 0>::pack_rgba
;
242 _packer
= Pack
<GLint
, 4294967295U, 2, 1>::pack_rgba
;
244 case GL_UNSIGNED_INT
:
245 _packer
= Pack
<GLuint
, 4294967295U, 1, 0>::pack_rgba
;
248 _packer
= Pack
<GLfloat
, 1, 1, 0>::pack_rgba
;
251 throw BadType(type());
255 throw BadFormat(format());
262 }; // namespace GLEAN