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.

243 lines
6.5 KiB

  1. /**************************************************************************
  2. *
  3. * Copyright (c) 2000 Microsoft Corporation
  4. *
  5. * Module Name:
  6. *
  7. * VGA color hash table
  8. *
  9. * Abstract:
  10. *
  11. * This module maintains a hash table which holds the 20 VGA colors
  12. * (this includes the 4 which can be modified.)
  13. * The 8bpp halftone code, for example, needs to detect these colors
  14. * so that it doesn't halftone them.
  15. *
  16. * Notes:
  17. *
  18. * The collision algorithm is designed to place very little
  19. * burden on the lookup code. It'll produce bad performance when there
  20. * are many collisions - which is fine since we expect only
  21. * a few collisions at most.
  22. *
  23. * Created:
  24. *
  25. * 04/06/2000 agodfrey
  26. * Created it.
  27. *
  28. **************************************************************************/
  29. #include "precomp.hpp"
  30. // The hash table. VgaColorHash is the actual hash table. It is
  31. // initialized from VgaColorHashInit, and then the 4 magic colors are added.
  32. //
  33. // An entry has the following layout:
  34. //
  35. // Bits 0-23: The RGB color
  36. // Bits 24-29: The palette index for that color. This is an index into
  37. // our logical palette (HTColorPalette).
  38. // Bit 30: FALSE if the entry is empty, TRUE if it is occupied.
  39. // Bit 31: Used for collisions - if this is TRUE, the lookup function
  40. // should continue to the next entry.
  41. ARGB VgaColorHash[VGA_HASH_SIZE];
  42. static ARGB VgaColorHashInit[VGA_HASH_SIZE] = {
  43. 0x40000000, 0x00000000, 0x00000000, 0x00000000,
  44. 0x44000080, 0x00000000, 0x00000000, 0x500000ff,
  45. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  46. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  47. 0x42008000, 0x00000000, 0x00000000, 0x00000000,
  48. 0x46008080, 0x00000000, 0x00000000, 0x00000000,
  49. 0x5200ffff, 0x00000000, 0x00000000, 0x00000000,
  50. 0x00000000, 0x00000000, 0x00000000, 0x4e00ff00,
  51. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  52. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  53. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  54. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  55. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  56. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  57. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  58. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  59. 0x41800000, 0x00000000, 0x00000000, 0x00000000,
  60. 0x45800080, 0x00000000, 0x00000000, 0x00000000,
  61. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  62. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  63. 0x43808000, 0x00000000, 0x00000000, 0x00000000,
  64. 0x4c808080, 0x00000000, 0x00000000, 0x00000000,
  65. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  66. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  67. 0x4fffff00, 0x00000000, 0x00000000, 0x00000000,
  68. 0x00000000, 0x00000000, 0x00000000, 0x53ffffff,
  69. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  70. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  71. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  72. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  73. 0x51ff00ff, 0x00000000, 0x00000000, 0x00000000,
  74. 0x00000000, 0x00000000, 0x47c0c0c0, 0x4dff0000
  75. };
  76. /**************************************************************************
  77. *
  78. * Function Description:
  79. *
  80. * Finds an entry in the table.
  81. *
  82. * Arguments:
  83. *
  84. * color - the color to find
  85. *
  86. * Return Value:
  87. *
  88. * The index corresponding to that color, or 0xff if not found.
  89. *
  90. * Notes:
  91. *
  92. * I don't expect performance-critical code to use this -
  93. * e.g. HalftoneToScreen_sRGB_8_216 needs to do this inline -
  94. * but it's useful for other code.
  95. *
  96. * Created:
  97. *
  98. * 04/08/2000 agodfrey
  99. * Created it.
  100. *
  101. **************************************************************************/
  102. BYTE
  103. VGAHashLookup(
  104. COLORREF color
  105. )
  106. {
  107. UINT hashKey = VGAHashColor(
  108. GetRValue(color),
  109. GetGValue(color),
  110. GetBValue(color)
  111. );
  112. ARGB rgbColor = (GetRValue(color) << 16) |
  113. (GetGValue(color) << 8) |
  114. GetBValue(color);
  115. UINT tblEntry;
  116. do
  117. {
  118. tblEntry = VgaColorHash[hashKey];
  119. if (((tblEntry ^ rgbColor) & 0xffffff) == 0)
  120. {
  121. return (tblEntry >> 24) & 0x3f;
  122. }
  123. if (static_cast<INT>(tblEntry) >= 0)
  124. {
  125. break;
  126. }
  127. hashKey++;
  128. hashKey &= (1 << VGA_HASH_BITS) - 1;
  129. } while (1);
  130. return 0xff;
  131. }
  132. /**************************************************************************
  133. *
  134. * Function Description:
  135. *
  136. * Adds an entry to the hash table. If the same color is already in
  137. * the table, adds nothing.
  138. *
  139. * Arguments:
  140. *
  141. * color - the color to add
  142. * index - the palette index of the color
  143. *
  144. * Return Value:
  145. *
  146. * NONE
  147. *
  148. * Created:
  149. *
  150. * 04/06/2000 agodfrey
  151. * Created it.
  152. *
  153. **************************************************************************/
  154. VOID
  155. VGAHashAddEntry(
  156. COLORREF color,
  157. INT index
  158. )
  159. {
  160. ASSERT ((index >= 0) & (index < 0x40));
  161. if (VGAHashLookup(color) != 0xff)
  162. {
  163. return;
  164. }
  165. UINT hashKey = VGAHashColor(
  166. GetRValue(color),
  167. GetGValue(color),
  168. GetBValue(color)
  169. );
  170. ARGB rgbColor = (GetRValue(color) << 16) |
  171. (GetGValue(color) << 8) |
  172. GetBValue(color);
  173. // Find an empty location
  174. while (VgaColorHash[hashKey] & 0x40000000)
  175. {
  176. // Set the high bit of each occupied location we hit, so that
  177. // the lookup code will find the value we're about to add.
  178. VgaColorHash[hashKey] |= 0x80000000;
  179. hashKey++;
  180. if (hashKey == VGA_HASH_SIZE)
  181. {
  182. hashKey = 0;
  183. }
  184. }
  185. // Store the new entry
  186. VgaColorHash[hashKey] = (rgbColor & 0xffffff) | (index << 24) | 0x40000000;
  187. }
  188. /**************************************************************************
  189. *
  190. * Function Description:
  191. *
  192. * Reinitializes the hash table, and adds the given 4 magic colors.
  193. *
  194. * Arguments:
  195. *
  196. * magicColors - the 4 magic colors
  197. *
  198. * Return Value:
  199. *
  200. * NONE
  201. *
  202. * Created:
  203. *
  204. * 04/06/2000 agodfrey
  205. * Created it.
  206. *
  207. **************************************************************************/
  208. VOID
  209. VGAHashRebuildTable(
  210. COLORREF *magicColors
  211. )
  212. {
  213. GpMemcpy(VgaColorHash, VgaColorHashInit, sizeof(VgaColorHashInit));
  214. VGAHashAddEntry(magicColors[0], 8);
  215. VGAHashAddEntry(magicColors[1], 9);
  216. VGAHashAddEntry(magicColors[2], 10);
  217. VGAHashAddEntry(magicColors[3], 11);
  218. }