VirtualBox

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

Last change on this file since 41109 was 35263, checked in by vboxsync, 14 years ago

crOpenGL: fix crashes in libnux-0.9 gpu tests

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