static char *IMFILTER_C="\n#if defined(REGIONS_PTYPE) || defined(__EMSCRIPTEN__) || defined(REGIONS_TEST)\n\n\n#ifdef REGIONS_TEST\n#include <stdio.h>\n#include <math.h>\n#include \"imregions.h\"\n#define REGIONS_PTYPE \"process\"\n#define IMFILTRTN _FilterRegions\n#define NSHAPE 2\n#define FILTER ((imcircle(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0)))&&(imcircle(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0))\n#define FILTSTR \"((imcircle(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0)))&&(imcircle(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0))\"\n#define FINIT imcirclei(g,1,1,1,4,(double)x,(double)y,8.0,8.0,5.0);imcirclei(g,2,2,0,1,(double)x,(double)y,8.0,8.0,3.0);\n#endif\n\n#if __EMSCRIPTEN__\n#include \"regionsP.h\"\n#include \"imregions.h\"\n#include <emscripten.h>\n#ifndef NSHAPE\n#define NSHAPE EM_ASM_INT({return window.Regions.NSHAPE();})\n#endif\n#ifndef FILTSTR\n#define FILTSTR \"\"\n#endif\n#ifndef FINIT\n#define FINIT EM_ASM({window.Regions.FINIT($0,$1,$2);}, g, x, y)\n#endif\n#ifndef FILTER\n#define FILTER EM_ASM_INT({return window.Regions.FILTER($0,$1,$2);}, g, x, y)\n#endif\n#endif\n\n\n#define MASKINC	10240\nstatic RegionsMask masks=NULL;	\nstatic int maxmask;		\nstatic int nmask;		\n\n\nstatic void incnmask(void)\n{\n  int oldmax;\n  if( ++nmask >= maxmask ){\n    oldmax = maxmask;\n    maxmask += MASKINC;\n    masks = (RegionsMask)realloc(masks, maxmask*sizeof(RegionsMaskRec));\n    memset(masks+oldmax, 0, (maxmask-oldmax)*sizeof(RegionsMaskRec));\n  }\n}\n\nRegionsMask IMFILTRTN(int txmin, int txmax, int tymin, int tymax, int tblock,\n		      int *got){\n  int i, j;\n  int rlen;\n  int nreg;\n  int nshape;\n  int filter;\n  int fieldonly;\n  int x=0, y=0;\n  int *rbuf;\n  int *rptr;\n  char *filtstr=NULL;\n  GReg g;\n  Scan scan, tscan;\n\n  \n  nshape = NSHAPE;\n  filtstr = FILTSTR;\n  \n  nmask = 0;\n  if( nshape <=0 ){\n    if( got ){\n      *got = 0;\n    }\n    return NULL;\n  }\n  \n  fieldonly = (nshape==1) && strstr(filtstr, \"field\");\n  \n  g = (GReg)calloc(1, sizeof(GRegRec));\n  \n  g->nshape = nshape;\n  g->maxshape = (nshape*(XSNO+1))+1;\n  g->shapes = (Shape)calloc(g->maxshape, sizeof(ShapeRec));\n  \n  g->block= max(1,tblock);\n  g->xmin = max(1,txmin); \n  g->xmax = txmax;\n  g->ymin = max(1,tymin);\n  g->ymax = tymax;\n  \n  g->x0 = 1;\n  g->y0 = 1;\n  g->x1 = (g->xmax-g->xmin)/g->block+1;\n  g->y1 = (g->ymax-g->ymin)/g->block+1;\n  \n  rlen = g->x1 - g->x0 + 1;\n  rbuf = (int *)calloc(rlen+1, sizeof(int));\n  \n  maxmask = MASKINC;\n  masks = (RegionsMask)calloc(maxmask, sizeof(RegionsMaskRec));\n  masks[nmask].region = 0;\n  \n  nreg = 0;\n  \n  g->ybuf = (int *)calloc(g->y1+1, sizeof(int));\n  g->x0s = (int *)calloc(g->y1+1, sizeof(int));\n  g->x1s = (int *)calloc(g->y1+1, sizeof(int));\n  \n  for(i=0; i<=g->y1; i++){\n    g->x0s[i]  = g->x1;\n  }\n  for(i=0; i<=g->y1; i++){\n    g->x1s[i]  = g->x0;\n  }\n  \n  FINIT;\n  \n  for(y=g->y0; y<=g->y1; y++){\n    if( fieldonly ){\n      \n      masks[nmask].region = 1;\n      masks[nmask].y = y - g->y0 + 1;\n      masks[nmask].xstart = 1;\n      masks[nmask].xstop = (g->x1 - g->x0 + 1);\n      incnmask();\n      continue;\n    }\n    if( g->ybuf[y] ){\n      \n      if( masks[nmask].region ){\n	\n	incnmask();\n	masks[nmask].region = 0;\n      }\n      \n      for(x=g->x0s[y], rptr=&rbuf[1+(g->x0s[y]-g->x0)]; x<=g->x1s[y];\n	  x++, rptr++){\n	\n	g->rid = 0;\n	filter = FILTER;\n	if( filter ){\n	  \n	  if( *rptr == 0 ){\n	    nreg++;\n	    *rptr = g->rid ? g->rid : -1;\n	  }\n	  \n	  else if( (*rptr == -1) && (g->rid >0) ){\n	    *rptr = g->rid;\n	  }\n	}\n      }\n    }\n    \n    if( nreg ){\n      for(i=1; i<=rlen; i++){\n	if( rbuf[i] != masks[nmask].region ){\n	  \n	  if( masks[nmask].region ){\n	    masks[nmask].xstop = i - 1;\n	    \n	    incnmask();\n	  }\n	  masks[nmask].y = y - g->y0 + 1;\n	  masks[nmask].region = rbuf[i];\n	  masks[nmask].xstart = i;\n	}\n      }\n      \n      if( masks[nmask].region ){\n	masks[nmask].xstop = (g->x1 - g->x0 + 1);\n	\n	incnmask();\n      }\n      \n      (void)memset(rbuf, 0, (rlen+1)*sizeof(int));\n      rptr = rbuf;\n      nreg = 0;\n    }\n  }\n  \n  if( rbuf) free(rbuf);\n  \n  if( g ){\n    for(i=0; i<g->maxshape; i++){\n      if( g->shapes[i].scanlist ){\n	for(j=0; j<=g->y1; j++){\n	  if( g->shapes[i].scanlist[j] ){\n	    for(scan=g->shapes[i].scanlist[j]; scan; ){\n	      tscan = scan->next;\n	      free(scan);\n	      scan = tscan;\n	    }\n	  }\n	}\n	free(g->shapes[i].scanlist);\n      }\n      if( g->shapes[i].pts ) free(g->shapes[i].pts);\n      if( g->shapes[i].xv ) free(g->shapes[i].xv);\n    }\n    if( g->shapes ) free(g->shapes);\n    if( g->ybuf )   free(g->ybuf);\n    if( g->x0s )    free(g->x0s);\n    if( g->x1s )    free(g->x1s);\n    if( g )         free(g);\n  }\n  \n  if( got ){\n    *got = nmask;\n  }\n  return masks;\n}\n\n\n#if defined(REGIONS_PTYPE)\n\n\nint main(int argc, char **argv)\n{\n  int i, txmin, txmax, tymin, tymax, tblock;\n  char tbuf[SZ_LINE];\n  char *s=NULL, *t=NULL, *u=NULL;\n#ifndef REGIONS_TEST\n  int get, obytes;\n#endif\n#ifndef __MINGW32__\n  int pipes[4];\n#endif\n#ifdef _WIN32\n  HANDLE hStdin, hStdout; \n  DWORD dwRead, dwWritten; \n#endif\n\n  \n#ifndef __MINGW32__\n  if( (s=getenv(\"LAUNCH_PIPES\")) ){\n    t = (char *)strdup(s);\n    for(i=0, u=(char *)strtok(t, \",\"); i<4 && u; \n	i++, u=(char *)strtok(NULL,\",\")){\n      pipes[i] = atoi(u);\n    }\n    if( t ) free(t);\n    if( i < 4 ) return(1);\n    close(pipes[0]);\n    close(pipes[3]);\n    dup2(pipes[2], 0);  close(pipes[2]);\n    dup2(pipes[1], 1);  close(pipes[1]);\n  }\n#endif\n#ifdef _WIN32\n  hStdout = GetStdHandle(STD_OUTPUT_HANDLE); \n  hStdin = GetStdHandle(STD_INPUT_HANDLE); \n  if( (hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE) ){\n    unlink(argv[0]);\n    return 0;\n  }\n#endif\n#ifdef REGIONS_TEST\n  \n  while( fgets(tbuf, SZ_LINE, stdin) ){\n#else  \n#ifdef _WIN32\n  \n  while((ReadFile(hStdin, &get, sizeof(int), &dwRead, NULL) != FALSE) && \n	(dwRead == sizeof(int)) ){\n    if((ReadFile(hStdin, tbuf, get, &dwRead, NULL)==FALSE) || (dwRead != get)){\n      break;\n    }\n#else\n  \n  while( read(0, &get, sizeof(int)) == sizeof(int) ){\n    if(read(0, tbuf, get) != get){\n      break;\n    }\n#endif\n#endif \n    \n    if( sscanf(tbuf, \"%d %d %d %d %d\",\n	       &txmin, &txmax, &tymin, &tymax, &tblock) != 5 ){\n      break;\n    }\n    \n    IMFILTRTN(txmin, txmax, tymin, tymax, tblock, NULL);\n#ifdef REGIONS_TEST\n    \n    fprintf(stdout, \"nmask=%d\\n\", nmask);\n    for(i=0; i<nmask; i++){\n      fprintf(stdout, \"region: %d\tx: (%d,%d)\ty: %d\\n\",\n	      masks[i].region, masks[i].xstart, masks[i].xstop, masks[i].y);\n    }\n    fflush(stdout);\n#else \n    \n    obytes =  nmask * sizeof(RegionsMaskRec);\n#ifdef _WIN32\n    \n    WriteFile(hStdout, &obytes, sizeof(int), &dwWritten, NULL); \n    WriteFile(hStdout, masks, obytes, &dwWritten, NULL); \n#else\n    \n    write(1, &obytes, sizeof(int));\n    write(1, masks, obytes);\n#endif\n#endif \n    \n    if( masks ){\n      free(masks);\n    }\n  }\n#ifndef REGIONS_TEST\n  unlink(argv[0]);\n#endif \n  return 0;\n}\n\nint has_imfilter = 1;\n\n#endif\n\n#else\nint has_imfilter = 0;\n\n#endif\n";
