VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/pixel.c@ 15759

Last change on this file since 15759 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 60.0 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_pixeldata.h"
8#include "cr_error.h"
9#include "cr_mem.h"
10#include "cr_version.h"
11
12
13/**
14 * Maybe export this someday.
15 */
16static int crSizeOfType( GLenum type )
17{
18 switch (type) {
19#ifdef CR_OPENGL_VERSION_1_2
20 case GL_UNSIGNED_BYTE_3_3_2:
21 case GL_UNSIGNED_BYTE_2_3_3_REV:
22#endif
23 case GL_UNSIGNED_BYTE:
24 case GL_BYTE:
25 return 1;
26 case GL_BITMAP:
27 return 0; /* special case */
28#ifdef CR_OPENGL_VERSION_1_2
29 case GL_UNSIGNED_SHORT_5_6_5:
30 case GL_UNSIGNED_SHORT_5_6_5_REV:
31 case GL_UNSIGNED_SHORT_5_5_5_1:
32 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
33 case GL_UNSIGNED_SHORT_4_4_4_4:
34 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
35#endif
36 case GL_UNSIGNED_SHORT:
37 case GL_SHORT:
38 return 2;
39#ifdef CR_OPENGL_VERSION_1_2
40 case GL_UNSIGNED_INT_8_8_8_8:
41 case GL_UNSIGNED_INT_8_8_8_8_REV:
42 case GL_UNSIGNED_INT_10_10_10_2:
43 case GL_UNSIGNED_INT_2_10_10_10_REV:
44#endif
45 case GL_UNSIGNED_INT:
46 case GL_INT:
47 case GL_FLOAT:
48 return 4;
49 case GL_DOUBLE:
50 return 8;
51 default:
52 crError( "Unknown pixel type in crSizeOfType: 0x%x", (unsigned int) type );
53 return 0;
54 }
55}
56
57
58/**
59 * Compute bytes per pixel for the given format/type combination.
60 * \return bytes per pixel or -1 for invalid format or type, 0 for bitmap data.
61 */
62int crPixelSize( GLenum format, GLenum type )
63{
64 int bytes = 1; /* picky Windows compiler, we override later */
65
66 switch (type) {
67#ifdef CR_OPENGL_VERSION_1_2
68 case GL_UNSIGNED_BYTE_3_3_2:
69 case GL_UNSIGNED_BYTE_2_3_3_REV:
70 return 1;
71#endif
72 case GL_UNSIGNED_BYTE:
73 case GL_BYTE:
74 bytes = 1;
75 break;
76 case GL_BITMAP:
77 return 0; /* special case */
78#ifdef CR_OPENGL_VERSION_1_2
79 case GL_UNSIGNED_SHORT_5_6_5:
80 case GL_UNSIGNED_SHORT_5_6_5_REV:
81 case GL_UNSIGNED_SHORT_5_5_5_1:
82 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
83 case GL_UNSIGNED_SHORT_4_4_4_4:
84 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
85 return 2;
86#endif
87 case GL_UNSIGNED_SHORT:
88 case GL_SHORT:
89 bytes = 2;
90 break;
91#ifdef CR_OPENGL_VERSION_1_2
92 case GL_UNSIGNED_INT_8_8_8_8:
93 case GL_UNSIGNED_INT_8_8_8_8_REV:
94 case GL_UNSIGNED_INT_10_10_10_2:
95 case GL_UNSIGNED_INT_2_10_10_10_REV:
96 return 4;
97#endif
98 case GL_UNSIGNED_INT:
99 case GL_INT:
100 case GL_FLOAT:
101 bytes = 4;
102 break;
103 default:
104 /*
105 crError( "Unknown pixel type in crPixelSize: 0x%x", (unsigned int) type );
106 */
107 return -1;
108 }
109
110 switch (format) {
111 case GL_COLOR_INDEX:
112 case GL_STENCIL_INDEX:
113 case GL_DEPTH_COMPONENT:
114 case GL_RED:
115 case GL_GREEN:
116 case GL_BLUE:
117 case GL_ALPHA:
118 case GL_LUMINANCE:
119 case GL_INTENSITY:
120 break;
121 case GL_LUMINANCE_ALPHA:
122 bytes *= 2;
123 break;
124 case GL_RGB:
125#ifdef CR_OPENGL_VERSION_1_2
126 case GL_BGR:
127#endif
128 bytes *= 3;
129 break;
130 case GL_RGBA:
131#ifdef GL_ABGR_EXT
132 case GL_ABGR_EXT:
133#endif
134#ifdef CR_OPENGL_VERSION_1_2
135 case GL_BGRA:
136#endif
137 bytes *= 4;
138 break;
139 default:
140 /*
141 crError( "Unknown pixel format in crPixelSize: 0x%x", (unsigned int) format );
142 */
143 return -1;
144 }
145
146 return bytes;
147}
148
149
150#define BYTE_TO_FLOAT(b) ((b) * (1.0/127.0))
151#define FLOAT_TO_BYTE(f) ((GLbyte) ((f) * 127.0))
152
153#define UBYTE_TO_FLOAT(b) ((b) * (1.0/255.0))
154#define FLOAT_TO_UBYTE(f) ((GLbyte) ((f) * 255.0))
155
156#define SHORT_TO_FLOAT(s) ((s) * (1.0/32768.0))
157#define FLOAT_TO_SHORT(f) ((GLshort) ((f) * 32768.0))
158
159#define USHORT_TO_FLOAT(s) ((s) * (1.0/65535.0))
160#define FLOAT_TO_USHORT(f) ((GLushort) ((f) * 65535.0))
161
162#define INT_TO_FLOAT(i) ((i) * (1.0F/2147483647.0))
163#define FLOAT_TO_INT(f) ((GLint) ((f) * 2147483647.0))
164
165#define UINT_TO_FLOAT(i) ((i) * (1.0F / 4294967295.0F))
166#define FLOAT_TO_UINT(f) ((GLuint) ((f) * 4294967295.0))
167
168
169#ifdef _MSC_VER
170/** @todo bird: MSC takes 5..20 mins to compile get_row and/or put_row with global
171 * optimizations enabled. It varies a bit between 8.0/64 and 7.1/32 - the latter seems
172 * to be fine with just disabling opts for get_row, while the former needs both to be
173 * disabled to compile it a decent time. It seems this isn't important code after all,
174 * so we're not overly worried about the performance degration. Even so, we might want
175 * to look into it before long, perhaps checking with Visual C++ 9.0 (aka 2008). */
176# pragma optimize("g", off)
177#endif
178
179/*
180 * Pack src pixel data into tmpRow array as either GLfloat[][1] or
181 * GLfloat[][4] depending on whether the format is for colors.
182 */
183static void
184get_row(const char *src, GLenum srcFormat, GLenum srcType,
185 GLsizei width, GLfloat *tmpRow)
186{
187 const GLbyte *bSrc = (GLbyte *) src;
188 const GLubyte *ubSrc = (GLubyte *) src;
189 const GLshort *sSrc = (GLshort *) src;
190 const GLushort *usSrc = (GLushort *) src;
191 const GLint *iSrc = (GLint *) src;
192 const GLuint *uiSrc = (GLuint *) src;
193 const GLfloat *fSrc = (GLfloat *) src;
194 const GLdouble *dSrc = (GLdouble *) src;
195 int i;
196
197 if (srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX) {
198 switch (srcType) {
199 case GL_BYTE:
200 for (i = 0; i < width; i++)
201 tmpRow[i] = (GLfloat) bSrc[i];
202 break;
203 case GL_UNSIGNED_BYTE:
204 for (i = 0; i < width; i++)
205 tmpRow[i] = (GLfloat) ubSrc[i];
206 break;
207 case GL_SHORT:
208 for (i = 0; i < width; i++)
209 tmpRow[i] = (GLfloat) sSrc[i];
210 break;
211 case GL_UNSIGNED_SHORT:
212 for (i = 0; i < width; i++)
213 tmpRow[i] = (GLfloat) usSrc[i];
214 break;
215 case GL_INT:
216 for (i = 0; i < width; i++)
217 tmpRow[i] = (GLfloat) iSrc[i];
218 break;
219 case GL_UNSIGNED_INT:
220 for (i = 0; i < width; i++)
221 tmpRow[i] = (GLfloat) uiSrc[i];
222 break;
223 case GL_FLOAT:
224 for (i = 0; i < width; i++)
225 tmpRow[i] = fSrc[i];
226 break;
227 case GL_DOUBLE:
228 for (i = 0; i < width; i++)
229 tmpRow[i] = (GLfloat) dSrc[i];
230 break;
231 default:
232 crError("unexpected type in get_row in pixel.c");
233 }
234 }
235 else if (srcFormat == GL_DEPTH_COMPONENT) {
236 switch (srcType) {
237 case GL_BYTE:
238 for (i = 0; i < width; i++)
239 tmpRow[i] = (GLfloat) BYTE_TO_FLOAT(bSrc[i]);
240 break;
241 case GL_UNSIGNED_BYTE:
242 for (i = 0; i < width; i++)
243 tmpRow[i] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i]);
244 break;
245 case GL_SHORT:
246 for (i = 0; i < width; i++)
247 tmpRow[i] = (GLfloat) SHORT_TO_FLOAT(sSrc[i]);
248 break;
249 case GL_UNSIGNED_SHORT:
250 for (i = 0; i < width; i++)
251 tmpRow[i] = (GLfloat) USHORT_TO_FLOAT(usSrc[i]);
252 break;
253 case GL_INT:
254 for (i = 0; i < width; i++)
255 tmpRow[i] = (GLfloat) INT_TO_FLOAT(bSrc[i]);
256 break;
257 case GL_UNSIGNED_INT:
258 for (i = 0; i < width; i++)
259 tmpRow[i] = (GLfloat) UINT_TO_FLOAT(bSrc[i]);
260 break;
261 case GL_FLOAT:
262 for (i = 0; i < width; i++)
263 tmpRow[i] = fSrc[i];
264 break;
265 case GL_DOUBLE:
266 for (i = 0; i < width; i++)
267 tmpRow[i] = (GLfloat) dSrc[i];
268 break;
269 default:
270 crError("unexpected type in get_row in pixel.c");
271 }
272 }
273 else if (srcFormat == GL_RED || srcFormat == GL_GREEN ||
274 srcFormat == GL_BLUE || srcFormat == GL_ALPHA) {
275 int dst;
276 if (srcFormat == GL_RED)
277 dst = 0;
278 else if (srcFormat == GL_GREEN)
279 dst = 1;
280 else if (srcFormat == GL_BLUE)
281 dst = 2;
282 else
283 dst = 3;
284 for (i = 0; i < width; i++) {
285 tmpRow[i*4+0] = 0.0;
286 tmpRow[i*4+1] = 0.0;
287 tmpRow[i*4+2] = 0.0;
288 tmpRow[i*4+3] = 1.0;
289 }
290 switch (srcType) {
291 case GL_BYTE:
292 for (i = 0; i < width; i++, dst += 4)
293 tmpRow[dst] = (GLfloat) BYTE_TO_FLOAT(bSrc[i]);
294 break;
295 case GL_UNSIGNED_BYTE:
296 for (i = 0; i < width; i++, dst += 4)
297 tmpRow[dst] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i]);
298 break;
299 case GL_SHORT:
300 for (i = 0; i < width; i++, dst += 4)
301 tmpRow[dst] = (GLfloat) SHORT_TO_FLOAT(sSrc[i]);
302 break;
303 case GL_UNSIGNED_SHORT:
304 for (i = 0; i < width; i++, dst += 4)
305 tmpRow[dst] = (GLfloat) USHORT_TO_FLOAT(usSrc[i]);
306 break;
307 case GL_INT:
308 for (i = 0; i < width; i++, dst += 4)
309 tmpRow[dst] = (GLfloat) INT_TO_FLOAT(iSrc[i]);
310 break;
311 case GL_UNSIGNED_INT:
312 for (i = 0; i < width; i++, dst += 4)
313 tmpRow[dst] = (GLfloat) UINT_TO_FLOAT(uiSrc[i]);
314 break;
315 case GL_FLOAT:
316 for (i = 0; i < width; i++, dst += 4)
317 tmpRow[dst] = fSrc[i];
318 break;
319 case GL_DOUBLE:
320 for (i = 0; i < width; i++, dst += 4)
321 tmpRow[dst] = (GLfloat) fSrc[i];
322 break;
323 default:
324 crError("unexpected type in get_row in pixel.c");
325 }
326 }
327 else if (srcFormat == GL_LUMINANCE) {
328 switch (srcType) {
329 case GL_BYTE:
330 for (i = 0; i < width; i++) {
331 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
332 = (GLfloat) BYTE_TO_FLOAT(bSrc[i]);
333 tmpRow[i*4+3] = 1.0;
334 }
335 break;
336 case GL_UNSIGNED_BYTE:
337 for (i = 0; i < width; i++) {
338 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
339 = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i]);
340 tmpRow[i*4+3] = 1.0;
341 }
342 break;
343 case GL_SHORT:
344 for (i = 0; i < width; i++) {
345 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
346 = (GLfloat) SHORT_TO_FLOAT(sSrc[i]);
347 tmpRow[i*4+3] = 1.0;
348 }
349 break;
350 case GL_UNSIGNED_SHORT:
351 for (i = 0; i < width; i++) {
352 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
353 = (GLfloat) USHORT_TO_FLOAT(usSrc[i]);
354 tmpRow[i*4+3] = 1.0;
355 }
356 break;
357 case GL_INT:
358 for (i = 0; i < width; i++) {
359 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
360 = (GLfloat) INT_TO_FLOAT(iSrc[i]);
361 tmpRow[i*4+3] = 1.0;
362 }
363 break;
364 case GL_UNSIGNED_INT:
365 for (i = 0; i < width; i++) {
366 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
367 = (GLfloat) UINT_TO_FLOAT(uiSrc[i]);
368 tmpRow[i*4+3] = 1.0;
369 }
370 break;
371 case GL_FLOAT:
372 for (i = 0; i < width; i++) {
373 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = fSrc[i];
374 tmpRow[i*4+3] = 1.0;
375 }
376 break;
377 case GL_DOUBLE:
378 for (i = 0; i < width; i++) {
379 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = (GLfloat) dSrc[i];
380 tmpRow[i*4+3] = 1.0;
381 }
382 break;
383 default:
384 crError("unexpected type in get_row in pixel.c");
385 }
386 }
387 else if (srcFormat == GL_INTENSITY) {
388 switch (srcType) {
389 case GL_BYTE:
390 for (i = 0; i < width; i++)
391 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
392 = (GLfloat) BYTE_TO_FLOAT(bSrc[i]);
393 break;
394 case GL_UNSIGNED_BYTE:
395 for (i = 0; i < width; i++)
396 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
397 = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i]);
398 break;
399 case GL_SHORT:
400 for (i = 0; i < width; i++)
401 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
402 = (GLfloat) SHORT_TO_FLOAT(sSrc[i]);
403 break;
404 case GL_UNSIGNED_SHORT:
405 for (i = 0; i < width; i++)
406 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
407 = (GLfloat) USHORT_TO_FLOAT(usSrc[i]);
408 break;
409 case GL_INT:
410 for (i = 0; i < width; i++)
411 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
412 = (GLfloat) INT_TO_FLOAT(iSrc[i]);
413 break;
414 case GL_UNSIGNED_INT:
415 for (i = 0; i < width; i++)
416 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
417 = UINT_TO_FLOAT(uiSrc[i]);
418 break;
419 case GL_FLOAT:
420 for (i = 0; i < width; i++)
421 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
422 = fSrc[i];
423 break;
424 case GL_DOUBLE:
425 for (i = 0; i < width; i++)
426 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = tmpRow[i*4+3]
427 = (GLfloat) dSrc[i];
428 break;
429 default:
430 crError("unexpected type in get_row in pixel.c");
431 }
432 }
433 else if (srcFormat == GL_LUMINANCE_ALPHA) {
434 switch (srcType) {
435 case GL_BYTE:
436 for (i = 0; i < width; i++) {
437 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
438 = (GLfloat) BYTE_TO_FLOAT(bSrc[i*2+0]);
439 tmpRow[i*4+3] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*2+1]);
440 }
441 break;
442 case GL_UNSIGNED_BYTE:
443 for (i = 0; i < width; i++) {
444 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
445 = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*2+0]);
446 tmpRow[i*4+3] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*2+1]);
447 }
448 break;
449 case GL_SHORT:
450 for (i = 0; i < width; i++) {
451 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
452 = (GLfloat) SHORT_TO_FLOAT(sSrc[i*2+0]);
453 tmpRow[i*4+3] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*2+1]);
454 }
455 break;
456 case GL_UNSIGNED_SHORT:
457 for (i = 0; i < width; i++) {
458 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
459 = (GLfloat) USHORT_TO_FLOAT(usSrc[i*2+0]);
460 tmpRow[i*4+3] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*2+1]);
461 }
462 break;
463 case GL_INT:
464 for (i = 0; i < width; i++) {
465 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
466 = (GLfloat) INT_TO_FLOAT(iSrc[i*2+0]);
467 tmpRow[i*4+3] = (GLfloat) INT_TO_FLOAT(iSrc[i*2+1]);
468 }
469 break;
470 case GL_UNSIGNED_INT:
471 for (i = 0; i < width; i++) {
472 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
473 = (GLfloat) UINT_TO_FLOAT(uiSrc[i*2+0]);
474 tmpRow[i*4+3] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*2+1]);
475 }
476 break;
477 case GL_FLOAT:
478 for (i = 0; i < width; i++) {
479 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2] = fSrc[i*2+0];
480 tmpRow[i*4+3] = fSrc[i*2+1];
481 }
482 break;
483 case GL_DOUBLE:
484 for (i = 0; i < width; i++) {
485 tmpRow[i*4+0] = tmpRow[i*4+1] = tmpRow[i*4+2]
486 = (GLfloat) dSrc[i*2+0];
487 tmpRow[i*4+3] = (GLfloat) dSrc[i*2+1];
488 }
489 break;
490 default:
491 crError("unexpected type in get_row in pixel.c");
492 }
493 }
494 else if (srcFormat == GL_RGB
495#ifdef CR_OPENGL_VERSION_1_2
496 || srcFormat == GL_BGR
497#endif
498 ) {
499 int r, b;
500 if (srcFormat == GL_RGB) {
501 r = 0; b = 2;
502 }
503 else {
504 r = 2; b = 0;
505 }
506 switch (srcType) {
507 case GL_BYTE:
508 for (i = 0; i < width; i++) {
509 tmpRow[i*4+0] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*3+r]);
510 tmpRow[i*4+1] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*3+1]);
511 tmpRow[i*4+2] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*3+b]);
512 tmpRow[i*4+3] = 1.0;
513 }
514 break;
515 case GL_UNSIGNED_BYTE:
516 for (i = 0; i < width; i++) {
517 tmpRow[i*4+0] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*3+r]);
518 tmpRow[i*4+1] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*3+1]);
519 tmpRow[i*4+2] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*3+b]);
520 tmpRow[i*4+3] = 1.0;
521 }
522 break;
523 case GL_SHORT:
524 for (i = 0; i < width; i++) {
525 tmpRow[i*4+0] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*3+r]);
526 tmpRow[i*4+1] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*3+1]);
527 tmpRow[i*4+2] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*3+b]);
528 tmpRow[i*4+3] = 1.0;
529 }
530 break;
531 case GL_UNSIGNED_SHORT:
532 for (i = 0; i < width; i++) {
533 tmpRow[i*4+0] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*3+r]);
534 tmpRow[i*4+1] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*3+1]);
535 tmpRow[i*4+2] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*3+b]);
536 tmpRow[i*4+3] = 1.0;
537 }
538 break;
539 case GL_INT:
540 for (i = 0; i < width; i++) {
541 tmpRow[i*4+0] = (GLfloat) INT_TO_FLOAT(iSrc[i*3+r]);
542 tmpRow[i*4+1] = (GLfloat) INT_TO_FLOAT(iSrc[i*3+1]);
543 tmpRow[i*4+2] = (GLfloat) INT_TO_FLOAT(iSrc[i*3+b]);
544 tmpRow[i*4+3] = 1.0;
545 }
546 break;
547 case GL_UNSIGNED_INT:
548 for (i = 0; i < width; i++) {
549 tmpRow[i*4+0] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*3+r]);
550 tmpRow[i*4+1] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*3+1]);
551 tmpRow[i*4+2] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*3+b]);
552 tmpRow[i*4+3] = 1.0;
553 }
554 break;
555 case GL_FLOAT:
556 for (i = 0; i < width; i++) {
557 tmpRow[i*4+0] = fSrc[i*3+r];
558 tmpRow[i*4+1] = fSrc[i*3+1];
559 tmpRow[i*4+2] = fSrc[i*3+b];
560 tmpRow[i*4+3] = 1.0;
561 }
562 break;
563 case GL_DOUBLE:
564 for (i = 0; i < width; i++) {
565 tmpRow[i*4+0] = (GLfloat) dSrc[i*3+r];
566 tmpRow[i*4+1] = (GLfloat) dSrc[i*3+1];
567 tmpRow[i*4+2] = (GLfloat) dSrc[i*3+b];
568 tmpRow[i*4+3] = 1.0;
569 }
570 break;
571#ifdef CR_OPENGL_VERSION_1_2
572 case GL_UNSIGNED_BYTE_3_3_2:
573 for (i = 0; i < width; i++) {
574 tmpRow[i*4+r] = (GLfloat) ((ubSrc[i] >> 5) ) / 7.0f;
575 tmpRow[i*4+1] = (GLfloat) ((ubSrc[i] >> 2) & 0x7) / 7.0f;
576 tmpRow[i*4+b] = (GLfloat) ((ubSrc[i] ) & 0x3) / 3.0f;
577 tmpRow[i*4+3] = 1.0;
578 }
579 break;
580 case GL_UNSIGNED_BYTE_2_3_3_REV:
581 for (i = 0; i < width; i++) {
582 tmpRow[i*4+r] = (GLfloat) ((ubSrc[i] ) & 0x7) / 7.0f;
583 tmpRow[i*4+1] = (GLfloat) ((ubSrc[i] >> 3) & 0x7) / 7.0f;
584 tmpRow[i*4+b] = (GLfloat) ((ubSrc[i] >> 6) ) / 3.0f;
585 tmpRow[i*4+3] = 1.0;
586 }
587 break;
588 case GL_UNSIGNED_SHORT_5_6_5:
589 for (i = 0; i < width; i++) {
590 tmpRow[i*4+r] = (GLfloat) ((usSrc[i] >> 11) & 0x1f) / 31.0f;
591 tmpRow[i*4+1] = (GLfloat) ((usSrc[i] >> 5) & 0x3f) / 63.0f;
592 tmpRow[i*4+b] = (GLfloat) ((usSrc[i] ) & 0x1f) / 31.0f;
593 tmpRow[i*4+3] = 1.0;
594 }
595 break;
596 case GL_UNSIGNED_SHORT_5_6_5_REV:
597 for (i = 0; i < width; i++) {
598 tmpRow[i*4+r] = (GLfloat) ((usSrc[i] ) & 0x1f) / 31.0f;
599 tmpRow[i*4+1] = (GLfloat) ((usSrc[i] >> 5) & 0x3f) / 63.0f;
600 tmpRow[i*4+b] = (GLfloat) ((usSrc[i] >> 11) & 0x1f) / 31.0f;
601 tmpRow[i*4+3] = 1.0;
602 }
603 break;
604#endif
605 default:
606 crError("unexpected type in get_row in pixel.c");
607 }
608 }
609 else if (srcFormat == GL_RGBA
610#ifdef CR_OPENGL_VERSION_1_2
611 || srcFormat == GL_BGRA
612#endif
613 ) {
614 int r, b;
615 if (srcFormat == GL_RGB) {
616 r = 0; b = 2;
617 }
618 else {
619 r = 2; b = 0;
620 }
621 switch (srcType) {
622 case GL_BYTE:
623 for (i = 0; i < width; i++) {
624 tmpRow[i*4+0] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*4+r]);
625 tmpRow[i*4+1] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*4+1]);
626 tmpRow[i*4+2] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*4+b]);
627 tmpRow[i*4+3] = (GLfloat) BYTE_TO_FLOAT(bSrc[i*4+3]);
628 }
629 break;
630 case GL_UNSIGNED_BYTE:
631 for (i = 0; i < width; i++) {
632 tmpRow[i*4+0] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*4+r]);
633 tmpRow[i*4+1] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*4+1]);
634 tmpRow[i*4+2] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*4+b]);
635 tmpRow[i*4+3] = (GLfloat) UBYTE_TO_FLOAT(ubSrc[i*4+3]);
636 }
637 break;
638 case GL_SHORT:
639 for (i = 0; i < width; i++) {
640 tmpRow[i*4+0] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*4+r]);
641 tmpRow[i*4+1] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*4+1]);
642 tmpRow[i*4+2] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*4+b]);
643 tmpRow[i*4+3] = (GLfloat) SHORT_TO_FLOAT(sSrc[i*4+3]);
644 }
645 break;
646 case GL_UNSIGNED_SHORT:
647 for (i = 0; i < width; i++) {
648 tmpRow[i*4+0] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*4+r]);
649 tmpRow[i*4+1] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*4+1]);
650 tmpRow[i*4+2] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*4+b]);
651 tmpRow[i*4+3] = (GLfloat) USHORT_TO_FLOAT(usSrc[i*4+3]);
652 }
653 break;
654 case GL_INT:
655 for (i = 0; i < width; i++) {
656 tmpRow[i*4+0] = (GLfloat) INT_TO_FLOAT(iSrc[i*4+r]);
657 tmpRow[i*4+1] = (GLfloat) INT_TO_FLOAT(iSrc[i*4+1]);
658 tmpRow[i*4+2] = (GLfloat) INT_TO_FLOAT(iSrc[i*4+b]);
659 tmpRow[i*4+3] = (GLfloat) INT_TO_FLOAT(iSrc[i*4+3]);
660 }
661 break;
662 case GL_UNSIGNED_INT:
663 for (i = 0; i < width; i++) {
664 tmpRow[i*4+0] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*4+r]);
665 tmpRow[i*4+1] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*4+1]);
666 tmpRow[i*4+2] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*4+b]);
667 tmpRow[i*4+3] = (GLfloat) UINT_TO_FLOAT(uiSrc[i*4+3]);
668 }
669 break;
670 case GL_FLOAT:
671 for (i = 0; i < width; i++) {
672 tmpRow[i*4+0] = fSrc[i*4+r];
673 tmpRow[i*4+1] = fSrc[i*4+1];
674 tmpRow[i*4+2] = fSrc[i*4+b];
675 tmpRow[i*4+3] = fSrc[i*4+3];
676 }
677 break;
678 case GL_DOUBLE:
679 for (i = 0; i < width; i++) {
680 tmpRow[i*4+0] = (GLfloat) dSrc[i*4+r];
681 tmpRow[i*4+1] = (GLfloat) dSrc[i*4+1];
682 tmpRow[i*4+2] = (GLfloat) dSrc[i*4+b];
683 tmpRow[i*4+3] = (GLfloat) dSrc[i*4+3];
684 }
685 break;
686#ifdef CR_OPENGL_VERSION_1_2
687 case GL_UNSIGNED_SHORT_5_5_5_1:
688 for (i = 0; i < width; i++) {
689 tmpRow[i*4+r] = (GLfloat) ((usSrc[i] >> 11) ) / 31.0f;
690 tmpRow[i*4+1] = (GLfloat) ((usSrc[i] >> 6) & 0x1f) / 31.0f;
691 tmpRow[i*4+b] = (GLfloat) ((usSrc[i] >> 1) & 0x1f) / 31.0f;
692 tmpRow[i*4+3] = (GLfloat) ((usSrc[i] ) & 0x01);
693 }
694 break;
695 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
696 for (i = 0; i < width; i++) {
697 tmpRow[i*4+r] = (GLfloat) ((usSrc[i] ) & 0x1f) / 31.0f;
698 tmpRow[i*4+1] = (GLfloat) ((usSrc[i] >> 5) & 0x1f) / 31.0f;
699 tmpRow[i*4+b] = (GLfloat) ((usSrc[i] >> 10) & 0x1f) / 31.0f;
700 tmpRow[i*4+3] = (GLfloat) ((usSrc[i] >> 15) );
701 }
702 break;
703 case GL_UNSIGNED_SHORT_4_4_4_4:
704 for (i = 0; i < width; i++) {
705 tmpRow[i*4+r] = (GLfloat) ((usSrc[i] >> 12) & 0xf) / 15.0f;
706 tmpRow[i*4+1] = (GLfloat) ((usSrc[i] >> 8) & 0xf) / 15.0f;
707 tmpRow[i*4+b] = (GLfloat) ((usSrc[i] >> 4) & 0xf) / 15.0f;
708 tmpRow[i*4+3] = (GLfloat) ((usSrc[i] ) & 0xf) / 15.0f;
709 }
710 break;
711 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
712 for (i = 0; i < width; i++) {
713 tmpRow[i*4+r] = (GLfloat) ((usSrc[i] ) & 0xf) / 15.0f;
714 tmpRow[i*4+1] = (GLfloat) ((usSrc[i] >> 4) & 0xf) / 15.0f;
715 tmpRow[i*4+b] = (GLfloat) ((usSrc[i] >> 8) & 0xf) / 15.0f;
716 tmpRow[i*4+3] = (GLfloat) ((usSrc[i] >> 12) & 0xf) / 15.0f;
717 }
718 break;
719 case GL_UNSIGNED_INT_8_8_8_8:
720 for (i = 0; i < width; i++) {
721 tmpRow[i*4+r] = (GLfloat) ((uiSrc[i] >> 24) & 0xff) / 255.0f;
722 tmpRow[i*4+1] = (GLfloat) ((uiSrc[i] >> 16) & 0xff) / 255.0f;
723 tmpRow[i*4+b] = (GLfloat) ((uiSrc[i] >> 8) & 0xff) / 255.0f;
724 tmpRow[i*4+3] = (GLfloat) ((uiSrc[i] ) & 0xff) / 255.0f;
725 }
726 break;
727 case GL_UNSIGNED_INT_8_8_8_8_REV:
728 for (i = 0; i < width; i++) {
729 tmpRow[i*4+r] = (GLfloat) ((uiSrc[i] ) & 0xff) / 255.0f;
730 tmpRow[i*4+1] = (GLfloat) ((uiSrc[i] >> 8) & 0xff) / 255.0f;
731 tmpRow[i*4+b] = (GLfloat) ((uiSrc[i] >> 16) & 0xff) / 255.0f;
732 tmpRow[i*4+3] = (GLfloat) ((uiSrc[i] >> 24) & 0xff) / 255.0f;
733 }
734 break;
735 case GL_UNSIGNED_INT_10_10_10_2:
736 for (i = 0; i < width; i++) {
737 tmpRow[i*4+r] = (GLfloat) ((uiSrc[i] >> 22) & 0x3ff) / 1023.0f;
738 tmpRow[i*4+1] = (GLfloat) ((uiSrc[i] >> 12) & 0x3ff) / 1023.0f;
739 tmpRow[i*4+b] = (GLfloat) ((uiSrc[i] >> 2) & 0x3ff) / 1023.0f;
740 tmpRow[i*4+3] = (GLfloat) ((uiSrc[i] ) & 0x003) / 3.0f;
741 }
742 break;
743 case GL_UNSIGNED_INT_2_10_10_10_REV:
744 for (i = 0; i < width; i++) {
745 tmpRow[i*4+r] = (GLfloat) ((uiSrc[i] ) & 0x3ff) / 1023.0f;
746 tmpRow[i*4+1] = (GLfloat) ((uiSrc[i] >> 10) & 0x3ff) / 1023.0f;
747 tmpRow[i*4+b] = (GLfloat) ((uiSrc[i] >> 20) & 0x3ff) / 1023.0f;
748 tmpRow[i*4+3] = (GLfloat) ((uiSrc[i] >> 30) & 0x003) / 3.0f;
749 }
750 break;
751#endif
752 default:
753 crError("unexpected type in get_row in pixel.c");
754 }
755 }
756 else{
757 crError("unexpected source format in get_row in pixel.c");
758 }
759}
760
761
762static void put_row(char *dst, GLenum dstFormat, GLenum dstType,
763 GLsizei width, const GLfloat *tmpRow)
764{
765 GLbyte *bDst = (GLbyte *) dst;
766 GLubyte *ubDst = (GLubyte *) dst;
767 GLshort *sDst = (GLshort *) dst;
768 GLushort *usDst = (GLushort *) dst;
769 GLint *iDst = (GLint *) dst;
770 GLuint *uiDst = (GLuint *) dst;
771 GLfloat *fDst = (GLfloat *) dst;
772 GLdouble *dDst = (GLdouble *) dst;
773 int i;
774
775 if (dstFormat == GL_COLOR_INDEX || dstFormat == GL_STENCIL_INDEX) {
776 switch (dstType) {
777 case GL_BYTE:
778 for (i = 0; i < width; i++)
779 bDst[i] = (GLbyte) tmpRow[i];
780 break;
781 case GL_UNSIGNED_BYTE:
782 for (i = 0; i < width; i++)
783 ubDst[i] = (GLubyte) tmpRow[i];
784 break;
785 case GL_SHORT:
786 for (i = 0; i < width; i++)
787 sDst[i] = (GLshort) tmpRow[i];
788 break;
789 case GL_UNSIGNED_SHORT:
790 for (i = 0; i < width; i++)
791 usDst[i] = (GLushort) tmpRow[i];
792 break;
793 case GL_INT:
794 for (i = 0; i < width; i++)
795 iDst[i] = (GLint) tmpRow[i];
796 break;
797 case GL_UNSIGNED_INT:
798 for (i = 0; i < width; i++)
799 uiDst[i] = (GLuint) tmpRow[i];
800 break;
801 case GL_FLOAT:
802 for (i = 0; i < width; i++)
803 fDst[i] = tmpRow[i];
804 break;
805 case GL_DOUBLE:
806 for (i = 0; i < width; i++)
807 dDst[i] = tmpRow[i];
808 break;
809 default:
810 crError("unexpected type in put_row in pixel.c");
811 }
812 }
813 else if (dstFormat == GL_DEPTH_COMPONENT) {
814 switch (dstType) {
815 case GL_BYTE:
816 for (i = 0; i < width; i++)
817 bDst[i] = FLOAT_TO_BYTE(tmpRow[i]);
818 break;
819 case GL_UNSIGNED_BYTE:
820 for (i = 0; i < width; i++)
821 ubDst[i] = FLOAT_TO_UBYTE(tmpRow[i]);
822 break;
823 case GL_SHORT:
824 for (i = 0; i < width; i++)
825 sDst[i] = FLOAT_TO_SHORT(tmpRow[i]);
826 break;
827 case GL_UNSIGNED_SHORT:
828 for (i = 0; i < width; i++)
829 sDst[i] = FLOAT_TO_SHORT(tmpRow[i]);
830 break;
831 case GL_INT:
832 for (i = 0; i < width; i++)
833 bDst[i] = (GLbyte) FLOAT_TO_INT(tmpRow[i]);
834 break;
835 case GL_UNSIGNED_INT:
836 for (i = 0; i < width; i++)
837 bDst[i] = (GLbyte) FLOAT_TO_UINT(tmpRow[i]);
838 break;
839 case GL_FLOAT:
840 for (i = 0; i < width; i++)
841 fDst[i] = tmpRow[i];
842 break;
843 case GL_DOUBLE:
844 for (i = 0; i < width; i++)
845 dDst[i] = tmpRow[i];
846 break;
847 default:
848 crError("unexpected type in put_row in pixel.c");
849 }
850 }
851 else if (dstFormat == GL_RED || dstFormat == GL_GREEN ||
852 dstFormat == GL_BLUE || dstFormat == GL_ALPHA ||
853 dstFormat == GL_LUMINANCE || dstFormat == GL_INTENSITY) {
854 int index;
855 if (dstFormat == GL_RED)
856 index = 0;
857 else if (dstFormat == GL_LUMINANCE)
858 index = 0;
859 else if (dstFormat == GL_INTENSITY)
860 index = 0;
861 else if (dstFormat == GL_GREEN)
862 index = 1;
863 else if (dstFormat == GL_BLUE)
864 index = 2;
865 else
866 index = 3;
867 switch (dstType) {
868 case GL_BYTE:
869 for (i = 0; i < width; i++)
870 bDst[i] = FLOAT_TO_BYTE(tmpRow[i*4+index]);
871 break;
872 case GL_UNSIGNED_BYTE:
873 for (i = 0; i < width; i++)
874 ubDst[i] = FLOAT_TO_UBYTE(tmpRow[i*4+index]);
875 break;
876 case GL_SHORT:
877 for (i = 0; i < width; i++)
878 sDst[i] = FLOAT_TO_SHORT(tmpRow[i*4+index]);
879 break;
880 case GL_UNSIGNED_SHORT:
881 for (i = 0; i < width; i++)
882 usDst[i] = FLOAT_TO_USHORT(tmpRow[i*4+index]);
883 break;
884 case GL_INT:
885 for (i = 0; i < width; i++)
886 iDst[i] = FLOAT_TO_INT(tmpRow[i*4+index]);
887 break;
888 case GL_UNSIGNED_INT:
889 for (i = 0; i < width; i++)
890 uiDst[i] = FLOAT_TO_UINT(tmpRow[i*4+index]);
891 break;
892 case GL_FLOAT:
893 for (i = 0; i < width; i++)
894 fDst[i] = tmpRow[i*4+index];
895 break;
896 case GL_DOUBLE:
897 for (i = 0; i < width; i++)
898 dDst[i] = tmpRow[i*4+index];
899 break;
900 default:
901 crError("unexpected type in put_row in pixel.c");
902 }
903 }
904 else if (dstFormat == GL_LUMINANCE_ALPHA) {
905 switch (dstType) {
906 case GL_BYTE:
907 for (i = 0; i < width; i++) {
908 bDst[i*2+0] = FLOAT_TO_BYTE(tmpRow[i*4+0]);
909 bDst[i*2+1] = FLOAT_TO_BYTE(tmpRow[i*4+3]);
910 }
911 break;
912 case GL_UNSIGNED_BYTE:
913 for (i = 0; i < width; i++) {
914 ubDst[i*2+0] = FLOAT_TO_UBYTE(tmpRow[i*4+0]);
915 ubDst[i*2+1] = FLOAT_TO_UBYTE(tmpRow[i*4+3]);
916 }
917 break;
918 case GL_SHORT:
919 for (i = 0; i < width; i++) {
920 sDst[i*2+0] = FLOAT_TO_SHORT(tmpRow[i*4+0]);
921 sDst[i*2+1] = FLOAT_TO_SHORT(tmpRow[i*4+3]);
922 }
923 break;
924 case GL_UNSIGNED_SHORT:
925 for (i = 0; i < width; i++) {
926 usDst[i*2+0] = FLOAT_TO_USHORT(tmpRow[i*4+0]);
927 usDst[i*2+1] = FLOAT_TO_USHORT(tmpRow[i*4+3]);
928 }
929 break;
930 case GL_INT:
931 for (i = 0; i < width; i++) {
932 iDst[i*2+0] = FLOAT_TO_INT(tmpRow[i*4+0]);
933 iDst[i*2+1] = FLOAT_TO_INT(tmpRow[i*4+3]);
934 }
935 break;
936 case GL_UNSIGNED_INT:
937 for (i = 0; i < width; i++) {
938 uiDst[i*2+0] = FLOAT_TO_UINT(tmpRow[i*4+0]);
939 uiDst[i*2+1] = FLOAT_TO_UINT(tmpRow[i*4+3]);
940 }
941 break;
942 case GL_FLOAT:
943 for (i = 0; i < width; i++) {
944 fDst[i*2+0] = tmpRow[i*4+0];
945 fDst[i*2+1] = tmpRow[i*4+3];
946 }
947 break;
948 case GL_DOUBLE:
949 for (i = 0; i < width; i++) {
950 dDst[i*2+0] = tmpRow[i*4+0];
951 dDst[i*2+1] = tmpRow[i*4+3];
952 }
953 break;
954 default:
955 crError("unexpected type in put_row in pixel.c");
956 }
957 }
958 else if (dstFormat == GL_RGB
959#ifdef CR_OPENGL_VERSION_1_2
960 || dstFormat == GL_BGR
961#endif
962 ) {
963 int r, b;
964 if (dstFormat == GL_RGB) {
965 r = 0; b = 2;
966 }
967 else {
968 r = 2; b = 0;
969 }
970 switch (dstType) {
971 case GL_BYTE:
972 for (i = 0; i < width; i++) {
973 bDst[i*3+r] = FLOAT_TO_BYTE(tmpRow[i*4+0]);
974 bDst[i*3+1] = FLOAT_TO_BYTE(tmpRow[i*4+1]);
975 bDst[i*3+b] = FLOAT_TO_BYTE(tmpRow[i*4+2]);
976 }
977 break;
978 case GL_UNSIGNED_BYTE:
979 for (i = 0; i < width; i++) {
980 ubDst[i*3+r] = FLOAT_TO_UBYTE(tmpRow[i*4+0]);
981 ubDst[i*3+1] = FLOAT_TO_UBYTE(tmpRow[i*4+1]);
982 ubDst[i*3+b] = FLOAT_TO_UBYTE(tmpRow[i*4+2]);
983 }
984 break;
985 case GL_SHORT:
986 for (i = 0; i < width; i++) {
987 sDst[i*3+r] = FLOAT_TO_SHORT(tmpRow[i*4+0]);
988 sDst[i*3+1] = FLOAT_TO_SHORT(tmpRow[i*4+1]);
989 sDst[i*3+b] = FLOAT_TO_SHORT(tmpRow[i*4+2]);
990 }
991 break;
992 case GL_UNSIGNED_SHORT:
993 for (i = 0; i < width; i++) {
994 usDst[i*3+r] = FLOAT_TO_USHORT(tmpRow[i*4+0]);
995 usDst[i*3+1] = FLOAT_TO_USHORT(tmpRow[i*4+1]);
996 usDst[i*3+b] = FLOAT_TO_USHORT(tmpRow[i*4+2]);
997 }
998 break;
999 case GL_INT:
1000 for (i = 0; i < width; i++) {
1001 iDst[i*3+r] = FLOAT_TO_INT(tmpRow[i*4+0]);
1002 iDst[i*3+1] = FLOAT_TO_INT(tmpRow[i*4+1]);
1003 iDst[i*3+b] = FLOAT_TO_INT(tmpRow[i*4+2]);
1004 }
1005 break;
1006 case GL_UNSIGNED_INT:
1007 for (i = 0; i < width; i++) {
1008 uiDst[i*3+r] = FLOAT_TO_UINT(tmpRow[i*4+0]);
1009 uiDst[i*3+1] = FLOAT_TO_UINT(tmpRow[i*4+1]);
1010 uiDst[i*3+b] = FLOAT_TO_UINT(tmpRow[i*4+2]);
1011 }
1012 break;
1013 case GL_FLOAT:
1014 for (i = 0; i < width; i++) {
1015 fDst[i*3+r] = tmpRow[i*4+0];
1016 fDst[i*3+1] = tmpRow[i*4+1];
1017 fDst[i*3+b] = tmpRow[i*4+2];
1018 }
1019 break;
1020 case GL_DOUBLE:
1021 for (i = 0; i < width; i++) {
1022 dDst[i*3+r] = tmpRow[i*4+0];
1023 dDst[i*3+1] = tmpRow[i*4+1];
1024 dDst[i*3+b] = tmpRow[i*4+2];
1025 }
1026 break;
1027#ifdef CR_OPENGL_VERSION_1_2
1028 case GL_UNSIGNED_BYTE_3_3_2:
1029 for (i = 0; i < width; i++) {
1030 int red = (int) (tmpRow[i*4+r] * 7.0);
1031 int green = (int) (tmpRow[i*4+1] * 7.0);
1032 int blue = (int) (tmpRow[i*4+b] * 3.0);
1033 ubDst[i] = (red << 5) | (green << 2) | blue;
1034 }
1035 break;
1036 case GL_UNSIGNED_BYTE_2_3_3_REV:
1037 for (i = 0; i < width; i++) {
1038 int red = (int) (tmpRow[i*4+r] * 7.0);
1039 int green = (int) (tmpRow[i*4+1] * 7.0);
1040 int blue = (int) (tmpRow[i*4+b] * 3.0);
1041 ubDst[i] = red | (green << 3) | (blue << 6);
1042 }
1043 break;
1044 case GL_UNSIGNED_SHORT_5_6_5:
1045 for (i = 0; i < width; i++) {
1046 int red = (int) (tmpRow[i*4+r] * 31.0);
1047 int green = (int) (tmpRow[i*4+1] * 63.0);
1048 int blue = (int) (tmpRow[i*4+b] * 31.0);
1049 usDst[i] = (red << 11) | (green << 5) | blue;
1050 }
1051 break;
1052 case GL_UNSIGNED_SHORT_5_6_5_REV:
1053 for (i = 0; i < width; i++) {
1054 int red = (int) (tmpRow[i*4+r] * 31.0);
1055 int green = (int) (tmpRow[i*4+1] * 63.0);
1056 int blue = (int) (tmpRow[i*4+b] * 31.0);
1057 usDst[i] = (blue << 11) | (green << 5) | red;
1058 }
1059 break;
1060#endif
1061 default:
1062 crError("unexpected type in put_row in pixel.c");
1063 }
1064 }
1065 else if (dstFormat == GL_RGBA
1066#ifdef CR_OPENGL_VERSION_1_2
1067 || dstFormat == GL_BGRA
1068#endif
1069 ) {
1070 int r, b;
1071 if (dstFormat == GL_RGB) {
1072 r = 0; b = 2;
1073 }
1074 else {
1075 r = 2; b = 0;
1076 }
1077 switch (dstType) {
1078 case GL_BYTE:
1079 for (i = 0; i < width; i++) {
1080 bDst[i*4+r] = FLOAT_TO_BYTE(tmpRow[i*4+0]);
1081 bDst[i*4+1] = FLOAT_TO_BYTE(tmpRow[i*4+1]);
1082 bDst[i*4+b] = FLOAT_TO_BYTE(tmpRow[i*4+2]);
1083 bDst[i*4+3] = FLOAT_TO_BYTE(tmpRow[i*4+3]);
1084 }
1085 break;
1086 case GL_UNSIGNED_BYTE:
1087 for (i = 0; i < width; i++) {
1088 ubDst[i*4+r] = FLOAT_TO_UBYTE(tmpRow[i*4+0]);
1089 ubDst[i*4+1] = FLOAT_TO_UBYTE(tmpRow[i*4+1]);
1090 ubDst[i*4+b] = FLOAT_TO_UBYTE(tmpRow[i*4+2]);
1091 ubDst[i*4+3] = FLOAT_TO_UBYTE(tmpRow[i*4+3]);
1092 }
1093 break;
1094 case GL_SHORT:
1095 for (i = 0; i < width; i++) {
1096 sDst[i*4+r] = FLOAT_TO_SHORT(tmpRow[i*4+0]);
1097 sDst[i*4+1] = FLOAT_TO_SHORT(tmpRow[i*4+1]);
1098 sDst[i*4+b] = FLOAT_TO_SHORT(tmpRow[i*4+2]);
1099 sDst[i*4+3] = FLOAT_TO_SHORT(tmpRow[i*4+3]);
1100 }
1101 break;
1102 case GL_UNSIGNED_SHORT:
1103 for (i = 0; i < width; i++) {
1104 usDst[i*4+r] = FLOAT_TO_USHORT(tmpRow[i*4+0]);
1105 usDst[i*4+1] = FLOAT_TO_USHORT(tmpRow[i*4+1]);
1106 usDst[i*4+b] = FLOAT_TO_USHORT(tmpRow[i*4+2]);
1107 usDst[i*4+3] = FLOAT_TO_USHORT(tmpRow[i*4+3]);
1108 }
1109 break;
1110 case GL_INT:
1111 for (i = 0; i < width; i++) {
1112 iDst[i*4+r] = FLOAT_TO_INT(tmpRow[i*4+0]);
1113 iDst[i*4+1] = FLOAT_TO_INT(tmpRow[i*4+1]);
1114 iDst[i*4+b] = FLOAT_TO_INT(tmpRow[i*4+2]);
1115 iDst[i*4+3] = FLOAT_TO_INT(tmpRow[i*4+3]);
1116 }
1117 break;
1118 case GL_UNSIGNED_INT:
1119 for (i = 0; i < width; i++) {
1120 uiDst[i*4+r] = FLOAT_TO_UINT(tmpRow[i*4+0]);
1121 uiDst[i*4+1] = FLOAT_TO_UINT(tmpRow[i*4+1]);
1122 uiDst[i*4+b] = FLOAT_TO_UINT(tmpRow[i*4+2]);
1123 uiDst[i*4+3] = FLOAT_TO_UINT(tmpRow[i*4+3]);
1124 }
1125 break;
1126 case GL_FLOAT:
1127 for (i = 0; i < width; i++) {
1128 fDst[i*4+r] = tmpRow[i*4+0];
1129 fDst[i*4+1] = tmpRow[i*4+1];
1130 fDst[i*4+b] = tmpRow[i*4+2];
1131 fDst[i*4+3] = tmpRow[i*4+3];
1132 }
1133 break;
1134 case GL_DOUBLE:
1135 for (i = 0; i < width; i++) {
1136 dDst[i*4+r] = tmpRow[i*4+0];
1137 dDst[i*4+1] = tmpRow[i*4+1];
1138 dDst[i*4+b] = tmpRow[i*4+2];
1139 dDst[i*4+3] = tmpRow[i*4+3];
1140 }
1141 break;
1142#ifdef CR_OPENGL_VERSION_1_2
1143 case GL_UNSIGNED_SHORT_5_5_5_1:
1144 for (i = 0; i < width; i++) {
1145 int red = (int) (tmpRow[i*4+r] * 31.0);
1146 int green = (int) (tmpRow[i*4+1] * 31.0);
1147 int blue = (int) (tmpRow[i*4+b] * 31.0);
1148 int alpha = (int) (tmpRow[i*4+3]);
1149 usDst[i] = (red << 11) | (green << 6) | (blue << 1) | alpha;
1150 }
1151 break;
1152 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
1153 for (i = 0; i < width; i++) {
1154 int red = (int) (tmpRow[i*4+r] * 31.0);
1155 int green = (int) (tmpRow[i*4+1] * 31.0);
1156 int blue = (int) (tmpRow[i*4+b] * 31.0);
1157 int alpha = (int) (tmpRow[i*4+3]);
1158 usDst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
1159 }
1160 break;
1161 case GL_UNSIGNED_SHORT_4_4_4_4:
1162 for (i = 0; i < width; i++) {
1163 int red = (int) (tmpRow[i*4+r] * 15.0f);
1164 int green = (int) (tmpRow[i*4+1] * 15.0f);
1165 int blue = (int) (tmpRow[i*4+b] * 15.0f);
1166 int alpha = (int) (tmpRow[i*4+3] * 15.0f);
1167 usDst[i] = (red << 12) | (green << 8) | (blue << 4) | alpha;
1168 }
1169 break;
1170 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
1171 for (i = 0; i < width; i++) {
1172 int red = (int) (tmpRow[i*4+r] * 15.0f);
1173 int green = (int) (tmpRow[i*4+1] * 15.0f);
1174 int blue = (int) (tmpRow[i*4+b] * 15.0f);
1175 int alpha = (int) (tmpRow[i*4+3] * 15.0f);
1176 usDst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
1177 }
1178 break;
1179 case GL_UNSIGNED_INT_8_8_8_8:
1180 for (i = 0; i < width; i++) {
1181 int red = (int) (tmpRow[i*4+r] * 255.0f);
1182 int green = (int) (tmpRow[i*4+1] * 255.0f);
1183 int blue = (int) (tmpRow[i*4+b] * 255.0f);
1184 int alpha = (int) (tmpRow[i*4+3] * 255.0f);
1185 uiDst[i] = (red << 24) | (green << 16) | (blue << 8) | alpha;
1186 }
1187 break;
1188 case GL_UNSIGNED_INT_8_8_8_8_REV:
1189 for (i = 0; i < width; i++) {
1190 int red = (int) (tmpRow[i*4+r] * 255.0f);
1191 int green = (int) (tmpRow[i*4+1] * 255.0f);
1192 int blue = (int) (tmpRow[i*4+b] * 255.0f);
1193 int alpha = (int) (tmpRow[i*4+3] * 255.0f);
1194 uiDst[i] = (alpha << 24) | (blue << 16) | (green << 8) | red;
1195 }
1196 break;
1197 case GL_UNSIGNED_INT_10_10_10_2:
1198 for (i = 0; i < width; i++) {
1199 int red = (int) (tmpRow[i*4+r] * 1023.0f);
1200 int green = (int) (tmpRow[i*4+1] * 1023.0f);
1201 int blue = (int) (tmpRow[i*4+b] * 1023.0f);
1202 int alpha = (int) (tmpRow[i*4+3] * 3.0f);
1203 uiDst[i] = (red << 22) | (green << 12) | (blue << 2) | alpha;
1204 }
1205 break;
1206 case GL_UNSIGNED_INT_2_10_10_10_REV:
1207 for (i = 0; i < width; i++) {
1208 int red = (int) (tmpRow[i*4+r] * 1023.0f);
1209 int green = (int) (tmpRow[i*4+1] * 1023.0f);
1210 int blue = (int) (tmpRow[i*4+b] * 1023.0f);
1211 int alpha = (int) (tmpRow[i*4+3] * 3.0f);
1212 uiDst[i] = (alpha << 30) | (blue << 20) | (green << 10) | red;
1213 }
1214 break;
1215#endif
1216 default:
1217 crError("unexpected type in put_row in pixel.c");
1218 }
1219 }
1220 else{
1221 crError("unexpected dest type in put_row in pixel.c");
1222 }
1223}
1224
1225#ifdef _MSC_VER
1226# pragma optimize("", on) /* bird: see #pragma optimize("g", off) above. */
1227#endif
1228
1229/**
1230 * Byte-swap an array of GLushorts
1231 */
1232static void
1233swap2(GLushort *us, GLuint n)
1234{
1235 GLuint i;
1236 for (i = 0; i < n; i++) {
1237 us[i] = (us[i] >> 8) | (us[i] << 8);
1238 }
1239}
1240
1241
1242/**
1243 * Byte-swap an array of GLuints
1244 */
1245static void
1246swap4(GLuint *ui, GLuint n)
1247{
1248 GLuint i;
1249
1250 for (i = 0; i < n; i++) {
1251 GLuint b = ui[i];
1252 ui[i] = (b >> 24)
1253 | ((b >> 8) & 0xff00)
1254 | ((b << 8) & 0xff0000)
1255 | ((b << 24) & 0xff000000);
1256 }
1257}
1258
1259
1260/**
1261 * Return number of bytes of storage needed to accomodate an
1262 * image with the given format, type, and size.
1263 * \return size in bytes or -1 if bad format or type
1264 */
1265unsigned int crImageSize( GLenum format, GLenum type, GLsizei width, GLsizei height )
1266{
1267 unsigned int bytes = width * height;
1268
1269 if (type == GL_BITMAP)
1270 {
1271 /* This was wrong in the old code! */
1272 bytes = ((width + 7) / 8) * height;
1273 }
1274 else
1275 {
1276 bytes = width * height * crPixelSize( format, type );
1277 }
1278
1279 return bytes;
1280}
1281
1282/**
1283 * Return number of bytes of storage needed to accomodate a
1284 * 3D texture with the give format, type, and size.
1285 * \return size in bytes or -1 if bad format or type
1286 */
1287unsigned int crTextureSize( GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth )
1288{
1289 unsigned int bytes = width * height;
1290
1291 if (type == GL_BITMAP)
1292 {
1293 /*
1294 * Not sure about this one, so just multiply
1295 * by the depth?
1296 */
1297 bytes = ((width + 7) / 8) * height * depth;
1298 }
1299 else
1300 {
1301 bytes = width * height * depth * crPixelSize( format, type );
1302 }
1303
1304 return bytes;
1305}
1306
1307static const CRPixelPackState defaultPacking = {
1308 0, /* rowLength */
1309 0, /* skipRows */
1310 0, /* skipPixels */
1311 1, /* alignment */
1312 0, /* imageHeight */
1313 0, /* skipImages */
1314 GL_FALSE, /* swapBytes */
1315 GL_FALSE /* psLSBFirst */
1316};
1317
1318
1319void crPixelCopy1D( GLvoid *dstPtr, GLenum dstFormat, GLenum dstType,
1320 const GLvoid *srcPtr, GLenum srcFormat, GLenum srcType,
1321 GLsizei width, const CRPixelPackState *srcPacking )
1322{
1323 crPixelCopy2D( width, 1,
1324 dstPtr, dstFormat, dstType, NULL, /* dst */
1325 srcPtr, srcFormat, srcType, srcPacking ); /* src */
1326}
1327
1328void crPixelCopy2D( GLsizei width, GLsizei height,
1329 GLvoid *dstPtr, GLenum dstFormat, GLenum dstType,
1330 const CRPixelPackState *dstPacking,
1331 const GLvoid *srcPtr, GLenum srcFormat, GLenum srcType,
1332 const CRPixelPackState *srcPacking )
1333
1334{
1335 const char *src = (const char *) srcPtr;
1336 char *dst = (char *) dstPtr;
1337 int srcBytesPerPixel;
1338 int dstBytesPerPixel;
1339 int srcBytesPerRow;
1340 int dstBytesPerRow;
1341 int srcRowStrideBytes;
1342 int dstRowStrideBytes;
1343 int bytesPerRow;
1344 int i;
1345
1346 if (!dstPacking)
1347 dstPacking = &defaultPacking;
1348
1349 if (!srcPacking)
1350 srcPacking = &defaultPacking;
1351
1352 if (srcType == GL_BITMAP)
1353 {
1354 CRASSERT(dstType == GL_BITMAP);
1355 bytesPerRow = (width + 7) / 8;
1356 if (srcPacking->rowLength > 0)
1357 srcRowStrideBytes = (srcPacking->rowLength + 7) / 8;
1358 else
1359 srcRowStrideBytes = bytesPerRow;
1360 dstRowStrideBytes = bytesPerRow;
1361
1362 for (i=0; i<height; i++) {
1363 crMemcpy( (void *) dst, (const void *) src, bytesPerRow );
1364 dst += dstRowStrideBytes;
1365 src += srcRowStrideBytes;
1366 }
1367 }
1368 else
1369 {
1370 CRASSERT(dstType != GL_BITMAP);
1371 srcBytesPerPixel = crPixelSize( srcFormat, srcType );
1372 dstBytesPerPixel = crPixelSize( dstFormat, dstType );
1373 if (srcBytesPerPixel < 0 || dstBytesPerPixel < 0)
1374 return;
1375
1376 /* Stride between rows (in bytes) */
1377 if (srcPacking->rowLength > 0)
1378 srcRowStrideBytes = srcPacking->rowLength * srcBytesPerPixel;
1379 else
1380 srcRowStrideBytes = width * srcBytesPerPixel;
1381
1382 if (dstPacking->rowLength > 0)
1383 dstRowStrideBytes = dstPacking->rowLength * dstBytesPerPixel;
1384 else
1385 dstRowStrideBytes = width * dstBytesPerPixel;
1386
1387 /* bytes per row */
1388 srcBytesPerRow = width * srcBytesPerPixel;
1389 dstBytesPerRow = width * dstBytesPerPixel;
1390
1391 /* handle the alignment */
1392 if (srcPacking->alignment != 1) {
1393 i = ((long) src) % srcPacking->alignment;
1394 if (i)
1395 src += srcPacking->alignment - i;
1396 i = (long) srcRowStrideBytes % srcPacking->alignment;
1397 if (i)
1398 srcRowStrideBytes += srcPacking->alignment - i;
1399 }
1400
1401 if (dstPacking->alignment != 1) {
1402 i = ((long) dst) % dstPacking->alignment;
1403 if (i)
1404 dst += dstPacking->alignment - i;
1405 i = (long) dstRowStrideBytes % dstPacking->alignment;
1406 if (i)
1407 dstRowStrideBytes += dstPacking->alignment - i;
1408 }
1409
1410 /* handle skip rows */
1411 src += srcPacking->skipRows * srcRowStrideBytes;
1412 dst += dstPacking->skipRows * dstRowStrideBytes;
1413
1414 /* handle skip pixels */
1415 src += srcPacking->skipPixels * srcBytesPerPixel;
1416 dst += dstPacking->skipPixels * dstBytesPerPixel;
1417
1418 /* we don't do LSBFirst yet */
1419 if (srcPacking->psLSBFirst)
1420 crError( "Sorry, no lsbfirst for you" );
1421 if (dstPacking->psLSBFirst)
1422 crError( "Sorry, no lsbfirst for you" );
1423
1424 if (srcFormat == dstFormat && srcType == dstType)
1425 {
1426 CRASSERT(srcBytesPerRow == dstBytesPerRow);
1427 for (i = 0; i < height; i++)
1428 {
1429 crMemcpy( (void *) dst, (const void *) src, srcBytesPerRow );
1430 /* check if src XOR dst swapping */
1431 if (srcPacking->swapBytes ^ dstPacking->swapBytes) {
1432 const GLint size = crSizeOfType(srcType);
1433 CRASSERT(srcType == dstType);
1434 if (size == 2) {
1435 swap2((GLushort *) dst, srcBytesPerRow / size);
1436 }
1437 else if (size == 4) {
1438 swap4((GLuint *) dst, srcBytesPerRow / size);
1439 }
1440 }
1441 dst += dstRowStrideBytes;
1442 src += srcRowStrideBytes;
1443 }
1444 }
1445 else
1446 {
1447 /* need to do format and/or type conversion */
1448 char *swapRow = NULL;
1449 GLfloat *tmpRow = crAlloc( 4 * width * sizeof(GLfloat) );
1450 if (!tmpRow)
1451 crError("Out of memory in crPixelCopy2D");
1452
1453 if (srcPacking->swapBytes) {
1454 swapRow = (char *) crAlloc(width * srcBytesPerPixel);
1455 if (!swapRow) {
1456 crError("Out of memory in crPixelCopy2D");
1457 }
1458 }
1459
1460 for (i = 0; i < height; i++)
1461 {
1462 /* get src row as floats */
1463 if (srcPacking->swapBytes) {
1464 const GLint size = crSizeOfType(srcType);
1465 const GLint bytes = width * srcBytesPerPixel;
1466 crMemcpy(swapRow, src, bytes);
1467 if (size == 2)
1468 swap2((GLushort *) swapRow, bytes / 2);
1469 else if (size == 4)
1470 swap4((GLuint *) swapRow, bytes / 4);
1471 get_row(swapRow, srcFormat, srcType, width, tmpRow);
1472 }
1473 else {
1474 get_row(src, srcFormat, srcType, width, tmpRow);
1475 }
1476
1477 /* store floats in dest row */
1478 if (dstPacking->swapBytes) {
1479 const GLint size = crSizeOfType(dstType);
1480 const GLint bytes = dstBytesPerPixel * width;
1481 put_row(dst, dstFormat, dstType, width, tmpRow);
1482 if (size == 2)
1483 swap2((GLushort *) dst, bytes / 2);
1484 else if (size == 4)
1485 swap4((GLuint *) dst, bytes / 4);
1486 }
1487 else {
1488 put_row(dst, dstFormat, dstType, width, tmpRow);
1489 }
1490
1491 /* increment pointers for next row */
1492 dst += dstRowStrideBytes;
1493 src += srcRowStrideBytes;
1494 }
1495
1496 crFree(tmpRow);
1497 if (swapRow)
1498 crFree(swapRow);
1499 }
1500 }
1501 }
1502
1503void crPixelCopy3D( GLsizei width, GLsizei height, GLsizei depth,
1504 GLvoid *dstPtr, GLenum dstFormat, GLenum dstType,
1505 const CRPixelPackState *dstPacking,
1506 const GLvoid *srcPtr, GLenum srcFormat, GLenum srcType,
1507 const CRPixelPackState *srcPacking )
1508
1509{
1510 int tex_size = 0;
1511
1512 (void)srcPacking;
1513 (void)srcType;
1514 (void)srcFormat;
1515 (void)dstPacking;
1516
1517 /*@todo this should be implemented properly*/
1518
1519 crWarning( "crPixelCopy3D: simply crMemcpy'ing from srcPtr to dstPtr" );
1520 if (dstFormat != srcFormat)
1521 crWarning( "crPixelCopy3D: formats don't match!" );
1522 if (dstType != srcType)
1523 crWarning( "crPixelCopy3D: formats don't match!" );
1524
1525 tex_size = RT_MIN (crTextureSize( dstFormat, dstType, width, height, depth ),
1526 crTextureSize( srcFormat, srcType, width, height, depth ));
1527 crMemcpy( (void *) dstPtr, (void *) srcPtr, tex_size );
1528}
1529
1530/* Round N up to the next multiple of 8 */
1531#define CEIL8(N) (((N) + 7) & ~0x7)
1532
1533void crBitmapCopy( GLsizei width, GLsizei height, GLubyte *dstPtr,
1534 const GLubyte *srcPtr, const CRPixelPackState *srcPacking )
1535{
1536 if (srcPacking->psLSBFirst == GL_FALSE &&
1537 (srcPacking->rowLength == 0 || srcPacking->rowLength == width) &&
1538 srcPacking->skipRows == 0 &&
1539 srcPacking->skipPixels == 0 &&
1540 srcPacking->alignment == 1) {
1541 /* simple case */
1542 crMemcpy(dstPtr, srcPtr, CEIL8(width) * height / 8);
1543 }
1544 else {
1545 /* general case */
1546 const GLubyte *srcRow;
1547 const GLint dst_row_length = CEIL8(width) / 8;
1548 GLubyte *dstRow;
1549 GLint src_row_length;
1550 GLint i, j;
1551
1552 if (srcPacking->rowLength > 0)
1553 src_row_length = srcPacking->rowLength;
1554 else
1555 src_row_length = width;
1556
1557 switch (srcPacking->alignment) {
1558 case 1:
1559 src_row_length = ( ( src_row_length + 7 ) & ~7 ) >> 3;
1560 break;
1561 case 2:
1562 src_row_length = ( ( src_row_length + 15 ) & ~15 ) >> 3;
1563 break;
1564 case 4:
1565 src_row_length = ( ( src_row_length + 31 ) & ~31 ) >> 3;
1566 break;
1567 case 8:
1568 src_row_length = ( ( src_row_length + 63 ) & ~63 ) >> 3;
1569 break;
1570 default:
1571 crError( "Invalid unpack alignment in crBitmapCopy");
1572 return;
1573 }
1574
1575 /* src_row_length and dst_row_length are in bytes */
1576
1577 srcRow = srcPtr + src_row_length * srcPacking->skipRows;
1578 dstRow = dstPtr;
1579
1580 if (srcPacking->psLSBFirst) {
1581 for (j = 0; j < height; j++) {
1582 crMemZero(dstRow, dst_row_length);
1583 for (i = 0; i < width; i++) {
1584 const GLint iByte = (i + srcPacking->skipPixels) / 8;
1585 const GLint iBit = (i + srcPacking->skipPixels) % 8;
1586 const GLubyte b = srcRow[iByte];
1587 if (b & (1 << iBit))
1588 dstRow[i / 8] |= (128 >> (i % 8));
1589 }
1590 srcRow += src_row_length;
1591 dstRow += dst_row_length;
1592 }
1593 }
1594 else {
1595 /* unpack MSB first */
1596 for (j = 0; j < height; j++) {
1597 crMemZero(dstRow, dst_row_length);
1598 for (i = 0; i < width; i++) {
1599 const GLint iByte = (i + srcPacking->skipPixels) / 8;
1600 const GLint iBit = (i + srcPacking->skipPixels) % 8;
1601 const GLubyte b = srcRow[iByte];
1602 if (b & (128 >> iBit))
1603 dstRow[i / 8] |= (128 >> (i % 8));
1604 }
1605 srcRow += src_row_length;
1606 dstRow += dst_row_length;
1607 }
1608 }
1609 }
1610}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette