Example #1
0
/*
** _nrrdKeyValueWrite
**
** writes a given key and value to a file, starting with the given
** prefix (if non-NULL), and ending with "\n"
*/
int
_nrrdKeyValueWrite(FILE *file, char **stringP, const char *prefix,
                   const char *key, const char *value) {

  if (!( (file || stringP) && key && value )) {
    return 1;
  }
  if (stringP) {
    /* 2*strlen() because at worst all characters will be escaped */
    *stringP = AIR_CALLOC(airStrlen(prefix) + 2*airStrlen(key)
                          + strlen(":=") + 2*airStrlen(value)
                          + strlen("\n") + 1, char);
    /* HEY error checking? */
  }
  if (prefix) {
    if (file) {
      fprintf(file, "%s", prefix);
    } else {
      strcat(*stringP, prefix);
    }
  }
  if (file) {
    _nrrdWriteEscaped(file, NULL, key, "\n\\", _NRRD_WHITESPACE_NOTAB);
    fprintf(file, ":=");
    _nrrdWriteEscaped(file, NULL, value, "\n\\", _NRRD_WHITESPACE_NOTAB);
    fprintf(file, "\n");
  } else {
    _nrrdWriteEscaped(NULL, *stringP, key, "\n\\", _NRRD_WHITESPACE_NOTAB);
    strcat(*stringP, ":=");
    _nrrdWriteEscaped(NULL, *stringP, value, "\n\\", _NRRD_WHITESPACE_NOTAB);
    strcat(*stringP, "\n");
  }
  return 0;
}
Example #2
0
/*
** _nrrdKeyValueWrite
**
** writes a given key and value to a file, starting with the given
** prefix (if non-NULL), and ending with "\n"
*/
int
_nrrdKeyValueWrite(FILE *file, char **stringP, const char *prefix, 
                   const char *key, const char *value) {
  
  if (!( (file || stringP) && key && value )) {
    return 1;
  }
  if (stringP) {
    /* 2*strlen() because at worst all characters will be escaped */
    *stringP = (char *)malloc(airStrlen(prefix) + 2*airStrlen(key)
                              + strlen(":=") + 2*airStrlen(value)
                              + strlen("\n") + 1);
    /* HEY error checking */
    strcpy(*stringP, "");
  }
  if (prefix) {
    if (file) {
      fprintf(file, "%s", prefix);
    } else {
      strcat(*stringP, prefix);
    }
  }
  if (file) {
    _nrrdWriteEscaped(file, NULL, key);
    fprintf(file, ":=");
    _nrrdWriteEscaped(file, NULL, value);
    fprintf(file, "\n");
  } else {
    _nrrdWriteEscaped(NULL, *stringP, key);
    strcat(*stringP, ":=");
    _nrrdWriteEscaped(NULL, *stringP, value);
    strcat(*stringP, "\n");
  }
  return 0;
}
/*
** _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) {