~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to components/aggpas/src/agg_blur.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//----------------------------------------------------------------------------
2
 
// Anti-Grain Geometry - Version 2.4 (Public License)
3
 
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4
 
//
5
 
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
 
// Pascal Port By: Milan Marusinec alias Milano
7
 
//                 milan@marusinec.sk
8
 
//                 http://www.aggpas.org
9
 
// Copyright (c) 2005-2006
10
 
//
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.
15
 
//
16
 
//----------------------------------------------------------------------------
17
 
// Contact: mcseem@antigrain.com
18
 
//          mcseemagg@yahoo.com
19
 
//          http://www.antigrain.com
20
 
//
21
 
//----------------------------------------------------------------------------
22
 
//
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.
31
 
//
32
 
// [Pascal Port History] -----------------------------------------------------
33
 
//
34
 
// 11.10.2007-Milano: recursive_blur & finished OK
35
 
// 10.10.2007-Milano: stack_blur
36
 
// 09.10.2007-Milano: Unit port establishment
37
 
//
38
 
{ agg_blur.pas }
39
 
unit
40
 
 agg_blur ;
41
 
 
42
 
INTERFACE
43
 
 
44
 
{$I agg_mode.inc }
45
 
{$Q- }
46
 
{$R- }
47
 
uses
48
 
 agg_basics ,
49
 
 agg_array ,
50
 
 agg_color ,
51
 
 agg_pixfmt ,
52
 
 agg_pixfmt_transposer ;
53
 
 
54
 
{ GLOBAL VARIABLES & CONSTANTS }
55
 
 
56
 
{ TYPES DEFINITION }
57
 
type
58
 
 stack_blur = object
59
 
  private
60
 
   m_buf   ,
61
 
   m_stack : pod_vector;
62
 
 
63
 
  public
64
 
   constructor Construct;
65
 
   destructor  Destruct;
66
 
 
67
 
   procedure blur_x(img : pixel_formats_ptr; radius : unsigned );
68
 
   procedure blur_y(img : pixel_formats_ptr; radius : unsigned );
69
 
 
70
 
   procedure blur(img : pixel_formats_ptr; radius : unsigned );
71
 
 
72
 
  end;
73
 
 
74
 
 recursive_blur = object
75
 
  private
76
 
   m_sum1 ,
77
 
   m_sum2 ,
78
 
   m_buf  : pod_vector;
79
 
 
80
 
  public
81
 
   constructor Construct;
82
 
   destructor  Destruct;
83
 
 
84
 
   procedure blur_x(img : pixel_formats_ptr; radius : double );
85
 
   procedure blur_y(img : pixel_formats_ptr; radius : double );
86
 
 
87
 
   procedure blur(img : pixel_formats_ptr; radius : double );
88
 
 
89
 
  end;
90
 
 
91
 
{ GLOBAL PROCEDURES }
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 );
95
 
 
96
 
 
97
 
IMPLEMENTATION
98
 
{ LOCAL VARIABLES & CONSTANTS }
99
 
const
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 );
117
 
 
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 );
135
 
 
136
 
type
137
 
 stack_calculator_ptr = ^stack_calculator;
138
 
 stack_calculator = object
139
 
   v ,
140
 
   r ,
141
 
   g ,
142
 
   b ,
143
 
   a : unsigned;
144
 
 
145
 
   procedure clear;
146
 
 
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 );
152
 
 
153
 
   procedure calc_pix (c : aggclr_ptr; div_ : unsigned );
154
 
   procedure calc_pix_(c : aggclr_ptr; mul_ ,shr_ : unsigned );
155
 
 
156
 
  end;
157
 
 
158
 
 gauss_calculator_ptr = ^gauss_calculator;
159
 
 gauss_calculator = object
160
 
   v ,
161
 
   r ,
162
 
   g ,
163
 
   b ,
164
 
   a : double;
165
 
 
166
 
   procedure from_pix(c : aggclr );
167
 
 
168
 
   procedure calc(
169
 
              b1 ,b2 ,b3 ,b4 : double;
170
 
              c1 ,c2 ,c3 ,c4 : gauss_calculator_ptr );
171
 
 
172
 
   procedure to_pix(c : aggclr_ptr );
173
 
 
174
 
  end;
175
 
 
176
 
{ UNIT IMPLEMENTATION }
177
 
{ CLEAR }
178
 
procedure stack_calculator.clear;
179
 
begin
180
 
 v:=0;
181
 
 r:=0;
182
 
 g:=0;
183
 
 b:=0;
184
 
 a:=0;
185
 
 
186
 
end;
187
 
 
188
 
{ ADD }
189
 
procedure stack_calculator.add(c : aggclr );
190
 
begin
191
 
 inc(v ,c.v );
192
 
 inc(r ,c.r );
193
 
 inc(g ,c.g );
194
 
 inc(b ,c.b );
195
 
 inc(a ,c.a );
196
 
 
197
 
end;
198
 
 
199
 
{ ADD__ }
200
 
procedure stack_calculator.add__(c : stack_calculator );
201
 
begin
202
 
 inc(v ,c.v );
203
 
 inc(r ,c.r );
204
 
 inc(g ,c.g );
205
 
 inc(b ,c.b );
206
 
 inc(a ,c.a );
207
 
 
208
 
end;
209
 
 
210
 
{ ADD_ }
211
 
procedure stack_calculator.add_(c : aggclr; k : unsigned );
212
 
begin
213
 
 inc(v ,c.v * k );
214
 
 inc(r ,c.r * k );
215
 
 inc(g ,c.g * k );
216
 
 inc(b ,c.b * k );
217
 
 inc(a ,c.a * k );
218
 
 
219
 
end;
220
 
 
221
 
{ SUB }
222
 
procedure stack_calculator.sub(c : aggclr );
223
 
begin
224
 
 dec(v ,c.v );
225
 
 dec(r ,c.r );
226
 
 dec(g ,c.g );
227
 
 dec(b ,c.b );
228
 
 dec(a ,c.a );
229
 
 
230
 
end;
231
 
 
232
 
{ SUB_ }
233
 
procedure stack_calculator.sub_(c : stack_calculator );
234
 
begin
235
 
 dec(v ,c.v );
236
 
 dec(r ,c.r );
237
 
 dec(g ,c.g );
238
 
 dec(b ,c.b );
239
 
 dec(a ,c.a );
240
 
 
241
 
end;
242
 
 
243
 
{ CALC_PIX }
244
 
procedure stack_calculator.calc_pix(c : aggclr_ptr; div_ : unsigned );
245
 
begin
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_ );
251
 
 
252
 
end;
253
 
 
254
 
{ CALC_PIX_ }
255
 
procedure stack_calculator.calc_pix_(c : aggclr_ptr; mul_ ,shr_ : unsigned );
256
 
begin
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_ );
262
 
 
263
 
end;
264
 
 
265
 
{ FROM_PIX }
266
 
procedure gauss_calculator.from_pix(c : aggclr );
267
 
begin
268
 
 v:=c.v;
269
 
 r:=c.r;
270
 
 g:=c.g;
271
 
 b:=c.b;
272
 
 a:=c.a;
273
 
 
274
 
end;
275
 
 
276
 
{ CALC }
277
 
procedure gauss_calculator.calc(
278
 
           b1 ,b2 ,b3 ,b4 : double;
279
 
           c1 ,c2 ,c3 ,c4 : gauss_calculator_ptr );
280
 
begin
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;
286
 
 
287
 
end;
288
 
 
289
 
{ TO_PIX }
290
 
procedure gauss_calculator.to_pix(c : aggclr_ptr );
291
 
begin
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 ) );
297
 
 
298
 
end;
299
 
 
300
 
{ CONSTRUCT }
301
 
constructor stack_blur.Construct;
302
 
begin
303
 
 m_buf.Construct  (sizeof(aggclr ) );
304
 
 m_stack.Construct(sizeof(aggclr ) );
305
 
 
306
 
end;
307
 
 
308
 
{ DESTRUCT }
309
 
destructor stack_blur.Destruct;
310
 
begin
311
 
 m_buf.Destruct;
312
 
 m_stack.Destruct;
313
 
 
314
 
end;
315
 
 
316
 
{ BLUR_X }
317
 
procedure stack_blur.blur_x(img : pixel_formats_ptr; radius : unsigned );
318
 
var
319
 
 x ,y ,xp ,i ,stack_ptr ,stack_start ,
320
 
 
321
 
 w ,h ,wm ,div_ ,div_sum ,mul_sum ,shr_sum ,max_val : unsigned;
322
 
 
323
 
 pix : aggclr;
324
 
 
325
 
 stack_pix ,_c : aggclr_ptr;
326
 
 
327
 
 sum ,sum_in ,sum_out : stack_calculator;
328
 
 
329
 
begin
330
 
 if radius < 1 then
331
 
  exit;
332
 
 
333
 
 w   :=img._width;
334
 
 h   :=img._height;
335
 
 wm  :=w - 1;
336
 
 div_:=radius * 2 + 1;
337
 
 
338
 
 div_sum:=(radius + 1 ) * (radius + 1 );
339
 
 mul_sum:=0;
340
 
 shr_sum:=0;
341
 
 max_val:=base_mask;
342
 
 
343
 
 if (max_val <= 255 ) and
344
 
    (radius < 255 ) then
345
 
  begin
346
 
   mul_sum:=g_stack_blur8_mul[radius ];
347
 
   shr_sum:=g_stack_blur8_shr[radius ];
348
 
 
349
 
  end;
350
 
 
351
 
 m_buf.allocate  (w    ,128 );
352
 
 m_stack.allocate(div_ ,32 );
353
 
 
354
 
 y:=0;
355
 
 
356
 
 while y < h do
357
 
  begin
358
 
   sum.clear;
359
 
   sum_in.clear;
360
 
   sum_out.clear;
361
 
 
362
 
   pix:=img.pixel(img ,0 ,y );
363
 
 
364
 
   i:=0;
365
 
 
366
 
   while i <= radius do
367
 
    begin
368
 
     move(pix ,m_stack.array_operator(i )^ ,sizeof(aggclr ) );
369
 
 
370
 
     sum.add_   (pix ,i + 1 );
371
 
     sum_out.add(pix );
372
 
 
373
 
     inc(i );
374
 
 
375
 
    end;
376
 
 
377
 
   i:=1;
378
 
 
379
 
   while i <= radius do
380
 
    begin
381
 
     if i > wm then
382
 
      pix:=img.pixel(img ,wm ,y )
383
 
     else
384
 
      pix:=img.pixel(img ,i ,y );
385
 
 
386
 
     move(pix ,m_stack.array_operator(i + radius )^ ,sizeof(aggclr ) );
387
 
 
388
 
     sum.add_  (pix ,radius + 1 - i );
389
 
     sum_in.add(pix );
390
 
 
391
 
     inc(i );
392
 
 
393
 
    end;
394
 
 
395
 
   stack_ptr:=radius;
396
 
 
397
 
   x:=0;
398
 
 
399
 
   while x < w do
400
 
    begin
401
 
     if mul_sum <> 0 then
402
 
      sum.calc_pix_(aggclr_ptr(m_buf.array_operator(x ) ) ,mul_sum ,shr_sum )
403
 
     else
404
 
      sum.calc_pix(aggclr_ptr(m_buf.array_operator(x ) ) ,div_sum );
405
 
 
406
 
     sum.sub_(sum_out );
407
 
 
408
 
     stack_start:=stack_ptr + div_ - radius;
409
 
 
410
 
     if stack_start >= div_ then
411
 
      dec(stack_start ,div_ );
412
 
 
413
 
     stack_pix:=m_stack.array_operator(stack_start );
414
 
 
415
 
     sum_out.sub(stack_pix^ );
416
 
 
417
 
     xp:=x + radius + 1;
418
 
 
419
 
     if xp > wm then
420
 
      xp:=wm;
421
 
 
422
 
     pix:=img.pixel(img ,xp ,y );
423
 
 
424
 
     stack_pix^:=pix;
425
 
 
426
 
     sum_in.add(pix );
427
 
     sum.add__ (sum_in );
428
 
 
429
 
     inc(stack_ptr );
430
 
 
431
 
     if stack_ptr >= div_ then
432
 
      stack_ptr:=0;
433
 
 
434
 
     stack_pix:=m_stack.array_operator(stack_ptr );
435
 
 
436
 
     sum_out.add(stack_pix^ );
437
 
     sum_in.sub (stack_pix^ );
438
 
 
439
 
     inc(x );
440
 
 
441
 
    end;
442
 
 
443
 
    _c:=m_buf.array_operator(0 );
444
 
 
445
 
   img.copy_color_hspan(img ,0 ,y ,w ,_c );
446
 
 
447
 
   inc(y );
448
 
 
449
 
  end;
450
 
 
451
 
end;
452
 
 
453
 
{ BLUR_Y }
454
 
procedure stack_blur.blur_y(img : pixel_formats_ptr; radius : unsigned );
455
 
var
456
 
 img2 : pixel_formats_transposer;
457
 
 
458
 
begin
459
 
 pixfmt_transposer(img2 ,img );
460
 
 blur_x           (@img2 ,radius );
461
 
 
462
 
end;
463
 
 
464
 
{ BLUR }
465
 
procedure stack_blur.blur(img : pixel_formats_ptr; radius : unsigned );
466
 
var
467
 
 img2 : pixel_formats_transposer;
468
 
 
469
 
begin
470
 
 blur_x           (img ,radius );
471
 
 pixfmt_transposer(img2 ,img );
472
 
 blur_x           (@img2 ,radius );
473
 
 
474
 
end;
475
 
 
476
 
{ CONSTRUCT }
477
 
constructor recursive_blur.Construct;
478
 
begin
479
 
 m_sum1.Construct(sizeof(gauss_calculator ) );
480
 
 m_sum2.Construct(sizeof(gauss_calculator ) );
481
 
 m_buf.Construct (sizeof(aggclr ) );
482
 
 
483
 
end;
484
 
 
485
 
{ DESTRUCT }
486
 
destructor recursive_blur.Destruct;
487
 
begin
488
 
 m_sum1.Destruct;
489
 
 m_sum2.Destruct;
490
 
 m_buf.Destruct;
491
 
 
492
 
end;
493
 
 
494
 
{ BLUR_X }
495
 
procedure recursive_blur.blur_x(img : pixel_formats_ptr; radius : double );
496
 
var
497
 
 s ,q ,q2 ,q3 ,b0 ,b1 ,b2 ,b3 ,b : double;
498
 
 
499
 
 w ,h ,wm ,x ,y : int;
500
 
 
501
 
 c : gauss_calculator;
502
 
 
503
 
 g0 ,g1 : gauss_calculator_ptr;
504
 
 
505
 
begin
506
 
 if radius < 0.62 then
507
 
  exit;
508
 
 
509
 
 if img._width < 3 then
510
 
  exit;
511
 
 
512
 
 s:=radius * 0.5;
513
 
 
514
 
 if s < 2.5 then
515
 
  q:=3.97156 - 4.14554 * Sqrt(1 - 0.26891 * s )
516
 
 else
517
 
  q:=0.98711 * s - 0.96330;
518
 
 
519
 
 q2:=q * q;
520
 
 q3:=q2 * q;
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;
524
 
 b3:=0.422205 * q3;
525
 
 b :=1 - (b1 + b2 + b3 ) * b0;
526
 
 b1:=b1 * b0;
527
 
 b2:=b2 * b0;
528
 
 b3:=b3 * b0;
529
 
 w :=img._width;
530
 
 h :=img._height;
531
 
 wm:=w - 1;
532
 
 
533
 
 m_sum1.allocate(w );
534
 
 m_sum2.allocate(w );
535
 
 m_buf.allocate (w );
536
 
 
537
 
 y:=0;
538
 
 
539
 
 while y < h do
540
 
  begin
541
 
   g0:=gauss_calculator_ptr(m_sum1.array_operator(0 ) );
542
 
 
543
 
   c.from_pix(img.pixel(img ,0 ,y ) );
544
 
   g0.calc(
545
 
    b ,b1 ,b2 ,b3 ,
546
 
    @c ,@c ,@c ,@c );
547
 
 
548
 
   g1:=gauss_calculator_ptr(m_sum1.array_operator(1 ) );
549
 
 
550
 
   c.from_pix(img.pixel(img ,1 ,y ) );
551
 
   g1.calc(
552
 
    b ,b1 ,b2 ,b3 ,
553
 
    @c ,g0 ,g0 ,g0 );
554
 
 
555
 
   c.from_pix          (img.pixel(img ,2 ,y ) );
556
 
   gauss_calculator_ptr(m_sum1.array_operator(2 ) ).calc(
557
 
    b ,b1 ,b2 ,b3 ,
558
 
    @c ,g1 ,g0 ,g0 );
559
 
 
560
 
   x:=3;
561
 
 
562
 
   while x < w do
563
 
    begin
564
 
     c.from_pix(img.pixel(img ,x ,y ) );
565
 
 
566
 
     gauss_calculator_ptr(m_sum1.array_operator(x ) ).calc(
567
 
      b ,b1 ,b2 ,b3 ,
568
 
      @c ,
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 ) ) );
572
 
 
573
 
     inc(x );
574
 
 
575
 
    end;
576
 
 
577
 
   g0:=gauss_calculator_ptr(m_sum1.array_operator(wm ) );
578
 
   g1:=gauss_calculator_ptr(m_sum2.array_operator(wm ) );
579
 
 
580
 
   g1.calc(
581
 
    b ,b1 ,b2 ,b3 ,
582
 
    g0 ,g0 ,g0 ,g0 );
583
 
 
584
 
   gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ).calc(
585
 
    b ,b1 ,b2 ,b3 ,
586
 
    gauss_calculator_ptr(m_sum1.array_operator(wm - 1 ) ) ,
587
 
    g1 ,g1 ,g1 );
588
 
 
589
 
   gauss_calculator_ptr(m_sum2.array_operator(wm - 2 ) ).calc(
590
 
    b ,b1 ,b2 ,b3 ,
591
 
    gauss_calculator_ptr(m_sum1.array_operator(wm - 2 ) ) ,
592
 
    gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ) ,
593
 
    g1 ,g1 );
594
 
 
595
 
   g1.to_pix(
596
 
    aggclr_ptr(m_buf.array_operator(wm ) ) );
597
 
 
598
 
   gauss_calculator_ptr(m_sum2.array_operator(wm - 1 ) ).to_pix(
599
 
    aggclr_ptr(m_buf.array_operator(wm - 1 ) ) );
600
 
 
601
 
   gauss_calculator_ptr(m_sum2.array_operator(wm - 2 ) ).to_pix(
602
 
    aggclr_ptr(m_buf.array_operator(wm - 2 ) ) );
603
 
 
604
 
   x:=wm - 3;
605
 
 
606
 
   while x >= 0 do
607
 
    begin
608
 
     gauss_calculator_ptr(m_sum2.array_operator(x ) ).calc(
609
 
      b ,b1 ,b2 ,b3 ,
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 ) ) );
614
 
 
615
 
     gauss_calculator_ptr(m_sum2.array_operator(x ) ).to_pix(
616
 
      aggclr_ptr(m_buf.array_operator(x ) ) );
617
 
 
618
 
     dec(x );
619
 
 
620
 
    end;
621
 
 
622
 
   img.copy_color_hspan(img ,0 ,y ,w ,m_buf.array_operator(0 ) );
623
 
 
624
 
   inc(y );
625
 
 
626
 
  end;
627
 
 
628
 
end;
629
 
 
630
 
{ BLUR_Y }
631
 
procedure recursive_blur.blur_y(img : pixel_formats_ptr; radius : double );
632
 
var
633
 
 img2 : pixel_formats_transposer;
634
 
 
635
 
begin
636
 
 pixfmt_transposer(img2 ,img );
637
 
 blur_x           (@img2 ,radius );
638
 
 
639
 
end;
640
 
 
641
 
{ BLUR }
642
 
procedure recursive_blur.blur(img : pixel_formats_ptr; radius : double );
643
 
var
644
 
 img2 : pixel_formats_transposer;
645
 
 
646
 
begin
647
 
 blur_x           (img ,radius );
648
 
 pixfmt_transposer(img2 ,img );
649
 
 blur_x           (@img2 ,radius );
650
 
 
651
 
end;
652
 
 
653
 
{ STACK_BLUR_GRAY8 }
654
 
procedure stack_blur_gray8(img : pixel_formats_ptr; rx ,ry : unsigned );
655
 
var
656
 
 stride : int;
657
 
 
658
 
 x ,y ,xp ,yp ,i ,pix ,stack_pix ,sum ,sum_in ,sum_out ,
659
 
 
660
 
 stack_ptr ,stack_start ,w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned;
661
 
 
662
 
 src_pix_ptr ,dst_pix_ptr : int8u_ptr;
663
 
 
664
 
 stack : pod_vector;
665
 
 
666
 
begin
667
 
 w :=img._width;
668
 
 h :=img._height;
669
 
 wm:=w - 1;
670
 
 hm:=h - 1;
671
 
 
672
 
 stack.Construct(sizeof(int8u ) );
673
 
 
674
 
 if rx > 0 then
675
 
  begin
676
 
   if rx > 254 then
677
 
    rx:=254;
678
 
 
679
 
   div_:=rx * 2 + 1;
680
 
 
681
 
   mul_sum:=g_stack_blur8_mul[rx ];
682
 
   shr_sum:=g_stack_blur8_shr[rx ];
683
 
 
684
 
   stack.allocate(div_ );
685
 
 
686
 
   y:=0;
687
 
 
688
 
   while y < h do
689
 
    begin
690
 
     sum    :=0;
691
 
     sum_in :=0;
692
 
     sum_out:=0;
693
 
 
694
 
     src_pix_ptr:=img.pix_ptr(0 ,y );
695
 
     pix        :=src_pix_ptr^;
696
 
 
697
 
     i:=0;
698
 
 
699
 
     while i <= rx do
700
 
      begin
701
 
       int8u_ptr(stack.array_operator(i ) )^:=pix;
702
 
 
703
 
       inc(sum ,pix * (i + 1 ) );
704
 
       inc(sum_out ,pix );
705
 
 
706
 
       inc(i );
707
 
 
708
 
      end;
709
 
 
710
 
     i:=1;
711
 
 
712
 
     while i <= rx do
713
 
      begin
714
 
       if i <= wm then
715
 
        inc(ptrcomp(src_pix_ptr ) ,img.m_step );
716
 
 
717
 
       pix:=src_pix_ptr^;
718
 
 
719
 
       int8u_ptr(stack.array_operator(i + rx ) )^:=pix;
720
 
 
721
 
       inc(sum    ,pix * (rx + 1 - i ) );
722
 
       inc(sum_in ,pix );
723
 
 
724
 
       inc(i );
725
 
 
726
 
      end;
727
 
 
728
 
     stack_ptr:=rx;
729
 
     xp       :=rx;
730
 
 
731
 
     if xp > wm then
732
 
      xp:=wm;
733
 
 
734
 
     src_pix_ptr:=img.pix_ptr(xp ,y );
735
 
     dst_pix_ptr:=img.pix_ptr(0 ,y );
736
 
 
737
 
     x:=0;
738
 
 
739
 
     while x < w do
740
 
      begin
741
 
       dst_pix_ptr^:=int8u((sum * mul_sum ) shr shr_sum );
742
 
 
743
 
       inc(ptrcomp(dst_pix_ptr ) ,img.m_step );
744
 
       dec(sum ,sum_out );
745
 
 
746
 
       stack_start:=stack_ptr + div_ - rx;
747
 
 
748
 
       if stack_start >= div_ then
749
 
        dec(stack_start ,div_ );
750
 
 
751
 
       dec(sum_out ,int8u_ptr(stack.array_operator(stack_start ) )^ );
752
 
 
753
 
       if xp < wm then
754
 
        begin
755
 
         inc(ptrcomp(src_pix_ptr ) ,img.m_step );
756
 
 
757
 
         pix:=src_pix_ptr^;
758
 
 
759
 
         inc(xp );
760
 
 
761
 
        end;
762
 
 
763
 
       int8u_ptr(stack.array_operator(stack_start ) )^:=pix;
764
 
 
765
 
       inc(sum_in ,pix );
766
 
       inc(sum ,sum_in );
767
 
 
768
 
       inc(stack_ptr );
769
 
 
770
 
       if stack_ptr >= div_ then
771
 
        stack_ptr:=0;
772
 
 
773
 
       stack_pix:=int8u_ptr(stack.array_operator(stack_ptr ) )^;
774
 
 
775
 
       inc(sum_out ,stack_pix );
776
 
       dec(sum_in  ,stack_pix );
777
 
 
778
 
       inc(x );
779
 
 
780
 
      end;
781
 
 
782
 
     inc(y );
783
 
 
784
 
    end;
785
 
 
786
 
  end;
787
 
 
788
 
 if ry > 0 then
789
 
  begin
790
 
   if ry > 254 then
791
 
    ry:=254;
792
 
 
793
 
   div_:=ry * 2 + 1;
794
 
 
795
 
   mul_sum:=g_stack_blur8_mul[ry ];
796
 
   shr_sum:=g_stack_blur8_shr[ry ];
797
 
 
798
 
   stack.allocate(div_ );
799
 
 
800
 
   stride:=img._stride;
801
 
 
802
 
   x:=0;
803
 
 
804
 
   while x < w do
805
 
    begin
806
 
     sum    :=0;
807
 
     sum_in :=0;
808
 
     sum_out:=0;
809
 
 
810
 
     src_pix_ptr:=img.pix_ptr(x ,0 );
811
 
     pix        :=src_pix_ptr^;
812
 
 
813
 
     i:=0;
814
 
 
815
 
     while i <= ry do
816
 
      begin
817
 
       int8u_ptr(stack.array_operator(i ) )^:=pix;
818
 
 
819
 
       inc(sum ,pix * (i + 1 ) );
820
 
       inc(sum_out ,pix );
821
 
 
822
 
       inc(i );
823
 
 
824
 
      end;
825
 
 
826
 
     i:=1;
827
 
 
828
 
     while i <= ry do
829
 
      begin
830
 
       if i <= hm then
831
 
        inc(ptrcomp(src_pix_ptr ) ,stride );
832
 
 
833
 
       pix:=src_pix_ptr^;
834
 
 
835
 
       int8u_ptr(stack.array_operator(i + ry ) )^:=pix;
836
 
 
837
 
       inc(sum ,pix * (ry + 1 - i ) );
838
 
       inc(sum_in ,pix );
839
 
 
840
 
       inc(i );
841
 
 
842
 
      end;
843
 
 
844
 
     stack_ptr:=ry;
845
 
     yp       :=ry;
846
 
 
847
 
     if yp > hm then
848
 
      yp:=hm;
849
 
 
850
 
     src_pix_ptr:=img.pix_ptr(x ,yp );
851
 
     dst_pix_ptr:=img.pix_ptr(x ,0 );
852
 
 
853
 
     y:=0;
854
 
 
855
 
     while y < h do
856
 
      begin
857
 
       dst_pix_ptr^:=int8u((sum * mul_sum ) shr shr_sum );
858
 
 
859
 
       inc(ptrcomp(dst_pix_ptr ) ,stride );
860
 
       dec(sum ,sum_out );
861
 
 
862
 
       stack_start:=stack_ptr + div_ - ry;
863
 
 
864
 
       if stack_start >= div_ then
865
 
        dec(stack_start ,div_ );
866
 
 
867
 
       dec(sum_out ,int8u_ptr(stack.array_operator(stack_start ) )^ );
868
 
 
869
 
       if yp < hm then
870
 
        begin
871
 
         inc(ptrcomp(src_pix_ptr ) ,stride );
872
 
 
873
 
         pix:=src_pix_ptr^;
874
 
 
875
 
         inc(yp );
876
 
 
877
 
        end;
878
 
 
879
 
       int8u_ptr(stack.array_operator(stack_start ) )^:=pix;
880
 
 
881
 
       inc(sum_in ,pix );
882
 
       inc(sum ,sum_in );
883
 
 
884
 
       inc(stack_ptr );
885
 
 
886
 
       if stack_ptr >= div_ then
887
 
        stack_ptr:=0;
888
 
 
889
 
       stack_pix:=int8u_ptr(stack.array_operator(stack_ptr ) )^;
890
 
 
891
 
       inc(sum_out ,stack_pix );
892
 
       dec(sum_in ,stack_pix );
893
 
 
894
 
       inc(y );
895
 
 
896
 
      end;
897
 
 
898
 
     inc(x );
899
 
 
900
 
    end;
901
 
 
902
 
  end;
903
 
 
904
 
 stack.Destruct;
905
 
 
906
 
end;
907
 
 
908
 
{ STACK_BLUR_RGB24 }
909
 
procedure stack_blur_rgb24(img : pixel_formats_ptr; rx ,ry : unsigned );
910
 
var
911
 
 R ,G ,B ,stride : int;
912
 
 
913
 
 x ,y ,xp ,yp ,i ,stack_ptr ,stack_start ,
914
 
 
915
 
 sum_r ,sum_g ,sum_b ,
916
 
 
917
 
 sum_in_r ,sum_in_g ,sum_in_b ,
918
 
 
919
 
 sum_out_r ,sum_out_g ,sum_out_b ,
920
 
 
921
 
 w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned;
922
 
 
923
 
 src_pix_ptr ,dst_pix_ptr : int8u_ptr;
924
 
 
925
 
 stack_pix_ptr : aggclr_ptr;
926
 
 
927
 
 stack : pod_array;
928
 
 
929
 
begin
930
 
 R:=img.m_order.R;
931
 
 G:=img.m_order.G;
932
 
 B:=img.m_order.B;
933
 
 
934
 
 w :=img._width;
935
 
 h :=img._height;
936
 
 wm:=w - 1;
937
 
 hm:=h - 1;
938
 
 
939
 
 stack.Construct(sizeof(aggclr ) );
940
 
 
941
 
 if rx > 0 then
942
 
  begin
943
 
   if rx > 254 then
944
 
    rx:=254;
945
 
 
946
 
   div_   :=rx * 2 + 1;
947
 
   mul_sum:=g_stack_blur8_mul[rx ];
948
 
   shr_sum:=g_stack_blur8_shr[rx ];
949
 
 
950
 
   stack.allocate(div_ );
951
 
 
952
 
   y:=0;
953
 
 
954
 
   while y < h do
955
 
    begin
956
 
     sum_r    :=0;
957
 
     sum_g    :=0;
958
 
     sum_b    :=0;
959
 
     sum_in_r :=0;
960
 
     sum_in_g :=0;
961
 
     sum_in_b :=0;
962
 
     sum_out_r:=0;
963
 
     sum_out_g:=0;
964
 
     sum_out_b:=0;
965
 
 
966
 
     src_pix_ptr:=img.pix_ptr(0 ,y );
967
 
 
968
 
     i:=0;
969
 
 
970
 
     while i <= rx do
971
 
      begin
972
 
       stack_pix_ptr:=stack.array_operator(i );
973
 
 
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 )^;
977
 
 
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 ) );
981
 
 
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 )^ );
985
 
 
986
 
       inc(i );
987
 
 
988
 
      end;
989
 
 
990
 
     i:=1;
991
 
 
992
 
     while i <= rx do
993
 
      begin
994
 
       if i <= wm then
995
 
        inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width ); 
996
 
 
997
 
       stack_pix_ptr:=stack.array_operator(i + rx );
998
 
 
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 )^;
1002
 
 
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 ) );
1006
 
 
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 )^ );
1010
 
 
1011
 
       inc(i );
1012
 
 
1013
 
      end;
1014
 
 
1015
 
     stack_ptr:=rx;
1016
 
     xp       :=rx;
1017
 
 
1018
 
     if xp > wm then
1019
 
      xp:=wm;
1020
 
 
1021
 
     src_pix_ptr:=img.pix_ptr(xp ,y );
1022
 
     dst_pix_ptr:=img.pix_ptr(0  ,y );
1023
 
 
1024
 
     x:=0;
1025
 
 
1026
 
     while x < w do
1027
 
      begin
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 );
1031
 
 
1032
 
       inc(ptrcomp(dst_pix_ptr ) ,img.m_pix_width );
1033
 
 
1034
 
       dec(sum_r ,sum_out_r );
1035
 
       dec(sum_g ,sum_out_g );
1036
 
       dec(sum_b ,sum_out_b );
1037
 
 
1038
 
       stack_start:=stack_ptr + div_ - rx;
1039
 
 
1040
 
       if stack_start >= div_ then
1041
 
        dec(stack_start ,div_ );
1042
 
 
1043
 
       stack_pix_ptr:=stack.array_operator(stack_start );
1044
 
 
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 );
1048
 
 
1049
 
       if xp < wm then
1050
 
        begin
1051
 
         inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
1052
 
         inc(xp );
1053
 
 
1054
 
        end;
1055
 
 
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 )^;
1059
 
 
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 )^ );
1063
 
 
1064
 
       inc(sum_r ,sum_in_r );
1065
 
       inc(sum_g ,sum_in_g );
1066
 
       inc(sum_b ,sum_in_b );
1067
 
 
1068
 
       inc(stack_ptr );
1069
 
 
1070
 
       if stack_ptr >= div_ then
1071
 
        stack_ptr:=0;
1072
 
 
1073
 
       stack_pix_ptr:=stack.array_operator(stack_ptr );
1074
 
 
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 );
1081
 
 
1082
 
       inc(x );
1083
 
 
1084
 
      end;
1085
 
 
1086
 
     inc(y );
1087
 
 
1088
 
    end;
1089
 
 
1090
 
  end;
1091
 
 
1092
 
 if ry > 0 then
1093
 
  begin
1094
 
   if ry > 254 then
1095
 
    ry:=254;
1096
 
 
1097
 
   div_:=ry * 2 + 1;
1098
 
 
1099
 
   mul_sum:=g_stack_blur8_mul[ry ];
1100
 
   shr_sum:=g_stack_blur8_shr[ry ];
1101
 
 
1102
 
   stack.allocate(div_ );
1103
 
 
1104
 
   stride:=img._stride;
1105
 
 
1106
 
   x:=0;
1107
 
 
1108
 
   while x < w do
1109
 
    begin
1110
 
     sum_r    :=0;
1111
 
     sum_g    :=0;
1112
 
     sum_b    :=0;
1113
 
     sum_in_r :=0;
1114
 
     sum_in_g :=0;
1115
 
     sum_in_b :=0;
1116
 
     sum_out_r:=0;
1117
 
     sum_out_g:=0;
1118
 
     sum_out_b:=0;
1119
 
 
1120
 
     src_pix_ptr:=img.pix_ptr(x ,0 );
1121
 
 
1122
 
     i:=0;
1123
 
 
1124
 
     while i <= ry do
1125
 
      begin
1126
 
       stack_pix_ptr:=stack.array_operator(i );
1127
 
 
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 )^;
1131
 
 
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 )^ );
1138
 
 
1139
 
       inc(i );
1140
 
 
1141
 
      end;
1142
 
 
1143
 
     i:=1;
1144
 
 
1145
 
     while i <= ry do
1146
 
      begin
1147
 
       if i <= hm then
1148
 
        inc(ptrcomp(src_pix_ptr ) ,stride );
1149
 
 
1150
 
       stack_pix_ptr:=stack.array_operator(i + ry );
1151
 
 
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 )^;
1155
 
 
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 )^ );
1162
 
 
1163
 
       inc(i );
1164
 
 
1165
 
      end;
1166
 
 
1167
 
     stack_ptr:=ry;
1168
 
     yp       :=ry;
1169
 
 
1170
 
     if yp > hm then
1171
 
      yp:=hm;
1172
 
 
1173
 
     src_pix_ptr:=img.pix_ptr(x ,yp );
1174
 
     dst_pix_ptr:=img.pix_ptr(x ,0 );
1175
 
 
1176
 
     y:=0;
1177
 
 
1178
 
     while y < h do
1179
 
      begin
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 );
1183
 
 
1184
 
       inc(ptrcomp(dst_pix_ptr ) ,stride );
1185
 
 
1186
 
       dec(sum_r ,sum_out_r );
1187
 
       dec(sum_g ,sum_out_g );
1188
 
       dec(sum_b ,sum_out_b );
1189
 
 
1190
 
       stack_start:=stack_ptr + div_ - ry;
1191
 
 
1192
 
       if stack_start >= div_ then
1193
 
        dec(stack_start ,div_ );
1194
 
 
1195
 
       stack_pix_ptr:=stack.array_operator(stack_start );
1196
 
 
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 );
1200
 
 
1201
 
       if yp < hm then
1202
 
        begin
1203
 
         inc(ptrcomp(src_pix_ptr ) ,stride );
1204
 
 
1205
 
         inc(yp );
1206
 
 
1207
 
        end;
1208
 
 
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 )^;
1212
 
 
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 );
1219
 
 
1220
 
       inc(stack_ptr );
1221
 
 
1222
 
       if stack_ptr >= div_ then
1223
 
        stack_ptr:=0;
1224
 
 
1225
 
       stack_pix_ptr:=stack.array_operator(stack_ptr );
1226
 
 
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 );
1233
 
 
1234
 
       inc(y );
1235
 
 
1236
 
      end;
1237
 
 
1238
 
     inc(x );
1239
 
 
1240
 
    end;
1241
 
 
1242
 
  end;
1243
 
 
1244
 
 stack.Destruct;
1245
 
 
1246
 
end;
1247
 
 
1248
 
{ STACK_BLUR_RGBA32 }
1249
 
procedure stack_blur_rgba32(img : pixel_formats_ptr; rx ,ry : unsigned );
1250
 
var
1251
 
 R ,G ,B ,A ,stride : int;
1252
 
 
1253
 
 x ,y ,xp ,yp ,i ,stack_ptr ,stack_start ,
1254
 
 
1255
 
 sum_r ,sum_g ,sum_b ,sum_a ,
1256
 
 
1257
 
 sum_in_r ,sum_in_g ,sum_in_b ,sum_in_a ,
1258
 
 
1259
 
 sum_out_r ,sum_out_g ,sum_out_b ,sum_out_a ,
1260
 
 
1261
 
 w ,h ,wm ,hm ,div_ ,mul_sum ,shr_sum : unsigned;
1262
 
 
1263
 
 src_pix_ptr ,dst_pix_ptr : int8u_ptr;
1264
 
 
1265
 
 stack_pix_ptr : aggclr_ptr;
1266
 
 
1267
 
 stack : pod_array;
1268
 
 
1269
 
begin
1270
 
 R:=img.m_order.R;
1271
 
 G:=img.m_order.G;
1272
 
 B:=img.m_order.B;
1273
 
 A:=img.m_order.A;
1274
 
 
1275
 
 w :=img._width;
1276
 
 h :=img._height;
1277
 
 wm:=w - 1;
1278
 
 hm:=h - 1;
1279
 
 
1280
 
 stack.Construct(sizeof(aggclr ) );
1281
 
 
1282
 
 if rx > 0 then
1283
 
  begin
1284
 
   if rx > 254 then
1285
 
    rx:=254;
1286
 
 
1287
 
   div_   :=rx * 2 + 1;
1288
 
   mul_sum:=g_stack_blur8_mul[rx ];
1289
 
   shr_sum:=g_stack_blur8_shr[rx ];
1290
 
 
1291
 
   stack.allocate(div_ );
1292
 
 
1293
 
   y:=0;
1294
 
 
1295
 
   while y < h do
1296
 
    begin
1297
 
     sum_r    :=0;
1298
 
     sum_g    :=0;
1299
 
     sum_b    :=0;
1300
 
     sum_a    :=0;
1301
 
     sum_in_r :=0;
1302
 
     sum_in_g :=0;
1303
 
     sum_in_b :=0;
1304
 
     sum_in_a :=0;
1305
 
     sum_out_r:=0;
1306
 
     sum_out_g:=0;
1307
 
     sum_out_b:=0;
1308
 
     sum_out_a:=0;
1309
 
 
1310
 
     src_pix_ptr:=img.pix_ptr(0 ,y );
1311
 
 
1312
 
     i:=0;
1313
 
 
1314
 
     while i <= rx do
1315
 
      begin
1316
 
       stack_pix_ptr:=stack.array_operator(i );
1317
 
 
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 )^;
1322
 
 
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 ) );
1327
 
 
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 )^ );
1332
 
 
1333
 
       inc(i );
1334
 
 
1335
 
      end;
1336
 
 
1337
 
     i:=1;
1338
 
 
1339
 
     while i <= rx do
1340
 
      begin
1341
 
       if i <= wm then
1342
 
        inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
1343
 
 
1344
 
       stack_pix_ptr:=stack.array_operator(i + rx );
1345
 
 
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 )^;
1350
 
 
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 ) );
1355
 
 
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 )^ );
1360
 
 
1361
 
       inc(i );
1362
 
 
1363
 
      end;
1364
 
 
1365
 
     stack_ptr:=rx;
1366
 
     xp       :=rx;
1367
 
 
1368
 
     if xp > wm then
1369
 
      xp:=wm;
1370
 
 
1371
 
     src_pix_ptr:=img.pix_ptr(xp ,y );
1372
 
     dst_pix_ptr:=img.pix_ptr(0  ,y );
1373
 
 
1374
 
     x:=0;
1375
 
 
1376
 
     while x < w do
1377
 
      begin
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 );
1382
 
 
1383
 
       inc(ptrcomp(dst_pix_ptr ) ,img.m_pix_width );
1384
 
 
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 );
1389
 
 
1390
 
       stack_start:=stack_ptr + div_ - rx;
1391
 
 
1392
 
       if stack_start >= div_ then
1393
 
        dec(stack_start ,div_ );
1394
 
 
1395
 
       stack_pix_ptr:=stack.array_operator(stack_start );
1396
 
 
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 );
1401
 
 
1402
 
       if xp < wm then
1403
 
        begin
1404
 
         inc(ptrcomp(src_pix_ptr ) ,img.m_pix_width );
1405
 
         inc(xp );
1406
 
 
1407
 
        end;
1408
 
 
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 )^;
1413
 
 
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 )^ );
1418
 
 
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 );
1423
 
 
1424
 
       inc(stack_ptr );
1425
 
 
1426
 
       if stack_ptr >= div_ then
1427
 
        stack_ptr:=0;
1428
 
 
1429
 
       stack_pix_ptr:=stack.array_operator(stack_ptr );
1430
 
 
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 );
1439
 
 
1440
 
       inc(x );
1441
 
 
1442
 
      end;
1443
 
 
1444
 
     inc(y );
1445
 
 
1446
 
    end;
1447
 
 
1448
 
  end;
1449
 
 
1450
 
 if ry > 0 then
1451
 
  begin
1452
 
   if ry > 254 then
1453
 
    ry:=254;
1454
 
 
1455
 
   div_:=ry * 2 + 1;
1456
 
 
1457
 
   mul_sum:=g_stack_blur8_mul[ry ];
1458
 
   shr_sum:=g_stack_blur8_shr[ry ];
1459
 
 
1460
 
   stack.allocate(div_ );
1461
 
 
1462
 
   stride:=img._stride;
1463
 
 
1464
 
   x:=0;
1465
 
 
1466
 
   while x < w do
1467
 
    begin
1468
 
     sum_r    :=0;
1469
 
     sum_g    :=0;
1470
 
     sum_b    :=0;
1471
 
     sum_a    :=0;
1472
 
     sum_in_r :=0;
1473
 
     sum_in_g :=0;
1474
 
     sum_in_b :=0;
1475
 
     sum_in_a :=0;
1476
 
     sum_out_r:=0;
1477
 
     sum_out_g:=0;
1478
 
     sum_out_b:=0;
1479
 
     sum_out_a:=0;
1480
 
 
1481
 
     src_pix_ptr:=img.pix_ptr(x ,0 );
1482
 
 
1483
 
     i:=0;
1484
 
 
1485
 
     while i <= ry do
1486
 
      begin
1487
 
       stack_pix_ptr:=stack.array_operator(i );
1488
 
 
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 )^;
1493
 
 
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 )^ );
1502
 
 
1503
 
       inc(i );
1504
 
 
1505
 
      end;
1506
 
 
1507
 
     i:=1;
1508
 
 
1509
 
     while i <= ry do
1510
 
      begin
1511
 
       if i <= hm then
1512
 
        inc(ptrcomp(src_pix_ptr ) ,stride );
1513
 
 
1514
 
       stack_pix_ptr:=stack.array_operator(i + ry );
1515
 
 
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 )^;
1520
 
 
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 )^ );
1529
 
 
1530
 
       inc(i );
1531
 
 
1532
 
      end;
1533
 
 
1534
 
     stack_ptr:=ry;
1535
 
     yp       :=ry;
1536
 
 
1537
 
     if yp > hm then
1538
 
      yp:=hm;
1539
 
 
1540
 
     src_pix_ptr:=img.pix_ptr(x ,yp );
1541
 
     dst_pix_ptr:=img.pix_ptr(x ,0 );
1542
 
 
1543
 
     y:=0;
1544
 
 
1545
 
     while y < h do
1546
 
      begin
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 );
1551
 
 
1552
 
       inc(ptrcomp(dst_pix_ptr ) ,stride );
1553
 
 
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 );
1558
 
 
1559
 
       stack_start:=stack_ptr + div_ - ry;
1560
 
 
1561
 
       if stack_start >= div_ then
1562
 
        dec(stack_start ,div_ );
1563
 
 
1564
 
       stack_pix_ptr:=stack.array_operator(stack_start );
1565
 
 
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 );
1570
 
 
1571
 
       if yp < hm then
1572
 
        begin
1573
 
         inc(ptrcomp(src_pix_ptr ) ,stride );
1574
 
 
1575
 
         inc(yp );
1576
 
 
1577
 
        end;
1578
 
 
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 )^;
1583
 
 
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 );
1592
 
 
1593
 
       inc(stack_ptr );
1594
 
 
1595
 
       if stack_ptr >= div_ then
1596
 
        stack_ptr:=0;
1597
 
 
1598
 
       stack_pix_ptr:=stack.array_operator(stack_ptr );
1599
 
 
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 );
1608
 
 
1609
 
       inc(y );
1610
 
 
1611
 
      end;
1612
 
 
1613
 
     inc(x );
1614
 
 
1615
 
    end;
1616
 
 
1617
 
  end;
1618
 
 
1619
 
 stack.Destruct;
1620
 
 
1621
 
end;
1622
 
 
1623
 
END.
1624