2
0

GR32_Blend.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. unit GR32_Blend;
  2. (* ***** BEGIN LICENSE BLOCK *****
  3. * Version: MPL 1.1 or LGPL 2.1 with linking exception
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. * http://www.mozilla.org/MPL/
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. *
  15. * Alternatively, the contents of this file may be used under the terms of the
  16. * Free Pascal modified version of the GNU Lesser General Public License
  17. * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
  18. * of this license are applicable instead of those above.
  19. * Please see the file LICENSE.txt for additional information concerning this
  20. * license.
  21. *
  22. * The Original Code is Graphics32
  23. *
  24. * The Initial Developer of the Original Code is
  25. * Alex A. Denisov
  26. *
  27. * Portions created by the Initial Developer are Copyright (C) 2000-2009
  28. * the Initial Developer. All Rights Reserved.
  29. *
  30. * ***** END LICENSE BLOCK ***** *)
  31. interface
  32. {$include GR32.inc}
  33. uses
  34. GR32,
  35. GR32_Bindings;
  36. //------------------------------------------------------------------------------
  37. //
  38. // Alpha Composition
  39. //
  40. //------------------------------------------------------------------------------
  41. //------------------------------------------------------------------------------
  42. // Blend
  43. //------------------------------------------------------------------------------
  44. //
  45. // The Blend operation mixes a foreground color (F) onto a background color (B),
  46. // using the alpha channel value of F:
  47. //
  48. // Result Z = Fa * (Fargb - Bargb) + Bargb
  49. // = Fa * Fargb + (1 - Fa) * Bargb
  50. //
  51. // The background color is assumed to be fully opaque (i.e. Ba=255).
  52. // If the alpha of the background is to be taken into account, the Merge
  53. // operation should be used instead.
  54. //
  55. // The blend operation is commonly just referred to as "alpha blending".
  56. //
  57. //------------------------------------------------------------------------------
  58. //------------------------------------------------------------------------------
  59. // Merge
  60. //------------------------------------------------------------------------------
  61. //
  62. // The Merge operation is based on a formula described in a paper by Bruce
  63. // Wallace in 1981.
  64. //
  65. // Merging is associative, that is, A over (B over C) = (A over B) over C.
  66. //
  67. // The formula is,
  68. //
  69. // Ra = Fa + Ba * (1 - Fa)
  70. // Rc = (Fa * (Fc - Bc * Ba) + Bc * Ba) / Ra
  71. //
  72. // where
  73. //
  74. // Rc is the resultant color,
  75. // Ra is the resultant alpha,
  76. // Fc is the foreground color,
  77. // Fa is the foreground alpha,
  78. // Bc is the background color,
  79. // Ba is the background alpha.
  80. //
  81. // Implementation:
  82. //
  83. // Ra := 1 - (1 - Fa) * (1 - Ba);
  84. // Wa := Fa / Ra;
  85. // Rc := Bc + Wa * (Fc - Bc);
  86. //
  87. // (1 - Fa) * (1 - Ba) = 1 - Fa - Ba + Fa * Ba = (1 - Ra)
  88. //
  89. //------------------------------------------------------------------------------
  90. //------------------------------------------------------------------------------
  91. // Combine
  92. //------------------------------------------------------------------------------
  93. //
  94. // The Combine operation performs linear interpolation, commonly refered to as
  95. // "Lerp", between two colors (X and Y), given a weight (W):
  96. //
  97. // Result Z = W * X + (1 - W) * Y
  98. // = W * (X - Y) + Y
  99. //
  100. // All channels are combined, including the alpha channel.
  101. //
  102. //------------------------------------------------------------------------------
  103. //------------------------------------------------------------------------------
  104. //
  105. // Function Prototypes
  106. //
  107. //------------------------------------------------------------------------------
  108. type
  109. //------------------------------------------------------------------------------
  110. // Blend & Merge
  111. //------------------------------------------------------------------------------
  112. TBlendReg = function(F, B: TColor32): TColor32;
  113. TBlendMem = procedure(F: TColor32; var B: TColor32);
  114. TBlendMems = procedure(F: TColor32; B: PColor32; Count: Integer);
  115. TBlendRegEx = function(F, B: TColor32; M: Cardinal): TColor32;
  116. TBlendMemEx = procedure(F: TColor32; var B: TColor32; M: Cardinal);
  117. TBlendRegRGB = function(F, B: TColor32; W: Cardinal): TColor32;
  118. TBlendMemRGB = procedure(F: TColor32; var B: TColor32; W: Cardinal);
  119. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  120. TBlendMemRGB128 = procedure(F: TColor32; var B: TColor32; W: UInt64);
  121. {$ENDIF}
  122. TBlendLine = procedure(Src, Dst: PColor32; Count: Integer);
  123. TBlendLineEx = procedure(Src, Dst: PColor32; Count: Integer; M: Cardinal);
  124. TBlendLine1 = TBlendMems deprecated 'Use TBlendMems';
  125. //------------------------------------------------------------------------------
  126. // Combine
  127. //------------------------------------------------------------------------------
  128. TCombineReg = function(X, Y: TColor32; W: Cardinal): TColor32;
  129. TCombineMem = procedure(X: TColor32; var Y: TColor32; W: Cardinal);
  130. TCombineLine = procedure(Src, Dst: PColor32; Count: Integer; W: Cardinal);
  131. //------------------------------------------------------------------------------
  132. // Misc
  133. //------------------------------------------------------------------------------
  134. TLightenReg = function(C: TColor32; Amount: Integer): TColor32;
  135. TScaleMems = procedure(Dst: PColor32; Count: Integer; Weight: Cardinal);
  136. //------------------------------------------------------------------------------
  137. //
  138. // Function variables (i.e. delegates)
  139. //
  140. //------------------------------------------------------------------------------
  141. var
  142. //------------------------------------------------------------------------------
  143. // Blend
  144. //------------------------------------------------------------------------------
  145. BlendReg: TBlendReg;
  146. BlendMem: TBlendMem;
  147. BlendMems: TBlendMems;
  148. BlendRegEx: TBlendRegEx;
  149. BlendMemEx: TBlendMemEx;
  150. BlendRegRGB: TBlendRegRGB;
  151. BlendMemRGB: TBlendMemRGB;
  152. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  153. BlendMemRGB128: TBlendMemRGB128;
  154. {$ENDIF}
  155. BlendLine: TBlendLine;
  156. BlendLineEx: TBlendLineEx;
  157. //------------------------------------------------------------------------------
  158. // Merge
  159. //------------------------------------------------------------------------------
  160. MergeReg: TBlendReg;
  161. MergeMem: TBlendMem;
  162. MergeMems: TBlendMems;
  163. MergeRegEx: TBlendRegEx;
  164. MergeMemEx: TBlendMemEx;
  165. MergeLine: TBlendLine;
  166. MergeLineEx: TBlendLineEx;
  167. //------------------------------------------------------------------------------
  168. // Combine
  169. //------------------------------------------------------------------------------
  170. CombineReg: TCombineReg;
  171. CombineMem: TCombineMem;
  172. CombineLine: TCombineLine;
  173. //------------------------------------------------------------------------------
  174. // Color algebra
  175. //------------------------------------------------------------------------------
  176. ColorAdd: TBlendReg;
  177. ColorSub: TBlendReg;
  178. ColorDiv: TBlendReg;
  179. ColorModulate: TBlendReg;
  180. ColorMax: TBlendReg;
  181. ColorMin: TBlendReg;
  182. ColorDifference: TBlendReg;
  183. ColorAverage: TBlendReg;
  184. ColorExclusion: TBlendReg;
  185. ColorScale: TBlendReg;
  186. ColorScreen: TBlendReg;
  187. ColorDodge: TBlendReg;
  188. ColorBurn: TBlendReg;
  189. //------------------------------------------------------------------------------
  190. // Blended color algebra
  191. //------------------------------------------------------------------------------
  192. BlendColorAdd: TBlendReg;
  193. BlendColorModulate: TBlendReg;
  194. //------------------------------------------------------------------------------
  195. // Misc
  196. //------------------------------------------------------------------------------
  197. LightenReg: TLightenReg;
  198. Lighten: TLightenReg absolute LightenReg; // Lighten is an alias for LigthenReg
  199. ScaleMems: TScaleMems;
  200. //------------------------------------------------------------------------------
  201. //
  202. // Access to alpha composite functions corresponding to a combine mode
  203. //
  204. //------------------------------------------------------------------------------
  205. type
  206. PBlendReg = ^TBlendReg;
  207. PBlendMem = ^TBlendMem;
  208. PBlendRegEx = ^TBlendRegEx;
  209. PBlendMemEx = ^TBlendMemEx;
  210. PBlendLine = ^TBlendLine;
  211. PBlendLineEx = ^TBlendLineEx;
  212. TBlendRegCombineModeArray = array[TCombineMode] of PBlendReg;
  213. TBlendMemCombineModeArray = array[TCombineMode] of PBlendMem;
  214. TBlendRegExCombineModeArray = array[TCombineMode] of PBlendRegEx;
  215. TBlendMemExCombineModeArray = array[TCombineMode] of PBlendMemEx;
  216. TBlendLineCombineModeArray = array[TCombineMode] of PBlendLine;
  217. TBlendLineExCombineModeArray = array[TCombineMode] of PBlendLineEx;
  218. const
  219. BLEND_REG: TBlendRegCombineModeArray = ((@@BlendReg),(@@MergeReg));
  220. BLEND_MEM: TBlendMemCombineModeArray = ((@@BlendMem),(@@MergeMem));
  221. BLEND_REG_EX: TBlendRegExCombineModeArray = ((@@BlendRegEx),(@@MergeRegEx));
  222. BLEND_MEM_EX: TBlendMemExCombineModeArray = ((@@BlendMemEx),(@@MergeMemEx));
  223. BLEND_LINE: TBlendLineCombineModeArray = ((@@BlendLine),(@@MergeLine));
  224. BLEND_LINE_EX: TBlendLineExCombineModeArray = ((@@BlendLineEx),(@@MergeLineEx));
  225. //------------------------------------------------------------------------------
  226. //
  227. // Function bindings
  228. //
  229. //------------------------------------------------------------------------------
  230. function BlendRegistry: TFunctionRegistry;
  231. const
  232. FID_EMMS = 0 deprecated;
  233. FID_MERGEREG = 1;
  234. FID_MERGEMEM = 2;
  235. FID_MERGELINE = 3;
  236. FID_MERGEMEMS = 4;
  237. FID_MERGELINE1 = FID_MERGEMEMS deprecated;
  238. FID_MERGEREGEX = 5;
  239. FID_MERGEMEMEX = 6;
  240. FID_MERGELINEEX = 7;
  241. FID_COMBINEREG = 8;
  242. FID_COMBINEMEM = 9;
  243. FID_COMBINELINE = 10;
  244. FID_BLENDREG = 11;
  245. FID_BLENDMEM = 12;
  246. FID_BLENDMEMS = 13;
  247. FID_BLENDLINE = 14;
  248. FID_BLENDREGEX = 15;
  249. FID_BLENDMEMEX = 16;
  250. FID_BLENDLINEEX = 17;
  251. FID_BLENDLINE1 = 18 deprecated;
  252. FID_COLORMAX = 19;
  253. FID_COLORMIN = 20;
  254. FID_COLORAVERAGE = 21;
  255. FID_COLORADD = 22;
  256. FID_COLORSUB = 23;
  257. FID_COLORDIV = 24;
  258. FID_COLORMODULATE = 25;
  259. FID_COLORDIFFERENCE = 26;
  260. FID_COLOREXCLUSION = 27;
  261. FID_COLORSCALE = 28;
  262. FID_COLORSCREEN = 29;
  263. FID_COLORDODGE = 30;
  264. FID_COLORBURN = 31;
  265. FID_BLENDCOLORADD = 32;
  266. FID_BLENDCOLORMODULATE= 33;
  267. FID_LIGHTEN = 34;
  268. FID_BLENDREGRGB = 35;
  269. FID_BLENDMEMRGB = 36;
  270. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  271. FID_BLENDMEMRGB128 = 37;
  272. {$ENDIF}
  273. //------------------------------------------------------------------------------
  274. //
  275. // Blending related lookup tables
  276. //
  277. //------------------------------------------------------------------------------
  278. type
  279. TLUT8 = array[byte] of byte;
  280. PLUT8 = ^TLUT8;
  281. TLUT88 = array [byte] of TLUT8;
  282. var
  283. //
  284. // DivMul255Table contains the result of a *division* of two values, specified
  285. // in the byte range:
  286. //
  287. // DivMul255Table[a, b] = Round(b * 255 / a)
  288. //
  289. // It is commonly used to perform the division of the merge operation:
  290. //
  291. // ResultColor = DivMul255Table[ResultAlpha, Color] = Color / ResultAlpha
  292. //
  293. // or unpremultiplication:
  294. //
  295. // Color = DivMul255Table[Alpha, PremultColor] = PremultColor / Alpha
  296. //
  297. DivMul255Table: TLUT88;
  298. //
  299. // MulDiv255Table contains the result of a *multiplication* of two values,
  300. // specified in the byte range:
  301. //
  302. // MulDiv255Table[a, b] = Round(a * b / 255)
  303. //
  304. // It is commonly used to perform the multiplications of the blend or merge operations:
  305. //
  306. // TempColor = MulDiv255Table[Color, Alpha] = Color * Alpha
  307. //
  308. // or premultiplication:
  309. //
  310. // PremultColor = MulDiv255Table[Color, Alpha] = Color * Alpha
  311. //
  312. MulDiv255Table: TLUT88;
  313. // RcTable and DivTable are the old names of the above two tables.
  314. // They are kept for backward compatibility and should be considered deprecated.
  315. var
  316. RcTable: TLUT88 absolute DivMul255Table;
  317. DivTable: TLUT88 absolute MulDiv255Table;
  318. //------------------------------------------------------------------------------
  319. type
  320. TMultEntry = array[0..3] of TColor32Entry;
  321. PMultEntry = ^TMultEntry;
  322. TMultTable = array[byte] of TMultEntry;
  323. PMultTable = ^TMultTable;
  324. var
  325. //
  326. // alpha_ptr: Pointer to a 16-byte aligned array[256] of 4 cardinal values.
  327. // The table is used to implement vectorized division by 255 in SIMD functions:
  328. //
  329. // (x div 255) = ((x + 128) shr 8)
  330. // = ((alpha_ptr[x] + bias_ptr^) shr 8)
  331. //
  332. alpha_ptr: PMultTable;
  333. //
  334. // bias_ptr points to the middle entry of the alpha_ptr table.
  335. // The entry contains the 4 cardinal values 00000080 00000080 00000080 00000080.
  336. //
  337. bias_ptr: PMultEntry;
  338. //------------------------------------------------------------------------------
  339. //
  340. // Backward compatibility
  341. //
  342. //------------------------------------------------------------------------------
  343. procedure MergeLine1(F: TColor32; B: PColor32; Count: Integer); {$IFDEF USEINLINING} inline; {$ENDIF} deprecated 'Use MergeMems';
  344. procedure BlendLine1(F: TColor32; B: PColor32; Count: Integer); {$IFDEF USEINLINING} inline; {$ENDIF} deprecated 'Use BlendMems';
  345. procedure EMMS; {$if defined(PUREPASCAL) or ((not defined(TARGET_X64)) and (not defined(TARGET_X86)))} {$IFDEF USEINLINING} inline; {$ENDIF} {$ifend} deprecated 'Graphics32 no longer supports MMX so calling EMMS is not necessary anymore';
  346. //------------------------------------------------------------------------------
  347. //------------------------------------------------------------------------------
  348. //------------------------------------------------------------------------------
  349. implementation
  350. uses
  351. GR32_System,
  352. {$IFNDEF PUREPASCAL}
  353. GR32.Blend.Assembler,
  354. {$IFNDEF OMIT_SSE2}
  355. GR32.Blend.SSE2,
  356. {$ENDIF}
  357. {$ENDIF}
  358. GR32.Blend.Pascal;
  359. //------------------------------------------------------------------------------
  360. //
  361. // GenAlphaTable
  362. //
  363. //------------------------------------------------------------------------------
  364. var
  365. AlphaTable: Pointer;
  366. procedure GenAlphaTable;
  367. var
  368. i: Integer;
  369. Color: TColor32Entry;
  370. begin
  371. GetMem(AlphaTable, SizeOf(TMultTable) + 16); // + 16 bytes for alignment
  372. // Align to 16 bytes
  373. alpha_ptr := pointer((NativeUInt(AlphaTable) + $F) and (not $F));
  374. // Values for division by 255: (x div 255) = ((alpha_ptr[x] + 128) shl 8)
  375. // Originally 2 entries per value for ASM and MMX.
  376. // Later expanded to 4 entries per value so the table can also be used with SSE.
  377. for i := Low(TMultTable) to High(TMultTable) do
  378. begin
  379. Color.Planes[0] := i;
  380. Color.Planes[1] := 0;
  381. Color.Planes[2] := i;
  382. Color.Planes[3] := 0;
  383. alpha_ptr[i][0] := Color;
  384. alpha_ptr[i][1] := Color;
  385. alpha_ptr[i][2] := Color;
  386. alpha_ptr[i][3] := Color;
  387. end;
  388. // bias_ptr points to ($80, 0, $80, 0)
  389. bias_ptr := @alpha_ptr[128][0];
  390. end;
  391. procedure FreeAlphaTable;
  392. begin
  393. if (AlphaTable <> nil) then
  394. FreeMem(AlphaTable);
  395. end;
  396. //------------------------------------------------------------------------------
  397. //
  398. // MakeMergeTables
  399. //
  400. //------------------------------------------------------------------------------
  401. procedure MakeMergeTables;
  402. var
  403. i, j: Integer;
  404. begin
  405. for j := 0 to 255 do
  406. begin
  407. for i := j to 255 do
  408. begin
  409. MulDiv255Table[i, j] := Round(i * j * COne255th);
  410. if (i <> j) then
  411. MulDiv255Table[j, i] := MulDiv255Table[i, j]; // a*b = b*a
  412. end;
  413. DivMul255Table[0, j] := 0;
  414. for i := 1 to 255 do
  415. begin
  416. if i > j then
  417. DivMul255Table[i, j] := Round(j * 255 / i)
  418. else
  419. DivMul255Table[i, j] := 255;
  420. end;
  421. end;
  422. end;
  423. //------------------------------------------------------------------------------
  424. //
  425. // Backward compatibility
  426. //
  427. //------------------------------------------------------------------------------
  428. procedure MergeLine1(F: TColor32; B: PColor32; Count: Integer);
  429. begin
  430. MergeMems(F, B, Count);
  431. end;
  432. procedure BlendLine1(F: TColor32; B: PColor32; Count: Integer);
  433. begin
  434. BlendMems(F, B, Count);
  435. end;
  436. {$if defined(PUREPASCAL) or ((not defined(TARGET_X64)) and (not defined(TARGET_X86)))}
  437. procedure EMMS;
  438. begin
  439. end;
  440. {$else}
  441. procedure EMMS; {$IFDEF FPC} assembler; nostackframe; {$ENDIF}
  442. asm
  443. EMMS
  444. end;
  445. {$ifend}
  446. //------------------------------------------------------------------------------
  447. //
  448. // Function bindings
  449. //
  450. //------------------------------------------------------------------------------
  451. procedure RegisterBindings;
  452. begin
  453. BlendRegistry.RegisterBinding(FID_BLENDREG, @@BlendReg, 'BlendReg');
  454. BlendRegistry.RegisterBinding(FID_BLENDMEM, @@BlendMem, 'BlendMem');
  455. BlendRegistry.RegisterBinding(FID_BLENDMEMS, @@BlendMems, 'BlendMems');
  456. BlendRegistry.RegisterBinding(FID_BLENDLINE, @@BlendLine, 'BlendLine');
  457. BlendRegistry.RegisterBinding(FID_BLENDREGEX, @@BlendRegEx, 'BlendRegEx');
  458. BlendRegistry.RegisterBinding(FID_BLENDMEMEX, @@BlendMemEx, 'BlendMemEx');
  459. BlendRegistry.RegisterBinding(FID_BLENDLINEEX, @@BlendLineEx, 'BlendLineEx');
  460. BlendRegistry.RegisterBinding(FID_BLENDREGRGB, @@BlendRegRGB, 'BlendRegRGB');
  461. BlendRegistry.RegisterBinding(FID_BLENDMEMRGB, @@BlendMemRGB, 'BlendMemRGB');
  462. {$IFDEF TEST_BLENDMEMRGB128SSE4}
  463. BlendRegistry.RegisterBinding(FID_BLENDMEMRGB128, @@BlendMemRGB128, 'BlendMemRGB128');
  464. {$ENDIF}
  465. BlendRegistry.RegisterBinding(FID_MERGEREG, @@MergeReg, 'MergeReg');
  466. BlendRegistry.RegisterBinding(FID_MERGEMEM, @@MergeMem, 'MergeMem');
  467. BlendRegistry.RegisterBinding(FID_MERGEMEMS, @@MergeMems, 'MergeMems');
  468. BlendRegistry.RegisterBinding(FID_MERGELINE, @@MergeLine, 'MergeLine');
  469. BlendRegistry.RegisterBinding(FID_MERGEREGEX, @@MergeRegEx, 'MergeRegEx');
  470. BlendRegistry.RegisterBinding(FID_MERGEMEMEX, @@MergeMemEx, 'MergeMemEx');
  471. BlendRegistry.RegisterBinding(FID_MERGELINEEX, @@MergeLineEx, 'MergeLineEx');
  472. BlendRegistry.RegisterBinding(FID_COMBINEREG, @@CombineReg, 'CombineReg');
  473. BlendRegistry.RegisterBinding(FID_COMBINEMEM, @@CombineMem, 'CombineMem');
  474. BlendRegistry.RegisterBinding(FID_COMBINELINE, @@CombineLine, 'CombineLine');
  475. BlendRegistry.RegisterBinding(FID_COLORMAX, @@ColorMax, 'ColorMax');
  476. BlendRegistry.RegisterBinding(FID_COLORMIN, @@ColorMin, 'ColorMin');
  477. BlendRegistry.RegisterBinding(FID_COLORAVERAGE, @@ColorAverage, 'ColorAverage');
  478. BlendRegistry.RegisterBinding(FID_COLORADD, @@ColorAdd, 'ColorAdd');
  479. BlendRegistry.RegisterBinding(FID_COLORSUB, @@ColorSub, 'ColorSub');
  480. BlendRegistry.RegisterBinding(FID_COLORDIV, @@ColorDiv, 'ColorDiv');
  481. BlendRegistry.RegisterBinding(FID_COLORMODULATE, @@ColorModulate, 'ColorModulate');
  482. BlendRegistry.RegisterBinding(FID_COLORDIFFERENCE, @@ColorDifference, 'ColorDifference');
  483. BlendRegistry.RegisterBinding(FID_COLOREXCLUSION, @@ColorExclusion, 'ColorExclusion');
  484. BlendRegistry.RegisterBinding(FID_COLORSCALE, @@ColorScale, 'ColorScale');
  485. BlendRegistry.RegisterBinding(FID_COLORSCREEN, @@ColorScreen, 'ColorScreen');
  486. BlendRegistry.RegisterBinding(FID_COLORDODGE, @@ColorDodge, 'ColorDodge');
  487. BlendRegistry.RegisterBinding(FID_COLORBURN, @@ColorBurn, 'ColorBurn');
  488. BlendRegistry.RegisterBinding(FID_BLENDCOLORADD, @@BlendColorAdd, 'BlendColorAdd');
  489. BlendRegistry.RegisterBinding(FID_BLENDCOLORMODULATE, @@BlendColorModulate, 'BlendColorModulate');
  490. BlendRegistry.RegisterBinding(FID_LIGHTEN, @@LightenReg, 'LightenReg');
  491. BlendRegistry.RegisterBinding(@@ScaleMems, 'ScaleMems');
  492. end;
  493. var
  494. FBlendRegistry: TFunctionRegistry = nil;
  495. function BlendRegistry: TFunctionRegistry;
  496. begin
  497. if (FBlendRegistry = nil) then
  498. begin
  499. FBlendRegistry := NewRegistry('GR32_Blend bindings');
  500. RegisterBindings;
  501. end;
  502. Result := FBlendRegistry;
  503. end;
  504. //------------------------------------------------------------------------------
  505. initialization
  506. BlendRegistry.RebindAll;
  507. MakeMergeTables;
  508. AlphaTable := nil;
  509. if [isSSE2] * CPU.InstructionSupport <> [] then
  510. GenAlphaTable;
  511. finalization
  512. FreeAlphaTable;
  513. end.