/* $Id: Point2.c,v 1.2 2001/08/22 10:16:48 dk Exp $ */ #include "IPAsupp.h" #include "Point.h" #include "PointSupp.h" static SV **temporary_prf_Sv; #undef METHOD #define METHOD "IPA::Point::mask" static PImage constant( int w, int h, int type, I32 vv) { PImage r = createNamedImage( w, h, type, "(temporary)"); U8 *line; int y; if (!r) croak( "%s: error creating temporary image", METHOD); line = r-> data; switch ( type) { case imByte: memset( line, (U8)vv, w); break; case imShort: { I16 v = (I16)vv; I16 *l = (I16*)line; while (w--) *l++ = v; } break; case imLong: { I32 *l = (I32*)line; while (w--) *l++ = vv; } break; } for ( y = 1; y < h; y++) memcpy( r-> data + r-> lineSize*y, line, r-> lineSize); return r; } PImage IPA__Point_mask( PImage mask, HV *profile) { PImage ifMatch = nil; PImage ifNoMatch = nil; PImage itest = nil; PImage o; I32 test = 0; I32 match = 0; I32 nomatch = 255; U8 *src, *dst; U8 *nnn, *mmm, *ttt; int y, sz, w, h; Bool freeMatch = false; Bool freeNoMatch = false; Bool freeTest = false; if ( !mask || !kind_of(( Handle) mask, CImage)) croak("%s: not an image passed", METHOD); switch ( mask-> type) { case imByte: sz = sizeof(U8); break; case imShort: sz = sizeof(I16); break; case imLong: sz = sizeof(I32); break; default: croak( "%s: mask image should have integer grayscale type", METHOD); } if ( profile) { SV *dummy; char *key; I32 l; hv_iterinit( profile); for (;;) { dummy = hv_iternextsv( profile, &key, &l); if ( key == nil || dummy == nil) break; if ( strcmp( key, "test") != 0 && strcmp( key, "match") != 0 && strcmp( key, "mismatch") != 0 && strncmp( key, "__", 2) != 0) croak( "%s: illegal option ``%s'' passed", METHOD, key); } } if ( profile && pexist(test)) { SV *sv = pget_sv(test); if (sv && SvROK(sv)) itest = (PImage)pget_H(test); else test = pget_i(test); } if ( profile && pexist(match)) { SV *sv = pget_sv(match); if (sv && SvROK(sv)) ifMatch = (PImage)pget_H(match); else match = pget_i(match); } if ( profile && pexist(mismatch)) { SV *sv = pget_sv(mismatch); if (sv && SvROK(sv)) ifNoMatch = (PImage)pget_H(mismatch); else nomatch = pget_i(mismatch); } if (ifMatch && (!kind_of((Handle)ifMatch,CImage) || ifMatch-> w != mask-> w || ifMatch-> h != mask-> h || ifMatch-> type != mask-> type)) croak( "%s: illegal ``ifMatch'' image passed", METHOD); if (itest && (!kind_of((Handle)itest,CImage) || itest-> w != mask-> w || itest-> h != mask-> h || itest-> type != mask-> type)) croak( "%s: illegal ``test'' image passed", METHOD); if (ifNoMatch && (!kind_of((Handle)ifNoMatch,CImage) || ifNoMatch-> w != mask-> w || ifNoMatch-> h != mask-> h || ifNoMatch-> type != mask-> type)) croak( "%s: illegal ``ifNoMatch'' image passed", METHOD); o = createNamedImage( mask-> w, mask-> h, mask-> type, METHOD); if (!o) croak( "%s: error creating output image", METHOD); w = mask-> w; h = mask-> h; if ( !itest) { freeTest = true; itest = constant( w, h, mask-> type, test); } if ( !ifMatch) { freeMatch = true; ifMatch = constant( w, h, mask-> type, match); } if ( !ifNoMatch) { freeNoMatch = true; ifNoMatch = constant( w, h, mask-> type, nomatch); } src = mask-> data; dst = o-> data; #define DOMASKING(TYP) \ { \ TYP *m, *n, *t, *s, *d, *stop; \ mmm = ifMatch-> data; \ nnn = ifNoMatch-> data; \ ttt = itest-> data; \ for ( y = 0; y < mask-> h; y++) { \ s = (TYP*)src; d = (TYP*)dst; stop = s + w; \ m = (TYP*)mmm; n = (TYP*)nnn; t = (TYP*)ttt; \ while ( s != stop) { \ *d = *s == *t ? *m : *n; \ m++; n++; s++; t++; d++; \ } \ src += mask-> lineSize; \ dst += o-> lineSize; \ mmm += ifMatch-> lineSize; \ nnn += ifNoMatch-> lineSize; \ ttt += itest-> lineSize; \ } \ } switch ( mask-> type) { case imByte: DOMASKING(U8); break; case imShort: DOMASKING(I16); break; case imLong: DOMASKING(I32); break; } #undef DOMASKING if ( freeTest) destroyImage( itest); if ( freeMatch) destroyImage( ifMatch); if ( freeNoMatch) destroyImage( ifNoMatch); return o; }