static inline void pack_table(Table *table) { _Table *object = (_Table *) (((char *) table) - Table_Offset); if (object->vsize > table_vsize(table)) { object->vsize = table_vsize(table); if (object->vsize != 0) table->vector = Guarded_Realloc(table->vector, object->vsize,"Pack_Table"); else { free(table->vector); table->vector = NULL; } } if (object->csize > table_csize(table)) { object->csize = table_csize(table); if (object->csize != 0) table->cells = Guarded_Realloc(table->cells, object->csize,"Pack_Table"); else { free(table->cells); table->cells = NULL; } } if (object->ssize > table_ssize(table)) { object->ssize = table_ssize(table); if (object->ssize != 0) table->strings = Guarded_Realloc(table->strings, object->ssize,"Pack_Table"); else { free(table->strings); table->strings = NULL; } } }
void Parse_Stack_Name(char *file_name, char **prefix, int *num_width, int *first_num) { static char *Prefix = NULL; static int Prefix_Max = 0; char *s, *t, c; s = file_name + strlen(file_name) - 4; if (strcmp(s,".tif") != 0) error("1st file, %s, in stack does not have .tif extension",file_name); t = s; while (t > file_name && isdigit(t[-1])) t -= 1; if (s-t <= 0) error("No number sequence in stack file names %s",file_name); if (t-file_name > Prefix_Max) { Prefix_Max = (int)((t-file_name)*1.2 + 20); Prefix = (char *) Guarded_Realloc(Prefix,Prefix_Max+1,"Parse_Stack_Name"); } c = *t; *t = '\0'; strcpy(Prefix,file_name); *t = c; *prefix = Prefix; *num_width = s-t; *first_num = atoi(t); }
static inline Table *new_table(int vsize, int csize, int ssize, char *routine) { _Table *object; Table *table; if (Free_Table_List == NULL) { object = (_Table *) Guarded_Realloc(NULL,sizeof(_Table),routine); table = &(object->table); object->vsize = 0; table->vector = NULL; object->csize = 0; table->cells = NULL; object->ssize = 0; table->strings = NULL; } else { object = Free_Table_List; Free_Table_List = object->next; table = &(object->table); } Table_Inuse += 1; object->refcnt = 1; if (Use_Table_List != NULL) Use_Table_List->prev = object; object->next = Use_Table_List; object->prev = NULL; Use_Table_List = object; allocate_table_vector(table,vsize,routine); allocate_table_cells(table,csize,routine); allocate_table_strings(table,ssize,routine); return (table); }
static inline Cdf *new_cdf(int tsize, char *routine) { _Cdf *object; Cdf *cdf; if (Free_Cdf_List == NULL) { object = (_Cdf *) Guarded_Realloc(NULL,sizeof(_Cdf),routine); cdf = &(object->cdf); object->tsize = 0; cdf->tab = NULL; } else { object = Free_Cdf_List; Free_Cdf_List = object->next; cdf = &(object->cdf); } Cdf_Inuse += 1; object->refcnt = 1; if (Use_Cdf_List != NULL) Use_Cdf_List->prev = object; object->next = Use_Cdf_List; object->prev = NULL; Use_Cdf_List = object; allocate_cdf_tab(cdf,tsize,routine); return (cdf); }
static inline void allocate_cdf_tab(Cdf *cdf, int tsize, char *routine) { _Cdf *object = (_Cdf *) (((char *) cdf) - Cdf_Offset); if (object->tsize < tsize) { cdf->tab = Guarded_Realloc(cdf->tab,tsize,routine); object->tsize = tsize; } }
static inline void allocate_table_cells(Table *table, int csize, char *routine) { _Table *object = (_Table *) (((char *) table) - Table_Offset); if (object->csize < csize) { table->cells = Guarded_Realloc(table->cells,csize,routine); object->csize = csize; } }
static inline void allocate_table_vector(Table *table, int vsize, char *routine) { _Table *object = (_Table *) (((char *) table) - Table_Offset); if (object->vsize < vsize) { table->vector = Guarded_Realloc(table->vector,vsize,routine); object->vsize = vsize; } }
static inline void allocate_table_strings(Table *table, int ssize, char *routine) { _Table *object = (_Table *) (((char *) table) - Table_Offset); if (object->ssize < ssize) { table->strings = Guarded_Realloc(table->strings,ssize,routine); object->ssize = ssize; } }
inline void pack_image(Image *image) { _Image *object = (_Image *) (((char *) image) - Image_Offset); if (object->asize != image_asize(image)) { object->asize = image_asize(image); object->image.array = (uint8 *)Guarded_Realloc(object->image.array, object->asize,"Pack_Image"); } }
void polyfit_realloc_workspace( int n, int degree, double **workspace ) { degree += 1; // e.g. for degree 2 need 3 coefficients if(workspace) { *workspace = Guarded_Realloc(*workspace, sizeof(double)*( polyfit_size_workspace(n,degree) ), "polyfit workspace" ); } else { *workspace = polyfit_alloc_workspace( n, degree ); } }
inline void pack_stack(Stack *stack) { _Stack *object = (_Stack *) (((char *) stack) - Stack_Offset); if (object->vsize != stack_vsize(stack)) { object->vsize = stack_vsize(stack); object->stack.array = (uint8 *)Guarded_Realloc(object->stack.array, object->vsize,"Pack_Stack"); } }
void *request_storage( void *buffer, size_t *maxlen, size_t nbytes, size_t minindex, char *msg ) { if( (nbytes*minindex) > *maxlen ) { size_t newsize = (size_t) (1.25 * minindex + 64) * nbytes; #ifdef DEBUG_REQUEST_STORAGE printf("REQUEST %7d bytes (%7d items) above current %7d bytes by %s\n",minindex * nbytes, minindex, *maxlen,msg); #endif buffer = Guarded_Realloc( buffer, newsize, msg ); *maxlen = newsize; } return buffer; }
// TODO - returns buffers where maxlen_items is a power of 2 void *request_storage_pow2items( void *buffer, size_t *maxlen_bytes, size_t nbytes, size_t minindex, char *msg ) { if( (nbytes*minindex) > *maxlen_bytes ) { #ifdef DEBUG_REQUEST_STORAGE printf("REQUEST %7d bytes (%7d items) above current %7d bytes by %s\n",minindex * nbytes, minindex, *maxlen_bytes,msg); assert(sizeof(size_t)==4); #endif *maxlen_bytes = (size_t) ( _next_pow2_uint32(minindex) ) * nbytes; buffer = Guarded_Realloc( buffer, *maxlen_bytes, msg ); } return buffer; }
static inline void pack_cdf(Cdf *cdf) { _Cdf *object = (_Cdf *) (((char *) cdf) - Cdf_Offset); if (object->tsize > cdf_tsize(cdf)) { object->tsize = cdf_tsize(cdf); if (object->tsize != 0) cdf->tab = Guarded_Realloc(cdf->tab, object->tsize,"Pack_Cdf"); else { free(cdf->tab); cdf->tab = NULL; } } }
static uint32 *get_raster(int npixels, char *routine) { static uint32 *Raster = NULL; static int Raster_Size = 0; // Manage read work buffer if (npixels < 0) { free(Raster); Raster_Size = 0; Raster = NULL; } else if (npixels > Raster_Size) { Raster_Size = npixels; Raster = (uint32 *) Guarded_Realloc(Raster,sizeof(uint32)*Raster_Size,routine); } return (Raster); }
Stack *Translate_Stack(Stack *stack, int kind, int in_place) { int width, height, depth; width = stack->width; height = stack->height; depth = stack->depth; if (in_place) { if (stack->kind == kind) return (stack); if (kind > stack->kind) { _Stack *object = (_Stack *) (((char *) stack) - Stack_Offset); if (object->vsize < width * height * depth * kind) { object->vsize = width * height * depth * kind; stack->array = (uint8 *)Guarded_Realloc(stack->array,object->vsize,"Translate_Stack"); } } translate(stack->kind,stack->array,kind,stack->array,width*height*depth); stack->kind = kind; return (stack); } else { Stack *xlate; if (stack->kind == kind) return (Copy_Stack(stack)); xlate = new_stack(kind*width*height*depth,"Translate_Stack"); xlate->depth = depth; xlate->width = width; xlate->height = height; xlate->kind = kind; translate(stack->kind,stack->array,kind,xlate->array,width*height*depth); return (xlate); } }
static inline Image *new_image(int asize, char *routine) { _Image *object; if (Free_Image_List == NULL) { object = (_Image *) Guarded_Malloc(sizeof(_Image),routine); Image_Offset = ((char *) &(object->image)) - ((char *) object); object->asize = asize; object->image.array = (uint8 *)Guarded_Malloc(asize,routine); Image_Inuse += 1; } else { object = Free_Image_List; Free_Image_List = object->next; if (object->asize < asize) { object->asize = asize; object->image.array = (uint8 *)Guarded_Realloc(object->image.array, asize,routine); } } return (&(object->image)); }
static inline Stack *new_stack(int vsize, char *routine) { _Stack *object; if (Free_Stack_List == NULL) { object = (_Stack *) Guarded_Malloc(sizeof(_Stack),routine); Stack_Offset = ((char *) &(object->stack)) - ((char *) object); object->vsize = vsize; object->stack.array = (uint8 *)Guarded_Malloc(vsize,routine); Stack_Inuse += 1; } else { object = Free_Stack_List; Free_Stack_List = object->next; if (object->vsize < vsize) { object->vsize = vsize; object->stack.array = (uint8 *)Guarded_Realloc(object->stack.array, vsize,routine); } } return (&(object->stack)); }
Image *Translate_Image(Image *image, int kind, int in_place) { int width, height; width = image->width; height = image->height; if (in_place) { if (image->kind == kind) return (image); if (kind > image->kind) { _Image *object = (_Image *) (((char *) image) - Image_Offset); if (object->asize < width * height * kind) { object->asize = width * height * kind; image->array = (uint8 *)Guarded_Realloc(image->array,object->asize,"Translate_Image"); } } translate(image->kind,image->array,kind,image->array,width*height); image->kind = kind; return (image); } else { Image *xlate; if (image->kind == kind) return (Copy_Image(image)); xlate = new_image(kind*width*height,"Translate_Image"); xlate->width = width; xlate->height = height; xlate->kind = kind; translate(image->kind,image->array,kind,xlate->array,width*height); return (xlate); } }
/* ** Uses a levelset and size threshold to segment an image constrained by the ** zone mask. */ SHARED_EXPORT Object_Map *find_objects(Image *image, int vthresh, int sthresh) { static Object_Map mymap; static int obj_max = 0; static Contour **objects = NULL; static Paint_Brush zero = { 0., 0., 0. }; uint8 *array = image->array; int carea = image->width*image->height; { int p, n; n = 0; for (p = 0; p < carea; p++) if (array[p] >= vthresh) // start at a non-masked pixel { Contour *c = Trace_Region(image,p,GE,vthresh,1); // trace the contour around that pixel Draw_Contour_Interior(c,&zero,image); // mask out that countour if (Contour_Area(c) >= sthresh) // apply a size threshold to the region { if (n >= obj_max) { obj_max = 1.2*n+500; objects = (Contour **) Guarded_Realloc(objects,sizeof(Contour *)*obj_max,Program_Name()); } objects[n++] = c; } else { Free_Contour( c ); } } mymap.num_objects = n; mymap.objects = objects; } return (&mymap); }
SHARED_EXPORT Seed_Vector *decompose_trace_x(Contour *trace, int width, int height, uint8 *value) { static Seed *seedlist = NULL; static int seedmax = 0; static Seed_Vector myseeds; static Seed *boo; int *yaster, ypairs; Raster *raster; int nseeds; int ntrk, mtrk, etrk; int r, x, x0; nseeds = 0; yaster = Yaster_Scan(trace,&ypairs,height); // reencode yaster as (x,y) points - in place raster = (Raster *) yaster; for (r = 0; r < ypairs; r++) { int mj = yaster[r]/height; // x int mn = yaster[r]%height; // y raster[r].major = mj; // x raster[r].minor = mn; // y } #ifdef SHOW_BRANCHES printf("\nTRACE:\n"); fflush(stdout); #endif ntrk = mtrk = etrk = 0; r = 0; while (r < ypairs) { x0 = x = raster[r].major; // the x value for this (vertical) raster #ifdef SHOW_TRACE printf(" %d:",x0); fflush(stdout); #endif ntrk = mtrk; mtrk = etrk; // advance over vertically aligned intervals in the raster while (x == x0) { raster[r].major = 0; // mark it #ifdef SHOW_TRACE // y0 y1 printf(" (%d,%d)",raster[r].minor,raster[r+1].minor-1); fflush(stdout); #endif r += 2; // move to next pair if (r >= ypairs) break; x = raster[r].major; } etrk = r; // remember the end of this sequence of intervals #ifdef SHOW_TRACE printf("\n"); fflush(stdout); #endif { int m, n; int mb, me; int nb, ne; int c, o; Seed *s; m = mtrk; n = ntrk; c = 0; while (n < mtrk) { if (m >= etrk) //if the end of this sequence of intervals has been passed... mb = me = ne; //...empty m interval located at end of n else { mb = raster[m].minor; //beginning of the m'th interval me = raster[m+1].minor; //end of the m'th interval } nb = raster[n].minor; //beginning of the n'th interval ne = raster[n+1].minor; //end of the n'th interval // init if (me > nb && ne > mb) //if the intervals have an intersection... { raster[m].major += 1; //...increment m's id c += 1; //...count } if (me < ne) //if m's end is before n's ... m += 2; //...increment to interval following m and move on else //else m and n intersect or m is past n { raster[n+1].major = -1; //...mark next if (c > 1) //if there was more than one intersection event... { // move o back till all intersection counts are accounted for // and add counts into interval labels o = m; while (1) { if (me > nb && ne > mb) // if m and n intersect ... { raster[o].major += 1; // ...increment label if (--c <= 0) break; // ...clear counts } o -= 2; // back up an interval mb = raster[o].minor; me = raster[o+1].minor; } } else if (c == 1) // if only one intersection count { if (ne > mb) { if ((n+2 >= mtrk || raster[n+2].minor >= me) && raster[m].major <= 1) raster[n+1].major = m; } else { if (raster[m-2].major <= 1) raster[n+1].major = m-2; } } #ifdef SHOW_BRANCHES if (raster[n+1].major < 0) printf("Track (%d,%d) %d expires\n", raster[n].minor,raster[n+1].minor-1,raster[n].major); #endif n += 2; c = 0; } } for (m = mtrk; m < etrk; m += 2) //iterate over sequence of vertically aligned intervals if (raster[m].major != 1) //if unlabelled { #ifdef SHOW_BRANCHES printf("Track (%d,%d) = %d starts\n", raster[m].minor,raster[m+1].minor-1,raster[m].major); #endif raster[m].major = 1; //...init label } for (n = ntrk; n < mtrk; n += 2) { c = raster[n+1].major; raster[n+1].major = x0-1; // set back to x0 if (c < 0) // if termination...compute seed on n'th { if (nseeds >= seedmax) { seedmax = 1.2*nseeds + 10; seedlist = (Seed *) Guarded_Realloc(seedlist,sizeof(Seed)*seedmax,Program_Name()); } s = compute_seed(raster,n,x0-1,width,value); if (s != NULL) seedlist[nseeds++] = *s; } else raster[c].major = raster[n].major+1; } } //end context } //end while { int m; Seed *s; for (m = mtrk; m < etrk; m += 2) { if (nseeds >= seedmax) { seedmax = 1.2*nseeds + 10; seedlist = (Seed *) Guarded_Realloc(seedlist,sizeof(Seed)*seedmax,Program_Name()); } s = compute_seed(raster,m,x0,width,value); if (s != NULL) seedlist[nseeds++] = *s; #ifdef SHOW_BRANCHES printf("Track (%d,%d) %d = 0 expires\n", raster[m].minor,raster[m+1].minor-1,raster[m].major); #endif } } myseeds.nseeds = nseeds; myseeds.seeds = seedlist; return (&myseeds); }
void String_Workspace_Realloc(String_Workspace *sw, int size) { sw->size = size; sw->array = (char*)Guarded_Realloc(sw->array, string_workspace_asize(sw), "String_Workspace_Realloc"); }
Overlaps *Find_Overlaps(Segmentation *segs) { Overlaps *ovl; int totsegs, *alist, *heads, *chans; int ecount, emax; uint8 **vals; Size_Type k; Indx_Type v, w, p; Region *rci; int c, d; int i, j; totsegs = segs[NumChans-1].base + segs[NumChans-1].nsegs; alist = (int *) Guarded_Malloc(sizeof(int)*(totsegs+1),Program_Name()); chans = (int *) Guarded_Malloc(sizeof(int)*totsegs,Program_Name()); emax = totsegs*NumChans; heads = (int *) Guarded_Malloc(sizeof(int)*emax,Program_Name()); for (k = 0; k <= totsegs; k++) alist[k] = 0; vals = (uint8 **) Guarded_Malloc(sizeof(uint8 *)*NumChans,Program_Name()); for (k = 0; k < NumChans; k++) vals[k] = AUINT8(segs[k].label); ecount = 0; for (c = 0; c < NumChans-1; c++) { printf("channel=%d numSegs=%d\n", c, segs[c].nsegs); for (i = 0; i < segs[c].nsegs; i++) { rci = segs[c].segs[i]; alist[segs[c].base+i] = ecount; chans[segs[c].base+i] = c; for (k = 0; k < rci->rastlen; k += 2) { v = rci->raster[k]; w = rci->raster[k+1]; for (p = v; p <= w; p++) for (d = c+1; d < NumChans; d++) { // printf("vals d=%d p=%d =%d\n", d, p, vals[d][p]); if (vals[d][p] > 0) { j = segs[d].base+(vals[d][p]-1); alist[j] += 1; if (alist[j] == MIN_OVERLAP) { if (ecount >= emax) { emax = 1.2*emax + 100; heads = (int *) Guarded_Realloc(heads,sizeof(int)*emax,Program_Name()); } heads[ecount++] = j; } } } } for (j = segs[c+1].base; j < totsegs; j++) alist[j] = 0; } } for (i = 0; i <= segs[c].nsegs; i++) { alist[segs[c].base+i] = ecount; chans[segs[c].base+i] = c; } free(vals); ovl = (Overlaps *) Guarded_Malloc(sizeof(Overlaps),Program_Name()); ovl->totsegs = totsegs; ovl->alist = alist; ovl->heads = heads; ovl->chans = chans; #ifdef VERBOSE { int k, h, c, i, d; printf("\nOverlaps:\n"); for (k = 0; k < ovl->totsegs; k++) { c = chans[k]; d = (k-segs[c].base)+1; if (d < 10) printf(" "); else if (d < 100) printf(" "); printf(" %c%d:",Letter[c],(k-segs[c].base)+1); for (h = alist[k]; h < alist[k+1]; h++) { i = heads[h]; c = chans[i]; printf(" %c%d",Letter[c],(i-segs[c].base)+1); } printf("\n"); fflush(stdout); } fflush(stdout); } #endif return (ovl); }
int Read_All_Channels(string name, int maxchans) { Tiff *tif; int depth, height, width, chans; int i; if(strcmp(getSuffix(name), "tif")==0 || strcmp(getSuffix(name), "lsm")==0) { tif = Open_Tiff(name,"r"); if (tif == NULL) { fprintf(stderr,"Cannot open file %s for reading\n",name); exit (1); } Get_IFD_Shape(tif,&width,&height,&chans); printf("width=%d height=%d chans=%d\n", width, height, chans); if (chans < 2) { fprintf(stderr,"LSM %s does not at least 2 channels\n",name); exit (1); } depth = 0; while ( ! Tiff_EOF(tif)) { int w, h, c; Get_IFD_Shape(tif,&w,&h,&c); if (w == width && h == height && c == chans) { for (i = 0; i < chans; i++) if (Get_IFD_Channel_Type(tif,i) != UINT16_TYPE) { fprintf(stderr,"Channel %d of %s is not 16-bit)\n",i,name); exit (1); } depth += 1; } Advance_Tiff(tif); } Rewind_Tiff(tif); if (NumChans + chans > maxchans) { maxchans = 1.2*(NumChans+chans) + 20; Images = (Array **) Guarded_Realloc(Images,sizeof(Array *)*maxchans,Program_Name()); } for (i = NumChans; i < NumChans + chans; i++) Images[i] = Make_Array_With_Shape(PLAIN_KIND,UINT16_TYPE,Coord3(depth,height,width)); depth = 0; while ( ! Tiff_EOF(tif)) { int w, h, c; Get_IFD_Shape(tif,&w,&h,&c); if (w == width && h == height && c == chans) { for (i = 0; i < chans; i++) { Array_Bundle plane = *(Images[NumChans+i]); Get_IFD_Channel(tif,i,Get_Array_Plane(&plane,depth)); } depth += 1; } Advance_Tiff(tif); } Close_Tiff(tif); NumChans += chans; return (maxchans); } else if (strcmp(getSuffix(name), "raw")==0 || strcmp(getSuffix(name), "v3draw")==0) { unsigned char* img; long* sz; img=0; sz=0; int rawLoadResult=loadRaw2Stack(name, &img, &sz, 2); if (rawLoadResult!=0) { fprintf(stderr, "Load of raw file failed\n"); exit(1); } if (sizeof(unsigned short)!=2) { fprintf(stderr, "Read_All_Channels() making false assumption that unsigned short is size=2\n"); exit(1); } unsigned short* rawp=(unsigned short*)img; width=sz[0]; height=sz[1]; depth=sz[2]; chans=sz[3]; printf("width=%d height=%d depth=%d chans=%d\n", width, height, depth, chans); if (chans < 2) { fprintf(stderr,"File %s does not contain at least 2 channels\n",name); exit (1); } if (NumChans + chans > maxchans) { maxchans = 1.2*(NumChans+chans) + 20; Images = (Array **) Guarded_Realloc(Images,sizeof(Array *)*maxchans,Program_Name()); } for (i = NumChans; i < NumChans + chans; i++) { Images[i] = Make_Array_With_Shape(PLAIN_KIND,UINT16_TYPE,Coord3(depth,height,width)); { int rx,ry,rz; uint16 *v; Indx_Type p; v = AUINT16(Images[i]); p = 0; long oc=(i-NumChans)*depth*height*width; for (rz=0;rz<depth;rz++) { long oz = rz*height*width; for (ry=0;ry<height;ry++) { long oy = ry*width; for (rx=0;rx<width;rx++) { long offset=oc + oz + oy + rx; unsigned short uv = *(rawp + offset); v[p++] = uv; } } } } } NumChans += chans; return (maxchans); } else { fprintf(stderr, "Do not recognize file suffix %s\n", getSuffix(name)); exit(1); } }
Int_Arraylist* Stack_Sp_Grow(const Stack *stack, const size_t *seeds, int nseed, const size_t *targets, int ntarget, Sp_Grow_Workspace *sgw) { size_t nvoxel = Stack_Voxel_Number(stack); sgw->width = stack->width; sgw->height = stack->height; sgw->depth = stack->depth; /* allocate workspace */ if (sgw->size < nvoxel) { sgw->dist = (double*) Guarded_Realloc(sgw->dist, sizeof(double) * nvoxel, "Stack_Sp_Grow"); sgw->path = (int*) Guarded_Realloc(sgw->path, sizeof(int) * nvoxel, "Stack_Sp_Grow"); sgw->checked = (int*) Guarded_Realloc(sgw->checked, sizeof(int) * nvoxel, "Stack_Sp_Grow"); sgw->flag = (uint8_t*) Guarded_Realloc(sgw->flag, sizeof(uint8_t) * nvoxel, "Stack_Sp_Grow"); if (sgw->lengthBufferEnabled) { sgw->length = (double*) Guarded_Realloc( sgw->length, sizeof(double) * nvoxel, "Stack_Sp_Grow"); } } else { if (sgw->dist == NULL) { sgw->dist = (double*) Guarded_Malloc(sizeof(double) * nvoxel, "Stack_Sp_Grow"); } if (sgw->path == NULL) { sgw->path = (int*) Guarded_Malloc(sizeof(int) * nvoxel, "Stack_Sp_Grow"); } if (sgw->checked == NULL) { sgw->checked = (int*) Guarded_Malloc(sizeof(int) * nvoxel, "Stack_Sp_Grow"); } if (sgw->flag == NULL) { sgw->flag = (uint8_t*) Guarded_Malloc(sizeof(uint8_t) * nvoxel, "Stack_Sp_Grow"); } if (sgw->lengthBufferEnabled) { if (sgw->length == NULL) { sgw->length = (double*) Guarded_Malloc( sizeof(double) * nvoxel, "Stack_Sp_Grow"); } } } sgw->size = nvoxel; /* initialize */ size_t s; for (s = 0; s < nvoxel; s++) { sgw->dist[s] = Infinity; if (sgw->length != NULL) { sgw->length[s] = 0.0; } sgw->path[s] = -1; sgw->checked[s] = 0; sgw->flag[s] = 0; } if (sgw->mask != NULL) { memcpy(sgw->flag, sgw->mask, nvoxel); } /* Recruit seeds (source) */ int i; for (i = 0; i < nseed; i++) { if (sgw->sp_option == 1) { sgw->dist[seeds[i]] = -Stack_Array_Value(stack, seeds[i]); } else { sgw->dist[seeds[i]] = 0.0; } sgw->checked[seeds[i]] = 1; sgw->flag[seeds[i]] = SP_GROW_SOURCE; } if (sgw->mask != NULL) { for (s = 0; s < nvoxel; s++) { if (sgw->flag[s] == SP_GROW_SOURCE) { if (sgw->sp_option == 1) { sgw->dist[s] = -Stack_Array_Value(stack, s); } else { sgw->dist[s] = 0.0; } sgw->checked[s] = 1; } } } Int_Arraylist *result = New_Int_Arraylist(); for (i = 0; i < ntarget; i++) { if (sgw->flag[targets[i]] == 2) { /* overlap of source and target */ Int_Arraylist_Add(result, targets[i]); sgw->value = 0.0; return result; } sgw->flag[targets[i]] = SP_GROW_TARGET; } int width = Stack_Width(stack); int height = Stack_Height(stack); int depth = Stack_Depth(stack); double dist[26]; Stack_Neighbor_Dist_R(sgw->conn, sgw->resolution, dist); int is_in_bound[26]; int neighbors[26]; Stack_Neighbor_Offset(sgw->conn, Stack_Width(stack), Stack_Height(stack), neighbors); BOOL stop = FALSE; /* Check neighbors of seeds */ int j; // for (i = 0; i < nseed; i++) { // size_t r = seeds[i]; /* alloc <heap> */ Int_Arraylist *heap = New_Int_Arraylist(); size_t r; for (r = 0; r < nvoxel; r++) { if (sgw->flag[r] == SP_GROW_SOURCE) { /* seeds */ int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, depth, r, is_in_bound); if (nbound == sgw->conn) { /* all neighbors are in bound */ for (j = 0; j < sgw->conn; j++) { size_t nbr_index = r + neighbors[j]; if (sgw->checked[nbr_index] != 1) { update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw); } } } else if (nbound > 0) { for (j = 0; j < sgw->conn; j++) { if (is_in_bound[j]) { size_t nbr_index = r + neighbors[j]; if (sgw->checked[nbr_index] != 1) { update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw); } } } } } } //Verify_Int_Heap_I(heap, sgw->dist); ssize_t last_r = -1; while (stop == FALSE) { ssize_t r = extract_min(sgw->dist, sgw->checked, sgw->size, heap); if (r >= 0) { last_r = r; if (sgw->flag[r] == 0) { /* normal voxel */ int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, depth, r, is_in_bound); if (nbound == sgw->conn) { /* all neighbors are in bound */ for (j = 0; j < sgw->conn; j++) { size_t nbr_index = r + neighbors[j]; if (sgw->checked[nbr_index] != 1) { update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw); } } } else if (nbound > 0) { for (j = 0; j < sgw->conn; j++) { if (is_in_bound[j]) { size_t nbr_index = r + neighbors[j]; if (sgw->checked[nbr_index] != 1) { update_waiting(stack, r, nbr_index, dist[j], heap, result, sgw); } } } } //Print_Int_Heap(heap, "%d"); //Verify_Int_Heap_I(heap, sgw->dist); } else if (sgw->flag[r] == SP_GROW_TARGET) { /* target reached */ //Int_Arraylist_Add(result, r); stop = TRUE; } else if (sgw->flag[r] == SP_GROW_CONDUCTOR) { /* 0-distance region (super conductor) */ int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, depth, r, is_in_bound); size_t tail_index = r; size_t old_tail_index = tail_index; size_t cur_index = r; #ifdef _DEBUG_2 printf("r: %lu\n", r); #endif #define UPDATE_SUPER_CONDUCTOR \ size_t nbr_index = cur_index + neighbors[j]; \ if (sgw->flag[nbr_index] == 4) { \ if (sgw->checked[nbr_index] > 1) { \ Int_Heap_Remove_I_At(heap, nbr_index, sgw->dist, \ sgw->checked); \ } \ tail_index = update_neighbor(cur_index, tail_index, nbr_index,sgw); \ } else { \ update_waiting(stack, cur_index, nbr_index, dist[j], heap, result,sgw); \ } if (nbound == sgw->conn) { /* all neighbors are in bound */ for (j = 0; j < sgw->conn; j++) { UPDATE_SUPER_CONDUCTOR } } else if (nbound > 0) { for (j = 0; j < sgw->conn; j++) { if (is_in_bound[j]) { UPDATE_SUPER_CONDUCTOR } } } int count = 0; while (tail_index != old_tail_index) { old_tail_index = tail_index; size_t cur_index = tail_index; while (sgw->checked[cur_index] != 1) { int nbound = Stack_Neighbor_Bound_Test_I(sgw->conn, width, height, depth, cur_index, is_in_bound); if (nbound == sgw->conn) { /* all neighbors are in bound */ for (j = 0; j < sgw->conn; j++) { UPDATE_SUPER_CONDUCTOR } } else if (nbound > 0) { for (j = 0; j < sgw->conn; j++) { if (is_in_bound[j]) { UPDATE_SUPER_CONDUCTOR } } } sgw->checked[cur_index] = 1; size_t tmp_index = cur_index; cur_index = sgw->path[cur_index]; sgw->path[tmp_index] = r; count++; } }