Exemple #1
0
int             main(int argc, char **argv)
{
  int		option,
		ok = 1,
		usage = 0;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  FILE		*fP = NULL;
  WlzObject	*oObj = NULL;
  WlzObject	*iObj[2];
  char 		*oObjFileStr;
  char  	*iObjFileStr[2];
  const char	*errMsg;
  static char	optList[] = "o:h",
		fileStrDef[] = "-";

  opterr = 0;
  iObj[0] = NULL;
  iObj[1] = NULL;
  oObjFileStr = fileStrDef;
  iObjFileStr[0] = fileStrDef;
  iObjFileStr[1] = fileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
	oObjFileStr = optarg;
	break;
      case 'h':
      default:
	usage = 1;
	break;
    }
  }
  if((iObjFileStr[0] == NULL) || (*iObjFileStr[0] == '\0') ||
     (iObjFileStr[1] == NULL) || (*iObjFileStr[1] == '\0') ||
     (oObjFileStr == NULL) || (*oObjFileStr == '\0'))
  {
    usage = 1;
  }
  if((usage == 0) && (optind < argc))
  {
    int 	i;

    i = 0;
    while((i < 2) && (optind < argc))
    {
      iObjFileStr[i] = *(argv + optind);
      ++optind;
      ++i;
    }
  }
  if((usage == 0) && (optind != argc))
  {
    usage = 1;
  }
  ok = !usage;
  if(ok)
  {
    int		i;

    i = 0;
    while((errNum == WLZ_ERR_NONE) && (i < 2))
    {
      errNum = WLZ_ERR_READ_EOF;
      if((iObjFileStr[i] == NULL) ||
	  (*iObjFileStr[i] == '\0') ||
	  ((fP = (strcmp(iObjFileStr[i], "-")?
		  fopen(iObjFileStr[i], "r"): stdin)) == NULL) ||
	  ((iObj[i]= WlzAssignObject(WlzReadObj(fP,
	  					   &errNum), NULL)) == NULL))
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: Failed to read object %d from file %s (%s).\n",
		       *argv, i, iObjFileStr[i], errMsg);
      }
      if(fP && strcmp(iObjFileStr[i], "-"))
      {
	fclose(fP);
      }
      ++i;
    }
  }
  if(ok)
  {
    oObj = WlzXORDom(iObj[0], iObj[1], &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: Failed to compute set xor object (%s).\n",
		     *argv, errMsg);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if(((fP = (strcmp(oObjFileStr, "-")? fopen(oObjFileStr, "w"):
	      				 stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, oObj)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: Failed to write output object (%s).\n",
		     *argv, errMsg);
    }
    if(fP && strcmp(oObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  WlzFreeObj(iObj[0]);
  WlzFreeObj(iObj[1]);
  WlzFreeObj(oObj);
  if(usage)
  {

    (void )fprintf(stderr,
	"Usage: %s"
	" [-o <out file>] [-h] [<in file 0>] [<in file 1>]\n"
	"Version: %s\n"
	"Options:\n"
	"  -o        Output file name.\n"
	"  -h        Help, prints this usage message.\n"
	"Computes the set exclusive or of the two given objects.\n"
	"The input objects are read from stdin and values are written\n"
	"to stdout unless the filenames are given.\n"
	"Example:\n%s -o out.wlz in0.wlz in1.wlz\n"
	"The exclusive of the the domains objects read from in0.wlz\n"
	"and in1.wlz is computed and written to out.wlz\n",
	*argv,
	WlzVersion(),
	*argv);
  }
  return(!ok);
}
Exemple #2
0
/*! 
* \ingroup      WlzValuesFilters
* \brief        Gaussian filter of grey-level 2D woolz object. x- and
 y-coordinate width parameters and derivative degree can be independently
 specified. For derivative zero, i.e. Gaussian smoothing, the filter is
 normalised. Derivatives are derivative of the normalised filter. RGB
 data will only return values for smoothing, higher derivatives are not
 implemented. The width parameter is the full-width half-height of the
 Gaussian distribution. Note RGB pixel types are converted to a compound 
 object with each channel returned with WLZ_GREY_SHORT pixel type.
*
* \return       Pointer to transformed object
* \param    obj	Input object
* \param    wx	x-direction width parameter
* \param    wy	y-direction width parameter
* \param    x_deriv	x-direction derivative
* \param    y_deriv	y-direction derivative
* \param    wlzErr	error return
* \par      Source:
*                WlzGauss.c
*/
WlzObject *WlzGauss2(
  WlzObject	*obj,
  double	wx,
  double	wy,
  int		x_deriv,
  int		y_deriv,
  WlzErrorNum	*wlzErr)
{
  WlzObject		*newobj=NULL;
  Wlz1DConvMask		x_params, y_params;
  float 		alpha, sum;
  int 			i, n, value;
  WlzErrorNum		errNum=WLZ_ERR_NONE;
    
  /* check object, don't need to check type etc. because WlzSepTrans
     does it */
  if( obj == NULL )
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* do need to check for rgb grey type */
  if( errNum == WLZ_ERR_NONE ){
    if( (obj->type == WLZ_2D_DOMAINOBJ) &&
        (WlzGreyTypeFromObj(obj, &errNum) == WLZ_GREY_RGBA) ){
      if( (x_deriv != 0) || (y_deriv != 0) ){
	/* implement this using a compond object since the
	   result should be a vector value */
	WlzCompoundArray *cobj;

	if((cobj = WlzRGBAToCompound(obj, WLZ_RGBA_SPACE_RGB,
	                             &errNum)) != NULL){
	  /* need to convert each to short for gradient calc */
	  for(i=0; i < 3; i++){
	    WlzObject *tmpObj;
	    tmpObj = cobj->o[i];
	    cobj->o[i] = WlzAssignObject(WlzConvertPix(tmpObj,
						       WLZ_GREY_SHORT,
						       &errNum), NULL);
	    WlzFreeObj(tmpObj);
	  }
	  newobj = WlzGauss2((WlzObject *) cobj, wx, wy, x_deriv, y_deriv,
			     &errNum);
	  WlzFreeObj((WlzObject *) cobj);
	  if( wlzErr ){
	    *wlzErr = errNum;
	  }
	  return newobj;
	}
      }
    }
  }

  /* now start work */
  if( errNum == WLZ_ERR_NONE ){
    alpha = (float )(4.0 * log((double )2.0));
    
    /* set up x function parameters */
    x_params.mask_size = (((int) wx * 4)/2)*2 + 1;
    if( (x_params.mask_values = (int *)
	 AlcMalloc(sizeof(int) * x_params.mask_size)) == NULL){
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else {
      n = x_params.mask_size / 2;
    
      switch( x_deriv ){

      case 0:
	for(i=0, sum = -AFACTOR; i <= n; i++){
	  value = (int )(AFACTOR * exp(((double) -alpha*i*i/wx/wx)));
	  *(x_params.mask_values+n-i) = value;
	  *(x_params.mask_values+n+i) = value;
	  sum += 2 * value;
	}
	x_params.norm_factor = sum;
	break;

      case 1:
	*(x_params.mask_values+n) = 0.0;
	for(i=1, sum = 0; i <= n; i++){
	  value = (int )(AFACTOR * i * exp(((double) -alpha*i*i/wx/wx)));
	  *(x_params.mask_values+n-i) = value;
	  *(x_params.mask_values+n+i) = -value;
	  sum += value;
	}
	/* sum *= -wx / 2 / sqrt( log( (double) 2 ) / WLZ_M_PI );*/
	if( n > 0 )
	  x_params.norm_factor = sum;
	else
	  x_params.norm_factor = 1;
	break;

      case 2:
	for(i=0; i <= n; i++){
	  value = (int )(AFACTOR * (alpha * i*i / wx/wx -1) *
	                 exp(((double) -alpha*i*i/wx/wx)));
	  *(x_params.mask_values+n-i) = value;
	  *(x_params.mask_values+n+i) = value;
	}
	x_params.norm_factor = (int )(*(x_params.mask_values+n) * wx*wx*wx /
	                              4 / alpha / sqrt(log((double )2) /
				      WLZ_M_PI ));
	break;

      default:
	AlcFree((void *) x_params.mask_values);
	x_params.mask_values = NULL;
	errNum = WLZ_ERR_PARAM_DATA;
	break;
      }
    }
  }
    
  /* set up y function parameters */
  if( errNum == WLZ_ERR_NONE ){
    y_params.mask_size = (((int) wy * 4)/2)*2 + 1;
    if( (y_params.mask_values = (int *)
	 AlcMalloc(sizeof(int) * y_params.mask_size)) == NULL){
      AlcFree((void *) x_params.mask_values);
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else {
      n = y_params.mask_size / 2;
    
      switch( y_deriv ){

      case 0:
	for(i=0, sum = -AFACTOR; i <= n; i++){
	  value = (int )(AFACTOR * exp(((double) -alpha*i*i/wy/wy)));
	  *(y_params.mask_values+n-i) = value;
	  *(y_params.mask_values+n+i) = value;
	  sum += 2 * value;
	}
	y_params.norm_factor = sum;
	break;

      case 1:
	*(y_params.mask_values+n) = 0.0;
	for(i=1, sum = 0; i <= n; i++){
	  value = (int )(AFACTOR * i * exp(((double) -alpha*i*i/wy/wy)));
	  *(y_params.mask_values+n-i) = value;
	  *(y_params.mask_values+n+i) = -value;
	  sum += value;
	}
	/* sum *= -wy / 2 / sqrt( log( (double) 2 ) /WLZ_M_PI );*/
	if( n > 0 )
	  y_params.norm_factor = sum;
	else
	  y_params.norm_factor = 1;
	break;

      case 2:
	for(i=0; i <= n; i++){
	  value = (int )(AFACTOR * (alpha * i*i / wy/wy -1) *
	                 exp(((double) -alpha*i*i/wy/wy)));
	  *(y_params.mask_values+n-i) = value;
	  *(y_params.mask_values+n+i) = value;
	}
	y_params.norm_factor = (int )(*(y_params.mask_values+n) * wy*wy*wy / 4 / alpha
	  / sqrt( log( (double) 2 ) / WLZ_M_PI ));
	break;

      default:
	AlcFree((void *) x_params.mask_values);
	AlcFree((void *) y_params.mask_values);
	x_params.mask_values = NULL;
	y_params.mask_values = NULL;
	errNum = WLZ_ERR_PARAM_DATA;
	break;
      }
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    newobj = WlzSepTrans(obj,
			 Wlz1DConv, (void *) &x_params,
			 Wlz1DConv, (void *) &y_params,
			 &errNum);
    AlcFree((void *) x_params.mask_values);
    AlcFree((void *) y_params.mask_values);
  }

  if( wlzErr )
  {
    *wlzErr = errNum;
  }
  return(newobj);
}
int             main(int argc, char **argv)
{
  int		idx,
  		option,
		asciiFlag = 0,
		nBins = 0,
		ok = 1,
		usage = 0;
  double	binOrigin = 0.0,
  		binSize = 1.0;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  FILE		*fP = NULL;
  WlzHistogramDomain *histDom;
  WlzObject	*inObj = NULL,
		*outObj = NULL;
  const char	*errMsg;
  char 		*outObjFileStr,
  		*inObjFileStr;
  static char	optList[] = "o:n:s:w:ah",
		outObjFileStrDef[] = "-",
  		inObjFileStrDef[] = "-";

  opterr = 0;
  outObjFileStr = outObjFileStrDef;
  inObjFileStr = inObjFileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'a':
        asciiFlag = 1;
	break;
      case 'o':
        outObjFileStr = optarg;
	break;
      case 'n':
	if(sscanf(optarg, "%d", &nBins) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 's':
	if(sscanf(optarg, "%lg", &binOrigin) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'w':
	if(sscanf(optarg, "%lg", &binSize) != 1)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'h':
      default:
        usage = 1;
	ok = 0;
	break;
    }
  }
  if((inObjFileStr == NULL) || (*inObjFileStr == '\0') ||
     (outObjFileStr == NULL) || (*outObjFileStr == '\0'))
  {
    ok = 0;
    usage = 1;
  }
  if(ok && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
      ok = 0;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_READ_EOF;
    if((inObjFileStr == NULL) ||
       (*inObjFileStr == '\0') ||
       ((fP = (strcmp(inObjFileStr, "-")?
	      fopen(inObjFileStr, "r"): stdin)) == NULL) ||
       ((inObj= WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to read object from file %s (%s)\n",
		     *argv, inObjFileStr, errMsg);
    }
    if(fP && strcmp(inObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  if(ok)
  {
    if(((outObj = WlzHistogramObj(inObj, nBins, binOrigin,
    				  binSize, &errNum)) == NULL) ||
       (errNum != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: failed to compute histogram object (%s)\n",
		     *argv,
		     WlzStringFromErrorNum(errNum, NULL));
    }
  }
  if(ok)
  {
    if(asciiFlag)
    {
      if((fP = (strcmp(outObjFileStr, "-")?
               fopen(outObjFileStr, "w"): stdout)) == NULL)
      {
        ok = 0;
	(void )fprintf(stderr,
		       "%s: failed to write output data\n",
		       *argv);
      }
      else
      {
	histDom = outObj->domain.hist;
	switch(histDom->type)
	{
	  case WLZ_HISTOGRAMDOMAIN_INT:
	    for(idx = 0; idx < histDom->nBins; ++idx)
	    {
	      fprintf(fP, "%8g %8d\n",
		      histDom->origin + (idx * histDom->binSize),
		      *(histDom->binValues.inp + idx));
	    }
	    break;
	  case WLZ_HISTOGRAMDOMAIN_FLOAT:
	    for(idx = 0; idx < histDom->nBins; ++idx)
	    {
	      fprintf(fP, "%8g %8g\n",
		      histDom->origin + (idx * histDom->binSize),
		      *(histDom->binValues.dbp + idx));
	    }
	    break;
	  default:
	    break;
	}
      }
    }
    else
    {
      errNum = WLZ_ERR_WRITE_EOF;
      if(((fP = (strcmp(outObjFileStr, "-")?
		fopen(outObjFileStr, "w"):
		stdout)) == NULL) ||
	 ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: failed to write output object (%s)\n",
		       *argv, errMsg);
      }
    }
    if(fP && strcmp(outObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  if(inObj)
  {
    WlzFreeObj(inObj);
  }
  if(outObj)
  {
    WlzFreeObj(outObj);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample 1: %s%sExample 2: %s%s",
    *argv,
    " [-h] [-a] [-o<out file>] [-n#] [-s#] [-w#] [<in object>]\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -a  Output the histogram as ascii data not a Woolz histogram object.\n"
    "  -o  Output object/data file name.\n"
    "  -n  Number of histogram bins.\n"
    "  -s  Start value, lower limit of histogram.\n"
    "  -w  Histogram bin width.\n"
    "  -h  Help, prints this usage message.\n"
    "Computes a Woolz histogram object from the input Woolz object.\n"
    "Objects/data are read from stdin and written to stdout unless the\n"
    "filenames are given.\n",
    *argv,
    " -a myobj.wlz | xgraph\n"
    "The input Woolz object is read from myobj.wlz, a histogram is\n"
    "computed and written as ascii data for display by the program xgraph.\n",
    *argv,
    " -o myHist.wlz myobj.wlz\n"
    "The input Woolz object is read from myobj.wlz, a histogram is computed\n"
    "and written as a Woolz histogram object to the file myHist.wlz\n");
  }
  return(!ok);
}
int WlzEdgeVerticesPoly(
  WlzPolygonDomain	*poly,
  WlzDVertex3		**vtxs,
  int			numVtxs,
  WlzErrorNum		*dstErr)
{
  int		nVtxs=0;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*polyObj;
  int		i;

  /* convert to an 8-connected polyline */
  if( poly ){
    if((polyObj = WlzPolyTo8Polygon(poly, 1, &errNum)) != NULL){
      nVtxs = polyObj->domain.poly->nvertices;
      if( numVtxs > 0 ){
	*vtxs = AlcRealloc(*vtxs, sizeof(WlzDVertex3)*
			   (numVtxs + nVtxs));
      }
      else {
	numVtxs = 0;
	*vtxs = AlcMalloc(sizeof(WlzDVertex3)*nVtxs);
      }
      switch( polyObj->domain.poly->type ){
      case WLZ_POLYGON_INT:
	for(i=0; i < nVtxs; i++){
	  (*vtxs)[numVtxs+i].vtX = polyObj->domain.poly->vtx[i].vtX;
	  (*vtxs)[numVtxs+i].vtY = polyObj->domain.poly->vtx[i].vtY;
	  (*vtxs)[numVtxs+i].vtZ = 0.0;
	}
	break;

      case WLZ_POLYGON_FLOAT:
	for(i=0; i < nVtxs; i++){
	  (*vtxs)[numVtxs+i].vtX =
	    ((WlzFVertex2 *) polyObj->domain.poly->vtx)[i].vtX;
	  (*vtxs)[numVtxs+i].vtY =
	    ((WlzFVertex2 *) polyObj->domain.poly->vtx)[i].vtY;
	  (*vtxs)[numVtxs+i].vtZ = 0.0;
	}
	break;

      case WLZ_POLYGON_DOUBLE:
	for(i=0; i < nVtxs; i++){
	  (*vtxs)[numVtxs+i].vtX =
	    ((WlzDVertex2 *) polyObj->domain.poly->vtx)[i].vtX;
	  (*vtxs)[numVtxs+i].vtY =
	    ((WlzDVertex2 *) polyObj->domain.poly->vtx)[i].vtY;
	  (*vtxs)[numVtxs+i].vtZ = 0.0;
	}
	break;
      default:
	errNum = WLZ_ERR_POLYGON_TYPE;
        break;
      }
      WlzFreeObj(polyObj);
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  nVtxs += numVtxs;
  return nVtxs;
}
Exemple #5
0
int             main(int argc, char **argv)
{
  int		option,
  		ok = 1,
		usage = 0;
  FILE		*fP = NULL;
  char 		*inObjFileStr,
  		*outFileStr;
  WlzObject     *inObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsg;
  static char	optList[] = "ho:",
  		fileStrDef[] = "-";

  opterr = 0;
  inObjFileStr = fileStrDef;
  outFileStr = fileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
        outFileStr = optarg;
	break;
      case 'h': /* FALLTHROUGH */
      default:
        usage = 1;
	break;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  ok = (usage == 0);
  if(ok)
  {
    if((inObjFileStr == NULL) ||
	(*inObjFileStr == '\0') ||
	((fP = (strcmp(inObjFileStr, "-")?
	       fopen(inObjFileStr, "r"): stdin)) == NULL) ||
	((inObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) ||
	(errNum != WLZ_ERR_NONE))
    {
      ok = 0;
    }
    if(fP)
    {
      if(strcmp(inObjFileStr, "-"))
      {
	(void )fclose(fP);
      }
      fP = NULL;
    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if((fP = (strcmp(outFileStr, "-")?
              fopen(outFileStr, "w"): stdout)) == NULL)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to open output file %s (%s).\n",
		     *argv, outFileStr, errMsg);
    }
    else
    {
      switch(inObj->type)
      {
        case WLZ_CMESH_2D:  /* FALLTHROUGH */
	case WLZ_CMESH_2D5: /* FALLTHROUGH */
	case WLZ_CMESH_3D:
	  errNum = WlzBoundaryVerticesCMesh(fP, inObj);
	  break;
        default:
	  errNum = WLZ_ERR_OBJECT_TYPE;
	  break;
      }
      if(errNum != WLZ_ERR_NONE)
      {
        ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s: Failed to output boundary vertices (%s).\n",
		       *argv, errMsg);
      }
    }
    if(fP && strcmp(outFileStr, "-"))
    {
      (void )fclose(fP);
    }
  }
  (void )WlzFreeObj(inObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample: %s%s",
    *argv,
    " [-h] [-o<output file>] [<input object>]\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -h  Help, prints usage message.\n"
    "  -o  Output file.\n"
    "Given an object that is represented by connected vertices (eg a mesh)\n"
    "this filter outputs the coordinates of the vertices that are on\n"
    "the boundary of the object.\n"
    "By default the input object if read from the standard input and the\n"
    "vertices are written to the standard output.\n",
    *argv,
    " -o out.num in.wlz\n"
    "The boundary vertices of the object read from the file in.wlz are\n"
    "written to the file out.num as white space seperated acsii text.\n");
  }
  return(!ok);
}
Exemple #6
0
void HGU_XmImageViewReadImageFromParamsCb(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data)
{
    HGU_XmImageViewDataStruct
    *data=(HGU_XmImageViewDataStruct *) client_data;
    int			intType;
    String		strBuf;
    FILE			*fp;
    WlzObject		*obj=NULL;

    /* check image file, read image */
    if( data->file == NULL ) {
        /* report error */
        return;
    }

    switch( data->type ) {
    case WLZEFF_FORMAT_WLZ:
    case WLZEFF_FORMAT_PNM:
    case WLZEFF_FORMAT_BMP:
    case WLZEFF_FORMAT_TIFF:
        obj = WlzAssignObject(WlzEffReadObj(NULL, data->file,
                                            data->type, 0, 0, 0, NULL), NULL);
        break;

    case WLZEFF_FORMAT_RAW:
        strBuf = AlcMalloc(sizeof(char) *
                           (strlen(data->file) + 48));
        switch( data->depth ) {
        default:
        case 8:
            intType = 3;
            break;
        case 12:
            intType = 2;
            break;
        case 16:
            intType = 7;
            break;
        case 32:
            intType = 1;
            break;
        }
        sprintf(strBuf, "WlzRawToWlz -%s %d %d %d %s", data->byteOrder?"b":"l",
                data->width, data->height, intType, data->file);
        if( (fp = popen(strBuf, "r")) ) {
            obj = WlzAssignObject(WlzEffReadObj(fp, NULL,
                                                WLZEFF_FORMAT_WLZ, 0, 0, 0, NULL), NULL);
            pclose(fp);
        }
        AlcFree(strBuf);
        break;

    default:
        /* report error */
        return;
    }

    if( obj == NULL ) {
        HGU_XmUserError(data->canvas,
                        "Failed to read the image, please\n"
                        "check the file, permissions and the\n"
                        "image format and try again.\n",
                        XmDIALOG_FULL_APPLICATION_MODAL);
        return;
    }
    if( obj->type != WLZ_2D_DOMAINOBJ ) {
        WlzFreeObj(obj);
        return;
    }

    /* install the object */
    HGU_XmImageViewInstallImage(obj, data);
    WlzFreeObj(obj);

    return;
}
Exemple #7
0
/*!
* \return	New 3D object.
* \ingroup	WlzAllocation
* \brief	Constructs a 3D domain object from 2D domain objects read
*		from the given files. Each file is read in turn and added
*		to the 3D object. An empty plane can be specified by
*		setting the file string to NULL. Either all or none of
*		the 2D objects must have values. When the 2D objects
*		have values then the background value of the first 2D
*		object is set to be the background value of the 3D object.
* \param	nFileStr		Number of file strings.
* \param	fileStr			File strings.
* \param	plane1			The plane coordinate of the first
*					2D object.
* \param	xSz			Column voxel size.
* \param	ySz			Line voxel size.
* \param	zSz			Plane voxel size.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzConstruct3DObjFromFile(int nFileStr, char **fileStr,
					  int plane1,
					  float xSz, float ySz, float zSz,
					  WlzErrorNum *dstErr)
{
  int		idx,
  		lastpl;
  WlzDomain	dom3D;
  WlzValues	val3D;
  WlzObject	*obj2D,
  		*obj3D = NULL;
  WlzPixelV	bgd;
  FILE		*fP = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  dom3D.core = NULL;
  val3D.core = NULL;
  lastpl = plane1 + nFileStr - 1;
  if((nFileStr <= 0) || (fileStr == NULL) || (*fileStr == NULL))
  {
    errNum = WLZ_ERR_PARAM_NULL;
  }
  else
  {
    if((fP = fopen(*fileStr, "r")) == NULL)
    {
      errNum = WLZ_ERR_READ_EOF;
    }
    else
    {
      obj2D = WlzReadObj(fP, &errNum);
      (void )fclose(fP);
      fP = NULL;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    switch(obj2D->type)
    {
      case WLZ_EMPTY_OBJ:
	break;
      case WLZ_2D_DOMAINOBJ:
	if(obj2D->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  /* Make a plane domain, set column and line bounds later. */
  if(errNum == WLZ_ERR_NONE)
  {
    dom3D.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
    				 plane1, lastpl,
				 0, 1, 0, 1, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dom3D.p->voxel_size[0] = xSz;
    dom3D.p->voxel_size[1] = ySz;
    dom3D.p->voxel_size[2] = zSz;
  }
  /* Make a voxel value table. */
  if(errNum == WLZ_ERR_NONE)
  {
    if(obj2D->values.core)
    {
      bgd = WlzGetBackground(obj2D, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	val3D.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					plane1, lastpl, bgd, NULL, &errNum);
      }
    }				    
  }
  idx = 0;
  while((errNum == WLZ_ERR_NONE) && (idx < nFileStr))
  {
    if(obj2D)
    {
      switch(obj2D->type)
      {
	case WLZ_EMPTY_OBJ:
	  break;
	case WLZ_2D_DOMAINOBJ:
	  if(obj2D->domain.core == NULL)
	  {
	    errNum = WLZ_ERR_DOMAIN_NULL;
	  }
	  break;
	default:
	  errNum = WLZ_ERR_OBJECT_TYPE;
	  break;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	*(dom3D.p->domains + idx) = WlzAssignDomain(obj2D->domain, NULL);
	if(val3D.core)
	{
	  if((obj2D->domain.core != NULL) && (obj2D->values.core == NULL))
	  {
	    errNum = WLZ_ERR_VALUES_NULL;
	  }
	  else
	  {
	    *(val3D.vox->values + idx) = WlzAssignValues(obj2D->values, NULL);
	  }
	}
      }
      WlzFreeObj(obj2D);
      obj2D = NULL;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      ++idx;
      if((idx < nFileStr) && *(fileStr + idx))
      {
	if((fP = fopen(*(fileStr + idx), "r")) == NULL)
	{
	  errNum = WLZ_ERR_READ_EOF;
	}
	else
	{
	  obj2D = WlzReadObj(fP, &errNum);
	  (void )fclose(fP);
	  fP = NULL;
	}
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzStandardPlaneDomain(dom3D.p, val3D.vox);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    obj3D = WlzMakeMain(WLZ_3D_DOMAINOBJ, dom3D, val3D, NULL, NULL, &errNum);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    if(dom3D.core)
    {
      (void )WlzFreeDomain(dom3D);
    }
    if(val3D.core)
    {
      (void )WlzFreeValues(val3D);
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(obj3D);
}
Exemple #8
0
WlzObject *SecListToTransforms(
  RecSectionList	*secList,
  int		relFlg,
  WlzErrorNum	*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*rtnObj=NULL;
  int		i, p, pMin, pMax;
  WlzDomain	domain;
  WlzValues	values;
  RecSection	*sec;
  HGUDlpListItem	*listItem;
  WlzAffineTransform	*recTrans, *tmpTrans;

  /* sort the section list and find the section range */
  RecSecListSort(secList->list, REC_SECMSK_INDEX);

  /* calculate the cumulative transforms */
  listItem = HGUDlpListTail(secList->list);
  if( relFlg ){
    RecSecCumTransfSet(secList->list, listItem);
  }

  /* define the reconstruct transform */
  recTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					   0.0, 0.0, 0.0,
					   secList->reconstruction.scale.vtX,
					   0.0, 0.0, 0.0, 0.0,
					   0.0, 0, NULL);

  /* create the transforms object */
  listItem = HGUDlpListHead(secList->list);
  sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem);
  pMin = sec->index;
  listItem = HGUDlpListTail(secList->list);
  sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem);
  pMax = sec->index;
  if( errNum == WLZ_ERR_NONE ){
    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_AFFINE,
				      pMin, pMax, 0, 0, 0, 0,
				      &errNum)) != NULL){
      values.core = NULL;
      rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ,
			   domain, values, NULL, NULL, &errNum);
    }
  }

  /* now put in the transforms */
  listItem = HGUDlpListHead(secList->list);
  while( listItem ){
    sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem);
    p = sec->index;
    i = p - rtnObj->domain.p->plane1;
    if( relFlg ){
      if( sec->cumTransform == NULL ){
	rtnObj->domain.p->domains[i].t =
	  WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
				        0.0, 0.0, 0.0, 1.0,
				        0.0, 0.0, 0.0, 0.0,
				        0.0, 0, NULL);
      }
      else {
	rtnObj->domain.p->domains[i].t =
	  WlzAssignAffineTransform(sec->cumTransform, NULL);
      }
    }
    else {
      rtnObj->domain.p->domains[i].t =
	WlzAssignAffineTransform(sec->transform, NULL);
    }

    /* apply the reconstruct transform */
    tmpTrans = WlzAffineTransformProduct(rtnObj->domain.p->domains[i].t,
					 recTrans, NULL);
    WlzFreeAffineTransform(rtnObj->domain.p->domains[i].t);
    rtnObj->domain.p->domains[i].t = WlzAssignAffineTransform(tmpTrans, NULL);

    listItem = HGUDlpListNext(secList->list, listItem);
  }

  WlzFreeAffineTransform(recTrans);

  if( dstErr ){
    *dstErr = errNum;
  }
  if( (errNum != WLZ_ERR_NONE) && rtnObj ){
    WlzFreeObj(rtnObj);
    rtnObj = NULL;
  }
  return rtnObj;
}
Exemple #9
0
WlzObject *ReadMAPaintRealignTransforms(
  FILE 		*fp,
  WlzErrorNum	*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*rtnObj=NULL;
  BibFileRecord		*bibfileRecord;
  BibFileError		bibFileErr=BIBFILE_ER_NONE;
  int		p, pMin, pMax;
  int		identFlg=0, planeFlg=0;
  WlzDomain	domain;
  WlzValues	values;
  char		*errMsg;
  int		numParsedFields=0;
  double		tx=0.0, ty=0.0, theta=0.0;
  WlzAffineTransform	*inTrans;

  /* read the file to establish the section range
     note must have an Ident record, also check for a repeat
     Ident record which indicates a following set of records
     e.g. if reading from stdin */
  bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, fp);
  if( bibFileErr != BIBFILE_ER_NONE ){
    errNum = WLZ_ERR_UNSPECIFIED;
  }
  identFlg = 0;
  while( bibFileErr == BIBFILE_ER_NONE ) 
  {
    /* do nothing until Ident found, quit if found twice */
    if( !identFlg ){
      if( !strncmp(bibfileRecord->name, "Ident", 5) ){
	identFlg = 1;
      }
      
    }
    else {
      /* should check what type of bibfile here */
      if( !strncmp(bibfileRecord->name, "Ident", 5) ){
	BibFileRecordFree(&bibfileRecord);
	break;
      }

      if( !strncmp(bibfileRecord->name, "Section", 7) ){
	/* get the plane number */
	p = atoi(bibfileRecord->id);
	if( planeFlg ){
	  pMin = WLZ_MIN(pMin, p);
	  pMax = WLZ_MAX(pMax, p);
	}
	else {
	  pMin = p;
	  pMax = p;
	  planeFlg = 1;
	}
      }
    }
    BibFileRecordFree(&bibfileRecord);
    bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, fp);
  }
  if( (bibFileErr != BIBFILE_ER_NONE) && (bibFileErr != BIBFILE_ER_EOF) ){
    errNum = WLZ_ERR_UNSPECIFIED;
  }
  /* this assumes that the records are at the beginning of the file */
  rewind(fp);

  /* make the tranforms object */
  if( errNum == WLZ_ERR_NONE ){
    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_AFFINE,
				      pMin, pMax, 0, 0, 0, 0,
				      &errNum)) != NULL){
      values.core = NULL;
      rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ,
			   domain, values, NULL, NULL, &errNum);
    }
  }

  /* now re-read the file, setting the transforms */
  if( errNum == WLZ_ERR_NONE ){
    bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, fp);
    if( bibFileErr != BIBFILE_ER_NONE ){
      errNum = WLZ_ERR_UNSPECIFIED;
    }
    identFlg = 0;
    while((bibFileErr == BIBFILE_ER_NONE) &&
	  (errNum == WLZ_ERR_NONE)) 
    {
      /* do nothing until Ident found, quit if found twice */
      if( !identFlg ){
	if( !strncmp(bibfileRecord->name, "Ident", 5) ){
	  identFlg = 1;
	}
      
      }
      else {
	/* should check what type of bibfile here */
	if( !strncmp(bibfileRecord->name, "Ident", 5) ){
	  BibFileRecordFree(&bibfileRecord);
	  break;
	}

	if( !strncmp(bibfileRecord->name, "Section", 7) ){
	  /* get the plane number */
	  p = atoi(bibfileRecord->id);
	  p -= rtnObj->domain.p->plane1;

	  /* parse the record */
	  numParsedFields = BibFileFieldParseFmt
	    (bibfileRecord->field,
	     (void *) &tx, "%lg", "TransformTx",
	     (void *) &ty, "%lg", "TransformTy",
	     (void *) &theta, "%lg", "TransformTheta",
	     NULL);

	  /* make the transform for this record */
	  inTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					       tx, ty, 0.0, 1.0,
					       theta, 0.0, 0.0, 0.0,
					       0.0, 0, NULL);

	  rtnObj->domain.p->domains[p].t =
	    WlzAssignAffineTransform(inTrans, NULL);

	}
      }
      BibFileRecordFree(&bibfileRecord);
      bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, fp);
    }
    if( (bibFileErr != BIBFILE_ER_NONE) && (bibFileErr != BIBFILE_ER_EOF) ){
      errNum = WLZ_ERR_UNSPECIFIED;
    }
  }
  

  if( dstErr ){
    *dstErr = errNum;
  }
  if( (errNum != WLZ_ERR_NONE) && rtnObj ){
    WlzFreeObj(rtnObj);
    rtnObj = NULL;
  }
  return rtnObj;
}
Exemple #10
0
static WlzObject *WlzGreyMask3d(
  WlzObject	*obj,
  WlzObject	*mask,
  WlzPixelV	maskVal,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzObject	*tmpMask, *obj1, *obj2;
  WlzDomain	*domains;
  WlzValues	values, *valuess, *newvaluess;
  WlzPlaneDomain	*pdom;
  int		p;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check the object - it is non-NULL and 3D but the
     domain needs checking */
  if( obj->domain.p == NULL ){
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else {
    switch( obj->domain.p->type ){
    case WLZ_2D_DOMAINOBJ:
      /* check there is a valuetable */
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      break;

    case WLZ_EMPTY_DOMAIN:
      return WlzMakeEmpty(dstErr);

    default:
      errNum = WLZ_ERR_DOMAIN_TYPE;
      break;
    }
  }

  /* check the mask */
  if( errNum == WLZ_ERR_NONE ){
    if( mask == NULL ){
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
      /* set some local variables */
      pdom = obj->domain.p;
      domains = obj->domain.p->domains;
      valuess = obj->values.vox->values;

      /* create a new voxel object, initially no values */
      values.vox = WlzMakeVoxelValueTb(obj->values.vox->type,
				       obj->values.vox->plane1,
				       obj->values.vox->lastpl,
				       obj->values.vox->bckgrnd,
				       obj, NULL);
      rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, obj->domain, values,
			   NULL, NULL, NULL);
      newvaluess = rtnObj->values.vox->values;

      /* switch on mask type - a 2D mask is applied to each plane */
      switch( mask->type ){
      case WLZ_2D_DOMAINOBJ:
      case WLZ_2D_POLYGON:
      case WLZ_BOUNDLIST:
      case WLZ_EMPTY_OBJ:
	for(p=pdom->plane1; p <= pdom->lastpl; p++, domains++, valuess++){
	  if( (*domains).core ){
	    obj1 = WlzAssignObject(
	      WlzMakeMain(WLZ_2D_DOMAINOBJ, *domains, *valuess,
			  NULL, NULL, NULL), NULL);
	    if((obj2 = WlzGreyMask(obj1, mask, maskVal, &errNum)) != NULL){
	      newvaluess[p - pdom->plane1] =
		WlzAssignValues(obj->values, NULL);
	      WlzFreeObj(obj2);
	    }
	    WlzFreeObj(obj1);
	  }
	}
	break;

      case WLZ_3D_DOMAINOBJ:
	/* switch on plane domain type - polygon and boundlist
	   are legal but need transforming first. */
	switch( obj->domain.p->type ){
	  WlzDomain	*maskDoms;

	case WLZ_PLANEDOMAIN_DOMAIN:
	  maskDoms = mask->domain.p->domains;
	  for(p=pdom->plane1; p <= pdom->lastpl; p++, domains++, valuess++){
	    if(((*domains).core)){
	      if((p >= mask->domain.p->plane1) &&
		 (p <= mask->domain.p->lastpl) &&
		 (maskDoms[p - mask->domain.p->plane1].core) ){
		values.core = NULL;
		tmpMask = WlzMakeMain(WLZ_2D_DOMAINOBJ,
				      maskDoms[p - mask->domain.p->plane1],
				      values, NULL, NULL, NULL);
	      }
	      else {
		tmpMask = WlzMakeEmpty(NULL);
	      }

	      obj1 = WlzAssignObject(
		WlzMakeMain(WLZ_2D_DOMAINOBJ, *domains, *valuess,
			    NULL, NULL, NULL), NULL);
	      if((obj2 = WlzGreyMask(obj1, tmpMask, maskVal,
	      			     &errNum)) != NULL){
		newvaluess[p - pdom->plane1] =
		  WlzAssignValues(obj2->values, NULL);
		WlzFreeObj(obj2);
	      }
	      WlzFreeObj(obj1);
	      WlzFreeObj(tmpMask);
	    }
	  }
	  break;

	case WLZ_PLANEDOMAIN_POLYGON:
	  maskDoms = mask->domain.p->domains;
	  for(p=pdom->plane1; p <= pdom->lastpl; p++, domains++, valuess++){
	    if(((*domains).core)){
	      if((p >= mask->domain.p->plane1) &&
		 (p <= mask->domain.p->lastpl) &&
		 (maskDoms[p - mask->domain.p->plane1].core) ){
		values.core = NULL;
		tmpMask = WlzMakeMain(WLZ_2D_POLYGON,
				      maskDoms[p - mask->domain.p->plane1],
				      values, NULL, NULL, NULL);
	      }
	      else {
		tmpMask = WlzMakeEmpty(NULL);
	      }

	      obj1 = WlzAssignObject(
		WlzMakeMain(WLZ_2D_DOMAINOBJ, *domains, *valuess,
			    NULL, NULL, NULL), NULL);
	      if((obj2 = WlzGreyMask(obj1, tmpMask, maskVal,
	                             &errNum)) != NULL){
		newvaluess[p - pdom->plane1] =
		  WlzAssignValues(obj2->values, NULL);
		WlzFreeObj(obj2);
	      }
	      WlzFreeObj(obj1);
	      WlzFreeObj(tmpMask);
	    }
	  }
	  break;

	case WLZ_PLANEDOMAIN_BOUNDLIST:
	  maskDoms = mask->domain.p->domains;
	  for(p=pdom->plane1; p <= pdom->lastpl; p++, domains++, valuess++){
	    if(((*domains).core)){
	      if((p >= mask->domain.p->plane1) &&
		 (p <= mask->domain.p->lastpl) &&
		 (maskDoms[p - mask->domain.p->plane1].core) ){
		values.core = NULL;
		tmpMask = WlzMakeMain(WLZ_BOUNDLIST,
				      maskDoms[p - mask->domain.p->plane1],
				      values, NULL, NULL, NULL);
	      }
	      else {
		tmpMask = WlzMakeEmpty(NULL);
	      }

	      obj1 = WlzAssignObject(
		WlzMakeMain(WLZ_2D_DOMAINOBJ, *domains, *valuess,
			    NULL, NULL, NULL), NULL);
	      if((obj2 = WlzGreyMask(obj1, tmpMask, maskVal,
	                             &errNum)) != NULL){
		newvaluess[p - pdom->plane1] =
		  WlzAssignValues(obj2->values, NULL);
		WlzFreeObj(obj2);
	      }
	      WlzFreeObj(obj1);
	      WlzFreeObj(tmpMask);
	    }
	  }
	  break;

	default:
	  errNum = WLZ_ERR_DOMAIN_TYPE;
	  WlzFreeObj(rtnObj);
	  rtnObj = NULL;
	  break;
	}
	break;

      default:
	errNum = WLZ_ERR_OBJECT_NULL;
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
	break;
      }
    }
  }


  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
Exemple #11
0
/*! 
* \ingroup      WlzValuesUtils
* \brief        Set the value maskVal within the domain given by the	
*		mask object. The mask object can be a 2D, 3D, polygon	
*		or boundary object. A 3D mask with a 2D object is an	
*		error. A 2D mask with a 3D object will be applied to	
*		each plane in turn.			
*
* \return       New object with the same domain as the input object but
 with values in the intersection with the mask domain set to the mask
 value. NULL on error.
 * \param    obj	Input object
 * \param    mask	Mask object.
 * \param    maskVal	mask value.
 * \param    dstErr	Error return.
* \par      Source:
*                WlzGreyMask.c
*/
WlzObject *WlzGreyMask(
  WlzObject	*obj,
  WlzObject	*mask,
  WlzPixelV	maskVal,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzObject	*tmpMask, *obj1;
  WlzValues	values;
  WlzPixelV	tmpMaskval;
  WlzIntervalWSpace	iwsp;
  WlzGreyWSpace		gwsp;
  WlzGreyP		gptr;
  int			i;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* check obj */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      return WlzGreyMask3d(obj, mask, maskVal, dstErr);

    case WLZ_TRANS_OBJ:
      if((values.obj = WlzGreyMask(obj->values.obj, mask, maskVal,
      				   &errNum)) != NULL){
	return WlzMakeMain(WLZ_TRANS_OBJ, obj->domain, values,
			   NULL, NULL, dstErr);
      }
      break;

    case WLZ_EMPTY_OBJ:
      return WlzMakeEmpty(dstErr);

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* check the mask */
  if( errNum == WLZ_ERR_NONE ){
    if( mask == NULL ){
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
      values.core = NULL;
      switch( mask->type ){
      case WLZ_2D_DOMAINOBJ:
	tmpMask = WlzMakeMain(WLZ_2D_DOMAINOBJ, mask->domain, values,
			      NULL, NULL, &errNum);
	break;

      case WLZ_TRANS_OBJ:
	tmpMask = WlzMakeMain(WLZ_2D_DOMAINOBJ, mask->values.obj->domain,
			      values, NULL, NULL, &errNum);
	break;

      case WLZ_EMPTY_OBJ:
	return WlzMakeMain(WLZ_2D_DOMAINOBJ, obj->domain, obj->values,
			   NULL, NULL, dstErr);

      case WLZ_2D_POLYGON:
	tmpMask = WlzPolyToObj(mask->domain.poly, WLZ_SIMPLE_FILL, &errNum);
	break;

      case WLZ_BOUNDLIST:
	tmpMask = WlzBoundToObj(mask->domain.b, WLZ_SIMPLE_FILL, &errNum);
	break;

      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
      if( errNum == WLZ_ERR_NONE ){
	tmpMask = WlzAssignObject(tmpMask, NULL);
      }
    }
  }

  /* copy input obj and setvalues in the intersection */
  if(errNum == WLZ_ERR_NONE){
    if((rtnObj = WlzNewGrey(obj, &errNum)) != NULL){
      if((obj1 = WlzIntersect2(obj, tmpMask, &errNum)) != NULL){
	obj1->values = WlzAssignValues(rtnObj->values, NULL);
	errNum = WlzInitGreyScan(obj1, &iwsp, &gwsp);
	WlzValueConvertPixel(&tmpMaskval, maskVal, gwsp.pixeltype);
	while((errNum == WLZ_ERR_NONE) &&
	      ((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE)){
	  gptr = gwsp.u_grintptr;
	  switch( gwsp.pixeltype ){
	  case WLZ_GREY_INT:
	    for(i=0; i<iwsp.colrmn; i++, gptr.inp++){
	      *gptr.inp = tmpMaskval.v.inv;
	    }
	    break;
	  case WLZ_GREY_SHORT:
	    for(i=0; i<iwsp.colrmn; i++, gptr.shp++){
	      *gptr.shp = tmpMaskval.v.shv;
	    }
	    break;
	  case WLZ_GREY_UBYTE:
	    for(i=0; i<iwsp.colrmn; i++, gptr.ubp++){
	      *gptr.ubp = tmpMaskval.v.ubv;
	    }
	    break;
	  case WLZ_GREY_FLOAT:
	    for(i=0; i<iwsp.colrmn; i++, gptr.flp++){
	      *gptr.flp = tmpMaskval.v.flv;
	    }
	    break;
	  case WLZ_GREY_DOUBLE:
	    for(i=0; i<iwsp.colrmn; i++, gptr.dbp++){
	      *gptr.dbp = tmpMaskval.v.dbv;
	    }
	    break;
	  case WLZ_GREY_RGBA:
	    for(i=0; i<iwsp.colrmn; i++, gptr.rgbp++){
	      *gptr.rgbp = tmpMaskval.v.rgbv;
	    }
	    break;
	  default:
	    errNum = WLZ_ERR_GREY_TYPE;
	    break;
	  }
	}
	if( errNum == WLZ_ERR_EOO ){
	  errNum = WLZ_ERR_NONE;
	}
	WlzFreeObj(obj1);
      }
      else {
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
      }
    }
    WlzFreeObj(tmpMask);
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
Exemple #12
0
int             main(int argc, char **argv)
{
  int		option,
		meanCrv = 0,
  		ok = 1,
		usage = 0;
  double	scale = 1.0;
  WlzInterpolationType interp = WLZ_INTERPOLATION_LINEAR;
  WlzObject     *inObj = NULL,
  		*outObj = NULL;
  FILE		*fP = NULL;
  char		*inObjFileStr,
  		*outObjFileStr;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsg;
  static char	optList[] = "hmNLQo:s:",
  		fileStrDef[] = "-";

  opterr = 0;
  inObjFileStr = fileStrDef;
  outObjFileStr = fileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'N':
        interp = WLZ_INTERPOLATION_NEAREST;
	break;
      case 'L':
        interp = WLZ_INTERPOLATION_LINEAR;
	break;
      case 'Q':
        interp = WLZ_INTERPOLATION_ORDER_2;
	break;
      case 'm':
        meanCrv = 1;
	break;
      case 'o':
        outObjFileStr = optarg;
	break;
      case 's':
        if(sscanf(optarg, "%lg", &scale) != 1)
	{
	  usage = 1;
	}
	break;
      case 'h': /* FALLTHROUGH */
      default:
        usage = 1;
	break;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inObjFileStr = *(argv + optind);
    }
  }
  ok = (usage == 0);
  if(ok)
  {
    if((inObjFileStr == NULL) ||
	(*inObjFileStr == '\0') ||
	((fP = (strcmp(inObjFileStr, "-")?
	       fopen(inObjFileStr, "r"): stdin)) == NULL) ||
	((inObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) ||
	(errNum != WLZ_ERR_NONE))
    {
      ok = 0;
    }
    if(fP)
    {
      if(strcmp(inObjFileStr, "-"))
      {
	(void )fclose(fP);
      }
      fP = NULL;
    }
  }
  if(ok)
  {
    outObj = WlzCMeshCurvToImage(inObj, scale, meanCrv, interp, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
	     "%s: Failed to create contour from conforming mesh (%s).\n",
	     *argv, errMsg);

    }
  }
  if(ok)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if(((fP = (strcmp(outObjFileStr, "-")?
              fopen(outObjFileStr, "w"): stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to write output object (%s).\n",
		     *argv, errMsg);
    }
    if(fP && strcmp(outObjFileStr, "-"))
    {
      (void )fclose(fP);
    }
  }
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(outObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample: %s%s",
    *argv,
    " [-h] [-m] [-N] [-L] [-Q] [-o<output object>] [-s#]\n"
    "      [<input object>]\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -h  Help, prints usage message.\n"
    "  -N  Nearest neighbour interpolation from nearest element node value.\n"
    "  -L  Linear interpolation from element node values.\n"
    "  -Q  Interpolation from nodes surrounding element.\n"
    "  -m  Set image values to the mean rather than the Gaussian curvature.\n"
    "  -o  Output object file.\n"
    "  -s  Additional scale factor to be used in going from the mesh to the\n"
    "      spatial domain.\n"
    "Creates a 2D domain object with grey values (image) in which the values\n"
    "that are interpolated from the Gaussian curvature of the mesh. The 2D\n"
    "domain is created to cover the mesh following it's displacement. The\n"
    "displaced mesh must have been computed so that the displacements\n"
    "transform it to a plane (as by WlzCMeshSurfaceMap(1)).\n"
    "By default files are read from the standard input and written to the\n"
    "standard output.\n",
    *argv,
    " -o out.wlz in.wlz\n"
    "Reads a 2D5 conforming mesh from the file in.wlz, applies the meshes\n"
    "displacements to create a 2D domain object with the values set using\n"
    "the Gaussian curvature of the mesh prior to he application of it's\n"
    "displacements. The 2D domain object image is then writen to the file\n"
    "out.wlz.\n");
  }
  return(!ok);
}
int		main(int argc, char *argv[])
{
  int		ok,
		binFlg = 0,
  		nAng = 360,
		maxRFlg = 0,
  		option,
		usage = 0;
  double	cen = 0.0,
  		maxR = 0.0;
  char		*fFileStr,
  		*rFileStr,
		*oFileStr;
  FILE		*fP = NULL;
  WlzObject	*fObj = NULL,
		*rObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsgStr;
  static char	optList[] = "bhn:o:R";
  const char    fileStrDef[] = "-";

  /* Parse the argument list and check for input files. */
  opterr = 0;
  fFileStr = (char *)fileStrDef;
  rFileStr = (char *)fileStrDef;
  oFileStr = (char *)fileStrDef;
  while((option = getopt(argc, argv, optList)) != EOF)
  {
    switch(option)
    {
      case 'b':
        binFlg = 1;
	break;
      case 'n':
	if((sscanf(optarg, "%d", &nAng) != 1) || (nAng <= 0))
	{
	  usage = 1;
	}
	break;
      case 'o':
	oFileStr = optarg;
	break;
      case 'R':
        maxRFlg = 1;
	break;
      case 'h':
      default:
	usage = 1;
	break;
    }
  }
  ok = !usage;
  if(ok && (optind < argc))
  {
    if((optind + 1) == argc)
    {
      fFileStr = argv[optind];
    }
    else if((optind + 2) == argc)
    {
      fFileStr = argv[optind];
      rFileStr = argv[optind + 1];
    }
    else
    {
      usage = 1;
    }
  }
  ok = !usage;
  /* Read the feature object. */
  if(ok)
  {
    if((fFileStr == NULL) ||
       (*fFileStr == '\0') ||
       ((fP = (strcmp(fFileStr, "-")?
              fopen(fFileStr, "r"): stdin)) == NULL) ||
       ((fObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to read feature object from file %s.\n",
                     argv[0], fFileStr);
    }
    if(fP && strcmp(fFileStr, "-"))
    {
      (void )fclose(fP); fP = NULL;
    }
  }
  /* Read the reference object. */
  if(ok)
  {
    if((rFileStr == NULL) ||
       (*rFileStr == '\0') ||
       ((fP = (strcmp(rFileStr, "-")?
              fopen(rFileStr, "r"): stdin)) == NULL) ||
       ((rObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to read reference object from file %s.\n",
                     argv[0], rFileStr);
    }
    if(fP && strcmp(rFileStr, "-"))
    {
      (void )fclose(fP); fP = NULL;
    }
  }
  /* Check object types and parse the promote the default distance function
   * if required. */
  if(ok)
  {
    if(rObj->type != fObj->type)
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Feature and reference object types differ.\n",
		     argv[0]);
    }
  }
  /* Compute centrality feature. */
  if(ok)
  {
    cen = WlzCentrality(fObj, rObj, nAng, binFlg, &maxR, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
                     "%s: Failed to compute centrality feature value (%s).\n",
                     argv[0], errMsgStr);
    }
  }
  /* Output the centrality feature value. */
  if(ok)
  {
    if((fP = (strcmp(oFileStr, "-")?
             fopen(oFileStr, "w"): stdout)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to open output file %s.\n",
                     argv[0], oFileStr);
    }
  }
  if(ok)
  {
    if(((maxRFlg == 0) && (fprintf(fP, "%lg\n", cen) <= 0)) ||
       ((maxRFlg != 0) && (fprintf(fP, "%lg %lg\n", cen, maxR) <= 0)))
    {
      ok = 0;
      errNum = WLZ_ERR_WRITE_INCOMPLETE;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
                     "%s: Failed to write output feature value (%s).\n",
                     argv[0], errMsgStr);
    }
  }
  (void )WlzFreeObj(fObj);
  (void )WlzFreeObj(rObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-b] [-h] [-n#] [-o <output file>] [-R]\n"
    "                        [<feat obj>] [<ref obj>]\n"
    "Version: %s\n"
    "Computes the centrality of the feature object's domain with respect to\n"
    "the reference object's domain.\n"
    "\n"
    "Options are:\n"
    "  -b  Treat the feature object as a binary object with constant values.\n"
    "  -h  Help - prints this usage message\n"
    "  -n  Number of angle increments to use (default 360).\n"
    "  -o  Output file for centrality feature value.\n"
    "  -R  Output maximum radius value after centrality value.\n"
    "By default the feature and reference objects are read from the standard\n"
    "input. This may be made explicit if only one of these is given by using\n"
    "- to specify the standard input.\n",
    argv[0],
    WlzVersion());
  }
  return(!ok);
}
Exemple #14
0
int main(int	argc,
         char	**argv)
{

    WlzObject	*obj, *newobj;
    FILE		*inFile;
    char 		optList[] = "cC:ms:hv";
    int		option;
    int		compoundFlg=1;
    WlzRGBAColorSpace	colSpc=WLZ_RGBA_SPACE_RGB;
    WlzRGBAColorChannel	chan=WLZ_RGBA_CHANNEL_GREY;
    WlzErrorNum	errNum;

    /* read the argument list and check for an input file */
    opterr = 0;
    while( (option = getopt(argc, argv, optList)) != EOF ) {
        switch( option ) {

        case 'c':
            compoundFlg = 1;
            break;

        case 'C':
            switch( chan = (WlzRGBAColorChannel) atoi(optarg) ) {
            case WLZ_RGBA_CHANNEL_RED:
            case WLZ_RGBA_CHANNEL_GREEN:
            case WLZ_RGBA_CHANNEL_BLUE:
            case WLZ_RGBA_CHANNEL_HUE:
            case WLZ_RGBA_CHANNEL_SATURATION:
            case WLZ_RGBA_CHANNEL_BRIGHTNESS:
            case WLZ_RGBA_CHANNEL_CYAN:
            case WLZ_RGBA_CHANNEL_MAGENTA:
            case WLZ_RGBA_CHANNEL_YELLOW:
                break;

            default:
                fprintf(stderr, "%s: colour channel = %d is invalid\n",
                        argv[0], chan );
                usage(argv[0]);
                return 1;

            }
            compoundFlg = 0;
            break;

        case 'm':
            compoundFlg = 0;
            break;

        case 's':
            switch( colSpc = (WlzRGBAColorSpace) atoi(optarg) ) {

            case WLZ_RGBA_SPACE_RGB:
            case WLZ_RGBA_SPACE_HSB:
            case WLZ_RGBA_SPACE_CMY:
                break;

            default:
                fprintf(stderr, "%s: colour space = %d is invalid\n",
                        argv[0], colSpc );
                usage(argv[0]);
                return 1;

            }
            break;

        case 'h':
        default:
            usage(argv[0]);
            return( 1 );

        }
    }

    inFile = stdin;
    if( optind < argc ) {
        if( (inFile = fopen(*(argv+optind), "r")) == NULL ) {
            fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
            usage(argv[0]);
            return 1;
        }
    }

    /* read objects and convert if possible */
    while( (obj = WlzReadObj(inFile, NULL)) != NULL ) {
        if( obj->type == WLZ_2D_DOMAINOBJ || obj->type == WLZ_3D_DOMAINOBJ ) {
            if( compoundFlg ) {
                if( (newobj = (WlzObject *)
                              WlzRGBAToCompound(obj, colSpc, &errNum)) != NULL ) {
                    (void )WlzWriteObj(stdout, newobj);
                    WlzFreeObj(newobj);
                }
                else {
                    if( errNum == WLZ_ERR_VALUES_TYPE ) {
                        fprintf(stderr, "%s: wrong values type, object not converted\n",
                                argv[0]);
                        (void )WlzWriteObj(stdout, obj);
                    }
                    else {
                        fprintf(stderr, "%s: something wrong, time to quit.\n",
                                argv[0]);
                        usage(argv[0]);
                        return 1;
                    }
                }
            }
            else {
                if( chan == WLZ_RGBA_CHANNEL_GREY ) {
                    if( (newobj = WlzRGBAToModulus(obj, &errNum)) != NULL ) {
                        (void )WlzWriteObj(stdout, newobj);
                        WlzFreeObj(newobj);
                    }
                    else {
                        if( errNum == WLZ_ERR_VALUES_TYPE ) {
                            fprintf(stderr, "%s: wrong values type, object not converted\n",
                                    argv[0]);
                            (void )WlzWriteObj(stdout, obj);
                        }
                        else {
                            fprintf(stderr, "%s: something wrong, time to quit.\n",
                                    argv[0]);
                            usage(argv[0]);
                            return 1;
                        }
                    }
                }
                else {
                    if( (newobj = WlzRGBAToChannel(obj, chan, &errNum)) != NULL ) {
                        (void )WlzWriteObj(stdout, newobj);
                        WlzFreeObj(newobj);
                    }
                    else {
                        if( errNum == WLZ_ERR_VALUES_TYPE ) {
                            fprintf(stderr, "%s: wrong values type, object not converted\n",
                                    argv[0]);
                            (void )WlzWriteObj(stdout, obj);
                        }
                        else {
                            fprintf(stderr, "%s: something wrong, time to quit.\n",
                                    argv[0]);
                            usage(argv[0]);
                            return 1;
                        }
                    }
                }
            }
        }
        else {
            (void )WlzWriteObj(stdout, obj);
        }

        WlzFreeObj(obj);
    }

    return WLZ_ERR_NONE;
}
Exemple #15
0
/*!
* \return	Transformed object.
* \ingroup	WlzTransform
* \brief	Transform an object using the given view-transform.
*		Typically this is for mapping section data back into
*		the 3D space of the reference image/reconstruction.
* \param	srcObj			Given source object.
* \param	viewStr			Given view transform.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject *Wlz3DViewTransformObj(
    WlzObject		*srcObj,
    WlzThreeDViewStruct	*viewStr,
    WlzErrorNum		*dstErr)
{
    WlzErrorNum		errNum=WLZ_ERR_NONE;
    AlcErrno		alcErr = ALC_ER_NONE;
    WlzObject		*dstObj=NULL;
    int			area;
    int			i, k, p, xp, yp, line;
    int			plane1, lastpl, line1, lastln, kol1, lastkl;
    WlzIVertex3		*vertices;
    int			numVtxs, vtxIdx;
    WlzIntervalWSpace	iwsp;
    WlzGreyWSpace		gwsp;
    WlzDomain		domain, tmpDomain;
    WlzValues		values;
    int			numInts, itvlFlg;
    WlzInterval		*itvl;


    /* check the object */
    if( srcObj == NULL ) {
        errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
        switch( srcObj->type ) {

        case WLZ_2D_DOMAINOBJ:
            if( srcObj->domain.core == NULL ) {
                errNum = WLZ_ERR_DOMAIN_NULL;
            }
            area = WlzArea(srcObj, &errNum);
            if( area == 0 ) {
                dstObj = WlzMakeEmpty(&errNum);
            }
            break;

        case WLZ_2D_POLYGON: /* to be done at some time to 3D polyline */
        case WLZ_BOUNDLIST: /* convert to 3D polylines */
        case WLZ_TRANS_OBJ:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;

        default:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;
        }
    }

    /* create the voxel list */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {
        numVtxs = sizeof(WlzIVertex3) * (area+4);

        vertices = AlcMalloc(sizeof(WlzIVertex3) * (area+4));
        numVtxs = 0;
        if( vertices ) {
            errNum = WlzInitRasterScan(srcObj, &iwsp, WLZ_RASTERDIR_ILIC);
        }
        else {
            errNum = WLZ_ERR_MEM_ALLOC;
        }

        if( errNum == WLZ_ERR_NONE ) {
            while( (errNum = WlzNextInterval(&iwsp)) == WLZ_ERR_NONE ) {
                float x, y, z;

                if((iwsp.linpos < (int) viewStr->minvals.vtY) ||
                        (iwsp.linpos > (int) viewStr->maxvals.vtY)) {
                    continue;
                }
                yp = iwsp.linpos - (int) viewStr->minvals.vtY;
                for(k=iwsp.lftpos; k <= iwsp.rgtpos; k++) {
                    if((k < (int) viewStr->minvals.vtX) ||
                            (k > (int) viewStr->maxvals.vtX)) {
                        continue;
                    }
                    xp = k - (int) viewStr->minvals.vtX;
                    x = (float )(viewStr->xp_to_x[xp] + viewStr->yp_to_x[yp]);
                    y = (float )(viewStr->xp_to_y[xp] + viewStr->yp_to_y[yp]);
                    z = (float )(viewStr->xp_to_z[xp] + viewStr->yp_to_z[yp]);
                    vertices[numVtxs].vtX = WLZ_NINT(x);
                    vertices[numVtxs].vtY = WLZ_NINT(y);
                    vertices[numVtxs].vtZ = WLZ_NINT(z);
                    numVtxs++;
                }
            }

            if(errNum == WLZ_ERR_EOO) /* Reset error from end of object */
            {
                errNum = WLZ_ERR_NONE;
            }
        }
    }

    /* sort wrt planes, lines, kols */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {
        qsort((void *) vertices, (size_t) numVtxs, sizeof(WlzIVertex3),
              compareVtxVal);

        /* create planedomain */
        plane1 = vertices[0].vtZ;
        lastpl = vertices[numVtxs - 1].vtZ;
        line1 = vertices[0].vtY;
        lastln = line1;
        kol1 = vertices[0].vtX;
        lastkl = kol1;
        for(i=1; i < numVtxs; i++) {
            if( kol1 > vertices[i].vtX ) {
                kol1 = vertices[i].vtX;
            }
            if( lastkl < vertices[i].vtX ) {
                lastkl = vertices[i].vtX;
            }
            if( line1 > vertices[i].vtY ) {
                line1 = vertices[i].vtY;
            }
            if( lastln < vertices[i].vtY ) {
                lastln = vertices[i].vtY;
            }
        }
        if( (domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
                                           plane1, lastpl,
                                           line1, lastln,
                                           kol1, lastkl,
                                           &errNum)) == NULL ) {
            AlcFree((void *) vertices);
        }
    }

    /* for each plane count intervals and make domain */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {

        vtxIdx = 0;
        for(p=plane1; p <= lastpl; p++) {

            /* increment vertex index to current plane */
            while( vertices[vtxIdx].vtZ < p ) {
                vtxIdx++;
            }

            /* check for empty domain */
            if( vertices[vtxIdx].vtZ > p ) {
                domain.p->domains[p - plane1].i = NULL;
                continue;
            }

            /* estimate intervals - foreach pixel add one,
            foreach adjacent pixel on the same line subtract one */
            numInts = 1;
            kol1 = vertices[vtxIdx].vtX;
            lastkl = kol1;
            for(i=vtxIdx+1; i < numVtxs; i++) {
                if( vertices[i].vtZ > p ) {
                    break;
                }
                numInts++;
                if((vertices[i].vtY == vertices[i-1].vtY) &&
                        ((vertices[i].vtX == (vertices[i-1].vtX)) ||
                         (vertices[i].vtX == (vertices[i-1].vtX + 1))
                        )) {
                    numInts--;
                }
                if(kol1 > vertices[i].vtX) {
                    kol1 = vertices[i].vtX;
                }
                if(lastkl < vertices[i].vtX) {
                    lastkl = vertices[i].vtX;
                }
            }
            line1 = vertices[vtxIdx].vtY;
            lastln = vertices[i-1].vtY;

            /* make the domain and add the intervals pointer */
            tmpDomain.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_INTVL,
                                                line1, lastln,
                                                kol1, lastkl,
                                                &errNum);
            itvl = (WlzInterval *) AlcMalloc(sizeof(WlzInterval)*numInts);
            tmpDomain.i->freeptr = AlcFreeStackPush(tmpDomain.i->freeptr,
                                                    (void *) itvl,
                                                    &alcErr);
            if(alcErr != ALC_ER_NONE) {
                errNum = WLZ_ERR_MEM_ALLOC;
            }
            /* one more loop to add the intervals */
            itvl->ileft = vertices[vtxIdx].vtX - kol1;
            line = vertices[vtxIdx].vtY;
            itvlFlg = 1; /* interval started */
            numInts = 1;
            for(i=vtxIdx+1; i < numVtxs; i++) {

                /* new plane -> interval finished if started */
                if( vertices[i].vtZ > p ) {
                    if( itvlFlg ) {
                        itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                        WlzMakeInterval(line, tmpDomain.i, numInts, itvl);
                        itvl += numInts;
                        itvlFlg = 0; /* interval finished */
                        numInts = 0;
                    }
                    break;
                }

                /* check if new interval */
                if( !itvlFlg ) {
                    itvl->ileft = vertices[i].vtX - kol1;
                    line = vertices[i].vtY;
                    itvlFlg = 1;
                    numInts = 1;
                    continue; /* no further tests */
                }

                /* check for gap  - increment interval count */
                if((vertices[i].vtY == line) &&
                        ((vertices[i].vtX - vertices[i-1].vtX) > 1)) {
                    itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                    numInts++;
                    itvl[numInts-1].ileft = vertices[i].vtX - kol1;
                    itvlFlg = 1;
                }

                /* check for new-line */
                if( line < vertices[i].vtY ) {
                    itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                    WlzMakeInterval(line, tmpDomain.i, numInts, itvl);
                    itvl += numInts;
                    itvl->ileft = vertices[i].vtX - kol1;
                    line = vertices[i].vtY;
                    itvlFlg = 1;
                    numInts = 1;
                }

            }

            /* complete the last interval */
            if( itvlFlg ) {
                itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                WlzMakeInterval(line, tmpDomain.i, numInts, itvl);
                itvl += numInts;
            }

            /* add the domain to the planedomain */
            domain.p->domains[p - plane1] =
                WlzAssignDomain(tmpDomain, &errNum);
            (void) WlzIntervalCount(tmpDomain.i, 0);

        }

    }

    /* create the new object */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {
        values.core = NULL;
        dstObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
                             NULL, NULL, &errNum);
    }

    /* check for grey-level data */
    if((errNum == WLZ_ERR_NONE) && dstObj &&
            (dstObj->type != WLZ_EMPTY_OBJ) && srcObj->values.core ) {
        WlzPixelV	bckgrnd;
        WlzObject	*tmpObj;
        WlzValues	tmpValues;
        WlzDVertex3	vtx;
        WlzGreyValueWSpace	*gVWSp = NULL;
        WlzObjectType	valueTbType;

        /* explicit intialisation to satisfy strict ANSI on SGI */
        bckgrnd = WlzGetBackground(srcObj, &errNum);
        valueTbType = WlzGreyTableType(WLZ_GREY_TAB_RAGR,
                                       bckgrnd.type, NULL);

        /* make a voxel table */
        values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
                                         plane1, lastpl, bckgrnd,
                                         NULL, &errNum);
        dstObj->values = WlzAssignValues(values, &errNum);

        /* set up grey-value random access to original
           and loop through planes setting values */
        gVWSp = WlzGreyValueMakeWSp(srcObj, NULL);
        for(p=plane1; p <= lastpl; p++) {

            /* check for empty domain */
            if( domain.p->domains[p-plane1].core == NULL ) {
                continue;
            }

            /* make a value table */
            tmpObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domain.p->domains[p-plane1],
                                 values.vox->values[p-plane1], NULL, NULL, &errNum);
            tmpValues.v = WlzNewValueTb(tmpObj, valueTbType, bckgrnd, &errNum);
            values.vox->values[p-plane1] = WlzAssignValues(tmpValues, &errNum);
            tmpObj->values = WlzAssignValues(tmpValues, &errNum);

            /* transfer values */
            errNum = WlzInitGreyScan(tmpObj, &iwsp, &gwsp);
            while((errNum == WLZ_ERR_NONE) &&
                    ((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE)) {

                for(i=0;  i<iwsp.colrmn; i++) {
                    vtx.vtX = iwsp.colpos + i;
                    vtx.vtY = iwsp.linpos;
                    vtx.vtZ = p;
                    Wlz3DSectionTransformVtx(&vtx, viewStr);
                    WlzGreyValueGet(gVWSp, 0.0,
                                    WLZ_NINT(vtx.vtY), WLZ_NINT(vtx.vtX));
                    switch( gwsp.pixeltype ) {
                    case WLZ_GREY_LONG:
                        *(gwsp.u_grintptr.lnp+i) = gVWSp->gVal[0].lnv;
                        break;
                    case WLZ_GREY_INT:
                        *(gwsp.u_grintptr.inp+i) = gVWSp->gVal[0].inv;
                        break;
                    case WLZ_GREY_SHORT:
                        *(gwsp.u_grintptr.shp+i) = gVWSp->gVal[0].shv;
                        break;
                    case WLZ_GREY_UBYTE:
                        *(gwsp.u_grintptr.ubp+i) = gVWSp->gVal[0].ubv;
                        break;
                    case WLZ_GREY_FLOAT:
                        *(gwsp.u_grintptr.flp+i) = gVWSp->gVal[0].flv;
                        break;
                    case WLZ_GREY_DOUBLE:
                        *(gwsp.u_grintptr.dbp+i) = gVWSp->gVal[0].dbv;
                        break;
                    case WLZ_GREY_RGBA:
                        *(gwsp.u_grintptr.rgbp+i) = gVWSp->gVal[0].rgbv;
                        break;
                    case WLZ_GREY_BIT: /* not sure what to do with these */
                    default:
                        break;
                    }
                }
            }
            if(errNum == WLZ_ERR_EOO) /* Reset error from end of object */
            {
                errNum = WLZ_ERR_NONE;
            }
            WlzFreeObj(tmpObj);
        }

        WlzGreyValueFreeWSp(gVWSp);
    }

    /* clean temp allocation */
    if( vertices ) {
        AlcFree((void *) vertices);
    }

    if( dstErr ) {
        *dstErr = errNum;
    }
    return dstObj;
}
Exemple #16
0
int main(int	argc,
	 char	**argv)
{

  WlzObject	*obj, *mask, *newobj;
  FILE		*inFile = NULL;
  char 		optList[] = "m:h";
  int		option;
  WlzPixelV	maskVal;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const char	*errMsg;
    
  /* read the argument list and check for an input file */
  opterr = 0;
  maskVal.type = WLZ_GREY_FLOAT;
  maskVal.v.flv = 0.0;
  
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){
    case 'm':
      maskVal.v.flv = atof(optarg);
      break;
    case 'h':
    default:
      usage(argv[0]);
      return 1;
    }
  }

  /* check for read from file, note if one file is defined then
     it is the mask and the object should be on stdin */
  if( (argc - optind) >= 2 ){
    /* read the mask */
    if( (inFile = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    if( (mask = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) == NULL ){
      fprintf(stderr, "%s: can't read mask from file %s\n", argv[0],
	      *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    fclose( inFile );
    optind++;

    /* read the object */
    if( (inFile = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    if( (obj = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) == NULL ){
      fprintf(stderr, "%s: can't read obj from file %s\n", argv[0],
	      *(argv+optind));

      usage(argv[0]);
      return 1;
    }
    fclose( inFile );
  }
  else if( (argc - optind) == 1 ){
    /* read the mask */
    if( (inFile = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    if( (mask = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) == NULL ){
      fprintf(stderr, "%s: can't read mask from file %s\n", argv[0],
	      *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    fclose( inFile );
    inFile = stdin;
    if( (obj = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) == NULL ){
      fprintf(stderr, "%s: can't read obj from stdin\n", argv[0]);
      usage(argv[0]);
      return 1;
    }
  }
  else {
    /* else read objects from stdin */
    if( (obj = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) == NULL ){
      fprintf(stderr, "%s: can't read obj from stdin\n", argv[0]);
      usage(argv[0]);
      return 1;
    }
    if( (mask = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) == NULL ){
      fprintf(stderr, "%s: can't read mask from stdin\n", argv[0]);
      usage(argv[0]);
      return 1;
    }
  }
    
  /* apply mask and write resultant object */
  if((newobj = WlzGreyMask(obj, mask, maskVal, &errNum)) != NULL){
    if((errNum = WlzWriteObj(stdout, newobj)) != WLZ_ERR_NONE) {
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
		     "%s: failed to write object (%s).\n",
		     argv[0], errMsg);
      return(1);
    }
    WlzFreeObj(newobj);
  }
  WlzFreeObj(mask);
  WlzFreeObj(obj);

  return 0;
}
Exemple #17
0
void HGU_XmImageViewControlledInstallImage(
    WlzObject			*obj,
    HGU_XmImageViewDataStruct	*data,
    unsigned int			cntrlMask)
{
    if( data == NULL ) {
        return;
    }
    if( obj == NULL || (obj->type != WLZ_2D_DOMAINOBJ) ) {
        if( cntrlMask & HGU_XmIMAGEVIEW_CLEARONINVALID ) {
            obj = NULL;
        }
        else {
            return;
        }
    }

    /* clear old object and ximage */
    if( data->obj ) {
        WlzFreeObj(data->obj);
        data->obj = NULL;
    }
    if( data->ximage ) {
        if( data->ximage->data ) {
            AlcFree(data->ximage->data);
            data->ximage->data = NULL;
        }
        XDestroyImage(data->ximage);
        data->ximage = NULL;
    }

    if( obj ) {
        Dimension	width, height;
        data->obj = WlzAssignObject(obj, NULL);

        /* reset the LUT */
        HGU_XmImageViewResetGreyRange(data);
        if( !(cntrlMask & HGU_XmIMAGEVIEW_KEEPLUTCONTROLVALUES) ) {
            HGU_XmImageViewResetLutControlValues(data);
        }
        HGU_XmImageViewSetLutTransform(data);
        HGU_XmImageViewSetLutControls(data);

        /* call canvas expose to provoke display */
        if( !(cntrlMask & HGU_XmIMAGEVIEW_KEEPMAGVALUE) ) {
            data->magVal = 1.0;
        }
        data->width = data->obj->domain.i->lastkl - data->obj->domain.i->kol1 + 1;
        data->height = data->obj->domain.i->lastln - data->obj->domain.i->line1 + 1;
        width = data->width * data->magVal;
        height = data->height * data->magVal;
        XtVaSetValues(data->canvas, XmNwidth, width,
                      XmNheight, height, NULL);
        XtCallCallbacks(data->canvas, XmNexposeCallback, NULL);
    }
    else {
        /* clear the canvas, leave data etc unchanged */
        XClearWindow(XtDisplay(data->canvas), XtWindow(data->canvas));
    }

    return;
}
Exemple #18
0
/*!
* \return	The filtered object, or NULL on error.
* \ingroup	WlzValueFilters
* \brief	Applies a recursive filter to the given object.
* \param	srcObj			Given object.
* \param	ftr			Recursive filter.
* \param	actionMsk		Action mask.
* \param	dstErr			Destination error pointer, may
*                                       be null.
*/
WlzObject	*WlzRsvFilterObj(WlzObject *srcObj, WlzRsvFilter *ftr,
			         int actionMsk, WlzErrorNum *dstErr)
{
  WlzValues	tVal;
  WlzObject	*xObj = NULL,
		*yObj = NULL,
		*xyObj = NULL,
		*zObj = NULL,
  		*dstObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if((srcObj == NULL) || (ftr == NULL))
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(srcObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(srcObj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else if(WlzGreyTableIsTiled(srcObj->values.core->type))
  {
    errNum = WLZ_ERR_VALUES_TYPE;
  }
  else
  {
    switch(srcObj->type)
    {
      case WLZ_EMPTY_OBJ:
        dstObj = WlzMakeEmpty(&errNum);
	break;
      case WLZ_2D_DOMAINOBJ:
	if((actionMsk & (WLZ_RSVFILTER_ACTION_X |
			 WLZ_RSVFILTER_ACTION_Y)) != 0)
	{
	  /* Filter in each required direction. */
	  if((actionMsk & WLZ_RSVFILTER_ACTION_X) != 0)
	  {
	    xObj = WlzRsvFilterObj2DX(srcObj, ftr, &errNum);
	  }
	  if((errNum == WLZ_ERR_NONE) &&
	     ((actionMsk & WLZ_RSVFILTER_ACTION_Y) != 0))
	  {
	    yObj = WlzRsvFilterObj2DY((xObj)? xObj: srcObj,
	    		              ftr, &errNum);
	  }
	  if(errNum == WLZ_ERR_NONE)
	  {
	    if(yObj)
	    {
	      dstObj = yObj;
	      yObj = NULL;
	    }
	    else if(xObj)
	    {
	      dstObj = xObj;
	      xObj = NULL;
	    }
	  }
	  if(xObj)
	  {
	    WlzFreeObj(xObj);
	  }
	  if(yObj)
	  {
	    WlzFreeObj(yObj);
	  }
	}
	else
	{
	  /* No filtering required. */
	  dstObj = WlzNewGrey(srcObj, &errNum);
	}
        break;
      case WLZ_3D_DOMAINOBJ:
	if((actionMsk & (WLZ_RSVFILTER_ACTION_X | WLZ_RSVFILTER_ACTION_Y |
			  WLZ_RSVFILTER_ACTION_Z)) != 0)
	{
	  if((actionMsk & (WLZ_RSVFILTER_ACTION_X | 
	  		   WLZ_RSVFILTER_ACTION_Y)) != 0)
	  {
	    xyObj = WlzRsvFilterObj3DXY(srcObj, ftr, actionMsk,
	    				&errNum);
	  }
	  if((errNum == WLZ_ERR_NONE) && 
	     ((actionMsk & WLZ_RSVFILTER_ACTION_Z) != 0))
	  {
	    zObj = WlzRsvFilterObj3DZ((xyObj)? xyObj: srcObj, ftr, &errNum);
	  }
	  if(errNum == WLZ_ERR_NONE)
	  {
	    if(zObj)
	    {
	      dstObj = zObj;
	      zObj = NULL;
	    }
	    else if(xyObj)
	    {
	      dstObj = xyObj;
	      xyObj = NULL;
	    }
	  }
	  if(xyObj)
	  {
	    WlzFreeObj(xyObj);
	  }
	  if(zObj)
	  {
	    WlzFreeObj(zObj);
	  }
	}
	else
	{
	  /* No filtering required. */
	  tVal = WlzCopyValues(srcObj->type, srcObj->values, srcObj->domain,
	  		       &errNum);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    dstObj= WlzMakeMain(srcObj->type, srcObj->domain, tVal,
	    			NULL, NULL, &errNum);
	  }
	}
        break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dstObj);
}
Exemple #19
0
void HGU_XmImageViewReadImageCb(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data)
{
    HGU_XmImageViewDataStruct
    *data=(HGU_XmImageViewDataStruct *) client_data;
    XmFileSelectionBoxCallbackStruct
    *cbs=(XmFileSelectionBoxCallbackStruct *) call_data;
    Widget		option;
    int			intType;
    String		strBuf, tmpBuf;
    FILE			*fp;
    WlzObject		*obj=NULL;

    /* get image type and file */
    XtVaGetValues(data->typeMenu, XmNmenuHistory, &option, NULL);
    if(WlzStringMatchValue(&intType, XtName(option),
                           "woolz", WLZEFF_FORMAT_WLZ,
                           "pgm", WLZEFF_FORMAT_PNM,
                           "bmp", WLZEFF_FORMAT_BMP,
                           "tiff", WLZEFF_FORMAT_TIFF,
                           "raw", WLZEFF_FORMAT_RAW,
                           NULL)) {
        data->type = (WlzEffFormat) intType;
    }
    else {
        data->type = WLZEFF_FORMAT_RAW;
    }
    data->file = HGU_XmGetFileStr(data->imageForm, cbs->value, cbs->dir);

    /* read the image */
    switch( data->type ) {
    default:
        return;

    case WLZEFF_FORMAT_WLZ:
        if( (fp = HGU_XmGetFilePointer(data->imageForm, cbs->value,
                                       cbs->dir, "r")) == NULL )
        {
            return;
        }
        obj = WlzAssignObject(WlzEffReadObj(fp, NULL,
                                            data->type, 0, 0, 0, NULL), NULL);
        fclose(fp);
        break;

    case WLZEFF_FORMAT_PNM:
    case WLZEFF_FORMAT_BMP:
    case WLZEFF_FORMAT_TIFF:
        if( data->file == NULL )
        {
            return;
        }
        obj = WlzAssignObject(WlzEffReadObj(NULL, data->file,
                                            data->type, 0, 0, 0, NULL), NULL);
        break;

    case WLZEFF_FORMAT_RAW:
        if( data->file == NULL )
        {
            return;
        }
        /* get the data size and byte ordering */
        tmpBuf = (String) AlcMalloc(sizeof(char) * 32);
        sprintf(tmpBuf, "%d,%d,%d,%d", data->width, data->height,
                data->depth, data->byteOrder? 1 : 0);
        if( (strBuf = HGU_XmUserGetstr(w,
                                       "Please type in: w, h, d, o where:\n"
                                       "\n"
                                       "\tw = image width in pixels\n"
                                       "\th = image height in pixels\n"
                                       "\td = number of bits per pixel\n"
                                       "\to = byte order:\n"
                                       "      1 - big-endian\n"
                                       "      0 - small-endian",
                                       "Ok", "Cancel", tmpBuf)) ) {
            if( sscanf(strBuf, "%d,%d,%d,%d", &(data->width), &(data->height),
                       &(data->depth), &(data->byteOrder)) < 4 ) {
                AlcFree(strBuf);
                AlcFree(tmpBuf);
                return;
            }
            AlcFree(strBuf);
            AlcFree(tmpBuf);
        }
        else {
            return;
        }
        strBuf = AlcMalloc(sizeof(char) *
                           (strlen(data->file) + 48));
        switch( data->depth ) {
        case 8:
            intType = 3;
            break;
        case 12:
            intType = 2;
            break;
        case 16:
            intType = 7;
            break;
        case 32:
            intType = 1;
            break;
        }
        sprintf(strBuf, "WlzRawToWlz -%s %d %d %d %s", data->byteOrder?"b":"l",
                data->width, data->height, intType, data->file);
        if( (fp = popen(strBuf, "r")) ) {
            obj = WlzAssignObject(WlzEffReadObj(fp, NULL,
                                                WLZEFF_FORMAT_WLZ, 0, 0, 0, NULL), NULL);
            pclose(fp);
        }
        AlcFree(strBuf);
        break;
    }
    if( obj == NULL ) {
        HGU_XmUserError(data->canvas,
                        "Failed to read the image, please\n"
                        "check the file, permissions and the\n"
                        "image format and try again.\n",
                        XmDIALOG_FULL_APPLICATION_MODAL);
        return;
    }
    if( obj->type != WLZ_2D_DOMAINOBJ ) {
        WlzFreeObj(obj);
        return;
    }

    /* install the object */
    HGU_XmImageViewInstallImage(obj, data);
    WlzFreeObj(obj);

    return;
}
int             main(int argc, char **argv)
{
  int		idM,
  		idN,
  		option,
		ok = 1,
		usage = 0;
  double	dif,
  		tol = 1e-06;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  int		dim[3];
  WlzObject	*obj[2];
  FILE		*fP = NULL;
  char 		*objFileStr[2];
  char		*outFileStr;
  static char	optList[] = "he:o:";

  opterr = 0;
  obj[0] = obj[1] = NULL;
  objFileStr[0] = objFileStr[1] = "-";
  outFileStr = "-";
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'e':
        if(sscanf(optarg, "%lg", &tol) != 1)
	{
	  usage = 1;
	}
	break;
      case 'o':
        outFileStr = optarg;
	break;
      case 'h':
      default: /* FALLTHROUGH */
        usage = 1;
	break;
    }
  }
  if(ok && (optind < argc))
  {
    if((optind + 2) != argc)
    {
      usage = 1;
    }
    else
    {
      objFileStr[0] = *(argv + optind);
      objFileStr[1] = *(argv + optind + 1);
    }
  }
  ok = !usage;
  /* Read the affine transforms objects. */
  if(ok)
  {
    idN = 0;
    while(ok && (idN < 2))
    {
      if((objFileStr[idN] == NULL) ||
	 (*(objFileStr[idN]) == '\0') ||
	 ((fP = (strcmp(objFileStr[idN], "-")?
		fopen(objFileStr[idN], "r"): stdin)) == NULL) ||
	 ((obj[idN] = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
      {
	ok = 0;
	(void )fprintf(stderr,
		       "%s: Failed to read object from file %s.\n",
		       *argv, objFileStr[idN]);
      }
      if(fP && strcmp(objFileStr[idN], "-"))
      {
	(void )fclose(fP); fP = NULL;
      }
      ++idN;
    }
  }
  /* Check object types. */
  if(ok)
  {
    idN = 0;
    while(ok && (idN < 2))
    {
      if(obj[idN]->type != WLZ_AFFINE_TRANS)
      {
        ok = 0;
	(void )fprintf(stderr,
		       "%s: Object read from %s is not an affine transform.\n",
		       *argv, objFileStr[idN]);
      }
      else if(obj[idN]->domain.core == NULL)
      {
        ok = 0;
	(void )fprintf(stderr,
		       "%s: Object read from %s has a NULL domain.\n",
		       *argv, objFileStr[idN]);
      }
      else
      {
        switch(obj[idN]->domain.t->type)
	{
          case WLZ_TRANSFORM_2D_AFFINE:  /* FALLTHROUGH */
  	  case WLZ_TRANSFORM_2D_REG:     /* FALLTHROUGH */
  	  case WLZ_TRANSFORM_2D_TRANS:   /* FALLTHROUGH */
  	  case WLZ_TRANSFORM_2D_NOSHEAR:
	    dim[idN] = 2;
	    break;
  	  case WLZ_TRANSFORM_3D_AFFINE:  /* FALLTHROUGH */
  	  case WLZ_TRANSFORM_3D_REG:     /* FALLTHROUGH */
  	  case WLZ_TRANSFORM_3D_TRANS:   /* FALLTHROUGH */
          case WLZ_TRANSFORM_3D_NOSHEAR:
	    dim[idN] = 3;
	    break;
	  default:
	    ok = 0;
	    (void )fprintf(stderr,
		       "%s: Object read from %s is not an affine transform.\n",
			   *argv, objFileStr[idN]);
	    break;
	}
      }
      ++idN;
    }
  }
  /* Open the output file. */
  if(ok)
  {
    if((outFileStr == NULL) ||
       (*outFileStr == '\0') ||
       ((fP = (strcmp(outFileStr, "-")?
	      fopen(outFileStr, "w"): stdout)) == NULL))
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Failed to open output file %s.\n",
		     *argv, outFileStr);
    }
  }
  /* Compare the transform dimensions. */
  if(ok)
  {
    if(dim[0] != dim[1])
    {
      ok = 0;
      (void )fprintf(fP, "dimension\n< %d\n---\n> %d\n", dim[0], dim[1]);
    }
    dim[2] = WLZ_MAX(dim[0], dim[1]);
    for(idM = 0; idM < dim[2]; ++idM)
    {
      for(idN = 0; idN < dim[2]; ++idN)
      {
        dif = obj[0]->domain.t->mat[idM][idN] -
	      obj[1]->domain.t->mat[idM][idN];
        dif = fabs(dif);
	if(dif > tol)
	{
	  ok = 0;
	  (void )fprintf(fP, "[%d][%d]\n< %1.8e\n---\n> %1.8e\n",
			 idM, idN,
	  		 obj[0]->domain.t->mat[idM][idN],
			 obj[1]->domain.t->mat[idM][idN]);
	}
      }
    }
  }
  if(fP && strcmp(outFileStr, "-"))
  {
    (void )fclose(fP); fP = NULL;
  }
  (void )WlzFreeObj(obj[0]);
  (void )WlzFreeObj(obj[1]);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample: %s%s",
    *argv,
    " [-h] [-e #] [-o<output file>]\n"
    "                              <transform 0> <transform 1>\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -h  Help, prints this usage message.\n"
    "  -e  Tolerance value.\n"
    "  -o  Output file for differences.\n"
    "Compares two given affine transforms for significant differences\n"
    "using the given tollerance value.\n"
    "The exit status is 0 if the two transforms do not significantly\n"
    "differ, otherwise it is 1.\n"
    "The output file (if given) will be touched even if there are no\n"
    "differences found.\n",
    *argv,
    " -e 0.00001 -o diff.out tr0.wlz tr1.wlz\n"
    "Reads a pair of affine transforms from tr0.wlz and tr1.wlz, then\n"
    "writes any differences to diff.out.\n");
  }
  return((ok)? 0: 1);
}
Exemple #21
0
/*!
* \return	Woolz error code.
* \ingroup	WlzValuesUtils
* \brief	Sets the backgound value of an image object.
* \param	obj			Given object in which to set the
*					background value.
* \param	bgd			Required background value.
*/
WlzErrorNum WlzSetBackground(WlzObject	*obj,
			     WlzPixelV	bgd)
{
  WlzPlaneDomain	*planedmn;
  WlzVoxelValues	*voxtab;
  WlzObject		*obj1;
  int			i;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* check the object */
  if( obj == NULL ){
    return( WLZ_ERR_OBJECT_NULL );
  }

  switch( obj->type ){

  case WLZ_2D_DOMAINOBJ:
  case WLZ_3D_DOMAINOBJ:
    break;

  case WLZ_TRANS_OBJ:
    return( WlzSetBackground(obj->values.obj, bgd) );

  case WLZ_EMPTY_OBJ:
    return( WLZ_ERR_NONE );

  default:
    return( WLZ_ERR_OBJECT_TYPE );

  }    

  if( obj->domain.core == NULL ){
    return( WLZ_ERR_DOMAIN_NULL );
  }
  if( obj->values.core == NULL ){
    return( WLZ_ERR_NONE );
  }

  /* check the background type */
  switch( bgd.type ){

  case WLZ_GREY_INT:
  case WLZ_GREY_SHORT:
  case WLZ_GREY_UBYTE:
  case WLZ_GREY_FLOAT:
  case WLZ_GREY_DOUBLE:
  case WLZ_GREY_RGBA:
    break;

  default:
    return( WLZ_ERR_GREY_TYPE );

  }
   

  (void )WlzValueConvertPixel(
    &bgd, bgd,
    WlzGreyTableTypeToGreyType(obj->values.core->type, &errNum));
  switch( obj->type ){

  case WLZ_2D_DOMAINOBJ:
    switch( WlzGreyTableTypeToTableType(obj->values.core->type, &errNum) ){

    case WLZ_GREY_TAB_RAGR:
      obj->values.v->bckgrnd = bgd;
      break;

    case WLZ_GREY_TAB_RECT:
      obj->values.r->bckgrnd = bgd;
      break;

    case WLZ_GREY_TAB_INTL:
      obj->values.i->bckgrnd = bgd;
      break;

    default:
      return( errNum );
    }
    break;

  case WLZ_3D_DOMAINOBJ:
    planedmn = obj->domain.p;
    if( planedmn->type != WLZ_PLANEDOMAIN_DOMAIN ){
      return( WLZ_ERR_PLANEDOMAIN_TYPE );
    }

    voxtab = obj->values.vox;
    if( voxtab->type != WLZ_VOXELVALUETABLE_GREY ){
      return( WLZ_ERR_VOXELVALUES_TYPE );
    }

    for(i=0; i <= planedmn->lastpl - planedmn->plane1; i++){
      if( planedmn->domains[i].core == NULL
	  || voxtab->values[i].core == NULL){
	continue;
      }
      obj1 = WlzMakeMain(WLZ_2D_DOMAINOBJ, planedmn->domains[i],
			 voxtab->values[i], NULL, NULL, &errNum);
      WlzSetBackground( obj1, bgd );

      WlzFreeObj( obj1 );
    }
    voxtab->bckgrnd = bgd;
    break;

  default:
    errNum = WLZ_ERR_OBJECT_TYPE;
    break;
  }

  return( errNum );
}
Exemple #22
0
/*!
* \return	Woolz error code.
* \ingroup	WlzBinaryOps
* \brief	Splits the given montage object into component objects
*		clipped from the montage object.  The montage object
*		must be composed of component images embedded in a
*		background, with little variation in the background
*		values.
* \param	mObj			Montage object, which must be either
*					a WLZ_2D_DOMAINOBJ or a
*					WLZ_3D_DOMAINOBJ with values.
* \param	gapV			Value for the uniform background.
*					Must be either WLZ_GREY_INT or
*					WLZ_GREY_RGBA.
* \param	tol			Tolerance (fraction) for the
*					variation in background values.
* \param	bWidth			Additional boundary width added
*					to detected images before they are
*					clipped.
* \param	minArea			Minimum area for a valid component
*					image, must be greater than zero.
* \param	maxComp			Maximum number of components.
* \param	dstNComp		Destination pointer for the number of
*					components extracted, must not be NULL.
* \param	dstComp			Destination pointer for the extracted
*					components, must not be NULL.
*/
WlzErrorNum 	WlzSplitMontageObj(WlzObject *mObj, WlzPixelV gapV,
				      double tol, int bWidth, int minArea,
				      int maxComp,
				      int *dstNComp, WlzObject ***dstComp)
{
  int		id0,
  		id1,
		area,
		nLComp = 0;
  WlzObject	*gObj = NULL,
  		*tObj = NULL;
  WlzObject	**lComp;
  WlzGreyType	objG;
  WlzBox	box;
  WlzPixelV	gapLV,
  		gapHV;
  WlzConnectType lCon;
  int		tI[8];
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  tol = WLZ_CLAMP(tol, 0.0, 1.0);
  if(mObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(minArea < 1)
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else
  {
    switch(mObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	lCon = WLZ_4_CONNECTED;
        break;
      case WLZ_3D_DOMAINOBJ:
	lCon = WLZ_6_CONNECTED;
        break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    objG = WlzGreyTypeFromObj(mObj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    switch(gapV.type)
    {
      case WLZ_GREY_INT: /* FALLTHROUGH */
      case WLZ_GREY_RGBA:
        break;
      default:
	errNum = WLZ_ERR_GREY_TYPE;
	break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(objG == WLZ_GREY_RGBA)
    {
      if(gapV.type != WLZ_GREY_RGBA)
      {
        (void )WlzValueConvertPixel(&gapV, gapV, WLZ_GREY_RGBA);
      }
    }
    else
    {
      if(gapV.type != WLZ_GREY_INT)
      {
        (void )WlzValueConvertPixel(&gapV, gapV, WLZ_GREY_INT);
      }
    }
    gapLV.type = gapHV.type = gapV.type;
    if(gapV.type == WLZ_GREY_INT)
    {
      tI[0] = gapV.v.inv * tol;
      gapLV.v.inv = gapV.v.inv - tI[0];
      gapHV.v.inv = gapV.v.inv + tI[0];
      tObj = WlzThreshold(mObj, gapLV, WLZ_THRESH_HIGH, &errNum);
      if((errNum == WLZ_ERR_NONE) && (tObj != NULL))
      {
	gObj = WlzThreshold(tObj, gapHV, WLZ_THRESH_LOW, &errNum);
      }
      (void )WlzFreeObj(tObj);
      tObj = NULL;
    }
    else /* gapV.type == WLZ_GREY_RGBA */
    {
	tI[0] = WLZ_RGBA_RED_GET(gapV.v.rgbv);
	tI[1] = (int )floor((double )(tI[0]) * tol);
	tI[2] = tI[0] - tI[1];
	tI[5] = tI[0] + tI[1];
	tI[0] = WLZ_RGBA_GREEN_GET(gapV.v.rgbv);
	tI[1] = (int )floor((double )(tI[0]) * tol);
	tI[3] = tI[0] - tI[1];
	tI[6] = tI[0] + tI[1];
	tI[0] = WLZ_RGBA_BLUE_GET(gapV.v.rgbv);
	tI[1] = (int )floor((double )(tI[0]) * tol);
	tI[4] = tI[0] - tI[1];
	tI[7] = tI[0] + tI[1];
	tI[2] = WLZ_CLAMP(tI[2], 0, 255);
	tI[3] = WLZ_CLAMP(tI[3], 0, 255);
	tI[4] = WLZ_CLAMP(tI[4], 0, 255);
	WLZ_RGBA_RGBA_SET(gapLV.v.rgbv, tI[2], tI[3], tI[4], 255);
	tI[5] = WLZ_CLAMP(tI[5], 0, 255);
	tI[6] = WLZ_CLAMP(tI[6], 0, 255);
	tI[7] = WLZ_CLAMP(tI[7], 0, 255);
	WLZ_RGBA_RGBA_SET(gapHV.v.rgbv, tI[5], tI[6], tI[7], 255);
        gObj = WlzRGBABoxThreshold(mObj, gapLV, gapHV, &errNum);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    tObj = WlzDiffDomain(mObj, gObj, &errNum);
  }
  (void )WlzFreeObj(gObj);
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzLabel(tObj, &nLComp, &lComp, maxComp, 0, lCon);
  }
  (void )WlzFreeObj(tObj);
  if(errNum == WLZ_ERR_NONE)
  {
    /* Get rid of small objects using minArea as the threshold. */
    id0 = 0;
    id1 = 0;
    while(id0 < nLComp)
    {
      switch((*(lComp + id0))->type)
      {
        case WLZ_2D_DOMAINOBJ:
	  area = WlzArea(*(lComp + id0), NULL);
	  break;
        case WLZ_3D_DOMAINOBJ:
	  area = WlzVolume(*(lComp + id0), NULL);
	  break;
        default:
          area = 0;
	  break;
      }
      if(area >= minArea)
      {
        *(lComp + id1) = *(lComp + id0);
        ++id1;
      }
      else
      {
        (void )WlzFreeObj(*(lComp + id0));
	*(lComp + id0) = NULL;
      }
      ++id0;
    }
    nLComp = id1;
  }
  if(errNum == WLZ_ERR_NONE)
  {
    /* Clip rectangular objects from the montage object. */
    id0 = 0;
    while((errNum == WLZ_ERR_NONE) && (id0 < nLComp))
    {
      if(tObj->type == WLZ_2D_DOMAINOBJ)
      {
        box.i2 = WlzBoundingBox2I(*(lComp + id0), &errNum);
	box.i2.xMin -= bWidth;
	box.i2.yMin -= bWidth;
	box.i2.xMax += bWidth;
	box.i2.yMax += bWidth;
	(void )WlzFreeObj(*(lComp + id0));
	*(lComp + id0) = WlzClipObjToBox2D(mObj, box.i2, &errNum);
      }
      else /* tObj->type == WLZ_3D_DOMAINOBJ */
      {
        box.i3 = WlzBoundingBox3I(*(lComp + id0), &errNum);
	box.i3.xMin -= bWidth;
	box.i3.yMin -= bWidth;
	box.i3.zMin -= bWidth;
	box.i3.xMax += bWidth;
	box.i3.yMax += bWidth;
	box.i3.zMax += bWidth;
	(void )WlzFreeObj(*(lComp + id0));
	*(lComp + id0) = WlzClipObjToBox3D(mObj, box.i3, &errNum);
      }
      ++id0;
    }
  }
  *dstNComp = nLComp;
  *dstComp = lComp;
  return(errNum);
}
Exemple #23
0
int WlzEdgeVertices(
  WlzObject	*obj,
  WlzDVertex3	**vtxs,
  WlzErrorNum	*dstErr)
{
  int		numVtxs = 0, n;
  WlzDVertex3	*rtnVtxs=NULL, *tmpVtxs;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*obj1, *obj2;
  int		i, j;
  WlzValues	values;
  WlzPlaneDomain	*planedmn;

  /* check object */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      if((obj1 = WlzObjToBoundary(obj, 1, &errNum)) != NULL){
	numVtxs = WlzEdgeVerticesBound(obj1->domain.b, &rtnVtxs,
				       0, &errNum);
	WlzFreeObj(obj1);
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      if( obj->domain.core == NULL){
	errNum = WLZ_ERR_DOMAIN_NULL;
      }
      else {
	switch( obj->domain.core->type ){
	case WLZ_PLANEDOMAIN_DOMAIN:
	  planedmn = obj->domain.p;
	  values.core = NULL;
	  for(i=planedmn->plane1; i <= planedmn->lastpl; i++){
	    if( planedmn->domains[i-planedmn->plane1].core ){
	      obj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ,
				 planedmn->domains[i-planedmn->plane1],
				 values, NULL, NULL, NULL);
	      if( (n = WlzEdgeVertices(obj2, &tmpVtxs, &errNum)) > 0){
		if( numVtxs > 0 ){
		  rtnVtxs = AlcRealloc(rtnVtxs,
				       sizeof(WlzDVertex3)*(numVtxs+n));
		}
		else {
		  rtnVtxs = AlcMalloc(sizeof(WlzDVertex3)*n);
		}
		for(j=0; j < n; j++){
		  tmpVtxs[j].vtZ = i;
		  rtnVtxs[numVtxs+j] = tmpVtxs[j];
		}
		AlcFree(tmpVtxs);
		numVtxs += n;
	      }
	      WlzFreeObj(obj2);
	    }
	  }
	  break;

	case WLZ_PLANEDOMAIN_POLYGON:
	case WLZ_PLANEDOMAIN_BOUNDLIST:
	  break;

	case WLZ_EMPTY_DOMAIN:
	  if( dstErr ){
	    *dstErr = errNum;
	  }
	  return numVtxs;

	default:
	  errNum = WLZ_ERR_DOMAIN_TYPE;
	}
      }
      break;

    case WLZ_2D_POLYGON:
      numVtxs = WlzEdgeVerticesPoly(obj->domain.poly, &rtnVtxs, 0, &errNum);
      break;

    case WLZ_BOUNDLIST:
      numVtxs = WlzEdgeVerticesBound(obj->domain.b, &rtnVtxs, 0, &errNum);
      break;

    case WLZ_EMPTY_OBJ:
      if( dstErr ){
	*dstErr = errNum;
      }
      return numVtxs;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  *vtxs = rtnVtxs;
  return numVtxs;
}
Exemple #24
0
/*!
* \return	Woolz error code.
* \ingroup	WlzBinaryOps
* \brief	Splits the reference object into component objects cliped
*		from the reference object, with the bounding box of each
*		of the component objects determined using the pre-processed
*		object. The component objects are returned in size order.
* \param	refObj			Reference object.
* \param	ppObj			Pre-processed object which is
*					normalised to values in the range
*					0 - 255 as WlzUByte greys.
* \param	bWidth			Border width.
* \param	bgdFrac			Minimum fraction of values which are
* 					background values, with range
*					[0.0+ - 1.0-].
* \param	sigma			Histogram smoothing parameter used
*					by WlzHistogramCnvGauss().
* \param	compThrMethod		Method for computing threshold, used
*					in call to WlzCompThresholdVT().
* \param	nReqComp		Number of required components.
* \param	dstNComp		Destination pointer for the number of
*					components extracted, must not be NULL.
* \param	dstComp			Destination pointer for the extracted
*					components, must not be NULL.
*/
WlzErrorNum	WlzSplitObj(WlzObject *refObj, WlzObject *ppObj,
			      int bWidth, double bgdFrac, double sigma,
			      WlzCompThreshType compThrMethod,
			      int nReqComp, int *dstNComp,
			      WlzObject ***dstComp)
{
  int		dim,
  		idC;
  WlzObject	*hObj = NULL,
  		*tObj = NULL;
  WlzObject 	**comp = NULL;
  WlzBox	box;
  WlzPixelV	tV;
  WlzSplitObjData split;
  WlzThresholdType tType;
  WlzConnectType lCon;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  const int	maxComp = 1024;

  split.nLComp = 0;
  split.compI = NULL;
  split.lCompSz = NULL;
  split.lComp = NULL;
  if((refObj == NULL) || (ppObj == NULL))
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if((refObj->domain.core == NULL) || (ppObj->domain.core == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if((refObj->values.core == NULL) || (ppObj->values.core == NULL))
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else if(refObj->type != ppObj->type)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if((dstNComp == NULL) || (dstComp == NULL))
  {
    errNum = WLZ_ERR_PARAM_NULL;
  }
  else if((bgdFrac < DBL_EPSILON) || (bgdFrac > (1.0 - DBL_EPSILON)))
  {
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else
  {
    switch(refObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	dim = 2;
        lCon = WLZ_8_CONNECTED;
	break;
      case WLZ_3D_DOMAINOBJ:
	dim = 3;
        lCon = WLZ_26_CONNECTED;
	break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  /* Compute threshold value and type from histogram. */
  if(errNum == WLZ_ERR_NONE)
  {
    hObj = WlzAssignObject(
    	   WlzHistogramObj(ppObj, 256, 0.0, 1.0, &errNum), NULL);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzHistogramCnvGauss(hObj, sigma, 0);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzCompThresholdVT(hObj, compThrMethod, bgdFrac, 0.0,
    			        0.0, &tV, &tType);
  }
  (void )WlzFreeObj(hObj); hObj = NULL;
  /* Threshold object. */
  if(errNum == WLZ_ERR_NONE)
  {
    tObj = WlzAssignObject(
     	   WlzThreshold(ppObj, tV, tType, &errNum), NULL);
  }
  /* Label to get connected components. */
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzLabel(tObj, &(split.nLComp), &(split.lComp), maxComp, 0, lCon);
  }
  /* Sort connected components by size. */
  if(errNum == WLZ_ERR_NONE)
  {
    if(split.nLComp < nReqComp)
    {
      nReqComp = split.nLComp;
    }
    if(((split.compI = (int *)AlcMalloc(sizeof(int) *
                                        split.nLComp)) == NULL) ||
       ((split.lCompSz = (int *)AlcMalloc(sizeof(int) *
                                          split.nLComp)) == NULL))
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    idC = 0; 
    while((errNum == WLZ_ERR_NONE) && (idC < split.nLComp))
    {
      split.compI[idC] = idC;
      split.lCompSz[idC] = (dim == 2)? WlzArea(split.lComp[idC], &errNum):
      				       WlzVolume(split.lComp[idC], &errNum);
      ++idC;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    /* Sort component indices by component size. */
    AlgQSort(split.compI, split.nLComp, sizeof(int), &split,
    	     WlzSplitObjSortSzFn);
    /* Allocate array for cliped component objects. */
    if((comp = (WlzObject **)AlcCalloc(sizeof(WlzObject *),
    				       split.nLComp)) == NULL)
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }
  /* Compute bounding box and clip objects from the reference object. */
  if(errNum == WLZ_ERR_NONE)
  {
    idC = 0;
    while((errNum == WLZ_ERR_NONE) && (idC < nReqComp))
    {
      if(dim == 2)
      {
        box.i2 = WlzBoundingBox2I(split.lComp[split.compI[idC]], &errNum);
	if(errNum == WLZ_ERR_NONE)
	{
	  box.i2.xMin -= bWidth;
	  box.i2.yMin -= bWidth;
	  box.i2.xMax += bWidth;
	  box.i2.yMax += bWidth;
	  comp[idC] = WlzClipObjToBox2D(refObj, box.i2, &errNum);
	}
      }
      else /* dim == 3 */
      {
        box.i3 = WlzBoundingBox3I(split.lComp[split.compI[idC]], &errNum);
	if(errNum == WLZ_ERR_NONE)
	{
	  box.i3.xMin -= bWidth;
	  box.i3.yMin -= bWidth;
	  box.i3.zMin -= bWidth;
	  box.i3.xMax += bWidth;
	  box.i3.yMax += bWidth;
	  box.i3.zMax += bWidth;
	  comp[idC] = WlzClipObjToBox3D(refObj, box.i3, &errNum);
	}
      }
      ++idC;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    *dstNComp = nReqComp;
    *dstComp = comp;
  }
  /* Free temporary storage. */
  if(split.lComp)
  {
    for(idC = 0; idC < split.nLComp; ++idC)
    {
      (void )WlzFreeObj(split.lComp[idC]);
    }
    AlcFree(split.lComp);
  }
  AlcFree(split.compI);
  AlcFree(split.lCompSz);
  (void )WlzFreeObj(tObj);
  return(errNum);
}
Exemple #25
0
int             main(int argc, char **argv)
{
    int		option,
            ok = 1,
            usage = 0;
    double	disp = 0.0;
    WlzObject     *inObj = NULL,
                   *outObj = NULL;
    FILE		*fP = NULL;
    char		*inObjFileStr,
                *outObjFileStr;
    WlzErrorNum	errNum = WLZ_ERR_NONE;
    const char	*errMsg;
    static char	optList[] = "hd:o:",
                            fileStrDef[] = "-";

    opterr = 0;
    inObjFileStr = fileStrDef;
    outObjFileStr = fileStrDef;
    while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
    {
        switch(option)
        {
        case 'o':
            outObjFileStr = optarg;
            break;
        case 'd':
            if(sscanf(optarg, "%lg", &disp) != 1)
            {
                usage = 1;
            }
            break;
        case 'h': /* FALLTHROUGH */
        default:
            usage = 1;
            break;
        }
    }
    if((usage == 0) && (optind < argc))
    {
        if((optind + 1) != argc)
        {
            usage = 1;
        }
        else
        {
            inObjFileStr = *(argv + optind);
        }
    }
    ok = (usage == 0);
    if(ok)
    {
        if((inObjFileStr == NULL) ||
                (*inObjFileStr == '\0') ||
                ((fP = (strcmp(inObjFileStr, "-")?
                        fopen(inObjFileStr, "r"): stdin)) == NULL) ||
                ((inObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) ||
                (errNum != WLZ_ERR_NONE))
        {
            ok = 0;
        }
        if(fP)
        {
            if(strcmp(inObjFileStr, "-"))
            {
                (void )fclose(fP);
            }
            fP = NULL;
        }
    }
    if(ok)
    {
        outObj = WlzCMeshToContour(inObj, disp, &errNum);
        if(errNum != WLZ_ERR_NONE)
        {
            ok = 0;
            (void )WlzStringFromErrorNum(errNum, &errMsg);
            (void )fprintf(stderr,
                           "%s: Failed to create contour from conforming mesh (%s).\n",
                           *argv, errMsg);

        }
    }
    if(ok)
    {
        errNum = WLZ_ERR_WRITE_EOF;
        if(((fP = (strcmp(outObjFileStr, "-")?
                   fopen(outObjFileStr, "w"): stdout)) == NULL) ||
                ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
        {
            ok = 0;
            (void )WlzStringFromErrorNum(errNum, &errMsg);
            (void )fprintf(stderr,
                           "%s: Failed to write output object (%s).\n",
                           *argv, errMsg);
        }
        if(fP && strcmp(outObjFileStr, "-"))
        {
            (void )fclose(fP);
        }
    }
    (void )WlzFreeObj(inObj);
    (void )WlzFreeObj(outObj);
    if(usage)
    {
        (void )fprintf(stderr,
                       "Usage: %s%s%s%sExample: %s%s",
                       *argv,
                       " [-h] [-d #] [-o<output object>] [<input object>]\n"
                       "Version: ",
                       WlzVersion(),
                       "\n"
                       "Options:\n"
                       "  -h  Help, prints usage message.\n"
                       "  -d  Apply given scale factor to mesh displacements if they exist.\n"
                       "      The default is no mesh displacements are applied.\n"
                       "  -o  Output object file.\n"
                       "Creates a contour object from a conforming mesh. This is currently\n"
                       "only possible for a 2D5 conforming mesh, which results in a 3D contour\n"
                       "(collection of surfaces).  By default the input file is read from the\n"
                       "standard input and the output file is written to the standard output.\n",
                       *argv,
                       "  -o out.wlz -d 1.0 in.wlz\n"
                       "Reads a 2D5 conforming mesh from the file in.wlz, applies the meshes\n"
                       "displacements to it's nodes and then outputs the corresponding contour\n"
                       "to the file out.wlz.\n");
    }
    return(!ok);
}
/*!
* \return	Rescaled object.
* \ingroup	WlzTransform
* \brief	Rescales the given 3D domain object using an integer scale.
* \param	gObj			Given object.
* \param	scale			Integer scale factor.
* \param	expand			If zero use \f$\frac{1}{scale}\f$.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzIntRescaleObj3D(WlzObject *gObj, int scale, int expand,
				    WlzErrorNum *dstErr)
{
  int		gPIdx,
  		nPIdx;
  WlzDomain	gDom,
  		nDom;
  WlzValues	gVal,
  		nVal,
		dumVal;
  WlzObject	*gTObj = NULL,
  		*nTObj = NULL,
		*rObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzIBox3	nBox;

  nDom.core = NULL;
  nVal.core = NULL;
  dumVal.core = NULL;
  gDom = gObj->domain;
  gVal = gObj->values;
  if(expand)
  {
    nBox.xMin = gDom.p->kol1 * scale;
    nBox.xMax = ((gDom.p->lastkl + 1) * scale) - 1;
    nBox.yMin = gDom.p->line1 * scale;
    nBox.yMax = ((gDom.p->lastln + 1) * scale) - 1;
    nBox.zMin = gDom.p->plane1 * scale;
    nBox.zMax = ((gDom.p->lastpl + 1) * scale) - 1;
  }
  else
  {
    nBox.xMin = gDom.p->kol1 / scale;
    nBox.xMax = gDom.p->lastkl / scale;
    nBox.yMin = gDom.p->line1 / scale;
    nBox.yMax = gDom.p->lastln / scale;
    nBox.zMin = gDom.p->plane1 / scale;
    nBox.zMax = gDom.p->lastpl / scale;
  }
  nDom.p = WlzMakePlaneDomain(gDom.p->type, nBox.zMin, nBox.zMax,
			      nBox.yMin, nBox.yMax, nBox.xMin, nBox.xMax,
			      &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    if(gVal.core && (gVal.core->type != WLZ_EMPTY_OBJ))
    {
      if(WlzGreyTableIsTiled(gVal.core->type))
      {
        errNum = WLZ_ERR_VALUES_TYPE;
      }
      else
      {
	nVal.vox = WlzMakeVoxelValueTb(gVal.vox->type, nBox.zMin, nBox.zMax,
				WlzGetBackground(gObj, NULL),
				NULL, &errNum);
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    nPIdx = nBox.zMin;
    while((errNum == WLZ_ERR_NONE) && (nPIdx <= nBox.zMax))
    {
      gPIdx = (expand)? nPIdx / scale: nPIdx * scale;
      if(nVal.vox)
      {
        gTObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
                            *(gDom.p->domains + gPIdx),
                            *(gVal.vox->values + gPIdx),
                            NULL, NULL, &errNum);
      }
      else
      {
        gTObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
                            *(gDom.p->domains + gPIdx),
                            dumVal,
                            NULL, NULL, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	nTObj = WlzIntRescaleObj2D(gTObj, scale, expand, &errNum);
      }
      (void )WlzFreeObj(gTObj);
      gTObj = NULL;
      if(errNum == WLZ_ERR_NONE)
      {
        *(nDom.p->domains + nPIdx) = WlzAssignDomain(nTObj->domain, NULL);
        if(nVal.vox)
        {
          *(nVal.vox->values + nPIdx) = WlzAssignValues(nTObj->values, NULL);
        }
      }
      (void )WlzFreeObj(nTObj);
      nTObj = NULL;
      ++nPIdx;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    rObj = WlzMakeMain(gObj->type, nDom, nVal, NULL, NULL, &errNum);
  }
  else
  {
    (void )WlzFreePlaneDomain(nDom.p);
    (void )WlzFreeVoxelValueTb(nVal.vox);
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rObj);
}
Exemple #27
0
int		main(int argc, char *argv[])
{
  int		ok,
  		option,
  		usage = 0;
  char		*inFileStr,
  		*outFileStr;
  WlzObject	*inObj = NULL;
  FILE		*fP = NULL;
  const char	*errMsg;
  static char	optList[] = "o:h",
  		fileStrDef[] = "-";
  WlzErrorNum	errNum = WLZ_ERR_NONE;


  opterr = 0;
  inFileStr = outFileStr = fileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
	outFileStr = optarg;
	break;
      case 'h':
      default:
	usage = 1;
	break;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inFileStr = *(argv + optind);
    }
  }
  ok = (usage == 0);
  if(ok)
  {
    errNum = WLZ_ERR_READ_EOF;
    if(((fP = (strcmp(inFileStr, "-")?
        fopen(inFileStr, "r"): stdin)) == NULL) ||
       ((inObj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to read object from file %s (%s)\n",
		     argv[0], inFileStr, errMsg);
    }
    if(fP && strcmp(inFileStr, "-"))
    {
      (void )fclose(fP);
      fP = NULL;
    }
  }
  if(ok)
  {
    /* Check object is valid for tensor export. */
    if(inObj == NULL)
    {
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else if(inObj->domain.core == NULL)
    {
      errNum = WLZ_ERR_DOMAIN_NULL;
    }
    else if(inObj->values.core == NULL)
    {
      errNum = WLZ_ERR_VALUES_NULL;
    }
    else
    {
      switch(inObj->type)
      {
        case WLZ_CMESH_3D:
	  if(inObj->domain.core->type  != WLZ_CMESH_3D)
	  {
	    errNum = WLZ_ERR_DOMAIN_TYPE;
	  }
	  if(inObj->values.core->type != WLZ_INDEXED_VALUES)
	  {
	    errNum = WLZ_ERR_VALUES_TYPE;
	  }
	  else if((inObj->values.x->attach != WLZ_VALUE_ATTACH_ELM) ||
		  (inObj->values.x->vType != WLZ_GREY_DOUBLE) ||
		  (inObj->values.x->rank != 2) ||
		  (inObj->values.x->dim[0] != 3) ||
		  (inObj->values.x->dim[1] != 3))
	  {
	    errNum = WLZ_ERR_VALUES_DATA;
	  }
	  break;
        case WLZ_POINTS:
	  if(inObj->domain.core->type  != WLZ_POINTS_3D)
	  {
	    errNum = WLZ_ERR_DOMAIN_TYPE;
	  }
	  else if(inObj->values.core->type != WLZ_POINT_VALUES)
	  {
	    errNum = WLZ_ERR_VALUES_TYPE;
	  }
	  else if((inObj->values.pts->vType != WLZ_GREY_DOUBLE) ||
	          (inObj->values.pts->rank != 2) ||
		  (inObj->values.pts->dim[0] != 3) ||
		  (inObj->values.pts->dim[1] != 3))
	  {
	    errNum = WLZ_ERR_VALUES_DATA;
	  }
	  break;
	default:
	  errNum = WLZ_ERR_OBJECT_TYPE;
	  break;
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Input object read from %s is inappropriate.\n"
		     "Only 3D conforming mesh objects with tensor values\n"
		     "attached to elements or points objects with tensor\n"
		     "values are aupported. (%s)\n",
		     argv[0], inFileStr, errMsg);
    }
  }
  if(ok)   
  {
    if((fP = (strcmp(outFileStr, "-")?
        fopen(outFileStr, "w"): stdin)) == NULL)
    {
      ok = 0;
      errNum = WLZ_ERR_WRITE_EOF;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to open output file %s (%s)\n",
		     argv[0], outFileStr, errMsg);
    }
  }
  if(ok)   
  {
    switch(inObj->type)
    {
      case WLZ_CMESH_3D:
        errNum = WlzVTKTensorFromCMesh(argv[0], inFileStr, fP, inObj);
	break;
      case WLZ_POINTS:
        errNum = WlzVTKTensorFromPoints(argv[0], inFileStr, fP, inObj);
	break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;   
	break;
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to write tesnsor data to file %s (%s).\n",
		     argv[0], outFileStr, errMsg);
      
    }
  }
  if(fP && strcmp(outFileStr, "-"))
  {
    (void )fclose(fP);
  }
  (void )WlzFreeObj(inObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-h] [-o<out vtk file>] [-s<x>,<y>[,<z>]]\n"
    "\t\t[<in woolz file>]\n"
    "Version: %s\n"
    "Options:\n"
    "  -h        Help, prints this usage message.\n"
    "  -o        Output vtk file name.\n"
    "  -s	 Sampling interval.\n"
    "Reads either a 3D Woolz conforming mesh object with tensor data\n"
    "attached to it's elements or a points object with 3D points and\n"
    "tensor values, then writes the tensor data to a VTK polydata file\n"
    "with points at either the conforming mesh centroids or at given\n"
    "points.\n"
    "By default files are read from the standard input and written to\n"
    "the standard output.\n"
    "Example:\n"
    "  %s -o out.vtk in.wlz\n"
    "Creates a VTK polydata file with tensor dataset attributes from the\n"
    "given Woolz file.\n",
    argv[0],
    WlzVersion(),
    argv[0]);
  }
  return(!ok);
}
int		main(int argc, char *argv[])
{
  int		ok = 1,
  		option,
  		usage = 0,
		markerSep = 16,
		markerSz = 4;
  FILE		*fP = NULL;
  char		*iFile,
  		*oFile;
  const char	*errMsg;
  WlzObject	*iObj = NULL,
  		*oObj = NULL;
  WlzMarkerType	markerType = WLZ_MARKER_SPHERE;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  static char   optList[] = "ho:s:t:z:";
  const char    defFile[] = "-";

  opterr = 0;
  iFile = (char *)defFile;
  oFile = (char *)defFile;
  while(ok && ((option = getopt(argc, argv, optList)) != EOF))
  {
    switch(option)
    {
      case 'o':
        oFile = optarg;
	break;
      case 's':
	if(sscanf(optarg, "%d", &markerSep) != 1)
	{
	  usage = 1;
	}
        break;
      case 't':
	markerType = WlzStringToMarkerType(optarg, &errNum);
	if(errNum != WLZ_ERR_NONE)
	{
	  usage = 1;
	}
        break;
      case 'z':
	if(sscanf(optarg, "%d", &markerSz) != 1)
	{
	  usage = 1;
	}
        break;
      case 'h': /* FALLTROUGH */
      default:
	usage = 1;
	break;
    }
  }
  if(usage == 0)
  {
    if((oFile == NULL) || (*oFile == '\0') ||
       (iFile == NULL) || (*iFile == '\0'))
    {
      usage = 1;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      iFile = *(argv + optind);
    }
  }
  ok = !usage;
  if(ok)
  {
    if((fP = (strcmp(iFile, "-")? fopen(iFile, "r"): stdin)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Failed to open input file %s.\n",
		     argv[0], iFile);
    }
  }
  if(ok)
  {
    iObj = WlzReadObj(fP, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to read input domain object, %s.\n",
		     argv[0], errMsg);
    }
  }
  if(fP && strcmp(iFile, "-"))
  {
    (void )fclose(fP);
  }
  if(ok)
  {
    oObj = WlzMarkerLattice(iObj, markerType, markerSz, markerSep, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: Failed to create domain from vertices (%s).\n",
      		     argv[0],
		     errMsg);
    }
  }
  if(ok)
  {
    if((fP = (strcmp(oFile, "-")? fopen(oFile, "w"): stdout)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Failed to open output file %s.\n",
		     argv[0], oFile);
    }
  }
  if(ok)
  {
    errNum = WlzWriteObj(fP, oObj);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to write output object, %s.\n",
		     argv[0], errMsg);
    }
  }
  if(fP && strcmp(oFile, "-"))
  {
    (void )fclose(fP);
  }
  (void )WlzFreeObj(iObj);
  (void )WlzFreeObj(oObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-h] [-o<output>] [-s #] [-t <type>] [-z #]\n"
    "                                  [<input>]\n"
    "Version: %s\n"
    "Options:\n"
    "  -h  Output this usage message.\n"
    "  -o  Output file name, default is the standard output.\n"
    "  -s  Marker separation.\n"
    "  -t  Marker type: Only valid type is 'sphere'.\n"
    "  -z  Marker size.\n"
    "Reads either a 2D or 3D spatial domain object from a given file or\n"
    "the standard input (default). A new domainis then constructed which\n"
    "covers the given domain with a lattice of markers.\n",
    argv[0],
    WlzVersion());
  }
  return(!ok);
}
Exemple #29
0
/*!
* \return	Autocorrelated object or NULL on error.
* \ingroup	WlzRegistration
* \brief	Computes the autocorrelation of the given 2D object, see
*		WlzAutoCor().
* \param	gObj			Given object.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzAutoCor2D(WlzObject *gObj, WlzErrorNum *dstErr)
{
  WlzIVertex2	aSz,
		wSz,
		aOrg,
  		wOrg;
  WlzIBox2	box;
  double	**wAr = NULL,
  		**aAr = NULL;
  WlzObject     *aObj = NULL;
  WlzErrorNum   errNum = WLZ_ERR_NONE;

  if(gObj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(gObj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(gObj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  if(errNum == WLZ_ERR_NONE)
  {
    box = WlzBoundingBox2I(gObj, &errNum);
    aSz.vtX = box.xMax - box.xMin + 1;
    aSz.vtY = box.yMax - box.yMin + 1;
    /* Make sure aSz is even in x and y. */
    if((aSz.vtX & 1) != 0)
    {
      aSz.vtX += 1;
    }
    if((aSz.vtY & 1) != 0)
    {
      aSz.vtY += 1;
    }
    wOrg.vtX = box.xMin - (aSz.vtX / 2);
    wOrg.vtY = box.yMin - (aSz.vtY / 2);
    wSz.vtX = aSz.vtX * 2;
    wSz.vtY = aSz.vtY * 2;
    (void )AlgBitNextPowerOfTwo((unsigned int *)&(wSz.vtX), wSz.vtX);
    (void )AlgBitNextPowerOfTwo((unsigned int *)&(wSz.vtY), wSz.vtY);
    errNum = WlzToArray2D((void ***)&wAr, gObj, wSz, wOrg, 0, WLZ_GREY_DOUBLE);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    (void )AlgAutoCorrelate2D(wAr, wSz.vtX, wSz.vtY);
    if(AlcDouble2Malloc(&aAr, aSz.vtY, aSz.vtX) != ALC_ER_NONE)
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    WlzAutoCorRearrange2D(aAr, aSz, wAr, wSz);
    aOrg.vtX = -(aSz.vtX / 2);
    aOrg.vtY = -(aSz.vtY / 2);
    aObj = WlzFromArray2D((void **)aAr, aSz, aOrg,
                          WLZ_GREY_DOUBLE, WLZ_GREY_DOUBLE, 0.0, 1.0,
			  0, 0, &errNum);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    if(aObj != NULL)
    {
      (void )WlzFreeObj(aObj);
    }
  }
  (void )Alc2Free((void **)wAr);
  (void )Alc2Free((void **)aAr);
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(aObj);
}
Exemple #30
0
/*! 
* \ingroup      WlzThreshold
* \brief        Apply independent thresholds to each colour channel
 independently and combine according to the settings encoded in
 combineMode. Each channel can have one of two modes: WLZ_BO_AND
 and WLZ_BO_OR. These are encoded into a single mode variable using
 the RGBA macro, e.g.:
 WLZ_RGBA_RGBA_SET(combineMode, redMode, greenMode, blueMode, 255);

 The macro WLZ_RGBA_RED_GET(combineMode) will return redMode and
 similarly for green and blue.
*
* \return       Thresholded object
* \param    obj	Object to be thresholded
* \param    lowVal	RGB low values
* \param    highVal	RGB high values
* \param    combineMode	Combination rules as an RGBA encoded unsigned integer
* \param    dstErr	Error return
* \par      Source:
*                WlzRGBAThreshold.c
*/
WlzObject *WlzRGBAMultiThreshold(
  WlzObject	*obj,
  WlzPixelV	lowVal,
  WlzPixelV	highVal,
  WlzUInt	combineMode,
  WlzErrorNum	*dstErr)
{
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*rtnObj=NULL;
  WlzObject	*obj1, *obj2;
  WlzValues	values;
  WlzCompoundArray	*cobj=NULL;
  int		low[3], high[3];
  WlzUInt	mode[3]; 

  /* check inputs */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    /* must be grey-type RGBA or compound with at least three channels */
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
    case WLZ_3D_DOMAINOBJ:
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      else {
	/* create compound object */
	if((cobj = WlzRGBAToCompound(obj, WLZ_RGBA_SPACE_RGB,
	                             &errNum)) != NULL){
	  cobj = (WlzCompoundArray *) WlzAssignObject((WlzObject *) cobj,
						      &errNum);
	}
      }
      break;

    case WLZ_TRANS_OBJ:
      if((obj1 = WlzRGBAMultiThreshold(obj->values.obj, lowVal, highVal,
				       combineMode, &errNum)) != NULL){
	values.obj = WlzAssignObject(obj1, NULL);
	rtnObj = WlzMakeMain(obj->type, obj->domain, values,
			     NULL, obj, &errNum);
      }
      break;

    case WLZ_COMPOUND_ARR_1:
    case WLZ_COMPOUND_ARR_2:
      cobj = (WlzCompoundArray *) WlzAssignObject(obj, &errNum);
      if( cobj->n < 3 ){
	errNum = WLZ_ERR_OBJECT_DATA;
	WlzFreeObj((WlzObject *) cobj);
      }
      else if((cobj->o[0]->values.core == NULL) ||
	      (cobj->o[1]->values.core == NULL) ||
	      (cobj->o[2]->values.core == NULL)){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      break;

    case WLZ_EMPTY_OBJ:
      rtnObj = WlzMakeEmpty(&errNum);
      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  if((errNum == WLZ_ERR_NONE) && (rtnObj == NULL)){
    if((lowVal.type != WLZ_GREY_RGBA) ||
       (highVal.type != WLZ_GREY_RGBA)){
      errNum = WLZ_ERR_PARAM_TYPE;
    }
    else {
      low[0] = WLZ_RGBA_RED_GET(lowVal.v.rgbv);
      low[1] = WLZ_RGBA_GREEN_GET(lowVal.v.rgbv);
      low[2] = WLZ_RGBA_BLUE_GET(lowVal.v.rgbv);
      high[0] = WLZ_RGBA_RED_GET(highVal.v.rgbv);
      high[1] = WLZ_RGBA_GREEN_GET(highVal.v.rgbv);
      high[2] = WLZ_RGBA_BLUE_GET(highVal.v.rgbv);
    }
  }

  if((errNum == WLZ_ERR_NONE) && (rtnObj == NULL)){
    mode[0] = WLZ_RGBA_RED_GET(combineMode);
    mode[1] = WLZ_RGBA_GREEN_GET(combineMode);
    mode[2] = WLZ_RGBA_BLUE_GET(combineMode);
  }

  /* get thresholded channels */
  if((errNum == WLZ_ERR_NONE) &&
     (cobj != NULL) && (rtnObj == NULL)){
    WlzObject	*objs[3];
    int		i;
    WlzPixelV	threshV;

    for(i=0; i < 3; i++){
      threshV.type = WLZ_GREY_INT;
      threshV.v.inv = low[i];
      if((obj1 = WlzThreshold(cobj->o[i], threshV, WLZ_THRESH_HIGH,
      			      &errNum)) != NULL){
	obj1 = WlzAssignObject(obj1, &errNum);
	threshV.v.inv = high[i] + 1;
	if((obj2 = WlzThreshold(obj1, threshV, WLZ_THRESH_LOW,
	                        &errNum)) != NULL){
	  objs[i] = WlzAssignObject(obj2, &errNum);
	}
	else {
	  objs[i] = NULL;
	}
	WlzFreeObj(obj1);
      }
      else {
	objs[i] = NULL;
      }
    }

    /* combine according to mode
       what to do here? AND against a channel implies that the threshold
       constraint must be satisfied, OR implies it may be satisfied so
       all AND implies intersection, all OR implies union. Otherwise union
       of ORs and intersect with the ANDs. What about XOR? */
    /* find union of all then intersect with ANDs */
    obj1 = WlzAssignObject(WlzMakeEmpty(&errNum), NULL);
    for(i=0; (i < 3) && (errNum == WLZ_ERR_NONE); i++){
      if( objs[i] ){
	obj2 = WlzUnion2(obj1, objs[i], &errNum);
	WlzFreeObj(obj1);
	obj1 = WlzAssignObject(obj2, &errNum);
      }
    }
    for(i=0; i < 3; i++){
      if( objs[i] ){
	if( (mode[i] == WLZ_BO_AND) && (errNum == WLZ_ERR_NONE) ){
	  obj2 = WlzIntersect2(obj1, objs[i], &errNum);
	  WlzFreeObj(obj1);
	  obj1 = WlzAssignObject(obj2, &errNum);
	}
	WlzFreeObj(objs[i]);
      }
    }

    /* create the return object and add grey-table if possible */
    if( obj1 ){
      if( WlzIsEmpty(obj1, &errNum) ){
	rtnObj = WlzMakeMain(obj1->type, obj1->domain, obj1->values,
			     NULL, NULL, &errNum);
      }
      else {
	if( obj1->type == obj->type ){
	  rtnObj = WlzMakeMain(obj1->type, obj1->domain, obj->values,
			       NULL, NULL, &errNum);
	}
	else {
	  rtnObj = WlzMakeMain(obj1->type, obj1->domain, obj1->values,
			       NULL, NULL, &errNum);
	}
      }
      WlzFreeObj(obj1);
    }
  }

  if( cobj ){
    WlzFreeObj((WlzObject *) cobj);
  }

  /* check error and return */
  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}