rensize.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice including the dates of first publication and
  13. * either this permission notice or a reference to
  14. * http://oss.sgi.com/projects/FreeB/
  15. * shall be included 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. * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  22. * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. *
  25. * Except as contained in this notice, the name of Silicon Graphics, Inc.
  26. * shall not be used in advertising or otherwise to promote the sale, use or
  27. * other dealings in this Software without prior written authorization from
  28. * Silicon Graphics, Inc.
  29. */
  30. #ifdef HAVE_DIX_CONFIG_H
  31. #include <dix-config.h>
  32. #endif
  33. #include <GL/gl.h>
  34. #include "glxserver.h"
  35. #include "GL/glxproto.h"
  36. #include "unpack.h"
  37. #include "indirect_size.h"
  38. #include "indirect_reqsize.h"
  39. #define SWAPL(a) \
  40. (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \
  41. ((a & 0xff00U)<<8) | ((a & 0xffU)<<24))
  42. int
  43. __glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen)
  44. {
  45. GLenum target;
  46. GLint order;
  47. target = *(GLenum *) (pc + 16);
  48. order = *(GLint *) (pc + 20);
  49. if (swap) {
  50. target = SWAPL(target);
  51. order = SWAPL(order);
  52. }
  53. if (order < 1)
  54. return -1;
  55. return safe_mul(8, safe_mul(__glMap1d_size(target), order));
  56. }
  57. int
  58. __glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen)
  59. {
  60. GLenum target;
  61. GLint order;
  62. target = *(GLenum *) (pc + 0);
  63. order = *(GLint *) (pc + 12);
  64. if (swap) {
  65. target = SWAPL(target);
  66. order = SWAPL(order);
  67. }
  68. if (order < 1)
  69. return -1;
  70. return safe_mul(4, safe_mul(__glMap1f_size(target), order));
  71. }
  72. static int
  73. Map2Size(int k, int majorOrder, int minorOrder)
  74. {
  75. if (majorOrder < 1 || minorOrder < 1)
  76. return -1;
  77. return safe_mul(k, safe_mul(majorOrder, minorOrder));
  78. }
  79. int
  80. __glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen)
  81. {
  82. GLenum target;
  83. GLint uorder, vorder;
  84. target = *(GLenum *) (pc + 32);
  85. uorder = *(GLint *) (pc + 36);
  86. vorder = *(GLint *) (pc + 40);
  87. if (swap) {
  88. target = SWAPL(target);
  89. uorder = SWAPL(uorder);
  90. vorder = SWAPL(vorder);
  91. }
  92. return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder));
  93. }
  94. int
  95. __glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen)
  96. {
  97. GLenum target;
  98. GLint uorder, vorder;
  99. target = *(GLenum *) (pc + 0);
  100. uorder = *(GLint *) (pc + 12);
  101. vorder = *(GLint *) (pc + 24);
  102. if (swap) {
  103. target = SWAPL(target);
  104. uorder = SWAPL(uorder);
  105. vorder = SWAPL(vorder);
  106. }
  107. return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder));
  108. }
  109. /**
  110. * Calculate the size of an image.
  111. *
  112. * The size of an image sent to the server from the client or sent from the
  113. * server to the client is calculated. The size is based on the dimensions
  114. * of the image, the type of pixel data, padding in the image, and the
  115. * alignment requirements of the image.
  116. *
  117. * \param format Format of the pixels. Same as the \c format parameter
  118. * to \c glTexImage1D
  119. * \param type Type of the pixel data. Same as the \c type parameter
  120. * to \c glTexImage1D
  121. * \param target Typically the texture target of the image. If the
  122. * target is one of \c GL_PROXY_*, the size returned is
  123. * always zero. For uses that do not have a texture target
  124. * (e.g, glDrawPixels), zero should be specified.
  125. * \param w Width of the image data. Must be >= 1.
  126. * \param h Height of the image data. Must be >= 1, even for 1D
  127. * images.
  128. * \param d Depth of the image data. Must be >= 1, even for 1D or
  129. * 2D images.
  130. * \param imageHeight If non-zero, defines the true height of a volumetric
  131. * image. This value will be used instead of \c h for
  132. * calculating the size of the image.
  133. * \param rowLength If non-zero, defines the true width of an image. This
  134. * value will be used instead of \c w for calculating the
  135. * size of the image.
  136. * \param skipImages Number of extra layers of image data in a volumtric
  137. * image that are to be skipped before the real data.
  138. * \param skipRows Number of extra rows of image data in an image that are
  139. * to be skipped before the real data.
  140. * \param alignment Specifies the alignment for the start of each pixel row
  141. * in memory. This value must be one of 1, 2, 4, or 8.
  142. *
  143. * \returns
  144. * The size of the image is returned. If the specified \c format and \c type
  145. * are invalid, -1 is returned. If \c target is one of \c GL_PROXY_*, zero
  146. * is returned.
  147. */
  148. int
  149. __glXImageSize(GLenum format, GLenum type, GLenum target,
  150. GLsizei w, GLsizei h, GLsizei d,
  151. GLint imageHeight, GLint rowLength,
  152. GLint skipImages, GLint skipRows, GLint alignment)
  153. {
  154. GLint bytesPerElement, elementsPerGroup, groupsPerRow;
  155. GLint groupSize, rowSize, padding, imageSize;
  156. if (w == 0 || h == 0 || d == 0)
  157. return 0;
  158. if (w < 0 || h < 0 || d < 0 ||
  159. (type == GL_BITMAP &&
  160. (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) {
  161. return -1;
  162. }
  163. /* proxy targets have no data */
  164. switch (target) {
  165. case GL_PROXY_TEXTURE_1D:
  166. case GL_PROXY_TEXTURE_2D:
  167. case GL_PROXY_TEXTURE_3D:
  168. case GL_PROXY_TEXTURE_4D_SGIS:
  169. case GL_PROXY_TEXTURE_CUBE_MAP:
  170. case GL_PROXY_TEXTURE_RECTANGLE_ARB:
  171. case GL_PROXY_HISTOGRAM:
  172. case GL_PROXY_COLOR_TABLE:
  173. case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
  174. case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
  175. case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
  176. case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
  177. return 0;
  178. }
  179. /* real data has to have real sizes */
  180. if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0)
  181. return -1;
  182. if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8)
  183. return -1;
  184. if (type == GL_BITMAP) {
  185. if (rowLength > 0) {
  186. groupsPerRow = rowLength;
  187. }
  188. else {
  189. groupsPerRow = w;
  190. }
  191. rowSize = bits_to_bytes(groupsPerRow);
  192. if (rowSize < 0)
  193. return -1;
  194. padding = (rowSize % alignment);
  195. if (padding) {
  196. rowSize += alignment - padding;
  197. }
  198. return safe_mul(safe_add(h, skipRows), rowSize);
  199. }
  200. else {
  201. switch (format) {
  202. case GL_COLOR_INDEX:
  203. case GL_STENCIL_INDEX:
  204. case GL_DEPTH_COMPONENT:
  205. case GL_RED:
  206. case GL_GREEN:
  207. case GL_BLUE:
  208. case GL_ALPHA:
  209. case GL_LUMINANCE:
  210. case GL_INTENSITY:
  211. case GL_RED_INTEGER_EXT:
  212. case GL_GREEN_INTEGER_EXT:
  213. case GL_BLUE_INTEGER_EXT:
  214. case GL_ALPHA_INTEGER_EXT:
  215. case GL_LUMINANCE_INTEGER_EXT:
  216. elementsPerGroup = 1;
  217. break;
  218. case GL_422_EXT:
  219. case GL_422_REV_EXT:
  220. case GL_422_AVERAGE_EXT:
  221. case GL_422_REV_AVERAGE_EXT:
  222. case GL_DEPTH_STENCIL_NV:
  223. case GL_DEPTH_STENCIL_MESA:
  224. case GL_YCBCR_MESA:
  225. case GL_LUMINANCE_ALPHA:
  226. case GL_LUMINANCE_ALPHA_INTEGER_EXT:
  227. elementsPerGroup = 2;
  228. break;
  229. case GL_RGB:
  230. case GL_BGR:
  231. case GL_RGB_INTEGER_EXT:
  232. case GL_BGR_INTEGER_EXT:
  233. elementsPerGroup = 3;
  234. break;
  235. case GL_RGBA:
  236. case GL_BGRA:
  237. case GL_RGBA_INTEGER_EXT:
  238. case GL_BGRA_INTEGER_EXT:
  239. case GL_ABGR_EXT:
  240. elementsPerGroup = 4;
  241. break;
  242. default:
  243. return -1;
  244. }
  245. switch (type) {
  246. case GL_UNSIGNED_BYTE:
  247. case GL_BYTE:
  248. bytesPerElement = 1;
  249. break;
  250. case GL_UNSIGNED_BYTE_3_3_2:
  251. case GL_UNSIGNED_BYTE_2_3_3_REV:
  252. bytesPerElement = 1;
  253. elementsPerGroup = 1;
  254. break;
  255. case GL_UNSIGNED_SHORT:
  256. case GL_SHORT:
  257. bytesPerElement = 2;
  258. break;
  259. case GL_UNSIGNED_SHORT_5_6_5:
  260. case GL_UNSIGNED_SHORT_5_6_5_REV:
  261. case GL_UNSIGNED_SHORT_4_4_4_4:
  262. case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  263. case GL_UNSIGNED_SHORT_5_5_5_1:
  264. case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  265. case GL_UNSIGNED_SHORT_8_8_APPLE:
  266. case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
  267. case GL_UNSIGNED_SHORT_15_1_MESA:
  268. case GL_UNSIGNED_SHORT_1_15_REV_MESA:
  269. bytesPerElement = 2;
  270. elementsPerGroup = 1;
  271. break;
  272. case GL_INT:
  273. case GL_UNSIGNED_INT:
  274. case GL_FLOAT:
  275. bytesPerElement = 4;
  276. break;
  277. case GL_UNSIGNED_INT_8_8_8_8:
  278. case GL_UNSIGNED_INT_8_8_8_8_REV:
  279. case GL_UNSIGNED_INT_10_10_10_2:
  280. case GL_UNSIGNED_INT_2_10_10_10_REV:
  281. case GL_UNSIGNED_INT_24_8_NV:
  282. case GL_UNSIGNED_INT_24_8_MESA:
  283. case GL_UNSIGNED_INT_8_24_REV_MESA:
  284. bytesPerElement = 4;
  285. elementsPerGroup = 1;
  286. break;
  287. default:
  288. return -1;
  289. }
  290. /* known safe by the switches above, not checked */
  291. groupSize = bytesPerElement * elementsPerGroup;
  292. if (rowLength > 0) {
  293. groupsPerRow = rowLength;
  294. }
  295. else {
  296. groupsPerRow = w;
  297. }
  298. if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0)
  299. return -1;
  300. padding = (rowSize % alignment);
  301. if (padding) {
  302. rowSize += alignment - padding;
  303. }
  304. if (imageHeight > 0)
  305. h = imageHeight;
  306. h = safe_add(h, skipRows);
  307. imageSize = safe_mul(h, rowSize);
  308. return safe_mul(safe_add(d, skipImages), imageSize);
  309. }
  310. }
  311. /* XXX this is used elsewhere - should it be exported from glxserver.h? */
  312. int
  313. __glXTypeSize(GLenum enm)
  314. {
  315. switch (enm) {
  316. case GL_BYTE:
  317. return sizeof(GLbyte);
  318. case GL_UNSIGNED_BYTE:
  319. return sizeof(GLubyte);
  320. case GL_SHORT:
  321. return sizeof(GLshort);
  322. case GL_UNSIGNED_SHORT:
  323. return sizeof(GLushort);
  324. case GL_INT:
  325. return sizeof(GLint);
  326. case GL_UNSIGNED_INT:
  327. return sizeof(GLint);
  328. case GL_FLOAT:
  329. return sizeof(GLfloat);
  330. case GL_DOUBLE:
  331. return sizeof(GLdouble);
  332. default:
  333. return -1;
  334. }
  335. }
  336. int
  337. __glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen)
  338. {
  339. __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc;
  340. __GLXdispatchDrawArraysComponentHeader *compHeader;
  341. GLint numVertexes = hdr->numVertexes;
  342. GLint numComponents = hdr->numComponents;
  343. GLint arrayElementSize = 0;
  344. GLint x, size;
  345. int i;
  346. if (swap) {
  347. numVertexes = SWAPL(numVertexes);
  348. numComponents = SWAPL(numComponents);
  349. }
  350. pc += sizeof(__GLXdispatchDrawArraysHeader);
  351. reqlen -= sizeof(__GLXdispatchDrawArraysHeader);
  352. size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader),
  353. numComponents);
  354. if (size < 0 || reqlen < 0 || reqlen < size)
  355. return -1;
  356. compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc;
  357. for (i = 0; i < numComponents; i++) {
  358. GLenum datatype = compHeader[i].datatype;
  359. GLint numVals = compHeader[i].numVals;
  360. GLint component = compHeader[i].component;
  361. if (swap) {
  362. datatype = SWAPL(datatype);
  363. numVals = SWAPL(numVals);
  364. component = SWAPL(component);
  365. }
  366. switch (component) {
  367. case GL_VERTEX_ARRAY:
  368. case GL_COLOR_ARRAY:
  369. case GL_TEXTURE_COORD_ARRAY:
  370. break;
  371. case GL_SECONDARY_COLOR_ARRAY:
  372. case GL_NORMAL_ARRAY:
  373. if (numVals != 3) {
  374. /* bad size */
  375. return -1;
  376. }
  377. break;
  378. case GL_FOG_COORD_ARRAY:
  379. case GL_INDEX_ARRAY:
  380. if (numVals != 1) {
  381. /* bad size */
  382. return -1;
  383. }
  384. break;
  385. case GL_EDGE_FLAG_ARRAY:
  386. if ((numVals != 1) && (datatype != GL_UNSIGNED_BYTE)) {
  387. /* bad size or bad type */
  388. return -1;
  389. }
  390. break;
  391. default:
  392. /* unknown component type */
  393. return -1;
  394. }
  395. x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype)));
  396. if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0)
  397. return -1;
  398. pc += sizeof(__GLXdispatchDrawArraysComponentHeader);
  399. }
  400. return safe_add(size, safe_mul(numVertexes, arrayElementSize));
  401. }
  402. int
  403. __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen)
  404. {
  405. __GLXdispatchConvolutionFilterHeader *hdr =
  406. (__GLXdispatchConvolutionFilterHeader *) pc;
  407. GLint image1size, image2size;
  408. GLenum format = hdr->format;
  409. GLenum type = hdr->type;
  410. GLint w = hdr->width;
  411. GLint h = hdr->height;
  412. GLint rowLength = hdr->rowLength;
  413. GLint alignment = hdr->alignment;
  414. if (swap) {
  415. format = SWAPL(format);
  416. type = SWAPL(type);
  417. w = SWAPL(w);
  418. h = SWAPL(h);
  419. rowLength = SWAPL(rowLength);
  420. alignment = SWAPL(alignment);
  421. }
  422. /* XXX Should rowLength be used for either or both image? */
  423. image1size = __glXImageSize(format, type, 0, w, 1, 1,
  424. 0, rowLength, 0, 0, alignment);
  425. image2size = __glXImageSize(format, type, 0, h, 1, 1,
  426. 0, rowLength, 0, 0, alignment);
  427. return safe_add(safe_pad(image1size), image2size);
  428. }