VirtualBox

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

Last change on this file since 69989 was 69392, checked in by vboxsync, 7 years ago

GuestHost/OpenGL: scm updates

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

© 2023 Oracle
ContactPrivacy policyTerms of Use