From 999f4294d1b765b04c08c37630eccb4d3239ab14 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Fri, 6 Jan 2012 10:39:39 +1100 Subject: [PATCH] rotate.c -> rotate.im transition convert to use the preprocessor to reduce code duplication --- .gitignore | 1 + MANIFEST | 2 +- rotate.c => rotate.im | 323 +++++++++++++++--------------------------- t/t64copyflip.t | 27 +++- 4 files changed, 142 insertions(+), 211 deletions(-) rename rotate.c => rotate.im (55%) diff --git a/.gitignore b/.gitignore index 27cc7a84..ba3c3655 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ imconfig.h paste.c render.c paste.c +rotate.c rubthru.c scale.c diff --git a/MANIFEST b/MANIFEST index 74e493b7..b3d91dab 100644 --- a/MANIFEST +++ b/MANIFEST @@ -238,7 +238,7 @@ regmach.h regops.perl render.im rendert.h Buffer rendering engine types -rotate.c +rotate.im rubthru.im samples/align-string.pl Demonstrate align_string method. samples/anaglyph.pl diff --git a/rotate.c b/rotate.im similarity index 55% rename from rotate.c rename to rotate.im index 90cf5912..e6d1d114 100644 --- a/rotate.c +++ b/rotate.im @@ -1,7 +1,7 @@ /* =head1 NAME - rotate.c - implements image rotations + rotate.im - implements image rotations =head1 SYNOPSIS @@ -31,34 +31,20 @@ i_img *i_rotate90(i_img *src, int degrees) { done in place */ targ = i_sametype(src, src->xsize, src->ysize); if (src->type == i_direct_type) { - if (src->bits == i_8_bits) { - i_color *vals = mymalloc(src->xsize * sizeof(i_color)); - for (y = 0; y < src->ysize; ++y) { - i_color tmp; - i_glin(src, 0, src->xsize, y, vals); - for (x = 0; x < src->xsize/2; ++x) { - tmp = vals[x]; - vals[x] = vals[src->xsize - x - 1]; - vals[src->xsize - x - 1] = tmp; - } - i_plin(targ, 0, src->xsize, src->ysize - y - 1, vals); - } - myfree(vals); - } - else { - i_fcolor *vals = mymalloc(src->xsize * sizeof(i_fcolor)); - for (y = 0; y < src->ysize; ++y) { - i_fcolor tmp; - i_glinf(src, 0, src->xsize, y, vals); - for (x = 0; x < src->xsize/2; ++x) { - tmp = vals[x]; - vals[x] = vals[src->xsize - x - 1]; - vals[src->xsize - x - 1] = tmp; - } - i_plinf(targ, 0, src->xsize, src->ysize - y - 1, vals); - } - myfree(vals); +#code src->bits <= 8 + IM_COLOR *vals = mymalloc(src->xsize * sizeof(IM_COLOR)); + for (y = 0; y < src->ysize; ++y) { + IM_COLOR tmp; + IM_GLIN(src, 0, src->xsize, y, vals); + for (x = 0; x < src->xsize/2; ++x) { + tmp = vals[x]; + vals[x] = vals[src->xsize - x - 1]; + vals[src->xsize - x - 1] = tmp; + } + IM_PLIN(targ, 0, src->xsize, src->ysize - y - 1, vals); } + myfree(vals); +#/code } else { i_palidx *vals = mymalloc(src->xsize * sizeof(i_palidx)); @@ -97,36 +83,21 @@ i_img *i_rotate90(i_img *src, int degrees) { } targ = i_sametype(src, src->ysize, src->xsize); if (src->type == i_direct_type) { - if (src->bits == i_8_bits) { - i_color *vals = mymalloc(src->xsize * sizeof(i_color)); - - tx = txstart; - for (y = 0; y < src->ysize; ++y) { - i_glin(src, 0, src->xsize, y, vals); - ty = tystart; - for (x = 0; x < src->xsize; ++x) { - i_ppix(targ, tx, ty, vals+x); - ty += tyinc; - } - tx += txinc; - } - myfree(vals); - } - else { - i_fcolor *vals = mymalloc(src->xsize * sizeof(i_fcolor)); - - tx = txstart; - for (y = 0; y < src->ysize; ++y) { - i_glinf(src, 0, src->xsize, y, vals); - ty = tystart; - for (x = 0; x < src->xsize; ++x) { - i_ppixf(targ, tx, ty, vals+x); - ty += tyinc; - } - tx += txinc; - } - myfree(vals); +#code src->bits <= 8 + IM_COLOR *vals = mymalloc(src->xsize * sizeof(IM_COLOR)); + + tx = txstart; + for (y = 0; y < src->ysize; ++y) { + IM_GLIN(src, 0, src->xsize, y, vals); + ty = tystart; + for (x = 0; x < src->xsize; ++x) { + IM_PPIX(targ, tx, ty, vals+x); + ty += tyinc; + } + tx += txinc; } + myfree(vals); +#/code } else { i_palidx *vals = mymalloc(src->xsize * sizeof(i_palidx)); @@ -231,165 +202,99 @@ i_img *i_matrix_transform_bg(i_img *src, i_img_dim xsize, i_img_dim ysize, const double sx, sy, sz; if (src->type == i_direct_type) { - if (src->bits == i_8_bits) { - i_color *vals = mymalloc(xsize * sizeof(i_color)); - i_color back; - i_fsample_t fsamp; - - if (backp) { - back = *backp; - } - else if (fbackp) { - for (ch = 0; ch < src->channels; ++ch) { - fsamp = fbackp->channel[ch]; - back.channel[ch] = fsamp < 0 ? 0 : fsamp > 1 ? 255 : fsamp * 255; - } - } - else { - for (ch = 0; ch < src->channels; ++ch) - back.channel[ch] = 0; - } - - for (y = 0; y < ysize; ++y) { - for (x = 0; x < xsize; ++x) { - /* dividing by sz gives us the ability to do perspective - transforms */ - sz = x * matrix[6] + y * matrix[7] + matrix[8]; - if (fabs(sz) > 0.0000001) { - sx = (x * matrix[0] + y * matrix[1] + matrix[2]) / sz; - sy = (x * matrix[3] + y * matrix[4] + matrix[5]) / sz; - } - else { - sx = sy = 0; - } +#code src->bits <= 8 + IM_COLOR *vals = mymalloc(xsize * sizeof(IM_COLOR)); + IM_COLOR back; + i_fsample_t fsamp; - /* anything outside these ranges is either a broken co-ordinate - or outside the source */ - if (fabs(sz) > 0.0000001 - && sx >= -1 && sx < src->xsize - && sy >= -1 && sy < src->ysize) { - - if (sx != (i_img_dim)sx) { - if (sy != (i_img_dim)sy) { - i_color c[2][2]; - i_color ci2[2]; - for (i = 0; i < 2; ++i) - for (j = 0; j < 2; ++j) - if (i_gpix(src, floor(sx)+i, floor(sy)+j, &c[j][i])) - c[j][i] = back; - for (j = 0; j < 2; ++j) - ci2[j] = interp_i_color(c[j][0], c[j][1], sx, src->channels); - vals[x] = interp_i_color(ci2[0], ci2[1], sy, src->channels); - } - else { - i_color ci2[2]; - for (i = 0; i < 2; ++i) - if (i_gpix(src, floor(sx)+i, sy, ci2+i)) - ci2[i] = back; - vals[x] = interp_i_color(ci2[0], ci2[1], sx, src->channels); - } - } - else { - if (sy != (i_img_dim)sy) { - i_color ci2[2]; - for (i = 0; i < 2; ++i) - if (i_gpix(src, sx, floor(sy)+i, ci2+i)) - ci2[i] = back; - vals[x] = interp_i_color(ci2[0], ci2[1], sy, src->channels); - } - else { - /* all the world's an integer */ - if (i_gpix(src, sx, sy, vals+x)) - vals[x] = back; - } - } - } - else { - vals[x] = back; - } - } - i_plin(result, 0, xsize, y, vals); +#ifdef IM_EIGHT_BIT + if (backp) { + back = *backp; + } + else if (fbackp) { + for (ch = 0; ch < src->channels; ++ch) { + fsamp = fbackp->channel[ch]; + back.channel[ch] = fsamp < 0 ? 0 : fsamp > 1 ? 255 : fsamp * 255; } - myfree(vals); } +#else +#define interp_i_color interp_i_fcolor + if (fbackp) { + back = *fbackp; + } + else if (backp) { + for (ch = 0; ch < src->channels; ++ch) + back.channel[ch] = backp->channel[ch] / 255.0; + } +#endif else { - i_fcolor *vals = mymalloc(xsize * sizeof(i_fcolor)); - i_fcolor back; - - if (fbackp) { - back = *fbackp; - } - else if (backp) { - for (ch = 0; ch < src->channels; ++ch) - back.channel[ch] = backp->channel[ch] / 255.0; - } - else { - for (ch = 0; ch < src->channels; ++ch) - back.channel[ch] = 0; - } + for (ch = 0; ch < src->channels; ++ch) + back.channel[ch] = 0; + } - for (y = 0; y < ysize; ++y) { - for (x = 0; x < xsize; ++x) { - /* dividing by sz gives us the ability to do perspective - transforms */ - sz = x * matrix[6] + y * matrix[7] + matrix[8]; - if (fabs(sz) > 0.0000001) { - sx = (x * matrix[0] + y * matrix[1] + matrix[2]) / sz; - sy = (x * matrix[3] + y * matrix[4] + matrix[5]) / sz; - } - else { - sx = sy = 0; - } - - /* anything outside these ranges is either a broken co-ordinate - or outside the source */ - if (fabs(sz) > 0.0000001 - && sx >= -1 && sx < src->xsize - && sy >= -1 && sy < src->ysize) { - - if (sx != (i_img_dim)sx) { - if (sy != (i_img_dim)sy) { - i_fcolor c[2][2]; - i_fcolor ci2[2]; - for (i = 0; i < 2; ++i) - for (j = 0; j < 2; ++j) - if (i_gpixf(src, floor(sx)+i, floor(sy)+j, &c[j][i])) - c[j][i] = back; - for (j = 0; j < 2; ++j) - ci2[j] = interp_i_fcolor(c[j][0], c[j][1], sx, src->channels); - vals[x] = interp_i_fcolor(ci2[0], ci2[1], sy, src->channels); - } - else { - i_fcolor ci2[2]; - for (i = 0; i < 2; ++i) - if (i_gpixf(src, floor(sx)+i, sy, ci2+i)) - ci2[i] = back; - vals[x] = interp_i_fcolor(ci2[0], ci2[1], sx, src->channels); - } - } - else { - if (sy != (i_img_dim)sy) { - i_fcolor ci2[2]; - for (i = 0; i < 2; ++i) - if (i_gpixf(src, sx, floor(sy)+i, ci2+i)) - ci2[i] = back; - vals[x] = interp_i_fcolor(ci2[0], ci2[1], sy, src->channels); - } - else { - /* all the world's an integer */ - if (i_gpixf(src, sx, sy, vals+x)) - vals[x] = back; - } - } - } - else { - vals[x] = back; - } - } - i_plinf(result, 0, xsize, y, vals); + for (y = 0; y < ysize; ++y) { + for (x = 0; x < xsize; ++x) { + /* dividing by sz gives us the ability to do perspective + transforms */ + sz = x * matrix[6] + y * matrix[7] + matrix[8]; + if (fabs(sz) > 0.0000001) { + sx = (x * matrix[0] + y * matrix[1] + matrix[2]) / sz; + sy = (x * matrix[3] + y * matrix[4] + matrix[5]) / sz; + } + else { + sx = sy = 0; + } + + /* anything outside these ranges is either a broken co-ordinate + or outside the source */ + if (fabs(sz) > 0.0000001 + && sx >= -1 && sx < src->xsize + && sy >= -1 && sy < src->ysize) { + + if (sx != (i_img_dim)sx) { + if (sy != (i_img_dim)sy) { + IM_COLOR c[2][2]; + IM_COLOR ci2[2]; + for (i = 0; i < 2; ++i) + for (j = 0; j < 2; ++j) + if (IM_GPIX(src, floor(sx)+i, floor(sy)+j, &c[j][i])) + c[j][i] = back; + for (j = 0; j < 2; ++j) + ci2[j] = interp_i_color(c[j][0], c[j][1], sx, src->channels); + vals[x] = interp_i_color(ci2[0], ci2[1], sy, src->channels); + } + else { + IM_COLOR ci2[2]; + for (i = 0; i < 2; ++i) + if (IM_GPIX(src, floor(sx)+i, sy, ci2+i)) + ci2[i] = back; + vals[x] = interp_i_color(ci2[0], ci2[1], sx, src->channels); + } + } + else { + if (sy != (i_img_dim)sy) { + IM_COLOR ci2[2]; + for (i = 0; i < 2; ++i) + if (IM_GPIX(src, sx, floor(sy)+i, ci2+i)) + ci2[i] = back; + vals[x] = interp_i_color(ci2[0], ci2[1], sy, src->channels); + } + else { + /* all the world's an integer */ + if (IM_GPIX(src, sx, sy, vals+x)) + vals[x] = back; + } + } + } + else { + vals[x] = back; + } } - myfree(vals); + IM_PLIN(result, 0, xsize, y, vals); } + myfree(vals); +#undef interp_i_color +#/code } else { /* don't interpolate for a palette based image */ diff --git a/t/t64copyflip.t b/t/t64copyflip.t index 15526e3b..5a48c058 100644 --- a/t/t64copyflip.t +++ b/t/t64copyflip.t @@ -1,6 +1,6 @@ #!perl -w use strict; -use Test::More tests => 77; +use Test::More tests => 83; use Imager; use Imager::Test qw(is_color3 is_image is_imaged test_image_double test_image isnt_image); @@ -106,6 +106,31 @@ if (!$rimg->write(file=>"testout/t64_rot10_back.ppm")) { ok(!$rimg, "should fail due to bad back color"); cmp_ok($img->errstr, '=~', "^No color named ", "check error message"); } +SKIP: +{ # rotate in double mode + my $dimg = $img->to_rgb16; + my $rimg = $dimg->rotate(degrees => 10); + ok($rimg, "rotate 16-bit image gave us an image") + or skip("could not rotate", 3); + ok($rimg->write(file => "testout/t64_rotf10.ppm", pnm_write_wide_data => 1), + "save wide data rotated") + or diag($rimg->errstr); + + # with a background color + my $rimgb = $dimg->rotate(degrees => 10, back => "#FF8000"); + ok($rimgb, "rotate 16-bit image with back gave us an image") + or skip("could not rotate", 1); + ok($rimgb->write(file => "testout/t64_rotfb10.ppm", pnm_write_wide_data => 1), + "save wide data rotated") + or diag($rimgb->errstr); +} +{ # rotate in paletted mode + my $rimg = $pimg->rotate(degrees => 10); + ok($rimg, "rotated paletted image 10 degrees"); + ok($rimg->write(file => "testout/t64_rotp10.ppm"), + "save paletted rotated") + or diag($rimg->errstr); +} my $trimg = $img->matrix_transform(matrix=>[ 1.2, 0, 0, 0, 1, 0, -- 2.30.2