1// 2// AggPas 2.4 RM3 Demo application 3// Note: Press F1 key on run to see more info about this demo 4// 5// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap 6// 7program 8 image_fltr_graph ; 9 10uses 11 Math , 12 13 agg_basics , 14 agg_platform_support , 15 16 agg_color , 17 agg_pixfmt , 18 agg_pixfmt_rgb , 19 20 agg_ctrl , 21 agg_slider_ctrl , 22 agg_rbox_ctrl , 23 agg_cbox_ctrl , 24 25 agg_rendering_buffer , 26 agg_renderer_base , 27 agg_renderer_scanline , 28 agg_rasterizer_scanline_aa , 29 agg_scanline , 30 agg_scanline_u , 31 agg_scanline_p , 32 agg_render_scanlines , 33 34 agg_ellipse , 35 agg_trans_affine , 36 agg_conv_transform , 37 agg_conv_stroke , 38 agg_span_allocator , 39 agg_span_interpolator_linear , 40 agg_span_image_filter , 41 agg_span_image_filter_rgb , 42 agg_image_filters , 43 agg_path_storage ; 44 45{$I agg_mode.inc } 46 47const 48 flip_y = true; 49 50type 51 filter_adaptor_ptr = ^filter_adaptor; 52 filter_adaptor = object 53 m_filter : image_filter_base_ptr; 54 55 constructor Construct(filter : image_filter_base_ptr ); 56 destructor Destruct; 57 58 function radius : double; 59 function calc_weight(x : double ) : double; 60 61 procedure set_radius(r : double ); 62 63 end; 64 65 the_application = object(platform_support ) 66 m_radius : slider_ctrl; 67 m_bilinear , 68 m_bicubic , 69 m_spline16 , 70 m_spline36 , 71 m_hanning , 72 m_hamming , 73 m_hermite , 74 m_kaiser , 75 m_quadric , 76 m_catrom , 77 m_gaussian , 78 m_bessel , 79 m_mitchell , 80 m_sinc , 81 m_lanczos , 82 m_blackman : cbox_ctrl; 83 84 m_filters : array[0..31 ] of cbox_ctrl_ptr; 85 86 m_filter_bilinear , 87 m_filter_bicubic , 88 m_filter_spline16 , 89 m_filter_spline36 , 90 m_filter_hanning , 91 m_filter_hamming , 92 m_filter_hermite , 93 m_filter_kaiser , 94 m_filter_quadric , 95 m_filter_catrom , 96 m_filter_gaussian , 97 m_filter_bessel , 98 m_filter_mitchell , 99 m_filter_sinc , 100 m_filter_lanczos , 101 m_filter_blackman : filter_adaptor; 102 103 m_filter_func : array[0..31 ] of filter_adaptor_ptr; 104 m_num_filters : unsigned; 105 106 constructor Construct(format_ : pix_format_e; flip_y_ : boolean ); 107 destructor Destruct; 108 109 procedure on_draw; virtual; 110 111 procedure on_key(x ,y : int; key ,flags : unsigned ); virtual; 112 113 end; 114 115{ CONSTRUCT } 116constructor filter_adaptor.Construct; 117begin 118 m_filter:=filter; 119 120end; 121 122{ DESTRUCT } 123destructor filter_adaptor.Destruct; 124begin 125 if m_filter <> NIL then 126 dispose(m_filter ); 127 128end; 129 130{ RADIUS } 131function filter_adaptor.radius; 132begin 133 if m_filter <> NIL then 134 result:=m_filter.radius 135 else 136 result:=0; 137 138end; 139 140{ CALC_WEIGHT } 141function filter_adaptor.calc_weight; 142begin 143 if m_filter <> NIL then 144 result:=m_filter.calc_weight(Abs(x ) ) 145 else 146 result:=0; 147 148end; 149 150{ SET_RADIUS } 151procedure filter_adaptor.set_radius; 152begin 153 if m_filter <> NIL then 154 m_filter.set_radius(r ); 155 156end; 157 158{ CONSTRUCT } 159constructor the_application.Construct; 160var 161 i : unsigned; 162 163begin 164 inherited Construct(format_ ,flip_y_ ); 165 166 m_radius.Construct (5.0 ,5.0 ,780 - 5 ,10.0 ,not flip_y_ ); 167 m_bilinear.Construct(8.0 ,30.0 + 15 * 0 ,'bilinear' ,not flip_y_ ); 168 m_bicubic.Construct (8.0 ,30.0 + 15 * 1 ,'bicubic ' ,not flip_y_ ); 169 m_spline16.Construct(8.0 ,30.0 + 15 * 2 ,'spline16' ,not flip_y_ ); 170 m_spline36.Construct(8.0 ,30.0 + 15 * 3 ,'spline36' ,not flip_y_ ); 171 m_hanning.Construct (8.0 ,30.0 + 15 * 4 ,'hanning ' ,not flip_y_ ); 172 m_hamming.Construct (8.0 ,30.0 + 15 * 5 ,'hamming ' ,not flip_y_ ); 173 m_hermite.Construct (8.0 ,30.0 + 15 * 6 ,'hermite ' ,not flip_y_ ); 174 m_kaiser.Construct (8.0 ,30.0 + 15 * 7 ,'kaiser ' ,not flip_y_ ); 175 m_quadric.Construct (8.0 ,30.0 + 15 * 8 ,'quadric ' ,not flip_y_ ); 176 m_catrom.Construct (8.0 ,30.0 + 15 * 9 ,'catrom ' ,not flip_y_ ); 177 m_gaussian.Construct(8.0 ,30.0 + 15 * 10 ,'gaussian' ,not flip_y_ ); 178 m_bessel.Construct (8.0 ,30.0 + 15 * 11 ,'bessel ' ,not flip_y_ ); 179 m_mitchell.Construct(8.0 ,30.0 + 15 * 12 ,'mitchell' ,not flip_y_ ); 180 m_sinc.Construct (8.0 ,30.0 + 15 * 13 ,'sinc ' ,not flip_y_ ); 181 m_lanczos.Construct (8.0 ,30.0 + 15 * 14 ,'lanczos ' ,not flip_y_ ); 182 m_blackman.Construct(8.0 ,30.0 + 15 * 15 ,'blackman' ,not flip_y_ ); 183 184 m_filter_bilinear.Construct(new(image_filter_bilinear_ptr ,Construct ) ); 185 m_filter_bicubic.Construct (new(image_filter_bicubic_ptr ,Construct ) ); 186 m_filter_spline16.Construct(new(image_filter_spline16_ptr ,Construct ) ); 187 m_filter_spline36.Construct(new(image_filter_spline36_ptr ,Construct ) ); 188 m_filter_hanning.Construct (new(image_filter_hanning_ptr ,Construct ) ); 189 m_filter_hamming.Construct (new(image_filter_hamming_ptr ,Construct ) ); 190 m_filter_hermite.Construct (new(image_filter_hermite_ptr ,Construct ) ); 191 m_filter_kaiser.Construct (new(image_filter_kaiser_ptr ,Construct ) ); 192 m_filter_quadric.Construct (new(image_filter_quadric_ptr ,Construct ) ); 193 m_filter_catrom.Construct (new(image_filter_catrom_ptr ,Construct ) ); 194 m_filter_gaussian.Construct(new(image_filter_gaussian_ptr ,Construct ) ); 195 m_filter_bessel.Construct (new(image_filter_bessel_ptr ,Construct ) ); 196 m_filter_mitchell.Construct(new(image_filter_mitchell_ptr ,Construct ) ); 197 m_filter_sinc.Construct (new(image_filter_sinc_ptr ,Construct(2.0 ) ) ); 198 m_filter_lanczos.Construct (new(image_filter_lanczos_ptr ,Construct(2.0 ) ) ); 199 m_filter_blackman.Construct(new(image_filter_blackman_ptr ,Construct(2.0 ) ) ); 200 201 m_num_filters:=0; 202 203 m_filters[m_num_filters ]:=@m_bilinear; inc(m_num_filters ); 204 m_filters[m_num_filters ]:=@m_bicubic; inc(m_num_filters ); 205 m_filters[m_num_filters ]:=@m_spline16; inc(m_num_filters ); 206 m_filters[m_num_filters ]:=@m_spline36; inc(m_num_filters ); 207 m_filters[m_num_filters ]:=@m_hanning; inc(m_num_filters ); 208 m_filters[m_num_filters ]:=@m_hamming; inc(m_num_filters ); 209 m_filters[m_num_filters ]:=@m_hermite; inc(m_num_filters ); 210 m_filters[m_num_filters ]:=@m_kaiser; inc(m_num_filters ); 211 m_filters[m_num_filters ]:=@m_quadric; inc(m_num_filters ); 212 m_filters[m_num_filters ]:=@m_catrom; inc(m_num_filters ); 213 m_filters[m_num_filters ]:=@m_gaussian; inc(m_num_filters ); 214 m_filters[m_num_filters ]:=@m_bessel; inc(m_num_filters ); 215 m_filters[m_num_filters ]:=@m_mitchell; inc(m_num_filters ); 216 m_filters[m_num_filters ]:=@m_sinc; inc(m_num_filters ); 217 m_filters[m_num_filters ]:=@m_lanczos; inc(m_num_filters ); 218 m_filters[m_num_filters ]:=@m_blackman; inc(m_num_filters ); 219 220 i:=0; 221 222 m_filter_func[i ]:=@m_filter_bilinear; inc(i ); 223 m_filter_func[i ]:=@m_filter_bicubic; inc(i ); 224 m_filter_func[i ]:=@m_filter_spline16; inc(i ); 225 m_filter_func[i ]:=@m_filter_spline36; inc(i ); 226 m_filter_func[i ]:=@m_filter_hanning; inc(i ); 227 m_filter_func[i ]:=@m_filter_hamming; inc(i ); 228 m_filter_func[i ]:=@m_filter_hermite; inc(i ); 229 m_filter_func[i ]:=@m_filter_kaiser; inc(i ); 230 m_filter_func[i ]:=@m_filter_quadric; inc(i ); 231 m_filter_func[i ]:=@m_filter_catrom; inc(i ); 232 m_filter_func[i ]:=@m_filter_gaussian; inc(i ); 233 m_filter_func[i ]:=@m_filter_bessel; inc(i ); 234 m_filter_func[i ]:=@m_filter_mitchell; inc(i ); 235 m_filter_func[i ]:=@m_filter_sinc; inc(i ); 236 m_filter_func[i ]:=@m_filter_lanczos; inc(i ); 237 m_filter_func[i ]:=@m_filter_blackman; inc(i ); 238 239 for i:=0 to m_num_filters - 1 do 240 add_ctrl(m_filters[i ] ); 241 242 m_radius.range_(2.0 ,8.0 ); 243 m_radius.value_(4.0 ); 244 m_radius.label_('Radius=%.3f' ); 245 246 add_ctrl(@m_radius ); 247 248end; 249 250{ DESTRUCT } 251destructor the_application.Destruct; 252begin 253 inherited Destruct; 254 255 m_radius.Destruct; 256 m_bilinear.Destruct; 257 m_bicubic.Destruct; 258 m_spline16.Destruct; 259 m_spline36.Destruct; 260 m_hanning.Destruct; 261 m_hamming.Destruct; 262 m_hermite.Destruct; 263 m_kaiser.Destruct; 264 m_quadric.Destruct; 265 m_catrom.Destruct; 266 m_gaussian.Destruct; 267 m_bessel.Destruct; 268 m_mitchell.Destruct; 269 m_sinc.Destruct; 270 m_lanczos.Destruct; 271 m_blackman.Destruct; 272 273 m_filter_bilinear.Destruct; 274 m_filter_bicubic.Destruct; 275 m_filter_spline16.Destruct; 276 m_filter_spline36.Destruct; 277 m_filter_hanning.Destruct; 278 m_filter_hamming.Destruct; 279 m_filter_hermite.Destruct; 280 m_filter_kaiser.Destruct; 281 m_filter_quadric.Destruct; 282 m_filter_catrom.Destruct; 283 m_filter_gaussian.Destruct; 284 m_filter_bessel.Destruct; 285 m_filter_mitchell.Destruct; 286 m_filter_sinc.Destruct; 287 m_filter_lanczos.Destruct; 288 m_filter_blackman.Destruct; 289 290end; 291 292{ ON_DRAW } 293procedure the_application.on_draw; 294var 295 pixf : pixel_formats; 296 rgba : aggclr; 297 298 rb : renderer_base; 299 rs : renderer_scanline_aa_solid; 300 sl : scanline_p8; 301 302 ras : rasterizer_scanline_aa; 303 304 normalized : image_filter_lut; 305 weights : int16_ptr; 306 307 x_start ,x_end ,y_start ,y_end ,x_center ,x ,y ,ys ,radius ,dy ,xs ,dx ,sum ,xf : double; 308 309 xfract ,ir : int; 310 311 i ,j ,n ,xint ,nn : unsigned; 312 313 p : path_storage; 314 pl : conv_stroke; 315 tr : conv_transform; 316 317begin 318// Initialize structures 319 pixfmt_bgr24(pixf ,rbuf_window ); 320 321 rb.Construct(@pixf ); 322 rs.Construct(@rb ); 323 324 rgba.ConstrDbl(1.0 ,1.0 ,1.0 ); 325 rb.clear (@rgba ); 326 327 ras.Construct; 328 sl.Construct; 329 330// Render 331 x_start :=125.0; 332 x_end :=_initial_width - 15.0; 333 y_start :=10.0; 334 y_end :=_initial_height - 10.0; 335 x_center:=(x_start + x_end ) / 2; 336 337 p.Construct; 338 pl.Construct(@p ); 339 tr.Construct(@pl ,_trans_affine_resizing ); 340 341 for i:=0 to 15 do 342 begin 343 x:=x_start + (x_end - x_start ) * i / 16.0; 344 345 p.remove_all; 346 p.move_to(x + 0.5 ,y_start ); 347 p.line_to(x + 0.5 ,y_end ); 348 349 ras.add_path(@tr ); 350 351 if i = 8 then 352 rgba.ConstrInt(0 ,0 ,0 ,255 ) 353 else 354 rgba.ConstrInt(0 ,0 ,0 ,100 ); 355 356 rs.color_ (@rgba ); 357 render_scanlines(@ras ,@sl ,@rs ); 358 359 end; 360 361 ys:=y_start + (y_end - y_start ) / 6.0; 362 363 p.remove_all; 364 p.move_to (x_start ,ys ); 365 p.line_to (x_end ,ys ); 366 ras.add_path (@tr ); 367 rgba.ConstrInt (0 ,0 ,0 ); 368 rs.color_ (@rgba ); 369 render_scanlines(@ras ,@sl ,@rs ); 370 371 pl.width_(1.0 ); 372 373 for i:=0 to m_num_filters - 1 do 374 if m_filters[i ]._status then 375 begin 376 m_filter_func[i ].set_radius(m_radius._value ); 377 378 radius:=m_filter_func[i ].radius; 379 380 n :=trunc(radius * 256 * 2 ); 381 dy:=y_end - ys; 382 383 xs:=(x_end + x_start ) / 2.0 - (radius * (x_end - x_start ) / 16.0 ); 384 dx:=(x_end - x_start ) * radius / 8.0; 385 386 p.remove_all; 387 p.move_to(xs + 0.5 ,ys + dy * m_filter_func[i ].calc_weight(-radius ) ); 388 389 j:=1; 390 391 while j < n do 392 begin 393 p.line_to( 394 xs + dx * j / n + 0.5 , 395 ys + dy * m_filter_func[i ].calc_weight(j / 256.0 - radius ) ); 396 397 inc(j ); 398 399 end; 400 401 ras.add_path (@tr ); 402 rgba.ConstrInt (100 ,0 ,0 ); 403 rs.color_ (@rgba ); 404 render_scanlines(@ras ,@sl ,@rs ); 405 406 p.remove_all; 407 408 ir:=trunc(Ceil(radius ) + 0.1 ); 409 410 for xint:=0 to 255 do 411 begin 412 sum:=0; 413 414 xfract:=-ir; 415 416 while xfract < ir do 417 begin 418 xf:=xint / 256.0 + xfract; 419 420 if (xf >= -radius ) or 421 (xf <= radius ) then 422 sum:=sum + m_filter_func[i ].calc_weight(xf ); 423 424 inc(xfract ); 425 426 end; 427 428 x:=x_center + ((-128.0 + xint ) / 128.0 ) * radius * (x_end - x_start ) / 16.0; 429 y:=ys + sum * 256 - 256; 430 431 if xint = 0 then 432 p.move_to(x ,y ) 433 else 434 p.line_to(x ,y ); 435 436 end; 437 438 ras.add_path (@tr ); 439 rgba.ConstrInt (0 ,100 ,0 ); 440 rs.color_ (@rgba ); 441 render_scanlines(@ras ,@sl ,@rs ); 442 443 normalized.Construct(m_filter_func[i ].m_filter ); 444 445 weights:=normalized.weight_array; 446 447 xs:=(x_end + x_start ) / 2.0 - (normalized.diameter * (x_end - x_start ) / 32.0 ); 448 nn:=normalized.diameter * 256; 449 450 p.remove_all; 451 p.move_to(xs + 0.5 ,ys + dy * int16_ptr(weights )^ / image_filter_size ); 452 453 j:=1; 454 455 while j < nn do 456 begin 457 p.line_to( 458 xs + dx * j / n + 0.5 , 459 ys + dy * int16_ptr(ptrcomp(weights ) + j * sizeof(int16 ) )^ / image_filter_size ); 460 461 inc(j ); 462 463 end; 464 465 ras.add_path (@tr ); 466 rgba.ConstrInt (0 ,0 ,100 ,255 ); 467 rs.color_ (@rgba ); 468 render_scanlines(@ras ,@sl ,@rs ); 469 470 // Free 471 normalized.Destruct; 472 473 end; 474 475// Render the controls 476 for i:=0 to m_num_filters - 1 do 477 render_ctrl(@ras ,@sl ,@rs ,m_filters[i ] ); 478 479 if m_sinc._status or 480 m_lanczos._status or 481 m_blackman._status then 482 render_ctrl(@ras ,@sl ,@rs ,@m_radius ); 483 484// Free AGG resources 485 ras.Destruct; 486 sl.Destruct; 487 488 p.Destruct; 489 pl.Destruct; 490 491end; 492 493{ ON_KEY } 494procedure the_application.on_key; 495begin 496 if key = key_f1 then 497 message_( 498 'Demonstration of the shapes of different interpolation filters. '#13 + 499 'Just in case if you are curious.' + 500 #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' ); 501 502end; 503 504VAR 505 app : the_application; 506 507BEGIN 508 app.Construct(pix_format_bgr24 ,flip_y ); 509 app.caption_ ('Image filters'' shape comparison (F1-Help)' ); 510 511 if app.init(780 ,300 ,window_resize ) then 512 app.run; 513 514 app.Destruct; 515 516END.