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.
28 * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer)
32 #include "bufferobj.h"
36 #include "mfeatures.h"
39 #include "main/dispatch.h"
42 #if FEATURE_pixel_transfer
45 /**********************************************************************/
46 /***** glPixelZoom *****/
47 /**********************************************************************/
49 static void GLAPIENTRY
50 _mesa_PixelZoom( GLfloat xfactor
, GLfloat yfactor
)
52 GET_CURRENT_CONTEXT(ctx
);
54 if (ctx
->Pixel
.ZoomX
== xfactor
&&
55 ctx
->Pixel
.ZoomY
== yfactor
)
58 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
59 ctx
->Pixel
.ZoomX
= xfactor
;
60 ctx
->Pixel
.ZoomY
= yfactor
;
65 /**********************************************************************/
66 /***** glPixelMap *****/
67 /**********************************************************************/
70 * Return pointer to a pixelmap by name.
72 static struct gl_pixelmap
*
73 get_pixelmap(struct gl_context
*ctx
, GLenum map
)
76 case GL_PIXEL_MAP_I_TO_I
:
77 return &ctx
->PixelMaps
.ItoI
;
78 case GL_PIXEL_MAP_S_TO_S
:
79 return &ctx
->PixelMaps
.StoS
;
80 case GL_PIXEL_MAP_I_TO_R
:
81 return &ctx
->PixelMaps
.ItoR
;
82 case GL_PIXEL_MAP_I_TO_G
:
83 return &ctx
->PixelMaps
.ItoG
;
84 case GL_PIXEL_MAP_I_TO_B
:
85 return &ctx
->PixelMaps
.ItoB
;
86 case GL_PIXEL_MAP_I_TO_A
:
87 return &ctx
->PixelMaps
.ItoA
;
88 case GL_PIXEL_MAP_R_TO_R
:
89 return &ctx
->PixelMaps
.RtoR
;
90 case GL_PIXEL_MAP_G_TO_G
:
91 return &ctx
->PixelMaps
.GtoG
;
92 case GL_PIXEL_MAP_B_TO_B
:
93 return &ctx
->PixelMaps
.BtoB
;
94 case GL_PIXEL_MAP_A_TO_A
:
95 return &ctx
->PixelMaps
.AtoA
;
103 * Helper routine used by the other _mesa_PixelMap() functions.
106 store_pixelmap(struct gl_context
*ctx
, GLenum map
, GLsizei mapsize
,
107 const GLfloat
*values
)
110 struct gl_pixelmap
*pm
= get_pixelmap(ctx
, map
);
112 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPixelMap(map)");
117 case GL_PIXEL_MAP_S_TO_S
:
119 ctx
->PixelMaps
.StoS
.Size
= mapsize
;
120 for (i
= 0; i
< mapsize
; i
++) {
121 ctx
->PixelMaps
.StoS
.Map
[i
] = (GLfloat
)IROUND(values
[i
]);
124 case GL_PIXEL_MAP_I_TO_I
:
126 ctx
->PixelMaps
.ItoI
.Size
= mapsize
;
127 for (i
= 0; i
< mapsize
; i
++) {
128 ctx
->PixelMaps
.ItoI
.Map
[i
] = values
[i
];
134 for (i
= 0; i
< mapsize
; i
++) {
135 GLfloat val
= CLAMP(values
[i
], 0.0F
, 1.0F
);
137 pm
->Map8
[i
] = (GLint
) (val
* 255.0F
);
144 * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
147 validate_pbo_access(struct gl_context
*ctx
, struct gl_pixelstore_attrib
*pack
,
148 GLsizei mapsize
, GLenum format
, GLenum type
,
153 /* Note, need to use DefaultPacking and Unpack's buffer object */
154 _mesa_reference_buffer_object(ctx
,
155 &ctx
->DefaultPacking
.BufferObj
,
158 ok
= _mesa_validate_pbo_access(1, &ctx
->DefaultPacking
, mapsize
, 1, 1,
162 _mesa_reference_buffer_object(ctx
,
163 &ctx
->DefaultPacking
.BufferObj
,
164 ctx
->Shared
->NullBufferObj
);
167 _mesa_error(ctx
, GL_INVALID_OPERATION
,
168 "glPixelMap(invalid PBO access)");
174 static void GLAPIENTRY
175 _mesa_PixelMapfv( GLenum map
, GLsizei mapsize
, const GLfloat
*values
)
177 GET_CURRENT_CONTEXT(ctx
);
178 ASSERT_OUTSIDE_BEGIN_END(ctx
);
180 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
181 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
182 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapfv(mapsize)" );
186 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
187 /* test that mapsize is a power of two */
188 if (!_mesa_is_pow_two(mapsize
)) {
189 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapfv(mapsize)" );
194 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
196 if (!validate_pbo_access(ctx
, &ctx
->Unpack
, mapsize
,
197 GL_INTENSITY
, GL_FLOAT
, values
)) {
201 values
= (const GLfloat
*) _mesa_map_pbo_source(ctx
, &ctx
->Unpack
, values
);
203 if (_mesa_is_bufferobj(ctx
->Unpack
.BufferObj
)) {
204 _mesa_error(ctx
, GL_INVALID_OPERATION
,
205 "glPixelMapfv(PBO is mapped)");
210 store_pixelmap(ctx
, map
, mapsize
, values
);
212 _mesa_unmap_pbo_source(ctx
, &ctx
->Unpack
);
216 static void GLAPIENTRY
217 _mesa_PixelMapuiv(GLenum map
, GLsizei mapsize
, const GLuint
*values
)
219 GLfloat fvalues
[MAX_PIXEL_MAP_TABLE
];
220 GET_CURRENT_CONTEXT(ctx
);
221 ASSERT_OUTSIDE_BEGIN_END(ctx
);
223 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
224 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
228 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
229 /* test that mapsize is a power of two */
230 if (!_mesa_is_pow_two(mapsize
)) {
231 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
236 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
238 if (!validate_pbo_access(ctx
, &ctx
->Unpack
, mapsize
,
239 GL_INTENSITY
, GL_UNSIGNED_INT
, values
)) {
243 values
= (const GLuint
*) _mesa_map_pbo_source(ctx
, &ctx
->Unpack
, values
);
245 if (_mesa_is_bufferobj(ctx
->Unpack
.BufferObj
)) {
246 _mesa_error(ctx
, GL_INVALID_OPERATION
,
247 "glPixelMapuiv(PBO is mapped)");
252 /* convert to floats */
253 if (map
== GL_PIXEL_MAP_I_TO_I
|| map
== GL_PIXEL_MAP_S_TO_S
) {
255 for (i
= 0; i
< mapsize
; i
++) {
256 fvalues
[i
] = (GLfloat
) values
[i
];
261 for (i
= 0; i
< mapsize
; i
++) {
262 fvalues
[i
] = UINT_TO_FLOAT( values
[i
] );
266 _mesa_unmap_pbo_source(ctx
, &ctx
->Unpack
);
268 store_pixelmap(ctx
, map
, mapsize
, fvalues
);
272 static void GLAPIENTRY
273 _mesa_PixelMapusv(GLenum map
, GLsizei mapsize
, const GLushort
*values
)
275 GLfloat fvalues
[MAX_PIXEL_MAP_TABLE
];
276 GET_CURRENT_CONTEXT(ctx
);
277 ASSERT_OUTSIDE_BEGIN_END(ctx
);
279 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
280 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapusv(mapsize)" );
284 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
285 /* test that mapsize is a power of two */
286 if (!_mesa_is_pow_two(mapsize
)) {
287 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
292 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
294 if (!validate_pbo_access(ctx
, &ctx
->Unpack
, mapsize
,
295 GL_INTENSITY
, GL_UNSIGNED_SHORT
, values
)) {
299 values
= (const GLushort
*) _mesa_map_pbo_source(ctx
, &ctx
->Unpack
, values
);
301 if (_mesa_is_bufferobj(ctx
->Unpack
.BufferObj
)) {
302 _mesa_error(ctx
, GL_INVALID_OPERATION
,
303 "glPixelMapusv(PBO is mapped)");
308 /* convert to floats */
309 if (map
== GL_PIXEL_MAP_I_TO_I
|| map
== GL_PIXEL_MAP_S_TO_S
) {
311 for (i
= 0; i
< mapsize
; i
++) {
312 fvalues
[i
] = (GLfloat
) values
[i
];
317 for (i
= 0; i
< mapsize
; i
++) {
318 fvalues
[i
] = USHORT_TO_FLOAT( values
[i
] );
322 _mesa_unmap_pbo_source(ctx
, &ctx
->Unpack
);
324 store_pixelmap(ctx
, map
, mapsize
, fvalues
);
328 static void GLAPIENTRY
329 _mesa_GetPixelMapfv( GLenum map
, GLfloat
*values
)
331 GET_CURRENT_CONTEXT(ctx
);
333 const struct gl_pixelmap
*pm
;
335 ASSERT_OUTSIDE_BEGIN_END(ctx
);
337 pm
= get_pixelmap(ctx
, map
);
339 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapfv(map)");
345 if (!validate_pbo_access(ctx
, &ctx
->Pack
, mapsize
,
346 GL_INTENSITY
, GL_FLOAT
, values
)) {
350 values
= (GLfloat
*) _mesa_map_pbo_dest(ctx
, &ctx
->Pack
, values
);
352 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
353 _mesa_error(ctx
, GL_INVALID_OPERATION
,
354 "glGetPixelMapfv(PBO is mapped)");
359 if (map
== GL_PIXEL_MAP_S_TO_S
) {
361 for (i
= 0; i
< mapsize
; i
++) {
362 values
[i
] = (GLfloat
) ctx
->PixelMaps
.StoS
.Map
[i
];
366 memcpy(values
, pm
->Map
, mapsize
* sizeof(GLfloat
));
369 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
373 static void GLAPIENTRY
374 _mesa_GetPixelMapuiv( GLenum map
, GLuint
*values
)
376 GET_CURRENT_CONTEXT(ctx
);
378 const struct gl_pixelmap
*pm
;
380 ASSERT_OUTSIDE_BEGIN_END(ctx
);
382 pm
= get_pixelmap(ctx
, map
);
384 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapuiv(map)");
389 if (!validate_pbo_access(ctx
, &ctx
->Pack
, mapsize
,
390 GL_INTENSITY
, GL_UNSIGNED_INT
, values
)) {
394 values
= (GLuint
*) _mesa_map_pbo_dest(ctx
, &ctx
->Pack
, values
);
396 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
397 _mesa_error(ctx
, GL_INVALID_OPERATION
,
398 "glGetPixelMapuiv(PBO is mapped)");
403 if (map
== GL_PIXEL_MAP_S_TO_S
) {
405 memcpy(values
, ctx
->PixelMaps
.StoS
.Map
, mapsize
* sizeof(GLint
));
408 for (i
= 0; i
< mapsize
; i
++) {
409 values
[i
] = FLOAT_TO_UINT( pm
->Map
[i
] );
413 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
417 static void GLAPIENTRY
418 _mesa_GetPixelMapusv( GLenum map
, GLushort
*values
)
420 GET_CURRENT_CONTEXT(ctx
);
422 const struct gl_pixelmap
*pm
;
424 ASSERT_OUTSIDE_BEGIN_END(ctx
);
426 pm
= get_pixelmap(ctx
, map
);
428 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapusv(map)");
433 if (!validate_pbo_access(ctx
, &ctx
->Pack
, mapsize
,
434 GL_INTENSITY
, GL_UNSIGNED_SHORT
, values
)) {
438 values
= (GLushort
*) _mesa_map_pbo_dest(ctx
, &ctx
->Pack
, values
);
440 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
441 _mesa_error(ctx
, GL_INVALID_OPERATION
,
442 "glGetPixelMapusv(PBO is mapped)");
449 case GL_PIXEL_MAP_I_TO_I
:
450 for (i
= 0; i
< mapsize
; i
++) {
451 values
[i
] = (GLushort
) CLAMP(ctx
->PixelMaps
.ItoI
.Map
[i
], 0.0, 65535.);
454 case GL_PIXEL_MAP_S_TO_S
:
455 for (i
= 0; i
< mapsize
; i
++) {
456 values
[i
] = (GLushort
) CLAMP(ctx
->PixelMaps
.StoS
.Map
[i
], 0.0, 65535.);
460 for (i
= 0; i
< mapsize
; i
++) {
461 CLAMPED_FLOAT_TO_USHORT(values
[i
], pm
->Map
[i
] );
465 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
470 /**********************************************************************/
471 /***** glPixelTransfer *****/
472 /**********************************************************************/
476 * Implements glPixelTransfer[fi] whether called immediately or from a
479 static void GLAPIENTRY
480 _mesa_PixelTransferf( GLenum pname
, GLfloat param
)
482 GET_CURRENT_CONTEXT(ctx
);
483 ASSERT_OUTSIDE_BEGIN_END(ctx
);
487 if (ctx
->Pixel
.MapColorFlag
== (param
? GL_TRUE
: GL_FALSE
))
489 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
490 ctx
->Pixel
.MapColorFlag
= param
? GL_TRUE
: GL_FALSE
;
493 if (ctx
->Pixel
.MapStencilFlag
== (param
? GL_TRUE
: GL_FALSE
))
495 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
496 ctx
->Pixel
.MapStencilFlag
= param
? GL_TRUE
: GL_FALSE
;
499 if (ctx
->Pixel
.IndexShift
== (GLint
) param
)
501 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
502 ctx
->Pixel
.IndexShift
= (GLint
) param
;
504 case GL_INDEX_OFFSET
:
505 if (ctx
->Pixel
.IndexOffset
== (GLint
) param
)
507 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
508 ctx
->Pixel
.IndexOffset
= (GLint
) param
;
511 if (ctx
->Pixel
.RedScale
== param
)
513 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
514 ctx
->Pixel
.RedScale
= param
;
517 if (ctx
->Pixel
.RedBias
== param
)
519 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
520 ctx
->Pixel
.RedBias
= param
;
523 if (ctx
->Pixel
.GreenScale
== param
)
525 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
526 ctx
->Pixel
.GreenScale
= param
;
529 if (ctx
->Pixel
.GreenBias
== param
)
531 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
532 ctx
->Pixel
.GreenBias
= param
;
535 if (ctx
->Pixel
.BlueScale
== param
)
537 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
538 ctx
->Pixel
.BlueScale
= param
;
541 if (ctx
->Pixel
.BlueBias
== param
)
543 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
544 ctx
->Pixel
.BlueBias
= param
;
547 if (ctx
->Pixel
.AlphaScale
== param
)
549 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
550 ctx
->Pixel
.AlphaScale
= param
;
553 if (ctx
->Pixel
.AlphaBias
== param
)
555 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
556 ctx
->Pixel
.AlphaBias
= param
;
559 if (ctx
->Pixel
.DepthScale
== param
)
561 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
562 ctx
->Pixel
.DepthScale
= param
;
565 if (ctx
->Pixel
.DepthBias
== param
)
567 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
568 ctx
->Pixel
.DepthBias
= param
;
571 _mesa_error( ctx
, GL_INVALID_ENUM
, "glPixelTransfer(pname)" );
577 static void GLAPIENTRY
578 _mesa_PixelTransferi( GLenum pname
, GLint param
)
580 _mesa_PixelTransferf( pname
, (GLfloat
) param
);
585 /**********************************************************************/
586 /***** State Management *****/
587 /**********************************************************************/
590 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
591 * pixel transfer operations are enabled.
594 update_image_transfer_state(struct gl_context
*ctx
)
598 if (ctx
->Pixel
.RedScale
!= 1.0F
|| ctx
->Pixel
.RedBias
!= 0.0F
||
599 ctx
->Pixel
.GreenScale
!= 1.0F
|| ctx
->Pixel
.GreenBias
!= 0.0F
||
600 ctx
->Pixel
.BlueScale
!= 1.0F
|| ctx
->Pixel
.BlueBias
!= 0.0F
||
601 ctx
->Pixel
.AlphaScale
!= 1.0F
|| ctx
->Pixel
.AlphaBias
!= 0.0F
)
602 mask
|= IMAGE_SCALE_BIAS_BIT
;
604 if (ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
)
605 mask
|= IMAGE_SHIFT_OFFSET_BIT
;
607 if (ctx
->Pixel
.MapColorFlag
)
608 mask
|= IMAGE_MAP_COLOR_BIT
;
610 ctx
->_ImageTransferState
= mask
;
615 * Update mesa pixel transfer derived state.
617 void _mesa_update_pixel( struct gl_context
*ctx
, GLuint new_state
)
619 if (new_state
& _MESA_NEW_TRANSFER_STATE
)
620 update_image_transfer_state(ctx
);
625 _mesa_init_pixel_dispatch(struct _glapi_table
*disp
)
627 SET_GetPixelMapfv(disp
, _mesa_GetPixelMapfv
);
628 SET_GetPixelMapuiv(disp
, _mesa_GetPixelMapuiv
);
629 SET_GetPixelMapusv(disp
, _mesa_GetPixelMapusv
);
630 SET_PixelMapfv(disp
, _mesa_PixelMapfv
);
631 SET_PixelMapuiv(disp
, _mesa_PixelMapuiv
);
632 SET_PixelMapusv(disp
, _mesa_PixelMapusv
);
633 SET_PixelTransferf(disp
, _mesa_PixelTransferf
);
634 SET_PixelTransferi(disp
, _mesa_PixelTransferi
);
635 SET_PixelZoom(disp
, _mesa_PixelZoom
);
639 #endif /* FEATURE_pixel_transfer */
642 /**********************************************************************/
643 /***** Initialization *****/
644 /**********************************************************************/
647 init_pixelmap(struct gl_pixelmap
*map
)
656 * Initialize the context's PIXEL attribute group.
659 _mesa_init_pixel( struct gl_context
*ctx
)
662 ctx
->Pixel
.RedBias
= 0.0;
663 ctx
->Pixel
.RedScale
= 1.0;
664 ctx
->Pixel
.GreenBias
= 0.0;
665 ctx
->Pixel
.GreenScale
= 1.0;
666 ctx
->Pixel
.BlueBias
= 0.0;
667 ctx
->Pixel
.BlueScale
= 1.0;
668 ctx
->Pixel
.AlphaBias
= 0.0;
669 ctx
->Pixel
.AlphaScale
= 1.0;
670 ctx
->Pixel
.DepthBias
= 0.0;
671 ctx
->Pixel
.DepthScale
= 1.0;
672 ctx
->Pixel
.IndexOffset
= 0;
673 ctx
->Pixel
.IndexShift
= 0;
674 ctx
->Pixel
.ZoomX
= 1.0;
675 ctx
->Pixel
.ZoomY
= 1.0;
676 ctx
->Pixel
.MapColorFlag
= GL_FALSE
;
677 ctx
->Pixel
.MapStencilFlag
= GL_FALSE
;
678 init_pixelmap(&ctx
->PixelMaps
.StoS
);
679 init_pixelmap(&ctx
->PixelMaps
.ItoI
);
680 init_pixelmap(&ctx
->PixelMaps
.ItoR
);
681 init_pixelmap(&ctx
->PixelMaps
.ItoG
);
682 init_pixelmap(&ctx
->PixelMaps
.ItoB
);
683 init_pixelmap(&ctx
->PixelMaps
.ItoA
);
684 init_pixelmap(&ctx
->PixelMaps
.RtoR
);
685 init_pixelmap(&ctx
->PixelMaps
.GtoG
);
686 init_pixelmap(&ctx
->PixelMaps
.BtoB
);
687 init_pixelmap(&ctx
->PixelMaps
.AtoA
);
688 /* GL_SGI_texture_color_table */
689 ASSIGN_4V(ctx
->Pixel
.TextureColorTableScale
, 1.0, 1.0, 1.0, 1.0);
690 ASSIGN_4V(ctx
->Pixel
.TextureColorTableBias
, 0.0, 0.0, 0.0, 0.0);
692 if (ctx
->Visual
.doubleBufferMode
) {
693 ctx
->Pixel
.ReadBuffer
= GL_BACK
;
696 ctx
->Pixel
.ReadBuffer
= GL_FRONT
;
700 ctx
->_ImageTransferState
= 0;