1 /*
2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: SGI-B-2.0
6 */
7
8 #include <GL/gl.h>
9 #include "glxclient.h"
10
11 /*
12 ** Return the number of elements per group of a specified format
13 */
14 GLint
__glElementsPerGroup(GLenum format,GLenum type)15 __glElementsPerGroup(GLenum format, GLenum type)
16 {
17 /*
18 ** To make row length computation valid for image extraction,
19 ** packed pixel types assume elements per group equals one.
20 */
21 switch (type) {
22 case GL_UNSIGNED_BYTE_3_3_2:
23 case GL_UNSIGNED_BYTE_2_3_3_REV:
24 case GL_UNSIGNED_SHORT_5_6_5:
25 case GL_UNSIGNED_SHORT_5_6_5_REV:
26 case GL_UNSIGNED_SHORT_4_4_4_4:
27 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
28 case GL_UNSIGNED_SHORT_5_5_5_1:
29 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
30 case GL_UNSIGNED_SHORT_8_8_APPLE:
31 case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
32 case GL_UNSIGNED_INT_8_8_8_8:
33 case GL_UNSIGNED_INT_8_8_8_8_REV:
34 case GL_UNSIGNED_INT_10_10_10_2:
35 case GL_UNSIGNED_INT_2_10_10_10_REV:
36 case GL_UNSIGNED_INT_24_8_NV:
37 return 1;
38 default:
39 break;
40 }
41
42 switch (format) {
43 case GL_RGB:
44 case GL_BGR:
45 case GL_RGB_INTEGER_EXT:
46 case GL_BGR_INTEGER_EXT:
47 return 3;
48 case GL_RG:
49 case GL_422_EXT:
50 case GL_422_REV_EXT:
51 case GL_422_AVERAGE_EXT:
52 case GL_422_REV_AVERAGE_EXT:
53 case GL_DEPTH_STENCIL_NV:
54 case GL_YCBCR_422_APPLE:
55 case GL_LUMINANCE_ALPHA:
56 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
57 return 2;
58 case GL_RGBA:
59 case GL_BGRA:
60 case GL_ABGR_EXT:
61 case GL_RGBA_INTEGER_EXT:
62 case GL_BGRA_INTEGER_EXT:
63 return 4;
64 case GL_COLOR_INDEX:
65 case GL_STENCIL_INDEX:
66 case GL_DEPTH_COMPONENT:
67 case GL_RED:
68 case GL_GREEN:
69 case GL_BLUE:
70 case GL_ALPHA:
71 case GL_LUMINANCE:
72 case GL_INTENSITY:
73 case GL_RED_INTEGER_EXT:
74 case GL_GREEN_INTEGER_EXT:
75 case GL_BLUE_INTEGER_EXT:
76 case GL_ALPHA_INTEGER_EXT:
77 case GL_LUMINANCE_INTEGER_EXT:
78 return 1;
79 default:
80 return 0;
81 }
82 }
83
84 /*
85 ** Return the number of bytes per element, based on the element type (other
86 ** than GL_BITMAP).
87 */
88 GLint
__glBytesPerElement(GLenum type)89 __glBytesPerElement(GLenum type)
90 {
91 switch (type) {
92 case GL_UNSIGNED_SHORT:
93 case GL_SHORT:
94 case GL_UNSIGNED_SHORT_5_6_5:
95 case GL_UNSIGNED_SHORT_5_6_5_REV:
96 case GL_UNSIGNED_SHORT_4_4_4_4:
97 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
98 case GL_UNSIGNED_SHORT_5_5_5_1:
99 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
100 case GL_UNSIGNED_SHORT_8_8_APPLE:
101 case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
102 return 2;
103 case GL_UNSIGNED_BYTE:
104 case GL_BYTE:
105 case GL_UNSIGNED_BYTE_3_3_2:
106 case GL_UNSIGNED_BYTE_2_3_3_REV:
107 return 1;
108 case GL_INT:
109 case GL_UNSIGNED_INT:
110 case GL_FLOAT:
111 case GL_UNSIGNED_INT_8_8_8_8:
112 case GL_UNSIGNED_INT_8_8_8_8_REV:
113 case GL_UNSIGNED_INT_10_10_10_2:
114 case GL_UNSIGNED_INT_2_10_10_10_REV:
115 case GL_UNSIGNED_INT_24_8_NV:
116 return 4;
117 default:
118 return 0;
119 }
120 }
121
122 /*
123 ** Compute memory required for internal packed array of data of given type
124 ** and format.
125 */
126 GLint
__glImageSize(GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLenum target)127 __glImageSize(GLsizei width, GLsizei height, GLsizei depth,
128 GLenum format, GLenum type, GLenum target)
129 {
130 int bytes_per_row;
131 int components;
132
133 switch (target) {
134 case GL_PROXY_TEXTURE_1D:
135 case GL_PROXY_TEXTURE_2D:
136 case GL_PROXY_TEXTURE_3D:
137 case GL_PROXY_TEXTURE_4D_SGIS:
138 case GL_PROXY_TEXTURE_CUBE_MAP:
139 case GL_PROXY_TEXTURE_RECTANGLE_ARB:
140 case GL_PROXY_HISTOGRAM:
141 case GL_PROXY_COLOR_TABLE:
142 case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
143 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
144 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
145 case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
146 return 0;
147 }
148
149 if (width < 0 || height < 0 || depth < 0) {
150 return 0;
151 }
152
153 /*
154 ** Zero is returned if either format or type are invalid.
155 */
156 components = __glElementsPerGroup(format, type);
157 if (type == GL_BITMAP) {
158 if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
159 bytes_per_row = (width + 7) >> 3;
160 }
161 else {
162 return 0;
163 }
164 }
165 else {
166 bytes_per_row = __glBytesPerElement(type) * width;
167 }
168
169 return bytes_per_row * height * depth * components;
170 }
171