/*! * \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); }