Exemple #1
0
void add_segment (line_struct *l, gdouble x0, gdouble y0, gdouble x1, gdouble y1) {
//	Add a segment to an irregular line struct
	l->cur_seg++;
	if (l->cur_seg>=l->max_seg)
		extend_line (l, l->cur_seg+1);
	(l->segments+l->cur_seg)->x0 = x0;
	(l->segments+l->cur_seg)->y0 = y0;
	(l->segments+l->cur_seg)->x1 = x1;
	(l->segments+l->cur_seg)->y1 = y1;
// printf("ADDING SEGMENT %d: (%5.2f,%5.2f) - (%5.2f,%5.2f)\n",l->cur_seg,x0,y0,x1,y1);
}
Exemple #2
0
static void
DoplotIOpen(int port, Bool fopen)
{
    struct traffic_info *pti;

    /* just for this port */
    if ((pti = FindPort(port)) == NULL)
	return;

    if (fopen)
	++pti->n_i_open;
    else
	--pti->n_i_open;

    extend_line(pti->line_niopen, current_time, pti->n_i_open);
}
/*
 * Store a character at the current position, updating the current position.
 * We expect (but do not require) that an underscore precedes a nonblank
 * character that will overstrike it.  (Some programs produce the underscore
 * second, rather than first).
 */
static void
put_cell(int c, int level, int ident)
{
	int	col;
	int	len;
	CHARCELL *p, *q;

	if (cur_line == 0)
		cur_line = allocate_line();

	len = cur_line->l_used;
	col = cur_line->l_this++;
	extend_line();

	p = &(cur_line->l_cell[col]);

	if (len > col) {	/* some type of overstrike */
		if (c == UNDERLINE) {
			while ((q = p->link) != 0)
				p = q;
			q = allocate_cell();
			p->link = q;
			p = q;
		} else {
			if ((c != SPACE)
			 || (p->c_value == UNDERLINE)) {
				q = allocate_cell();
				*q = *p;
				p->link = q;
			} else if (c == SPACE)
				return;
		}
	}

	p->c_value = c;
	p->c_level = level;
	p->c_ident = ident;

	if (cur_line->l_used < cur_line->l_this)
		cur_line->l_used = cur_line->l_this;
}
Exemple #4
0
/* graph RTT samples in milliseconds */
static void
graph_rtt_sample (tcptrace_context_t *context,
                  tcb * ptcb,
		  segment * pseg,
		  unsigned long etime_rtt)
{
    char title[210];
    tcptrace_runtime_options_t *options = context->options;

    /* if the FILE is NULL, open file */
    if (ptcb->rtt_plotter == NO_PLOTTER) {
	char *name_from, *name_to;
	if (ptcb == &ptcb->ptp->a2b) {
	    name_from = ptcb->ptp->a_endpoint;
	    name_to = ptcb->ptp->b_endpoint;
	} else {
	    name_from = ptcb->ptp->b_endpoint;
	    name_to = ptcb->ptp->a_endpoint;
	}
	snprintf (title, sizeof (title), "%s_==>_%s (rtt samples)",
		  name_from, name_to);
	ptcb->rtt_plotter =
	    new_plotter(context, ptcb, NULL, title, "time", "rtt (ms)",
                        RTT_GRAPH_FILE_EXTENSION);
	plotter_perm_color (ptcb->rtt_plotter, "red");

	if (options->graph_time_zero) {
	    /* set graph zero points */
	    plotter_nothing (ptcb->rtt_plotter, context->current_time);
	}
	ptcb->rtt_line = new_line (ptcb->rtt_plotter, "rtt", "red");
    }

    if (etime_rtt <= 1)
	return;

    extend_line(ptcb->rtt_line, context->current_time, (int) (etime_rtt / 1000));
}
Exemple #5
0
static void
AgeTraffic(void)
{
    struct traffic_info *pti;
    struct conn_info *pci;
    static timeval last_time = {0,0};
    float etime;
    int ups;			/* units per second */

    /* first time doesn't count */
    if (ZERO_TIME(&last_time)) {
	last_time = current_time;
	return;
    }

    /* check elapsed time */
    etime = elapsed(last_time, current_time);
    if (ldebug>1)
	printf("AgeTraffic called, elapsed time is %.3f seconds\n", etime/1000000);
    if (etime == 0.0)
	return;

    /* roll the open/active/long connections into the port records */
    for (pci=connhead; pci; pci=pci->next) {
	if (pci->wasactive) {
	    if (pci->pti1)
		++pci->pti1->nactive;
	    if (pci->pti2)
		++pci->pti2->nactive;
	    pci->wasactive = 0;
	    ++ports[0]->nactive;
	}
	if (pci->isopen) {
	    if (pci->pti1)
		++pci->pti1->nopen;
	    if (pci->pti2)
		++pci->pti2->nopen;
	    ++ports[0]->nopen;
	    if (pci->islong) {
		if (pci->pti1)
		    ++pci->pti1->nlong;
		if (pci->pti2)
		    ++pci->pti2->nlong;
		++ports[0]->nlong;
	    }

	    if (!pci->wasactive) {
		/* open and !active ==> IDLE */
		if (pci->pti1)
		    ++pci->pti1->nidle;
		if (pci->pti2)
		    ++pci->pti2->nidle;
		++ports[0]->nidle;
	    }
	}
    }
    

    /* ============================================================ */
    /* plot halfopen conns */
    if (doplot_halfopen) {
	/* draw lines */
	extend_line(line_num_halfopens,current_time, num_halfopens);
    }


    /* ============================================================ */
    /* plot connection activity */
    /* opens */
    if (doplot_openclose) {
	/* draw lines */
	extend_line(line_num_opens,current_time, num_opens);
	extend_line(line_num_closes,current_time, num_closes);
	extend_line(line_open_conns,current_time, open_conns);

	/* reset interval counters */
	 
// Counting ttl_num_opens instantaneously as and when num_opens is incremented,
// so that ttl_num_opens is printed properly in traffic_stats.dat even 
// when the -C(openclose) option is not given.
// Hence commenting off the following line. - Mani, 4 Aug 2003.
//	ttl_num_opens += num_opens;
	ttl_num_closes += num_closes;
	num_opens = 0;
	num_closes = 0;
    }


    /* ============================================================ */
    /* report of loss events */
    if (doplot_loss) {
	/* convert to events/second */
	/* sdo bugfix - Wed May 12, 1999 - round UP!! */
	dupacks = (dupacks+age_interval-1)/age_interval;
	rexmits = (rexmits+age_interval-1)/age_interval;

	/* draw lines */
	extend_line(line_dupacks,current_time, dupacks);
	extend_line(line_rexmits,current_time, rexmits);

	/* reset interval counters */
	dupacks = 0;
	rexmits = 0;
    }


    /* ============================================================ */
    /* report of RTT */
    if (doplot_rtt && (rtt_samples > 0)) {
	int rtt_avg;

	/* convert to average rtt */
	rtt_avg = (int)((rtt_ttl/(float)rtt_samples));

	/* draw lines */
	extend_line(line_rtt_avg, current_time, rtt_avg);
	if (rtt_min != -1)
	    extend_line(line_rtt_min, current_time, rtt_min);
	if (rtt_max != -1)
	    extend_line(line_rtt_max, current_time, rtt_max);

	/* reset interval counters */
	rtt_ttl = 0;
	rtt_samples = 0;
	rtt_min = -1;
	rtt_max = -1;
    }


    /* ============================================================ */
    /* report of total data */
    if (doplot_data) {
	extend_line(line_data_all, current_time, data_nbytes_all);
	extend_line(line_data_nonrexmit, current_time, data_nbytes_nonrexmit);
    }

    /* ============================================================ */
    /* print them out */
    for (pti=traffichead; pti; pti=pti->next) {
	if (ldebug>1)
	    printf("  Aging Port %u   bytes: %lu  packets: %lu\n",
		   pti->port, pti->nbytes, pti->npackets);

	/* plot bytes */
	if (doplot_bytes) {
	    /* convert to units per second */
	    ups = (int)((float)pti->nbytes * 1000000.0 / etime);

	    /* plot it */
	    extend_line(pti->line_nbytes,current_time, ups);
	}

	/* plot packets */
	if (doplot_packets) {
	    /* convert to units per second */
	    ups = (int)((float)pti->npackets * 1000000.0 / etime);

	    /* plot it */
	    extend_line(pti->line_npackets,current_time, ups);
	}



	/* plot active connections */
	if (doplot_active) {
	    /* plot it */
	    extend_line(pti->line_nactive,current_time, pti->nactive);
	}

	/* plot idle connections */
	if (doplot_idle) {
	    /* plot it */
	    extend_line(pti->line_nidle,current_time, pti->nidle);
	}


	/* plot open connections */
	if (doplot_open) {
	    /* plot it */
	    extend_line(pti->line_nopen,current_time, pti->nopen);
	}

	/* plot long-duration */
	if (doplot_long) {
	    extend_line(pti->line_nlong,current_time, pti->nlong);
	}

	/* plot pureacks */
	if (doplot_pureacks) {
	    /* convert to units per second */
	    ups = (int)((float)pti->npureacks * 1000000.0 / etime);

	    extend_line(pti->line_pureacks, current_time, ups);
	}
    }

    /* zero them out */
    for (pti=traffichead; pti; pti=pti->next) {
	pti->ttlbytes += pti->nbytes;
	pti->ttlpackets += pti->npackets;
	pti->ttlpureacks += pti->npureacks;

	pti->nbytes = 0;
	pti->nlong = 0;
	pti->npackets = 0;
	pti->nactive = 0;
	pti->nidle = 0;
	pti->nopen = 0;
	pti->npureacks = 0;
    }

    last_time = current_time;
}
Exemple #6
0
int write_ep(struct Edge *e)
{
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;

    if (!Points) {
	Points = Vect_new_line_struct();
	Cats = Vect_new_cats_struct();
    }

    if (!triangulate) {
	double x1, y1, x2, y2;

	if (e->ep[le] != NULL && e->ep[re] != NULL) {	/* both end defined */
	    x1 = e->ep[le]->coord.x;
	    y1 = e->ep[le]->coord.y;
	    x2 = e->ep[re]->coord.x;
	    y2 = e->ep[re]->coord.y;

	    if (!Vect_point_in_box(x1, y1, 0.0, &Box) ||
		!Vect_point_in_box(x2, y2, 0.0, &Box)) {
		Vect_box_clip(&x1, &y1, &x2, &y2, &Box);
	    }

	    /* Don't write zero length */
	    if (x1 == x2 && y1 == y2)
		return 0;

	    Vect_reset_line(Points);
	    Vect_append_point(Points, x1, y1, 0.0);
	    Vect_append_point(Points, x2, y2, 0.0);
	    Vect_write_line(&Out, Type, Points, Cats);
	}
	else {
	    int knownPointAtLeft;

	    if (e->ep[le] != NULL) {
		x1 = e->ep[le]->coord.x;
		y1 = e->ep[le]->coord.y;
		knownPointAtLeft = 1;
	    }
	    else {
		x1 = e->ep[re]->coord.x;
		y1 = e->ep[re]->coord.y;
		knownPointAtLeft = 0;
	    }

	    if (extend_line(Box.S, Box.N, Box.W, Box.E,
			    e->a, e->b, e->c, x1, y1, &x2, &y2,
			    knownPointAtLeft)
		) {
		/* Don't write zero length */
		if (x1 == x2 && y1 == y2)
		    return 0;

		Vect_reset_line(Points);
		Vect_append_point(Points, x1, y1, 0.0);
		Vect_append_point(Points, x2, y2, 0.0);
		Vect_write_line(&Out, Type, Points, Cats);
	    }
	}
    }

    return 0;
}
Exemple #7
0
void
DoThru(
    tcb *ptcb,
    int nbytes)
{
    double etime;
    double thruput;
    char *myname, *hisname;

    /* init, if not already done */
    if (ZERO_TIME(&ptcb->thru_firsttime)) {
	char title[210];

	ptcb->thru_firsttime = current_time;
	ptcb->thru_lasttime = current_time;
	ptcb->thru_pkts = 1;
	ptcb->thru_bytes = nbytes;
	

	/* bug fix from Michele Clark - UNC */
	if (&ptcb->ptp->a2b == ptcb) {
	    myname = ptcb->ptp->a_endpoint;
	    hisname = ptcb->ptp->b_endpoint;
	} else {
	    myname = ptcb->ptp->b_endpoint;
	    hisname = ptcb->ptp->a_endpoint;
	}
	/* create the plotter file */
	snprintf(title,sizeof(title),"%s_==>_%s (throughput)",
		myname, hisname);
	ptcb->thru_plotter = new_plotter(ptcb,NULL,title,
					 "time","thruput (bytes/sec)",
					 THROUGHPUT_FILE_EXTENSION);
	if (graph_time_zero) {
	    /* set graph zero points */
	    plotter_nothing(ptcb->thru_plotter, current_time);
	}

	/* create lines for average and instantaneous values */
	ptcb->thru_avg_line =
	    new_line(ptcb->thru_plotter, "avg. tput", "blue");
	ptcb->thru_inst_line =
	    new_line(ptcb->thru_plotter, "inst. tput", "red");

	return;
    }

    /* if no data, then nothing to do */
    if (nbytes == 0)
	return;

    /* see if we should output the stats yet */
    if (ptcb->thru_pkts+1 >= thru_interval) {

	/* compute stats for this interval */
	etime = elapsed(ptcb->thru_firsttime,current_time);
	if (etime == 0.0)
	    etime = 1000;	/* ick, what if "no time" has passed?? */
	thruput = (double) ptcb->thru_bytes / ((double) etime / 1000000.0);

	/* instantaneous plot */
	extend_line(ptcb->thru_inst_line,
		     current_time, (int) thruput);

	/* compute stats for connection lifetime */
	etime = elapsed(ptcb->ptp->first_time,current_time);
	if (etime == 0.0)
	    etime = 1000;	/* ick, what if "no time" has passed?? */
	thruput = (double) ptcb->data_bytes / ((double) etime / 1000000.0);

	/* long-term average */
	extend_line(ptcb->thru_avg_line,
		     current_time, (int) thruput);

	/* reset stats for this interval */
	ptcb->thru_firsttime = current_time;
	ptcb->thru_pkts = 0;
	ptcb->thru_bytes = 0;
    }

    /* immediate value in yellow ticks */
    if (plot_tput_instant) {
	etime = elapsed(ptcb->thru_lasttime,current_time);
	if (etime == 0.0)
	    etime = 1000;	/* ick, what if "no time" has passed?? */
	thruput = (double) nbytes / ((double) etime / 1000000.0);
	plotter_temp_color(ptcb->thru_plotter,"yellow");
	plotter_dot(ptcb->thru_plotter,
		    current_time, (int) thruput);
    }

    /* add in the latest packet */
    ptcb->thru_lasttime = current_time;
    ++ptcb->thru_pkts;
    ptcb->thru_bytes += nbytes;
}
Exemple #8
0
/************************************************************************
*									*
*  Calculate some line info  			                        *
*									*/
void
Line::some_info(int moving)
{
    char str[100];		// holds text to be displayed in info window
    int i;			// counter
    int num_points ;		// number of data points underneath this line
    float *pdata ;		// pointer to image data  (intensities)

    // Don't do anything if there is no line profile display active
    if (! Win_line_info::winlineinfo){
	return;
    }

    // Do not do anything if we are not the active ROI
    if (position_in_active_list(this) > 0){
	return;
    }

    Gframe *gf = owner_frame;
    Imginfo *img = gf->imginfo;

    //fix_line_direction();
    
    // Calculate and print out the line length
    // ASSUME THE "SPAN" (GetRatioFast/GetRatioMedium) GIVES THE DISTANCE
    // FROM ONE EDGE OF THE PICTURE TO THE OTHER, RATHER THAN THE
    // DISTANCE BETWEEN CENTERS OF THE OPPOSITE EDGE DATELS.
    // THEREFORE, WE DIVIDE BY THE NUMBER OF DATELS, RATHER THAN THE
    // NUMBER OF DATELS MINUS 1.
    float xscale = img->GetRatioFast() / img->GetFast();
    float yscale = img->GetRatioMedium() / img->GetMedium();
    float lenx = second_point_on_data.x - first_point_on_data.x;
    float lenxcm = lenx * xscale;
    float leny = second_point_on_data.y - first_point_on_data.y;
    float lenycm = leny * yscale;
    float line_len =  (double) sqrt((lenxcm*lenxcm) + (lenycm*lenycm));
    sprintf (str, "Length of line: %.4g cm", line_len);
    Win_line_info::show_line_length(str);
    
    // Print the line end coords.
    sprintf (str,"Coordinates: (%.1f, %.1f) to (%.1f, %.1f)",
	     first_point_on_data.x, first_point_on_data.y,
	     second_point_on_data.x, second_point_on_data.y);

    Win_line_info::show_coordinates(str) ;

    int x0 = (int)first_point_on_data.x;
    int x1 = (int)second_point_on_data.x;
    int y0 = (int)first_point_on_data.y;
    int y1 = (int)second_point_on_data.y;
    num_points = abs(x1 - x0);
    if ( abs(y1 - y0) > num_points ){
	num_points = abs(y1 - y0);
    }
    num_points++;

    if (gf->imginfo->type != TYPE_FLOAT){
	msgerr_print ("Data type not supported");
	return;
    }

    float *project = 0;
    if (Win_line_info::projection_type == ON_LINE){
	project = new float [num_points];
	for (pdata=FirstPixel(), i=0; pdata, i<num_points; pdata=NextPixel()){
	    project[i++] = *pdata;
	}
    }else if (! moving){	// projection_type == ACROSS_LINE
	// Increase number of points, so we don't miss any pixels.
	num_points *= 2;
	project = new float [num_points];
	// Step through "num_points" equally spaced points along the line.
	Fpoint orig;
	Fpoint slope;
	Fpoint clip[2];
	Fpoint ends[2];
	float dx = lenx / (num_points - 1);
	float dy = leny / (num_points - 1);
	orig.x = first_point_on_data.x;
	orig.y = first_point_on_data.y;
	slope.x = -lenycm / xscale;	// Slope of normal to the line
	slope.y = lenxcm / yscale;	//  in pixel units.
	clip[0].x = clip[0].y = 0;
	clip[1].x = img->GetFast() - 1;
	clip[1].y = img->GetMedium() - 1;

	float t;
	for (i=0; i<num_points; i++, orig.x += dx, orig.y += dy){
	    // Erect a normal to the line at this (orig) location that
	    // just fits in the data space.  The slope of the normal is
	    // (-lenx/leny).  The following routine returns the endpoints
	    // of the required line.
	    extend_line(orig,		// A point on the line
			slope,		// Slope of the line
			clip,		// Clipping corners
			ends);		// Returns endpoints
	    // Find the maximum value along the line.
	    Line *line = new Line(ends[0], ends[1]);
	    line->owner_frame = gf;
	    t = *(pdata = line->FirstPixel());
	    for ( ; pdata; pdata=line->NextPixel()){
		if (*pdata > t){
		    t = *pdata;
		}
	    }
	    project[i] = t;
	    delete line;
	}
    }
    if (project){
	Win_line_info::set_projection_type(-1);
	Win_line_info::show_projection(project, num_points, line_len);
	delete [] project;
    }
}      //  Line::some_info
Exemple #9
0
static int update_list(int count)
{
    struct COOR *new_ptr1, *new_ptr2, *new_ptr3;

    G_debug(3, "update_list: count:%d row:%d col:%d", count, row, col - 1);

    switch (count) {
    case 0:
	G_debug(1, "Isolated cell (%d,%d)", row, col);
	break;
    case 1:			/* begin or end line */
	if (ml)
	    h_ptr = end_line(h_ptr, 0);
	if (tl)
	    v_list[col].left = end_line(v_list[col].left, 0);
	if (tc)
	    v_list[col].center = end_line(v_list[col].center, 0);
	if (tr)
	    v_list[col].right = end_line(v_list[col].right, 0);
	if (mr)
	    h_ptr = start_line(0);
	if (br)
	    v_list[col + 1].left = start_line(0);
	if (bc)
	    v_list[col].center = start_line(0);
	if (bl)
	    v_list[col - 1].right = start_line(0);
	break;
    case 2:			/* straight or bent line */
	if (tl != 0 && br != 0) {	/* slanted line (\) */
	    v_list[col + 1].left = v_list[col].left;
	    v_list[col].left = NULL;
	}
	else if (tr != 0 && bl != 0) {	/* slanted line (/) */
	    v_list[col - 1].right = v_list[col].right;
	    v_list[col].right = NULL;
	}

	/* first take care of the cases where both non-zero
	   neighbours are in a upper-left corner (cw from ml to tr) */
	else if (ml != 0 && tc != 0) {	/* bend (_|) */
	    join_lines(h_ptr, v_list[col].center);
	    h_ptr = v_list[col].center = NULL;
	}
	else if (ml != 0 && tr != 0) {	/* bend (_/) */
	    join_lines(h_ptr, v_list[col].right);
	    h_ptr = v_list[col].left = NULL;
	}
	else if (tl != 0 && tr != 0) {	/* bend (\/) */
	    join_lines(v_list[col].left, v_list[col].right);
	    v_list[col].left = v_list[col].right = NULL;
	}
	else if (tl != 0 && tc != 0)	/* bend (\|) */
	    v_list[col].center = end_line(v_list[col].center, 1);
	else if (tr != 0 && tc != 0)	/* bend |/ */
	    v_list[col].center = end_line(v_list[col].center, 1);
	else if (tl != 0 && ml != 0)
	    h_ptr = end_line(h_ptr, 1);

	/* now take care of the cases when non-zero neighbours
	   are next to nonzero neighbours in a top-left corner */
	else if (bl != 0 && ml != 0)
	    v_list[col].center = start_line(1);
	else if (tr != 0 && mr != 0)
	    h_ptr = start_line(1);
	else if (!((tc != 0 && bc != 0) || (ml != 0 && mr != 0)))
	    /* if not horiz or vertical line */
	{
	    /* one of the non zero neighbours is in the top left corner,
	       and the other one is one of bl - mr, not next to the first one */
	    if (ml || tl || tc || tr) {	/* old line bends toward *//*   new area */
		new_ptr1 = get_ptr();

		if (ml) {	/* join new to where came from */
		    if (h_ptr == NULL)
			G_debug(1, "h_ptr is NULL!");

		    /* this should never happen by the logic of algorithm */
		    extend_line(h_ptr, new_ptr1);
		    h_ptr = NULL;
		}
		else if (tl) {
		    if (v_list[col].left == NULL)
			G_debug(1, "v_list[col].left is NULL!");

		    /* this should never happen by the logic of algorithm */
		    extend_line(v_list[col].left, new_ptr1);
		    v_list[col].left = NULL;
		}
		else if (tc) {
		    if (v_list[col].center == NULL)
			G_debug(1, "v_list[col].center is NULL!");

		    /* this should never happen by the logic of algorithm */
		    extend_line(v_list[col].center, new_ptr1);
		    v_list[col].center = NULL;
		}
		else {		/* tr */

		    if (v_list[col].right == NULL)
			G_debug(1, "v_list[col].right is NULL!");

		    /* this should never happen by the logic of algorithm */
		    extend_line(v_list[col].right, new_ptr1);
		    v_list[col].right = NULL;
		}

		if (mr)
		    /* find out where going */
		    /* tr is 0 here */
		    h_ptr = new_ptr1;
		else if (br)
		    v_list[col + 1].left = new_ptr1;
		else if (bc)
		    v_list[col].center = new_ptr1;
		else		/* bl, ml is 0 here */
		    v_list[col - 1].right = new_ptr1;
	    }
	    else {		/* lower-left */
		/* if the non-zero neigbours are adjacent */
		if (mr && br)
		    h_ptr = start_line(1);
		else if ((br && bc) || (bl && bc))
		    v_list[col].center = start_line(1);
		else
		    /* the non-zero neigbours are not adjacent */
		{		/* starting in middle of line */
		    new_ptr1 = get_ptr();
		    new_ptr2 = get_ptr();
		    new_ptr3 = get_ptr();
		    new_ptr1->fptr = new_ptr2;
		    new_ptr1->bptr = new_ptr3;
		    new_ptr3->bptr = new_ptr2->bptr = new_ptr1;

		    if (mr && bc) {
			h_ptr = new_ptr2;
			v_list[col].center = new_ptr3;
		    }
		    else if (mr && bl) {
			h_ptr = new_ptr2;
			v_list[col - 1].right = new_ptr3;
		    }
		    else if (bl && br) {
			v_list[col - 1].right = new_ptr3;
			v_list[col + 1].left = new_ptr2;
		    }
		}		/* starting in the middle of the line */
	    }
	}
	else if (value_flag) {	/* horizontal or vertical line */
	    int ml_val, mc_val, mr_val;	/* horiz */
	    int tc_val, bc_val;	/* vert */

	    ml_val = mc_val = mr_val = tc_val = bc_val = 0;
	    /* only CELL supported */
	    if (data_type == CELL_TYPE) {
		ml_val = ((CELL *) middle)[col - 1];
		mc_val = ((CELL *) middle)[col];
		mr_val = ((CELL *) middle)[col + 1];

		tc_val = ((CELL *) top)[col];
		bc_val = ((CELL *) bottom)[col];
	    }

	    if ((mc && mr) && mc_val != mr_val) {	/* break the horizontal line */
		h_ptr = end_line(h_ptr, 1);
		h_ptr = start_line(1);
	    }
	    else if ((mc && bc) && mc_val != bc_val) {	/* break the vertical line */
		v_list[col].center = end_line(v_list[col].center, 1);
		v_list[col].center = start_line(1);
	    }

	    if ((mc && ml) && mc_val != ml_val) {
		h_ptr->bptr->val = mc_val;
	    }
	    else if ((mc && tc) && mc_val != tc_val) {
		v_list[col].center->bptr->val = mc_val;
	    }
	}
	break;
    case 3:
	if (ml || tl || tc || (tr && !mr)) {
	    if (ml)		/* stop horz. and vert. lines */
		h_ptr = end_line(h_ptr, 1);

	    if (tc)
		v_list[col].center = end_line(v_list[col].center, 1);

	    /* stop diag lines if no horz,vert */
	    if ((tl) && (!ml) && (!tc))
		v_list[col].left = end_line(v_list[col].left, 1);
	    if ((tr) && (!mr) && (!tc))
		v_list[col].right = end_line(v_list[col].right, 1);
	}

	if (mr)			/* start horz. and vert */
	    h_ptr = start_line(1);
	if (bc)
	    v_list[col].center = start_line(1);

	/* start diag if no horz,vert */
	if ((br) && (!mr) && (!bc))
	    v_list[col + 1].left = start_line(1);
	if ((bl) && (!ml) && (!bc))
	    v_list[col - 1].right = start_line(1);
	break;
    case 4:
	if (ml)			/* end horz. and vert lines */
	    h_ptr = end_line(h_ptr, 1);

	if (tc)
	    v_list[col].center = end_line(v_list[col].center, 1);

	/* end diag lines only if no horz,vert */
	if ((tl) && (!ml) && (!tc))
	    v_list[col].left = end_line(v_list[col].left, 1);
	if ((tr) && (!mr) && (!tc))
	    v_list[col].right = end_line(v_list[col].right, 1);

	if (mr)			/* start horz. and vert */
	    h_ptr = start_line(1);
	if (bc)
	    v_list[col].center = start_line(1);

	/* start diag if no horz,vert */
	if ((br) && (!mr) && (!bc))
	    v_list[col + 1].left = start_line(1);
	if ((bl) && (!ml) && (!bc))
	    if (bl)
		v_list[col - 1].right = start_line(1);
	break;
    case 5:
	/* G_message(_("crowded cell %xH (%d,%d) -continuing"),count,row,col); */
	/* I think 5 neighbours is nor crowded, so we shouldn't worry the user
	   Olga */
	if (ml)			/* end horz. and vert lines */
	    h_ptr = end_line(h_ptr, 1);

	if (tc)
	    v_list[col].center = end_line(v_list[col].center, 1);

	/* end diag lines only if no horz,vert */
	if ((tl) && (!ml) && (!tc))
	    v_list[col].left = end_line(v_list[col].left, 1);
	if ((tr) && (!mr) && (!tc))
	    v_list[col].right = end_line(v_list[col].right, 1);

	if (mr)			/* start horz. and vert */
	    h_ptr = start_line(1);
	if (bc)
	    v_list[col].center = start_line(1);

	/* start diag if no horz,vert */
	if ((br) && (!mr) && (!bc))
	    v_list[col + 1].left = start_line(1);
	if ((bl) && (!ml) && (!bc))
	    v_list[col - 1].right = start_line(1);
	break;
    case 6:
	/* the same as case 5 */
	G_debug(1, "Crowded cell %xH (%d,%d), continuing", count, row, col);

	if (ml)			/* end horz. and vert lines */
	    h_ptr = end_line(h_ptr, 1);

	if (tc)
	    v_list[col].center = end_line(v_list[col].center, 1);

	/* end diag lines only if no horz,vert */
	if ((tl) && (!ml) && (!tc))
	    v_list[col].left = end_line(v_list[col].left, 1);
	if ((tr) && (!mr) && (!tc))
	    v_list[col].right = end_line(v_list[col].right, 1);

	if (mr)			/* start horz. and vert */
	    h_ptr = start_line(1);
	if (bc)
	    v_list[col].center = start_line(1);

	/* start diag if no horz,vert */
	if ((br) && (!mr) && (!bc))
	    v_list[col + 1].left = start_line(1);
	if ((bl) && (!ml) && (!bc))
	    v_list[col - 1].right = start_line(1);
	break;
    default:
	G_message(_("Crowded cell at (%f, %f): row %d, col %d, count %d"),
		  Rast_col_to_easting((double)col - .5, &cell_head),
		  Rast_row_to_northing((double)row + .5, &cell_head),
		  row, col - 1, count);
	G_fatal_error(_("Raster map is not thinned properly.\nPlease run r.thin."));
    }				/* switch count */

    return 0;
}