VirtualBox

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

Last change on this file since 30045 was 27398, checked in by vboxsync, 15 years ago

crOpenGL: fix burn

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