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; }
int main(int argc, char *argv[]) { int option, numSec, absMode = 1, ok = 1, usage = 0; char *inFile, *outFile; FILE *fP = NULL; RecError recErr = REC_ERR_NONE; RecSectionList *secList = NULL; char *errMsg; static char optList[] = "ahro:", defFile[] = "-", defErrMsg[] = "none."; opterr = 0; errMsg = defErrMsg; inFile = outFile = defFile; while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1)) { switch(option) { case 'a': absMode = 1; break; case 'r': absMode = 0; break; case 'o': outFile = optarg; break; case 'h': /* FALLTHROUGH */ default: usage = 1; break; } } if((usage == 0) && (optind < argc)) { if((optind + 1) != argc) { usage = 1; } else { inFile = *(argv + optind); } } ok = !usage; /* Read input bibfile. */ if(ok) { if((secList = RecSecNewSectionList(&recErr)) == NULL) { ok = 0; (void )fprintf(stderr, "%s: Failed to memory for allocate section list.\n", *argv); } } if(ok) { if((inFile == NULL) || (*inFile == '\0') || ((fP = (strcmp(inFile, "-")? fopen(inFile, "r"): stdin)) == NULL)) { ok = 0; (void )fprintf(stderr, "%s: Failed to open input file %s\n", *argv, (inFile)? inFile: "(null)"); } } if(ok) { if(RecFileSecListRead(secList, &numSec, fP, &errMsg) != REC_ERR_NONE) { ok = 0; (void )fprintf(stderr, "%s: Failed to read section list from file %s.\n" "Error message - %s\n", *argv, inFile, errMsg); } } if(fP && (strcmp(inFile, "-") == 0)) { (void )fclose(fP); } /* Convert transforms. */ if(ok) { if(absMode) { recErr = RecSecListAbsFromRel(secList); } else { recErr = RecSecListRelFromAbs(secList); } if(recErr != REC_ERR_NONE) { ok = 0; (void )fprintf(stderr, "%s: Failed to convert the section list from %s to\n" "%s transforms.\n", *argv, (absMode)? "relative": "absolute", (absMode)? "absolute": "relative"); } } /* Write output bibfile. */ if(ok) { if((outFile == NULL) || (*outFile == '\0') || ((fP = (strcmp(outFile, "-")? fopen(outFile, "w"): stdout)) == NULL)) { ok = 0; (void )fprintf(stderr, "%s: Failed to open output file %s\n", *argv, (inFile)? inFile: "(null)"); } } if(ok) { if(RecFileSecListWrite(fP, secList, numSec, &errMsg) != REC_ERR_NONE) { (void )fprintf(stderr, "%s: Failed to write section list to file %s.\n" "Error message - %s\n", *argv, inFile, errMsg); ok = 0; } } if(fP && (strcmp(outFile, "-") == 0)) { (void )fclose(fP); } if(usage) { (void )fprintf(stderr, "Usage: %s [-a] [-h] [-r] [-o outfile] [<infile>]\n" "Reads a reconstruction bibfile and writes it to the output file\n" "with either absolute or relative transforms.\n" "Version: %s\n" "Options:\n" " -a Output bibfile with absolute transforms (%s).\n" " -h Help - print this usage information.\n" " -r Output bibfile with relative transforms (%s).\n" " -o Output file name.\n" "By default %s reads from it's standard input and\n" "writes to it's standard output.\n", *argv, WlzVersion(), (absMode != 0)? "set": "not set", (absMode == 0)? "set": "not set", *argv); } exit(!ok); }