Exemplo n.º 1
0
void sort_tree(struct tnode *root) {
	if(root == NULL)
		return;	 
	sort_tree(root->left);
	
	add_to_list(root);
	
	sort_tree(root->right);
}
Exemplo n.º 2
0
/* 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 );
 }
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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);
	}
}
Exemplo n.º 5
0
	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;
}
Exemplo n.º 6
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 = 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);
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
void Fl_Tree::sort_tree(int (*compar)(Fl_Node *, Fl_Node *),
                        sort_order order) {
  if (first_)
    first_ = top_ = sort_tree(first_, compar, order);
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
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);
}