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.

344 lines
7.5 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1999-2000 Microsoft Corporation
  4. *
  5. * Module name:
  6. *
  7. * The "Convert" scan operation.
  8. *
  9. * Abstract:
  10. *
  11. * See Gdiplus\Specs\ScanOperation.doc for an overview.
  12. *
  13. * This module implements scan operations for converting pixels from
  14. * one format, to another of equal or greater color precision.
  15. * (Conversion to a lesser color precision is done with either a "Quantize"
  16. * operation or a "Halftone" operation.)
  17. *
  18. * Notes:
  19. *
  20. * If the source format doesn't have alpha, we assume an alpha of 1.
  21. *
  22. * If the source format has a palette, it is supplied in otherParams->Srcpal.
  23. *
  24. * When converting to greater color precision, we need to be careful.
  25. * The operation must:
  26. * + Map 0 to 0
  27. * + Map the maximum value to the maxmimum value (e.g. in 555->32bpp,
  28. * it must map 31 to 255).
  29. *
  30. * In addition, we desire that the mapping is as close to linear as possible.
  31. *
  32. * Currently (12/16/1999), our 16bpp->32bpp code does have slight rounding
  33. * errors. e.g. we get a different value from "round(x*31/255)" when x is
  34. * 3, 7, 24, or 28. This is probably acceptable. We could also speed
  35. * the code up by using byte lookup tables. (From an unpublished paper
  36. * by Blinn & Marr of MSR.)
  37. *
  38. * Revision History:
  39. *
  40. * 05/13/1999 davidx
  41. * Created it.
  42. * 12/02/1999 agodfrey
  43. * Moved it to from Imaging\Api\convertfmt.cpp.
  44. *
  45. \**************************************************************************/
  46. #include "precomp.hpp"
  47. /**************************************************************************\
  48. *
  49. * Operation Description:
  50. *
  51. * Convert: Convert pixel format up to 32bpp ARGB.
  52. *
  53. * Arguments:
  54. *
  55. * dst - The destination scan (32bpp ARGB)
  56. * src - The source scan
  57. * count - The length of the scan, in pixels
  58. * otherParams - Additional conversion data.
  59. *
  60. * Return Value:
  61. *
  62. * None
  63. *
  64. * History:
  65. *
  66. * 05/13/1999 davidx
  67. * Created it.
  68. * 12/02/1999 agodfrey
  69. * Moved & reorganized it.
  70. *
  71. \**************************************************************************/
  72. // Convert from 1bpp indexed to sRGB
  73. VOID FASTCALL
  74. ScanOperation::Convert_1_sRGB(
  75. VOID *dst,
  76. const VOID *src,
  77. INT count,
  78. const OtherParams *otherParams
  79. )
  80. {
  81. DEFINE_POINTERS(BYTE, ARGB)
  82. ASSERT(otherParams->Srcpal);
  83. ASSERT(otherParams->Srcpal->Count >= 2);
  84. UINT n, bits;
  85. ARGB c0 = otherParams->Srcpal->Entries[0];
  86. ARGB c1 = otherParams->Srcpal->Entries[1];
  87. // NOTE: We choose code size over speed here
  88. while (count)
  89. {
  90. bits = *s++;
  91. n = count > 8 ? 8 : count;
  92. count -= n;
  93. while (n--)
  94. {
  95. *d++ = (bits & 0x80) ? c1 : c0;
  96. bits <<= 1;
  97. }
  98. }
  99. }
  100. // Convert from 4bpp indexed to sRGB
  101. VOID FASTCALL
  102. ScanOperation::Convert_4_sRGB(
  103. VOID *dst,
  104. const VOID *src,
  105. INT count,
  106. const OtherParams *otherParams
  107. )
  108. {
  109. DEFINE_POINTERS(BYTE, ARGB)
  110. ASSERT(otherParams->Srcpal);
  111. const ARGB* colors = otherParams->Srcpal->Entries;
  112. UINT n = count >> 1;
  113. // Handle whole bytes
  114. while (n--)
  115. {
  116. UINT bits = *s++;
  117. ASSERT((bits >> 4) < otherParams->Srcpal->Count);
  118. ASSERT((bits & 0xf) < otherParams->Srcpal->Count);
  119. d[0] = colors[bits >> 4];
  120. d[1] = colors[bits & 0xf];
  121. d += 2;
  122. }
  123. // Handle the last odd nibble, if any
  124. if (count & 1)
  125. *d = colors[*s >> 4];
  126. }
  127. // Convert from 8bpp indexed to sRGB
  128. VOID FASTCALL
  129. ScanOperation::Convert_8_sRGB(
  130. VOID *dst,
  131. const VOID *src,
  132. INT count,
  133. const OtherParams *otherParams
  134. )
  135. {
  136. DEFINE_POINTERS(BYTE, ARGB)
  137. ASSERT(otherParams->Srcpal);
  138. const ARGB* colors = otherParams->Srcpal->Entries;
  139. while (count--)
  140. {
  141. #if DBG
  142. if (*s >= otherParams->Srcpal->Count)
  143. {
  144. WARNING(("Palette missing entries on conversion from 8bpp to sRGB"));
  145. }
  146. #endif
  147. *d++ = colors[*s++];
  148. }
  149. }
  150. // Convert 16bpp RGB555 to sRGB
  151. VOID FASTCALL
  152. ScanOperation::Convert_555_sRGB(
  153. VOID *dst,
  154. const VOID *src,
  155. INT count,
  156. const OtherParams *otherParams
  157. )
  158. {
  159. DEFINE_POINTERS(WORD, ARGB)
  160. while (count--)
  161. {
  162. ARGB v = *s++;
  163. ARGB r = (v >> 10) & 0x1f;
  164. ARGB g = (v >> 5) & 0x1f;
  165. ARGB b = (v ) & 0x1f;
  166. *d++ = ALPHA_MASK |
  167. (((r << 3) | (r >> 2)) << RED_SHIFT) |
  168. (((g << 3) | (g >> 2)) << GREEN_SHIFT) |
  169. (((b << 3) | (b >> 2)) << BLUE_SHIFT);
  170. }
  171. }
  172. // Convert from 16bpp RGB565 to sRGB
  173. VOID FASTCALL
  174. ScanOperation::Convert_565_sRGB(
  175. VOID *dst,
  176. const VOID *src,
  177. INT count,
  178. const OtherParams *otherParams
  179. )
  180. {
  181. DEFINE_POINTERS(WORD, ARGB)
  182. while (count--)
  183. {
  184. ARGB v = *s++;
  185. ARGB r = (v >> 11) & 0x1f;
  186. ARGB g = (v >> 5) & 0x3f;
  187. ARGB b = (v ) & 0x1f;
  188. *d++ = ALPHA_MASK |
  189. (((r << 3) | (r >> 2)) << RED_SHIFT) |
  190. (((g << 2) | (g >> 4)) << GREEN_SHIFT) |
  191. (((b << 3) | (b >> 2)) << BLUE_SHIFT);
  192. }
  193. }
  194. // Convert from 16bpp ARGB1555 to sRGB
  195. VOID FASTCALL
  196. ScanOperation::Convert_1555_sRGB(
  197. VOID *dst,
  198. const VOID *src,
  199. INT count,
  200. const OtherParams *otherParams
  201. )
  202. {
  203. DEFINE_POINTERS(WORD, ARGB)
  204. while (count--)
  205. {
  206. ARGB v = *s++;
  207. ARGB a = (v & 0x8000) ? ALPHA_MASK : 0;
  208. ARGB r = (v >> 10) & 0x1f;
  209. ARGB g = (v >> 5) & 0x1f;
  210. ARGB b = (v ) & 0x1f;
  211. *d++ = a |
  212. (((r << 3) | (r >> 2)) << RED_SHIFT) |
  213. (((g << 3) | (g >> 2)) << GREEN_SHIFT) |
  214. (((b << 3) | (b >> 2)) << BLUE_SHIFT);
  215. }
  216. }
  217. // Convert from 24bpp RGB to sRGB
  218. VOID FASTCALL
  219. ScanOperation::Convert_24_sRGB(
  220. VOID *dst,
  221. const VOID *src,
  222. INT count,
  223. const OtherParams *otherParams
  224. )
  225. {
  226. DEFINE_POINTERS(BYTE, ARGB)
  227. while (count--)
  228. {
  229. *d++ = ALPHA_MASK |
  230. ((ARGB) s[0] << BLUE_SHIFT) |
  231. ((ARGB) s[1] << GREEN_SHIFT) |
  232. ((ARGB) s[2] << RED_SHIFT);
  233. s += 3;
  234. }
  235. }
  236. // Convert from 24bpp BGR to sRGB
  237. VOID FASTCALL
  238. ScanOperation::Convert_24BGR_sRGB(
  239. VOID *dst,
  240. const VOID *src,
  241. INT count,
  242. const OtherParams *otherParams
  243. )
  244. {
  245. DEFINE_POINTERS(BYTE, ARGB)
  246. while (count--)
  247. {
  248. *d++ = ALPHA_MASK |
  249. ((ARGB) s[0] << RED_SHIFT) |
  250. ((ARGB) s[1] << GREEN_SHIFT) |
  251. ((ARGB) s[2] << BLUE_SHIFT);
  252. s += 3;
  253. }
  254. }
  255. // Convert from 32bpp RGB to sRGB
  256. VOID FASTCALL
  257. ScanOperation::Convert_32RGB_sRGB(
  258. VOID *dst,
  259. const VOID *src,
  260. INT count,
  261. const OtherParams *otherParams
  262. )
  263. {
  264. DEFINE_POINTERS(ARGB, ARGB)
  265. while (count--)
  266. {
  267. *d++ = *s++ | ALPHA_MASK;
  268. }
  269. }
  270. // Convert from 48bpp RGB to sRGB64
  271. VOID FASTCALL
  272. ScanOperation::Convert_48_sRGB64(
  273. VOID *dst,
  274. const VOID *src,
  275. INT count,
  276. const OtherParams *otherParams
  277. )
  278. {
  279. DEFINE_POINTERS(INT16, ARGB64)
  280. while (count--)
  281. {
  282. using namespace sRGB;
  283. sRGB64Color c;
  284. c.a = SRGB_ONE;
  285. c.b = s[0];
  286. c.g = s[1];
  287. c.r = s[2];
  288. *d++ = c.argb;
  289. s += 3;
  290. }
  291. }