/*! * \return New Woolz object read from file. * \ingroup WlzExtFF * \brief Reads a Woolz object from the given file using the * Amira lattice (.am file) format. * \param fP Input file pointer. * \param split Split label lattice files into a * compound object of domains if non * zero. * \param dstErr Destination pointer for error number, * may be NULL. */ WlzObject *WlzEffReadObjAm(FILE *fP, int split, WlzErrorNum *dstErr) { WlzEffAmHead *head; WlzObject *tObj, *obj = NULL; void ***data = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; if((head = WlzEffAmNewHead()) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffAmReadHead(fP, head); } if(errNum == WLZ_ERR_NONE) { /* Check type of lattice file can be read and call appropriate function. */ switch(head->latType) { case WLZEFF_AM_LATTYPE_DATA: obj = WlzEffAmReadArray3DToObj(fP, head, &errNum); break; case WLZEFF_AM_LATTYPE_LABELS: obj = WlzEffAmReadArray3DToObj(fP, head, &errNum); if(split && (errNum == WLZ_ERR_NONE)) { tObj = (WlzObject *)WlzEffAmSplitLabelObj(WlzAssignObject(obj, NULL), head, &errNum); WlzFreeObj(obj); obj = tObj; } break; default: errNum = WLZ_ERR_READ_INCOMPLETE; break; } } WlzEffAmFreeHead(head); if(data) { if(obj) { **data = NULL; } Alc3Free(data); } if(errNum != WLZ_ERR_NONE) { if(obj) { (void )WlzFreeObj(obj); obj = NULL; } } if(dstErr) { *dstErr = errNum; } return(obj); }
/*! * \return Woolz error code. * \ingroup WlzExtFF * \brief Writes the given Woolz 3D domain object with values to * the given file using the Amira lattice (.am file) format. * \param fP Output file pointer * \param obj Object to be written. */ static WlzErrorNum WlzEffAmWrite3DDomObj(FILE *fP, WlzObject *obj) { size_t dataCnt, dataSz; WlzDBox3 bbD; WlzIBox3 bbI; WlzIVertex3 sz, org; WlzDVertex3 vSz; char *dateS, *dataTypeS; time_t tTime; WlzGreyType gType; void ***data = NULL; WlzErrorNum errNum = WLZ_ERR_UNIMPLEMENTED; if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN) { errNum = WLZ_ERR_DOMAIN_TYPE; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else if(obj->values.core->type != WLZ_VOXELVALUETABLE_GREY) { errNum = WLZ_ERR_VALUES_TYPE; } else { bbI = WlzBoundingBox3I(obj, &errNum); } if(errNum == WLZ_ERR_NONE) { tTime = time(NULL); dateS = ctime(&tTime); *(dateS + strlen(dateS) - 1) = '\0'; } if(errNum == WLZ_ERR_NONE) { vSz = WlzVozelSz(obj, &errNum); } if(errNum == WLZ_ERR_NONE) { bbD.xMin = bbI.xMin * vSz.vtX; bbD.xMax = bbI.xMax * vSz.vtX; bbD.yMin = bbI.yMin * vSz.vtY; bbD.yMax = bbI.yMax * vSz.vtY; bbD.zMin = bbI.zMin * vSz.vtZ; bbD.zMax = bbI.zMax * vSz.vtZ; sz.vtX = bbI.xMax - bbI.xMin + 1; sz.vtY = bbI.yMax - bbI.yMin + 1; sz.vtZ = bbI.zMax - bbI.zMin + 1; org.vtX = bbI.xMin; org.vtY = bbI.yMin; org.vtZ = bbI.zMin; gType = WlzGreyTypeFromObj(obj, &errNum); } if(errNum == WLZ_ERR_NONE) { switch(gType) { case WLZ_GREY_SHORT: dataTypeS = "short"; break; case WLZ_GREY_UBYTE: dataTypeS = "byte"; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { if(fprintf(fP, "# AmiraMesh 3D BINARY 2.0\n" "# WlzExtFF\n" "# CreationDate: %s\n" "\n" "define Lattice %d %d %d\n" "\n" "Parameters {\n" " Content \"%dx%dx%d %s, uniform coordinates\",\n" " BoundingBox %g %g %g %g %g %g,\n" " CoordType \"uniform\"\n" "}\n" "\n" "Lattice { %s Data } @1\n" "\n" "# Data section follows\n" "@1\n", dateS, sz.vtX, sz.vtY, sz.vtZ, sz.vtX, sz.vtY, sz.vtZ, dataTypeS, bbD.xMin, bbD.xMax, bbD.yMin, bbD.yMax, bbD.zMin, bbD.zMax, dataTypeS) <= 0) { errNum = WLZ_ERR_WRITE_INCOMPLETE; } } if(errNum == WLZ_ERR_NONE) { errNum = WlzToArray3D(&data, obj, sz, org, 0, gType); } if(errNum == WLZ_ERR_NONE) { dataCnt = sz.vtX * sz.vtY * sz.vtZ; switch(gType) { case WLZ_GREY_SHORT: dataSz = 2; break; case WLZ_GREY_UBYTE: dataSz = 1; break; default: break; } if(fwrite(**data, dataSz, dataCnt, fP) != dataSz * dataCnt) { errNum = WLZ_ERR_WRITE_INCOMPLETE; } } (void )Alc3Free(data); return(errNum); }
/*! * \return New Woolz object read from file. * \ingroup WlzExtFF * \brief Reads a Woolz object from the given file using the * previously parsed Amira lattice file header. * \param fP Input file pointer. * \param head Amira lattice file header. * \param dstErr Destination pointer for error number, * may be NULL. */ static WlzObject *WlzEffAmReadArray3DToObj(FILE *fP, WlzEffAmHead *head, WlzErrorNum *dstErr) { WlzIVertex3 org; WlzDVertex3 voxSz; WlzGreyType gType; WlzObject *obj = NULL; void ***data = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; if((head->dim != WLZEFF_AM_DIM_3) || (head->fmt != WLZEFF_AM_FMT_BINARY) || (head->latSize.vtX < 1) || (head->latSize.vtY < 1) || (head->latSize.vtZ < 1) || ((voxSz.vtX = head->bBox.xMax - head->bBox.xMin) < DBL_EPSILON) || ((voxSz.vtY = head->bBox.yMax - head->bBox.yMin) < DBL_EPSILON) || ((voxSz.vtZ = head->bBox.zMax - head->bBox.zMin) < DBL_EPSILON)) { errNum = WLZ_ERR_READ_INCOMPLETE; } if(errNum == WLZ_ERR_NONE) { switch(head->latComp) { case WLZEFF_AM_LATCOMP_NONE: /* FALLTHROUGH */ case WLZEFF_AM_LATCOMP_HXBYTERLE: break; default: errNum = WLZ_ERR_UNIMPLEMENTED; break; } } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffAmSeekLabel(fP, head->latLabel); } if(errNum == WLZ_ERR_NONE) { switch(head->latDatType) { case WLZEFF_AM_DATTYPE_BYTE: gType = WLZ_GREY_UBYTE; if(AlcChar3Malloc((char ****)&data, head->latSize.vtZ, head->latSize.vtY, head->latSize.vtX) != ALC_ER_NONE) { errNum = WLZ_ERR_MEM_ALLOC; } break; case WLZEFF_AM_DATTYPE_SHORT: gType = WLZ_GREY_SHORT; if(AlcShort3Malloc((short ****)&data, head->latSize.vtZ, head->latSize.vtY, head->latSize.vtX) != ALC_ER_NONE) { errNum = WLZ_ERR_MEM_ALLOC; } break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffAmReadArray3D(fP, data, head, gType); } if(errNum == WLZ_ERR_NONE) { /* Compute voxel size and origin. * The Amira bounding box is for voxel centres and NOT * voxel boundaries. */ if(head->latSize.vtX > 1) { voxSz.vtX /= (double )(head->latSize.vtX - 1); } if(head->latSize.vtY > 1) { voxSz.vtY /= (double )(head->latSize.vtY - 1); } if(head->latSize.vtZ > 1) { voxSz.vtZ /= (double )(head->latSize.vtZ - 1); } org.vtX = head->bBox.xMin / voxSz.vtX; org.vtY = head->bBox.yMin / voxSz.vtY; org.vtZ = head->bBox.zMin / voxSz.vtZ; obj = WlzFromArray3D(data, head->latSize, org, gType, gType, 0.0, 1.0, 0, 1, &errNum); } if(errNum == WLZ_ERR_NONE) { obj->domain.p->voxel_size[0] = voxSz.vtX; obj->domain.p->voxel_size[1] = voxSz.vtY; obj->domain.p->voxel_size[2] = voxSz.vtZ; } if(data) { if(obj) { **data = NULL; } Alc3Free(data); } if(errNum != WLZ_ERR_NONE) { if(obj) { (void )WlzFreeObj(obj); obj = NULL; } } if(dstErr) { *dstErr = errNum; } return(obj); }
/*! * \return Object read from file. * \ingroup WlzExtFF * \brief Reads a Woolz object from the given stream using the '.ipl' * file format. * \param fP Input file stream. * \param dstErr Destination error number ptr, * may be NULL. */ WlzObject *WlzEffReadObjIPL(FILE *fP, WlzErrorNum *dstErr) { int idxZ, i, planeSz, pixelSz; void ***data = NULL; unsigned char ***ubData = NULL; short ***shData = NULL; int ***inData = NULL; float ***flData = NULL; unsigned char *planeBuf = NULL, *planePtr; WlzIVertex3 origin, size; WlzObject *obj = NULL; WlzErrorNum errNum = WLZ_ERR_READ_INCOMPLETE; WlzEffIPLHeader header; WlzGreyType gType; origin.vtX = origin.vtY = origin.vtZ = 0; if(fP == NULL) { errNum = WLZ_ERR_PARAM_NULL; } else { (void )memset((void *)&header, 0, sizeof(WlzEffIPLHeader)); errNum = WlzEffHeadReadIPL(&header, fP); size.vtX = header.nWidth; size.vtY = header.nHeight; size.vtZ = header.nFrames; } if(errNum == WLZ_ERR_NONE) { switch( header.dType ){ case WLZEFF_IPL_TYPE_UBYTE: gType = WLZ_GREY_UBYTE; pixelSz = sizeof(char); if((AlcUnchar3Malloc(&ubData, size.vtZ, size.vtY, size.vtX) != ALC_ER_NONE) || (ubData == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } data = (void ***) ubData; break; case WLZEFF_IPL_TYPE_SHORT: case WLZEFF_IPL_TYPE_U_16: case WLZEFF_IPL_TYPE_COL_16: gType = WLZ_GREY_SHORT; pixelSz = sizeof(short); if((AlcShort3Malloc(&shData, size.vtZ, size.vtY, size.vtX) != ALC_ER_NONE) || (shData == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } data = (void ***) shData; break; case WLZEFF_IPL_TYPE_INT: case WLZEFF_IPL_TYPE_COL_24: gType = WLZ_GREY_INT; pixelSz = sizeof(int); if((AlcInt3Malloc(&inData, size.vtZ, size.vtY, size.vtX) != ALC_ER_NONE) || (inData == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } data = (void ***) inData; break; case WLZEFF_IPL_TYPE_FLOAT: gType = WLZ_GREY_FLOAT; pixelSz = sizeof(float); if((AlcFloat3Malloc(&flData, size.vtZ, size.vtY, size.vtX) != ALC_ER_NONE) || (flData == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } data = (void ***) flData; break; default: errNum = WLZ_ERR_PARAM_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { planeSz = size.vtX * size.vtY; idxZ = 0; while((idxZ < size.vtZ) && (errNum == WLZ_ERR_NONE)) { /* Read in each slice into the buffer */ planePtr = (unsigned char *) (**(data + idxZ)); switch( header.dType ){ case WLZEFF_IPL_TYPE_UBYTE: case WLZEFF_IPL_TYPE_SHORT: case WLZEFF_IPL_TYPE_U_16: case WLZEFF_IPL_TYPE_COL_16: case WLZEFF_IPL_TYPE_INT: case WLZEFF_IPL_TYPE_FLOAT: if(fread(planePtr, pixelSz, planeSz, fP) != planeSz) { errNum = WLZ_ERR_READ_INCOMPLETE; } break; case WLZEFF_IPL_TYPE_COL_24: for(i=0; (i < planeSz) && (errNum == WLZ_ERR_NONE); i++, planePtr++){ if(fread(planePtr, sizeof(char)*3, 1, fP) != 1) { errNum = WLZ_ERR_READ_INCOMPLETE; } planePtr[3] = 0; } break; default: break; } ++idxZ; } } if(errNum == WLZ_ERR_NONE) { obj = WlzFromArray3D((void ***)data, size, origin, gType, gType, 0.0, 1.0, 0, 1, &errNum); } if(errNum == WLZ_ERR_NONE) { obj->domain.p->voxel_size[0] = 1.0; obj->domain.p->voxel_size[1] = 1.0; obj->domain.p->voxel_size[2] = 1.0; } if(planeBuf) { AlcFree(planeBuf); } if(errNum != WLZ_ERR_NONE) { if(obj) { WlzFreeObj(obj); } else if(data) { Alc3Free((void ***)data); } } if(dstErr) { *dstErr = errNum; } return(obj); }
/*! * \return Woolz error number. * \ingroup WlzExtFF * \brief Writes the given Woolz object to the given stream using the * '.ipl' file format. * \param fP Output file stream. * \param obj Given woolz object. */ WlzErrorNum WlzEffWriteObjIPL(FILE *fP, WlzObject *obj) { WlzIVertex3 size; WlzErrorNum errNum = WLZ_ERR_WRITE_INCOMPLETE; WlzIVertex3 origin; unsigned char ***data = NULL; WlzEffIPLHeader header; if(fP == NULL) { errNum = WLZ_ERR_PARAM_NULL; } else if(obj == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } else if(obj->type != WLZ_3D_DOMAINOBJ) { errNum = WLZ_ERR_OBJECT_TYPE; } else if(obj->domain.core == NULL) { errNum = WLZ_ERR_DOMAIN_NULL; } else if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN) { errNum = WLZ_ERR_DOMAIN_TYPE; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else if(obj->values.core->type != WLZ_VOXELVALUETABLE_GREY) { errNum = WLZ_ERR_VALUES_TYPE; } else { origin.vtX = obj->domain.p->kol1; origin.vtY = obj->domain.p->line1; origin.vtZ = obj->domain.p->plane1; size.vtX = obj->domain.p->lastkl - origin.vtX + 1; size.vtY = obj->domain.p->lastln - origin.vtY + 1; size.vtZ = obj->domain.p->lastpl - origin.vtZ + 1; if((size.vtX <= 0) || (size.vtY <= 0) || (size.vtZ <= 0)) { errNum = WLZ_ERR_DOMAIN_DATA; } else { errNum = WlzToArray3D((void ****)&data, obj, size, origin, 0, WLZ_GREY_UBYTE); } } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffHeadWriteIPL(&header, fP); } if(errNum == WLZ_ERR_NONE) { /* write the data */ } if(data) { Alc3Free((void ***)data); } return(errNum); }
/*! * \return Woolz error code. * \ingroup WlzExtFF * \brief Writes the given Woolz object to the given file(s) * using the ANALYZE 7.5 file format. The given file name is * used to generate the '.hdr' and '.img' filenames. * \param gvnFileName Given file name with .hdr, .img or no * extension. * \param obj Given woolz object. */ WlzErrorNum WlzEffWriteObjAnl(const char *gvnFileName, WlzObject *obj) { int cnt = 0; double dMin, dMax; FILE *fP = NULL; void *data = NULL; WlzGreyP dataP; WlzEffAnlDsr dsr; WlzGreyType gType; WlzVertex org, sz; char *fileName = NULL, *hdrFileName = NULL, *imgFileName = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; dataP.v = NULL; if((gvnFileName == NULL) || (*gvnFileName == '\0')) { errNum = WLZ_ERR_PARAM_NULL; } else if(obj == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } else if(obj->domain.core == NULL) { errNum = WLZ_ERR_DOMAIN_NULL; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else { errNum = WlzEffAnlFileNames(&fileName, &hdrFileName, &imgFileName, gvnFileName); } /* Fill in the ANALYZE file header data structures. */ if(errNum == WLZ_ERR_NONE) { (void )memset(&dsr, 0, sizeof(WlzEffAnlDsr)); switch(obj->type) { case WLZ_2D_DOMAINOBJ: org.i2.vtX = obj->domain.i->kol1; org.i2.vtY = obj->domain.i->line1; sz.i2.vtX = obj->domain.i->lastkl - org.i2.vtX + 1; sz.i2.vtY = obj->domain.i->lastln - org.i2.vtY + 1; if((sz.i2.vtX <= 0) || (sz.i2.vtY <= 0)) { errNum = WLZ_ERR_DOMAIN_DATA; } else { dsr.dim.dim[0] = 2; dsr.dim.dim[1] = sz.i2.vtX; dsr.dim.dim[2] = sz.i2.vtY; dsr.dim.pixdim[0] = 2; dsr.dim.pixdim[1] = 1.0; dsr.dim.pixdim[2] = 1.0; } break; case WLZ_3D_DOMAINOBJ: org.i3.vtX = obj->domain.p->kol1; org.i3.vtY = obj->domain.p->line1; org.i3.vtZ = obj->domain.p->plane1; sz.i3.vtX = obj->domain.p->lastkl - org.i3.vtX + 1; sz.i3.vtY = obj->domain.p->lastln - org.i3.vtY + 1; sz.i3.vtZ = obj->domain.p->lastpl - org.i3.vtZ + 1; if((sz.i3.vtX <= 0) || (sz.i3.vtY <= 0) || (sz.i3.vtZ <= 0)) { errNum = WLZ_ERR_DOMAIN_DATA; } else { dsr.dim.dim[0] = 3; dsr.dim.dim[1] = sz.i3.vtX; dsr.dim.dim[2] = sz.i3.vtY; dsr.dim.dim[3] = sz.i3.vtZ; dsr.dim.pixdim[0] = 3; dsr.dim.pixdim[1] = obj->domain.p->voxel_size[0]; dsr.dim.pixdim[2] = obj->domain.p->voxel_size[1]; dsr.dim.pixdim[3] = obj->domain.p->voxel_size[2]; } break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { (void )WlzGreyStats(obj, &gType, &dMin, &dMax, NULL, NULL, NULL, NULL, &errNum); } if(errNum == WLZ_ERR_NONE) { dsr.dim.glMax = (int )ceil(dMax); dsr.dim.glMin = (int )floor(dMin); switch(gType) { case WLZ_GREY_INT: dsr.dim.dataType = WLZEFF_ANL_DT_SIGNED_INT; dsr.dim.bitPix = 32; break; case WLZ_GREY_SHORT: dsr.dim.dataType = WLZEFF_ANL_DT_SIGNED_SHORT; dsr.dim.bitPix = 16; break; case WLZ_GREY_UBYTE: dsr.dim.dataType = WLZEFF_ANL_DT_UNSIGNED_CHAR; dsr.dim.bitPix = 8; break; case WLZ_GREY_FLOAT: dsr.dim.dataType = WLZEFF_ANL_DT_FLOAT; dsr.dim.bitPix = 32; break; case WLZ_GREY_DOUBLE: dsr.dim.dataType = WLZEFF_ANL_DT_DOUBLE; dsr.dim.bitPix = 64; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { dsr.hk.hdrSz = 348; dsr.hk.regular = 'r'; dsr.hk.extents = 16384; (void )strcpy(dsr.hist.descrip, "Converted from Woolz"); (void )strcpy(dsr.hist.originator, "Woolz"); (void )strcpy(dsr.hist.generated, "Woolz"); } /* Get Woolz object's values as an array. */ if(WLZ_ERR_NONE == errNum) { switch(obj->type) { case WLZ_2D_DOMAINOBJ: cnt = sz.i2.vtX * sz.i2.vtY; errNum = WlzToArray2D((void ***)&data, obj, sz.i2, org.i2, 0, gType); if(errNum == WLZ_ERR_NONE) { switch(gType) { case WLZ_GREY_INT: dataP.inp = *(int **)data; break; case WLZ_GREY_SHORT: dataP.shp = *(short **)data; break; case WLZ_GREY_UBYTE: dataP.ubp = *(WlzUByte **)data; break; case WLZ_GREY_FLOAT: dataP.flp = *(float **)data; break; case WLZ_GREY_DOUBLE: dataP.dbp = *(double **)data; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } break; case WLZ_3D_DOMAINOBJ: cnt = sz.i3.vtX * sz.i3.vtY * sz.i3.vtZ; errNum = WlzToArray3D((void ****)&data, obj, sz.i3, org.i3, 0, gType); if(errNum == WLZ_ERR_NONE) { switch(gType) { case WLZ_GREY_INT: dataP.inp = **(int ***)data; break; case WLZ_GREY_SHORT: dataP.shp = **(short ***)data; break; case WLZ_GREY_UBYTE: dataP.ubp = **(WlzUByte ***)data; break; case WLZ_GREY_FLOAT: dataP.flp = **(float ***)data; break; case WLZ_GREY_DOUBLE: dataP.dbp = **(double ***)data; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } /* Open the ANALYZE .hdr file and write the header information. */ if(errNum == WLZ_ERR_NONE) { if((fP = fopen(hdrFileName, "w")) == NULL) { errNum = WLZ_ERR_WRITE_EOF; } #ifdef _WIN32 else if(_setmode(_fileno(fP), 0x8000) == -1) { errNum = WLZ_ERR_READ_EOF; } #endif } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffWriteAnlHdrKey(fP, &dsr); } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffWriteAnlHdrImageDim(fP, &dsr); } if(errNum == WLZ_ERR_NONE) { errNum = WlzEffWriteAnlHdrDataHistory(fP, &dsr); } if(fP) { (void )fclose(fP); fP = NULL; } /* Open the ANALYZE .img file and write the image data. */ if(errNum == WLZ_ERR_NONE) { if((fP = fopen(imgFileName, "w")) == NULL) { errNum = WLZ_ERR_WRITE_EOF; } #ifdef _WIN32 else if(_setmode(_fileno(fP), 0x8000) == -1) { errNum = WLZ_ERR_READ_EOF; } #endif } if(errNum == WLZ_ERR_NONE) { switch(gType) { case WLZ_GREY_INT: errNum = WlzEffWriteAnlInt(fP, cnt, dataP.inp); break; case WLZ_GREY_SHORT: errNum = WlzEffWriteAnlShort(fP, cnt, dataP.shp); break; case WLZ_GREY_UBYTE: errNum = WlzEffWriteAnlChar(fP, cnt, dataP.ubp); break; case WLZ_GREY_FLOAT: errNum = WlzEffWriteAnlFloat(fP, cnt, dataP.flp); break; case WLZ_GREY_DOUBLE: errNum = WlzEffWriteAnlDouble(fP, cnt, dataP.dbp); break; default: break; } } if(fP) { (void )fclose(fP); } if(data) { switch(obj->type) { case WLZ_2D_DOMAINOBJ: Alc2Free((void **)data); break; case WLZ_3D_DOMAINOBJ: Alc3Free((void ***)data); break; default: break; } } (void )AlcFree(fileName); (void )AlcFree(hdrFileName); (void )AlcFree(imgFileName); return(errNum); }
/*! * \return Object read from file. * \ingroup WlzExtFF * \brief Reads a 3D Woolz object from the given file(s) using the given * (2D) file format. * \param gvnFileName Given file name. * \param fFmt Given file format (must be a 2D file * format). * \param dstErr Destination error number ptr, may be * NULL. */ static WlzObject *WlzEffReadObjStack3D(const char *gvnFileName, WlzEffFormat fFmt, WlzErrorNum *dstErr) { int tI0, planeIdx, planeOff; char *tCP0, *recTok, *fNameStr = NULL, *fPathStr = NULL, *fBodyStr = NULL, *fExtStr = NULL, *fCtrStr = NULL; FILE *fP = NULL, *fP2D = NULL; WlzIVertex2 imgSz2D; WlzErrorNum errNum = WLZ_ERR_NONE; WlzObject *obj = NULL; unsigned char ***data = NULL; char fRecord[WLZEFF_STACK_CTR_RECORDMAX]; WlzEffStackCtrHeader header; errNum = WlzEffStackFileNameParse(gvnFileName, fFmt, &fPathStr, &fBodyStr, &fExtStr, &fCtrStr); if(errNum == WLZ_ERR_NONE) { tI0 = strlen(fPathStr) + strlen(fBodyStr) + strlen(fExtStr) + 16; if((fNameStr = AlcMalloc(tI0 * sizeof(char))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } else { sprintf(fNameStr, "%s%s.%s", fPathStr, fBodyStr, fCtrStr); if((fP = fopen(fNameStr, "r")) == NULL) { errNum = WLZ_ERR_READ_EOF; } else { #ifdef _WIN32 if (fP != NULL){ if(_setmode(_fileno(fP), 0x8000) == -1) { errNum = WLZ_ERR_READ_EOF; } } #endif errNum = WlzEffHeadParseStackCtr(&header, fP); } } } if(errNum == WLZ_ERR_NONE) { imgSz2D.vtX = header.volSize.vtX; imgSz2D.vtY = header.volSize.vtY; if((AlcUnchar3Malloc(&data, header.volSize.vtZ, header.volSize.vtY, header.volSize.vtX) != ALC_ER_NONE) || (data == NULL)) { errNum = WLZ_ERR_MEM_ALLOC; } } if(errNum == WLZ_ERR_NONE) { planeOff = 0; planeIdx = header.volOrigin.vtZ; while((planeOff < header.volSize.vtZ) && (errNum == WLZ_ERR_NONE)) { if(fgets(fRecord, WLZEFF_STACK_CTR_RECORDMAX, fP) == NULL) { errNum = WLZ_ERR_READ_INCOMPLETE; } else { fRecord[WLZEFF_STACK_CTR_RECORDMAX - 1] = '\0'; if((tCP0 = strrchr(fRecord, '\n')) != NULL) { *tCP0 = '\0'; } if(((recTok = strtok(fRecord, " \t")) == NULL) || (sscanf(recTok, "%d", &tI0) != 1) || (tI0 != planeIdx) || ((recTok = strtok(NULL, " \t\n")) == NULL)) { errNum = WLZ_ERR_READ_INCOMPLETE; } else { sprintf(fNameStr, "%s%s", fPathStr, recTok); if((fP2D = fopen(fNameStr, "r")) == NULL) { errNum = WLZ_ERR_READ_EOF; } else { #ifdef _WIN32 if (fP2D != NULL){ if(_setmode(_fileno(fP2D), 0x8000) == -1) { errNum = WLZ_ERR_READ_EOF; } } #endif errNum = WlzEffReadObjStackData2D(fP2D, fFmt, &imgSz2D, (data + planeOff)); fclose(fP2D); } } } ++planeOff; ++planeIdx; } } if(errNum == WLZ_ERR_NONE) { obj = WlzFromArray3D((void ***)data, header.volSize, header.volOrigin, WLZ_GREY_UBYTE, WLZ_GREY_UBYTE, 0.0, 1.0, 0, 1, &errNum); } if(errNum == WLZ_ERR_NONE) { obj->domain.p->voxel_size[0] = header.voxSize.vtX; obj->domain.p->voxel_size[1] = header.voxSize.vtY; obj->domain.p->voxel_size[2] = header.voxSize.vtZ; } if(data) { if(obj) { /* **data used in object */ AlcFree(*data); AlcFree(data); } else { if(data) { Alc3Free((void ***)data); } } } if(dstErr) { *dstErr = errNum; } if(fNameStr) { AlcFree(fNameStr); } if(fPathStr) { AlcFree(fPathStr); } if(fBodyStr) { AlcFree(fBodyStr); } if(fExtStr) { AlcFree(fExtStr); } if(fCtrStr) { AlcFree(fCtrStr); } if(dstErr) { *dstErr = errNum; } return(obj); }