VInstant VFSNode::modificationDate() const { VFSNodeInfo info; bool nodeExists = this->_platform_getNodeInfo(info); if (!nodeExists) throw VException(VSystemError(info.mErrNo), VSTRING_FORMAT("VFSNode::modificationDate failed for '%s'.", mPath.chars())); return VInstant::instantFromRawValue(info.mModificationDate); }
VFSize VFSNode::size() const { VFSNodeInfo info; bool nodeExists = this->_platform_getNodeInfo(info); if (!nodeExists) throw VException(VSystemError(info.mErrNo), VSTRING_FORMAT("VFSNode::size failed for '%s'.", mPath.chars())); return info.mFileSize; }
VPointer VCalloc (size_t n, size_t size) { VPointer p; if (n == 0 || size == 0) return NULL; if (! (p = (VPointer) calloc (n, size))) VSystemError ("VCalloc: Memory allocation failure"); return p; }
VPointer VMalloc (size_t size) { VPointer p; if (size == 0) return NULL; if (! (p = (VPointer) malloc (size))) VSystemError ("VMalloc: Memory allocation failure"); return p; }
// static VFSNode VFSNode::_platform_getExecutable() { const int PATH_BUFFER_SIZE = 1024; VString executablePath; executablePath.preflight(PATH_BUFFER_SIZE); ssize_t len = ::readlink(PROCESS_LINKPATH, executablePath.buffer(), PATH_BUFFER_SIZE - 1); if (len == -1) { throw VStackTraceException(VSystemError(), "VFSNode::_platform_getExecutable: Unable to determine executable path."); } executablePath.postflight(len); return VFSNode(VFSNode::normalizePath(executablePath)); // must supply normalized form to VFSNode below }
VPointer VRealloc (VPointer p, size_t size) { if (size == 0) { VFree (p); return NULL; } if (! p) return VMalloc (size); if (! (p = (VPointer) realloc (p, size))) VSystemError ("VRealloc: Memory allocation failure"); return p; }
void VFSNode::_platform_renameNode(const VString& newPath) const { int result = VFileSystem::rename(mPath, newPath); if (result != 0) throw VException(VSystemError(), VSTRING_FORMAT("VFSNode::_platform_renameNode failed with result %d renaming '%s' to '%s'.", result, mPath.chars(), newPath.chars())); }
void VFSNode::_platform_createDirectory() const { int result = VFileSystem::mkdir(mPath, (S_IFDIR | S_IRWXO | S_IRWXG | S_IRWXU)); if (result != 0) throw VException(VSystemError(), VSTRING_FORMAT("VFSNode::_platform_createDirectory failed with result %d for '%s'.", result, mPath.chars())); }
// static VFSNode VFSNode::_platform_getKnownDirectoryNode(KnownDirectoryIdentifier id, const VString& companyName, const VString& appName) { if (id == CURRENT_WORKING_DIRECTORY) { return VFSNode(VSystemAPI::getcwd()); } if (id == EXECUTABLE_DIRECTORY) { VFSNode executable = VFSNode::getExecutable(); VFSNode executableDirectory; executable.getParentNode(executableDirectory); return executableDirectory; } struct passwd* pwInfo = ::getpwuid(::getuid()); // Get info about the current user. if (pwInfo == NULL) { throw VStackTraceException( // Oddity: errno 0 can occur and means "no such user". (errno == 0 ? VSystemError(0, "No such user") : VSystemError()), "VFSNode::_platform_getKnownDirectoryNode failed to get current user info from getpwuid()." ); } const VString homePath(pwInfo->pw_dir); if (id == USER_HOME_DIRECTORY) { return VFSNode(homePath); } VString basePath; VString companyFolderName(companyName); switch (id) { case USER_HOME_DIRECTORY: // handled earlier; we returned above break; case LOG_FILES_DIRECTORY: basePath = homePath + "/log"; break; case USER_PREFERENCES_DIRECTORY: basePath = homePath; if (companyName.isNotEmpty()) { companyFolderName.format(".%s", companyName.chars()); } break; case CACHED_DATA_DIRECTORY: basePath = homePath + "/cache"; break; case APPLICATION_DATA_DIRECTORY: basePath = homePath + "/data"; break; case CURRENT_WORKING_DIRECTORY: // handled earlier; we returned above break; case EXECUTABLE_DIRECTORY: // handled earlier; we returned above break; default: throw VStackTraceException(VSTRING_FORMAT("VFSNode::_platform_getKnownDirectoryNode: Requested invalid directory ID %d.", (int) id)); break; } VFSNode baseDir(basePath); baseDir.mkdir(); VFSNode companyFolder; if (companyFolderName.isEmpty()) { companyFolder = baseDir; } else { baseDir.getChildNode(companyFolderName, companyFolder); companyFolder.mkdir(); } VFSNode resultNode; if (appName.isEmpty()) { resultNode = companyFolder; } else { companyFolder.getChildNode(appName, resultNode); resultNode.mkdir(); } return resultNode; }
VBoolean VIdentifyFiles (int noptions, VOptionDescRec options[], VStringConst keyword, int *argc, char **argv, int fd) { VOptionDescRec *opt; VArgVector *vec; VBoolean switch_found = FALSE; VStringConst *values; struct stat stat_buf; int i, j, n; /* A -in or -out switch on the command line may specify one or more files. Look for the switch's entry in the option table supplied: */ for (i = 0, opt = options; i < noptions; i++, opt++) if (strcmp (keyword, opt->keyword) == 0) break; if (i == noptions) VError ("VIdentifyFiles: Option -%s not defined in option table", keyword); /* The option table entry must specify a location for storing filenames: */ if (! opt->value) VError ("VIdentifyFiles: No value storage for option -%s", keyword); vec = ((VArgVector *) opt->value); /* Whether or not the option was present on the command line should have been recorded in a "found" flag: */ if (opt->found && opt->found != VRequiredOpt && opt->found != VOptionalOpt) switch_found = *(opt->found); else VError ("VIdentifyFiles: No \"found\" flag for option -%s", keyword); /* If a -in or -out switch was specified, it supplies the files' names: */ if (switch_found) return TRUE; /* If no switch was specified but some extra arguments were supplied with the command, those arguments should be the files' names: */ if (*argc > 1) { /* If any number are permitted, allocate storage for all of them: */ if (opt->number == 0) { vec->vector = VMalloc ((*argc - 1) * sizeof (VStringConst)); values = (VStringConst *) vec->vector; } else values = (VStringConst *) opt->value; /* Accept arguments as filenames provided they don't begin with a single -: */ for (i = j = 1, n = 0; i < *argc; i++) if ((argv[i][0] == '-' && argv[i][1] != '-') || (opt->number && n == opt->number)) argv[j++] = argv[i]; /* not a filename */ else if (argv[i][0] == '-' && argv[i][1] == '-') values[n++] = argv[i] + 1; /* filename with -- prefix */ else values[n++] = argv[i]; /* filename */ /* Ensure that a sufficient number were supplied: */ if (n) { if (opt->number) { if (n != opt->number) if (opt->number == 1) goto WrongNumber1; else goto WrongNumberN; } else vec->number = n; *argc = j; return TRUE; } } /* That leaves only an open file descriptor as the file. In that case there can be at most one such file: */ if (opt->number > 1) { WrongNumberN: fprintf (stderr, "%s: %d files must be specified by -%s or " "extra command arguments.\n", argv[0], opt->number, keyword); return FALSE; } /* If a particular file descriptor is specified by fd, ensure that it is connected to a pipe or file (not the terminal): */ if (fd >= 0) { if (fstat (fd, & stat_buf) == -1) VSystemError ("Failed to fstat() fd %d", fd); if (! S_ISREG (stat_buf.st_mode) && ! S_ISSOCK (stat_buf.st_mode) && ! S_ISLNK (stat_buf.st_mode) && ! S_ISFIFO (stat_buf.st_mode)) { WrongNumber1: fprintf (stderr, "%s: No file specified by -%s, extra command " "argument, or %c.\n", argv[0], keyword, "<>"[fd]); return FALSE; } } /* Record the file as being "-": */ if (opt->number == 0) { vec->number = 1; vec->vector = VMalloc (sizeof (VStringConst)); ((VStringConst *) vec->vector)[0] = "-"; } else * ((VStringConst *) opt->value) = "-"; return TRUE; }
int main(int argc, char *argv[]) { /* command line arguments */ static VString out_filename; static VArgVector in_files; static VString trans_filename = ""; static VBoolean in_found, out_found; static VShort minval = 0; static VBoolean compress = TRUE; static VFloat resolution = 3; static VOptionDescRec options[] = { { "in", VStringRepn, 0, & in_files, & in_found, NULL, "Input file" }, { "out", VStringRepn, 1, & out_filename, & out_found, NULL, "Output file" }, { "trans", VStringRepn, 1, &trans_filename, VRequiredOpt, NULL, "File containing transformation matrix" }, { "resolution", VFloatRepn, 1, &resolution, VOptionalOpt, NULL, "Output voxel resolution in mm" }, { "minval", VShortRepn, 1, &minval, VOptionalOpt, NULL, "Signal threshold" }, { "compress", VBooleanRepn, 1, &compress, VOptionalOpt, NULL, "Whether to compress empty slices" } }; VStringConst in_filename; FILE *in_file, *out_file, *fp; VAttrList list, list1, out_list; VAttrListPosn posn; VImage trans = NULL; VImage *dst_image; VImageInfo *imageInfo; int nobject = 0, ntimesteps = 0, nbands = 0, nrows = 0, ncols = 0; VString ca, cp, extent, str; int found = 0; int j, dest_nbands; char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vfunctrans V%s", ver); fprintf(stderr, "%s\n", prg_name); /* Parse command line arguments: */ if(! VParseCommand(VNumber(options), options, & argc, argv) || ! VIdentifyFiles(VNumber(options), options, "in", & argc, argv, 0) || ! VIdentifyFiles(VNumber(options), options, "out", & argc, argv, -1)) goto Usage; if(argc > 1) { VReportBadArgs(argc, argv); Usage: VReportUsage(argv[0], VNumber(options), options, NULL); exit(EXIT_FAILURE); } if(resolution <= 0) VError(" 'resolution' must be an integer > 0"); /* ** Read the transformation matrix: */ fp = VOpenInputFile(trans_filename, TRUE); list1 = VReadFile(fp, NULL); if(! list1) VError("Error reading image"); fclose(fp); for(VFirstAttr(list1, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; if(strncmp(VGetAttrName(&posn), "transform", 9) != 0) continue; VGetAttrValue(& posn, NULL, VImageRepn, & trans); break; } if(trans == NULL) VError("transformation matrix not found"); /* ** check attributes */ if(VGetAttr(VImageAttrList(trans), "ca", NULL, VStringRepn, (VPointer) & ca) != VAttrFound) VError(" attribute 'ca' missing in transformation matrix "); if(VGetAttr(VImageAttrList(trans), "cp", NULL, VStringRepn, (VPointer) & cp) != VAttrFound) VError(" attribute 'cp' missing in transformation matrix "); if(VGetAttr(VImageAttrList(trans), "extent", NULL, VStringRepn, (VPointer) & extent) != VAttrFound) VError(" attribute 'extent' missing in transformation matrix "); /* ** open in-file */ if(in_files.number < 1 || in_files.number > 1) VError(" incorrect number of input files: %d", in_files.number); in_filename = ((VStringConst *) in_files.vector)[0]; if(strcmp(in_filename, "-") == 0) in_file = stdin; else { in_file = fopen((char *)in_filename, "r"); if(! in_file) VError("Failed to open input file %s", in_filename); } /* ** read file info */ if(! ReadHeader(in_file)) VError("error reading header"); if(!(list = ReadAttrList(in_file))) VError("error reading attr list"); j = 0; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { j++; } imageInfo = (VImageInfo *) VMalloc(sizeof(VImageInfo) * (j + 1)); nobject = nbands = found = 0; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { str = VGetAttrName(&posn); if(strncmp(str, "history", 7) == 0) { nobject++; continue; } VImageInfoIni(&imageInfo[nbands]); if(! VGetImageInfo(in_file, list, nobject, &imageInfo[nbands])) VError(" error reading image info"); if(imageInfo[nbands].repn == VShortRepn) { found = 1; nrows = imageInfo[nbands].nrows; ncols = imageInfo[nbands].ncolumns; ntimesteps = imageInfo[nbands].nbands; nbands++; } nobject++; } fclose(in_file); if(!found) VError(" couldn't find functional data"); /* ** process each time step */ dst_image = VFunctrans(in_filename, imageInfo, nbands, trans, resolution, ntimesteps, minval, compress, &dest_nbands); /* ** output */ out_list = VCreateAttrList(); VHistory(VNumber(options), options, prg_name, &list, &out_list); for(j = 0; j < dest_nbands; j++) { VAppendAttr(out_list, "image", NULL, VImageRepn, dst_image[j]); } /* Open and write the output file: */ if(strcmp(out_filename, "-") == 0) out_file = stdout; else { out_file = fopen(out_filename, "w"); if(! out_file) VError("Failed to open output file %s", out_filename); } if(!VWriteFile(out_file, out_list) || fclose(out_file)) VSystemError("error writing output file"); fprintf(stderr, "\n%s: done.\n", argv[0]); return (EXIT_SUCCESS); }