int unrrdu_minmaxDoit(char *me, char *inS, int blind8BitRange, FILE *fout) { char err[BIFF_STRLEN]; Nrrd *nrrd; NrrdRange *range; airArray *mop; mop = airMopNew(); airMopAdd(mop, nrrd=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); if (nrrdLoad(nrrd, inS, NULL)) { sprintf(err, "%s: trouble loading \"%s\"", me, inS); biffMove(me, err, NRRD); airMopError(mop); return 1; } range = nrrdRangeNewSet(nrrd, blind8BitRange); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); airSinglePrintf(fout, NULL, "min: %g\n", range->min); airSinglePrintf(fout, NULL, "max: %g\n", range->max); if (0 == range->min && 0 == range->max) { fprintf(fout, "# min == max == 0.0 exactly\n"); } if (range->hasNonExist) { fprintf(fout, "# has non-existent values\n"); } airMopOkay(mop); return 0; }
void _nrrdStrcatSpaceVector(char *str, int spaceDim, const double val[NRRD_SPACE_DIM_MAX]) { char buff[AIR_STRLEN_MED]; /* bad Gordon */ int dd; if (AIR_EXISTS(val[0])) { strcat(str, "("); for (dd=0; dd<spaceDim; dd++) { strcpy(buff, ""); airSinglePrintf(NULL, buff, "%g", val[dd]); strcat(str, buff); sprintf(buff, "%s", dd < spaceDim-1 ? "," : ")"); strcat(str, buff); } } else { strcat(str, _nrrdNoSpaceVector); } return; }
int main(int argc, char *argv[]) { char *fS, buff[128]; float f; double d, sd; int ret; me = argv[0]; if (2 != argc) { fprintf(stderr, "usage: %s <double>\n", me); exit(1); } fS = argv[1]; ret = sscanf(fS, "%lf", &sd); if (!ret) { printf("%s: sscanf(%s, \"%%lf\") failed\n", me, fS); printf("\n"); } if (1 != airSingleSscanf(fS, "%lf", &d)) { fprintf(stderr, "%s: couldn't parse \"%s\" as double\n", me, fS); exit(1); } if (ret && (sd != d)) { printf("%s: sscanf result (%f) != airSingleSscanf (%f)!!!\n", me, sd, d); printf("\n"); } f = d; airSinglePrintf(NULL, buff, "%f", f); printf("%s: printf/airSinglePrintf as float:\n%f\n%s\n", me, f, buff); airSinglePrintf(NULL, buff, "%lf", d); printf("\n"); printf("%s: printf/airSinglePrintf as double:\n%f\n%s\n", me, d, buff); printf("\n"); printf("%s: airFPFprintf_d:\n", me); airFPFprintf_d(stderr, d); exit(0); }
/* ******** nrrdDescribe ** ** writes verbose description of nrrd to given file */ void nrrdDescribe(FILE *file, const Nrrd *nrrd) { unsigned int ai; char stmp[AIR_STRLEN_SMALL]; if (file && nrrd) { fprintf(file, "Nrrd at 0x%p:\n", AIR_CVOIDP(nrrd)); fprintf(file, "Data at 0x%p is %s elements of type %s.\n", nrrd->data, airSprintSize_t(stmp, nrrdElementNumber(nrrd)), airEnumStr(nrrdType, nrrd->type)); if (nrrdTypeBlock == nrrd->type) { fprintf(file, "The blocks have size %s\n", airSprintSize_t(stmp, nrrd->blockSize)); } if (airStrlen(nrrd->content)) { fprintf(file, "Content = \"%s\"\n", nrrd->content); } fprintf(file, "%d-dimensional array, with axes:\n", nrrd->dim); for (ai=0; ai<nrrd->dim; ai++) { if (airStrlen(nrrd->axis[ai].label)) { fprintf(file, "%d: (\"%s\") ", ai, nrrd->axis[ai].label); } else { fprintf(file, "%d: ", ai); } fprintf(file, "%s-centered, size=%s, ", airEnumStr(nrrdCenter, nrrd->axis[ai].center), airSprintSize_t(stmp, nrrd->axis[ai].size)); airSinglePrintf(file, NULL, "spacing=%lg, \n", nrrd->axis[ai].spacing); airSinglePrintf(file, NULL, "thickness=%lg, \n", nrrd->axis[ai].thickness); airSinglePrintf(file, NULL, " axis(Min,Max) = (%lg,", nrrd->axis[ai].min); airSinglePrintf(file, NULL, "%lg)\n", nrrd->axis[ai].max); if (airStrlen(nrrd->axis[ai].units)) { fprintf(file, "units=%s, \n", nrrd->axis[ai].units); } } /* airSinglePrintf(file, NULL, "The min, max values are %lg", nrrd->min); airSinglePrintf(file, NULL, ", %lg\n", nrrd->max); */ airSinglePrintf(file, NULL, "The old min, old max values are %lg", nrrd->oldMin); airSinglePrintf(file, NULL, ", %lg\n", nrrd->oldMax); /* fprintf(file, "hasNonExist = %d\n", nrrd->hasNonExist); */ if (nrrd->cmtArr->len) { fprintf(file, "Comments:\n"); for (ai=0; ai<nrrd->cmtArr->len; ai++) { fprintf(file, "%s\n", nrrd->cmt[ai]); } } fprintf(file, "\n"); } }
/* ** _nrrdSprintFieldInfo ** ** this prints "<prefix><field>: <info>" into *strP (after allocating it for ** big enough, usually with a stupidly big margin of error), in a form ** suitable to be written to NRRD or other image headers. This will always ** print something (for valid inputs), even stupid <info>s like ** "(unknown endian)". It is up to the caller to decide which fields ** are worth writing, via _nrrdFieldInteresting(). ** ** NOTE: some of these fields make sense in non-NRRD files (e.g. all ** the per-axis information), but many only make sense in NRRD files. ** This is just one example of NRRD-format-specific stuff that is not ** in formatNRRD.c */ void _nrrdSprintFieldInfo(char **strP, char *prefix, const Nrrd *nrrd, NrrdIoState *nio, int field) { char me[]="_nrrdSprintFieldInfo", buff[AIR_STRLEN_MED], *fnb; double colvec[NRRD_SPACE_DIM_MAX]; const char *fs; unsigned int ii, dd, uintStrlen = 11, size_tStrlen = 33, doubleStrlen = 513; int fslen, fdlen, endi, maxl; if (!( strP && prefix && nrrd && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX) && AIR_IN_OP(nrrdField_unknown, field, nrrdField_last) )) { return; } if (!_nrrdFieldInteresting(nrrd, nio, field)) { *strP = airStrdup(""); } fs = airEnumStr(nrrdField, field); fslen = strlen(prefix) + strlen(fs) + strlen(": ") + 1; switch (field) { case nrrdField_comment: case nrrdField_keyvalue: fprintf(stderr, "%s: CONFUSION: why are you calling me on \"%s\"?\n", me, airEnumStr(nrrdField, nrrdField_comment)); *strP = airStrdup(""); break; case nrrdField_content: airOneLinify(nrrd->content); *strP = (char *)calloc(fslen + strlen(nrrd->content), sizeof(char)); sprintf(*strP, "%s%s: %s", prefix, fs, nrrd->content); break; case nrrdField_number: *strP = (char *)calloc(fslen + size_tStrlen, sizeof(char)); sprintf(*strP, "%s%s: " _AIR_SIZE_T_CNV, prefix, fs, nrrdElementNumber(nrrd)); break; case nrrdField_type: *strP = (char *)calloc(fslen + strlen(airEnumStr(nrrdType, nrrd->type)), sizeof(char)); sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdType, nrrd->type)); break; case nrrdField_block_size: *strP = (char *)calloc(fslen + size_tStrlen, sizeof(char)); sprintf(*strP, "%s%s: " _AIR_SIZE_T_CNV, prefix, fs, nrrd->blockSize); break; case nrrdField_dimension: *strP = (char *)calloc(fslen + uintStrlen, sizeof(char)); sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->dim); break; case nrrdField_space: *strP = (char *)calloc(fslen + strlen(airEnumStr(nrrdSpace, nrrd->space)), sizeof(char)); sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdSpace, nrrd->space)); break; case nrrdField_space_dimension: *strP = (char *)calloc(fslen + uintStrlen, sizeof(char)); sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->spaceDim); break; /* ---- begin per-axis fields ---- */ case nrrdField_sizes: *strP = (char *)calloc(fslen + nrrd->dim*(size_tStrlen + 1), sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { sprintf(buff, " " _AIR_SIZE_T_CNV, nrrd->axis[ii].size); strcat(*strP, buff); } break; case nrrdField_spacings: *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].spacing); strcat(*strP, buff); } break; case nrrdField_thicknesses: *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].thickness); strcat(*strP, buff); } break; case nrrdField_axis_mins: *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].min); strcat(*strP, buff); } break; case nrrdField_axis_maxs: *strP = (char *)calloc(fslen + nrrd->dim*(doubleStrlen + 1), sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %g", nrrd->axis[ii].max); strcat(*strP, buff); } break; case nrrdField_space_directions: *strP = (char *)calloc(fslen + nrrd->dim*nrrd->spaceDim*(doubleStrlen + strlen("(,) ")), sizeof(char)); sprintf(*strP, "%s%s: ", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, nrrd->axis[ii].spaceDirection); if (ii < nrrd->dim-1) { strcat(*strP, " "); } } break; case nrrdField_centers: fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { fdlen += 1 + airStrlen(nrrd->axis[ii].center ? airEnumStr(nrrdCenter, nrrd->axis[ii].center) : NRRD_UNKNOWN); } *strP = (char *)calloc(fslen + fdlen, sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { sprintf(buff, " %s", (nrrd->axis[ii].center ? airEnumStr(nrrdCenter, nrrd->axis[ii].center) : NRRD_UNKNOWN)); strcat(*strP, buff); } break; case nrrdField_kinds: fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { fdlen += 1 + airStrlen(nrrd->axis[ii].kind ? airEnumStr(nrrdKind, nrrd->axis[ii].kind) : NRRD_UNKNOWN); } *strP = (char *)calloc(fslen + fdlen, sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { sprintf(buff, " %s", (nrrd->axis[ii].kind ? airEnumStr(nrrdKind, nrrd->axis[ii].kind) : NRRD_UNKNOWN)); strcat(*strP, buff); } break; case nrrdField_labels: fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { fdlen += airStrlen(nrrd->axis[ii].label) + 4; } *strP = (char *)calloc(fslen + fdlen, sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { strcat(*strP, " \""); if (airStrlen(nrrd->axis[ii].label)) { strcat(*strP, nrrd->axis[ii].label); } strcat(*strP, "\""); } break; case nrrdField_units: fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { fdlen += airStrlen(nrrd->axis[ii].units) + 4; } *strP = (char *)calloc(fslen + fdlen, sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { strcat(*strP, " \""); if (airStrlen(nrrd->axis[ii].units)) { strcat(*strP, nrrd->axis[ii].units); } strcat(*strP, "\""); } break; /* ---- end per-axis fields ---- */ case nrrdField_min: case nrrdField_max: /* we're basically a no-op, now that these fields became meaningless */ *strP = (char *)calloc(fslen + doubleStrlen, sizeof(char)); sprintf(*strP, "%s%s: 0.0", prefix, fs); strcat(*strP, buff); break; case nrrdField_old_min: *strP = (char *)calloc(fslen + doubleStrlen, sizeof(char)); sprintf(*strP, "%s%s: ", prefix, fs); airSinglePrintf(NULL, buff, "%g", nrrd->oldMin); strcat(*strP, buff); break; case nrrdField_old_max: *strP = (char *)calloc(fslen + doubleStrlen, sizeof(char)); sprintf(*strP, "%s%s: ", prefix, fs); airSinglePrintf(NULL, buff, "%g", nrrd->oldMax); strcat(*strP, buff); break; case nrrdField_endian: if (airEndianUnknown != nio->endian) { /* we know a specific endianness because either it was recorded as part of "unu make -h", or it was set (and data was possibly altered) as part of "unu save" */ endi = nio->endian; } else { /* we record our current architecture's endian because we're going to writing out data */ endi = AIR_ENDIAN; } *strP = (char *)calloc(fslen + strlen(airEnumStr(airEndian, endi)), sizeof(char)); sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(airEndian, endi)); break; case nrrdField_encoding: *strP = (char *)calloc(fslen + strlen(nio->encoding->name), sizeof(char)); sprintf(*strP, "%s%s: %s", prefix, fs, nio->encoding->name); break; case nrrdField_line_skip: *strP = (char *)calloc(fslen + uintStrlen, sizeof(char)); sprintf(*strP, "%s%s: %d", prefix, fs, nio->lineSkip); break; case nrrdField_byte_skip: *strP = (char *)calloc(fslen + uintStrlen, sizeof(char)); sprintf(*strP, "%s%s: %d", prefix, fs, nio->byteSkip); break; case nrrdField_sample_units: airOneLinify(nrrd->sampleUnits); *strP = (char *)calloc(fslen + strlen(nrrd->sampleUnits), sizeof(char)); sprintf(*strP, "%s%s: \"%s\"", prefix, fs, nrrd->sampleUnits); break; case nrrdField_space_units: fdlen = 0; for (ii=0; ii<nrrd->spaceDim; ii++) { fdlen += airStrlen(nrrd->spaceUnits[ii]) + 4; } *strP = (char *)calloc(fslen + fdlen, sizeof(char)); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->spaceDim; ii++) { strcat(*strP, " \""); if (airStrlen(nrrd->spaceUnits[ii])) { strcat(*strP, nrrd->spaceUnits[ii]); } strcat(*strP, "\""); } break; case nrrdField_space_origin: *strP = (char *)calloc(fslen + nrrd->spaceDim*(doubleStrlen + strlen("(,) ")), sizeof(char)); sprintf(*strP, "%s%s: ", prefix, fs); _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, nrrd->spaceOrigin); break; case nrrdField_measurement_frame: *strP = (char *)calloc(fslen + (nrrd->spaceDim* nrrd->spaceDim*(doubleStrlen + strlen("(,) "))), sizeof(char)); sprintf(*strP, "%s%s: ", prefix, fs); for (dd=0; dd<nrrd->spaceDim; dd++) { for (ii=0; ii<nrrd->spaceDim; ii++) { colvec[ii] = nrrd->measurementFrame[dd][ii]; } _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, colvec); if (dd < nrrd->spaceDim-1) { strcat(*strP, " "); } } break; case nrrdField_data_file: /* NOTE: this comes last (nrrdField_data_file is the highest-valued member of the nrrdField* enum) because the "LIST" form of the data file specification requires that the following lines be the filenames */ /* error checking elsewhere: assumes there is data file info */ if (nio->dataFNFormat) { *strP = (char *)calloc(fslen + strlen(nio->dataFNFormat) + 4*uintStrlen, sizeof(char)); if (nio->dataFileDim == nrrd->dim-1) { sprintf(*strP, "%s%s: %s %d %d %d", prefix, fs, nio->dataFNFormat, nio->dataFNMin, nio->dataFNMax, nio->dataFNStep); } else { sprintf(*strP, "%s%s: %s %d %d %d %d", prefix, fs, nio->dataFNFormat, nio->dataFNMin, nio->dataFNMax, nio->dataFNStep, nio->dataFileDim); } } else if (nio->dataFNArr->len > 1) { maxl = 0; for (ii=0; ii<nio->dataFNArr->len; ii++) { maxl = AIR_MAX(maxl, (int)strlen(nio->dataFN[ii])); } *strP = (char *)calloc(fslen + strlen(NRRD_LIST_FLAG) + uintStrlen + nio->dataFNArr->len * (maxl + 1), sizeof(char)); fnb = (char *)calloc(fslen + strlen(NRRD_LIST_FLAG) + uintStrlen + maxl + 1, sizeof(char)); if (nio->dataFileDim == nrrd->dim-1) { sprintf(*strP, "%s%s: LIST\n", prefix, fs); } else { sprintf(*strP, "%s%s: LIST %d\n", prefix, fs, nio->dataFileDim); } for (ii=0; ii<nio->dataFNArr->len; ii++) { sprintf(fnb, "%s%s", nio->dataFN[ii], ii<nio->dataFNArr->len-1 ? "\n" : ""); strcat(*strP, fnb); } free(fnb); } else { /* there is some ambiguity between a "LIST" of length one, and a single explicit data filename, but that's harmless */ *strP = (char *)calloc(fslen + strlen("./") + strlen(nio->dataFN[0]) + 1, sizeof(char)); sprintf(*strP, "%s%s: %s%s", prefix, fs, /* this is a favor to older readers that can deal with this NRRD file because its being saved in a NRRD0003 (or below) version, so we don't want to confuse them by not having the old explicit header-relative flag */ (_nrrdFormatNRRD_whichVersion(nrrd, nio) < 4 ? "./" : ""), nio->dataFN[0]); } break; default: fprintf(stderr, "%s: CONFUSION: field %d unrecognized\n", me, field); break; } return; }
/* ** _nrrdSprintFieldInfo ** ** this prints "<prefix><field>: <info>" into *strP (after allocating it for ** big enough, usually with a stupidly big margin of error), in a form ** suitable to be written to NRRD or other image headers. This will always ** print something (for valid inputs), even stupid <info>s like ** "(unknown endian)". It is up to the caller to decide which fields ** are worth writing, via _nrrdFieldInteresting(). ** ** NOTE: some of these fields make sense in non-NRRD files (e.g. all ** the per-axis information), but many only make sense in NRRD files. ** This is just one example of NRRD-format-specific stuff that is not ** in formatNRRD.c */ void _nrrdSprintFieldInfo(char **strP, const char *prefix, const Nrrd *nrrd, NrrdIoState *nio, int field) { static const char me[]="_nrrdSprintFieldInfo"; char buff[AIR_STRLEN_MED], *fnb, stmp[AIR_STRLEN_SMALL], *strtmp=NULL; double colvec[NRRD_SPACE_DIM_MAX]; const char *fs; unsigned int ii, dd, uintStrlen = 11, size_tStrlen = 33, doubleStrlen = 513; size_t fslen, fdlen, maxl; int endi; if (!( strP && prefix && nrrd && AIR_IN_CL(1, nrrd->dim, NRRD_DIM_MAX) && AIR_IN_OP(nrrdField_unknown, field, nrrdField_last) )) { return; } /* As of Sun Dec 2 01:57:48 CST 2012 (revision 5832) the only places where this function is called is when it has been guarded by "if (_nrrdFieldInteresting())" (except for in formatText.c when its called on the dimension field, which is always interesting). So, the following: if (!_nrrdFieldInteresting(nrrd, nio, field)) { *strP = airStrdup(""); } was redundant and confusingly created the appearance of a memory leak waiting to happen. We now let the default switch statement set *strP to NULL (all the other cases set it), to smoke out errors in how this function is called */ fs = airEnumStr(nrrdField, field); fslen = strlen(prefix) + strlen(fs) + strlen(": ") + 1; switch (field) { case nrrdField_comment: case nrrdField_keyvalue: fprintf(stderr, "%s: CONFUSION: why are you calling me on \"%s\"?\n", me, airEnumStr(nrrdField, nrrdField_comment)); *strP = airStrdup(""); break; case nrrdField_content: strtmp = airOneLinify(airStrdup(nrrd->content)); *strP = AIR_CALLOC(fslen + strlen(strtmp), char); sprintf(*strP, "%s%s: %s", prefix, fs, strtmp); airFree(strtmp); strtmp = NULL; break; case nrrdField_number: *strP = AIR_CALLOC(fslen + size_tStrlen, char); sprintf(*strP, "%s%s: %s", prefix, fs, airSprintSize_t(stmp, nrrdElementNumber(nrrd))); break; case nrrdField_type: *strP = AIR_CALLOC(fslen + strlen(airEnumStr(nrrdType, nrrd->type)), char); sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdType, nrrd->type)); break; case nrrdField_block_size: *strP = AIR_CALLOC(fslen + size_tStrlen, char); sprintf(*strP, "%s%s: %s", prefix, fs, airSprintSize_t(stmp, nrrd->blockSize)); break; case nrrdField_dimension: *strP = AIR_CALLOC(fslen + uintStrlen, char); sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->dim); break; case nrrdField_space: *strP = AIR_CALLOC(fslen + strlen(airEnumStr(nrrdSpace, nrrd->space)), char); sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(nrrdSpace, nrrd->space)); break; case nrrdField_space_dimension: *strP = AIR_CALLOC(fslen + uintStrlen, char); sprintf(*strP, "%s%s: %d", prefix, fs, nrrd->spaceDim); break; /* ---- begin per-axis fields ---- */ case nrrdField_sizes: *strP = AIR_CALLOC(fslen + nrrd->dim*(size_tStrlen + 1), char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { sprintf(buff, " %s", airSprintSize_t(stmp, nrrd->axis[ii].size)); strcat(*strP, buff); } break; case nrrdField_spacings: *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].spacing); strcat(*strP, buff); } break; case nrrdField_thicknesses: *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].thickness); strcat(*strP, buff); } break; case nrrdField_axis_mins: *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].min); strcat(*strP, buff); } break; case nrrdField_axis_maxs: *strP = AIR_CALLOC(fslen + nrrd->dim*(doubleStrlen + 1), char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { airSinglePrintf(NULL, buff, " %.17g", nrrd->axis[ii].max); strcat(*strP, buff); } break; case nrrdField_space_directions: *strP = AIR_CALLOC(fslen + nrrd->dim*nrrd->spaceDim*(doubleStrlen + strlen("(,) ")), char); sprintf(*strP, "%s%s: ", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, nrrd->axis[ii].spaceDirection); if (ii < nrrd->dim-1) { strcat(*strP, " "); } } break; case nrrdField_centers: fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { fdlen += 1 + airStrlen(nrrd->axis[ii].center ? airEnumStr(nrrdCenter, nrrd->axis[ii].center) : NRRD_UNKNOWN); } *strP = AIR_CALLOC(fslen + fdlen, char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { sprintf(buff, " %s", (nrrd->axis[ii].center ? airEnumStr(nrrdCenter, nrrd->axis[ii].center) : NRRD_UNKNOWN)); strcat(*strP, buff); } break; case nrrdField_kinds: fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { fdlen += 1 + airStrlen(nrrd->axis[ii].kind ? airEnumStr(nrrdKind, nrrd->axis[ii].kind) : NRRD_UNKNOWN); } *strP = AIR_CALLOC(fslen + fdlen, char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { sprintf(buff, " %s", (nrrd->axis[ii].kind ? airEnumStr(nrrdKind, nrrd->axis[ii].kind) : NRRD_UNKNOWN)); strcat(*strP, buff); } break; case nrrdField_labels: case nrrdField_units: #define LABEL_OR_UNITS (nrrdField_labels == field \ ? nrrd->axis[ii].label \ : nrrd->axis[ii].units) fdlen = 0; for (ii=0; ii<nrrd->dim; ii++) { /* The "2*" is because at worst every character needs escaping. The "+ 3" for the |" "| between each part */ fdlen += 2*airStrlen(LABEL_OR_UNITS) + 3; } fdlen += 1; /* for '\0' */ *strP = AIR_CALLOC(fslen + fdlen, char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->dim; ii++) { strcat(*strP, " \""); if (airStrlen(nrrd->axis[ii].label)) { _nrrdWriteEscaped(NULL, *strP, LABEL_OR_UNITS, "\"", _NRRD_WHITESPACE_NOTAB); } strcat(*strP, "\""); } #undef LABEL_OR_UNITS break; /* ---- end per-axis fields ---- */ case nrrdField_min: case nrrdField_max: /* we're basically a no-op, now that these fields became meaningless */ *strP = AIR_CALLOC(fslen + doubleStrlen, char); sprintf(*strP, "%s%s: 0.0", prefix, fs); strcat(*strP, buff); break; case nrrdField_old_min: *strP = AIR_CALLOC(fslen + doubleStrlen, char); sprintf(*strP, "%s%s: ", prefix, fs); airSinglePrintf(NULL, buff, "%.17g", nrrd->oldMin); strcat(*strP, buff); break; case nrrdField_old_max: *strP = AIR_CALLOC(fslen + doubleStrlen, char); sprintf(*strP, "%s%s: ", prefix, fs); airSinglePrintf(NULL, buff, "%.17g", nrrd->oldMax); strcat(*strP, buff); break; case nrrdField_endian: if (airEndianUnknown != nio->endian) { /* we know a specific endianness because either it was recorded as part of "unu make -h", or it was set (and data was possibly altered) as part of "unu save" */ endi = nio->endian; } else { /* we record our current architecture's endian because we're going to writing out data */ endi = airMyEndian(); } *strP = AIR_CALLOC(fslen + strlen(airEnumStr(airEndian, endi)), char); sprintf(*strP, "%s%s: %s", prefix, fs, airEnumStr(airEndian, endi)); break; case nrrdField_encoding: *strP = AIR_CALLOC(fslen + strlen(nio->encoding->name), char); sprintf(*strP, "%s%s: %s", prefix, fs, nio->encoding->name); break; case nrrdField_line_skip: *strP = AIR_CALLOC(fslen + uintStrlen, char); sprintf(*strP, "%s%s: %d", prefix, fs, nio->lineSkip); break; case nrrdField_byte_skip: *strP = AIR_CALLOC(fslen + uintStrlen, char); sprintf(*strP, "%s%s: %ld", prefix, fs, nio->byteSkip); break; case nrrdField_sample_units: strtmp = airOneLinify(airStrdup(nrrd->sampleUnits)); *strP = AIR_CALLOC(fslen + strlen(strtmp), char); sprintf(*strP, "%s%s: \"%s\"", prefix, fs, strtmp); airFree(strtmp); strtmp = NULL; break; case nrrdField_space_units: fdlen = 0; for (ii=0; ii<nrrd->spaceDim; ii++) { /* The "2*" is because at worst every character needs escaping. See note in formatNRRD.c about how even though its not part of the format, we have worst-case scenario of having to escape a space units which is nothing but ". The "+ 3" for the |" "| between each part */ fdlen += 2*airStrlen(nrrd->spaceUnits[ii]) + 3; } fdlen += 1; /* for '\0' */ *strP = AIR_CALLOC(fslen + fdlen, char); sprintf(*strP, "%s%s:", prefix, fs); for (ii=0; ii<nrrd->spaceDim; ii++) { strcat(*strP, " \""); if (airStrlen(nrrd->spaceUnits[ii])) { _nrrdWriteEscaped(NULL, *strP, nrrd->spaceUnits[ii], "\"", _NRRD_WHITESPACE_NOTAB); } strcat(*strP, "\""); } break; case nrrdField_space_origin: *strP = AIR_CALLOC(fslen + nrrd->spaceDim*(doubleStrlen + strlen("(,) ")), char); sprintf(*strP, "%s%s: ", prefix, fs); _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, nrrd->spaceOrigin); break; case nrrdField_measurement_frame: *strP = AIR_CALLOC(fslen + (nrrd->spaceDim* nrrd->spaceDim*(doubleStrlen + strlen("(,) "))), char); sprintf(*strP, "%s%s: ", prefix, fs); for (dd=0; dd<nrrd->spaceDim; dd++) { for (ii=0; ii<nrrd->spaceDim; ii++) { colvec[ii] = nrrd->measurementFrame[dd][ii]; } _nrrdStrcatSpaceVector(*strP, nrrd->spaceDim, colvec); if (dd < nrrd->spaceDim-1) { strcat(*strP, " "); } } break; case nrrdField_data_file: /* NOTE: this comes last (nrrdField_data_file is the highest-valued member of the nrrdField* enum) because the "LIST" form of the data file specification requires that the following lines be the filenames */ /* error checking elsewhere: assumes there is data file info */ if (nio->dataFNFormat) { *strP = AIR_CALLOC(fslen + strlen(nio->dataFNFormat) + 4*uintStrlen, char); if (nio->dataFileDim == nrrd->dim-1) { sprintf(*strP, "%s%s: %s %d %d %d", prefix, fs, nio->dataFNFormat, nio->dataFNMin, nio->dataFNMax, nio->dataFNStep); } else { sprintf(*strP, "%s%s: %s %d %d %d %u", prefix, fs, nio->dataFNFormat, nio->dataFNMin, nio->dataFNMax, nio->dataFNStep, nio->dataFileDim); } } else if (nio->dataFNArr->len > 1) {
int _nrrdSprintDB(char *s, const DB *v) { return airSinglePrintf(NULL, s, "%.17g", *v); }
/* HEY: sizeof(float) and sizeof(double) assumed here, since we're basing "8" and "17" on 6 == FLT_DIG and 15 == DBL_DIG, which are digits of precision for floats and doubles, respectively */ int _nrrdSprintFL(char *s, const FL *v) { return airSinglePrintf(NULL, s, "%.8g", (double)(*v)); }
static int _nrrdFprintDB(FILE *f, const DB *v) { return airSinglePrintf(f, NULL, "%.17g", *v); }
static int _nrrdFprintFL(FILE *f, const FL *v) { return airSinglePrintf(f, NULL, "%.8g", (double)(*v)); }