fpcolcnv.inc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2003 by the Free Pascal development team
  5. Some color conversion routines.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. function FillOtherBits (initial:word;CorrectBits:byte):word;
  13. var r,c : byte;
  14. begin
  15. c := 16 div CorrectBits;
  16. result := initial;
  17. for r := 1 to c do
  18. result := (result shr CorrectBits) or result;
  19. end;
  20. function ShiftAndFill (initial:word; CorrectBits:byte):word;
  21. begin
  22. result := FillOtherBits (initial shl (16-correctbits), correctbits);
  23. end;
  24. type
  25. TColorBits = array [0..3] of TColorData;
  26. // 0:alpha, 1:red, 2:green, 3:blue
  27. TShiftBits = array [0..3] of shortint;
  28. const
  29. ColorBits : array[cfRGB15..cfABGR64] of TColorBits = (
  30. // alpha red green blue
  31. {cfRGB15} ($00000000, $00007C00, $000003E0, $0000001F),
  32. {cfRGB16} ($00000000, $00007C00, $000003E0, $0000001F),
  33. {cfRGB24} ($00000000, $00FF0000, $0000FF00, $000000FF),
  34. {cfRGB32} ($00000000, $00FF0000, $0000FF00, $000000FF),
  35. {cfRGB48} ($00000000, $FFFF0000, $FFFF0000, $0000FFFF),
  36. // shl 16
  37. {cfRGBA8} ($00000003, $000000C0, $00000030, $0000000C),
  38. {cfRGBA16}($0000000F, $0000F000, $00000F00, $000000F0),
  39. {cfRGBA32}($000000FF, $FF000000, $00FF0000, $0000FF00),
  40. {cfRGBA64}($0000FFFF, $FFFF0000, $FFFF0000, $FFFF0000),
  41. // shl 32 shl 16
  42. {cfBGR15} ($00000000, $0000001F, $000003E0, $00007C00),
  43. {cfBGR16} ($00000000, $0000001F, $000003E0, $00007C00),
  44. {cfBGR24} ($00000000, $000000FF, $0000FF00, $00FF0000),
  45. {cfBGR32} ($00000000, $000000FF, $0000FF00, $00FF0000),
  46. {cfBGR48} ($00000000, $0000FFFF, $FFFF0000, $FFFF0000),
  47. // shl 16
  48. {cfABGR8} ($000000C0, $00000003, $0000000C, $00000030),
  49. {cfABGR16}($0000F000, $0000000F, $000000F0, $00000F00),
  50. {cfABGR32}($FF000000, $000000FF, $0000FF00, $00FF0000),
  51. {cfABGR64}($FFFF0000, $0000FFFF, $FFFF0000, $FFFF0000)
  52. // shl 32 shl 16
  53. );
  54. ShiftBits : array[cfRGB15..cfABGR64] of TShiftBits = ( // <0:shl, >0:shr
  55. {cfRGB15} ( 0, -1, -6, -11),
  56. {cfRGB16} ( 0, -1, -6, -11),
  57. {cfRGB24} ( 0, 8, 0, -8),
  58. {cfRGB32} ( 0, 8, 0, -8),
  59. {cfRGB48} ( 0, 32, 16, 0),
  60. {cfRGBA8} (-14, -8, -10, -12),
  61. {cfRGBA16}(-12, 0, -4, -8),
  62. {cfRGBA32}( -8, 16, 8, 0),
  63. {cfRGBA64}( 0, 48, 32, 16),
  64. {cfBGR15} ( 0, -11, -6, -1),
  65. {cfBGR16} ( 0, -11, -6, -1),
  66. {cfBGR24} ( 0, -8, 0, 8),
  67. {cfBGR32} ( 0, -8, 0, 8),
  68. {cfBGR48} ( 0, 0, 16, 32),
  69. {cfBGRA8} ( -8, -14, -12, -10),
  70. {cfBGRA16}( 0, -12, -8, -4),
  71. {cfBGRA32}( 16, -8, 0, 8),
  72. {cfBGRA64}( 48, 0, 16, 32)
  73. );
  74. Bitdepths : array[cfRGB15..cfABGR64] of byte=
  75. (5,5,8,8,16, 2,4,8,16, 5,5,8,8,16, 2,4,8,16);
  76. function EnlargeColor (data:TColorData;CFmt:TColorFormat;component:byte):word;
  77. var w : word;
  78. i : TColorData;
  79. s : shortint;
  80. begin
  81. i := data and ColorBits[CFmt,component];
  82. s := ShiftBits[CFmt,component];
  83. if s = 0 then
  84. w := i
  85. else if s < 0 then
  86. w := i shl -s
  87. else
  88. w := i shr s;
  89. result := FillOtherBits (w ,BitDepths[CFmt]);
  90. end;
  91. function ConvertColor (const From : TColorData; FromFmt:TColorFormat) : TFPColor;
  92. function SetGrayScale (value : word) : TFPColor;
  93. begin
  94. with result do
  95. begin
  96. red := Value;
  97. green := value;
  98. blue := Value;
  99. end;
  100. end;
  101. function SetGrayScaleA (value : word) : TFPColor;
  102. begin
  103. result := SetGrayScale (value);
  104. result.alpha := alphaOpaque;
  105. end;
  106. begin
  107. case FromFmt of
  108. cfMono : result := SetGrayScaleA (ShiftAndFill(From,1));
  109. cfGray2 : result := SetGrayScaleA (ShiftAndFill(From,2));
  110. cfGray4 : result := SetGrayScaleA (ShiftAndFill(From,4));
  111. cdGray8 : result := SetGrayScaleA (ShiftAndFill(From,8));
  112. cfGray16 : result := SetGrayScaleA (From);
  113. cfGray24 : result := SetGrayScaleA ((From and $00FFFF00) shr 8);
  114. cfGrayA8 :
  115. begin
  116. result := SetGrayScale (FillOtherBits((From and $000000F0) shl 8,4));
  117. result.alpha := ShiftAndFill((From and $0000000F),4);
  118. end;
  119. cfGrayA16 :
  120. begin
  121. result := SetGrayScale (FillOtherBits((From and $0000FF00),8));
  122. result.alpha := ShiftAndFill((From and $000000FF),8);
  123. end;
  124. cfGrayA32 :
  125. begin
  126. result := SetGrayScale ((From and $FFFF0000) shr 16);
  127. result.alpha := (From and $0000FFFF);
  128. end;
  129. cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48,
  130. cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48 :
  131. begin
  132. result.alpha := AlphaOpaque;
  133. result.red := EnlargeColor(From, FromFmt, 1);
  134. result.green := EnlargeColor(From, FromFmt, 2);
  135. result.blue := EnlargeColor(From, FromFmt, 3);
  136. end;
  137. cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64,
  138. cfABGR8,cfABGR16,cfABGR32,cfABGR64 :
  139. begin
  140. result.alpha := EnlargeColor(From, FromFmt, 0);
  141. result.red := EnlargeColor(From, FromFmt, 1);
  142. result.green := EnlargeColor(From, FromFmt, 2);
  143. result.blue := EnlargeColor(From, FromFmt, 3);
  144. end;
  145. end;
  146. end;
  147. function ConvertColor (const From : TDeviceColor) : TFPColor;
  148. begin
  149. result := ConvertColor (From.data, From.Fmt)
  150. end;
  151. function CalculateGray (const c : TFPcolor; Bits:byte) : TColorData;
  152. begin
  153. // MG: ToDo
  154. if (c.alpha=0) or (Bits=0) then ;
  155. Result:=0;
  156. end;
  157. function CalculateGrayA (const c : TFPcolor; Bits:byte) : TColorData;
  158. var r : longword;
  159. d : byte;
  160. begin
  161. d := bits div 2;
  162. r := CalculateGray (c, d);
  163. result := r shl d;
  164. r := c.alpha shr (16-d);
  165. result := result or r;
  166. end;
  167. function ConvertColorToData (const From : TFPColor; Fmt : TColorFormat) : TColorData;
  168. var sb : TShiftBits;
  169. cb : TColorBits;
  170. function MakeSample (Value:word; ToShift:shortint; ToUse:TColorData) : TColorData;
  171. begin
  172. result := Value;
  173. if ToShift > 0 then
  174. result := result shl ToShift
  175. else
  176. result := result shr ToShift;
  177. result := result and ToUse;
  178. end;
  179. begin
  180. case Fmt of
  181. cfMono : result := CalculateGray (From,1);
  182. cfGray2 : result := CalculateGray (From,2);
  183. cfGray4 : result := CalculateGray (From,4);
  184. cdGray8 : result := CalculateGray (From,8);
  185. cfGray16 : result := CalculateGray (From,16);
  186. cfGray24 : result := CalculateGray (From,24);
  187. cfGrayA8 : result := CalculateGrayA (From, 8);
  188. cfGrayA16 : result := CalculateGrayA (From, 16);
  189. cfGrayA32 : result := CalculateGrayA (From, 32);
  190. cfRGB15,cfRGB16,cfRGB24,cfRGB32,cfRGB48,
  191. cfBGR15,cfBGR16,cfBGR24,cfBGR32,cfBGR48 :
  192. begin
  193. sb := ShiftBits[Fmt];
  194. cb := ColorBits[Fmt];
  195. result := MakeSample(From.blue, sb[3], cb[3]) or
  196. MakeSample(From.red, sb[1], cb[1]) or
  197. MakeSample(From.green, sb[2], cb[2]);
  198. end;
  199. cfRGBA8,cfRGBA16,cfRGBA32,cfRGBA64,
  200. cfABGR8,cfABGR16,cfABGR32,cfABGR64 :
  201. begin
  202. sb := ShiftBits[Fmt];
  203. cb := ColorBits[Fmt];
  204. result := MakeSample(From.alpha, sb[0], cb[0]) or
  205. MakeSample(From.red, sb[1], cb[1]) or
  206. MakeSample(From.green, sb[2], cb[2]) or
  207. MakeSample(From.blue, sb[3], cb[3]);
  208. end;
  209. end;
  210. end;
  211. function ConvertColor (const From : TFPColor; Fmt : TColorFormat) : TDeviceColor;
  212. begin
  213. result.Fmt := Fmt;
  214. result.data := convertColorToData(From, Fmt);
  215. end;
  216. function ConvertColorToData (const From : TDeviceColor; Fmt : TColorFormat) : TColorData;
  217. var c : TFPColor;
  218. begin
  219. c := ConvertColor (From);
  220. result := ConvertColorToData (c, Fmt);
  221. end;
  222. function ConvertColor (const From : TDeviceColor; Fmt : TColorFormat) : TDeviceColor;
  223. begin
  224. result.Fmt := Fmt;
  225. result.data := ConvertColorToData (From, Fmt);
  226. end;
  227. function CompareColors(const Color1, Color2: TFPColor): integer;
  228. begin
  229. Result:=integer(Color1.Red)-integer(Color2.Red);
  230. if Result<>0 then exit;
  231. Result:=integer(Color1.Green)-integer(Color2.Green);
  232. if Result<>0 then exit;
  233. Result:=integer(Color1.Blue)-integer(Color2.Blue);
  234. if Result<>0 then exit;
  235. Result:=integer(Color1.Alpha)-integer(Color2.Alpha);
  236. end;