// Get slices for storage based on needed size of display void TumblerWindow::setSlice(TumblerStruct *xtum) { int xsize, ysize; if (xtum->slice) sliceFree(xtum->slice); if (xtum->stslice) sliceFree(xtum->stslice); if (xtum->bwslice) sliceFree(xtum->bwslice); if (xtum->count) sliceFree(xtum->count); if (xtum->highres){ xsize = ysize = xtum->ms * xtum->zoom; if (xtum->stereo && xsize > xtum->width / 2) xsize = xtum->width / 2; }else{ xsize = ysize = xtum->ms; } xtum->slice = sliceCreate(xsize, ysize, SLICE_MODE_SHORT); xtum->stslice = sliceCreate(xsize, ysize, SLICE_MODE_SHORT); xtum->bwslice = sliceCreate(xsize, ysize, xtum->vi->rawImageStore); xtum->count = sliceCreate(xsize, ysize, SLICE_MODE_SHORT); newData(xtum); return; }
// Respond to close event. Have to remove control first void TumblerWindow::closeEvent ( QCloseEvent * e ) { TumblerStruct *xtum = mTum; xtum->closing = 1; ivwRemoveControl(xtum->vi, xtum->ctrl); imodDialogManager.remove((QWidget *)xtum->dialog); sliceFree(xtum->slice); sliceFree(xtum->stslice); sliceFree(xtum->bwslice); sliceFree(xtum->count); b3dFreeCIImage(xtum->image); free(xtum); e->accept(); }
/*! * Puts values from the slice [s] into the volume in * the @@Istack structure@ [v] at coordinate [sno] along the axis given by * [axis], which must be one of x, X, y, Y, z, or Z. For a Z slice, * the existing slice is freed and the supplied slice becomes part of the * stack, so it should not be freed separately from the stack. Returns 0. */ int mrc_slice_putvol(Istack *v, Islice *s, int sno, char axis) { Ival val; int i, j, k; switch (axis){ case 'z': case 'Z': sliceFree(v->vol[sno]); v->vol[sno] = s; break; case 'y': case 'Y': for (k = 0; k < s->ysize; k++) for(i = 0; i < s->xsize; i++){ sliceGetVal(s, i, k, val); slicePutVal(v->vol[k], i, sno, val); } break; case 'x': case 'X': for (k = 0; k < s->ysize; k++) for (j = 0; j < s->xsize; j++){ sliceGetVal(s, j, k, val); slicePutVal(v->vol[k], sno, j, val); } break; default: return(0); } return(0); }
int grap_volume_free(Istack *v) { int k; if (!v) return(-1); for (k = 0; k < v->zsize; k++) sliceFree(v->vol[k]); free(v->vol); free(v); return(0); }
/*! * Returns a slice with one Z plane of data at Z value [secno] from the file * described by the @@mrcfiles.html#MrcHeader structure@ [hin]. * The file pointer in [hin] is used. Bytes are swapped if necessary. * Returns NULL for errors. */ Islice *sliceReadFloat(MrcHeader *hin, int secno) { Islice *slice; if (sliceModeIfReal(hin->mode) < 0) { b3dError(stderr, "ERROR: sliceReadFloat - file mode must be real"); return NULL; } slice = sliceCreate(hin->nx, hin->ny, MRC_MODE_FLOAT); if (!slice) return NULL; if (mrcReadFloatSlice(slice->data.f, hin, secno)) { sliceFree(slice); return NULL; } return slice; }
/* 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); }
/* Read the required data volume */ Istack *grap_volume_read(MrcHeader *hin, ClipOptions *opt) { Istack *v; Islice *s; Ival val; int i, j, k, x, y, z; if (opt->dim == 2){ if (opt->iz == IP_DEFAULT) opt->iz = 0; if (opt->iz2 == IP_DEFAULT) opt->iz2 = hin->nz - 1; if (opt->iz2 == 0) opt->iz2 = opt->iz; if (opt->iz2 < opt->iz) opt->iz2 = opt->iz; opt->cz = ( opt->iz2 + opt->iz) / 2.; opt->iz = opt->iz2 - opt->iz + 1; } if (opt->ix == IP_DEFAULT) opt->ix = hin->nx; if (opt->iy == IP_DEFAULT) opt->iy = hin->ny; if (opt->iz == IP_DEFAULT) opt->iz = hin->nz; if (opt->cx == IP_DEFAULT) opt->cx = hin->nx / 2.; if (opt->cy == IP_DEFAULT) opt->cy = hin->ny / 2.; if (opt->cz == IP_DEFAULT) opt->cz = hin->nz / 2.; /* Do not set opt->pad yet, just pad with current mean */ val[0] = opt->pad; if (opt->pad == IP_DEFAULT) val[0] = hin->amean; val[1] = val[0]; val[2] = val[0]; /* Create volume and initialize to pad value. */ v = (Istack *)malloc(sizeof(Istack)); v->vol = (Islice **)malloc( opt->iz * sizeof(Islice *)); v->zsize = opt->iz; for (k = 0; k < opt->iz; k++) { v->vol[k] = sliceCreate(opt->ix, opt->iy, hin->mode); if (!v->vol[k]) return(NULL); for( j = 0; j < opt->iy; j++) for(i = 0; i < opt->ix; i++) slicePutVal(v->vol[k], i, j, val); v->vol[k]->mean = hin->amean; v->vol[k]->max = hin->amax; v->vol[k]->min = hin->amin; } s = sliceCreate(hin->nx, hin->ny, hin->mode); if (!s) return(NULL); /* Read slices in, copying just the part that is needed */ k = (int)floor(opt->cz - ((float)opt->iz * 0.5f)); /* printf("k = %d\n", k); */ for (z = 0; (k < hin->nz) && (z < opt->iz); k++, z++) { if (k >= 0) { if (mrc_read_slice((void *)s->data.b, hin->fp, hin, k, 'z')) return (NULL); j = (int)floor(opt->cy - opt->iy / 2.); for (y = 0; (j < hin->ny) && (y < opt->iy); j++, y++) { if (j >= 0) { i = (int)floor(opt->cx - opt->ix / 2.); x = 0; if (i < 0) { x = -i; i = 0; } for (; (i < hin->nx) && (x < opt->ix); i++, x++) { sliceGetVal(s, i, j, val); slicePutVal(v->vol[z], x, y, val); } } } } } sliceFree(s); return(v); }
/* * 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; }