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); }
RecError RecSecListAbsFromRel(RecSectionList *secList) { RecSection *sec; HGUDlpListItem *item; WlzAffineTransform *tr0 = NULL, *tr1; RecError recErr = REC_ERR_NONE; WlzErrorNum wlzErr = WLZ_ERR_NONE; if(secList == NULL) { recErr = REC_ERR_FUNC; } else if(secList->attributes.trMode == REC_TRMODE_REL) { item = HGUDlpListHead(secList->list); do { sec = (RecSection *)HGUDlpListEntryGet(secList->list, item); if(sec && strcmp(sec->imageFile, "empty")) { if(tr0) { tr1 = WlzAffineTransformProduct(sec->transform, tr0, &wlzErr); if(wlzErr == WLZ_ERR_NONE) { (void )WlzFreeAffineTransform(sec->transform); sec->transform = WlzAssignAffineTransform(tr1, NULL); } tr0 = tr1; } else { tr0 = sec->transform; } } item = HGUDlpListNext(secList->list, item); } while((wlzErr == WLZ_ERR_NONE) && item && (item != HGUDlpListHead(secList->list))); secList->attributes.trMode = REC_TRMODE_ABS; recErr = RecErrorFromWlz(wlzErr); } return(recErr); }
/*! * \return Affine transform which brings the two objects into register. * \ingroup WlzRegistration * \brief Registers the two given 2D domain objects using a * frequency domain cross correlation. An affine transform * is computed, which when applied to the source object * takes it into register with the target object. * \param tObj The target object. Must have * been assigned. * \param sObj The source object to be * registered with target object. * \param initTr Initial affine transform * to be applied to the source * object prior to registration. * Only translations in x and y * and rotation about the z axis * are used. May be NULL which is * equivalent to an identity transform. * \param trType Required transform type. * \param maxTran Maximum translation. * \param maxRot Maximum rotation. * \param maxItr Maximum number of iterations, * if \f$\leq\f$ 0 then infinite iterations are allowed. * \param winFn Window function. * \param noise Use Gaussian noise if non-zero. * \param dstConv Destination ptr for the * convergence flag (non zero * on convergence), may be NULL. * \param dstCCor Destination ptr for the cross * correlation value, may be NULL. * \param dstErr Destination error pointer, * may be NULL. */ static WlzAffineTransform *WlzRegCCorObjs2D1(WlzObject *tObj, WlzObject *sObj, WlzAffineTransform *initTr, WlzTransformType trType, WlzDVertex2 maxTran, double maxRot, int maxItr, WlzWindowFnType winFn, int noise, int *dstConv, double *dstCCor, WlzErrorNum *dstErr) { int itr, conv; WlzAffineTransform *tTr0 = NULL, *tTr1 = NULL, *curTr = NULL, *regTr = NULL; double rot, lastRot, cCor; WlzDVertex2 tran; WlzErrorNum errNum = WLZ_ERR_NONE; const double tranTol = 0.5; /* Register for translation. */ tran = WlzRegCCorObjs2DTran(tObj, sObj, initTr, maxTran, winFn, noise, &cCor, &errNum); if(errNum == WLZ_ERR_NONE) { tTr0 = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, tran.vtX, tran.vtY, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, &errNum); } if(errNum == WLZ_ERR_NONE) { curTr = WlzAffineTransformProduct(initTr, tTr0, &errNum); (void )WlzFreeAffineTransform(tTr0); tTr0 = NULL; } if(trType == WLZ_TRANSFORM_2D_TRANS) { conv = 1; } else /* trType == WLZ_TRANSFORM_2D_REG */ { /* Iterate until translation is less tahn tollerance value or * number of itterations exceeds the maximum. */ itr = 0; rot = 0.0; lastRot = 1.0; /* The convergence test must only test the translation and not the * rotation too, as the rotation has already been applied when * finding the translation. */ while((errNum == WLZ_ERR_NONE) && ((conv = (fabs(tran.vtX) <= tranTol) && (fabs(tran.vtY) <= tranTol)) == 0) && ((maxItr < 0) || (itr++ < maxItr))) { /* Register for rotation. */ lastRot = rot; rot = WlzRegCCorObjs2DRot(tObj, sObj, curTr, maxRot, winFn, noise, &errNum); if(errNum == WLZ_ERR_NONE) { tTr0 = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0, 1.0, rot, 0.0, 0.0, 0.0, 0.0, 0, &errNum); } if(errNum == WLZ_ERR_NONE) { tTr1 = WlzAffineTransformProduct(curTr, tTr0, &errNum); } if(errNum == WLZ_ERR_NONE) { (void )WlzFreeAffineTransform(tTr0); tTr0 = NULL; (void )WlzFreeAffineTransform(curTr); curTr = tTr1; tTr1 = NULL; } /* Register for translation. */ if(errNum == WLZ_ERR_NONE) { tran = WlzRegCCorObjs2DTran(tObj, sObj, curTr, maxTran, winFn, noise, &cCor, &errNum); } if(errNum == WLZ_ERR_NONE) { tTr0 = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, tran.vtX, tran.vtY, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, &errNum); } if(errNum == WLZ_ERR_NONE) { tTr1 = WlzAffineTransformProduct(curTr, tTr0, &errNum); } if(errNum == WLZ_ERR_NONE) { (void )WlzFreeAffineTransform(tTr0); tTr0 = NULL; (void )WlzFreeAffineTransform(curTr); curTr = tTr1; tTr1 = NULL; } } (void )WlzFreeAffineTransform(tTr0); (void )WlzFreeAffineTransform(tTr1); } if(errNum == WLZ_ERR_NONE) { regTr = curTr; if(dstConv) { *dstConv = conv; } if(dstCCor) { *dstCCor = cCor; } } if(dstErr) { *dstErr = errNum; } return(regTr); }
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; }
WlzObject *SecListToTransforms( RecSectionList *secList, int relFlg, WlzErrorNum *dstErr) { WlzErrorNum errNum=WLZ_ERR_NONE; WlzObject *rtnObj=NULL; int i, p, pMin, pMax; WlzDomain domain; WlzValues values; RecSection *sec; HGUDlpListItem *listItem; WlzAffineTransform *recTrans, *tmpTrans; /* sort the section list and find the section range */ RecSecListSort(secList->list, REC_SECMSK_INDEX); /* calculate the cumulative transforms */ listItem = HGUDlpListTail(secList->list); if( relFlg ){ RecSecCumTransfSet(secList->list, listItem); } /* define the reconstruct transform */ recTrans = WlzAffineTransformFromPrimVal(WLZ_TRANSFORM_2D_AFFINE, 0.0, 0.0, 0.0, secList->reconstruction.scale.vtX, 0.0, 0.0, 0.0, 0.0, 0.0, 0, NULL); /* create the transforms object */ listItem = HGUDlpListHead(secList->list); sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem); pMin = sec->index; listItem = HGUDlpListTail(secList->list); sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem); pMax = sec->index; if( errNum == WLZ_ERR_NONE ){ if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_AFFINE, pMin, pMax, 0, 0, 0, 0, &errNum)) != NULL){ values.core = NULL; rtnObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values, NULL, NULL, &errNum); } } /* now put in the transforms */ listItem = HGUDlpListHead(secList->list); while( listItem ){ sec = (RecSection *) HGUDlpListEntryGet(secList->list, listItem); p = sec->index; i = p - rtnObj->domain.p->plane1; if( relFlg ){ if( sec->cumTransform == NULL ){ rtnObj->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 { rtnObj->domain.p->domains[i].t = WlzAssignAffineTransform(sec->cumTransform, NULL); } } else { rtnObj->domain.p->domains[i].t = WlzAssignAffineTransform(sec->transform, NULL); } /* apply the reconstruct transform */ tmpTrans = WlzAffineTransformProduct(rtnObj->domain.p->domains[i].t, recTrans, NULL); WlzFreeAffineTransform(rtnObj->domain.p->domains[i].t); rtnObj->domain.p->domains[i].t = WlzAssignAffineTransform(tmpTrans, NULL); listItem = HGUDlpListNext(secList->list, listItem); } WlzFreeAffineTransform(recTrans); if( dstErr ){ *dstErr = errNum; } if( (errNum != WLZ_ERR_NONE) && rtnObj ){ WlzFreeObj(rtnObj); rtnObj = NULL; } return rtnObj; }
/*! * \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); }
/*! * \return Non-zero to continue iteration. * \ingroup Reconstruct * \brief Iterated function which sets the cumulative transform * fields of a section list, working from the head of the * list towards the tail and stoping when the specified * list item has been processed. * \param secList Given section list. * \param secItem Given section item. * \param itData Used to pass item to stop at. */ static int RecSecCumTransfSetItFn(HGUDlpList *secList, HGUDlpListItem *secItem, void *itData) { int iterate = 0; HGUDlpListItem *prevItem, *stopItem; WlzAffineTransform *cumTransf = NULL; RecSection *curSec, *prevSec; WlzAffineTransformPrim prim; REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_2), ("RecSecCumTransfSetItFn FE 0x%lx 0x%lx 0x%lx\n", (unsigned long )secList, (unsigned long )secItem, (unsigned long )itData)); if(secList && secItem && itData) { stopItem = (HGUDlpListItem *)itData; curSec = (RecSection *)HGUDlpListEntryGet(secList, secItem); if(curSec && curSec->transform) /* Should always be true */ { if(HGUDlpListItemIsHead(secList, secItem)) { if(curSec->cumTransform == NULL) { curSec->cumTransform = curSec->transform; ++(curSec->cumTransform->linkcount); } cumTransf = curSec->cumTransform; } else { if(curSec->cumTransform == NULL) { prevItem = HGUDlpListPrev(secList, secItem); prevSec = (RecSection *)HGUDlpListEntryGet(secList, prevItem); if(prevSec && prevSec->cumTransform) /* Should always be true */ { cumTransf = WlzAffineTransformProduct(curSec->transform, prevSec->cumTransform, NULL); curSec->cumTransform = cumTransf; ++(curSec->cumTransform->linkcount); } } else { cumTransf = curSec->cumTransform; } } REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_2), ("RecSecCumTransfSetItFn 02 0x%lx\n", (unsigned long )cumTransf)); if(cumTransf) { (void )WlzAffineTransformPrimGet(cumTransf, &prim); REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_3), ("RecSecCumTransfSetItFn 02 %d %g %g %g %g %g %g %g %g %g %d\n", cumTransf->type, prim.tx, prim.ty, prim.tz, prim.scale, prim.theta, prim.phi, prim.alpha, prim.psi, prim.xsi, prim.invert)); if(secItem != stopItem) { iterate = 1; } } } } REC_DBG((REC_DBG_SEC|REC_DBG_LVL_FN|REC_DBG_LVL_2), ("RecSecCumTransfSetItFn FX %d\n", iterate)); return(iterate); }