• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * 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
_mesa_PixelStorei(GLenum pname,GLint param)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 
44    switch (pname) {
45       case GL_PACK_SWAP_BYTES:
46          if (!_mesa_is_desktop_gl(ctx))
47             goto invalid_enum_error;
48          ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
49          break;
50       case GL_PACK_LSB_FIRST:
51          if (!_mesa_is_desktop_gl(ctx))
52             goto invalid_enum_error;
53          ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
54          break;
55       case GL_PACK_ROW_LENGTH:
56          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
57             goto invalid_enum_error;
58          if (param<0)
59             goto invalid_value_error;
60          ctx->Pack.RowLength = param;
61          break;
62       case GL_PACK_IMAGE_HEIGHT:
63          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
64             goto invalid_enum_error;
65          if (param<0)
66             goto invalid_value_error;
67          ctx->Pack.ImageHeight = param;
68          break;
69       case GL_PACK_SKIP_PIXELS:
70          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
71             goto invalid_enum_error;
72          if (param<0)
73             goto invalid_value_error;
74          ctx->Pack.SkipPixels = param;
75          break;
76       case GL_PACK_SKIP_ROWS:
77          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
78             goto invalid_enum_error;
79          if (param<0)
80             goto invalid_value_error;
81          ctx->Pack.SkipRows = param;
82          break;
83       case GL_PACK_SKIP_IMAGES:
84          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
85             goto invalid_enum_error;
86          if (param<0)
87             goto invalid_value_error;
88          ctx->Pack.SkipImages = param;
89          break;
90       case GL_PACK_ALIGNMENT:
91          if (param!=1 && param!=2 && param!=4 && param!=8)
92             goto invalid_value_error;
93          ctx->Pack.Alignment = param;
94          break;
95       case GL_PACK_INVERT_MESA:
96          if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.MESA_pack_invert)
97             goto invalid_enum_error;
98          ctx->Pack.Invert = param;
99          break;
100       case GL_PACK_COMPRESSED_BLOCK_WIDTH:
101          if (!_mesa_is_desktop_gl(ctx))
102             goto invalid_enum_error;
103          if (param<0)
104             goto invalid_value_error;
105          ctx->Pack.CompressedBlockWidth = param;
106          break;
107       case GL_PACK_COMPRESSED_BLOCK_HEIGHT:
108          if (!_mesa_is_desktop_gl(ctx))
109             goto invalid_enum_error;
110          if (param<0)
111             goto invalid_value_error;
112          ctx->Pack.CompressedBlockHeight = param;
113          break;
114       case GL_PACK_COMPRESSED_BLOCK_DEPTH:
115          if (!_mesa_is_desktop_gl(ctx))
116             goto invalid_enum_error;
117          if (param<0)
118             goto invalid_value_error;
119          ctx->Pack.CompressedBlockDepth = param;
120          break;
121       case GL_PACK_COMPRESSED_BLOCK_SIZE:
122          if (!_mesa_is_desktop_gl(ctx))
123             goto invalid_enum_error;
124          if (param<0)
125             goto invalid_value_error;
126          ctx->Pack.CompressedBlockSize = param;
127          break;
128 
129       case GL_UNPACK_SWAP_BYTES:
130          if (!_mesa_is_desktop_gl(ctx))
131             goto invalid_enum_error;
132          ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
133          break;
134       case GL_UNPACK_LSB_FIRST:
135          if (!_mesa_is_desktop_gl(ctx))
136             goto invalid_enum_error;
137          ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
138          break;
139       case GL_UNPACK_ROW_LENGTH:
140          if (ctx->API == API_OPENGLES)
141             goto invalid_enum_error;
142          if (param<0)
143             goto invalid_value_error;
144          ctx->Unpack.RowLength = param;
145          break;
146       case GL_UNPACK_IMAGE_HEIGHT:
147          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
148             goto invalid_enum_error;
149          if (param<0)
150             goto invalid_value_error;
151          ctx->Unpack.ImageHeight = param;
152          break;
153       case GL_UNPACK_SKIP_PIXELS:
154          if (ctx->API == API_OPENGLES)
155             goto invalid_enum_error;
156          if (param<0)
157             goto invalid_value_error;
158          ctx->Unpack.SkipPixels = param;
159          break;
160       case GL_UNPACK_SKIP_ROWS:
161          if (ctx->API == API_OPENGLES)
162             goto invalid_enum_error;
163          if (param<0)
164             goto invalid_value_error;
165          ctx->Unpack.SkipRows = param;
166          break;
167       case GL_UNPACK_SKIP_IMAGES:
168          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
169             goto invalid_enum_error;
170          if (param < 0)
171             goto invalid_value_error;
172          ctx->Unpack.SkipImages = param;
173          break;
174       case GL_UNPACK_ALIGNMENT:
175          if (param!=1 && param!=2 && param!=4 && param!=8)
176             goto invalid_value_error;
177          ctx->Unpack.Alignment = param;
178          break;
179       case GL_UNPACK_COMPRESSED_BLOCK_WIDTH:
180          if (!_mesa_is_desktop_gl(ctx))
181             goto invalid_enum_error;
182          if (param<0)
183             goto invalid_value_error;
184          ctx->Unpack.CompressedBlockWidth = param;
185          break;
186       case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT:
187          if (!_mesa_is_desktop_gl(ctx))
188             goto invalid_enum_error;
189          if (param<0)
190             goto invalid_value_error;
191          ctx->Unpack.CompressedBlockHeight = param;
192          break;
193       case GL_UNPACK_COMPRESSED_BLOCK_DEPTH:
194          if (!_mesa_is_desktop_gl(ctx))
195             goto invalid_enum_error;
196          if (param<0)
197             goto invalid_value_error;
198          ctx->Unpack.CompressedBlockDepth = param;
199          break;
200       case GL_UNPACK_COMPRESSED_BLOCK_SIZE:
201          if (!_mesa_is_desktop_gl(ctx))
202             goto invalid_enum_error;
203          if (param<0)
204             goto invalid_value_error;
205          ctx->Unpack.CompressedBlockSize = param;
206          break;
207       default:
208          goto invalid_enum_error;
209    }
210 
211    return;
212 
213 invalid_enum_error:
214    _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
215    return;
216 
217 invalid_value_error:
218    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
219    return;
220 }
221 
222 
223 void GLAPIENTRY
_mesa_PixelStoref(GLenum pname,GLfloat param)224 _mesa_PixelStoref( GLenum pname, GLfloat param )
225 {
226    _mesa_PixelStorei( pname, IROUND(param) );
227 }
228 
229 
230 
231 /**
232  * Initialize the context's pixel store state.
233  */
234 void
_mesa_init_pixelstore(struct gl_context * ctx)235 _mesa_init_pixelstore( struct gl_context *ctx )
236 {
237    /* Pixel transfer */
238    ctx->Pack.Alignment = 4;
239    ctx->Pack.RowLength = 0;
240    ctx->Pack.ImageHeight = 0;
241    ctx->Pack.SkipPixels = 0;
242    ctx->Pack.SkipRows = 0;
243    ctx->Pack.SkipImages = 0;
244    ctx->Pack.SwapBytes = GL_FALSE;
245    ctx->Pack.LsbFirst = GL_FALSE;
246    ctx->Pack.Invert = GL_FALSE;
247    ctx->Pack.CompressedBlockWidth = 0;
248    ctx->Pack.CompressedBlockHeight = 0;
249    ctx->Pack.CompressedBlockDepth = 0;
250    ctx->Pack.CompressedBlockSize = 0;
251    _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj,
252                                  ctx->Shared->NullBufferObj);
253    ctx->Unpack.Alignment = 4;
254    ctx->Unpack.RowLength = 0;
255    ctx->Unpack.ImageHeight = 0;
256    ctx->Unpack.SkipPixels = 0;
257    ctx->Unpack.SkipRows = 0;
258    ctx->Unpack.SkipImages = 0;
259    ctx->Unpack.SwapBytes = GL_FALSE;
260    ctx->Unpack.LsbFirst = GL_FALSE;
261    ctx->Unpack.Invert = GL_FALSE;
262    ctx->Unpack.CompressedBlockWidth = 0;
263    ctx->Unpack.CompressedBlockHeight = 0;
264    ctx->Unpack.CompressedBlockDepth = 0;
265    ctx->Unpack.CompressedBlockSize = 0;
266    _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj,
267                                  ctx->Shared->NullBufferObj);
268 
269    /*
270     * _mesa_unpack_image() returns image data in this format.  When we
271     * execute image commands (glDrawPixels(), glTexImage(), etc) from
272     * within display lists we have to be sure to set the current
273     * unpacking parameters to these values!
274     */
275    ctx->DefaultPacking.Alignment = 1;
276    ctx->DefaultPacking.RowLength = 0;
277    ctx->DefaultPacking.SkipPixels = 0;
278    ctx->DefaultPacking.SkipRows = 0;
279    ctx->DefaultPacking.ImageHeight = 0;
280    ctx->DefaultPacking.SkipImages = 0;
281    ctx->DefaultPacking.SwapBytes = GL_FALSE;
282    ctx->DefaultPacking.LsbFirst = GL_FALSE;
283    ctx->DefaultPacking.Invert = GL_FALSE;
284    _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj,
285                                  ctx->Shared->NullBufferObj);
286 }
287 
288 
289 /**
290  * Check if the given compressed pixel storage parameters are legal.
291  * Record a GL error if illegal.
292  * \return  true if legal, false if illegal
293  */
294 bool
_mesa_compressed_pixel_storage_error_check(struct gl_context * ctx,GLint dimensions,const struct gl_pixelstore_attrib * packing,const char * caller)295 _mesa_compressed_pixel_storage_error_check(
296    struct gl_context *ctx,
297    GLint dimensions,
298    const struct gl_pixelstore_attrib *packing,
299    const char *caller)
300 {
301    if (!_mesa_is_desktop_gl(ctx) || !packing->CompressedBlockSize)
302       return true;
303 
304    if (packing->CompressedBlockWidth &&
305        packing->SkipPixels % packing->CompressedBlockWidth) {
306       _mesa_error(ctx, GL_INVALID_OPERATION,
307                   "%s(skip-pixels %% block-width)", caller);
308       return false;
309    }
310 
311    if (dimensions > 1 &&
312        packing->CompressedBlockHeight &&
313        packing->SkipRows % packing->CompressedBlockHeight) {
314       _mesa_error(ctx, GL_INVALID_OPERATION,
315                   "%s(skip-rows %% block-height)", caller);
316       return false;
317    }
318 
319    if (dimensions > 2 &&
320        packing->CompressedBlockDepth &&
321        packing->SkipImages % packing->CompressedBlockDepth) {
322       _mesa_error(ctx, GL_INVALID_OPERATION,
323                   "%s(skip-images %% block-depth)", caller);
324       return false;
325    }
326 
327    return true;
328 }
329