1 | unit GR32_Blend;
|
---|
2 |
|
---|
3 | (* ***** BEGIN LICENSE BLOCK *****
|
---|
4 | * Version: MPL 1.1 or LGPL 2.1 with linking exception
|
---|
5 | *
|
---|
6 | * The contents of this file are subject to the Mozilla Public License Version
|
---|
7 | * 1.1 (the "License"); you may not use this file except in compliance with
|
---|
8 | * the License. You may obtain a copy of the License at
|
---|
9 | * http://www.mozilla.org/MPL/
|
---|
10 | *
|
---|
11 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
12 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
13 | * for the specific language governing rights and limitations under the
|
---|
14 | * License.
|
---|
15 | *
|
---|
16 | * Alternatively, the contents of this file may be used under the terms of the
|
---|
17 | * Free Pascal modified version of the GNU Lesser General Public License
|
---|
18 | * Version 2.1 (the "FPC modified LGPL License"), in which case the provisions
|
---|
19 | * of this license are applicable instead of those above.
|
---|
20 | * Please see the file LICENSE.txt for additional information concerning this
|
---|
21 | * license.
|
---|
22 | *
|
---|
23 | * The Original Code is Graphics32
|
---|
24 | *
|
---|
25 | * The Initial Developer of the Original Code is
|
---|
26 | * Alex A. Denisov
|
---|
27 | *
|
---|
28 | * Portions created by the Initial Developer are Copyright (C) 2000-2009
|
---|
29 | * the Initial Developer. All Rights Reserved.
|
---|
30 | *
|
---|
31 | * Contributor(s):
|
---|
32 | * Mattias Andersson
|
---|
33 | * - 2004/07/07 - MMX Blendmodes
|
---|
34 | * - 2004/12/10 - _MergeReg, M_MergeReg
|
---|
35 | *
|
---|
36 | * Michael Hansen <dyster_tid@hotmail.com>
|
---|
37 | * - 2004/07/07 - Pascal Blendmodes, function setup
|
---|
38 | * - 2005/08/19 - New merge table concept and reference implementations
|
---|
39 | *
|
---|
40 | * Bob Voigt
|
---|
41 | * - 2004/08/25 - ColorDiv
|
---|
42 | *
|
---|
43 | * Christian-W. Budde
|
---|
44 | * - 2019/04/01 - Refactoring
|
---|
45 | *
|
---|
46 | * ***** END LICENSE BLOCK ***** *)
|
---|
47 |
|
---|
48 | interface
|
---|
49 |
|
---|
50 | {$I GR32.inc}
|
---|
51 |
|
---|
52 | uses
|
---|
53 | GR32, GR32_Bindings, SysUtils;
|
---|
54 |
|
---|
55 | var
|
---|
56 | MMX_ACTIVE: Boolean;
|
---|
57 |
|
---|
58 | type
|
---|
59 | { Function Prototypes }
|
---|
60 | TBlendReg = function(F, B: TColor32): TColor32;
|
---|
61 | TBlendMem = procedure(F: TColor32; var B: TColor32);
|
---|
62 | TBlendMems = procedure(F: TColor32; B: PColor32; Count: Integer);
|
---|
63 | TBlendRegEx = function(F, B, M: TColor32): TColor32;
|
---|
64 | TBlendMemEx = procedure(F: TColor32; var B: TColor32; M: TColor32);
|
---|
65 | TBlendRegRGB = function(F, B, W: TColor32): TColor32;
|
---|
66 | TBlendMemRGB = procedure(F: TColor32; var B: TColor32; W: TColor32);
|
---|
67 | {$IFDEF TEST_BLENDMEMRGB128SSE4}
|
---|
68 | TBlendMemRGB128 = procedure(F: TColor32; var B: TColor32; W: UInt64);
|
---|
69 | {$ENDIF}
|
---|
70 | TBlendLine = procedure(Src, Dst: PColor32; Count: Integer);
|
---|
71 | TBlendLineEx = procedure(Src, Dst: PColor32; Count: Integer; M: TColor32);
|
---|
72 | TBlendLine1 = procedure(Src: TColor32; Dst: PColor32; Count: Integer);
|
---|
73 | TCombineReg = function(X, Y, W: TColor32): TColor32;
|
---|
74 | TCombineMem = procedure(X: TColor32; var Y: TColor32; W: TColor32);
|
---|
75 | TCombineLine = procedure(Src, Dst: PColor32; Count: Integer; W: TColor32);
|
---|
76 | TLightenReg = function(C: TColor32; Amount: Integer): TColor32;
|
---|
77 |
|
---|
78 | var
|
---|
79 | {$IFNDEF OMIT_MMX}
|
---|
80 | EMMS: procedure;
|
---|
81 | {$ENDIF}
|
---|
82 |
|
---|
83 | { Function Variables }
|
---|
84 | BlendReg: TBlendReg;
|
---|
85 | BlendMem: TBlendMem;
|
---|
86 | BlendMems: TBlendMems;
|
---|
87 |
|
---|
88 | BlendRegEx: TBlendRegEx;
|
---|
89 | BlendMemEx: TBlendMemEx;
|
---|
90 |
|
---|
91 | BlendRegRGB: TBlendRegRGB;
|
---|
92 | BlendMemRGB: TBlendMemRGB;
|
---|
93 | {$IFDEF TEST_BLENDMEMRGB128SSE4}
|
---|
94 | BlendMemRGB128: TBlendMemRGB128;
|
---|
95 | {$ENDIF}
|
---|
96 |
|
---|
97 | BlendLine: TBlendLine;
|
---|
98 | BlendLineEx: TBlendLineEx;
|
---|
99 | BlendLine1: TBlendLine1;
|
---|
100 |
|
---|
101 | CombineReg: TCombineReg;
|
---|
102 | CombineMem: TCombineMem;
|
---|
103 | CombineLine: TCombineLine;
|
---|
104 |
|
---|
105 | MergeReg: TBlendReg;
|
---|
106 | MergeMem: TBlendMem;
|
---|
107 |
|
---|
108 | MergeRegEx: TBlendRegEx;
|
---|
109 | MergeMemEx: TBlendMemEx;
|
---|
110 |
|
---|
111 | MergeLine: TBlendLine;
|
---|
112 | MergeLineEx: TBlendLineEx;
|
---|
113 | MergeLine1: TBlendLine1;
|
---|
114 |
|
---|
115 | { Color algebra functions }
|
---|
116 | ColorAdd: TBlendReg;
|
---|
117 | ColorSub: TBlendReg;
|
---|
118 | ColorDiv: TBlendReg;
|
---|
119 | ColorModulate: TBlendReg;
|
---|
120 | ColorMax: TBlendReg;
|
---|
121 | ColorMin: TBlendReg;
|
---|
122 | ColorDifference: TBlendReg;
|
---|
123 | ColorAverage: TBlendReg;
|
---|
124 | ColorExclusion: TBlendReg;
|
---|
125 | ColorScale: TBlendReg;
|
---|
126 | ColorScreen: TBlendReg;
|
---|
127 | ColorDodge: TBlendReg;
|
---|
128 | ColorBurn: TBlendReg;
|
---|
129 |
|
---|
130 | { Blended color algebra functions }
|
---|
131 | BlendColorAdd: TBlendReg;
|
---|
132 | BlendColorModulate: TBlendReg;
|
---|
133 |
|
---|
134 | { Special LUT pointers }
|
---|
135 | AlphaTable: Pointer;
|
---|
136 | bias_ptr: Pointer;
|
---|
137 | alpha_ptr: Pointer;
|
---|
138 |
|
---|
139 |
|
---|
140 | { Misc stuff }
|
---|
141 | LightenReg: TLightenReg;
|
---|
142 |
|
---|
143 | function Lighten(C: TColor32; Amount: Integer): TColor32; {$IFDEF USEINLINING} inline; {$ENDIF}
|
---|
144 |
|
---|
145 | { Access to alpha composite functions corresponding to a combine mode }
|
---|
146 |
|
---|
147 | type
|
---|
148 | PBlendReg = ^TBlendReg;
|
---|
149 | PBlendMem = ^TBlendMem;
|
---|
150 | PBlendRegEx = ^TBlendRegEx;
|
---|
151 | PBlendMemEx = ^TBlendMemEx;
|
---|
152 | PBlendLine = ^TBlendLine;
|
---|
153 | PBlendLineEx = ^TBlendLineEx;
|
---|
154 |
|
---|
155 | TBlendRegCombineModeArray = array[TCombineMode] of PBlendReg;
|
---|
156 | TBlendMemCombineModeArray = array[TCombineMode] of PBlendMem;
|
---|
157 | TBlendRegExCombineModeArray = array[TCombineMode] of PBlendRegEx;
|
---|
158 | TBlendMemExCombineModeArray = array[TCombineMode] of PBlendMemEx;
|
---|
159 | TBlendLineCombineModeArray = array[TCombineMode] of PBlendLine;
|
---|
160 | TBlendLineExCombineModeArray = array[TCombineMode] of PBlendLineEx;
|
---|
161 |
|
---|
162 | const
|
---|
163 | BLEND_REG: TBlendRegCombineModeArray = ((@@BlendReg),(@@MergeReg));
|
---|
164 | BLEND_MEM: TBlendMemCombineModeArray = ((@@BlendMem),(@@MergeMem));
|
---|
165 | BLEND_REG_EX: TBlendRegExCombineModeArray = ((@@BlendRegEx),(@@MergeRegEx));
|
---|
166 | BLEND_MEM_EX: TBlendMemExCombineModeArray = ((@@BlendMemEx),(@@MergeMemEx));
|
---|
167 | BLEND_LINE: TBlendLineCombineModeArray = ((@@BlendLine),(@@MergeLine));
|
---|
168 | BLEND_LINE_EX: TBlendLineExCombineModeArray = ((@@BlendLineEx),(@@MergeLineEx));
|
---|
169 |
|
---|
170 | var
|
---|
171 | BlendRegistry: TFunctionRegistry;
|
---|
172 |
|
---|
173 | {$IFDEF OMIT_MMX}
|
---|
174 | procedure EMMS; {$IFDEF USEINLINING} inline; {$ENDIF}
|
---|
175 | {$ENDIF}
|
---|
176 |
|
---|
177 | var
|
---|
178 | RcTable: array [Byte, Byte] of Byte;
|
---|
179 | DivTable: array [Byte, Byte] of Byte;
|
---|
180 |
|
---|
181 | implementation
|
---|
182 |
|
---|
183 | uses
|
---|
184 | GR32_LowLevel,
|
---|
185 | {$IFNDEF PUREPASCAL}
|
---|
186 | GR32_BlendASM,
|
---|
187 | {$IFNDEF OMIT_MMX}
|
---|
188 | GR32_BlendMMX,
|
---|
189 | {$ENDIF}
|
---|
190 | {$IFNDEF OMIT_SSE2}
|
---|
191 | GR32_BlendSSE2,
|
---|
192 | {$ENDIF}
|
---|
193 | {$ENDIF}
|
---|
194 | GR32_System;
|
---|
195 |
|
---|
196 | {$IFDEF OMIT_MMX}
|
---|
197 | procedure EMMS;
|
---|
198 | begin
|
---|
199 | end;
|
---|
200 | {$ENDIF}
|
---|
201 |
|
---|
202 | { Pure Pascal }
|
---|
203 |
|
---|
204 | function BlendReg_Pas(F, B: TColor32): TColor32;
|
---|
205 | var
|
---|
206 | FX: TColor32Entry absolute F;
|
---|
207 | BX: TColor32Entry absolute B;
|
---|
208 | Af, Ab: PByteArray;
|
---|
209 | FA : Byte;
|
---|
210 | begin
|
---|
211 | FA := FX.A;
|
---|
212 |
|
---|
213 | if FA = 0 then
|
---|
214 | begin
|
---|
215 | Result := B;
|
---|
216 | Exit;
|
---|
217 | end;
|
---|
218 |
|
---|
219 | if FA = $FF then
|
---|
220 | begin
|
---|
221 | Result := F;
|
---|
222 | Exit;
|
---|
223 | end;
|
---|
224 |
|
---|
225 | Af := @DivTable[FA];
|
---|
226 | Ab := @DivTable[not FA];
|
---|
227 | with BX do
|
---|
228 | begin
|
---|
229 | R := Af[FX.R] + Ab[R];
|
---|
230 | G := Af[FX.G] + Ab[G];
|
---|
231 | B := Af[FX.B] + Ab[B];
|
---|
232 | A := $FF;
|
---|
233 | end;
|
---|
234 | Result := B;
|
---|
235 | end;
|
---|
236 |
|
---|
237 | procedure BlendMem_Pas(F: TColor32; var B: TColor32);
|
---|
238 | var
|
---|
239 | FX: TColor32Entry absolute F;
|
---|
240 | BX: TColor32Entry absolute B;
|
---|
241 | Af, Ab: PByteArray;
|
---|
242 | FA : Byte;
|
---|
243 | begin
|
---|
244 | FA := FX.A;
|
---|
245 |
|
---|
246 | if FA = 0 then Exit;
|
---|
247 |
|
---|
248 | if FA = $FF then
|
---|
249 | begin
|
---|
250 | B := F;
|
---|
251 | Exit;
|
---|
252 | end;
|
---|
253 |
|
---|
254 | Af := @DivTable[FA];
|
---|
255 | Ab := @DivTable[not FA];
|
---|
256 | with BX do
|
---|
257 | begin
|
---|
258 | R := Af[FX.R] + Ab[R];
|
---|
259 | G := Af[FX.G] + Ab[G];
|
---|
260 | B := Af[FX.B] + Ab[B];
|
---|
261 | A := $FF;
|
---|
262 | end;
|
---|
263 | end;
|
---|
264 |
|
---|
265 | procedure BlendMems_Pas(F: TColor32; B: PColor32; Count: Integer);
|
---|
266 | begin
|
---|
267 | while Count > 0 do
|
---|
268 | begin
|
---|
269 | BlendMem(F, B^);
|
---|
270 | Inc(B);
|
---|
271 | Dec(Count);
|
---|
272 | end;
|
---|
273 | end;
|
---|
274 |
|
---|
275 | function BlendRegEx_Pas(F, B, M: TColor32): TColor32;
|
---|
276 | var
|
---|
277 | FX: TColor32Entry absolute F;
|
---|
278 | BX: TColor32Entry absolute B;
|
---|
279 | Af, Ab: PByteArray;
|
---|
280 | begin
|
---|
281 | Af := @DivTable[M];
|
---|
282 |
|
---|
283 | M := Af[FX.A];
|
---|
284 |
|
---|
285 | if M = 0 then
|
---|
286 | begin
|
---|
287 | Result := B;
|
---|
288 | Exit;
|
---|
289 | end;
|
---|
290 |
|
---|
291 | if M = $FF then
|
---|
292 | begin
|
---|
293 | Result := F;
|
---|
294 | Exit;
|
---|
295 | end;
|
---|
296 |
|
---|
297 | Ab := @DivTable[255 - M];
|
---|
298 | with BX do
|
---|
299 | begin
|
---|
300 | R := Af[FX.R] + Ab[R];
|
---|
301 | G := Af[FX.G] + Ab[G];
|
---|
302 | B := Af[FX.B] + Ab[B];
|
---|
303 | A := $FF;
|
---|
304 | end;
|
---|
305 | Result := B;
|
---|
306 | end;
|
---|
307 |
|
---|
308 | procedure BlendMemEx_Pas(F: TColor32; var B: TColor32; M: TColor32);
|
---|
309 | var
|
---|
310 | FX: TColor32Entry absolute F;
|
---|
311 | BX: TColor32Entry absolute B;
|
---|
312 | Af, Ab: PByteArray;
|
---|
313 | begin
|
---|
314 | Af := @DivTable[M];
|
---|
315 |
|
---|
316 | M := Af[FX.A];
|
---|
317 |
|
---|
318 | if M = 0 then
|
---|
319 | begin
|
---|
320 | Exit;
|
---|
321 | end;
|
---|
322 |
|
---|
323 | if M = $FF then
|
---|
324 | begin
|
---|
325 | B := F;
|
---|
326 | Exit;
|
---|
327 | end;
|
---|
328 |
|
---|
329 | Ab := @DivTable[255 - M];
|
---|
330 | with BX do
|
---|
331 | begin
|
---|
332 | R := Af[FX.R] + Ab[R];
|
---|
333 | G := Af[FX.G] + Ab[G];
|
---|
334 | B := Af[FX.B] + Ab[B];
|
---|
335 | A := $FF;
|
---|
336 | end;
|
---|
337 | end;
|
---|
338 |
|
---|
339 | function BlendRegRGB_Pas(F, B, W: TColor32): TColor32;
|
---|
340 | var
|
---|
341 | FX: TColor32Entry absolute F;
|
---|
342 | BX: TColor32Entry absolute B;
|
---|
343 | WX: TColor32Entry absolute W;
|
---|
344 | RX: TColor32Entry absolute Result;
|
---|
345 | begin
|
---|
346 | RX.R := (FX.R - BX.R) * WX.B div 255 + BX.R;
|
---|
347 | RX.G := (FX.G - BX.G) * WX.G div 255 + BX.G;
|
---|
348 | RX.B := (FX.B - BX.B) * WX.R div 255 + BX.B;
|
---|
349 | end;
|
---|
350 |
|
---|
351 | procedure BlendMemRGB_Pas(F: TColor32; var B: TColor32; W: TColor32);
|
---|
352 | var
|
---|
353 | FX: TColor32Entry absolute F;
|
---|
354 | BX: TColor32Entry absolute B;
|
---|
355 | WX: TColor32Entry absolute W;
|
---|
356 | begin
|
---|
357 | BX.R := (FX.R - BX.R) * WX.B div 255 + BX.R;
|
---|
358 | BX.G := (FX.G - BX.G) * WX.G div 255 + BX.G;
|
---|
359 | BX.B := (FX.B - BX.B) * WX.R div 255 + BX.B;
|
---|
360 | end;
|
---|
361 |
|
---|
362 | procedure BlendLine1_Pas(Src: TColor32; Dst: PColor32; Count: Integer);
|
---|
363 | begin
|
---|
364 | while Count > 0 do
|
---|
365 | begin
|
---|
366 | BlendMem(Src, Dst^);
|
---|
367 | Inc(Dst);
|
---|
368 | Dec(Count);
|
---|
369 | end;
|
---|
370 | end;
|
---|
371 |
|
---|
372 | procedure BlendLine_Pas(Src, Dst: PColor32; Count: Integer);
|
---|
373 | begin
|
---|
374 | while Count > 0 do
|
---|
375 | begin
|
---|
376 | BlendMem(Src^, Dst^);
|
---|
377 | Inc(Src);
|
---|
378 | Inc(Dst);
|
---|
379 | Dec(Count);
|
---|
380 | end;
|
---|
381 | end;
|
---|
382 |
|
---|
383 | procedure BlendLineEx_Pas(Src, Dst: PColor32; Count: Integer; M: TColor32);
|
---|
384 | begin
|
---|
385 | while Count > 0 do
|
---|
386 | begin
|
---|
387 | BlendMemEx(Src^, Dst^, M);
|
---|
388 | Inc(Src);
|
---|
389 | Inc(Dst);
|
---|
390 | Dec(Count);
|
---|
391 | end;
|
---|
392 | end;
|
---|
393 |
|
---|
394 | function CombineReg_Pas(X, Y, W: TColor32): TColor32;
|
---|
395 | var
|
---|
396 | Xe: TColor32Entry absolute X;
|
---|
397 | Ye: TColor32Entry absolute Y;
|
---|
398 | Af, Ab: PByteArray;
|
---|
399 | begin
|
---|
400 | if W = 0 then
|
---|
401 | begin
|
---|
402 | Result := Y;
|
---|
403 | Exit;
|
---|
404 | end;
|
---|
405 |
|
---|
406 | if W >= $FF then
|
---|
407 | begin
|
---|
408 | Result := X;
|
---|
409 | Exit;
|
---|
410 | end;
|
---|
411 |
|
---|
412 | Af := @DivTable[W];
|
---|
413 | Ab := @DivTable[255 - W];
|
---|
414 | with Xe do
|
---|
415 | begin
|
---|
416 | R := Ab[Ye.R] + Af[R];
|
---|
417 | G := Ab[Ye.G] + Af[G];
|
---|
418 | B := Ab[Ye.B] + Af[B];
|
---|
419 | A := Ab[Ye.A] + Af[A];
|
---|
420 | end;
|
---|
421 | Result := X;
|
---|
422 | end;
|
---|
423 |
|
---|
424 | procedure CombineMem_Pas(X: TColor32; var Y: TColor32; W: TColor32);
|
---|
425 | var
|
---|
426 | Xe: TColor32Entry absolute X;
|
---|
427 | Ye: TColor32Entry absolute Y;
|
---|
428 | Af, Ab: PByteArray;
|
---|
429 | begin
|
---|
430 | if W = 0 then
|
---|
431 | begin
|
---|
432 | Exit;
|
---|
433 | end;
|
---|
434 |
|
---|
435 | if W >= $FF then
|
---|
436 | begin
|
---|
437 | Y := X;
|
---|
438 | Exit;
|
---|
439 | end;
|
---|
440 |
|
---|
441 | Af := @DivTable[W];
|
---|
442 | Ab := @DivTable[255 - W];
|
---|
443 | with Xe do
|
---|
444 | begin
|
---|
445 | R := Ab[Ye.R] + Af[R];
|
---|
446 | G := Ab[Ye.G] + Af[G];
|
---|
447 | B := Ab[Ye.B] + Af[B];
|
---|
448 | A := Ab[Ye.A] + Af[A];
|
---|
449 | end;
|
---|
450 | Y := X;
|
---|
451 | end;
|
---|
452 |
|
---|
453 | procedure CombineLine_Pas(Src, Dst: PColor32; Count: Integer; W: TColor32);
|
---|
454 | begin
|
---|
455 | while Count > 0 do
|
---|
456 | begin
|
---|
457 | CombineMem(Src^, Dst^, W);
|
---|
458 | Inc(Src);
|
---|
459 | Inc(Dst);
|
---|
460 | Dec(Count);
|
---|
461 | end;
|
---|
462 | end;
|
---|
463 |
|
---|
464 | function MergeReg_Pas(F, B: TColor32): TColor32;
|
---|
465 | var
|
---|
466 | Fa, Ba, Wa: TColor32;
|
---|
467 | Fw, Bw: PByteArray;
|
---|
468 | Fx: TColor32Entry absolute F;
|
---|
469 | Bx: TColor32Entry absolute B;
|
---|
470 | Rx: TColor32Entry absolute Result;
|
---|
471 | begin
|
---|
472 | Fa := F shr 24;
|
---|
473 | Ba := B shr 24;
|
---|
474 | if Fa = $FF then
|
---|
475 | Result := F
|
---|
476 | else if Fa = $0 then
|
---|
477 | Result := B
|
---|
478 | else if Ba = $0 then
|
---|
479 | Result := F
|
---|
480 | else
|
---|
481 | begin
|
---|
482 | Rx.A := DivTable[Fa xor 255, Ba xor 255] xor 255;
|
---|
483 | Wa := RcTable[Rx.A, Fa];
|
---|
484 | Fw := @DivTable[Wa];
|
---|
485 | Bw := @DivTable[Wa xor $FF];
|
---|
486 | Rx.R := Fw[Fx.R] + Bw[Bx.R];
|
---|
487 | Rx.G := Fw[Fx.G] + Bw[Bx.G];
|
---|
488 | Rx.B := Fw[Fx.B] + Bw[Bx.B];
|
---|
489 | end;
|
---|
490 | end;
|
---|
491 |
|
---|
492 | function MergeRegEx_Pas(F, B, M: TColor32): TColor32;
|
---|
493 | begin
|
---|
494 | Result := MergeReg(DivTable[M, F shr 24] shl 24 or F and $00FFFFFF, B);
|
---|
495 | end;
|
---|
496 |
|
---|
497 | procedure MergeMem_Pas(F: TColor32; var B: TColor32);
|
---|
498 | begin
|
---|
499 | B := MergeReg(F, B);
|
---|
500 | end;
|
---|
501 |
|
---|
502 | procedure MergeMemEx_Pas(F: TColor32; var B: TColor32; M: TColor32);
|
---|
503 | begin
|
---|
504 | B := MergeReg(DivTable[M, F shr 24] shl 24 or F and $00FFFFFF, B);
|
---|
505 | end;
|
---|
506 |
|
---|
507 | procedure MergeLine1_Pas(Src: TColor32; Dst: PColor32; Count: Integer);
|
---|
508 | begin
|
---|
509 | while Count > 0 do
|
---|
510 | begin
|
---|
511 | Dst^ := MergeReg(Src, Dst^);
|
---|
512 | Inc(Dst);
|
---|
513 | Dec(Count);
|
---|
514 | end;
|
---|
515 | end;
|
---|
516 |
|
---|
517 | procedure MergeLine_Pas(Src, Dst: PColor32; Count: Integer);
|
---|
518 | begin
|
---|
519 | while Count > 0 do
|
---|
520 | begin
|
---|
521 | Dst^ := MergeReg(Src^, Dst^);
|
---|
522 | Inc(Src);
|
---|
523 | Inc(Dst);
|
---|
524 | Dec(Count);
|
---|
525 | end;
|
---|
526 | end;
|
---|
527 |
|
---|
528 | procedure MergeLineEx_Pas(Src, Dst: PColor32; Count: Integer; M: TColor32);
|
---|
529 | var
|
---|
530 | PM: PByteArray absolute M;
|
---|
531 | begin
|
---|
532 | PM := @DivTable[M];
|
---|
533 | while Count > 0 do
|
---|
534 | begin
|
---|
535 | Dst^ := MergeReg((PM[Src^ shr 24] shl 24) or (Src^ and $00FFFFFF), Dst^);
|
---|
536 | Inc(Src);
|
---|
537 | Inc(Dst);
|
---|
538 | Dec(Count);
|
---|
539 | end;
|
---|
540 | end;
|
---|
541 |
|
---|
542 | procedure EMMS_Pas;
|
---|
543 | begin
|
---|
544 | // Dummy
|
---|
545 | end;
|
---|
546 |
|
---|
547 | function LightenReg_Pas(C: TColor32; Amount: Integer): TColor32;
|
---|
548 | var
|
---|
549 | r, g, b: Integer;
|
---|
550 | CX: TColor32Entry absolute C;
|
---|
551 | RX: TColor32Entry absolute Result;
|
---|
552 | begin
|
---|
553 | r := CX.R;
|
---|
554 | g := CX.G;
|
---|
555 | b := CX.B;
|
---|
556 |
|
---|
557 | Inc(r, Amount);
|
---|
558 | Inc(g, Amount);
|
---|
559 | Inc(b, Amount);
|
---|
560 |
|
---|
561 | if r > 255 then r := 255 else if r < 0 then r := 0;
|
---|
562 | if g > 255 then g := 255 else if g < 0 then g := 0;
|
---|
563 | if b > 255 then b := 255 else if b < 0 then b := 0;
|
---|
564 |
|
---|
565 | // preserve alpha
|
---|
566 | RX.A := CX.A;
|
---|
567 | RX.R := r;
|
---|
568 | RX.G := g;
|
---|
569 | RX.B := b;
|
---|
570 | end;
|
---|
571 |
|
---|
572 | { Color algebra }
|
---|
573 |
|
---|
574 | function ColorAdd_Pas(C1, C2: TColor32): TColor32;
|
---|
575 | var
|
---|
576 | Xe: TColor32Entry absolute C1;
|
---|
577 | Ye: TColor32Entry absolute C2;
|
---|
578 | R: TColor32Entry absolute Result;
|
---|
579 | begin
|
---|
580 | R.A := Clamp(Xe.A + Ye.A, 255);
|
---|
581 | R.R := Clamp(Xe.R + Ye.R, 255);
|
---|
582 | R.G := Clamp(Xe.G + Ye.G, 255);
|
---|
583 | R.B := Clamp(Xe.B + Ye.B, 255);
|
---|
584 | end;
|
---|
585 |
|
---|
586 | function ColorSub_Pas(C1, C2: TColor32): TColor32;
|
---|
587 | var
|
---|
588 | Xe: TColor32Entry absolute C1;
|
---|
589 | Ye: TColor32Entry absolute C2;
|
---|
590 | R: TColor32Entry absolute Result;
|
---|
591 | Temp: SmallInt;
|
---|
592 | begin
|
---|
593 | Temp := Xe.A - Ye.A;
|
---|
594 | if Temp < 0 then
|
---|
595 | R.A := 0
|
---|
596 | else
|
---|
597 | R.A := Temp;
|
---|
598 | Temp := Xe.R - Ye.R;
|
---|
599 | if Temp < 0 then
|
---|
600 | R.R := 0
|
---|
601 | else
|
---|
602 | R.R := Temp;
|
---|
603 | Temp := Xe.G - Ye.G;
|
---|
604 | if Temp < 0 then
|
---|
605 | R.G := 0
|
---|
606 | else
|
---|
607 | R.G := Temp;
|
---|
608 | Temp := Xe.B - Ye.B;
|
---|
609 | if Temp < 0 then
|
---|
610 | R.B := 0
|
---|
611 | else
|
---|
612 | R.B := Temp;
|
---|
613 | end;
|
---|
614 |
|
---|
615 | function ColorDiv_Pas(C1, C2: TColor32): TColor32;
|
---|
616 | var
|
---|
617 | C1e: TColor32Entry absolute C1;
|
---|
618 | C2e: TColor32Entry absolute C2;
|
---|
619 | Re: TColor32Entry absolute Result;
|
---|
620 | Temp: Word;
|
---|
621 | begin
|
---|
622 | if C1e.A = 0 then
|
---|
623 | Re.A := $FF
|
---|
624 | else
|
---|
625 | begin
|
---|
626 | Temp := (C2e.A shl 8) div C1e.A;
|
---|
627 | if Temp > $FF then
|
---|
628 | Re.A := $FF
|
---|
629 | else
|
---|
630 | Re.A := Temp;
|
---|
631 | end;
|
---|
632 |
|
---|
633 | if C1e.R = 0 then
|
---|
634 | Re.R := $FF
|
---|
635 | else
|
---|
636 | begin
|
---|
637 | Temp := (C2e.R shl 8) div C1e.R;
|
---|
638 | if Temp > $FF then
|
---|
639 | Re.R := $FF
|
---|
640 | else
|
---|
641 | Re.R := Temp;
|
---|
642 | end;
|
---|
643 |
|
---|
644 | if C1e.G = 0 then
|
---|
645 | Re.G := $FF
|
---|
646 | else
|
---|
647 | begin
|
---|
648 | Temp := (C2e.G shl 8) div C1e.G;
|
---|
649 | if Temp > $FF then
|
---|
650 | Re.G := $FF
|
---|
651 | else
|
---|
652 | Re.G := Temp;
|
---|
653 | end;
|
---|
654 |
|
---|
655 | if C1e.B = 0 then
|
---|
656 | Re.B := $FF
|
---|
657 | else
|
---|
658 | begin
|
---|
659 | Temp := (C2e.B shl 8) div C1e.B;
|
---|
660 | if Temp > $FF then
|
---|
661 | Re.B := $FF
|
---|
662 | else
|
---|
663 | Re.B := Temp;
|
---|
664 | end;
|
---|
665 | end;
|
---|
666 |
|
---|
667 | function ColorModulate_Pas(C1, C2: TColor32): TColor32;
|
---|
668 | var
|
---|
669 | C1e: TColor32Entry absolute C2;
|
---|
670 | C2e: TColor32Entry absolute C2;
|
---|
671 | Re: TColor32Entry absolute Result;
|
---|
672 | begin
|
---|
673 | Re.A := (C2e.A * C1e.A + $80) shr 8;
|
---|
674 | Re.R := (C2e.R * C1e.R + $80) shr 8;
|
---|
675 | Re.G := (C2e.G * C1e.G + $80) shr 8;
|
---|
676 | Re.B := (C2e.B * C1e.B + $80) shr 8;
|
---|
677 | end;
|
---|
678 |
|
---|
679 | function ColorMax_Pas(C1, C2: TColor32): TColor32;
|
---|
680 | var
|
---|
681 | REnt: TColor32Entry absolute Result;
|
---|
682 | C2Ent: TColor32Entry absolute C2;
|
---|
683 | begin
|
---|
684 | Result := C1;
|
---|
685 | with C2Ent do
|
---|
686 | begin
|
---|
687 | if A > REnt.A then REnt.A := A;
|
---|
688 | if R > REnt.R then REnt.R := R;
|
---|
689 | if G > REnt.G then REnt.G := G;
|
---|
690 | if B > REnt.B then REnt.B := B;
|
---|
691 | end;
|
---|
692 | end;
|
---|
693 |
|
---|
694 | function ColorMin_Pas(C1, C2: TColor32): TColor32;
|
---|
695 | var
|
---|
696 | REnt: TColor32Entry absolute Result;
|
---|
697 | C2Ent: TColor32Entry absolute C2;
|
---|
698 | begin
|
---|
699 | Result := C1;
|
---|
700 | with C2Ent do
|
---|
701 | begin
|
---|
702 | if A < REnt.A then REnt.A := A;
|
---|
703 | if R < REnt.R then REnt.R := R;
|
---|
704 | if G < REnt.G then REnt.G := G;
|
---|
705 | if B < REnt.B then REnt.B := B;
|
---|
706 | end;
|
---|
707 | end;
|
---|
708 |
|
---|
709 | function ColorDifference_Pas(C1, C2: TColor32): TColor32;
|
---|
710 | var
|
---|
711 | Xe: TColor32Entry absolute C1;
|
---|
712 | Ye: TColor32Entry absolute C2;
|
---|
713 | R: TColor32Entry absolute Result;
|
---|
714 | begin
|
---|
715 | R.A := Abs(Xe.A - Ye.A);
|
---|
716 | R.R := Abs(Xe.R - Ye.R);
|
---|
717 | R.G := Abs(Xe.G - Ye.G);
|
---|
718 | R.B := Abs(Xe.B - Ye.B);
|
---|
719 | end;
|
---|
720 |
|
---|
721 | function ColorExclusion_Pas(C1, C2: TColor32): TColor32;
|
---|
722 | var
|
---|
723 | Xe: TColor32Entry absolute C1;
|
---|
724 | Ye: TColor32Entry absolute C2;
|
---|
725 | R: TColor32Entry absolute Result;
|
---|
726 | begin
|
---|
727 | R.A := Xe.A + Ye.A - ((Xe.A * Ye.A) shl 7);
|
---|
728 | R.R := Xe.R + Ye.R - ((Xe.R * Ye.R) shr 7);
|
---|
729 | R.G := Xe.G + Ye.G - ((Xe.G * Ye.G) shr 7);
|
---|
730 | R.B := Xe.B + Ye.B - ((Xe.B * Ye.B) shr 7);
|
---|
731 | end;
|
---|
732 |
|
---|
733 | function ColorAverage_Pas(C1, C2: TColor32): TColor32;
|
---|
734 | //(A + B)/2 = (A and B) + (A xor B)/2
|
---|
735 | var
|
---|
736 | C3 : TColor32;
|
---|
737 | begin
|
---|
738 | C3 := C1;
|
---|
739 | C1 := C1 xor C2;
|
---|
740 | C1 := C1 shr 1;
|
---|
741 | C1 := C1 and $7F7F7F7F;
|
---|
742 | C3 := C3 and C2;
|
---|
743 | Result := C3 + C1;
|
---|
744 | end;
|
---|
745 |
|
---|
746 | function ColorScale_Pas(C, W: TColor32): TColor32;
|
---|
747 | var
|
---|
748 | Ce: TColor32Entry absolute C;
|
---|
749 | var
|
---|
750 | r1, g1, b1, a1: Cardinal;
|
---|
751 | begin
|
---|
752 | a1 := Ce.A * W shr 8;
|
---|
753 | r1 := Ce.R * W shr 8;
|
---|
754 | g1 := Ce.G * W shr 8;
|
---|
755 | b1 := Ce.B * W shr 8;
|
---|
756 |
|
---|
757 | if a1 > 255 then a1 := 255;
|
---|
758 | if r1 > 255 then r1 := 255;
|
---|
759 | if g1 > 255 then g1 := 255;
|
---|
760 | if b1 > 255 then b1 := 255;
|
---|
761 |
|
---|
762 | Result := a1 shl 24 + r1 shl 16 + g1 shl 8 + b1;
|
---|
763 | end;
|
---|
764 |
|
---|
765 | function ColorScreen_Pas(B, S: TColor32): TColor32;
|
---|
766 | var
|
---|
767 | Be: TColor32Entry absolute B;
|
---|
768 | Se: TColor32Entry absolute S;
|
---|
769 | R: TColor32Entry absolute Result;
|
---|
770 | begin
|
---|
771 | R.A := Be.A + Se.A - (Be.A * Se.A) div 255;
|
---|
772 | R.R := Be.R + Se.R - (Be.R * Se.R) div 255;
|
---|
773 | R.G := Be.G + Se.G - (Be.G * Se.G) div 255;
|
---|
774 | R.B := Be.B + Se.B - (Be.B * Se.B) div 255;
|
---|
775 | end;
|
---|
776 |
|
---|
777 | function ColorDodge_Pas(B, S: TColor32): TColor32;
|
---|
778 |
|
---|
779 | function Dodge(B, S: Byte): Byte;
|
---|
780 | begin
|
---|
781 | if B = 0 then
|
---|
782 | Result := 0
|
---|
783 | else
|
---|
784 | if S = 255 then
|
---|
785 | Result := 255
|
---|
786 | else
|
---|
787 | Result := Clamp((255 * B) div (255 - S), 255);
|
---|
788 | end;
|
---|
789 |
|
---|
790 | var
|
---|
791 | Be: TColor32Entry absolute B;
|
---|
792 | Se: TColor32Entry absolute S;
|
---|
793 | R: TColor32Entry absolute Result;
|
---|
794 | begin
|
---|
795 | R.A := Dodge(Be.A, Se.A);
|
---|
796 | R.R := Dodge(Be.R, Se.R);
|
---|
797 | R.G := Dodge(Be.G, Se.G);
|
---|
798 | R.B := Dodge(Be.B, Se.B);
|
---|
799 | end;
|
---|
800 |
|
---|
801 | function ColorBurn_Pas(B, S: TColor32): TColor32;
|
---|
802 |
|
---|
803 | function Burn(B, S: Byte): Byte;
|
---|
804 | begin
|
---|
805 | if B = 255 then
|
---|
806 | Result := 255
|
---|
807 | else
|
---|
808 | if S = 0 then
|
---|
809 | Result := 0
|
---|
810 | else
|
---|
811 | Result := 255 - Clamp(255 * (255 - B) div S, 255);
|
---|
812 | end;
|
---|
813 |
|
---|
814 | var
|
---|
815 | Be: TColor32Entry absolute B;
|
---|
816 | Se: TColor32Entry absolute S;
|
---|
817 | R: TColor32Entry absolute Result;
|
---|
818 | begin
|
---|
819 | R.A := Burn(Be.A, Se.A);
|
---|
820 | R.R := Burn(Be.R, Se.R);
|
---|
821 | R.G := Burn(Be.G, Se.G);
|
---|
822 | R.B := Burn(Be.B, Se.B);
|
---|
823 | end;
|
---|
824 |
|
---|
825 |
|
---|
826 | { Blended color algebra }
|
---|
827 |
|
---|
828 | function BlendColorAdd_Pas(C1, C2: TColor32): TColor32;
|
---|
829 | var
|
---|
830 | Xe: TColor32Entry absolute C1;
|
---|
831 | Ye: TColor32Entry absolute C2;
|
---|
832 | R: TColor32Entry absolute Result;
|
---|
833 | Af, Ab: PByteArray;
|
---|
834 | begin
|
---|
835 | Af := @DivTable[Xe.A];
|
---|
836 | Ab := @DivTable[not Xe.A];
|
---|
837 | R.A := Af[Clamp(Xe.A + Ye.A, 255)] + Ab[Ye.A];
|
---|
838 | R.R := Af[Clamp(Xe.R + Ye.R, 255)] + Ab[Ye.R];
|
---|
839 | R.G := Af[Clamp(Xe.G + Ye.G, 255)] + Ab[Ye.G];
|
---|
840 | R.B := Af[Clamp(Xe.B + Ye.B, 255)] + Ab[Ye.B];
|
---|
841 | end;
|
---|
842 |
|
---|
843 | function BlendColorModulate_Pas(C1, C2: TColor32): TColor32;
|
---|
844 | var
|
---|
845 | C1e: TColor32Entry absolute C1;
|
---|
846 | C2e: TColor32Entry absolute C2;
|
---|
847 | R: TColor32Entry absolute Result;
|
---|
848 | Af, Ab: PByteArray;
|
---|
849 | begin
|
---|
850 | Af := @DivTable[C1e.A];
|
---|
851 | Ab := @DivTable[not C1e.A];
|
---|
852 | R.A := Af[(C2e.A * C1e.A + $80) shr 8] + Ab[C2e.A];
|
---|
853 | R.R := Af[(C2e.R * C1e.R + $80) shr 8] + Ab[C2e.R];
|
---|
854 | R.G := Af[(C2e.G * C1e.G + $80) shr 8] + Ab[C2e.G];
|
---|
855 | R.B := Af[(C2e.B * C1e.B + $80) shr 8] + Ab[C2e.B];
|
---|
856 | end;
|
---|
857 |
|
---|
858 | {$IFNDEF PUREPASCAL}
|
---|
859 |
|
---|
860 | procedure GenAlphaTable;
|
---|
861 | var
|
---|
862 | I: Integer;
|
---|
863 | L: LongWord;
|
---|
864 | P: PLongWord;
|
---|
865 | begin
|
---|
866 | GetMem(AlphaTable, 257 * 8 * SizeOf(Cardinal));
|
---|
867 | {$IFDEF HAS_NATIVEINT}
|
---|
868 | alpha_ptr := Pointer(NativeUInt(AlphaTable) and (not $F));
|
---|
869 | if NativeUInt(alpha_ptr) < NativeUInt(AlphaTable) then
|
---|
870 | alpha_ptr := Pointer(NativeUInt(alpha_ptr) + 16);
|
---|
871 | {$ELSE}
|
---|
872 | alpha_ptr := Pointer(Cardinal(AlphaTable) and (not $F));
|
---|
873 | if Cardinal(alpha_ptr) < Cardinal(AlphaTable) then
|
---|
874 | Inc(Cardinal(alpha_ptr), 16);
|
---|
875 | {$ENDIF}
|
---|
876 | P := alpha_ptr;
|
---|
877 | for I := 0 to 255 do
|
---|
878 | begin
|
---|
879 | L := I + I shl 16;
|
---|
880 | P^ := L;
|
---|
881 | Inc(P);
|
---|
882 | P^ := L;
|
---|
883 | Inc(P);
|
---|
884 | P^ := L;
|
---|
885 | Inc(P);
|
---|
886 | P^ := L;
|
---|
887 | Inc(P);
|
---|
888 | end;
|
---|
889 | bias_ptr := alpha_ptr;
|
---|
890 | Inc(PLongWord(bias_ptr), 4 * $80);
|
---|
891 | end;
|
---|
892 |
|
---|
893 | procedure FreeAlphaTable;
|
---|
894 | begin
|
---|
895 | FreeMem(AlphaTable);
|
---|
896 | end;
|
---|
897 | {$ENDIF}
|
---|
898 |
|
---|
899 | { Misc stuff }
|
---|
900 |
|
---|
901 | function Lighten(C: TColor32; Amount: Integer): TColor32;
|
---|
902 | begin
|
---|
903 | Result := LightenReg(C, Amount);
|
---|
904 | end;
|
---|
905 |
|
---|
906 | procedure MakeMergeTables;
|
---|
907 | var
|
---|
908 | I, J: Integer;
|
---|
909 | begin
|
---|
910 | for J := 0 to 255 do
|
---|
911 | begin
|
---|
912 | DivTable[0, J] := 0;
|
---|
913 | RcTable[0, J] := 0;
|
---|
914 | end;
|
---|
915 | for J := 0 to 255 do
|
---|
916 | for I := 1 to 255 do
|
---|
917 | begin
|
---|
918 | DivTable[I, J] := Round(I * J * COne255th);
|
---|
919 | RcTable[I, J] := Round(J * 255 / I)
|
---|
920 | end;
|
---|
921 | end;
|
---|
922 |
|
---|
923 | const
|
---|
924 | FID_EMMS = 0;
|
---|
925 | FID_MERGEREG = 1;
|
---|
926 | FID_MERGEMEM = 2;
|
---|
927 | FID_MERGELINE = 3;
|
---|
928 | FID_MERGELINE1 = 4;
|
---|
929 | FID_MERGEREGEX = 5;
|
---|
930 | FID_MERGEMEMEX = 6;
|
---|
931 | FID_MERGELINEEX = 7;
|
---|
932 | FID_COMBINEREG = 8;
|
---|
933 | FID_COMBINEMEM = 9;
|
---|
934 | FID_COMBINELINE = 10;
|
---|
935 |
|
---|
936 | FID_BLENDREG = 11;
|
---|
937 | FID_BLENDMEM = 12;
|
---|
938 | FID_BLENDMEMS = 13;
|
---|
939 | FID_BLENDLINE = 14;
|
---|
940 | FID_BLENDREGEX = 15;
|
---|
941 | FID_BLENDMEMEX = 16;
|
---|
942 | FID_BLENDLINEEX = 17;
|
---|
943 | FID_BLENDLINE1 = 18;
|
---|
944 |
|
---|
945 | FID_COLORMAX = 19;
|
---|
946 | FID_COLORMIN = 20;
|
---|
947 | FID_COLORAVERAGE = 21;
|
---|
948 | FID_COLORADD = 22;
|
---|
949 | FID_COLORSUB = 23;
|
---|
950 | FID_COLORDIV = 24;
|
---|
951 | FID_COLORMODULATE = 25;
|
---|
952 | FID_COLORDIFFERENCE = 26;
|
---|
953 | FID_COLOREXCLUSION = 27;
|
---|
954 | FID_COLORSCALE = 28;
|
---|
955 | FID_COLORSCREEN = 29;
|
---|
956 | FID_COLORDODGE = 30;
|
---|
957 | FID_COLORBURN = 31;
|
---|
958 | FID_BLENDCOLORADD = 32;
|
---|
959 | FID_BLENDCOLORMODULATE = 33;
|
---|
960 | FID_LIGHTEN = 34;
|
---|
961 |
|
---|
962 | FID_BLENDREGRGB = 35;
|
---|
963 | FID_BLENDMEMRGB = 36;
|
---|
964 | {$IFDEF TEST_BLENDMEMRGB128SSE4}
|
---|
965 | FID_BLENDMEMRGB128 = 37;
|
---|
966 | {$ENDIF}
|
---|
967 |
|
---|
968 | const
|
---|
969 | BlendBindingFlagPascal = $0001;
|
---|
970 |
|
---|
971 |
|
---|
972 | procedure RegisterBindings;
|
---|
973 | begin
|
---|
974 | BlendRegistry := NewRegistry('GR32_Blend bindings');
|
---|
975 | {$IFNDEF OMIT_MMX}
|
---|
976 | BlendRegistry.RegisterBinding(FID_EMMS, @@EMMS);
|
---|
977 | {$ENDIF}
|
---|
978 | BlendRegistry.RegisterBinding(FID_MERGEREG, @@MergeReg);
|
---|
979 | BlendRegistry.RegisterBinding(FID_MERGEMEM, @@MergeMem);
|
---|
980 | BlendRegistry.RegisterBinding(FID_MERGELINE, @@MergeLine);
|
---|
981 | BlendRegistry.RegisterBinding(FID_MERGEREGEX, @@MergeRegEx);
|
---|
982 | BlendRegistry.RegisterBinding(FID_MERGEMEMEX, @@MergeMemEx);
|
---|
983 | BlendRegistry.RegisterBinding(FID_MERGELINEEX, @@MergeLineEx);
|
---|
984 | BlendRegistry.RegisterBinding(FID_COMBINEREG, @@CombineReg);
|
---|
985 | BlendRegistry.RegisterBinding(FID_COMBINEMEM, @@CombineMem);
|
---|
986 | BlendRegistry.RegisterBinding(FID_COMBINELINE, @@CombineLine);
|
---|
987 |
|
---|
988 | BlendRegistry.RegisterBinding(FID_BLENDREG, @@BlendReg);
|
---|
989 | BlendRegistry.RegisterBinding(FID_BLENDMEM, @@BlendMem);
|
---|
990 | BlendRegistry.RegisterBinding(FID_BLENDMEMS, @@BlendMems);
|
---|
991 | BlendRegistry.RegisterBinding(FID_BLENDLINE, @@BlendLine);
|
---|
992 | BlendRegistry.RegisterBinding(FID_BLENDREGEX, @@BlendRegEx);
|
---|
993 | BlendRegistry.RegisterBinding(FID_BLENDMEMEX, @@BlendMemEx);
|
---|
994 | BlendRegistry.RegisterBinding(FID_BLENDLINEEX, @@BlendLineEx);
|
---|
995 | BlendRegistry.RegisterBinding(FID_BLENDLINE1, @@BlendLine1);
|
---|
996 |
|
---|
997 | BlendRegistry.RegisterBinding(FID_COLORMAX, @@ColorMax);
|
---|
998 | BlendRegistry.RegisterBinding(FID_COLORMIN, @@ColorMin);
|
---|
999 | BlendRegistry.RegisterBinding(FID_COLORAVERAGE, @@ColorAverage);
|
---|
1000 | BlendRegistry.RegisterBinding(FID_COLORADD, @@ColorAdd);
|
---|
1001 | BlendRegistry.RegisterBinding(FID_COLORSUB, @@ColorSub);
|
---|
1002 | BlendRegistry.RegisterBinding(FID_COLORDIV, @@ColorDiv);
|
---|
1003 | BlendRegistry.RegisterBinding(FID_COLORMODULATE, @@ColorModulate);
|
---|
1004 | BlendRegistry.RegisterBinding(FID_COLORDIFFERENCE, @@ColorDifference);
|
---|
1005 | BlendRegistry.RegisterBinding(FID_COLOREXCLUSION, @@ColorExclusion);
|
---|
1006 | BlendRegistry.RegisterBinding(FID_COLORSCALE, @@ColorScale);
|
---|
1007 | BlendRegistry.RegisterBinding(FID_COLORSCREEN, @@ColorScreen);
|
---|
1008 | BlendRegistry.RegisterBinding(FID_COLORDODGE, @@ColorDodge);
|
---|
1009 | BlendRegistry.RegisterBinding(FID_COLORBURN, @@ColorBurn);
|
---|
1010 |
|
---|
1011 | BlendRegistry.RegisterBinding(FID_BLENDCOLORADD, @@BlendColorAdd);
|
---|
1012 | BlendRegistry.RegisterBinding(FID_BLENDCOLORMODULATE, @@BlendColorModulate);
|
---|
1013 |
|
---|
1014 | BlendRegistry.RegisterBinding(FID_LIGHTEN, @@LightenReg);
|
---|
1015 | BlendRegistry.RegisterBinding(FID_BLENDREGRGB, @@BlendRegRGB);
|
---|
1016 | BlendRegistry.RegisterBinding(FID_BLENDMEMRGB, @@BlendMemRGB);
|
---|
1017 | {$IFDEF TEST_BLENDMEMRGB128SSE4}
|
---|
1018 | BlendRegistry.RegisterBinding(FID_BLENDMEMRGB128, @@BlendMemRGB128);
|
---|
1019 | {$ENDIF}
|
---|
1020 |
|
---|
1021 | // pure pascal
|
---|
1022 | BlendRegistry.Add(FID_EMMS, @EMMS_Pas, [], BlendBindingFlagPascal);
|
---|
1023 | BlendRegistry.Add(FID_MERGEREG, @MergeReg_Pas, [], BlendBindingFlagPascal);
|
---|
1024 | BlendRegistry.Add(FID_MERGEMEM, @MergeMem_Pas, [], BlendBindingFlagPascal);
|
---|
1025 | BlendRegistry.Add(FID_MERGEMEMEX, @MergeMemEx_Pas, [], BlendBindingFlagPascal);
|
---|
1026 | BlendRegistry.Add(FID_MERGEREGEX, @MergeRegEx_Pas, [], BlendBindingFlagPascal);
|
---|
1027 | BlendRegistry.Add(FID_MERGELINE, @MergeLine_Pas, [], BlendBindingFlagPascal);
|
---|
1028 | BlendRegistry.Add(FID_MERGELINEEX, @MergeLineEx_Pas, [], BlendBindingFlagPascal);
|
---|
1029 | BlendRegistry.Add(FID_MERGELINE1, @MergeLine1_Pas, [], BlendBindingFlagPascal);
|
---|
1030 | BlendRegistry.Add(FID_COLORDIV, @ColorDiv_Pas, [], BlendBindingFlagPascal);
|
---|
1031 | BlendRegistry.Add(FID_COLORAVERAGE, @ColorAverage_Pas, [], BlendBindingFlagPascal);
|
---|
1032 | BlendRegistry.Add(FID_COMBINEREG, @CombineReg_Pas, [], BlendBindingFlagPascal);
|
---|
1033 | BlendRegistry.Add(FID_COMBINEMEM, @CombineMem_Pas, [], BlendBindingFlagPascal);
|
---|
1034 | BlendRegistry.Add(FID_COMBINELINE, @CombineLine_Pas, [], BlendBindingFlagPascal);
|
---|
1035 | BlendRegistry.Add(FID_BLENDREG, @BlendReg_Pas, [], BlendBindingFlagPascal);
|
---|
1036 | BlendRegistry.Add(FID_BLENDMEM, @BlendMem_Pas, [], BlendBindingFlagPascal);
|
---|
1037 | BlendRegistry.Add(FID_BLENDMEMS, @BlendMems_Pas, [], BlendBindingFlagPascal);
|
---|
1038 | BlendRegistry.Add(FID_BLENDLINE, @BlendLine_Pas, [], BlendBindingFlagPascal);
|
---|
1039 | BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_Pas, [], BlendBindingFlagPascal);
|
---|
1040 | BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_Pas, [], BlendBindingFlagPascal);
|
---|
1041 | BlendRegistry.Add(FID_BLENDLINEEX, @BlendLineEx_Pas, [], BlendBindingFlagPascal);
|
---|
1042 | BlendRegistry.Add(FID_BLENDLINE1, @BlendLine1_Pas, [], BlendBindingFlagPascal);
|
---|
1043 | BlendRegistry.Add(FID_COLORMAX, @ColorMax_Pas, [], BlendBindingFlagPascal);
|
---|
1044 | BlendRegistry.Add(FID_COLORMIN, @ColorMin_Pas, [], BlendBindingFlagPascal);
|
---|
1045 | BlendRegistry.Add(FID_COLORADD, @ColorAdd_Pas, [], BlendBindingFlagPascal);
|
---|
1046 | BlendRegistry.Add(FID_COLORSUB, @ColorSub_Pas, [], BlendBindingFlagPascal);
|
---|
1047 | BlendRegistry.Add(FID_COLORMODULATE, @ColorModulate_Pas, [], BlendBindingFlagPascal);
|
---|
1048 | BlendRegistry.Add(FID_COLORDIFFERENCE, @ColorDifference_Pas, [], BlendBindingFlagPascal);
|
---|
1049 | BlendRegistry.Add(FID_COLOREXCLUSION, @ColorExclusion_Pas, [], BlendBindingFlagPascal);
|
---|
1050 | BlendRegistry.Add(FID_COLORSCALE, @ColorScale_Pas, [], BlendBindingFlagPascal);
|
---|
1051 | BlendRegistry.Add(FID_COLORSCREEN, @ColorScreen_Pas, [], BlendBindingFlagPascal);
|
---|
1052 | BlendRegistry.Add(FID_COLORDODGE, @ColorDodge_Pas, [], BlendBindingFlagPascal);
|
---|
1053 | BlendRegistry.Add(FID_COLORBURN, @ColorBurn_Pas, [], BlendBindingFlagPascal);
|
---|
1054 | BlendRegistry.Add(FID_BLENDCOLORADD, @BlendColorAdd_Pas, [], BlendBindingFlagPascal);
|
---|
1055 | BlendRegistry.Add(FID_BLENDCOLORMODULATE, @BlendColorModulate_Pas, [], BlendBindingFlagPascal);
|
---|
1056 | BlendRegistry.Add(FID_LIGHTEN, @LightenReg_Pas, [], BlendBindingFlagPascal);
|
---|
1057 | BlendRegistry.Add(FID_BLENDREGRGB, @BlendRegRGB_Pas, [], BlendBindingFlagPascal);
|
---|
1058 | BlendRegistry.Add(FID_BLENDMEMRGB, @BlendMemRGB_Pas, [], BlendBindingFlagPascal);
|
---|
1059 |
|
---|
1060 | {$IFNDEF PUREPASCAL}
|
---|
1061 | BlendRegistry.Add(FID_EMMS, @EMMS_ASM, []);
|
---|
1062 | BlendRegistry.Add(FID_COMBINEREG, @CombineReg_ASM, []);
|
---|
1063 | BlendRegistry.Add(FID_COMBINEMEM, @CombineMem_ASM, []);
|
---|
1064 | BlendRegistry.Add(FID_BLENDREG, @BlendReg_ASM, []);
|
---|
1065 | BlendRegistry.Add(FID_BLENDMEM, @BlendMem_ASM, []);
|
---|
1066 | BlendRegistry.Add(FID_BLENDMEMS, @BlendMems_ASM, []);
|
---|
1067 | BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_ASM, []);
|
---|
1068 | BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_ASM, []);
|
---|
1069 | BlendRegistry.Add(FID_BLENDLINE, @BlendLine_ASM, []);
|
---|
1070 | BlendRegistry.Add(FID_BLENDLINE1, @BlendLine1_ASM, []);
|
---|
1071 | {$IFNDEF TARGET_x64}
|
---|
1072 | BlendRegistry.Add(FID_MERGEREG, @MergeReg_ASM, []);
|
---|
1073 | {$ENDIF}
|
---|
1074 | {$IFNDEF OMIT_MMX}
|
---|
1075 | BlendRegistry.Add(FID_EMMS, @EMMS_MMX, [ciMMX]);
|
---|
1076 | BlendRegistry.Add(FID_COMBINEREG, @CombineReg_MMX, [ciMMX]);
|
---|
1077 | BlendRegistry.Add(FID_COMBINEMEM, @CombineMem_MMX, [ciMMX]);
|
---|
1078 | BlendRegistry.Add(FID_COMBINELINE, @CombineLine_MMX, [ciMMX]);
|
---|
1079 | BlendRegistry.Add(FID_BLENDREG, @BlendReg_MMX, [ciMMX]);
|
---|
1080 | BlendRegistry.Add(FID_BLENDMEM, @BlendMem_MMX, [ciMMX]);
|
---|
1081 | BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_MMX, [ciMMX]);
|
---|
1082 | BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_MMX, [ciMMX]);
|
---|
1083 | BlendRegistry.Add(FID_BLENDLINE, @BlendLine_MMX, [ciMMX]);
|
---|
1084 | BlendRegistry.Add(FID_BLENDLINEEX, @BlendLineEx_MMX, [ciMMX]);
|
---|
1085 | BlendRegistry.Add(FID_COLORMAX, @ColorMax_EMMX, [ciEMMX]);
|
---|
1086 | BlendRegistry.Add(FID_COLORMIN, @ColorMin_EMMX, [ciEMMX]);
|
---|
1087 | BlendRegistry.Add(FID_COLORADD, @ColorAdd_MMX, [ciMMX]);
|
---|
1088 | BlendRegistry.Add(FID_COLORSUB, @ColorSub_MMX, [ciMMX]);
|
---|
1089 | BlendRegistry.Add(FID_COLORMODULATE, @ColorModulate_MMX, [ciMMX]);
|
---|
1090 | BlendRegistry.Add(FID_COLORDIFFERENCE, @ColorDifference_MMX, [ciMMX]);
|
---|
1091 | BlendRegistry.Add(FID_COLOREXCLUSION, @ColorExclusion_MMX, [ciMMX]);
|
---|
1092 | BlendRegistry.Add(FID_COLORSCALE, @ColorScale_MMX, [ciMMX]);
|
---|
1093 | BlendRegistry.Add(FID_LIGHTEN, @LightenReg_MMX, [ciMMX]);
|
---|
1094 | BlendRegistry.Add(FID_BLENDREGRGB, @BlendRegRGB_MMX, [ciMMX]);
|
---|
1095 | BlendRegistry.Add(FID_BLENDMEMRGB, @BlendMemRGB_MMX, [ciMMX]);
|
---|
1096 | {$ENDIF}
|
---|
1097 | {$IFNDEF OMIT_SSE2}
|
---|
1098 | BlendRegistry.Add(FID_EMMS, @EMMS_SSE2, [ciSSE2]);
|
---|
1099 | BlendRegistry.Add(FID_MERGEREG, @MergeReg_SSE2, [ciSSE2]);
|
---|
1100 | BlendRegistry.Add(FID_COMBINEREG, @CombineReg_SSE2, [ciSSE2]);
|
---|
1101 | BlendRegistry.Add(FID_COMBINEMEM, @CombineMem_SSE2, [ciSSE2]);
|
---|
1102 | BlendRegistry.Add(FID_COMBINELINE, @CombineLine_SSE2, [ciSSE2]);
|
---|
1103 | BlendRegistry.Add(FID_BLENDREG, @BlendReg_SSE2, [ciSSE2]);
|
---|
1104 | BlendRegistry.Add(FID_BLENDMEM, @BlendMem_SSE2, [ciSSE2]);
|
---|
1105 | BlendRegistry.Add(FID_BLENDMEMS, @BlendMems_SSE2, [ciSSE2]);
|
---|
1106 | BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_SSE2, [ciSSE2]);
|
---|
1107 | BlendRegistry.Add(FID_BLENDLINE, @BlendLine_SSE2, [ciSSE2]);
|
---|
1108 | BlendRegistry.Add(FID_BLENDLINEEX, @BlendLineEx_SSE2, [ciSSE2]);
|
---|
1109 | BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_SSE2, [ciSSE2]);
|
---|
1110 | BlendRegistry.Add(FID_COLORMAX, @ColorMax_SSE2, [ciSSE2]);
|
---|
1111 | BlendRegistry.Add(FID_COLORMIN, @ColorMin_SSE2, [ciSSE2]);
|
---|
1112 | BlendRegistry.Add(FID_COLORADD, @ColorAdd_SSE2, [ciSSE2]);
|
---|
1113 | BlendRegistry.Add(FID_COLORSUB, @ColorSub_SSE2, [ciSSE2]);
|
---|
1114 | BlendRegistry.Add(FID_COLORMODULATE, @ColorModulate_SSE2, [ciSSE2]);
|
---|
1115 | BlendRegistry.Add(FID_COLORDIFFERENCE, @ColorDifference_SSE2, [ciSSE2]);
|
---|
1116 | BlendRegistry.Add(FID_COLOREXCLUSION, @ColorExclusion_SSE2, [ciSSE2]);
|
---|
1117 | BlendRegistry.Add(FID_COLORSCALE, @ColorScale_SSE2, [ciSSE2]);
|
---|
1118 | BlendRegistry.Add(FID_LIGHTEN, @LightenReg_SSE2, [ciSSE]);
|
---|
1119 | BlendRegistry.Add(FID_BLENDREGRGB, @BlendRegRGB_SSE2, [ciSSE2]);
|
---|
1120 | BlendRegistry.Add(FID_BLENDMEMRGB, @BlendMemRGB_SSE2, [ciSSE2]);
|
---|
1121 | {$IFDEF TEST_BLENDMEMRGB128SSE4}
|
---|
1122 | BlendRegistry.Add(FID_BLENDMEMRGB128, @BlendMemRGB128_SSE4, [ciSSE2]);
|
---|
1123 | {$ENDIF}
|
---|
1124 | {$ENDIF}
|
---|
1125 | {$ENDIF}
|
---|
1126 |
|
---|
1127 | BlendRegistry.RebindAll;
|
---|
1128 | end;
|
---|
1129 |
|
---|
1130 | initialization
|
---|
1131 | BlendColorAdd := BlendColorAdd_Pas;
|
---|
1132 |
|
---|
1133 | RegisterBindings;
|
---|
1134 | MakeMergeTables;
|
---|
1135 |
|
---|
1136 | {$IFNDEF PUREPASCAL}
|
---|
1137 | MMX_ACTIVE := (ciMMX in CPUFeatures);
|
---|
1138 | if [ciMMX, ciSSE2] * CPUFeatures <> [] then
|
---|
1139 | GenAlphaTable;
|
---|
1140 | {$ELSE}
|
---|
1141 | MMX_ACTIVE := False;
|
---|
1142 | {$ENDIF}
|
---|
1143 |
|
---|
1144 | finalization
|
---|
1145 | {$IFNDEF PUREPASCAL}
|
---|
1146 | if [ciMMX, ciSSE2] * CPUFeatures <> [] then
|
---|
1147 | FreeAlphaTable;
|
---|
1148 | {$ENDIF}
|
---|
1149 |
|
---|
1150 | end.
|
---|