new X86 CPU detection code (Petr Sebor)
[mesa.git] / src / mesa / main / pixel.c
1 /* $Id: pixel.c,v 1.37 2002/10/24 23:57:21 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #include "glheader.h"
28 #include "imports.h"
29 #include "colormac.h"
30 #include "context.h"
31 #include "macros.h"
32 #include "pixel.h"
33 #include "mtypes.h"
34
35
36 /**********************************************************************/
37 /***** glPixelZoom *****/
38 /**********************************************************************/
39
40
41
42 void
43 _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
44 {
45 GET_CURRENT_CONTEXT(ctx);
46
47 if (ctx->Pixel.ZoomX == xfactor &&
48 ctx->Pixel.ZoomY == yfactor)
49 return;
50
51 FLUSH_VERTICES(ctx, _NEW_PIXEL);
52 ctx->Pixel.ZoomX = xfactor;
53 ctx->Pixel.ZoomY = yfactor;
54 }
55
56
57
58 /**********************************************************************/
59 /***** glPixelStore *****/
60 /**********************************************************************/
61
62
63 void
64 _mesa_PixelStorei( GLenum pname, GLint param )
65 {
66 /* NOTE: this call can't be compiled into the display list */
67 GET_CURRENT_CONTEXT(ctx);
68 ASSERT_OUTSIDE_BEGIN_END(ctx);
69
70 switch (pname) {
71 case GL_PACK_SWAP_BYTES:
72 if (param == (GLint)ctx->Pack.SwapBytes)
73 return;
74 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
75 ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
76 break;
77 case GL_PACK_LSB_FIRST:
78 if (param == (GLint)ctx->Pack.LsbFirst)
79 return;
80 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
81 ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
82 break;
83 case GL_PACK_ROW_LENGTH:
84 if (param<0) {
85 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
86 return;
87 }
88 if (ctx->Pack.RowLength == param)
89 return;
90 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
91 ctx->Pack.RowLength = param;
92 break;
93 case GL_PACK_IMAGE_HEIGHT:
94 if (param<0) {
95 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
96 return;
97 }
98 if (ctx->Pack.ImageHeight == param)
99 return;
100 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
101 ctx->Pack.ImageHeight = param;
102 break;
103 case GL_PACK_SKIP_PIXELS:
104 if (param<0) {
105 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
106 return;
107 }
108 if (ctx->Pack.SkipPixels == param)
109 return;
110 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
111 ctx->Pack.SkipPixels = param;
112 break;
113 case GL_PACK_SKIP_ROWS:
114 if (param<0) {
115 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
116 return;
117 }
118 if (ctx->Pack.SkipRows == param)
119 return;
120 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
121 ctx->Pack.SkipRows = param;
122 break;
123 case GL_PACK_SKIP_IMAGES:
124 if (param<0) {
125 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
126 return;
127 }
128 if (ctx->Pack.SkipImages == param)
129 return;
130 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
131 ctx->Pack.SkipImages = param;
132 break;
133 case GL_PACK_ALIGNMENT:
134 if (param!=1 && param!=2 && param!=4 && param!=8) {
135 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
136 return;
137 }
138 if (ctx->Pack.Alignment == param)
139 return;
140 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
141 ctx->Pack.Alignment = param;
142 break;
143 case GL_PACK_INVERT_MESA:
144 if (!ctx->Extensions.MESA_pack_invert) {
145 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
146 return;
147 }
148 if (ctx->Pack.Invert == param)
149 return;
150 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
151 ctx->Pack.Invert = param;
152 break;
153
154 case GL_UNPACK_SWAP_BYTES:
155 if (param == (GLint)ctx->Unpack.SwapBytes)
156 return;
157 if ((GLint)ctx->Unpack.SwapBytes == param)
158 return;
159 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
160 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
161 break;
162 case GL_UNPACK_LSB_FIRST:
163 if (param == (GLint)ctx->Unpack.LsbFirst)
164 return;
165 if ((GLint)ctx->Unpack.LsbFirst == param)
166 return;
167 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
168 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
169 break;
170 case GL_UNPACK_ROW_LENGTH:
171 if (param<0) {
172 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
173 return;
174 }
175 if (ctx->Unpack.RowLength == param)
176 return;
177 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
178 ctx->Unpack.RowLength = param;
179 break;
180 case GL_UNPACK_IMAGE_HEIGHT:
181 if (param<0) {
182 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
183 return;
184 }
185 if (ctx->Unpack.ImageHeight == param)
186 return;
187
188 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
189 ctx->Unpack.ImageHeight = param;
190 break;
191 case GL_UNPACK_SKIP_PIXELS:
192 if (param<0) {
193 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
194 return;
195 }
196 if (ctx->Unpack.SkipPixels == param)
197 return;
198 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
199 ctx->Unpack.SkipPixels = param;
200 break;
201 case GL_UNPACK_SKIP_ROWS:
202 if (param<0) {
203 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
204 return;
205 }
206 if (ctx->Unpack.SkipRows == param)
207 return;
208 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
209 ctx->Unpack.SkipRows = param;
210 break;
211 case GL_UNPACK_SKIP_IMAGES:
212 if (param < 0) {
213 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
214 return;
215 }
216 if (ctx->Unpack.SkipImages == param)
217 return;
218 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
219 ctx->Unpack.SkipImages = param;
220 break;
221 case GL_UNPACK_ALIGNMENT:
222 if (param!=1 && param!=2 && param!=4 && param!=8) {
223 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
224 return;
225 }
226 if (ctx->Unpack.Alignment == param)
227 return;
228 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
229 ctx->Unpack.Alignment = param;
230 break;
231 case GL_UNPACK_CLIENT_STORAGE_APPLE:
232 if (param == (GLint)ctx->Unpack.ClientStorage)
233 return;
234 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
235 ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE;
236 break;
237 default:
238 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
239 return;
240 }
241 }
242
243
244 void
245 _mesa_PixelStoref( GLenum pname, GLfloat param )
246 {
247 _mesa_PixelStorei( pname, (GLint) param );
248 }
249
250
251
252 /**********************************************************************/
253 /***** glPixelMap *****/
254 /**********************************************************************/
255
256
257
258 void
259 _mesa_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
260 {
261 GLint i;
262 GET_CURRENT_CONTEXT(ctx);
263 ASSERT_OUTSIDE_BEGIN_END(ctx);
264
265 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
266 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
267 return;
268 }
269
270 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
271 /* test that mapsize is a power of two */
272 if (_mesa_bitcount((GLuint) mapsize) != 1) {
273 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
274 return;
275 }
276 }
277
278 FLUSH_VERTICES(ctx, _NEW_PIXEL);
279
280 switch (map) {
281 case GL_PIXEL_MAP_S_TO_S:
282 ctx->Pixel.MapStoSsize = mapsize;
283 for (i=0;i<mapsize;i++) {
284 ctx->Pixel.MapStoS[i] = (GLint) values[i];
285 }
286 break;
287 case GL_PIXEL_MAP_I_TO_I:
288 ctx->Pixel.MapItoIsize = mapsize;
289 for (i=0;i<mapsize;i++) {
290 ctx->Pixel.MapItoI[i] = (GLint) values[i];
291 }
292 break;
293 case GL_PIXEL_MAP_I_TO_R:
294 ctx->Pixel.MapItoRsize = mapsize;
295 for (i=0;i<mapsize;i++) {
296 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
297 ctx->Pixel.MapItoR[i] = val;
298 ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
299 }
300 break;
301 case GL_PIXEL_MAP_I_TO_G:
302 ctx->Pixel.MapItoGsize = mapsize;
303 for (i=0;i<mapsize;i++) {
304 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
305 ctx->Pixel.MapItoG[i] = val;
306 ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
307 }
308 break;
309 case GL_PIXEL_MAP_I_TO_B:
310 ctx->Pixel.MapItoBsize = mapsize;
311 for (i=0;i<mapsize;i++) {
312 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
313 ctx->Pixel.MapItoB[i] = val;
314 ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
315 }
316 break;
317 case GL_PIXEL_MAP_I_TO_A:
318 ctx->Pixel.MapItoAsize = mapsize;
319 for (i=0;i<mapsize;i++) {
320 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
321 ctx->Pixel.MapItoA[i] = val;
322 ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
323 }
324 break;
325 case GL_PIXEL_MAP_R_TO_R:
326 ctx->Pixel.MapRtoRsize = mapsize;
327 for (i=0;i<mapsize;i++) {
328 ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0F, 1.0F );
329 }
330 break;
331 case GL_PIXEL_MAP_G_TO_G:
332 ctx->Pixel.MapGtoGsize = mapsize;
333 for (i=0;i<mapsize;i++) {
334 ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0F, 1.0F );
335 }
336 break;
337 case GL_PIXEL_MAP_B_TO_B:
338 ctx->Pixel.MapBtoBsize = mapsize;
339 for (i=0;i<mapsize;i++) {
340 ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0F, 1.0F );
341 }
342 break;
343 case GL_PIXEL_MAP_A_TO_A:
344 ctx->Pixel.MapAtoAsize = mapsize;
345 for (i=0;i<mapsize;i++) {
346 ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0F, 1.0F );
347 }
348 break;
349 default:
350 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
351 }
352 }
353
354
355
356 void
357 _mesa_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values )
358 {
359 const GLint n = MIN2(mapsize, MAX_PIXEL_MAP_TABLE);
360 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
361 GLint i;
362 if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
363 for (i=0;i<n;i++) {
364 fvalues[i] = (GLfloat) values[i];
365 }
366 }
367 else {
368 for (i=0;i<n;i++) {
369 fvalues[i] = UINT_TO_FLOAT( values[i] );
370 }
371 }
372 _mesa_PixelMapfv(map, mapsize, fvalues);
373 }
374
375
376
377 void
378 _mesa_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values )
379 {
380 const GLint n = MIN2(mapsize, MAX_PIXEL_MAP_TABLE);
381 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
382 GLint i;
383 if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
384 for (i=0;i<n;i++) {
385 fvalues[i] = (GLfloat) values[i];
386 }
387 }
388 else {
389 for (i=0;i<n;i++) {
390 fvalues[i] = USHORT_TO_FLOAT( values[i] );
391 }
392 }
393 _mesa_PixelMapfv(map, mapsize, fvalues);
394 }
395
396
397
398 void
399 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
400 {
401 GET_CURRENT_CONTEXT(ctx);
402 GLint i;
403 ASSERT_OUTSIDE_BEGIN_END(ctx);
404
405 switch (map) {
406 case GL_PIXEL_MAP_I_TO_I:
407 for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
408 values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
409 }
410 break;
411 case GL_PIXEL_MAP_S_TO_S:
412 for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
413 values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
414 }
415 break;
416 case GL_PIXEL_MAP_I_TO_R:
417 MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
418 break;
419 case GL_PIXEL_MAP_I_TO_G:
420 MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
421 break;
422 case GL_PIXEL_MAP_I_TO_B:
423 MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
424 break;
425 case GL_PIXEL_MAP_I_TO_A:
426 MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
427 break;
428 case GL_PIXEL_MAP_R_TO_R:
429 MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
430 break;
431 case GL_PIXEL_MAP_G_TO_G:
432 MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
433 break;
434 case GL_PIXEL_MAP_B_TO_B:
435 MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
436 break;
437 case GL_PIXEL_MAP_A_TO_A:
438 MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
439 break;
440 default:
441 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
442 }
443 }
444
445
446 void
447 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
448 {
449 GET_CURRENT_CONTEXT(ctx);
450 GLint i;
451 ASSERT_OUTSIDE_BEGIN_END(ctx);
452
453 switch (map) {
454 case GL_PIXEL_MAP_I_TO_I:
455 MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
456 break;
457 case GL_PIXEL_MAP_S_TO_S:
458 MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
459 break;
460 case GL_PIXEL_MAP_I_TO_R:
461 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
462 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
463 }
464 break;
465 case GL_PIXEL_MAP_I_TO_G:
466 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
467 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
468 }
469 break;
470 case GL_PIXEL_MAP_I_TO_B:
471 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
472 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
473 }
474 break;
475 case GL_PIXEL_MAP_I_TO_A:
476 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
477 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
478 }
479 break;
480 case GL_PIXEL_MAP_R_TO_R:
481 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
482 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
483 }
484 break;
485 case GL_PIXEL_MAP_G_TO_G:
486 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
487 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
488 }
489 break;
490 case GL_PIXEL_MAP_B_TO_B:
491 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
492 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
493 }
494 break;
495 case GL_PIXEL_MAP_A_TO_A:
496 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
497 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
498 }
499 break;
500 default:
501 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
502 }
503 }
504
505
506 void
507 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
508 {
509 GET_CURRENT_CONTEXT(ctx);
510 GLint i;
511 ASSERT_OUTSIDE_BEGIN_END(ctx);
512
513 switch (map) {
514 case GL_PIXEL_MAP_I_TO_I:
515 for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
516 values[i] = (GLushort) ctx->Pixel.MapItoI[i];
517 }
518 break;
519 case GL_PIXEL_MAP_S_TO_S:
520 for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
521 values[i] = (GLushort) ctx->Pixel.MapStoS[i];
522 }
523 break;
524 case GL_PIXEL_MAP_I_TO_R:
525 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
526 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
527 }
528 break;
529 case GL_PIXEL_MAP_I_TO_G:
530 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
531 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
532 }
533 break;
534 case GL_PIXEL_MAP_I_TO_B:
535 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
536 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
537 }
538 break;
539 case GL_PIXEL_MAP_I_TO_A:
540 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
541 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
542 }
543 break;
544 case GL_PIXEL_MAP_R_TO_R:
545 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
546 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
547 }
548 break;
549 case GL_PIXEL_MAP_G_TO_G:
550 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
551 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
552 }
553 break;
554 case GL_PIXEL_MAP_B_TO_B:
555 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
556 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
557 }
558 break;
559 case GL_PIXEL_MAP_A_TO_A:
560 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
561 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
562 }
563 break;
564 default:
565 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
566 }
567 }
568
569
570
571 /**********************************************************************/
572 /***** glPixelTransfer *****/
573 /**********************************************************************/
574
575
576 /*
577 * Implements glPixelTransfer[fi] whether called immediately or from a
578 * display list.
579 */
580 void
581 _mesa_PixelTransferf( GLenum pname, GLfloat param )
582 {
583 GET_CURRENT_CONTEXT(ctx);
584 ASSERT_OUTSIDE_BEGIN_END(ctx);
585
586 switch (pname) {
587 case GL_MAP_COLOR:
588 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
589 return;
590 FLUSH_VERTICES(ctx, _NEW_PIXEL);
591 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
592 break;
593 case GL_MAP_STENCIL:
594 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
595 return;
596 FLUSH_VERTICES(ctx, _NEW_PIXEL);
597 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
598 break;
599 case GL_INDEX_SHIFT:
600 if (ctx->Pixel.IndexShift == (GLint) param)
601 return;
602 FLUSH_VERTICES(ctx, _NEW_PIXEL);
603 ctx->Pixel.IndexShift = (GLint) param;
604 break;
605 case GL_INDEX_OFFSET:
606 if (ctx->Pixel.IndexOffset == (GLint) param)
607 return;
608 FLUSH_VERTICES(ctx, _NEW_PIXEL);
609 ctx->Pixel.IndexOffset = (GLint) param;
610 break;
611 case GL_RED_SCALE:
612 if (ctx->Pixel.RedScale == param)
613 return;
614 FLUSH_VERTICES(ctx, _NEW_PIXEL);
615 ctx->Pixel.RedScale = param;
616 break;
617 case GL_RED_BIAS:
618 if (ctx->Pixel.RedBias == param)
619 return;
620 FLUSH_VERTICES(ctx, _NEW_PIXEL);
621 ctx->Pixel.RedBias = param;
622 break;
623 case GL_GREEN_SCALE:
624 if (ctx->Pixel.GreenScale == param)
625 return;
626 FLUSH_VERTICES(ctx, _NEW_PIXEL);
627 ctx->Pixel.GreenScale = param;
628 break;
629 case GL_GREEN_BIAS:
630 if (ctx->Pixel.GreenBias == param)
631 return;
632 FLUSH_VERTICES(ctx, _NEW_PIXEL);
633 ctx->Pixel.GreenBias = param;
634 break;
635 case GL_BLUE_SCALE:
636 if (ctx->Pixel.BlueScale == param)
637 return;
638 FLUSH_VERTICES(ctx, _NEW_PIXEL);
639 ctx->Pixel.BlueScale = param;
640 break;
641 case GL_BLUE_BIAS:
642 if (ctx->Pixel.BlueBias == param)
643 return;
644 FLUSH_VERTICES(ctx, _NEW_PIXEL);
645 ctx->Pixel.BlueBias = param;
646 break;
647 case GL_ALPHA_SCALE:
648 if (ctx->Pixel.AlphaScale == param)
649 return;
650 FLUSH_VERTICES(ctx, _NEW_PIXEL);
651 ctx->Pixel.AlphaScale = param;
652 break;
653 case GL_ALPHA_BIAS:
654 if (ctx->Pixel.AlphaBias == param)
655 return;
656 FLUSH_VERTICES(ctx, _NEW_PIXEL);
657 ctx->Pixel.AlphaBias = param;
658 break;
659 case GL_DEPTH_SCALE:
660 if (ctx->Pixel.DepthScale == param)
661 return;
662 FLUSH_VERTICES(ctx, _NEW_PIXEL);
663 ctx->Pixel.DepthScale = param;
664 break;
665 case GL_DEPTH_BIAS:
666 if (ctx->Pixel.DepthBias == param)
667 return;
668 FLUSH_VERTICES(ctx, _NEW_PIXEL);
669 ctx->Pixel.DepthBias = param;
670 break;
671 case GL_POST_COLOR_MATRIX_RED_SCALE:
672 if (ctx->Pixel.PostColorMatrixScale[0] == param)
673 return;
674 FLUSH_VERTICES(ctx, _NEW_PIXEL);
675 ctx->Pixel.PostColorMatrixScale[0] = param;
676 break;
677 case GL_POST_COLOR_MATRIX_RED_BIAS:
678 if (ctx->Pixel.PostColorMatrixBias[0] == param)
679 return;
680 FLUSH_VERTICES(ctx, _NEW_PIXEL);
681 ctx->Pixel.PostColorMatrixBias[0] = param;
682 break;
683 case GL_POST_COLOR_MATRIX_GREEN_SCALE:
684 if (ctx->Pixel.PostColorMatrixScale[1] == param)
685 return;
686 FLUSH_VERTICES(ctx, _NEW_PIXEL);
687 ctx->Pixel.PostColorMatrixScale[1] = param;
688 break;
689 case GL_POST_COLOR_MATRIX_GREEN_BIAS:
690 if (ctx->Pixel.PostColorMatrixBias[1] == param)
691 return;
692 FLUSH_VERTICES(ctx, _NEW_PIXEL);
693 ctx->Pixel.PostColorMatrixBias[1] = param;
694 break;
695 case GL_POST_COLOR_MATRIX_BLUE_SCALE:
696 if (ctx->Pixel.PostColorMatrixScale[2] == param)
697 return;
698 FLUSH_VERTICES(ctx, _NEW_PIXEL);
699 ctx->Pixel.PostColorMatrixScale[2] = param;
700 break;
701 case GL_POST_COLOR_MATRIX_BLUE_BIAS:
702 if (ctx->Pixel.PostColorMatrixBias[2] == param)
703 return;
704 FLUSH_VERTICES(ctx, _NEW_PIXEL);
705 ctx->Pixel.PostColorMatrixBias[2] = param;
706 break;
707 case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
708 if (ctx->Pixel.PostColorMatrixScale[3] == param)
709 return;
710 FLUSH_VERTICES(ctx, _NEW_PIXEL);
711 ctx->Pixel.PostColorMatrixScale[3] = param;
712 break;
713 case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
714 if (ctx->Pixel.PostColorMatrixBias[3] == param)
715 return;
716 FLUSH_VERTICES(ctx, _NEW_PIXEL);
717 ctx->Pixel.PostColorMatrixBias[3] = param;
718 break;
719 case GL_POST_CONVOLUTION_RED_SCALE:
720 if (ctx->Pixel.PostConvolutionScale[0] == param)
721 return;
722 FLUSH_VERTICES(ctx, _NEW_PIXEL);
723 ctx->Pixel.PostConvolutionScale[0] = param;
724 break;
725 case GL_POST_CONVOLUTION_RED_BIAS:
726 if (ctx->Pixel.PostConvolutionBias[0] == param)
727 return;
728 FLUSH_VERTICES(ctx, _NEW_PIXEL);
729 ctx->Pixel.PostConvolutionBias[0] = param;
730 break;
731 case GL_POST_CONVOLUTION_GREEN_SCALE:
732 if (ctx->Pixel.PostConvolutionScale[1] == param)
733 return;
734 FLUSH_VERTICES(ctx, _NEW_PIXEL);
735 ctx->Pixel.PostConvolutionScale[1] = param;
736 break;
737 case GL_POST_CONVOLUTION_GREEN_BIAS:
738 if (ctx->Pixel.PostConvolutionBias[1] == param)
739 return;
740 FLUSH_VERTICES(ctx, _NEW_PIXEL);
741 ctx->Pixel.PostConvolutionBias[1] = param;
742 break;
743 case GL_POST_CONVOLUTION_BLUE_SCALE:
744 if (ctx->Pixel.PostConvolutionScale[2] == param)
745 return;
746 FLUSH_VERTICES(ctx, _NEW_PIXEL);
747 ctx->Pixel.PostConvolutionScale[2] = param;
748 break;
749 case GL_POST_CONVOLUTION_BLUE_BIAS:
750 if (ctx->Pixel.PostConvolutionBias[2] == param)
751 return;
752 FLUSH_VERTICES(ctx, _NEW_PIXEL);
753 ctx->Pixel.PostConvolutionBias[2] = param;
754 break;
755 case GL_POST_CONVOLUTION_ALPHA_SCALE:
756 if (ctx->Pixel.PostConvolutionScale[2] == param)
757 return;
758 FLUSH_VERTICES(ctx, _NEW_PIXEL);
759 ctx->Pixel.PostConvolutionScale[2] = param;
760 break;
761 case GL_POST_CONVOLUTION_ALPHA_BIAS:
762 if (ctx->Pixel.PostConvolutionBias[2] == param)
763 return;
764 FLUSH_VERTICES(ctx, _NEW_PIXEL);
765 ctx->Pixel.PostConvolutionBias[2] = param;
766 break;
767 default:
768 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
769 return;
770 }
771 }
772
773
774 void
775 _mesa_PixelTransferi( GLenum pname, GLint param )
776 {
777 _mesa_PixelTransferf( pname, (GLfloat) param );
778 }
779
780
781
782 /**********************************************************************/
783 /***** Pixel processing functions ******/
784 /**********************************************************************/
785
786
787 /*
788 * Apply scale and bias factors to an array of RGBA pixels.
789 */
790 void
791 _mesa_scale_and_bias_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4],
792 GLfloat rScale, GLfloat gScale,
793 GLfloat bScale, GLfloat aScale,
794 GLfloat rBias, GLfloat gBias,
795 GLfloat bBias, GLfloat aBias)
796 {
797 if (rScale != 1.0 || rBias != 0.0) {
798 GLuint i;
799 for (i = 0; i < n; i++) {
800 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
801 }
802 }
803 if (gScale != 1.0 || gBias != 0.0) {
804 GLuint i;
805 for (i = 0; i < n; i++) {
806 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
807 }
808 }
809 if (bScale != 1.0 || bBias != 0.0) {
810 GLuint i;
811 for (i = 0; i < n; i++) {
812 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
813 }
814 }
815 if (aScale != 1.0 || aBias != 0.0) {
816 GLuint i;
817 for (i = 0; i < n; i++) {
818 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
819 }
820 }
821 }
822
823
824 /*
825 * Apply pixel mapping to an array of floating point RGBA pixels.
826 */
827 void
828 _mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
829 {
830 const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1);
831 const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1);
832 const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1);
833 const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1);
834 const GLfloat *rMap = ctx->Pixel.MapRtoR;
835 const GLfloat *gMap = ctx->Pixel.MapGtoG;
836 const GLfloat *bMap = ctx->Pixel.MapBtoB;
837 const GLfloat *aMap = ctx->Pixel.MapAtoA;
838 GLuint i;
839 for (i=0;i<n;i++) {
840 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
841 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
842 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
843 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
844 rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
845 rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
846 rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
847 rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
848 }
849 }
850
851
852 /*
853 * Apply the color matrix and post color matrix scaling and biasing.
854 */
855 void
856 _mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
857 {
858 const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
859 const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
860 const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
861 const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
862 const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
863 const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
864 const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
865 const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
866 const GLfloat *m = ctx->ColorMatrixStack.Top->m;
867 GLuint i;
868 for (i = 0; i < n; i++) {
869 const GLfloat r = rgba[i][RCOMP];
870 const GLfloat g = rgba[i][GCOMP];
871 const GLfloat b = rgba[i][BCOMP];
872 const GLfloat a = rgba[i][ACOMP];
873 rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
874 rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
875 rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
876 rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
877 }
878 }
879
880
881 /*
882 * Apply a color table lookup to an array of colors.
883 */
884 void
885 _mesa_lookup_rgba(const struct gl_color_table *table,
886 GLuint n, GLfloat rgba[][4])
887 {
888 ASSERT(table->FloatTable);
889 if (!table->Table || table->Size == 0)
890 return;
891
892 switch (table->Format) {
893 case GL_INTENSITY:
894 /* replace RGBA with I */
895 if (!table->FloatTable) {
896 const GLint max = table->Size - 1;
897 const GLfloat scale = (GLfloat) max;
898 const GLchan *lut = (const GLchan *) table->Table;
899 GLuint i;
900 for (i = 0; i < n; i++) {
901 GLint j = IROUND(rgba[i][RCOMP] * scale);
902 GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, 1)]);
903 rgba[i][RCOMP] = rgba[i][GCOMP] =
904 rgba[i][BCOMP] = rgba[i][ACOMP] = c;
905 }
906
907 }
908 else {
909 const GLint max = table->Size - 1;
910 const GLfloat scale = (GLfloat) max;
911 const GLfloat *lut = (const GLfloat *) table->Table;
912 GLuint i;
913 for (i = 0; i < n; i++) {
914 GLint j = IROUND(rgba[i][RCOMP] * scale);
915 GLfloat c = lut[CLAMP(j, 0, max)];
916 rgba[i][RCOMP] = rgba[i][GCOMP] =
917 rgba[i][BCOMP] = rgba[i][ACOMP] = c;
918 }
919 }
920 break;
921 case GL_LUMINANCE:
922 /* replace RGB with L */
923 if (!table->FloatTable) {
924 const GLint max = table->Size - 1;
925 const GLfloat scale = (GLfloat) max;
926 const GLchan *lut = (const GLchan *) table->Table;
927 GLuint i;
928 for (i = 0; i < n; i++) {
929 GLint j = IROUND(rgba[i][RCOMP] * scale);
930 GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
931 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
932 }
933 }
934 else {
935 const GLint max = table->Size - 1;
936 const GLfloat scale = (GLfloat) max;
937 const GLfloat *lut = (const GLfloat *) table->Table;
938 GLuint i;
939 for (i = 0; i < n; i++) {
940 GLint j = IROUND(rgba[i][RCOMP] * scale);
941 GLfloat c = lut[CLAMP(j, 0, max)];
942 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
943 }
944 }
945 break;
946 case GL_ALPHA:
947 /* replace A with A */
948 if (!table->FloatTable) {
949 const GLint max = table->Size - 1;
950 const GLfloat scale = (GLfloat) max;
951 const GLchan *lut = (const GLchan *) table->Table;
952 GLuint i;
953 for (i = 0; i < n; i++) {
954 GLint j = IROUND(rgba[i][ACOMP] * scale);
955 rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
956 }
957 }
958 else {
959 const GLint max = table->Size - 1;
960 const GLfloat scale = (GLfloat) max;
961 const GLfloat *lut = (const GLfloat *) table->Table;
962 GLuint i;
963 for (i = 0; i < n; i++) {
964 GLint j = IROUND(rgba[i][ACOMP] * scale);
965 rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
966 }
967 }
968 break;
969 case GL_LUMINANCE_ALPHA:
970 /* replace RGBA with LLLA */
971 if (!table->FloatTable) {
972 const GLint max = table->Size - 1;
973 const GLfloat scale = (GLfloat) max;
974 const GLchan *lut = (const GLchan *) table->Table;
975 GLuint i;
976 for (i = 0; i < n; i++) {
977 GLint jL = IROUND(rgba[i][RCOMP] * scale);
978 GLint jA = IROUND(rgba[i][ACOMP] * scale);
979 GLfloat luminance, alpha;
980 jL = CLAMP(jL, 0, max);
981 jA = CLAMP(jA, 0, max);
982 luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
983 alpha = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
984 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
985 rgba[i][ACOMP] = alpha;;
986 }
987 }
988 else {
989 const GLint max = table->Size - 1;
990 const GLfloat scale = (GLfloat) max;
991 const GLfloat *lut = (const GLfloat *) table->Table;
992 GLuint i;
993 for (i = 0; i < n; i++) {
994 GLint jL = IROUND(rgba[i][RCOMP] * scale);
995 GLint jA = IROUND(rgba[i][ACOMP] * scale);
996 GLfloat luminance, alpha;
997 jL = CLAMP(jL, 0, max);
998 jA = CLAMP(jA, 0, max);
999 luminance = lut[jL * 2 + 0];
1000 alpha = lut[jA * 2 + 1];
1001 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1002 rgba[i][ACOMP] = alpha;;
1003 }
1004 }
1005 break;
1006 case GL_RGB:
1007 /* replace RGB with RGB */
1008 if (!table->FloatTable) {
1009 const GLint max = table->Size - 1;
1010 const GLfloat scale = (GLfloat) max;
1011 const GLchan *lut = (const GLchan *) table->Table;
1012 GLuint i;
1013 for (i = 0; i < n; i++) {
1014 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1015 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1016 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1017 jR = CLAMP(jR, 0, max);
1018 jG = CLAMP(jG, 0, max);
1019 jB = CLAMP(jB, 0, max);
1020 rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
1021 rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
1022 rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
1023 }
1024 }
1025 else {
1026 const GLint max = table->Size - 1;
1027 const GLfloat scale = (GLfloat) max;
1028 const GLfloat *lut = (const GLfloat *) table->Table;
1029 GLuint i;
1030 for (i = 0; i < n; i++) {
1031 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1032 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1033 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1034 jR = CLAMP(jR, 0, max);
1035 jG = CLAMP(jG, 0, max);
1036 jB = CLAMP(jB, 0, max);
1037 rgba[i][RCOMP] = lut[jR * 3 + 0];
1038 rgba[i][GCOMP] = lut[jG * 3 + 1];
1039 rgba[i][BCOMP] = lut[jB * 3 + 2];
1040 }
1041 }
1042 break;
1043 case GL_RGBA:
1044 /* replace RGBA with RGBA */
1045 if (!table->FloatTable) {
1046 const GLint max = table->Size - 1;
1047 const GLfloat scale = (GLfloat) max;
1048 const GLchan *lut = (const GLchan *) table->Table;
1049 GLuint i;
1050 for (i = 0; i < n; i++) {
1051 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1052 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1053 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1054 GLint jA = IROUND(rgba[i][ACOMP] * scale);
1055 jR = CLAMP(jR, 0, max);
1056 jG = CLAMP(jG, 0, max);
1057 jB = CLAMP(jB, 0, max);
1058 jA = CLAMP(jA, 0, max);
1059 rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
1060 rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
1061 rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
1062 rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
1063 }
1064 }
1065 else {
1066 const GLint max = table->Size - 1;
1067 const GLfloat scale = (GLfloat) max;
1068 const GLfloat *lut = (const GLfloat *) table->Table;
1069 GLuint i;
1070 for (i = 0; i < n; i++) {
1071 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1072 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1073 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1074 GLint jA = IROUND(rgba[i][ACOMP] * scale);
1075 jR = CLAMP(jR, 0, max);
1076 jG = CLAMP(jG, 0, max);
1077 jB = CLAMP(jB, 0, max);
1078 jA = CLAMP(jA, 0, max);
1079 rgba[i][RCOMP] = lut[jR * 4 + 0];
1080 rgba[i][GCOMP] = lut[jG * 4 + 1];
1081 rgba[i][BCOMP] = lut[jB * 4 + 2];
1082 rgba[i][ACOMP] = lut[jA * 4 + 3];
1083 }
1084 }
1085 break;
1086 default:
1087 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba");
1088 return;
1089 }
1090 }
1091
1092
1093
1094 /*
1095 * Apply color index shift and offset to an array of pixels.
1096 */
1097 void
1098 _mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
1099 {
1100 GLint shift = ctx->Pixel.IndexShift;
1101 GLint offset = ctx->Pixel.IndexOffset;
1102 GLuint i;
1103 if (shift > 0) {
1104 for (i=0;i<n;i++) {
1105 indexes[i] = (indexes[i] << shift) + offset;
1106 }
1107 }
1108 else if (shift < 0) {
1109 shift = -shift;
1110 for (i=0;i<n;i++) {
1111 indexes[i] = (indexes[i] >> shift) + offset;
1112 }
1113 }
1114 else {
1115 for (i=0;i<n;i++) {
1116 indexes[i] = indexes[i] + offset;
1117 }
1118 }
1119 }
1120
1121
1122 /*
1123 * Apply color index mapping to color indexes.
1124 */
1125 void
1126 _mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
1127 {
1128 GLuint mask = ctx->Pixel.MapItoIsize - 1;
1129 GLuint i;
1130 for (i=0;i<n;i++) {
1131 index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
1132 }
1133 }
1134
1135
1136 /*
1137 * Map color indexes to rgba values.
1138 */
1139 void
1140 _mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
1141 const GLuint index[], GLchan rgba[][4] )
1142 {
1143 #if CHAN_BITS == 8
1144 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1145 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1146 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1147 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1148 const GLubyte *rMap = ctx->Pixel.MapItoR8;
1149 const GLubyte *gMap = ctx->Pixel.MapItoG8;
1150 const GLubyte *bMap = ctx->Pixel.MapItoB8;
1151 const GLubyte *aMap = ctx->Pixel.MapItoA8;
1152 GLuint i;
1153 for (i=0;i<n;i++) {
1154 rgba[i][RCOMP] = rMap[index[i] & rmask];
1155 rgba[i][GCOMP] = gMap[index[i] & gmask];
1156 rgba[i][BCOMP] = bMap[index[i] & bmask];
1157 rgba[i][ACOMP] = aMap[index[i] & amask];
1158 }
1159 #else
1160 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1161 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1162 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1163 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1164 const GLfloat *rMap = ctx->Pixel.MapItoR;
1165 const GLfloat *gMap = ctx->Pixel.MapItoG;
1166 const GLfloat *bMap = ctx->Pixel.MapItoB;
1167 const GLfloat *aMap = ctx->Pixel.MapItoA;
1168 GLuint i;
1169 for (i=0;i<n;i++) {
1170 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1171 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1172 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1173 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1174 }
1175 #endif
1176 }
1177
1178
1179 /*
1180 * Map color indexes to float rgba values.
1181 */
1182 void
1183 _mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1184 const GLuint index[], GLfloat rgba[][4] )
1185 {
1186 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1187 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1188 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1189 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1190 const GLfloat *rMap = ctx->Pixel.MapItoR;
1191 const GLfloat *gMap = ctx->Pixel.MapItoG;
1192 const GLfloat *bMap = ctx->Pixel.MapItoB;
1193 const GLfloat *aMap = ctx->Pixel.MapItoA;
1194 GLuint i;
1195 for (i=0;i<n;i++) {
1196 rgba[i][RCOMP] = rMap[index[i] & rmask];
1197 rgba[i][GCOMP] = gMap[index[i] & gmask];
1198 rgba[i][BCOMP] = bMap[index[i] & bmask];
1199 rgba[i][ACOMP] = aMap[index[i] & amask];
1200 }
1201 }
1202
1203
1204 /*
1205 * Map 8-bit color indexes to rgb values.
1206 */
1207 void
1208 _mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1209 GLchan rgba[][4] )
1210 {
1211 #if CHAN_BITS == 8
1212 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1213 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1214 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1215 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1216 const GLubyte *rMap = ctx->Pixel.MapItoR8;
1217 const GLubyte *gMap = ctx->Pixel.MapItoG8;
1218 const GLubyte *bMap = ctx->Pixel.MapItoB8;
1219 const GLubyte *aMap = ctx->Pixel.MapItoA8;
1220 GLuint i;
1221 for (i=0;i<n;i++) {
1222 rgba[i][RCOMP] = rMap[index[i] & rmask];
1223 rgba[i][GCOMP] = gMap[index[i] & gmask];
1224 rgba[i][BCOMP] = bMap[index[i] & bmask];
1225 rgba[i][ACOMP] = aMap[index[i] & amask];
1226 }
1227 #else
1228 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1229 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1230 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1231 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1232 const GLfloat *rMap = ctx->Pixel.MapItoR;
1233 const GLfloat *gMap = ctx->Pixel.MapItoG;
1234 const GLfloat *bMap = ctx->Pixel.MapItoB;
1235 const GLfloat *aMap = ctx->Pixel.MapItoA;
1236 GLuint i;
1237 for (i=0;i<n;i++) {
1238 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1239 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1240 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1241 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1242 }
1243 #endif
1244 }
1245
1246
1247 void
1248 _mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1249 GLstencil stencil[] )
1250 {
1251 GLuint i;
1252 GLint shift = ctx->Pixel.IndexShift;
1253 GLint offset = ctx->Pixel.IndexOffset;
1254 if (shift > 0) {
1255 for (i=0;i<n;i++) {
1256 stencil[i] = (stencil[i] << shift) + offset;
1257 }
1258 }
1259 else if (shift < 0) {
1260 shift = -shift;
1261 for (i=0;i<n;i++) {
1262 stencil[i] = (stencil[i] >> shift) + offset;
1263 }
1264 }
1265 else {
1266 for (i=0;i<n;i++) {
1267 stencil[i] = stencil[i] + offset;
1268 }
1269 }
1270
1271 }
1272
1273
1274 void
1275 _mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1276 {
1277 GLuint mask = ctx->Pixel.MapStoSsize - 1;
1278 GLuint i;
1279 for (i=0;i<n;i++) {
1280 stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1281 }
1282 }
1283
1284
1285
1286 /*
1287 * This function converts an array of GLchan colors to GLfloat colors.
1288 * Most importantly, it undoes the non-uniform quantization of pixel
1289 * values introduced when we convert shallow (< 8 bit) pixel values
1290 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
1291 * This fixes a number of OpenGL conformance failures when running on
1292 * 16bpp displays, for example.
1293 */
1294 void
1295 _mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
1296 CONST GLchan rgba[][4], GLfloat rgbaf[][4])
1297 {
1298 #if CHAN_TYPE == GL_FLOAT
1299 MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat));
1300 #else
1301 const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
1302 const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
1303 const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
1304 GLuint aShift;
1305 const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits ) - 1);
1306 const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
1307 const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
1308 GLfloat aScale;
1309 GLuint i;
1310
1311 if (ctx->Visual.alphaBits > 0) {
1312 aShift = CHAN_BITS - ctx->Visual.alphaBits;
1313 aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
1314 }
1315 else {
1316 aShift = 0;
1317 aScale = 1.0F / CHAN_MAXF;
1318 }
1319
1320 for (i = 0; i < n; i++) {
1321 const GLint r = rgba[i][RCOMP] >> rShift;
1322 const GLint g = rgba[i][GCOMP] >> gShift;
1323 const GLint b = rgba[i][BCOMP] >> bShift;
1324 const GLint a = rgba[i][ACOMP] >> aShift;
1325 rgbaf[i][RCOMP] = (GLfloat) r * rScale;
1326 rgbaf[i][GCOMP] = (GLfloat) g * gScale;
1327 rgbaf[i][BCOMP] = (GLfloat) b * bScale;
1328 rgbaf[i][ACOMP] = (GLfloat) a * aScale;
1329 }
1330 #endif
1331 }