https://github.com/ma-tech/Woolz
Tip revision: 5ab012fff0fb50186d6ea8508f0d8b3063c45dc3 authored by Bill Hill on 15 August 2022, 13:30:41 UTC
README now Readme.md.
README now Readme.md.
Tip revision: 5ab012f
WlzWriteObj.c
#if defined(__GNUC__)
#ident "University of Edinburgh $Id$"
#else
static char _WlzWriteObj_c[] = "University of Edinburgh $Id$";
#endif
/*!
* \file libWlz/WlzWriteObj.c
* \author Richard Baldock, Bill Hill
* \date September 2005
* \version $Id$
* \par
* Address:
* MRC Human Genetics Unit,
* MRC Institute of Genetics and Molecular Medicine,
* University of Edinburgh,
* Western General Hospital,
* Edinburgh, EH4 2XU, UK.
* \par
* Copyright (C), [2012],
* The University Court of the University of Edinburgh,
* Old College, Edinburgh, UK.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be
* useful but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
* \brief Functions for writing Woolz objects.
* \ingroup WlzIO
*/
#include <errno.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <Wlz.h>
/* #define WLZ_DEBUG_WRITEOBJ */
#if defined(_WIN32) && !defined(__x86)
#define __x86
#endif
static WlzErrorNum WlzWriteIntervalDomain(
FILE *fP,
WlzIntervalDomain *itvl);
static WlzErrorNum WlzWritePlaneDomain(
FILE *fP,
WlzPlaneDomain *planedm);
static WlzErrorNum WlzWritePropertyList(
FILE *fP,
WlzPropertyList *pList);
static WlzErrorNum WlzWriteProperty(
FILE *fP,
WlzProperty property);
static WlzErrorNum WlzWriteValueTable(
FILE *fP,
WlzObject *obj);
static WlzErrorNum WlzWriteVoxelValueTable(
FILE *fP,
WlzObject *obj);
static WlzErrorNum WlzWriteTiledValueTable(
FILE *fP,
WlzObject *obj,
int writeTiles);
static WlzErrorNum WlzWritePolygon(
FILE *fP,
WlzPolygonDomain *poly);
static WlzErrorNum WlzWriteBoundList(
FILE *fP,
WlzBoundList *blist);
static WlzErrorNum WlzWriteRect(
FILE *fP,
WlzIRect *rdom);
static WlzErrorNum WlzWriteHistogramDomain(
FILE *fP,
WlzHistogramDomain *hist);
static WlzErrorNum WlzWriteCompoundA(
FILE *fP,
WlzCompoundArray *c);
static WlzErrorNum WlzWriteAffineTransform(
FILE *fP,
WlzAffineTransform *trans);
static WlzErrorNum WlzWriteWarpTrans(
FILE *fP,
WlzWarpTrans *obj);
static WlzErrorNum WlzWriteFMatchObj(
FILE *fP,
WlzFMatchObj *obj);
static WlzErrorNum WlzWrite3DWarpTrans(
FILE *fP,
Wlz3DWarpTrans *obj);
static WlzErrorNum WlzWriteContour(
FILE *fP,
WlzContour *ctr);
static WlzErrorNum WlzWriteGMModel(
FILE *fP,
WlzGMModel *model);
static WlzErrorNum WlzWriteInt(
FILE *fP,
int *iP,
size_t nI);
static WlzErrorNum WlzWriteShort(
FILE *fP,
short *iP,
size_t nI);
static WlzErrorNum WlzWriteUByte(
FILE *fP,
WlzUByte *iP,
size_t nI);
static WlzErrorNum WlzWriteFloat(
FILE *fP,
float *iP,
size_t nI);
static WlzErrorNum WlzWriteDouble(
FILE *fP,
double *iP,
size_t nI);
static WlzErrorNum WlzWriteVertex2I(
FILE *fP,
WlzIVertex2 *vP,
int nV);
static WlzErrorNum WlzWriteVertex2D(
FILE *fP,
WlzDVertex2 *vP,
int nV);
static WlzErrorNum WlzWriteVertex3I(
FILE *fP,
WlzIVertex3 *vP,
int nV);
static WlzErrorNum WlzWriteVertex3D(
FILE *fP,
WlzDVertex3 *vP,
int nV);
static WlzErrorNum WlzWriteStr(
FILE *fP,
char *str);
static WlzErrorNum WlzWritePixelV(
FILE *fP,
WlzPixelV *pV,
int nPV);
static WlzErrorNum WlzWriteGreyV(
FILE *fP,
WlzGreyType type,
WlzGreyV *gV,
int nGV);
static WlzErrorNum WlzWriteMeshTransform2D(
FILE *fP,
WlzMeshTransform *mTrans);
static WlzErrorNum WlzWriteCMesh2D(
FILE *fP,
int **dstNodTbl,
WlzCMesh2D *mesh);
static WlzErrorNum WlzWriteCMesh2D5(
FILE *fP,
int **dstNodTbl,
WlzCMesh2D5 *mesh);
static WlzErrorNum WlzWriteCMesh3D(
FILE *fP,
int **dstNodTbl,
WlzCMesh3D *mesh);
static WlzErrorNum WlzWriteIndexedValues(
FILE *fP,
WlzObject *obj);
static WlzErrorNum WlzWriteLUTDomain(
FILE *fP,
WlzLUTDomain *lDom);
static WlzErrorNum WlzWriteLUTValues(
FILE *fP,
WlzObject *obj);
static WlzErrorNum WlzWrite3DViewStruct(
FILE *fp,
WlzThreeDViewStruct *vs);
static WlzErrorNum WlzWritePoints(
FILE *fP,
WlzPoints *pts);
static WlzErrorNum WlzWritePointValues(
FILE *fP,
WlzObject *obj);
static WlzErrorNum WlzWriteConvexHull(
FILE *fP,
WlzDomain dom);
static WlzErrorNum WlzWriteSpline(
FILE *fP,
WlzBSpline *bs);
#ifdef WLZ_UNUSED_FUNCTIONS
static WlzErrorNum WlzWriteBox2I(
FILE *fP,
WlzIBox2 *bP,
int nB);
static WlzErrorNum WlzWriteBox2D(
FILE *fP,
WlzDBox2 *bP,
int nB);
static WlzErrorNum WlzWriteBox3I(
FILE *fP,
WlzIBox3 *bP,
int nB);
static WlzErrorNum WlzWriteBox3D(
FILE *fP,
WlzDBox3 *bP,
int nB);
#endif /* WLZ_UNUSED_FUNCTIONS */
/* These macros convert sequences of bytes from the architecture's endianness
* to the Woolz file format order. */
#if defined (__sparc) || defined (__mips) || defined (__ppc)
#define WLZ_SWAP_OUT_WORD(T,S) \
(T).ubytes[0] = (S).ubytes[3]; \
(T).ubytes[1] = (S).ubytes[2]; \
(T).ubytes[2] = (S).ubytes[1]; \
(T).ubytes[3] = (S).ubytes[0];
#endif /* __sparc || __mips */
#if defined (__x86) || defined (__alpha)
#define WLZ_SWAP_OUT_WORD(T,S) \
(T).inv = (S).inv;
#endif /* __x86 || __alpha */
#if defined (__sparc) || defined (__mips) || defined (__ppc)
#define WLZ_SWAP_OUT_SHORT(T,S) \
(T).ubytes[0] = (S).ubytes[1]; \
(T).ubytes[1] = (S).ubytes[0];
#endif /* __sparc || __mips */
#if defined (__x86) || defined (__alpha)
#define WLZ_SWAP_OUT_SHORT(T,S) \
(T).shv = (S).shv;
#endif /* __x86 || __alpha */
#if defined (__sparc) || defined (__mips) || defined (__ppc)
#define WLZ_SWAP_OUT_FLOAT(T,S) \
(T).ubytes[0] = (S).ubytes[1]; \
(T).ubytes[1] = (S).ubytes[0] + 1; \
(T).ubytes[2] = (S).ubytes[3]; \
(T).ubytes[3] = (S).ubytes[2];
#endif /* __sparc || __mips */
#if defined (__x86) || defined (__alpha)
#define WLZ_SWAP_OUT_FLOAT(T,S) \
(T).ubytes[3] = (S).ubytes[1]; \
(T).ubytes[2] = (S).ubytes[0]; \
(T).ubytes[1] = (S).ubytes[3] + 1; \
(T).ubytes[0] = (S).ubytes[2];
#endif /* __x86 || __alpha */
#if defined (__sparc) || defined (__mips) || defined (__ppc)
#define WLZ_SWAP_OUT_DOUBLE(T,S) \
(T).ubytes[0] = (S).ubytes[7]; \
(T).ubytes[1] = (S).ubytes[6]; \
(T).ubytes[2] = (S).ubytes[5]; \
(T).ubytes[3] = (S).ubytes[4]; \
(T).ubytes[4] = (S).ubytes[3]; \
(T).ubytes[5] = (S).ubytes[2]; \
(T).ubytes[6] = (S).ubytes[1]; \
(T).ubytes[7] = (S).ubytes[0];
#endif /* __sparc || __mips */
#if defined (__x86) || defined (__alpha)
#define WLZ_SWAP_OUT_DOUBLE(T,S) \
(T).dbv = (S).dbv;
#endif /* __x86 || __alpha */
/*!
* \return Number of bytes written.
* \ingroup WlzIO
* \brief Writes an integer reordered to DEC VAX(!) format.
* \param i Value written.
* \param fP Given file.
*/
static int putword(int i, FILE *fP)
{
WlzGreyV in,
out;
in.inv = i;
WLZ_SWAP_OUT_WORD(out, in);
return((int )fwrite(out.ubytes, sizeof(char), 4, fP));
}
/*!
* \return Number of bytes written.
* \ingroup WlzIO
* \brief Writes a short reordered to DEC VAX(!) format.
* \param i Value written.
* \param fP Given file.
*/
static int putshort(short i, FILE *fP)
{
WlzGreyV in,
out;
in.shv = i;
WLZ_SWAP_OUT_SHORT(out, in);
return((int )fwrite(out.ubytes, sizeof(char), 2, fP));
}
/*!
* \return Number of bytes written.
* \ingroup WlzIO
* \brief Writes a float reordered to DEC VAX(!) format.
* \param f Value written.
* \param fP Given file.
*/
static int putfloat(float f, FILE *fP)
{
WlzGreyV in,
out;
in.flv = f;
WLZ_SWAP_OUT_FLOAT(out, in);
return((int )fwrite(out.ubytes, sizeof(char), 4, fP));
}
/*!
* \return Number of bytes written.
* \ingroup WlzIO
* \brief Writes a double reordered to DEC VAX(!) format.
* \param f Value written.
* \param fP Given file.
*/
static int putdouble(double d, FILE *fP)
{
WlzGreyV in,
out;
in.dbv = d;
WLZ_SWAP_OUT_DOUBLE(out, in);
return((int )fwrite(out.ubytes, sizeof(char), 8, fP));
}
/*!
* \return Woolz error number code.
* \ingroup WlzIO
* \brief Top-level procedure for writing an object to a file stream.
* For historical reasons most data are written using DEC VAX
* byte ordering.
*
* \param fP File pointer for output.
* \param obj Ptr to top-level object to be written.
*/
WlzErrorNum WlzWriteObj(FILE *fP, WlzObject *obj)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
if(fP == NULL)
{
errNum = WLZ_ERR_PARAM_NULL;
}
#ifdef _WIN32
else if(_setmode(_fileno(fP), 0x8000) == -1)
{
errNum = WLZ_ERR_READ_EOF;
}
#endif
else if(obj == NULL)
{
if(putc((unsigned int )0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else if(putc((unsigned int )obj->type, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
else if(errNum == WLZ_ERR_NONE)
{
switch( obj->type )
{
case WLZ_EMPTY_OBJ:
/* Nothing except the object type needs to be written */
break;
case WLZ_2D_DOMAINOBJ:
errNum = WlzWriteIntervalDomain(fP, obj->domain.i);
if(errNum == WLZ_ERR_NONE)
{
if((obj->values.core == NULL) ||
(WlzGreyTableIsTiled(obj->values.core->type) == 0))
{
errNum = WlzWriteValueTable(fP, obj);
}
else
{
errNum = WlzWriteTiledValueTable(fP, obj, 1);
}
}
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_3D_DOMAINOBJ:
errNum = WlzWritePlaneDomain(fP, obj->domain.p);
if(errNum == WLZ_ERR_NONE)
{
if((obj->values.core == NULL) ||
(WlzGreyTableIsTiled(obj->values.core->type) == 0))
{
errNum = WlzWriteVoxelValueTable(fP, obj);
}
else
{
errNum = WlzWriteTiledValueTable(fP, obj, 1);
}
}
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_TRANS_OBJ:
if(((errNum = WlzWriteAffineTransform(fP,
obj->domain.t)) == WLZ_ERR_NONE) &&
((errNum = WlzWriteObj(fP, obj->values.obj)) == WLZ_ERR_NONE))
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_3D_WARP_TRANS:
if((errNum = WlzWrite3DWarpTrans(fP,
(Wlz3DWarpTrans *)obj)) == WLZ_ERR_NONE)
{
errNum = WlzWritePropertyList(fP, ((Wlz3DWarpTrans *)obj)->plist);
}
break;
case WLZ_2D_POLYGON:
errNum = WlzWritePolygon(fP, obj->domain.poly);
break;
case WLZ_BOUNDLIST:
errNum = WlzWriteBoundList(fP, obj->domain.b);
break;
case WLZ_HISTOGRAM:
errNum = WlzWriteHistogramDomain(fP, obj->domain.hist);
break;
case WLZ_CONTOUR:
errNum = WlzWriteContour(fP, obj->domain.ctr);
break;
case WLZ_SPLINE:
errNum = WlzWriteSpline(fP, obj->domain.bs);
break;
case WLZ_CMESH_2D:
if(((errNum = WlzWriteCMesh2D(fP, NULL,
obj->domain.cm2)) == WLZ_ERR_NONE) &&
((errNum = WlzWriteIndexedValues(fP, obj)) == WLZ_ERR_NONE))
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_CMESH_2D5:
if(((errNum = WlzWriteCMesh2D5(fP, NULL,
obj->domain.cm2d5)) == WLZ_ERR_NONE) &&
((errNum = WlzWriteIndexedValues(fP, obj)) == WLZ_ERR_NONE))
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_CMESH_3D:
if(((errNum = WlzWriteCMesh3D(fP, NULL,
obj->domain.cm3)) == WLZ_ERR_NONE) &&
((errNum = WlzWriteIndexedValues(fP, obj)) == WLZ_ERR_NONE))
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_RECTANGLE:
errNum = WlzWriteRect(fP, obj->domain.r);
break;
case WLZ_AFFINE_TRANS:
errNum = WlzWriteAffineTransform(fP, obj->domain.t);
break;
case WLZ_3D_VIEW_STRUCT:
errNum = WlzWrite3DViewStruct(fP, obj->domain.vs3d);
break;
case WLZ_WARP_TRANS:
errNum = WlzWriteWarpTrans(fP, (WlzWarpTrans *)obj);
break;
case WLZ_FMATCHOBJ:
errNum = WlzWriteFMatchObj(fP, (WlzFMatchObj *)obj);
break;
case WLZ_COMPOUND_ARR_1: /* FALLTHROUGH */
case WLZ_COMPOUND_ARR_2:
errNum = WlzWriteCompoundA(fP, (WlzCompoundArray *)obj);
break;
case WLZ_PROPERTY_OBJ:
errNum = WlzWritePropertyList(fP, obj->plist);
break;
case WLZ_CONV_HULL:
#ifdef WLZ_OLDCODE_CONVHULL
if((errNum = WlzWritePolygon(fP, obj->domain.poly)) == WLZ_ERR_NONE)
{
errNum = WlzWriteConvexHullValues(fP, obj->values.c);
}
#else
errNum = WlzWriteConvexHull(fP, obj->domain);
#endif
break;
case WLZ_3D_POLYGON:
errNum = WLZ_ERR_OBJECT_TYPE;
break;
case WLZ_MESH_TRANS:
errNum = WlzWriteMeshTransform2D(fP, obj->domain.mt);
break;
case WLZ_LUT:
if(((errNum = WlzWriteLUTDomain(fP,
obj->domain.lut)) == WLZ_ERR_NONE) &&
((errNum = WlzWriteLUTValues(fP, obj)) == WLZ_ERR_NONE))
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
case WLZ_POINTS:
if(((errNum = WlzWritePoints(fP,
obj->domain.pts)) == WLZ_ERR_NONE) &&
((errNum = WlzWritePointValues(fP, obj)) == WLZ_ERR_NONE))
{
errNum = WlzWritePropertyList(fP, obj->plist);
}
break;
/* Orphans and not yet implemented object types for I/O */
case WLZ_CONVOLVE_INT: /* FALLTHROUGH */
case WLZ_CONVOLVE_FLOAT: /* FALLTHROUGH */
case WLZ_TEXT: /* FALLTHROUGH */
case WLZ_COMPOUND_LIST_1: /* FALLTHROUGH */
case WLZ_COMPOUND_LIST_2: /* FALLTHROUGH */
default:
errNum = WLZ_ERR_OBJECT_TYPE;
break;
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given native int values to the given file
* as a 4 byte integer.
* \param fP Given file.
* \param iP Ptr to native ints.
* \param nI Number of ints.
*/
static WlzErrorNum WlzWriteInt(FILE *fP, int *iP, size_t nI)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nI-- > 0))
{
if(!putword(*iP, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++iP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given native short values to the given file
* as a 2 byte short integer.
* \param fP Given file.
* \param iP Ptr to native shorts.
* \param nI Number of shorts.
*/
static WlzErrorNum WlzWriteShort(FILE *fP, short *iP, size_t nI)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nI-- > 0))
{
if(!putshort(*iP, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++iP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given native unsigned byte values to the given file
* as a single unsigned byte.
* \param fP Given file.
* \param iP Ptr to native unsigned bytes.
* \param nI Number of bytes.
*/
static WlzErrorNum WlzWriteUByte(FILE *fP, WlzUByte *iP, size_t nI)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
if(fwrite(iP, sizeof(WlzUByte), nI, fP) != nI)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given native float values to the given file
* as a 4 floats.
* \param fP Given file.
* \param iP Ptr to native floats.
* \param nI Number of floats.
*/
static WlzErrorNum WlzWriteFloat(FILE *fP, float *iP, size_t nI)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nI-- > 0))
{
if(!putfloat(*iP, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++iP;
}
if(fwrite(iP, sizeof(float), nI, fP) != nI)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given native double values to the given file
* as a 8 byte doubles.
* \param fP Given file.
* \param iP Ptr to native doubles.
* \param nI Number of doubles.
*/
static WlzErrorNum WlzWriteDouble(FILE *fP, double *iP, size_t nI)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nI-- > 0))
{
if(!putdouble(*iP, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++iP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 2D integer verticies to the given file.
* \param fP Given file.
* \param vP Ptr to 2D integer verticies.
* \param nV Number of verticies.
*/
static WlzErrorNum WlzWriteVertex2I(FILE *fP, WlzIVertex2 *vP, int nV)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nV-- > 0))
{
if(!putword(vP->vtY, fP) || !putword(vP->vtX, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++vP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 2D double verticies to the given file.
* \param fP Given file.
* \param vP Ptr to 2D double verticies.
* \param nV Number of verticies.
*/
static WlzErrorNum WlzWriteVertex2D(FILE *fP, WlzDVertex2 *vP, int nV)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nV-- > 0))
{
if(!putdouble(vP->vtY, fP) || !putdouble(vP->vtX, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++vP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 3D integer verticies to the given file.
* \param fP Given file.
* \param vP Ptr to 3D integer verticies.
* \param nV Number of verticies.
*/
static WlzErrorNum WlzWriteVertex3I(FILE *fP, WlzIVertex3 *vP, int nV)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nV-- > 0))
{
if(!putword(vP->vtX, fP) || !putword(vP->vtY, fP) ||
!putword(vP->vtZ, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++vP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 3D double verticies to the given file.
* \param fP Given file stream.
* \param vP Ptr to 3D double verticies.
* \param nV Number of verticies.
*/
static WlzErrorNum WlzWriteVertex3D(FILE *fP, WlzDVertex3 *vP, int nV)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nV-- > 0))
{
if(!putdouble(vP->vtX, fP) || !putdouble(vP->vtY, fP) ||
!putdouble(vP->vtZ, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++vP;
}
return(errNum);
}
#ifdef WLZ_UNUSED_FUNCTIONS
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 2D integer box to the given file.
* \param fP Given file.
* \param bP Ptr to 2D integer box.
* \param nB Number of bounding boxes.
*/
static WlzErrorNum WlzWriteBox2I(FILE *fP, WlzIBox2 *bP, int nB)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nB-- > 0))
{
if(!putword(bP->xMin, fP) || !putword(bP->yMin, fP) ||
!putword(bP->xMax, fP) || !putword(bP->yMax, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++bP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 2D double box to the given file.
* \param fP Given file.
* \param bP Ptr to 2D double box.
* \param nB Number of bounding boxes.
*/
static WlzErrorNum WlzWriteBox2D(FILE *fP, WlzDBox2 *bP, int nB)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nB-- > 0))
{
if(!putdouble(bP->xMin, fP) || !putdouble(bP->yMin, fP) ||
!putdouble(bP->xMax, fP) || !putdouble(bP->yMax, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++bP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 3D integer box to the given file.
* \param fP Given file.
* \param bP Ptr to 3D integer box.
* \param nB Number of bounding boxes.
*/
static WlzErrorNum WlzWriteBox3I(FILE *fP, WlzIBox3 *bP, int nB)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nB-- > 0))
{
if(!putword(bP->xMin, fP) || !putword(bP->yMin, fP) ||
!putword(bP->zMin, fP) ||
!putword(bP->xMax, fP) || !putword(bP->yMax, fP) ||
!putword(bP->zMax, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++bP;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given 3D double box to the given file.
* \param fP Given file.
* \param bP Ptr to 3D double box.
* \param nB Number of bounding boxes.
*/
static WlzErrorNum WlzWriteBox3D(FILE *fP, WlzDBox3 *bP, int nB)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nB-- > 0))
{
if(!putdouble(bP->xMin, fP) || !putdouble(bP->yMin, fP) ||
!putdouble(bP->zMin, fP) ||
!putdouble(bP->xMax, fP) || !putdouble(bP->yMax, fP) ||
!putdouble(bP->zMax, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++bP;
}
return(errNum);
}
#endif /* WLZ_UNUSED_FUNCTIONS */
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes an ASCII string to the given file.
* \verbatim
<number of characters> int, 4 bytes
<characters>
\endverbatim
* \param fP Given file.
* \param str The string.
*/
static WlzErrorNum WlzWriteStr(FILE *fP, char *str)
{
int len;
WlzErrorNum errNum = WLZ_ERR_NONE;
len = strlen(str);
if((putword(len, fP) != 4) || (fwrite(str, 1, len, fP) != len))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes the given grey values to the given file. Each
* of the grey values may be of the same type.
* \param fP Given file.
* \param type Grey value type.
* \param gV The grey values.
* \param nGV Number of grey values to write.
*/
static WlzErrorNum WlzWriteGreyV(FILE *fP, WlzGreyType type,
WlzGreyV *gV, int nGV)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
switch(type)
{
case WLZ_GREY_INT:
while((errNum == WLZ_ERR_NONE) && (nGV-- > 0))
{
if(putword(gV->inv, fP) != 4)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++gV;
}
break;
case WLZ_GREY_SHORT:
while((errNum == WLZ_ERR_NONE) && (nGV-- > 0))
{
if(putshort(gV->shv, fP) != 2)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++gV;
}
break;
case WLZ_GREY_UBYTE:
while((errNum == WLZ_ERR_NONE) && (nGV-- > 0))
{
if(putc(((unsigned int )(gV->ubv)), fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++gV;
}
break;
case WLZ_GREY_FLOAT:
while((errNum == WLZ_ERR_NONE) && (nGV-- > 0))
{
if(putfloat(gV->flv, fP) != 4)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++gV;
}
break;
case WLZ_GREY_DOUBLE:
while((errNum == WLZ_ERR_NONE) && (nGV-- > 0))
{
if(putdouble(gV->dbv, fP) != 8)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++gV;
}
break;
case WLZ_GREY_RGBA:
while((errNum == WLZ_ERR_NONE) && (nGV-- > 0))
{
if(putword((int )(gV->rgbv), fP) != 4)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
++gV;
}
break;
default:
errNum = WLZ_ERR_GREY_TYPE;
break;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes the given pixel values to the given file. Each
* of the pixel values may be of a different type.
* \param fP Given file.
* \param pV The pixel values.
* \param nGV Number of grey values to write.
*/
static WlzErrorNum WlzWritePixelV(FILE *fP, WlzPixelV *pV, int nPV)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
while((errNum == WLZ_ERR_NONE) && (nPV-- > 0))
{
if(putc((unsigned int)pV->type, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzWriteGreyV(fP, pV->type, &(pV->v), 1);
}
++pV;
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's the given Woolz interval domain to the given file.
* \param fP Given file.
* \param itvl Interval domain.
*/
static WlzErrorNum WlzWriteIntervalDomain(FILE *fP, WlzIntervalDomain *itvl)
{
int i,
j,
nlines;
WlzIntervalLine *ivln;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(itvl == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
/* standardise it so no non-standard domains on disk
- can't do this it conflicts with read-only access
to object store */
/*WlzStandardIntervalDomain(itvl);*/
/* write the type and bounding box */
if((putc((unsigned int) itvl->type, fP) == EOF) ||
!putword(itvl->line1, fP) ||
!putword(itvl->lastln, fP) ||
!putword(itvl->kol1, fP) ||
!putword(itvl->lastkl, fP) )
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
switch(itvl->type)
{
case WLZ_INTERVALDOMAIN_INTVL:
nlines = itvl->lastln - itvl->line1;
for(i = 0; (i <= nlines) && (errNum == WLZ_ERR_NONE); i++)
{
if(!putword(itvl->intvlines[i].nintvs, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
ivln = itvl->intvlines;
for(i = 0; (i <= nlines) && (errNum == WLZ_ERR_NONE); i++)
{
for(j = 0; (j < ivln->nintvs) && (errNum == WLZ_ERR_NONE); j++)
{
if(!putword(ivln->intvs[j].ileft, fP) ||
!putword(ivln->intvs[j].iright, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
ivln++;
}
}
break;
case WLZ_INTERVALDOMAIN_RECT:
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a plane domain to the given file.
* \param fP Given file.
* \param planedm Palne domain.
*/
static WlzErrorNum WlzWritePlaneDomain(FILE *fP, WlzPlaneDomain *planedm)
{
int i,
nplanes;
float dummy_float = 0.0;
WlzDomain *domains;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(planedm == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if((putc((unsigned int )(planedm->type), fP) == EOF) ||
!putword(planedm->plane1, fP) ||
!putword(planedm->lastpl, fP) ||
!putword(planedm->line1, fP) ||
!putword(planedm->lastln, fP) ||
!putword(planedm->kol1, fP) ||
!putword(planedm->lastkl, fP) ||
!putfloat((planedm->voxel_size)[0], fP) ||
!putfloat((planedm->voxel_size)[1], fP) ||
!putfloat((planedm->voxel_size)[2], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
/* write dummy values of plane positions for backward
compatibility - should go on file-format revision */
nplanes = planedm->lastpl - planedm->plane1 + 1;
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++)
{
if(!putfloat(dummy_float, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
if(errNum == WLZ_ERR_NONE)
{
domains = planedm->domains;
switch(planedm->type)
{
case WLZ_PLANEDOMAIN_DOMAIN:
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++, domains++)
{
errNum = WlzWriteIntervalDomain(fP, (*domains).i);
}
break;
case WLZ_PLANEDOMAIN_POLYGON:
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++, domains++)
{
errNum = WlzWritePolygon(fP, (*domains).poly);
}
break;
case WLZ_PLANEDOMAIN_BOUNDLIST:
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++, domains++)
{
errNum = WlzWriteBoundList(fP, (*domains).b);
}
break;
case WLZ_PLANEDOMAIN_HISTOGRAM:
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++, domains++)
{
errNum = WlzWriteHistogramDomain(fP, (*domains).hist);
}
break;
case WLZ_PLANEDOMAIN_AFFINE:
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++, domains++)
{
errNum = WlzWriteAffineTransform(fP, (*domains).t);
}
break;
case WLZ_PLANEDOMAIN_WARP:
for(i = 0; (i < nplanes) && (errNum == WLZ_ERR_NONE); i++, domains++)
{
errNum = WlzWriteWarpTrans(fP, (*domains).wt);
}
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a single property to the given file.
* \param fP Given file.
* \param property Property to be written.
*/
static WlzErrorNum WlzWriteProperty(FILE *fP, WlzProperty property)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
if(property.core == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
switch( property.core->type ){
case WLZ_PROPERTY_SIMPLE:
/* Write the size */
if((putc((unsigned int) WLZ_PROPERTY_SIMPLE, fP) == EOF) ||
!putword(property.simple->size, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else if(!fwrite(property.simple->prop, property.simple->size, 1, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
break;
case WLZ_PROPERTY_EMAP:
if((putc((unsigned int) WLZ_PROPERTY_EMAP, fP) == EOF) ||
(putc((unsigned int) property.emap->emapType, fP) == EOF) ||
!fwrite(property.emap->modelUID,
EMAP_PROPERTY_UID_LENGTH, 1, fP) ||
!fwrite(property.emap->anatomyUID,
EMAP_PROPERTY_UID_LENGTH, 1, fP) ||
!fwrite(property.emap->targetUID,
EMAP_PROPERTY_UID_LENGTH, 1, fP) ||
!fwrite(property.emap->targetVersion,
EMAP_PROPERTY_VERSION_LENGTH, 1, fP) ||
!fwrite(property.emap->stage,
EMAP_PROPERTY_STAGE_LENGTH, 1, fP) ||
!fwrite(property.emap->subStage,
EMAP_PROPERTY_STAGE_LENGTH, 1, fP) ||
!fwrite(property.emap->modelName,
EMAP_PROPERTY_MODELNAME_LENGTH, 1, fP) ||
!fwrite(property.emap->version,
EMAP_PROPERTY_VERSION_LENGTH, 1, fP) ||
!putword(property.emap->creationTime, fP) ||
!fwrite(property.emap->creationAuthor,
EMAP_PROPERTY_AUTHORNAME_LENGTH, 1, fP) ||
!fwrite(property.emap->creationMachineName,
EMAP_PROPERTY_MACHINENAME_LENGTH, 1, fP) ||
!putword(property.emap->modificationTime, fP) ||
!fwrite(property.emap->modificationAuthor,
EMAP_PROPERTY_AUTHORNAME_LENGTH, 1, fP)){
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else {
if(property.emap->fileName &&
(strlen(property.emap->fileName) > 0)){
if(!putword(strlen(property.emap->fileName), fP) ||
!fwrite(property.emap->fileName, strlen(property.emap->fileName),
1, fP)){
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
else {
if(!putword(0, fP)){
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if((errNum == WLZ_ERR_NONE) && property.emap->comment &&
(strlen(property.emap->comment))){
if(!putword(strlen(property.emap->comment), fP) ||
!fwrite(property.emap->comment, strlen(property.emap->comment),
1, fP)){
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
else {
if(!putword(0, fP)){
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
break;
case WLZ_PROPERTY_NAME:
if(putc((unsigned int) WLZ_PROPERTY_NAME, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzWriteStr(fP, property.name->name);
}
break;
case WLZ_PROPERTY_GREY:
if(putc((unsigned int) WLZ_PROPERTY_GREY, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else if((errNum = WlzWriteStr(fP, property.greyV->name)) == WLZ_ERR_NONE)
{
errNum = WlzWritePixelV(fP, &(property.greyV->value), 1);
}
break;
case WLZ_PROPERTY_TEXT:
if(putc((unsigned int) WLZ_PROPERTY_TEXT, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else if((errNum = WlzWriteStr(fP, property.text->name)) == WLZ_ERR_NONE)
{
errNum = WlzWriteStr(fP, property.text->text);
}
break;
default:
errNum = WLZ_ERR_PROPERTY_TYPE;
break;
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a property list to the given file.
* \param fP Given file.
* \param pList Property list.
*/
static WlzErrorNum WlzWritePropertyList(FILE *fP, WlzPropertyList *pList)
{
AlcDLPItem *item;
WlzProperty property;
WlzErrorNum errNum = WLZ_ERR_NONE;
if((pList == NULL) || (pList->list == NULL) ||
(AlcDLPListCount(pList->list, NULL) < 1))
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if((putc(2,fP) == EOF) || !putword(AlcDLPListCount(pList->list, NULL), fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
item = pList->list->head;
do
{
if(item)
{
if(item->entry != NULL)
{
property.core = (WlzCoreProperty *)(item->entry);
errNum = WlzWriteProperty(fP, property);
}
else
{
putc(0,fP);
}
item = item->next;
}
} while((errNum == WLZ_ERR_NONE) && (item != pList->list->head));
}
}
return errNum;
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes the 2D values of a Woolz 2D domain object to the
* given file.
* \param fP Given file.
* \param obj Object containing values that
* are to be written to file.
*/
static WlzErrorNum WlzWriteValueTable(FILE *fP, WlzObject *obj)
{
WlzIntervalWSpace iwsp;
WlzGreyWSpace gwsp;
WlzGreyType gType;
WlzGreyP g;
WlzPixelV background,
min,
max;
int i;
WlzGreyType packing;
WlzErrorNum errNum = WLZ_ERR_NONE;
/* obj == NULL has been checked by WlzWriteObj() */
if(obj->values.core == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if(errNum == WLZ_ERR_NONE)
{
gType = WlzGreyTableTypeToGreyType(obj->values.core->type, &errNum);
}
if(errNum == WLZ_ERR_NONE)
{
/* The "type" written to disc only codes the pixel type.
The shape type on subsequent reading is entirely
determined by the object domain.
For the moment, choice is between standard ragged-rectangle
or true rectangle. */
if(putc((unsigned int )gType, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
background = WlzGetBackground(obj, &errNum);
if(errNum == WLZ_ERR_NONE)
{
switch(gType)
{
case WLZ_GREY_INT:
/* Calculate packing to minimise disc space */
if((errNum = WlzGreyRange(obj, &min, &max)) == WLZ_ERR_NONE)
{
if((min.v.inv >= 0) && (max.v.inv <= 255))
{
packing = WLZ_GREY_UBYTE;
}
else if((min.v.inv >= SHRT_MIN) && (max.v.inv <= SHRT_MAX))
{
packing = WLZ_GREY_SHORT;
}
else
{
packing = WLZ_GREY_INT;
}
if((putc((unsigned int )packing, fP) == EOF) ||
!putword(background.v.inv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
if((errNum = WlzInitGreyScan(obj, &iwsp, &gwsp)) == WLZ_ERR_NONE)
{
while((errNum == WLZ_ERR_NONE) &&
((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
{
g = gwsp.u_grintptr;
switch(packing)
{
case WLZ_GREY_INT:
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.inp++)
{
if(!putword(*g.inp, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
case WLZ_GREY_SHORT:
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.inp++)
{
if(!putshort((short) (*g.inp), fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
case WLZ_GREY_UBYTE:
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.inp++)
{
if(putc((unsigned int )*g.inp, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
default:
errNum = WLZ_ERR_GREY_TYPE;
break;
}
}
(void )WlzEndGreyScan(&iwsp, &gwsp);
if(errNum == WLZ_ERR_EOO)
{
errNum = WLZ_ERR_NONE;
}
}
}
break;
case WLZ_GREY_SHORT:
/* Calculate packing to minimise disc space */
if((errNum = WlzGreyRange(obj, &min, &max)) == WLZ_ERR_NONE)
{
if((min.v.shv >= 0) && (max.v.shv <= 255))
{
packing = WLZ_GREY_UBYTE;
}
else
{
packing = WLZ_GREY_SHORT;
}
if((putc((unsigned int )packing, fP) == EOF) ||
!putword(background.v.shv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
if((errNum = WlzInitGreyScan(obj, &iwsp, &gwsp)) == WLZ_ERR_NONE)
{
while((errNum == WLZ_ERR_NONE) &&
((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
{
g = gwsp.u_grintptr;
switch(packing)
{
case WLZ_GREY_SHORT:
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.shp++)
{
if(!putshort(*g.shp, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
case WLZ_GREY_UBYTE:
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.shp++)
{
if(putc((unsigned int) *g.shp, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
default:
errNum = WLZ_ERR_GREY_TYPE;
break;
}
}
(void )WlzEndGreyScan(&iwsp, &gwsp);
if(errNum == WLZ_ERR_EOO)
{
errNum = WLZ_ERR_NONE;
}
}
}
break;
case WLZ_GREY_UBYTE:
packing = WLZ_GREY_UBYTE;
if((putc((unsigned int )packing, fP) == EOF) ||
!putword(background.v.ubv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzInitGreyScan(obj, &iwsp, &gwsp);
}
if(errNum == WLZ_ERR_NONE)
{
while((errNum == WLZ_ERR_NONE) &&
((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
{
g = gwsp.u_grintptr;
if((int )fwrite(g.ubp, sizeof(WlzUByte),
iwsp.colrmn, fP) < iwsp.colrmn)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
(void )WlzEndGreyScan(&iwsp, &gwsp);
if(errNum == WLZ_ERR_EOO)
{
errNum = WLZ_ERR_NONE;
}
}
break;
case WLZ_GREY_FLOAT:
packing = WLZ_GREY_FLOAT;
if((putc((unsigned int )packing, fP) == EOF) ||
!putfloat(background.v.flv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzInitGreyScan(obj, &iwsp, &gwsp);
}
if(errNum == WLZ_ERR_NONE)
{
while((errNum == WLZ_ERR_NONE) &&
((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
{
g = gwsp.u_grintptr;
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.flp++)
{
if(!putfloat(*g.flp, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
(void )WlzEndGreyScan(&iwsp, &gwsp);
if(errNum == WLZ_ERR_EOO)
{
errNum = WLZ_ERR_NONE;
}
}
break;
case WLZ_GREY_DOUBLE:
packing = WLZ_GREY_DOUBLE;
if((putc((unsigned int )packing, fP) == EOF) ||
!putdouble(background.v.dbv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzInitGreyScan(obj, &iwsp, &gwsp);
}
if(errNum == WLZ_ERR_NONE)
{
while((errNum == WLZ_ERR_NONE) &&
((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
{
g = gwsp.u_grintptr;
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.dbp++)
{
if(!putdouble(*g.dbp, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
(void )WlzEndGreyScan(&iwsp, &gwsp);
if(errNum == WLZ_ERR_EOO)
{
errNum = WLZ_ERR_NONE;
}
}
break;
case WLZ_GREY_RGBA:
packing = WLZ_GREY_RGBA;
if((putc((unsigned int )packing, fP) == EOF) ||
!putword(background.v.rgbv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzInitGreyScan(obj, &iwsp, &gwsp);
}
if(errNum == WLZ_ERR_NONE)
{
while((errNum == WLZ_ERR_NONE) &&
((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
{
g = gwsp.u_grintptr;
for(i = 0; (i < iwsp.colrmn) && (errNum == WLZ_ERR_NONE);
i++, g.rgbp++)
{
if(!putword(*g.rgbp, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
(void )WlzEndGreyScan(&iwsp, &gwsp);
if(errNum == WLZ_ERR_EOO)
{
errNum = WLZ_ERR_NONE;
}
}
break;
default:
errNum = WLZ_ERR_GREY_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes the voxel values of a Woolz object to the given file.
* \param fP Given file.
* \param obj Object with values.
*/
static WlzErrorNum WlzWriteVoxelValueTable(FILE *fP, WlzObject *obj)
{
int i, nplanes;
WlzObject tempobj;
WlzDomain *domains;
WlzValues *values;
WlzVoxelValues *voxtab;
WlzPlaneDomain *planedm;
WlzErrorNum errNum = WLZ_ERR_NONE;
/* check object */
if(obj->values.core == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
voxtab = (WlzVoxelValues *) obj->values.vox;
/* note here the background is written without a type and as an
integer. On read the value is replaced by a value from one of
the plane valuetables */
if((putc((unsigned int) voxtab->type, fP) == EOF) ||
!putword(voxtab->bckgrnd.v.inv, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
planedm = obj->domain.p;
switch(voxtab->type)
{
case WLZ_VOXELVALUETABLE_GREY:
nplanes = planedm->lastpl - planedm->plane1 + 1;
values = voxtab->values;
domains = planedm->domains;
tempobj.type = WLZ_2D_DOMAINOBJ;
#ifdef _OPENMP
#pragma omp critical (WlzLinkcount)
#endif
{
tempobj.linkcount = 0;
}
tempobj.plist = NULL;
tempobj.assoc = NULL;
for(i=0; (i < nplanes) && (errNum == WLZ_ERR_NONE);
i++, domains++, values++)
{
tempobj.domain.i = (*domains).i;
tempobj.values.v = (*values).v;
errNum = WlzWriteValueTable(fP, &tempobj);
}
break;
default:
errNum = WLZ_ERR_VALUES_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a polygon domain to the given file.
* \param fP Given file.
* \param poly Polygon domain.
*/
static WlzErrorNum WlzWritePolygon(FILE *fP, WlzPolygonDomain *poly)
{
int nvertices, i;
WlzIVertex2 *ivtx;
WlzFVertex2 *fvtx;
WlzDVertex2 *dvtx;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(poly == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
/* Write the number of vertices */
nvertices = poly->nvertices;
if((putc((unsigned int )poly->type, fP) == EOF) ||
!putword(nvertices, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE && poly)
{
switch(poly->type)
{
case WLZ_POLYGON_INT:
ivtx = poly->vtx;
for(i = 0; (i < nvertices) && (errNum == WLZ_ERR_NONE); i++, ivtx++)
{
if(!putword(ivtx->vtY, fP) || !putword(ivtx->vtX, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
case WLZ_POLYGON_FLOAT:
fvtx = (WlzFVertex2 *)poly->vtx;
for(i = 0; (i < nvertices) && (errNum == WLZ_ERR_NONE); i++, fvtx++)
{
if(!putfloat(fvtx->vtY, fP) || !putfloat(fvtx->vtX, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
case WLZ_POLYGON_DOUBLE:
dvtx = (WlzDVertex2 *)poly->vtx;
for(i = 0; (i < nvertices) && (errNum == WLZ_ERR_NONE); i++, dvtx++)
{
if(!putdouble(dvtx->vtY, fP) || !putdouble(dvtx->vtX, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
break;
default:
errNum = WLZ_ERR_POLYGON_TYPE;
break;
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a B-spline domain to the given file.
* \param fP Given file.
* \param bs Spline domain.
*/
static WlzErrorNum WlzWriteSpline(FILE *fP, WlzBSpline *bs)
{
int dim = 0;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(bs == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
switch(bs->type)
{
case WLZ_BSPLINE_C2D:
dim = 2;
break;
case WLZ_BSPLINE_C3D:
dim = 3;
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Write the B-spline type, order and number of knots. */
if((putc((unsigned int )bs->type, fP) == EOF) ||
!putword(bs->order, fP) ||
!putword(bs->nKnots, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Write knots. */
errNum = WlzWriteDouble(fP, bs->knots, bs->nKnots);
}
if(errNum == WLZ_ERR_NONE)
{
int nC;
/* Write coefficients. */
nC = dim * bs->nKnots;
errNum = WlzWriteDouble(fP, bs->coefficients, nC);
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a boundary list to the given file.
* \param fP Given file.
* \param blist Boundary list.
*/
static WlzErrorNum WlzWriteBoundList(FILE *fP, WlzBoundList *blist)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
if(blist == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if((putc(1, fP) == EOF) ||
(putc((unsigned int)blist->type, fP) == EOF))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else if(((errNum = WlzWriteBoundList(fP, blist->next)) == WLZ_ERR_NONE) &&
((errNum = WlzWriteBoundList(fP, blist->down)) == WLZ_ERR_NONE))
{
if(!putword(blist->wrap, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzWritePolygon(fP, blist->poly);
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes an integer rectangle to the given file.
* \param fP Given file.
* \param rdom Integer rectangle.
*/
static WlzErrorNum WlzWriteRect(FILE *fP, WlzIRect *rdom)
{
WlzFRect *frdom;
int i;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(rdom == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if(putc(rdom->type,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
switch(rdom->type)
{
case WLZ_RECTANGLE_DOMAIN_INT:
for(i = 0; (i < 4) && (errNum == WLZ_ERR_NONE); ++i)
{
if(!putword(rdom->irk[i], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
for(i = 0; (i < 4) && (errNum == WLZ_ERR_NONE); ++i)
{
if(!putword(rdom->irl[i], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(!putfloat(rdom->rangle, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
break;
case WLZ_RECTANGLE_DOMAIN_FLOAT:
frdom = (WlzFRect *) rdom;
for(i = 0; (i < 4) && (errNum == WLZ_ERR_NONE); ++i)
{
if(!putfloat(frdom->frk[i], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
for(i = 0; (i < 4) && (errNum == WLZ_ERR_NONE); ++i)
{
if(!putfloat(frdom->frl[i], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(!putfloat(frdom->rangle, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a histogram domain to the given file.
* \param fP Given file.
* \param hist Histogram domain.
*/
static WlzErrorNum WlzWriteHistogramDomain(FILE *fP, WlzHistogramDomain *hist)
{
int tI0;
int *tIP0;
double *tDP0;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(hist == NULL)
{
if(putc(0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if((putc(hist->type, fP) == EOF) ||
(putword((hist->nBins > 0)? (hist->nBins): 0, fP) == 0) ||
(putdouble(hist->origin, fP) == 0) ||
(putdouble(hist->binSize, fP) == 0))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else if((hist->type != WLZ_HISTOGRAMDOMAIN_INT) &&
(hist->type != WLZ_HISTOGRAMDOMAIN_FLOAT))
{
errNum = WLZ_ERR_DOMAIN_TYPE;
}
else
{
if((tI0 = hist->nBins) > 0)
{
switch(hist->type)
{
case WLZ_HISTOGRAMDOMAIN_INT:
tIP0 = hist->binValues.inp;
do
{
if(!putword(*tIP0++, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
} while((--tI0 > 0) && (errNum == WLZ_ERR_NONE));
break;
case WLZ_HISTOGRAMDOMAIN_FLOAT:
tDP0 = hist->binValues.dbp;
do
{
if(!putdouble(*tDP0++, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
} while((--tI0 > 0) && (errNum == WLZ_ERR_NONE));
break;
default:
break;
}
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a compound array object to the given file.
* \param fP Given file.
* \param c Compound array object.
*/
static WlzErrorNum WlzWriteCompoundA(FILE *fP, WlzCompoundArray *c)
{
int i;
WlzErrorNum errNum = WLZ_ERR_NONE;
/* No need to check for NULL because checked by WlzWriteObj() */
if((putc((unsigned int )c->otype, fP) == EOF) || !putword(c->n, fP))
{
errNum = WLZ_ERR_WRITE_EOF;
}
else
{
/* Write the objects, note NULL is a legal value */
for(i = 0; (i < c->n) && (errNum == WLZ_ERR_NONE); i++)
{
if(c->o[i] == NULL)
{
if(putc(0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
else
{
errNum = WlzWriteObj(fP, c->o[i]);
}
}
}
if( errNum == WLZ_ERR_NONE )
{
errNum = WlzWritePropertyList(fP, c->plist);
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a Woolz affine transform to the given file.
* \param fP Given file.
* \param trans Affine transform.
*/
static WlzErrorNum WlzWriteAffineTransform(FILE *fP, WlzAffineTransform *trans)
{
int i,
j;
WlzErrorNum errNum = WLZ_ERR_NONE;
/* check for NULL */
if(trans == NULL)
{
if(putc((unsigned int )0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if(putc((unsigned int) trans->type, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
if(errNum == WLZ_ERR_NONE)
{
for(i = 0; (i < 4) && (errNum == WLZ_ERR_NONE); i++)
{
for(j = 0; (j < 4) && (errNum == WLZ_ERR_NONE); j++)
{
if(!putdouble(trans->mat[i][j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a FE warp transform to the given file.
* \param fP Given file.
* \param obj Warp transform.
*/
static WlzErrorNum WlzWriteWarpTrans(FILE *fP, WlzWarpTrans *obj)
{
int i,
j;
WlzDVertex2 *dptr;
WlzTElement *eptr;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(!putc((unsigned int )obj->type, fP))
{
errNum = WLZ_ERR_WRITE_EOF;
}
else if(!putword(obj->nelts,fP) ||
!putword(obj->nodes,fP) ||
!putfloat(obj->imdisp,fP) ||
!putfloat(obj->iterdisp,fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
/* Write out nodal coords */
dptr = obj->ncoords;
for(i = 0; (i < obj->nodes) && (errNum == WLZ_ERR_NONE); i++, dptr++)
{
if(!putfloat((float) dptr->vtX, fP) ||
!putfloat((float) dptr->vtY, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Write out nodal displacements */
dptr = obj->displacements;
for(i = 0; (i < obj->nodes) && (errNum == WLZ_ERR_NONE); i++, dptr++)
{
if(!putfloat((float) dptr->vtX, fP) ||
!putfloat((float) dptr->vtY, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Write out elements */
eptr = obj->eltlist;
for(i = 0; (i < obj->nelts) && (errNum == WLZ_ERR_NONE); i++, eptr++)
{
if((putc((unsigned int) eptr->type, fP) == EOF) ||
!putword(eptr->n, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
for(j = 0; (j < 3) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putword(eptr->nodes[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
for(j = 0; (j < 3) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putfloat(eptr->u[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
for(j = 0; (j < 3) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putfloat(eptr->a[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes FE warp match features to the given file.
* \param fP Given file.
* \param obj Match features.
*/
static WlzErrorNum WlzWriteFMatchObj(FILE *fP, WlzFMatchObj *obj)
{
int i,
j;
WlzFMatchPoint *mptr;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(!putword(obj->nopts,fP))
{
errNum = WLZ_ERR_WRITE_EOF;
}
else
{
mptr = obj->matchpts;
for(i = 0; (i < obj->nopts) && (errNum == WLZ_ERR_NONE); i++, mptr++)
{
if(!putword(mptr->type,fP) ||
!putword(mptr->node,fP) ||
!putfloat(mptr->ptcoords.vtX,fP) ||
!putfloat(mptr->ptcoords.vtY,fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
for(j = 0; (j < WLZ_MAX_NODAL_DEGREE) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putword(mptr->elements[j],fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a 3D FE warp transform to the given file.
* \param fP Given file.
* \param obj Warp transform.
*/
static WlzErrorNum WlzWrite3DWarpTrans(FILE *fP, Wlz3DWarpTrans *obj)
{
int i;
WlzFMatchObj **intdoms;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(!putword(obj->iteration,fP))
{
errNum = WLZ_ERR_WRITE_EOF;
}
else if(!putword(obj->currentplane,fP) ||
!putfloat(obj->maxdisp,fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else if(!WlzWritePlaneDomain(fP, obj->pdom))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
intdoms = obj->intptdoms;
for(i = obj->pdom->plane1;
(i <= obj->pdom->lastpl) && (errNum == WLZ_ERR_NONE); i++, intdoms++)
{
if(!WlzWriteFMatchObj(fP, *intdoms))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes either a 2D or 3D contour to the given file.
* \param fP Given file.
* \param ctr Contour.
*/
static WlzErrorNum WlzWriteContour(FILE *fP, WlzContour *ctr)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
if(ctr == NULL)
{
errNum = WLZ_ERR_DOMAIN_NULL;
}
else if(ctr->type != WLZ_CONTOUR)
{
errNum = WLZ_ERR_DOMAIN_TYPE;
}
else
{
if(putc((unsigned int )(ctr->type), fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = WlzWriteGMModel(fP, ctr->model);
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Write's a geometric model data structure to the given file.
* The format is:
* \verbatim
model->type (byte)
{
case WLZ_GMMOD_2I
case WLZ_GMMOD_2D
case WLZ_GMMOD_2N
nEdge (int)
case WLZ_GMMOD_3I
case WLZ_GMMOD_3D
case WLZ_GMMOD_3N
nLoop (int)
}
{
case model->type == WLZ_GMMOD_2I
vertexGU.vg2I->vtx (WlzIVertex2, int * 2)
case model->type == WLZ_GMMOD_2D
vertexGU.vg2D->vtx (WlzDVertex2, double * 2)
case model->type == WLZ_GMMOD_2N
vertexGU.vg2D->vtx (WlzDVertex2, double * 2)
vertexGU.vg2D->nrm (WlzDVertex2, double * 2)
case model->type == WLZ_GMMOD_3I
vertexGU.vg3I->vtx (WlzIVertex2, int * 3)
case model->type == WLZ_GMMOD_3D
vertexGU.vg3D->vtx (WlzDVertex2, double * 3)
case model->type == WLZ_GMMOD_3N
vertexGU.vg3D->vtx (WlzDVertex2, double * 3)
vertexGU.vg3D->nrm (WlzDVertex2, double * 3)
} * nVertex
{
case WLZ_GMMOD_2I
case WLZ_GMMOD_2D
case WLZ_GMMOD_2N
{
2 vertex indicies
} * nEdge
case WLZ_GMMOD_3I
case WLZ_GMMOD_3D
case WLZ_GMMOD_3N
{
3 vertex indicies
} * nLoop
}
\endverbatim
* \param fP Given file.
* \param model Geometric model.
*/
static WlzErrorNum WlzWriteGMModel(FILE *fP, WlzGMModel *model)
{
int idI,
iCnt,
vCnt,
encodeMtd = 0;
int bufI[3];
AlcVector *vec;
WlzGMEdgeT *tET;
WlzGMElemP eP;
WlzGMResIdxTb *resIdxTb = NULL;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(model == NULL)
{
errNum = WLZ_ERR_DOMAIN_NULL;
}
else
{
/* Check the model type. */
switch(model->type)
{
case WLZ_GMMOD_2I: /* FALLTHROUGH */
case WLZ_GMMOD_2D: /* FALLTHROUGH */
case WLZ_GMMOD_2N: /* FALLTHROUGH */
case WLZ_GMMOD_3I: /* FALLTHROUGH */
case WLZ_GMMOD_3D: /* FALLTHROUGH */
case WLZ_GMMOD_3N:
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Output model type and file encoding method, followed by the number of
* verticies and the number of simplicies. Currently the file encoding
* method is just output as '0', but in future new encoding methods
* may be used, for example strips of simplicies to reduce the file
* size. */
switch(model->type)
{
case WLZ_GMMOD_2I: /* FALLTHROUGH */
case WLZ_GMMOD_2D: /* FALLTHROUGH */
case WLZ_GMMOD_2N:
if((putc((unsigned int )(model->type), fP) == EOF) ||
(putc((unsigned int )encodeMtd, fP) == EOF) ||
!putword(model->res.vertex.numElm, fP) ||
!putword(model->res.edge.numElm, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
break;
case WLZ_GMMOD_3I: /* FALLTHROUGH */
case WLZ_GMMOD_3D: /* FALLTHROUGH */
case WLZ_GMMOD_3N:
if((putc((unsigned int )(model->type), fP) == EOF) ||
(putc((unsigned int )encodeMtd, fP) == EOF) ||
!putword(model->res.vertex.numElm, fP) ||
!putword(model->res.face.numElm, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
break;
}
}
if((errNum == WLZ_ERR_NONE) && (model->res.vertex.numElm > 0))
{
/* Index the verticies. */
resIdxTb = WlzGMModelResIdx(model, WLZ_GMELMFLG_VERTEX, &errNum);
if(errNum == WLZ_ERR_NONE)
{
/* Output the vertex geometries. */
idI = 0;
vec = model->res.vertex.vec;
iCnt = model->res.vertex.numIdx;
vCnt = 0;
while((errNum == WLZ_ERR_NONE) && (iCnt-- > 0))
{
eP.vertex = (WlzGMVertex *)AlcVectorItemGet(vec, idI++);
if(eP.vertex->idx >= 0)
{
++vCnt;
switch(model->type)
{
case WLZ_GMMOD_2I:
errNum = WlzWriteVertex2I(fP, &(eP.vertex->geo.vg2I->vtx), 1);
break;
case WLZ_GMMOD_2D:
errNum = WlzWriteVertex2D(fP, &(eP.vertex->geo.vg2D->vtx), 1);
break;
case WLZ_GMMOD_2N:
errNum = WlzWriteVertex2D(fP, &(eP.vertex->geo.vg2N->vtx), 1);
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWriteVertex2D(fP, &(eP.vertex->geo.vg2N->nrm), 1);
}
break;
case WLZ_GMMOD_3I:
errNum = WlzWriteVertex3I(fP, &(eP.vertex->geo.vg3I->vtx), 1);
break;
case WLZ_GMMOD_3D:
errNum = WlzWriteVertex3D(fP, &(eP.vertex->geo.vg3D->vtx), 1);
break;
case WLZ_GMMOD_3N:
errNum = WlzWriteVertex3D(fP, &(eP.vertex->geo.vg3N->vtx), 1);
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWriteVertex3D(fP, &(eP.vertex->geo.vg3N->nrm), 1);
}
break;
}
}
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Output the vertex indicies of the simplicies. */
idI = 0;
vCnt = 0;
switch(model->type)
{
case WLZ_GMMOD_2I:
case WLZ_GMMOD_2D:
case WLZ_GMMOD_2N:
vec = model->res.edge.vec;
iCnt = model->res.edge.numIdx;
while((errNum == WLZ_ERR_NONE) && (iCnt-- > 0))
{
++vCnt;
eP.edge = (WlzGMEdge *)AlcVectorItemGet(vec, idI++);
if(eP.edge->idx >= 0)
{
tET = eP.edge->edgeT;
bufI[0] = *(resIdxTb->vertex.idxLut +
tET->vertexT->diskT->vertex->idx);
bufI[1] = *(resIdxTb->vertex.idxLut +
tET->opp->vertexT->diskT->vertex->idx);
errNum = WlzWriteInt(fP, bufI, 2);
}
}
break;
case WLZ_GMMOD_3I:
case WLZ_GMMOD_3D:
case WLZ_GMMOD_3N:
vec = model->res.face.vec;
iCnt = model->res.face.numIdx;
while((errNum == WLZ_ERR_NONE) && (iCnt-- > 0))
{
eP.face = (WlzGMFace *)AlcVectorItemGet(vec, idI++);
if(eP.face->idx >= 0)
{
++vCnt;
/* Loop IS a triangle, in 3D nothing else is allowed. */
tET = eP.face->loopT->edgeT;
bufI[0] = *(resIdxTb->vertex.idxLut +
tET->vertexT->diskT->vertex->idx);
bufI[1] = *(resIdxTb->vertex.idxLut +
tET->next->vertexT->diskT->vertex->idx);
bufI[2] = *(resIdxTb->vertex.idxLut +
tET->prev->vertexT->diskT->vertex->idx);
errNum = WlzWriteInt(fP, bufI, 3);
}
}
break;
}
}
}
if(resIdxTb)
{
WlzGMModelResIdxFree(resIdxTb);
}
return(errNum);
}
/* function: WlzWriteMeshTransform3D */
/*!
* \ingroup WlzIO
* \author J. Rao.
* \brief Write a 3D mesh transform to the given file-stream.
*
* \return Error number.
* \param fP Output file-stream pointer
* \param obj Mesh transform to be written.
* \par Source:
* WlzWriteObj.c
*/
WlzErrorNum WlzWriteMeshTransform3D(
FILE *fP,
WlzMeshTransform3D *obj)
{
int i,
j;
WlzMeshNode3D *dptr;
WlzMeshElem3D *eptr;
WlzErrorNum errNum = WLZ_ERR_NONE;
/*
if( !putc((unsigned int )obj->type, fP) )
{
errNum = WLZ_ERR_WRITE_EOF;
}
*/
if( !putword(obj->nElem, fP) ||
!putword(obj->nNodes ,fP) )
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
/* Write out nodal position and displacement */
dptr = obj->nodes;
for(i = 0; (i < obj->nNodes) && (errNum == WLZ_ERR_NONE); i++, dptr++)
{ /* position */
if(!putfloat((float) dptr->position.vtX, fP) ||
!putfloat((float) dptr->position.vtY, fP) ||
!putfloat((float) dptr->position.vtZ, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
/* displacement */
if(!putfloat((float) dptr->displacement.vtX, fP) ||
!putfloat((float) dptr->displacement.vtY, fP) ||
!putfloat((float) dptr->displacement.vtZ, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Write out elements */
eptr = obj->elements;
for(i = 0; (i < obj->nElem) && (errNum == WLZ_ERR_NONE); i++, eptr++)
{/*
if(!putc((unsigned int )eptr->type, fP) )
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
} */
/* output the index of this element */
if(!putword(eptr->idx, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
/* output nodes indeces */
for(j = 0; (j < 4) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putword(eptr->nodes[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
/* output its neighbours */
/*
for(j = 0; (j < 4) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putword(eptr->neighbours[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
*/
}
}
/* now Write out displacement */
/*
if(errNum == WLZ_ERR_NONE)
{
dptr = obj->nodes;
for(i = 0; (i < obj->nNodes) && (errNum == WLZ_ERR_NONE); i++, dptr++)
{
if(!putfloat((float) dptr->displacement.vtX, fP) ||
!putfloat((float) dptr->displacement.vtY, fP) ||
!putfloat((float) dptr->displacement.vtZ, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
*/
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a 2D mesh transform to the given file.
* \param fP Given file.
* \param obj Mesh transform.
*/
WlzErrorNum WlzWriteMeshTransform2D(
FILE *fP,
WlzMeshTransform *obj)
{
int i,
j;
WlzMeshNode *dptr;
WlzMeshElem *eptr;
WlzErrorNum errNum = WLZ_ERR_NONE;
if( !putword(obj->nElem, fP) ||
!putword(obj->nNodes ,fP) )
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
/* Write out nodal position and displacement */
dptr = obj->nodes;
for(i = 0; (i < obj->nNodes) && (errNum == WLZ_ERR_NONE); i++, dptr++)
{ /* position */
if(!putfloat((float) dptr->position.vtX, fP) ||
!putfloat((float) dptr->position.vtY, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
/* displacement */
if(!putfloat((float) dptr->displacement.vtX, fP) ||
!putfloat((float) dptr->displacement.vtY, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
if(errNum == WLZ_ERR_NONE)
{
/* Write out elements */
eptr = obj->elements;
for(i = 0; (i < obj->nElem) && (errNum == WLZ_ERR_NONE); i++, eptr++)
{
/* output the index of this element */
if(!putword(eptr->idx, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
/* output the neighbour flags */
if(!putword(eptr->flags, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
/* output nodes indeces */
for(j = 0; (j < 3) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putword(eptr->nodes[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
/* output its neighbours */
for(j = 0; (j < 3) && (errNum == WLZ_ERR_NONE); j++)
{
if (!putword(eptr->neighbours[j], fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
}
/* Write out displacement */
if(errNum == WLZ_ERR_NONE)
{
dptr = obj->nodes;
for(i = 0; (i < obj->nNodes) && (errNum == WLZ_ERR_NONE); i++, dptr++)
{
if(!putfloat((float) dptr->displacement.vtX, fP) ||
!putfloat((float) dptr->displacement.vtY, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a 2D conforming mesh to the given file.
* \param fP Given file.
* \param dstNodTbl If non-null the node table used in
* squeezing out the non-valid nodes is
* returned, otherwise the table is
* freed.
* \param mesh Conforming mesh (3D).
*/
static WlzErrorNum WlzWriteCMesh2D(FILE *fP, int **dstNodTbl,
WlzCMesh2D *mesh)
{
int idN,
idE,
nNod,
nElm;
WlzCMeshNod2D *nod;
WlzCMeshElm2D *elm;
WlzCMeshNod2D *nodes[3];
int *nodTbl = NULL;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(mesh == NULL)
{
errNum = WLZ_ERR_DOMAIN_NULL;
}
else if(mesh->type != WLZ_CMESH_2D)
{
errNum = WLZ_ERR_DOMAIN_TYPE;
}
/* Generate mesh node index table to avoid deleted nodes and then
* write the number of nodes followed by the number of elements
* to the file. */
if(errNum == WLZ_ERR_NONE)
{
if((nodTbl = (int *)AlcMalloc(mesh->res.nod.maxEnt * sizeof(int))) == NULL)
{
errNum = WLZ_ERR_MEM_ALLOC;
}
}
if(errNum == WLZ_ERR_NONE)
{
nNod = 0;
for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN)
{
nod = (WlzCMeshNod2D *)AlcVectorItemGet(mesh->res.nod.vec, idN);
if(nod->idx >= 0)
{
nodTbl[idN] = nNod++;
}
}
nElm = 0;
for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE)
{
elm = (WlzCMeshElm2D *)AlcVectorItemGet(mesh->res.elm.vec, idE);
if(elm->idx >= 0)
{
nElm++;
}
}
putword(nNod, fP);
putword(nElm, fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D() "
"%d %d\n",
nNod, nElm);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
/* Write node flags then node position (x then y). */
if(errNum == WLZ_ERR_NONE)
{
for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN)
{
nod = (WlzCMeshNod2D *)AlcVectorItemGet(mesh->res.nod.vec, idN);
if(nod->idx >= 0)
{
putword(nod->flags, fP);
putdouble(nod->pos.vtX, fP);
putdouble(nod->pos.vtY, fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D() "
"% 8d % 8d 0x%08x % 8g % 8g\n",
nod->idx, nodTbl[idN], nod->flags,
nod->pos.vtX, nod->pos.vtY);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
/* Write element flags and node indices. */
if(errNum == WLZ_ERR_NONE)
{
for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE)
{
elm = (WlzCMeshElm2D *)AlcVectorItemGet(mesh->res.elm.vec, idE);
if(elm->idx >= 0)
{
nodes[0] = WLZ_CMESH_ELM2D_GET_NODE_0(elm);
nodes[1] = WLZ_CMESH_ELM2D_GET_NODE_1(elm);
nodes[2] = WLZ_CMESH_ELM2D_GET_NODE_2(elm);
putword(elm->flags, fP);
putword(nodTbl[nodes[0]->idx], fP);
putword(nodTbl[nodes[1]->idx], fP);
putword(nodTbl[nodes[2]->idx], fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D() "
"% 8d 0x%08x % 8d % 8d % 8d\n",
elm->idx, elm->flags,
nodes[0]->idx, nodes[1]->idx,
nodes[2]->idx);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
if(dstNodTbl)
{
*dstNodTbl = nodTbl;
}
else
{
AlcFree(nodTbl);
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a 2D5 conforming mesh to the given file.
* \param fP Given file.
* \param dstNodTbl If non-null the node table used in
* squeezing out the non-valid nodes is
* returned, otherwise the table is
* freed.
* \param mesh Conforming mesh (3D).
*/
static WlzErrorNum WlzWriteCMesh2D5(FILE *fP, int **dstNodTbl,
WlzCMesh2D5 *mesh)
{
int idN,
idE,
nNod,
nElm;
WlzCMeshNod2D5 *nod;
WlzCMeshElm2D5 *elm;
WlzCMeshNod2D5 *nodes[3];
int *nodTbl = NULL;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(mesh == NULL)
{
errNum = WLZ_ERR_DOMAIN_NULL;
}
else if(mesh->type != WLZ_CMESH_2D5)
{
errNum = WLZ_ERR_DOMAIN_TYPE;
}
/* Generate mesh node index table to avoid deleted nodes and then
* write the number of nodes followed by the number of elements
* to the file. */
if(errNum == WLZ_ERR_NONE)
{
if((nodTbl = (int *)AlcMalloc(mesh->res.nod.maxEnt * sizeof(int))) == NULL)
{
errNum = WLZ_ERR_MEM_ALLOC;
}
}
if(errNum == WLZ_ERR_NONE)
{
nNod = 0;
for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN)
{
nod = (WlzCMeshNod2D5 *)AlcVectorItemGet(mesh->res.nod.vec, idN);
if(nod->idx >= 0)
{
nodTbl[idN] = nNod++;
}
}
nElm = 0;
for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE)
{
elm = (WlzCMeshElm2D5 *)AlcVectorItemGet(mesh->res.elm.vec, idE);
if(elm->idx >= 0)
{
nElm++;
}
}
putword(nNod, fP);
putword(nElm, fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D() "
"%d %d\n",
nNod, nElm);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
/* Write node flags then node position (x then y). */
if(errNum == WLZ_ERR_NONE)
{
for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN)
{
nod = (WlzCMeshNod2D5 *)AlcVectorItemGet(mesh->res.nod.vec, idN);
if(nod->idx >= 0)
{
putword(nod->flags, fP);
putdouble(nod->pos.vtX, fP);
putdouble(nod->pos.vtY, fP);
putdouble(nod->pos.vtZ, fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D5() "
"% 8d % 8d 0x%08x % 8g % 8g % 8g\n",
nod->idx, nodTbl[idN], nod->flags,
nod->pos.vtX, nod->pos.vtY, nod->pos.vtZ);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
/* Write element flags and node indices. */
if(errNum == WLZ_ERR_NONE)
{
for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE)
{
elm = (WlzCMeshElm2D5 *)AlcVectorItemGet(mesh->res.elm.vec, idE);
if(elm->idx >= 0)
{
nodes[0] = WLZ_CMESH_ELM2D5_GET_NODE_0(elm);
nodes[1] = WLZ_CMESH_ELM2D5_GET_NODE_1(elm);
nodes[2] = WLZ_CMESH_ELM2D5_GET_NODE_2(elm);
putword(elm->flags, fP);
putword(nodTbl[nodes[0]->idx], fP);
putword(nodTbl[nodes[1]->idx], fP);
putword(nodTbl[nodes[2]->idx], fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D5() "
"% 8d 0x%08x % 8d % 8d % 8d\n",
elm->idx, elm->flags,
nodes[0]->idx, nodes[1]->idx,
nodes[2]->idx);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
if(dstNodTbl)
{
*dstNodTbl = nodTbl;
}
else
{
AlcFree(nodTbl);
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a 3D conforming mesh to the given file.
* \param fP Given file.
* \param dstNodTbl If non-null the node table used in
* squeezing out the non-valid nodes is
* returned, otherwise the table is
* freed.
* \param mesh Conforming mesh (3D).
*/
static WlzErrorNum WlzWriteCMesh3D(FILE *fP, int **dstNodTbl,
WlzCMesh3D *mesh)
{
int idN,
idE,
nNod,
nElm;
WlzCMeshNod3D *nod;
WlzCMeshElm3D *elm;
WlzCMeshNod3D *nodes[4];
int *nodTbl = NULL;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(mesh == NULL)
{
errNum = WLZ_ERR_DOMAIN_NULL;
}
else if(mesh->type != WLZ_CMESH_3D)
{
errNum = WLZ_ERR_DOMAIN_TYPE;
}
/* Generate mesh node index table to avoid deleted nodes and then
* write the number of nodes followed by the number of elements
* to the file. */
if(errNum == WLZ_ERR_NONE)
{
if((nodTbl = (int *)AlcMalloc(mesh->res.nod.maxEnt * sizeof(int))) == NULL)
{
errNum = WLZ_ERR_MEM_ALLOC;
}
}
if(errNum == WLZ_ERR_NONE)
{
nNod = 0;
for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN)
{
nod = (WlzCMeshNod3D *)AlcVectorItemGet(mesh->res.nod.vec, idN);
if(nod->idx >= 0)
{
nodTbl[idN] = nNod++;
}
}
nElm = 0;
for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE)
{
elm = (WlzCMeshElm3D *)AlcVectorItemGet(mesh->res.elm.vec, idE);
if(elm->idx >= 0)
{
nElm++;
}
}
putword(nNod, fP);
putword(nElm, fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh3D() "
"%d %d\n",
nNod, nElm);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
/* Write node flags then node position (x then y). */
if(errNum == WLZ_ERR_NONE)
{
for(idN = 0; idN < mesh->res.nod.maxEnt; ++idN)
{
nod = (WlzCMeshNod3D *)AlcVectorItemGet(mesh->res.nod.vec, idN);
if(nod->idx >= 0)
{
putword(nod->flags, fP);
putdouble(nod->pos.vtX, fP);
putdouble(nod->pos.vtY, fP);
putdouble(nod->pos.vtZ, fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh2D() "
"% 8d % 8d 0x%08x % 8g % 8g % 8g\n",
nod->idx, nodTbl[idN], nod->flags,
nod->pos.vtX, nod->pos.vtY, nod->pos.vtZ);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
/* Write element flags and node indices. */
if(errNum == WLZ_ERR_NONE)
{
for(idE = 0; idE < mesh->res.elm.maxEnt; ++idE)
{
elm = (WlzCMeshElm3D *)AlcVectorItemGet(mesh->res.elm.vec, idE);
if(elm->idx >= 0)
{
nodes[0] = WLZ_CMESH_ELM3D_GET_NODE_0(elm);
nodes[1] = WLZ_CMESH_ELM3D_GET_NODE_1(elm);
nodes[2] = WLZ_CMESH_ELM3D_GET_NODE_2(elm);
nodes[3] = WLZ_CMESH_ELM3D_GET_NODE_3(elm);
putword(elm->flags, fP);
putword(nodTbl[nodes[0]->idx], fP);
putword(nodTbl[nodes[1]->idx], fP);
putword(nodTbl[nodes[2]->idx], fP);
putword(nodTbl[nodes[3]->idx], fP);
#ifdef WLZ_DEBUG_WRITEOBJ
(void )fprintf(stderr,
"WlzWriteCMesh3D() "
"% 8d 0x%08x % 8d % 8d % 8d % 8d\n",
elm->idx, elm->flags,
nodes[0]->idx, nodes[1]->idx,
nodes[2]->idx, nodes[3]->idx);
#endif /* WLZ_DEBUG_WRITEOBJ */
if(feof(fP) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
if(dstNodTbl)
{
*dstNodTbl = nodTbl;
}
else
{
AlcFree(nodTbl);
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes an indexed value table to the given file.
* \param fP Given file pointer.
* \param obj Object with an indexed value table
* that's to be written to the file.
*/
static WlzErrorNum WlzWriteIndexedValues(FILE *fP, WlzObject *obj)
{
int idX,
idV,
vCount,
nValues = 0;
WlzGreyP gP;
WlzCMeshP mesh;
WlzIndexedValues *ixv;
WlzErrorNum errNum = WLZ_ERR_NONE;
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)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
ixv = obj->values.x;
if(ixv->type != (WlzObjectType )WLZ_INDEXED_VALUES)
{
errNum = WLZ_ERR_VALUES_TYPE;
}
else
{
switch(obj->domain.core->type)
{
case WLZ_CMESH_2D:
mesh.m2 = obj->domain.cm2;
switch(ixv->attach)
{
case WLZ_VALUE_ATTACH_NOD:
nValues = mesh.m2->res.nod.numEnt;
break;
case WLZ_VALUE_ATTACH_ELM:
nValues = mesh.m2->res.elm.numEnt;
break;
default:
errNum = WLZ_ERR_VALUES_TYPE;
break;
}
break;
case WLZ_CMESH_2D5:
mesh.m2d5 = obj->domain.cm2d5;
switch(ixv->attach)
{
case WLZ_VALUE_ATTACH_NOD:
nValues = mesh.m2d5->res.nod.numEnt;
break;
case WLZ_VALUE_ATTACH_ELM:
nValues = mesh.m2d5->res.elm.numEnt;
break;
default:
errNum = WLZ_ERR_VALUES_TYPE;
break;
}
break;
case WLZ_CMESH_3D:
mesh.m3 = obj->domain.cm3;
switch(ixv->attach)
{
case WLZ_VALUE_ATTACH_NOD:
nValues = mesh.m3->res.nod.numEnt;
break;
case WLZ_VALUE_ATTACH_ELM:
nValues = mesh.m3->res.elm.numEnt;
break;
default:
errNum = WLZ_ERR_VALUES_TYPE;
break;
}
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
if(errNum == WLZ_ERR_NONE)
{
if(putc((unsigned int )(ixv->type), fP) == 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
(void )putword(ixv->rank, fP);
for(idX = 0; idX < ixv->rank; ++idX)
{
(void )putword(ixv->dim[idX], fP);
}
(void )putc((unsigned int )(ixv->vType), fP);
(void )putc((unsigned int )(ixv->attach), fP);
(void )putword(nValues, fP);
if(feof(fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
vCount = 1;
if(ixv->rank > 0)
{
for(idX = 0; idX < ixv->rank; ++idX)
{
vCount *= ixv->dim[idX];
}
}
for(idX = 0; idX < nValues; ++idX)
{
gP.v = WlzIndexedValueGet(ixv, idX);
for(idV = 0; idV < vCount; ++idV)
{
switch(ixv->vType)
{
case WLZ_GREY_INT:
(void )putword(gP.inp[idV], fP);
break;
case WLZ_GREY_SHORT:
(void )putshort(gP.shp[idV], fP);
break;
case WLZ_GREY_UBYTE:
(void )putc(gP.ubp[idV], fP);
break;
case WLZ_GREY_FLOAT:
(void )putfloat(gP.flp[idV], fP);
break;
case WLZ_GREY_DOUBLE:
(void )putdouble(gP.dbp[idV], fP);
break;
case WLZ_GREY_RGBA:
(void )putword(gP.rgbp[idV], fP);
break;
default:
errNum = WLZ_ERR_GREY_TYPE;
break;
}
}
if(feof(fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
break;
}
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes an tiled value table to the given file.
* \param fP Given file pointer.
* \param obj Object with an tiled value table
* that's to be written to the file.
* \param writeTiles Write tiles even if no tiles are
* allocated for the valuetable.
*/
static WlzErrorNum WlzWriteTiledValueTable(FILE *fP, WlzObject *obj,
int writeTiles)
{
long tMrk;
size_t vSz = 1;
WlzGreyType gType;
WlzTiledValues *tVal = NULL;
WlzErrorNum errNum = WLZ_ERR_NONE;
tVal = obj->values.t;
gType = WlzGreyTableTypeToGreyType(tVal->type, &errNum);
if(errNum == WLZ_ERR_NONE)
{
if(putc((unsigned int )(tVal->type), fP) == EOF)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
putc(tVal->dim, fP);
putword(tVal->kol1, fP);
putword(tVal->lastkl, fP);
putword(tVal->line1, fP);
putword(tVal->lastln, fP);
putword(tVal->plane1, fP);
putword(tVal->lastpl, fP);
errNum = WlzWritePixelV(fP, &(tVal->bckgrnd), 1);
}
if(errNum == WLZ_ERR_NONE)
{
if(tVal->vRank > 0)
{
int idx;
(void )putword(tVal->vRank, fP);
for(idx = 0; idx < tVal->vRank; ++idx)
{
vSz *= tVal->vDim[idx];
(void )putword(tVal->vDim[idx], fP);
}
}
}
if(errNum == WLZ_ERR_NONE)
{
int nIdx;
putword(tVal->tileSz, fP);
putword(tVal->tileWidth, fP);
putword(tVal->numTiles, fP);
putword(tVal->nIdx[0], fP);
putword(tVal->nIdx[1], fP);
nIdx = tVal->nIdx[0] * tVal->nIdx[1];
if(tVal->dim > 2)
{
putword(tVal->nIdx[2], fP);
nIdx *= tVal->nIdx[2];
}
errNum = WlzWriteInt(fP, (int *)(tVal->indices), nIdx);
}
if(errNum == WLZ_ERR_NONE)
{
long blks;
WlzLong off[2];
tMrk = ftell(fP) + (2 * sizeof(unsigned int ));
blks = (tMrk + tVal->tileSz - 1) / tVal->tileSz;
tMrk = blks * tVal->tileSz;
off[0] = tMrk & 0xffffffff;
off[1] = (sizeof(long) > 4)? tMrk >> 32: 0;
putword((unsigned int )(off[0]), fP);
putword((unsigned int )(off[1]), fP);
if(fseek(fP, tMrk, SEEK_SET) != 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
size_t gSz,
tSz;
gSz = WlzGreySize(gType);
tSz = tVal->numTiles * tVal->tileSz;
if(tVal->tiles.v != NULL)
{
size_t n;
n = tSz * vSz;
if(fwrite(tVal->tiles.v, gSz, n, fP) != n)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
else if(writeTiles != 0)
{
/* No tile data so reserve tile space in the file by seeking
* to the end of the tiles and writing a byte. */
if((fseek(fP, (gSz * tSz * vSz) - 1, SEEK_CUR) != 0) ||
(fwrite("", 1, 1, fP) != 1))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
#ifdef WLZ_DEBUG_WRITEOBJ
if(tVal == NULL)
{
(void )fprintf(stderr, "WlzReadTiledValues() tVal == NULL\n");
}
else
{
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal\n");
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->type = %d\n",
(int )(tVal->type));
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->linkcount = %d\n",
tVal->linkcount);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->dim = %d\n",
tVal->dim);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->kol1 = %d\n",
tVal->kol1);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->lastkl = %d\n",
tVal->lastkl);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->line1 = %d\n",
tVal->line1);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->lastln = %d\n",
tVal->lastln);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->plane1 = %d\n",
tVal->plane1);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->lastpl = %d\n",
tVal->lastpl);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->bckgrnd.type = %d\n",
(int )(tVal->bckgrnd.type));
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->tileSz = %ld\n",
(long )(tVal->tileSz));
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->tileWidth = %ld\n",
(long )tVal->tileWidth);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->numTiles = %ld\n",
(long )tVal->numTiles);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->nIdx = %d, %d, %d\n",
tVal->nIdx[0], tVal->nIdx[1],
(tVal->dim == 2)? 0: tVal->nIdx[2]);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->indices = %p\n",
tVal->indices);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->fd = %d\n",
tVal->fd);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->tileOffset = %ld\n",
tVal->tileOffset);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tVal->tiles.v = %p\n",
tVal->tiles.v);
(void )fprintf(stderr, "WlzWriteTiledValueTable() tMrk = %ld\n",
tMrk);
(void )fprintf(stderr, "WlzWriteTiledValueTable() errno = %s\n",
strerror(errno));
}
#endif /* WLZ_DEBUG_WRITEOBJ */
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a look up table domain to the given file.
* \param fP Given file.
* \param lDom Look up table domain.
*/
static WlzErrorNum WlzWriteLUTDomain(FILE *fP, WlzLUTDomain *lDom)
{
const WlzUByte version = 1;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(lDom == NULL)
{
if(putc(0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if((putc(lDom->type, fP) == EOF) ||
(putc(version, fP) == EOF) ||
(putword(lDom->bin1, fP) == 0) ||
(putword(lDom->lastbin, fP) == 0))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes look up table values to the given file.
* \param fP Given file.
* \param obj Look up table object.
*/
static WlzErrorNum WlzWriteLUTValues(FILE *fP, WlzObject *obj)
{
const WlzUByte version = 1;
WlzErrorNum errNum = WLZ_ERR_NONE;
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)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
WlzLUTDomain *lutDom;
WlzLUTValues *lutVal;
lutDom = obj->domain.lut;
lutVal = obj->values.lut;
if(lutVal->type != WLZ_LUT)
{
errNum = WLZ_ERR_VALUES_TYPE;
}
if(errNum == WLZ_ERR_NONE)
{
if(putc((unsigned int )(lutVal->type), fP) == 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
int i,
n;
WlzGreyP gP;
gP = lutVal->val;
(void )putc(version, fP);
(void )putc(lutVal->vType, fP);
n = lutDom->lastbin - lutDom->bin1 + 1;
(void )putword(n, fP);
switch(lutVal->vType)
{
case WLZ_GREY_INT:
for(i = 0; i < n; ++i)
{
(void )putword(gP.inp[i], fP);
}
break;
case WLZ_GREY_SHORT:
for(i = 0; i < n; ++i)
{
(void )putshort(gP.shp[i], fP);
}
break;
case WLZ_GREY_UBYTE:
for(i = 0; i < n; ++i)
{
(void )putc(gP.ubp[i], fP);
}
break;
case WLZ_GREY_FLOAT:
for(i = 0; i < n; ++i)
{
(void )putfloat(gP.flp[i], fP);
}
break;
case WLZ_GREY_DOUBLE:
for(i = 0; i < n; ++i)
{
(void )putdouble(gP.dbp[i], fP);
}
break;
case WLZ_GREY_RGBA:
for(i = 0; i < n; ++i)
{
(void )putword(gP.rgbp[i], fP);
}
break;
default:
break;
}
if(feof(fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a 3D section structure to the given open file.
* \param fP Given file.
* \param vs Given view.
*/
static WlzErrorNum WlzWrite3DViewStruct(FILE *fP, WlzThreeDViewStruct *vs)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
/* check for NULL */
if(vs == NULL)
{
if(putc((unsigned int )0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if(putc((unsigned int) vs->type, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWriteVertex3D(fP, &(vs->fixed), 1);
}
if(errNum == WLZ_ERR_NONE)
{
if(!putdouble(vs->theta, fP) ||
!putdouble(vs->phi, fP) ||
!putdouble(vs->zeta, fP) ||
!putdouble(vs->dist, fP) ||
!putdouble(vs->scale, fP) ||
!putdouble(vs->voxelSize[0], fP) ||
!putdouble(vs->voxelSize[1], fP) ||
!putdouble(vs->voxelSize[2], fP) ||
!putword(vs->voxelRescaleFlg, fP) ||
(putc((unsigned int)vs->interp, fP) == EOF) ||
(putc((unsigned int)vs->view_mode, fP) == EOF))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWriteVertex3D(fP, &(vs->up), 1);
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes a points domain to the given open file.
* \param fP Given file.
* \param pts Given points domain.
*/
static WlzErrorNum WlzWritePoints(FILE *fP, WlzPoints *pts)
{
const WlzUByte version = 1;
WlzErrorNum errNum = WLZ_ERR_NONE;
if(pts == NULL)
{
if(putc(0, fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
if((putc(pts->type, fP) == EOF) ||
(putc(version, fP) == EOF) ||
(putword(pts->nPoints, fP) == 0))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
switch(pts->type)
{
case WLZ_POINTS_2I:
errNum = WlzWriteVertex2I(fP, pts->points.i2, pts->nPoints);
break;
case WLZ_POINTS_2D:
errNum = WlzWriteVertex2D(fP, pts->points.d2, pts->nPoints);
break;
case WLZ_POINTS_3I:
errNum = WlzWriteVertex3I(fP, pts->points.i3, pts->nPoints);
break;
case WLZ_POINTS_3D:
errNum = WlzWriteVertex3D(fP, pts->points.d3, pts->nPoints);
break;
default:
errNum = WLZ_ERR_DOMAIN_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes point values to the given file.
* \param fP Given file.
* \param obj Points object.
*/
static WlzErrorNum WlzWritePointValues(FILE *fP, WlzObject *obj)
{
size_t vCount = 1;
const WlzUByte version = 1;
WlzErrorNum errNum = WLZ_ERR_NONE;
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)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else
{
WlzPoints *pDom;
WlzPointValues *pVal;
pDom = obj->domain.pts;
pVal = obj->values.pts;
if(pVal->type != (WlzObjectType )WLZ_POINT_VALUES)
{
errNum = WLZ_ERR_VALUES_TYPE;
}
if(errNum == WLZ_ERR_NONE)
{
if(putc((unsigned int )(pVal->type), fP) == 0)
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
int idx;
(void )putc(version, fP);
(void )putword(pVal->rank, fP);
for(idx = 0; idx < pVal->rank; ++idx)
{
vCount *= pVal->dim[idx];
(void )putword(pVal->dim[idx], fP);
}
(void )putc((unsigned int )(pVal->vType), fP);
(void )putword(pDom->nPoints, fP);
if(feof(fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
}
if(errNum == WLZ_ERR_NONE)
{
WlzGreyP gP;
vCount *= pDom->nPoints;
gP = pVal->values;
switch(pVal->vType)
{
case WLZ_GREY_INT:
errNum = WlzWriteInt(fP, gP.inp, vCount);
break;
case WLZ_GREY_SHORT:
errNum = WlzWriteShort(fP, gP.shp, vCount);
break;
case WLZ_GREY_UBYTE:
errNum = WlzWriteUByte(fP, gP.ubp, vCount);
break;
case WLZ_GREY_FLOAT:
errNum = WlzWriteFloat(fP, gP.flp, vCount);
break;
case WLZ_GREY_DOUBLE:
errNum = WlzWriteDouble(fP, gP.dbp, vCount);
break;
case WLZ_GREY_RGBA:
errNum = WlzWriteInt(fP, (int *)(gP.rgbp), vCount);
break;
default:
errNum = WLZ_ERR_GREY_TYPE;
break;
}
}
}
return(errNum);
}
/*!
* \return Woolz error code.
* \ingroup WlzIO
* \brief Writes either a 2D or 3D convex hull to the given file.
* \param fP Given file.
* \param dom Domain with either 2 or 3D convex hull.
*/
static WlzErrorNum WlzWriteConvexHull(FILE *fP, WlzDomain dom)
{
WlzErrorNum errNum = WLZ_ERR_NONE;
if(dom.core == NULL)
{
if(putc(0,fP) == EOF)
{
errNum = WLZ_ERR_WRITE_EOF;
}
}
else if(dom.core->type == WLZ_CONVHULL_DOMAIN_2D)
{
WlzConvHullDomain2 *cvh;
cvh = dom.cvh2;
if((cvh->vtxType != WLZ_VERTEX_I2) && (cvh->vtxType != WLZ_VERTEX_D2))
{
errNum = WLZ_ERR_PARAM_TYPE;
}
else
{
if((putc((unsigned int )cvh->type, fP) == EOF) ||
(putc((unsigned int )cvh->vtxType, fP) == EOF) ||
!putword(cvh->nVertices, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = (cvh->vtxType == WLZ_VERTEX_I2)?
WlzWriteVertex2I(fP, &(cvh->centroid.i2), 1):
WlzWriteVertex2D(fP, &(cvh->centroid.d2), 1);
}
if(errNum == WLZ_ERR_NONE)
{
errNum = (cvh->vtxType == WLZ_VERTEX_I2)?
WlzWriteVertex2I(fP, cvh->vertices.i2, cvh->nVertices):
WlzWriteVertex2D(fP, cvh->vertices.d2, cvh->nVertices);
}
}
}
else if(dom.core->type == WLZ_CONVHULL_DOMAIN_3D)
{
WlzConvHullDomain3 *cvh;
cvh = dom.cvh3;
if((cvh->vtxType != WLZ_VERTEX_I3) && (cvh->vtxType != WLZ_VERTEX_D3))
{
errNum = WLZ_ERR_PARAM_TYPE;
}
else
{
if((putc((unsigned int )cvh->type, fP) == EOF) ||
(putc((unsigned int )cvh->vtxType, fP) == EOF) ||
!putword(cvh->nVertices, fP) ||
!putword(cvh->nFaces, fP))
{
errNum = WLZ_ERR_WRITE_INCOMPLETE;
}
else
{
errNum = (cvh->vtxType == WLZ_VERTEX_I3)?
WlzWriteVertex3I(fP, &(cvh->centroid.i3), 1):
WlzWriteVertex3D(fP, &(cvh->centroid.d3), 1);
}
if(errNum == WLZ_ERR_NONE)
{
errNum = (cvh->vtxType == WLZ_VERTEX_I3)?
WlzWriteVertex3I(fP, cvh->vertices.i3, cvh->nVertices):
WlzWriteVertex3D(fP, cvh->vertices.d3, cvh->nVertices);
}
if(errNum == WLZ_ERR_NONE)
{
errNum = WlzWriteInt(fP, cvh->faces, 3 * cvh->nFaces);
}
}
}
else
{
errNum = WLZ_ERR_DOMAIN_TYPE;
}
return(errNum);
}