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.

1460 lines
41 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: px_fast.c *
  3. * *
  4. * Fast special case code for the pixel routines *
  5. * *
  6. * Created: 10-Oct-1995 *
  7. * Author: Drew Bliss [drewb] *
  8. * *
  9. * Copyright (c) 1995 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <gencx.h>
  14. #include <devlock.h>
  15. #include "px_fast.h"
  16. #ifdef NT
  17. // Color rescaling table for [0,255] -> [0,7]
  18. // Generated by (i*14+255)/510, which matches the OpenGL conversion of
  19. // i*7.0/255.0+0.5
  20. static GLubyte ab255to7[256] =
  21. {
  22. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  23. 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  24. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  25. 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  26. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  27. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
  28. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  29. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  30. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  31. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  32. 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  33. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  34. 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
  35. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  36. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
  37. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  38. };
  39. // Similar table for [0,255] -> [0,3]
  40. static GLubyte ab255to3[256] =
  41. {
  42. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  43. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  44. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
  45. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  46. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  47. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  48. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  49. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  50. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  51. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  52. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  53. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  54. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  55. 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  56. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  57. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
  58. };
  59. // Color rescaling table for [0,7] -> [0,255]
  60. // Computed as i*255/7
  61. static GLubyte ab7to255[8] =
  62. {
  63. 0, 36, 72, 109, 145, 182, 218, 255
  64. };
  65. // Similar table for [0,3] -> [0,255]
  66. static GLubyte ab3to255[4] =
  67. {
  68. 0, 85, 170, 255
  69. };
  70. /******************************Public*Routine******************************\
  71. *
  72. * DrawRgbPixels
  73. *
  74. * Special case of glDrawPixels for GL_RGB with straight data copy
  75. *
  76. * History:
  77. * Tue Oct 10 18:43:04 1995 -by- Drew Bliss [drewb]
  78. * Created
  79. *
  80. \**************************************************************************/
  81. GLboolean DrawRgbPixels(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  82. {
  83. HDC hdc = NULL;
  84. HBITMAP hbm = NULL;
  85. __GLcolorBuffer *cfb;
  86. BYTE abBitmapInfo[sizeof(BITMAPINFO)+2*sizeof(RGBQUAD)];
  87. BITMAPINFO *pbmi = NULL;
  88. BITMAPINFOHEADER *pbmih;
  89. BYTE *pbBits, *pbSrc, *pbDst;
  90. int x, y, xDst, yDst;
  91. GLboolean bFail = GL_TRUE;
  92. int cbSrcLine, cbSrcExtra, cbDstExtra, cbSrcElement, cbDstElement;
  93. int cbSrcWidth, cbDstWidth;
  94. int cBits;
  95. __GLGENcontext *gengc;
  96. HPALETTE hpal;
  97. #if 0
  98. DbgPrint("DrawRgbPixels\n");
  99. #endif
  100. gengc = (__GLGENcontext *)gc;
  101. cBits = gengc->gsurf.pfd.cColorBits;
  102. // Don't bother with 4bpp because of problems with color reduction
  103. // The same problems occur in 8bpp but there is special case code
  104. // to handle it.
  105. if (cBits < 8)
  106. {
  107. return GL_FALSE;
  108. }
  109. // If there is no lock, we must have failed to reacquire the lock
  110. // from some previous call. This is an error condition
  111. // and we should not continue.
  112. if (gengc->fsLocks == 0)
  113. {
  114. WARNING("DrawRgbPixels: No lock\n");
  115. return GL_FALSE;
  116. }
  117. // We need to synchronize with GDI so that the surface state is
  118. // stable before we begin making GDI calls
  119. glsrvSynchronizeWithGdi(gengc, gengc->pwndLocked, COLOR_LOCK_FLAGS);
  120. cfb = gc->drawBuffer;
  121. // Determine buffer coordinates
  122. xDst = __GL_UNBIAS_X(gc, spanInfo->startCol);
  123. yDst = __GL_UNBIAS_Y(gc, spanInfo->startRow)-spanInfo->height+1;
  124. if (cBits == 8)
  125. {
  126. pbmi = (BITMAPINFO *)gcTempAlloc(gc, sizeof(BITMAPINFO)+
  127. 255*sizeof(RGBQUAD));
  128. if (pbmi == NULL)
  129. {
  130. goto EH_Fail;
  131. }
  132. }
  133. else
  134. {
  135. pbmi = (BITMAPINFO *)abBitmapInfo;
  136. }
  137. pbmih = &pbmi->bmiHeader;
  138. pbmih->biSize = sizeof(BITMAPINFOHEADER);
  139. // Start out setting the width to the line length to describe
  140. // the actual data coming in
  141. pbmih->biWidth = spanInfo->srcLineLength;
  142. pbmih->biHeight = spanInfo->height;
  143. pbmih->biPlanes = 1;
  144. if (cBits == 8)
  145. {
  146. int i;
  147. RGBQUAD rqTmp;
  148. // If the destination is 8bpp then we do the color
  149. // reduction ourselves. In this case we want to create
  150. // an 8bpp DIB whose color table matches the destination
  151. pbmih->biBitCount = 8;
  152. pbmih->biCompression = BI_RGB;
  153. hpal = GetCurrentObject(CURRENT_DC, OBJ_PAL);
  154. if (hpal == NULL)
  155. {
  156. goto EH_Fail;
  157. }
  158. if (GetPaletteEntries(hpal, 0, 256,
  159. (LPPALETTEENTRY)pbmi->bmiColors) != 256)
  160. {
  161. goto EH_Fail;
  162. }
  163. for (i = 0; i < 256; i++)
  164. {
  165. rqTmp = pbmi->bmiColors[i];
  166. pbmi->bmiColors[i].rgbRed = rqTmp.rgbBlue;
  167. pbmi->bmiColors[i].rgbBlue = rqTmp.rgbRed;
  168. pbmi->bmiColors[i].rgbReserved = 0;
  169. }
  170. cbDstElement = 1;
  171. }
  172. else
  173. {
  174. if (spanInfo->srcFormat == GL_BGRA_EXT)
  175. {
  176. pbmih->biBitCount = 32;
  177. pbmih->biCompression = BI_BITFIELDS;
  178. *((DWORD *)pbmi->bmiColors+0) = 0xff0000;
  179. *((DWORD *)pbmi->bmiColors+1) = 0xff00;
  180. *((DWORD *)pbmi->bmiColors+2) = 0xff;
  181. cbDstElement = 4;
  182. }
  183. else
  184. {
  185. pbmih->biBitCount = 24;
  186. pbmih->biCompression = BI_RGB;
  187. cbDstElement = 3;
  188. }
  189. }
  190. pbmih->biSizeImage = 0;
  191. pbmih->biXPelsPerMeter = 0;
  192. pbmih->biYPelsPerMeter = 0;
  193. pbmih->biClrUsed = 0;
  194. pbmih->biClrImportant = 0;
  195. // For GL_BGR_EXT and GL_BGRA_EXT we can use the data directly if
  196. // it is laid out in memory like a DIB. The key thing to check
  197. // is that scanlines are DWORD aligned.
  198. // If we can't use the data directly, fall back on the DIB section
  199. // method which works for anything
  200. if (cBits > 8 &&
  201. (spanInfo->srcFormat == GL_BGR_EXT ||
  202. spanInfo->srcFormat == GL_BGRA_EXT) &&
  203. spanInfo->srcAlignment == 4)
  204. {
  205. if (SetDIBitsToDevice(CURRENT_DC, xDst, yDst,
  206. spanInfo->width, spanInfo->height,
  207. spanInfo->srcSkipPixels, spanInfo->srcSkipLines,
  208. 0, spanInfo->height, spanInfo->srcImage,
  209. pbmi, DIB_RGB_COLORS) == 0)
  210. {
  211. goto EH_Fail;
  212. }
  213. bFail = GL_FALSE;
  214. goto EH_Fail;
  215. }
  216. // Create a DIB section of the appropriate height and width
  217. // We originally set the BITMAPINFO width to the width of the
  218. // incoming data, but we only need to create a DIB section
  219. // as large as the data we're going to copy so reset the
  220. // width
  221. pbmih->biWidth = spanInfo->width;
  222. hdc = CreateCompatibleDC(CURRENT_DC);
  223. if (hdc == NULL)
  224. {
  225. goto EH_Fail;
  226. }
  227. hbm = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS,
  228. &pbBits, NULL, 0);
  229. if (hbm == NULL)
  230. {
  231. goto EH_Fail;
  232. }
  233. if (SelectObject(hdc, hbm) == NULL)
  234. {
  235. goto EH_Fail;
  236. }
  237. // Copy the input data to the DIB's contents, possibly swapping R and B,
  238. // plus skipping any appropriate data, fixing up alignment and
  239. // obeying the line length
  240. if (spanInfo->srcFormat == GL_BGRA_EXT)
  241. {
  242. cbSrcElement = 4;
  243. }
  244. else
  245. {
  246. cbSrcElement = 3;
  247. }
  248. cbSrcLine = spanInfo->srcLineLength*cbSrcElement;
  249. cbSrcExtra = cbSrcLine % spanInfo->srcAlignment;
  250. if (cbSrcExtra != 0)
  251. {
  252. cbSrcExtra = spanInfo->srcAlignment-cbSrcExtra;
  253. cbSrcLine += cbSrcExtra;
  254. }
  255. cbSrcWidth = spanInfo->width * cbSrcElement;
  256. cbSrcExtra = cbSrcLine - cbSrcWidth;
  257. cbDstWidth = spanInfo->width * cbDstElement;
  258. cbDstExtra = cbDstWidth & 3;
  259. if (cbDstExtra != 0)
  260. {
  261. cbDstExtra = 4-cbDstExtra;
  262. }
  263. pbSrc = (BYTE *)spanInfo->srcImage+
  264. spanInfo->srcSkipPixels*cbSrcElement+
  265. spanInfo->srcSkipLines*cbSrcLine;
  266. pbDst = pbBits;
  267. if (cBits == 8)
  268. {
  269. // For 8bpp destinations we need to perform the color reduction
  270. // ourselves because GDI's reduction doesn't match OpenGL's.
  271. // GDI does a closest-match-in-palette for each pixel, while
  272. // OpenGL does a rescaling of the color range plus rounding
  273. switch(spanInfo->srcFormat)
  274. {
  275. case GL_RGB:
  276. for (y = 0; y < spanInfo->height; y++)
  277. {
  278. for (x = 0; x < spanInfo->width; x++)
  279. {
  280. *pbDst++ =
  281. (ab255to3[*(pbSrc+2)] << cfb->blueShift) |
  282. (ab255to7[*(pbSrc+1)] << cfb->greenShift) |
  283. (ab255to7[*(pbSrc+0)] << cfb->redShift);
  284. pbSrc += 3;
  285. }
  286. pbSrc += cbSrcExtra;
  287. pbDst += cbDstExtra;
  288. }
  289. break;
  290. case GL_BGR_EXT:
  291. case GL_BGRA_EXT:
  292. for (y = 0; y < spanInfo->height; y++)
  293. {
  294. for (x = 0; x < spanInfo->width; x++)
  295. {
  296. *pbDst++ =
  297. (ab255to3[*(pbSrc+0)] << cfb->blueShift) |
  298. (ab255to7[*(pbSrc+1)] << cfb->greenShift) |
  299. (ab255to7[*(pbSrc+2)] << cfb->redShift);
  300. pbSrc += cbSrcElement;
  301. }
  302. pbSrc += cbSrcExtra;
  303. pbDst += cbDstExtra;
  304. }
  305. break;
  306. }
  307. }
  308. else
  309. {
  310. switch(spanInfo->srcFormat)
  311. {
  312. case GL_RGB:
  313. for (y = 0; y < spanInfo->height; y++)
  314. {
  315. for (x = 0; x < spanInfo->width; x++)
  316. {
  317. *pbDst++ = *(pbSrc+2);
  318. *pbDst++ = *(pbSrc+1);
  319. *pbDst++ = *pbSrc;
  320. pbSrc += 3;
  321. }
  322. pbSrc += cbSrcExtra;
  323. pbDst += cbDstExtra;
  324. }
  325. break;
  326. case GL_BGR_EXT:
  327. case GL_BGRA_EXT:
  328. if (cbSrcExtra == 0 && cbDstExtra == 0)
  329. {
  330. CopyMemory(pbDst, pbSrc, cbSrcWidth*spanInfo->height);
  331. }
  332. else
  333. {
  334. cbDstWidth += cbDstExtra;
  335. for (y = 0; y < spanInfo->height; y++)
  336. {
  337. CopyMemory(pbDst, pbSrc, cbSrcWidth);
  338. pbSrc += cbSrcLine;
  339. pbDst += cbDstWidth;
  340. }
  341. }
  342. break;
  343. }
  344. }
  345. // Copy the DIB to the buffer
  346. bFail = !BitBlt(CURRENT_DC, xDst, yDst, spanInfo->width, spanInfo->height,
  347. hdc, 0, 0, SRCCOPY);
  348. EH_Fail:
  349. if (hdc != NULL)
  350. {
  351. DeleteDC(hdc);
  352. }
  353. if (hbm != NULL)
  354. {
  355. DeleteObject(hbm);
  356. }
  357. if (pbmi != NULL && pbmi != (BITMAPINFO *)abBitmapInfo)
  358. {
  359. gcTempFree(gc, pbmi);
  360. }
  361. // No more need for GDI operations
  362. glsrvDecoupleFromGdi(gengc, gengc->pwndLocked, COLOR_LOCK_FLAGS);
  363. return !bFail;
  364. }
  365. /******************************Public*Routine******************************\
  366. *
  367. * StoreZPixels
  368. *
  369. * Special case of glDrawPixels for GL_DEPTH_COMPONENTs going directly
  370. * into the Z buffer with no color buffer modification.
  371. *
  372. * History:
  373. * Tue Oct 10 18:43:36 1995 -by- Drew Bliss [drewb]
  374. * Created
  375. *
  376. \**************************************************************************/
  377. GLboolean StoreZPixels(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  378. {
  379. __GLdepthBuffer *fb;
  380. BYTE *pbBits, *pbSrc, *pbDst;
  381. int x, y;
  382. int cbElement, cbSrcLine, cbSrcExtra, cbDstExtra;
  383. #if 0
  384. DbgPrint("StoreZPixels\n");
  385. #endif
  386. fb = &gc->depthBuffer;
  387. // Copy the input data to the depth buffer,
  388. // skipping any appropriate data, fixing up alignment and
  389. // obeying the line length
  390. switch(spanInfo->srcType)
  391. {
  392. case GL_UNSIGNED_SHORT:
  393. cbElement = 2;
  394. break;
  395. case GL_UNSIGNED_INT:
  396. cbElement = 4;
  397. break;
  398. default:
  399. ASSERTOPENGL(0, "StoreZPixels: Unknown srcType\n");
  400. break;
  401. }
  402. cbSrcLine = spanInfo->srcLineLength*cbElement;
  403. cbSrcExtra = cbSrcLine % spanInfo->srcAlignment;
  404. if (cbSrcExtra != 0)
  405. {
  406. cbSrcExtra = spanInfo->srcAlignment-cbSrcExtra;
  407. cbSrcLine += cbSrcExtra;
  408. }
  409. pbSrc = (BYTE *)spanInfo->srcImage+
  410. spanInfo->srcSkipPixels*cbElement+
  411. spanInfo->srcSkipLines*cbSrcLine;
  412. // Determine buffer coordinates
  413. x = spanInfo->startCol;
  414. y = spanInfo->startRow;
  415. if (fb->buf.elementSize == sizeof(__GLzValue))
  416. {
  417. pbDst = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLzValue*), x, y);
  418. cbDstExtra = -(fb->buf.outerWidth+spanInfo->width)*sizeof(__GLzValue);
  419. }
  420. else
  421. {
  422. pbDst = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLz16Value*), x, y);
  423. cbDstExtra = -(fb->buf.outerWidth+spanInfo->width)*
  424. sizeof(__GLz16Value);
  425. }
  426. switch(spanInfo->srcType)
  427. {
  428. case GL_UNSIGNED_SHORT:
  429. if (fb->buf.elementSize == sizeof(__GLzValue))
  430. {
  431. ASSERTOPENGL(fb->scale == 0x7fffffff,
  432. "Depth buffer scale invalid\n");
  433. for (y = 0; y < spanInfo->height; y++)
  434. {
  435. for (x = 0; x < spanInfo->width; x++)
  436. {
  437. *(__GLzValue *)pbDst =
  438. (__GLzValue)(*(GLushort *)pbSrc) << (Z16_SHIFT-1);
  439. pbDst += sizeof(__GLzValue);
  440. pbSrc += cbElement;
  441. }
  442. pbSrc += cbSrcExtra;
  443. pbDst += cbDstExtra;
  444. }
  445. }
  446. else
  447. {
  448. ASSERTOPENGL(fb->scale == 0x7fff,
  449. "Depth buffer scale invalid\n");
  450. for (y = 0; y < spanInfo->height; y++)
  451. {
  452. for (x = 0; x < spanInfo->width; x++)
  453. {
  454. *(__GLz16Value *)pbDst =
  455. (*(GLushort *)pbSrc) >> 1;
  456. pbDst += sizeof(__GLz16Value);
  457. pbSrc += cbElement;
  458. }
  459. pbSrc += cbSrcExtra;
  460. pbDst += cbDstExtra;
  461. }
  462. }
  463. break;
  464. case GL_UNSIGNED_INT:
  465. if (fb->buf.elementSize == sizeof(__GLzValue))
  466. {
  467. ASSERTOPENGL(fb->scale == 0x7fffffff,
  468. "Depth buffer scale invalid\n");
  469. for (y = 0; y < spanInfo->height; y++)
  470. {
  471. for (x = 0; x < spanInfo->width; x++)
  472. {
  473. *(__GLzValue *)pbDst =
  474. (*(GLuint *)pbSrc) >> 1;
  475. pbDst += sizeof(__GLzValue);
  476. pbSrc += cbElement;
  477. }
  478. pbSrc += cbSrcExtra;
  479. pbDst += cbDstExtra;
  480. }
  481. }
  482. else
  483. {
  484. ASSERTOPENGL(fb->scale == 0x7fff,
  485. "Depth buffer scale invalid\n");
  486. for (y = 0; y < spanInfo->height; y++)
  487. {
  488. for (x = 0; x < spanInfo->width; x++)
  489. {
  490. *(__GLz16Value *)pbDst =
  491. (__GLz16Value)((*(GLuint *)pbSrc) >> (Z16_SHIFT+1));
  492. pbDst += sizeof(__GLz16Value);
  493. pbSrc += cbElement;
  494. }
  495. pbSrc += cbSrcExtra;
  496. pbDst += cbDstExtra;
  497. }
  498. }
  499. break;
  500. }
  501. return GL_TRUE;
  502. }
  503. /******************************Public*Routine******************************\
  504. *
  505. * ReadRgbPixels
  506. *
  507. * Special case of glReadPixels for GL_RGB with straight data copy
  508. *
  509. * History:
  510. * Tue Oct 10 18:43:04 1995 -by- Drew Bliss [drewb]
  511. * Created
  512. *
  513. \**************************************************************************/
  514. GLboolean ReadRgbPixels(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  515. {
  516. HDC hdc = NULL;
  517. HBITMAP hbm = NULL;
  518. __GLcolorBuffer *cfb;
  519. BYTE abBitmapInfo[sizeof(BITMAPINFO)+2*sizeof(RGBQUAD)];
  520. BITMAPINFO *pbmi = NULL;
  521. BITMAPINFOHEADER *pbmih;
  522. BYTE *pbBits, *pbDst, *pbSrc;
  523. DWORD *pdwDst;
  524. int x, y;
  525. GLboolean bFail = GL_TRUE;
  526. int cbDstLine, cbDstExtra, cbSrcExtra, cbSrcElement, cbDstElement;
  527. int cbSrcWidth, cbDstWidth;
  528. int cBits;
  529. HPALETTE hpal;
  530. __GLGENcontext *gengc;
  531. #if 0
  532. DbgPrint("ReadRgbPixels\n");
  533. #endif
  534. gengc = (__GLGENcontext *)gc;
  535. cBits = gengc->gsurf.pfd.cColorBits;
  536. // Don't bother with 4bpp surfaces
  537. if (cBits < 8)
  538. {
  539. return GL_FALSE;
  540. }
  541. // If there is no lock, we must have failed to reacquire the lock
  542. // from some previous call. This is an error condition
  543. // and we should not continue.
  544. if (gengc->fsLocks == 0)
  545. {
  546. WARNING("ReadRgbPixels: No lock\n");
  547. return GL_FALSE;
  548. }
  549. // We need to synchronize with GDI so that the surface state is
  550. // stable before we begin making GDI calls
  551. glsrvSynchronizeWithGdi(gengc, gengc->pwndLocked, COLOR_LOCK_FLAGS);
  552. cfb = gc->readBuffer;
  553. if (cBits == 8)
  554. {
  555. pbmi = (BITMAPINFO *)gcTempAlloc(gc, sizeof(BITMAPINFO)+
  556. 255*sizeof(RGBQUAD));
  557. if (pbmi == NULL)
  558. {
  559. goto EH_Fail;
  560. }
  561. }
  562. else
  563. {
  564. pbmi = (BITMAPINFO *)abBitmapInfo;
  565. }
  566. pbmih = &pbmi->bmiHeader;
  567. pbmih->biSize = sizeof(BITMAPINFOHEADER);
  568. // Start out setting the width to the line length to describe
  569. // the actual data coming in
  570. pbmih->biWidth = spanInfo->width;
  571. pbmih->biHeight = spanInfo->height;
  572. pbmih->biPlanes = 1;
  573. if (cBits == 8)
  574. {
  575. int i;
  576. RGBQUAD rqTmp;
  577. // If the destination is 8bpp then we do the color
  578. // expansion ourselves. In this case we want to create
  579. // an 8bpp DIB whose color table matches the source
  580. pbmih->biBitCount = 8;
  581. pbmih->biCompression = BI_RGB;
  582. hpal = GetCurrentObject(CURRENT_DC, OBJ_PAL);
  583. if (hpal == NULL)
  584. {
  585. goto EH_Fail;
  586. }
  587. if (GetPaletteEntries(hpal, 0, 256,
  588. (LPPALETTEENTRY)pbmi->bmiColors) != 256)
  589. {
  590. goto EH_Fail;
  591. }
  592. for (i = 0; i < 256; i++)
  593. {
  594. rqTmp = pbmi->bmiColors[i];
  595. pbmi->bmiColors[i].rgbRed = rqTmp.rgbBlue;
  596. pbmi->bmiColors[i].rgbBlue = rqTmp.rgbRed;
  597. pbmi->bmiColors[i].rgbReserved = 0;
  598. }
  599. cbSrcElement = 1;
  600. }
  601. else
  602. {
  603. if (spanInfo->dstFormat == GL_BGRA_EXT)
  604. {
  605. pbmih->biBitCount = 32;
  606. pbmih->biCompression = BI_BITFIELDS;
  607. *((DWORD *)pbmi->bmiColors+0) = 0xff0000;
  608. *((DWORD *)pbmi->bmiColors+1) = 0xff00;
  609. *((DWORD *)pbmi->bmiColors+2) = 0xff;
  610. cbSrcElement = 4;
  611. }
  612. else
  613. {
  614. pbmih->biBitCount = 24;
  615. pbmih->biCompression = BI_RGB;
  616. cbSrcElement = 3;
  617. }
  618. }
  619. pbmih->biSizeImage = 0;
  620. pbmih->biXPelsPerMeter = 0;
  621. pbmih->biYPelsPerMeter = 0;
  622. pbmih->biClrUsed = 0;
  623. pbmih->biClrImportant = 0;
  624. // Create a DIB section of the appropriate height and width
  625. // We originally set the BITMAPINFO width to the width of the
  626. // incoming data, but we only need to create a DIB section
  627. // as large as the data we're going to copy so reset the
  628. // width
  629. pbmih->biWidth = spanInfo->width;
  630. hdc = CreateCompatibleDC(CURRENT_DC);
  631. if (hdc == NULL)
  632. {
  633. goto EH_Fail;
  634. }
  635. hbm = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS,
  636. &pbBits, NULL, 0);
  637. if (hbm == NULL)
  638. {
  639. goto EH_Fail;
  640. }
  641. if (SelectObject(hdc, hbm) == NULL)
  642. {
  643. goto EH_Fail;
  644. }
  645. if (cBits <= 8)
  646. {
  647. hpal = GetCurrentObject(CURRENT_DC, OBJ_PAL);
  648. if (hpal != NULL)
  649. {
  650. if (SelectPalette(hdc, hpal, FALSE) == NULL)
  651. {
  652. goto EH_Fail;
  653. }
  654. if (RealizePalette(hdc) == GDI_ERROR)
  655. {
  656. goto EH_Fail;
  657. }
  658. }
  659. }
  660. // Determine buffer coordinates
  661. x = __GL_UNBIAS_X(gc, (GLint)spanInfo->readX);
  662. y = __GL_UNBIAS_Y(gc, (GLint)spanInfo->readY)-spanInfo->height+1;
  663. // Copy the buffer's contents to the DIB
  664. if (!BitBlt(hdc, 0, 0, spanInfo->width, spanInfo->height,
  665. CURRENT_DC, x, y, SRCCOPY))
  666. {
  667. goto EH_Fail;
  668. }
  669. GdiFlush();
  670. // Copy the DIB's contents to the output buffer, swapping R and B,
  671. // plus skipping any appropriate data, fixing up alignment and
  672. // obeying the line length
  673. if (spanInfo->dstFormat == GL_BGRA_EXT)
  674. {
  675. cbDstElement = 4;
  676. }
  677. else
  678. {
  679. cbDstElement = 3;
  680. }
  681. cbDstLine = spanInfo->dstLineLength*cbDstElement;
  682. cbDstExtra = cbDstLine % spanInfo->dstAlignment;
  683. if (cbDstExtra != 0)
  684. {
  685. cbDstExtra = spanInfo->dstAlignment-cbDstExtra;
  686. cbDstLine += cbDstExtra;
  687. }
  688. cbDstWidth = spanInfo->width * cbDstElement;
  689. cbDstExtra = cbDstLine - cbDstWidth;
  690. cbSrcWidth = spanInfo->width * cbSrcElement;
  691. cbSrcExtra = cbSrcWidth & 3;
  692. if (cbSrcExtra != 0)
  693. {
  694. cbSrcExtra = 4-cbSrcExtra;
  695. }
  696. pbSrc = pbBits;
  697. pbDst = (BYTE *)spanInfo->dstImage+
  698. spanInfo->dstSkipPixels*cbDstElement+
  699. spanInfo->dstSkipLines*cbDstLine;
  700. if (cBits == 8)
  701. {
  702. BYTE b;
  703. // For 8bpp sources we need to do the color expansion ourselves
  704. // because the 8bpp palette is only an approximation of a 3-3-2
  705. // palette since the system colors are forced into it. Also,
  706. // GL does a rescaling of the color range.
  707. switch(spanInfo->dstFormat)
  708. {
  709. case GL_RGB:
  710. for (y = 0; y < spanInfo->height; y++)
  711. {
  712. for (x = 0; x < spanInfo->width; x++)
  713. {
  714. b = *pbSrc++;
  715. *pbDst++ =
  716. ab7to255[(b & gc->modes.redMask) >> cfb->redShift];
  717. *pbDst++ =
  718. ab7to255[(b & gc->modes.greenMask) >> cfb->greenShift];
  719. *pbDst++ =
  720. ab3to255[(b & gc->modes.blueMask) >> cfb->blueShift];
  721. }
  722. pbSrc += cbSrcExtra;
  723. pbDst += cbDstExtra;
  724. }
  725. break;
  726. case GL_BGR_EXT:
  727. for (y = 0; y < spanInfo->height; y++)
  728. {
  729. for (x = 0; x < spanInfo->width; x++)
  730. {
  731. b = *pbSrc++;
  732. *pbDst++ =
  733. ab3to255[(b & gc->modes.blueMask) >> cfb->blueShift];
  734. *pbDst++ =
  735. ab7to255[(b & gc->modes.greenMask) >> cfb->greenShift];
  736. *pbDst++ =
  737. ab7to255[(b & gc->modes.redMask) >> cfb->redShift];
  738. }
  739. pbSrc += cbSrcExtra;
  740. pbDst += cbDstExtra;
  741. }
  742. break;
  743. case GL_BGRA_EXT:
  744. pdwDst = (DWORD *)pbDst;
  745. for (y = 0; y < spanInfo->height; y++)
  746. {
  747. for (x = 0; x < spanInfo->width; x++)
  748. {
  749. b = *pbSrc++;
  750. *pdwDst++ =
  751. 0xff000000 |
  752. ((DWORD)ab7to255[(b & gc->modes.redMask) >>
  753. cfb->redShift] << 16) |
  754. ((DWORD)ab7to255[(b & gc->modes.greenMask) >>
  755. cfb->greenShift] << 8) |
  756. ((DWORD)ab3to255[(b & gc->modes.blueMask) >>
  757. cfb->blueShift]);
  758. }
  759. pbSrc += cbSrcExtra;
  760. pdwDst = (DWORD *)(((BYTE *)pdwDst) + cbDstExtra);
  761. }
  762. break;
  763. }
  764. }
  765. else
  766. {
  767. switch(spanInfo->dstFormat)
  768. {
  769. case GL_RGB:
  770. for (y = 0; y < spanInfo->height; y++)
  771. {
  772. for (x = 0; x < spanInfo->width; x++)
  773. {
  774. *pbDst++ = *(pbSrc+2);
  775. *pbDst++ = *(pbSrc+1);
  776. *pbDst++ = *pbSrc;
  777. pbSrc += 3;
  778. }
  779. pbSrc += cbSrcExtra;
  780. pbDst += cbDstExtra;
  781. }
  782. break;
  783. case GL_BGR_EXT:
  784. if (cbSrcExtra == 0 && cbDstExtra == 0)
  785. {
  786. CopyMemory(pbDst, pbSrc, cbDstWidth*spanInfo->height);
  787. }
  788. else
  789. {
  790. cbSrcWidth += cbSrcExtra;
  791. for (y = 0; y < spanInfo->height; y++)
  792. {
  793. CopyMemory(pbDst, pbSrc, cbDstWidth);
  794. pbSrc += cbSrcWidth;
  795. pbDst += cbDstLine;
  796. }
  797. }
  798. break;
  799. case GL_BGRA_EXT:
  800. {
  801. DWORD *pdwSrc = (DWORD *)pbSrc;
  802. pdwDst = (DWORD *)pbDst;
  803. for (y = 0; y < spanInfo->height; y++)
  804. {
  805. for (x = 0; x < spanInfo->width; x++)
  806. {
  807. *pdwDst++ = 0xff000000 | (*pdwSrc++);
  808. }
  809. pdwSrc = (DWORD *)(((BYTE *)pdwSrc) + cbSrcExtra);
  810. pdwDst = (DWORD *)(((BYTE *)pdwDst) + cbDstExtra);
  811. }
  812. }
  813. }
  814. }
  815. bFail = GL_FALSE;
  816. EH_Fail:
  817. if (hdc != NULL)
  818. {
  819. DeleteDC(hdc);
  820. }
  821. if (hbm != NULL)
  822. {
  823. DeleteObject(hbm);
  824. }
  825. if (pbmi != NULL && pbmi != (BITMAPINFO *)abBitmapInfo)
  826. {
  827. gcTempFree(gc, pbmi);
  828. }
  829. // No more need for GDI operations
  830. glsrvDecoupleFromGdi(gengc, gengc->pwndLocked, COLOR_LOCK_FLAGS);
  831. return !bFail;
  832. }
  833. /******************************Public*Routine******************************\
  834. *
  835. * ReadZPixels
  836. *
  837. * Special case of glReadPixels for GL_DEPTH_COMPONENTs with
  838. * unsigned types that require minimal transformation
  839. *
  840. * History:
  841. * Tue Oct 10 18:43:36 1995 -by- Drew Bliss [drewb]
  842. * Created
  843. *
  844. \**************************************************************************/
  845. GLboolean ReadZPixels(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  846. {
  847. __GLdepthBuffer *fb;
  848. BYTE *pbBits, *pbSrc, *pbDst;
  849. int x, y;
  850. int cbElement, cbDstLine, cbSrcExtra, cbDstExtra;
  851. #if 0
  852. DbgPrint("ReadZPixels\n");
  853. #endif
  854. fb = &gc->depthBuffer;
  855. // Copy the depth buffer data to the output
  856. // skipping any appropriate data, fixing up alignment and
  857. // obeying the line length
  858. switch(spanInfo->dstType)
  859. {
  860. case GL_UNSIGNED_SHORT:
  861. cbElement = 2;
  862. break;
  863. case GL_UNSIGNED_INT:
  864. cbElement = 4;
  865. break;
  866. default:
  867. ASSERTOPENGL(0, "ReadZPixels: Unknown dstType\n");
  868. break;
  869. }
  870. cbDstLine = spanInfo->dstLineLength*cbElement;
  871. cbDstExtra = cbDstLine % spanInfo->dstAlignment;
  872. if (cbDstExtra != 0)
  873. {
  874. cbDstExtra = spanInfo->dstAlignment-cbDstExtra;
  875. cbDstLine += cbDstExtra;
  876. }
  877. pbDst = (BYTE *)spanInfo->dstImage+
  878. spanInfo->dstSkipPixels*cbElement+
  879. spanInfo->dstSkipLines*cbDstLine;
  880. // Determine buffer coordinates
  881. x = (GLint)spanInfo->readX;
  882. y = (GLint)spanInfo->readY;
  883. if (fb->buf.elementSize == sizeof(__GLzValue))
  884. {
  885. pbSrc = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLzValue*), x, y);
  886. cbSrcExtra = -(fb->buf.outerWidth+spanInfo->width)*sizeof(__GLzValue);
  887. }
  888. else
  889. {
  890. pbSrc = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLz16Value*), x, y);
  891. cbSrcExtra = -(fb->buf.outerWidth+spanInfo->width)*
  892. sizeof(__GLz16Value);
  893. }
  894. switch(spanInfo->dstType)
  895. {
  896. case GL_UNSIGNED_SHORT:
  897. if (fb->buf.elementSize == sizeof(__GLzValue))
  898. {
  899. ASSERTOPENGL(fb->scale == 0x7fffffff,
  900. "Depth buffer scale invalid\n");
  901. for (y = 0; y < spanInfo->height; y++)
  902. {
  903. for (x = 0; x < spanInfo->width; x++)
  904. {
  905. *(GLushort *)pbDst =
  906. (GLushort)(*(__GLzValue *)pbSrc) >> (Z16_SHIFT-1);
  907. pbSrc += sizeof(__GLzValue);
  908. pbDst += cbElement;
  909. }
  910. pbSrc += cbSrcExtra;
  911. pbDst += cbDstExtra;
  912. }
  913. }
  914. else
  915. {
  916. ASSERTOPENGL(fb->scale == 0x7fff,
  917. "Depth buffer scale invalid\n");
  918. for (y = 0; y < spanInfo->height; y++)
  919. {
  920. for (x = 0; x < spanInfo->width; x++)
  921. {
  922. *(GLushort *)pbDst =
  923. (*(__GLz16Value *)pbSrc) << 1;
  924. pbSrc += sizeof(__GLz16Value);
  925. pbDst += cbElement;
  926. }
  927. pbSrc += cbSrcExtra;
  928. pbDst += cbDstExtra;
  929. }
  930. }
  931. break;
  932. case GL_UNSIGNED_INT:
  933. if (fb->buf.elementSize == sizeof(__GLzValue))
  934. {
  935. ASSERTOPENGL(fb->scale == 0x7fffffff,
  936. "Depth buffer scale invalid\n");
  937. for (y = 0; y < spanInfo->height; y++)
  938. {
  939. for (x = 0; x < spanInfo->width; x++)
  940. {
  941. *(GLuint *)pbDst =
  942. (*(__GLzValue *)pbSrc) << 1;
  943. pbSrc += sizeof(__GLzValue);
  944. pbDst += cbElement;
  945. }
  946. pbSrc += cbSrcExtra;
  947. pbDst += cbDstExtra;
  948. }
  949. }
  950. else
  951. {
  952. ASSERTOPENGL(fb->scale == 0x7fff,
  953. "Depth buffer scale invalid\n");
  954. for (y = 0; y < spanInfo->height; y++)
  955. {
  956. for (x = 0; x < spanInfo->width; x++)
  957. {
  958. *(GLuint *)pbDst =
  959. (GLuint)((*(__GLz16Value *)pbSrc) << (Z16_SHIFT+1));
  960. pbSrc += sizeof(__GLz16Value);
  961. pbDst += cbElement;
  962. }
  963. pbSrc += cbSrcExtra;
  964. pbDst += cbDstExtra;
  965. }
  966. }
  967. break;
  968. }
  969. return GL_TRUE;
  970. }
  971. /******************************Public*Routine******************************\
  972. *
  973. * CopyRgbPixels
  974. *
  975. * Special case of glCopyPixels for straight data copy
  976. *
  977. * Currently we only have to deal with normal color buffers
  978. * If we start supporting aux buffers it may no longer be possible
  979. * to accelerate this function in all cases
  980. *
  981. * History:
  982. * Tue Oct 10 18:43:04 1995 -by- Drew Bliss [drewb]
  983. * Created
  984. *
  985. \**************************************************************************/
  986. GLboolean CopyRgbPixels(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  987. {
  988. __GLcolorBuffer *cfbSrc, *cfbDst;
  989. int xSrc, ySrc, xDst, yDst;
  990. GLboolean bFail;
  991. __GLGENcontext *gengc;
  992. #if 0
  993. DbgPrint("CopyRgbPixels\n");
  994. #endif
  995. gengc = (__GLGENcontext *)gc;
  996. // If there is no lock, we must have failed to reacquire the lock
  997. // from some previous call. This is an error condition
  998. // and we should not continue.
  999. if (gengc->fsLocks == 0)
  1000. {
  1001. WARNING("CopyRgbPixels: No lock\n");
  1002. return GL_FALSE;
  1003. }
  1004. // We need to synchronize with GDI so that the surface state is
  1005. // stable before we begin making GDI calls
  1006. glsrvSynchronizeWithGdi(gengc, gengc->pwndLocked, COLOR_LOCK_FLAGS);
  1007. cfbSrc = gc->readBuffer;
  1008. cfbDst = gc->drawBuffer;
  1009. // Determine buffer coordinates
  1010. xSrc = __GL_UNBIAS_X(gc, (GLint)spanInfo->readX);
  1011. ySrc = __GL_UNBIAS_Y(gc, (GLint)spanInfo->readY)-spanInfo->height+1;
  1012. xDst = __GL_UNBIAS_X(gc, (GLint)spanInfo->x);
  1013. yDst = __GL_UNBIAS_Y(gc, (GLint)spanInfo->y)-spanInfo->height+1;
  1014. // Copy the data between the buffers
  1015. bFail = (GLboolean)BitBlt(CURRENT_DC_CFB(cfbDst), xDst, yDst,
  1016. spanInfo->width, spanInfo->height,
  1017. CURRENT_DC_CFB(cfbSrc), xSrc, ySrc, SRCCOPY);
  1018. // No more need for GDI operations
  1019. glsrvDecoupleFromGdi(gengc, gengc->pwndLocked, COLOR_LOCK_FLAGS);
  1020. return bFail;
  1021. }
  1022. /******************************Public*Routine******************************\
  1023. *
  1024. * CopyZPixels
  1025. *
  1026. * Special case of glCopyPixels for GL_DEPTH where there is no
  1027. * destination color buffer and the Z function is GL_ALWAYS
  1028. *
  1029. * History:
  1030. * Tue Oct 10 18:43:36 1995 -by- Drew Bliss [drewb]
  1031. * Created
  1032. *
  1033. \**************************************************************************/
  1034. GLboolean CopyZPixels(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  1035. {
  1036. __GLdepthBuffer *fb;
  1037. BYTE *pbSrc, *pbDst;
  1038. int y, xSrc, ySrc, xDst, yDst;
  1039. int cbLine, cbWidth;
  1040. #if 0
  1041. DbgPrint("CopyZPixels\n");
  1042. #endif
  1043. fb = &gc->depthBuffer;
  1044. // Determine buffer coordinates
  1045. xSrc = (GLint)spanInfo->readX;
  1046. ySrc = (GLint)spanInfo->readY;
  1047. xDst = (GLint)spanInfo->x;
  1048. yDst = (GLint)spanInfo->y;
  1049. if (fb->buf.elementSize == sizeof(__GLzValue))
  1050. {
  1051. pbSrc = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLzValue*), xSrc, ySrc);
  1052. pbDst = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLzValue*), xDst, yDst);
  1053. cbLine = -fb->buf.outerWidth*sizeof(__GLzValue);
  1054. cbWidth = spanInfo->width*sizeof(__GLzValue);
  1055. }
  1056. else
  1057. {
  1058. pbSrc = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLz16Value*), xSrc, ySrc);
  1059. pbDst = (BYTE *)__GL_DEPTH_ADDR(fb, (__GLz16Value*), xDst, yDst);
  1060. cbLine = -fb->buf.outerWidth*sizeof(__GLz16Value);
  1061. cbWidth = spanInfo->width*sizeof(__GLz16Value);
  1062. }
  1063. if (cbLine == cbWidth)
  1064. {
  1065. MoveMemory(pbDst, pbSrc, cbWidth*spanInfo->height);
  1066. }
  1067. else
  1068. {
  1069. // Adjust copy direction to handle overlap cases
  1070. if (ySrc > yDst)
  1071. {
  1072. pbSrc += cbLine*spanInfo->height;
  1073. pbDst += cbLine*spanInfo->height;
  1074. for (y = 0; y < spanInfo->height; y++)
  1075. {
  1076. pbSrc -= cbLine;
  1077. pbDst -= cbLine;
  1078. CopyMemory(pbDst, pbSrc, cbWidth);
  1079. }
  1080. }
  1081. else if (ySrc < yDst)
  1082. {
  1083. for (y = 0; y < spanInfo->height; y++)
  1084. {
  1085. CopyMemory(pbDst, pbSrc, cbWidth);
  1086. pbSrc += cbLine;
  1087. pbDst += cbLine;
  1088. }
  1089. }
  1090. else
  1091. {
  1092. for (y = 0; y < spanInfo->height; y++)
  1093. {
  1094. MoveMemory(pbDst, pbSrc, cbWidth);
  1095. pbSrc += cbLine;
  1096. pbDst += cbLine;
  1097. }
  1098. }
  1099. }
  1100. return GL_TRUE;
  1101. }
  1102. /******************************Public*Routine******************************\
  1103. *
  1104. * CopyAlignedImage
  1105. *
  1106. * Copies data between memory images where straight data copy is applicable
  1107. *
  1108. * This routine doesn't handle overlap
  1109. * The old code doesn't seem to either, so perhaps this isn't a problem
  1110. *
  1111. * History:
  1112. * Tue Nov 07 14:27:06 1995 -by- Drew Bliss [drewb]
  1113. * Created
  1114. *
  1115. \**************************************************************************/
  1116. GLboolean CopyAlignedImage(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  1117. {
  1118. int cbLine;
  1119. int y;
  1120. GLubyte *src, *dst;
  1121. ASSERTOPENGL(spanInfo->srcGroupIncrement == spanInfo->dstGroupIncrement,
  1122. "CopyAlignedImage: Group size mismatch\n");
  1123. cbLine = spanInfo->width*spanInfo->dstGroupIncrement;
  1124. if (spanInfo->srcRowIncrement == spanInfo->dstRowIncrement &&
  1125. cbLine == spanInfo->srcRowIncrement)
  1126. {
  1127. // Source and destination rows are the same size and the copy
  1128. // is copying all of the row so we can do everything with a
  1129. // single copy
  1130. CopyMemory(spanInfo->dstCurrent, spanInfo->srcCurrent,
  1131. cbLine*spanInfo->height);
  1132. }
  1133. else
  1134. {
  1135. // Either the rows aren't the same size or we're not copying
  1136. // all of each row, so we have to go row by row
  1137. src = spanInfo->srcCurrent;
  1138. dst = spanInfo->dstCurrent;
  1139. for (y = spanInfo->height; y > 0; y--)
  1140. {
  1141. CopyMemory(dst, src, cbLine);
  1142. src += spanInfo->srcRowIncrement;
  1143. dst += spanInfo->dstRowIncrement;
  1144. }
  1145. }
  1146. return GL_TRUE;
  1147. }
  1148. /******************************Public*Routine******************************\
  1149. *
  1150. * CopyRgbToBgraImage
  1151. *
  1152. * Special case for 24-bit RGB to 32-bit BGRA
  1153. *
  1154. * History:
  1155. * Tue Nov 07 15:09:47 1995 -by- Drew Bliss [drewb]
  1156. * Created
  1157. *
  1158. \**************************************************************************/
  1159. GLboolean CopyRgbToBgraImage(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  1160. {
  1161. int x, y;
  1162. GLubyte *src;
  1163. GLuint *dst;
  1164. int srcStep, dstStep;
  1165. src = spanInfo->srcCurrent;
  1166. dst = spanInfo->dstCurrent;
  1167. srcStep = spanInfo->srcRowIncrement-
  1168. spanInfo->width*spanInfo->srcGroupIncrement;
  1169. dstStep = spanInfo->dstRowIncrement-
  1170. spanInfo->width*spanInfo->dstGroupIncrement;
  1171. ASSERTOPENGL((dstStep & 3) == 0, "Non-dword step\n");
  1172. dstStep >>= 2;
  1173. for (y = spanInfo->height; y > 0; y--)
  1174. {
  1175. for (x = spanInfo->width; x > 0; x--)
  1176. {
  1177. *dst++ =
  1178. 0xff000000 |
  1179. ((GLuint)src[0] << 16) |
  1180. ((GLuint)src[1] << 8) |
  1181. ((GLuint)src[2] << 0);
  1182. src += 3;
  1183. }
  1184. src += srcStep;
  1185. dst += dstStep;
  1186. }
  1187. return GL_TRUE;
  1188. }
  1189. /******************************Public*Routine******************************\
  1190. *
  1191. * CopyRgbaToBgraImage
  1192. *
  1193. * Special case for 32-bit RGBA to 32-bit BGRA
  1194. *
  1195. * History:
  1196. * Tue Nov 07 15:09:47 1995 -by- Drew Bliss [drewb]
  1197. * Created
  1198. *
  1199. \**************************************************************************/
  1200. GLboolean CopyRgbaToBgraImage(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  1201. {
  1202. int x, y;
  1203. GLubyte *src;
  1204. GLuint *dst;
  1205. int srcStep, dstStep;
  1206. src = spanInfo->srcCurrent;
  1207. dst = spanInfo->dstCurrent;
  1208. srcStep = spanInfo->srcRowIncrement-
  1209. spanInfo->width*spanInfo->srcGroupIncrement;
  1210. dstStep = spanInfo->dstRowIncrement-
  1211. spanInfo->width*spanInfo->dstGroupIncrement;
  1212. ASSERTOPENGL((dstStep & 3) == 0, "Non-dword step\n");
  1213. dstStep >>= 2;
  1214. for (y = spanInfo->height; y > 0; y--)
  1215. {
  1216. for (x = spanInfo->width; x > 0; x--)
  1217. {
  1218. *dst++ =
  1219. ((GLuint)src[0] << 16) |
  1220. ((GLuint)src[1] << 8) |
  1221. ((GLuint)src[2] << 0) |
  1222. ((GLuint)src[3] << 24);
  1223. src += 4;
  1224. }
  1225. src += srcStep;
  1226. dst += dstStep;
  1227. }
  1228. return GL_TRUE;
  1229. }
  1230. /******************************Public*Routine******************************\
  1231. *
  1232. * CopyBgrToBgraImage
  1233. *
  1234. * Special case for 24-bit BGR to 32-bit BGRA
  1235. *
  1236. * History:
  1237. * Tue Nov 07 15:09:47 1995 -by- Drew Bliss [drewb]
  1238. * Created
  1239. *
  1240. \**************************************************************************/
  1241. GLboolean CopyBgrToBgraImage(__GLcontext *gc, __GLpixelSpanInfo *spanInfo)
  1242. {
  1243. int x, y;
  1244. GLubyte *src;
  1245. GLuint *dst;
  1246. int srcStep, dstStep;
  1247. src = spanInfo->srcCurrent;
  1248. dst = spanInfo->dstCurrent;
  1249. srcStep = spanInfo->srcRowIncrement-
  1250. spanInfo->width*spanInfo->srcGroupIncrement;
  1251. dstStep = spanInfo->dstRowIncrement-
  1252. spanInfo->width*spanInfo->dstGroupIncrement;
  1253. ASSERTOPENGL((dstStep & 3) == 0, "Non-dword step\n");
  1254. dstStep >>= 2;
  1255. for (y = spanInfo->height; y > 0; y--)
  1256. {
  1257. for (x = spanInfo->width; x > 0; x--)
  1258. {
  1259. *dst++ =
  1260. 0xff000000 |
  1261. ((GLuint)src[0] << 0) |
  1262. ((GLuint)src[1] << 8) |
  1263. ((GLuint)src[2] << 16);
  1264. src += 3;
  1265. }
  1266. src += srcStep;
  1267. dst += dstStep;
  1268. }
  1269. return GL_TRUE;
  1270. }
  1271. #endif