1
//----------------------------------------------------------------------------
2
// Anti-Grain Geometry - Version 2.4 (Public License)
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
// Pascal Port By: Milan Marusinec alias Milano
8
// http://www.aggpas.org
9
// Copyright (c) 2005-2006
11
// Permission to copy, use, modify, sell and distribute this software
12
// is granted provided this copyright notice appears in all copies.
13
// This software is provided "as is" without express or implied
14
// warranty, and with no claim as to its suitability for any purpose.
16
//----------------------------------------------------------------------------
17
// Contact: mcseem@antigrain.com
18
// mcseemagg@yahoo.com
19
// http://www.antigrain.com
21
//----------------------------------------------------------------------------
23
// The Stack Blur Algorithm was invented by Mario Klingemann,
24
// mario@quasimondo.com and described here:
25
// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php
26
// (search phrase "Stackblur: Fast But Goodlooking").
27
// The major improvement is that there's no more division table
28
// that was very expensive to create for large blur radii. Insted,
29
// for 8-bit per channel and radius not exceeding 254 the division is
30
// replaced by multiplication and shift.
32
// [Pascal Port History] -----------------------------------------------------
34
// 11.10.2007-Milano: recursive_blur & finished OK
35
// 10.10.2007-Milano: stack_blur
36
// 09.10.2007-Milano: Unit port establishment
52
agg_pixfmt_transposer ;
54
{ GLOBAL VARIABLES & CONSTANTS }
64
constructor Construct;
67
procedure blur_x(img : pixel_formats_ptr; radius : unsigned );
68
procedure blur_y(img : pixel_formats_ptr; radius : unsigned );
70
procedure blur(img : pixel_formats_ptr; radius : unsigned );
74
recursive_blur = object
81
constructor Construct;
84
procedure blur_x(img : pixel_formats_ptr; radius : double );
85
procedure blur_y(img : pixel_formats_ptr; radius : double );
87
procedure blur(img : pixel_formats_ptr; radius : double );
92
procedure stack_blur_gray8 (img : pixel_formats_ptr; rx ,ry : unsigned );
93
procedure stack_blur_rgb24 (img : pixel_formats_ptr; rx ,ry : unsigned );
94
procedure stack_blur_rgba32(img : pixel_formats_ptr; rx ,ry : unsigned );
98
{ LOCAL VARIABLES & CONSTANTS }
100
g_stack_blur8_mul : array[0..254 ] of int16u = (
101
512 ,512 ,456 ,512 ,328 ,456 ,335 ,512 ,405 ,328 ,271 ,456 ,388 ,335 ,292 ,512 ,
102
454 ,405 ,364 ,328 ,298 ,271 ,496 ,456 ,420 ,388 ,360 ,335 ,312 ,292 ,273 ,512 ,
103
482 ,454 ,428 ,405 ,383 ,364 ,345 ,328 ,312 ,298 ,284 ,271 ,259 ,496 ,475 ,456 ,
104
437 ,420 ,404 ,388 ,374 ,360 ,347 ,335 ,323 ,312 ,302 ,292 ,282 ,273 ,265 ,512 ,
105
497 ,482 ,468 ,454 ,441 ,428 ,417 ,405 ,394 ,383 ,373 ,364 ,354 ,345 ,337 ,328 ,
106
320 ,312 ,305 ,298 ,291 ,284 ,278 ,271 ,265 ,259 ,507 ,496 ,485 ,475 ,465 ,456 ,
107
446 ,437 ,428 ,420 ,412 ,404 ,396 ,388 ,381 ,374 ,367 ,360 ,354 ,347 ,341 ,335 ,
108
329 ,323 ,318 ,312 ,307 ,302 ,297 ,292 ,287 ,282 ,278 ,273 ,269 ,265 ,261 ,512 ,
109
505 ,497 ,489 ,482 ,475 ,468 ,461 ,454 ,447 ,441 ,435 ,428 ,422 ,417 ,411 ,405 ,
110
399 ,394 ,389 ,383 ,378 ,373 ,368 ,364 ,359 ,354 ,350 ,345 ,341 ,337 ,332 ,328 ,
111
324 ,320 ,316 ,312 ,309 ,305 ,301 ,298 ,294 ,291 ,287 ,284 ,281 ,278 ,274 ,271 ,
112
268 ,265 ,262 ,259 ,257 ,507 ,501 ,496 ,491 ,485 ,480 ,475 ,470 ,465 ,460 ,456 ,
113
451 ,446 ,442 ,437 ,433 ,428 ,424 ,420 ,416 ,412 ,408 ,404 ,400 ,396 ,392 ,388 ,
114
385 ,381 ,377 ,374 ,370 ,367 ,363 ,360 ,357 ,354 ,350 ,347 ,344 ,341 ,338 ,335 ,
115
332 ,329 ,326 ,323 ,320 ,318 ,315 ,312 ,310 ,307 ,304 ,302 ,299 ,297 ,294 ,292 ,
116
289 ,287 ,285 ,282 ,280 ,278 ,275 ,273 ,271 ,269 ,267 ,265 ,263 ,261 ,259 );
118
g_stack_blur8_shr : array[0..254 ] of int8u = (
119
9 ,11 ,12 ,13 ,13 ,14 ,14 ,15 ,15 ,15 ,15 ,16 ,16 ,16 ,16 ,17 ,
120
17 ,17 ,17 ,17 ,17 ,17 ,18 ,18 ,18 ,18 ,18 ,18 ,18 ,18 ,18 ,19 ,
121
19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,20 ,20 ,20 ,
122
20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,21 ,
123
21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,
124
21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,22 ,22 ,22 ,22 ,22 ,22 ,
125
22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,
126
22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,23 ,
127
23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,
128
23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,
129
23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,
130
23 ,23 ,23 ,23 ,23 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,
131
24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,
132
24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,
133
24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,
134
24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 );
137
stack_calculator_ptr = ^stack_calculator;
138
stack_calculator = object
147
procedure add (c : aggclr );
148
procedure add_ (c : aggclr; k : unsigned );
149
procedure add__(c : stack_calculator );
150
procedure sub (c : aggclr );
151
procedure sub_ (c : stack_calculator );
153
procedure calc_pix (c : aggclr_ptr; div_ : unsigned );
154
procedure calc_pix_(c : aggclr_ptr; mul_ ,shr_ : unsigned );
158
gauss_calculator_ptr = ^gauss_calculator;
159
gauss_calculator = object
166
procedure from_pix(c : aggclr );
169
b1 ,b2 ,b3 ,b4 : double;
170
c1 ,c2 ,c3 ,c4 : gauss_calculator_ptr );
172
procedure to_pix(c : aggclr_ptr );
176
{ UNIT IMPLEMENTATION }
178
procedure stack_calculator.clear;
189
procedure stack_calculator.add(c : aggclr );
200
procedure stack_calculator.add__(c : stack_calculator );
211
procedure stack_calculator.add_(c : aggclr; k : unsigned );
222
procedure stack_calculator.sub(c : aggclr );
233
procedure stack_calculator.sub_(c : stack_calculator );
244
procedure stack_calculator.calc_pix(c : aggclr_ptr; div_ : unsigned );
246
c.v:=int8u(v div div_ );
247
c.r:=int8u(r div div_ );
248
c.g:=int8u(g div div_ );
249
c.b:=int8u(b div div_ );
250
c.a:=int8u(a div div_ );
255
procedure stack_calculator.calc_pix_(c : aggclr_ptr; mul_ ,shr_ : unsigned );
257
c.v:=int8u((v * mul_ ) shr shr_ );
258
c.r:=int8u((r * mul_ ) shr shr_ );
259
c.g:=int8u((g * mul_ ) shr shr_ );
260
c.b:=int8u((b * mul_ ) shr shr_ );
261
c.a:=int8u((a * mul_ ) shr shr_ );
266
procedure gauss_calculator.from_pix(c : aggclr );
277
procedure gauss_calculator.calc(
278
b1 ,b2 ,b3 ,b4 : double;
279
c1 ,c2 ,c3 ,c4 : gauss_calculator_ptr );
281
v:=b1 * c1.v + b2 * c2.v + b3 * c3.v + b4 * c4.v;
282
r:=b1 * c1.r + b2 * c2.r + b3 * c3.r + b4 * c4.r;
283
g:=b1 * c1.g + b2 * c2.g + b3 * c3.g + b4 * c4.g;
284
b:=b1 * c1.b + b2 * c2.b + b3 * c3.b + b4 * c4.b;
285
a:=b1 * c1.a + b2 * c2.a + b3 * c3.a + b4 * c4.a;
290
procedure gauss_calculator.to_pix(c : aggclr_ptr );
292
c.v:=int8u(uround(v ) );
293
c.r:=int8u(uround(r ) );
294
c.g:=int8u(uround(g ) );
295
c.b:=int8u(uround(b ) );
296
c.a:=int8u(uround(a ) );
301
constructor stack_blur.Construct;
303
m_buf.Construct (sizeof(aggclr ) );
304
m_stack.Construct(sizeof(aggclr ) );
309
destructor stack_blur.Destruct;
317
procedure stack_blur.blur_x(img : pixel_formats_ptr; radius : unsigned );
319
x ,y ,xp ,i ,stack_ptr ,stack_start ,
321
w ,h ,wm ,div_ ,div_sum ,mul_sum ,shr_sum ,max_val : unsigned;
325
stack_pix ,_c : aggclr_ptr;
327
sum ,sum_in ,sum_out : stack_calculator;
336
div_:=radius * 2 + 1;
338
div_sum:=(radius + 1 ) * (radius + 1 );
343
if (max_val <= 255 ) and
346
mul_sum:=g_stack_blur8_mul[radius ];
347
shr_sum:=g_stack_blur8_shr[radius ];
351
m_buf.allocate (w ,128 );
352
m_stack.allocate(div_ ,32 );
362
pix:=img.pixel(img ,0 ,y );
368
move(pix ,m_stack.array_operator(i )^ ,sizeof(aggclr ) );
370
sum.add_ (pix ,i + 1 );
382
pix:=img.pixel(img ,wm ,y )
384
pix:=img.pixel(img ,i ,y );
386
move(pix ,m_stack.array_operator(i + radius )^ ,sizeof(aggclr ) );
388
sum.add_ (pix ,radius + 1 - i );
402
sum.calc_pix_(aggclr_ptr(m_buf.array_operator(x ) ) ,mul_sum ,shr_sum )
404
sum.calc_pix(aggclr_ptr(m_buf.array_operator(x ) ) ,div_sum );
408
stack_start:=stack_ptr + div_ - radius;
410
if stack_start >= div_ then
411
dec(stack_start ,div_ );
413
stack_pix:=m_stack.array_operator(stack_start );
415
sum_out.sub(stack_pix^ );
422
pix:=img.pixel(img ,xp ,y );
431
if stack_ptr >= div_ then
434
stack_pix:=m_stack.array_operator(stack_ptr );
436
sum_out.add(stack_pix^ );
437
sum_in.sub (stack_pix^ );
443
_c:=m_buf.array_operator(0 );
445
img.copy_color_hspan(img ,0 ,y ,w ,_c );
454
procedure stack_blur.blur_y(img : pixel_formats_ptr; radius : unsigned );
456
img2 : pixel_formats_transposer;
459
pixfmt_transposer(img2 ,img );
460
blur_x (@img2 ,radius );
465
procedure stack_blur.blur(img : pixel_formats_ptr; radius : unsigned );
467
img2 : pixel_formats_transposer;
470
blur_x (img ,radius );
471
pixfmt_transposer(img2 ,img );
472
blur_x (@img2 ,radius );
477
constructor recursive_blur.Construct;
479
m_sum1.Construct(sizeof(gauss_calculator ) );
480
m_sum2.Construct(sizeof(gauss_calculator ) );
481
m_buf.Construct (sizeof(aggclr ) );
486
destructor recursive_blur.Destruct;
495
procedure recursive_blur.blur_x(img : pixel_formats_ptr; radius : double );
497
s ,q ,q2 ,q3 ,b0 ,b1 ,b2 ,b3 ,b : double;
499
w ,h ,wm ,x ,y : int;
501
c : gauss_calculator;
503
g0 ,g1 : gauss_calculator_ptr;
506
if radius < 0.62 then
509
if img._width < 3 then
515
q:=3.97156 - 4.14554 * Sqrt(1 - 0.26891 * s )
517
q:=0.98711 * s - 0.96330;
521
b0:=1.0 / (1.578250 + 2.444130 * q + 1.428100 * q2 + 0.422205 * q3 );
522
b1:=2.44413 * q + 2.85619 * q2 + 1.26661 * q3;
523
b2:=-1.42810 * q2 + -1.26661 * q3;
525
b :=1 - (b1 + b2 + b3 ) * b0;
541
g0:=gauss_calculator_ptr(m_sum1.array_operator(0 ) );
543
c.from_pix(img.pixel(img ,0 ,y ) );
548
g1:=gauss_calculator_ptr(m_sum1.array_operator(1 ) );
550
c.from_pix(img.pixel(img ,1 ,y ) );
555
c.from_pix (img.pixel(img ,2 ,y ) );
556
gauss_calculator_ptr(m_sum1.array_operator(2 ) ).calc(
564
c.from_pix(img.pixel(img ,x ,y ) );
566
gauss_calculator_ptr(m_sum1.array_operator(x ) ).calc(
569
gauss_calculator_ptr(m_sum1.array_operator(x - 1 ) ) ,
570
gauss_calculator_ptr(m_sum1.array_operator(x - 2 ) ) ,
571
gauss_calculator_ptr(m_sum1.array_operator(x - 3 ) ) );
577
g0:=gauss_calculator_ptr(m_sum1.array_operator(wm ) );
578
g1:=gauss_calculator_ptr(m_sum2.array_operator(wm ) );
584
gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ).calc(
586
gauss_calculator_ptr(m_sum1.array_operator(wm - 1 ) ) ,
589
gauss_calculator_ptr(m_sum2.array_operator(wm - 2 ) ).calc(
591
gauss_calculator_ptr(m_sum1.array_operator(wm - 2 ) ) ,
592
gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ) ,
596
aggclr_ptr(m_buf.array_operator(wm ) ) );
598
gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ).to_pix(
599
aggclr_ptr(m_buf.array_operator(wm - 1 ) ) );
601
gauss_calculator_ptr(m_sum2.array_operator(wm - 2 ) ).to_pix(
602
aggclr_ptr(m_buf.array_operator(wm - 2 ) ) );
608
gauss_calculator_ptr(m_sum2.array_operator(x ) ).calc(
610
gauss_calculator_ptr(m_sum1.array_operator(x ) ) ,
611
gauss_calculator_ptr(m_sum2.array_operator(x + 1 ) ) ,
612
gauss_calculator_ptr(m_sum2.array_operator(x + 2 ) ) ,
613
gauss_calculator_ptr(m_sum2.array_operator(x + 3 ) ) );
615
gauss_calculator_ptr(m_sum2.array_operator(x ) ).to_pix(
616
aggclr_ptr(m_buf.array_operator(x ) ) );
622
img.copy_color_hspan(img ,0 ,y ,w ,m_buf.array_operator(0 ) );
631
procedure recursive_blur.blur_y(img : pixel_formats_ptr; radius : double );
633
img2 : pixel_formats_transposer;
636
pixfmt_transposer(img2 ,img );
637
blur_x (@img2 ,radius );
642
procedure recursive_blur.blur(img : pixel_formats_ptr; radius : double );
644
img2 : pixel_formats_transposer;
647
blur_x (img ,radius );
648
pixfmt_transposer(img2 ,img );
649
blur_x (@img2 ,radius );
654
procedure stack_blur_gray8(img : pixel_formats_ptr; rx ,ry : unsigned );
658
x ,y ,xp ,yp ,i ,pix ,stack_pix ,sum ,sum_in ,sum_out ,
660
stack_ptr ,stack_start ,w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned;
662
src_pix_ptr ,dst_pix_ptr : int8u_ptr;
672
stack.Construct(sizeof(int8u ) );
681
mul_sum:=g_stack_blur8_mul[rx ];
682
shr_sum:=g_stack_blur8_shr[rx ];
684
stack.allocate(div_ );
694
src_pix_ptr:=img.pix_ptr(0 ,y );
701
int8u_ptr(stack.array_operator(i ) )^:=pix;
703
inc(sum ,pix * (i + 1 ) );
715
inc(ptrcomp(src_pix_ptr ) ,img.m_step );
719
int8u_ptr(stack.array_operator(i + rx ) )^:=pix;
721
inc(sum ,pix * (rx + 1 - i ) );
734
src_pix_ptr:=img.pix_ptr(xp ,y );
735
dst_pix_ptr:=img.pix_ptr(0 ,y );
741
dst_pix_ptr^:=int8u((sum * mul_sum ) shr shr_sum );
743
inc(ptrcomp(dst_pix_ptr ) ,img.m_step );
746
stack_start:=stack_ptr + div_ - rx;
748
if stack_start >= div_ then
749
dec(stack_start ,div_ );
751
dec(sum_out ,int8u_ptr(stack.array_operator(stack_start ) )^ );
755
inc(ptrcomp(src_pix_ptr ) ,img.m_step );
763
int8u_ptr(stack.array_operator(stack_start ) )^:=pix;
770
if stack_ptr >= div_ then
773
stack_pix:=int8u_ptr(stack.array_operator(stack_ptr ) )^;
775
inc(sum_out ,stack_pix );
776
dec(sum_in ,stack_pix );
795
mul_sum:=g_stack_blur8_mul[ry ];
796
shr_sum:=g_stack_blur8_shr[ry ];
798
stack.allocate(div_ );
810
src_pix_ptr:=img.pix_ptr(x ,0 );
817
int8u_ptr(stack.array_operator(i ) )^:=pix;
819
inc(sum ,pix * (i + 1 ) );
831
inc(ptrcomp(src_pix_ptr ) ,stride );
835
int8u_ptr(stack.array_operator(i + ry ) )^:=pix;
837
inc(sum ,pix * (ry + 1 - i ) );
850
src_pix_ptr:=img.pix_ptr(x ,yp );
851
dst_pix_ptr:=img.pix_ptr(x ,0 );
857
dst_pix_ptr^:=int8u((sum * mul_sum ) shr shr_sum );
859
inc(ptrcomp(dst_pix_ptr ) ,stride );
862
stack_start:=stack_ptr + div_ - ry;
864
if stack_start >= div_ then
865
dec(stack_start ,div_ );
867
dec(sum_out ,int8u_ptr(stack.array_operator(stack_start ) )^ );
871
inc(ptrcomp(src_pix_ptr ) ,stride );
879
int8u_ptr(stack.array_operator(stack_start ) )^:=pix;
886
if stack_ptr >= div_ then
889
stack_pix:=int8u_ptr(stack.array_operator(stack_ptr ) )^;
891
inc(sum_out ,stack_pix );
892
dec(sum_in ,stack_pix );
909
procedure stack_blur_rgb24(img : pixel_formats_ptr; rx ,ry : unsigned );
911
R ,G ,B ,stride : int;
913
x ,y ,xp ,yp ,i ,stack_ptr ,stack_start ,
915
sum_r ,sum_g ,sum_b ,
917
sum_in_r ,sum_in_g ,sum_in_b ,
919
sum_out_r ,sum_out_g ,sum_out_b ,
921
w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned;
923
src_pix_ptr ,dst_pix_ptr : int8u_ptr;
925
stack_pix_ptr : aggclr_ptr;
939
stack.Construct(sizeof(aggclr ) );
947
mul_sum:=g_stack_blur8_mul[rx ];
948
shr_sum:=g_stack_blur8_shr[rx ];
950
stack.allocate(div_ );
966
src_pix_ptr:=img.pix_ptr(0 ,y );
972
stack_pix_ptr:=stack.array_operator(i );
974
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
975
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
976
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
978
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) );
979
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) );
980
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) );
982
inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
983
inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
984
inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
995
inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
997
stack_pix_ptr:=stack.array_operator(i + rx );
999
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1000
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1001
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1003
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (rx + 1 - i ) );
1004
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (rx + 1 - i ) );
1005
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (rx + 1 - i ) );
1007
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1008
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1009
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1021
src_pix_ptr:=img.pix_ptr(xp ,y );
1022
dst_pix_ptr:=img.pix_ptr(0 ,y );
1028
int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum );
1029
int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum );
1030
int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum );
1032
inc(ptrcomp(dst_pix_ptr ) ,img.m_pix_width );
1034
dec(sum_r ,sum_out_r );
1035
dec(sum_g ,sum_out_g );
1036
dec(sum_b ,sum_out_b );
1038
stack_start:=stack_ptr + div_ - rx;
1040
if stack_start >= div_ then
1041
dec(stack_start ,div_ );
1043
stack_pix_ptr:=stack.array_operator(stack_start );
1045
dec(sum_out_r ,stack_pix_ptr.r );
1046
dec(sum_out_g ,stack_pix_ptr.g );
1047
dec(sum_out_b ,stack_pix_ptr.b );
1051
inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
1056
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1057
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1058
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1060
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1061
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1062
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1064
inc(sum_r ,sum_in_r );
1065
inc(sum_g ,sum_in_g );
1066
inc(sum_b ,sum_in_b );
1070
if stack_ptr >= div_ then
1073
stack_pix_ptr:=stack.array_operator(stack_ptr );
1075
inc(sum_out_r ,stack_pix_ptr.r );
1076
inc(sum_out_g ,stack_pix_ptr.g );
1077
inc(sum_out_b ,stack_pix_ptr.b );
1078
dec(sum_in_r ,stack_pix_ptr.r );
1079
dec(sum_in_g ,stack_pix_ptr.g );
1080
dec(sum_in_b ,stack_pix_ptr.b );
1099
mul_sum:=g_stack_blur8_mul[ry ];
1100
shr_sum:=g_stack_blur8_shr[ry ];
1102
stack.allocate(div_ );
1104
stride:=img._stride;
1120
src_pix_ptr:=img.pix_ptr(x ,0 );
1126
stack_pix_ptr:=stack.array_operator(i );
1128
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1129
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1130
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1132
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) );
1133
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) );
1134
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) );
1135
inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1136
inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1137
inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1148
inc(ptrcomp(src_pix_ptr ) ,stride );
1150
stack_pix_ptr:=stack.array_operator(i + ry );
1152
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1153
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1154
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1156
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (ry + 1 - i ) );
1157
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (ry + 1 - i ) );
1158
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (ry + 1 - i ) );
1159
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1160
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1161
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1173
src_pix_ptr:=img.pix_ptr(x ,yp );
1174
dst_pix_ptr:=img.pix_ptr(x ,0 );
1180
int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum );
1181
int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum );
1182
int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum );
1184
inc(ptrcomp(dst_pix_ptr ) ,stride );
1186
dec(sum_r ,sum_out_r );
1187
dec(sum_g ,sum_out_g );
1188
dec(sum_b ,sum_out_b );
1190
stack_start:=stack_ptr + div_ - ry;
1192
if stack_start >= div_ then
1193
dec(stack_start ,div_ );
1195
stack_pix_ptr:=stack.array_operator(stack_start );
1197
dec(sum_out_r ,stack_pix_ptr.r );
1198
dec(sum_out_g ,stack_pix_ptr.g );
1199
dec(sum_out_b ,stack_pix_ptr.b );
1203
inc(ptrcomp(src_pix_ptr ) ,stride );
1209
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1210
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1211
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1213
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1214
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1215
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1216
inc(sum_r ,sum_in_r );
1217
inc(sum_g ,sum_in_g );
1218
inc(sum_b ,sum_in_b );
1222
if stack_ptr >= div_ then
1225
stack_pix_ptr:=stack.array_operator(stack_ptr );
1227
inc(sum_out_r ,stack_pix_ptr.r );
1228
inc(sum_out_g ,stack_pix_ptr.g );
1229
inc(sum_out_b ,stack_pix_ptr.b );
1230
dec(sum_in_r ,stack_pix_ptr.r );
1231
dec(sum_in_g ,stack_pix_ptr.g );
1232
dec(sum_in_b ,stack_pix_ptr.b );
1248
{ STACK_BLUR_RGBA32 }
1249
procedure stack_blur_rgba32(img : pixel_formats_ptr; rx ,ry : unsigned );
1251
R ,G ,B ,A ,stride : int;
1253
x ,y ,xp ,yp ,i ,stack_ptr ,stack_start ,
1255
sum_r ,sum_g ,sum_b ,sum_a ,
1257
sum_in_r ,sum_in_g ,sum_in_b ,sum_in_a ,
1259
sum_out_r ,sum_out_g ,sum_out_b ,sum_out_a ,
1261
w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned;
1263
src_pix_ptr ,dst_pix_ptr : int8u_ptr;
1265
stack_pix_ptr : aggclr_ptr;
1280
stack.Construct(sizeof(aggclr ) );
1288
mul_sum:=g_stack_blur8_mul[rx ];
1289
shr_sum:=g_stack_blur8_shr[rx ];
1291
stack.allocate(div_ );
1310
src_pix_ptr:=img.pix_ptr(0 ,y );
1316
stack_pix_ptr:=stack.array_operator(i );
1318
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1319
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1320
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1321
stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^;
1323
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) );
1324
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) );
1325
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) );
1326
inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (i + 1 ) );
1328
inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1329
inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1330
inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1331
inc(sum_out_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ );
1342
inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
1344
stack_pix_ptr:=stack.array_operator(i + rx );
1346
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1347
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1348
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1349
stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^;
1351
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (rx + 1 - i ) );
1352
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (rx + 1 - i ) );
1353
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (rx + 1 - i ) );
1354
inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (rx + 1 - i ) );
1356
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1357
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1358
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1359
inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ );
1371
src_pix_ptr:=img.pix_ptr(xp ,y );
1372
dst_pix_ptr:=img.pix_ptr(0 ,y );
1378
int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum );
1379
int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum );
1380
int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum );
1381
int8u_ptr(ptrcomp(dst_pix_ptr ) + A )^:=int8u((sum_a * mul_sum ) shr shr_sum );
1383
inc(ptrcomp(dst_pix_ptr ) ,img.m_pix_width );
1385
dec(sum_r ,sum_out_r );
1386
dec(sum_g ,sum_out_g );
1387
dec(sum_b ,sum_out_b );
1388
dec(sum_a ,sum_out_a );
1390
stack_start:=stack_ptr + div_ - rx;
1392
if stack_start >= div_ then
1393
dec(stack_start ,div_ );
1395
stack_pix_ptr:=stack.array_operator(stack_start );
1397
dec(sum_out_r ,stack_pix_ptr.r );
1398
dec(sum_out_g ,stack_pix_ptr.g );
1399
dec(sum_out_b ,stack_pix_ptr.b );
1400
dec(sum_out_a ,stack_pix_ptr.a );
1404
inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
1409
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1410
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1411
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1412
stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^;
1414
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1415
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1416
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1417
inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ );
1419
inc(sum_r ,sum_in_r );
1420
inc(sum_g ,sum_in_g );
1421
inc(sum_b ,sum_in_b );
1422
inc(sum_a ,sum_in_a );
1426
if stack_ptr >= div_ then
1429
stack_pix_ptr:=stack.array_operator(stack_ptr );
1431
inc(sum_out_r ,stack_pix_ptr.r );
1432
inc(sum_out_g ,stack_pix_ptr.g );
1433
inc(sum_out_b ,stack_pix_ptr.b );
1434
inc(sum_out_a ,stack_pix_ptr.a );
1435
dec(sum_in_r ,stack_pix_ptr.r );
1436
dec(sum_in_g ,stack_pix_ptr.g );
1437
dec(sum_in_b ,stack_pix_ptr.b );
1438
dec(sum_in_a ,stack_pix_ptr.a );
1457
mul_sum:=g_stack_blur8_mul[ry ];
1458
shr_sum:=g_stack_blur8_shr[ry ];
1460
stack.allocate(div_ );
1462
stride:=img._stride;
1481
src_pix_ptr:=img.pix_ptr(x ,0 );
1487
stack_pix_ptr:=stack.array_operator(i );
1489
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1490
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1491
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1492
stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^;
1494
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) );
1495
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) );
1496
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) );
1497
inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (i + 1 ) );
1498
inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1499
inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1500
inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1501
inc(sum_out_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ );
1512
inc(ptrcomp(src_pix_ptr ) ,stride );
1514
stack_pix_ptr:=stack.array_operator(i + ry );
1516
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1517
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1518
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1519
stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^;
1521
inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (ry + 1 - i ) );
1522
inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (ry + 1 - i ) );
1523
inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (ry + 1 - i ) );
1524
inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (ry + 1 - i ) );
1525
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1526
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1527
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1528
inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ );
1540
src_pix_ptr:=img.pix_ptr(x ,yp );
1541
dst_pix_ptr:=img.pix_ptr(x ,0 );
1547
int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum );
1548
int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum );
1549
int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum );
1550
int8u_ptr(ptrcomp(dst_pix_ptr ) + A )^:=int8u((sum_a * mul_sum ) shr shr_sum );
1552
inc(ptrcomp(dst_pix_ptr ) ,stride );
1554
dec(sum_r ,sum_out_r );
1555
dec(sum_g ,sum_out_g );
1556
dec(sum_b ,sum_out_b );
1557
dec(sum_a ,sum_out_a );
1559
stack_start:=stack_ptr + div_ - ry;
1561
if stack_start >= div_ then
1562
dec(stack_start ,div_ );
1564
stack_pix_ptr:=stack.array_operator(stack_start );
1566
dec(sum_out_r ,stack_pix_ptr.r );
1567
dec(sum_out_g ,stack_pix_ptr.g );
1568
dec(sum_out_b ,stack_pix_ptr.b );
1569
dec(sum_out_a ,stack_pix_ptr.a );
1573
inc(ptrcomp(src_pix_ptr ) ,stride );
1579
stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^;
1580
stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^;
1581
stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^;
1582
stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^;
1584
inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ );
1585
inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ );
1586
inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ );
1587
inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ );
1588
inc(sum_r ,sum_in_r );
1589
inc(sum_g ,sum_in_g );
1590
inc(sum_b ,sum_in_b );
1591
inc(sum_a ,sum_in_a );
1595
if stack_ptr >= div_ then
1598
stack_pix_ptr:=stack.array_operator(stack_ptr );
1600
inc(sum_out_r ,stack_pix_ptr.r );
1601
inc(sum_out_g ,stack_pix_ptr.g );
1602
inc(sum_out_b ,stack_pix_ptr.b );
1603
inc(sum_out_a ,stack_pix_ptr.a );
1604
dec(sum_in_r ,stack_pix_ptr.r );
1605
dec(sum_in_g ,stack_pix_ptr.g );
1606
dec(sum_in_b ,stack_pix_ptr.b );
1607
dec(sum_in_a ,stack_pix_ptr.a );