]> git.imager.perl.org - imager.git/commitdiff
Added map.c which implements mapping images through tables.
authorArnar Mar Hrafnkelsson <addi@cpan.org>
Wed, 16 May 2001 08:43:33 +0000 (08:43 +0000)
committerArnar Mar Hrafnkelsson <addi@cpan.org>
Wed, 16 May 2001 08:43:33 +0000 (08:43 +0000)
MANIFEST
Makefile.PL
design/represent.txt
map.c [new file with mode: 0644]

index f55468d0c8ab98cdae2b147d18e5018197e30273..93fda1cf0e4a5fb202028c0de58e304d06a35daf 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -8,6 +8,7 @@ draw.c
 draw.h
 conv.c
 convert.c
+map.c
 error.c
 gaussian.c
 ppport.h
index 855c8af4f3535fdf83e06f494ae4ff6e9d498389..27ac85a708d25e963e76c8e0bc56a0bf9fe5c207 100644 (file)
@@ -61,7 +61,8 @@ if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
 @objs = qw(Imager.o draw.o image.o io.o iolayer.o log.o
           gaussian.o conv.o pnm.o raw.o feat.o font.o
           filters.o dynaload.o stackmach.o datatypes.o
-          regmach.o trans2.o quant.o error.o convert.o);
+          regmach.o trans2.o quant.o error.o convert.o
+          map.o);
 
 %opts=(
        'NAME'         => 'Imager',
index f2610d313873d1a74813433309152ba592a4e6b7..28370d51eebd5cba74a6073366d5f379f805a49b 100644 (file)
@@ -152,7 +152,10 @@ hence we need to support use of integer algorithms where appropriate.
 By preferring access via the functions we can reduce the possibility
 of incorrect access to the image data.
 
-If an image interface function pointer isn't implemented, it should be set to NULL rather than being left uninitialized.  This is so that use of the ununsed pointer results in an immediate crash rather than possibly calling the wrong function and crashing at some later point.
+If an image interface function pointer isn't implemented, it should be
+set to NULL rather than being left uninitialized.  This is so that use 
+of the ununsed pointer results in an immediate crash rather than
+possibly calling the wrong function and crashing at some later point.
 
 In a debug build of Imager the image interface functions should check
 that the correct type of image pointer is being passed in.  This means
diff --git a/map.c b/map.c
new file mode 100644 (file)
index 0000000..0f9bd19
--- /dev/null
+++ b/map.c
@@ -0,0 +1,94 @@
+/*
+=head1 NAME
+
+  map.c - inplace image mapping and related functionality
+
+=head1 SYNOPSIS
+
+  i_map(srcimage, coeffs, outchans, inchans)
+
+=head1 DESCRIPTION
+
+Converts images from one format to another, typically in this case for
+converting from RGBA to greyscale and back.
+
+=over
+
+=cut
+*/
+
+#include "image.h"
+
+
+/*
+=item i_map(im, mapcount, maps, chmasks)
+
+maps im inplace into another image.
+
+  Each map is a unsigned char array of 256 entries, its corresponding
+  channel mask is the same numbered entry in the chmasks array.
+  If two maps apply to the same channel then the second one is used.
+  If no map applies to a channel then that channel is not altered.
+  mapcount is the number of maps.
+
+=cut
+*/
+
+void
+i_map(i_img *im, int mapcount, unsigned char (*maps)[256], unsigned int *chmasks) {
+  i_color *vals;
+  int x, y;
+  int mapno, i, ch;
+  unsigned int mask = 0;
+  unsigned char (**cmaps)[256];
+  int minset = -1, maxset;
+
+  mm_log((1,"i_map(im %p, mapcount %d, maps %p, chmasks %p)\n", im, mapcount, maps, chmasks));
+
+
+  for(mapno=0; mapno<mapcount; mapno++) mask |=chmasks[mapno];
+  if (!mask) return; /* nothing to do here */
+
+
+
+  for(i=0; i<im->channels; i++)
+    if (mask & (1<<i)) {
+      if (minset == -1) minset = i;
+      maxset = i;
+    }
+
+  cmaps = mymalloc(sizeof(unsigned char (*)[256])*im->channels);
+  memset(cmaps, 0, sizeof(unsigned char (*)[256])*im->channels);
+  for(mapno=0; mapno<mapcount; mapno++)
+    for(ch=0; ch<im->channels; ch++) 
+      if (chmasks[i] & (1<<ch)) cmaps[ch] = &maps[mapno];
+  
+  vals = mymalloc(sizeof(i_color) * im->xsize);
+  for (y = 0; y < im->ysize; ++y) {
+    i_glin(im, 0, im->xsize, y, vals);
+    for (x = 0; x < im->xsize; ++x) {
+      int lidx = x * im->channels;
+      for(ch = minset; ch<=maxset; ch++) {
+       if (!cmaps[ch]) continue;
+       vals[lidx].channel[ch] = (*cmaps[ch])[vals[lidx].channel[ch]];
+      }
+    }
+    i_plin(im, 0, im->xsize, y, vals);
+  }
+  myfree(cmaps);
+  myfree(vals);
+}
+
+/*
+=back
+
+=head1 SEE ALSO
+
+Imager(3)
+
+=head1 AUTHOR
+
+Arnar M. Hrafnkelsson <addi@umich.edu>
+
+=cut
+*/