void sort_tree(struct tnode *root) { if(root == NULL) return; sort_tree(root->left); add_to_list(root); sort_tree(root->right); }
/* Sorting the nodes such that topological equal trees has * the same image. The algorithm sort rekursivly all children * and then the silbings with quicksort. * * */ void sort_tree(Node *root){ if( root->width == 0) return;//leaf reached /* Sort children and store pointer to this children */ Node** children = (Node**) malloc( root->width*sizeof(Node*) ); Node** next = children; Node* c = root->child; while( c != NULL ){ sort_tree(c); *next=c; c = c->silbing; next++; } //now, next points behind children array if( root->width > 1){ Node** end = next; quicksort_silbings(children, end); //rearange children of root like sorted array propose. c = *children; root->child = c; next = children+1; while(next<end){ c->silbing = *next; c=*next; next++; } c->silbing = NULL;//remove previous anchor in last child. } free( children ); }
Fl_Node* Fl_Tree::sort_ (Fl_Node* start, int (*compar)(Fl_Node *, Fl_Node *), int down, sort_order order) { int i; Fl_Node* node; i = 0; node = start; while (node) { node = node->next_; i++; } Fl_Node** array = new Fl_Node * [i]; i = 0; node = start; while (node) { array[i] = node; node = node->next_; i++; } s_node_compare_ = compar; if (order == REVERSE_SORT) { qsort(array, i, sizeof(Fl_Node*), (int (*)(const void*, const void*))s_compare_reverse_ ); } else { qsort(array, i, sizeof(Fl_Node*), (int (*)(const void*, const void*))s_compare_); } start = array[0]; int j = 1; node = start; node->prev_ = 0; //james while (j < i) { node->next_ = array[j]; node->next_->prev_ = node; node = node->next_; j++; } node->next_ = 0; if (down) { node = start; while (node) { if (node->sub_) node->sub_ = sort_tree(node->sub_, compar, order); if (node->vsub_) node->vsub_ = node->sub_; node = node->next_; } } delete [] array; return start; }
void sort_print(struct tnode *root) { int i; sort_tree(root); printf("lsp = %d",lsp); for(i = 0; i < lsp; i++) { printf("%s : %d", (sort_list[i])->word, (sort_list[i])->count); } }
FORCEINLINE Tree* find_depthtree( const unsigned char *data, const unsigned int w, const unsigned int h, const BlobtreeRect roi, const unsigned char *depth_map, const unsigned int stepwidth, DepthtreeWorkspace *workspace, Blob** tree_data ) { //#define stepwidth 7 //speed up due faster addition for fixed stepwidth?! #define stepheight stepwidth /* Marks of 10 Cases: * x - stepwidth, y - stepheight, swr - (w-1)%x, shr - (h-1)%y * <----------------------- w ---------------------------------> * | <-- roi.width --------------> * | <-- roi.width-swr --> * | * | | | A ←x→ B ←x→ … B ←x→ B ←swr→ C * | | roi ↑ ↑ ↑ * h | hei y y y * | r ght ↓ ↓ ↓ * | o - E ←x→ F ←x→ … F ←x→ G ←swr→ H * | i shr ↑ ↑ ↑ * | . | y y y * | h | ↓ ↓ ↓ * | e | E ←x→ F ←x→ … F ←x→ G ←swr→ H * | i | … … … * | g | E ←x→ F ←x→ … F ←x→ G ←swr→ H * | h ↑ ↑ ↑ * | t shr shr shr * | | ↓ ↓ ↓ * h | L ←x→ M ←x→ … M ←x→ N ←swr→ P * | * | * | * */ //init unsigned int const r=w-roi.x-roi.width; //right border unsigned int const b=h-roi.y-roi.height; //bottom border if( r<0 || b<0 ){ fprintf(stderr,"[blob.c] BlobtreeRect not matching.\n"); *tree_data = NULL; return NULL; } unsigned int const swr = (roi.width-1)%stepwidth; // remainder of width/stepwidth; unsigned int const shr = (roi.height-1)%stepheight; // remainder of height/stepheight; unsigned int const sh = stepheight*w; unsigned int const sh1 = (stepheight-1)*w; unsigned int const sh2 = shr*w; unsigned int id=-1;//id for last component, attention, unsigned variable!! unsigned int k; //loop variable unsigned int max_comp = workspace->max_comp; unsigned int idA, idB; unsigned char depX; unsigned int* ids = workspace->ids; unsigned int* comp_same = workspace->comp_same; unsigned int* prob_parent = workspace->prob_parent; unsigned int* id_depth = workspace->id_depth; #ifdef BLOB_COUNT_PIXEL unsigned int* comp_size = workspace->comp_size; #endif #ifdef BLOB_DIMENSION unsigned int* top_index = workspace->top_index; unsigned int* left_index = workspace->left_index; unsigned int* right_index = workspace->right_index; unsigned int* bottom_index = workspace->bottom_index; #endif #ifdef PIXEL_POSITION unsigned int s=roi.x,z=roi.y; //s-spalte, z-zeile #else const unsigned int s=0,z=0; //Should not be used. #endif #ifdef BLOB_BARYCENTER BLOB_BARYCENTER_TYPE *pixel_sum_X = workspace->pixel_sum_X; BLOB_BARYCENTER_TYPE *pixel_sum_Y = workspace->pixel_sum_Y; #endif unsigned int *a_ids, *b_ids/*, *c_ids, *d_ids*/; unsigned char *a_dep, *b_dep/*, *c_dep, *d_dep*/; #ifdef NO_DEPTH_MAP /* map depth on data array */ unsigned char * const depths = data; #else unsigned char * const depths = workspace->depths; #endif unsigned char * const depS = depths+w*roi.y+roi.x; const unsigned char* const dS = data+(depS-depths); const unsigned char* depR = depS+roi.width; //Pointer to right border. Update on every line const unsigned char* depR2 = depR-swr; //cut last indizies. const unsigned char* const depE = depR + (roi.height-1)*w; const unsigned char* const depE2 = depE - shr*w;//remove last lines. unsigned int* iPi = ids+(dS-data); // Poiner to ids+i unsigned char *depPi = depS; /* Eval depth(roi) aka *(depth_map+i) for i∈roi * */ #ifndef NO_DEPTH_MAP const unsigned char* dPi = dS; // Pointer to data+i for( ; depPi<depE2 ; ){ for( ; depPi<depR2 ; dPi += stepwidth, depPi += stepwidth ){ *depPi = *(depth_map + *dPi); } //handle last index of current line dPi -= stepwidth-swr; depPi -= stepwidth-swr; if( swr ){ *depPi = *(depth_map + *dPi); } //move pointer to 'next' row dPi += r+roi.x+sh1+1; depPi += r+roi.x+sh1+1; depR += sh; //rechter Randindex wird in nächste Zeile geschoben. depR2 += sh; } //handle last line & last element if( shr ){ dPi -= sh-sh2; depPi -= sh-sh2; depR -= sh-sh2; depR2 -= sh-sh2; for( ; depPi<depR2 ; dPi += stepwidth, depPi += stepwidth ){ *depPi = *(depth_map + *dPi); } //handle last index of current line dPi -= stepwidth-swr; depPi -= stepwidth-swr; if( swr ){ *depPi = *(depth_map + *dPi); } } //reset pointer; depPi = depths+(dS-data); depR = depS+roi.width; depR2 = depR-swr; //cut last indizies. #if VERBOSE > 0 printf("Depth matix(roi): \n"); debug_print_matrix_char( depths, w, h, roi, 1, 1); #endif #else #endif /* Dummy for foreground (id=0, depth=255). It's important to set id=0 for * this component. */ NEW_COMPONENT(1, 255 ); /* Dummy for background (id=1, depth=0), Attention, -1=MAX_UINT */ NEW_COMPONENT(-1, 0 ); #ifdef BLOB_COUNT_PIXEL /* Set size of dummy foreground component to 0. */ *(comp_size+0) = 0; #endif #ifdef BLOB_BARYCENTER /* Dummy foreground should not influence the barycenter. */ *(pixel_sum_X+0) = 0; *(pixel_sum_Y+0) = 0; #endif /**** A,A'-CASE *****/ //top, left corner of BlobtreeRect get first id (=2). depX = *depPi; if( depX>0 ){ #ifdef BLOB_COUNT_PIXEL /* Set size of background dummy component to 0. */ *(comp_size+1) = 0; #endif #ifdef BLOB_BARYCENTER /* Dummy background should not influence the barycenter. */ *(pixel_sum_X+1) = 0; *(pixel_sum_Y+1) = 0; #endif NEW_COMPONENT(1, depX ); }else{ //use dummy component id=1 for corner element. This avoid wrapping of //all blobs. *iPi = 1; } iPi += stepwidth; depPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif //top border /**** B-CASE *****/ for( ; depPi<depR2; iPi += stepwidth, depPi += stepwidth ){ idA = *(iPi-stepwidth); depX = *depPi; INSERT_ELEMENT1( idA, iPi, *depPi); #ifdef PIXEL_POSITION s += stepwidth; #endif } //correct pointer shift of last for loop step. iPi -= stepwidth-swr; depPi -= stepwidth-swr; #ifdef PIXEL_POSITION s -= stepwidth-swr; #endif //continue with +swr stepwidth if(swr){ /**** C-CASE *****/ idA = *(iPi-swr); depX = *depPi; INSERT_ELEMENT1( idA, iPi, *depPi); } //move pointer to 'next' row depPi += r+roi.x+sh1+1; iPi += r+roi.x+sh1+1; depR += sh; //rechter Randindex wird in nächste Zeile geschoben. depR2 += sh; #ifdef PIXEL_POSITION s=roi.x; z += stepheight; #endif //2nd,...,(h-shr)-row for( ; depPi<depE2 ; depPi += r+roi.x+sh1+1, iPi += r+roi.x+sh1+1, depR += sh, depR2 += sh ){ //left border /**** E-CASE *****/ idA = ARGMAX2( *(iPi-sh), *(iPi-sh+stepwidth), *(depPi-sh), *(depPi-sh+stepwidth) ); depX = *depPi; INSERT_ELEMENT1( idA, iPi, *depPi); iPi += stepwidth; depPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif /*inner elements till last colum before depR2 reached. * => Lefthand tests with -stepwidth * Righthand tests with +stepwidth */ for( ; depPi<depR2-stepwidth; iPi += stepwidth, depPi += stepwidth ){ /**** F-CASE *****/ idA = ARGMAX2( *(iPi-sh-stepwidth), *(iPi-stepwidth), *(depPi-sh-stepwidth), *(depPi-stepwidth) ); /* max(a,d) */ idB = ARGMAX2( *(iPi-sh), *(iPi-sh+stepwidth), *(depPi-sh), *(depPi-sh+stepwidth) ); /* max(b,c) */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); #ifdef PIXEL_POSITION s += stepwidth; #endif } /* If depR2==depR, then the last column is reached. Thus it's not possibe * to check diagonal element. (only G case) * Otherwise use G and H cases. */ if( swr /*depR2!=depR*/ ){ //structure: (depPi-stepwidth),(depPi),(depPi+swr) /**** G-CASE *****/ idA = ARGMAX2( *(iPi-sh-stepwidth), *(iPi-stepwidth), *(depPi-sh-stepwidth), *(depPi-stepwidth) ); /* max(a,d) */ idB = ARGMAX2( *(iPi-sh), *(iPi-sh+swr), *(depPi-sh), *(depPi-sh+swr) ); /* max(b,c) */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); iPi+=swr; depPi+=swr; #ifdef PIXEL_POSITION s+=swr; #endif //right border, not check diag element /**** H-CASE *****/ idA = ARGMAX2( *(iPi-sh-swr), *(iPi-swr), *(depPi-sh-swr), *(depPi-swr) ); /* max(a,d) */ idB = *(iPi-sh); /* b */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); }else{ /**** G-CASE *****/ idA = ARGMAX2( *(iPi-sh-stepwidth), *(iPi-stepwidth), *(depPi-sh-stepwidth), *(depPi-stepwidth) ); /* max(a,d) */ idB = *(iPi-sh); /* b */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); }//end of else case of (depR2!=depR) #ifdef PIXEL_POSITION s=roi.x; z += stepheight; #endif } //row for loop iPi -= sh-sh2;//(stepheight-1)*w; depPi -= sh-sh2;//(stepheight-1)*w; depR -= sh-sh2; depR2 -= sh-sh2; #ifdef PIXEL_POSITION z -= stepheight-shr; #endif if( shr /*dE2<dE*/ ){ //left border /**** L-CASE *****/ idA = ARGMAX2( *(iPi-sh2), *(iPi-sh2+stepwidth), *(depPi-sh2), *(depPi-sh2+stepwidth) ); depX = *depPi; INSERT_ELEMENT1( idA, iPi, *depPi); iPi += stepwidth; depPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif /*inner elements till last colum before depR2 reached. * => Lefthand tests with -stepwidth * Righthand tests with +stepwidth */ for( ; depPi<depR2-stepwidth; iPi += stepwidth, depPi += stepwidth ){ /**** M-CASE *****/ idA = ARGMAX2( *(iPi-sh2-stepwidth), *(iPi-stepwidth), *(depPi-sh2-stepwidth), *(depPi-stepwidth) ); /* max(a,d) */ idB = ARGMAX2( *(iPi-sh2), *(iPi-sh2+stepwidth), *(depPi-sh2), *(depPi-sh2+stepwidth) ); /* max(b,c) */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); #ifdef PIXEL_POSITION s += stepwidth; #endif } /* If depR2==depR, then the last column is reached. Thus it's not possibe * to check diagonal element. (only N case) * Otherwise use N and P cases. */ if( swr/*depR2!=depR*/ ){ //structure: (depPi-stepwidth),(depPi),(depPi+swr) /**** N-CASE *****/ idA = ARGMAX2( *(iPi-sh2-stepwidth), *(iPi-stepwidth), *(depPi-sh2-stepwidth), *(depPi-stepwidth) ); /* max(a,d) */ idB = ARGMAX2( *(iPi-sh2), *(iPi-sh2+swr), *(depPi-sh2), *(depPi-sh2+swr) ); /* max(b,c) */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); iPi+=swr; depPi+=swr; #ifdef PIXEL_POSITION s+=swr; #endif //right border, not check diag element /**** P-CASE *****/ idA = ARGMAX2( *(iPi-sh2-swr), *(iPi-swr), *(depPi-sh2-swr), *(depPi-swr) ); /* max(a,d) */ idB = *(iPi-sh2); /* b */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); }else{ /**** N-CASE *****/ idA =ARGMAX2( *(iPi-sh2-stepwidth), *(iPi-stepwidth), *(depPi-sh2-stepwidth), *(depPi-stepwidth) ); /* max(a,d) */ idB = *(iPi-sh2); /* b */ depX = *depPi; INSERT_ELEMENT2( idA, idB, iPi, *depPi); }//end of else case of (depR2!=depR) } //end of if(depE2<depE) /* end of main algo */ #if VERBOSE > 0 //printf("Matrix of ids:\n"); //print_matrix(ids,w,h); //printf("comp_same:\n"); //print_matrix(comp_same, id+1, 1); debug_print_matrix( ids, w, h, roi, 1, 1); debug_print_matrix2( ids, comp_same, w, h, roi, 1, 1, true); #endif /* Postprocessing. * Sum up all areas with connecteted ids. * Then create nodes and connect them. * If BLOB_DIMENSION is set, detect * extremal limits in [left|right|bottom]_index(*(real_ids+X)). * */ unsigned int nids = id+1; //number of ids unsigned int tmp_id,/*tmp_id2,*/ real_ids_size=0,l; //int* real_ids = calloc( nids,sizeof(int) ); //store join of ids. //int* real_ids_inv = calloc( nids,sizeof(int) ); //store for every id with position in real_id link to it's position. free(workspace->real_ids); workspace->real_ids = calloc( nids, sizeof(int) ); //store join of ids. unsigned int* const real_ids = workspace->real_ids; free(workspace->real_ids_inv); workspace->real_ids_inv = calloc( nids, sizeof(unsigned int) ); //store for every id with position in real_id link to it's position. unsigned int* const real_ids_inv = workspace->real_ids_inv; for(k=1;k<nids;k++){ // k=1 skips the foreground dummy component id=0 /* Sei F=comp_same. Wegen F(x)<=x folgt (F wird innerhalb dieser Schleife angepasst!) * F^2 = F^3 = ... = F^* * D.h. um die endgültige id zu finden muss comp_same maximal zweimal aufgerufen werden. * */ tmp_id = *(comp_same+k); #if VERBOSE > 0 printf("%u: (%u->%u ",k,k,tmp_id); #endif if( tmp_id != k ){ tmp_id = *(comp_same+tmp_id); *(comp_same+k) = tmp_id; #if VERBOSE > 0 printf("->%u ",tmp_id); #endif } #if VERBOSE > 0 printf(")\n"); #endif if( tmp_id != k ){ #ifdef BLOB_COUNT_PIXEL //move area size to other id. *(comp_size+tmp_id) += *(comp_size+k); *(comp_size+k) = 0; #endif #ifdef BLOB_DIMENSION //update dimension if( *( top_index+tmp_id ) > *( top_index+k ) ) *( top_index+tmp_id ) = *( top_index+k ); if( *( left_index+tmp_id ) > *( left_index+k ) ) *( left_index+tmp_id ) = *( left_index+k ); if( *( right_index+tmp_id ) < *( right_index+k ) ) *( right_index+tmp_id ) = *( right_index+k ); if( *( bottom_index+tmp_id ) < *( bottom_index+k ) ) *( bottom_index+tmp_id ) = *( bottom_index+k ); #endif #ifdef BLOB_BARYCENTER //shift values to other id *(pixel_sum_X+tmp_id) += *(pixel_sum_X+k); *(pixel_sum_X+k) = 0; *(pixel_sum_Y+tmp_id) += *(pixel_sum_Y+k); *(pixel_sum_Y+k) = 0; #endif }else{ //Its a component id of a new area *(real_ids+real_ids_size) = tmp_id; *(real_ids_inv+tmp_id) = real_ids_size;//inverse function real_ids_size++; } } /* * Generate tree structure */ /* store for real_ids the index of the node in the tree array */ unsigned int *tree_id_relation = malloc( (real_ids_size+1)*sizeof(unsigned int) ); Node *nodes = malloc( (real_ids_size+1)*sizeof(Node) ); Blob *blobs = malloc( (real_ids_size+1)*sizeof(Blob) ); Tree *tree = malloc( sizeof(Tree) ); tree->root = nodes; tree->size = real_ids_size + 1; //init all node as leafs for(l=0;l<real_ids_size+1;l++) *(nodes+l)=Leaf; //set root node (the desired output are the child(ren) of this node.) Node * const root = nodes; Node *cur = nodes; Blob *curdata = blobs; /* Set root node which represents the whole image/ROI. * Keep in mind, that the number of children depends * on the border pixels of the ROI. * Almost in every cases it's only one child, but not always. * */ curdata->id = -1; /* = MAX_UINT */ memcpy( &curdata->roi, &roi, sizeof(BlobtreeRect) ); curdata->area = roi.width * roi.height; #ifdef SAVE_DEPTH_MAP_VALUE curdata->depth_level = 0; #endif cur->data = curdata; // link to the data array. BlobtreeRect *rect; for(l=0;l<real_ids_size;l++){ cur++; curdata++; cur->data = curdata; // link to the data array. const unsigned int rid = *(real_ids+l); curdata->id = rid; //Set id of this blob. #ifdef BLOB_DIMENSION rect = &curdata->roi; rect->y = *(top_index + rid); rect->height = *(bottom_index + rid) - rect->y + 1; rect->x = *(left_index + rid); rect->width = *(right_index + rid) - rect->x + 1; #endif #ifdef BLOB_BARYCENTER /* The barycenter will not set here, but in eval_barycenters(...) */ //curdata->barycenter[0] = *(pixel_sum_X + rid) / *(comp_same + rid); //curdata->barycenter[1] = *(pixel_sum_Y + rid) / *(comp_same + rid); #endif #ifdef SAVE_DEPTH_MAP_VALUE curdata->depth_level = *(id_depth + rid ); #endif tmp_id = *(prob_parent+*(real_ids+l)); //get id of parent (or child) area. if( tmp_id == -1 /*=MAX_UINT*/ ){ /* Use root as parent node. */ //cur->parent = root; add_child(root, cur ); }else{ //find real id of parent id. #if 1 tmp_id = *(comp_same+tmp_id); #else //this was commented out because comp_same is here a projection. tmp_id2 = *(comp_same+tmp_id); while( tmp_id != tmp_id2 ){ tmp_id = tmp_id2; tmp_id2 = *(comp_same+tmp_id); } #endif /*Now, tmp_id is in real_id array. And real_ids_inv is defined. */ add_child( root + 1/*root pos shift*/ + *(real_ids_inv+tmp_id ), cur ); } } #ifdef BLOB_BARYCENTER eval_barycenters(root->child,root, comp_size, pixel_sum_X, pixel_sum_Y); #define SUM_AREAS_IS_REDUNDANT #endif //sum up node areas #ifdef BLOB_COUNT_PIXEL #if VERBOSE > 1 unsigned int ci; printf("comp_size Array:\n"); for( ci=0 ; ci<nids; ci++){ printf("cs[%u]=%u\n",ci, *(comp_size + *(real_ids+ci) ) ); } #endif #ifndef SUM_AREAS_IS_REDUNDANT sum_areas(root->child, comp_size); #endif #endif /* If no pixel has depth=0, the dummy component with id=1 (or=2 ?) * wrapping all blobs. In this case we could remove this * blob from the tree. * */ if( *(comp_size+1)==0 ){ root->child = root->child->child; } #ifdef BLOB_DIMENSION #ifdef EXTEND_BOUNDING_BOXES extend_bounding_boxes( tree ); #endif #endif #ifdef BLOB_SORT_TREE //sort_tree(root->child); sort_tree(root); #endif //current id indicates maximal used id in ids-array workspace->used_comp=id; //clean up free(tree_id_relation); //free(real_ids); //free(real_ids_inv); //set output parameter //*tree_size = real_ids_size+1; *tree_data = blobs; return tree; }
int main(int argc, char *argv[]) { struct boot_info *bi; const char *inform = "dts"; const char *outform = "dts"; const char *outname = "-"; const char *depname = NULL; int force = 0, sort = 0; const char *arg; int opt; FILE *outf = NULL; int outversion = DEFAULT_FDT_VERSION; long long cmdline_boot_cpuid = -1; quiet = 0; reservenum = 0; minsize = 0; padsize = 0; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case 'I': inform = optarg; break; case 'O': outform = optarg; break; case 'o': outname = optarg; break; case 'V': outversion = strtol(optarg, NULL, 0); break; case 'd': depname = optarg; break; case 'R': reservenum = strtol(optarg, NULL, 0); break; case 'S': minsize = strtol(optarg, NULL, 0); break; case 'p': padsize = strtol(optarg, NULL, 0); break; case 'f': force = 1; break; case 'q': quiet++; break; case 'b': cmdline_boot_cpuid = strtoll(optarg, NULL, 0); break; case 'i': srcfile_add_search_path(optarg); break; case 'v': util_version(); case 'H': if (streq(optarg, "legacy")) phandle_format = PHANDLE_LEGACY; else if (streq(optarg, "epapr")) phandle_format = PHANDLE_EPAPR; else if (streq(optarg, "both")) phandle_format = PHANDLE_BOTH; else die("Invalid argument \"%s\" to -H option\n", optarg); break; case 's': sort = 1; break; case 'W': parse_checks_option(true, false, optarg); break; case 'E': parse_checks_option(false, true, optarg); break; case '@': symbol_fixup_support = 1; break; case 'h': usage(NULL); default: usage("unknown option"); } } if (argc > (optind+1)) usage("missing files"); else if (argc < (optind+1)) arg = "-"; else arg = argv[optind]; /* minsize and padsize are mutually exclusive */ if (minsize && padsize) die("Can't set both -p and -S\n"); if (depname) { depfile = fopen(depname, "w"); if (!depfile) die("Couldn't open dependency file %s: %s\n", depname, strerror(errno)); fprintf(depfile, "%s:", outname); } if (streq(inform, "dts")) bi = dt_from_source(arg); else if (streq(inform, "fs")) bi = dt_from_fs(arg); else if(streq(inform, "dtb")) bi = dt_from_blob(arg); else die("Unknown input format \"%s\"\n", inform); if (depfile) { fputc('\n', depfile); fclose(depfile); } if (cmdline_boot_cpuid != -1) bi->boot_cpuid_phys = cmdline_boot_cpuid; fill_fullpaths(bi->dt, ""); process_checks(force, bi); if (sort) sort_tree(bi); if (streq(outname, "-")) { outf = stdout; } else { outf = fopen(outname, "w"); if (! outf) die("Couldn't open output file %s: %s\n", outname, strerror(errno)); } if (streq(outform, "dts")) { dt_to_source(outf, bi); } else if (streq(outform, "dtb")) { dt_to_blob(outf, bi, outversion); } else if (streq(outform, "asm")) { dt_to_asm(outf, bi, outversion); } else if (streq(outform, "null")) { /* do nothing */ } else { die("Unknown output format \"%s\"\n", outform); } exit(0); }
Tree* find_connection_components_subcheck( const unsigned char *data, const unsigned int w, const unsigned int h, const BlobtreeRect roi, const unsigned char thresh, const unsigned int stepwidth, Blob** tree_data, ThreshtreeWorkspace *workspace ) { /* With region of interrest (roi) * and fixed stepwidth. * A - stepwidth - B * | | * | stepwidth * | | * C ------------- D * */ /* Marks of ι Cases: * x - stepwidth, y - stepwidth, swr - (w-1)%x, shr - (h-1)%y * <----------------------- w ---------------------------------> * | <-- roi.width ------------------------> * | <- roi.width-stepwidth-swr --> * | * | | | A ←x→ B ←x→ … B ←x→ C ←swr+stepwidth→ C * | | roi ↑ ↑ ↑ * h | hei y y y * | r ght ↓ ↓ ↓ * | o - E ←x→ F ←x→ … F ←x→ G ←swr+stepwidth→ H * | i ste ↑ ↑ ↑ * | . pwi y y y * | h dth ↓ ↓ ↓ * | e - E ←x→ F ←x→ … F ←x→ G ←swr+stepwidth→ H * | i shr … … … * | g | E ←x→ F ←x→ … F ←x→ G ←swr+stepwidth→ H * | h ↑ ↑ ↑ * | t 1 1 1 * | | ↓ ↓ ↓ * h | L ←x→ M ←x→ … M ←x→ N ←swr+stepwidth→ P * | | ↑ ↑ ↑ * | | 1 1 1 * | | ↓ ↓ ↓ * h | L ←x→ M ←x→ … M ←x→ N ←swr+stepwidth→ P * | * | * | * */ if( stepwidth < 2){ return find_connection_components_coarse(data,w,h,roi,thresh,1,1,tree_data, workspace); } //init unsigned int r=w-roi.x-roi.width; //right border unsigned int b=h-roi.y-roi.height; //bottom border if( r>(1<<16) || b>(1<<16) ){ fprintf(stderr,"[blob.c] BlobtreeRect not matching.\n"); *tree_data = NULL; return NULL; } unsigned int swr = (roi.width-1)%stepwidth; // remainder of width/stepwidth; unsigned int shr = (roi.height-1)%stepheight; // remainder of height/stepheight; unsigned int sh = stepheight*w; unsigned int sh1 = (stepheight-1)*w; // unsigned int sh2 = shr*w; #define DUMMY_ID -1 //id virtual parent of first element (id=0) unsigned int id=-1;//id for next component would be ++id unsigned int a1,a2; // for comparation of g(f(x))=a1,a2=g(f(y)) unsigned int k; //loop variable /* Create pointer to workspace arrays */ unsigned int max_comp = workspace->max_comp; unsigned int* ids = workspace->ids; unsigned int* comp_same = workspace->comp_same; unsigned int* prob_parent = workspace->prob_parent; #ifdef BLOB_COUNT_PIXEL unsigned int* comp_size = workspace->comp_size; #endif #ifdef BLOB_DIMENSION unsigned int* top_index = workspace->top_index; unsigned int* left_index = workspace->left_index; unsigned int* right_index = workspace->right_index; unsigned int* bottom_index = workspace->bottom_index; #endif #ifdef BLOB_BARYCENTER BLOB_BARYCENTER_TYPE *pixel_sum_X = workspace->pixel_sum_X; BLOB_BARYCENTER_TYPE *pixel_sum_Y = workspace->pixel_sum_Y; #endif #ifdef PIXEL_POSITION unsigned int s=roi.x,z=roi.y; //s-spalte, z-zeile #else const unsigned int s=0,z=0; //Should not be used. #endif /* triangle array store information about the * evaluation of ids between the grid pixels. * This info is needed to avoid double evaluation * of ids for some pixels, which would be a critical problem. * Let sw = stepwidth, x%sw=0, y%sw=0. * * The image will divided into quads [x,x+sw) x (y-sw,y+sw] * Quads on right and bottom border will expand to image border. * Quads on the top border will notional shrinked to [x,x+sw) x (-1,0]. * * 0 - Only the ids of the corners of a quad was evaluated * 1 - Ids for all Pixels over the anti-diagonal and the corners was evaluated. * 2 - All pixels of the quad was examined. * * */ const unsigned int triwidth = (roi.width-1)/stepwidth + 1; const size_t triangle_len = (triwidth+1)* ( (roi.height-1)/stepheight + 1); if( triangle_len > workspace->triangle_len ){ free(workspace->triangle); workspace->triangle = (unsigned char*) malloc( triangle_len * sizeof(unsigned char) ); if( workspace->triangle == NULL ){ printf("(threshtree) Critical error: Mem allocation for triangle failed\n"); } workspace->triangle_len = triangle_len; } unsigned char* const triangle = workspace->triangle; unsigned char* tri = triangle; #if VERBOSE > 0 printf("triwidth: %u\n", triwidth); #endif const unsigned char* const dS = data+w*roi.y+roi.x; const unsigned char* dR = dS+roi.width; //Pointer to right border. Update on every line //unsigned char* dR2 = swr>0?dR-swr-stepwidth-stepwidth:dR; //cut last indizies. const unsigned char* dR2 = dR-swr-stepwidth; //cut last indizies. const unsigned char* const dE = dR + (roi.height-1)*w; const unsigned char* const dE2 = dE - shr*w;//remove last lines. //unsigned int i = w*roi.y+roi.x; const unsigned char* dPi = dS; // Pointer to data+i unsigned int* iPi = ids+(dS-data); // Poiner to ids+i #if VERBOSE > 0 //debug: prefill array printf("Note: Prefill ids array with 0. This will be removed for VERBOSE=0\n"); memset(ids,0, w*h*sizeof(unsigned int)); #endif /**** A,A'-CASE *****/ //top, left corner of BlobtreeRect get first id. NEW_COMPONENT(DUMMY_ID); BLOB_INC_COMP_SIZE( *iPi ); BLOB_INC_BARY( *iPi ); iPi += stepwidth; dPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif ++tri; /* Split all logic to two subcases: * *(dPi)<=thresh (marked as B,C,…), * *(dPi)>thresh (marked as B',C',…) * to avoid many 'x&&y || x|y==0' checks. * */ /* *tri beschreibt, was in der Zelle rechts davon/darüber passiert ist.*/ //top border for( ;dPi<dR2; ){ if( *(dPi) > thresh ){ /**** B-CASE *****/ if(*(dPi-stepwidth) > thresh ){//same component as left neighbour LEFT_CHECK(stepwidth); *(tri-1)=0; }else{//new component SUBCHECK_ROW(dPi,iPi,stepwidth,w,sh,s,z,0); *(tri-1)=2; } }else{ /**** B'-CASE *****/ if(*(dPi-stepwidth) <= thresh ){//same component as left neighbour LEFT_CHECK(stepwidth) *(tri-1)=0; }else{//new component SUBCHECK_ROW(dPi,iPi,stepwidth,w,sh,s,z,0); *(tri-1)=2; } } BLOB_INC_COMP_SIZE( *iPi ); BLOB_INC_BARY( *iPi ); iPi += stepwidth; dPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif ++tri; } //now process last, bigger, cell. stepwidth+swr indizies left. SUBCHECK_ROW(dPi,iPi,stepwidth,w,sh,s,z,swr); *(tri-1)=2; *(tri) = 9;//Dummy, unused value. /* Pointer is swr behind currrent element.*/ //BLOB_INC_COMP_SIZE; would increase wrong element, omit macro #ifdef BLOB_COUNT_PIXEL *(comp_size+*(iPi-swr)) += 1; #endif #ifdef BLOB_BARYCENTER *(pixel_sum_X+*(iPi-swr)) += s; *(pixel_sum_Y+*(iPi-swr)) += z; #endif /* Move pointer to 'next' row.*/ dPi += r+roi.x+sh1+1; iPi += r+roi.x+sh1+1; dR += sh; // Move right border to next row. dR2 += sh; #ifdef PIXEL_POSITION s=roi.x; z += stepheight; #endif ++tri; //2nd,...,(h-shr)-row for( ; dPi<dE2 ; ){ //left border /* 8 Cases for >thresh-Test of 3 positions * a — b * | * x * * The positions in '—' are already evaluated if a!=b (<=> *(tri-triwidth)==2 ) * */ { const unsigned char casenbr = ( *(dPi) > thresh )? \ ( (( *(dPi-sh+stepwidth) <= thresh ) << 1) | (( *(dPi-sh) <= thresh ) << 0)): \ ( (( *(dPi-sh+stepwidth) > thresh ) << 1) | (( *(dPi-sh) > thresh ) << 0)); switch( casenbr ){ case 0:{ /* no differences */ TOP_CHECK(stepheight, sh); *(tri) = 0; break; } case 1: case 2:{ SUBCHECK_PART2b(dPi,iPi,stepwidth,w,sh,s,z); *(tri) = 1; break; } case 3:{ /* a and b at same side of thresh, evaluate pixels between them*/ if( *(tri-triwidth)<3 ){ /* For second row value 2 is possible => do not use !=1.*/ SUBCHECK_PART1c(dPi,iPi,stepwidth,w,sh,s,z); } SUBCHECK_PART2b(dPi,iPi,stepwidth,w,sh,s,z); *(tri) = 1; break; } } } BLOB_INC_COMP_SIZE( *iPi ); BLOB_INC_BARY( *iPi ); iPi += stepwidth; dPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif ++tri; /*inner elements till last colum before dR2 reached. * => Lefthand tests with -stepwidth * Righthand tests with +stepwidth */ for( ; dPi<dR2; ){ /* Bit order: * 0 2 3 * 1 */ /*const*/ unsigned char casenbr = ( *(dPi) > thresh )? \ ( (( *(dPi-sh+stepwidth) <= thresh ) << 3) | (( *(dPi-sh) <= thresh ) << 2) | (( *(dPi-stepwidth) <= thresh ) << 1) | (( *(dPi-sh-stepwidth) <= thresh ) << 0)): \ ( (( *(dPi-sh+stepwidth) > thresh ) << 3) | (( *(dPi-sh) > thresh ) << 2) | (( *(dPi-stepwidth) > thresh ) << 1) | (( *(dPi-sh-stepwidth) > thresh ) << 0)); #if VERBOSE > 1 debug_print_matrix( ids, w, h, roi, 1, 1); printf("F, casenbr: %u, *tri: %u %u %u\n",casenbr, *(tri-1), *(tri-triwidth), *(tri-triwidth+1)); debug_getline(); #endif if( dPi+stepwidth>=dR2 ){ //set bit do avoid PART1c/PART1d calls for column of last loop step. //Could be unrolled... casenbr = casenbr | 0x08; } if( dPi+sh>=dE2 ){ //set bit do force PART4 calls for this row. casenbr = casenbr | 0x02; } /* Legend: * X Current position of pointer * o Coarse grid positions * • Fine positions. Ids can already set or not ( information is encoded by casenbr ) * ♣ Known ids, already set. * ♦ New id, set in this step. (Not set for -,| if already set) * */ /* *(tri-2)=0: Positions * -2 -1 0 <== tri-shift * o o•••o•••o o o♦♦♦o♦♦♦o o o•••o•••o * • ♦♦♦♦♦♦♦♦ • * • ==> ♦♦♦♦♦♦♦ or • * • ♦♦♦♦♦♦ • * o o X o o♦♦♦X o o X */ /* *(tri-2)=1: * o♣♣♣o•••o•••o o♣♣♣o♦♦♦o♦♦♦o o♣♣♣o•••o•••o * ♣♣♣♣• ♣♣♣♣♦♦♦♦♦♦♦♦ ♣♣♣♣• * ♣♣♣ • ==> ♣♣♣ ♦♦♦♦♦♦♦ or ♣♣♣ • * ♣♣ • ♣♣ ♦♦♦♦♦♦ ♣♣ • * o o X o o♦♦♦X o o X */ /* *(tri-2)=3: * o♣♣♣o♣♣♣o•••o o♣♣♣o♦♦♦o♦♦♦o o♣♣♣o♣♣♣o•••o * ♣♣♣♣♣♣♣♣ ♣♣♣♣♣♣♣♣♦♦♦♦ ♣♣♣♣♣♣♣♣ * ♣♣♣♣♣♣♣ ==> ♣♣♣♣♣♣♣♦♦♦♦ or ♣♣♣♣♣♣♣ * ♣♣♣♣♣♣ ♣♣♣♣♣♣♦♦♦♦ ♣♣♣♣♣♣ * o♣♣♣o X o♣♣♣o♦♦♦X o o X */ /* ==> Wenn man die |-Stellen im Fall *(tri-2) nicht von den Dreieckswerten * links davor abhängig macht, sind Fall 0 und Fall 1. identisch zu behandeln. * In dem Fall kann man auch *(tri-1) für die Entscheidung heran ziehen. * Trickreich ist noch die Einbeziehung der tri-Werte der vorigen Reihe, was * nicht dargestellt ist. * */ #if VERBOSE > 1 if( *(tri-1) > 1 ){ printf("(threshtree) Logic error: tri>1 should not be possible here.\n"); } #endif if( *(tri-1) == 1 ){ switch( casenbr) { case 0: case 8: { TOP_CHECK(stepheight, sh); TOP_LEFT_COMP(stepwidth); *(tri) = 0; //tri filled, quad not. break; } case 1:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 2:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 3:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 4:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 5:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 6:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 7:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 9:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 10:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 11:{ SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 12:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 13:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 14:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 15:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3b(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } } }else{ switch( casenbr ){ case 0: case 8: { TOP_CHECK(stepheight, sh); TOP_LEFT_COMP(stepwidth); *(tri) = 0; break; } case 1:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 2:{ SUBCHECK_PART1ab(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 3:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 4:{ SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 5:{ SUBCHECK_PART1ab(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 6:{ SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 7:{ SUBCHECK_PART1ab(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 9:{ SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 10:{ SUBCHECK_PART1ab(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 11:{ SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 12:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 13:{ SUBCHECK_PART1ab(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; /*SUBCHECK_PART4b*/SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 14:{ SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } case 15:{ SUBCHECK_PART1ab(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART1cd(dPi,iPi,stepwidth,w,sh,s,z); SUBCHECK_PART3a(dPi,iPi,stepwidth,w,sh,s,z); *(tri-1) = 3; *(tri) = 1; SUBCHECK_PART4a(dPi,iPi,stepwidth,w,sh,s,z); break; } } } BLOB_INC_COMP_SIZE( *iPi ); BLOB_INC_BARY( *iPi ); dPi += stepwidth; iPi += stepwidth; #ifdef PIXEL_POSITION s += stepwidth; #endif ++tri; } #if VERBOSE > 2 debug_print_matrix( ids, w, h, roi, 1, 1); printf("G *tri: %u %u %u\n", *(tri-1), *(tri-triwidth), *(tri-triwidth+1)); debug_getline(); #endif /* now process last, bigger, cell. * There exists only two cases: * triangle=0 or triangle=1. Top border was always evaluated * and bottom border should evaluated, too. */ if( *(tri-1) == 1 ){ SUBCHECK_PART6b(dPi,iPi,stepwidth,w,sh,s,z,swr); }else{ SUBCHECK_PART6a(dPi,iPi,stepwidth,w,sh,s,z,swr); } *(tri-1) = 3; *(tri) = 3; //redundant /* Pointer is still on currrent element.*/ BLOB_INC_COMP_SIZE( *iPi ); BLOB_INC_BARY( *iPi ); /* Move pointer to 'next' row.*/ dPi += r+roi.x+sh1+swr+1; iPi += r+roi.x+sh1+swr+1; dR += sh; // Move border indizes to next row. dR2 += sh; #ifdef PIXEL_POSITION s=roi.x; z += stepheight; #endif ++tri; #if VERBOSE > 2 debug_print_matrix( ids, w, h, roi, 1, 1); printf("Z:%u, S:%u, I:%u %u\n",z,s,dPi-dS, iPi-ids-(dS-data) ); debug_getline(); #endif } //row loop //correct pointer of last for loop step iPi -= sh1; dPi -= sh1; dR -= sh1; dR2 -= sh1; #ifdef PIXEL_POSITION z -= stepheight-1; #endif #if VERBOSE > 1 debug_print_matrix( ids, w, h, roi, 1, 1); printf("Z:%u, S:%u, I:%u %u\n",z,s,dPi-dS, iPi-ids-(dS-data) ); debug_getline(); #endif if( dE2 != dE ){ //Process elementwise till end of ROI reached. /* Note: This pixels are not influence the values of * comp_size because it doesn't made sense to mix up * the counting for coarse pixels and subgrid pixels. * All pixels below dE2 are only elements of the fine grid. * */ for( ; dPi<dE ; ){ SUBCHECK_TOPDIAG(dPi,iPi,stepwidth,w,sh,s,z); ++dPi; ++iPi; #ifdef PIXEL_POSITION ++s; #endif for( ; dPi<dR-1 ; ){ SUBCHECK_ALLDIR(dPi,iPi,stepwidth,w,sh,s,z); ++dPi; ++iPi; #ifdef PIXEL_POSITION ++s; #endif } //right border SUBCHECK_TOPLEFT(dPi,iPi,stepwidth,w,sh,s,z); //move pointer to 'next' row dPi += r+roi.x+1; iPi += r+roi.x+1; #ifdef PIXEL_POSITION s = roi.x; ++z; #endif dR += w; //dR2 += w; //not ness. #if VERBOSE > 1 debug_print_matrix( ids, w, h, roi, 1, 1); printf("Z:%u, S:%u, I:%u %u\n",z,s,dPi-dS, iPi-ids-(dS-data) ); debug_getline(); #endif } }//end of if(dE2<dE) /* end of main algo */ #if VERBOSE > 0 //printf("Matrix of ids:\n"); //print_matrix(ids,w,h); //printf("comp_same:\n"); //print_matrix(comp_same, id+1, 1); debug_print_matrix( ids, w, h, roi, 1, 1); debug_print_matrix2( ids, comp_same, w, h, roi, 1, 1, 0); if( stepwidth*stepheight >1 ){ debug_print_matrix( ids, w, h, roi, stepwidth, stepheight); //printf("\n\n"); debug_print_matrix2( ids, comp_same, w, h, roi, stepwidth, stepheight, 0); } #endif /* Postprocessing. * Sum up all areas with connecteted ids. * Then create nodes and connect them. * If BLOB_DIMENSION is set, detect * extremal limits in [left|right|bottom]_index(*(real_ids+X)). * */ unsigned int nids = id+1; //number of ids unsigned int tmp_id,/*tmp_id2,*/ real_ids_size=0,l; free(workspace->real_ids); workspace->real_ids = calloc( nids, sizeof(unsigned int) ); //store join of ids. unsigned int* const real_ids = workspace->real_ids; free(workspace->real_ids_inv); workspace->real_ids_inv = calloc( nids, sizeof(unsigned int) ); //store for every id with position in real_id link to it's position. unsigned int* const real_ids_inv = workspace->real_ids_inv; #if 1 for(k=0;k<nids;k++){ /* Sei F=comp_same. Wegen F(x)<=x folgt (F wird innerhalb dieser Schleife angepasst!) * F^2 = F^3 = ... = F^* * D.h. um die endgültige id zu finden muss comp_same maximal zweimal aufgerufen werden. * */ tmp_id = *(comp_same+k); #if VERBOSE > 0 printf("%u: (%u->%u ",k,k,tmp_id); #endif if( tmp_id != k ){ tmp_id = *(comp_same+tmp_id); *(comp_same+k) = tmp_id; #if VERBOSE > 0 printf("->%u ",tmp_id); #endif } #if VERBOSE > 0 printf(")\n"); #endif if( tmp_id != k ){ #ifdef BLOB_COUNT_PIXEL //move area size to other id. *(comp_size+tmp_id) += *(comp_size+k); *(comp_size+k) = 0; #endif #ifdef BLOB_DIMENSION //update dimension if( *( top_index+tmp_id ) > *( top_index+k ) ) *( top_index+tmp_id ) = *( top_index+k ); if( *( left_index+tmp_id ) > *( left_index+k ) ) *( left_index+tmp_id ) = *( left_index+k ); if( *( right_index+tmp_id ) < *( right_index+k ) ) *( right_index+tmp_id ) = *( right_index+k ); if( *( bottom_index+tmp_id ) < *( bottom_index+k ) ) *( bottom_index+tmp_id ) = *( bottom_index+k ); #endif #ifdef BLOB_BARYCENTER //shift values to other id *(pixel_sum_X+tmp_id) += *(pixel_sum_X+k); *(pixel_sum_X+k) = 0; *(pixel_sum_Y+tmp_id) += *(pixel_sum_Y+k); *(pixel_sum_Y+k) = 0; #endif }else{ #ifdef BLOB_COUNT_PIXEL /* Elements without nodes on the coarse grid has area-value 0 (if the * area value was evaluated). This elements are problematic because * this provoke the division by 0 due the barycenter evaluation. * Thus, it's probably the best decision * to ignore these nodes. */ if( *(comp_size+tmp_id ) ){ *(real_ids+real_ids_size) = tmp_id; *(real_ids_inv+tmp_id) = real_ids_size;//inverse function real_ids_size++; } #else //Its a component id of a new area *(real_ids+real_ids_size) = tmp_id; *(real_ids_inv+tmp_id) = real_ids_size;//inverse function real_ids_size++; #endif } } #else /* Old approach: Attention, old version does not create * the projection property of comp_same (cs). Here, only cs^2=cs^3. */ unsigned int found; for(k=0;k<nids;k++){ tmp_id = k; tmp_id2 = *(comp_same+tmp_id); #if VERBOSE > 0 printf("%u: (%u->%u) ",k,tmp_id,tmp_id2); #endif while( tmp_id2 != tmp_id ){ tmp_id = tmp_id2; tmp_id2 = *(comp_same+tmp_id); #if VERBOSE > 0 printf("(%u->%u) ",tmp_id,tmp_id2); #endif } #if VERBOSE > 0 printf("\n"); #endif #ifdef BLOB_COUNT_PIXEL //move area size to other id. *(comp_size+tmp_id2) += *(comp_size+k); *(comp_size+k) = 0; #endif #ifdef BLOB_DIMENSION //update dimension if( *( top_index+tmp_id2 ) > *( top_index+k ) ) *( top_index+tmp_id2 ) = *( top_index+k ); if( *( left_index+tmp_id2 ) > *( left_index+k ) ) *( left_index+tmp_id2 ) = *( left_index+k ); if( *( right_index+tmp_id2 ) < *( right_index+k ) ) *( right_index+tmp_id2 ) = *( right_index+k ); if( *( bottom_index+tmp_id2 ) < *( bottom_index+k ) ) *( bottom_index+tmp_id2 ) = *( bottom_index+k ); #endif #ifdef BLOB_BARYCENTER //shift values to other id *(pixel_sum_X+tmp_id) += *(pixel_sum_X+k); *(pixel_sum_X+k) = 0; *(pixel_sum_Y+tmp_id) += *(pixel_sum_Y+k); *(pixel_sum_Y+k) = 0; #endif //check if area id already identified as real id found = 0; for(l=0;l<real_ids_size;l++){ if( *(real_ids+l) == tmp_id ){ found = 1; break; } } if( !found ){ *(real_ids+real_ids_size) = tmp_id; *(real_ids_inv+tmp_id) = real_ids_size;//inverse function real_ids_size++; } } #endif /* * Generate tree structure */ /* store for real_ids the index of the node in the tree array */ unsigned int *tree_id_relation = malloc( (real_ids_size+1)*sizeof(unsigned int) ); Node *nodes = malloc( (real_ids_size+1)*sizeof(Node) ); Blob *blobs = malloc( (real_ids_size+1)*sizeof(Blob) ); Tree *tree = malloc( sizeof(Tree) ); tree->root = nodes; tree->size = real_ids_size + 1; //init all node as leafs for(l=0;l<real_ids_size+1;l++) *(nodes+l)=Leaf; Node * const root = nodes; Node *cur = nodes; Blob *curdata = blobs; curdata->id = -1; /* = MAX_UINT */ memcpy( &curdata->roi, &roi, sizeof(BlobtreeRect) ); curdata->area = roi.width * roi.height; #ifdef SAVE_DEPTH_MAP_VALUE curdata->depth_level = 0; #endif cur->data = curdata; // link to the data array. BlobtreeRect *rect; for(l=0;l<real_ids_size;l++){ cur++; curdata++; cur->data = curdata; // link to the data array. const unsigned int rid = *(real_ids+l); curdata->id = rid; //Set id of this blob. #ifdef BLOB_DIMENSION rect = &curdata->roi; rect->y = *(top_index + rid); rect->height = *(bottom_index + rid) - rect->y + 1; rect->x = *(left_index + rid); rect->width = *(right_index + rid) - rect->x + 1; #endif #ifdef BLOB_BARYCENTER /* The barycenter will not set here, but in eval_barycenters(...) */ //curdata->barycenter[0] = *(pixel_sum_X + rid) / *(comp_same + rid); //curdata->barycenter[1] = *(pixel_sum_Y + rid) / *(comp_same + rid); #endif #ifdef SAVE_DEPTH_MAP_VALUE curdata->depth_level = 0; /* ??? without anchor not trivial.*/ #endif tmp_id = *(prob_parent+rid); //get id of parent (or child) area. if( tmp_id == DUMMY_ID ){ /* Use root as parent node. */ //cur->parent = root; add_child(root, cur ); }else{ //find real id of parent id. #if 1 tmp_id = *(comp_same+tmp_id); #else //this was commented out because comp_same is here a projection. tmp_id2 = *(comp_same+tmp_id); while( tmp_id != tmp_id2 ){ tmp_id = tmp_id2; tmp_id2 = *(comp_same+tmp_id); } #endif /*Now, tmp_id is in real_id array. And real_ids_inv is defined. */ add_child( root + 1/*root pos shift*/ + *(real_ids_inv+tmp_id ), cur ); } } #ifdef BLOB_BARYCENTER eval_barycenters(root->child,root, comp_size, pixel_sum_X, pixel_sum_Y); #define SUM_AREAS_IS_REDUNDANT #endif /* Evaluate exact areas of blobs for stepwidth==1 * and try to approximate for stepwith>1. The * approximation requires a bounding box. * */ #ifdef BLOB_DIMENSION #ifdef BLOB_COUNT_PIXEL if(stepwidth == 1){ #ifndef SUM_AREAS_IS_REDUNDANT sum_areas(root->child, comp_size); #endif }else{ approx_areas(tree, root->child, comp_size, stepwidth, stepheight); //replace estimation with exact value for full image area Blob* img = (Blob*)root->child->data; img->area = img->roi.width * img->roi.height; } #else set_area_prop(root->child); #endif #else #ifdef BLOB_COUNT_PIXEL if(stepwidth == 1){ #ifndef SUM_AREAS_IS_REDUNDANT sum_areas(root->child, comp_size); #endif }else{ #ifndef SUM_AREAS_IS_REDUNDANT sum_areas(root->child, comp_size); #endif //Be aware, this values scales by stepwidth. fprintf(stderr,"(threshtree) Warning: Eval areas for stepwidth>1.\n"); } #endif #endif #ifdef BLOB_SORT_TREE sort_tree(root); #endif //current id indicates maximal used id in ids-array workspace->used_comp=id; //clean up free(tree_id_relation); //free(triangle); // free(anchors); //set output parameter *tree_data = blobs; return tree; }
void Fl_Tree::sort_tree(int (*compar)(Fl_Node *, Fl_Node *), sort_order order) { if (first_) first_ = top_ = sort_tree(first_, compar, order); }
int main(int argc, char *argv[]) { struct dt_info *dti; const char *inform = NULL; const char *outform = NULL; const char *outname = "-"; const char *depname = NULL; bool force = false, sort = false; const char *arg; int opt; FILE *outf = NULL; int outversion = DEFAULT_FDT_VERSION; long long cmdline_boot_cpuid = -1; quiet = 0; reservenum = 0; minsize = 0; padsize = 0; alignsize = 0; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case 'I': inform = optarg; break; case 'O': outform = optarg; break; case 'o': outname = optarg; break; case 'V': outversion = strtol(optarg, NULL, 0); break; case 'd': depname = optarg; break; case 'R': reservenum = strtol(optarg, NULL, 0); break; case 'S': minsize = strtol(optarg, NULL, 0); break; case 'p': padsize = strtol(optarg, NULL, 0); break; case 'a': alignsize = strtol(optarg, NULL, 0); if (!is_power_of_2(alignsize)) die("Invalid argument \"%d\" to -a option\n", alignsize); break; case 'f': force = true; break; case 'q': quiet++; break; case 'b': cmdline_boot_cpuid = strtoll(optarg, NULL, 0); break; case 'i': srcfile_add_search_path(optarg); break; case 'v': util_version(); case 'H': if (streq(optarg, "legacy")) phandle_format = PHANDLE_LEGACY; else if (streq(optarg, "epapr")) phandle_format = PHANDLE_EPAPR; else if (streq(optarg, "both")) phandle_format = PHANDLE_BOTH; else die("Invalid argument \"%s\" to -H option\n", optarg); break; case 's': sort = true; break; case 'W': parse_checks_option(true, false, optarg); break; case 'E': parse_checks_option(false, true, optarg); break; case '@': generate_symbols = 1; break; case 'A': auto_label_aliases = 1; break; case 'h': usage(NULL); default: usage("unknown option"); } } if (argc > (optind+1)) usage("missing files"); else if (argc < (optind+1)) arg = "-"; else arg = argv[optind]; /* minsize and padsize are mutually exclusive */ if (minsize && padsize) die("Can't set both -p and -S\n"); if (depname) { depfile = fopen(depname, "w"); if (!depfile) die("Couldn't open dependency file %s: %s\n", depname, strerror(errno)); fprintf(depfile, "%s:", outname); } if (inform == NULL) inform = guess_input_format(arg, "dts"); if (outform == NULL) { outform = guess_type_by_name(outname, NULL); if (outform == NULL) { if (streq(inform, "dts")) outform = "dtb"; else outform = "dts"; } } if (streq(inform, "dts")) dti = dt_from_source(arg); else if (streq(inform, "fs")) dti = dt_from_fs(arg); else if(streq(inform, "dtb")) dti = dt_from_blob(arg); else die("Unknown input format \"%s\"\n", inform); dti->outname = outname; if (depfile) { fputc('\n', depfile); fclose(depfile); } if (cmdline_boot_cpuid != -1) dti->boot_cpuid_phys = cmdline_boot_cpuid; fill_fullpaths(dti->dt, ""); process_checks(force, dti); /* on a plugin, generate by default */ if (dti->dtsflags & DTSF_PLUGIN) { generate_fixups = 1; } if (auto_label_aliases) generate_label_tree(dti, "aliases", false); if (generate_symbols) generate_label_tree(dti, "__symbols__", true); if (generate_fixups) { generate_fixups_tree(dti, "__fixups__"); generate_local_fixups_tree(dti, "__local_fixups__"); } if (sort) sort_tree(dti); if (streq(outname, "-")) { outf = stdout; } else { outf = fopen(outname, "wb"); if (! outf) die("Couldn't open output file %s: %s\n", outname, strerror(errno)); } if (streq(outform, "dts")) { dt_to_source(outf, dti); } else if (streq(outform, "dtb")) { dt_to_blob(outf, dti, outversion); } else if (streq(outform, "asm")) { dt_to_asm(outf, dti, outversion); } else if (streq(outform, "null")) { /* do nothing */ } else { die("Unknown output format \"%s\"\n", outform); } exit(0); }
int main(int argc, char *argv[]) { struct boot_info *bi; const char *inform = "dts"; const char *outform = "dts"; const char *outname = "-"; const char *depname = NULL; int force = 0, sort = 0; const char *arg; int opt; FILE *outf = NULL; int outversion = DEFAULT_FDT_VERSION; long long cmdline_boot_cpuid = -1; quiet = 0; reservenum = 0; minsize = 0; padsize = 0; while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fcqb:vH:s")) != EOF) { switch (opt) { case 'I': inform = optarg; break; case 'O': outform = optarg; break; case 'o': outname = optarg; break; case 'V': outversion = strtol(optarg, NULL, 0); break; case 'd': depname = optarg; break; case 'R': reservenum = strtol(optarg, NULL, 0); break; case 'S': minsize = strtol(optarg, NULL, 0); break; case 'p': padsize = strtol(optarg, NULL, 0); break; case 'f': force = 1; break; case 'q': quiet++; break; case 'b': cmdline_boot_cpuid = strtoll(optarg, NULL, 0); break; case 'v': printf("Version: %s\n", DTC_VERSION); exit(0); case 'H': if (streq(optarg, "legacy")) phandle_format = PHANDLE_LEGACY; else if (streq(optarg, "epapr")) phandle_format = PHANDLE_EPAPR; else if (streq(optarg, "both")) phandle_format = PHANDLE_BOTH; else die("Invalid argument \"%s\" to -H option\n", optarg); break; case 's': sort = 1; break; case 'h': default: usage(); } } if (argc > (optind+1)) usage(); else if (argc < (optind+1)) arg = "-"; else arg = argv[optind]; if (minsize && padsize) die("Can't set both -p and -S\n"); if (minsize) fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n"); fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", inform, outform, arg); if (depname) { depfile = fopen(depname, "w"); if (!depfile) die("Couldn't open dependency file %s: %s\n", depname, strerror(errno)); fprintf(depfile, "%s:", outname); } if (streq(inform, "dts")) bi = dt_from_source(arg); else if (streq(inform, "fs")) bi = dt_from_fs(arg); else if(streq(inform, "dtb")) bi = dt_from_blob(arg); else die("Unknown input format \"%s\"\n", inform); if (depfile) { fputc('\n', depfile); fclose(depfile); } if (cmdline_boot_cpuid != -1) bi->boot_cpuid_phys = cmdline_boot_cpuid; fill_fullpaths(bi->dt, ""); process_checks(force, bi); if (sort) sort_tree(bi); if (streq(outname, "-")) { outf = stdout; } else { outf = fopen(outname, "w"); if (! outf) die("Couldn't open output file %s: %s\n", outname, strerror(errno)); } if (streq(outform, "dts")) { dt_to_source(outf, bi); } else if (streq(outform, "dtb")) { dt_to_blob(outf, bi, outversion); } else if (streq(outform, "asm")) { dt_to_asm(outf, bi, outversion); } else if (streq(outform, "null")) { } else { die("Unknown output format \"%s\"\n", outform); } exit(0); }