Source code of Windows XP (NT5)
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.

463 lines
13 KiB

  1. /*
  2. ** Copyright 1991,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. */
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #ifdef GL_EXT_paletted_texture
  21. GLboolean __glCheckColorTableArgs(__GLcontext *gc, GLenum format, GLenum type)
  22. {
  23. switch (format)
  24. {
  25. case GL_RED:
  26. case GL_GREEN: case GL_BLUE:
  27. case GL_ALPHA: case GL_RGB:
  28. case GL_RGBA:
  29. #ifdef GL_EXT_bgra
  30. case GL_BGRA_EXT:
  31. case GL_BGR_EXT:
  32. #endif
  33. break;
  34. default:
  35. bad_enum:
  36. __glSetError(GL_INVALID_ENUM);
  37. return GL_FALSE;
  38. }
  39. switch (type) {
  40. case GL_BYTE:
  41. case GL_UNSIGNED_BYTE:
  42. case GL_SHORT:
  43. case GL_UNSIGNED_SHORT:
  44. case GL_INT:
  45. case GL_UNSIGNED_INT:
  46. case GL_FLOAT:
  47. break;
  48. default:
  49. goto bad_enum;
  50. }
  51. return GL_TRUE;
  52. }
  53. void APIPRIVATE __glim_ColorTableEXT(GLenum target,
  54. GLenum internalFormat, GLsizei width,
  55. GLenum format, GLenum type,
  56. const GLvoid *data, GLboolean _IsDlist)
  57. {
  58. __GLtexture *tex;
  59. GLint level;
  60. __GLpixelSpanInfo spanInfo;
  61. GLenum baseFormat;
  62. RGBQUAD *newData;
  63. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  64. switch(internalFormat)
  65. {
  66. case GL_RGB: case 3:
  67. case GL_R3_G3_B2: case GL_RGB4:
  68. case GL_RGB5: case GL_RGB8:
  69. case GL_RGB10: case GL_RGB12:
  70. case GL_RGB16:
  71. baseFormat = GL_RGB;
  72. break;
  73. case GL_RGBA: case 4:
  74. case GL_RGBA2: case GL_RGBA4:
  75. case GL_RGBA8: case GL_RGB5_A1:
  76. case GL_RGBA12: case GL_RGBA16:
  77. case GL_RGB10_A2:
  78. baseFormat = GL_RGBA;
  79. break;
  80. default:
  81. __glSetError(GL_INVALID_ENUM);
  82. return;
  83. }
  84. // width must be a positive power of two greater than zero
  85. if (width <= 0 || (width & (width-1)) != 0)
  86. {
  87. __glSetError(GL_INVALID_VALUE);
  88. return;
  89. }
  90. if (!__glCheckColorTableArgs(gc, format, type))
  91. {
  92. return;
  93. }
  94. tex = __glLookUpTexture(gc, target);
  95. if (target == GL_PROXY_TEXTURE_1D ||
  96. target == GL_PROXY_TEXTURE_2D)
  97. {
  98. // Consider - How do MCD's indicate their palette support?
  99. // We're only in this case if it's a legal proxy target value
  100. // so there's no need to do a real check
  101. ASSERTOPENGL(tex != NULL, "Invalid proxy target");
  102. tex->paletteRequestedFormat = internalFormat;
  103. tex->paletteTotalSize = width;
  104. tex->paletteSize = tex->paletteTotalSize;
  105. // Proxies have no data so there's no need to do any more
  106. return;
  107. }
  108. if (data == NULL)
  109. {
  110. return;
  111. }
  112. if (tex == NULL)
  113. {
  114. __glSetError(GL_INVALID_ENUM);
  115. return;
  116. }
  117. // Allocate palette storage
  118. newData = GCREALLOC(gc, tex->paletteTotalData, sizeof(RGBQUAD)*width);
  119. if (newData == NULL)
  120. {
  121. return;
  122. }
  123. tex->paletteBaseFormat = baseFormat;
  124. tex->paletteRequestedFormat = internalFormat;
  125. tex->paletteTotalSize = width;
  126. __glSetPaletteSubdivision(tex, tex->paletteTotalSize);
  127. tex->paletteTotalData = newData;
  128. tex->paletteData = tex->paletteTotalData;
  129. // This routine can be called on any kind of texture, not necessarily
  130. // color-indexed ones. If it is a color-index texture then we
  131. // need to set the appropriate baseFormat and extract procs
  132. // according to the palette data
  133. if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT ||
  134. tex->level[0].internalFormat == GL_COLOR_INDEX16_EXT)
  135. {
  136. for (level = 0; level < gc->constants.maxMipMapLevel; level++)
  137. {
  138. tex->level[level].baseFormat = tex->paletteBaseFormat;
  139. // Pick proper extraction proc
  140. if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT)
  141. {
  142. __glSetPaletteLevelExtract8(tex, &tex->level[level],
  143. tex->level[level].border);
  144. }
  145. else
  146. {
  147. ASSERTOPENGL(tex->level[0].internalFormat ==
  148. GL_COLOR_INDEX16_EXT,
  149. "Unexpected internalFormat\n");
  150. __glSetPaletteLevelExtract16(tex, &tex->level[level],
  151. tex->level[level].border);
  152. }
  153. }
  154. // We need to repick the texture procs because the baseFormat
  155. // field has changed
  156. __GL_DELAY_VALIDATE(gc);
  157. }
  158. // Copy user palette data into BGRA form
  159. spanInfo.dstImage = tex->paletteTotalData;
  160. __glInitTextureUnpack(gc, &spanInfo, width, 1, format, type, data,
  161. GL_BGRA_EXT, _IsDlist);
  162. __glInitUnpacker(gc, &spanInfo);
  163. __glInitPacker(gc, &spanInfo);
  164. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  165. // Don't update the optimized palette unless it would actually
  166. // get used
  167. if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT ||
  168. tex->level[0].internalFormat == GL_COLOR_INDEX16_EXT)
  169. {
  170. __GLtextureObject *pto;
  171. pto = __glLookUpTextureObject(gc, target);
  172. __glGenUpdateTexturePalette(gc, tex, pto->loadKey,
  173. 0, tex->paletteTotalSize);
  174. }
  175. }
  176. void APIPRIVATE __glim_ColorSubTableEXT(GLenum target, GLsizei start,
  177. GLsizei count, GLenum format,
  178. GLenum type, const GLvoid *data,
  179. GLboolean _IsDlist)
  180. {
  181. __GLtexture *tex;
  182. __GLpixelSpanInfo spanInfo;
  183. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  184. if (!__glCheckColorTableArgs(gc, format, type))
  185. {
  186. return;
  187. }
  188. tex = __glLookUpTexture(gc, target);
  189. if (tex == NULL ||
  190. target == GL_PROXY_TEXTURE_1D ||
  191. target == GL_PROXY_TEXTURE_2D)
  192. {
  193. __glSetError(GL_INVALID_ENUM);
  194. return;
  195. }
  196. if (data == NULL)
  197. {
  198. return;
  199. }
  200. // Validate start and count
  201. if (start > tex->paletteTotalSize ||
  202. start+count > tex->paletteTotalSize)
  203. {
  204. __glSetError(GL_INVALID_VALUE);
  205. return;
  206. }
  207. // Copy user palette data into BGRA form
  208. spanInfo.dstImage = tex->paletteTotalData;
  209. __glInitTextureUnpack(gc, &spanInfo, count, 1, format, type, data,
  210. GL_BGRA_EXT, _IsDlist);
  211. spanInfo.dstSkipPixels += start;
  212. __glInitUnpacker(gc, &spanInfo);
  213. __glInitPacker(gc, &spanInfo);
  214. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  215. // Don't update the optimized palette unless it would actually
  216. // get used
  217. if (tex->level[0].internalFormat == GL_COLOR_INDEX8_EXT ||
  218. tex->level[0].internalFormat == GL_COLOR_INDEX16_EXT)
  219. {
  220. __GLtextureObject *pto;
  221. pto = __glLookUpTextureObject(gc, target);
  222. __glGenUpdateTexturePalette(gc, tex, pto->loadKey, start, count);
  223. }
  224. }
  225. void APIPRIVATE __glim_GetColorTableEXT(GLenum target, GLenum format,
  226. GLenum type, GLvoid *data)
  227. {
  228. __GLtexture *tex;
  229. GLint level;
  230. __GLpixelSpanInfo spanInfo;
  231. GLenum baseFormat;
  232. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  233. if (!__glCheckColorTableArgs(gc, format, type))
  234. {
  235. return;
  236. }
  237. tex = __glLookUpTexture(gc, target);
  238. if (tex == NULL ||
  239. target == GL_PROXY_TEXTURE_1D ||
  240. target == GL_PROXY_TEXTURE_2D)
  241. {
  242. __glSetError(GL_INVALID_ENUM);
  243. return;
  244. }
  245. ASSERTOPENGL(tex->paletteTotalData != NULL,
  246. "GetColorTable with no palette data\n");
  247. // Copy BGRA data into user buffer
  248. spanInfo.srcImage = tex->paletteTotalData;
  249. spanInfo.srcFormat = GL_BGRA_EXT;
  250. spanInfo.srcType = GL_UNSIGNED_BYTE;
  251. spanInfo.srcAlignment = 4;
  252. __glInitImagePack(gc, &spanInfo, tex->paletteTotalSize, 1,
  253. format, type, data);
  254. __glInitUnpacker(gc, &spanInfo);
  255. __glInitPacker(gc, &spanInfo);
  256. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  257. }
  258. void APIPRIVATE __glim_GetColorTableParameterivEXT(GLenum target,
  259. GLenum pname,
  260. GLint *params)
  261. {
  262. __GLtexture *tex;
  263. __GL_SETUP_NOT_IN_BEGIN();
  264. tex = __glLookUpTexture(gc, target);
  265. if (tex == NULL)
  266. {
  267. __glSetError(GL_INVALID_ENUM);
  268. return;
  269. }
  270. switch(pname)
  271. {
  272. case GL_COLOR_TABLE_FORMAT_EXT:
  273. *params = tex->paletteRequestedFormat;
  274. break;
  275. case GL_COLOR_TABLE_WIDTH_EXT:
  276. *params = tex->paletteTotalSize;
  277. break;
  278. case GL_COLOR_TABLE_RED_SIZE_EXT:
  279. case GL_COLOR_TABLE_GREEN_SIZE_EXT:
  280. case GL_COLOR_TABLE_BLUE_SIZE_EXT:
  281. case GL_COLOR_TABLE_ALPHA_SIZE_EXT:
  282. *params = 8;
  283. break;
  284. #ifdef GL_EXT_flat_paletted_lighting
  285. case GL_COLOR_TABLE_SUBDIVISION_EXT:
  286. *params = tex->paletteSize;
  287. break;
  288. #endif
  289. default:
  290. __glSetError(GL_INVALID_ENUM);
  291. return;
  292. }
  293. }
  294. void APIPRIVATE __glim_GetColorTableParameterfvEXT(GLenum target,
  295. GLenum pname,
  296. GLfloat *params)
  297. {
  298. __GLtexture *tex;
  299. __GL_SETUP_NOT_IN_BEGIN();
  300. tex = __glLookUpTexture(gc, target);
  301. if (tex == NULL)
  302. {
  303. __glSetError(GL_INVALID_ENUM);
  304. return;
  305. }
  306. switch(pname)
  307. {
  308. case GL_COLOR_TABLE_FORMAT_EXT:
  309. *params = (GLfloat)tex->paletteRequestedFormat;
  310. break;
  311. case GL_COLOR_TABLE_WIDTH_EXT:
  312. *params = (GLfloat)tex->paletteTotalSize;
  313. break;
  314. case GL_COLOR_TABLE_RED_SIZE_EXT:
  315. case GL_COLOR_TABLE_GREEN_SIZE_EXT:
  316. case GL_COLOR_TABLE_BLUE_SIZE_EXT:
  317. case GL_COLOR_TABLE_ALPHA_SIZE_EXT:
  318. *params = (GLfloat)8;
  319. break;
  320. #ifdef GL_EXT_flat_paletted_lighting
  321. case GL_COLOR_TABLE_SUBDIVISION_EXT:
  322. *params = (GLfloat)tex->paletteSize;
  323. break;
  324. #endif
  325. default:
  326. __glSetError(GL_INVALID_ENUM);
  327. return;
  328. }
  329. }
  330. #endif // GL_EXT_paletted_texture
  331. #ifdef GL_EXT_flat_paletted_lighting
  332. void APIPRIVATE __glim_ColorTableParameterivEXT(GLenum target,
  333. GLenum pname,
  334. const GLint *params)
  335. {
  336. __GLtexture *tex;
  337. GLint ival;
  338. __GL_SETUP_NOT_IN_BEGIN();
  339. tex = __glLookUpTexture(gc, target);
  340. if (tex == NULL)
  341. {
  342. __glSetError(GL_INVALID_ENUM);
  343. return;
  344. }
  345. switch(pname)
  346. {
  347. case GL_COLOR_TABLE_SUBDIVISION_EXT:
  348. ival = *params;
  349. // Value must be an integer power of two between one and the total
  350. // palette size
  351. if ((ival & (ival-1)) != 0 ||
  352. ival < 1 ||
  353. ival > tex->paletteTotalSize)
  354. {
  355. __glSetError(GL_INVALID_VALUE);
  356. return;
  357. }
  358. __glSetPaletteSubdivision(tex, ival);
  359. break;
  360. default:
  361. __glSetError(GL_INVALID_ENUM);
  362. return;
  363. }
  364. }
  365. void APIPRIVATE __glim_ColorTableParameterfvEXT(GLenum target,
  366. GLenum pname,
  367. const GLfloat *params)
  368. {
  369. __GLtexture *tex;
  370. GLfloat fval;
  371. GLint ival;
  372. __GL_SETUP_NOT_IN_BEGIN();
  373. tex = __glLookUpTexture(gc, target);
  374. if (tex == NULL)
  375. {
  376. __glSetError(GL_INVALID_ENUM);
  377. return;
  378. }
  379. switch(pname)
  380. {
  381. case GL_COLOR_TABLE_SUBDIVISION_EXT:
  382. fval = *params;
  383. ival = (int)fval;
  384. // Value must be an integer power of two between one and the total
  385. // palette size
  386. if (fval != (GLfloat)ival ||
  387. (ival & (ival-1)) != 0 ||
  388. ival < 1 ||
  389. ival > tex->paletteTotalSize)
  390. {
  391. __glSetError(GL_INVALID_VALUE);
  392. return;
  393. }
  394. __glSetPaletteSubdivision(tex, ival);
  395. break;
  396. default:
  397. __glSetError(GL_INVALID_ENUM);
  398. return;
  399. }
  400. }
  401. #endif // GL_EXT_flat_paletted_lighting