Example #1
0
/*!
* \return	New vertex array.
* \brief	Reads an array of vertices (2D or 3D) from the given file.
* \param	fP			File pointer.
* \param	dim			Dimension which MUST be either 2 or 3.
* \param	dstNVtx			Destination pointer for the number of
*					vertices read, MUST not be NULL.
* \param	dstErr			Used to return Woolz error code,
*					MUST not be NULL.
*/
static WlzVertexP 	WlzCFPReadVtxArray(FILE *fP, int dim, int *dstNVtx, 
					   WlzErrorNum *dstErr)
{
  int		datCnt = 0,
  		datMax = 0;
  char		lnBuf[WLZ_CFP_READLN_LEN];
  WlzVertex	datV;
  WlzVertexP	datVP;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  datVP.v = NULL;
  while((errNum == WLZ_ERR_NONE) &&
	(fgets(lnBuf, WLZ_CFP_READLN_LEN, fP) != NULL))
  {
    lnBuf[WLZ_CFP_READLN_LEN - 1] = '\0';
    switch(dim)
    {
      case 2:
	errNum = WLZ_ERR_UNIMPLEMENTED;
	break;
      case 3:
        if(sscanf(lnBuf, "%lg %lg %lg",
	          &(datV.d3.vtX), &(datV.d3.vtY), &(datV.d3.vtZ)) != 3)
	{
	  errNum = WLZ_ERR_READ_INCOMPLETE;
	}
	else
	{
	  if(datCnt >= datMax)
	  {
	    datMax = (datMax + 1024) * 2;
	    if((datVP.v = AlcRealloc(datVP.v,
	    			     sizeof(WlzDVertex3) * datMax)) == NULL)
	    {
	      errNum = WLZ_ERR_MEM_ALLOC;
	    }
	  }
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  *(datVP.d3 + datCnt++) = datV.d3;
	}
	break;
    }
  }
  *dstErr = errNum;
  *dstNVtx = datCnt;
  return(datVP);
}
Example #2
0
/*!
* \return	Number of file names in given string or NULL on error.
* \ingroup	BinWlzApp
* \brief	Tries to parse file names from the given comma separated
* 		list. It's an error if there are insufficient file names.
* \param	fNames			Source and destination pointer for
* 					the array of file names.
* \param	fList			Comma separated list of file names.
* \param	newCnt			Number of file names expected.
*/
static int 	WlzProjDomParseNameList(char ***fNames, char *fList,
				int newCnt)
{
  if((fNames == NULL) || (newCnt < 1))
  {
    newCnt = 0;
  }
  else
  {
    if((*fNames = AlcRealloc(*fNames, sizeof(char *) * newCnt)) == NULL)
    {
      newCnt = 0;
    }
  }
  if(newCnt > 0)
  {
    int		idx;
    char	*tok;
    
    tok = strtok(fList, ",");
    for(idx = 0; (tok != NULL) && (idx < newCnt); ++idx)
    {
      if(WlzProjDomStripSpaces(tok) < 1)
      {
        tok = NULL;
      }
      else
      {
        (*fNames)[idx] = tok;
	tok = strtok(NULL, ",");
      }
    }
    if(idx != newCnt)
    {
      newCnt = 0;
    }
  }
  return(newCnt);
}
Example #3
0
/*!
* \return	New vertex array.
* \brief	Reads an array of vertices (2D or 3D) from the given file.
* \param	fP			File pointer.
* \param	dim			Dimension which MUST be either 2 or 3.
* \param	dstNVtx			Destination pointer for the number of
*					vertices read, MUST not be NULL.
* \param	dstVType		Destination pointer for the vertex
*					type, MUST not be NULL.
* \param	dstErr			Used to return Woolz error code,
*					MUST not be NULL.
*/
static WlzVertexP 	WlzMTDReadVtxArray(FILE *fP, int dim, int *dstNVtx, 
					   WlzVertexType *dstVType,
					   WlzErrorNum *dstErr)
{
  int		datCnt = 0,
  		datMax = 0;
  char		lnBuf[WLZ_CFP_READLN_LEN];
  WlzVertex	datV;
  WlzVertexP	datVP;
  WlzVertexType vType;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  datVP.v = NULL;
  while((errNum == WLZ_ERR_NONE) &&
	(fgets(lnBuf, WLZ_CFP_READLN_LEN, fP) != NULL))
  {
    lnBuf[WLZ_CFP_READLN_LEN - 1] = '\0';
    switch(dim)
    {
      case 2:
	vType = WLZ_VERTEX_I2;
        if(sscanf(lnBuf, "%lg %lg",
	          &(datV.d2.vtX), &(datV.d2.vtY)) != 2)
	{
	  errNum = WLZ_ERR_READ_INCOMPLETE;
	}
	else
	{
	  if(datCnt >= datMax)
	  {
	    datMax = (datMax + 1024) * 2;
	    if((datVP.v = AlcRealloc(datVP.v,
	    			     sizeof(WlzIVertex2) * datMax)) == NULL)
	    {
	      errNum = WLZ_ERR_MEM_ALLOC;
	    }
	  }
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  (datVP.i2 + datCnt)->vtX = ALG_NINT(datV.d2.vtX);
	  (datVP.i2 + datCnt)->vtY = ALG_NINT(datV.d2.vtY);
	  ++datCnt;
	}
	break;
      case 3:
	vType = WLZ_VERTEX_I3;
        if(sscanf(lnBuf, "%lg %lg %lg",
	          &(datV.d3.vtX), &(datV.d3.vtY), &(datV.d3.vtZ)) != 3)
	{
	  errNum = WLZ_ERR_READ_INCOMPLETE;
	}
	else
	{
	  if(datCnt >= datMax)
	  {
	    datMax = (datMax + 1024) * 2;
	    if((datVP.v = AlcRealloc(datVP.v,
	    			     sizeof(WlzIVertex3) * datMax)) == NULL)
	    {
	      errNum = WLZ_ERR_MEM_ALLOC;
	    }
	  }
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  (datVP.i3 + datCnt)->vtX = ALG_NINT(datV.d3.vtX);
	  (datVP.i3 + datCnt)->vtY = ALG_NINT(datV.d3.vtY);
	  (datVP.i3 + datCnt)->vtZ = ALG_NINT(datV.d3.vtZ);
	  ++datCnt;
	}
	break;
      default:
        errNum = WLZ_ERR_PARAM_DATA;
	break;
    }
  }
  *dstErr = errNum;
  *dstVType = vType;
  *dstNVtx = datCnt;
  return(datVP);
}
Example #4
0
WlzPolygonDomain *HGU_XGetPolyDomain(
  Display		*dpy,
  Window		win,
  int			mode,
  HGU_XInteractCallbacks	*callbacks,
  WlzPolygonDomain	*start)
{
  XEvent		event;
  GC			gc;
  XWindowAttributes	win_att;
  WlzFVertex2		*vtxs=NULL, vtx, vtxp;
  int			nvtxs=0, max_nvtxs=0;
  int			finished = 0;
  HGU_XGetVtxsCallbackStruct	cb_struct;
  int			i;
  int			dx, dy;
  WlzPolygonDomain	*return_polydmn;
    
  /* initialise vertex */
  vtxp.vtX = 0;
  vtxp.vtY = 0;
    
  /* set up the callback struct */
  cb_struct.event = &event;

  /* get interact gc */
  gc = HGU_XGetGC( dpy, win, HGU_XGC_INTERACT );
    
  /* copy the given polygon */
  if( (start != NULL) && (start->nvertices > 0) ){

    for(i=0; i < start->nvertices; i++){
	    
      switch( start->type ){
      case WLZ_POLYGON_INT:
	vtx.vtX = start->vtx[i].vtX;
	vtx.vtY = start->vtx[i].vtY;
	break;
      case WLZ_POLYGON_FLOAT:
	vtx.vtX = ((WlzFVertex2 *) start->vtx)[i].vtX;
	vtx.vtY = ((WlzFVertex2 *) start->vtx)[i].vtY;
	break;
      case WLZ_POLYGON_DOUBLE:
	vtx.vtX = ((WlzDVertex2 *) start->vtx)[i].vtX;
	vtx.vtY = ((WlzDVertex2 *) start->vtx)[i].vtY;
	break;
      default:
	vtx.vtX = 0;
	vtx.vtY = 0;
	break;
      }
	    
      NEW_VTX((&vtx));
    }
	
    /* warp pointer */
    XWarpPointer(dpy,None,win,0,0,0,0,(int) (vtx.vtX), (int) (vtx.vtY));
  }
    
  /* select input */
  if( XGetWindowAttributes(dpy, win, &win_att) == 0 ){
    HGU_XError(dpy, win, "HGU_XGetPolydmn",
	       "failed to get window attributes", 0);
    return( NULL );
  }
  XSelectInput(dpy, win, win_att.your_event_mask |
	       KeyPressMask | KeyReleaseMask |
	       EnterWindowMask | LeaveWindowMask );
  if(  QueryInWindow( dpy, win ) ){
    HGU_XGrabPointer(dpy, win, mode&HGU_XConfineMask);
  }
    
  /* get the polyline */
  while( !finished ){
	
    XNextEvent(dpy, &event);
    if( event.xany.window != win ){
      finished = HGU_XInteractNonwindowEvent(dpy, win, mode, callbacks,
					     &event);
      continue;
    }
	
    switch( event.type ){
	    
    case ButtonPress:
      switch( event.xbutton.button ){
      case Button1:		/* new vertex or select */
      case Button2:
	vtx.vtX = event.xbutton.x;
	vtx.vtY = event.xbutton.y;
	NEW_VTX((&vtx));
	break;
      case Button3:
	finished = 1;
	break;
      default:
	break;
      }
      break;

    case ButtonRelease:
      switch( event.xbutton.button ){
      case Button1:		/*  */
      case Button2:
	/* CHECK NOCONFIRM */
	break;
      case Button3:
      default:
	break;
      }
      break;

    case KeyPress:
      switch( XLookupKeysym(&event.xkey, 0) ){
      case XK_Delete:
      case XK_BackSpace:
	vtx.vtX = event.xkey.x;
	vtx.vtY = event.xkey.y;
	REMOVE_VTX((&vtx));
	break;
      case XK_Right:
	MOVE_POINTER(1,0,event.xkey.state&ControlMask);
	break;
      case XK_Left:
	MOVE_POINTER(-1,0,event.xkey.state&ControlMask);
	break;
      case XK_Up:
	MOVE_POINTER(0,-1,event.xkey.state&ControlMask);
	break;
      case XK_Down:
	MOVE_POINTER(0,1,event.xkey.state&ControlMask);
	break;
      case XK_space:
	vtx.vtX = event.xkey.x;
	vtx.vtY = event.xkey.y;
	NEW_VTX((&vtx));
	break;
      case XK_Return:
	finished = 1;
	break;
      case XK_Help:
	break;
      default:
	break;
      }
      break;
	    
    case KeyRelease:
      switch( XLookupKeysym(&event.xkey, 0) ){
      case XK_Delete:
      case XK_BackSpace:
	finished = mode & HGU_XNoConfirmMask;
	break;
      default:
	break;
      }
      break;

    case MotionNotify:
      /* check button masks */
      vtx.vtX = event.xmotion.x;
      vtx.vtY = event.xmotion.y;
      if( event.xmotion.state & (Button1Mask|Button2Mask) ){
	NEW_VTX((&vtx));
      } else {
	MOVE_VTX((&vtx));
      }
      cb_struct.x = event.xmotion.x;
      cb_struct.y = event.xmotion.y;
      cb_struct.vtxs  = vtxs;
      cb_struct.nvtxs = nvtxs;
      finished = HGU_XInteractWindowEvent(dpy, win, mode, callbacks,
					  (caddr_t) &cb_struct);
      break;
	    
    case EnterNotify:
      HGU_XGrabPointer(dpy, win, mode&HGU_XConfineMask);
      break;
	    
    case LeaveNotify:
      HGU_XUngrabPointer(dpy, win);
      break;
	    
    default:
      cb_struct.vtxs  = vtxs;
      cb_struct.nvtxs = nvtxs;
      finished = HGU_XInteractWindowEvent(dpy, win, mode, callbacks,
					  (caddr_t) &cb_struct);
      break;
    }
  }
    
  /* remove the line */
  for(i=1; i < nvtxs; i++)
    MyDrawLine(dpy, win, gc, &vtxs[i-1], &vtxs[i]);
  if( nvtxs )
    MyDrawLine(dpy, win, gc, &vtxs[nvtxs-1], &vtxp);
    
  /* ungrab the pointer */
  HGU_XUngrabPointer(dpy, win);
    
  /* reset input mask */
  XSelectInput(dpy, win, win_att.your_event_mask );
    
  /* check for defined points */
  if( nvtxs == 0 ){
    if( vtxs != NULL )
      AlcFree( (void *) vtxs );
    return( NULL );
  }
   
  /* make a polygondomain to return values */
  vtxs = (WlzFVertex2 *) AlcRealloc(vtxs, sizeof(WlzFVertex2)*(nvtxs+2));
  vtxs[nvtxs] = vtxp;
  vtxs[nvtxs+1] = vtxs[0];

  /* return the new polygon */
  return_polydmn = WlzMakePolygonDomain(WLZ_POLYGON_FLOAT, nvtxs+1,
					 (WlzIVertex2 *) vtxs,
					 nvtxs+2, 1, NULL);
  AlcFree( (void *) vtxs );
  return return_polydmn;
}
Example #5
0
/*!
* \return	Woolz error code.
* \brief	Reads 2D tie points from the file and checks that they
* 		are within the mesh if the mesh is given.
* \param	dstNVx			Destination pointer for number of
* 					tie point pairs, must not be NULL.
* \param	dstVx0			Destination pointer for source
* 					vertices, must not be NULL.
* \param	dstVx1			Destination pointer for displacement
* 					vertices, must not be NULL.
* \param	fP			Input file.
* \param	tMesh			Target mesh, may be NULL.
* \param	prog			Program name for error output, must
* 					not be NULL.
* \param	fStr			input file name for error output, must
* 					not be NULL.
*/
static WlzErrorNum WlzBFTOGetVertices2D(int *dstNVx,
				WlzDVertex2 **dstVx0, WlzDVertex2 **dstVx1,
				FILE *fP, WlzCMesh2D *tMesh,
				const char *prog, const char *fStr)
{
  int		vxCount = 0,
  		vxLimit = 0;
  char 		*rec;
  WlzDVertex2	*vx0,
  		*vx1,
		*vxA0 = NULL,
		*vxA1 = NULL;
  const char    *errMsg;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  char  	inRecord[IN_RECORD_MAX];

  while((errNum == WLZ_ERR_NONE) &&
        (fgets(inRecord, IN_RECORD_MAX - 1, fP) != NULL))
  {
    inRecord[IN_RECORD_MAX - 1] = '\0';
    rec = inRecord;
    while(*rec && isspace(*rec))
    {
      ++rec;
    }
    if(*rec && (*rec != '#'))
    {
      if(vxCount >= vxLimit)
      {
	vxLimit += 4096;
	if(((vxA0 = (WlzDVertex2 *)
		    AlcRealloc(vxA0,
			       vxLimit * sizeof(WlzDVertex2))) == NULL) ||
	    ((vxA1 = (WlzDVertex2 *)
		     AlcRealloc(vxA1,
				vxLimit * sizeof(WlzDVertex2))) == NULL))
	{
	  errNum = WLZ_ERR_MEM_ALLOC;
	}
	else
	{
	  vx0 = vxA0 + vxCount;
	  vx1 = vxA1 + vxCount;
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
	if(sscanf(rec, "%lg %lg %lg %lg", &(vx0->vtX), &(vx0->vtY),
	      &(vx1->vtX), &(vx1->vtY)) != 4)
	{
	  errNum = WLZ_ERR_READ_INCOMPLETE;
	}
	else
	{
	  vx1->vtX += vx0->vtX;
	  vx1->vtY += vx0->vtY;
	}
      }
      if((errNum == WLZ_ERR_NONE) && (tMesh != NULL))
      {
	if(WlzCMeshElmEnclosingPos2D(tMesh, -1, vx1->vtX, vx1->vtY,
	                             0, NULL) < 0) 
	{
	  errNum = WLZ_ERR_DOMAIN_DATA;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
	      "%s: tie points line %d not in target mesh (%s).\n",
	      prog, vxCount, errMsg);
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
	++vx0;
	++vx1;
	++vxCount;
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    *dstNVx = vxCount;
    *dstVx0 = vxA0;
    *dstVx1 = vxA1;
  }
  else
  {
    (void )WlzStringFromErrorNum(errNum, &errMsg);
    (void )fprintf(stderr,
	"%s: Failed to read tie points file %s (%s).\n",
	prog, fStr, errMsg);
  }
  return(errNum);
}
Example #6
0
int main(int	argc,
	 char	**argv)
{

  WlzObject	*inObj, *outObj;
  WlzDomain	domain;
  WlzValues	values;
  FILE		*inFP, *outFP, *bibFP;
  char		*outFile, *bibFile;
  char 		optList[] = "b:f:o:hv";
  int		option;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  BibFileRecord	*bibfileRecord;
  BibFileError	bibFileErr;
  int		verboseFlg=0;
  WlzMeshTransform *meshTr = NULL;
  WlzFnType		wlzFnType;
  WlzMeshGenMethod	meshMthd;
  int			basisFnPolyOrder = 3;
  int			meshMinDst;
  int	 		meshMaxDst;
  WlzTransformType	affineType;
  WlzDVertex2		*srcVtxs, *dstVtxs;
  int		relFlg=0;
  int		numVtxs, maxNumVtxs;
  char		*errMsg;
    
  /* additional defaults */
  outFile = "-";
  bibFile = NULL;
  numVtxs = 0;
  maxNumVtxs = 0;
  srcVtxs = NULL;
  dstVtxs = NULL;

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

    case 'b':
      bibFile = optarg;
      break;

    case 'o':
      outFile = optarg;
      break;

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

    case 'v':
      verboseFlg = 1;
      break;

    }
  }

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

  /* check output file/stream */
  if(strcmp(outFile, "-"))
  {
    if((outFP = fopen(outFile, "w")) == NULL)
    {
      errNum = WLZ_ERR_WRITE_EOF;
    }
  }
  else
  {
    outFP = stdout;
  }

  /* check bibfile - get warp function parameters and tie-points */
  if((errNum == WLZ_ERR_NONE) && (bibFile != NULL)){
    if((bibFP = fopen(bibFile, "r")) != NULL){
      bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP);
      while( bibFileErr == BIBFILE_ER_NONE ){

	/* test for warp function and mesh parameters */
	if( !strncmp(bibfileRecord->name, "WlzWarpTransformParams", 22) ){

	  WlzEffBibParseWarpTransformParamsRecord(bibfileRecord,
						  &wlzFnType,
						  &affineType,
						  &meshMthd,
						  &meshMinDst, &meshMaxDst);
	}

	/* test for tie points */
	if( !strncmp(bibfileRecord->name, "WlzTiePointVtxs", 15) ){
	  int		index;
	  WlzDVertex3	dstVtx;
	  WlzDVertex3	srcVtx;

	  WlzEffBibParseTiePointVtxsRecord(bibfileRecord, &index,
				       &dstVtx, &srcVtx, &relFlg);
	  if( relFlg ){
	    fprintf(stderr, "%s: warning, relative vertex positions, probably an error\n",
		    argv[0]);
	  }
	  if( numVtxs >= maxNumVtxs ){
	    maxNumVtxs += 512;
	    srcVtxs = (WlzDVertex2 *) AlcRealloc(srcVtxs,
						 sizeof(WlzDVertex2)*maxNumVtxs);
	    dstVtxs = (WlzDVertex2 *) AlcRealloc(dstVtxs,
						 sizeof(WlzDVertex2)*maxNumVtxs);
	  }
	  srcVtxs[numVtxs].vtX = srcVtx.vtX;
	  srcVtxs[numVtxs].vtY = srcVtx.vtY;
	  dstVtxs[numVtxs].vtX = dstVtx.vtX;
	  dstVtxs[numVtxs].vtY = dstVtx.vtY;
	  numVtxs++;
	}

	BibFileRecordFree(&bibfileRecord);
	bibFileErr = BibFileRecordRead(&bibfileRecord, &errMsg, bibFP);
      }
      fclose( bibFP );
      if( bibFileErr == BIBFILE_ER_EOF ){
	bibFileErr = BIBFILE_ER_NONE;
      }
      if( bibFileErr != BIBFILE_ER_NONE ){
	fprintf(stderr, "%s: error reading bibfile\n", argv[0]);
  	return 1;
      }
    }
    else {
      fprintf(stderr, "%s: can't open parameter bibfile %s\n", argv[0],
	      bibFile);
      return 1;
    }
  }
  else {
    fprintf(stderr, "%s: warp parameters and tie-points bibfile required\n",
	    argv[0]);
    usage(argv[0]);
    return 1;
  }
  
  /* read objects and section if possible */
  while((errNum == WLZ_ERR_NONE) &&
        ((inObj = WlzReadObj(inFP, &errNum)) != NULL))
  {
    switch( inObj->type )
    {
    case WLZ_2D_DOMAINOBJ:
      /* now create the mesh transform */
      if((meshTr = WlzMeshTransformFromCPts(inObj, wlzFnType, basisFnPolyOrder,
					    numVtxs, srcVtxs, numVtxs, dstVtxs,
					    meshMthd, meshMinDst, meshMaxDst,
					    &errNum)) != NULL){
	/* write out transform and free */
	domain.mt = meshTr;
	values.core = NULL;
	outObj = WlzMakeMain(WLZ_MESH_TRANS, domain, values, NULL, NULL, &errNum);
	WlzWriteObj(outFP, outObj);
	WlzFreeObj(outObj);
      }
      else {
	/* something wrong */
	fprintf(stderr,
		"%s: failed to generate a mesh transform, error code: %d\n",
		argv[0], errNum);
      }
      break;

    default:
      fprintf(stderr, "%s: 2D input object required\n", argv[0]);
      usage(argv[0]);
      return 1;
    }

    WlzFreeObj(inObj);
  }
  if(errNum == WLZ_ERR_READ_EOF)
  {
    errNum = WLZ_ERR_NONE;
  }

  return errNum;
}
int		main(int argc, char *argv[])
{
  int		idC,
  		idO,
		idP,
  		option,
		ok = 1,
  		usage = 0,
		mean = 0,
		stddev = 0,
		nObjs = 0,
		maxObjs = 0;
  FILE		*fP = NULL;
  char		*fStr,
  		*outObjFileStr;
  const char	*errMsgStr;
  WlzObject	*inObj = NULL,
  		*outObj = NULL;
  WlzObject	**objs = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  static char   optList[] = "hmso:";
  const char    fileStrDef[] = "-";
  const int	stepObjs = 1024;

  opterr = 0;
  outObjFileStr = (char *)fileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != EOF))
  {
    switch(option)
    {
      case 'o':
        outObjFileStr = optarg;
	break;
      case 'm':
	mean = 1;
	break;
      case 's':
        stddev = 1;
	break;
      case 'h':
      default:
	usage = 1;
	break;
    }
  }
  ok = !usage;
  if(ok)
  {
    if((outObjFileStr == NULL) || (*outObjFileStr == '\0'))
    {
      ok = 0;
      usage = 1;
    }
  }
  if(ok)
  {
    maxObjs += stepObjs;
    if((objs = AlcMalloc(maxObjs * sizeof(WlzObject *))) == NULL)
    {
      ok = 0;
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }
  /* Read objects from the command line. */
  if(ok) 
  {
    int		nFiles;

    idO = 0;
    nFiles = argc - optind;
    while((errNum == WLZ_ERR_NONE) && (idO < nFiles))
    {
      if(nObjs >= maxObjs)
      {
        maxObjs += stepObjs;
	if((objs = AlcRealloc(objs, stepObjs * sizeof(WlzObject *))) == NULL)
	{
	  ok = 0;
	  errNum = WLZ_ERR_MEM_ALLOC;
	  break;
	}
      }
      if(ok)
      {
        fStr = *(argv + optind + idO);
	if((fP = (strcmp(fStr, "-")?  fopen(fStr, "rb"): stdin)) == NULL)
	{
	  errNum = WLZ_ERR_READ_EOF;
	}
	else
	{
	  objs[nObjs] = WlzAssignObject(
	  		WlzReadObj(fP, &errNum), NULL);
	  if(errNum == WLZ_ERR_NONE)
	  {
	    ++nObjs;
	  }
	  if(strcmp(fStr, "-"))
	  {
	    (void )fclose(fP);
	  }
	}
      }
      ++idO;
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
	       "%s: failed to read input objects from command line (%s).\n",
		     *argv, errMsgStr);
    }
  }
  /* Create a single compound object from the input objects. */
  if(ok)
  {
    int		oCnt = 0,
    		oType = 0;

    for(idO = 0; idO < nObjs; ++idO)
    {
      if(objs[idO])
      {
        switch(objs[idO]->type)
	{
	  case WLZ_2D_DOMAINOBJ:
	    ++oCnt;
	    if(oType == 0)
	    {
	      oType = 2;
	    }
	    else if(oType != 2)
	    {
	      errNum = WLZ_ERR_OBJECT_TYPE;
	    }
	    break;
	  case WLZ_3D_DOMAINOBJ:
	    ++oCnt;
	    if(oType == 0)
	    {
	      oType = 3;
	    }
	    else if(oType != 3)
	    {
	      errNum = WLZ_ERR_OBJECT_TYPE;
	    }
	    break;
	  case WLZ_COMPOUND_ARR_1: /* FALLTHOUGH */
	  case WLZ_COMPOUND_ARR_2:
	    oCnt += ((WlzCompoundArray *)(objs[idO]))->n;
	    break;
	  default:
	    errNum = WLZ_ERR_OBJECT_TYPE;
	    break;
	}
	if(errNum != WLZ_ERR_NONE)
	{
	  break;
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      inObj = (WlzObject *)WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1,
      				1, oCnt, NULL, WLZ_NULL, &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      idC = 0;
      for(idO = 0; idO < nObjs; ++idO)
      {
	if(objs[idO])
	{
	  switch(objs[idO]->type)
	  {
	    case WLZ_2D_DOMAINOBJ: /* FALLTHOUGH */
	    case WLZ_3D_DOMAINOBJ:
	      ((WlzCompoundArray *)inObj)->o[idC++] =
	        WlzAssignObject(objs[idO], NULL);
	      break;
	    case WLZ_COMPOUND_ARR_1: /* FALLTHOUGH */
	    case WLZ_COMPOUND_ARR_2:
	      for(idP = 0; idP < ((WlzCompoundArray *)(objs[idO]))->n; ++idP)
	      {
		((WlzCompoundArray *)inObj)->o[idC++] =
		  WlzAssignObject(((WlzCompoundArray *)(objs[idO]))->o[idP],
		                  NULL);
	      }
	      break;
	    default:
	      break;
	  }
	}
      }
      ((WlzCompoundArray *)(inObj))->n = idC;
      if((((WlzCompoundArray *)(inObj))->n < 1) ||
         (((WlzCompoundArray *)(inObj))->o[0] == NULL))
      {
        errNum = WLZ_ERR_OBJECT_NULL;
      }
      else
      {
        ((WlzCompoundArray *)(inObj))->otype = ((WlzCompoundArray *)
	                                        (inObj))->o[0]->type;
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
	       "%s: Failed to create compound object of input object (%s).\n",
		     *argv, errMsgStr);
    }
  }
  if(objs)
  {
    for(idO = 0; idO < nObjs; ++idO)
    {
      (void )WlzFreeObj(objs[idO]);
    }
    AlcFree(objs);
    objs = NULL;
  }
  /* Create compound object for collecting thye statistics. */
  if(ok)
  {
    outObj = (WlzObject *)WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1,
      				1, 4, NULL, 
				((WlzCompoundArray *)(inObj))->otype,
				&errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
	   "%s: Failed to allocate compound object for output object (%s).\n",
		     *argv, errMsgStr);
    }
  }
  /* Compute the cross object statistics. */
  if(ok)
  {
    errNum = WlzNObjGreyStats(inObj, mean, stddev, NULL,
                              &(((WlzCompoundArray *)outObj)->o[0]),
                              &(((WlzCompoundArray *)outObj)->o[1]),
                              &(((WlzCompoundArray *)outObj)->o[2]),
                              &(((WlzCompoundArray *)outObj)->o[3]));
    if(errNum == WLZ_ERR_NONE)
    {
      for(idO = 0; idO < 4; ++idO)
      {
        (void )WlzAssignObject(((WlzCompoundArray *)outObj)->o[idO], NULL);
      }
    }
    else
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
      "%s: Failed to compute cross object statistics (%s).\n",
                     *argv, errMsgStr);
    }
  }
  /* Output cross object statistics compound object. */
  if(ok)
  {
    if((fP = (strcmp(outObjFileStr, "-")?
	     fopen(outObjFileStr, "w"): stdout)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Failed to open output file %s.\n",
		     argv[0], outObjFileStr);
    }
  }
  if(ok)
  {
    errNum = WlzWriteObj(fP, outObj);
    if(strcmp(outObjFileStr, "-"))
    {
      (void )fclose(fP);
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
                     "%s: Failed to write output object, %s.\n",
		     argv[0], errMsgStr);
    }
  }
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(outObj);
  /* Report usage. */
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-h] [-m] [-s] [-o<output file>] [<input objects>]\n"
    "Version: %s\n"
    "Options:\n"
    "  -h  Output this usage message.\n"
    "  -o  Output file name, default is the standard output.\n"
    "  -m  Output mean instead of sum of values.\n"
    "  -s  Output standard deviation instead of sum of squares of values.\n"
    "Reads objects (including compound objects) from the given files in\n"
    "turn: First from the files specified on the commandline and then from\n"
    "the standard input. The output objects are written to a single compound\n"
    "object. Each object of the compound object will have the same domain\n"
    "(which is the intersection of the input object domains) and values for\n"
    "the simple statistics. The statistics generated are min value, max\n"
    "value, sum of values and sum of squares of values.\n"
    "Example:\n"
    "  cat obj1.wlz obj2.wlz obj3.wlz | %s -s -m obj4.wlz >out.wlz\n"
    "Creates a compound object with four component objects, the domains of\n"
    "which are all the intersection of the domains of the input objects\n"
    "(obj[1-4].wlz) and the values are the minimum, maximum, mean and\n"
    "standard deviation of the input object values across the objects within\n"
    "the intersection domain.\n",
    argv[0],
    WlzVersion(),
    argv[0]);
  }
  return(!ok);
}
Example #8
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;
}
Example #9
0
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;
}
Example #10
0
int             main(int argc, char **argv)
{
  int		nTiePP,
		option,
		vxCount = 0,
		vxLimit = 0,
		basisFnPolyOrder = 3,
                index,
                relFlag,
                meshMinDist,
                meshMaxDist;
  char 		*srcFileStr,
		*bibFileStr = NULL,
                *outFileStr,
                *bibErrMsg;
  const char    *errMsg;
  FILE		*inFile = NULL,
                *outFile = NULL;
  WlzDVertex2   *sVtx2 = NULL,
                *dVtx2 = NULL,
                *srcVtx2 = NULL,
                *dstVtx2 = NULL;
  WlzDVertex3   *dVtx = NULL, 
                *sVtx = NULL,
                *srcVtx = NULL,   
                *dstVtx = NULL;
  WlzObject	*inObj = NULL;
  WlzCompoundArray  *outObj = NULL;              
  WlzBasisFnTransform  *basisTr;
  WlzTransformType     trType;
  WlzFnType basisFnType;
  WlzMeshGenMethod genMethod;
  WlzErrorNum	errNum = WLZ_ERR_NONE; 
  BibFileRecord	       *bibfileRecord;
  BibFileError         bibFileErr;
  
  /* read the argument list and check for an input file */

  static char	       optList[] = "s:b:t:h";
 
   while( (option = getopt(argc, argv, optList)) != EOF )
   {
      switch( option )
      {
        case 'h':
             usage(argv[0]);
	     return(0);
        case 'b':
	    bibFileStr = optarg;
	    break;
        case 's':
	    srcFileStr = optarg;
	    break;
        case 't':
	    outFileStr = optarg;
	    break;
        default:
              return(0);
      }
   }
   if((inFile = fopen(bibFileStr, "r")) == NULL )
   {
       printf("cannot open the input bib file.\n");
       exit(1);
   }
   /* read the bibfile until we get the WlzWarptransformParams part */

   while( !feof(inFile) ){
      bibFileErr = BibFileRecordRead(&bibfileRecord, &bibErrMsg, inFile);
      if(bibFileErr != BIBFILE_ER_EOF)
      {
	bibFileErr = WlzEffBibParseWarpTransformParamsRecord(
						bibfileRecord,
						&basisFnType,
						&trType,
						&genMethod,
						&meshMinDist,
						&meshMaxDist);
	 if (bibFileErr == BIBFILE_ER_NONE)
	   break;
      }
      else
	break;
   }

   /* read the bibfile until we get the TiePointVtxs part */
   if(  bibFileErr == BIBFILE_ER_NONE )
   {
     while( !feof(inFile) ){
       bibFileErr = BibFileRecordRead(&bibfileRecord, &bibErrMsg, inFile);
       if(bibFileErr != BIBFILE_ER_EOF)
       {
	    if(vxCount >= vxLimit)
	    {
	      vxLimit = (vxLimit + 1024) * 2;
	      if(((srcVtx = (WlzDVertex3 *)AlcRealloc(srcVtx,
			     vxLimit * sizeof(WlzDVertex3))) == NULL) ||
		 ((dstVtx = (WlzDVertex3 *)AlcRealloc(dstVtx,
			     vxLimit * sizeof(WlzDVertex3))) == NULL))
	      {
		errNum = WLZ_ERR_MEM_ALLOC;
	      }
	      else
	      {
		sVtx = srcVtx + vxCount;
		dVtx = dstVtx + vxCount;
	      }
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      bibFileErr = WlzEffBibParseTiePointVtxsRecord(
						bibfileRecord,
						&index,
						dVtx,
						sVtx,
						&relFlag);
	      if (bibFileErr == BIBFILE_ER_NONE)
	      {	      
		++sVtx;
		++dVtx;
		++vxCount;
	      }
	    }
      }
      else
	break;
     }
   }

   nTiePP = vxCount;

   BibFileRecordFree(&bibfileRecord);

   fclose(inFile);

   if(  bibFileErr == BIBFILE_ER_EOF )
   {
     errNum = WLZ_ERR_NONE;
   }
   else
   {
     printf("Read bib file error.\n");
     exit(1);
   }

   /* copy 3D verices to 2D vertices - cast won't work */
   if(((srcVtx2 = (WlzDVertex2 *)AlcRealloc(srcVtx2,
		  vxCount * sizeof(WlzDVertex2))) == NULL) ||
		  ((dstVtx2 = (WlzDVertex2 *)AlcRealloc(dstVtx2,
		  vxCount * sizeof(WlzDVertex2))) == NULL))
   {
     errNum = WLZ_ERR_MEM_ALLOC;
   }
   else
   {
     sVtx = srcVtx;
     dVtx = dstVtx;
     sVtx2 = srcVtx2;
     dVtx2 = dstVtx2;
     for (vxCount = 0; vxCount < nTiePP;  vxCount++)
     {
       sVtx2->vtX = sVtx->vtX;
       sVtx2->vtY = sVtx->vtY;
       dVtx2->vtX = dVtx->vtX;
       dVtx2->vtY = dVtx->vtY;
       ++sVtx2;
       ++dVtx2;
       ++sVtx;
       ++dVtx;
     }
   }

   errNum = WLZ_ERR_READ_EOF;
   if((srcFileStr == NULL) ||
	(*srcFileStr == '\0') ||
	((inFile = (strcmp(srcFileStr, "-")?
		fopen(srcFileStr, "r"): stdin)) == NULL) ||
       	((inObj= WlzAssignObject(WlzReadObj(inFile, &errNum), NULL)) == NULL) 
               || (errNum != WLZ_ERR_NONE))
   {
      (void )fprintf(stderr,
		     "%s: failed to read object from file %s\n",
		     *argv, srcFileStr);
   }
   if(inFile)
   {
      if(strcmp(srcFileStr, "-"))
      {
	fclose(inFile);
      }
      inFile = NULL;
   }
  if(errNum == WLZ_ERR_NONE)
  {
      basisTr = WlzAffineBasisFnTransformFromCPtsT(inObj, basisFnType, 
					    basisFnPolyOrder,
					    nTiePP, srcVtx2, nTiePP, dstVtx2, 
					    &errNum);
  }
  
  /* Calculate tensor components and then write them out. */
  if(errNum == WLZ_ERR_NONE)
  {
    outObj = WlzBasisFnTensorTransformObjPrv(inObj, basisTr, &errNum);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    (void )WlzStringFromErrorNum(errNum, &errMsg);
    (void )fprintf(stderr,
    	       "%s: failed to transform object (%s).\n",
       	       *argv, errMsg);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WLZ_ERR_WRITE_EOF;
    if(((outFile = (strcmp(outFileStr, "-")?
		  fopen(outFileStr, "w"):
		  stdout)) == NULL) ||
	          ((errNum = WlzWriteObj(outFile, (WlzObject *)outObj)) 
		   != WLZ_ERR_NONE))
    {
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
			 "%s: failed to write output compound array (%s).\n",
			 *argv, errMsg);
    }
    if(outFile && strcmp(outFileStr, "-"))
    {
      fclose(outFile);
    }
  }

  /* free memory */
  AlcFree(srcVtx);
  AlcFree(dstVtx);
  AlcFree(srcVtx2);
  AlcFree(dstVtx2);
  WlzBasisFnFreeTransform(basisTr);
  return(errNum);
}
int		main(int argc, char *argv[])
{
  int		option,
  		ok = 1,
  		idx = 0,
  		usage = 0,
		fileList = 0,
		gTrans = 0,
		nObj,
		nObjMax,
		nFiles,
		plane1 = 0,
		sTrans = 0;
  FILE		*fP;
  char		*fStr,
  		*fLstStr = NULL,
  		*outFileStr = NULL;
  const char	*errMsgStr;
  WlzEffFormat	outFmt = WLZEFF_FORMAT_WLZ;
  WlzDVertex3	voxSz;
  WlzObject	*obj = NULL;
  WlzObject	**objs = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  char		fStrBuf[WLZEFFCON_BUF_LEN];
  static char   optList[] = "fho:p:s:ST";
  const char    outFileStrDef[] = "-";

  opterr = 0;
  fStr = "";
  voxSz.vtX = voxSz.vtY = voxSz.vtZ = 1.0;
  outFileStr = (char *)outFileStrDef;
  while(ok && ((option = getopt(argc, argv, optList)) != EOF))
  {
    switch(option)
    {
      case 'f':
        fileList = 1;
	break;
      case 'o':
        outFileStr = optarg;
	break;
      case 'p':
	if(sscanf(optarg, "%d", &plane1) != 1)
	{
	  usage = 1;
	}
        break;
      case 's':
	if(sscanf(optarg, "%lg,%lg,%lg",
	          &(voxSz.vtX), &(voxSz.vtY), &(voxSz.vtZ)) != 3)
	{
	  usage = 1;
	}
        break;
      case 'G':
        gTrans = 1;
	break;
      case 'S':
        sTrans = 1;
	break;
      case 'h':
      default:
	usage = 1;
	break;
    }
  }
  ok = !usage;
  if(ok)
  {
    if((outFileStr == NULL) || (*outFileStr == '\0'))
    {
      ok = 0;
      usage = 1;
    }
  }
  if(ok)
  {
    if(((nFiles = argc - optind) <= 0) ||
       ((fileList != 0) && (nFiles != 1)))
    {
      ok = 0;
      usage = 1;
    }
  }
  if(ok)
  {
    nObj = 0;
    nObjMax = (fileList)? WLZEFFCON_FILE_STEP: nFiles;
    if((objs = (WlzObject **)AlcMalloc(nObjMax * sizeof(WlzObject *))) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: failed to allocate object list.\n",
		     *argv);
    }
  }
  /* Read the 2D image files. */
  if(ok)
  {
    if(fileList == 0)
    {
      idx = 0;
      while((errNum == WLZ_ERR_NONE) && (idx < nFiles))
      {
	fStr = *(argv + optind + idx);
	errNum = WlzEFFConAddImg(objs + idx, fStr, sTrans, gTrans);
	++idx;
      }
      nObj = idx;
    }
    else /* fileList != 0 */
    {
      fLstStr = *(argv + optind);
      if((fP = (strcmp(fLstStr, "-")?
	        fopen(fLstStr, "r"): stdin)) == NULL)
      {
	ok = 0;
	(void )fprintf(stderr,
		       "%s: failed to open file list in file %s.\n",
		       *argv, fStr);
      }
      else
      {
        idx = 0;
	nObj = 0;
	while((errNum == WLZ_ERR_NONE) &&
	      (fgets(fStrBuf, WLZEFFCON_BUF_LEN, fP) != NULL))
	{
	  if((idx + 1) > nObjMax)
	  {
	    nObjMax += WLZEFFCON_FILE_STEP;
	    if((objs = (WlzObject **)
	               AlcRealloc(objs,
		                  nObjMax * sizeof(WlzObject *))) == NULL)
            {
	      errNum = WLZ_ERR_MEM_ALLOC;
	    }
	  }
	  if(errNum == WLZ_ERR_NONE)
	  {
	    if(((fStr = strtok(fStrBuf, " \t\n")) != NULL) && (*fStr != '#'))
	    {
	      errNum = WlzEFFConAddImg(objs + idx, fStr, sTrans, gTrans);
	      ++idx;
	    }
	  }
	}
	nObj = idx;
      }
      if(fP && (strcmp(fLstStr, "-")))
      {
        (void )fclose(fP);
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: failed to read images at image %d\n",
		     *argv, idx);
    }
  }
  /* Construct the 3D object. */
  if(ok)
  {
    obj = WlzConstruct3DObjFromObj(nObj, objs, plane1,
                                   voxSz.vtX, voxSz.vtY, voxSz.vtZ,
				   &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
      		     "%s: Failed to construct 3D object (%s).\n",
      		     argv[0],
		     errMsgStr);
    }
  }
  /* Write out the 3D object. */
  if(ok)
  {
    if(strcmp(outFileStr, "-") == 0)
    {
      fP = stdout;
      outFileStr = NULL;
      outFmt = WLZEFF_FORMAT_WLZ;
    }
    else
    {
      fP = NULL;
      outFmt = WlzEffStringFormatFromFileName(outFileStr);
    }
    if(outFmt == WLZEFF_FORMAT_NONE)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Unrecognized file format for output file %s.\n",
		     argv[0], outFileStr);
    }
  }
  if(ok)
  {
    errNum = WlzEffWriteObj(NULL, outFileStr, obj, outFmt);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
                     "%s: Failed to write output object, %s.\n",
		     argv[0], errMsgStr);
    }
  }
  if(obj)
  {
    (void )WlzFreeObj(obj);
  }
  if(objs)
  {
    for(idx = 0; idx < nObj; ++idx)
    {
      (void )WlzFreeObj(*(objs + idx));
    }
    AlcFree(objs);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-h] [-f] [-o<output file>] [-p #] [-s #,#,#]\n"
    "                           [-G] [-S] [<file>|<input file list>]\n"
    "Version: %s\n"
    "Options:\n"
    "  -h  Output this usage message.\n"
    "  -f  Input file is a list of image files.\n"
    "  -o  Output file name, default is the standard output.\n"
    "  -p  Coordinate of the first plane.\n"
    "  -s  Voxel size (x,y,z).\n"
    "  -G  Apply grey value transforms.\n"
    "  -S  Use spatial transforms to create WLZ_TRANS_OBJ objects\n"
    "      (by default just offsets are applied).\n"
    "Given a set of 2D image files, these are read in turn and used\n"
    "to build a 3D image. The 2D image files can either be given on\n"
    "the command line or in a file.\n"
    "Alignment of the 2D images is assumed to be perfect and is not\n"
    "addressed.\n"
    "If a file is used to give the 2D image file names then there\n"
    "should be one image file name per line, although lines which\n"
    "start with a '#' character will be treated as comments and\n"
    "ignored.\n"
    "File formats are specified using the file 'extension' (.bmp,\n"
    ".jpg, .wlz, etc) in the file name.  The dash character ('-')\n"
    "can be used to specify the standard input and standard output,\n"
    "in which case the Woolz object format is used."
    "The word 'NULL' may be used to specify an empty section.\n"
    "Example:\n"
    "%s img00.bmp img01.bmp NULL img03.bmp img04.bmp >out.wlz\n"
    "Constructs a 3D woolz object from the 2D BMP image files\n"
    "img0X.bmp, with an empty 3rd section.\n",
    argv[0],
    WlzVersion(),
    argv[0]);
  }
  return(!ok);
}