From: Tony Cook Date: Mon, 10 Dec 2007 03:21:33 +0000 (+0000) Subject: - added the det() function to the transform2() engine. X-Git-Tag: Imager-0.63~21 X-Git-Url: http://git.imager.perl.org/imager.git/commitdiff_plain/3309187a700fc44245c4c59f8cf66952a593e290 - added the det() function to the transform2() engine. added the sample quad_to_square.pl --- diff --git a/Changes b/Changes index 288f1305..e3cfc64a 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,11 @@ Imager 0.62 - unreleased So henceforth Imager uses the dlopen() family of functions, and you will need version 10.3 or later of OS X. + - added the det() function to the transform2() engine. + added the sample quad_to_square.pl + Courtesy Richard Fairhurst. + http://rt.cpan.org/Ticket/Display.html?id=31244 + Bug fixes: - samples/gifscale.pl sourced the base value for gif_top from diff --git a/MANIFEST b/MANIFEST index 5048227e..1e9441b1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -206,6 +206,7 @@ samples/gifscale.pl Scale an animated GIF, preserving animation info samples/inline_capture2image.pl convert captured BGR data to an image samples/inline_replace_color.pl replace colors using Inline::C samples/interleave.pl +samples/quad_to_square.pl Transform a quadrilateral into a square samples/replace_color.pl replace colors using transform2() samples/samp-form.cgi samples/samp-image.cgi diff --git a/lib/Imager/Engines.pod b/lib/Imager/Engines.pod index 6561d4a4..42784712 100644 --- a/lib/Imager/Engines.pod +++ b/lib/Imager/Engines.pod @@ -403,6 +403,21 @@ I B -- I =back +=item det(a, b, c, d) + +Calculate the determinant of the 2 x 2 matrix; + + a b + c d + +rpnexpr usage: + +=over + +I I I I B -- I + +=back + =back =head3 Constants diff --git a/lib/Imager/Regops.pm b/lib/Imager/Regops.pm index 8e0ade17..e2ed07e6 100644 --- a/lib/Imager/Regops.pm +++ b/lib/Imager/Regops.pm @@ -57,9 +57,10 @@ use constant RBC_HSVA => 47; use constant RBC_ALPHA => 48; use constant RBC_LOG => 49; use constant RBC_EXP => 50; -use constant RBC_OP_COUNT => 51; +use constant RBC_DET => 51; +use constant RBC_OP_COUNT => 52; -@EXPORT = qw(RBC_ADD RBC_SUBTRACT RBC_MULT RBC_DIV RBC_MOD RBC_POW RBC_UMINUS RBC_MULTP RBC_ADDP RBC_SUBTRACTP RBC_SIN RBC_COS RBC_ATAN2 RBC_SQRT RBC_DISTANCE RBC_GETP1 RBC_GETP2 RBC_GETP3 RBC_VALUE RBC_HUE RBC_SAT RBC_HSV RBC_RED RBC_GREEN RBC_BLUE RBC_RGB RBC_INT RBC_IF RBC_IFP RBC_LE RBC_LT RBC_GE RBC_GT RBC_EQ RBC_NE RBC_AND RBC_OR RBC_NOT RBC_ABS RBC_RET RBC_JUMP RBC_JUMPZ RBC_JUMPNZ RBC_SET RBC_SETP RBC_PRINT RBC_RGBA RBC_HSVA RBC_ALPHA RBC_LOG RBC_EXP RBC_OP_COUNT); +@EXPORT = qw(RBC_ADD RBC_SUBTRACT RBC_MULT RBC_DIV RBC_MOD RBC_POW RBC_UMINUS RBC_MULTP RBC_ADDP RBC_SUBTRACTP RBC_SIN RBC_COS RBC_ATAN2 RBC_SQRT RBC_DISTANCE RBC_GETP1 RBC_GETP2 RBC_GETP3 RBC_VALUE RBC_HUE RBC_SAT RBC_HSV RBC_RED RBC_GREEN RBC_BLUE RBC_RGB RBC_INT RBC_IF RBC_IFP RBC_LE RBC_LT RBC_GE RBC_GT RBC_EQ RBC_NE RBC_AND RBC_OR RBC_NOT RBC_ABS RBC_RET RBC_JUMP RBC_JUMPZ RBC_JUMPNZ RBC_SET RBC_SETP RBC_PRINT RBC_RGBA RBC_HSVA RBC_ALPHA RBC_LOG RBC_EXP RBC_DET RBC_OP_COUNT); %Attr = ( @@ -127,6 +128,14 @@ use constant RBC_OP_COUNT => 51; 'result' => 'r', 'types' => 'r', }, + 'det' => + { + 'func' => 1, + 'opcode' => 51, + 'parms' => 4, + 'result' => 'r', + 'types' => 'rrrr', + }, 'distance' => { 'func' => 1, @@ -346,7 +355,7 @@ use constant RBC_OP_COUNT => 51; 'op_count' => { 'func' => 0, - 'opcode' => 51, + 'opcode' => 52, 'parms' => 0, 'result' => undef, 'types' => '', @@ -369,10 +378,10 @@ use constant RBC_OP_COUNT => 51; }, 'print' => { - 'func' => 0, + 'func' => 1, 'opcode' => 45, 'parms' => 1, - 'result' => undef, + 'result' => 'r', 'types' => 'r', }, 'red' => diff --git a/regmach.c b/regmach.c index 02ea5e3c..c7fe613b 100644 --- a/regmach.c +++ b/regmach.c @@ -421,9 +421,14 @@ i_color i_rm_run(struct rm_op codes[], size_t code_count, break; case rbc_print: + nout = na; printf("r%d is %g\n", codes->ra, na); break; + case rbc_det: + nout = na*nd-nb*nc; + break; + default: /*croak("bad opcode"); */ printf("bad op %d\n", codes->code); diff --git a/regmach.h b/regmach.h index e8df6ea2..ed1e3037 100644 --- a/regmach.h +++ b/regmach.h @@ -53,12 +53,13 @@ enum rm_byte_codes { rbc_jumpnz, /* jump if ra != 0 to jb */ rbc_set, /* ra -> r */ rbc_setp, /* pa -> p*/ - rbc_print, /* prints ra */ + rbc_print, /* print(ra) -> r -- prints, leaves on stack */ rbc_rgba, /* rgba(ra, rb, rc, rd) -> p */ rbc_hsva, /* hsva(ra, rb, rc, rd) -> p */ rbc_alpha, /* alpha(pa) -> r */ rbc_log, /* log(ra) -> r */ rbc_exp, /* exp(ra) -> r */ + rbc_det, /* det(ra, rb, rc, rd) -> r */ rbc_op_count }; diff --git a/samples/README b/samples/README index a6ce36dc..a45f37af 100644 --- a/samples/README +++ b/samples/README @@ -110,3 +110,9 @@ gifscale.pl Scales an animated GIF image, preserving GIF animation information and adjusting the image screen positions to account for the scale factor. + +quad_to_square.pl + + Sample from Richard Fairhurst demonstrating the use of the transform2() + det() function. Transforms an arbitrary quadrilateral in the input into + a square on the output. diff --git a/samples/quad_to_square.pl b/samples/quad_to_square.pl new file mode 100644 index 00000000..97230d95 --- /dev/null +++ b/samples/quad_to_square.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl -w +use strict; +# Convert quadrilateral to square + +use Imager; + +my $src=Imager->new(); +$src->open(file=>"oldmap_200px.jpg"); + +# example co-ordinates of quadrilateral +my $x0=12; my $y0=4; # top left +my $x1=157; my $y1=0; # top right +my $x2=140; my $y2=150; # bottom right +my $x3=27; my $y3=159; # bottom left + +my $code=<$code, +width=>200, +height=>200, +constants=>{x0=>$x0,y0=>$y0, +x1=>$x1,y1=>$y1, +x2=>$x2,y2=>$y2, +x3=>$x3,y3=>$y3}}, +($src)); +$newimg->write(file=>"output_imager.jpg"); + +=head1 NAME + +quad_to_square.pl - transform an arbitrary quadrilateral to a square. + +=head1 SYNOPSIS + + perl quad_to_square.pl + +=head1 DESCRIPTION + +Courtesy Richard Fairhurst: + +I've been using it to rectify ("square up") a load of roughly scanned +maps, so that an arbitrary quadrilateral is resized into a square. The +transform2 function is ideal for that. + +Thought you might be interested to see what people are doing with +Imager - feel free to include this in the sample code. + +=head1 AUTHOR + +Richard Fairhurst + +=cut diff --git a/t/t58trans2.t b/t/t58trans2.t index 39f7f7ee..46db20a5 100644 --- a/t/t58trans2.t +++ b/t/t58trans2.t @@ -1,6 +1,6 @@ #!perl -w use strict; -use Test::More tests => 36; +use Test::More tests => 37; BEGIN { use_ok('Imager'); } use Imager::Test qw(is_color3); @@ -134,6 +134,9 @@ EOS op_test('000000', <<'EOS', 50, 82, 0, 'exp log'); 1 exp log 50 * 0.5 + 0.5 exp 50 * 0 rgb EOS +op_test('800000', <<'EOS', 128, 0, 0, 'det'); +1 0 0 1 det 128 * 1 1 1 1 det 128 * 0 rgb +EOS use Imager::Transform; @@ -168,7 +171,7 @@ sub op_test ($$$$$$) { { my $out = Imager::transform2({ rpnexpr => $code }, $im); unless ($out) { - fail("$comment: coult not compile $code - ".Imager->errstr); + fail("$comment: could not compile $code - ".Imager->errstr); return; } my $found = $out->getpixel(x => 0, y => 0);