Leaked source code of windows server 2003
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.

320 lines
9.8 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include "drawdibi.h"
  4. #include "dither.h"
  5. //#define GRAY_SCALE
  6. extern BOOL gf286;
  7. extern UINT gwRasterCaps;
  8. void FAR PASCAL Map16to24(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID);
  9. extern LPVOID glpDitherTable;
  10. //////////////////////////////////////////////////////////////////////////////
  11. //
  12. // DitherInit()
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. LPVOID VFWAPI
  16. DitherInit(LPBITMAPINFOHEADER lpbiIn,
  17. LPBITMAPINFOHEADER lpbiOut,
  18. DITHERPROC FAR * lpDitherProc,
  19. LPVOID lpDitherTable)
  20. {
  21. switch ((int)lpbiOut->biBitCount)
  22. {
  23. case 8:
  24. if ((int)lpbiIn->biBitCount == 8 && (gwRasterCaps & RC_PALETTE))
  25. return Dither8Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable);
  26. if ((int)lpbiIn->biBitCount == 8 && !(gwRasterCaps & RC_PALETTE))
  27. return DitherDeviceInit(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable);
  28. if ((int)lpbiIn->biBitCount == 16)
  29. return Dither16Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable);
  30. if ((int)lpbiIn->biBitCount == 24)
  31. return Dither24Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable);
  32. if ((int)lpbiIn->biBitCount == 32)
  33. return Dither32Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable);
  34. return (LPVOID)-1;
  35. case 24:
  36. if (!gf286) {
  37. if (lpbiIn->biBitCount == 16) {
  38. *lpDitherProc = Map16to24;
  39. return NULL;
  40. } else if (lpbiIn->biBitCount == 32) {
  41. *lpDitherProc = Map32to24;
  42. return NULL;
  43. }
  44. }
  45. return (LPVOID)-1;
  46. default:
  47. return (LPVOID)-1;
  48. }
  49. }
  50. //////////////////////////////////////////////////////////////////////////////
  51. //
  52. // DitherTerm()
  53. //
  54. //////////////////////////////////////////////////////////////////////////////
  55. void VFWAPI
  56. DitherTerm(LPVOID lpDitherTable)
  57. {
  58. if (lpDitherTable == glpDitherTable)
  59. Dither16Term(lpDitherTable);
  60. else
  61. Dither8Term(lpDitherTable);
  62. }
  63. //////////////////////////////////////////////////////////////////////////////
  64. //
  65. // DitherDeviceInit() - dither to the colors of the display driver
  66. //
  67. //////////////////////////////////////////////////////////////////////////////
  68. LPVOID FAR PASCAL DitherDeviceInit(LPBITMAPINFOHEADER lpbi, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR *lpDitherProc, LPVOID lpDitherTable)
  69. {
  70. HBRUSH hbr;
  71. HDC hdcMem;
  72. HDC hdc;
  73. HBITMAP hbm;
  74. HBITMAP hbmT;
  75. int i;
  76. int nColors;
  77. LPRGBQUAD prgb;
  78. BITMAPINFOHEADER biSave = *lpbiOut;
  79. //
  80. // we dont need to re-init the dither table, unless it is not ours then
  81. // we should free it.
  82. //
  83. if (lpDitherTable == glpDitherTable)
  84. {
  85. DitherTerm(lpDitherTable);
  86. lpDitherTable = NULL;
  87. }
  88. if (lpDitherTable == NULL)
  89. {
  90. lpDitherTable = GlobalAllocPtr(GHND, 256*8*8);
  91. }
  92. if (lpDitherTable == NULL)
  93. return (LPVOID)-1;
  94. hdc = GetDC(NULL);
  95. hdcMem = CreateCompatibleDC(hdc);
  96. hbm = CreateCompatibleBitmap(hdc, 256*8, 8);
  97. hbmT = SelectObject(hdcMem, hbm);
  98. if ((nColors = (int)lpbi->biClrUsed) == 0)
  99. nColors = 1 << (int)lpbi->biBitCount;
  100. prgb = (LPRGBQUAD)(lpbi+1);
  101. for (i=0; i<nColors; i++)
  102. {
  103. hbr = CreateSolidBrush(RGB(prgb[i].rgbRed,prgb[i].rgbGreen,prgb[i].rgbBlue));
  104. hbr = SelectObject(hdcMem, hbr);
  105. PatBlt(hdcMem, i*8, 0, 8, 8, PATCOPY);
  106. hbr = SelectObject(hdcMem, hbr);
  107. DeleteObject(hbr);
  108. }
  109. #ifdef XDEBUG
  110. for (i=0; i<16; i++)
  111. BitBlt(hdc,0,i*8,16*8,8,hdcMem,i*(16*8),0,SRCCOPY);
  112. #endif
  113. SelectObject(hdcMem, hbmT);
  114. DeleteDC(hdcMem);
  115. lpbiOut->biSize = sizeof(BITMAPINFOHEADER);
  116. lpbiOut->biPlanes = 1;
  117. lpbiOut->biBitCount = 8;
  118. lpbiOut->biWidth = 256*8;
  119. lpbiOut->biHeight = 8;
  120. lpbiOut->biCompression = BI_RGB;
  121. lpbiOut->biSizeImage = 256*8*8;
  122. lpbiOut->biXPelsPerMeter = 0;
  123. lpbiOut->biYPelsPerMeter = 0;
  124. lpbiOut->biClrUsed = 0;
  125. lpbiOut->biClrImportant = 0;
  126. GetDIBits(hdc, hbm, 0, 8, lpDitherTable, (LPBITMAPINFO)lpbiOut, DIB_RGB_COLORS);
  127. i = (int)lpbiOut->biClrUsed;
  128. *lpbiOut = biSave;
  129. lpbiOut->biClrUsed = i;
  130. DeleteObject(hbm);
  131. ReleaseDC(NULL, hdc);
  132. *lpDitherProc = Dither8;
  133. return (LPVOID)lpDitherTable;
  134. }
  135. //////////////////////////////////////////////////////////////////////////////
  136. //
  137. // DitherTerm()
  138. //
  139. //////////////////////////////////////////////////////////////////////////////
  140. void FAR PASCAL Dither8Term(LPVOID lpDitherTable)
  141. {
  142. if (lpDitherTable)
  143. GlobalFreePtr(lpDitherTable);
  144. }
  145. #ifdef WIN32
  146. //
  147. // call this to actually do the dither.
  148. //
  149. void FAR PASCAL Dither8(
  150. LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest
  151. LPVOID lpDst, // --> to destination bits
  152. int DstX, // Destination origin - x coordinate
  153. int DstY, // Destination origin - y coordinate
  154. int DstXE, // x extent of the BLT
  155. int DstYE, // y extent of the BLT
  156. LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source
  157. LPVOID lpSrc, // --> to source bits
  158. int SrcX, // Source origin - x coordinate
  159. int SrcY, // Source origin - y coordinate
  160. LPVOID lpDitherTable) // dither table.
  161. {
  162. int x,y;
  163. UINT wWidthSrc;
  164. UINT wWidthDst;
  165. BYTE _huge *pbS;
  166. BYTE _huge *pbD;
  167. DWORD dw;
  168. if (biDst->biBitCount != 8 || biSrc->biBitCount != 8)
  169. return;
  170. // tomor -- A little help! seems initialization is not done yet.
  171. if(!lpDitherTable)
  172. return;
  173. wWidthSrc = ((UINT)biSrc->biWidth+3)&~3;
  174. wWidthDst = ((UINT)biDst->biWidth+3)&~3;
  175. pbD = (BYTE _huge *)lpDst + DstX + DstY * wWidthDst;
  176. pbS = (BYTE _huge *)lpSrc + SrcX + SrcY * wWidthSrc;
  177. wWidthSrc -= DstXE;
  178. wWidthDst -= DstXE;
  179. #define DODITH8(px, x, y) ((LPBYTE)lpDitherTable)[((y) & 7) * 256 * 8 + (px) * 8 + (x & 7)]
  180. for (y=0; y<DstYE; y++) {
  181. /* write two DWORDs (one dither cell horizontally) at once */
  182. for (x=0; x <= (DstXE - 8); x += 8) {
  183. dw = DODITH8(*pbS++, 0, y);
  184. dw |= (DODITH8(*pbS++, 1, y) << 8);
  185. dw |= (DODITH8(*pbS++, 2, y) << 16);
  186. dw |= (DODITH8(*pbS++, 3, y) << 24);
  187. * ( (DWORD _huge UNALIGNED *) pbD)++ = dw;
  188. dw = DODITH8(*pbS++, 4, y);
  189. dw |= (DODITH8(*pbS++, 5, y) << 8);
  190. dw |= (DODITH8(*pbS++, 6, y) << 16);
  191. dw |= (DODITH8(*pbS++, 7, y) << 24);
  192. * ( (DWORD _huge UNALIGNED *) pbD)++ = dw;
  193. }
  194. /* clean up remainder (less than 8 bytes per row) */
  195. for ( ; x < DstXE; x++) {
  196. *pbD++ = DODITH8(*pbS++, x, y);
  197. }
  198. pbS += wWidthSrc;
  199. pbD += wWidthDst;
  200. }
  201. #undef DODITH8
  202. }
  203. /*
  204. * C version of 16->24 mapping (in asm for win16)
  205. */
  206. extern void FAR PASCAL Map16to24(
  207. LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest
  208. LPVOID lpDst, // --> to destination bits
  209. int DstX, // Destination origin - x coordinate
  210. int DstY, // Destination origin - y coordinate
  211. int DstXE, // x extent of the BLT
  212. int DstYE, // y extent of the BLT
  213. LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source
  214. LPVOID lpSrc, // --> to source bits
  215. int SrcX, // Source origin - x coordinate
  216. int SrcY, // Source origin - y coordinate
  217. LPVOID lpDitherTable) // dither table.
  218. {
  219. int x,y;
  220. UINT wWidthSrc;
  221. UINT wWidthDst;
  222. BYTE _huge *pbS;
  223. BYTE _huge *pbD;
  224. WORD wRGB;
  225. if (biDst->biBitCount != 24 || biSrc->biBitCount != 16)
  226. return;
  227. /* width of one row is nr pixels * size of pixel rounded to 4-bytes */
  228. wWidthSrc = ((UINT) (biSrc->biWidth * 2) +3)&~3;
  229. wWidthDst = ((UINT) (biDst->biWidth * 3) +3)&~3;
  230. /* advance to start of source, dest rect within DIB */
  231. pbD = (BYTE _huge *)lpDst + (DstX * 3) + DstY * wWidthDst;
  232. pbS = (BYTE _huge *)lpSrc + (SrcX * 2) + SrcY * wWidthSrc;
  233. /* amount to advance pointer to next line from end of source, dest rect */
  234. wWidthSrc -= (DstXE * 2);
  235. wWidthDst -= (DstXE * 3);
  236. for (y=0; y<DstYE; y++) {
  237. for (x=0; x<DstXE; x++) {
  238. wRGB = *((LPWORD)pbS)++;
  239. *pbD++ = (wRGB << 3) & 0xf8;
  240. *pbD++ = (wRGB >> 2) & 0xf8;
  241. *pbD++ = (wRGB >> 7) & 0xf8;
  242. }
  243. pbS += wWidthSrc;
  244. pbD += wWidthDst;
  245. }
  246. }
  247. void FAR PASCAL Map32to24(
  248. LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest
  249. LPVOID lpDst, // --> to destination bits
  250. int DstX, // Destination origin - x coordinate
  251. int DstY, // Destination origin - y coordinate
  252. int DstXE, // x extent of the BLT
  253. int DstYE, // y extent of the BLT
  254. LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source
  255. LPVOID lpSrc, // --> to source bits
  256. int SrcX, // Source origin - x coordinate
  257. int SrcY, // Source origin - y coordinate
  258. LPVOID lpDitherTable) // dither table.
  259. {
  260. return;
  261. }
  262. #endif