mesa/es: Validate glPixelStore pname in Mesa code rather than the ES wrapper
[mesa.git] / src / mesa / main / pixelstore.c
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
39 void 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 (!_mesa_is_desktop_gl(ctx))
49 goto invalid_enum_error;
50 if (param == (GLint)ctx->Pack.SwapBytes)
51 return;
52 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
53 ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
54 break;
55 case GL_PACK_LSB_FIRST:
56 if (!_mesa_is_desktop_gl(ctx))
57 goto invalid_enum_error;
58 if (param == (GLint)ctx->Pack.LsbFirst)
59 return;
60 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
61 ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
62 break;
63 case GL_PACK_ROW_LENGTH:
64 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
65 goto invalid_enum_error;
66 if (param<0) {
67 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
68 return;
69 }
70 if (ctx->Pack.RowLength == param)
71 return;
72 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
73 ctx->Pack.RowLength = param;
74 break;
75 case GL_PACK_IMAGE_HEIGHT:
76 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
77 goto invalid_enum_error;
78 if (param<0) {
79 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
80 return;
81 }
82 if (ctx->Pack.ImageHeight == param)
83 return;
84 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
85 ctx->Pack.ImageHeight = param;
86 break;
87 case GL_PACK_SKIP_PIXELS:
88 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
89 goto invalid_enum_error;
90 if (param<0) {
91 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
92 return;
93 }
94 if (ctx->Pack.SkipPixels == param)
95 return;
96 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
97 ctx->Pack.SkipPixels = param;
98 break;
99 case GL_PACK_SKIP_ROWS:
100 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
101 goto invalid_enum_error;
102 if (param<0) {
103 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
104 return;
105 }
106 if (ctx->Pack.SkipRows == param)
107 return;
108 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
109 ctx->Pack.SkipRows = param;
110 break;
111 case GL_PACK_SKIP_IMAGES:
112 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
113 goto invalid_enum_error;
114 if (param<0) {
115 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
116 return;
117 }
118 if (ctx->Pack.SkipImages == param)
119 return;
120 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
121 ctx->Pack.SkipImages = param;
122 break;
123 case GL_PACK_ALIGNMENT:
124 if (param!=1 && param!=2 && param!=4 && param!=8) {
125 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
126 return;
127 }
128 if (ctx->Pack.Alignment == param)
129 return;
130 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
131 ctx->Pack.Alignment = param;
132 break;
133 case GL_PACK_INVERT_MESA:
134 if (!_mesa_is_desktop_gl(ctx))
135 goto invalid_enum_error;
136 if (!ctx->Extensions.MESA_pack_invert) {
137 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
138 return;
139 }
140 if (ctx->Pack.Invert == param)
141 return;
142 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
143 ctx->Pack.Invert = param;
144 break;
145
146 case GL_UNPACK_SWAP_BYTES:
147 if (!_mesa_is_desktop_gl(ctx))
148 goto invalid_enum_error;
149 if (param == (GLint)ctx->Unpack.SwapBytes)
150 return;
151 if ((GLint)ctx->Unpack.SwapBytes == param)
152 return;
153 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
154 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
155 break;
156 case GL_UNPACK_LSB_FIRST:
157 if (!_mesa_is_desktop_gl(ctx))
158 goto invalid_enum_error;
159 if (param == (GLint)ctx->Unpack.LsbFirst)
160 return;
161 if ((GLint)ctx->Unpack.LsbFirst == param)
162 return;
163 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
164 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
165 break;
166 case GL_UNPACK_ROW_LENGTH:
167 if (ctx->API == API_OPENGLES)
168 goto invalid_enum_error;
169 if (param<0) {
170 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
171 return;
172 }
173 if (ctx->Unpack.RowLength == param)
174 return;
175 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
176 ctx->Unpack.RowLength = param;
177 break;
178 case GL_UNPACK_IMAGE_HEIGHT:
179 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
180 goto invalid_enum_error;
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 (ctx->API == API_OPENGLES)
193 goto invalid_enum_error;
194 if (param<0) {
195 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
196 return;
197 }
198 if (ctx->Unpack.SkipPixels == param)
199 return;
200 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
201 ctx->Unpack.SkipPixels = param;
202 break;
203 case GL_UNPACK_SKIP_ROWS:
204 if (ctx->API == API_OPENGLES)
205 goto invalid_enum_error;
206 if (param<0) {
207 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
208 return;
209 }
210 if (ctx->Unpack.SkipRows == param)
211 return;
212 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
213 ctx->Unpack.SkipRows = param;
214 break;
215 case GL_UNPACK_SKIP_IMAGES:
216 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
217 goto invalid_enum_error;
218 if (param < 0) {
219 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
220 return;
221 }
222 if (ctx->Unpack.SkipImages == param)
223 return;
224 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
225 ctx->Unpack.SkipImages = param;
226 break;
227 case GL_UNPACK_ALIGNMENT:
228 if (param!=1 && param!=2 && param!=4 && param!=8) {
229 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
230 return;
231 }
232 if (ctx->Unpack.Alignment == param)
233 return;
234 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
235 ctx->Unpack.Alignment = param;
236 break;
237 default:
238 goto invalid_enum_error;
239 }
240
241 return;
242
243 invalid_enum_error:
244 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
245 return;
246 }
247
248
249 void GLAPIENTRY
250 _mesa_PixelStoref( GLenum pname, GLfloat param )
251 {
252 _mesa_PixelStorei( pname, IROUND(param) );
253 }
254
255
256
257 /**
258 * Initialize the context's pixel store state.
259 */
260 void
261 _mesa_init_pixelstore( struct gl_context *ctx )
262 {
263 /* Pixel transfer */
264 ctx->Pack.Alignment = 4;
265 ctx->Pack.RowLength = 0;
266 ctx->Pack.ImageHeight = 0;
267 ctx->Pack.SkipPixels = 0;
268 ctx->Pack.SkipRows = 0;
269 ctx->Pack.SkipImages = 0;
270 ctx->Pack.SwapBytes = GL_FALSE;
271 ctx->Pack.LsbFirst = GL_FALSE;
272 ctx->Pack.Invert = GL_FALSE;
273 #if FEATURE_EXT_pixel_buffer_object
274 _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj,
275 ctx->Shared->NullBufferObj);
276 #endif
277 ctx->Unpack.Alignment = 4;
278 ctx->Unpack.RowLength = 0;
279 ctx->Unpack.ImageHeight = 0;
280 ctx->Unpack.SkipPixels = 0;
281 ctx->Unpack.SkipRows = 0;
282 ctx->Unpack.SkipImages = 0;
283 ctx->Unpack.SwapBytes = GL_FALSE;
284 ctx->Unpack.LsbFirst = GL_FALSE;
285 ctx->Unpack.Invert = GL_FALSE;
286 #if FEATURE_EXT_pixel_buffer_object
287 _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj,
288 ctx->Shared->NullBufferObj);
289 #endif
290
291 /*
292 * _mesa_unpack_image() returns image data in this format. When we
293 * execute image commands (glDrawPixels(), glTexImage(), etc) from
294 * within display lists we have to be sure to set the current
295 * unpacking parameters to these values!
296 */
297 ctx->DefaultPacking.Alignment = 1;
298 ctx->DefaultPacking.RowLength = 0;
299 ctx->DefaultPacking.SkipPixels = 0;
300 ctx->DefaultPacking.SkipRows = 0;
301 ctx->DefaultPacking.ImageHeight = 0;
302 ctx->DefaultPacking.SkipImages = 0;
303 ctx->DefaultPacking.SwapBytes = GL_FALSE;
304 ctx->DefaultPacking.LsbFirst = GL_FALSE;
305 ctx->DefaultPacking.Invert = GL_FALSE;
306 #if FEATURE_EXT_pixel_buffer_object
307 _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj,
308 ctx->Shared->NullBufferObj);
309 #endif
310 }