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.

354 lines
9.7 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: test.c
  3. *
  4. * Created: 09-Dec-1992 10:51:46
  5. * Author: Kirk Olynyk [kirko]
  6. *
  7. * Copyright (c) 1991 Microsoft Corporation
  8. *
  9. * Contains the test
  10. *
  11. \**************************************************************************/
  12. #include <windows.h>
  13. #include <objbase.h>
  14. #include <math.h> // sin & cos
  15. #include <stdio.h>
  16. #include "wndstuff.h"
  17. #include <gdiplus.h>
  18. using namespace Gdiplus;
  19. enum SurfaceFormat {
  20. SurfaceFormatUnknown,
  21. SurfaceFormat565,
  22. SurfaceFormat555
  23. };
  24. /**************************************************************************\
  25. * GetSurfaceFormat
  26. *
  27. * Returns:
  28. * Returns the display mode, or
  29. * SurfaceFormatUnknown if unknown or on error.
  30. *
  31. * Only recognizes 555 and 565.
  32. *
  33. \**************************************************************************/
  34. SurfaceFormat
  35. GetSurfaceFormat(
  36. HDC hdc
  37. )
  38. {
  39. HBITMAP hbm;
  40. SurfaceFormat ret = SurfaceFormatUnknown;
  41. BYTE bmi_buf[sizeof(BITMAPINFO) + (sizeof(RGBQUAD) * 255)];
  42. BITMAPINFO *pbmi = (BITMAPINFO *) bmi_buf;
  43. memset(bmi_buf, 0, sizeof(bmi_buf));
  44. // Create a dummy bitmap from which we can query color format info
  45. // about the device surface.
  46. if ( (hbm = CreateCompatibleBitmap(hdc, 1, 1)) != NULL )
  47. {
  48. pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  49. // Call first time to fill in BITMAPINFO header.
  50. GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
  51. // First handle the 'simple' case of indexed formats.
  52. if ( (pbmi->bmiHeader.biBitCount == 16)
  53. && ( pbmi->bmiHeader.biCompression == BI_BITFIELDS ))
  54. {
  55. DWORD redMask = 0;
  56. DWORD greenMask = 0;
  57. DWORD blueMask = 0;
  58. // Call a second time to get the color masks.
  59. // It's a GetDIBits Win32 "feature".
  60. GetDIBits(
  61. hdc,
  62. hbm,
  63. 0,
  64. pbmi->bmiHeader.biHeight,
  65. NULL,
  66. pbmi,
  67. DIB_RGB_COLORS
  68. );
  69. DWORD* masks = reinterpret_cast<DWORD*>(&pbmi->bmiColors[0]);
  70. redMask = masks[0];
  71. greenMask = masks[1];
  72. blueMask = masks[2];
  73. if ((redMask == 0x0000f800) &&
  74. (greenMask == 0x000007e0) &&
  75. (blueMask == 0x0000001f) &&
  76. (pbmi->bmiHeader.biBitCount == 16))
  77. {
  78. ret = SurfaceFormat565;
  79. }
  80. if ((redMask == 0x00007c00) &&
  81. (greenMask == 0x000003e0) &&
  82. (blueMask == 0x0000001f) &&
  83. (pbmi->bmiHeader.biBitCount == 16))
  84. {
  85. ret = SurfaceFormat555;
  86. }
  87. }
  88. DeleteObject(hbm);
  89. }
  90. return ret;
  91. }
  92. static HBITMAP CreateMyDIB(HDC hdcin, PVOID *ppvBits) {
  93. // these combined give BITMAPINFO structure.
  94. struct {
  95. BITMAPINFOHEADER bmih;
  96. RGBQUAD rgbquad16[3];
  97. } bmi;
  98. bmi.bmih.biSize = sizeof(BITMAPINFOHEADER);
  99. bmi.bmih.biWidth = 8;
  100. bmi.bmih.biHeight = 8;
  101. bmi.bmih.biPlanes = 1;
  102. bmi.bmih.biBitCount = 16;
  103. bmi.bmih.biCompression = BI_BITFIELDS;
  104. bmi.bmih.biSizeImage = 0;
  105. bmi.bmih.biXPelsPerMeter = 0;
  106. bmi.bmih.biYPelsPerMeter = 0;
  107. bmi.bmih.biClrUsed = 0; // only used for <= 16bpp
  108. bmi.bmih.biClrImportant = 0;
  109. RGBQUAD rgbQuad16[3] = { { 0, 0xf8, 0, 0 }, { 0xe0, 07, 0, 0 }, { 0x1f, 0, 0, 0 } };
  110. memcpy(bmi.rgbquad16, rgbQuad16, sizeof(rgbQuad16));
  111. HBITMAP hbitmap;
  112. hbitmap = CreateDIBSection(
  113. hdcin,
  114. (BITMAPINFO*)&bmi,
  115. DIB_RGB_COLORS,
  116. ppvBits,
  117. NULL,
  118. 0);
  119. return hbitmap;
  120. }
  121. static int sysColorNum[4] = {
  122. COLOR_3DSHADOW,
  123. COLOR_3DFACE,
  124. COLOR_3DHIGHLIGHT,
  125. COLOR_DESKTOP
  126. };
  127. static void DumpBitmap(FILE *fp, WORD *pBits) {
  128. WORD * pBits2 = pBits;
  129. WORD col = *pBits2++;
  130. int count;
  131. for (count = 1;count < 64; count++) {
  132. if (col != *pBits2++) break;
  133. }
  134. if (count == 64) {
  135. fprintf(fp, " Solid %04x\n\n", col);
  136. } else {
  137. int i,j;
  138. for (i=0;i<8;i++) {
  139. fprintf(fp, " ");
  140. for (j=0;j<8;j++) {
  141. fprintf(fp, "%04x ", *pBits++);
  142. }
  143. fprintf(fp, "\n");
  144. }
  145. fprintf(fp, "\n");
  146. }
  147. }
  148. static void DumpColor(FILE *fp, Color &c) {
  149. fprintf(fp, "(%02x, %02x, %02x)", c.GetRed(), c.GetGreen(), c.GetBlue());
  150. }
  151. VOID
  152. Test(
  153. HWND hwnd
  154. )
  155. {
  156. HDC hdc = NULL;
  157. Graphics *g = NULL;
  158. HBITMAP hbm = NULL;
  159. HDC hdcOffscreen = NULL;
  160. HBITMAP bmOld = NULL;
  161. PVOID pvBits = NULL;
  162. FILE *fp = NULL;
  163. SurfaceFormat format = SurfaceFormatUnknown;
  164. Rect rect1(
  165. 0,
  166. 40,
  167. 8,
  168. 8
  169. );
  170. Rect rect2(
  171. 0,
  172. 0,
  173. 8,
  174. 8
  175. );
  176. hdc = GetDC(hwnd);
  177. g = new Graphics(hdc);
  178. {
  179. HDC h = g->GetHDC();
  180. format = GetSurfaceFormat(h);
  181. if ( (format == SurfaceFormat555)
  182. || (format == SurfaceFormat565)) {
  183. hbm = CreateMyDIB(h, &pvBits);
  184. hdcOffscreen = CreateCompatibleDC(h);
  185. bmOld = (HBITMAP) SelectObject(hdcOffscreen, hbm);
  186. } else {
  187. printf("Error: Display doesn't seem to be in 16bpp\n");
  188. g->ReleaseHDC(h);
  189. goto ErrorOut;
  190. }
  191. g->ReleaseHDC(h);
  192. }
  193. fp = fopen("output.txt", "w");
  194. fprintf(fp,
  195. "The 16bpp mode on this machine is in %s format.\n\n"
  196. "This is test output for examining rendering to 16bpp (555/565) destinations,\n"
  197. "and comparing Win9x with NT output.\n"
  198. "Related bugs: #294433, #292492, #298264, #298283, #351610, #321960.\n"
  199. "We use 3*256 test colors; for each channel, one test color for each possible\n"
  200. "0-255 level.\n"
  201. "This output has 2 sections.\n\n"
  202. "--------------------------------------------------------------------------------\n"
  203. "SECTION 1: GetNearestColor\n"
  204. "Shows the result of calling GetNearestColor on that color. For section 2, we\n"
  205. "also remember which colors were the result of a GetNearestColor call.\n"
  206. "\n",
  207. (format == SurfaceFormat555) ? "555" : "565"
  208. );
  209. int num;
  210. const int numColors = 256 * 3;
  211. BYTE colors[numColors][3];
  212. BOOL isNearest[numColors];
  213. for (num=0; num < numColors; num++) {
  214. isNearest[num] = FALSE;
  215. }
  216. for (num=0; num < numColors; num++) {
  217. colors[num][0] = 0;
  218. colors[num][1] = 0;
  219. colors[num][2] = 0;
  220. int chnum = num / 256;
  221. colors[num][chnum] = (BYTE) (num % 256);
  222. Color color(colors[num][0], colors[num][1], colors[num][2]);
  223. Color color2(colors[num][0], colors[num][1], colors[num][2]);
  224. g->GetNearestColor(&color2);
  225. BYTE nc[3];
  226. nc[0] = color2.GetRed();
  227. nc[1] = color2.GetGreen();
  228. nc[2] = color2.GetBlue();
  229. int nearestIdx = nc[chnum] + 256*chnum;
  230. nc[chnum] = 0;
  231. if ((nc[0] != 0) ||
  232. (nc[1] != 0) ||
  233. (nc[2] != 0) ||
  234. (nearestIdx < 0) ||
  235. (nearestIdx >= numColors))
  236. {
  237. fprintf(fp, "UNEXPECTED: ");
  238. }
  239. else
  240. {
  241. isNearest[nearestIdx] = TRUE;
  242. }
  243. fprintf(fp, "GetNearestColor(");
  244. DumpColor(fp, color);
  245. fprintf(fp, ") == ");
  246. DumpColor(fp, color2);
  247. fprintf(fp, "\n");
  248. }
  249. fprintf(fp,
  250. "\n--------------------------------------------------------------------------------\n"
  251. "SECTION 2: FillRect\n"
  252. "Shows the result of calling FillRectangle of an 8x8 rectangle using the input\n"
  253. "color. If all 64 pixels are the same, we say \"Solid xxxx\" with the resulting\n"
  254. "16-bit value. Otherwise, all 64 pixels are reported.\n"
  255. "\n"
  256. "* next to the color means that GetNearestColor can return this color.\n"
  257. "\n"
  258. );
  259. for (num=0; num < numColors; num++) {
  260. Color color(colors[num][0], colors[num][1], colors[num][2]);
  261. fprintf(fp, "%sColor: ", isNearest[num]?"* ":" ");
  262. DumpColor(fp, color);
  263. fprintf(fp, "\n");
  264. SolidBrush solidBrush1(color);
  265. fprintf(fp, " GDI+ FillRectangle to screen (uses GDI CreateSolidBrush & PatBlt):\n");
  266. {
  267. g->FillRectangle(&solidBrush1, rect1);
  268. HDC hdcGraphics = g->GetHDC();
  269. BitBlt(hdcOffscreen, 0, 0, rect1.Width, rect1.Height, hdcGraphics, rect1.X, rect1.Y, SRCCOPY);
  270. g->ReleaseHDC(hdcGraphics);
  271. }
  272. DumpBitmap(fp, (WORD *) pvBits);
  273. fprintf(fp, " GDI+ FillRectangle to DIBSection (uses GDI+ dithering):\n");
  274. {
  275. Graphics g2(hdcOffscreen);
  276. g2.FillRectangle(&solidBrush1, rect2);
  277. }
  278. DumpBitmap(fp, (WORD *) pvBits);
  279. }
  280. ErrorOut:
  281. if (fp) fclose(fp);
  282. if (bmOld) SelectObject(hdcOffscreen, bmOld);
  283. if (hdcOffscreen) DeleteDC(hdcOffscreen);
  284. if (hbm) DeleteObject(hbm);
  285. delete g;
  286. if (hdc) ReleaseDC(hwnd, hdc);
  287. }