Пример #1
0
/*!
 * Writes the header for unit [iunit] to file with the minimum, maximum and mean
 * density values in [dmin], [dmax], and [dmean].  A single title can be supplied in
 * an 80-byte array, [label], and will be treated according to the value of [labFlag]: ^
 *  0:  [label] becomes the only title ^
 *  1:  [label] is added at the end of existing titles, replacing the last one if there 
 * are already 10 titles ^
 *  2:  [label] is added as the first title and others are shifted up ^
 * -1 or anything else: do not add a title ^
 * Returns -1 for various internal errors or 1 for an error writing the header.
 * Fortran wrappers iiuWriteHeader and iwrhdr (a void).
 */
int iiuWriteHeader(int iunit, int *label, int labFlag, float dmin, float dmax,
                    float dmean)
{
  int doExit = iiuGetExitOnError();
  int i;
  MrcHeader *hdr = iiuMrcHeader(iunit, "iiuWriteHeader", doExit, 2);
  if (!hdr)
    return -1;
  if (labFlag == 0) {
    iiuAltLabels(iunit, label, 1);
  } else if (labFlag == 1) {
    hdr->nlabl = B3DMIN(hdr->nlabl + 1, MRC_NLABELS);
    memcpy(hdr->labels[hdr->nlabl - 1], label, MRC_LABEL_SIZE);
    fixTitlePadding(hdr->labels[hdr->nlabl - 1]);
  } else if (labFlag == 2) {
    hdr->nlabl = B3DMIN(hdr->nlabl + 1, MRC_NLABELS);
    for (i = hdr->nlabl - 1; i > 0; i--)
      memcpy(hdr->labels[i], hdr->labels[i - 1], MRC_LABEL_SIZE);
    memcpy(hdr->labels[0], label, MRC_LABEL_SIZE);
    fixTitlePadding(hdr->labels[0]);
  }

  hdr->amin = dmin;
  hdr->amax = dmax;
  hdr->amean = dmean;
  if (mrc_head_write(hdr->fp, hdr)) {
    if (doExit)
      exit(1);
    return 1;
  }
  return 0;
}
Пример #2
0
// Set the drawing state and dialog to the start or end of the given movie segment
void mvImageSetMovieEndState(int startEnd, MovieSegment &segment)
{
  MovieTerminus *term = &segment.start;
  int maxSlices = B3DMIN(Imodv->vi->zsize, MAX_SLICES);
  if (startEnd == IMODV_MOVIE_END_STATE)
    term = &segment.end;

  if (mvImageSetMovieDrawState(segment))
    return;
 
  // Otherwise set the image position and copy all the data over
  sImageTrans = term->imgTransparency;
  ivwSetLocation(Imodv->vi, term->imgXcenter - 1, term->imgYcenter - 1, 
                 term->imgZcenter - 1);
  sNumSlices = B3DMIN(term->imgSlices, maxSlices);

  // Update the dialog as needed
  if (sDia) {

    // Set this to prevent Y/Z swapping of sizes in the update
    sLastYsize = Imodv->vi->ysize;
    sDia->updateCoords();
    sDia->mSliders->setValue(IIS_SLICES, sNumSlices);
    sDia->mSliders->setValue(IIS_TRANSPARENCY, sImageTrans);
  }
}
Пример #3
0
/*!
 * Extracts a square matrix of size [dim] from the slice [sin], centered 
 * around position [x], [y] and places the result into the array [mat].
 */
void mrc_slice_mat_getimat(Islice *sin, int x, int y, int dim, 
                           float *mat)
{
  int xs, ys, xe, ye;
  int i, j, ic, jc;


  xs = x - (dim / 2);
  xe = xs + dim;
  ys = y - (dim / 2);
  ye = ys + dim;

  if (xs >= 0 && xe < sin->xsize && ys >= 0 && ye < sin->ysize) {
    for(j = ys; j < ye; j++)
      for(i = xs; i < xe; i++)
        mat[(i-xs )+ dim * (j-ys)] = sliceGetPixelMagnitude(sin, i, j);
  } else {

    /* If any pixels are out of bounds, replicate from inside pixels */
    for(j = ys; j < ye; j++)
      for(i = xs; i < xe; i++) {
        ic = B3DMAX(0, B3DMIN(sin->xsize - 1, i));
        jc = B3DMAX(0, B3DMIN(sin->ysize - 1, j));
        mat[(i-xs )+ dim * (j-ys)] = sliceGetPixelMagnitude(sin, ic, jc);
      }
  }
}
Пример #4
0
void ContourCopy::update()
{
  int minVal, maxVal, curVal;
  ImodView *vw = sData.vw;

  // For each operation that uses spin box, set up min and max value
  // and adjust the current value if necessary
  switch(sData.copyOperation){
  case COPY_TO_OBJECT:
    minVal = 1;
    maxVal = vw->imod->objsize;
    sData.objectNumber = B3DMAX(1, B3DMIN(maxVal, sData.objectNumber));
    curVal = sData.objectNumber;
    break;

  case COPY_TO_SECTION:
    minVal = 1;
    maxVal = vw->zsize;
    sData.sectionNumber = B3DMAX(1, B3DMIN(maxVal, sData.sectionNumber));
    curVal = sData.sectionNumber;
    break;

  case COPY_TO_TIME:
    minVal = 1;
    maxVal = vw->numTimes;
    sData.timeIndex = B3DMAX(1, B3DMIN(maxVal, sData.timeIndex));
    curVal = sData.timeIndex;
    break;

  case COPY_TO_NEXT_SECTION:
  case COPY_TO_PREV_SECTION:
  case COPY_TO_CURRENT:
  default:
    minVal = 0;
    maxVal = 0;
    curVal = 0;
    break;
  }

  // Set up spin box limits and value and enable it if meaningful
  diaSetSpinMMVal(mToSpinBox, minVal, maxVal, curVal);
  mToSpinBox->setSpecialValueText(minVal ? "" : "   ");
  mToSpinBox->setEnabled(minVal > 0);
  mEllipseBox->setEnabled(sData.copyOperation == COPY_TO_OBJECT);

  // Enable the time radio button if appropriate
  if (vw->numTimes)
    mTimeRadio->setEnabled(sData.copyOperation == COPY_TO_TIME);

}
Пример #5
0
/*
 * Ruueads a file of tilt angles whose name is in angleFile, and which must
 * have at least nzz lines.  angleSign should be 1., or -1. to invert the
 * sign of the angles.  Minimum and maximum angles are returned in minAngle
 * and maxAngle.  The return value is the array of tilt angles.
 */
float *readTiltAngles(const char *angleFile, int nzz, float angleSign,
                      float &minAngle, float &maxAngle)
{
  char angleStr[MAX_LINE];
  FILE *fpAngle;
  int k, err;
  float currAngle;
  float *tiltAngles = (float *)malloc(nzz * sizeof(float));
  minAngle = 10000.;
  maxAngle = -10000.;
  if (!tiltAngles)
    exitError("Allocating array for tilt angles");
  if ((fpAngle = fopen(angleFile, "r")) == 0)
    exitError("Opening tilt angle file %s", angleFile);
  for (k = 0; k < nzz; k++) {
    do {
      err = fgetline(fpAngle, angleStr, MAX_LINE);
    } while (err == 0);
    if (err == -1 || err == -2)
      exitError("%seading tilt angle file %s\n",
                err == -1 ? "R" : "End of file while r", angleFile);
    sscanf(angleStr, "%f", &currAngle);
    currAngle *= angleSign;
    minAngle = B3DMIN(minAngle, currAngle);
    maxAngle = B3DMAX(maxAngle, currAngle);
    tiltAngles[k] = currAngle;
  }
  fclose(fpAngle);
  return tiltAngles;
}
Пример #6
0
/*!
 * Computes the minimum [DMIN], maximum [dmax], mean [avg], and standard deviation [SD]
 * from data in [array], dimensioned [nx] by [ny], for X indices from [ix0] to [ix1] and 
 * Y indices from [iy0] to [iy1], inclusive (numbered from 0 when calling from C).  It
 * also returns the sum in [sumDbl] and sum of squares in [sumSqDl].
 */
void arrayMinMaxMeanSd(float *array, int nx, int ny, int ix0, int ix1, int iy0, int iy1,
                       float *dmin, float *dmax, double *sumDbl, double *sumSqDbl,
                       float *avg, float *SD)
{
  float den;
  float *arrTmp;
  double sumTmp, sumTmpSq;
  int ix, iy;

  *sumDbl = 0.;
  *sumSqDbl = 0.;
  *dmin = 1.e37;
  *dmax = -1.e37;
  for (iy = iy0; iy <= iy1; iy++) {
    sumTmp = 0.;;
    sumTmpSq = 0.;
    arrTmp = array + (size_t)iy * nx + ix0;
    for (ix = ix0; ix <= ix1; ix++) {
      den = *arrTmp++;
      sumTmp = sumTmp + den;
      sumTmpSq = sumTmpSq + den * den;
      *dmin = B3DMIN(*dmin, den);
      *dmax = B3DMAX(*dmax, den);
    }
    *sumDbl += sumTmp;
    *sumSqDbl += sumTmpSq;
  }
  sumsToAvgSDdbl(*sumDbl, *sumSqDbl, ix1 + 1 - ix0, iy1 + 1 - iy0, avg, SD);
}
Пример #7
0
/*
 * Compute the limits of usable data in one dimension for calling from the interp function
 */
static void interpLimits(int na, int nb, float cen, float trans, double scale,
                         float *aOff, int *bSize, int *bOff)
{
    float bcStart, bcEnd;
    int bdStart, bdEnd;

    /* Get starting and ending continuous coordinates in b from corners of a and limit
       them to edges of first and last pixel */
    bcStart = -cen / scale + nb / 2. + trans;
    bcEnd = (na - cen) / scale + nb / 2. + trans;
    bcStart = B3DMAX(0., bcStart);
    bcEnd = B3DMIN(nb, bcEnd);

    /* Get discrete coordinates of the nearest whole pixel by rounding up on the start and
       down on the end, then get the offset and size from them */
    bdStart = (int)ceil(bcStart - 0.001);
    bdEnd = (int)floor(bcEnd + 0.001) - 1;
    *bOff = bdStart;
    *aOff = scale * (bdStart - nb / 2. - trans) + cen;

    /* Make sure this is not negative; roundoff errors can give negative values */
    *aOff = B3DMAX(0., *aOff);
    *bSize = bdEnd + 1 - bdStart;

    /* Make sure the output size will pass the test below too */
    if (*bSize * scale + *aOff > na)
        (*bSize)--;
}
Пример #8
0
// Compute starting and ending draw coordinates from center coordinate, desired
// size and maximum size, shifting center if necessary
static void setCoordLimits(int cur, int maxSize, int drawSize, 
                           int &str, int &end)
{
  str = cur - drawSize / 2;
  str = B3DMAX(1, str);
  end = B3DMIN(str + drawSize, maxSize - 1);
  str = B3DMAX(1, end - drawSize);
}
Пример #9
0
void SliceCache::clearAndSetSize(int dim, int hyper, int tSize)
{
  int fftXdim, i, j, rIndex;
  double freqInc;
  numXtiles = mHeader.nx / (tSize / 2) - 1;
  mNumYtiles = mHeader.ny / (tSize / 2) - 1;
  mPsArraySize = numXtiles * mNumYtiles * mPsDim;
  mMaxSliceNum = mMaxCacheSize * 1024 * 1024 / (mPsArraySize * sizeof(float));
  for (i = 0; i < (int)mCachedPS.size(); i++) {
    free(mCachedPS[i]);
    free(mCachedTileDone[i]);
    free(mCachedMeans[i]);
  }
  if (mTile)
    free(mTile);
  mTile = (float *)malloc(tSize * (tSize + 2) * sizeof(float));
  if (mTileToPsInd)
    free(mTileToPsInd);
  mTileToPsInd = (int *)malloc(tSize * (tSize + 2) * sizeof(int));
  if (!mTile || !mTileToPsInd)
    exitError("Allocating memory for mTile or PS index");

  // Compute the index for each component of FFT and the counts in each bin
  mTileSize = tSize;
  mNDim = dim;
  mHyperRes = hyper;
  fftXdim = (mTileSize + 2) / 2;
  freqInc = 1. / ((mNDim - 1) * hyper);
  for (i = 0; i < mPsDim; i++)
    mFreqCount[i] = 0;
  for (i = 0; i < fftXdim - 1; i++) {
    for (j = 0; j < fftXdim; j++) {

      // Here make bins with integer truncation
      rIndex = (int)(sqrt((double)(i * i + j * j)) / (fftXdim - 1) / freqInc);
      rIndex = B3DMIN(rIndex, mPsDim - 1);
      mTileToPsInd[i * fftXdim + j] = rIndex;
      mFreqCount[rIndex] += 2;
    }
  }

  /*for (i = 0; i < mPsDim; i++)
    printf("%d\n", mFreqCount[i]); */

  // Clear cache components
  mCachedPS.clear();
  mCachedMeans.clear();
  mCachedTileDone.clear();
  mSliceAngles.clear();
  mCachedSliceMap.clear();
  mOldestIdx = -1;

  if (debugLevel >= 2)
    printf("cacheSize is set to %d \n", mMaxSliceNum);
}
Пример #10
0
/*!
 * Sets the labels for unit [iunit] from the array in [labels], which should have the
 * 80 characters for [numLabels] labels packed contiguously.  The labels may be 
 * null-terminated; the null and following bytes will be filled with spaces.
 * Fortran wrappers iiuAltLabels and iallab.
 */
void iiuAltLabels(int iunit, int *labels, int numLabels)
{
  MrcHeader *hdr = iiuMrcHeader(iunit, "iiuAltLabels", 1, 0);
  int i;
  hdr->nlabl = B3DMIN(MRC_NLABELS, numLabels);
  for (i = 0; i < hdr->nlabl; i++) {
    memcpy(hdr->labels[i], labels + 20 * i, MRC_LABEL_SIZE);
    fixTitlePadding(hdr->labels[i]);
  }
  for (i = hdr->nlabl; i < MRC_NLABELS; i++)
    memset(hdr->labels[i], 0, MRC_LABEL_SIZE + 1);
}
Пример #11
0
// Set ancillary parameters to the state for a movie segment
int mvImageSetMovieDrawState(MovieSegment &segment)
{
 if (!segment.imgAxisFlags) {

    // If there is no image drawing, turn off Imodv flag and then, if there is currently,
    // take the update route to updating this module
    Imodv->texMap = 0;
    if (sFlags) 
      mvImageUpdate(Imodv);
    return 1;
  }
  sFlags = segment.imgAxisFlags;
  Imodv->texMap = 1;
  sWhiteLevel = segment.imgWhiteLevel;
  sBlackLevel = segment.imgBlackLevel;
  sFalsecolor = segment.imgFalseColor;
  makeColorMap();
  sXdrawSize = B3DMIN(segment.imgXsize, Imodv->vi->xsize);
  sYdrawSize = B3DMIN(segment.imgYsize, Imodv->vi->ysize);
  sZdrawSize = B3DMIN(segment.imgZsize, Imodv->vi->zsize);

  // Update the dialog as needed
  if (sDia) {

    sDia->mSliders->setValue(IIS_X_SIZE, sXdrawSize);
    sDia->mSliders->setValue(IIS_Y_SIZE, sYdrawSize);
    sDia->mSliders->setValue(IIS_Z_SIZE, sZdrawSize);
    diaSetChecked(sDia->mViewXBox, (sFlags & IMODV_DRAW_CX) != 0);
    diaSetChecked(sDia->mViewYBox, (sFlags & IMODV_DRAW_CY) != 0);
    diaSetChecked(sDia->mViewZBox, (sFlags & IMODV_DRAW_CZ) != 0);
    sDia->mSliders->setValue(IIS_BLACK, sBlackLevel);
    sDia->mSliders->setValue(IIS_WHITE, sWhiteLevel);
    diaSetChecked(sDia->mFalseBox, sFalsecolor != 0);
  }
  return 0;
}
Пример #12
0
/*
 * Does common initial tasks for a montage snapshot: allocates the arrays,
 * (returns true for an error), and saves and adjusts the scale bar data 
 */
bool utilStartMontSnap(int winx, int winy, int xFullSize, int yFullSize,
                       float factor, ScaleBar &barSaved, int &numChunks,
                       unsigned char **framePix, unsigned char ***fullPix,
                       unsigned char ***linePtrs)
{
  int iy, maxLines, line, ch, ndo;
  int chunkMax = 10000000;    // This was needed to get to 2.9 GB on WinXP
  ScaleBar *barReal = scaleBarGetParams();

  maxLines = B3DMAX(1, chunkMax / (4 * xFullSize));
  numChunks = (yFullSize + maxLines - 1) / maxLines;
  *fullPix = (unsigned char **)malloc(numChunks * sizeof (unsigned char *));
  if (!*fullPix)
    return true;
  for (ch = 0; ch < numChunks; ch++)
    (*fullPix)[ch] = NULL;
  *linePtrs = NULL;
  *framePix = NULL;
  *framePix = (unsigned char *)malloc(4 * winx * winy);
  *linePtrs = (unsigned char **)malloc(yFullSize * sizeof(unsigned char *));
  if (!*framePix || !*linePtrs) {
    utilFreeMontSnapArrays(*fullPix, numChunks, *framePix, *linePtrs);
    return true;
  }
  
  line = 0;
  for (ch = 0; ch < numChunks; ch++) {
    ndo = B3DMIN(yFullSize - line, maxLines);
    (*fullPix)[ch] = (unsigned char *)malloc(ndo * 4 * xFullSize);
    if (!(*fullPix)[ch]) {
      imodPrintStderr("Failed on chunk %d, after %u\n", ch, (unsigned int)ch * ndo * 4 * xFullSize);
      utilFreeMontSnapArrays(*fullPix, numChunks, *framePix, *linePtrs);
      return true;
    }
    for (iy = 0; iy < ndo; iy++)
      (*linePtrs)[iy+line] = (*fullPix)[ch] + 4 * xFullSize * iy;
    line += ndo;
  }

  // Save and modify scale bar directives
  barSaved = *barReal;
  barReal->minLength = B3DNINT(factor * barReal->minLength);
  barReal->thickness = B3DNINT(factor * barReal->thickness);
  barReal->indentX = B3DNINT(factor * barReal->indentX);
  barReal->indentY = B3DNINT(factor * barReal->indentY);
  return false;
}
Пример #13
0
// Return the limits of what is being drawn in X and Y
bool mvImageSubsetLimits(double &zoom, float &zoomUpLimit, float &zoomDownLimit, 
                         int &ixStart, int &iyStart, int &nxUse, int &nyUse)
{
  int ixCur, iyCur, izCur, xend, yend;
  ImodvApp *a = Imodv;
  if (ImodvClosed || !a->texMap || !sFlags || sXdrawSize <= 0)
    return false;
  zoomUpLimit = sPyrZoomUpLimit;
  zoomDownLimit = sPyrZoomDownLimit;
  zoom = 0.5 * B3DMIN(a->winx, a->winy) / a->imod->view->rad;
  ivwGetLocation(a->vi, &ixCur, &iyCur, &izCur);
  setCoordLimits(ixCur, a->vi->xsize, sXdrawSize, ixStart, xend);
  setCoordLimits(iyCur, a->vi->ysize, sYdrawSize, iyStart, yend);
  nxUse = xend + 1 - ixStart;
  nyUse = yend + 1 - iyStart;
  return true;
}
Пример #14
0
/*
 * Finds the next section in the current object with a contour, given curz is
 * the current Z and dir is 1 to go forward or -1 to go back
 */
int utilNextSecWithCont(ImodView *vi, Iobj *obj, int curz, int dir)
{
  int diff, co, contz;
  int newz = curz;
  Icont *cont;
  if (!obj)
    return newz;
  newz = -1;
  for (co = 0; co < obj->contsize; co++) {
    cont = &obj->cont[co];
    if (!cont->psize)
      continue;
    contz = B3DNINT(cont->pts[0].z);
    contz = B3DMAX(0, B3DMIN(contz, vi->zsize - 1));
    diff = dir * (contz - curz);
    if (diff > 0 && (newz < 0 || diff < dir * (newz - curz)))
      newz = contz;
  }
  return newz >= 0 ? newz : curz;
}
Пример #15
0
/*!
 * Computes the minimum [DMIN], maximum [dmax], and mean [dmean] from data in [array],
 * dimensioned [nx] by [ny], for X indices from [ix0] to [ix1] and Y indices from [iy0]
 * to [iy1], inclusive (numbered from 0 when calling from C).
 */
void arrayMinMaxMean(float *array, int nx, int ny, int ix0, int ix1, int iy0, int iy1,
                     float *dmin, float *dmax, float *dmean)
{
  float den, sumTmp;
  float *arrTmp;
  double sumDbl;
  int ix, iy;

  sumDbl = 0.;
  *dmin = 1.e37;
  *dmax = -1.e37;
  for (iy = iy0; iy <= iy1; iy++) {
    sumTmp = 0.;;
    arrTmp = array + (size_t)iy * nx + ix0;
    for (ix = ix0; ix <= ix1; ix++) {
      den = *arrTmp++;
      sumTmp = sumTmp + den;
      *dmin = B3DMIN(*dmin, den);
      *dmax = B3DMAX(*dmax, den);
    }
    sumDbl += sumTmp;
  }
  *dmean = sumDbl / ((double)(ix1 + 1 - ix0) * (iy1 + 1 - iy0)); 
}
Пример #16
0
static void plax_draw_text(b3dInt32 thickness,
                           b3dInt32 iysize,
                           b3dInt32 cindex,
                           b3dInt32 x, b3dInt32 y, 
                           b3dInt32 strsize, char *string)

{
  static int lastbold;
  int width, height, align, maxWidth, maxHeight;

  int ysize = (int)(iysize * TEXT_SIZE_SCALE);
  int ifbold = 0;
  char *cstring = f2cString(string, strsize);

  if (!cstring)
    return;

#ifdef PLAX_DEBUG
  printf("draw text %d %d %d %d %d %s\n", thickness, iysize, cindex, x, y,
         cstring);
#endif

  if (thickness > 1)
    ifbold = 1;

  ysize = plax_scale(ysize);
  if (ysize <= 1)
    ysize = 1;

  if (sLastSize != ysize || lastbold != ifbold) {
    //QFont newFont("courier", ysize);
    QFont newFont;
    newFont.setPointSize(ysize);
    newFont.setStyleHint(QFont::TypeWriter);
    newFont.setItalic(false);
    newFont.setBold(ifbold != 0);
    sPainter->setFont(newFont);
  }
  lastbold = ifbold;
  sLastSize = ysize;

  plax_transform(&x, &y);
  plax_set_pen(cindex, 0);
  
  if (sNextTextAlign % 10) {
    maxWidth = 2 * B3DMIN(x, sPlaxWidth - x);
    maxHeight = 2 * B3DMIN(y - 1, sPlaxHeight - y - 1);
    switch (sNextTextAlign % 10) {
    case 1:  // Top center
      align = Qt::AlignHCenter | Qt::AlignTop;
      width = B3DMIN(maxWidth, sPlaxWidth / 2);
      height = B3DMIN(sPlaxHeight - 1 - y, sPlaxHeight / 2);
      x -= width / 2;
      break;

    case 2: // right center
      align = Qt::AlignVCenter | Qt::AlignRight;
      width = B3DMIN(x - 1, sPlaxWidth / 2);
      height = B3DMIN(maxHeight, sPlaxHeight / 2);
      x -= width;
      y -= height / 2;
      break;

    case 3:  // Bottom center
      align = Qt::AlignHCenter | Qt::AlignBottom;
      width = B3DMIN(maxWidth, sPlaxWidth / 2);
      height = B3DMIN(y - 1, sPlaxHeight / 2);
      x -= width / 2;
      y -= height;
      break;

    case 4:  // left center
      align = Qt::AlignVCenter | Qt::AlignLeft;
      width = B3DMIN(sPlaxWidth - x - 1, sPlaxWidth / 2);
      height = B3DMIN(maxHeight, sPlaxHeight / 2);
      y -= height / 2;
      break;

    default: // all centered
      align = Qt::AlignVCenter | Qt::AlignHCenter;
      height = B3DMIN(maxHeight, sPlaxHeight / 2);
      width = B3DMIN(maxWidth, sPlaxWidth / 2);
      x -= width / 2;
      y -= height / 2;
      break;
    }
    if (sNextTextAlign >= 10) 
      align |= Qt::TextWordWrap;
    sPainter->drawText(x, y, width, height, align, QString(cstring));
    //printf("%d %d %d %d %d %s\n", x,y, width, height, align,cstring);
    sNextTextAlign = 0;

  } else {
    //printf("%d %d %s\n", x,y, cstring);
    sPainter->drawText(x, y, QString(cstring));
  }
  fflush(stdout);
  free(cstring);
}
Пример #17
0
static void fillPatchFromTiles(std::vector<FastSegment> &segments, 
                               std::vector<int> &startInds, int ushort,
                               unsigned char *bmap, int fillXsize, int istart, int iend,
                               int jstart, int jend)
{
  int u, v, j, i, iseg, numSeg, segEnd, nextToFill, uvind, segStart;
  FastSegment *segp;
  unsigned char *imdata;
  unsigned short *usimdata;
  unsigned char pix;

  for (j = jstart; j < jend; j++) {
    v = j - jstart;
    numSeg = startInds[j + 1] - startInds[j];
    nextToFill = istart;
      
    for (iseg = startInds[j]; iseg < startInds[j + 1]; iseg++) {
      segp = &(segments[iseg]);

      // If segment starts past the end, done with segments
      if (segp->XorY >= iend)
        break;

      // If segment ends before the start, skip it
      if (segp->XorY + segp->length <= istart)
        continue;

      // If segment starts past next place to fill, need to fill with 0's
      if (segp->XorY > nextToFill) {
        for (i = nextToFill; i < segp->XorY; i++) {
          u = i - istart;
          FILLDATA(0);
        }
      }

      // Fill with segment data
      segEnd = B3DMIN(segp->XorY + segp->length, iend);
      segStart = B3DMAX(segp->XorY, istart);
      imdata = segp->line + segp->stride * (segStart - segp->XorY);
      if (ushort) {
        usimdata = (unsigned short *)imdata;
        for (i = segStart; i < segEnd; i++) {
          u = i - istart;
          pix = bmap[*usimdata];
          usimdata += segp->stride;
          FILLDATA(pix);
        }
      } else {
        for (i = segStart; i < segEnd; i++) {
          u = i - istart;
          pix = *imdata;
          imdata += segp->stride;
          FILLDATA(pix);
        }
      }
      nextToFill = segEnd;
    }

    // Fill past end
    for (i = nextToFill; i < iend; i++) {
      u = i - istart;
      FILLDATA(0);
    }
  }
}
Пример #18
0
// The call from within the openGL calling routines to draw the image
void imodvDrawImage(ImodvApp *a, int drawTrans)
{
  Ipoint lowerLeft, lowerRight, upperRight, upperLeft, clamp;
  int tstep;
  int ixCur, iyCur, izCur;
  int xsize, ysize, zsize;
  int xstr, xend, ystr, yend, zstr, zend, fillXsize;
  unsigned char **idata;
  b3dUInt16 **usidata;
  unsigned char pix;
  int i, j, ypatch, jend, xpatch, zpatch, iend, xconst;
  int u, v, uvind;
  int iz, idir, numSave, baseXstr, baseXsize, baseYstr, baseYsize;
  int cacheSum, curtime, cacheInd = -1;
  float clampEnd;
  int pyrXYscale = 1, pyrZscale = 1;
  float pyrXoffset = 0., pyrYoffset = 0., pyrZoffset = 0.;
  double zoom;
  unsigned char **imdata;
  b3dUInt16 **usimdata;
  unsigned char *bmap = NULL;
  bool flipped, invertX, invertY, invertZ;
  Imat *mat;
  Ipoint inp, outp;
  std::vector<FastSegment> segments;
  std::vector<int> startInds;
  QTime drawTime;
  drawTime.start();
  sWallLoad = sWallDraw = 0.;

  xsize = a->vi->xsize;
  ysize = a->vi->ysize;
  zsize = a->vi->zsize;
  if (sDia)
    sDia->updateCoords();

  if (!sFlags) 
    return;

  if (a->vi->pyrCache != NULL) {
    zoom = 0.5 * B3DMIN(a->winx, a->winy) / a->imod->view->rad;
    cacheInd =  a->vi->pyrCache->pickBestCache(zoom, sPyrZoomUpLimit, sPyrZoomDownLimit,
                                               pyrXYscale);
    imodTrace('t', "zoom = %.3f, cache %d, scale %d", zoom, cacheInd, pyrXYscale);
  }
  ivwGetLocation(a->vi, &ixCur, &iyCur, &izCur);
  ivwGetTime(a->vi, &curtime);
  if (!sCmapInit || (a->vi->colormapImage && 
                    (izCur != cmapZ || curtime != cmapTime))) {
    makeColorMap();
    cmapTime = curtime;
    cmapZ = izCur;
  }

  if (sXdrawSize < 0) {
    sXdrawSize = xsize;
    sYdrawSize = ysize;
    sZdrawSize = zsize;
  }

  // If doing stereo pairs, draw the pair as long as the step up stays in the
  // same set of images for an area
  if (a->imageStereo && a->stereo < 0) {
    iz = izCur + a->imageDeltaZ;
    if (izCur % a->imagesPerArea < iz % a->imagesPerArea)
      izCur = iz;
  }

  // Get data pointers if doing X or Y planes
  if ((sFlags & (IMODV_DRAW_CX | IMODV_DRAW_CY)) && cacheInd < 0 &&
       !(a->imageStereo && a->stereo)) {
    if (ivwSetupFastAccess(a->vi, &imdata, 0, &cacheSum))
      return;
    flipped = (!a->vi->vmSize || a->vi->fullCacheFlipped) && 
      a->vi->li->axis == 2;
    usimdata = (b3dUInt16 **)imdata;
  }
  if (a->vi->ushortStore) {
    bmap = ivwUShortInRangeToByteMap(a->vi);
    if (!bmap)
      return;
  }

  // If doing multiple slices, need to find direction in which to do them
  invertX = invertY = invertZ = false;
  if (a->vi->colormapImage && sNumSlices > 1) {
    sNumSlices = 1;
    if (sDia)
      sDia->mSliders->setValue(IIS_SLICES, sNumSlices);
  }
  numSave = sNumSlices;
  if (a->imageStereo && a->stereo)
    sNumSlices = 1;

  if (sNumSlices > 1) {
    mat = imodMatNew(3);
    imodMatRot(mat, (double)a->imod->view->rot.z, b3dZ);
    imodMatRot(mat, (double)a->imod->view->rot.y, b3dY);
    imodMatRot(mat, (double)a->imod->view->rot.x, b3dX);
    
    inp.x = 1.;
    inp.y = inp.z = 0.0f;
    imodMatTransform(mat, &inp, &outp);
    invertX = outp.z < 0.;
    inp.x = 0.;
    inp.y = 1.;
    imodMatTransform(mat, &inp, &outp);
    invertY = outp.z < 0.;
    inp.y = 0.;
    inp.z = 1.;
    imodMatTransform(mat, &inp, &outp);
    invertZ = outp.z < 0.;
    imodMatDelete(mat);
  }

  if (!sTexImageSize && initTexMapping())
    return;

  tstep = sTexImageSize - 2;
  clampEnd = (tstep + 1.) / (tstep + 2.);

  // This used to be 1 with RGB data being passed in
  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  glEnable(GL_TEXTURE_2D);
 
 /* Draw Current Z image. */
  if (sFlags & IMODV_DRAW_CZ) {

    // Get the limits for the 3 axes.  In every section, xstr, xend etc are the full image
    // starting and ending coordinates in actual X, Y, and Z diections.
    setSliceLimits(izCur, zsize, invertZ, drawTrans, zstr, zend, idir);
    setCoordLimits(ixCur, xsize, sXdrawSize, xstr, xend);
    setCoordLimits(iyCur, ysize, sYdrawSize, ystr, yend);
    baseXstr = xstr;
    baseXsize = xend + 1 - xstr;
    baseYstr = ystr;
    baseYsize = yend + 1 - ystr;

    // When displaying a lower resolution cache, this converts all of the limits to 
    // loaded coordinates in that cache
    adjustLimitsForTiles(a, cacheInd, idir, xstr, xend, ystr, yend, zstr, zend,
                         pyrXoffset, pyrYoffset, pyrZoffset, pyrZscale);

    // Outer loop is on the coordinate that varies through multiple slices if any
    for (iz = zstr; idir * (zend - iz) >= 0 ; iz += idir) {
      setAlpha(iz, zstr, zend, idir);
      lowerLeft.z = lowerRight.z = upperRight.z = upperLeft.z = iz * pyrZscale + 
        pyrZoffset;

      // Load the area if this is the central Z value, and set up access to the tiles
      if (cacheInd >= 0) {
        if (iz == B3DNINT((izCur - pyrZoffset) / pyrZscale))
          a->vi->pyrCache->loadTilesContainingArea(cacheInd, baseXstr, baseYstr,
                                                   baseXsize, baseYsize, iz); 
        if (a->vi->pyrCache->fastPlaneAccess(cacheInd, iz, b3dZ, segments, startInds))
          continue;
      } else {

        // Or get the Z section
        idata = ivwGetZSection(a->vi, iz);
        if (!idata)
          continue;
        usidata = (b3dUInt16 **)idata;
      }

      // Loop on patches in Y, for each patch get limits to fill and set corners
      // ypatch is the starting coordinate and jend is the ending one
      for (ypatch = ystr; ypatch < yend; ypatch += tstep){
        clamp.y = clampEnd;
        jend = ypatch + tstep;
        if (jend > yend) {
          jend = yend;
          clamp.y = (yend + 1. - ypatch) / (tstep + 2.);
        }
        lowerRight.y = lowerLeft.y = ypatch * pyrXYscale + pyrYoffset;
        upperLeft.y = upperRight.y = jend * pyrXYscale + pyrYoffset;
          
        // Loop on patches in X, for each patch get limits to fill and set corners
        // xpatch is the starting coordinate and iend is the ending one
        for (xpatch = xstr; xpatch < xend; xpatch += tstep){
          clamp.x = clampEnd;
          iend = xpatch + tstep;
          if (iend > xend) {
            iend = xend;
            clamp.x = (xend + 1. - xpatch) / (tstep + 2.);
          }
          upperLeft.x = lowerLeft.x = xpatch * pyrXYscale + pyrXoffset;
          upperRight.x = lowerRight.x = iend * pyrXYscale + pyrXoffset;
          fillXsize = 2 + iend - xpatch;
        
          // Fill the data for one patch then draw the patch
          // each patch is filled to one more than its limits to allow interpolation
          // u and v are the coordinates in the plane being filled
          if (cacheInd >= 0) {
            fillPatchFromTiles(segments, startInds, a->vi->ushortStore, bmap, fillXsize,
                               xpatch-1, iend+1, ypatch-1, jend+1);
          } else if (a->vi->ushortStore) {
            for (j = ypatch-1; j < jend+1; j++) {
              v = (j - (ypatch-1));
              for (i = xpatch-1; i < iend+1; i++) {
                u = i - (xpatch-1);
                pix = bmap[usidata[j][i]];
                FILLDATA(pix);
              }
            }
          } else {
            for (j = ypatch-1; j < jend+1; j++) {
              v = (j - (ypatch-1));
              for (i = xpatch-1; i < iend+1; i++) {
                u = i - (xpatch-1);
                pix = idata[j][i];
                FILLDATA(pix);
              }
            }
          }
          
          imodvDrawTImage(&lowerLeft, &lowerRight, &upperRight, &upperLeft, &clamp,
                          (unsigned char *)sTdata, fillXsize, 2 + jend - ypatch);
        }
      }
    }
  }
  glDisable(GL_BLEND);

  /* Draw Current X image. */
  if ((sFlags & IMODV_DRAW_CX) && 
      !(a->stereo && a->imageStereo)) {

    setSliceLimits(ixCur, xsize, invertX, drawTrans, xstr, xend, idir);
    setCoordLimits(iyCur, ysize, sYdrawSize, ystr, yend);
    setCoordLimits(izCur, zsize, sZdrawSize, zstr, zend);

    adjustLimitsForTiles(a, cacheInd, idir, xstr, xend, ystr, yend, zstr, zend, 
                         pyrXoffset, pyrYoffset, pyrZoffset, pyrZscale);

    // Outer loop on X
    for (xpatch = xstr; idir * (xend - xpatch) >= 0 ; xpatch += idir) {
      setAlpha(xpatch, xstr, xend, idir);
      lowerLeft.x = lowerRight.x = upperRight.x = upperLeft.x = xpatch * pyrXYscale + 
        pyrXoffset;
      if (cacheInd >= 0) {
        if (a->vi->pyrCache->fastPlaneAccess(cacheInd, xpatch, b3dX, segments, startInds))
          continue;
      }

      // Next loop on Z patches
      for (zpatch = zstr; zpatch < zend; zpatch += tstep){
        clamp.y = clampEnd;
        jend = zpatch + tstep;
        if (jend > zend) {
          jend = zend;
          clamp.y = (zend + 1. - zpatch) / (tstep + 2.);
        }
        lowerRight.z = lowerLeft.z = zpatch * pyrZscale + pyrZoffset;
        upperLeft.z = upperRight.z = jend * pyrZscale + pyrZoffset;
        
        // Loop on Y patches
        for (ypatch = ystr; ypatch < yend; ypatch += tstep){
          clamp.x = clampEnd;
          iend = ypatch + tstep;
          if (iend > yend) {
            iend = yend;
            clamp.x = (yend + 1. - ypatch) / (tstep + 2.);
          }
          upperLeft.y = lowerLeft.y = ypatch * pyrXYscale + pyrYoffset;
          upperRight.y = lowerRight.y = iend * pyrXYscale + pyrYoffset;
          fillXsize = 2 + iend - ypatch;
     
          if (cacheInd >= 0) {
            fillPatchFromTiles(segments, startInds, a->vi->ushortStore, bmap, fillXsize,
                               ypatch-1, iend+1, zpatch-1, jend+1);
   
          // Handle cases of flipped or not with different loops to put test
          // on presence of data in the outer loop
          } else if (flipped) {
            for (i = ypatch-1; i < iend+1; i++) {
              u = i - (ypatch-1);
              if (imdata[i]) {
                
                // Invert Z when accessing cache for flipped data
                xconst = xpatch + (zsize - 1) * xsize;
                if (a->vi->ushortStore) {
                  for (j = zpatch-1; j < jend+1; j++) {
                    v = j - (zpatch-1);
                    pix = bmap[usimdata[i][xconst - j * xsize]];
                    FILLDATA(pix);
                  }
                } else {
                  for (j = zpatch-1; j < jend+1; j++) {
                    v = j - (zpatch-1);
                    pix = imdata[i][xconst - j * xsize];
                    FILLDATA(pix);
                  }
                }
              } else {
                for (j = zpatch-1; j < jend+1; j++) {
                  v = j - (zpatch-1);
                  FILLDATA(0);
                }
              }
            }
          } else {
            for (j = zpatch-1; j < jend+1; j++) {
              v = j - (zpatch-1);
              if (imdata[j]) {
                if (a->vi->ushortStore) {
                  for (i = ypatch-1; i < iend+1; i++) {
                    u = i - (ypatch-1);
                    pix = bmap[usimdata[j][xpatch + (i * xsize)]];
                    FILLDATA(pix);
                  }
                } else {
                  for (i = ypatch-1; i < iend+1; i++) {
                    u = i - (ypatch-1);
                    pix = imdata[j][xpatch + (i * xsize)];
                    FILLDATA(pix);
                  }
                }
              } else {
                for (i = ypatch-1; i < iend+1; i++) {
                  u = i - (ypatch-1);
                  FILLDATA(0);
                }
              }
            }
          }
          
          imodvDrawTImage(&lowerLeft, &lowerRight, &upperRight, &upperLeft, &clamp,
                          (unsigned char *)sTdata, fillXsize, 2 + jend - zpatch);
        }
      }
    }       
  }
  glDisable(GL_BLEND);

  /* Draw Current Y image. */
  if ((sFlags & IMODV_DRAW_CY) && 
      !(a->stereo && a->imageStereo)) {
    setSliceLimits(iyCur, ysize, invertY, drawTrans, ystr, yend, idir);
    setCoordLimits(ixCur, xsize, sXdrawSize, xstr, xend);
    setCoordLimits(izCur, zsize, sZdrawSize, zstr, zend);
    adjustLimitsForTiles(a, cacheInd, idir, xstr, xend, ystr, yend, zstr, zend, pyrXoffset,
                         pyrYoffset, pyrZoffset, pyrZscale);
    // Outer loop on Y
    for (ypatch = ystr; idir * (yend - ypatch) >= 0 ; ypatch += idir) {
      setAlpha(ypatch, ystr, yend, idir);
      lowerLeft.y = lowerRight.y = upperRight.y = upperLeft.y = ypatch * pyrXYscale + 
        pyrYoffset;
      if (cacheInd >= 0) {
        if (a->vi->pyrCache->fastPlaneAccess(cacheInd, ypatch, b3dY, segments, startInds))
          continue;
      }

      // Loop on patches in Z
      for (zpatch = zstr; zpatch < zend; zpatch += tstep) {
        clamp.y = clampEnd;
        jend = zpatch + tstep;
        if (jend > zend) {
          jend = zend;
          clamp.y = (zend + 1. - zpatch) / (tstep + 2.);
        }
        lowerRight.z = lowerLeft.z = zpatch * pyrZscale + pyrZoffset;
        upperLeft.z = upperRight.z = jend * pyrZscale + pyrZoffset;

        // Loop on patches in X
        for (xpatch = xstr; xpatch < xend; xpatch += tstep) {
          clamp.x = clampEnd;
          iend = xpatch + tstep;
          if (iend > xend) {
            iend = xend;
            clamp.x = (xend + 1. - xpatch) / (tstep + 2.);
          }
          upperLeft.x = lowerLeft.x = xpatch * pyrXYscale + pyrXoffset;
          upperRight.x = lowerRight.x = iend * pyrXYscale + pyrXoffset;
          fillXsize = 2 + iend - xpatch;
          
          if (cacheInd >= 0) {
            fillPatchFromTiles(segments, startInds, a->vi->ushortStore, bmap, fillXsize,
                               xpatch-1, iend+1, zpatch-1, jend+1);
          } else {

            // This one is easier, one outer loop and flipped, non-flipped, or
            // no data cases for inner loop
            for (j = zpatch-1; j < jend+1; j++) {
              v = j - (zpatch-1);
              if (flipped && imdata[ypatch]) {
                xconst = (zsize - 1 - j) * xsize;
                if (a->vi->ushortStore) {
                  for (i = xpatch-1; i < iend+1; i++) {
                    u = i - (xpatch-1);
                    pix = bmap[usimdata[ypatch][i + xconst]];
                    FILLDATA(pix);
                  }
                } else {
                  for (i = xpatch-1; i < iend+1; i++) {
                    u = i - (xpatch-1);
                    pix = imdata[ypatch][i + xconst];
                    FILLDATA(pix);
                  }
                }
              } else if (!flipped && imdata[j]) {
                if (a->vi->ushortStore) {
                  for (i = xpatch-1; i < iend+1; i++) {
                    u = i - (xpatch-1);
                    pix = bmap[usimdata[j][i + (ypatch * xsize)]];
                    FILLDATA(pix);
                  }
                } else {
                  for (i = xpatch-1; i < iend+1; i++) {
                    u = i - (xpatch-1);
                    pix = imdata[j][i + (ypatch * xsize)];
                    FILLDATA(pix);
                  }
                }
              } else {
                for (i = xpatch-1; i < iend+1; i++) {
                  u = i - (xpatch-1);
                  FILLDATA(0);
                }
              }
            }
          }
          imodvDrawTImage(&lowerLeft, &lowerRight, &upperRight, &upperLeft, &clamp,
                          (unsigned char *)sTdata, fillXsize, 2 + jend - zpatch);
        }
      }
    }
  }

  B3DFREE(bmap);
  glDisable(GL_BLEND);
  //glFlush();
  glDisable(GL_TEXTURE_2D);
  sNumSlices = numSave;
  if (imodDebug('v'))
    imodPrintStderr("Draw time %d  load %.2f draw %.2f\n", drawTime.elapsed(),
                    sWallLoad * 1000., sWallDraw * 1000.);
}
Пример #19
0
// Read an image as raw or byte data
static int ReadSection(ImodImageFile *inFile, char *buf, int byte)
{
  int ysize = inFile->ny;
  int i, pixel, y, maxind;
  float slope = inFile->slope;
  float offset = inFile->offset;
  int outmin = 0;
  int outmax = 255;
  int xmin, xmax, ymin, ymax;
  unsigned char *obuf;
  float *fbuf;
  unsigned char *bdata;
  unsigned char map[256];
  QRgb *rgbdata;
  QRgb rgbval;
  QImage *image;
  QImage image2;
  unsigned char *map2 = NULL;
  QVector<QRgb> colorTable;
     
  if (inFile->axis == 2)
    return -1;
  if (byte && (inFile->format != IIFORMAT_LUMINANCE))
    return -1;
  if (!inFile->header && iiReopen(inFile))
    return -1;
  image = (QImage *)inFile->header;

  // Convert a 16-bpp image to 32
  if (image->depth() == 16) {
    image2 = image->convertToFormat(QImage::Format_RGB32);
    if (image2.isNull())
      return -1;
    image = &image2;
  }

  colorTable = image->colorTable();

  /* set the dimensions to read in */
  xmin   = inFile->llx;
  ymin   = inFile->lly;
  if (inFile->urx < 0)
    xmax = inFile->nx-1;
  else
    xmax = inFile->urx;
  if (inFile->ury < 0)
    ymax = inFile->ny-1;
  else
    ymax = inFile->ury;

  if (byte) {

    // Get a map for scaling the bytes, then get composite map to go from
    // pixel indexes to scaled value;
    map2 = get_byte_map(slope, offset, outmin, outmax, 0);
    maxind = B3DMAX(0, colorTable.size() - 1);
    for (i = 0; i < 256; i++) {
      pixel = qRed(colorTable[B3DMIN(i, maxind)]);
      map[i] = map2[pixel];
    }
  }

  // Loop on the lines to get data
  obuf = (unsigned char *)buf;
  fbuf = (float *)buf;
  for (y = ymin; y <= ymax; y++) {
    bdata = image->scanLine(ysize - 1 - y);

    // Bytes: just map the index values
    if (byte == 1) {
      for (i = xmin; i <= xmax; i++)
        *obuf++ = map[bdata[i]];

    } else if (byte == 2) {
      for (i = xmin; i <= xmax; i++)
        *fbuf++ = bdata[i];


      // 8 bit RGB: look up in color table
    } else if (image->depth() == 8) {
      for (i = xmin; i <= xmax; i++) {
        rgbval = colorTable[bdata[i]];
        *obuf++ = qRed(rgbval);
        *obuf++ = qGreen(rgbval);
        *obuf++ = qBlue(rgbval);
      }

      // 32-bit: convert scan line pointer to rgb, get components
    } else {
      rgbdata = (QRgb *)bdata;
      for (i = xmin; i <= xmax; i++) {
        rgbval = rgbdata[i];
        *obuf++ = qRed(rgbval);
        *obuf++ = qGreen(rgbval);
        *obuf++ = qBlue(rgbval);
      }
    }
  }

  return 0;
}
Пример #20
0
// A new size comes in.  Compute a new rad value to keep scale constant, set window size
// accounting for the menu bar
void ImodvWindow::newResizerSize(int sizeX, int sizeY)
{
  ImodvApp *a = Imodv;
  a->imod->view->rad *= ((float)B3DMIN(sizeX, sizeY)) / B3DMIN(a->winx, a->winy);
  a->mainWin->resize(sizeX, sizeY + a->mainWin->height() - a->winy);
}
Пример #21
0
int main( int argc, char *argv[])
{
  int i, ind, col, maxValType;
  FILE *fout;
  Imod *mod;
  int npatch = 0;
  int numValues[MAX_VALUE_COLS], valueIDs[MAX_VALUE_COLS];
  int ix, iy, iz;
  int colForVal1 = 1;
  float dx, dy, dz;
  float value, maxVal[MAX_VALUE_COLS];
  int ob, co, listInd, listStart, numCols;
  Ipoint *pts;
  char format[MAX_VALUE_COLS][10];
  int colToTypeMap[MAX_VALUE_COLS];

  setExitPrefix("ERROR: imod2patch - ");


  if (argc < 3){
    if (argc != 1)
      printf("ERROR: imod2patch - wrong # of arguments\n");
    printf("imod2patch usage:\n");
    printf("imod2patch [-v col] imod_model patch_file\n");
    exit(1);
  }
  for (ind = 0; ind < MAX_VALUE_COLS; ind++) {
    numValues[ind] = 0;
    valueIDs[ind] = 0;
    colToTypeMap[ind] = -1;
    maxVal[ind] = -1.e37;
  }

  i = 1;
  if (!strcmp(argv[i], "-v")) {
    i++;
    colForVal1 = atoi(argv[i++]);
  }

  mod = imodRead(argv[i]);
  if (!mod)
    exitError("Reading model %s\n", argv[i]);
  
  if (imodBackupFile(argv[++i]))
    exitError("Renaming existing output file to %s\n", argv[i]);
  
  fout = fopen(argv[i], "w");
  if (!fout)
    exitError("Could not open %s\n", argv[i]);

  /* Count up patches and values and find max of values */
  for (ob = 0; ob < mod->objsize; ob++) {
    listInd = 0;
    for (co = 0; co < mod->obj[ob].contsize; co++) {
      listStart = listInd;
      if (mod->obj[ob].cont[co].psize >= 2) {
        npatch++;
        for (ind = 0; ind < MAX_VALUE_COLS; ind++) {
          listInd = listStart;
          if (istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE1 + 2 * ind, &value,
                              &listInd)) {
            maxVal[ind] = B3DMAX(maxVal[ind], value);
            numValues[ind]++;
          }
        }
      }
    }
  }
  /* printf("numval %d %d %d %f %f %f\n", numValues[0], numValues[1], numValues[2], 
     maxVal[0], maxVal[1], maxVal[2]); */

  /* Get the value ID's if any and convert an entered ID to a type #.  Also set format
     for output based on maximum value */
  maxValType = -1;
  numCols = 0;
  for (ind = 0; ind < MAX_VALUE_COLS; ind++) {
    strcpy(format[ind], "%10.4f");
    if (numValues[ind]) {
      numCols++;
      maxValType = ind;
      if (maxVal[ind] > 10.1)
        strcpy(format[ind], "%10.2f");
      else if (maxVal[ind] > 1.01)
        strcpy(format[ind], "%10.3f");
    }
  }
  for (ind = 0; ind < B3DMIN(maxValType + 1, mod->obj[0].extra[IOBJ_EXSIZE - 1]); ind++)
    valueIDs[ind] = mod->obj[0].extra[IOBJ_EXSIZE - 2 - ind];
  /*printf("# vla ID %d %d %d %d\n", maxValType, valueIDs[0],valueIDs[1],valueIDs[2]);*/

  /* Error checks on the column for value 1 */
  if (colForVal1 < 1 || colForVal1 > numCols) {
      if (numCols)
        exitError("The column for general value type must be between 1 and %d", numCols);
      exitError("There are no general values stored in the model");
  }
  colForVal1--;
  
  /* Set up map from column to value type index */
  if (numValues[0])
    colToTypeMap[colForVal1] = 0;
  col = 0;
  for (ind = 1; ind <= maxValType; ind++) {
    if (numValues[ind]) {
      if (!colToTypeMap[col])
        col++;
      colToTypeMap[col++] = ind;
    }
  }
  /*printf("%d %d %d %d\n", numCols, colToTypeMap[0], colToTypeMap[1], colToTypeMap[2]);*/

  /* Output the header line */
  fprintf(fout, "%d   edited positions", npatch);
  if (mod->obj[0].extra[IOBJ_EXSIZE - 1] > 0)
    for (col = 0; col < numCols; col++)
      fprintf(fout, "  %d", valueIDs[colToTypeMap[col]]);
  fprintf(fout, "\n");

  for (ob = 0; ob < mod->objsize; ob++) {
    listInd = 0;
    for (co = 0; co < mod->obj[ob].contsize; co++) {
      listStart = listInd;
      if (mod->obj[ob].cont[co].psize >= 2) {
        pts = mod->obj[ob].cont[co].pts;
        ix = pts[0].x + 0.5;
        iy = pts[0].y + 0.5;
        iz = pts[0].z + 0.5;
        dx = (pts[1].x - pts[0].x) / mod->pixsize;
        dy = (pts[1].y - pts[0].y) / mod->pixsize;
        dz = (pts[1].z - pts[0].z) / mod->pixsize;
        if (mod->flags & IMODF_FLIPYZ)
          fprintf(fout, "%6d %5d %5d %8.2f %8.2f %8.2f", 
                  ix, iz, iy, dx, dz, dy);
        else
          fprintf(fout, "%6d %5d %5d %8.2f %8.2f %8.2f", 
                  ix, iy, iz, dx, dy, dz);
        for (col = 0; col < numCols; col++) {
          ind = colToTypeMap[col];
          if (numValues[ind]) {
            listInd = listStart;
            value = 0.;
            istoreFindValue(mod->obj[ob].store, co, GEN_STORE_VALUE1 + 2 * ind, &value,
                            &listInd);
            fprintf(fout, format[ind], value);
          }
        }
        fprintf(fout, "\n");

      }
    }
  }
  fclose(fout);
  exit(0);
}
Пример #22
0
/*
 * Sets up variables for defining the input size and center, and section lists
 * for the 2D processing case, and also sets ox, oy,oz and output mode.
 */
void set_input_options(ClipOptions *opt, MrcHeader *hin)
{
  int i, zst, znd, ozst;

  if (opt->nofsecs == IP_DEFAULT){
    opt->nofsecs = hin->nz;
    opt->secs = (int *)malloc(sizeof(int) * hin->nz);
    for (i = 0; i < hin->nz; i++)
      opt->secs[i] = i;
     
  }
  if (opt->dim == 3){
    if (opt->iz == IP_DEFAULT){
      opt->iz = hin->nz;
    }
    if (opt->cz == IP_DEFAULT){
      opt->cz = hin->nz * 0.5f;
    }

    /* If there is no output entry, make it be same as input; but if there is,
       and it is smaller output, trim input to that size */
    if (opt->oz == IP_DEFAULT)
      opt->oz = opt->iz;
    else if (opt->iz > opt->oz)
      opt->iz = opt->oz;

    /* Set up a section list for the case where something is treated as
       2d without -2d being given */
    if (opt->nofsecs != IP_DEFAULT)
      free(opt->secs);
    zst = (int)floor(opt->cz - opt->iz / 2.);
    znd = B3DMAX(B3DMIN(zst + opt->iz - 1, hin->nz - 1), 0);
    zst = B3DMAX(B3DMIN(zst, hin->nz - 1), 0);
    opt->nofsecs = znd + 1 - zst;
    opt->secs = (int *)malloc(sizeof(int) * opt->nofsecs);
    for (i = zst; i <= znd; i++)
      opt->secs[i - zst] = i;

    /* If requested output is larger than this output set, keep track of 
       blank slices to put out before and after */
    if (opt->oz != IP_DEFAULT && opt->oz > opt->nofsecs) {
      ozst = (int)floor(opt->cz - opt->oz / 2.);
      opt->outBefore = B3DMAX(0, zst - ozst);
      opt->outAfter = opt->oz - opt->nofsecs - opt->outBefore;
      if (opt->outAfter < 0) {
        opt->outBefore += opt->outAfter;
        opt->outAfter = 0;
      }
    }
  } else {

    /* 2D case: use section list size for default output size */
    if (opt->oz == IP_DEFAULT)
      opt->oz = opt->nofsecs;
  }

  /* Convert starting, ending X or Y to ix/cx entries - main routine already
     checked for conflict */
  if (opt->x != IP_DEFAULT) {
    opt->x2 = B3DMAX(opt->x, opt->x2);
    opt->cx = (opt->x + opt->x2 + 1) / 2.;
    opt->ix = opt->x2 + 1 - opt->x;
  }
  if (opt->ix == IP_DEFAULT)
    opt->ix = hin->nx;
  if ((int)opt->cx == IP_DEFAULT)
    opt->cx = hin->nx * 0.5f;
  if (opt->ox == IP_DEFAULT) {
    opt->ox = opt->ix;
    if (opt->process == IP_UNPACK)
      opt->ox *= 2;
  } else {
    if (!opt->ocanresize){
      show_warning("clip - Process can't change output size.");
      opt->ox = opt->ix;
    }
  }

  if (opt->y != IP_DEFAULT) {
    opt->y2 = B3DMAX(opt->y, opt->y2);
    opt->cy = (opt->y + opt->y2 + 1) / 2.;
    opt->iy = opt->y2 + 1 - opt->y;
  }
  if (opt->iy == IP_DEFAULT)
    opt->iy = hin->ny;
  if ((int)opt->cy == IP_DEFAULT)
    opt->cy = hin->ny * 0.5f;
  if (opt->oy == IP_DEFAULT)
    opt->oy = opt->iy;
  else{
    if (!opt->ocanresize){
      show_warning("clip - Process can't change output size.");
      opt->oy = opt->iy;
    }
  }

  if (opt->pad == IP_DEFAULT)
    opt->pad = hin->amean;

  if (opt->mode == IP_DEFAULT)
    opt->mode = hin->mode;
}
Пример #23
0
/* 
 * Write one slice to output file
 * kSec is the index of the sections being processed, 
 * zWrite is address of z value at which to write, maintained here
 * freeSlice 1 indicates to free the slice when done
 */
int clipWriteSlice(Islice *slice, MrcHeader *hout, ClipOptions *opt, int kSec, 
                   int *zWrite, int freeSlice)
{
  Islice *ps = NULL;
  Islice *s;
  int z;
  int blankBefore = 0;
  int blankAfter = 0;

  /* Ignore if output size is smaller than # being processed */
  if (kSec < (opt->nofsecs - opt->oz) / 2 || 
      kSec >= (opt->nofsecs - opt->oz) / 2 + opt->oz) {
    if (freeSlice)
      sliceFree(slice);
    return 0;
  }

  /* determine if blank slices need to be written before or after this slice */
  if (opt->oz > opt->nofsecs) {
    if (!kSec) {
      if (opt->outBefore == IP_DEFAULT)
        blankBefore = (opt->oz - opt->nofsecs) / 2;
      else
        blankBefore = opt->outBefore;
    }
    if (kSec == opt->nofsecs - 1) {
      if (opt->outAfter == IP_DEFAULT)
        blankAfter = opt->oz - opt->nofsecs - (opt->oz - opt->nofsecs) / 2;
      else
        blankAfter = opt->outAfter;
    }
    if (blankBefore || blankAfter) {
      ps = clipBlankSlice(hout, opt);
      if (!ps)
        return -1;
    }
  }

  /* Write blank slices before */
  for (z = 0; z < blankBefore; z++)
    if (mrc_write_slice((void *)ps->data.b, hout->fp, hout, (*zWrite)++, 'z'))
      return -1;
    
  /* convert slice to output mode if needed */
  if (slice->mode != opt->mode && sliceNewMode(slice, opt->mode) < 0)
    return -1;

  /* Resize slice if necessary */
  s = slice;
  if (opt->ox != slice->xsize || opt->oy != slice->ysize) {
    slice->mean = opt->pad;
    s = mrc_slice_resize(slice, opt->ox, opt->oy);
    if (!s) {
      fprintf(stderr, "clipWriteSlice: error resizing slice.\n");
      return(-1);
    }
  }
   
  /*   maintain min & max, add to mean unless overwriting */
  sliceMMM(s);
  hout->amin = B3DMIN(hout->amin, s->min);
  hout->amax = B3DMAX(hout->amax, s->max);
  if (opt->add2file != IP_APPEND_OVERWRITE)
    hout->amean += (s->mean + (blankBefore + blankAfter) * opt->pad) /
      hout->nz;

  /* Write slice, free slices as needed */
  if (mrc_write_slice((void *)s->data.b, hout->fp, hout, (*zWrite)++, 'z'))
    return -1;
  if (opt->ox != slice->xsize || opt->oy != slice->ysize)
    sliceFree(s);
  if (freeSlice)
    sliceFree(slice);

  /* Write blank slices after */
  for (z = 0; z < blankAfter; z++)
    if (mrc_write_slice((void *)ps->data.b, hout->fp, hout, (*zWrite)++, 'z'))
      return -1;
  if (ps)
    sliceFree(ps);
  return 0;
}
Пример #24
0
int main( int argc, char *argv[] )
{

  int    i = 0;
  FILE   *fin, *fout;
  struct MRCheader hdata, hout;
  struct MRCheader *hptr;
  unsigned char *buf;
  int bsize, csize, dsize;
  int inside = 0;
  int ntaper = DEFAULT_TAPER;
  int taperEntered = 0;
  Islice slice;
  int zmin = -1, zmax = -1;
  int secofs;
  char *progname = imodProgName(argv[0]);
  setStandardExitPrefix(progname);

  if (argc < 2){
    fprintf(stderr, 
            "%s version %s\n", progname, VERSION_NAME);
    imodCopyright();
    mrctaper_help(progname);
    exit(3);
  }

  for (i = 1; i < argc; i++) {
    if (argv[i][0] == '-') {
      switch (argv[i][1]) {
          
      case 'i':
        inside = 1;
        break;

      case 't':
        taperEntered = 1;
        if (argv[i][2] != 0x00)
          sscanf(argv[i], "-t%d", &ntaper);
        else
          sscanf(argv[++i], "%d", &ntaper);
        break;

      case 'z':
        if (argv[i][2] != 0x00)
          sscanf(argv[i], "-z%d%*c%d", &zmin, &zmax);
        else
          sscanf(argv[++i], "%d%*c%d", &zmin, &zmax);
        break;

      default:
        printf("ERROR: %s - illegal option\n", progname);
        mrctaper_help(progname);
        exit(1);
        break;
      }
    } else
      break;
  }

  if (i < (argc - 2) || i == argc){
    mrctaper_help(progname);
    exit(3);      
  }

  if (ntaper < 1 || ntaper > 127)
    exitError("Taper must be between 1 and 127.");

  if (i < argc - 1)
    fin = iiFOpen(argv[i++], "rb");
  else
    fin = iiFOpen(argv[i++], "rb+");

  if (fin == NULL)
    exitError("Opening %s.", argv[i - 1]);
  if (mrc_head_read(fin, &hdata))
    exitError("Can't Read Input File Header.");

  if (sliceModeIfReal(hdata.mode) < 0)
    exitError("Can operate only on byte, integer and real data.");

  if (!taperEntered) {
    ntaper = (hdata.nx + hdata.ny) / 200;
    ntaper = B3DMIN(127, B3DMAX(DEFAULT_TAPER, ntaper));
    printf("Tapering over %d pixels\n", ntaper);
  }
     
  if (zmin == -1 && zmax == -1) {
    zmin = 0;
    zmax = hdata.nz - 1;
  } else {
    if (zmin < 0)
      zmin = 0;
    if (zmax >= hdata.nz)
      zmax = hdata.nz - 1;
  }
     
  if (i < argc) {
    fout = iiFOpen(argv[i], "wb");
    if (fout == NULL)
      exitError("Opening %s.", argv[i]);
    hout = hdata;
    hout.fp = fout;

    /* DNM: eliminate extra header info in the output, and mark it as not swapped  */
    mrcInitOutputHeader(&hout);
    hptr = &hout;
    hout.nz = zmax + 1 - zmin;
    hout.mz = hout.nz;
    hout.zlen = hout.nz;
    secofs = zmin;
  } else {
    if (b3dOutputFileType() == IIFILE_TIFF)
      exitError("Cannot write to an existing TIFF file.");
      
    hptr = &hdata;
    fout = fin;
    secofs = 0;
  }
     
  mrc_getdcsize(hdata.mode, &dsize, &csize);

  bsize = hdata.nx * hdata.ny;
  buf = (unsigned char *)malloc(dsize * csize * bsize);
     
  if (!buf)
    exitError("Couldn't get memory for slice.");
  sliceInit(&slice, hdata.nx, hdata.ny, hdata.mode, buf);

  for (i = zmin; i <= zmax; i++) {
    printf("\rDoing section #%4d", i);
    fflush(stdout);
    if (mrc_read_slice(buf, fin, &hdata, i, 'Z'))
      exitError("Reading section %d.", i);
      
    if (sliceTaperAtFill(&slice, ntaper, inside))
      exitError("Can't get memory for taper operation.");
          
    if (mrc_write_slice(buf, fout, hptr, i - secofs, 'Z'))
      exitError("Writing section %d.", i);
  }
  puts("\nDone!");

  mrc_head_label(hptr, "mrctaper: Image tapered down to fill value at edges");

  mrc_head_write(fout, hptr);
  iiFClose(fout);

  return(0);
}
Пример #25
0
/* Write the data volume with potential padding */
int grap_volume_write(Istack *v,  MrcHeader *hout, ClipOptions *opt)
{
  FILE *fp = hout->fp;
  int zs, ks, z;
  int k;
  float min, max, mean, zscale;
  Islice  *s, *ps = NULL;
  int labels;

  if (opt->mode == IP_DEFAULT)
    opt->mode = v->vol[0]->mode;
  if (opt->ox == IP_DEFAULT)
    opt->ox = v->vol[0]->xsize;
  if (opt->oy == IP_DEFAULT)
    opt->oy = v->vol[0]->ysize;
  if (opt->oz == IP_DEFAULT)
    opt->oz = v->zsize;

  if (v->vol[0]->mode != opt->mode)
    for(k = 0; k < v->zsize; k++){
      sliceNewMode(v->vol[k], opt->mode);
    }

  /* calculate min, max, mean of volume. */
  sliceMMM(v->vol[0]);
  min = v->vol[0]->min;
  max = v->vol[0]->max;
  mean = v->vol[0]->mean;
  for(k = 1; k < v->zsize; k++){
    sliceMMM(v->vol[k]);
    min = B3DMIN(min, v->vol[k]->min);
    max = B3DMAX(max, v->vol[k]->max);
    mean += v->vol[k]->mean;
  }
  mean /= (float)v->zsize;

  /* DNM 6/26/02: do not make a new header if appending or overwriting! */
  switch(opt->add2file){
  case IP_APPEND_OVERWRITE:
    ks = opt->isec;
    hout->nz = ks + opt->oz;
    opt->ox = hout->nx;
    opt->oy = hout->ny;
    if (hout->mode != v->vol[0]->mode){
      fprintf(stderr,
              "overwriting requires data modes to be the same.\n");
      return(-1);
    }
    /* DNM 6/26/02: fix min and max, also fix mz and zlen */
    /* DNM 9/13/02: oops, had xlen instead of zlen */
    /* todo: recalc mmm.  This is a start but not much */
    hout->amin = B3DMIN(min, hout->amin);
    hout->amax = B3DMAX(max, hout->amax);
    zscale = hout->zlen / hout->mz;
    hout->mz = hout->nz;
    hout->zlen = hout->mz * zscale;
    break;

  case IP_APPEND_ADD:
    ks = hout->nz;
    hout->nz = hout->nz + opt->oz;
    opt->ox = hout->nx;
    opt->oy = hout->ny;
    if (hout->mode != v->vol[0]->mode){
      fprintf(stderr, "inserting requires data modes to be the same.\n");
      return(-1);
    }
    hout->amin = B3DMIN(min, hout->amin);
    hout->amax = B3DMAX(max, hout->amax);
    hout->amean = ((hout->amean * ks) + (mean * opt->oz)) / hout->nz; 
    zscale = hout->zlen / hout->mz;
    hout->mz = hout->nz;
    hout->zlen = hout->mz * zscale;
    break;

  case IP_APPEND_FALSE:

    /* New file: reinitialize header but preserve the labels, set 
       min/max/mean */
    labels = hout->nlabl;
    mrc_head_new(hout, opt->ox, opt->oy, opt->oz, v->vol[0]->mode);
    hout->nlabl = labels;
    hout->amin = min;
    hout->amax = max;
    hout->amean = mean;
    ks = 0;

  }

  if (opt->pad == IP_DEFAULT)
    opt->pad = hout->amean;

  if (mrc_head_write(fp, hout))
    return -1;

  zs = (v->zsize - opt->oz) / 2;
  for (k = ks, z = zs; k < hout->nz; k++, z++) {

    /* printf("%d %d\n", k, z);*/
    /* Write blank slice outside z range */
    if ((z < 0) || (z >= v->zsize)) {
      if (!ps) {
        ps = clipBlankSlice(hout, opt);
        if (!ps)
          return -1;
      }
      if (mrc_write_slice((void *)ps->data.b, fp, hout, k, 'z'))
        return (-1);
    } else {

      /* Resize slice only if necessary */
      s = v->vol[z];
      if (opt->ox != v->vol[0]->xsize || opt->oy != v->vol[0]->ysize) {
        v->vol[z]->mean =  opt->pad;
        s = mrc_slice_resize(v->vol[z], opt->ox, opt->oy);
        if (!s){
          fprintf(stderr, "volume_write: error resizing slice.\n");
          return(-1);
        }
      }
      if (mrc_write_slice((void *)s->data.b, fp, hout, k, 'z'))
        return (-1);
      if (opt->ox != v->vol[0]->xsize || opt->oy != v->vol[0]->ysize)
        sliceFree(s);
    }
  }

  if (ps)
    sliceFree(ps);
  return(0);
}
Пример #26
0
/* Really fill the slice data for one slice */
void TumblerWindow::fillASlice(TumblerStruct *xtum)
{
  unsigned short *sdata;
  short *ndata = xtum->count->data.s;
  int xysize = xtum->slice->xsize * xtum->slice->ysize;
  int n;
  float xs, ys, zs, xt, yt, zt;
  float x, y, z;
  float xsx, xsy, xsz;
  float ysx, ysy, ysz;
  float zsx, zsy, zsz;
  float xtz, ytz, ztz;
  int isize, jsize;
  int ksize, xsize, ysize, zsize;
  int xi, yi, zi;
  int i, j, k;
  float zoomfac;
  int xmin,ymin,zmin,xmax,ymax,zmax;
  int val;
  float dx, dy, dz;
  float x1, x2, y1, y2, z1, z2;
  float a, b, c, d, e, f;
  int pxi, nxi, pyi, nyi, pzi, nzi, cindex;
  int maxval = xtum->maxval;
  int minval = xtum->minval;
  float dsum;
  int nsum, shortcut, izoom, ilimshort, jlimshort, ishort, fillval, nmax;
  float zoom = xtum->zoom;
  unsigned char *bmap = NULL;
  sdata = (unsigned short *)xtum->slice->data.s;

  if (xtum->slice->xsize <= 0)
    return;
  if (xtum->slice->ysize <= 0)
    return;

  if (xtum->vi->ushortStore) {
    bmap = ivwUShortInRangeToByteMap(xtum->vi);
    if (!bmap)
      return;
  }

  zoomfac = xtum->highres ? zoom : 1.0;
  xmin = xtum->cx - xtum->nx/2;
  if (xmin < 0) xmin = 0;
  ymin = xtum->cy - xtum->ny/2;
  if (ymin < 0) ymin = 0;
  zmin = xtum->cz - xtum->nz/2;
  if (zmin < 0) zmin = 0;
  xmax = xtum->cx + xtum->nx/2;
  if (xmax >= xtum->vi->xsize)
    xmax = xtum->vi->xsize - 1;
  ymax = xtum->cy + xtum->ny/2;
  if (ymax >= xtum->vi->ysize)
    ymax = xtum->vi->ysize - 1;
  zmax = xtum->cz + xtum->nz/2;
  if (zmax >= xtum->vi->zsize)
    zmax = xtum->vi->zsize - 1;

  isize = xtum->slice->xsize;
  jsize = xtum->slice->ysize;
  ksize = xtum->ms;

  xsize = xtum->vi->xsize;
  ysize = xtum->vi->ysize;
  zsize = xtum->vi->zsize;

  xsx = xtum->xstep.x/zoomfac;
  xsy = xtum->xstep.y/zoomfac; 
  xsz = xtum->xstep.z/zoomfac;
     
  ysx = xtum->ystep.x/zoomfac; 
  ysy = xtum->ystep.y/zoomfac; 
  ysz = xtum->ystep.z/zoomfac;

  /* Steps in Z are independent of highres */
  zsx = xtum->zstep.x; 
  zsy = xtum->zstep.y;
  zsz = xtum->zstep.z;

  /* DNM 4/29/04: rewrote for compactness and clarity */
  xs = xtum->cx - 0.5f * (xsx * isize + ysx * jsize + zsx * xtum->ms);
  ys = xtum->cy - 0.5f * (xsy * isize + ysy * jsize + zsy * xtum->ms);
  zs = xtum->cz - 0.5f * (xsz * isize + ysz * jsize + zsz * xtum->ms);

  /* imodPrintStderr("xyzs %f %f %f\n", xs, ys, zs); */
  x = xs; y = ys; z = zs;

  shortcut = 0;
  izoom = (int)zoom;
  if (xtum->highres && (zoom == izoom) && (zoom > 1.0)) {
    shortcut = 1;
    ilimshort = izoom * ((isize - 1) / izoom - 1);
    jlimshort = izoom * ((jsize - 1) / izoom - 1);
  } else
    izoom = 1;

  for(n = 0; n < xysize; n++) {
    sdata[n] = 0;
    ndata[n] = 0;
  }

  for(k = 0; k < ksize; k++){
    xtz = x; ytz = y; ztz = z;
    for(j = 0, n = 0; j < jsize; j++){
      xt = x; yt = y; zt = z;
      cindex = j * isize;
      for(i = 0; i < isize; i++){

        /* DNM 2/25/03: eliminate floor as in slicer */
        xi = (int)x;
        yi = (int)y;
        zi = (int)(z + 0.5);

        if ((xi >= xmin) && (xi <= xmax) &&
            (yi >= ymin) && (yi <= ymax) &&
            (zi >= zmin) && (zi <= zmax)
            ){
          val = (*ivwFastGetValue)(xi, yi, zi);
                         
	  if (xtum->highres) {
	    dx = x - xi - 0.5;
	    dy = y - yi - 0.5;
	    dz = z - zi;
	    
	    pxi = xi - 1;
	    nxi = xi + 1;
	    pyi = yi - 1;
	    nyi = yi + 1;
	    pzi = zi - 1;
	    nzi = zi + 1;
	    
	    if (pxi < 0) pxi = 0;
	    if (nxi >= xsize) nxi = xi;
	    if (pyi < 0) pyi = 0;
	    if (nyi >= ysize) nyi = yi;
	    if (pzi < 0) pzi = 0;
	    if (nzi >= zsize) nzi = zi;
	    
	    
	    x1 = (*ivwFastGetValue)(pxi,  yi,  zi);
	    x2 = (*ivwFastGetValue)(nxi,  yi,  zi);
	    y1 = (*ivwFastGetValue)( xi, pyi,  zi);
	    y2 = (*ivwFastGetValue)( xi, nyi,  zi);
	    z1 = (*ivwFastGetValue)( xi,  yi, pzi);
	    z2 = (*ivwFastGetValue)( xi,  yi, nzi);
	    
	    a = (x1 + x2) * 0.5f - (float)val;
	    b = (y1 + y2) * 0.5f - (float)val;
	    c = (z1 + z2) * 0.5f - (float)val;
	    d = (x2 - x1) * 0.5f;
	    e = (y2 - y1) * 0.5f;
	    f = (z2 - z1) * 0.5f;
	    val = (int) ((a * dx * dx) + (b * dy * dy) + (c * dz * dz)
	      + (d * dx) + (e * dy) + (f * dz) + (float)val + 0.5);
	  }
          if (bmap)
            val = bmap[B3DMAX(0, B3DMIN(65535, val))];
          if (val > maxval)
            val = maxval;
          if (val < minval)
            val = minval;
          sdata[cindex + i] += (unsigned short)val;
          ndata[cindex + i]++;
        }
        x += xsx;
        y += xsy;
        z += xsz;

	/* If taking short cut, advance the source position to get to next
	 unzoomed pixel position */
        if (shortcut != 0 && ((i >= izoom && j % izoom == 0) ||
                              (i >= izoom - 1 && j % izoom != 0))
            && i < ilimshort && j >= izoom && j < jlimshort) {
          ishort = izoom - 1;
          if (j % izoom)
            ishort = ilimshort - izoom;
          x += xsx * ishort;
          y += xsy * ishort;
          z += xsz * ishort;
          i += ishort;
        }
      }
      x = xt + ysx;
      y = yt + ysy;
      z = zt + ysz;
    }
    x = xtz + zsx;
    y = ytz + zsy;
    z = ztz + zsz;
  }

  nmax = 0;
  nsum = 0;
  dsum = 0.;
  for (n = 0; n < xysize; n++) {
    if (nmax < ndata[n])
      nmax = ndata[n];
    nsum += ndata[n];
    dsum += sdata[n];
  }
  fillval = (int)(dsum / nsum + 0.5);

  for(n = 0; n < xysize; n++)
    sdata[n] += (nmax - ndata[n]) * fillval;

  xtum->fillval = fillval * nmax;

  if (shortcut)
    slicerCubicFillin(sdata, isize, jsize, izoom, ilimshort, jlimshort, 0, 65535, 0);
  B3DFREE(bmap);
}
Пример #27
0
/*!
 * Fills [mat] with the coefficients of a Gaussian kernel with standard deviation 
 * [sigma].  The size of the kernel is set to 3 for [sigma] up to 1., 5 for [sigma]
 * up to 2., etc., up to the size given by [limit]. The size is returned in [dim].
 * The coefficients are scaled to sum to 1.
 */
void scaledGaussianKernel(float *mat, int *dim, int limit, float sigma)
{
  *dim = 2 * (int)ceil((double)sigma) + 1;
  *dim = B3DMIN(limit, *dim);
  sliceGaussianKernel(mat, *dim, sigma);
}
Пример #28
0
/* Draw one of the image arrays in a subarea of the window */
void TumblerWindow::drawSubArea(TumblerStruct *xtum, unsigned short *sdata,
				    int llx, int urx)
{
  float scale, offset;
  unsigned int i, xysize;
  unsigned char *data;
  b3dUInt16 *usdata;
  float tf, tmax, tmin;
  int xo, yo;
  int zoom = xtum->zoom;

  xysize = xtum->slice->xsize * xtum->slice->ysize;
  data = xtum->bwslice->data.b;
  usdata = xtum->bwslice->data.us;

  scaleData(xtum, sdata);

  tmax = 255.0f;
  tmin = 0.0f;
  scale  = xtum->scale;
  offset = xtum->offset;
     
  /* DNM: scale for depth 8 only if not rgba */
  if (App->depth == 8 && !App->rgba){
    scale *= xtum->vi->rampsize/256.0f;
    tmax = xtum->vi->rampbase + xtum->vi->rampsize;
    tmin = xtum->vi->rampbase;
    for(i = 0; i < xysize; i++){
      tf = ((sdata[i] + offset) * scale) + xtum->vi->rampbase;
      if (tf < tmin) tf = tmin;
      if (tf > tmax) tf = tmax;
      data[i] = (unsigned char)tf;
    }
  } else if (xtum->vi->ushortStore) {
    tmax = 65535.;
    scale *= 256.;
    for (i = 0; i < xysize; i++) {
      tf = (sdata[i] + offset) * scale;
      usdata[i] = (b3dUInt16)B3DMAX(tmin, B3DMIN(tmax, tf));
    }
  } else {
    for(i = 0; i < xysize; i++){
      tf = (sdata[i] + offset) * scale;
      data[i] = (unsigned char)B3DMAX(tmin, B3DMIN(tmax, tf));
    }
  }

  if (xtum->highres)
    zoom = 1;

  /* DNM 1/20/02: add slice argument to graphics calls; make it -1 to 
     prevent image re-use */
  
  b3dDrawGreyScalePixelsSubArea
    (xtum->image, ivwMakeLinePointers(xtum->vi, data, xtum->slice->xsize,
                                      xtum->slice->ysize, xtum->vi->rawImageStore),
     xtum->slice->xsize, xtum->slice->ysize,
     0, 0, llx, 0, urx, xtum->height,
     xtum->vi->rampbase, zoom,
     &xo, &yo, -1);
}
Пример #29
0
/*!
 * Converts the data in slice [s] from its current mode to [mode], allocating 
 * a new data array as needed.  Complex values are converted to others by 
 * taking the magnitude.  Values are converted to complex modes by setting the
 * real component to the value, and the imaginary component to 0.  RGB values
 * are converted by taking a weighted sum of components.  When converting to a
 * mode with integer or byte values, the data are truncated to fit within the
 * range of the new mode.  Returns the new mode or -1 for error.
 */
int sliceNewMode(Islice *s, int mode)
{
  Islice *ns;
  Ival val;
  int i, j;
  int default_copy = 0;
  int limit_val = 0;
  float minval, maxval;

  if (!s)
    return(-1);
     
  if (s->mode == mode)
    return(mode);

  ns = sliceCreate(s->xsize, s->ysize, mode);

  /* Set up limiting values */
  if (mode == MRC_MODE_BYTE || mode == MRC_MODE_RGB) {
    limit_val = 1;
    minval = 0.;
    maxval = 255;
  } else if (mode == MRC_MODE_SHORT) {
    limit_val = 1;
    minval = -32768.;
    maxval = 32767.;
  } else if (mode == MRC_MODE_USHORT) {
    limit_val = 1;
    minval = 0.;
    maxval = 65535.;
  }

  if (!ns)
    return(-1);

  switch(s->mode){
  case MRC_MODE_BYTE:
  case MRC_MODE_SHORT:
  case MRC_MODE_USHORT:
  case MRC_MODE_FLOAT:
    switch(mode){
    case MRC_MODE_BYTE:
    case MRC_MODE_SHORT:
    case MRC_MODE_USHORT:
    case MRC_MODE_FLOAT:
      default_copy = 1;
      break;
    case MRC_MODE_COMPLEX_FLOAT:
    case MRC_MODE_COMPLEX_SHORT:
      val[1] = 0;
      default_copy = 1;
      break;
    case MRC_MODE_RGB:
      for(j = 0; j < s->ysize; j++)
        for(i = 0; i < s->xsize; i++){
          sliceGetVal(s,  i, j, val);
          if (limit_val)
            val[0] = B3DMIN(maxval, B3DMAX(minval, val[0]));
          val[2] = val[1] = val[0];
          slicePutVal(ns, i, j, val);
        }
      break;
    default:
      default_copy = 1;
      break;
    }
    break;

  case MRC_MODE_COMPLEX_FLOAT:
  case MRC_MODE_COMPLEX_SHORT:
    switch(mode){
    case MRC_MODE_BYTE:
    case MRC_MODE_SHORT:
    case MRC_MODE_USHORT:
    case MRC_MODE_FLOAT:
      for(j = 0; j < s->ysize; j++)
        for(i = 0; i < s->xsize; i++){
          sliceGetVal(s,  i, j, val);
          val[0] = (float)sqrt(val[0] * val[0] + val[1] * val[1]);
          if (limit_val)
            val[0] = B3DMIN(maxval, B3DMAX(minval, val[0]));
          slicePutVal(ns, i, j, val);
        }
      break;
    case MRC_MODE_COMPLEX_FLOAT:
    case MRC_MODE_COMPLEX_SHORT:
      default_copy = 1;
      break;
    case MRC_MODE_RGB:
      for(j = 0; j < s->ysize; j++)
        for(i = 0; i < s->xsize; i++){
          sliceGetVal(s,  i, j, val);
          val[0] = (float)sqrt(val[0] * val[0] + val[1] * val[1]);
          if (limit_val)
            val[0] = B3DMIN(maxval, B3DMAX(minval, val[0]));
          val[2] = val[1] = val[0];
          slicePutVal(ns, i, j, val);
        }
      break;
    }
    break;

  case MRC_MODE_RGB:
    switch(mode){
    case MRC_MODE_BYTE:
    case MRC_MODE_SHORT:
    case MRC_MODE_USHORT:
    case MRC_MODE_FLOAT:
      for(j = 0; j < s->ysize; j++)
        for(i = 0; i < s->xsize; i++){
          sliceGetVal(s,  i, j, val);
          val[0] = (val[0] * 0.3f) +
            (val[1] * 0.59f) + (val[2] * 0.11f);
          if (limit_val)
            val[0] = B3DMIN(maxval, B3DMAX(minval, val[0]));
          slicePutVal(ns, i, j, val);
        }
      break;
           
    case MRC_MODE_COMPLEX_FLOAT:
    case MRC_MODE_COMPLEX_SHORT:
      for(j = 0; j < s->ysize; j++)
        for(i = 0; i < s->xsize; i++){
          sliceGetVal(s,  i, j, val);
          val[0] = (val[0] * 0.3f) +
            (val[1] * 0.59f) + (val[2] * 0.11f);
          val[1] = 0;
          slicePutVal(ns, i, j, val);
        }
      break;
           
    default:
      default_copy = 1;
      break;
    }
    break;

  default:
    default_copy = 1;
    break;

  }

  if (default_copy){
    for(j = 0; j < s->ysize; j++)
      for(i = 0; i < s->xsize; i++){
        sliceGetVal(s,  i, j, val);
        if (limit_val)
          val[0] = B3DMIN(maxval, B3DMAX(minval, val[0]));
        slicePutVal(ns, i, j, val);
      }
  }
     
  free(s->data.b);

  /* 2/3/07: switch from copying ns to s to just setting data and mode */
  s->data.b = ns->data.b;
  s->mode = mode;
  free(ns);
  return(mode);
}
Пример #30
0
/*
 * Main entry
 */
int main( int argc, char *argv[])
{
    Imod *imod;
    Iobj *obj;
    Ipoint point;
    Istore store;
    FILE *infp;
    char line[1024];
    int open = 0, zsort = 0, scat = 0, numPerCont = 0, fromZero = 0, zFromZero = 0;
    int err, nvals, nread, ob, co, lineNum, after, needcont, i, numOffset, linelen;
    int numPts = 0, numConts = 0, numObjs = 0;
    int sphere = 0, circle = 0;
    float tst1, tst2, xx, yy, zz, value;
    float zOffset = 0.;
    int numColors = 0;
    int numNames = 0;
    int hasValues = 0;
    int contValues = 0;
    int *red, *green, *blue;
    int directScale = 0;
    float xscale = 1., yscale = 1., zscale = 1., xtrans = 0., ytrans = 0., ztrans = 0.;
    char **names = NULL;

    char *progname = imodProgName(argv[0]);
    char *filename, *imagename;
    MrcHeader hdata;
    IrefImage *ref;
    FILE *fpimage = NULL;
    char *errString;
    int numOptArgs, numNonOptArgs;

    /* Fallbacks from    ../manpages/autodoc2man 2 1 point2model  */
    int numOptions = 16;
    const char *options[] = {
        "input:InputFile:FN:", "output:OutputFile:FN:", "open:OpenContours:B:",
        "scat:ScatteredPoints:B:", "number:PointsPerContour:I:", "planar:PlanarContours:B:",
        "zero:NumberedFromZero:B:", "zcoord:ZCoordinatesFromZero:B:",
        "values:ValuesInLastColumn:I:", "circle:CircleSize:I:", "sphere:SphereRadius:I:",
        "color:ColorOfObject:ITM:", "name:NameOfObject:CHM:",
        "image:ImageForCoordinates:FN:", "pixel:PixelSpacingOfImage:FT:",
        "origin:OriginOfImage:FT:"
    };

    /* Startup with fallback */
    PipReadOrParseOptions(argc, argv, options, numOptions, progname,
                          2, 1, 1, &numOptArgs, &numNonOptArgs, imodUsageHeader);

    /* Get input and output files */
    if (PipGetInOutFile("InputFile", 0, &filename))
        exitError("No input file specified");
    infp = fopen(filename, "r");
    if (!infp)
        exitError("Error opening input file %s", filename);
    free(filename);
    if (PipGetInOutFile("OutputFile", 1, &filename))
        exitError("No output file specified");

    if (!PipGetString("ImageForCoordinates", &imagename)) {
        fpimage = fopen(imagename, "rb");
        if (!fpimage)
            exitError("Could not open image file for coordinates: %s", imagename);
        if (mrc_head_read(fpimage, &hdata))
            exitError("Reading header from %s", imagename);
        free(imagename);
    }

    directScale = 2 - PipGetThreeFloats("PixelSpacingOfImage", &xscale, &yscale, &zscale)
                  - PipGetThreeFloats("OriginOfImage", &xtrans, &ytrans, &ztrans);
    if (directScale && fpimage)
        exitError("You cannot use -image together with -pixel or -origin");

    err = PipGetInteger("PointsPerContour", &numPerCont);
    err = PipGetInteger("SphereRadius", &sphere);
    err = PipGetInteger("CircleSize", &circle);
    err = PipGetBoolean("OpenContours", &open);
    err = PipGetBoolean("ScatteredPoints", &scat);
    err = PipGetBoolean("PlanarContours", &zsort);
    err = PipGetInteger("ValuesInLastColumn", &hasValues);
    err = PipGetBoolean("ZCoordinatesFromZero", &zFromZero);
    if (zFromZero)
        zOffset = 0.5;
    B3DCLAMP(hasValues, -1, 1);
    if (hasValues < 0) {
        hasValues = 1;
        contValues = 1;
    }
    err = PipGetBoolean("NumberedFromZero", &fromZero);
    numOffset = 1 - fromZero;
    if (numPerCont < 0)
        exitError("Number of points per contour must be positive or zero");
    if (open + scat > 1)
        exitError("Only one of -open or -scat may be entered");

    // Get colors
    err = PipNumberOfEntries("ColorOfObject", &numColors);
    if (numColors) {
        red = (int *)malloc(numColors * sizeof(int));
        green = (int *)malloc(numColors * sizeof(int));
        blue = (int *)malloc(numColors * sizeof(int));
        if (!red || !green || !blue)
            exitError("Allocating memory for colors");
        for (co = 0; co < numColors; co++)
            err = PipGetThreeIntegers("ColorOfObject", &red[co], &green[co],
                                      &blue[co]);
    }

    // Get names
    err = PipNumberOfEntries("NameOfObject", &numNames);
    if (numNames) {
        names = (char **)malloc(numNames * sizeof(char *));
        if (!names)
            exitError("Allocating memory for names");
        for (co = 0; co < numNames; co++)
            err = PipGetString("NameOfObject", &names[co]);
    }

    PipDone();

    // Read first line of file, figure out how many values
    if (fgetline(infp, line, 1024) <= 0)
        exitError("Reading beginning of file");

    nvals = sscanf(line, "%f %f %f %f %f %f", &tst1, &tst2, &xx, &yy, &zz, &value);
    nvals -= hasValues;
    if (nvals < 3)
        exitError("There must be at least %d values per line", 3 + hasValues);
    nvals = B3DMIN(nvals, 5);
    if (numPerCont && nvals > 3) {
        exitError("The point file has contour numbers and the -number option "
                  "cannot be used");
    }
    if (zsort && nvals > 3)
        exitError("The point file has contour numbers and the -planar option "
                  "cannot be used");

    rewind(infp);

    imod = imodNew();
    if (!imod)
        exitError("Failed to get model structure");

    // Set the image reference scaling
    if (fpimage) {
        imodSetRefImage(imod, &hdata);
        fclose(fpimage);
    } else if (directScale) {
        imod->refImage = (IrefImage *)malloc(sizeof(IrefImage));
        if (!imod->refImage)
            exitError("Allocating IrefImage structure");
        ref = imod->refImage;
        ref->ctrans.x = xtrans;
        ref->ctrans.y = ytrans;
        ref->ctrans.z = ztrans;
        ref->cscale.x = xscale;
        ref->cscale.y = yscale;
        ref->cscale.z = zscale;
        ref->oscale.x = ref->oscale.y = ref->oscale.z = 1.;
        ref->orot.x = ref->orot.y = ref->orot.z = 0.;
        ref->crot.x = ref->crot.y = ref->crot.z = 0.;
        ref->otrans.x = ref->otrans.y = ref->otrans.z = 0.;
    }

    ob = 0;
    co = 0;
    lineNum = 0;
    imod->xmax = 0.;
    imod->ymax = 0.;
    imod->zmax = 0.;
    store.type = GEN_STORE_VALUE1;
    store.flags = GEN_STORE_FLOAT << 2;

    // To do: error check contour and object #'s, and they are numbered from 1.
    while (1) {

        // get line, done on EOF, skip blank line
        linelen = fgetline(infp, line, 1024);
        if (linelen < 0)
            break;
        if (linelen == 0)
            continue;

        if (nvals == 3) {
            nread = sscanf(line, "%f %f %f %f", &xx, &yy, &zz, &value);
        } else if (nvals == 4) {
            nread = sscanf(line, "%d %f %f %f %f", &co, &xx, &yy, &zz, &value);
            co -= numOffset;
        } else {
            nread = sscanf(line, "%d %d %f %f %f %f", &ob, &co, &xx, &yy, &zz, &value);
            co -= numOffset;
            ob -= numOffset;
        }
        zz -= zOffset;
        lineNum++;

        // Skip line with no values
        if (nread <= 0)
            continue;
        if (B3DMIN(5 + hasValues, nread) != nvals + hasValues &&
                !(contValues && nread == nvals))
            exitError("Every line should have %d entries; line %d has %d",
                      nvals + hasValues, lineNum, nread);

        if (ob < 0 || co < 0)
            exitError("Illegal object or contour number (object %d, contour %d at line %d",
                      ob + numOffset, co + numOffset, lineNum);

        // Add objects if needed to get to the current object
        if (ob >= imod->objsize) {
            for (i = imod->objsize; i <= ob; i++) {
                if (imodNewObject(imod))
                    exitError("Failed to add object to model");
                if (open)
                    imod->obj[i].flags |= IMOD_OBJFLAG_OPEN;
                if (scat)
                    imod->obj[i].flags |= IMOD_OBJFLAG_SCAT | IMOD_OBJFLAG_OPEN;
                numObjs++;
                imod->obj[i].pdrawsize = B3DMAX(0, sphere);
                if (circle > 0) {
                    imod->obj[i].symsize = circle;
                    imod->obj[i].symbol = IOBJ_SYM_CIRCLE;
                }
                if (i < numColors) {
                    imod->obj[i].red = red[i] / 255.;
                    imod->obj[i].green = green[i] / 255.;
                    imod->obj[i].blue = blue[i] / 255.;
                }
                if (i < numNames) {
                    strncpy(imod->obj[i].name, names[i], IOBJ_STRSIZE - 1);
                    imod->obj[i].name[IOBJ_STRSIZE - 1] = 0x00;
                }
            }
        }

        // Determine if a contour is needed: either the contour number is too high
        // or the number limit is reached or there is a change in Z
        needcont = 0;
        obj = &imod->obj[ob];
        if (co >= obj->contsize)
            needcont = 1;
        else if ((numPerCont && obj->cont[co].psize >= numPerCont) ||
                 (zsort && B3DNINT(obj->cont[co].pts[0].z) != B3DNINT(zz))) {
            co++;
            needcont = 1;
        }

        if (needcont) {
            imodSetIndex(imod, ob, -1, -1);
            for (i = obj->contsize; i<= co; i++) {
                if (imodNewContour(imod))
                    exitError("Failed to add contour to model");
                numConts++;
            }
        }

        point.x = xx;
        point.y = yy;
        point.z = zz;
        imod->xmax = B3DMAX(imod->xmax, B3DNINT(xx + 10.));
        imod->ymax = B3DMAX(imod->ymax, B3DNINT(yy + 10.));
        imod->zmax = B3DMAX(imod->zmax, B3DNINT(zz + 1.));
        if (!imodPointAppend(&obj->cont[co], &point))
            exitError("Failed to add point to contour");
        numPts++;

        // take care of value for contour or point, only add one per contour
        if (hasValues) {
            store.value.f = value;
            err = 0;
            if (contValues && istoreLookup(obj->store, co, &after) < 0) {
                if (nread < nvals + 1)
                    exitError("The first point for a contour must have a value entry; line %d "
                              "has only %d entries", lineNum, nread);
                store.index.i = co;
                err = istoreInsert(&obj->store, &store);
            } else {
                store.index.i = obj->cont[co].psize - 1;
                err = istoreInsert(&obj->cont[co].store, &store);
            }
            if (err)
                exitError("Failed to add general value");
        }
    }

    // Get the object min/max values set up
    if (hasValues) {
        for (ob = 0; ob < imod->objsize; ob++) {
            if (imod->obj[ob].contsize && istoreFindAddMinMax1(&imod->obj[ob]))
                exitError("Adding min/max values to object");
        }
    }

    // Attach image file's size as the max values
    if (fpimage) {
        imod->xmax = hdata.nx;
        imod->ymax = hdata.ny;
        imod->zmax = hdata.nz;
    }

    fclose(infp);
    if (imodBackupFile(filename))
        printf("Warning: %s - Failed to make old version of %s be a backup file\n",
               progname, filename);

    imod->file = fopen(filename, "wb");
    if (!imod->file)
        exitError("Opening new model file %s", filename);
    if (imodWriteFile(imod))
        exitError("Writing model file %s", filename);
    free(filename);
    printf("Model created with %d objects, %d contours, %d points\n", numObjs,
           numConts, numPts);
    exit(0);
}