VirtualBox

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

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

crOpenGL/wddm: disable partial blits for hd4800 only

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