pixelstore.c revision 3464ebd5
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.1
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 */
24
25/**
26 * \file pixelstore.c
27 * glPixelStore functions.
28 */
29
30
31#include "glheader.h"
32#include "bufferobj.h"
33#include "context.h"
34#include "pixelstore.h"
35#include "mfeatures.h"
36#include "mtypes.h"
37
38
39void GLAPIENTRY
40_mesa_PixelStorei( GLenum pname, GLint param )
41{
42   /* NOTE: this call can't be compiled into the display list */
43   GET_CURRENT_CONTEXT(ctx);
44   ASSERT_OUTSIDE_BEGIN_END(ctx);
45
46   switch (pname) {
47      case GL_PACK_SWAP_BYTES:
48	 if (param == (GLint)ctx->Pack.SwapBytes)
49	    return;
50	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
51         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
52	 break;
53      case GL_PACK_LSB_FIRST:
54	 if (param == (GLint)ctx->Pack.LsbFirst)
55	    return;
56	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
57         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
58	 break;
59      case GL_PACK_ROW_LENGTH:
60	 if (param<0) {
61	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
62	    return;
63	 }
64	 if (ctx->Pack.RowLength == param)
65	    return;
66	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
67	 ctx->Pack.RowLength = param;
68	 break;
69      case GL_PACK_IMAGE_HEIGHT:
70         if (param<0) {
71            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
72	    return;
73	 }
74	 if (ctx->Pack.ImageHeight == param)
75	    return;
76	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
77	 ctx->Pack.ImageHeight = param;
78         break;
79      case GL_PACK_SKIP_PIXELS:
80	 if (param<0) {
81	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
82	    return;
83	 }
84	 if (ctx->Pack.SkipPixels == param)
85	    return;
86	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
87	 ctx->Pack.SkipPixels = param;
88	 break;
89      case GL_PACK_SKIP_ROWS:
90	 if (param<0) {
91	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
92	    return;
93	 }
94	 if (ctx->Pack.SkipRows == param)
95	    return;
96	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
97	 ctx->Pack.SkipRows = param;
98	 break;
99      case GL_PACK_SKIP_IMAGES:
100	 if (param<0) {
101	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
102	    return;
103	 }
104	 if (ctx->Pack.SkipImages == param)
105	    return;
106	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
107	 ctx->Pack.SkipImages = param;
108	 break;
109      case GL_PACK_ALIGNMENT:
110         if (param!=1 && param!=2 && param!=4 && param!=8) {
111	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
112	    return;
113	 }
114	 if (ctx->Pack.Alignment == param)
115	    return;
116	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
117	 ctx->Pack.Alignment = param;
118	 break;
119      case GL_PACK_INVERT_MESA:
120         if (!ctx->Extensions.MESA_pack_invert) {
121            _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
122            return;
123         }
124         if (ctx->Pack.Invert == param)
125            return;
126         FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
127         ctx->Pack.Invert = param;
128         break;
129
130      case GL_UNPACK_SWAP_BYTES:
131	 if (param == (GLint)ctx->Unpack.SwapBytes)
132	    return;
133	 if ((GLint)ctx->Unpack.SwapBytes == param)
134	    return;
135	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
136	 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
137         break;
138      case GL_UNPACK_LSB_FIRST:
139	 if (param == (GLint)ctx->Unpack.LsbFirst)
140	    return;
141	 if ((GLint)ctx->Unpack.LsbFirst == param)
142	    return;
143	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
144	 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
145	 break;
146      case GL_UNPACK_ROW_LENGTH:
147	 if (param<0) {
148	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
149	    return;
150	 }
151	 if (ctx->Unpack.RowLength == param)
152	    return;
153	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
154	 ctx->Unpack.RowLength = param;
155	 break;
156      case GL_UNPACK_IMAGE_HEIGHT:
157         if (param<0) {
158            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
159	    return;
160	 }
161	 if (ctx->Unpack.ImageHeight == param)
162	    return;
163
164	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
165	 ctx->Unpack.ImageHeight = param;
166         break;
167      case GL_UNPACK_SKIP_PIXELS:
168	 if (param<0) {
169	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
170	    return;
171	 }
172	 if (ctx->Unpack.SkipPixels == param)
173	    return;
174	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
175	 ctx->Unpack.SkipPixels = param;
176	 break;
177      case GL_UNPACK_SKIP_ROWS:
178	 if (param<0) {
179	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
180	    return;
181	 }
182	 if (ctx->Unpack.SkipRows == param)
183	    return;
184	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
185	 ctx->Unpack.SkipRows = param;
186	 break;
187      case GL_UNPACK_SKIP_IMAGES:
188	 if (param < 0) {
189	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
190	    return;
191	 }
192	 if (ctx->Unpack.SkipImages == param)
193	    return;
194	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
195	 ctx->Unpack.SkipImages = param;
196	 break;
197      case GL_UNPACK_ALIGNMENT:
198         if (param!=1 && param!=2 && param!=4 && param!=8) {
199	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
200	    return;
201	 }
202	 if (ctx->Unpack.Alignment == param)
203	    return;
204	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
205	 ctx->Unpack.Alignment = param;
206	 break;
207      case GL_UNPACK_CLIENT_STORAGE_APPLE:
208         if (param == (GLint)ctx->Unpack.ClientStorage)
209            return;
210         FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
211         ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE;
212         break;
213      default:
214	 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
215	 return;
216   }
217}
218
219
220void GLAPIENTRY
221_mesa_PixelStoref( GLenum pname, GLfloat param )
222{
223   _mesa_PixelStorei( pname, (GLint) param );
224}
225
226
227
228/**
229 * Initialize the context's pixel store state.
230 */
231void
232_mesa_init_pixelstore( struct gl_context *ctx )
233{
234   /* Pixel transfer */
235   ctx->Pack.Alignment = 4;
236   ctx->Pack.RowLength = 0;
237   ctx->Pack.ImageHeight = 0;
238   ctx->Pack.SkipPixels = 0;
239   ctx->Pack.SkipRows = 0;
240   ctx->Pack.SkipImages = 0;
241   ctx->Pack.SwapBytes = GL_FALSE;
242   ctx->Pack.LsbFirst = GL_FALSE;
243   ctx->Pack.ClientStorage = GL_FALSE;
244   ctx->Pack.Invert = GL_FALSE;
245#if FEATURE_EXT_pixel_buffer_object
246   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj,
247                                 ctx->Shared->NullBufferObj);
248#endif
249   ctx->Unpack.Alignment = 4;
250   ctx->Unpack.RowLength = 0;
251   ctx->Unpack.ImageHeight = 0;
252   ctx->Unpack.SkipPixels = 0;
253   ctx->Unpack.SkipRows = 0;
254   ctx->Unpack.SkipImages = 0;
255   ctx->Unpack.SwapBytes = GL_FALSE;
256   ctx->Unpack.LsbFirst = GL_FALSE;
257   ctx->Unpack.ClientStorage = GL_FALSE;
258   ctx->Unpack.Invert = GL_FALSE;
259#if FEATURE_EXT_pixel_buffer_object
260   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj,
261                                 ctx->Shared->NullBufferObj);
262#endif
263
264   /*
265    * _mesa_unpack_image() returns image data in this format.  When we
266    * execute image commands (glDrawPixels(), glTexImage(), etc) from
267    * within display lists we have to be sure to set the current
268    * unpacking parameters to these values!
269    */
270   ctx->DefaultPacking.Alignment = 1;
271   ctx->DefaultPacking.RowLength = 0;
272   ctx->DefaultPacking.SkipPixels = 0;
273   ctx->DefaultPacking.SkipRows = 0;
274   ctx->DefaultPacking.ImageHeight = 0;
275   ctx->DefaultPacking.SkipImages = 0;
276   ctx->DefaultPacking.SwapBytes = GL_FALSE;
277   ctx->DefaultPacking.LsbFirst = GL_FALSE;
278   ctx->DefaultPacking.ClientStorage = GL_FALSE;
279   ctx->DefaultPacking.Invert = GL_FALSE;
280#if FEATURE_EXT_pixel_buffer_object
281   _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj,
282                                 ctx->Shared->NullBufferObj);
283#endif
284}
285