VirtualBox

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

Last change on this file since 62479 was 53726, checked in by vboxsync, 10 years ago

properties.

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

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