//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.4 (Public License) // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // // Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) // Pascal Port By: Milan Marusinec alias Milano // milan@marusinec.sk // http://www.aggpas.org // Copyright (c) 2005-2006 // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://www.antigrain.com // //---------------------------------------------------------------------------- // // The Stack Blur Algorithm was invented by Mario Klingemann, // mario@quasimondo.com and described here: // http://incubator.quasimondo.com/processing/fast_blur_deluxe.php // (search phrase "Stackblur: Fast But Goodlooking"). // The major improvement is that there's no more division table // that was very expensive to create for large blur radii. Insted, // for 8-bit per channel and radius not exceeding 254 the division is // replaced by multiplication and shift. // // [Pascal Port History] ----------------------------------------------------- // // 11.10.2007-Milano: recursive_blur & finished OK // 10.10.2007-Milano: stack_blur // 09.10.2007-Milano: Unit port establishment // { agg_blur.pas } unit agg_blur ; INTERFACE {$I agg_mode.inc } {$Q- } {$R- } uses agg_basics , agg_array , agg_color , agg_pixfmt , agg_pixfmt_transposer ; { GLOBAL VARIABLES & CONSTANTS } { TYPES DEFINITION } type stack_blur = object private m_buf , m_stack : pod_vector; public constructor Construct; destructor Destruct; procedure blur_x(img : pixel_formats_ptr; radius : unsigned ); procedure blur_y(img : pixel_formats_ptr; radius : unsigned ); procedure blur(img : pixel_formats_ptr; radius : unsigned ); end; recursive_blur = object private m_sum1 , m_sum2 , m_buf : pod_vector; public constructor Construct; destructor Destruct; procedure blur_x(img : pixel_formats_ptr; radius : double ); procedure blur_y(img : pixel_formats_ptr; radius : double ); procedure blur(img : pixel_formats_ptr; radius : double ); end; { GLOBAL PROCEDURES } procedure stack_blur_gray8 (img : pixel_formats_ptr; rx ,ry : unsigned ); procedure stack_blur_rgb24 (img : pixel_formats_ptr; rx ,ry : unsigned ); procedure stack_blur_rgba32(img : pixel_formats_ptr; rx ,ry : unsigned ); IMPLEMENTATION { LOCAL VARIABLES & CONSTANTS } const g_stack_blur8_mul : array[0..254 ] of int16u = ( 512 ,512 ,456 ,512 ,328 ,456 ,335 ,512 ,405 ,328 ,271 ,456 ,388 ,335 ,292 ,512 , 454 ,405 ,364 ,328 ,298 ,271 ,496 ,456 ,420 ,388 ,360 ,335 ,312 ,292 ,273 ,512 , 482 ,454 ,428 ,405 ,383 ,364 ,345 ,328 ,312 ,298 ,284 ,271 ,259 ,496 ,475 ,456 , 437 ,420 ,404 ,388 ,374 ,360 ,347 ,335 ,323 ,312 ,302 ,292 ,282 ,273 ,265 ,512 , 497 ,482 ,468 ,454 ,441 ,428 ,417 ,405 ,394 ,383 ,373 ,364 ,354 ,345 ,337 ,328 , 320 ,312 ,305 ,298 ,291 ,284 ,278 ,271 ,265 ,259 ,507 ,496 ,485 ,475 ,465 ,456 , 446 ,437 ,428 ,420 ,412 ,404 ,396 ,388 ,381 ,374 ,367 ,360 ,354 ,347 ,341 ,335 , 329 ,323 ,318 ,312 ,307 ,302 ,297 ,292 ,287 ,282 ,278 ,273 ,269 ,265 ,261 ,512 , 505 ,497 ,489 ,482 ,475 ,468 ,461 ,454 ,447 ,441 ,435 ,428 ,422 ,417 ,411 ,405 , 399 ,394 ,389 ,383 ,378 ,373 ,368 ,364 ,359 ,354 ,350 ,345 ,341 ,337 ,332 ,328 , 324 ,320 ,316 ,312 ,309 ,305 ,301 ,298 ,294 ,291 ,287 ,284 ,281 ,278 ,274 ,271 , 268 ,265 ,262 ,259 ,257 ,507 ,501 ,496 ,491 ,485 ,480 ,475 ,470 ,465 ,460 ,456 , 451 ,446 ,442 ,437 ,433 ,428 ,424 ,420 ,416 ,412 ,408 ,404 ,400 ,396 ,392 ,388 , 385 ,381 ,377 ,374 ,370 ,367 ,363 ,360 ,357 ,354 ,350 ,347 ,344 ,341 ,338 ,335 , 332 ,329 ,326 ,323 ,320 ,318 ,315 ,312 ,310 ,307 ,304 ,302 ,299 ,297 ,294 ,292 , 289 ,287 ,285 ,282 ,280 ,278 ,275 ,273 ,271 ,269 ,267 ,265 ,263 ,261 ,259 ); g_stack_blur8_shr : array[0..254 ] of int8u = ( 9 ,11 ,12 ,13 ,13 ,14 ,14 ,15 ,15 ,15 ,15 ,16 ,16 ,16 ,16 ,17 , 17 ,17 ,17 ,17 ,17 ,17 ,18 ,18 ,18 ,18 ,18 ,18 ,18 ,18 ,18 ,19 , 19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,19 ,20 ,20 ,20 , 20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,20 ,21 , 21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 , 21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,21 ,22 ,22 ,22 ,22 ,22 ,22 , 22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 , 22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,22 ,23 , 23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 , 23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 , 23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 ,23 , 23 ,23 ,23 ,23 ,23 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 , 24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 , 24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 , 24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 , 24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ,24 ); type stack_calculator_ptr = ^stack_calculator; stack_calculator = object v , r , g , b , a : unsigned; procedure clear; procedure add (c : aggclr ); procedure add_ (c : aggclr; k : unsigned ); procedure add__(c : stack_calculator ); procedure sub (c : aggclr ); procedure sub_ (c : stack_calculator ); procedure calc_pix (c : aggclr_ptr; div_ : unsigned ); procedure calc_pix_(c : aggclr_ptr; mul_ ,shr_ : unsigned ); end; gauss_calculator_ptr = ^gauss_calculator; gauss_calculator = object v , r , g , b , a : double; procedure from_pix(c : aggclr ); procedure calc( b1 ,b2 ,b3 ,b4 : double; c1 ,c2 ,c3 ,c4 : gauss_calculator_ptr ); procedure to_pix(c : aggclr_ptr ); end; { UNIT IMPLEMENTATION } { CLEAR } procedure stack_calculator.clear; begin v:=0; r:=0; g:=0; b:=0; a:=0; end; { ADD } procedure stack_calculator.add(c : aggclr ); begin inc(v ,c.v ); inc(r ,c.r ); inc(g ,c.g ); inc(b ,c.b ); inc(a ,c.a ); end; { ADD__ } procedure stack_calculator.add__(c : stack_calculator ); begin inc(v ,c.v ); inc(r ,c.r ); inc(g ,c.g ); inc(b ,c.b ); inc(a ,c.a ); end; { ADD_ } procedure stack_calculator.add_(c : aggclr; k : unsigned ); begin inc(v ,c.v * k ); inc(r ,c.r * k ); inc(g ,c.g * k ); inc(b ,c.b * k ); inc(a ,c.a * k ); end; { SUB } procedure stack_calculator.sub(c : aggclr ); begin dec(v ,c.v ); dec(r ,c.r ); dec(g ,c.g ); dec(b ,c.b ); dec(a ,c.a ); end; { SUB_ } procedure stack_calculator.sub_(c : stack_calculator ); begin dec(v ,c.v ); dec(r ,c.r ); dec(g ,c.g ); dec(b ,c.b ); dec(a ,c.a ); end; { CALC_PIX } procedure stack_calculator.calc_pix(c : aggclr_ptr; div_ : unsigned ); begin c.v:=int8u(v div div_ ); c.r:=int8u(r div div_ ); c.g:=int8u(g div div_ ); c.b:=int8u(b div div_ ); c.a:=int8u(a div div_ ); end; { CALC_PIX_ } procedure stack_calculator.calc_pix_(c : aggclr_ptr; mul_ ,shr_ : unsigned ); begin c.v:=int8u((v * mul_ ) shr shr_ ); c.r:=int8u((r * mul_ ) shr shr_ ); c.g:=int8u((g * mul_ ) shr shr_ ); c.b:=int8u((b * mul_ ) shr shr_ ); c.a:=int8u((a * mul_ ) shr shr_ ); end; { FROM_PIX } procedure gauss_calculator.from_pix(c : aggclr ); begin v:=c.v; r:=c.r; g:=c.g; b:=c.b; a:=c.a; end; { CALC } procedure gauss_calculator.calc( b1 ,b2 ,b3 ,b4 : double; c1 ,c2 ,c3 ,c4 : gauss_calculator_ptr ); begin v:=b1 * c1.v + b2 * c2.v + b3 * c3.v + b4 * c4.v; r:=b1 * c1.r + b2 * c2.r + b3 * c3.r + b4 * c4.r; g:=b1 * c1.g + b2 * c2.g + b3 * c3.g + b4 * c4.g; b:=b1 * c1.b + b2 * c2.b + b3 * c3.b + b4 * c4.b; a:=b1 * c1.a + b2 * c2.a + b3 * c3.a + b4 * c4.a; end; { TO_PIX } procedure gauss_calculator.to_pix(c : aggclr_ptr ); begin c.v:=int8u(uround(v ) ); c.r:=int8u(uround(r ) ); c.g:=int8u(uround(g ) ); c.b:=int8u(uround(b ) ); c.a:=int8u(uround(a ) ); end; { CONSTRUCT } constructor stack_blur.Construct; begin m_buf.Construct (sizeof(aggclr ) ); m_stack.Construct(sizeof(aggclr ) ); end; { DESTRUCT } destructor stack_blur.Destruct; begin m_buf.Destruct; m_stack.Destruct; end; { BLUR_X } procedure stack_blur.blur_x(img : pixel_formats_ptr; radius : unsigned ); var x ,y ,xp ,i ,stack_ptr ,stack_start , w ,h ,wm ,div_ ,div_sum ,mul_sum ,shr_sum ,max_val : unsigned; pix : aggclr; stack_pix ,_c : aggclr_ptr; sum ,sum_in ,sum_out : stack_calculator; begin if radius < 1 then exit; w :=img._width; h :=img._height; wm :=w - 1; div_:=radius * 2 + 1; div_sum:=(radius + 1 ) * (radius + 1 ); mul_sum:=0; shr_sum:=0; max_val:=base_mask; if (max_val <= 255 ) and (radius < 255 ) then begin mul_sum:=g_stack_blur8_mul[radius ]; shr_sum:=g_stack_blur8_shr[radius ]; end; m_buf.allocate (w ,128 ); m_stack.allocate(div_ ,32 ); y:=0; while y < h do begin sum.clear; sum_in.clear; sum_out.clear; pix:=img.pixel(img ,0 ,y ); i:=0; while i <= radius do begin move(pix ,m_stack.array_operator(i )^ ,sizeof(aggclr ) ); sum.add_ (pix ,i + 1 ); sum_out.add(pix ); inc(i ); end; i:=1; while i <= radius do begin if i > wm then pix:=img.pixel(img ,wm ,y ) else pix:=img.pixel(img ,i ,y ); move(pix ,m_stack.array_operator(i + radius )^ ,sizeof(aggclr ) ); sum.add_ (pix ,radius + 1 - i ); sum_in.add(pix ); inc(i ); end; stack_ptr:=radius; x:=0; while x < w do begin if mul_sum <> 0 then sum.calc_pix_(aggclr_ptr(m_buf.array_operator(x ) ) ,mul_sum ,shr_sum ) else sum.calc_pix(aggclr_ptr(m_buf.array_operator(x ) ) ,div_sum ); sum.sub_(sum_out ); stack_start:=stack_ptr + div_ - radius; if stack_start >= div_ then dec(stack_start ,div_ ); stack_pix:=m_stack.array_operator(stack_start ); sum_out.sub(stack_pix^ ); xp:=x + radius + 1; if xp > wm then xp:=wm; pix:=img.pixel(img ,xp ,y ); stack_pix^:=pix; sum_in.add(pix ); sum.add__ (sum_in ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix:=m_stack.array_operator(stack_ptr ); sum_out.add(stack_pix^ ); sum_in.sub (stack_pix^ ); inc(x ); end; _c:=m_buf.array_operator(0 ); img.copy_color_hspan(img ,0 ,y ,w ,_c ); inc(y ); end; end; { BLUR_Y } procedure stack_blur.blur_y(img : pixel_formats_ptr; radius : unsigned ); var img2 : pixel_formats_transposer; begin pixfmt_transposer(img2 ,img ); blur_x (@img2 ,radius ); end; { BLUR } procedure stack_blur.blur(img : pixel_formats_ptr; radius : unsigned ); var img2 : pixel_formats_transposer; begin blur_x (img ,radius ); pixfmt_transposer(img2 ,img ); blur_x (@img2 ,radius ); end; { CONSTRUCT } constructor recursive_blur.Construct; begin m_sum1.Construct(sizeof(gauss_calculator ) ); m_sum2.Construct(sizeof(gauss_calculator ) ); m_buf.Construct (sizeof(aggclr ) ); end; { DESTRUCT } destructor recursive_blur.Destruct; begin m_sum1.Destruct; m_sum2.Destruct; m_buf.Destruct; end; { BLUR_X } procedure recursive_blur.blur_x(img : pixel_formats_ptr; radius : double ); var s ,q ,q2 ,q3 ,b0 ,b1 ,b2 ,b3 ,b : double; w ,h ,wm ,x ,y : int; c : gauss_calculator; g0 ,g1 : gauss_calculator_ptr; begin if radius < 0.62 then exit; if img._width < 3 then exit; s:=radius * 0.5; if s < 2.5 then q:=3.97156 - 4.14554 * Sqrt(1 - 0.26891 * s ) else q:=0.98711 * s - 0.96330; q2:=q * q; q3:=q2 * q; b0:=1.0 / (1.578250 + 2.444130 * q + 1.428100 * q2 + 0.422205 * q3 ); b1:=2.44413 * q + 2.85619 * q2 + 1.26661 * q3; b2:=-1.42810 * q2 + -1.26661 * q3; b3:=0.422205 * q3; b :=1 - (b1 + b2 + b3 ) * b0; b1:=b1 * b0; b2:=b2 * b0; b3:=b3 * b0; w :=img._width; h :=img._height; wm:=w - 1; m_sum1.allocate(w ); m_sum2.allocate(w ); m_buf.allocate (w ); y:=0; while y < h do begin g0:=gauss_calculator_ptr(m_sum1.array_operator(0 ) ); c.from_pix(img.pixel(img ,0 ,y ) ); g0.calc( b ,b1 ,b2 ,b3 , @c ,@c ,@c ,@c ); g1:=gauss_calculator_ptr(m_sum1.array_operator(1 ) ); c.from_pix(img.pixel(img ,1 ,y ) ); g1.calc( b ,b1 ,b2 ,b3 , @c ,g0 ,g0 ,g0 ); c.from_pix (img.pixel(img ,2 ,y ) ); gauss_calculator_ptr(m_sum1.array_operator(2 ) ).calc( b ,b1 ,b2 ,b3 , @c ,g1 ,g0 ,g0 ); x:=3; while x < w do begin c.from_pix(img.pixel(img ,x ,y ) ); gauss_calculator_ptr(m_sum1.array_operator(x ) ).calc( b ,b1 ,b2 ,b3 , @c , gauss_calculator_ptr(m_sum1.array_operator(x - 1 ) ) , gauss_calculator_ptr(m_sum1.array_operator(x - 2 ) ) , gauss_calculator_ptr(m_sum1.array_operator(x - 3 ) ) ); inc(x ); end; g0:=gauss_calculator_ptr(m_sum1.array_operator(wm ) ); g1:=gauss_calculator_ptr(m_sum2.array_operator(wm ) ); g1.calc( b ,b1 ,b2 ,b3 , g0 ,g0 ,g0 ,g0 ); gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ).calc( b ,b1 ,b2 ,b3 , gauss_calculator_ptr(m_sum1.array_operator(wm - 1 ) ) , g1 ,g1 ,g1 ); gauss_calculator_ptr(m_sum2.array_operator(wm - 2 ) ).calc( b ,b1 ,b2 ,b3 , gauss_calculator_ptr(m_sum1.array_operator(wm - 2 ) ) , gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ) , g1 ,g1 ); g1.to_pix( aggclr_ptr(m_buf.array_operator(wm ) ) ); gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ).to_pix( aggclr_ptr(m_buf.array_operator(wm - 1 ) ) ); gauss_calculator_ptr(m_sum2.array_operator(wm - 2 ) ).to_pix( aggclr_ptr(m_buf.array_operator(wm - 2 ) ) ); x:=wm - 3; while x >= 0 do begin gauss_calculator_ptr(m_sum2.array_operator(x ) ).calc( b ,b1 ,b2 ,b3 , gauss_calculator_ptr(m_sum1.array_operator(x ) ) , gauss_calculator_ptr(m_sum2.array_operator(x + 1 ) ) , gauss_calculator_ptr(m_sum2.array_operator(x + 2 ) ) , gauss_calculator_ptr(m_sum2.array_operator(x + 3 ) ) ); gauss_calculator_ptr(m_sum2.array_operator(x ) ).to_pix( aggclr_ptr(m_buf.array_operator(x ) ) ); dec(x ); end; img.copy_color_hspan(img ,0 ,y ,w ,m_buf.array_operator(0 ) ); inc(y ); end; end; { BLUR_Y } procedure recursive_blur.blur_y(img : pixel_formats_ptr; radius : double ); var img2 : pixel_formats_transposer; begin pixfmt_transposer(img2 ,img ); blur_x (@img2 ,radius ); end; { BLUR } procedure recursive_blur.blur(img : pixel_formats_ptr; radius : double ); var img2 : pixel_formats_transposer; begin blur_x (img ,radius ); pixfmt_transposer(img2 ,img ); blur_x (@img2 ,radius ); end; { STACK_BLUR_GRAY8 } procedure stack_blur_gray8(img : pixel_formats_ptr; rx ,ry : unsigned ); var stride : int; x ,y ,xp ,yp ,i ,pix ,stack_pix ,sum ,sum_in ,sum_out , stack_ptr ,stack_start ,w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned; src_pix_ptr ,dst_pix_ptr : int8u_ptr; stack : pod_vector; begin w :=img._width; h :=img._height; wm:=w - 1; hm:=h - 1; stack.Construct(sizeof(int8u ) ); if rx > 0 then begin if rx > 254 then rx:=254; div_:=rx * 2 + 1; mul_sum:=g_stack_blur8_mul[rx ]; shr_sum:=g_stack_blur8_shr[rx ]; stack.allocate(div_ ); y:=0; while y < h do begin sum :=0; sum_in :=0; sum_out:=0; src_pix_ptr:=img.pix_ptr(0 ,y ); pix :=src_pix_ptr^; i:=0; while i <= rx do begin int8u_ptr(stack.array_operator(i ) )^:=pix; inc(sum ,pix * (i + 1 ) ); inc(sum_out ,pix ); inc(i ); end; i:=1; while i <= rx do begin if i <= wm then inc(ptrcomp(src_pix_ptr ) ,img.m_step ); pix:=src_pix_ptr^; int8u_ptr(stack.array_operator(i + rx ) )^:=pix; inc(sum ,pix * (rx + 1 - i ) ); inc(sum_in ,pix ); inc(i ); end; stack_ptr:=rx; xp :=rx; if xp > wm then xp:=wm; src_pix_ptr:=img.pix_ptr(xp ,y ); dst_pix_ptr:=img.pix_ptr(0 ,y ); x:=0; while x < w do begin dst_pix_ptr^:=int8u((sum * mul_sum ) shr shr_sum ); inc(ptrcomp(dst_pix_ptr ) ,img.m_step ); dec(sum ,sum_out ); stack_start:=stack_ptr + div_ - rx; if stack_start >= div_ then dec(stack_start ,div_ ); dec(sum_out ,int8u_ptr(stack.array_operator(stack_start ) )^ ); if xp < wm then begin inc(ptrcomp(src_pix_ptr ) ,img.m_step ); pix:=src_pix_ptr^; inc(xp ); end; int8u_ptr(stack.array_operator(stack_start ) )^:=pix; inc(sum_in ,pix ); inc(sum ,sum_in ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix:=int8u_ptr(stack.array_operator(stack_ptr ) )^; inc(sum_out ,stack_pix ); dec(sum_in ,stack_pix ); inc(x ); end; inc(y ); end; end; if ry > 0 then begin if ry > 254 then ry:=254; div_:=ry * 2 + 1; mul_sum:=g_stack_blur8_mul[ry ]; shr_sum:=g_stack_blur8_shr[ry ]; stack.allocate(div_ ); stride:=img._stride; x:=0; while x < w do begin sum :=0; sum_in :=0; sum_out:=0; src_pix_ptr:=img.pix_ptr(x ,0 ); pix :=src_pix_ptr^; i:=0; while i <= ry do begin int8u_ptr(stack.array_operator(i ) )^:=pix; inc(sum ,pix * (i + 1 ) ); inc(sum_out ,pix ); inc(i ); end; i:=1; while i <= ry do begin if i <= hm then inc(ptrcomp(src_pix_ptr ) ,stride ); pix:=src_pix_ptr^; int8u_ptr(stack.array_operator(i + ry ) )^:=pix; inc(sum ,pix * (ry + 1 - i ) ); inc(sum_in ,pix ); inc(i ); end; stack_ptr:=ry; yp :=ry; if yp > hm then yp:=hm; src_pix_ptr:=img.pix_ptr(x ,yp ); dst_pix_ptr:=img.pix_ptr(x ,0 ); y:=0; while y < h do begin dst_pix_ptr^:=int8u((sum * mul_sum ) shr shr_sum ); inc(ptrcomp(dst_pix_ptr ) ,stride ); dec(sum ,sum_out ); stack_start:=stack_ptr + div_ - ry; if stack_start >= div_ then dec(stack_start ,div_ ); dec(sum_out ,int8u_ptr(stack.array_operator(stack_start ) )^ ); if yp < hm then begin inc(ptrcomp(src_pix_ptr ) ,stride ); pix:=src_pix_ptr^; inc(yp ); end; int8u_ptr(stack.array_operator(stack_start ) )^:=pix; inc(sum_in ,pix ); inc(sum ,sum_in ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix:=int8u_ptr(stack.array_operator(stack_ptr ) )^; inc(sum_out ,stack_pix ); dec(sum_in ,stack_pix ); inc(y ); end; inc(x ); end; end; stack.Destruct; end; { STACK_BLUR_RGB24 } procedure stack_blur_rgb24(img : pixel_formats_ptr; rx ,ry : unsigned ); var R ,G ,B ,stride : int; x ,y ,xp ,yp ,i ,stack_ptr ,stack_start , sum_r ,sum_g ,sum_b , sum_in_r ,sum_in_g ,sum_in_b , sum_out_r ,sum_out_g ,sum_out_b , w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned; src_pix_ptr ,dst_pix_ptr : int8u_ptr; stack_pix_ptr : aggclr_ptr; stack : pod_array; begin R:=img.m_order.R; G:=img.m_order.G; B:=img.m_order.B; w :=img._width; h :=img._height; wm:=w - 1; hm:=h - 1; stack.Construct(sizeof(aggclr ) ); if rx > 0 then begin if rx > 254 then rx:=254; div_ :=rx * 2 + 1; mul_sum:=g_stack_blur8_mul[rx ]; shr_sum:=g_stack_blur8_shr[rx ]; stack.allocate(div_ ); y:=0; while y < h do begin sum_r :=0; sum_g :=0; sum_b :=0; sum_in_r :=0; sum_in_g :=0; sum_in_b :=0; sum_out_r:=0; sum_out_g:=0; sum_out_b:=0; src_pix_ptr:=img.pix_ptr(0 ,y ); i:=0; while i <= rx do begin stack_pix_ptr:=stack.array_operator(i ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) ); inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(i ); end; i:=1; while i <= rx do begin if i <= wm then inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width ); stack_pix_ptr:=stack.array_operator(i + rx ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (rx + 1 - i ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (rx + 1 - i ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (rx + 1 - i ) ); inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(i ); end; stack_ptr:=rx; xp :=rx; if xp > wm then xp:=wm; src_pix_ptr:=img.pix_ptr(xp ,y ); dst_pix_ptr:=img.pix_ptr(0 ,y ); x:=0; while x < w do begin int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum ); inc(ptrcomp(dst_pix_ptr ) ,img.m_pix_width ); dec(sum_r ,sum_out_r ); dec(sum_g ,sum_out_g ); dec(sum_b ,sum_out_b ); stack_start:=stack_ptr + div_ - rx; if stack_start >= div_ then dec(stack_start ,div_ ); stack_pix_ptr:=stack.array_operator(stack_start ); dec(sum_out_r ,stack_pix_ptr.r ); dec(sum_out_g ,stack_pix_ptr.g ); dec(sum_out_b ,stack_pix_ptr.b ); if xp < wm then begin inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width ); inc(xp ); end; stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_r ,sum_in_r ); inc(sum_g ,sum_in_g ); inc(sum_b ,sum_in_b ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix_ptr:=stack.array_operator(stack_ptr ); inc(sum_out_r ,stack_pix_ptr.r ); inc(sum_out_g ,stack_pix_ptr.g ); inc(sum_out_b ,stack_pix_ptr.b ); dec(sum_in_r ,stack_pix_ptr.r ); dec(sum_in_g ,stack_pix_ptr.g ); dec(sum_in_b ,stack_pix_ptr.b ); inc(x ); end; inc(y ); end; end; if ry > 0 then begin if ry > 254 then ry:=254; div_:=ry * 2 + 1; mul_sum:=g_stack_blur8_mul[ry ]; shr_sum:=g_stack_blur8_shr[ry ]; stack.allocate(div_ ); stride:=img._stride; x:=0; while x < w do begin sum_r :=0; sum_g :=0; sum_b :=0; sum_in_r :=0; sum_in_g :=0; sum_in_b :=0; sum_out_r:=0; sum_out_g:=0; sum_out_b:=0; src_pix_ptr:=img.pix_ptr(x ,0 ); i:=0; while i <= ry do begin stack_pix_ptr:=stack.array_operator(i ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) ); inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(i ); end; i:=1; while i <= ry do begin if i <= hm then inc(ptrcomp(src_pix_ptr ) ,stride ); stack_pix_ptr:=stack.array_operator(i + ry ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (ry + 1 - i ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (ry + 1 - i ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (ry + 1 - i ) ); inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(i ); end; stack_ptr:=ry; yp :=ry; if yp > hm then yp:=hm; src_pix_ptr:=img.pix_ptr(x ,yp ); dst_pix_ptr:=img.pix_ptr(x ,0 ); y:=0; while y < h do begin int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum ); inc(ptrcomp(dst_pix_ptr ) ,stride ); dec(sum_r ,sum_out_r ); dec(sum_g ,sum_out_g ); dec(sum_b ,sum_out_b ); stack_start:=stack_ptr + div_ - ry; if stack_start >= div_ then dec(stack_start ,div_ ); stack_pix_ptr:=stack.array_operator(stack_start ); dec(sum_out_r ,stack_pix_ptr.r ); dec(sum_out_g ,stack_pix_ptr.g ); dec(sum_out_b ,stack_pix_ptr.b ); if yp < hm then begin inc(ptrcomp(src_pix_ptr ) ,stride ); inc(yp ); end; stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_r ,sum_in_r ); inc(sum_g ,sum_in_g ); inc(sum_b ,sum_in_b ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix_ptr:=stack.array_operator(stack_ptr ); inc(sum_out_r ,stack_pix_ptr.r ); inc(sum_out_g ,stack_pix_ptr.g ); inc(sum_out_b ,stack_pix_ptr.b ); dec(sum_in_r ,stack_pix_ptr.r ); dec(sum_in_g ,stack_pix_ptr.g ); dec(sum_in_b ,stack_pix_ptr.b ); inc(y ); end; inc(x ); end; end; stack.Destruct; end; { STACK_BLUR_RGBA32 } procedure stack_blur_rgba32(img : pixel_formats_ptr; rx ,ry : unsigned ); var R ,G ,B ,A ,stride : int; x ,y ,xp ,yp ,i ,stack_ptr ,stack_start , sum_r ,sum_g ,sum_b ,sum_a , sum_in_r ,sum_in_g ,sum_in_b ,sum_in_a , sum_out_r ,sum_out_g ,sum_out_b ,sum_out_a , w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned; src_pix_ptr ,dst_pix_ptr : int8u_ptr; stack_pix_ptr : aggclr_ptr; stack : pod_array; begin R:=img.m_order.R; G:=img.m_order.G; B:=img.m_order.B; A:=img.m_order.A; w :=img._width; h :=img._height; wm:=w - 1; hm:=h - 1; stack.Construct(sizeof(aggclr ) ); if rx > 0 then begin if rx > 254 then rx:=254; div_ :=rx * 2 + 1; mul_sum:=g_stack_blur8_mul[rx ]; shr_sum:=g_stack_blur8_shr[rx ]; stack.allocate(div_ ); y:=0; while y < h do begin sum_r :=0; sum_g :=0; sum_b :=0; sum_a :=0; sum_in_r :=0; sum_in_g :=0; sum_in_b :=0; sum_in_a :=0; sum_out_r:=0; sum_out_g:=0; sum_out_b:=0; sum_out_a:=0; src_pix_ptr:=img.pix_ptr(0 ,y ); i:=0; while i <= rx do begin stack_pix_ptr:=stack.array_operator(i ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) ); inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (i + 1 ) ); inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_out_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ ); inc(i ); end; i:=1; while i <= rx do begin if i <= wm then inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width ); stack_pix_ptr:=stack.array_operator(i + rx ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (rx + 1 - i ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (rx + 1 - i ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (rx + 1 - i ) ); inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (rx + 1 - i ) ); inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ ); inc(i ); end; stack_ptr:=rx; xp :=rx; if xp > wm then xp:=wm; src_pix_ptr:=img.pix_ptr(xp ,y ); dst_pix_ptr:=img.pix_ptr(0 ,y ); x:=0; while x < w do begin int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + A )^:=int8u((sum_a * mul_sum ) shr shr_sum ); inc(ptrcomp(dst_pix_ptr ) ,img.m_pix_width ); dec(sum_r ,sum_out_r ); dec(sum_g ,sum_out_g ); dec(sum_b ,sum_out_b ); dec(sum_a ,sum_out_a ); stack_start:=stack_ptr + div_ - rx; if stack_start >= div_ then dec(stack_start ,div_ ); stack_pix_ptr:=stack.array_operator(stack_start ); dec(sum_out_r ,stack_pix_ptr.r ); dec(sum_out_g ,stack_pix_ptr.g ); dec(sum_out_b ,stack_pix_ptr.b ); dec(sum_out_a ,stack_pix_ptr.a ); if xp < wm then begin inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width ); inc(xp ); end; stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^; inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ ); inc(sum_r ,sum_in_r ); inc(sum_g ,sum_in_g ); inc(sum_b ,sum_in_b ); inc(sum_a ,sum_in_a ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix_ptr:=stack.array_operator(stack_ptr ); inc(sum_out_r ,stack_pix_ptr.r ); inc(sum_out_g ,stack_pix_ptr.g ); inc(sum_out_b ,stack_pix_ptr.b ); inc(sum_out_a ,stack_pix_ptr.a ); dec(sum_in_r ,stack_pix_ptr.r ); dec(sum_in_g ,stack_pix_ptr.g ); dec(sum_in_b ,stack_pix_ptr.b ); dec(sum_in_a ,stack_pix_ptr.a ); inc(x ); end; inc(y ); end; end; if ry > 0 then begin if ry > 254 then ry:=254; div_:=ry * 2 + 1; mul_sum:=g_stack_blur8_mul[ry ]; shr_sum:=g_stack_blur8_shr[ry ]; stack.allocate(div_ ); stride:=img._stride; x:=0; while x < w do begin sum_r :=0; sum_g :=0; sum_b :=0; sum_a :=0; sum_in_r :=0; sum_in_g :=0; sum_in_b :=0; sum_in_a :=0; sum_out_r:=0; sum_out_g:=0; sum_out_b:=0; sum_out_a:=0; src_pix_ptr:=img.pix_ptr(x ,0 ); i:=0; while i <= ry do begin stack_pix_ptr:=stack.array_operator(i ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (i + 1 ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (i + 1 ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (i + 1 ) ); inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (i + 1 ) ); inc(sum_out_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_out_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_out_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_out_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ ); inc(i ); end; i:=1; while i <= ry do begin if i <= hm then inc(ptrcomp(src_pix_ptr ) ,stride ); stack_pix_ptr:=stack.array_operator(i + ry ); stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^; inc(sum_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ * (ry + 1 - i ) ); inc(sum_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ * (ry + 1 - i ) ); inc(sum_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ * (ry + 1 - i ) ); inc(sum_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ * (ry + 1 - i ) ); inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ ); inc(i ); end; stack_ptr:=ry; yp :=ry; if yp > hm then yp:=hm; src_pix_ptr:=img.pix_ptr(x ,yp ); dst_pix_ptr:=img.pix_ptr(x ,0 ); y:=0; while y < h do begin int8u_ptr(ptrcomp(dst_pix_ptr ) + R )^:=int8u((sum_r * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + G )^:=int8u((sum_g * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + B )^:=int8u((sum_b * mul_sum ) shr shr_sum ); int8u_ptr(ptrcomp(dst_pix_ptr ) + A )^:=int8u((sum_a * mul_sum ) shr shr_sum ); inc(ptrcomp(dst_pix_ptr ) ,stride ); dec(sum_r ,sum_out_r ); dec(sum_g ,sum_out_g ); dec(sum_b ,sum_out_b ); dec(sum_a ,sum_out_a ); stack_start:=stack_ptr + div_ - ry; if stack_start >= div_ then dec(stack_start ,div_ ); stack_pix_ptr:=stack.array_operator(stack_start ); dec(sum_out_r ,stack_pix_ptr.r ); dec(sum_out_g ,stack_pix_ptr.g ); dec(sum_out_b ,stack_pix_ptr.b ); dec(sum_out_a ,stack_pix_ptr.a ); if yp < hm then begin inc(ptrcomp(src_pix_ptr ) ,stride ); inc(yp ); end; stack_pix_ptr.r:=int8u_ptr(ptrcomp(src_pix_ptr ) + R )^; stack_pix_ptr.g:=int8u_ptr(ptrcomp(src_pix_ptr ) + G )^; stack_pix_ptr.b:=int8u_ptr(ptrcomp(src_pix_ptr ) + B )^; stack_pix_ptr.a:=int8u_ptr(ptrcomp(src_pix_ptr ) + A )^; inc(sum_in_r ,int8u_ptr(ptrcomp(src_pix_ptr ) + R )^ ); inc(sum_in_g ,int8u_ptr(ptrcomp(src_pix_ptr ) + G )^ ); inc(sum_in_b ,int8u_ptr(ptrcomp(src_pix_ptr ) + B )^ ); inc(sum_in_a ,int8u_ptr(ptrcomp(src_pix_ptr ) + A )^ ); inc(sum_r ,sum_in_r ); inc(sum_g ,sum_in_g ); inc(sum_b ,sum_in_b ); inc(sum_a ,sum_in_a ); inc(stack_ptr ); if stack_ptr >= div_ then stack_ptr:=0; stack_pix_ptr:=stack.array_operator(stack_ptr ); inc(sum_out_r ,stack_pix_ptr.r ); inc(sum_out_g ,stack_pix_ptr.g ); inc(sum_out_b ,stack_pix_ptr.b ); inc(sum_out_a ,stack_pix_ptr.a ); dec(sum_in_r ,stack_pix_ptr.r ); dec(sum_in_g ,stack_pix_ptr.g ); dec(sum_in_b ,stack_pix_ptr.b ); dec(sum_in_a ,stack_pix_ptr.a ); inc(y ); end; inc(x ); end; end; stack.Destruct; end; END.