Exemple #1
0
int
main(int argc, char **argv)
{
    struct bu_rb_tree *palette;	/* Pixel palette */
    char *inf_name;	/* name of input stream */
    char *outf_name;	/* " " output " */
    unsigned char *buf;		/* the current input pixel */
    FILE *infp = NULL;	/* input stream */
    int ch;		/* current char in command line */
    struct pixel *pp;

    /*
     * Process the command line
     */
    while ((ch = bu_getopt(argc, argv, optstring)) != -1)
	switch (ch) {
	    case '#':
		if (sscanf(bu_optarg, "%d", &pixel_size) != 1) {
		    bu_log("Invalid pixel size: '%s'\n", bu_optarg);
		    print_usage();
		}
		break;
	    case '?':
	    default:
		print_usage();
	}
    switch (argc - bu_optind) {
	case 0:
	    infp = stdin;
	    /* Break intentionally missing */
	case 1:
	    outfp = stdout;
	    /* Break intentionally missing */
	case 2:
	    break;
	default:
	    print_usage();
    }

    /*
     * Open input and output files, as necessary
     */
    if (infp == NULL) {
	inf_name = argv[bu_optind];
	if ((infp = fopen(inf_name, "r")) == NULL)
	    bu_exit(1, "Cannot open input file '%s'\n", inf_name);
	if (outfp == NULL) {
	    outf_name = argv[++bu_optind];
	    if ((outfp = fopen(outf_name, "w")) == NULL)
		bu_exit(1, "Cannot open output file '%s'\n", outf_name);
	}
    }

    /*
     * Ensure that infp is kosher,
     */
    if (infp == stdin) {
	if (isatty(fileno(stdin))) {
	    bu_log("FATAL: pixcount reads only from file or pipe\n");
	    print_usage();
	}
    }

    palette = bu_rb_create1("Pixel palette", (int (*)(void))compare_pixels);
    bu_rb_uniq_on1(palette);

    /*
     * Read the input stream into the palette
     */
    buf = (unsigned char *)
	bu_malloc(pixel_size * sizeof(unsigned char),
		  "pixel buffer");
    while (fread((void *)buf, pixel_size * sizeof(unsigned char), 1, infp) == 1) {
	pp = lookup_pixel(palette, buf);
	BU_CKMAG(pp, PIXEL_MAGIC, "pixel");

	++(pp->p_count);
    }
    bu_free((void *)buf, "pixel buffer");

    bu_rb_walk1(palette, (void (*)(void))print_pixel, BU_RB_WALK_INORDER);

    return 0;
}
Exemple #2
0
/*
 *                                M A I N ( )
 */
int
main (int argc, char **argv)
{
    char		*label[2];	/* Labels of edge endpoints */
    int			ch;		/* Command-line character */
    int			i;
    int			numeric = 0;	/* Use vertex indices (vs. labels)? */
    long		index[2];	/* Indices of edge endpoints */
    double		weight;		/* Edge weight */
    bu_rb_tree		*dictionary;	/* Dictionary of vertices */
    struct bridge	*bp;		/* The current bridge */
    struct vertex	*up;		/* An uncivilized neighbor of vup */
    struct vertex	*vcp;		/* The civilized vertex of bp */
    struct vertex	*vup;		/* The uncivilized vertex of bp */
    struct vertex	*vertex[2];	/* The current edge */
    struct neighbor	*neighbor[2];	/* Their neighbors */
    struct neighbor	*np;		/* A neighbor of vup */
    int			(*po[2])();	/* Priority queue order functions */

    while ((ch = bu_getopt(argc, argv, OPT_STRING)) != EOF)
	switch (ch)
	{
	    case 'n':
		numeric = 1;
		break;
	    case '?':
	    default:
		print_usage();
		bu_exit (ch != '?', NULL);
		return(0);
	}

    /*
     *	Initialize the dictionary
     */
    dictionary = bu_rb_create1("Dictionary of vertices",
			       numeric ? compare_vertex_indices
			       : compare_vertex_labels);
    bu_rb_uniq_on1(dictionary);

    /*
     *	Read in the graph
     */
    while (get_edge(stdin, index, label, &weight, numeric))
    {
	for (i = 0; i < 2; ++i)		/* For each end of the edge... */
	{
	    vertex[i] = lookup_vertex(dictionary, index[i], label[i]);
	    neighbor[i] = mk_neighbor(VERTEX_NULL, weight);
	    BU_LIST_INSERT(&(vertex[i] -> v_neighbors), &(neighbor[i] -> l));
	}
	neighbor[0] -> n_vertex = vertex[1];
	neighbor[1] -> n_vertex = vertex[0];
    }

    /*
     *	Initialize the priority queue
     */
    po[PRIOQ_INDEX] = compare_bridge_indices;
    po[PRIOQ_WEIGHT] = compare_bridge_weights;
    prioq = bu_rb_create("Priority queue of bridges", 2, po);
    bu_rb_walk1(dictionary, add_to_prioq, INORDER);

    if (debug)
    {
	print_prioq();
	bu_rb_walk1(dictionary, print_vertex, INORDER);
    }

    /*
     *	Grow a minimum spanning tree, using Prim's algorithm...
     *
     *	While there exists a min-weight bridge (to a vertex v) in the queue
     *	    Dequeue the bridge
     *	    If the weight is finite
     *	        Output the bridge
     *	    Mark v as civilized
     *	    For every uncivilized neighbor u of v
     *	        if uv is cheaper than u's current bridge
     *		    dequeue u's current bridge
     *		    enqueue bridge(uv)
     */
    weight = 0.0;
    while ((bp = extract_min()) != BRIDGE_NULL)
    {
	if (debug)
	{
	    bu_log("extracted min-weight bridge <x%x>, leaving...\n", bp);
	    print_prioq();
	}

	BU_CKMAG(bp, BRIDGE_MAGIC, "bridge");
	vcp = bp -> b_vert_civ;
	vup = bp -> b_vert_unciv;
	BU_CKMAG(vup, VERTEX_MAGIC, "vertex");

	if (is_finite_bridge(bp))
	{
	    BU_CKMAG(vcp, VERTEX_MAGIC, "vertex");
	    if (numeric)
		(void) printf("%ld %ld %g\n",
			      vcp -> v_index, vup -> v_index, bp -> b_weight);
	    else
		(void) printf("%s %s %g\n",
			      vcp -> v_label, vup -> v_label, bp -> b_weight);
	    weight += bp -> b_weight;
	}
	free_bridge(bp);
	vup -> v_civilized = 1;

	if (debug)
	{
	    bu_log("Looking for uncivilized neighbors of...\n");
	    print_vertex((void *) vup, 0);
	}
	while (BU_LIST_WHILE(np, neighbor, &(vup -> v_neighbors)))
	{
	    BU_CKMAG(np, NEIGHBOR_MAGIC, "neighbor");
	    up = np -> n_vertex;
	    BU_CKMAG(up, VERTEX_MAGIC, "vertex");

	    if (up -> v_civilized == 0)
	    {
		BU_CKMAG(up -> v_bridge, BRIDGE_MAGIC, "bridge");
		if (compare_weights(np -> n_weight,
				    up -> v_bridge -> b_weight) < 0)
		{
		    del_from_prioq(up);
		    if (debug)
		    {
			bu_log("After the deletion of bridge <x%x>...\n",
			       up -> v_bridge);
			print_prioq();
		    }
		    up -> v_bridge -> b_vert_civ = vup;
		    up -> v_bridge -> b_weight = np -> n_weight;
		    add_to_prioq((void *) up, 0);
		    if (debug)
		    {
			bu_log("Reduced bridge <x%x> weight to %g\n",
			       up -> v_bridge,
			       up -> v_bridge -> b_weight);
			print_prioq();
		    }
		}
		else if (debug)
		    bu_log("bridge <x%x>'s weight of %g stands up\n",
			   up -> v_bridge, up -> v_bridge -> b_weight);
	    }
	    else if (debug)
		bu_log("Skipping civilized neighbor <x%x>\n", up);
	    BU_LIST_DEQUEUE(&(np -> l));
	}
    }

    bu_log("MST weight: %g\n", weight);
    return 0;
}