Source code of Windows XP (NT5)
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.

218 lines
7.0 KiB

  1. /* HALFTONE.C
  2. Frosting: Master Theme Selector for Windows '95
  3. Copyright (c) 1994-1999 Microsoft Corporation. All rights reserved.
  4. */
  5. #include<windows.h>
  6. #include<windowsx.h>
  7. /*----------------------------------------------------------------------------
  8. Division lookup tables. These tables compute 0-255 divided by 51 and
  9. modulo 51. These tables could approximate gamma correction.
  10. */
  11. char unsigned const aDividedBy51Rounded[256] =
  12. {
  13. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  14. 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  15. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  16. 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  17. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  18. 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  19. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  20. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  21. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  22. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  23. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  24. };
  25. char unsigned const aDividedBy51[256] =
  26. {
  27. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  28. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  29. 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  30. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  31. 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  32. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  33. 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  34. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  35. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  36. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  37. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
  38. };
  39. char unsigned const aModulo51[256] =
  40. {
  41. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  42. 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
  43. 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6,
  44. 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
  45. 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
  46. 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  47. 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
  48. 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  49. 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
  50. 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  51. 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3,
  52. 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  53. 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  54. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0,
  55. };
  56. /*----------------------------------------------------------------------------
  57. Multiplication LUTs. These compute 0-5 times 6 and 36.
  58. */
  59. char unsigned const aTimes6[6] =
  60. {
  61. 0, 6, 12, 18, 24, 30
  62. };
  63. char unsigned const aTimes36[6] =
  64. {
  65. 0, 36, 72, 108, 144, 180
  66. };
  67. /*----------------------------------------------------------------------------
  68. Dither matrices for 8 bit to 2.6 bit halftones.
  69. */
  70. char unsigned const aHalftone8x8[64] =
  71. {
  72. 0, 38, 9, 47, 2, 40, 11, 50,
  73. 25, 12, 35, 22, 27, 15, 37, 24,
  74. 6, 44, 3, 41, 8, 47, 5, 43,
  75. 31, 19, 28, 15, 34, 21, 31, 18,
  76. 1, 39, 11, 49, 0, 39, 10, 48,
  77. 27, 14, 36, 23, 26, 13, 35, 23,
  78. 7, 46, 4, 43, 7, 45, 3, 42,
  79. 33, 20, 30, 17, 32, 19, 29, 16,
  80. };
  81. /*----------------------------------------------------------------------------
  82. Buffer for brush bits.
  83. */
  84. static BYTE aTranslate[216]; // map a 666 to a palette index
  85. /*----------------------------------------------------------------------------
  86. Dithering functions.
  87. */
  88. __inline char unsigned DitherColor( char unsigned RedDiv51,
  89. char unsigned RedMod51, char unsigned GreenDiv51, char unsigned GreenMod51,
  90. char unsigned BlueDiv51, char unsigned BlueMod51, char unsigned Index )
  91. {
  92. // cbh! try out scoy's trick of adding without jumping
  93. #pragma warning (disable:4135) // conversion between different integral types
  94. char unsigned RedTemp = RedDiv51 + (RedMod51 > Index);
  95. char unsigned GreenTemp = GreenDiv51 + (GreenMod51 > Index);
  96. char unsigned BlueTemp = BlueDiv51 + (BlueMod51 > Index);
  97. return aTranslate[RedTemp + aTimes6[GreenTemp] + aTimes36[BlueTemp]];
  98. #pragma warning (default:4135) // conversion between different integral types
  99. }
  100. __inline BYTE DitherColorXY(COLORREF Color, int x, int y)
  101. {
  102. char unsigned RedDiv51 = aDividedBy51[GetRValue(Color)];
  103. char unsigned RedMod51 = aModulo51[GetRValue(Color)];
  104. char unsigned GreenDiv51 = aDividedBy51[GetGValue(Color)];
  105. char unsigned GreenMod51 = aModulo51[GetGValue(Color)];
  106. char unsigned BlueDiv51 = aDividedBy51[GetBValue(Color)];
  107. char unsigned BlueMod51 = aModulo51[GetBValue(Color)];
  108. return DitherColor(RedDiv51,RedMod51,GreenDiv51,
  109. GreenMod51,BlueDiv51,BlueMod51,
  110. aHalftone8x8[(x&7) + (y&7)*8]);
  111. }
  112. void InitHalftone(RGBQUAD FAR *pct)
  113. {
  114. int r,g,b,n,i;
  115. DWORD FAR *pdw;
  116. HPALETTE hpal;
  117. if (hpal = CreateHalftonePalette(NULL))
  118. {
  119. pdw = (DWORD FAR *)pct;
  120. n = GetPaletteEntries(hpal, 0, 256, (LPPALETTEENTRY)pdw);
  121. //
  122. // get the halftone palette colors
  123. //
  124. for (i=0; i<256; i++)
  125. pdw[i] = RGB(GetBValue(pdw[i]),GetGValue(pdw[i]),GetRValue(pdw[i]));
  126. pdw[8] = 0;
  127. pdw[9] = 0;
  128. pdw[246] = 0;
  129. pdw[247] = 0;
  130. //
  131. // now build the 666->index translate,
  132. //
  133. for (i=b=0; b<6; b++)
  134. for (g=0; g<6; g++)
  135. for (r=0; r<6; r++)
  136. aTranslate[i++] = (BYTE)(GetNearestPaletteIndex(hpal, RGB(r*51,g*51,b*51)));
  137. DeleteObject(hpal);
  138. }
  139. }
  140. BOOL HalftoneImage(HDC hdc, HBITMAP hbm, LPBITMAPINFOHEADER lpbi, LPBYTE lpBits)
  141. {
  142. int x, y;
  143. BYTE r,g,b;
  144. int dx, dy;
  145. BITMAP bm;
  146. LPBYTE pbSrc;
  147. LPBYTE pbDst;
  148. RGBQUAD ct[256];
  149. if (lpbi->biBitCount != 24)
  150. return FALSE;
  151. InitHalftone(ct);
  152. SetDIBColorTable(hdc, 0, 256, ct);
  153. GetObject(hbm, sizeof(bm), &bm);
  154. dx = lpbi->biWidth;
  155. dy = lpbi->biHeight;
  156. /* read line by line, quantize, and transfer */
  157. for (y=0; y<dy; y++)
  158. {
  159. pbSrc = lpBits;
  160. pbDst = bm.bmBits;
  161. for (x=0; x<dx; x++)
  162. {
  163. b = *pbSrc++;
  164. g = *pbSrc++;
  165. r = *pbSrc++;
  166. *pbDst++ = DitherColorXY(RGB(r,g,b),x,y);
  167. }
  168. (LPBYTE)lpBits += (lpbi->biWidth*3+3)&~3;
  169. (LPBYTE)bm.bmBits += bm.bmWidthBytes;
  170. }
  171. return TRUE;
  172. }