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