1706f2543Smrg/*
2706f2543Smrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3706f2543Smrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6706f2543Smrg * copy of this software and associated documentation files (the "Software"),
7706f2543Smrg * to deal in the Software without restriction, including without limitation
8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
10706f2543Smrg * Software is furnished to do so, subject to the following conditions:
11706f2543Smrg *
12706f2543Smrg * The above copyright notice including the dates of first publication and
13706f2543Smrg * either this permission notice or a reference to
14706f2543Smrg * http://oss.sgi.com/projects/FreeB/
15706f2543Smrg * shall be included in all copies or substantial portions of the Software.
16706f2543Smrg *
17706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20706f2543Smrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23706f2543Smrg * SOFTWARE.
24706f2543Smrg *
25706f2543Smrg * Except as contained in this notice, the name of Silicon Graphics, Inc.
26706f2543Smrg * shall not be used in advertising or otherwise to promote the sale, use or
27706f2543Smrg * other dealings in this Software without prior written authorization from
28706f2543Smrg * Silicon Graphics, Inc.
29706f2543Smrg */
30706f2543Smrg
31706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
32706f2543Smrg#include <dix-config.h>
33706f2543Smrg#endif
34706f2543Smrg
35706f2543Smrg#include <GL/gl.h>
36706f2543Smrg#include "glxserver.h"
37706f2543Smrg#include "GL/glxproto.h"
38706f2543Smrg#include "unpack.h"
39706f2543Smrg#include "indirect_size.h"
40706f2543Smrg#include "indirect_reqsize.h"
41706f2543Smrg
42706f2543Smrg#define SWAPL(a) \
43706f2543Smrg  (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
44706f2543Smrg   ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
45706f2543Smrg
46706f2543Smrgint __glXMap1dReqSize( const GLbyte *pc, Bool swap, int reqlen )
47706f2543Smrg{
48706f2543Smrg    GLenum target;
49706f2543Smrg    GLint order;
50706f2543Smrg
51706f2543Smrg    target = *(GLenum*) (pc + 16);
52706f2543Smrg    order = *(GLint*) (pc + 20);
53706f2543Smrg    if (swap) {
54706f2543Smrg	target = SWAPL( target );
55706f2543Smrg	order = SWAPL( order );
56706f2543Smrg    }
57706f2543Smrg    if (order < 1)
58706f2543Smrg        return -1;
59706f2543Smrg    return safe_mul(8, safe_mul(__glMap1d_size(target), order));
60706f2543Smrg}
61706f2543Smrg
62706f2543Smrgint __glXMap1fReqSize( const GLbyte *pc, Bool swap, int reqlen )
63706f2543Smrg{
64706f2543Smrg    GLenum target;
65706f2543Smrg    GLint order;
66706f2543Smrg
67706f2543Smrg    target = *(GLenum *)(pc + 0);
68706f2543Smrg    order = *(GLint *)(pc + 12);
69706f2543Smrg    if (swap) {
70706f2543Smrg	target = SWAPL( target );
71706f2543Smrg	order = SWAPL( order );
72706f2543Smrg    }
73706f2543Smrg    if (order < 1)
74706f2543Smrg        return -1;
75706f2543Smrg    return safe_mul(4, safe_mul(__glMap1f_size(target), order));
76706f2543Smrg}
77706f2543Smrg
78706f2543Smrgstatic int Map2Size(int k, int majorOrder, int minorOrder)
79706f2543Smrg{
80706f2543Smrg    if (majorOrder < 1 || minorOrder < 1)
81706f2543Smrg         return -1;
82706f2543Smrg    return safe_mul(k, safe_mul(majorOrder, minorOrder));
83706f2543Smrg}
84706f2543Smrg
85706f2543Smrgint __glXMap2dReqSize( const GLbyte *pc, Bool swap, int reqlen )
86706f2543Smrg{
87706f2543Smrg    GLenum target;
88706f2543Smrg    GLint uorder, vorder;
89706f2543Smrg
90706f2543Smrg    target = *(GLenum *)(pc + 32);
91706f2543Smrg    uorder = *(GLint *)(pc + 36);
92706f2543Smrg    vorder = *(GLint *)(pc + 40);
93706f2543Smrg    if (swap) {
94706f2543Smrg	target = SWAPL( target );
95706f2543Smrg	uorder = SWAPL( uorder );
96706f2543Smrg	vorder = SWAPL( vorder );
97706f2543Smrg    }
98706f2543Smrg    return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder));
99706f2543Smrg}
100706f2543Smrg
101706f2543Smrgint __glXMap2fReqSize( const GLbyte *pc, Bool swap, int reqlen )
102706f2543Smrg{
103706f2543Smrg    GLenum target;
104706f2543Smrg    GLint uorder, vorder;
105706f2543Smrg
106706f2543Smrg    target = *(GLenum *)(pc + 0);
107706f2543Smrg    uorder = *(GLint *)(pc + 12);
108706f2543Smrg    vorder = *(GLint *)(pc + 24);
109706f2543Smrg    if (swap) {
110706f2543Smrg	target = SWAPL( target );
111706f2543Smrg	uorder = SWAPL( uorder );
112706f2543Smrg	vorder = SWAPL( vorder );
113706f2543Smrg    }
114706f2543Smrg    return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder));
115706f2543Smrg}
116706f2543Smrg
117706f2543Smrg/**
118706f2543Smrg * Calculate the size of an image.
119706f2543Smrg *
120706f2543Smrg * The size of an image sent to the server from the client or sent from the
121706f2543Smrg * server to the client is calculated.  The size is based on the dimensions
122706f2543Smrg * of the image, the type of pixel data, padding in the image, and the
123706f2543Smrg * alignment requirements of the image.
124706f2543Smrg *
125706f2543Smrg * \param format       Format of the pixels.  Same as the \c format parameter
126706f2543Smrg *                     to \c glTexImage1D
127706f2543Smrg * \param type         Type of the pixel data.  Same as the \c type parameter
128706f2543Smrg *                     to \c glTexImage1D
129706f2543Smrg * \param target       Typically the texture target of the image.  If the
130706f2543Smrg *                     target is one of \c GL_PROXY_*, the size returned is
131706f2543Smrg *                     always zero. For uses that do not have a texture target
132706f2543Smrg *                     (e.g, glDrawPixels), zero should be specified.
133706f2543Smrg * \param w            Width of the image data.  Must be >= 1.
134706f2543Smrg * \param h            Height of the image data.  Must be >= 1, even for 1D
135706f2543Smrg *                     images.
136706f2543Smrg * \param d            Depth of the image data.  Must be >= 1, even for 1D or
137706f2543Smrg *                     2D images.
138706f2543Smrg * \param imageHeight  If non-zero, defines the true height of a volumetric
139706f2543Smrg *                     image.  This value will be used instead of \c h for
140706f2543Smrg *                     calculating the size of the image.
141706f2543Smrg * \param rowLength    If non-zero, defines the true width of an image.  This
142706f2543Smrg *                     value will be used instead of \c w for calculating the
143706f2543Smrg *                     size of the image.
144706f2543Smrg * \param skipImages   Number of extra layers of image data in a volumtric
145706f2543Smrg *                     image that are to be skipped before the real data.
146706f2543Smrg * \param skipRows     Number of extra rows of image data in an image that are
147706f2543Smrg *                     to be skipped before the real data.
148706f2543Smrg * \param alignment    Specifies the alignment for the start of each pixel row
149706f2543Smrg *                     in memory.  This value must be one of 1, 2, 4, or 8.
150706f2543Smrg *
151706f2543Smrg * \returns
152706f2543Smrg * The size of the image is returned.  If the specified \c format and \c type
153706f2543Smrg * are invalid, -1 is returned.  If \c target is one of \c GL_PROXY_*, zero
154706f2543Smrg * is returned.
155706f2543Smrg */
156706f2543Smrgint __glXImageSize( GLenum format, GLenum type, GLenum target,
157706f2543Smrg		    GLsizei w, GLsizei h, GLsizei d,
158706f2543Smrg		    GLint imageHeight, GLint rowLength,
159706f2543Smrg		    GLint skipImages, GLint skipRows, GLint alignment )
160706f2543Smrg{
161706f2543Smrg    GLint bytesPerElement, elementsPerGroup, groupsPerRow;
162706f2543Smrg    GLint groupSize, rowSize, padding, imageSize;
163706f2543Smrg
164706f2543Smrg    if (w == 0 || h == 0 || d == 0)
165706f2543Smrg        return 0;
166706f2543Smrg
167706f2543Smrg    if (w < 0 || h < 0 || d < 0 ||
168706f2543Smrg	(type == GL_BITMAP &&
169706f2543Smrg	 (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
170706f2543Smrg	return -1;
171706f2543Smrg    }
172706f2543Smrg
173706f2543Smrg    /* proxy targets have no data */
174706f2543Smrg    switch( target ) {
175706f2543Smrg    case GL_PROXY_TEXTURE_1D:
176706f2543Smrg    case GL_PROXY_TEXTURE_2D:
177706f2543Smrg    case GL_PROXY_TEXTURE_3D:
178706f2543Smrg    case GL_PROXY_TEXTURE_4D_SGIS:
179706f2543Smrg    case GL_PROXY_TEXTURE_CUBE_MAP:
180706f2543Smrg    case GL_PROXY_TEXTURE_RECTANGLE_ARB:
181706f2543Smrg    case GL_PROXY_HISTOGRAM:
182706f2543Smrg    case GL_PROXY_COLOR_TABLE:
183706f2543Smrg    case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
184706f2543Smrg    case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
185706f2543Smrg    case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
186706f2543Smrg    case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
187706f2543Smrg	return 0;
188706f2543Smrg    }
189706f2543Smrg
190706f2543Smrg    /* real data has to have real sizes */
191706f2543Smrg    if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0)
192706f2543Smrg        return -1;
193706f2543Smrg    if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8)
194706f2543Smrg        return -1;
195706f2543Smrg
196706f2543Smrg    if (type == GL_BITMAP) {
197706f2543Smrg	if (rowLength > 0) {
198706f2543Smrg	    groupsPerRow = rowLength;
199706f2543Smrg	} else {
200706f2543Smrg	    groupsPerRow = w;
201706f2543Smrg	}
202706f2543Smrg	rowSize = bits_to_bytes(groupsPerRow);
203706f2543Smrg        if (rowSize < 0)
204706f2543Smrg            return -1;
205706f2543Smrg	padding = (rowSize % alignment);
206706f2543Smrg	if (padding) {
207706f2543Smrg	    rowSize += alignment - padding;
208706f2543Smrg	}
209706f2543Smrg
210706f2543Smrg        return safe_mul(safe_add(h, skipRows), rowSize);
211706f2543Smrg    } else {
212706f2543Smrg	switch(format) {
213706f2543Smrg	  case GL_COLOR_INDEX:
214706f2543Smrg	  case GL_STENCIL_INDEX:
215706f2543Smrg	  case GL_DEPTH_COMPONENT:
216706f2543Smrg	  case GL_RED:
217706f2543Smrg	  case GL_GREEN:
218706f2543Smrg	  case GL_BLUE:
219706f2543Smrg	  case GL_ALPHA:
220706f2543Smrg	  case GL_LUMINANCE:
221706f2543Smrg	  case GL_INTENSITY:
222706f2543Smrg          case GL_RED_INTEGER_EXT:
223706f2543Smrg          case GL_GREEN_INTEGER_EXT:
224706f2543Smrg          case GL_BLUE_INTEGER_EXT:
225706f2543Smrg          case GL_ALPHA_INTEGER_EXT:
226706f2543Smrg          case GL_LUMINANCE_INTEGER_EXT:
227706f2543Smrg	    elementsPerGroup = 1;
228706f2543Smrg	    break;
229706f2543Smrg	  case GL_422_EXT:
230706f2543Smrg	  case GL_422_REV_EXT:
231706f2543Smrg	  case GL_422_AVERAGE_EXT:
232706f2543Smrg	  case GL_422_REV_AVERAGE_EXT:
233706f2543Smrg	  case GL_DEPTH_STENCIL_NV:
234706f2543Smrg	  case GL_DEPTH_STENCIL_MESA:
235706f2543Smrg	  case GL_YCBCR_MESA:
236706f2543Smrg	  case GL_LUMINANCE_ALPHA:
237706f2543Smrg          case GL_LUMINANCE_ALPHA_INTEGER_EXT:
238706f2543Smrg	    elementsPerGroup = 2;
239706f2543Smrg	    break;
240706f2543Smrg	  case GL_RGB:
241706f2543Smrg	  case GL_BGR:
242706f2543Smrg          case GL_RGB_INTEGER_EXT:
243706f2543Smrg          case GL_BGR_INTEGER_EXT:
244706f2543Smrg	    elementsPerGroup = 3;
245706f2543Smrg	    break;
246706f2543Smrg	  case GL_RGBA:
247706f2543Smrg	  case GL_BGRA:
248706f2543Smrg          case GL_RGBA_INTEGER_EXT:
249706f2543Smrg          case GL_BGRA_INTEGER_EXT:
250706f2543Smrg	  case GL_ABGR_EXT:
251706f2543Smrg	    elementsPerGroup = 4;
252706f2543Smrg	    break;
253706f2543Smrg	  default:
254706f2543Smrg	    return -1;
255706f2543Smrg	}
256706f2543Smrg	switch(type) {
257706f2543Smrg	  case GL_UNSIGNED_BYTE:
258706f2543Smrg	  case GL_BYTE:
259706f2543Smrg	    bytesPerElement = 1;
260706f2543Smrg	    break;
261706f2543Smrg	  case GL_UNSIGNED_BYTE_3_3_2:
262706f2543Smrg	  case GL_UNSIGNED_BYTE_2_3_3_REV:
263706f2543Smrg	    bytesPerElement = 1;
264706f2543Smrg	    elementsPerGroup = 1;
265706f2543Smrg	    break;
266706f2543Smrg	  case GL_UNSIGNED_SHORT:
267706f2543Smrg	  case GL_SHORT:
268706f2543Smrg	    bytesPerElement = 2;
269706f2543Smrg	    break;
270706f2543Smrg	  case GL_UNSIGNED_SHORT_5_6_5:
271706f2543Smrg	  case GL_UNSIGNED_SHORT_5_6_5_REV:
272706f2543Smrg	  case GL_UNSIGNED_SHORT_4_4_4_4:
273706f2543Smrg 	  case GL_UNSIGNED_SHORT_4_4_4_4_REV:
274706f2543Smrg	  case GL_UNSIGNED_SHORT_5_5_5_1:
275706f2543Smrg	  case GL_UNSIGNED_SHORT_1_5_5_5_REV:
276706f2543Smrg	  case GL_UNSIGNED_SHORT_8_8_APPLE:
277706f2543Smrg	  case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
278706f2543Smrg	  case GL_UNSIGNED_SHORT_15_1_MESA:
279706f2543Smrg	  case GL_UNSIGNED_SHORT_1_15_REV_MESA:
280706f2543Smrg	    bytesPerElement = 2;
281706f2543Smrg	    elementsPerGroup = 1;
282706f2543Smrg	    break;
283706f2543Smrg	  case GL_INT:
284706f2543Smrg	  case GL_UNSIGNED_INT:
285706f2543Smrg	  case GL_FLOAT:
286706f2543Smrg	    bytesPerElement = 4;
287706f2543Smrg	    break;
288706f2543Smrg	  case GL_UNSIGNED_INT_8_8_8_8:
289706f2543Smrg	  case GL_UNSIGNED_INT_8_8_8_8_REV:
290706f2543Smrg	  case GL_UNSIGNED_INT_10_10_10_2:
291706f2543Smrg	  case GL_UNSIGNED_INT_2_10_10_10_REV:
292706f2543Smrg	  case GL_UNSIGNED_INT_24_8_NV:
293706f2543Smrg	  case GL_UNSIGNED_INT_24_8_MESA:
294706f2543Smrg	  case GL_UNSIGNED_INT_8_24_REV_MESA:
295706f2543Smrg	    bytesPerElement = 4;
296706f2543Smrg	    elementsPerGroup = 1;
297706f2543Smrg	    break;
298706f2543Smrg	  default:
299706f2543Smrg	    return -1;
300706f2543Smrg	}
301706f2543Smrg        /* known safe by the switches above, not checked */
302706f2543Smrg	groupSize = bytesPerElement * elementsPerGroup;
303706f2543Smrg	if (rowLength > 0) {
304706f2543Smrg	    groupsPerRow = rowLength;
305706f2543Smrg	} else {
306706f2543Smrg	    groupsPerRow = w;
307706f2543Smrg	}
308706f2543Smrg        if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0)
309706f2543Smrg            return -1;
310706f2543Smrg	padding = (rowSize % alignment);
311706f2543Smrg	if (padding) {
312706f2543Smrg	    rowSize += alignment - padding;
313706f2543Smrg	}
314706f2543Smrg
315706f2543Smrg        if (imageHeight > 0)
316706f2543Smrg            h = imageHeight;
317706f2543Smrg        h = safe_add(h, skipRows);
318706f2543Smrg
319706f2543Smrg        imageSize = safe_mul(h, rowSize);
320706f2543Smrg
321706f2543Smrg        return safe_mul(safe_add(d, skipImages), imageSize);
322706f2543Smrg    }
323706f2543Smrg}
324706f2543Smrg
325706f2543Smrg
326706f2543Smrg/* XXX this is used elsewhere - should it be exported from glxserver.h? */
327706f2543Smrgint __glXTypeSize(GLenum enm)
328706f2543Smrg{
329706f2543Smrg  switch(enm) {
330706f2543Smrg    case GL_BYTE:		return sizeof(GLbyte);
331706f2543Smrg    case GL_UNSIGNED_BYTE:	return sizeof(GLubyte);
332706f2543Smrg    case GL_SHORT:		return sizeof(GLshort);
333706f2543Smrg    case GL_UNSIGNED_SHORT:	return sizeof(GLushort);
334706f2543Smrg    case GL_INT:		return sizeof(GLint);
335706f2543Smrg    case GL_UNSIGNED_INT:	return sizeof(GLint);
336706f2543Smrg    case GL_FLOAT:		return sizeof(GLfloat);
337706f2543Smrg    case GL_DOUBLE:		return sizeof(GLdouble);
338706f2543Smrg    default:			return -1;
339706f2543Smrg  }
340706f2543Smrg}
341706f2543Smrg
342706f2543Smrgint __glXDrawArraysReqSize( const GLbyte *pc, Bool swap, int reqlen )
343706f2543Smrg{
344706f2543Smrg    __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
345706f2543Smrg    __GLXdispatchDrawArraysComponentHeader *compHeader;
346706f2543Smrg    GLint numVertexes = hdr->numVertexes;
347706f2543Smrg    GLint numComponents = hdr->numComponents;
348706f2543Smrg    GLint arrayElementSize = 0;
349706f2543Smrg    GLint x, size;
350706f2543Smrg    int i;
351706f2543Smrg
352706f2543Smrg    if (swap) {
353706f2543Smrg	numVertexes = SWAPL( numVertexes );
354706f2543Smrg	numComponents = SWAPL( numComponents );
355706f2543Smrg    }
356706f2543Smrg
357706f2543Smrg    pc += sizeof(__GLXdispatchDrawArraysHeader);
358706f2543Smrg    reqlen -= sizeof(__GLXdispatchDrawArraysHeader);
359706f2543Smrg
360706f2543Smrg    size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader),
361706f2543Smrg                    numComponents);
362706f2543Smrg    if (size < 0 || reqlen < 0 || reqlen < size)
363706f2543Smrg        return -1;
364706f2543Smrg
365706f2543Smrg    compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
366706f2543Smrg
367706f2543Smrg    for (i=0; i<numComponents; i++) {
368706f2543Smrg	GLenum datatype = compHeader[i].datatype;
369706f2543Smrg	GLint numVals = compHeader[i].numVals;
370706f2543Smrg	GLint component = compHeader[i].component;
371706f2543Smrg
372706f2543Smrg	if (swap) {
373706f2543Smrg	    datatype = SWAPL( datatype );
374706f2543Smrg	    numVals = SWAPL( numVals );
375706f2543Smrg	    component = SWAPL( component );
376706f2543Smrg	}
377706f2543Smrg
378706f2543Smrg	switch (component) {
379706f2543Smrg	  case GL_VERTEX_ARRAY:
380706f2543Smrg	  case GL_COLOR_ARRAY:
381706f2543Smrg	  case GL_TEXTURE_COORD_ARRAY:
382706f2543Smrg	    break;
383706f2543Smrg	  case GL_SECONDARY_COLOR_ARRAY:
384706f2543Smrg	  case GL_NORMAL_ARRAY:
385706f2543Smrg	    if (numVals != 3) {
386706f2543Smrg		/* bad size */
387706f2543Smrg		return -1;
388706f2543Smrg	    }
389706f2543Smrg	    break;
390706f2543Smrg	  case GL_FOG_COORD_ARRAY:
391706f2543Smrg	  case GL_INDEX_ARRAY:
392706f2543Smrg	    if (numVals != 1) {
393706f2543Smrg		/* bad size */
394706f2543Smrg		return -1;
395706f2543Smrg	    }
396706f2543Smrg	    break;
397706f2543Smrg	  case GL_EDGE_FLAG_ARRAY:
398706f2543Smrg	    if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) {
399706f2543Smrg		/* bad size or bad type */
400706f2543Smrg		return -1;
401706f2543Smrg	    }
402706f2543Smrg	    break;
403706f2543Smrg	  default:
404706f2543Smrg	    /* unknown component type */
405706f2543Smrg	    return -1;
406706f2543Smrg	}
407706f2543Smrg
408706f2543Smrg	arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype));
409706f2543Smrg
410706f2543Smrg	pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
411706f2543Smrg    }
412706f2543Smrg
413706f2543Smrg    return safe_add(size, safe_mul(numVertexes, arrayElementSize));
414706f2543Smrg}
415706f2543Smrg
416706f2543Smrgint __glXSeparableFilter2DReqSize( const GLbyte *pc, Bool swap, int reqlen )
417706f2543Smrg{
418706f2543Smrg    __GLXdispatchConvolutionFilterHeader *hdr =
419706f2543Smrg			(__GLXdispatchConvolutionFilterHeader *) pc;
420706f2543Smrg
421706f2543Smrg    GLint image1size, image2size;
422706f2543Smrg    GLenum format = hdr->format;
423706f2543Smrg    GLenum type = hdr->type;
424706f2543Smrg    GLint w = hdr->width;
425706f2543Smrg    GLint h = hdr->height;
426706f2543Smrg    GLint rowLength = hdr->rowLength;
427706f2543Smrg    GLint alignment = hdr->alignment;
428706f2543Smrg
429706f2543Smrg    if (swap) {
430706f2543Smrg	format = SWAPL( format );
431706f2543Smrg	type = SWAPL( type );
432706f2543Smrg	w = SWAPL( w );
433706f2543Smrg	h = SWAPL( h );
434706f2543Smrg	rowLength = SWAPL( rowLength );
435706f2543Smrg	alignment = SWAPL( alignment );
436706f2543Smrg    }
437706f2543Smrg
438706f2543Smrg    /* XXX Should rowLength be used for either or both image? */
439706f2543Smrg    image1size = __glXImageSize( format, type, 0, w, 1, 1,
440706f2543Smrg				 0, rowLength, 0, 0, alignment );
441706f2543Smrg    image2size = __glXImageSize( format, type, 0, h, 1, 1,
442706f2543Smrg				 0, rowLength, 0, 0, alignment );
443706f2543Smrg
444706f2543Smrg    return safe_add(safe_pad(image1size), image2size);
445706f2543Smrg}
446