Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

982 lines
25 KiB

5 years ago
  1. /*
  2. ** Copyright 1992, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. ** $Revision: 1.4 $
  18. ** $Date: 1996/03/29 01:55:31 $
  19. */
  20. #ifdef NT
  21. #include <glos.h>
  22. #endif
  23. #include <assert.h>
  24. #include "gluint.h"
  25. #include <GL/glu.h>
  26. #include <stdio.h>
  27. #ifdef NT
  28. #include "winmem.h"
  29. #else
  30. #include <stdlib.h>
  31. #endif
  32. #include <string.h>
  33. #include <math.h>
  34. typedef union {
  35. unsigned char ub[4];
  36. unsigned short us[2];
  37. unsigned long ui;
  38. char b[4];
  39. short s[2];
  40. long i;
  41. float f;
  42. } Type_Widget;
  43. /* Pixel storage modes */
  44. typedef struct {
  45. GLint pack_alignment;
  46. GLint pack_row_length;
  47. GLint pack_skip_rows;
  48. GLint pack_skip_pixels;
  49. GLint pack_lsb_first;
  50. GLint pack_swap_bytes;
  51. GLint unpack_alignment;
  52. GLint unpack_row_length;
  53. GLint unpack_skip_rows;
  54. GLint unpack_skip_pixels;
  55. GLint unpack_lsb_first;
  56. GLint unpack_swap_bytes;
  57. } PixelStorageModes;
  58. /*
  59. * internal function declarations
  60. */
  61. static GLfloat bytes_per_element(GLenum type);
  62. static GLint elements_per_group(GLenum format);
  63. #ifdef NT
  64. static GLboolean is_index(GLenum format);
  65. #else
  66. static GLint is_index(GLenum format);
  67. #endif
  68. static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
  69. static void fill_image(const PixelStorageModes *,
  70. GLint width, GLint height, GLenum format,
  71. GLenum type, GLboolean index_format,
  72. const void *userdata, GLushort *newimage);
  73. static void empty_image(const PixelStorageModes *,
  74. GLint width, GLint height, GLenum format,
  75. GLenum type, GLboolean index_format,
  76. const GLushort *oldimage, void *userdata);
  77. static void scale_internal(GLint components, GLint widthin, GLint heightin,
  78. const GLushort *datain,
  79. GLint widthout, GLint heightout,
  80. GLushort *dataout);
  81. static void retrieveStoreModes(PixelStorageModes *psm)
  82. {
  83. glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
  84. glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
  85. glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
  86. glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
  87. glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
  88. glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
  89. glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
  90. glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
  91. glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
  92. glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
  93. glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
  94. glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
  95. }
  96. static int computeLog(GLuint value)
  97. {
  98. int i;
  99. i = 0;
  100. /* Error! */
  101. if (value == 0) return -1;
  102. for (;;) {
  103. if (value & 1) {
  104. /* Error ! */
  105. if (value != 1) return -1;
  106. return i;
  107. }
  108. value = value >> 1;
  109. i++;
  110. }
  111. }
  112. /*
  113. ** Compute the nearest power of 2 number. This algorithm is a little
  114. ** strange, but it works quite well.
  115. */
  116. static int nearestPower(GLuint value)
  117. {
  118. int i;
  119. i = 1;
  120. /* Error! */
  121. if (value == 0) return -1;
  122. for (;;) {
  123. if (value == 1) {
  124. return i;
  125. } else if (value == 3) {
  126. return i*4;
  127. }
  128. value = value >> 1;
  129. i *= 2;
  130. }
  131. }
  132. static void halveImage(GLint components, GLuint width, GLuint height,
  133. const GLushort *datain, GLushort *dataout)
  134. {
  135. int i, j, k;
  136. int newwidth, newheight;
  137. int delta;
  138. GLushort *s;
  139. const GLushort *t;
  140. newwidth = width / 2;
  141. newheight = height / 2;
  142. delta = width * components;
  143. s = dataout;
  144. t = datain;
  145. /* Piece o' cake! */
  146. for (i = 0; i < newheight; i++) {
  147. for (j = 0; j < newwidth; j++) {
  148. for (k = 0; k < components; k++) {
  149. s[0] = (t[0] + t[components] + t[delta] +
  150. t[delta+components] + 2) / 4;
  151. s++; t++;
  152. }
  153. t += components;
  154. }
  155. t += delta;
  156. }
  157. }
  158. static void scale_internal(GLint components, GLint widthin, GLint heightin,
  159. const GLushort *datain,
  160. GLint widthout, GLint heightout,
  161. GLushort *dataout)
  162. {
  163. float x, lowx, highx, convx, halfconvx;
  164. float y, lowy, highy, convy, halfconvy;
  165. float xpercent,ypercent;
  166. float percent;
  167. /* Max components in a format is 4, so... */
  168. float totals[4];
  169. float area;
  170. int i,j,k,yint,xint,xindex,yindex;
  171. int temp;
  172. if (widthin == widthout*2 && heightin == heightout*2) {
  173. halveImage(components, widthin, heightin, datain, dataout);
  174. return;
  175. }
  176. convy = (float) heightin/heightout;
  177. convx = (float) widthin/widthout;
  178. halfconvx = convx/2;
  179. halfconvy = convy/2;
  180. for (i = 0; i < heightout; i++) {
  181. y = convy * (i+0.5);
  182. if (heightin > heightout) {
  183. highy = y + halfconvy;
  184. lowy = y - halfconvy;
  185. } else {
  186. highy = y + 0.5;
  187. lowy = y - 0.5;
  188. }
  189. for (j = 0; j < widthout; j++) {
  190. x = convx * (j+0.5);
  191. if (widthin > widthout) {
  192. highx = x + halfconvx;
  193. lowx = x - halfconvx;
  194. } else {
  195. highx = x + 0.5;
  196. lowx = x - 0.5;
  197. }
  198. /*
  199. ** Ok, now apply box filter to box that goes from (lowx, lowy)
  200. ** to (highx, highy) on input data into this pixel on output
  201. ** data.
  202. */
  203. totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
  204. area = 0.0;
  205. y = lowy;
  206. yint = floor(y);
  207. while (y < highy) {
  208. yindex = (yint + heightin) % heightin;
  209. if (highy < yint+1) {
  210. ypercent = highy - y;
  211. } else {
  212. ypercent = yint+1 - y;
  213. }
  214. x = lowx;
  215. xint = floor(x);
  216. while (x < highx) {
  217. xindex = (xint + widthin) % widthin;
  218. if (highx < xint+1) {
  219. xpercent = highx - x;
  220. } else {
  221. xpercent = xint+1 - x;
  222. }
  223. percent = xpercent * ypercent;
  224. area += percent;
  225. temp = (xindex + (yindex * widthin)) * components;
  226. for (k = 0; k < components; k++) {
  227. totals[k] += datain[temp + k] * percent;
  228. }
  229. xint++;
  230. x = xint;
  231. }
  232. yint++;
  233. y = yint;
  234. }
  235. temp = (j + (i * widthout)) * components;
  236. for (k = 0; k < components; k++) {
  237. dataout[temp + k] = totals[k]/area;
  238. }
  239. }
  240. }
  241. }
  242. static GLboolean legalFormat(GLenum format)
  243. {
  244. switch(format) {
  245. case GL_COLOR_INDEX:
  246. case GL_STENCIL_INDEX:
  247. case GL_DEPTH_COMPONENT:
  248. case GL_RED:
  249. case GL_GREEN:
  250. case GL_BLUE:
  251. case GL_ALPHA:
  252. case GL_RGB:
  253. case GL_RGBA:
  254. #ifdef GL_EXT_bgra
  255. case GL_BGR_EXT:
  256. case GL_BGRA_EXT:
  257. #endif
  258. case GL_LUMINANCE:
  259. case GL_LUMINANCE_ALPHA:
  260. return GL_TRUE;
  261. default:
  262. return GL_FALSE;
  263. }
  264. }
  265. static GLboolean legalType(GLenum type)
  266. {
  267. switch(type) {
  268. case GL_BITMAP:
  269. case GL_BYTE:
  270. case GL_UNSIGNED_BYTE:
  271. case GL_SHORT:
  272. case GL_UNSIGNED_SHORT:
  273. case GL_INT:
  274. case GL_UNSIGNED_INT:
  275. case GL_FLOAT:
  276. return GL_TRUE;
  277. default:
  278. return GL_FALSE;
  279. }
  280. }
  281. GLint gluScaleImage(GLenum format, GLint widthin, GLint heightin,
  282. GLenum typein, const void *datain,
  283. GLint widthout, GLint heightout, GLenum typeout,
  284. void *dataout)
  285. {
  286. int components;
  287. GLushort *beforeImage;
  288. GLushort *afterImage;
  289. PixelStorageModes psm;
  290. if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
  291. return 0;
  292. }
  293. if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
  294. return GLU_INVALID_VALUE;
  295. }
  296. if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
  297. return GLU_INVALID_ENUM;
  298. }
  299. beforeImage =
  300. malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
  301. afterImage =
  302. malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
  303. if (beforeImage == NULL || afterImage == NULL) {
  304. return GLU_OUT_OF_MEMORY;
  305. }
  306. retrieveStoreModes(&psm);
  307. fill_image(&psm,widthin, heightin, format, typein, is_index(format),
  308. datain, beforeImage);
  309. components = elements_per_group(format);
  310. scale_internal(components, widthin, heightin, beforeImage,
  311. widthout, heightout, afterImage);
  312. empty_image(&psm,widthout, heightout, format, typeout,
  313. is_index(format), afterImage, dataout);
  314. free((GLbyte *) beforeImage);
  315. free((GLbyte *) afterImage);
  316. return 0;
  317. }
  318. GLint gluBuild1DMipmaps(GLenum target, GLint components, GLint width,
  319. GLenum format, GLenum type, const void *data)
  320. {
  321. GLint newwidth;
  322. GLint level, levels;
  323. GLushort *newImage;
  324. GLint newImage_width;
  325. GLushort *otherImage;
  326. GLushort *imageTemp;
  327. GLint memreq;
  328. GLint maxsize;
  329. GLint cmpts;
  330. PixelStorageModes psm;
  331. if (width < 1) {
  332. return GLU_INVALID_VALUE;
  333. }
  334. if (!legalFormat(format) || !legalType(type)) {
  335. return GLU_INVALID_ENUM;
  336. }
  337. if (format == GL_STENCIL_INDEX) {
  338. return GLU_INVALID_ENUM;
  339. }
  340. if (format == GL_DEPTH_COMPONENT) {
  341. return GLU_INVALID_ENUM;
  342. }
  343. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
  344. retrieveStoreModes(&psm);
  345. newwidth = nearestPower(width);
  346. if (newwidth > maxsize) newwidth = maxsize;
  347. levels = computeLog(newwidth);
  348. otherImage = NULL;
  349. newImage = (GLushort *)
  350. malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
  351. newImage_width = width;
  352. if (newImage == NULL) {
  353. return GLU_OUT_OF_MEMORY;
  354. }
  355. fill_image(&psm,width, 1, format, type, is_index(format),
  356. data, newImage);
  357. cmpts = elements_per_group(format);
  358. glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
  359. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  360. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  361. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  362. /*
  363. ** If swap_bytes was set, swapping occurred in fill_image.
  364. */
  365. glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  366. for (level = 0; level <= levels; level++) {
  367. if (newImage_width == newwidth) {
  368. /* Use newImage for this level */
  369. glTexImage1D(target, level, components, newImage_width,
  370. 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
  371. } else {
  372. if (otherImage == NULL) {
  373. memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
  374. otherImage = (GLushort *) malloc(memreq);
  375. if (otherImage == NULL) {
  376. glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  377. glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  378. glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
  379. glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  380. glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  381. return GLU_OUT_OF_MEMORY;
  382. }
  383. }
  384. scale_internal(cmpts, newImage_width, 1, newImage,
  385. newwidth, 1, otherImage);
  386. /* Swap newImage and otherImage */
  387. imageTemp = otherImage;
  388. otherImage = newImage;
  389. newImage = imageTemp;
  390. newImage_width = newwidth;
  391. glTexImage1D(target, level, components, newImage_width,
  392. 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
  393. }
  394. if (newwidth > 1) newwidth /= 2;
  395. }
  396. glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  397. glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  398. glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  399. glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  400. glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  401. free((GLbyte *) newImage);
  402. if (otherImage) {
  403. free((GLbyte *) otherImage);
  404. }
  405. return 0;
  406. }
  407. GLint gluBuild2DMipmaps(GLenum target, GLint components, GLint width,
  408. GLint height, GLenum format,
  409. GLenum type, const void *data)
  410. {
  411. GLint newwidth, newheight;
  412. GLint level, levels;
  413. GLushort *newImage;
  414. GLint newImage_width;
  415. GLint newImage_height;
  416. GLushort *otherImage;
  417. GLushort *imageTemp;
  418. GLint memreq;
  419. GLint maxsize;
  420. GLint cmpts;
  421. PixelStorageModes psm;
  422. if (width < 1 || height < 1) {
  423. return GLU_INVALID_VALUE;
  424. }
  425. if (!legalFormat(format) || !legalType(type)) {
  426. return GLU_INVALID_ENUM;
  427. }
  428. if (format == GL_STENCIL_INDEX) {
  429. return GLU_INVALID_ENUM;
  430. }
  431. if (format == GL_DEPTH_COMPONENT) {
  432. return GLU_INVALID_ENUM;
  433. }
  434. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
  435. retrieveStoreModes(&psm);
  436. newwidth = nearestPower(width);
  437. if (newwidth > maxsize) newwidth = maxsize;
  438. newheight = nearestPower(height);
  439. if (newheight > maxsize) newheight = maxsize;
  440. levels = computeLog(newwidth);
  441. level = computeLog(newheight);
  442. if (level > levels) levels=level;
  443. otherImage = NULL;
  444. newImage = (GLushort *)
  445. malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
  446. newImage_width = width;
  447. newImage_height = height;
  448. if (newImage == NULL) {
  449. return GLU_OUT_OF_MEMORY;
  450. }
  451. fill_image(&psm,width, height, format, type, is_index(format),
  452. data, newImage);
  453. cmpts = elements_per_group(format);
  454. glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
  455. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  456. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  457. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  458. /*
  459. ** If swap_bytes was set, swapping occurred in fill_image.
  460. */
  461. glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  462. for (level = 0; level <= levels; level++) {
  463. if (newImage_width == newwidth && newImage_height == newheight) {
  464. /* Use newImage for this level */
  465. glTexImage2D(target, level, components, newImage_width,
  466. newImage_height, 0, format, GL_UNSIGNED_SHORT,
  467. (void *) newImage);
  468. } else {
  469. if (otherImage == NULL) {
  470. memreq =
  471. image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
  472. otherImage = (GLushort *) malloc(memreq);
  473. if (otherImage == NULL) {
  474. glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  475. glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  476. glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  477. glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  478. glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  479. return GLU_OUT_OF_MEMORY;
  480. }
  481. }
  482. scale_internal(cmpts, newImage_width, newImage_height, newImage,
  483. newwidth, newheight, otherImage);
  484. /* Swap newImage and otherImage */
  485. imageTemp = otherImage;
  486. otherImage = newImage;
  487. newImage = imageTemp;
  488. newImage_width = newwidth;
  489. newImage_height = newheight;
  490. glTexImage2D(target, level, components, newImage_width,
  491. newImage_height, 0, format, GL_UNSIGNED_SHORT,
  492. (void *) newImage);
  493. }
  494. if (newwidth > 1) newwidth /= 2;
  495. if (newheight > 1) newheight /= 2;
  496. }
  497. glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
  498. glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
  499. glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
  500. glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
  501. glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
  502. free((GLbyte *) newImage);
  503. if (otherImage) {
  504. free((GLbyte *) otherImage);
  505. }
  506. return 0;
  507. }
  508. /*
  509. * Utility Routines
  510. */
  511. static GLint elements_per_group(GLenum format)
  512. {
  513. /*
  514. * Return the number of elements per group of a specified format
  515. */
  516. switch(format) {
  517. case GL_RGB:
  518. #ifdef GL_EXT_bgra
  519. case GL_BGR_EXT:
  520. #endif
  521. return 3;
  522. case GL_LUMINANCE_ALPHA:
  523. return 2;
  524. case GL_RGBA:
  525. #ifdef GL_EXT_bgra
  526. case GL_BGRA_EXT:
  527. #endif
  528. return 4;
  529. default:
  530. return 1;
  531. }
  532. }
  533. static GLfloat bytes_per_element(GLenum type)
  534. {
  535. /*
  536. * Return the number of bytes per element, based on the element type
  537. */
  538. switch(type) {
  539. case GL_BITMAP:
  540. return 1.0 / 8.0;
  541. case GL_UNSIGNED_SHORT:
  542. case GL_SHORT:
  543. return 2;
  544. case GL_UNSIGNED_BYTE:
  545. case GL_BYTE:
  546. return 1;
  547. case GL_INT:
  548. case GL_UNSIGNED_INT:
  549. case GL_FLOAT:
  550. default:
  551. return 4;
  552. }
  553. }
  554. #ifdef NT
  555. static GLboolean is_index(GLenum format)
  556. #else
  557. static GLint is_index(GLenum format)
  558. #endif
  559. {
  560. return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
  561. }
  562. /*
  563. ** Compute memory required for internal packed array of data of given type
  564. ** and format.
  565. */
  566. static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
  567. {
  568. int bytes_per_row;
  569. int components;
  570. assert(width > 0);
  571. assert(height > 0);
  572. components = elements_per_group(format);
  573. if (type == GL_BITMAP) {
  574. bytes_per_row = (width + 7) / 8;
  575. } else {
  576. bytes_per_row = bytes_per_element(type) * width;
  577. }
  578. return bytes_per_row * height * components;
  579. }
  580. /*
  581. ** Extract array from user's data applying all pixel store modes.
  582. ** The internal format used is an array of unsigned shorts.
  583. */
  584. static void fill_image(const PixelStorageModes *psm,
  585. GLint width, GLint height, GLenum format,
  586. GLenum type, GLboolean index_format,
  587. const void *userdata, GLushort *newimage)
  588. {
  589. GLint components;
  590. GLint element_size;
  591. GLint rowsize;
  592. GLint padding;
  593. GLint groups_per_line;
  594. GLint group_size;
  595. GLint elements_per_line;
  596. const GLubyte *start;
  597. const GLubyte *iter;
  598. GLushort *iter2;
  599. GLint i, j, k;
  600. GLint myswap_bytes;
  601. myswap_bytes = psm->unpack_swap_bytes;
  602. components = elements_per_group(format);
  603. if (psm->unpack_row_length > 0) {
  604. groups_per_line = psm->unpack_row_length;
  605. } else {
  606. groups_per_line = width;
  607. }
  608. /* All formats except GL_BITMAP fall out trivially */
  609. if (type == GL_BITMAP) {
  610. GLint bit_offset;
  611. GLint current_bit;
  612. rowsize = (groups_per_line * components + 7) / 8;
  613. padding = (rowsize % psm->unpack_alignment);
  614. if (padding) {
  615. rowsize += psm->unpack_alignment - padding;
  616. }
  617. start = (GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
  618. (psm->unpack_skip_pixels * components / 8);
  619. elements_per_line = width * components;
  620. iter2 = newimage;
  621. for (i = 0; i < height; i++) {
  622. iter = start;
  623. bit_offset = (psm->unpack_skip_pixels * components) % 8;
  624. for (j = 0; j < elements_per_line; j++) {
  625. /* Retrieve bit */
  626. if (psm->unpack_lsb_first) {
  627. current_bit = iter[0] & (1 << bit_offset);
  628. } else {
  629. current_bit = iter[0] & (1 << (7 - bit_offset));
  630. }
  631. if (current_bit) {
  632. if (index_format) {
  633. *iter2 = 1;
  634. } else {
  635. *iter2 = 65535;
  636. }
  637. } else {
  638. *iter2 = 0;
  639. }
  640. bit_offset++;
  641. if (bit_offset == 8) {
  642. bit_offset = 0;
  643. iter++;
  644. }
  645. iter2++;
  646. }
  647. start += rowsize;
  648. }
  649. } else {
  650. element_size = bytes_per_element(type);
  651. group_size = element_size * components;
  652. if (element_size == 1) myswap_bytes = 0;
  653. rowsize = groups_per_line * group_size;
  654. padding = (rowsize % psm->unpack_alignment);
  655. if (padding) {
  656. rowsize += psm->unpack_alignment - padding;
  657. }
  658. start = (GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
  659. psm->unpack_skip_pixels * group_size;
  660. elements_per_line = width * components;
  661. iter2 = newimage;
  662. for (i = 0; i < height; i++) {
  663. iter = start;
  664. for (j = 0; j < elements_per_line; j++) {
  665. Type_Widget widget;
  666. switch(type) {
  667. case GL_UNSIGNED_BYTE:
  668. if (index_format) {
  669. *iter2 = *iter;
  670. } else {
  671. *iter2 = (*iter) * 257;
  672. }
  673. break;
  674. case GL_BYTE:
  675. if (index_format) {
  676. *iter2 = *((GLbyte *) iter);
  677. } else {
  678. /* rough approx */
  679. *iter2 = (*((GLbyte *) iter)) * 516;
  680. }
  681. break;
  682. case GL_UNSIGNED_SHORT:
  683. case GL_SHORT:
  684. if (myswap_bytes) {
  685. widget.ub[0] = iter[1];
  686. widget.ub[1] = iter[0];
  687. } else {
  688. widget.ub[0] = iter[0];
  689. widget.ub[1] = iter[1];
  690. }
  691. if (type == GL_SHORT) {
  692. if (index_format) {
  693. *iter2 = widget.s[0];
  694. } else {
  695. /* rough approx */
  696. *iter2 = widget.s[0]*2;
  697. }
  698. } else {
  699. *iter2 = widget.us[0];
  700. }
  701. break;
  702. case GL_INT:
  703. case GL_UNSIGNED_INT:
  704. case GL_FLOAT:
  705. if (myswap_bytes) {
  706. widget.ub[0] = iter[3];
  707. widget.ub[1] = iter[2];
  708. widget.ub[2] = iter[1];
  709. widget.ub[3] = iter[0];
  710. } else {
  711. widget.ub[0] = iter[0];
  712. widget.ub[1] = iter[1];
  713. widget.ub[2] = iter[2];
  714. widget.ub[3] = iter[3];
  715. }
  716. if (type == GL_FLOAT) {
  717. if (index_format) {
  718. *iter2 = widget.f;
  719. } else {
  720. *iter2 = 65535 * widget.f;
  721. }
  722. } else if (type == GL_UNSIGNED_INT) {
  723. if (index_format) {
  724. *iter2 = widget.ui;
  725. } else {
  726. *iter2 = widget.ui >> 16;
  727. }
  728. } else {
  729. if (index_format) {
  730. *iter2 = widget.i;
  731. } else {
  732. *iter2 = widget.i >> 15;
  733. }
  734. }
  735. break;
  736. }
  737. iter += element_size;
  738. iter2++;
  739. }
  740. start += rowsize;
  741. }
  742. }
  743. }
  744. /*
  745. ** Insert array into user's data applying all pixel store modes.
  746. ** The internal format is an array of unsigned shorts.
  747. ** empty_image() because it is the opposite of fill_image().
  748. */
  749. static void empty_image(const PixelStorageModes *psm,
  750. GLint width, GLint height, GLenum format,
  751. GLenum type, GLboolean index_format,
  752. const GLushort *oldimage, void *userdata)
  753. {
  754. GLint components;
  755. GLint element_size;
  756. GLint rowsize;
  757. GLint padding;
  758. GLint groups_per_line;
  759. GLint group_size;
  760. GLint elements_per_line;
  761. GLubyte *start;
  762. GLubyte *iter;
  763. const GLushort *iter2;
  764. GLint i, j, k;
  765. GLint myswap_bytes;
  766. myswap_bytes = psm->pack_swap_bytes;
  767. components = elements_per_group(format);
  768. if (psm->pack_row_length > 0) {
  769. groups_per_line = psm->pack_row_length;
  770. } else {
  771. groups_per_line = width;
  772. }
  773. /* All formats except GL_BITMAP fall out trivially */
  774. if (type == GL_BITMAP) {
  775. GLint bit_offset;
  776. GLint current_bit;
  777. rowsize = (groups_per_line * components + 7) / 8;
  778. padding = (rowsize % psm->pack_alignment);
  779. if (padding) {
  780. rowsize += psm->pack_alignment - padding;
  781. }
  782. start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
  783. (psm->pack_skip_pixels * components / 8);
  784. elements_per_line = width * components;
  785. iter2 = oldimage;
  786. for (i = 0; i < height; i++) {
  787. iter = start;
  788. bit_offset = (psm->pack_skip_pixels * components) % 8;
  789. for (j = 0; j < elements_per_line; j++) {
  790. if (index_format) {
  791. current_bit = iter2[0] & 1;
  792. } else {
  793. if (iter2[0] > 32767) {
  794. current_bit = 1;
  795. } else {
  796. current_bit = 0;
  797. }
  798. }
  799. if (current_bit) {
  800. if (psm->pack_lsb_first) {
  801. *iter |= (1 << bit_offset);
  802. } else {
  803. *iter |= (1 << (7 - bit_offset));
  804. }
  805. } else {
  806. if (psm->pack_lsb_first) {
  807. *iter &= ~(1 << bit_offset);
  808. } else {
  809. *iter &= ~(1 << (7 - bit_offset));
  810. }
  811. }
  812. bit_offset++;
  813. if (bit_offset == 8) {
  814. bit_offset = 0;
  815. iter++;
  816. }
  817. iter2++;
  818. }
  819. start += rowsize;
  820. }
  821. } else {
  822. element_size = bytes_per_element(type);
  823. group_size = element_size * components;
  824. if (element_size == 1) myswap_bytes = 0;
  825. rowsize = groups_per_line * group_size;
  826. padding = (rowsize % psm->pack_alignment);
  827. if (padding) {
  828. rowsize += psm->pack_alignment - padding;
  829. }
  830. start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
  831. psm->pack_skip_pixels * group_size;
  832. elements_per_line = width * components;
  833. iter2 = oldimage;
  834. for (i = 0; i < height; i++) {
  835. iter = start;
  836. for (j = 0; j < elements_per_line; j++) {
  837. Type_Widget widget;
  838. switch(type) {
  839. case GL_UNSIGNED_BYTE:
  840. if (index_format) {
  841. *iter = *iter2;
  842. } else {
  843. *iter = *iter2 >> 8;
  844. }
  845. break;
  846. case GL_BYTE:
  847. if (index_format) {
  848. *((GLbyte *) iter) = *iter2;
  849. } else {
  850. *((GLbyte *) iter) = *iter2 >> 9;
  851. }
  852. break;
  853. case GL_UNSIGNED_SHORT:
  854. case GL_SHORT:
  855. if (type == GL_SHORT) {
  856. if (index_format) {
  857. widget.s[0] = *iter2;
  858. } else {
  859. widget.s[0] = *iter2 >> 1;
  860. }
  861. } else {
  862. widget.us[0] = *iter2;
  863. }
  864. if (myswap_bytes) {
  865. iter[0] = widget.ub[1];
  866. iter[1] = widget.ub[0];
  867. } else {
  868. iter[0] = widget.ub[0];
  869. iter[1] = widget.ub[1];
  870. }
  871. break;
  872. case GL_INT:
  873. case GL_UNSIGNED_INT:
  874. case GL_FLOAT:
  875. if (type == GL_FLOAT) {
  876. if (index_format) {
  877. widget.f = *iter2;
  878. } else {
  879. widget.f = *iter2 / (float) 65535.0;
  880. }
  881. } else if (type == GL_UNSIGNED_INT) {
  882. if (index_format) {
  883. widget.ui = *iter2;
  884. } else {
  885. widget.ui = (unsigned int) *iter2 * 65537;
  886. }
  887. } else {
  888. if (index_format) {
  889. widget.i = *iter2;
  890. } else {
  891. widget.i = ((unsigned int) *iter2 * 65537)/2;
  892. }
  893. }
  894. if (myswap_bytes) {
  895. iter[3] = widget.ub[0];
  896. iter[2] = widget.ub[1];
  897. iter[1] = widget.ub[2];
  898. iter[0] = widget.ub[3];
  899. } else {
  900. iter[0] = widget.ub[0];
  901. iter[1] = widget.ub[1];
  902. iter[2] = widget.ub[2];
  903. iter[3] = widget.ub[3];
  904. }
  905. break;
  906. }
  907. iter += element_size;
  908. iter2++;
  909. }
  910. start += rowsize;
  911. }
  912. }
  913. }