RecError RecSecListRelFromAbs(RecSectionList *secList) { RecSection *sec; HGUDlpListItem *item; WlzAffineTransform *tr0 = NULL, *tr1, *tr2; RecError recErr = REC_ERR_NONE; WlzErrorNum wlzErr = WLZ_ERR_NONE; if(secList == NULL) { recErr = REC_ERR_FUNC; } else if(secList->attributes.trMode == REC_TRMODE_ABS) { item = HGUDlpListHead(secList->list); do { sec = (RecSection *)HGUDlpListEntryGet(secList->list, item); if(sec && strcmp(sec->imageFile, "empty")) { if(tr0) { tr1 = WlzAffineTransformInverse(tr0, &wlzErr); if(wlzErr == WLZ_ERR_NONE) { (void )WlzFreeAffineTransform(tr0); tr0 = WlzAssignAffineTransform(sec->transform, NULL); tr2 = WlzAffineTransformProduct(tr0, tr1, &wlzErr); } if(wlzErr == WLZ_ERR_NONE) { (void )WlzTransformNearIdentity2D(tr2, 1.0e-6); (void )WlzFreeAffineTransform(sec->transform); sec->transform = WlzAssignAffineTransform(tr2, NULL); } } else { tr0 = WlzAssignAffineTransform(sec->transform, NULL); } } item = HGUDlpListNext(secList->list, item); } while((wlzErr == WLZ_ERR_NONE) && item && (item != HGUDlpListHead(secList->list))); if(tr0) { (void )WlzFreeAffineTransform(tr0); } secList->attributes.trMode = REC_TRMODE_REL; recErr = RecErrorFromWlz(wlzErr); } return(recErr); }
int main(int argc, char **argv) { FILE *inFile1=NULL, *inFile2=NULL; char optList[] = "AR123f:F:iIx:y:z:s:a:b:u:v:w:hV"; int option; int trans1RelFlg=0, trans2RelFlg=0, trans3DFlg=0, outputRelFlg=0; int invertFlg=0, inverseFlg=0, threeDFlg=0; WlzAffineTransform *cmdLineTrans=NULL; double tx, ty, tz, scale, theta, phi, alpha, psi, xsi; int verboseFlg=0; RecSectionList recSecList1, recSecList2; RecSectionList *secList1=&recSecList1, *secList2=&recSecList2; HGUDlpListItem *listItem, *listItem1; RecSection *sec, *sec1; char *errMsg = NULL; RecError errFlg = REC_ERR_NONE; int numSec1, numSec2; WlzErrorNum errNum=WLZ_ERR_NONE; WlzObject *transformsObj1, *transformsObj2; int p, i, ip; WlzAffineTransform *newTransform, *tmpTrans, *tmp1Trans, *reconTrans; /* default transform */ tx = 0.0; ty = 0.0; tx = 0.0; scale = 1.0; theta = 0.0; phi = 0.0; alpha = 0.0; psi = 0.0; xsi = 0.0; /* parse the command line */ opterr = 0; while( (option = getopt(argc, argv, optList)) != EOF ){ switch( option ){ case 'A': outputRelFlg = 0; break; case 'R': outputRelFlg = 1; break; case '1': trans1RelFlg = 1; break; case '2': trans2RelFlg = 1; break; case '3': trans3DFlg = 1; break; case 'f': if( (optarg != NULL) && (strlen(optarg) > 0) ){ if( (inFile1 = fopen(optarg, "r")) == NULL ){ fprintf(stderr, "%s: failed to open input file %s\n", argv[0], optarg); usage(argv[0]); return 1; } } else { usage(argv[0]); return 1; } break; case 'F': if( (optarg != NULL) && (strlen(optarg) > 0) ){ if( (inFile2 = fopen(optarg, "r")) == NULL ){ fprintf(stderr, "%s: failed to open input file %s\n", argv[0], optarg); usage(argv[0]); return 1; } } else { usage(argv[0]); return 1; } break; case 'i': invertFlg = 1; break; case 'I': inverseFlg = 1; break; case 'a': if(sscanf(optarg, "%lg", &theta) != 1) { usage(argv[0]); return 1; } break; case 'b': if(sscanf(optarg, "%lg", &phi) != 1) { usage(argv[0]); return 1; } break; case 's': if(sscanf(optarg, "%lg", &scale) != 1) { usage(argv[0]); return 1; } break; case 'u': if(sscanf(optarg, "%lg", &alpha) != 1) { usage(argv[0]); return 1; } break; case 'v': if(sscanf(optarg, "%lg", &psi) != 1) { usage(argv[0]); return 1; } break; case 'w': if(sscanf(optarg, "%lg", &xsi) != 1) { usage(argv[0]); return 1; } break; case 'x': if(sscanf(optarg, "%lg", &tx) != 1) { usage(argv[0]); return 1; } break; case 'y': if(sscanf(optarg, "%lg", &ty) != 1) { usage(argv[0]); return 1; } break; case 'z': if(sscanf(optarg, "%lg", &tz) != 1) { usage(argv[0]); return 1; } break; case 'V': verboseFlg = 1; break; case 'h': default: usage(argv[0]); return 1; } } /* create the command line transform */ if( threeDFlg ){ cmdLineTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_3D_AFFINE, tx, ty, tz, scale, theta, phi, alpha, psi, xsi, invertFlg, &errNum); } else { cmdLineTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, tx, ty, tz, scale, theta, phi, alpha, psi, xsi, invertFlg, &errNum); } /* check for files on the command line */ if( (inFile1 == NULL) && (optind < argc) ){ if( (inFile1 = fopen(*(argv+optind), "r")) == NULL ){ fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind)); usage(argv[0]); return 1; } optind++; } if( (inFile2 == NULL) && (optind < argc) ){ if( (inFile2 = fopen(*(argv+optind), "r")) == NULL ){ fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind)); usage(argv[0]); return 1; } optind++; } /* now read the transforms, in each case the logic is that transform 1 is applied then transform 2 then the command line transform. If transform 1 is a reconstruct bib file then the output will include the file information. Note in this case the output transform will be absolute unless specified on the command line */ /* transform 1 - try to read as a Reconstruct file, on failure rewind and read as an MAPaint file */ if( inFile1 != NULL ){ errFlg = RecFileSecListRead(secList1, &numSec1, inFile1, &errMsg); if( errFlg == REC_ERR_NONE ){ /* check transform attribute */ switch( secList1->attributes.trMode ){ case REC_TRMODE_REL: trans1RelFlg = 1; break; case REC_TRMODE_ABS: trans1RelFlg = 0; break; } transformsObj1 = SecListToTransforms(secList1, trans1RelFlg, &errNum); } else { secList1 = NULL; rewind(inFile1); transformsObj1 = ReadMAPaintRealignTransforms(inFile1, &errNum); } } else { fprintf(stderr, "%s: a file for transform 1 must be defined\n", argv[0]); usage(argv[0]); return 1; } /* transform 2 - try to read as a Reconstruct file, on failure rewind and read as an MAPaint file */ if( inFile2 != NULL ){ errFlg = RecFileSecListRead(secList2, &numSec2, inFile2, &errMsg); if( errFlg == REC_ERR_NONE ){ /* check transform attribute */ switch( secList2->attributes.trMode ){ case REC_TRMODE_REL: trans2RelFlg = 1; break; case REC_TRMODE_ABS: trans2RelFlg = 0; break; } transformsObj2 = SecListToTransforms(secList2, trans2RelFlg, &errNum); } else { secList2 = NULL; rewind(inFile2); transformsObj2 = ReadMAPaintRealignTransforms(inFile2, &errNum); } } else { transformsObj2 = NULL; } /* form the plane by plane product of the transforms, note the output will be of the planes in transform 1 */ for(p=transformsObj1->domain.p->plane1, i=0; p <= transformsObj1->domain.p->lastpl; p++, i++){ /* get the existing transform */ if( transformsObj1->domain.p->domains[i].t ){ newTransform = WlzAssignAffineTransform(transformsObj1->domain.p->domains[i].t, NULL); } else { newTransform = NULL; } /* check for transform 2 */ if(newTransform && transformsObj2 && (p >= transformsObj2->domain.p->plane1) && (p <= transformsObj2->domain.p->lastpl) && (transformsObj2->domain.p-> domains[p-transformsObj2->domain.p->plane1].t)){ tmpTrans = WlzAffineTransformProduct(newTransform, transformsObj2->domain.p-> domains[p-transformsObj2->domain.p->plane1].t, NULL); WlzFreeAffineTransform(newTransform); newTransform = tmpTrans; } /* apply the command line transform */ if( newTransform && cmdLineTrans ){ tmpTrans = WlzAffineTransformProduct(newTransform, cmdLineTrans, NULL); WlzFreeAffineTransform(newTransform); newTransform = tmpTrans; } /* put it back into transformsObj1 */ if( transformsObj1->domain.p->domains[i].t ){ WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t); } transformsObj1->domain.p->domains[i].t = WlzAssignAffineTransform(newTransform, NULL); } /* if there is a section list in Reconstruct form then take out the reconstruct transform */ if( secList1 ){ /* take out the reconstruct transform first */ reconTrans = WlzAffineTransformFromPrimVal (WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0, 1.0 / secList1->reconstruction.scale.vtX, 0.0, 0.0, 0.0, 0.0, 0.0, 0, NULL); listItem = HGUDlpListHead(secList1->list); while( listItem ){ sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem); if( sec ){ p = sec->index; i = p - transformsObj1->domain.p->plane1; if( transformsObj1->domain.p->domains[i].t ){ tmpTrans = WlzAffineTransformProduct (transformsObj1->domain.p->domains[i].t, reconTrans, NULL); WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t); transformsObj1->domain.p->domains[i].t = WlzAssignAffineTransform(tmpTrans, NULL); } } listItem = HGUDlpListNext(secList1->list, listItem); } } /* check for relative flag */ if( outputRelFlg ){ /* use the section list if available */ if( secList1 ){ /* sort out the relative transform */ listItem = HGUDlpListTail(secList1->list); while( listItem != HGUDlpListHead(secList1->list) ){ sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem); if( sec ){ p = sec->index; i = p - transformsObj1->domain.p->plane1; if( strncmp(sec->imageFile, "empty", 5) == 0 ){ WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t); transformsObj1->domain.p->domains[i].t = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, NULL); } else { /* walk backwards to previous non-empty section */ listItem1 = HGUDlpListPrev(secList1->list, listItem); while( listItem1 != HGUDlpListHead(secList1->list) ){ sec1 = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem1); if( strncmp(sec1->imageFile, "empty", 5) ){ break; } listItem1 = HGUDlpListPrev(secList1->list, listItem1); } ip = sec1->index - transformsObj1->domain.p->plane1; tmpTrans = WlzAffineTransformInverse(transformsObj1->domain.p->domains[ip].t, NULL); tmp1Trans = WlzAffineTransformProduct( transformsObj1->domain.p->domains[i].t, tmpTrans, NULL); checkTrans(tmp1Trans); WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t); WlzFreeAffineTransform(tmpTrans); transformsObj1->domain.p->domains[i].t = tmp1Trans; } } listItem = HGUDlpListPrev(secList1->list, listItem); } } else { i = transformsObj1->domain.p->lastpl - transformsObj1->domain.p->plane1; ip = i; for(p = transformsObj1->domain.p->lastpl; p >= transformsObj1->domain.p->plane1; p--, i--){ if( i > ip ){ continue; } ip--; if(transformsObj1->domain.p->domains[i].t){ /* jump over any NULL transforms */ while((ip >= 0) && (transformsObj1->domain.p->domains[ip].t == NULL)){ ip--; } /* push the transform down the line */ if(ip >= 0){ tmpTrans = WlzAffineTransformInverse(transformsObj1->domain.p->domains[ip].t, NULL); tmp1Trans = WlzAffineTransformProduct(transformsObj1->domain.p->domains[i].t, tmpTrans, NULL); checkTrans(tmp1Trans); WlzFreeAffineTransform(transformsObj1->domain.p->domains[i].t); WlzFreeAffineTransform(tmpTrans); transformsObj1->domain.p->domains[i].t = WlzAssignAffineTransform(tmp1Trans, NULL); } } } } } /* if there is a section list one then output in Reconstruct bibfile format else MAPaint style */ if( secList1 ){ /* set the relative/absolute attribute */ if( outputRelFlg ){ secList1->attributes.trMode = REC_TRMODE_REL; } else { secList1->attributes.trMode = REC_TRMODE_ABS; } /* put back the transforms */ listItem = HGUDlpListHead(secList1->list); while( listItem ){ sec = (RecSection *) HGUDlpListEntryGet(secList1->list, listItem); p = sec->index; i = p - transformsObj1->domain.p->plane1; /* check for NULL transform */ if( transformsObj1->domain.p->domains[i].t == NULL ){ transformsObj1->domain.p->domains[i].t = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, NULL); } sec->transform = transformsObj1->domain.p->domains[i].t; listItem = HGUDlpListNext(secList1->list, listItem); } RecFileSecListWrite(stdout, secList1, numSec1, &errMsg); } else { WriteMAPaintRealignTransforms(stdout, transformsObj1, outputRelFlg); } return 0; }
/*! * \return New BasisFn transform. * \ingroup WlzTransform * \brief Computes a basis function transform for the given object and a * set of control points using both an affine and a basis * function transform. * \param obj Given object. * \param basisFnType Required basis function type. * \param polyOrder Order of polynomial, only used for * WLZ_FN_BASIS_2DPOLY. * \param nSPts Number of source control points. * \param sPts Source control points. * \param nDPts Number of destination control points. * \param dPts Destination control points. * \param dstErr Destination error pointer, may be * NULL. */ static WlzBasisFnTransform *WlzAffineBasisFnTransformFromCPtsT(WlzObject *obj, WlzFnType basisFnType, int polyOrder, int nSPts, WlzDVertex2 *sPts, int nDPts, WlzDVertex2 *dPts, WlzErrorNum *dstErr) { int idx; WlzDVertex2 *dPtsT = NULL; WlzAffineTransform *aTr = NULL, *aTrI = NULL; WlzBasisFnTransform *bTr = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; if(obj == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } else if((nDPts <= 0) || (nDPts != nSPts)) { errNum = WLZ_ERR_PARAM_DATA; } else if((dPts == NULL) || (sPts == NULL)) { errNum = WLZ_ERR_PARAM_NULL; } /* Compute least squares affine transform from the tie points. */ if(errNum == WLZ_ERR_NONE) { aTr = WlzAffineTransformLSq2D(nSPts, sPts, nSPts, dPts, 0, NULL, WLZ_TRANSFORM_2D_AFFINE, &errNum); } if(errNum == WLZ_ERR_NONE) { if(nSPts >= 4) { /* Create a new array of destination vertices which have the original * destination transformed by the inverse affine transform. */ if((dPtsT = (WlzDVertex2 *)AlcMalloc(sizeof(WlzDVertex2) * nSPts)) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } if(errNum == WLZ_ERR_NONE) { aTrI = WlzAffineTransformInverse(aTr, &errNum); } if(errNum == WLZ_ERR_NONE) { for(idx = 0; idx < nDPts; ++idx) { dPtsT[idx] = WlzAffineTransformVertexD2(aTrI, dPts[idx], NULL); } bTr = WlzBasisFnTrFromCPts2D(basisFnType, polyOrder, nSPts, sPts, nSPts, dPtsT, NULL, &errNum); } } } AlcFree(dPtsT); (void )WlzFreeAffineTransform(aTr); (void )WlzFreeAffineTransform(aTrI); if(errNum != WLZ_ERR_NONE) { (void )WlzBasisFnFreeTransform(bTr); } if(dstErr) { *dstErr = errNum; } return(bTr); }
/*! * \return Grey value work space or NULL on error. * \ingroup WlzAccess * \brief Creates a grey value work space from the given object. * The resulting grey value work space should be freed * using WlzGreyValueFreeWSp(). * \param obj Given object. * \param dstErrNum Destination error pointer, may be NULL. */ WlzGreyValueWSpace *WlzGreyValueMakeWSp(WlzObject *obj, WlzErrorNum *dstErrNum) { int planeIdx, numPlanes; WlzDomain *planeDomains; WlzValues *planeValues; WlzObjectType gTabType0, gTabType1 = WLZ_DUMMY_ENTRY; WlzGreyType gType0 = WLZ_GREY_ERROR, gType1 = WLZ_GREY_ERROR; WlzPixelV bkdPix; WlzAffineTransform *trans0, *trans1; WlzGreyValueWSpace *gVWSp = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; bkdPix.v.ubv = 0; bkdPix.type = WLZ_GREY_INT; WLZ_DBG((WLZ_DBG_LVL_1), ("WlzGreyValueMakeWSp FE %p %p\n", obj, dstErrNum)); if(obj == NULL) { errNum = WLZ_ERR_PARAM_DATA; } else { switch(obj->type) { case WLZ_2D_DOMAINOBJ: if(obj->domain.core == NULL) { errNum = WLZ_ERR_DOMAIN_NULL; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else if((gVWSp = (WlzGreyValueWSpace *)AlcCalloc(1, sizeof(WlzGreyValueWSpace))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } else { gVWSp->objType = obj->type; gVWSp->values = obj->values; gVWSp->gType = WlzGreyTableTypeToGreyType(obj->values.core->type, &errNum); if(errNum == WLZ_ERR_NONE) { gVWSp->gTabType = WlzGreyTableTypeToTableType( obj->values.core->type, &errNum); gVWSp->gTabType2D = gVWSp->gTabType; } if(errNum == WLZ_ERR_NONE) { switch(gVWSp->gTabType2D) { case WLZ_GREY_TAB_RAGR: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.v->bckgrnd; break; case WLZ_GREY_TAB_RECT: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.r->bckgrnd; break; case WLZ_GREY_TAB_INTL: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.i->bckgrnd; break; case WLZ_GREY_TAB_TILED: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.t->bckgrnd; break; default: errNum = WLZ_ERR_VALUES_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { switch(gVWSp->gType) { case WLZ_GREY_LONG: case WLZ_GREY_INT: case WLZ_GREY_SHORT: case WLZ_GREY_UBYTE: case WLZ_GREY_FLOAT: case WLZ_GREY_DOUBLE: case WLZ_GREY_RGBA: break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if((gVWSp->gType != bkdPix.type) && (errNum == WLZ_ERR_NONE)) { errNum = WLZ_ERR_VALUES_DATA; } } if(errNum == WLZ_ERR_NONE) { gVWSp->gBkd = bkdPix.v; gVWSp->domain = obj->domain; gVWSp->iDom2D = obj->domain.i; if((gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_INTVL) && (gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_RECT)) { errNum = WLZ_ERR_DOMAIN_TYPE; } } break; case WLZ_3D_DOMAINOBJ: if(obj->domain.core == NULL) { errNum = WLZ_ERR_DOMAIN_NULL; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN) { errNum = WLZ_ERR_DOMAIN_TYPE; } else if((gVWSp = (WlzGreyValueWSpace *)AlcCalloc(1, sizeof(WlzGreyValueWSpace))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } else { gVWSp->objType = obj->type; gVWSp->domain = obj->domain; gVWSp->values = obj->values; if(WlzGreyTableIsTiled(obj->values.core->type) == WLZ_GREY_TAB_TILED) { gVWSp->gTabType = WLZ_GREY_TAB_TILED; gVWSp->gTabType2D = WLZ_GREY_TAB_TILED; gVWSp->gType = WlzGreyTableTypeToGreyType( obj->values.core->type, &errNum); gVWSp->plane = obj->domain.p->plane1; gVWSp->iDom2D = (*(obj->domain.p->domains)).i; gVWSp->gBkd = obj->values.t->bckgrnd.v; if(obj->values.t->bckgrnd.type != gVWSp->gType) { errNum = WLZ_ERR_VALUES_DATA; } } else { gVWSp->gTabType = WLZ_VOXELVALUETABLE_GREY; /* Put in a list of grey-table types - purely for efficiency to avoid re-computing the type for each voxel request. When table types are no longer computed this in principle could go */ numPlanes = obj->domain.p->lastpl - obj->domain.p->plane1 + 1; if((gVWSp->gTabTypes3D = (WlzObjectType *) AlcCalloc(numPlanes, sizeof(WlzObjectType))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } if(errNum == WLZ_ERR_NONE) { WlzObjectType *gTabTypes3D; gVWSp->values2D.core = NULL; planeIdx = obj->domain.p->plane1; planeDomains = obj->domain.p->domains; planeValues = obj->values.vox->values; gTabTypes3D = gVWSp->gTabTypes3D; while((planeIdx <= obj->domain.p->lastpl) && (errNum == WLZ_ERR_NONE)) { if(((*planeValues).core) && ((*planeValues).core->type != WLZ_EMPTY_OBJ)) { gType0 = WlzGreyTableTypeToGreyType( (*planeValues).core->type, &errNum); if(errNum == WLZ_ERR_NONE) { gTabType0 = WlzGreyTableTypeToTableType((*planeValues). core->type, &errNum); *gTabTypes3D = gTabType0; } if(errNum == WLZ_ERR_NONE) { if((gType0 != gType1) && (gType1 != WLZ_GREY_ERROR)) { errNum = WLZ_ERR_VALUES_DATA; } else { gType1 = gType0; gTabType1 = gTabType0; if(gVWSp->values2D.core == NULL) { gVWSp->plane = planeIdx; gVWSp->iDom2D = (*planeDomains).i; gVWSp->values2D = *planeValues; } } } } ++planeIdx; ++planeDomains; ++planeValues; ++gTabTypes3D; } if((gType1 == WLZ_GREY_ERROR) || (gTabType1 == WLZ_DUMMY_ENTRY)) { errNum = WLZ_ERR_VALUES_DATA; } } if(errNum == WLZ_ERR_NONE) { gVWSp->gType = gType0; gVWSp->gTabType2D = gVWSp->gTabTypes3D[0]; switch(gVWSp->gTabType2D) { case WLZ_GREY_TAB_RAGR: bkdPix = gVWSp->values2D.v->bckgrnd; break; case WLZ_GREY_TAB_RECT: bkdPix = gVWSp->values2D.r->bckgrnd; break; case WLZ_GREY_TAB_INTL: bkdPix = gVWSp->values2D.i->bckgrnd; break; case WLZ_GREY_TAB_TILED: bkdPix = gVWSp->values2D.t->bckgrnd; break; default: errNum = WLZ_ERR_VALUES_TYPE; break; } if((gVWSp->gType != bkdPix.type) && (errNum == WLZ_ERR_NONE)) { errNum = WLZ_ERR_VALUES_DATA; } else if((gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_INTVL) && (gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_RECT)) { errNum = WLZ_ERR_DOMAIN_TYPE; } else { gVWSp->gBkd = bkdPix.v; } } } } break; case WLZ_TRANS_OBJ: trans0 = NULL; while((errNum == WLZ_ERR_NONE) && (obj->type == WLZ_TRANS_OBJ)) { if(trans0 == NULL) { trans0 = WlzAffineTransformCopy(obj->domain.t, &errNum); } else { if((trans1 = WlzAffineTransformProduct(trans0, obj->domain.t, &errNum)) != NULL) { WlzFreeAffineTransform(trans0); trans0 = trans1; trans1 = NULL; } } if((obj = obj->values.obj) == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } } if(errNum == WLZ_ERR_NONE) { gVWSp = WlzGreyValueMakeWSp(obj, &errNum); } if(errNum == WLZ_ERR_NONE) { gVWSp->invTrans = WlzAffineTransformInverse(trans0, &errNum); } if(trans0) { WlzFreeAffineTransform(trans0); } break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } if((errNum != WLZ_ERR_NONE) && (gVWSp != NULL)) { WlzGreyValueFreeWSp(gVWSp); gVWSp = NULL; } if(dstErrNum) { *dstErrNum = errNum; } WLZ_DBG((WLZ_DBG_LVL_FN|WLZ_DBG_LVL_1), ("WlzGreyValueMakeWSp FX %p\n", gVWSp)); return(gVWSp); }