2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer)
32 #if FEATURE_pixel_transfer
35 /**********************************************************************/
36 /***** glPixelZoom *****/
37 /**********************************************************************/
39 static void GLAPIENTRY
40 _mesa_PixelZoom( GLfloat xfactor
, GLfloat yfactor
)
42 GET_CURRENT_CONTEXT(ctx
);
44 ASSERT_OUTSIDE_BEGIN_END(ctx
);
46 if (ctx
->Pixel
.ZoomX
== xfactor
&&
47 ctx
->Pixel
.ZoomY
== yfactor
)
50 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
51 ctx
->Pixel
.ZoomX
= xfactor
;
52 ctx
->Pixel
.ZoomY
= yfactor
;
57 /**********************************************************************/
58 /***** glPixelMap *****/
59 /**********************************************************************/
62 * Return pointer to a pixelmap by name.
64 static struct gl_pixelmap
*
65 get_pixelmap(struct gl_context
*ctx
, GLenum map
)
68 case GL_PIXEL_MAP_I_TO_I
:
69 return &ctx
->PixelMaps
.ItoI
;
70 case GL_PIXEL_MAP_S_TO_S
:
71 return &ctx
->PixelMaps
.StoS
;
72 case GL_PIXEL_MAP_I_TO_R
:
73 return &ctx
->PixelMaps
.ItoR
;
74 case GL_PIXEL_MAP_I_TO_G
:
75 return &ctx
->PixelMaps
.ItoG
;
76 case GL_PIXEL_MAP_I_TO_B
:
77 return &ctx
->PixelMaps
.ItoB
;
78 case GL_PIXEL_MAP_I_TO_A
:
79 return &ctx
->PixelMaps
.ItoA
;
80 case GL_PIXEL_MAP_R_TO_R
:
81 return &ctx
->PixelMaps
.RtoR
;
82 case GL_PIXEL_MAP_G_TO_G
:
83 return &ctx
->PixelMaps
.GtoG
;
84 case GL_PIXEL_MAP_B_TO_B
:
85 return &ctx
->PixelMaps
.BtoB
;
86 case GL_PIXEL_MAP_A_TO_A
:
87 return &ctx
->PixelMaps
.AtoA
;
95 * Helper routine used by the other _mesa_PixelMap() functions.
98 store_pixelmap(struct gl_context
*ctx
, GLenum map
, GLsizei mapsize
,
99 const GLfloat
*values
)
102 struct gl_pixelmap
*pm
= get_pixelmap(ctx
, map
);
104 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPixelMap(map)");
109 case GL_PIXEL_MAP_S_TO_S
:
111 ctx
->PixelMaps
.StoS
.Size
= mapsize
;
112 for (i
= 0; i
< mapsize
; i
++) {
113 ctx
->PixelMaps
.StoS
.Map
[i
] = (GLfloat
)IROUND(values
[i
]);
116 case GL_PIXEL_MAP_I_TO_I
:
118 ctx
->PixelMaps
.ItoI
.Size
= mapsize
;
119 for (i
= 0; i
< mapsize
; i
++) {
120 ctx
->PixelMaps
.ItoI
.Map
[i
] = values
[i
];
126 for (i
= 0; i
< mapsize
; i
++) {
127 GLfloat val
= CLAMP(values
[i
], 0.0F
, 1.0F
);
129 pm
->Map8
[i
] = (GLint
) (val
* 255.0F
);
135 static void GLAPIENTRY
136 _mesa_PixelMapfv( GLenum map
, GLsizei mapsize
, const GLfloat
*values
)
138 GET_CURRENT_CONTEXT(ctx
);
139 ASSERT_OUTSIDE_BEGIN_END(ctx
);
141 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
142 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
143 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapfv(mapsize)" );
147 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
148 /* test that mapsize is a power of two */
149 if (!_mesa_is_pow_two(mapsize
)) {
150 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapfv(mapsize)" );
155 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
161 store_pixelmap(ctx
, map
, mapsize
, values
);
165 static void GLAPIENTRY
166 _mesa_PixelMapuiv(GLenum map
, GLsizei mapsize
, const GLuint
*values
)
168 GLfloat fvalues
[MAX_PIXEL_MAP_TABLE
];
169 GET_CURRENT_CONTEXT(ctx
);
170 ASSERT_OUTSIDE_BEGIN_END(ctx
);
172 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
173 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
177 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
178 /* test that mapsize is a power of two */
179 if (!_mesa_is_pow_two(mapsize
)) {
180 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
185 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
191 /* convert to floats */
192 if (map
== GL_PIXEL_MAP_I_TO_I
|| map
== GL_PIXEL_MAP_S_TO_S
) {
194 for (i
= 0; i
< mapsize
; i
++) {
195 fvalues
[i
] = (GLfloat
) values
[i
];
200 for (i
= 0; i
< mapsize
; i
++) {
201 fvalues
[i
] = UINT_TO_FLOAT( values
[i
] );
205 store_pixelmap(ctx
, map
, mapsize
, fvalues
);
209 static void GLAPIENTRY
210 _mesa_PixelMapusv(GLenum map
, GLsizei mapsize
, const GLushort
*values
)
212 GLfloat fvalues
[MAX_PIXEL_MAP_TABLE
];
213 GET_CURRENT_CONTEXT(ctx
);
214 ASSERT_OUTSIDE_BEGIN_END(ctx
);
216 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
217 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapusv(mapsize)" );
221 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
222 /* test that mapsize is a power of two */
223 if (!_mesa_is_pow_two(mapsize
)) {
224 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
229 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
235 /* convert to floats */
236 if (map
== GL_PIXEL_MAP_I_TO_I
|| map
== GL_PIXEL_MAP_S_TO_S
) {
238 for (i
= 0; i
< mapsize
; i
++) {
239 fvalues
[i
] = (GLfloat
) values
[i
];
244 for (i
= 0; i
< mapsize
; i
++) {
245 fvalues
[i
] = USHORT_TO_FLOAT( values
[i
] );
249 store_pixelmap(ctx
, map
, mapsize
, fvalues
);
253 static void GLAPIENTRY
254 _mesa_GetPixelMapfv( GLenum map
, GLfloat
*values
)
256 GET_CURRENT_CONTEXT(ctx
);
258 const struct gl_pixelmap
*pm
;
260 ASSERT_OUTSIDE_BEGIN_END(ctx
);
262 pm
= get_pixelmap(ctx
, map
);
264 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapfv(map)");
274 if (map
== GL_PIXEL_MAP_S_TO_S
) {
276 for (i
= 0; i
< mapsize
; i
++) {
277 values
[i
] = (GLfloat
) ctx
->PixelMaps
.StoS
.Map
[i
];
281 memcpy(values
, pm
->Map
, mapsize
* sizeof(GLfloat
));
286 static void GLAPIENTRY
287 _mesa_GetPixelMapuiv( GLenum map
, GLuint
*values
)
289 GET_CURRENT_CONTEXT(ctx
);
291 const struct gl_pixelmap
*pm
;
293 ASSERT_OUTSIDE_BEGIN_END(ctx
);
295 pm
= get_pixelmap(ctx
, map
);
297 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapuiv(map)");
307 if (map
== GL_PIXEL_MAP_S_TO_S
) {
309 memcpy(values
, ctx
->PixelMaps
.StoS
.Map
, mapsize
* sizeof(GLint
));
312 for (i
= 0; i
< mapsize
; i
++) {
313 values
[i
] = FLOAT_TO_UINT( pm
->Map
[i
] );
319 static void GLAPIENTRY
320 _mesa_GetPixelMapusv( GLenum map
, GLushort
*values
)
322 GET_CURRENT_CONTEXT(ctx
);
324 const struct gl_pixelmap
*pm
;
326 ASSERT_OUTSIDE_BEGIN_END(ctx
);
328 pm
= get_pixelmap(ctx
, map
);
330 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapusv(map)");
342 case GL_PIXEL_MAP_I_TO_I
:
343 for (i
= 0; i
< mapsize
; i
++) {
344 values
[i
] = (GLushort
) CLAMP(ctx
->PixelMaps
.ItoI
.Map
[i
], 0.0, 65535.);
347 case GL_PIXEL_MAP_S_TO_S
:
348 for (i
= 0; i
< mapsize
; i
++) {
349 values
[i
] = (GLushort
) CLAMP(ctx
->PixelMaps
.StoS
.Map
[i
], 0.0, 65535.);
353 for (i
= 0; i
< mapsize
; i
++) {
354 CLAMPED_FLOAT_TO_USHORT(values
[i
], pm
->Map
[i
] );
360 /**********************************************************************/
361 /***** glPixelTransfer *****/
362 /**********************************************************************/
366 * Implements glPixelTransfer[fi] whether called immediately or from a
370 _mesa_PixelTransferf( GLenum pname
, GLfloat param
)
372 GET_CURRENT_CONTEXT(ctx
);
373 ASSERT_OUTSIDE_BEGIN_END(ctx
);
377 if (ctx
->Pixel
.MapColorFlag
== (param
? GL_TRUE
: GL_FALSE
))
379 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
380 ctx
->Pixel
.MapColorFlag
= param
? GL_TRUE
: GL_FALSE
;
383 if (ctx
->Pixel
.MapStencilFlag
== (param
? GL_TRUE
: GL_FALSE
))
385 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
386 ctx
->Pixel
.MapStencilFlag
= param
? GL_TRUE
: GL_FALSE
;
389 if (ctx
->Pixel
.IndexShift
== (GLint
) param
)
391 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
392 ctx
->Pixel
.IndexShift
= (GLint
) param
;
394 case GL_INDEX_OFFSET
:
395 if (ctx
->Pixel
.IndexOffset
== (GLint
) param
)
397 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
398 ctx
->Pixel
.IndexOffset
= (GLint
) param
;
401 if (ctx
->Pixel
.RedScale
== param
)
403 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
404 ctx
->Pixel
.RedScale
= param
;
407 if (ctx
->Pixel
.RedBias
== param
)
409 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
410 ctx
->Pixel
.RedBias
= param
;
413 if (ctx
->Pixel
.GreenScale
== param
)
415 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
416 ctx
->Pixel
.GreenScale
= param
;
419 if (ctx
->Pixel
.GreenBias
== param
)
421 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
422 ctx
->Pixel
.GreenBias
= param
;
425 if (ctx
->Pixel
.BlueScale
== param
)
427 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
428 ctx
->Pixel
.BlueScale
= param
;
431 if (ctx
->Pixel
.BlueBias
== param
)
433 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
434 ctx
->Pixel
.BlueBias
= param
;
437 if (ctx
->Pixel
.AlphaScale
== param
)
439 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
440 ctx
->Pixel
.AlphaScale
= param
;
443 if (ctx
->Pixel
.AlphaBias
== param
)
445 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
446 ctx
->Pixel
.AlphaBias
= param
;
449 if (ctx
->Pixel
.DepthScale
== param
)
451 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
452 ctx
->Pixel
.DepthScale
= param
;
455 if (ctx
->Pixel
.DepthBias
== param
)
457 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
458 ctx
->Pixel
.DepthBias
= param
;
461 _mesa_error( ctx
, GL_INVALID_ENUM
, "glPixelTransfer(pname)" );
467 static void GLAPIENTRY
468 _mesa_PixelTransferi( GLenum pname
, GLint param
)
470 _mesa_PixelTransferf( pname
, (GLfloat
) param
);
475 /**********************************************************************/
476 /***** State Management *****/
477 /**********************************************************************/
480 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
481 * pixel transfer operations are enabled.
484 update_image_transfer_state(struct gl_context
*ctx
)
488 if (ctx
->Pixel
.RedScale
!= 1.0F
|| ctx
->Pixel
.RedBias
!= 0.0F
||
489 ctx
->Pixel
.GreenScale
!= 1.0F
|| ctx
->Pixel
.GreenBias
!= 0.0F
||
490 ctx
->Pixel
.BlueScale
!= 1.0F
|| ctx
->Pixel
.BlueBias
!= 0.0F
||
491 ctx
->Pixel
.AlphaScale
!= 1.0F
|| ctx
->Pixel
.AlphaBias
!= 0.0F
)
492 mask
|= IMAGE_SCALE_BIAS_BIT
;
494 if (ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
)
495 mask
|= IMAGE_SHIFT_OFFSET_BIT
;
497 if (ctx
->Pixel
.MapColorFlag
)
498 mask
|= IMAGE_MAP_COLOR_BIT
;
500 ctx
->_ImageTransferState
= mask
;
505 * Update mesa pixel transfer derived state.
507 void _mesa_update_pixel( struct gl_context
*ctx
, GLuint new_state
)
509 if (new_state
& _NEW_PIXEL
)
510 update_image_transfer_state(ctx
);
515 _mesa_init_pixel_dispatch(struct _glapi_table
*disp
)
517 SET_GetPixelMapfv(disp
, _mesa_GetPixelMapfv
);
518 SET_GetPixelMapuiv(disp
, _mesa_GetPixelMapuiv
);
519 SET_GetPixelMapusv(disp
, _mesa_GetPixelMapusv
);
520 SET_PixelMapfv(disp
, _mesa_PixelMapfv
);
521 SET_PixelMapuiv(disp
, _mesa_PixelMapuiv
);
522 SET_PixelMapusv(disp
, _mesa_PixelMapusv
);
523 SET_PixelTransferf(disp
, _mesa_PixelTransferf
);
524 SET_PixelTransferi(disp
, _mesa_PixelTransferi
);
525 SET_PixelZoom(disp
, _mesa_PixelZoom
);
529 #endif /* FEATURE_pixel_transfer */
532 /**********************************************************************/
533 /***** Initialization *****/
534 /**********************************************************************/
537 init_pixelmap(struct gl_pixelmap
*map
)
546 * Initialize the context's PIXEL attribute group.
549 _mesa_init_pixel( struct gl_context
*ctx
)
552 ctx
->Pixel
.RedBias
= 0.0;
553 ctx
->Pixel
.RedScale
= 1.0;
554 ctx
->Pixel
.GreenBias
= 0.0;
555 ctx
->Pixel
.GreenScale
= 1.0;
556 ctx
->Pixel
.BlueBias
= 0.0;
557 ctx
->Pixel
.BlueScale
= 1.0;
558 ctx
->Pixel
.AlphaBias
= 0.0;
559 ctx
->Pixel
.AlphaScale
= 1.0;
560 ctx
->Pixel
.DepthBias
= 0.0;
561 ctx
->Pixel
.DepthScale
= 1.0;
562 ctx
->Pixel
.IndexOffset
= 0;
563 ctx
->Pixel
.IndexShift
= 0;
564 ctx
->Pixel
.ZoomX
= 1.0;
565 ctx
->Pixel
.ZoomY
= 1.0;
566 ctx
->Pixel
.MapColorFlag
= GL_FALSE
;
567 ctx
->Pixel
.MapStencilFlag
= GL_FALSE
;
568 init_pixelmap(&ctx
->PixelMaps
.StoS
);
569 init_pixelmap(&ctx
->PixelMaps
.ItoI
);
570 init_pixelmap(&ctx
->PixelMaps
.ItoR
);
571 init_pixelmap(&ctx
->PixelMaps
.ItoG
);
572 init_pixelmap(&ctx
->PixelMaps
.ItoB
);
573 init_pixelmap(&ctx
->PixelMaps
.ItoA
);
574 init_pixelmap(&ctx
->PixelMaps
.RtoR
);
575 init_pixelmap(&ctx
->PixelMaps
.GtoG
);
576 init_pixelmap(&ctx
->PixelMaps
.BtoB
);
577 init_pixelmap(&ctx
->PixelMaps
.AtoA
);
579 if (ctx
->Visual
.doubleBufferMode
) {
580 ctx
->Pixel
.ReadBuffer
= GL_BACK
;
583 ctx
->Pixel
.ReadBuffer
= GL_FRONT
;
587 ctx
->_ImageTransferState
= 0;