Skip to content

Commit

Permalink
- added comment support the postfix transform2() expression
Browse files Browse the repository at this point in the history
          parser
        - transform2() can now produce images with other than 3 channels.
        - added a correct T_AVREF input mapping to the typemap to
          simplify parameter lists
  • Loading branch information
Tony Cook committed Jun 26, 2003
1 parent cde2dbc commit e5744e0
Show file tree
Hide file tree
Showing 11 changed files with 444 additions and 333 deletions.
5 changes: 5 additions & 0 deletions Changes
Expand Up @@ -720,6 +720,11 @@ Revision history for Perl extension Imager.
source image is used. source image is used.
- the image fills didn't handle filling with source images of - the image fills didn't handle filling with source images of
less than four channels correctly less than four channels correctly
- added comment support the postfix transform2() expression
parser
- transform2() can now produce images with other than 3 channels.
- added a correct T_AVREF input mapping to the typemap to
simplify parameter lists


================================================================= =================================================================


Expand Down
7 changes: 6 additions & 1 deletion Imager.pm
Expand Up @@ -1722,9 +1722,14 @@ sub transform2 {
$Imager::ERRSTR = Imager::Expr::error(); $Imager::ERRSTR = Imager::Expr::error();
return; return;
} }
my $channels = $opts->{channels} || 3;
unless ($channels >= 1 && $channels <= 4) {
return Imager->_set_error("channels must be an integer between 1 and 4");
}


my $img = Imager->new(); my $img = Imager->new();
$img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(), $img->{IMG} = i_transform2($opts->{width}, $opts->{height},
$channels, $code->code(),
$code->nregs(), $code->cregs(), $code->nregs(), $code->cregs(),
[ map { $_->{IMG} } @imgs ]); [ map { $_->{IMG} } @imgs ]);
if (!defined $img->{IMG}) { if (!defined $img->{IMG}) {
Expand Down
58 changes: 25 additions & 33 deletions Imager.xs
Expand Up @@ -2870,7 +2870,14 @@ i_transform(im,opx,opy,parm)
else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL); else sv_setref_pv(ST(0), "Imager::ImgRaw", (void*)RETVAL);


Imager::ImgRaw Imager::ImgRaw
i_transform2(width,height,ops,n_regs,c_regs,in_imgs) i_transform2(sv_width,sv_height,channels,sv_ops,av_n_regs,av_c_regs,av_in_imgs)
SV *sv_width
SV *sv_height
SV *sv_ops
AV *av_n_regs
AV *av_c_regs
AV *av_in_imgs
int channels
PREINIT: PREINIT:
int width; int width;
int height; int height;
Expand All @@ -2889,32 +2896,18 @@ i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
IV tmp; IV tmp;
int i; int i;
CODE: CODE:
if (!SvROK(ST(3))) croak("Imager: Parameter 4 must be a reference to an array\n");
if (!SvROK(ST(4))) croak("Imager: Parameter 5 must be a reference to an array\n"); in_imgs_count = av_len(av_in_imgs)+1;
if (!SvROK(ST(5))) croak("Imager: Parameter 6 must be a reference to an array of images\n"); for (i = 0; i < in_imgs_count; ++i) {
if (SvTYPE(SvRV(ST(3))) != SVt_PVAV) croak("Imager: Parameter 4 must be a reference to an array\n"); sv1 = *av_fetch(av_in_imgs, i, 0);
if (SvTYPE(SvRV(ST(4))) != SVt_PVAV) croak("Imager: Parameter 5 must be a reference to an array\n"); if (!sv_derived_from(sv1, "Imager::ImgRaw")) {

croak("sv_in_img must contain only images");
/*if (SvTYPE(SvRV(ST(5))) != SVt_PVAV) croak("Imager: Parameter 6 must be a reference to an array\n");*/

if (SvTYPE(SvRV(ST(5))) == SVt_PVAV) {
av = (AV*)SvRV(ST(5));
in_imgs_count = av_len(av)+1;
for (i = 0; i < in_imgs_count; ++i) {
sv1 = *av_fetch(av, i, 0);
if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
croak("Parameter 5 must contain only images");
}
} }
} }
else {
in_imgs_count = 0;
}
if (in_imgs_count > 0) { if (in_imgs_count > 0) {
av = (AV*)SvRV(ST(5));
in_imgs = mymalloc(in_imgs_count*sizeof(i_img*)); in_imgs = mymalloc(in_imgs_count*sizeof(i_img*));
for (i = 0; i < in_imgs_count; ++i) { for (i = 0; i < in_imgs_count; ++i) {
sv1 = *av_fetch(av,i,0); sv1 = *av_fetch(av_in_imgs,i,0);
if (!sv_derived_from(sv1, "Imager::ImgRaw")) { if (!sv_derived_from(sv1, "Imager::ImgRaw")) {
croak("Parameter 5 must contain only images"); croak("Parameter 5 must contain only images");
} }
Expand All @@ -2927,38 +2920,37 @@ i_transform2(width,height,ops,n_regs,c_regs,in_imgs)
in_imgs = NULL; in_imgs = NULL;
} }
/* default the output size from the first input if possible */ /* default the output size from the first input if possible */
if (SvOK(ST(0))) if (SvOK(sv_width))
width = SvIV(ST(0)); width = SvIV(sv_width);
else if (in_imgs_count) else if (in_imgs_count)
width = in_imgs[0]->xsize; width = in_imgs[0]->xsize;
else else
croak("No output image width supplied"); croak("No output image width supplied");


if (SvOK(ST(1))) if (SvOK(sv_height))
height = SvIV(ST(1)); height = SvIV(sv_height);
else if (in_imgs_count) else if (in_imgs_count)
height = in_imgs[0]->ysize; height = in_imgs[0]->ysize;
else else
croak("No output image height supplied"); croak("No output image height supplied");


ops = (struct rm_op *)SvPV(ST(2), ops_len); ops = (struct rm_op *)SvPV(sv_ops, ops_len);
if (ops_len % sizeof(struct rm_op)) if (ops_len % sizeof(struct rm_op))
croak("Imager: Parameter 3 must be a bitmap of regops\n"); croak("Imager: Parameter 3 must be a bitmap of regops\n");
ops_count = ops_len / sizeof(struct rm_op); ops_count = ops_len / sizeof(struct rm_op);
av = (AV*)SvRV(ST(3));
n_regs_count = av_len(av)+1; n_regs_count = av_len(av_n_regs)+1;
n_regs = mymalloc(n_regs_count * sizeof(double)); n_regs = mymalloc(n_regs_count * sizeof(double));
for (i = 0; i < n_regs_count; ++i) { for (i = 0; i < n_regs_count; ++i) {
sv1 = *av_fetch(av,i,0); sv1 = *av_fetch(av_n_regs,i,0);
if (SvOK(sv1)) if (SvOK(sv1))
n_regs[i] = SvNV(sv1); n_regs[i] = SvNV(sv1);
} }
av = (AV*)SvRV(ST(4)); c_regs_count = av_len(av_c_regs)+1;
c_regs_count = av_len(av)+1;
c_regs = mymalloc(c_regs_count * sizeof(i_color)); c_regs = mymalloc(c_regs_count * sizeof(i_color));
/* I don't bother initializing the colou?r registers */ /* I don't bother initializing the colou?r registers */


RETVAL=i_transform2(width, height, 3, ops, ops_count, RETVAL=i_transform2(width, height, channels, ops, ops_count,
n_regs, n_regs_count, n_regs, n_regs_count,
c_regs, c_regs_count, in_imgs, in_imgs_count); c_regs, c_regs_count, in_imgs, in_imgs_count);
if (in_imgs) if (in_imgs)
Expand Down
27 changes: 24 additions & 3 deletions lib/Imager/Engines.pod
Expand Up @@ -91,6 +91,11 @@ images an error occurs.
constants - a reference to hash of constants to define for the constants - a reference to hash of constants to define for the
expression engine. Some extra constants are defined by Imager expression engine. Some extra constants are defined by Imager


=item *

channels - the number of channels in the output image. If this isn't
supplied a 3 channel image will be created.

=back =back


The tranformation function is specified using either the expr or The tranformation function is specified using either the expr or
Expand Down Expand Up @@ -180,16 +185,21 @@ respectively. I may add a getpn() function at some point, but this
prevents static checking of the instructions against the number of prevents static checking of the instructions against the number of
images actually passed in. images actually passed in.


=item value(c), hue(c), sat(c), hsv(h,s,v) =item value(c), hue(c), sat(c), hsv(h,s,v), hsva(h,s,v,alpha)


Separates a colour value into it's value (brightness), hue (colour) Separates a colour value into it's value (brightness), hue (colour)
and saturation elements. Use hsv() to put them back together (after and saturation elements. Use hsv() to put them back together (after
suitable manipulation). suitable manipulation), or hsva() to include a tranparency value.


=item red(c), green(c), blue(c), rgb(r,g,b) =item red(c), green(c), blue(c), rgb(r,g,b)


Separates a colour value into it's red, green and blue colours. Use Separates a colour value into it's red, green and blue colours. Use
rgb(r,g,b) to put it back together. rgb(r,g,b) to put it back together, or rgba() to include a
transparency value.

=item alpha(c)

Retrieve the alpha value from a colour.


=item int(n) =item int(n)


Expand Down Expand Up @@ -262,6 +272,17 @@ L<Imager::regmach.pod>.
EOS EOS
}); });


# replace green portions of an image with another image
my $newimg = Imager::transform2({
rpnexpr => <<EOS
x y getp2 !pat # used to replace green portions
x y getp1 !pix # source with "green screen"
@pix red 10 lt @pix blue 10 lt && # low blue and red
@pix green 254 gt && # and high green
@pat @pix ifp
EOS
}, $source, $background);

=head2 Matrix Transformations =head2 Matrix Transformations


Rather than having to write code in a little language, you can use a Rather than having to write code in a little language, you can use a
Expand Down
1 change: 1 addition & 0 deletions lib/Imager/Expr.pm
Expand Up @@ -298,6 +298,7 @@ my %op_names = ( '+'=>'add', '-'=>'subtract', '*'=>'mult', '/' => 'div',
sub compile { sub compile {
my ($self, $expr, $opts) = @_; my ($self, $expr, $opts) = @_;


$expr =~ s/#.*//; # remove comments
my @st_ops = split ' ', $expr; my @st_ops = split ' ', $expr;


for (@st_ops) { for (@st_ops) {
Expand Down

0 comments on commit e5744e0

Please sign in to comment.