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.

223 lines
5.3 KiB

  1. /**************************************************************************\
  2. *
  3. * Copyright (c) 1999-2000 Microsoft Corporation
  4. *
  5. * Module name:
  6. *
  7. * The "AlphaMultiply" and "AlphaDivide" scan operations.
  8. *
  9. * Abstract:
  10. *
  11. * See Gdiplus\Specs\ScanOperation.doc for an overview.
  12. *
  13. * These scan operations multiply/divide the color components by the alpha
  14. * component. API-level input colors are (usually) specified in
  15. * 'non-premultiplied'. Given a non-premultiplied
  16. * color (R, G, B, A), its 'premultiplied' form is (RA, GA, BA, A).
  17. *
  18. * Notes:
  19. *
  20. * Since "AlphaMultiply" loses information, "AlphaDivide" is not a true
  21. * inverse operation. (But it is an inverse if all pixels have an alpha of 1.)
  22. *
  23. * If the alpha is 0, "AlphaDivide" won't cause a divide-by-zero exception or
  24. * do anything drastic. But it may do something random. Currently, the pixel
  25. * value is unchanged. It could, instead, set the pixel to 0.
  26. *
  27. * Revision History:
  28. *
  29. * 12/14/1999 agodfrey
  30. * Created it.
  31. *
  32. \**************************************************************************/
  33. #include "precomp.hpp"
  34. /**************************************************************************\
  35. *
  36. * Operation Description:
  37. *
  38. * AlphaMultiply/AlphaDivide: Convert between premultiplied and
  39. * non-premultiplied alpha.
  40. *
  41. * Arguments:
  42. *
  43. * dst - The destination scan
  44. * src - The source scan
  45. * count - The length of the scan, in pixels
  46. * otherParams - Additional data. (Ignored.)
  47. *
  48. * Return Value:
  49. *
  50. * None
  51. *
  52. * Notes:
  53. *
  54. * !!![agodfrey] Currently we use 'Unpremultiply' from imgutils.cpp.
  55. * While we may keep the tables and lookup in imgutils.cpp,
  56. * it needs better naming, and we want the alpha=0 and alpha=255 cases in
  57. * here, not out-of-line in imgutils.cpp.
  58. *
  59. * History:
  60. *
  61. * 12/14/1999 agodfrey
  62. * Created it.
  63. *
  64. \**************************************************************************/
  65. ARGB Unpremultiply(ARGB argb);
  66. // AlphaDivide from 32bpp PARGB
  67. VOID FASTCALL
  68. ScanOperation::AlphaDivide_sRGB(
  69. VOID *dst,
  70. const VOID *src,
  71. INT count,
  72. const OtherParams *otherParams
  73. )
  74. {
  75. DEFINE_POINTERS(ARGB, ARGB)
  76. while (count--)
  77. {
  78. sRGB::sRGBColor c;
  79. c.argb = *s;
  80. if (sRGB::isTranslucent(c.argb))
  81. {
  82. c.argb = Unpremultiply(c.argb);
  83. }
  84. *d = c.argb;
  85. d++;
  86. s++;
  87. }
  88. }
  89. // !!![agodfrey] This should be sorted out. It should be out-of-line, and kept
  90. // with its mates in imgutils.cpp (which should maybe move), but it
  91. // shouldn't have a translucency check (we want to do that in
  92. // AlphaMultiply_sRGB).
  93. ARGB MyPremultiply(ARGB argb)
  94. {
  95. ARGB a = (argb >> ALPHA_SHIFT);
  96. ARGB _000000gg = (argb >> 8) & 0x000000ff;
  97. ARGB _00rr00bb = (argb & 0x00ff00ff);
  98. ARGB _0000gggg = _000000gg * a + 0x00000080;
  99. _0000gggg += (_0000gggg >> 8);
  100. ARGB _rrrrbbbb = _00rr00bb * a + 0x00800080;
  101. _rrrrbbbb += ((_rrrrbbbb >> 8) & 0x00ff00ff);
  102. return (a << ALPHA_SHIFT) |
  103. (_0000gggg & 0x0000ff00) |
  104. ((_rrrrbbbb >> 8) & 0x00ff00ff);
  105. }
  106. // AlphaMultiply from 32bpp ARGB
  107. VOID FASTCALL
  108. ScanOperation::AlphaMultiply_sRGB(
  109. VOID *dst,
  110. const VOID *src,
  111. INT count,
  112. const OtherParams *otherParams
  113. )
  114. {
  115. DEFINE_POINTERS(ARGB, ARGB)
  116. while (count--)
  117. {
  118. sRGB::sRGBColor c;
  119. c.argb = *s;
  120. ARGB alpha = c.argb & 0xff000000;
  121. if (alpha != 0xff000000)
  122. {
  123. if (alpha != 0x00000000)
  124. {
  125. c.argb = MyPremultiply(c.argb);
  126. }
  127. else
  128. {
  129. c.argb = 0;
  130. }
  131. }
  132. *d = c.argb;
  133. d++;
  134. s++;
  135. }
  136. }
  137. // !!![agodfrey] We may want to round off, in both AlphaDivide_sRGB64 and
  138. // AlphaMultiply_sRGB64.
  139. // AlphaDivide from 64bpp PARGB
  140. VOID FASTCALL
  141. ScanOperation::AlphaDivide_sRGB64(
  142. VOID *dst,
  143. const VOID *src,
  144. INT count,
  145. const OtherParams *otherParams
  146. )
  147. {
  148. DEFINE_POINTERS(ARGB64, ARGB64)
  149. while (count--)
  150. {
  151. using namespace sRGB;
  152. sRGB64Color c;
  153. c.argb = *s;
  154. if (isTranslucent64(c.a))
  155. {
  156. c.r = ((INT) c.r << SRGB_FRACTIONBITS) / c.a;
  157. c.g = ((INT) c.g << SRGB_FRACTIONBITS) / c.a;
  158. c.b = ((INT) c.b << SRGB_FRACTIONBITS) / c.a;
  159. }
  160. *d = c.argb;
  161. d++;
  162. s++;
  163. }
  164. }
  165. // AlphaMultiply from 64bpp ARGB
  166. VOID FASTCALL
  167. ScanOperation::AlphaMultiply_sRGB64(
  168. VOID *dst,
  169. const VOID *src,
  170. INT count,
  171. const OtherParams *otherParams
  172. )
  173. {
  174. DEFINE_POINTERS(ARGB64, ARGB64)
  175. while (count--)
  176. {
  177. using namespace sRGB;
  178. sRGB64Color c;
  179. c.argb = *s;
  180. if (c.a != SRGB_ONE)
  181. {
  182. if (c.a != 0)
  183. {
  184. c.r = ((INT) c.r * c.a) >> SRGB_FRACTIONBITS;
  185. c.g = ((INT) c.g * c.a) >> SRGB_FRACTIONBITS;
  186. c.b = ((INT) c.b * c.a) >> SRGB_FRACTIONBITS;
  187. }
  188. else
  189. {
  190. c.argb = 0;
  191. }
  192. }
  193. *d = c.argb;
  194. d++;
  195. s++;
  196. }
  197. }