Exemplo n.º 1
0
/*!
* \return	Error code.
* \ingroup	Reconstruct
* \brief	Given a destination directory and file body and a 3D
*		Woolz object, the 3D object is and exploded into a series of 2D
*		section files (in the destination directory) each with a name
*		formed from the given file body and the source plane index. A
*		section list is also created in the directory using the given
*		file body together with the  '.bib' file extension.
* \param	dstDirStr		Destination directory.
* \param	dstBodyStr		Destination file body.
* \param	srcObj			Source 3D woolz object.
* \param	srcFName		Source file name, may be NULL.
* \param	srcFFormat		Source file format, may be
*					WLZEFF_FORMAT_NONE.
* \param	eMsg			Destinagtion pointer for messages.
*/
RecError	RecExplode3DObjToFile(char *dstDirStr, char *dstBodyStr,
				      WlzObject *srcObj, char *srcFName,
				      WlzEffFormat srcFFormat, char **eMsg)
{
  int		objIdx,
		planeIdx,
  		objVecCount,
		fileStrSpace;
  char		*fileStr = NULL,
  		*fileTemplateStr = NULL;
  FILE		*fP;
  WlzObject	**objVec = NULL;
  RecSectionList *secList = NULL;
  RecError	errFlag = REC_ERR_NONE;
  struct stat	statBuf;
  const char 	*errDirAccessStr = "Failed to access directory",
		*errDirCreateStr = "Failed to create directory",
  		*errExplodeStr = "Failed to explode 3D object",
  		*errWriteWoolzStr = "Failed to write 2D section file",
		*errListAppendStr = "Failed to build section list",
		*errWriteListStr = "Failed to write section list to file";
  const char	*errStr = NULL;

  REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_1),
	  ("RecExplode3DObjToFile FE 0x%lx 0x%lx 0x%lx 0x%lx %d 0x%lx\n",
	   (unsigned long )dstDirStr, (unsigned long )dstBodyStr,
	   (unsigned long )srcObj, (unsigned long )srcFName,
	   srcFFormat, (unsigned long )eMsg));
  if((dstDirStr == NULL) || (strlen(dstDirStr) == 0) ||
     (dstBodyStr == NULL) || (strlen(dstBodyStr) == 0) || 
     (srcObj == NULL) || (srcObj->type != WLZ_3D_DOMAINOBJ) ||
     (srcObj->domain.core == NULL))
  {
    errFlag = REC_ERR_FUNC;
  }
  if(errFlag == REC_ERR_NONE)       /* Check for/create destination directory */
  {
    if(stat(dstDirStr, &statBuf) == 0)			 /* Directory exists */
    {
#ifdef LINUX2
      if((statBuf.st_mode & (__S_IFDIR|__S_IREAD|__S_IWRITE|__S_IEXEC)) == 0)
#else /* LINUX2 */
      if((statBuf.st_mode & (S_IFDIR | S_IRWXU)) == 0)
#endif /* LINUX2 */
      {
	errStr = errDirAccessStr;
	errFlag = REC_ERR_WRITE;         /* Can't read/write/search directory */
      }
    }
    else
    {
      if(mkdir(dstDirStr, S_IRWXU))
      {
	errStr = errDirCreateStr;
	errFlag = REC_ERR_WRITE;
      }
      
    }
    REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_2),
	    ("RecExplode3DObjToFile 01 %d\n",
	     (int )errFlag));
  }
  if(errFlag == REC_ERR_NONE) 	  	      /* Explode the 3D Woolz object */
  {
    if((errFlag = RecErrorFromWlz(
    		  WlzExplode3D(&objVecCount, &objVec, srcObj))) != REC_ERR_NONE)
    {
      errStr = errExplodeStr;
    }
    REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_2),
	    ("RecExplode3DObjToFile 02 %d\n",
	     (int )errFlag));
  }
  if(errFlag == REC_ERR_NONE)                       /* Create a section list */
  {
    if(((secList = RecSecNewSectionList(NULL)) == NULL) ||
       ((secList->list = HGUDlpListCreate(NULL)) == NULL))
    {
      errFlag = REC_ERR_MALLOC;
    }
    else
    {
      secList->reconstruction.fileName = srcFName;
      secList->reconstruction.fileFormat = srcFFormat;
    }
    REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_2),
	    ("RecExplode3DObjToFile 03 %d\n",
	     (int )errFlag));
  }
  if(errFlag == REC_ERR_NONE)     /* Write 2D files, build/write section list */
  {
    fP = NULL;
    objIdx = 0;
    planeIdx = srcObj->domain.p->plane1;
    fileStrSpace = (int )strlen(dstDirStr) + (int )strlen(dstBodyStr) + 64;
    if(((fileStr = AlcMalloc(sizeof(char) * fileStrSpace)) == NULL) ||
       ((fileTemplateStr = AlcMalloc(sizeof(char) * fileStrSpace)) == NULL))
    {
      errFlag = REC_ERR_MALLOC;
    }
    else
    {
      (void )sprintf(fileTemplateStr, "%s/%s", dstDirStr, dstBodyStr);
    }
    while((errFlag == REC_ERR_NONE) && (objIdx < objVecCount))
    {
      (void )sprintf(fileStr, "%s_%06d.wlz", fileTemplateStr, planeIdx);
      if((fP = fopen(fileStr, "w")) == NULL)
      {
	errStr = errWriteWoolzStr;
        errFlag = REC_ERR_WRITE;
      }
      if(errFlag == REC_ERR_NONE)
      {
	if((errFlag = RecErrorFromWlz(
		      WlzWriteObj(fP, *(objVec + objIdx)))) != REC_ERR_NONE)
	{
	  errStr = errWriteWoolzStr;
	}
        fclose(fP);
      }
      if(errFlag == REC_ERR_NONE)
      {
        errFlag = RecSecAppendListFromFiles(secList->list, NULL, &fileStr, 1,
					    planeIdx, 1);
        if(errFlag != REC_ERR_NONE)
	{
	  errStr = errListAppendStr;
	}
      }
      if(errFlag == REC_ERR_NONE)
      {
	++objIdx;
	++planeIdx;
      }
    }
    if(objVec && (objVecCount > 0))
    {
      for(objIdx = 0; objIdx < objVecCount; ++objIdx)
      {
	if(*(objVec + objIdx))
	{
	  (void )WlzFreeObj(*(objVec + objIdx));
	}
      }
      free(objVec);
    }
    if(errFlag == REC_ERR_NONE)
    {
      (void )sprintf(fileStr, "%s.bib", fileTemplateStr);
      if((fP = fopen(fileStr, "w")) == NULL)
      {
        errStr = errWriteListStr;
	errFlag = REC_ERR_WRITE;
      }
      else
      {
	errFlag = RecFileSecListWrite(fP, secList, objVecCount, eMsg);
	fclose(fP);
      }
    }
    if(fileStr)
    {
      free(fileStr);
    }
    if(fileTemplateStr)
    {
      free(fileTemplateStr);
    }
    if(secList)
    {
      HGUDlpListDestroy(secList->list);
      AlcFree(secList);
    }
    REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_2),
	    ("RecExplode3DObjToFile 04 %d\n",
	     (int )errFlag));
  }
  if((errFlag != REC_ERR_NONE) && eMsg && (*eMsg == NULL) && (errStr != NULL))
  {
    *eMsg = AlcStrDup(errStr);
  }
  REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_1),
  	  ("RecExplode3DObjToFile FX %d\n",
	   (int )errFlag));
  return(errFlag);
}
Exemplo n.º 2
0
int main(int	argc,
	 char	**argv)
{
  FILE		*inFile1=NULL, *inFile2=NULL;
  char 		optList[] = "AR123f:F:iIx:y:z:s:a:b:u:v:w:hV";
  int		option;
  int		trans1RelFlg=0, trans2RelFlg=0, trans3DFlg=0, outputRelFlg=0;
  int		invertFlg=0, inverseFlg=0, threeDFlg=0;
  WlzAffineTransform	*cmdLineTrans=NULL;
  double	tx, ty, tz, scale, theta, phi, alpha, psi, xsi;
  int		verboseFlg=0;
  RecSectionList	recSecList1, recSecList2;
  RecSectionList	*secList1=&recSecList1, *secList2=&recSecList2;
  HGUDlpListItem	*listItem, *listItem1;
  RecSection	*sec, *sec1;
  char		*errMsg = NULL;
  RecError	errFlg = REC_ERR_NONE;
  int		numSec1, numSec2;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzObject	*transformsObj1, *transformsObj2;
  int		p, i, ip;
  WlzAffineTransform	*newTransform, *tmpTrans, *tmp1Trans, *reconTrans;

  /* default transform */
  tx = 0.0;
  ty = 0.0;
  tx = 0.0;
  scale = 1.0;
  theta = 0.0;
  phi = 0.0;
  alpha = 0.0;
  psi = 0.0;
  xsi = 0.0;

  /* parse the command line */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'A':
      outputRelFlg = 0;
      break;

    case 'R':
      outputRelFlg = 1;
      break;

    case '1':
      trans1RelFlg = 1;
      break;

    case '2':
      trans2RelFlg = 1;
      break;

    case '3':
      trans3DFlg = 1;
      break;

    case 'f':
      if( (optarg != NULL) && (strlen(optarg) > 0) ){
	if( (inFile1 = fopen(optarg, "r")) == NULL ){
	  fprintf(stderr, "%s: failed to open input file %s\n",
		  argv[0], optarg);
	  usage(argv[0]);
	  return 1;
	}
      }
      else {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'F':
      if( (optarg != NULL) && (strlen(optarg) > 0) ){
	if( (inFile2 = fopen(optarg, "r")) == NULL ){
	  fprintf(stderr, "%s: failed to open input file %s\n",
		  argv[0], optarg);
	  usage(argv[0]);
	  return 1;
	}
      }
      else {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'i':
      invertFlg = 1;
      break;

    case 'I':
      inverseFlg = 1;
      break;

    case 'a':
      if(sscanf(optarg, "%lg", &theta) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'b':
      if(sscanf(optarg, "%lg", &phi) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 's':
      if(sscanf(optarg, "%lg", &scale) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'u':
      if(sscanf(optarg, "%lg", &alpha) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'v':
      if(sscanf(optarg, "%lg", &psi) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'w':
      if(sscanf(optarg, "%lg", &xsi) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'x':
      if(sscanf(optarg, "%lg", &tx) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

     case 'y':
      if(sscanf(optarg, "%lg", &ty) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'z':
      if(sscanf(optarg, "%lg", &tz) != 1)
      {
	usage(argv[0]);
	return 1;
      }
      break;

    case 'V':
      verboseFlg = 1;
      break;

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

    }
  }

  /* create the command line transform */
  if( threeDFlg ){
    cmdLineTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_3D_AFFINE,
					      tx, ty, tz, scale, theta, phi,
					      alpha, psi, xsi,
					      invertFlg, &errNum);
  }
  else {
     cmdLineTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					      tx, ty, tz, scale, theta, phi,
					      alpha, psi, xsi,
					      invertFlg, &errNum);
  }

  /* check for files on the command line */
  if( (inFile1 == NULL) && (optind < argc) ){
    if( (inFile1 = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    optind++;
  }
  if( (inFile2 == NULL) && (optind < argc) ){
    if( (inFile2 = fopen(*(argv+optind), "r")) == NULL ){
      fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind));
      usage(argv[0]);
      return 1;
    }
    optind++;
  }

  /* now read the transforms, in each case the logic is that
     transform 1 is applied then transform 2 then the command line
     transform. If transform 1 is a reconstruct bib file then the
     output will include the file information. Note in this case
     the output transform will be absolute unless specified on the
     command line */

  /* transform 1 - try to read as a Reconstruct file, on failure
     rewind and read as an MAPaint file */
  if( inFile1 != NULL ){
    errFlg = RecFileSecListRead(secList1, &numSec1, inFile1, &errMsg);
    if( errFlg == REC_ERR_NONE ){
      /* check transform attribute */
      switch( secList1->attributes.trMode ){
      case REC_TRMODE_REL:
	trans1RelFlg = 1;
	break;
      case REC_TRMODE_ABS:
	trans1RelFlg = 0;
	break;
      }
      transformsObj1 = SecListToTransforms(secList1, trans1RelFlg, &errNum);
    }
    else {
      secList1 = NULL;
      rewind(inFile1);
      transformsObj1 = ReadMAPaintRealignTransforms(inFile1, &errNum);
    }
  }
  else {
    fprintf(stderr, "%s: a file for transform 1 must be defined\n", argv[0]);
    usage(argv[0]);
    return 1;
  }

  /* transform 2 - try to read as a Reconstruct file, on failure
     rewind and read as an MAPaint file */
  if( inFile2 != NULL ){
    errFlg = RecFileSecListRead(secList2, &numSec2, inFile2, &errMsg);
    if( errFlg == REC_ERR_NONE ){
      /* check transform attribute */
      switch( secList2->attributes.trMode ){
      case REC_TRMODE_REL:
	trans2RelFlg = 1;
	break;
      case REC_TRMODE_ABS:
	trans2RelFlg = 0;
	break;
      }
      transformsObj2 = SecListToTransforms(secList2, trans2RelFlg, &errNum);
    }
    else {
      secList2 = NULL;
      rewind(inFile2);
      transformsObj2 = ReadMAPaintRealignTransforms(inFile2, &errNum);
    }
  }
  else {
    transformsObj2 = NULL;
  }

  /* form the plane by plane product of the transforms,
     note the output will be of the planes in transform 1 */
  for(p=transformsObj1->domain.p->plane1, i=0;
      p <= transformsObj1->domain.p->lastpl; p++, i++){

    /* get the existing transform */
    if( transformsObj1->domain.p->domains[i].t ){
      newTransform =
	WlzAssignAffineTransform(transformsObj1->domain.p->domains[i].t,
				 NULL);
    }
    else {
      newTransform = NULL;
    }

    /* check for transform 2 */
    if(newTransform && transformsObj2 &&
       (p >= transformsObj2->domain.p->plane1) &&
       (p <= transformsObj2->domain.p->lastpl) &&
       (transformsObj2->domain.p->
	domains[p-transformsObj2->domain.p->plane1].t)){
      tmpTrans =
	WlzAffineTransformProduct(newTransform,
				  transformsObj2->domain.p->
				  domains[p-transformsObj2->domain.p->plane1].t,
				  NULL);
      WlzFreeAffineTransform(newTransform);
      newTransform = tmpTrans;
    }

    /* apply the command line transform */
    if( newTransform && cmdLineTrans ){
      tmpTrans = WlzAffineTransformProduct(newTransform, cmdLineTrans, NULL);
      WlzFreeAffineTransform(newTransform);
      newTransform = tmpTrans;
    }

    /* put it back into transformsObj1 */
    if( transformsObj1->domain.p->domains[i].t ){
      WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
    }
    transformsObj1->domain.p->domains[i].t =
      WlzAssignAffineTransform(newTransform, NULL);
  }

  /* if there is a section list in Reconstruct form
     then take out the reconstruct transform */
  if( secList1 ){
    /* take out the reconstruct transform first */
    reconTrans = WlzAffineTransformFromPrimVal
      (WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0,
       1.0 / secList1->reconstruction.scale.vtX,
       0.0, 0.0, 0.0, 0.0, 0.0, 0, NULL);
    listItem = HGUDlpListHead(secList1->list);
    while( listItem ){
      sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem);
      if( sec ){
	p = sec->index;
	i = p - transformsObj1->domain.p->plane1;
	if( transformsObj1->domain.p->domains[i].t ){
	  tmpTrans = WlzAffineTransformProduct
	    (transformsObj1->domain.p->domains[i].t, reconTrans, NULL);
	  WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	  transformsObj1->domain.p->domains[i].t =
	    WlzAssignAffineTransform(tmpTrans, NULL);
	}
      }
      listItem = HGUDlpListNext(secList1->list, listItem);
    }

  }

  /* check for relative flag */
  if( outputRelFlg ){
    /* use the section list if available */
    if( secList1 ){

      /* sort out the relative transform */
      listItem = HGUDlpListTail(secList1->list);
      while( listItem != HGUDlpListHead(secList1->list) ){
	sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem);
	if( sec ){
	  p = sec->index;
	  i = p - transformsObj1->domain.p->plane1;
	  if( strncmp(sec->imageFile, "empty", 5) == 0 ){
	    WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	    transformsObj1->domain.p->domains[i].t =
	      WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
					 0.0, 0.0, 0.0, 1.0,
					 0.0, 0.0, 0.0, 0.0,
					 0.0, 0, NULL);
	  }
	  else {
	    /* walk backwards to previous non-empty section */
	    listItem1 = HGUDlpListPrev(secList1->list, listItem);
	    while( listItem1 != HGUDlpListHead(secList1->list) ){
	      sec1 = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem1);
	      if( strncmp(sec1->imageFile, "empty", 5) ){
		break;
	      }
	      listItem1 = HGUDlpListPrev(secList1->list, listItem1);
	    }
	    ip = sec1->index - transformsObj1->domain.p->plane1;
	    tmpTrans =
	      WlzAffineTransformInverse(transformsObj1->domain.p->domains[ip].t,
					NULL);
	    tmp1Trans = WlzAffineTransformProduct(
	      transformsObj1->domain.p->domains[i].t,
	      tmpTrans, NULL);
	    checkTrans(tmp1Trans);
	    WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	    WlzFreeAffineTransform(tmpTrans);
	    transformsObj1->domain.p->domains[i].t = tmp1Trans;
	  }
	}
	listItem = HGUDlpListPrev(secList1->list, listItem);
      }
    }
    else {
      i = transformsObj1->domain.p->lastpl - transformsObj1->domain.p->plane1;
      ip = i;
      for(p = transformsObj1->domain.p->lastpl;
	  p >= transformsObj1->domain.p->plane1; p--, i--){
	if( i > ip ){
	  continue;
	}
	ip--;
	if(transformsObj1->domain.p->domains[i].t){
	  /* jump over any NULL transforms */
	  while((ip >= 0) &&
		(transformsObj1->domain.p->domains[ip].t == NULL)){
	      ip--;
	  }

	  /* push the transform down the line */
	  if(ip >= 0){
	    tmpTrans =
	      WlzAffineTransformInverse(transformsObj1->domain.p->domains[ip].t,
					NULL);
	    tmp1Trans =
	      WlzAffineTransformProduct(transformsObj1->domain.p->domains[i].t,
					tmpTrans,
					NULL);
	    checkTrans(tmp1Trans);
	    WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t);
	    WlzFreeAffineTransform(tmpTrans);
	    transformsObj1->domain.p->domains[i].t =
	      WlzAssignAffineTransform(tmp1Trans, NULL);
	  }
	}
      }
    }
  }

  /* if there is a section list one then output in Reconstruct
     bibfile format else MAPaint style */
  if( secList1 ){
    /* set the relative/absolute attribute */
    if( outputRelFlg ){
      secList1->attributes.trMode = REC_TRMODE_REL;
    }
    else {
      secList1->attributes.trMode = REC_TRMODE_ABS;
    }

    /* put back the transforms */
    listItem = HGUDlpListHead(secList1->list);
    while( listItem ){
      sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem);
      p = sec->index;
      i = p - transformsObj1->domain.p->plane1;

      /* check for NULL transform */
      if( transformsObj1->domain.p->domains[i].t == NULL ){
	transformsObj1->domain.p->domains[i].t =
	  WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE,
				     0.0, 0.0, 0.0, 1.0,
				     0.0, 0.0, 0.0, 0.0,
				     0.0, 0, NULL);
      }

      sec->transform = 
	transformsObj1->domain.p->domains[i].t;
      
      listItem = HGUDlpListNext(secList1->list, listItem);
    }
    RecFileSecListWrite(stdout, secList1, numSec1, &errMsg);
  }
  else {
    WriteMAPaintRealignTransforms(stdout, transformsObj1, outputRelFlg);
  }

  return 0;
}
Exemplo n.º 3
0
int		 main(int argc, char *argv[])
{
  int		option,
  		numSec,
  		absMode = 1,
		ok = 1,
  		usage = 0;
  char		*inFile,
  		*outFile;
  FILE		*fP = NULL;
  RecError	recErr = REC_ERR_NONE;
  RecSectionList *secList = NULL;
  char		*errMsg;
  static char	optList[] = "ahro:",
  		defFile[] = "-",
		defErrMsg[] = "none.";

  opterr = 0;
  errMsg = defErrMsg;
  inFile = outFile = defFile;
  while((usage == 0) &&
        ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'a':
	absMode = 1;
	break;
      case 'r':
	absMode = 0;
	break;
      case 'o':
	outFile = optarg;
	break;
      case 'h': /* FALLTHROUGH */
      default:
	usage = 1;
	break;
    }
  }
  if((usage == 0) && (optind < argc))
  {
    if((optind + 1) != argc)
    {
      usage = 1;
    }
    else
    {
      inFile = *(argv + optind);
    }
  }
  ok = !usage;
  /* Read input bibfile. */
  if(ok)
  {
    if((secList = RecSecNewSectionList(&recErr)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Failed to memory for allocate section list.\n",
		     *argv);
    }
  }
  if(ok)
  {
    if((inFile == NULL) ||
       (*inFile == '\0') ||
       ((fP = (strcmp(inFile, "-")?  fopen(inFile, "r"): stdin)) == NULL))
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to open input file %s\n",
		     *argv, (inFile)? inFile: "(null)");
    }
  }
  if(ok)
  {
    if(RecFileSecListRead(secList, &numSec, fP, &errMsg) != REC_ERR_NONE)
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to read section list from file %s.\n"
		     "Error message - %s\n",
		     *argv, inFile, errMsg);
    }
  }
  if(fP && (strcmp(inFile, "-") == 0))
  {
    (void )fclose(fP);
  }
  /* Convert transforms. */
  if(ok)
  {
    if(absMode)
    {
      recErr = RecSecListAbsFromRel(secList);
    }
    else
    {
      recErr = RecSecListRelFromAbs(secList);
    }
    if(recErr != REC_ERR_NONE)
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to convert the section list from %s to\n"
		     "%s transforms.\n",
		     *argv,
		     (absMode)? "relative": "absolute",
		     (absMode)? "absolute": "relative");

    }
  }
  /* Write output bibfile. */
  if(ok)
  {
    if((outFile == NULL) ||
       (*outFile == '\0') ||
       ((fP = (strcmp(outFile, "-")?  fopen(outFile, "w"): stdout)) == NULL))
    {
      ok = 0;
      (void )fprintf(stderr,
                     "%s: Failed to open output file %s\n",
		     *argv, (inFile)? inFile: "(null)");
    }
  }
  if(ok)
  {
    if(RecFileSecListWrite(fP, secList, numSec, &errMsg) != REC_ERR_NONE)
    {
      (void )fprintf(stderr,
      		     "%s: Failed to write section list to file %s.\n"
		     "Error message - %s\n",
		     *argv, inFile, errMsg);
      ok = 0;
    }
  }
  if(fP && (strcmp(outFile, "-") == 0))
  {
    (void )fclose(fP);
  }
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s [-a] [-h] [-r] [-o outfile] [<infile>]\n"
    "Reads a reconstruction bibfile and writes it to the output file\n"
    "with either absolute or relative transforms.\n"
    "Version: %s\n"
    "Options:\n"
    "  -a  Output bibfile with absolute transforms (%s).\n"
    "  -h  Help - print this usage information.\n"
    "  -r  Output bibfile with relative transforms (%s).\n"
    "  -o  Output file name.\n"
    "By default %s reads from it's standard input and\n"
    "writes to it's standard output.\n",
    *argv,
    WlzVersion(),
    (absMode != 0)? "set": "not set",
    (absMode == 0)? "set": "not set",
    *argv);
  }
  exit(!ok);
}