e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
1cbb892011-04-25Martin Stjernholm || $Id$
e576bb2002-10-11Martin Nilsson */
c43fc11999-03-01Henrik Wallin  /* This file is incuded in search.c with the following defines set: NAME The name of the match function. This is undef:ed at end of this file INAME The name of the match c-function. This is nudef:ed at end of this file
12de551999-03-15Henrik Wallin PIXEL_VALUE_DISTANCE The inner loop code for each pixel. undef:ed at end of this file
1826491999-03-21Henrik Wallin NEEDLEAVRCODE If this is set, needle_average is calculated. Not undef:ed at end
c43fc11999-03-01Henrik Wallin NORMCODE code used for normalizing in the haystack. Not undef:ed at end
12de551999-03-15Henrik Wallin SCALE_MODIFY(x) This modifies the output in each pixel
c43fc11999-03-01Henrik Wallin  */ void INAME(INT32 args) { struct object *o;
1826491999-03-21Henrik Wallin  struct image *img,*needle=0, *haystack_cert=0, *haystack_avoid=0, *haystack=0, *needle_cert=0, *this;
c43fc11999-03-01Henrik Wallin  rgb_group *imgi=0, *needlei=0, *haystack_certi=0, *haystack_avoidi=0, *haystacki=0, *needle_certi=0, *thisi=0; int type=0; /* type==1 : (int|float scale, needle) type==2 : (int|float scale, needle, haystack_cert, needle_cert) type==3 : (int|float scale, needle, haystack_avoid, int foo) type==4 : (int|float scale, needle, haystack_cert, needle_cert, haystack_avoid, int foo) */ int xs,ys, y, x; /* for this & img */ int nxs,nys, ny, nx; /* for neddle */ int foo=0;
36a00c2000-08-15Henrik Grubbström (Grubba)  double scale = 1.0;
c43fc11999-03-01Henrik Wallin  int needle_average=0; int needle_size=0;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if (!THIS->img) { Pike_error("no image\n"); return; }
c43fc11999-03-01Henrik Wallin  this=THIS; haystacki=this->img; haystack=this;
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  if (!args) { Pike_error("Missing arguments to image->"NAME"\n"); return; } else if (args<2) { Pike_error("Too few arguments to image->"NAME"\n"); return; }
c43fc11999-03-01Henrik Wallin  else { if (sp[-args].type==T_INT)
ea7a4d2000-08-09Henrik Grubbström (Grubba)  scale = (double)sp[-args].u.integer;
c43fc11999-03-01Henrik Wallin  else if (sp[-args].type==T_FLOAT)
ea7a4d2000-08-09Henrik Grubbström (Grubba)  scale = sp[-args].u.float_number;
c43fc11999-03-01Henrik Wallin  else
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Illegal argument 1 to image->"NAME"\n");
c43fc11999-03-01Henrik Wallin  if ((sp[1-args].type!=T_OBJECT) || !(needle= (struct image*)get_storage(sp[1-args].u.object,image_program)))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Illegal argument 2 to image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  if ((needle->xsize>haystack->xsize)|| (needle->ysize>haystack->ysize))
a4a1722000-12-05Per Hedbor  Pike_error("Haystack must be bigger than needle, error in image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  needlei=needle->img; haystacki=haystack->img; if ((args==2)||(args==3)) type=1; else { if ((sp[2-args].type!=T_OBJECT)|| !(haystack_cert= (struct image*)get_storage(sp[2-args].u.object,image_program)))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Illegal argument 3 to image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  else if ((haystack->xsize!=haystack_cert->xsize)|| (haystack->ysize!=haystack_cert->ysize))
a4a1722000-12-05Per Hedbor  Pike_error("Argument 3 must be the same size as haystack error in image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  if ((sp[3-args].type==T_INT)) { foo=sp[3-args].u.integer; type=3; haystack_avoid=haystack_cert; haystack_cert=0; } else if ((sp[3-args].type!=T_OBJECT)|| !(needle_cert= (struct image*)get_storage(sp[3-args].u.object,image_program)))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Illegal argument 4 to image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  else { if ((needle_cert->xsize!=needle->xsize)|| (needle_cert->ysize!=needle->ysize))
a4a1722000-12-05Per Hedbor  Pike_error("Needle_cert must be the same size as needle error in image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  type=2; } if (args>=6) { if (sp[5-args].type==T_INT) { foo=sp[5-args].u.integer; type=4; } else
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Illegal argument 6 to image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  if ((sp[4-args].type!=T_OBJECT)|| !(haystack_avoid= (struct image*)get_storage(sp[4-args].u.object,image_program)))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Illegal argument 5 to image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  else if ((haystack->xsize!=haystack_avoid->xsize)|| (haystack->ysize!=haystack_avoid->ysize))
a4a1722000-12-05Per Hedbor  Pike_error("Haystack_avoid must be the same size as haystack error in image->"NAME"()\n");
c43fc11999-03-01Henrik Wallin  } } push_int(this->xsize); push_int(this->ysize); o=clone_object(image_program,2); img=(struct image*)get_storage(o,image_program); imgi=img->img; pop_n_elems(args); if (haystack_cert) haystack_certi=haystack_cert->img; if (haystack_avoid) haystack_avoidi=haystack_avoid->img; if (needle_cert) needle_certi=needle_cert->img; THREADS_ALLOW();
12de551999-03-15Henrik Wallin  nxs=needle->xsize; nys=needle->ysize; xs=this->xsize; ys=this->ysize-nys; /* This sets needle_average to something nice :-) */
d0ba6a1999-03-15Henrik Wallin  /* match and match_phase don't use this */
1826491999-03-21Henrik Wallin #ifdef NEEDLEAVRCODE needle_size=nxs*nys; for(x=0; x<needle_size; x++) needle_average+=needlei[x].r+needlei[x].g+needlei[x].b; needle_average=(int)(((float)needle_average)/(3*needle_size)); #define NORMCODE for(ny=0; ny<nys; ny++) \ for(nx=0; nx<nxs; nx++) \ { \ int j=i+ny*xs+nx; \ tempavr+=haystacki[j].r+haystacki[j].g+ \ haystacki[j].b; \ } #else #define NORMCODE #endif #define DOUBLE_LOOP(AVOID_IS_TOO_BIG, CERTI1, CERTI2,R1,G1,B1) \
7ff6501999-03-29Henrik Wallin  for(y=0; y<ys; y++) \ for(x=0; x<xs-nxs; x++) \ { \ int i=y*this->xsize+x; \ int sum=0; \ int tempavr=0;\ if (AVOID_IS_TOO_BIG) \ {\ int k=0; \ imgi[k=i+(nys/2)*xs+(nxs/2)].r=0;\ imgi[k].g=100; imgi[k].b=0;\ }\ else\ {\ NORMCODE;\
ea7a4d2000-08-09Henrik Grubbström (Grubba)  tempavr = DOUBLE_TO_INT(((double)tempavr)/(3*needle_size)); \
7ff6501999-03-29Henrik Wallin  for(ny=0; ny<nys; ny++) \ for(nx=0; nx<nxs; nx++) \
12de551999-03-15Henrik Wallin  { \
7ff6501999-03-29Henrik Wallin  int j=i+ny*xs+nx; \ int h=0;\ int n=0;\
78b0d02002-05-29Per Hedbor  sum+=(MAXIMUM(CERTI1 R1, CERTI1 R1) * PIXEL_VALUE_DISTANCE(r)); \ sum+=(MAXIMUM(CERTI1 G1, CERTI1 G1) * PIXEL_VALUE_DISTANCE(g)); \ sum+=(MAXIMUM(CERTI1 B1, CERTI1 B1) * PIXEL_VALUE_DISTANCE(b)); \
7ff6501999-03-29Henrik Wallin  } \ imgi[i+(nys/2)*xs+(nxs/2)].r=\
ea7a4d2000-08-09Henrik Grubbström (Grubba)  DOUBLE_TO_INT(255.99/(1.0+((((double)scale) * SCALE_MODIFY((double)sum))))); \
7ff6501999-03-29Henrik Wallin  }\ }
12de551999-03-15Henrik Wallin 
1826491999-03-21Henrik Wallin  #define AVOID_IS_TOO_BIG ((haystack_avoidi[i].r)>(foo))
c43fc11999-03-01Henrik Wallin 
12de551999-03-15Henrik Wallin  if (type==1)
941bd21999-06-17Henrik Wallin  DOUBLE_LOOP(0,1,1, *1, *1, *1)
12de551999-03-15Henrik Wallin  else if (type==2)
1826491999-03-21Henrik Wallin  DOUBLE_LOOP(0, haystack_certi[j], needle_certi[ny*nxs+nx],.r,.g,.b)
12de551999-03-15Henrik Wallin  else if (type==3)
941bd21999-06-17Henrik Wallin  DOUBLE_LOOP(AVOID_IS_TOO_BIG,1,1, *1, *1, *1)
12de551999-03-15Henrik Wallin  else if (type==4)
1826491999-03-21Henrik Wallin  DOUBLE_LOOP(AVOID_IS_TOO_BIG, haystack_certi[j], needle_certi[ny*nxs+nx],.r,.g,.b)
12de551999-03-15Henrik Wallin 
1826491999-03-21Henrik Wallin #undef NORMCODE #undef AVOID_IS_TOO_BIG
12de551999-03-15Henrik Wallin #undef PIXEL_VALUE_DISTANCE #undef DOUBLE_LOOP
c43fc11999-03-01Henrik Wallin  THREADS_DISALLOW(); } push_object(o); } #undef NAME #undef INAME