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