#!/usr/bin/perl -w
sub
iterate {
my
(
$drawable
,
$message
,
$kernel
)=
@_
;
Gimp->progress_init (
$message
);
my
@bounds
=
$drawable
->bounds;
my
@off
=
$drawable
->offsets;
$bounds
[2]--
if
$bounds
[0]+
$bounds
[2] >=
$off
[0]+
$drawable
->width;
$bounds
[3]--
if
$bounds
[1]+
$bounds
[3] >=
$off
[1]+
$drawable
->height;
{
my
$src
= new Gimp::PixelRgn (
$drawable
,
@bounds
[0,1],
$bounds
[2]+1,
$bounds
[3]+1,0,0);
my
$dst
= new Gimp::PixelRgn (
$drawable
,
@bounds
,1,1);
my
$iter
= Gimp->pixel_rgns_register (
$dst
);
my
$area
=
$bounds
[2]
*$bounds
[3];
my
$progress
= 0;
do
{
my
(
$x
,
$y
,
$w
,
$h
)=(
$dst
->x,
$dst
->y,
$dst
->w,
$dst
->h);
$dst
->data(
$kernel
->(
$src
->get_rect(
$x
,
$y
,
$w
+1,
$h
+1)->convert(short)));
$progress
+=
$w
*$h
/
$area
;
Gimp->progress_update (
$progress
);
}
while
(Gimp->pixel_rgns_process (
$iter
));
}
Gimp->progress_update (1);
$drawable
->merge_shadow (1);
$drawable
->update (
@bounds
);
();
}
register
"blur_2x2"
,
"smooth (low pass filter) an image using a fast 2x2 kernel"
,
"Low-pass filtering (smoothing) using a fast 2x2 kernel"
,
''
,
''
,
''
,
N_
"<Image>/Filters/Blur/2x2 Blur"
,
''
,
''
,
sub
{
my
(
$image
,
$drawable
)=
@_
;
iterate
$drawable
,
"2x2 smoothing..."
,
sub
{
(
$_
[0]->slice(
":,0:-2,0:-2"
)+
$_
[0]->slice(
":,1:-1,0:-2"
)+
$_
[0]->slice(
":,1:-1,1:-1"
)+
$_
[0]->slice(
":,0:-2,1:-1"
))>>2;
};
};
register
"contrast_enhance_2x2"
,
"contrast enhance an image using a fast 2x2 kernel"
,
"Contrast Enhance an image using a fast 2x2 kernel"
,
''
,
''
,
''
,
N_
"<Image>/Filters/Enhance/2x2 Contrast Enhance"
,
''
,
''
,
sub
{
my
(
$image
,
$drawable
)=
@_
;
iterate
$drawable
,
"2x2 contrast enhancing..."
,
sub
{
my
$T
=
$_
[0]->slice(
":,0:-2,0:-2"
);
my
$D
=
$_
[0]->slice(
":,1:-1,1:-1"
);
((
$T
<<1)-
$D
)->clip(0,255);
};
};
register
"edge_detect_2x2"
,
"detects edges in an image using a fast 2x2 kernel"
,
"Detect edges in the image using a 2x2 kernel. It is similar to Sobel, yet sharper (and lower quality)."
,
''
,
''
,
''
,
N_
"<Image>/Filters/Edge-Detect/2x2 Edge Detect"
,
''
,
''
,
sub
{
my
(
$image
,
$drawable
)=
@_
;
iterate
$drawable
,
"2x2 cross gradient..."
,
sub
{
my
$T
=
$_
[0]->slice(
":,0:-2,0:-2"
);
my
$R
=
$_
[0]->slice(
":,1:-1,0:-2"
);
my
$D
=
$_
[0]->slice(
":,1:-1,1:-1"
);
abs
(cat(
$T
-
$R
,
$T
-
$D
))
->convert(byte)
->mv(3,0)
->maximum;
};
};
exit
main;