Permalink
Browse files

the rubthrough() method now supports destination images with an alpha

channel.

Also added a statement on the relationship between the alpha channel
and color data in Imager.

The new rubthrough() code uses a new pre-processor that reduces source
code duplication between 8-bit/sample and double/sample processing.
  • Loading branch information...
1 parent be72aee commit fe415ad2caee20c8d87fda35959174becb733f6f Tony Cook committed Aug 29, 2006
Showing with 459 additions and 104 deletions.
  1. +2 −0 MANIFEST
  2. +1 −0 MANIFEST.SKIP
  3. +18 −2 Makefile.PL
  4. +3 −1 apidocs.perl
  5. +0 −98 image.c
  6. +207 −0 imtoc.perl
  7. +1 −1 lib/Imager/APIRef.pod
  8. +4 −0 lib/Imager/ImageTypes.pod
  9. +152 −0 rubthru.im
  10. +71 −2 t/t69rubthru.t
View
@@ -117,6 +117,7 @@ img16.c
imgdouble.c Implements double/sample images
imio.h
imperl.h
+imtoc.perl Sample size adapter pre-processor
io.c
iolayer.c
iolayer.h
@@ -173,6 +174,7 @@ regmach.h
regops.perl
rgb.c Reading and writing SGI rgb files
rotate.c
+rubthru.im
samples/README
samples/align-string.pl Demonstrate align_string method.
samples/anaglyph.pl
View
@@ -43,6 +43,7 @@ Makefile\.old
^imconfig\.h$
^ICO/ICO\.c$
^ICO/testout
+^rubthru\.c$
# trash from profiling
\.gcno$
View
@@ -155,7 +155,7 @@ my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
regmach.o trans2.o quant.o error.o convert.o
map.o tags.o palimg.o maskimg.o img16.o rotate.o
bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
- imext.o scale.o);
+ imext.o scale.o rubthru.o);
$Recommends{Imager} =
{ 'Parse::RecDescent' => 0 };
@@ -194,6 +194,9 @@ exit;
sub MY::postamble {
my $self = shift;
my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
+ my $mani = maniread;
+
+ my @ims = grep /\.im$/, keys %$mani;
'
dyntest.$(MYEXTLIB) : dynfilt/Makefile
cd dynfilt && $(MAKE) $(PASTHRU)
@@ -209,7 +212,20 @@ imconfig.h : Makefile.PL
lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
$perl apidocs.perl lib/Imager/APIRef.pod
-!;
+!.join('', map _im_rule($perl, $_), @ims)
+
+}
+
+sub _im_rule {
+ my ($perl, $im) = @_;
+
+ (my $c = $im) =~ s/\.im$/.c/;
+ return <<MAKE;
+
+$c: $im imtoc.perl
+ $perl imtoc.perl $im $c
+
+MAKE
}
View
@@ -1,5 +1,6 @@
#!perl -w
use strict;
+use ExtUtils::Manifest 'maniread';
my $outname = shift || '-';
@@ -9,7 +10,8 @@
# look for files to parse
-my @files = grep $_ ne 'Imager.xs', glob '*.c';
+my $mani = maniread;
+my @files = grep /\.(c|im)$/, keys %$mani;
# scan each file for =item <func>\b
my $func;
View
98 image.c
@@ -697,104 +697,6 @@ i_copy(i_img *src) {
}
-/*
-=item i_rubthru(im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy )
-
-=category Image
-
-Takes the sub image I<src[src_minx, src_maxx)[src_miny, src_maxy)> and
-overlays it at (I<tx>,I<ty>) on the image object.
-
-The alpha channel of each pixel in I<src> is used to control how much
-the existing colour in I<im> is replaced, if it is 255 then the colour
-is completely replaced, if it is 0 then the original colour is left
-unmodified.
-
-=cut
-*/
-
-int
-i_rubthru(i_img *im, i_img *src, int tx, int ty, int src_minx, int src_miny,
- int src_maxx, int src_maxy) {
- int x, y, ttx, tty;
- int chancount;
- int chans[3];
- int alphachan;
- int ch;
-
- mm_log((1,"i_rubthru(im %p, src %p, tx %d, ty %d, src_minx %d, "
- "src_miny %d, src_maxx %d, src_maxy %d)\n",
- im, src, tx, ty, src_minx, src_miny, src_maxx, src_maxy));
- i_clear_error();
-
- if (im->channels == 3 && src->channels == 4) {
- chancount = 3;
- chans[0] = 0; chans[1] = 1; chans[2] = 2;
- alphachan = 3;
- }
- else if (im->channels == 3 && src->channels == 2) {
- chancount = 3;
- chans[0] = chans[1] = chans[2] = 0;
- alphachan = 1;
- }
- else if (im->channels == 1 && src->channels == 2) {
- chancount = 1;
- chans[0] = 0;
- alphachan = 1;
- }
- else {
- i_push_error(0, "rubthru can only work where (dest, src) channels are (3,4), (3,2) or (1,2)");
- return 0;
- }
-
- if (im->bits <= 8) {
- /* if you change this code, please make sure the else branch is
- changed in a similar fashion - TC */
- int alpha;
- i_color pv, orig, dest;
- tty = ty;
- for(y = src_miny; y < src_maxy; y++) {
- ttx = tx;
- for(x = src_minx; x < src_maxx; x++) {
- i_gpix(src, x, y, &pv);
- i_gpix(im, ttx, tty, &orig);
- alpha = pv.channel[alphachan];
- for (ch = 0; ch < chancount; ++ch) {
- dest.channel[ch] = (alpha * pv.channel[chans[ch]]
- + (255 - alpha) * orig.channel[ch])/255;
- }
- i_ppix(im, ttx, tty, &dest);
- ttx++;
- }
- tty++;
- }
- }
- else {
- double alpha;
- i_fcolor pv, orig, dest;
-
- tty = ty;
- for(y = src_miny; y < src_maxy; y++) {
- ttx = tx;
- for(x = src_minx; x < src_maxx; x++) {
- i_gpixf(src, x, y, &pv);
- i_gpixf(im, ttx, tty, &orig);
- alpha = pv.channel[alphachan];
- for (ch = 0; ch < chancount; ++ch) {
- dest.channel[ch] = alpha * pv.channel[chans[ch]]
- + (1 - alpha) * orig.channel[ch];
- }
- i_ppixf(im, ttx, tty, &dest);
- ttx++;
- }
- tty++;
- }
- }
-
- return 1;
-}
-
-
/*
=item i_flipxy(im, axis)
View
@@ -0,0 +1,207 @@
+#!perl -w
+use strict;
+
+my $src = shift;
+my $dest = shift
+ or usage();
+
+open SRC, "< $src"
+ or die "Cannot open $src: $!\n";
+
+my $cond;
+my $cond_line;
+my $save_code;
+my @code;
+my $code_line;
+my @out;
+my $failed;
+
+push @out, "#line 1 \"$src\"\n";
+while (defined(my $line = <SRC>)) {
+ if ($line =~ /^\#code (.+)$/) {
+ $save_code
+ and do { warn "$src:$code_line:Unclosed #code block\n"; ++$failed; };
+
+ $cond = $1;
+ $cond_line = $.;
+ $code_line = $. + 1;
+ $save_code = 1;
+ }
+ elsif ($line =~ /^\#\/code$/) {
+ $save_code
+ or do { warn "$src:$.:#/code without #code\n"; ++$failed; next; };
+
+ push @out, "#line $cond_line \"$src\"\n";
+ push @out, " if ($cond) {\n";
+ push @out, "#line $code_line \"$src\"\n";
+ push @out, byte_samples(@code);
+ push @out, " }\n", " else {\n";
+ push @out, "#line $code_line \"$src\"\n";
+ push @out, double_samples(@code);
+ push @out, " }\n";
+ push @out, "#line $. \"$src\"\n";
+ @code = ();
+ $save_code = 0;
+ }
+ elsif ($save_code) {
+ push @code, $line;
+ }
+ else {
+ push @out, $line;
+ }
+}
+
+if ($save_code) {
+ warn "$src:$code_line:#code block not closed by EOF\n";
+ ++$failed;
+}
+
+close SRC;
+
+$failed
+ and die "Errors during parsing, aborting\n";
+
+open DEST, "> $dest"
+ or die "Cannot open $dest: $!\n";
+print DEST @out;
+close DEST;
+
+sub byte_samples {
+ # important we make a copy
+ my @lines = @_;
+
+ for (@lines) {
+ s/\bIM_GPIX\b/i_gpix/g;
+ s/\bIM_GLIN\b/i_glin/g;
+ s/\bIM_PPIX\b/i_ppix/g;
+ s/\bIM_PLIN\b/i_plin/g;
+ s/\bIM_GSAMP\b/i_gsamp/g;
+ s/\bIM_SAMPLE_MAX\b/255/g;
+ s/\bIM_SAMPLE_T/i_sample_t/g;
+ s/\bIM_COLOR\b/i_color/g;
+ s/\bIM_WORK_T\b/int/g;
+ s/\bIM_Sf\b/"%d"/g;
+ s/\bIM_Wf\b/"%d"/g;
+ }
+
+ @lines;
+}
+
+sub double_samples {
+ # important we make a copy
+ my @lines = @_;
+
+ for (@lines) {
+ s/\bIM_GPIX\b/i_gpixf/g;
+ s/\bIM_GLIN\b/i_glinf/g;
+ s/\bIM_PPIX\b/i_ppixf/g;
+ s/\bIM_PLIN\b/i_plinf/g;
+ s/\bIM_GSAMP\b/i_gsampf/g;
+ s/\bIM_SAMPLE_MAX\b/1.0/g;
+ s/\bIM_SAMPLE_T/i_fsample_t/g;
+ s/\bIM_COLOR\b/i_fcolor/g;
+ s/\bIM_WORK_T\b/double/g;
+ s/\bIM_Sf\b/"%f"/g;
+ s/\bIM_Wf\b/"%f"/g;
+ }
+
+ @lines;
+}
+
+=head1 NAME
+
+imtoc.perl - simple preprocessor for handling multiple sample sizes
+
+=head1 SYNOPSIS
+
+ /* in the source: */
+ #code condition true to work with 8-bit samples
+ ... code using preprocessor types/values ...
+ #/code
+
+ perl imtoc.perl foo.im foo.c
+
+=head1 DESCRIPTION
+
+This is a simple preprocessor that aims to reduce duplication of
+source code when implementing an algorithm both for 8-bit samples and
+double samples in Imager.
+
+Imager's Makefile.PL currently scans the MANIFEST for .im files and
+adds Makefile files to convert these to .c files.
+
+The beginning of a sample-independent section of code is preceded by:
+
+ #code expression
+
+where I<expression> should return true if processing should be done at
+8-bits/sample.
+
+The end of a sample-independent section of code is terminated by:
+
+ #/code
+
+#code sections cannot be nested.
+
+#/code without a starting #code is an error.
+
+The following types and values are defined in a #code section:
+
+=over
+
+=item *
+
+IM_GPIX(im, x, y, &col)
+
+=item *
+
+IM_GLIN(im, l, r, y, colors)
+
+=item *
+
+IM_PPIX(im, x, y, &col)
+
+=item *
+
+IM_PLIN(im, x, y, colors)
+
+=item *
+
+IM_GSAMP(im, l, r, y, samples, chans, chan_count)
+
+These correspond to the appropriate image function, eg. IM_GPIX()
+becomes i_gpix() or i_gpixf() as appropriate.
+
+=item *
+
+IM_SAMPLE_MAX - maximum value for a sample
+
+=item *
+
+IM_SAMPLE_T - type of a sample (i_sample_t or i_fsample_t)
+
+=item *
+
+IM_COLOR - color type, either i_color or i_fcolor.
+
+=item *
+
+IM_WORK_T - working sample type, either int or double.
+
+=item *
+
+IM_Sf - format string for the sample type, C<"%d"> or C<"%f">.
+
+=item *
+
+IM_Wf - format string for the work type, C<"%d"> or C<"%f">.
+
+=back
+
+Other types, functions and values may be added in the future.
+
+=head1 AUTHOR
+
+Tony Cook <tony@imager.perl.org>
+
+=cut
Oops, something went wrong.

0 comments on commit fe415ad

Please sign in to comment.