Exemplo n.º 1
0
/*!
* \ingroup	JWlz
* \brief	Free's a temporary 2D array.
* \param	aDat			Array data structure.
* \param	aSz			Array size.
* \param	dSKey			Data structure identification.
* \param	isCpy			Copy flag for JNI functions.
*/
void		WlzJavaArray2DFree(void *aDat, WlzIVertex2 aSz,
			      int dSKey, jboolean isCpy)
{
  if(isCpy && aDat && (aSz.vtX > 0) && (aSz.vtY > 0))
  {
    switch(dSKey)
    {
      case WLZ_JPM_KEY_INT_ARY2:   /* FALLTHROUGH */
      case WLZ_JPM_KEY_SHORT_ARY2: /* FALLTHROUGH */
      case WLZ_JPM_KEY_BYTE_ARY2:  /* FALLTHROUGH */
      case WLZ_JPM_KEY_FLOAT_ARY2: /* FALLTHROUGH */
      case WLZ_JPM_KEY_DOUBLE_ARY2:
        Alc2Free((void **)aDat);
	break;
      default:
	break;
    }
  }
}
Exemplo n.º 2
0
/*!
* \return	Object read from file.
* \ingroup	WlzExtFF
* \brief	Reads a 2D Woolz object from the given file using the given
* 		(2D) file format.
* \param	fP			Given file.
* \param	fFmt			Given file format (must be a 2D file
* 					format).
* \param	dstErr			Destination error number ptr, may be
* 					NULL.
*/
static WlzObject *WlzEffReadObjStack2D(FILE *fP, WlzEffFormat fFmt,
				       WlzErrorNum *dstErr)
{
  WlzObject	*obj = NULL;
  unsigned char **data = NULL;
  WlzIVertex2	imgSz,
  		imgOrg;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  imgSz.vtX = 0;
  imgSz.vtY = 0;
  imgOrg.vtX = 0;
  imgOrg.vtY = 0;
  errNum = WlzEffReadObjStackData2D(fP, fFmt, &imgSz, &data);
  if(errNum == WLZ_ERR_NONE)
  {
    obj = WlzFromArray2D((void **)data, imgSz, imgOrg,
    			 WLZ_GREY_UBYTE, WLZ_GREY_UBYTE,
			 0.0, 1.0, 0, 1, &errNum);
  }
  if(data)
  {
    if(obj)
    {
      AlcFree(data); 			    /* **data used by object */
    }
    else
    {
      Alc2Free((void **)data);
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(obj);
}
int main(int	argc,
	 char	**argv)
{

  FILE	        *inFile = NULL;   /* used to read Woolz object */ 
  /* FILE       *outFile = NULL;   used to read Woolz object */
  int           i;
  int           startShell = -10, endShell = -15, startSection = -10, endSection = -15;
  int           startLoop  = -10, endLoop  = -15;
  int           downOrUp = 0;
  int		option;
  int           numP_in_Z= 10;
  int           numOf2DWlzFiles = 0;
  int           sectionLength_N       = 40;
  int           subSubSectionLength_L = sectionLength_N /2;
  int           numberOfSampleP_k     =  2;
  int           numOfTrackUpOrDown    =  5;
  int           startTrackingFile     =  5;
  int           iloop=1, test=0;
  double        DisForInOut = 15, DisForInOutGuid = 15;
  double        minDis = 10.;
  /* char       *outFileStr; unused */
  unsigned char        **TwoDImageFilesNameList;
  char         *ContourFilesNameList = NULL;
  char         *surfacePointFileName = NULL, *surfaceInPointFileName = NULL,
               *surfaceOutPointFileName = NULL;
  /* WlzDVertex3          *SurfacePatchPoints; unused */
  WlzErrorNum	       errNum = WLZ_ERR_NONE;
  AlcErrno             alcErr = ALC_ER_NONE;

  /* read the argument list and check for an input file */
  static char	optList[] = "s:t:n:o:O:i:l:L:j:J:a:A:b:B:c:d:e:E:f:F:g:G:h";

  while( (option = getopt(argc, argv, optList)) != EOF )
  {
      switch( option )
      {
        case 'h':
             usage(argv[0]);
	     return(0);
        case 'L':
	     ContourFilesNameList       = optarg;
	     break;
        case 't':
	 if(sscanf(optarg, "%d", &downOrUp) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
        case 'd':
	 if(sscanf(optarg, "%lg", &minDis) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'f':
	 if(sscanf(optarg, "%lg", &DisForInOut) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'F':
	 if(sscanf(optarg, "%lg", &DisForInOutGuid) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'g':
	 if(sscanf(optarg, "%d", &numOfTrackUpOrDown) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'G':
	 if(sscanf(optarg, "%d", &startTrackingFile) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'n':
	 if(sscanf(optarg, "%d", &numP_in_Z) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'l':
	 if(sscanf(optarg, "%d", &iloop) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'j':
	 if(sscanf(optarg, "%d", &numberOfSampleP_k) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'J':
	 if(sscanf(optarg, "%d", &sectionLength_N) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'c':
	 if(sscanf(optarg, "%d", &subSubSectionLength_L) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'o':
	     /* outFileStr = optarg; unused */
	     break;
       case 's':
	     surfacePointFileName = optarg;
	     break;
       case 'i':
	     surfaceInPointFileName = optarg;
	     break;
       case 'O':
	     surfaceOutPointFileName = optarg;
	     break;
       case 'a':
	 if(sscanf(optarg, "%d", &startShell) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'A':
	 if(sscanf(optarg, "%d", &endShell) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'b':
	 if(sscanf(optarg, "%d", &startSection) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'B':
	 if(sscanf(optarg, "%d", &endSection) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
       case 'e':
	 if(sscanf(optarg, "%d", &startLoop) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
       case 'E':
	 if(sscanf(optarg, "%d", &endLoop) != 1)
	     {
	       printf("read error");
	       exit(1);
	     }
	     break;
	     
        default:
             return(0);
      }
  }

  /*  allocate memory for the file name list */
  alcErr = AlcUnchar2Calloc(&TwoDImageFilesNameList, 50, 120);
  if(alcErr != ALC_ER_NONE)
  {
     printf("allocate memory for 2D array of file list");
     exit(1);

  }
     
  /* Read the contour Wlz file name List */
  if((inFile = fopen(ContourFilesNameList, "r")) == NULL )
  {
        printf("cannot open the 2D image files list file.\n");
        exit(1);
  }
  i=0;
  while(!feof(inFile))
  {
        fscanf(inFile, "%s", *(TwoDImageFilesNameList + i ));
	/*  printf("%s\n", *(TwoDImageFilesNameList + i ) ); */
	i++;
  }
  fclose(inFile); 
  inFile = NULL;
  numOf2DWlzFiles = i-1;

  if( 2 * numOfTrackUpOrDown + 1 > numOf2DWlzFiles)
  {
      printf("there are not enough 2D image files to track.\n");
      exit(0);

  }

  if( ( startTrackingFile - numOfTrackUpOrDown >0 )  ||
      ( startTrackingFile + numOfTrackUpOrDown) >  numOf2DWlzFiles )
      {
        printf("there are not enough 2D image files to track if we use the file as a start.\n");
        exit(0);
      }
    /* ---- output for test ---- */
    /*
    if(test  &&  ( errNum == WLZ_ERR_NONE ) )
    {
      OutPutSectionsForTest(WObjS, WObj2D, outFile, outFileStr, iloop, &errNum);
     }
    */
    /*---------- extract contour and track down or up  to get the surface patch ----------- */
    if( (!test)  && ( errNum == WLZ_ERR_NONE ) )
    {
      /* SurfacePatchPoints = unused */
      (void )WlzGeometryTrackUpAndDown_s(      
							numP_in_Z,
                                                        startTrackingFile,
							numOfTrackUpOrDown,
							DisForInOutGuid,
                                                        DisForInOut,
                                                        TwoDImageFilesNameList,
                                                        numOf2DWlzFiles,
                                                        downOrUp,  
  							sectionLength_N,
  							subSubSectionLength_L,
  							numberOfSampleP_k,
							surfacePointFileName,
							surfaceInPointFileName,
							surfaceOutPointFileName, 
							startShell,
							endShell,
							startSection,
							endSection,
							minDis,
						       &errNum );
    }

   Alc2Free( (void **)TwoDImageFilesNameList);

  return ( 0 );
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
0
/*!
* \return	Woolz error code.
* \ingroup	WlzExtFF
* \brief	Writes the given Woolz object to the given file(s)
*		using the ANALYZE 7.5 file format. The given file name is
*		used to generate the '.hdr' and '.img' filenames.
* \param	gvnFileName		Given file name with .hdr, .img or no
* 					extension.
* \param	obj			Given woolz object.
*/
WlzErrorNum	WlzEffWriteObjAnl(const char *gvnFileName, WlzObject *obj)
{
  int  		cnt = 0;
  double	dMin,
  		dMax;
  FILE		*fP = NULL;
  void	 	*data = NULL;
  WlzGreyP	dataP;
  WlzEffAnlDsr 	dsr;
  WlzGreyType	gType;
  WlzVertex	org,
  		sz;
  char		*fileName = NULL,
  		*hdrFileName = NULL,
		*imgFileName = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  dataP.v = NULL;
  if((gvnFileName == NULL) || (*gvnFileName == '\0'))
  {
    errNum = WLZ_ERR_PARAM_NULL;
  }
  else if(obj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(obj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(obj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else
  {
    errNum = WlzEffAnlFileNames(&fileName, &hdrFileName, &imgFileName,
				gvnFileName);
  }
  /* Fill in the ANALYZE file header data structures. */
  if(errNum == WLZ_ERR_NONE)
  {
    (void )memset(&dsr, 0, sizeof(WlzEffAnlDsr));
    switch(obj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	org.i2.vtX = obj->domain.i->kol1;
	org.i2.vtY = obj->domain.i->line1;
	sz.i2.vtX = obj->domain.i->lastkl - org.i2.vtX + 1;
	sz.i2.vtY = obj->domain.i->lastln - org.i2.vtY + 1;
	if((sz.i2.vtX <= 0) || (sz.i2.vtY <= 0))
	{
	  errNum = WLZ_ERR_DOMAIN_DATA;
	}
	else
	{
	  dsr.dim.dim[0] = 2;
	  dsr.dim.dim[1] = sz.i2.vtX;
	  dsr.dim.dim[2] = sz.i2.vtY;
	  dsr.dim.pixdim[0] = 2;
	  dsr.dim.pixdim[1] = 1.0;
	  dsr.dim.pixdim[2] = 1.0;
	}
        break;
      case WLZ_3D_DOMAINOBJ:
	org.i3.vtX = obj->domain.p->kol1;
	org.i3.vtY = obj->domain.p->line1;
	org.i3.vtZ = obj->domain.p->plane1;
	sz.i3.vtX = obj->domain.p->lastkl - org.i3.vtX + 1;
	sz.i3.vtY = obj->domain.p->lastln - org.i3.vtY + 1;
	sz.i3.vtZ = obj->domain.p->lastpl - org.i3.vtZ + 1;
	if((sz.i3.vtX <= 0) || (sz.i3.vtY <= 0) || (sz.i3.vtZ <= 0))
	{
	  errNum = WLZ_ERR_DOMAIN_DATA;
	}
        else
	{
	  dsr.dim.dim[0] = 3;
	  dsr.dim.dim[1] = sz.i3.vtX;
	  dsr.dim.dim[2] = sz.i3.vtY;
	  dsr.dim.dim[3] = sz.i3.vtZ;
	  dsr.dim.pixdim[0] = 3;
	  dsr.dim.pixdim[1] = obj->domain.p->voxel_size[0];
	  dsr.dim.pixdim[2] = obj->domain.p->voxel_size[1];
	  dsr.dim.pixdim[3] = obj->domain.p->voxel_size[2];
	}
        break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    (void )WlzGreyStats(obj, &gType, &dMin, &dMax, NULL, NULL, NULL, NULL,
    			&errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dsr.dim.glMax = (int )ceil(dMax);
    dsr.dim.glMin = (int )floor(dMin);
    switch(gType)
    {
      case WLZ_GREY_INT:
        dsr.dim.dataType = WLZEFF_ANL_DT_SIGNED_INT;
        dsr.dim.bitPix = 32;
        break;
      case WLZ_GREY_SHORT:
        dsr.dim.dataType = WLZEFF_ANL_DT_SIGNED_SHORT;
        dsr.dim.bitPix = 16;
	break;
      case WLZ_GREY_UBYTE:
        dsr.dim.dataType = WLZEFF_ANL_DT_UNSIGNED_CHAR;
        dsr.dim.bitPix = 8;
	break;
      case WLZ_GREY_FLOAT:
        dsr.dim.dataType = WLZEFF_ANL_DT_FLOAT;
        dsr.dim.bitPix = 32;
	break;
      case WLZ_GREY_DOUBLE:
        dsr.dim.dataType = WLZEFF_ANL_DT_DOUBLE;
        dsr.dim.bitPix = 64;
	break;
      default:
	errNum = WLZ_ERR_GREY_TYPE;
        break;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dsr.hk.hdrSz = 348;
    dsr.hk.regular = 'r';
    dsr.hk.extents = 16384;
    (void )strcpy(dsr.hist.descrip, "Converted from Woolz");
    (void )strcpy(dsr.hist.originator, "Woolz");
    (void )strcpy(dsr.hist.generated, "Woolz");
  }
  /* Get Woolz object's values as an array. */
  if(WLZ_ERR_NONE == errNum)
  {
    switch(obj->type)
    {
      case WLZ_2D_DOMAINOBJ:
        cnt = sz.i2.vtX * sz.i2.vtY;
	errNum = WlzToArray2D((void ***)&data, obj, sz.i2, org.i2, 0, gType);
	if(errNum == WLZ_ERR_NONE)
	{
	  switch(gType)
	  {
	    case WLZ_GREY_INT:
	      dataP.inp = *(int **)data;
	      break;
	    case WLZ_GREY_SHORT:
	      dataP.shp = *(short **)data;
	      break;
	    case WLZ_GREY_UBYTE:
	      dataP.ubp = *(WlzUByte **)data;
	      break;
	    case WLZ_GREY_FLOAT:
	      dataP.flp = *(float **)data;
	      break;
	    case WLZ_GREY_DOUBLE:
	      dataP.dbp = *(double **)data;
	      break;
	    default:
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	  }
	}
        break;
      case WLZ_3D_DOMAINOBJ:
        cnt = sz.i3.vtX * sz.i3.vtY * sz.i3.vtZ;
	errNum = WlzToArray3D((void ****)&data, obj, sz.i3, org.i3, 0, gType);
	if(errNum == WLZ_ERR_NONE)
	{
	  switch(gType)
	  {
	    case WLZ_GREY_INT:
	      dataP.inp = **(int ***)data;
	      break;
	    case WLZ_GREY_SHORT:
	      dataP.shp = **(short ***)data;
	      break;
	    case WLZ_GREY_UBYTE:
	      dataP.ubp = **(WlzUByte ***)data;
	      break;
	    case WLZ_GREY_FLOAT:
	      dataP.flp = **(float ***)data;
	      break;
	    case WLZ_GREY_DOUBLE:
	      dataP.dbp = **(double ***)data;
	      break;
	    default:
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	  }
	}
        break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
        break;
    }
  }
  /* Open the ANALYZE .hdr file and write the header information. */
  if(errNum == WLZ_ERR_NONE)
  {
    if((fP = fopen(hdrFileName, "w")) == NULL)
    {
      errNum = WLZ_ERR_WRITE_EOF;
    }
#ifdef _WIN32
    else if(_setmode(_fileno(fP), 0x8000) == -1)
    {
	errNum = WLZ_ERR_READ_EOF;
    }
#endif
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzEffWriteAnlHdrKey(fP, &dsr);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzEffWriteAnlHdrImageDim(fP, &dsr);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzEffWriteAnlHdrDataHistory(fP, &dsr);
  }
  if(fP)
  {
    (void )fclose(fP);
    fP = NULL;
  }
  /* Open the ANALYZE .img file and write the image data. */
  if(errNum == WLZ_ERR_NONE)
  {
    if((fP = fopen(imgFileName, "w")) == NULL)
    {
      errNum = WLZ_ERR_WRITE_EOF;
    }
#ifdef _WIN32
    else if(_setmode(_fileno(fP), 0x8000) == -1)
    {
	errNum = WLZ_ERR_READ_EOF;
    }
#endif
  }
  if(errNum == WLZ_ERR_NONE)
  {
    switch(gType)
    {
      case WLZ_GREY_INT:
	errNum = WlzEffWriteAnlInt(fP, cnt, dataP.inp);
        break;
      case WLZ_GREY_SHORT:
	errNum = WlzEffWriteAnlShort(fP, cnt, dataP.shp);
        break;
      case WLZ_GREY_UBYTE:
	errNum = WlzEffWriteAnlChar(fP, cnt, dataP.ubp);
        break;
      case WLZ_GREY_FLOAT:
	errNum = WlzEffWriteAnlFloat(fP, cnt, dataP.flp);
        break;
      case WLZ_GREY_DOUBLE:
	errNum = WlzEffWriteAnlDouble(fP, cnt, dataP.dbp);
	break;
      default:
        break;
    }
  }
  if(fP)
  {
    (void )fclose(fP);
  }
  if(data)
  {
    switch(obj->type)
    {
      case WLZ_2D_DOMAINOBJ:
	Alc2Free((void **)data);
	break;
      case WLZ_3D_DOMAINOBJ:
	Alc3Free((void ***)data);
	break;
      default:
	break;
    }
  }
  (void )AlcFree(fileName);
  (void )AlcFree(hdrFileName);
  (void )AlcFree(imgFileName);
  return(errNum);
}
Exemplo n.º 6
0
/*!
* \return	New Woolz domain object with maximal domain and grey
*		values which encode the gradient's direction or NULL
*		on error.
* \ingroup	WlzFeatures
* \brief	Computes the maximal domain and gradient direction of
*               given Woolz 2D domain object.
* \note         All the objects domains are known to be the same.
* \param	grdM			Gradient magnitude.
* \param	grdY			Gradient (partial derivative)
*                                       through lines.
* \param	grdX			Gradient (partial derivative)
*                                       through columns.
* \param	minThrV			Minimum gradient value to
*                                       consider.
* \param	dstErr			Destination error pointer, may
*                                       be null.
*/
static WlzObject *WlzNMSuppress2D(WlzObject *grdM,
				  WlzObject *grdY, WlzObject *grdX,
				  WlzPixelV minThrV, WlzErrorNum *dstErr)
{
  int		idN,
		inLen,
		outLen,
  		inLnIdx = 0;
  WlzGreyType	gType,
  		bufType;
  WlzIVertex2	bufSz,
  		inPos,
		outPos,
		orgPos;
  WlzValues	tmpVal;
  WlzDomain	dstDom,
  		grdDom;
  WlzIntervalWSpace tmpIWSp = {0},
  		grdMIWSp = {0},
  		grdYIWSp = {0},
		grdXIWSp = {0};
  WlzGreyWSpace tmpGWSp,
  		grdMGWSp,
  		grdYGWSp,
		grdXGWSp;
  WlzPixelV	zeroV;
  WlzGreyP	grdMBufGP,
  		grdYBufGP,
		grdXBufGP;
  WlzDynItvPool pool;
  WlzObject	*dstObj = NULL,
  		*tmpObj = NULL;
  void 		*grdYBuf = NULL,
		*grdXBuf = NULL;
  void		**grdMBuf = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  tmpVal.core = NULL;
  pool.itvBlock = NULL;
  dstDom.core = NULL;
  if((grdM->type != WLZ_2D_DOMAINOBJ) ||
     (grdY->type != WLZ_2D_DOMAINOBJ) ||
     (grdX->type != WLZ_2D_DOMAINOBJ))
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if((grdM->domain.core == NULL) ||
          (grdY->domain.core == NULL) ||
          (grdX->domain.core == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if((grdM->values.core == NULL) ||
  	  (grdY->values.core == NULL) ||
	  (grdX->values.core == NULL))
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else
  {
    /* Find required buffer type (WLZ_GREY_DOUBLE or WLZ_GREY_INT). */
    bufType = WLZ_GREY_INT;
    gType = WlzGreyTableTypeToGreyType(grdM->values.core->type, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      if((gType == WLZ_GREY_FLOAT) || (gType == WLZ_GREY_DOUBLE))
      {
	bufType = WLZ_GREY_DOUBLE;
      }
      else
      {
	gType = WlzGreyTableTypeToGreyType(grdY->values.core->type, &errNum);
	if(errNum == WLZ_ERR_NONE)
	{
	  if((gType == WLZ_GREY_FLOAT) || (gType == WLZ_GREY_DOUBLE))
	  {
	    bufType = WLZ_GREY_DOUBLE;
	  }
	  else
	  {
	    gType = WlzGreyTableTypeToGreyType(grdX->values.core->type,
	    				       &errNum);
	    if(errNum == WLZ_ERR_NONE)
	    {
	      if((gType == WLZ_GREY_FLOAT) || (gType == WLZ_GREY_DOUBLE))
	      {
		bufType = WLZ_GREY_DOUBLE;
	      }
	    }
	  }
	}
      }
    }
  }
  /* Convert minimum gradient threshold value. */
  if(errNum == WLZ_ERR_NONE)
  {
    if(bufType == WLZ_GREY_INT)
    {
      errNum = WlzValueConvertPixel(&minThrV, minThrV, WLZ_GREY_INT);
    }
    else /* bufType == WLZ_GREY_DOUBLE */
    {
      errNum = WlzValueConvertPixel(&minThrV, minThrV, WLZ_GREY_DOUBLE);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    grdDom = grdM->domain;
    /* Make destination object with WLZ_GREY_UBYTE greys. */
    zeroV.type = WLZ_GREY_UBYTE;
    zeroV.v.inv = 0;
    tmpVal.v = WlzNewValueTb(grdM, WlzGreyTableType(WLZ_GREY_TAB_RAGR,
						    WLZ_GREY_UBYTE, NULL),
			     zeroV, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      /* Use the input domain while calculating the new maximal domain. */
      tmpObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, grdM->domain, tmpVal,
			   NULL, NULL, &errNum);
    }
  }
  /* Initialize the memory pool with some size of block. Any +ve number
   * greater than the maximum number of intervals in any destination line
   * would work but the fewer allocations then the more efficient the code,
   * hence this attempt to guess the required number of intervals in the
   * destination domain. */
  if(errNum == WLZ_ERR_NONE)
  {
    pool.itvsInBlock = (((grdDom.i->lastkl - grdDom.i->kol1 + 1) *
			(grdDom.i->lastln - grdDom.i->line1 + 1)) / 64) +
		       grdDom.i->lastkl - grdDom.i->kol1 + 1024;
  }
  /* Make gradient buffers. */
  if(errNum == WLZ_ERR_NONE)
  {
    bufSz.vtY = 3;
    bufSz.vtX = grdDom.i->lastkl - grdDom.i->kol1 + 1;
    if(bufType == WLZ_GREY_INT)
    {
      if((AlcInt2Malloc((int ***)&grdMBuf,
			bufSz.vtY, bufSz.vtX) != ALC_ER_NONE) ||
	 ((grdYBuf = AlcMalloc(sizeof(int) * bufSz.vtX)) == NULL) ||
	 ((grdXBuf = AlcMalloc(sizeof(int) * bufSz.vtX)) == NULL))
      {
	errNum = WLZ_ERR_MEM_ALLOC;
      }
      else
      {
	grdYBufGP.inp = (int *)grdYBuf;
	grdXBufGP.inp = (int *)grdXBuf;
      }
    }
    else /* bufType == WLZ_GREY_DOUBLE */
    {
      if((AlcDouble2Malloc((double ***)&grdMBuf,
			   bufSz.vtY, bufSz.vtX) != ALC_ER_NONE) ||
	 ((grdYBuf = AlcMalloc(sizeof(double) * bufSz.vtX)) == NULL) ||
	 ((grdXBuf = AlcMalloc(sizeof(double) * bufSz.vtX)) == NULL))
      {
	errNum = WLZ_ERR_MEM_ALLOC;
      }
      else
      {
	grdYBufGP.dbp = (double *)grdYBuf;
	grdXBufGP.dbp = (double *)grdXBuf;
      }
    }
  }
  /* Make destination interval domain with interval lines but not intervals. */
  if(errNum == WLZ_ERR_NONE)
  {
    dstDom.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_INTVL,
    				     grdDom.i->line1, grdDom.i->lastln,
				     grdDom.i->kol1, grdDom.i->lastkl,
				     &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    /* Scan down through the gradient objects. */
    if(((errNum = WlzInitGreyScan(tmpObj,
    				  &tmpIWSp, &tmpGWSp)) == WLZ_ERR_NONE) &&
       ((errNum = WlzInitGreyScan(grdM,
    				  &grdMIWSp, &grdMGWSp)) == WLZ_ERR_NONE) &&
       ((errNum = WlzInitGreyScan(grdY,
    				  &grdYIWSp, &grdYGWSp)) == WLZ_ERR_NONE) &&
       ((errNum = WlzInitGreyScan(grdX,
    				  &grdXIWSp, &grdXGWSp)) == WLZ_ERR_NONE))
    {
      orgPos.vtX = grdDom.i->kol1;
      orgPos.vtY = grdDom.i->line1;
      while((errNum == WLZ_ERR_NONE) &&
            ((errNum = WlzNextGreyInterval(&grdMIWSp)) == WLZ_ERR_NONE))
      {
        inLen = grdMIWSp.rgtpos - grdMIWSp.lftpos + 1;
	inPos.vtX = grdMIWSp.lftpos - orgPos.vtX;
	/* Process any lines between this and the last by clearing the
	 * gradient magnitude buffer . */
	if(grdMIWSp.nwlpos > 0)
	{
	  idN = (grdMIWSp.nwlpos >= 3)? 3: grdMIWSp.nwlpos;
	  while(--idN >= 0)
	  {
	    inPos.vtY = grdMIWSp.linpos - orgPos.vtY - idN;
	    inLnIdx = (3 + inPos.vtY) % 3;
	    if(bufType == WLZ_GREY_INT)
	    {
	      WlzValueSetInt(*((int **)grdMBuf + inLnIdx), 0,
	      		     bufSz.vtX);
	    }
	    else /* bufType == WLZ_GREY_DOUBLE */
	    {
	      WlzValueSetDouble(*((double **)grdMBuf + inLnIdx), 0,
	      			bufSz.vtX);
	    }
	  }
	}
	/* Copy intervals to values buffers. */
	if(bufType == WLZ_GREY_INT)
	{
	  grdMBufGP.inp = *((int **)grdMBuf + inLnIdx);
	}
	else /* bufType == WLZ_GREY_DOUBLE */
	{
	  grdMBufGP.dbp = *((double **)grdMBuf + inLnIdx);
	}
	WlzValueCopyGreyToGrey(grdMBufGP, inPos.vtX, bufType,
			       grdMGWSp.u_grintptr, 0, grdMGWSp.pixeltype,
			       inLen);
	if(grdMIWSp.intrmn == 0)
	{
	  while((errNum == WLZ_ERR_NONE) &&
	        (tmpIWSp.linpos < grdMIWSp.linpos))
	  {
	    outPos.vtY = tmpIWSp.linpos - orgPos.vtY;
	    if(outPos.vtY >= 0)
	    {
	      outLen = tmpIWSp.rgtpos - tmpIWSp.lftpos + 1;
	      outPos.vtX = tmpIWSp.lftpos - orgPos.vtX;
	      WlzValueCopyGreyToGrey(grdYBufGP, 0, bufType,
				     grdYGWSp.u_grintptr, 0,
				     grdYGWSp.pixeltype, outLen);
	      WlzValueCopyGreyToGrey(grdXBufGP, 0, bufType,
				     grdXGWSp.u_grintptr, 0,
				     grdXGWSp.pixeltype, outLen);
	      if(bufType == WLZ_GREY_INT)
	      {
		errNum = WlzNMSuppress2DBufI(dstDom.i,
					     (int **)grdMBuf,
					     (int *)grdYBuf,
					     (int *)grdXBuf,
					     &pool,
					     tmpGWSp.u_grintptr.ubp,
					     outLen, outPos, orgPos,
					     minThrV.v.inv);
	      }
	      else /* bufType == WLZ_GREY_DOUBLE */
	      {
		errNum = WlzNMSuppress2DBufD(dstDom.i,
				    	     (double **)grdMBuf,
				    	     (double *)grdYBuf,
					     (double *)grdXBuf,
					     &pool,
					     tmpGWSp.u_grintptr.ubp,
					     outLen, outPos, orgPos,
					     minThrV.v.dbv);
	      }
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      errNum = WlzNextGreyInterval(&tmpIWSp);
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      errNum = WlzNextGreyInterval(&grdYIWSp);
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      errNum = WlzNextGreyInterval(&grdXIWSp);
	    }
	  }
        }
      }
      if(errNum == WLZ_ERR_EOO)
      {
        errNum = WLZ_ERR_NONE;
      }
    }
    if(tmpIWSp.gryptr == &tmpGWSp)
    {
      (void )WlzEndGreyScan(&tmpIWSp, &tmpGWSp);
    }
    if(grdMIWSp.gryptr == &grdMGWSp)
    {
      (void )WlzEndGreyScan(&grdMIWSp, &grdMGWSp);
    }
    if(grdYIWSp.gryptr == &grdYGWSp)
    {
      (void )WlzEndGreyScan(&grdYIWSp, &grdYGWSp);
    }
    if(grdXIWSp.gryptr == &grdXGWSp)
    {
      (void )WlzEndGreyScan(&grdXIWSp, &grdXGWSp);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if((errNum = WlzStandardIntervalDomain(dstDom.i)) == WLZ_ERR_NONE)
    {
      dstObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, dstDom, tmpVal,
			   NULL, NULL, &errNum);
    }
  }
  if(tmpObj)
  {
    WlzFreeObj(tmpObj);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    if(tmpObj == NULL)
    {
      if(dstDom.core)
      {
        (void )WlzFreeDomain(dstDom);
      }
      if(tmpVal.core)
      {
        (void )WlzFreeValues(tmpVal);
      }
    }
  }
  if(grdMBuf)
  {
    Alc2Free(grdMBuf);
  }
  if(grdYBuf)
  {
    AlcFree(grdYBuf);
  }
  if(grdXBuf)
  {
    AlcFree(grdXBuf);
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dstObj);
}
Exemplo n.º 7
0
/*! 
* \return       New object with the rojection.
* \ingroup      WlzTransform
* \brief        Use the view transform to define a projection from
*		3D to 2D and then project the object onto this plane.
*		The object supplied to this function must be a 3D
*		spatial domain object (WLZ_3D_DOMAINOBJ) with either
*		no values or for integration WLZ_GREY_UBYTE values.
*		Integration will assign each output pixel the sum of
*		all input voxels mapped via either the domain density
*		or the voxel density.
*		The integration is controled by the integrate parameter
*		with valid values:
*		WLZ_PROJECT_INT_MODE_NONE - a "shadow domain" without values
*               is computed,
*		WLZ_PROJECT_INT_MODE_DOMAIN - the voxels of the domain are
*		integrated using
*		\f[
		p = \frac{1}{255} n d
                \f]
*		WLZ_PROJECT_INT_MODE_VALUES - the voxel values are integrated
*		using
*		\f[
		p = \frac{1}{255} \sum{l\left[v\right]}.
		\f]
*		Where
*		  \f$p\f$ is the projected image value,
*		  \f$n\f$ is the number of voxels projected for \f$p\f$,
*		  \f$d\f$ is the density of domain voxels,
*		  \f$l\f$ is the voxel value density look up table and
*		  \f$v\f$ is a voxel value.
* \param	obj			The given object.
* \param	vStr			Given view structure defining the
* 					projection plane.
* \param	intMod			This may take three values:
* 					WLZ_PROJECT_INT_MODE_NONE,
* 					WLZ_PROJECT_INT_MODE_DOMAIN or
* 					WLZ_PROJECT_INT_MODE_VALUES.
* \param	denDom			Density of domain voxels this value
* 					is not used unless the integration
* 					mode is WLZ_PROJECT_INT_MODE_DOMAIN.
* \param	denVal			Density look up table for object
* 					voxel density values which must be
* 					an array of 256 values. This may be
* 					NULL if the integration mode is not
* 					WLZ_PROJECT_INT_MODE_VALUES.
* \param	depth			If greater than zero, the projection
* 					depth perpendicular to the viewing
* 					plane.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject 	*WlzProjectObjToPlane(WlzObject *obj,
  				WlzThreeDViewStruct *vStr,
  				WlzProjectIntMode intMod,
				WlzUByte denDom, WlzUByte *denVal,
				double depth, WlzErrorNum *dstErr)
{
  int		nThr = 1,
		itvVal = 0;
  WlzIVertex2	prjSz;
  WlzIBox2	prjBox = {0};
  double	pln[4];
  WlzObject	*bufObj = NULL,
  		*prjObj = NULL;
  WlzThreeDViewStruct *vStr1 = NULL;
  double	**vMat = NULL;
  WlzValues	nullVal;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzAffineTransform *rescaleTr = NULL;
  WlzGreyValueWSpace **gVWSp = NULL;
  void		***prjAry = NULL;
  const double	eps = 0.000001;
#ifdef WLZ_DEBUG_PROJECT3D_TIME
struct timeval	times[3];
#endif /* WLZ_DEBUG_PROJECT3D_TIME */

  nullVal.core = NULL;
  if(obj == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(obj->type != WLZ_3D_DOMAINOBJ)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if(obj->domain.core == NULL)
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN)
  {
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }
  else if(vStr == NULL)
  {
    errNum = WLZ_ERR_TRANSFORM_NULL;
  }
  else if((intMod == WLZ_PROJECT_INT_MODE_VALUES) &&
          (obj->values.core == NULL))
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
#ifdef WLZ_DEBUG_PROJECT3D_TIME
  gettimeofday(times + 0, NULL);
#endif /* WLZ_DEBUG_PROJECT3D_TIME */
  /* Create new view transform without voxel scaling. The voxel scaling
   * is done after the projection. */
  if(errNum == WLZ_ERR_NONE)
  {
    if((vStr1 = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum)) != NULL)
    {
      vStr1->fixed = vStr->fixed;
      vStr1->theta = vStr->theta;
      vStr1->phi = vStr->phi;
      vStr1->zeta = vStr->zeta;
      vStr1->dist = vStr->dist;
      vStr1->scale = vStr->scale;
      vStr1->voxelSize[0] = 1.0;
      vStr1->voxelSize[1] = 1.0;
      vStr1->voxelSize[2] = 1.0;
      vStr1->voxelRescaleFlg = 0;
      vStr1->interp = vStr->interp;
      vStr1->view_mode = vStr->view_mode;
      vStr1->up = vStr->up;
      vStr1->initialised = WLZ_3DVIEWSTRUCT_INIT_NONE;
      vMat = vStr1->trans->mat;
      errNum = WlzInit3DViewStructAffineTransform(vStr1);
      if(errNum == WLZ_ERR_NONE)
      {
        errNum = Wlz3DViewStructTransformBB(obj, vStr1);
      }
      if(errNum != WLZ_ERR_NONE)
      {
	WlzFree3DViewStruct(vStr1);
	vStr1 = NULL;
      }
    }
  }
  /* Compute bounding box of the projection. */
  if(errNum == WLZ_ERR_NONE)
  {
    prjBox.xMin = WLZ_NINT(vStr1->minvals.vtX);
    prjBox.yMin = WLZ_NINT(vStr1->minvals.vtY);
    prjBox.xMax = WLZ_NINT(vStr1->maxvals.vtX);
    prjBox.yMax = WLZ_NINT(vStr1->maxvals.vtY);
    prjSz.vtX = prjBox.xMax - prjBox.xMin + 1;
    prjSz.vtY = prjBox.yMax - prjBox.yMin + 1;
  }
  /* Compute post projection scaling. */
  if((errNum == WLZ_ERR_NONE) && (vStr->voxelRescaleFlg != 0))
  {
    WlzIBox2	sBox;
    WlzIVertex2 sSz;
    WlzThreeDViewStruct *vStr2;

    vStr2 = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      vStr2->fixed = vStr->fixed;
      vStr2->theta = vStr->theta;
      vStr2->phi = vStr->phi;
      vStr2->zeta = vStr->zeta;
      vStr2->dist = vStr->dist;
      vStr2->scale = vStr->scale;
      vStr2->voxelSize[0] = vStr->voxelSize[0];
      vStr2->voxelSize[1] = vStr->voxelSize[1];
      vStr2->voxelSize[2] = vStr->voxelSize[2];
      vStr2->voxelRescaleFlg = vStr->voxelRescaleFlg;
      vStr2->interp = vStr->interp;
      vStr2->view_mode = vStr->view_mode;
      vStr2->up = vStr->up;
      vStr2->initialised = WLZ_3DVIEWSTRUCT_INIT_NONE;
      errNum = WlzInit3DViewStructAffineTransform(vStr2);
      if(errNum == WLZ_ERR_NONE)
      {
        errNum = Wlz3DViewStructTransformBB(obj, vStr2);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	sBox.xMin = WLZ_NINT(vStr2->minvals.vtX);
	sBox.yMin = WLZ_NINT(vStr2->minvals.vtY);
	sBox.xMax = WLZ_NINT(vStr2->maxvals.vtX);
	sBox.yMax = WLZ_NINT(vStr2->maxvals.vtY);
	sSz.vtX = sBox.xMax - sBox.xMin + 1;
	sSz.vtY = sBox.yMax - sBox.yMin + 1;
        rescaleTr = WlzMakeAffineTransform(WLZ_TRANSFORM_2D_AFFINE, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
        double	**m;

	m = rescaleTr->mat;
	m[0][0] = (sSz.vtX * eps) / (prjSz.vtX * eps);
	m[1][1] = (sSz.vtY * eps) / (prjSz.vtY * eps);
	m[0][2] = sBox.xMin - WLZ_NINT(m[0][0] * prjBox.xMin);
	m[1][2] = sBox.yMin - WLZ_NINT(m[1][1] * prjBox.yMin);
      }
      (void )WlzFree3DViewStruct(vStr2);
    }
  }
  /* Compute plane equation, used to clip intervals if depth was given. */
  if((errNum == WLZ_ERR_NONE) && (depth > eps))
  {
    Wlz3DViewGetPlaneEqn(vStr1, pln + 0, pln + 1, pln + 2, pln + 3);
  }
  /* Create rectangular projection array buffers, one for each thread,
   * also if integrating values create a grey value workspace per thread. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		idB;

#ifdef _OPENMP
#pragma omp parallel
    {
#pragma omp master
      {
        nThr = omp_get_num_threads();
      }
    }
#endif
    if((prjAry = (void ***)AlcCalloc(nThr, sizeof(void **))) == NULL)
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else
    {
      if(intMod == WLZ_PROJECT_INT_MODE_NONE)
      {
	for(idB = 0; idB < nThr; ++idB)
	{
	  if(AlcUnchar2Calloc((WlzUByte ***)&(prjAry[idB]),
			      prjSz.vtY, prjSz.vtX) != ALC_ER_NONE)
	  {
	    errNum = WLZ_ERR_MEM_ALLOC;
	    break;
	  }
	}
      }
      else
      {
	for(idB = 0; idB < nThr; ++idB)
	{
	  if(AlcInt2Calloc((int ***)&(prjAry[idB]),
			   prjSz.vtY, prjSz.vtX) != ALC_ER_NONE)
	  {
	    errNum = WLZ_ERR_MEM_ALLOC;
	    break;
	  }
	}
      }
    }
    if((errNum == WLZ_ERR_NONE) &&
       (intMod == WLZ_PROJECT_INT_MODE_VALUES))
    {
      itvVal = (WlzGreyTableIsTiled(obj->values.core->type) == 0);
      if(itvVal == 0)
      {
	if((gVWSp = AlcCalloc(nThr, sizeof(WlzGreyValueWSpace *))) == NULL)
	{
	  errNum = WLZ_ERR_MEM_ALLOC;
	}
	else
	{
	  for(idB = 0; idB < nThr; ++idB) 
	  {
	    gVWSp[idB] = WlzGreyValueMakeWSp(obj, &errNum);
	    if(gVWSp[idB]->gType != WLZ_GREY_UBYTE)
	    {
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	    }
	  }
	}
      }
    }
  }
  /* Scan through the 3D domain setting value in the projection array. */
  if(errNum == WLZ_ERR_NONE)
  {
    int		pIdx,
    		pCnt;
    WlzDomain	*doms;
    WlzValues	*vals = NULL;

    doms = obj->domain.p->domains;
    if(itvVal)
    {
      vals = obj->values.vox->values;
    }
    pCnt = obj->domain.p->lastpl - obj->domain.p->plane1 + 1;
#ifdef _OPENMP
#pragma omp parallel for
#endif
    for(pIdx =  0; pIdx < pCnt; ++pIdx)
    {
      int	thrId = 0;

      if((errNum == WLZ_ERR_NONE) && (doms[pIdx].core != NULL))
      {
	WlzObject   *obj2;
	WlzGreyWSpace gWSp;
	WlzIntervalWSpace iWSp;
	WlzErrorNum errNum2 = WLZ_ERR_NONE;

#ifdef _OPENMP
	thrId = omp_get_thread_num();
#endif
        obj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ, doms[pIdx],
	                   (vals)? vals[pIdx]: nullVal,
	                   NULL, NULL, &errNum2);
        if(errNum2 == WLZ_ERR_NONE)
	{
	  if(itvVal)
	  {
	    errNum2 = WlzInitGreyScan(obj2, &iWSp, &gWSp);
	  }
	  else
	  {
	    errNum2 = WlzInitRasterScan(obj2, &iWSp, WLZ_RASTERDIR_ILIC);
	  }
	}
        if(errNum2 == WLZ_ERR_NONE)
	{
	  double      plnZ,
	  	      vMZX,
	  	      vMZY;
	  WlzIVertex3 p0,
	    	      p1;

	  p0.vtZ = p1.vtZ = obj->domain.p->plane1 + pIdx;
	  vMZX = (vMat[0][2] * p0.vtZ) + vMat[0][3] - prjBox.xMin;
	  vMZY = (vMat[1][2] * p0.vtZ) + vMat[1][3] - prjBox.yMin;
	  plnZ = (pln[2] * p0.vtZ) + pln[3];
	  while(((itvVal == 0) &&
	        ((errNum2 = WlzNextInterval(&iWSp)) == WLZ_ERR_NONE)) ||
	        ((itvVal != 0) &&
	        ((errNum2 = WlzNextGreyInterval(&iWSp)) == WLZ_ERR_NONE)))
	  {
	    int		skip = 0;
	    WlzDVertex2 q0,
	    		q1;

            p0.vtX = iWSp.lftpos;
	    p1.vtX = iWSp.rgtpos;
	    p0.vtY = p1.vtY = iWSp.linpos;
	    if(depth > eps)
	    {
	      int	c;
	      double	d0,
	      		d1,
			plnYZ;

	      /* Clip the 3D line segment p0,p1 using the plane equation. */
	      plnYZ = (pln[1] * p0.vtY) + plnZ;
	      d0 = (pln[0] * p0.vtX) + plnYZ;
	      d1 = (pln[0] * p1.vtX) + plnYZ;
	      c = ((d1 >  depth) << 3) | ((d0 >  depth) << 2) |
		  ((d1 < -depth) << 1) |  (d0 < -depth);
	      if(c)
	      {
		if((c == 3) || (c == 12)) /* 00-- or ++00 */
		{
		  /* Both out of range, so don't render. */
		  skip = 1;
		}
		else
		{
		  if(fabs(pln[0]) > eps)
		  {
		    double	plnX;

		    plnX = -1.0 / pln[0];
		    if((c &  1) != 0)      /* x0x- */
		    {
		      p0.vtX = plnX * (plnYZ + depth);
		    }
		    else if((c &  4) != 0) /* x+x0 */
		    {
		      p0.vtX = plnX * (plnYZ - depth);
		    }
		    if((c &  2) != 0)      /* 0x-x */
		    {
		      p1.vtX = plnX * (plnYZ + depth);
		    }
		    else if((c &  8) != 0) /* +x0x */
		    {
		      p1.vtX = plnX * (plnYZ - depth);
		    }
		  }
		}
	      }
	    }
	    if(skip == 0)
	    {
	      q0.vtX = (vMat[0][0] * p0.vtX) + (vMat[0][1] * p0.vtY) + vMZX;
	      q0.vtY = (vMat[1][0] * p0.vtX) + (vMat[1][1] * p0.vtY) + vMZY;
	      q1.vtX = (vMat[0][0] * p1.vtX) + (vMat[0][1] * p1.vtY) + vMZX;
	      q1.vtY = (vMat[1][0] * p1.vtX) + (vMat[1][1] * p1.vtY) + vMZY;
	      switch(intMod)
	      {
		case WLZ_PROJECT_INT_MODE_NONE:
		  {
		    WlzIVertex2 u0,
				u1;

		    WLZ_VTX_2_NINT(u0, q0);
		    WLZ_VTX_2_NINT(u1, q1);
		    WlzProjectObjLine((WlzUByte **)(prjAry[thrId]), u0, u1);
		  }
		  break;
		case WLZ_PROJECT_INT_MODE_DOMAIN:
		  {
		    int	        np,
				nq;
		    WlzDVertex3 dq;
		    WlzIVertex2 u0,
				u1;

		    WLZ_VTX_2_NINT(u0, q0);
		    WLZ_VTX_2_NINT(u1, q1);
		    WLZ_VTX_2_SUB(dq, q0, q1);
		    np = denDom * (iWSp.rgtpos - iWSp.lftpos + 1);
		    nq = (int )ceil(WLZ_VTX_2_LENGTH(dq) + eps);
		    WlzProjectObjLineDom((int **)(prjAry[thrId]), np / nq,
					 u0, u1);
		  }
		  break;
		case WLZ_PROJECT_INT_MODE_VALUES:
		  if(itvVal)
		  {
		    WlzProjectObjLineVal((int **)(prjAry[thrId]), denVal,
					 gWSp.u_grintptr.ubp, NULL,
					 vMat, vMZX, vMZY, p0, p1);
		  }
		  else
		  {
		    WlzProjectObjLineVal((int **)(prjAry[thrId]), denVal,
					 NULL, gVWSp[thrId],
					 vMat, vMZX, vMZY, p0, p1);
		  }
		  break;
	      }
	    }
	  }
	  (void )WlzEndGreyScan(&iWSp, &gWSp);
	  if(errNum2 == WLZ_ERR_EOO)
	  {
	    errNum2 = WLZ_ERR_NONE;
	  }
	}
	(void )WlzFreeObj(obj2);
	if(errNum2 != WLZ_ERR_NONE)
	{
#ifdef _OPENMP
#pragma omp critical
	  {
#endif
	    if(errNum == WLZ_ERR_NONE)
	    {
	      errNum = errNum2;
	    }
#ifdef _OPENMP
	  }
#endif
	}
      }
    }
  }
  /* Free grey value workspaces if they were created. */
  if(gVWSp)
  {
    int		idB;

    for(idB = 0; idB < nThr; ++idB) 
    {
      WlzGreyValueFreeWSp(gVWSp[idB]);
    }
    AlcFree(gVWSp);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    int		idB;
    size_t	idC,
    		bufSz;
    WlzGreyP	buf0,
      		buf1;
    WlzIVertex2	prjOrg;

    prjOrg.vtX = prjBox.xMin;
    prjOrg.vtY = prjBox.yMin;
    bufSz = prjSz.vtX * prjSz.vtY;
    for(idB = 1; idB < nThr; ++idB)
    {
      if(intMod == WLZ_PROJECT_INT_MODE_NONE)
      {
        buf0.ubp = ((WlzUByte ***)(prjAry))[0][0],
	buf1.ubp = ((WlzUByte ***)(prjAry))[idB][0];
	for(idC = 0; idC < bufSz; ++idC)
	{
	  buf0.ubp[idC] += buf1.ubp[idC];
	}
      }
      else
      {
        buf0.inp = ((int ***)(prjAry))[0][0],
	buf1.inp = ((int ***)(prjAry))[idB][0];
	for(idC = 0; idC < bufSz; ++idC)
	{
	  buf0.inp[idC] += buf1.inp[idC];
	}
      }
    }
    switch(intMod != WLZ_PROJECT_INT_MODE_NONE)
    {
      buf0.inp = ((int ***)(prjAry))[0][0];
      for(idC = 0; idC < bufSz; ++idC)
      {
	buf0.inp[idC] /= 256;
      }
    }
    if(intMod == WLZ_PROJECT_INT_MODE_NONE)
    {
      bufObj = WlzAssignObject(
	       WlzFromArray2D((void **)(prjAry[0]), prjSz, prjOrg,
			      WLZ_GREY_UBYTE, WLZ_GREY_UBYTE,
			      0.0, 1.0, 1, 0, &errNum), NULL);
    }
    else
    {
      bufObj = WlzAssignObject(
	       WlzFromArray2D((void **)(prjAry[0]), prjSz, prjOrg,
			      WLZ_GREY_INT, WLZ_GREY_INT,
			      0.0, 1.0, 1, 0, &errNum), NULL);
    }
  }
  /* Free the projection array(s). */
  if(prjAry)
  {
    int		idB;

    for(idB = 0; idB < nThr; ++idB)
    {
      (void )Alc2Free((prjAry[idB]));
    }
    AlcFree(prjAry);
  }
  /* Make return object using threshold. */
  if(errNum == WLZ_ERR_NONE)
  {
    WlzPixelV	tV;
    WlzObject	*tObj = NULL;

    tV.type = WLZ_GREY_UBYTE;
    tV.v.ubv = 1;
    tObj = WlzAssignObject(
	   WlzThreshold(bufObj, tV, WLZ_THRESH_HIGH, &errNum), NULL);
    if(tObj)
    {
      if(intMod == WLZ_PROJECT_INT_MODE_NONE)
      {
	prjObj = WlzMakeMain(tObj->type, tObj->domain, nullVal,
			     NULL, NULL, &errNum);
      }
      else
      {
	prjObj = WlzMakeMain(tObj->type, tObj->domain, tObj->values,
			     NULL, NULL, &errNum);
      }
    }
    (void )WlzFreeObj(tObj);
  }
  (void )WlzFreeObj(bufObj);
  (void )WlzFree3DViewStruct(vStr1);
  /* Scale image. */
  if(rescaleTr != NULL)
  {
    if(errNum == WLZ_ERR_NONE)
    {
      WlzObject	*tObj = NULL;

      tObj = WlzAffineTransformObj(prjObj, rescaleTr, 
				   WLZ_INTERPOLATION_NEAREST, &errNum);
      
      (void )WlzFreeObj(prjObj);
      prjObj = tObj;
    }
    (void )WlzFreeAffineTransform(rescaleTr);
  }
#ifdef WLZ_DEBUG_PROJECT3D_TIME
  gettimeofday(times + 1, NULL);
  ALC_TIMERSUB(times + 1, times + 0, times + 2);
  (void )fprintf(stderr, "WlzGetProjectionFromObject: Elapsed time = %g\n",
                 times[2].tv_sec + (0.000001 * times[2].tv_usec));
#endif /* WLZ_DEBUG_PROJECT3D_TIME */
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(prjObj);
}
Exemplo n.º 8
0
/*!
* \return	The value held in the given Java object.
* \ingroup	JWlz
* \brief	Returns a 2D array built from the given 2D java array.
* \param	jEnv			Given JNI environment ptr.
* \param	cObjName		The Java woolz C object class string.	
* \param	jObjName		The Java woolz Java object class
* 					string.
* \param	jniObjName		The Java woolz JNI object class string.
* \param	idrCnt			Indirection count (ie 1 for *, 2 for
* 					**, ...).
* \param	pKey			Parameter key.
* \param	jWArray			The Java Woolz array.
* \param	wArraySz		The number of elements in the Java
* 					Woolz array.
* \param	isCpy			Destination pointer for JNI copy flag.
*/
jlong 		WlzJavaArray2DGet(JNIEnv *jEnv,
				       char *cObjName,
				       char *jObjName,
				       char *jniObjName,
				       int idrCnt, int pKey,
				       jarray jWArray,
				       WlzIVertex2 wArraySz,
				       jboolean *isCpy)
{
  int		idY,
  		ok = 0;
  void		*bufJ;
  jobject	aryJ1D;
  void		**aryW2D = NULL;
  jlong		rtnVal = 0;

  if(jWArray && (wArraySz.vtX > 0) && (wArraySz.vtY > 0))
  {
    switch(pKey)
    {
      case WLZ_JPM_KEY_BYTE_ARY2:
	ok = AlcChar2Malloc((char ***)&aryW2D,
			    wArraySz.vtY, wArraySz.vtX) == ALC_ER_NONE;
	if(ok)
	{
	  idY = 0;
	  while(ok && (idY < wArraySz.vtY))
	  {
	    ok = ((aryJ1D = (*jEnv)->GetObjectArrayElement(jEnv,
	    					(jobjectArray )jWArray,
						idY)) != NULL) &&
	         ((bufJ = (void *)(*jEnv)->GetByteArrayElements(jEnv,
				    		(jbyteArray )aryJ1D,
						isCpy)) == NULL);
	    if(ok)
	    {
	      (void )memcpy(*((WlzUByte **)aryW2D + idY), bufJ,
	      		    wArraySz.vtX * sizeof(jbyte));
	      if(*isCpy)
	      {
	        (*jEnv)->ReleaseByteArrayElements(jEnv, (jbyteArray )aryJ1D,
						  (jbyte *)bufJ, 0);
	        *isCpy = JNI_FALSE;
	      }
	    }
	    ++idY;
	  }
	}
	break;
      case WLZ_JPM_KEY_SHORT_ARY2:
	ok = AlcShort2Malloc((short ***)&aryW2D,
			     wArraySz.vtY, wArraySz.vtX) == ALC_ER_NONE;
	if(ok)
	{
	  idY = 0;
	  while(ok && (idY < wArraySz.vtY))
	  {
	    ok = ((aryJ1D = (*jEnv)->GetObjectArrayElement(jEnv,
	    					(jobjectArray )jWArray,
						idY)) != NULL) &&
	         ((bufJ = (void *)(*jEnv)->GetShortArrayElements(jEnv,
		 				(jshortArray )aryJ1D,
						isCpy)) != NULL);
	    if(ok)
	    {
	      (void )memcpy(*((WlzUByte **)aryW2D + idY), bufJ,
	      		    wArraySz.vtX * sizeof(short));
	      if(*isCpy)
	      {
	        (*jEnv)->ReleaseShortArrayElements(jEnv,
						(jshortArray )aryJ1D,
						(jshort *)bufJ, 0);
	        *isCpy = JNI_FALSE;
	      }
	    }
	    ++idY;
	  }
	}
	break;
      case WLZ_JPM_KEY_INT_ARY2:
	ok = AlcInt2Malloc((int ***)&aryW2D,
			   wArraySz.vtY, wArraySz.vtX) == ALC_ER_NONE;
	if(ok)
	{
	  idY = 0;
	  while(ok && (idY < wArraySz.vtY))
	  {
	    ok = ((aryJ1D = (*jEnv)->GetObjectArrayElement(jEnv,
	    					(jobjectArray )jWArray,
						idY)) != NULL) &&
	         ((bufJ = (void *)(*jEnv)->GetIntArrayElements(jEnv,
						(jintArray )aryJ1D,
						isCpy)) != NULL);
	    if(ok)
	    {
	      (void )memcpy(*((WlzUByte **)aryW2D + idY), bufJ,
	      		    wArraySz.vtX * sizeof(int));
	      if(*isCpy)
	      {
	        (*jEnv)->ReleaseIntArrayElements(jEnv,
						(jintArray )aryJ1D,
						(jint *)bufJ, 0);
	        *isCpy = JNI_FALSE;
	      }
	    }
	    ++idY;
	  }
	}
	break;
      case WLZ_JPM_KEY_FLOAT_ARY2:
	ok = AlcFloat2Malloc((float ***)&aryW2D,
			     wArraySz.vtY, wArraySz.vtX) == ALC_ER_NONE;
        if(ok)
	{
	  idY = 0;
	  while(ok && (idY < wArraySz.vtY))
	  {
	    ok = ((aryJ1D = (*jEnv)->GetObjectArrayElement(jEnv,
	    					(jobjectArray )jWArray,
						idY)) != NULL) &&
	       ((bufJ = (void *)(*jEnv)->GetFloatArrayElements(jEnv,
						(jfloatArray )aryJ1D,
						 isCpy)) != NULL);
	    if(ok)
	    {
	      (void )memcpy(*((WlzUByte **)aryW2D + idY), bufJ,
	      		    wArraySz.vtX * sizeof(float));
	      if(*isCpy)
	      {
	        (*jEnv)->ReleaseFloatArrayElements(jEnv,
						(jfloatArray )aryJ1D,
						(jfloat *)bufJ, 0);
	        *isCpy = JNI_FALSE;
	      }
	    }
	    ++idY;
	  }
	}
	break;
      case WLZ_JPM_KEY_DOUBLE_ARY2:
	ok = AlcDouble2Malloc((double ***)&aryW2D,
			      wArraySz.vtY, wArraySz.vtX) == ALC_ER_NONE;
	if(ok)
	{
	  idY = 0;
	  while(ok && (idY < wArraySz.vtY))
	  {
	    ok = ((aryJ1D = (*jEnv)->GetObjectArrayElement(jEnv,
	    					(jobjectArray )jWArray,
						idY)) != NULL) &&
	       ((bufJ = (void *)(*jEnv)->GetDoubleArrayElements(jEnv,
						(jdoubleArray )aryJ1D,
						isCpy)) != NULL);
	    if(ok)
	    {
	      (void )memcpy(*((WlzUByte **)aryW2D + idY), bufJ,
	      		    wArraySz.vtX * sizeof(double));
	      if(*isCpy)
	      {
	        (*jEnv)->ReleaseDoubleArrayElements(jEnv,
						(jdoubleArray )aryJ1D,
						(jdouble *)bufJ, 0);
	        *isCpy = JNI_FALSE;
	      }
	    }
	    ++idY;
	  }
	}
	break;
      default:
	break;
    }
    if(ok)
    {
      rtnVal = (jlong )aryW2D;
      *isCpy = JNI_TRUE;
    }
    else if(aryW2D)
    {
      Alc2Free(aryW2D);
    }
  }
  return(rtnVal);
}
Exemplo n.º 9
0
/*!
* \return	New Woolz domain object with gradient grey values or NULL on
*		error.
* \ingroup      WlzValuesFilters
* \brief	Computes the magnitude of the gray values in the
*               3 given Woolz 2D domain objects.
* \param	srcObj0			First object.
* \param	srcObj1			Second object.
* \param	srcObj2			Third object.
* \param	dstErr			Destination error pointer, may be null.
*/
static WlzObject *WlzGreyMagnitude2D3(WlzObject *srcObj0, WlzObject *srcObj1,
				      WlzObject *srcObj2,
				      WlzErrorNum *dstErr)
{
  int		idN,
		itvLen,
  		bufSz;
  double	**iBufA = NULL;
  WlzObject     *tObj0,
		*istObj = NULL,
                *dstObj = NULL;
  WlzObject	*iObjA[3],
  		*tObjA[3];
  WlzGreyP	tGP0;
  WlzGreyType	dstGType = WLZ_GREY_ERROR;
  WlzGreyType	gTypeA[3];
  WlzPixelV	dstBgd;
  WlzPixelV	bgdA[3];
  WlzValues	dstVal;
  WlzIntervalWSpace dstIWSp;
  WlzGreyWSpace	dstGWSp;
  WlzIntervalWSpace iIWSpA[3];
  WlzGreyWSpace	iGWSpA[3];
  WlzErrorNum   errNum = WLZ_ERR_NONE;

  *(iObjA + 0) = *(iObjA + 1) = *(iObjA + 2) = NULL;
  /* Check source objects. */
  if((srcObj0 == NULL) || (srcObj1 == NULL) ||(srcObj2 == NULL))
  {
    errNum = WLZ_ERR_OBJECT_NULL;;
  }
  else if((srcObj0->type != WLZ_2D_DOMAINOBJ) ||
          (srcObj1->type != WLZ_2D_DOMAINOBJ) ||
          (srcObj2->type != WLZ_2D_DOMAINOBJ))
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if((srcObj0->domain.core == NULL) ||
          (srcObj1->domain.core == NULL) ||
          (srcObj2->domain.core == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if((srcObj0->values.core == NULL) ||
          (srcObj1->values.core == NULL) ||
          (srcObj2->values.core == NULL))
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  /* Compute the intersection of the source objects. */
  if(errNum == WLZ_ERR_NONE)
  {
    *(tObjA + 0) = srcObj0;
    *(tObjA + 1) = srcObj1;
    *(tObjA + 2) = srcObj2;
    istObj = WlzIntersectN(3, tObjA, 0, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    *(iObjA + 0) = WlzMakeMain(WLZ_2D_DOMAINOBJ,
    			       istObj->domain, srcObj0->values,
    			       NULL, NULL, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    *(iObjA + 1) = WlzMakeMain(WLZ_2D_DOMAINOBJ,
    			       istObj->domain, srcObj1->values,
    			       NULL, NULL, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    *(iObjA + 2) = WlzMakeMain(WLZ_2D_DOMAINOBJ,
    			       istObj->domain, srcObj2->values,
    			       NULL, NULL, &errNum);
  }
  /* Get background value and grey types */
  idN = 0;
  while((errNum == WLZ_ERR_NONE) && (idN < 3))
  {
    tObj0 = *(iObjA + idN);
    *(gTypeA + idN) = WlzGreyTableTypeToGreyType(tObj0->values.core->type,
				                 &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      *(bgdA + idN) = WlzGetBackground(tObj0, &errNum);
    }
    ++idN;
  }
  /* Promote grey types. */
  if(errNum == WLZ_ERR_NONE)
  {
    if((*(gTypeA + 0) == WLZ_GREY_DOUBLE) ||
       (*(gTypeA + 1) == WLZ_GREY_DOUBLE) ||
       (*(gTypeA + 2) == WLZ_GREY_DOUBLE))
    {
      dstGType = WLZ_GREY_DOUBLE;
    }
    else if((*(gTypeA + 0) == WLZ_GREY_FLOAT) ||
	    (*(gTypeA + 1) == WLZ_GREY_FLOAT) ||
	    (*(gTypeA + 2) == WLZ_GREY_FLOAT))
    {
      dstGType = WLZ_GREY_FLOAT;
    }
    else if((*(gTypeA + 0) == WLZ_GREY_INT) ||
	    (*(gTypeA + 1) == WLZ_GREY_INT) ||
	    (*(gTypeA + 2) == WLZ_GREY_INT))
    {
      dstGType = WLZ_GREY_INT;
    }
    else if((*(gTypeA + 0) == WLZ_GREY_SHORT) ||
	    (*(gTypeA + 1) == WLZ_GREY_SHORT) ||
	    (*(gTypeA + 2) == WLZ_GREY_SHORT))
    {
      dstGType = WLZ_GREY_SHORT;
    }
    else if((*(gTypeA + 0) == WLZ_GREY_UBYTE) ||
	    (*(gTypeA + 1) == WLZ_GREY_UBYTE) ||
	    (*(gTypeA + 2) == WLZ_GREY_UBYTE))
    {
      dstGType = WLZ_GREY_SHORT;
    }
    else
    {
      /* RGBA to be done RAB */
      errNum = WLZ_ERR_GREY_TYPE;
    }
  }
  /* Make destination object with intersection domain and new values. */
  if(errNum == WLZ_ERR_NONE)
  {
    (void )WlzValueConvertPixel(&dstBgd, *(bgdA + 0), dstGType);
    dstVal.v = WlzNewValueTb(*(iObjA + 0),
    			     WlzGreyValueTableType(0, WLZ_GREY_TAB_RAGR,
			     dstGType, NULL),
			     dstBgd, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      dstObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, istObj->domain, dstVal,
      			   NULL, NULL, &errNum);
    }
  }
  if(istObj)
  {
    WlzFreeObj(istObj);
  }
  /* Make buffers. */
  if(errNum == WLZ_ERR_NONE)
  {
    bufSz = dstObj->domain.i->lastkl - dstObj->domain.i->kol1 + 1;
    if(AlcDouble2Malloc(&iBufA, 3, bufSz) != ALC_ER_NONE)
    {
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }
  /* Scan through the objects computing the magnitude. */
  if(errNum == WLZ_ERR_NONE)
  {
    idN = 0;
    while((errNum == WLZ_ERR_NONE) && (idN < 3))
    {
      errNum = WlzInitGreyScan(*(iObjA + idN), iIWSpA + idN, iGWSpA + idN);
      ++idN;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzInitGreyScan(dstObj, &dstIWSp, &dstGWSp);
    }
    while((errNum == WLZ_ERR_NONE) &&
    	  ((errNum = WlzNextGreyInterval(iIWSpA + 0)) == WLZ_ERR_NONE) &&
	  ((errNum = WlzNextGreyInterval(iIWSpA + 1)) == WLZ_ERR_NONE) &&
	  ((errNum = WlzNextGreyInterval(iIWSpA + 2)) == WLZ_ERR_NONE) &&
	  ((errNum = WlzNextGreyInterval(&dstIWSp)) == WLZ_ERR_NONE))
    {
      itvLen = dstIWSp.rgtpos - dstIWSp.lftpos + 1;
      /* Copy intervals to double buffers. */
      idN = 0;
      while(idN < 3)
      {
	tGP0.dbp = *(iBufA + idN);
        WlzValueCopyGreyToGrey(tGP0, 0,
			       WLZ_GREY_DOUBLE,
			       (iGWSpA + idN)->u_grintptr, 0,
			       (iGWSpA + idN)->pixeltype,
			       itvLen);
        ++idN;
      }
      /* Compute magnitude. */
      WlzBufMagD3(*(iBufA + 0), *(iBufA + 1), *(iBufA + 2), itvLen);
      /* Clamp into destination interval. */
      tGP0.dbp = *(iBufA + 0);
      WlzValueClampGreyIntoGrey(dstGWSp.u_grintptr, 0, dstGWSp.pixeltype,
				tGP0, 0, WLZ_GREY_DOUBLE,
				itvLen);
    }
    if(errNum == WLZ_ERR_EOO)
    {
      errNum = WLZ_ERR_NONE;
    }
  }
  /* Free intersection objects. */
  idN = 0;
  while(idN < 3)
  {
    if(iObjA[idN])
    {
      WlzFreeObj(iObjA[idN]);
    }
    ++idN;
  }
  /* Free buffers. */
  if(iBufA)
  {
    Alc2Free((void **)iBufA);
  }
  /* Tidy up on error. */
  if(dstObj && (errNum != WLZ_ERR_NONE))
  {
    WlzFreeObj(dstObj);
    dstObj = NULL;
  }
  /* Pass back error status. */
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dstObj);
}