char *
_nrrdGetQuotedString(char **hP, int useBiff) {
  char me[]="_nrrdGetQuotedString", err[BIFF_STRLEN], *h, *buff, *ret;
  airArray *buffArr;
  int pos;
  _chpu uu;
  
  h = *hP;
  /* skip past space */
  /* printf("!%s: h |%s|\n", me, h);*/
  h += strspn(h, _nrrdFieldSep);
  /* printf("!%s: h |%s|\n", me, h);*/

  /* make sure we have something */
  if (!*h) {
    sprintf(err, "%s: hit end of string before seeing opening \"", me);
    biffMaybeAdd(NRRD, err, useBiff); return NULL;
  }
  /* make sure we have a starting quote */
  if ('"' != *h) {
    sprintf(err, "%s: didn't start with \"", me);
    biffMaybeAdd(NRRD, err, useBiff); return NULL;
  }
  h++;
    
  /* parse string until end quote */
  buff = NULL;
  uu.c = &buff;
  buffArr = airArrayNew(uu.v, NULL, sizeof(char), 2);
  if (!buffArr) {
    sprintf(err, "%s: couldn't create airArray", me);
      biffMaybeAdd(NRRD, err, useBiff); return NULL;
  }
  pos = airArrayLenIncr(buffArr, 1);  /* pos should get 0 */
  while (h[pos]) {
    /* printf("!%s: h+%d |%s|\n", me, pos, h+pos); */
    if ('\"' == h[pos]) {
      break;
    }
    if ('\\' == h[pos] && '\"' == h[pos+1]) {
      h += 1;
    }
    buff[pos] = h[pos];
    pos = airArrayLenIncr(buffArr, 1);
  }
  if ('\"' != h[pos]) {
    sprintf(err, "%s: didn't see ending \" soon enough", me);
    biffMaybeAdd(NRRD, err, useBiff); return NULL;
  }
  h += pos + 1;
  buff[pos] = 0;

  ret = airStrdup(buff);
  airArrayNuke(buffArr);
  *hP = h;
  
  return ret;
}
Ejemplo n.º 2
0
/*
******** nrrdKeyValueAdd
**
** This will COPY the given strings, and so does not depend on
** them existing past the return of this function
**
** NOTE: Despite what might be most logical, there is no effort made
** here to cleanup key or value, including any escaping or filtering
** that might be warranted for white space other than \n
**
** does NOT use BIFF
*/
int
nrrdKeyValueAdd(Nrrd *nrrd, const char *key, const char *value) {
  unsigned int ki;
  int found;

  if (!( nrrd && key && value )) {
    /* got NULL pointer */
    return 1;
  }
  if (!strlen(key)) {
    /* reject empty keys */
    return 1;
  }
  ki = _kvpIdxFind(nrrd, key, &found);
  if (found) {
    /* over-writing value for an existing key, so have to free old value */
    airFree(nrrd->kvp[1 + 2*ki]);
    nrrd->kvp[1 + 2*ki] = airStrdup(value);
  } else {
    /* adding value for a new key */
    ki = airArrayLenIncr(nrrd->kvpArr, 1);
    nrrd->kvp[0 + 2*ki] = airStrdup(key);
    nrrd->kvp[1 + 2*ki] = airStrdup(value);
  }
  return 0;
}
Ejemplo n.º 3
0
/*
** _bmsgAdd()
**
** if given key already has a biffMsg in _bmsg, returns that.
** otherise, adds a new biffMsg for given key to _bmsg, and returns it
** panics and exit(1)s if there is a problem
*/
biffMsg *
_bmsgAdd(const char *key) {
  static const char me[]="[biff] _bmsgAdd";
  size_t ii;
  biffMsg *msg;

  msg = NULL;
  /* find if key exists already */
  for (ii=0; ii<_bmsgNum; ii++) {
    if (!strcmp(key, _bmsg[ii]->key)) {
      msg = _bmsg[ii];
      break;
    }
  }
  if (!msg) {
    /* have to add new biffMsg */
    ii = airArrayLenIncr(_bmsgArr, 1);
    if (!_bmsg) {
      fprintf(stderr, "%s: PANIC: couldn't accomodate one more key\n", me);
      exit(1);
    }
    msg = _bmsg[ii] = biffMsgNew(key);
  }
  return msg;
}
Ejemplo n.º 4
0
/*
******** biffDone()
**
** frees everything associated with given key, and shrinks list of keys,
** and calls _bmsgFinish() if there are no keys left
*/
void
biffDone(const char *key) {
  static const char me[]="biffDone";
  unsigned int idx;
  biffMsg *msg;

  _bmsgStart();
  
  msg = _bmsgFind(key);
  if (!msg) {
    fprintf(stderr, "%s: WARNING: no information for key \"%s\"\n", me, key);
    return;
  }
  idx = _bmsgFindIdx(msg);
  biffMsgNix(msg);
  if (_bmsgNum > 1) {
    /* if we have more than one key in action, move the last biffMsg
       to the position that was just cleared up */
    _bmsg[idx] = _bmsg[_bmsgNum-1];
  }
  airArrayLenIncr(_bmsgArr, -1);
  /* if that was the last key, close shop */
  if (!_bmsgArr->len) {
    _bmsgFinish();
  }

  return;
}
Ejemplo n.º 5
0
/*
** except for allocation error, this always returns 0,
** to facilitate this weird idiom:
**
**   if (!(nmeasr = nrrdNew())
**       || airMopAdd(mop, nmeasr, (airMopper)nrrdNuke, airMopAlways)
**       || !(nsize = nrrdNew())
**       || airMopAdd(mop, nsize, (airMopper)nrrdNuke, airMopAlways)
**       || !(pair = AIR_CAST(ccpair *, calloc(pctx->CCNum, sizeof(ccpair))))
**       || airMopAdd(mop, pair, airFree, airMopAlways)) {
**
** GLK may regret this.
*/
int
airMopAdd(airArray *arr, void *ptr, airMopper mop, int when) {
  static const char me[]="airMopAdd";
  airMop *mops;
  unsigned int ii;

  if (!arr) {
    return 0;
  }

  mops = (airMop *)arr->data;
  /* first see if this is something we already set a callback for */
  for (ii=0; ii<arr->len; ii++) {
    if (mops[ii].ptr == ptr && mops[ii].mop == mop) {
      mops[ii].when = when;
      /* we're done */
      return 0;
    }
  }
  /* this is a new ptr */
  ii = airArrayLenIncr(arr, 1);
  if (!arr->data) {
    fprintf(stderr, "%s: PANIC: can't re-allocate mop array\n", me);
    return 1;
  }
  mops = (airMop *)arr->data;
  mops[ii].ptr = ptr;
  mops[ii].mop = mop;
  mops[ii].when = when;
  return 0;
}
Ejemplo n.º 6
0
void
airMopAdd(airArray *arr, void *ptr, airMopper mop, int when)
{
    airMop *mops;
    unsigned int ii;

    if (!arr)
    {
        return;
    }

    mops = (airMop *)arr->data;
    /* first see if this is something we already set a callback for */
    for (ii=0; ii<arr->len; ii++)
    {
        if (mops[ii].ptr == ptr && mops[ii].mop == mop)
        {
            mops[ii].when = when;
            /* we're done */
            return;
        }
    }
    /* this is a new ptr */
    ii = airArrayLenIncr(arr, 1);  /* HEY no error checking */
    mops = (airMop *)arr->data;
    mops[ii].ptr = ptr;
    mops[ii].mop = mop;
    mops[ii].when = when;
    return;
}
Ejemplo n.º 7
0
int
tkwbReadFileToString(char **strP, int *hitEOF, FILE *file, char *stop) {
    char **all, line[AIR_STRLEN_HUGE];
    airArray *allArr;
    unsigned int allLen;
    unsigned int lineLen, lineIdx, totalLen;
    _tkwbU uu;

    uu.pc = &all;
    allArr = airArrayNew(uu.v, &allLen, sizeof(char*), tkwbArrayIncr);
    airArrayPointerCB(allArr, airNull, airFree);
    lineLen = airOneLine(file, line, AIR_STRLEN_HUGE);
    totalLen = 0;
    while (lineLen && (!( airStrlen(stop) && !strcmp(line, stop) )) ) {
        lineIdx = airArrayLenIncr(allArr, 1); /* HEY error checking */
        all[lineIdx] = (char *)calloc(strlen(line) + strlen("\n") + 1,
                                      sizeof(char));
        sprintf(all[lineIdx], "%s\n", line);
        totalLen += strlen(line) + 1;
        lineLen = airOneLine(file, line, AIR_STRLEN_HUGE);
    }
    if (hitEOF) {
        *hitEOF = !lineLen;
    }

    *strP = (char*)calloc(totalLen+1, sizeof(char));
    strcpy(*strP, "");
    for (lineIdx=0; lineIdx<allLen; lineIdx++) {
        strcat(*strP, all[lineIdx]);
    }

    airArrayNuke(allArr);
    return 0;
}
Ejemplo n.º 8
0
/*
** _biffAddKey()
**
** adds a key to _biffErr, and returns a pointer to the new entry
** assumes that given key does NOT appear in current list.
** panics and exit(1)s if there is a problem
*/
_biffEntry *
_biffAddKey(const char *key) {
  char me[]="_biffAddKey";
  int ii, newIdx;
  _biffEntry *ent;

  /* find index of new key */
  for (ii=0; ii<(int)_biffNum; ii++) {
    if (strcmp(key, _biffErr[ii]->key) < 0) {
      /* we've hit the one which comes after the new key */
      break;
    }
  }
  /* if the for loop was never broken, _biffNum is the correct new index */
  newIdx = ii;
  /* printf("HEY: index(new key \"%s\") = %d\n", key, ii); */

  airArrayLenIncr(_biffAA, 1);
  if (!_biffAA->data) {
    fprintf(stderr, "%s: PANIC: couldn't accomodate one more key\n", me);
    exit(1);
  }

  /* _biffNum is now one bigger */
  for (ii=_biffNum-2; ii>=newIdx; ii--) {
    _biffErr[ii+1] = _biffErr[ii];
  }
  ent = _biffErr[newIdx] = _biffNewEntry(key);

  return ent;
}
Ejemplo n.º 9
0
/*
** _biffAddErr()
**
** adds a given message to the given entry.  The message is processed to
** convert all whitespace into ' ', and to eliminate whitespace at the
** end of the message.
** panics and exit(1)s if there is a problem
*/
void
_biffAddErr(_biffEntry *e, const char *err) {
  char *buf, me[]="_biffAddErr";
  size_t ii, len;

  /* printf("%s: HEY(before): err[%s]->num = %d\n", me, e->key, e->num); */
  airArrayLenIncr(e->AA, 1);
  if (!e->AA->data) {
    fprintf(stderr, "%s: PANIC: couldn't add message for key %s\n",
            me, e->key);
    exit(1);
  }
  /* printf("%s: HEY(after): err[%s]->num = %d\n", me, e->key, e->num); */
  buf = airStrdup(err);
  len = strlen(buf);
  for (ii=0; ii<=len-1; ii++) {
    if (isspace(buf[ii])) {
      buf[ii] = ' ';
    }
  }
  ii = len-1;
  while (isspace(buf[ii])) {
    buf[ii--] = 0;
  }
  /* printf("%s: HEY(after): err[%s]->num = %d\n", me, e->key, e->num); */
  /* printf("%s: HEY: err[%s][%d] now \"%s\"\n", me, e->key, e->num-1, buf); */
  e->err[e->num-1] = buf;
  return;
}
Ejemplo n.º 10
0
/*
** the bin loses track of the point, caller responsible for ownership,
** even though caller never identifies it by pointer, which is weird
*/
void
_pullBinPointRemove(pullContext *pctx, pullBin *bin, int loseIdx) {

  AIR_UNUSED(pctx);
  bin->point[loseIdx] = bin->point[bin->pointNum-1];
  airArrayLenIncr(bin->pointArr, -1);
  return;
}
Ejemplo n.º 11
0
/*
** this makes the bin the owner of the point
*/
void
_pullBinPointAdd(pullContext *pctx, pullBin *bin, pullPoint *point) {
  int pntI;

  AIR_UNUSED(pctx);
  pntI = airArrayLenIncr(bin->pointArr, 1);
  bin->point[pntI] = point;
  return;
}
Ejemplo n.º 12
0
/* Tries to increase or decrease the length of h. returns 0 upon success. */
static int heapLenIncr (airHeap *h, int delta) {
  unsigned int oldlen=h->key_a->len;
  unsigned int newlen=oldlen+delta;
  if (delta==0)
    return 0;
  airArrayLenIncr(h->key_a, delta);
  if (h->data_a!=NULL) airArrayLenIncr(h->data_a, delta);
  airArrayLenIncr(h->idx_a, delta);
  airArrayLenIncr(h->invidx_a, delta);
  if (h->key_a->len<newlen || (h->data_a!=NULL && h->data_a->len<newlen) ||
      h->idx_a->len<newlen || h->invidx_a->len<newlen) {
    /* Error. Try to undo changes and return error code. */
    if (h->key_a->len>oldlen)    airArrayLenSet(h->key_a, oldlen);
    if (h->data_a!=NULL && h->data_a->len>oldlen)
      airArrayLenSet(h->data_a, oldlen);
    if (h->idx_a->len>oldlen)    airArrayLenSet(h->idx_a, oldlen);
    if (h->invidx_a->len>oldlen) airArrayLenSet(h->invidx_a, oldlen);
    return 1;
  }
  return 0;
}
Ejemplo n.º 13
0
void
_echoSceneLightAdd(echoScene *scene, echoObject *obj) {
  unsigned int idx;
  
  for (idx=0; idx<scene->lightArr->len; idx++) {
    if (obj == scene->light[idx]) {
      break;
    }
  }
  if (scene->lightArr->len == idx) {
    idx = airArrayLenIncr(scene->lightArr, 1);
    scene->light[idx] = obj;
  }
}
Ejemplo n.º 14
0
void
echoListAdd(echoObject *list, echoObject *child) {
  int idx;
  
  if (!( list && child &&
         (echoTypeList == list->type ||
          echoTypeAABBox == list->type) ))
    return;
  
  idx = airArrayLenIncr(LIST(list)->objArr, 1);
  LIST(list)->obj[idx] = child;

  return;
}
Ejemplo n.º 15
0
void
_echoSceneNrrdAdd(echoScene *scene, Nrrd *nrrd) {
  unsigned int idx;
  
  for (idx=0; idx<scene->nrrdArr->len; idx++) {
    if (nrrd == scene->nrrd[idx]) {
      break;
    }
    if (scene->nrrdArr->len == idx) {
      idx = airArrayLenIncr(scene->nrrdArr, 1);
      scene->nrrd[idx] = nrrd;
    }
  }
}
Ejemplo n.º 16
0
/*
******** nrrdCommentAdd()
**
** Adds a given string to the list of comments
** Leading spaces (' ') and comment chars ('#') are not included.
**
** This function does NOT use biff.
*/
int
nrrdCommentAdd(Nrrd *nrrd, const char *_str)
{
  char /* me[]="nrrdCommentAdd", err[512], */ *str;
  int i;

  if (!(nrrd && _str))
  {
    /*
    sprintf(err, "%s: got NULL pointer", me);
    biffMaybeAdd(NRRD, err, useBiff);
    */
    return 1;
  }
  _str += strspn(_str, " #");
  if (!strlen(_str))
  {
    /* we don't bother adding comments with no length */
    return 0;
  }
  if (!strcmp(_str, _nrrdFormatURLLine0)
      || !strcmp(_str, _nrrdFormatURLLine1))
  {
    /* sneaky hack: don't store the format URL comment lines */
    return 0;
  }
  str = airStrdup(_str);
  if (!str)
  {
    /*
    sprintf(err, "%s: couldn't strdup given string", me);
    biffMaybeAdd(NRRD, err, useBiff);
    */
    return 1;
  }
  /* clean out carraige returns that would screw up reader */
  airOneLinify(str);
  i = airArrayLenIncr(nrrd->cmtArr, 1);
  if (!nrrd->cmtArr->data)
  {
    /*
    sprintf(err, "%s: couldn't lengthen comment array", me);
    biffMaybeAdd(NRRD, err, useBiff);
    */
    return 1;
  }
  nrrd->cmt[i] = str;
  return 0;
}
Ejemplo n.º 17
0
/*
******** nrrdKeyValueAdd
**
** This will COPY the given strings, and so does not depend on
** them existing past the return of this function
*/
int
nrrdKeyValueAdd(Nrrd *nrrd, const char *key, const char *value) {
  int ki;

  if (!( nrrd && key && value )) {
    /* got NULL pointer */
    return 1;
  }
  if (!strlen(key)) {
    /* reject empty keys */
    return 1;
  }
  if (-1 != (ki = _nrrdKeyValueIdxFind(nrrd, key))) {
    nrrd->kvp[1 + 2*ki] = (char *)airFree(nrrd->kvp[1 + 2*ki]);
    nrrd->kvp[1 + 2*ki] = airStrdup(value);
  } else {
    ki = airArrayLenIncr(nrrd->kvpArr, 1);
    nrrd->kvp[0 + 2*ki] = airStrdup(key);
    nrrd->kvp[1 + 2*ki] = airStrdup(value);
  }

  return 0;
}
Ejemplo n.º 18
0
int
nrrdKeyValueErase(Nrrd *nrrd, const char *key) {
  unsigned int nk, ki;
  int found;

  if (!( nrrd && key )) {
    /* got NULL pointer */
    return 1;
  }
  ki = _kvpIdxFind(nrrd, key, &found);
  if (!found) {
    return 0;
  }
  nrrd->kvp[0 + 2*ki] = (char *)airFree(nrrd->kvp[0 + 2*ki]);
  nrrd->kvp[1 + 2*ki] = (char *)airFree(nrrd->kvp[1 + 2*ki]);
  nk = nrrd->kvpArr->len;
  for (; ki<nk-1; ki++) {
    nrrd->kvp[0 + 2*ki] = nrrd->kvp[0 + 2*(ki+1)];
    nrrd->kvp[1 + 2*ki] = nrrd->kvp[1 + 2*(ki+1)];
  }
  airArrayLenIncr(nrrd->kvpArr, -1);

  return 0;
}
Ejemplo n.º 19
0
/*
******** biffDone()
**
** frees everything associated with given key, and shrinks list of keys
*/
void
biffDone(const char *key) {
  char me[]="biffDone";
  int i, idx;
  _biffEntry *ent;

  _biffInit();
  _biffCheckKey(key);

  ent = _biffFindKey(key);
  if (!ent) {
    fprintf(stderr, "%s: WARNING: no information for key \"%s\"\n", me, key);
    return;
  }
  idx = _biffIdx;

  _biffNukeEntry(ent);
  for (i=idx; i<(int)_biffNum-1; i++) {
    _biffErr[i] = _biffErr[i+1];
  }
  airArrayLenIncr(_biffAA, -1);

  return;
}
Ejemplo n.º 20
0
/*
** adds a given message to the given entry.  The message is processed to
** convert all whitespace into ' ', and to eliminate whitespace at the
** end of the message.
*/
void
biffMsgAdd(biffMsg *msg, const char *err) {
  static const char me[]="biffMsgAdd";
  unsigned int idx;

  if (biffMsgNoop == msg) {
    return;
  }
  if (!( msg && err )) {
    fprintf(stderr, "%s: PANIC got NULL msg (%p) or err (%p)\n", me,
            AIR_VOIDP(msg), AIR_CVOIDP(err));
    /* exit(1); */
  }
  idx = airArrayLenIncr(msg->errArr, 1);
  if (!msg->err) {
    fprintf(stderr, "%s: PANIC: couldn't add message to %s\n", me, msg->key);
    /* exit(1); */
  }
  if (!( msg->err[idx] = airOneLinify(airStrdup(err)) )) {
    fprintf(stderr, "%s: PANIC: couldn't alloc message to %s\n", me, msg->key);
    /* exit(1); */
  }
  return;
}
Ejemplo n.º 21
0
int
nrrdKeyValueErase(Nrrd *nrrd, const char *key) {
  unsigned int nk;
  int ki;
  
  if (!( nrrd && key )) {
    /* got NULL pointer */
    return 1;
  }
  ki = _nrrdKeyValueIdxFind(nrrd, key);
  if (-1 == ki) {
    return 0;
  }
  nrrd->kvp[0 + 2*ki] = (char *)airFree(nrrd->kvp[0 + 2*ki]);
  nrrd->kvp[1 + 2*ki] = (char *)airFree(nrrd->kvp[1 + 2*ki]);
  nk = nrrd->kvpArr->len;
  for (; ki<(int)nk-1; ki++) {  /* HEY scrutize cast */
    nrrd->kvp[0 + 2*ki] = nrrd->kvp[0 + 2*(ki+1)];
    nrrd->kvp[1 + 2*ki] = nrrd->kvp[1 + 2*(ki+1)];
  }
  airArrayLenIncr(nrrd->kvpArr, -1);

  return 0;
}
Ejemplo n.º 22
0
int
_limnReadCamanim(int imgSize[2], limnCamera **keycamP, double **timeP,
                 unsigned int *numKeysP, FILE *fin) {
  char me[]="_limnReadCamanim", err[AIR_STRLEN_MED];
  char line[AIR_STRLEN_HUGE];
  unsigned int ki;
  double *tmp, *dwell, di, dn, df, fr[3], at[3], up[3], va;
  airArray *mop, *camA, *dwellA;
  
  if (!( 0 < airOneLine(fin, line, AIR_STRLEN_HUGE)
         && !strcmp(_LIMNMAGIC, line) )) {
    sprintf(err, "%s: couldn't read first line or it wasn't \"%s\"",
            me, _LIMNMAGIC);
    biffAdd(LIMN, err); return 1;
  }
  if (!( 0 < airOneLine(fin, line, AIR_STRLEN_HUGE)
         && 2 == (airStrtrans(airStrtrans(line, '{', ' '), '}', ' '),
                  sscanf(line, "imgSize %d %d", imgSize+0, imgSize+1)) )) {
    sprintf(err, "%s: couldn't read second line or it wasn't "
            "\"imgSize <sizeX> <sizeY>\"", me);
    biffAdd(LIMN, err); return 1;
  }
  
  mop = airMopNew();
  camA = airArrayNew((void **)keycamP, numKeysP, sizeof(limnCamera), 1);
  dwellA = airArrayNew((void **)&dwell, NULL, sizeof(double), 1);
  airMopAdd(mop, camA, (airMopper)airArrayNix, airMopAlways);
  airMopAdd(mop, dwellA, (airMopper)airArrayNuke, airMopAlways);

  while ( 0 < airOneLine(fin, line, AIR_STRLEN_HUGE) ) {
    airStrtrans(airStrtrans(line, '{', ' '), '}', ' ');
    ki = airArrayLenIncr(camA, 1);
    airArrayLenIncr(dwellA, 1);
    if (14 != sscanf(line, "cam.di %lg cam.at %lg %lg %lg "
                     "cam.up %lg %lg %lg cam.dn %lg cam.df %lg cam.va %lg "
                     "relDwell %lg cam.fr %lg %lg %lg",
                     &di, at+0, at+1, at+2,
                     up+0, up+1, up+2, &dn, &df, &va,
                     dwell+ki, fr+0, fr+1, fr+2)) {
      sprintf(err, "%s: trouble parsing line %d: \"%s\"", me, ki, line);
      biffAdd(LIMN, err); airMopError(mop); return 1;
    }
    (*keycamP)[ki].neer = dn;
    (*keycamP)[ki].faar = df;
    (*keycamP)[ki].dist = di;
    ELL_3V_COPY((*keycamP)[ki].from, fr);
    ELL_3V_COPY((*keycamP)[ki].at, at);
    ELL_3V_COPY((*keycamP)[ki].up, up);
    (*keycamP)[ki].fov = va;
    (*keycamP)[ki].aspect = (double)imgSize[0]/imgSize[1];
    (*keycamP)[ki].atRelative = AIR_FALSE;
    (*keycamP)[ki].orthographic = AIR_FALSE;
    (*keycamP)[ki].rightHanded = AIR_TRUE;
  }

  tmp = (double*)calloc(*numKeysP, sizeof(double));
  airMopAdd(mop, tmp, airFree, airMopAlways);
  *timeP = (double*)calloc(*numKeysP, sizeof(double));
  for (ki=0; ki<*numKeysP; ki++) {
    dwell[ki] = AIR_CLAMP(0, dwell[ki], 2);
    tmp[ki] = tan(AIR_AFFINE(-0.01, dwell[ki], 2.01, 0.0, AIR_PI/2));
  }
  (*timeP)[0] = 0;
  for (ki=1; ki<*numKeysP; ki++) {
    (*timeP)[ki] = (*timeP)[ki-1] + (tmp[ki-1] + tmp[ki])/2;
  } 
  for (ki=0; ki<*numKeysP; ki++) {
    (*timeP)[ki] /= (*timeP)[*numKeysP-1];
  }

  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 23
0
int
tkwbReadSlides(tkwbSlide ***slideP, char *filename, airArray *pmop) {
    char me[]="tkwbReadSlides", err[BIFF_STRLEN];
    FILE *file;
    airArray *mop, *slideArr;
    tkwbSlide **slide = NULL;
    char *title, *image, *text, stop[AIR_STRLEN_HUGE], line[AIR_STRLEN_HUGE];
    int slideIdx=0, hitEOF, notReally;
    unsigned int len;
    _tkwbU uu;

    mop = airMopNew();
    if (!( file = airFopen(filename, stdin, "rb") )) {
        sprintf(err, "%s: couldn't open %s: %s", me, filename, strerror(errno));
        biffAdd(TKWB, err);
        airMopError(mop);
        return 1;
    }
    airMopAdd(mop, file, (airMopper)airFclose, airMopAlways);

    len = airOneLine(file, stop, AIR_STRLEN_HUGE);
    if (!( len > 1 )) {
        sprintf(err, "%s: didn't get a stop delimiter from %s", me, filename);
        biffAdd(TKWB, err);
        airMopError(mop);
        return 1;
    }

    uu.ps = &slide;
    slideArr = airArrayNew(uu.v, NULL,
                           sizeof(tkwbSlide*), tkwbArrayIncr);
    airMopAdd(mop, slideArr, (airMopper)airArrayNix, airMopAlways);
    hitEOF = notReally = AIR_FALSE;
    while (!hitEOF) {
        slideIdx = airArrayLenIncr(slideArr, 1); /* HEY error checking */
        len = airOneLine(file, line, AIR_STRLEN_HUGE);
        if (!len) {
            /* got EOF after a division marker, that's okay */
            notReally = AIR_TRUE;
            break;
        }
        title = airStrdup(line);
        len = airOneLine(file, line, AIR_STRLEN_HUGE);
        if (!len) {
            break;
        }
        image = airStrdup(line);
        if (tkwbReadFileToString(&text, &hitEOF, file, stop)) {
            sprintf(err, "%s: couldn't read in slide %d", me, slideIdx);
            biffAdd(TKWB, err);
            airMopError(mop);
            return 1;
        }
        slide[slideIdx] = tkwbSlideNew(title, image, text);
        airMopAdd(pmop, slide[slideIdx], (airMopper)tkwbSlideNix, airMopAlways);
    }
    if (!hitEOF && !notReally) {
        sprintf(err, "%s: got incomplete slide info for slide %d\n", me, slideIdx);
        biffAdd(TKWB, err);
        airMopError(mop);
        return 1;
    }
    if (!notReally) {
        slideIdx = airArrayLenIncr(slideArr, 1); /* HEY error checking */
    }
    slide[slideIdx] = NULL;

    *slideP = slide;
    airMopOkay(mop);
    return 0;
}
Ejemplo n.º 24
0
/*
******** tenFiberTraceSet
**
** slightly more flexible API for fiber tracking than tenFiberTrace
**
** EITHER: pass a non-NULL nfiber, and NULL, 0, NULL, NULL for 
** the following arguments, and things are the same as with tenFiberTrace:
** data inside the nfiber is allocated, and the tract vertices are copied
** into it, having been stored in dynamically allocated airArrays
**
** OR: pass a NULL nfiber, and a buff allocated for 3*(2*halfBuffLen + 1)
** (note the "+ 1" !!!) doubles.  The fiber tracking on each half will stop
** at halfBuffLen points. The given seedpoint will be stored in
** buff[0,1,2 + 3*halfBuffLen].  The indices for the end of the first
** tract half, and the end of the second tract half, will be set in
** *startIdxP and *endIdxP respectively.
*/
int
tenFiberTraceSet(tenFiberContext *tfx, Nrrd *nfiber,
                 double *buff, unsigned int halfBuffLen,
                 unsigned int *startIdxP, unsigned int *endIdxP,
                 double seed[3]) {
  char me[]="tenFiberTraceSet", err[BIFF_STRLEN];
  airArray *fptsArr[2];      /* airArrays of backward (0) and forward (1)
                                fiber points */
  double *fpts[2];           /* arrays storing forward and backward
                                fiber points */
  double
    tmp[3],
    iPos[3],
    currPoint[3], 
    forwDir[3],
    *fiber;                  /* array of both forward and backward points, 
                                when finished */
  int ret, whyStop, buffIdx, fptsIdx, outIdx, oldStop;
  unsigned int i;
  airArray *mop;

  if (!(tfx)) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(TEN, err); return 1;
  }
  /* HEY: a hack to preserve the state inside tenFiberContext so that
     we have fewer side effects (tfx->maxNumSteps may still be set) */
  oldStop = tfx->stop;
  if (!nfiber) {
    if (!( buff && halfBuffLen > 0 && startIdxP && startIdxP )) {
      sprintf(err, "%s: need either non-NULL nfiber or fpts buffer info", me);
      biffAdd(TEN, err); return 1;
    }
    if (tenFiberStopSet(tfx, tenFiberStopNumSteps, halfBuffLen)) {
      sprintf(err, "%s: error setting new fiber stop", me);
      biffAdd(TEN, err); return 1;
    }
  }

  /* initialize the quantities which describe the fiber halves */
  tfx->halfLen[0] = tfx->halfLen[1] = 0.0;
  tfx->numSteps[0] = tfx->numSteps[1] = 0;
  tfx->whyStop[0] = tfx->whyStop[1] = tenFiberStopUnknown;

  /* try probing once */
  if (tfx->useIndexSpace) {
    ret = gageProbe(tfx->gtx,
                    AIR_CAST(gage_t, seed[0]),
                    AIR_CAST(gage_t, seed[1]),
                    AIR_CAST(gage_t, seed[2]));
  } else {
    gageShapeWtoI(tfx->gtx->shape, tmp, seed);
    ret = gageProbe(tfx->gtx,
                    AIR_CAST(gage_t, tmp[0]),
                    AIR_CAST(gage_t, tmp[1]),
                    AIR_CAST(gage_t, tmp[2]));
  }
  if (ret) {
    sprintf(err, "%s: first gageProbe failed: %s (%d)", 
            me, tfx->gtx->errStr, tfx->gtx->errNum);
    biffAdd(TEN, err); return 1;
  }

  /* see if we're doomed */
  if ((whyStop = _tenFiberStopCheck(tfx))) {
    /* stopped immediately at seed point, but that's not an error */
    tfx->whyNowhere = whyStop;
    if (nfiber) {
      nrrdEmpty(nfiber);
    } else {
      *startIdxP = *endIdxP = 0;
    }
    return 0;
  } else {
    /* did not immediately halt */
    tfx->whyNowhere = tenFiberStopUnknown;
  }

  /* record the principal eigenvector at the seed point, which
     is needed to align the 4 intermediate steps of RK4 for the
     FIRST step of each half of the tract */
  ELL_3V_COPY(tfx->firstEvec, tfx->evec + 3*0);

  /* airMop{Error,Okay}() can safely be called on NULL */
  mop = nfiber ? airMopNew() : NULL;

  for (tfx->dir=0; tfx->dir<=1; tfx->dir++) {
    if (nfiber) {
      fptsArr[tfx->dir] = airArrayNew((void**)&(fpts[tfx->dir]), NULL, 
                                      3*sizeof(double), TEN_FIBER_INCR);
      airMopAdd(mop, fptsArr[tfx->dir], (airMopper)airArrayNuke, airMopAlways);
      buffIdx = -1;
    } else {
      fptsArr[tfx->dir] = NULL;
      fpts[tfx->dir] = NULL;
      buffIdx = halfBuffLen;
      fptsIdx = -1;
    }
    tfx->halfLen[tfx->dir] = 0;
    if (tfx->useIndexSpace) {
      ELL_3V_COPY(iPos, seed);
      gageShapeItoW(tfx->gtx->shape, tfx->wPos, iPos);
    } else {
      gageShapeWtoI(tfx->gtx->shape, iPos, seed);
      ELL_3V_COPY(tfx->wPos, seed);
    }
    ELL_3V_SET(tfx->lastDir, 0, 0, 0);
    tfx->lastDirSet = AIR_FALSE;
    for (tfx->numSteps[tfx->dir] = 0; AIR_TRUE; tfx->numSteps[tfx->dir]++) {
      if (_tenFiberProbe(tfx, tfx->wPos)) {
        /* even if gageProbe had an error OTHER than going out of bounds,
           we're not going to report it any differently here, alas */
        tfx->whyStop[tfx->dir] = tenFiberStopBounds;
        break;
      }
      if ((whyStop = _tenFiberStopCheck(tfx))) {
        if (tenFiberStopNumSteps == whyStop) {
          /* we stopped along this direction because tfx->numSteps[tfx->dir]
             exceeded tfx->maxNumSteps.  Okay.  But tfx->numSteps[tfx->dir]
             is supposed to be a record of how steps were (successfully)
             taken.  So we need to decrementing before moving on ... */
          tfx->numSteps[tfx->dir]--;
        }
        tfx->whyStop[tfx->dir] = whyStop;
        break;
      }
      if (tfx->useIndexSpace) {
        gageShapeWtoI(tfx->gtx->shape, iPos, tfx->wPos);
        ELL_3V_COPY(currPoint, iPos);
      } else {
        ELL_3V_COPY(currPoint, tfx->wPos);
      }
      if (nfiber) {
        fptsIdx = airArrayLenIncr(fptsArr[tfx->dir], 1);
        ELL_3V_COPY(fpts[tfx->dir] + 3*fptsIdx, currPoint);
      } else {
        ELL_3V_COPY(buff + 3*buffIdx, currPoint);
        /*
        fprintf(stderr, "!%s: (dir %d) saving to %d pnt %g %g %g\n", me,
                tfx->dir, buffIdx,
                currPoint[0], currPoint[1], currPoint[2]);
        */
        buffIdx += !tfx->dir ? -1 : 1;
      }
      /* forwDir is set by this to point to the next fiber point */
      if (_tenFiberIntegrate[tfx->intg](tfx, forwDir)) {
        tfx->whyStop[tfx->dir] = tenFiberStopBounds;
        break;
      }
      ELL_3V_COPY(tfx->lastDir, forwDir);
      tfx->lastDirSet = AIR_TRUE;
      ELL_3V_ADD2(tfx->wPos, tfx->wPos, forwDir);
      tfx->halfLen[tfx->dir] += ELL_3V_LEN(forwDir);
    }
  }

  if (nfiber) {
    if (nrrdMaybeAlloc_va(nfiber, nrrdTypeDouble, 2,
                          AIR_CAST(size_t, 3),
                          AIR_CAST(size_t, (fptsArr[0]->len 
                                            + fptsArr[1]->len - 1)))) {
      sprintf(err, "%s: couldn't allocate fiber nrrd", me);
      biffMove(TEN, err, NRRD); airMopError(mop); return 1;
    }
    fiber = (double*)(nfiber->data);
    outIdx = 0;
    for (i=fptsArr[0]->len-1; i>=1; i--) {
      ELL_3V_COPY(fiber + 3*outIdx, fpts[0] + 3*i);
      outIdx++;
    }
    for (i=0; i<=fptsArr[1]->len-1; i++) {
      ELL_3V_COPY(fiber + 3*outIdx, fpts[1] + 3*i);
      outIdx++;
    }
  } else {
    *startIdxP = halfBuffLen - tfx->numSteps[0];
    *endIdxP = halfBuffLen + tfx->numSteps[1];
  }

  tfx->stop = oldStop;
  airMopOkay(mop);
  return 0;
}
Ejemplo n.º 25
0
double
_energyFromPoints(pullTask *task, pullBin *bin, pullPoint *point, 
                  /* output */
                  double egradSum[4]) {
  /* char me[]="_energyFromPoints"; */
  double energySum, distSqSum, spaDistSqMax, wghtSum;
  int nopt,     /* optimiziation: we sometimes re-use neighbor lists */
    ntrue;      /* we search all possible neighbors, stored in the bins
                   (either because !nopt, or, this iter we learn true
                   subset of interacting neighbors).  This could also
                   be called "dontreuse" or something like that */
  unsigned int nidx,
    nnum;       /* how much of task->neigh[] we use */

  /* set nopt and ntrue */
  if (task->pctx->neighborTrueProb < 1) {
    nopt = AIR_TRUE;
    if (egradSum) {
      /* We allow the neighbor list optimization only when we're also asked
         to compute the energy gradient.  When we're not getting the energy
         gradient, we're being called to test the waters at possible new
         locations, in which case we can't be changing the effective particle 
         neighborhood */
      ntrue = (0 == task->pctx->iter
               || airDrandMT_r(task->rng) < task->pctx->neighborTrueProb);
    } else {
      ntrue = AIR_FALSE;
    }
  } else {
    nopt = AIR_FALSE;
    ntrue = AIR_TRUE;
  }
  /*
  fprintf(stderr, "!%s(%u), nopt = %d, ntrue = %d\n", me, point->idtag,
          nopt, ntrue);
  */
  /* set nnum and task->neigh[] */
  if (ntrue) {
    nnum = _neighBinPoints(task, bin, point);
    if (nopt) {
      airArrayLenSet(point->neighArr, 0);
    }
  } else {
    /* (nopt true) this iter we re-use existing neighbor list */
    nnum = point->neighNum;
    for (nidx=0; nidx<nnum; nidx++) {
      task->neighPoint[nidx] = point->neighPoint[nidx];
    }
  }

  /* loop through neighbor points */
  spaDistSqMax = 4*task->pctx->radiusSpace*task->pctx->radiusSpace;
  /*
  fprintf(stderr, "%s: radiusSpace = %g -> spaDistSqMax = %g\n", me,
          task->pctx->radiusSpace, spaDistSqMax);
  */
  wghtSum = 0;
  energySum = 0;
  distSqSum = 0;
  point->neighInterNum = 0;
  point->neighDist = 0.0;
  point->neighMode = 0.0;
  if (egradSum) {
    ELL_4V_SET(egradSum, 0, 0, 0, 0);
  }
  for (nidx=0; nidx<nnum; nidx++) {
    double diff[4], spaDistSq, enr, egrad[4];
    pullPoint *herPoint;
    herPoint = task->neighPoint[nidx];
    ELL_4V_SUB(diff, herPoint->pos, point->pos);
    spaDistSq = ELL_3V_DOT(diff, diff);
    /*
    fprintf(stderr, "!%s: %u:%g,%g,%g <-- %u:%g,%g,%g = sqd %g %s %g\n", me,
            point->idtag, point->pos[0], point->pos[1], point->pos[2], 
            herPoint->idtag,
            herPoint->pos[0], herPoint->pos[1], herPoint->pos[2],
            spaDistSq, spaDistSq > spaDistSqMax ? ">" : "<=", spaDistSqMax);
    */
    if (spaDistSq > spaDistSqMax) {
      continue;
    }
    if (AIR_ABS(diff[3] > task->pctx->radiusScale)) {
      continue;
    }
    enr = _energyInterParticle(task, point, herPoint, egrad);
    /*
    fprintf(stderr, "!%s: energySum = %g + %g = %g\n", me, 
            energySum, enr, energySum + enr);
    */
    energySum += enr;
    if (egradSum) {
      ELL_4V_INCR(egradSum, egrad);
      if (ELL_4V_DOT(egrad, egrad)) {
        point->neighInterNum++;
        point->neighDist = spaDistSq;
        if (task->pctx->ispec[pullInfoTangentMode]) {
          double w, m;
          m = _pullPointScalar(task->pctx, herPoint, pullInfoTangentMode,
                               NULL, NULL);
          w = 1.0/spaDistSq;
          point->neighMode += w*m;
          wghtSum += w;
        }
        if (nopt && ntrue) {
          unsigned int ii;
          ii = airArrayLenIncr(point->neighArr, 1);
          point->neighPoint[ii] = herPoint;
        }
      }
    }
  }
  
  /* finish computing things averaged over neighbors */
  if (point->neighInterNum) {
    point->neighDist = sqrt(point->neighDist/point->neighInterNum);
    point->neighMode /= wghtSum;
  } else {
    point->neighDist = -1;
    point->neighMode = AIR_NAN;
  }

  return energySum;
}
Ejemplo n.º 26
0
double
miteSample(miteThread *mtt, miteRender *mrr, miteUser *muu,
           int num, double rayT, int inside,
           double samplePosWorld[3],
           double samplePosIndex[3]) {
  static const char me[]="miteSample";
  mite_t R, G, B, A;
  double *NN;
  double NdotV, kn[3], knd[3], ref[3], len, *dbg=NULL;

  if (!inside) {
    return mtt->rayStep;
  }

  if (mtt->skip) {
    /* we have one verbose pixel, but we're not on it */
    return 0.0;
  }

  /* early ray termination */
  if (1-mtt->TT >= muu->opacNear1) {
    mtt->TT = 0.0;
    return 0.0;
  }

  /* set (fake) view based on fake from */
  if (AIR_EXISTS(muu->fakeFrom[0])) {
    ELL_3V_SUB(mtt->V, samplePosWorld, muu->fakeFrom);
    ELL_3V_NORM(mtt->V, mtt->V, len);
  }

  /* do probing at this location to determine values of everything
     that might appear in the txf domain */
  if (gageProbe(mtt->gctx,
                samplePosIndex[0],
                samplePosIndex[1],
                samplePosIndex[2])) {
    biffAddf(MITE, "%s: gage trouble: %s (%d)", me,
             mtt->gctx->errStr, mtt->gctx->errNum);
    return AIR_NAN;
  }

  if (mrr->queryMiteNonzero) {
    /* There is some optimal trade-off between slowing things down
       with too many branches on all possible checks of queryMite,
       and slowing things down with doing the work of setting them all.
       This code has not been profiled whatsoever */
    mtt->directAnsMiteVal[miteValXw][0] = samplePosWorld[0];
    mtt->directAnsMiteVal[miteValXi][0] = samplePosIndex[0];
    mtt->directAnsMiteVal[miteValYw][0] = samplePosWorld[1];
    mtt->directAnsMiteVal[miteValYi][0] = samplePosIndex[1];
    mtt->directAnsMiteVal[miteValZw][0] = samplePosWorld[2];
    mtt->directAnsMiteVal[miteValZi][0] = samplePosIndex[2];
    mtt->directAnsMiteVal[miteValRw][0] = ELL_3V_LEN(samplePosWorld);
    mtt->directAnsMiteVal[miteValRi][0] = ELL_3V_LEN(samplePosIndex);
    mtt->directAnsMiteVal[miteValTw][0] = rayT;
    mtt->directAnsMiteVal[miteValTi][0] = num;
    ELL_3V_COPY(mtt->directAnsMiteVal[miteValView], mtt->V);
    NN = mtt->directAnsMiteVal[miteValNormal];
    if (mtt->_normal) {
      if (1 == muu->normalSide) {
        ELL_3V_SCALE(NN, -1, mtt->_normal);
      } else {
        ELL_3V_COPY(NN, mtt->_normal);
      }
    }

    if ((GAGE_QUERY_ITEM_TEST(mrr->queryMite, miteValNdotV)
         || GAGE_QUERY_ITEM_TEST(mrr->queryMite, miteValNdotL)
         || GAGE_QUERY_ITEM_TEST(mrr->queryMite, miteValVrefN))) {
      mtt->directAnsMiteVal[miteValNdotV][0] = ELL_3V_DOT(NN, mtt->V);
      mtt->directAnsMiteVal[miteValNdotL][0] =
        ELL_3V_DOT(NN, muu->lit->dir[0]);
      if (!muu->normalSide) {
        mtt->directAnsMiteVal[miteValNdotV][0] =
          AIR_ABS(mtt->directAnsMiteVal[miteValNdotV][0]);
        mtt->directAnsMiteVal[miteValNdotL][0] =
          AIR_ABS(mtt->directAnsMiteVal[miteValNdotL][0]);
      }
      NdotV = mtt->directAnsMiteVal[miteValNdotV][0];
      ELL_3V_SCALE_ADD2(ref, 2*NdotV, NN, -1, mtt->V);
      ELL_3V_NORM(mtt->directAnsMiteVal[miteValVrefN], ref, len);
    }

    if (GAGE_QUERY_ITEM_TEST(mrr->queryMite, miteValGTdotV)) {
      ELL_3MV_MUL(kn, mtt->nPerp, mtt->V);
      ELL_3V_NORM(kn, kn, len);
      ELL_3MV_MUL(knd, mtt->geomTens, kn);
      mtt->directAnsMiteVal[miteValGTdotV][0] = ELL_3V_DOT(knd, kn);
    }
  }


  /* initialize txf range quantities, and apply all txfs */
  if (mtt->verbose) {
    muu->debugIdx = airArrayLenIncr(muu->debugArr, muu->ndebug->axis[0].size);
  }

  memcpy(mtt->range, muu->rangeInit, MITE_RANGE_NUM*sizeof(mite_t));
  _miteStageRun(mtt, muu);

  /* if there's opacity, do shading and compositing */
  if (mtt->range[miteRangeAlpha]) {
    /* fprintf(stderr, "%s: mtt->TT = %g\n", me, mtt->TT); */
    /*
    if (mtt->verbose) {
      fprintf(stderr, "%s: before compositing: RGBT = %g,%g,%g,%g\n",
              me, mtt->RR, mtt->GG, mtt->BB, mtt->TT);
    }
    */
    _miteRGBACalc(&R, &G, &B, &A, mtt, mrr, muu);
    mtt->RR += mtt->TT*A*R;
    mtt->GG += mtt->TT*A*G;
    mtt->BB += mtt->TT*A*B;
    mtt->TT *= 1-A;
    /*
    if (mtt->verbose) {
      fprintf(stderr, "%s: after compositing: RGBT = %g,%g,%g,%g\n",
              me, mtt->RR, mtt->GG, mtt->BB, mtt->TT);
    }
    */
    /* fprintf(stderr, "%s: mtt->TT = %g\n", me, mtt->TT); */
  } else {
    R = G = B = A = 0;
  }
  if (mtt->verbose) {
    dbg = muu->debug + muu->debugIdx;
    dbg[0 + 2*mtt->stageNum] = R;
    dbg[1 + 2*mtt->stageNum] = G;
    dbg[2 + 2*mtt->stageNum] = B;
    dbg[3 + 2*mtt->stageNum] = A;
    dbg[4 + 2*mtt->stageNum] = rayT;
  }

  /* set Z if it hasn't been set already */
  if (1-mtt->TT >= muu->opacMatters && !AIR_EXISTS(mtt->ZZ)) {
    mtt->ZZ = rayT;
  }

  /* this is used to index mtt->debug */
  mtt->raySample += 1;

  return mtt->rayStep;
}
Ejemplo n.º 27
0
int
main(int argc, char *argv[]) {
    char *me, *err, *outS;
    limnCamera *cam;
    float matA[16], matB[16], winscale, edgeWidth[5];
    hestOpt *hopt=NULL;
    airArray *mop;
    limnObject *obj;
    limnLook *look;
    int lookIdx;
    limnWindow *win;
    int partIdx, wire, concave;
    Nrrd *nmap;

    mop = airMopNew();
    cam = limnCameraNew();
    airMopAdd(mop, cam, (airMopper)limnCameraNix, airMopAlways);

    me = argv[0];
    hestOptAdd(&hopt, "fr", "from point", airTypeDouble, 3, 3, cam->from,"4 4 4",
               "position of camera, used to determine view vector");
    hestOptAdd(&hopt, "at", "at point", airTypeDouble, 3, 3, cam->at, "0 0 0",
               "camera look-at point, used to determine view vector");
    hestOptAdd(&hopt, "up", "up vector", airTypeDouble, 3, 3, cam->up, "0 0 1",
               "camera pseudo-up vector, used to determine view coordinates");
    hestOptAdd(&hopt, "rh", NULL, airTypeInt, 0, 0, &(cam->rightHanded), NULL,
               "use a right-handed UVN frame (V points down)");
    hestOptAdd(&hopt, "or", NULL, airTypeInt, 0, 0, &(cam->orthographic), NULL,
               "use orthogonal projection");
    hestOptAdd(&hopt, "ur", "uMin uMax", airTypeDouble, 2, 2, cam->uRange,
               "-1 1", "range in U direction of image plane");
    hestOptAdd(&hopt, "vr", "vMin vMax", airTypeDouble, 2, 2, cam->vRange,
               "-1 1", "range in V direction of image plane");
    hestOptAdd(&hopt, "e", "envmap", airTypeOther, 1, 1, &nmap, NULL,
               "16checker-based environment map",
               NULL, NULL, nrrdHestNrrd);
    hestOptAdd(&hopt, "ws", "winscale", airTypeFloat, 1, 1, &winscale,
               "200", "world to points (PostScript) scaling");
    hestOptAdd(&hopt, "wire", NULL, airTypeInt, 0, 0, &wire, NULL,
               "just do wire-frame rendering");
    hestOptAdd(&hopt, "concave", NULL, airTypeInt, 0, 0, &concave, NULL,
               "use slightly buggy rendering method suitable for "
               "concave or self-occluding objects");
    hestOptAdd(&hopt, "wd", "5 widths", airTypeFloat, 5, 5, edgeWidth,
               "0.0 0.0 3.0 2.0 0.0",
               "width of edges drawn for five kinds of "
               "edges: back non-crease, back crease, "
               "silohuette, front crease, front non-crease");
    hestOptAdd(&hopt, "o", "output PS", airTypeString, 1, 1, &outS, "out.ps",
               "output file to render postscript into");
    hestParseOrDie(hopt, argc-1, argv+1, NULL,
                   me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE);
    airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
    airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

    cam->neer = -0.000000001;
    cam->dist = 0;
    cam->faar = 0.0000000001;
    cam->atRelative = AIR_TRUE;

    if (limnCameraUpdate(cam)) {
        fprintf(stderr, "%s: trouble:\n%s\n", me, err = biffGet(LIMN));
        free(err);
        return 1;
    }
    obj = limnObjectNew(10, AIR_TRUE);
    airMopAdd(mop, obj, (airMopper)limnObjectNix, airMopAlways);

    /* create limnLooks for diffuse (#0) and flat (#1) shading */
    lookIdx = airArrayLenIncr(obj->lookArr, 2);
    look = obj->look + lookIdx + 0;
    ELL_4V_SET(look->rgba, 1, 1, 1, 1);
    ELL_3V_SET(look->kads, 0, 1, 0);
    look->spow = 0;
    look = obj->look + lookIdx + 1;
    ELL_4V_SET(look->rgba, 1, 1, 1, 1);
    ELL_3V_SET(look->kads, 1, 0, 0);
    look->spow = 0;

    /* X axis: rod */
    partIdx = limnObjectCylinderAdd(obj, 0, 0, 16);
    ELL_4M_IDENTITY_SET(matA);
    ELL_4M_SCALE_SET(matB, 1, 0.2, 0.2);
    ell_4m_post_mul_f(matA, matB);
    ELL_4M_TRANSLATE_SET(matB, 1.3, 0.0, 0.0);
    ell_4m_post_mul_f(matA, matB);
    limnObjectPartTransform(obj, partIdx, matA);

    /* Y axis: rod + ball */
    partIdx = limnObjectCylinderAdd(obj, 0, 1, 16);
    ELL_4M_IDENTITY_SET(matA);
    ELL_4M_SCALE_SET(matB, 0.2, 1, 0.2);
    ell_4m_post_mul_f(matA, matB);
    ELL_4M_TRANSLATE_SET(matB, 0.0, 1.3, 0.0);
    ell_4m_post_mul_f(matA, matB);
    limnObjectPartTransform(obj, partIdx, matA);

    partIdx = limnObjectPolarSphereAdd(obj, 0, 0, 32, 16);
    ELL_4M_IDENTITY_SET(matA);
    ELL_4M_SCALE_SET(matB, 0.28, 0.28, 0.28);
    ell_4m_post_mul_f(matA, matB);
    ELL_4M_TRANSLATE_SET(matB, 0.0, 2.6, 0.0);
    ell_4m_post_mul_f(matA, matB);
    limnObjectPartTransform(obj, partIdx, matA);

    /* Z axis: rod + ball + ball */
    partIdx = limnObjectCylinderAdd(obj, 0, 2, 16);
    ELL_4M_IDENTITY_SET(matA);
    ELL_4M_SCALE_SET(matB, 0.2, 0.2, 1);
    ell_4m_post_mul_f(matA, matB);
    ELL_4M_TRANSLATE_SET(matB, 0.0, 0.0, 1.3);
    ell_4m_post_mul_f(matA, matB);
    limnObjectPartTransform(obj, partIdx, matA);

    partIdx = limnObjectPolarSphereAdd(obj, 0, 1, 32, 16);
    ELL_4M_IDENTITY_SET(matA);
    ELL_4M_SCALE_SET(matB, 0.28, 0.28, 0.28);
    ell_4m_post_mul_f(matA, matB);
    ELL_4M_TRANSLATE_SET(matB, 0.0, 0.0, 2.6);
    ell_4m_post_mul_f(matA, matB);
    limnObjectPartTransform(obj, partIdx, matA);

    partIdx = limnObjectPolarSphereAdd(obj, 0, 2, 32, 16);
    ELL_4M_IDENTITY_SET(matA);
    ELL_4M_SCALE_SET(matB, 0.28, 0.28, 0.28);
    ell_4m_post_mul_f(matA, matB);
    ELL_4M_TRANSLATE_SET(matB, 0.0, 0.0, 3.2);
    ell_4m_post_mul_f(matA, matB);
    limnObjectPartTransform(obj, partIdx, matA);

    win = limnWindowNew(limnDevicePS);
    win->scale = winscale;
    win->ps.wireFrame = wire;
    win->ps.lineWidth[limnEdgeTypeBackFacet] = edgeWidth[0];
    win->ps.lineWidth[limnEdgeTypeBackCrease] = edgeWidth[1];
    win->ps.lineWidth[limnEdgeTypeContour] = edgeWidth[2];
    win->ps.lineWidth[limnEdgeTypeFrontCrease] = edgeWidth[3];
    win->ps.lineWidth[limnEdgeTypeFrontFacet] = edgeWidth[4];

    win->file = fopen(outS, "w");
    airMopAdd(mop, win, (airMopper)limnWindowNix, airMopAlways);

    if (limnObjectRender(obj, cam, win)
            || (concave
                ? limnObjectPSDrawConcave(obj, cam, nmap, win)
                : limnObjectPSDraw(obj, cam, nmap, win))) {
        airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble:\n%s\n", me, err);
        airMopError(mop);
        return 1;
    }
    fclose(win->file);

    airMopOkay(mop);
    return 0;
}
/*
** Sat Jan 29 16:44:50 EST 2005: this used to "open the seperate
** datafile, and set the FILE* in nio->dataFile, which otherwise will
** stay NULL", but now we support multiple detached data files.  So.
**
** The job of this function is to map the "data file" specification to
** one or more filenames that can be passed direction to fopen for 
** reading in the data.  This involves parsing the various formats for
** identifying multiple data files, and possibly prefixing them with
** nio->path.
*/
int
_nrrdReadNrrdParse_data_file (FILE *ffile, Nrrd *nrrd, 
                              NrrdIoState *nio, int useBiff) {
  char me[]="_nrrdReadNrrdParse_data_file", err[BIFF_STRLEN];
  char *info, *nums;
  unsigned int linelen;
  int tmp;
  airArray *mop;

  mop = airMopNew();
  info = airStrdup(nio->line + nio->pos);
  if (!info) {
    sprintf(err, "%s: couldn't copy line!", me);
    biffMaybeAdd(NRRD, err, useBiff); return 1;
  }
  airMopAdd(mop, info, airFree, airMopAlways);

  if (_nrrdContainsPercentDAndMore(info)) {
    /* ---------------------------------------------------------- */
    /* --------- format.%d <min> <max> <step> [<dim>] ----------- */
    /* ---------------------------------------------------------- */
    nums = info + strcspn(info, _nrrdFieldSep);
    tmp = strspn(nums, _nrrdFieldSep);
    nums[0] = 0;   /* terminate so that format is now in info */
    nums += tmp;
    if (!( 3 == sscanf(nums, "%d %d %d",&(nio->dataFNMin), 
                       &(nio->dataFNMax), &(nio->dataFNStep)) )) {
      sprintf(err, "%s: couldn't parse three ints (min, max, step) after "
              "data filename template", me);
      biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
    }
    if ( 4 == sscanf(nums, "%d %d %d %u", &(nio->dataFNMin), 
                     &(nio->dataFNMax), &(nio->dataFNStep), 
                     &(nio->dataFileDim)) ) {
      if (!( nio->dataFileDim >= 1 && nio->dataFileDim <= nrrd->dim )) {
        sprintf(err, "%s: datafile dimension %d outside valid range [1,%d]", 
                me, nio->dataFileDim, nrrd->dim);
        biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
      }
    } else {
      nio->dataFileDim = nrrd->dim-1;
    }
    if (0 == nio->dataFNStep) {
      sprintf(err, "%s: file number step must be non-zero", me);
      biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
    }
    if ((nio->dataFNMax - nio->dataFNMin)*(nio->dataFNStep) < 0) {
      sprintf(err, "%s: file number max %d not approached from min %d "
              "by step %d", me, 
              nio->dataFNMax, nio->dataFNMin, nio->dataFNStep);
      biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
    }
    if (!( nio->dataFNFormat = airStrdup(info) )) {
      sprintf(err, "%s: couldn't copy data filename format", me);
      biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
    }
  } else if (!strncmp(info, NRRD_LIST_FLAG, strlen(NRRD_LIST_FLAG))) {
    /* ---------------------------------------------------------- */
    /* ------------------------- LIST --------------------------- */
    /* ---------------------------------------------------------- */
    if (_nrrdHeaderCheck(nrrd, nio, AIR_TRUE)) {
      sprintf(err, "%s: NRRD header is incomplete. \"" NRRD_LIST_FLAG 
              "\" data file specification must be contiguous with "
              "end of header!", me);
      biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
    }
    info += strlen(NRRD_LIST_FLAG);
    if (info[0]) {
      if (1 == sscanf(info, "%u", &(nio->dataFileDim))) {
        if (!( nio->dataFileDim >= 1 && nio->dataFileDim <= nrrd->dim )) {
          sprintf(err, "%s: datafile dimension %d outside valid range [1,%d]",
                  me, nio->dataFileDim, nrrd->dim);
          biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
        }
      } else {
        sprintf(err, "%s: couldn't parse info after \"" 
                NRRD_LIST_FLAG "\" as an int", me);
        biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
      }
    } else {
      /* nothing after NRRD_LIST_FLAG, so dataFileDim is implicit */
      nio->dataFileDim = nrrd->dim-1;
    }
    /* read in all the datafile names */
    do {
      /* yes, nio->line is re-used/over-written here, but I don't
         think that's a problem */
      if (_nrrdOneLine(&linelen, nio, ffile)) {
        sprintf(err, "%s: trouble getting file name line", me);
        biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
      }
      if (linelen > 0) {
        tmp = airArrayLenIncr(nio->dataFNArr, 1);
        nio->dataFN[tmp] = airStrdup(nio->line);
      }
    } while (linelen > 0);

  } else {
    /* ---------------------------------------------------------- */
    /* -------------------- (single filename) ------------------- */
    /* ---------------------------------------------------------- */
    /* there is apparently only a single detached data file */
    tmp = airArrayLenIncr(nio->dataFNArr, 1);
    nio->dataFN[tmp] = airStrdup(info);
    nio->dataFileDim = nrrd->dim;
  }
  if (_nrrdDataFNCheck(nio, nrrd, useBiff)) {
    sprintf(err, "%s: trouble with number of datafiles", me);
    biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1;
  }
  airMopOkay(mop);   
  return 0;
}
Ejemplo n.º 29
0
void
undosConvert(char *me, char *name, int reverse, int mac,
             int quiet, int noAction) {
  airArray *mop;
  FILE *fin, *fout;
  char *data=NULL;
  airArray *dataArr;
  unsigned int ci;
  int car, numBad, willConvert;
  _undosU uu;

  mop = airMopNew();
  if (!airStrlen(name)) {
    fprintf(stderr, "%s: empty filename\n", me);
    airMopError(mop); return;
  }

  /* -------------------------------------------------------- */
  /* open input file  */
  fin = airFopen(name, stdin, "rb");
  if (!fin) {
    if (!quiet) {
      fprintf(stderr, "%s: couldn't open \"%s\" for reading: \"%s\"\n", 
              me, name, strerror(errno));
    }
    airMopError(mop); return;
  }
  airMopAdd(mop, fin, (airMopper)airFclose, airMopOnError);

  /* -------------------------------------------------------- */
  /* create buffer */
  uu.c = &data;
  dataArr = airArrayNew(uu.v, NULL, sizeof(char), AIR_STRLEN_HUGE);
  if (!dataArr) {
    if (!quiet) {
      fprintf(stderr, "%s: internal allocation error #1\n", me);
    }
    airMopError(mop); return;
  }
  airMopAdd(mop, dataArr, (airMopper)airArrayNuke, airMopAlways);

  /* -------------------------------------------------------- */
  /* read input file, testing for binary-ness along the way */
  numBad = 0;
  car = getc(fin);
  if (EOF == car) {
    if (!quiet) {
      fprintf(stderr, "%s: \"%s\" is empty, skipping ...\n", me, name);
    }
    airMopError(mop); return;
  }
  do {
    ci = airArrayLenIncr(dataArr, 1);
    if (!dataArr->data) {
      if (!quiet) {
        fprintf(stderr, "%s: internal allocation error #2\n", me);
      }
      airMopError(mop); return;
    }
    data[ci] = car;
    numBad += !(isprint(data[ci]) || isspace(data[ci]));
    car = getc(fin);
  } while (EOF != car && BAD_PERC > 100.0*numBad/dataArr->len);
  if (EOF != car) {
    if (!quiet) {
      fprintf(stderr, "%s: more than %g%% of \"%s\" is non-printing, "
              "skipping ...\n", me, BAD_PERC, name);
    }
    airMopError(mop); return;    
  }
  fin = airFclose(fin);

  /* -------------------------------------------------------- */
  /* see if we really need to do anything */
  willConvert = AIR_FALSE;
  if (!strcmp("-", name)) {
    willConvert = AIR_TRUE;
  } else if (reverse) {
    for (ci=0; ci<dataArr->len; ci++) {
      if (mac) {
        if (CR == data[ci]) {
          willConvert = AIR_TRUE;
          break;
        }
      } else {
        if (CR == data[ci] && (ci && LF != data[ci-1])) {
          willConvert = AIR_TRUE;
          break;
        }
      }
    }
  } else {
    for (ci=0; ci<dataArr->len; ci++) {
      if (mac) {
        if (LF == data[ci]) {
          willConvert = AIR_TRUE;
          break;
        }
      } else {
        if (LF == data[ci] && (ci+1<dataArr->len && CR == data[ci+1])) {
          willConvert = AIR_TRUE;
          break;
        }
      }
    }
  }
  if (!willConvert) {
    /* no, we don't need to do anything; quietly quit */
    airMopOkay(mop);
    return;
  } else {
    if (!quiet) {
      fprintf(stderr, "%s: %s \"%s\" %s %s ... \n", me, 
              noAction ? "would convert" : "converting",
              name,
              reverse ? "to" : "from",
              mac ? "MAC" : "DOS");
    }
  }
  if (noAction) {
    /* just joking, we won't actually write anything.
       (yes, even if input was stdin) */
    airMopOkay(mop);
    return;
  }

  /* -------------------------------------------------------- */
  /* open output file */
  fout = airFopen(name, stdout, "wb");
  if (!fout) {
    if (!quiet) {
      fprintf(stderr, "%s: couldn't open \"%s\" for writing: \"%s\"\n", 
              me, name, strerror(errno));
    }
    airMopError(mop); return;
  }
  airMopAdd(mop, fout, (airMopper)airFclose, airMopOnError);

  /* -------------------------------------------------------- */
  /* write output file */
  car = 'a';
  if (reverse) {
    for (ci=0; ci<dataArr->len; ci++) {
      if ((mac && CR == data[ci])
          || (CR == data[ci] && (ci && LF != data[ci-1]))) {
        car = putc(LF, fout);
        if (!mac && EOF != car) {
          car = putc(CR, fout);
        }
      } else {
        car = putc(data[ci], fout);
      }
    }
  } else {
    for (ci=0; EOF != car && ci<dataArr->len; ci++) {
      if ((mac && LF == data[ci])
          || (LF == data[ci] && (ci+1<dataArr->len && CR == data[ci+1]))) {
        car = putc(CR, fout);
        ci += !mac;
      } else {
        car = putc(data[ci], fout);
      }
    }
  }
  if (EOF == car) {
    if (!quiet) {
      fprintf(stderr, "%s: ERROR writing \"%s\" possible data loss !!! "
              "(sorry)\n", me, name);
    }
  }
  fout = airFclose(fout);

  airMopOkay(mop);
  return;
}
Ejemplo n.º 30
0
/*
** nio->byteSkip < 0 functionality contributed by Katharina Quintus
*/
int
_nrrdEncodingGzip_read(FILE *file, void *_data, size_t elNum,
                       Nrrd *nrrd, NrrdIoState *nio) {
  char me[]="_nrrdEncodingGzip_read", err[BIFF_STRLEN];
#if TEEM_ZLIB
  size_t sizeData, sizeRed, sizeChunk;
  int error;
  long int bi;
  unsigned int read;
  char *data;
  gzFile gzfin;
  ptrHack hack;

  sizeData = nrrdElementSize(nrrd)*elNum;
  /* Create the gzFile for reading in the gzipped data. */
  if ((gzfin = _nrrdGzOpen(file, "rb")) == Z_NULL) {
    /* there was a problem */
    sprintf(err, "%s: error opening gzFile", me);
    biffAdd(NRRD, err);
    return 1;
  }

  /* keeps track of how many bytes have been successfully read in */
  sizeRed = 0;
  
  /* zlib can only handle data sizes up to UINT_MAX ==> if there's more
     than UINT_MAX bytes to read in, we read in in chunks */
  sizeChunk = AIR_MIN(sizeData, UINT_MAX);
  
  if (nio->byteSkip < 0) { 
    /* We don't know the size of the size to skip before the data, so
       decompress the data first into a temporary memory buffer.  Then
       the byteskipping is then just memcpy-ing the appropriate region
       of memory from "buff" into the given "_data" pointer */
    char *buff;
    airArray *buffArr;
      
    /* setting the airArray increment to twice the chunk size means that for
       headers that are small compared to the data, the airArray never
       actually has to reallocate.  The unit is 1 because we are managing
       the reading in terms of bytes (sizeof(char)==1 by definition) */
    buff = NULL;
    hack.c = &buff;
    buffArr = airArrayNew(hack.v, NULL, 1, 2*sizeChunk);
    airArrayLenSet(buffArr, sizeChunk);
    if (!( buffArr && buffArr->data )) {
      sprintf(err, "%s: couldn't initialize airArray\n", me);
      biffAdd(NRRD, err);
      return 1;
    }
    
    /* we keep reading in chunks as long as there hasn't been an error,
       and we haven't hit EOF (EOF signified by read == 0).  Unlike the
       code below (for positive byteskip), we are obligated to read until
       the bitter end, and can't update sizeChunk to encompass only the 
       required data.  Cast on third arg ok because of AIR_MIN use above */
    while (!(error = _nrrdGzRead(gzfin, buff + sizeRed,
                                 AIR_CAST(unsigned int, sizeChunk),
                                 &read))
           && read > 0) {
      sizeRed += read;
      if (read >= sizeChunk) {
        /* we were able to read as much data as we requested, maybe there is
           more, so we need to make our temp buffer bigger */
        airArrayLenIncr(buffArr, sizeChunk);
        if (!buffArr->data) {
          sprintf(err, "%s: couldn't re-allocate data buffer", me);
          biffAdd(NRRD, err);
          return 1;
        }
      }
    }
    if (error) {
      sprintf(err, "%s: error reading from gzFile", me);
      biffAdd(NRRD, err);
      return 1;
    }
    if (sizeRed < sizeData + (-nio->byteSkip - 1)) {
      sprintf(err, "%s: expected " _AIR_SIZE_T_CNV " bytes and received only "
              _AIR_SIZE_T_CNV " bytes", me,
              AIR_CAST(size_t, sizeData + (-nio->byteSkip - 1)), sizeRed);
      biffAdd(NRRD, err);
      return 1;
    }
    /* also handles nio->byteSkip == -N-1 signifying extra N bytes at end */
    memcpy(_data, buff + sizeRed - sizeData - (-nio->byteSkip - 1), sizeData);
    airArrayNuke(buffArr);
  } else {