mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 18:53:48 +02:00
516 lines
12 KiB
ObjectPascal
516 lines
12 KiB
ObjectPascal
//
|
|
// AggPas 2.4 RM3 Demo application
|
|
// Note: Press F1 key on run to see more info about this demo
|
|
//
|
|
// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
|
|
//
|
|
program
|
|
image_fltr_graph ;
|
|
|
|
uses
|
|
Math ,
|
|
|
|
agg_basics ,
|
|
agg_platform_support ,
|
|
|
|
agg_color ,
|
|
agg_pixfmt ,
|
|
agg_pixfmt_rgb ,
|
|
|
|
agg_ctrl ,
|
|
agg_slider_ctrl ,
|
|
agg_rbox_ctrl ,
|
|
agg_cbox_ctrl ,
|
|
|
|
agg_rendering_buffer ,
|
|
agg_renderer_base ,
|
|
agg_renderer_scanline ,
|
|
agg_rasterizer_scanline_aa ,
|
|
agg_scanline ,
|
|
agg_scanline_u ,
|
|
agg_scanline_p ,
|
|
agg_render_scanlines ,
|
|
|
|
agg_ellipse ,
|
|
agg_trans_affine ,
|
|
agg_conv_transform ,
|
|
agg_conv_stroke ,
|
|
agg_span_allocator ,
|
|
agg_span_interpolator_linear ,
|
|
agg_span_image_filter ,
|
|
agg_span_image_filter_rgb ,
|
|
agg_image_filters ,
|
|
agg_path_storage ;
|
|
|
|
{$I agg_mode.inc }
|
|
|
|
const
|
|
flip_y = true;
|
|
|
|
type
|
|
filter_adaptor_ptr = ^filter_adaptor;
|
|
filter_adaptor = object
|
|
m_filter : image_filter_base_ptr;
|
|
|
|
constructor Construct(filter : image_filter_base_ptr );
|
|
destructor Destruct;
|
|
|
|
function radius : double;
|
|
function calc_weight(x : double ) : double;
|
|
|
|
procedure set_radius(r : double );
|
|
|
|
end;
|
|
|
|
the_application = object(platform_support )
|
|
m_radius : slider_ctrl;
|
|
m_bilinear ,
|
|
m_bicubic ,
|
|
m_spline16 ,
|
|
m_spline36 ,
|
|
m_hanning ,
|
|
m_hamming ,
|
|
m_hermite ,
|
|
m_kaiser ,
|
|
m_quadric ,
|
|
m_catrom ,
|
|
m_gaussian ,
|
|
m_bessel ,
|
|
m_mitchell ,
|
|
m_sinc ,
|
|
m_lanczos ,
|
|
m_blackman : cbox_ctrl;
|
|
|
|
m_filters : array[0..31 ] of cbox_ctrl_ptr;
|
|
|
|
m_filter_bilinear ,
|
|
m_filter_bicubic ,
|
|
m_filter_spline16 ,
|
|
m_filter_spline36 ,
|
|
m_filter_hanning ,
|
|
m_filter_hamming ,
|
|
m_filter_hermite ,
|
|
m_filter_kaiser ,
|
|
m_filter_quadric ,
|
|
m_filter_catrom ,
|
|
m_filter_gaussian ,
|
|
m_filter_bessel ,
|
|
m_filter_mitchell ,
|
|
m_filter_sinc ,
|
|
m_filter_lanczos ,
|
|
m_filter_blackman : filter_adaptor;
|
|
|
|
m_filter_func : array[0..31 ] of filter_adaptor_ptr;
|
|
m_num_filters : unsigned;
|
|
|
|
constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
|
|
destructor Destruct;
|
|
|
|
procedure on_draw; virtual;
|
|
|
|
procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor filter_adaptor.Construct;
|
|
begin
|
|
m_filter:=filter;
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor filter_adaptor.Destruct;
|
|
begin
|
|
if m_filter <> NIL then
|
|
dispose(m_filter );
|
|
|
|
end;
|
|
|
|
{ RADIUS }
|
|
function filter_adaptor.radius;
|
|
begin
|
|
if m_filter <> NIL then
|
|
result:=m_filter.radius
|
|
else
|
|
result:=0;
|
|
|
|
end;
|
|
|
|
{ CALC_WEIGHT }
|
|
function filter_adaptor.calc_weight;
|
|
begin
|
|
if m_filter <> NIL then
|
|
result:=m_filter.calc_weight(Abs(x ) )
|
|
else
|
|
result:=0;
|
|
|
|
end;
|
|
|
|
{ SET_RADIUS }
|
|
procedure filter_adaptor.set_radius;
|
|
begin
|
|
if m_filter <> NIL then
|
|
m_filter.set_radius(r );
|
|
|
|
end;
|
|
|
|
{ CONSTRUCT }
|
|
constructor the_application.Construct;
|
|
var
|
|
i : unsigned;
|
|
|
|
begin
|
|
inherited Construct(format_ ,flip_y_ );
|
|
|
|
m_radius.Construct (5.0 ,5.0 ,780 - 5 ,10.0 ,not flip_y_ );
|
|
m_bilinear.Construct(8.0 ,30.0 + 15 * 0 ,'bilinear' ,not flip_y_ );
|
|
m_bicubic.Construct (8.0 ,30.0 + 15 * 1 ,'bicubic ' ,not flip_y_ );
|
|
m_spline16.Construct(8.0 ,30.0 + 15 * 2 ,'spline16' ,not flip_y_ );
|
|
m_spline36.Construct(8.0 ,30.0 + 15 * 3 ,'spline36' ,not flip_y_ );
|
|
m_hanning.Construct (8.0 ,30.0 + 15 * 4 ,'hanning ' ,not flip_y_ );
|
|
m_hamming.Construct (8.0 ,30.0 + 15 * 5 ,'hamming ' ,not flip_y_ );
|
|
m_hermite.Construct (8.0 ,30.0 + 15 * 6 ,'hermite ' ,not flip_y_ );
|
|
m_kaiser.Construct (8.0 ,30.0 + 15 * 7 ,'kaiser ' ,not flip_y_ );
|
|
m_quadric.Construct (8.0 ,30.0 + 15 * 8 ,'quadric ' ,not flip_y_ );
|
|
m_catrom.Construct (8.0 ,30.0 + 15 * 9 ,'catrom ' ,not flip_y_ );
|
|
m_gaussian.Construct(8.0 ,30.0 + 15 * 10 ,'gaussian' ,not flip_y_ );
|
|
m_bessel.Construct (8.0 ,30.0 + 15 * 11 ,'bessel ' ,not flip_y_ );
|
|
m_mitchell.Construct(8.0 ,30.0 + 15 * 12 ,'mitchell' ,not flip_y_ );
|
|
m_sinc.Construct (8.0 ,30.0 + 15 * 13 ,'sinc ' ,not flip_y_ );
|
|
m_lanczos.Construct (8.0 ,30.0 + 15 * 14 ,'lanczos ' ,not flip_y_ );
|
|
m_blackman.Construct(8.0 ,30.0 + 15 * 15 ,'blackman' ,not flip_y_ );
|
|
|
|
m_filter_bilinear.Construct(new(image_filter_bilinear_ptr ,Construct ) );
|
|
m_filter_bicubic.Construct (new(image_filter_bicubic_ptr ,Construct ) );
|
|
m_filter_spline16.Construct(new(image_filter_spline16_ptr ,Construct ) );
|
|
m_filter_spline36.Construct(new(image_filter_spline36_ptr ,Construct ) );
|
|
m_filter_hanning.Construct (new(image_filter_hanning_ptr ,Construct ) );
|
|
m_filter_hamming.Construct (new(image_filter_hamming_ptr ,Construct ) );
|
|
m_filter_hermite.Construct (new(image_filter_hermite_ptr ,Construct ) );
|
|
m_filter_kaiser.Construct (new(image_filter_kaiser_ptr ,Construct ) );
|
|
m_filter_quadric.Construct (new(image_filter_quadric_ptr ,Construct ) );
|
|
m_filter_catrom.Construct (new(image_filter_catrom_ptr ,Construct ) );
|
|
m_filter_gaussian.Construct(new(image_filter_gaussian_ptr ,Construct ) );
|
|
m_filter_bessel.Construct (new(image_filter_bessel_ptr ,Construct ) );
|
|
m_filter_mitchell.Construct(new(image_filter_mitchell_ptr ,Construct ) );
|
|
m_filter_sinc.Construct (new(image_filter_sinc_ptr ,Construct(2.0 ) ) );
|
|
m_filter_lanczos.Construct (new(image_filter_lanczos_ptr ,Construct(2.0 ) ) );
|
|
m_filter_blackman.Construct(new(image_filter_blackman_ptr ,Construct(2.0 ) ) );
|
|
|
|
m_num_filters:=0;
|
|
|
|
m_filters[m_num_filters ]:=@m_bilinear; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_bicubic; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_spline16; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_spline36; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_hanning; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_hamming; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_hermite; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_kaiser; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_quadric; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_catrom; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_gaussian; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_bessel; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_mitchell; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_sinc; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_lanczos; inc(m_num_filters );
|
|
m_filters[m_num_filters ]:=@m_blackman; inc(m_num_filters );
|
|
|
|
i:=0;
|
|
|
|
m_filter_func[i ]:=@m_filter_bilinear; inc(i );
|
|
m_filter_func[i ]:=@m_filter_bicubic; inc(i );
|
|
m_filter_func[i ]:=@m_filter_spline16; inc(i );
|
|
m_filter_func[i ]:=@m_filter_spline36; inc(i );
|
|
m_filter_func[i ]:=@m_filter_hanning; inc(i );
|
|
m_filter_func[i ]:=@m_filter_hamming; inc(i );
|
|
m_filter_func[i ]:=@m_filter_hermite; inc(i );
|
|
m_filter_func[i ]:=@m_filter_kaiser; inc(i );
|
|
m_filter_func[i ]:=@m_filter_quadric; inc(i );
|
|
m_filter_func[i ]:=@m_filter_catrom; inc(i );
|
|
m_filter_func[i ]:=@m_filter_gaussian; inc(i );
|
|
m_filter_func[i ]:=@m_filter_bessel; inc(i );
|
|
m_filter_func[i ]:=@m_filter_mitchell; inc(i );
|
|
m_filter_func[i ]:=@m_filter_sinc; inc(i );
|
|
m_filter_func[i ]:=@m_filter_lanczos; inc(i );
|
|
m_filter_func[i ]:=@m_filter_blackman; inc(i );
|
|
|
|
for i:=0 to m_num_filters - 1 do
|
|
add_ctrl(m_filters[i ] );
|
|
|
|
m_radius.range_(2.0 ,8.0 );
|
|
m_radius.value_(4.0 );
|
|
m_radius.label_('Radius=%.3f' );
|
|
|
|
add_ctrl(@m_radius );
|
|
|
|
end;
|
|
|
|
{ DESTRUCT }
|
|
destructor the_application.Destruct;
|
|
begin
|
|
inherited Destruct;
|
|
|
|
m_radius.Destruct;
|
|
m_bilinear.Destruct;
|
|
m_bicubic.Destruct;
|
|
m_spline16.Destruct;
|
|
m_spline36.Destruct;
|
|
m_hanning.Destruct;
|
|
m_hamming.Destruct;
|
|
m_hermite.Destruct;
|
|
m_kaiser.Destruct;
|
|
m_quadric.Destruct;
|
|
m_catrom.Destruct;
|
|
m_gaussian.Destruct;
|
|
m_bessel.Destruct;
|
|
m_mitchell.Destruct;
|
|
m_sinc.Destruct;
|
|
m_lanczos.Destruct;
|
|
m_blackman.Destruct;
|
|
|
|
m_filter_bilinear.Destruct;
|
|
m_filter_bicubic.Destruct;
|
|
m_filter_spline16.Destruct;
|
|
m_filter_spline36.Destruct;
|
|
m_filter_hanning.Destruct;
|
|
m_filter_hamming.Destruct;
|
|
m_filter_hermite.Destruct;
|
|
m_filter_kaiser.Destruct;
|
|
m_filter_quadric.Destruct;
|
|
m_filter_catrom.Destruct;
|
|
m_filter_gaussian.Destruct;
|
|
m_filter_bessel.Destruct;
|
|
m_filter_mitchell.Destruct;
|
|
m_filter_sinc.Destruct;
|
|
m_filter_lanczos.Destruct;
|
|
m_filter_blackman.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_DRAW }
|
|
procedure the_application.on_draw;
|
|
var
|
|
pixf : pixel_formats;
|
|
rgba : aggclr;
|
|
|
|
rb : renderer_base;
|
|
rs : renderer_scanline_aa_solid;
|
|
sl : scanline_p8;
|
|
|
|
ras : rasterizer_scanline_aa;
|
|
|
|
normalized : image_filter_lut;
|
|
weights : int16_ptr;
|
|
|
|
x_start ,x_end ,y_start ,y_end ,x_center ,x ,y ,ys ,radius ,dy ,xs ,dx ,sum ,xf : double;
|
|
|
|
xfract ,ir : int;
|
|
|
|
i ,j ,n ,xint ,nn : unsigned;
|
|
|
|
p : path_storage;
|
|
pl : conv_stroke;
|
|
tr : conv_transform;
|
|
|
|
begin
|
|
// Initialize structures
|
|
pixfmt_bgr24(pixf ,rbuf_window );
|
|
|
|
rb.Construct(@pixf );
|
|
rs.Construct(@rb );
|
|
|
|
rgba.ConstrDbl(1.0 ,1.0 ,1.0 );
|
|
rb.clear (@rgba );
|
|
|
|
ras.Construct;
|
|
sl.Construct;
|
|
|
|
// Render
|
|
x_start :=125.0;
|
|
x_end :=_initial_width - 15.0;
|
|
y_start :=10.0;
|
|
y_end :=_initial_height - 10.0;
|
|
x_center:=(x_start + x_end ) / 2;
|
|
|
|
p.Construct;
|
|
pl.Construct(@p );
|
|
tr.Construct(@pl ,_trans_affine_resizing );
|
|
|
|
for i:=0 to 15 do
|
|
begin
|
|
x:=x_start + (x_end - x_start ) * i / 16.0;
|
|
|
|
p.remove_all;
|
|
p.move_to(x + 0.5 ,y_start );
|
|
p.line_to(x + 0.5 ,y_end );
|
|
|
|
ras.add_path(@tr );
|
|
|
|
if i = 8 then
|
|
rgba.ConstrInt(0 ,0 ,0 ,255 )
|
|
else
|
|
rgba.ConstrInt(0 ,0 ,0 ,100 );
|
|
|
|
rs.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@rs );
|
|
|
|
end;
|
|
|
|
ys:=y_start + (y_end - y_start ) / 6.0;
|
|
|
|
p.remove_all;
|
|
p.move_to (x_start ,ys );
|
|
p.line_to (x_end ,ys );
|
|
ras.add_path (@tr );
|
|
rgba.ConstrInt (0 ,0 ,0 );
|
|
rs.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@rs );
|
|
|
|
pl.width_(1.0 );
|
|
|
|
for i:=0 to m_num_filters - 1 do
|
|
if m_filters[i ]._status then
|
|
begin
|
|
m_filter_func[i ].set_radius(m_radius._value );
|
|
|
|
radius:=m_filter_func[i ].radius;
|
|
|
|
n :=trunc(radius * 256 * 2 );
|
|
dy:=y_end - ys;
|
|
|
|
xs:=(x_end + x_start ) / 2.0 - (radius * (x_end - x_start ) / 16.0 );
|
|
dx:=(x_end - x_start ) * radius / 8.0;
|
|
|
|
p.remove_all;
|
|
p.move_to(xs + 0.5 ,ys + dy * m_filter_func[i ].calc_weight(-radius ) );
|
|
|
|
j:=1;
|
|
|
|
while j < n do
|
|
begin
|
|
p.line_to(
|
|
xs + dx * j / n + 0.5 ,
|
|
ys + dy * m_filter_func[i ].calc_weight(j / 256.0 - radius ) );
|
|
|
|
inc(j );
|
|
|
|
end;
|
|
|
|
ras.add_path (@tr );
|
|
rgba.ConstrInt (100 ,0 ,0 );
|
|
rs.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@rs );
|
|
|
|
p.remove_all;
|
|
|
|
ir:=trunc(Ceil(radius ) + 0.1 );
|
|
|
|
for xint:=0 to 255 do
|
|
begin
|
|
sum:=0;
|
|
|
|
xfract:=-ir;
|
|
|
|
while xfract < ir do
|
|
begin
|
|
xf:=xint / 256.0 + xfract;
|
|
|
|
if (xf >= -radius ) or
|
|
(xf <= radius ) then
|
|
sum:=sum + m_filter_func[i ].calc_weight(xf );
|
|
|
|
inc(xfract );
|
|
|
|
end;
|
|
|
|
x:=x_center + ((-128.0 + xint ) / 128.0 ) * radius * (x_end - x_start ) / 16.0;
|
|
y:=ys + sum * 256 - 256;
|
|
|
|
if xint = 0 then
|
|
p.move_to(x ,y )
|
|
else
|
|
p.line_to(x ,y );
|
|
|
|
end;
|
|
|
|
ras.add_path (@tr );
|
|
rgba.ConstrInt (0 ,100 ,0 );
|
|
rs.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@rs );
|
|
|
|
normalized.Construct(m_filter_func[i ].m_filter );
|
|
|
|
weights:=normalized.weight_array;
|
|
|
|
xs:=(x_end + x_start ) / 2.0 - (normalized.diameter * (x_end - x_start ) / 32.0 );
|
|
nn:=normalized.diameter * 256;
|
|
|
|
p.remove_all;
|
|
p.move_to(xs + 0.5 ,ys + dy * int16_ptr(weights )^ / image_filter_size );
|
|
|
|
j:=1;
|
|
|
|
while j < nn do
|
|
begin
|
|
p.line_to(
|
|
xs + dx * j / n + 0.5 ,
|
|
ys + dy * int16_ptr(ptrcomp(weights ) + j * sizeof(int16 ) )^ / image_filter_size );
|
|
|
|
inc(j );
|
|
|
|
end;
|
|
|
|
ras.add_path (@tr );
|
|
rgba.ConstrInt (0 ,0 ,100 ,255 );
|
|
rs.color_ (@rgba );
|
|
render_scanlines(@ras ,@sl ,@rs );
|
|
|
|
// Free
|
|
normalized.Destruct;
|
|
|
|
end;
|
|
|
|
// Render the controls
|
|
for i:=0 to m_num_filters - 1 do
|
|
render_ctrl(@ras ,@sl ,@rs ,m_filters[i ] );
|
|
|
|
if m_sinc._status or
|
|
m_lanczos._status or
|
|
m_blackman._status then
|
|
render_ctrl(@ras ,@sl ,@rs ,@m_radius );
|
|
|
|
// Free AGG resources
|
|
ras.Destruct;
|
|
sl.Destruct;
|
|
|
|
p.Destruct;
|
|
pl.Destruct;
|
|
|
|
end;
|
|
|
|
{ ON_KEY }
|
|
procedure the_application.on_key;
|
|
begin
|
|
if key = key_f1 then
|
|
message_(
|
|
'Demonstration of the shapes of different interpolation filters. '#13 +
|
|
'Just in case if you are curious.' +
|
|
#13#13'Note: F2 key saves current "screenshot" file in this demo''s directory. ' );
|
|
|
|
end;
|
|
|
|
VAR
|
|
app : the_application;
|
|
|
|
BEGIN
|
|
app.Construct(pix_format_bgr24 ,flip_y );
|
|
app.caption_ ('Image filters'' shape comparison (F1-Help)' );
|
|
|
|
if app.init(780 ,300 ,window_resize ) then
|
|
app.run;
|
|
|
|
app.Destruct;
|
|
|
|
END. |