Exemple #1
0
void
ImagingPaletteCacheUpdate(ImagingPalette palette, int r, int g, int b)
{
    int i, j;
    unsigned int dmin[256], dmax;
    int r0, g0, b0;
    int r1, g1, b1;
    int rc, gc, bc;
    unsigned int d[BOXVOLUME];
    UINT8 c[BOXVOLUME];

    /* Get box boundaries for the given (r,g,b)-triplet.  Each box
       covers eight cache slots (32 colour values, that is). */

    r0 = r & 0xe0; r1 = r0 + 0x1f; rc = (r0 + r1) / 2;
    g0 = g & 0xe0; g1 = g0 + 0x1f; gc = (g0 + g1) / 2;
    b0 = b & 0xe0; b1 = b0 + 0x1f; bc = (b0 + b1) / 2;

    /* Step 1 -- Select relevant palette entries (after Heckbert) */

    /* For each palette entry, calculate the min and max distances to
     * any position in the box given by the colour we're looking for. */

    dmax = (unsigned int) ~0;

    for (i = 0; i < 256; i++) {

	int r, g, b;
	unsigned int tmin, tmax;

	/* Find min and max distances to any point in the box */
	r = palette->palette[i*4+0];
	tmin = (r < r0) ? RDIST(r, r1) : (r > r1) ? RDIST(r, r0) : 0;
	tmax = (r <= rc) ? RDIST(r, r1) : RDIST(r, r0);

	g = palette->palette[i*4+1];
	tmin += (g < g0) ? GDIST(g, g1) : (g > g1) ? GDIST(g, g0) : 0;
	tmax += (g <= gc) ? GDIST(g, g1) : GDIST(g, g0);

	b = palette->palette[i*4+2];
	tmin += (b < b0) ? BDIST(b, b1) : (b > b1) ? BDIST(b, b0) : 0;
	tmax += (b <= bc) ? BDIST(b, b1) : BDIST(b, b0);

	dmin[i] = tmin;
	if (tmax < dmax)
	    dmax = tmax; /* keep the smallest max distance only */

    }

    /* Step 2 -- Incrementally update cache slot (after Thomas) */

    /* Find the box containing the nearest palette entry, and update
     * all slots in that box.  We only check boxes for which the min
     * distance is less than or equal the smallest max distance */

    for (i = 0; i < BOXVOLUME; i++)
	d[i] = (unsigned int) ~0;

    for (i = 0; i < 256; i++)

	if (dmin[i] <= dmax) {

	    int rd, gd, bd;
	    int ri, gi, bi;
	    int rx, gx, bx;

	    ri = (r0 - palette->palette[i*4+0]) * RSCALE;
	    gi = (g0 - palette->palette[i*4+1]) * GSCALE;
	    bi = (b0 - palette->palette[i*4+2]) * BSCALE;

	    rd = ri*ri + gi*gi + bi*bi;

	    ri = ri * (2 * RSTEP) + RSTEP * RSTEP;
	    gi = gi * (2 * GSTEP) + GSTEP * GSTEP;
	    bi = bi * (2 * BSTEP) + BSTEP * BSTEP;

	    rx = ri;
	    for (r = j = 0; r < BOX; r++) {
		gd = rd; gx = gi;
		for (g = 0; g < BOX; g++) {
		    bd = gd; bx = bi;
		    for (b = 0; b < BOX; b++) {
			if ((unsigned int) bd < d[j]) {
			    d[j] = bd;
			    c[j] = (UINT8) i;
			}
			bd += bx;
			bx += 2 * BSTEP * BSTEP;
			j++;
		    }
		    gd += gx;
		    gx += 2 * GSTEP * GSTEP;
		}
		rd += rx;
		rx += 2 * RSTEP * RSTEP;
	    }
	}

    /* Step 3 -- Update cache */

    /* The c array now contains the closest match for each
     * cache slot in the box.  Update the cache. */

    j = 0;
    for (r = r0; r < r1; r+=4)
	for (g = g0; g < g1; g+=4)
	    for (b = b0; b < b1; b+=4)
		ImagingPaletteCache(palette, r, g, b) = c[j++];
}
Exemple #2
0
	static
	void
compute_edge_graph (

bitmap_t *	tmap,		/* IN - valid set of terminals */
bitmap_t *	fset_mask,	/* IN - valid FSTs */
struct cinfo *	cip		/* IN - compatibility info */
)
{
int			i, j, i1, i2;
int			sp_index;
int			sp_total;
int			n2edges;
int			nedges;
struct full_set *	fsp;
struct pset *		terms;
struct point *		p1;
struct point *		p2;
dist_t			d = 0.0;
char			buf1 [128];
char			buf2 [128];

	/* Total number of Steiner points and ordinary edges */
	nedges = cip -> num_edges;
	sp_total = 0;
	n2edges	 = 0;
	for (i = 0; i < nedges; i++) {
		if (NOT BITON (fset_mask, i)) continue;
		sp_total += cip -> full_trees [i] -> steiners -> n;
		n2edges	 += cip -> full_trees [i] -> nedges;
	}

	/* Write header */
	if (Print_ORLibrary_Format) {
		printf ("%d %d\n", cip -> num_verts + sp_total, n2edges);
	}

	if (Print_SteinLib_Format) {
		printf ("33d32945 STP File, STP Format Version 1.00\n"
			"Section Comment\n"
			"Name    \"%s\"\n"
			"Creator \"GeoSteiner\"\n"
			"Remark  \"Reduced graph from FST generator\"\n"
			"End\n\n"
			"Section Graph\n"
			"Nodes %d\n"
			"Edges %d\n",
			cip -> description, cip -> num_verts + sp_total, n2edges);
	}

	/* Write (ordinary) graph edges */
	sp_index = cip -> num_verts;
	for (i = 0; i < nedges; i++) {
		if (NOT BITON (fset_mask, i)) continue;
		fsp = cip -> full_trees [i];
		terms = fsp -> terminals;
		for (j = 0; j < fsp -> nedges; j++) {

			/* Compute length of this edge */
			p1 = (fsp -> edges[j].p1 < terms -> n)
				? &(terms -> a[ fsp -> edges[j].p1 ])
				: &(fsp -> steiners -> a [fsp -> edges[j].p1 - terms -> n]);
			p2 = (fsp -> edges[j].p2 < terms -> n)
				? &(terms -> a[ fsp -> edges[j].p2 ])
				: &(fsp -> steiners -> a [fsp -> edges[j].p2 - terms -> n]);

			i1 = (fsp -> edges[j].p1 < terms -> n)
				? terms -> a[ fsp -> edges[j].p1 ].pnum + 1
				: fsp -> edges[j].p1 - terms -> n + sp_index + 1;
			i2 = (fsp -> edges[j].p2 < terms -> n)
				? terms -> a[ fsp -> edges[j].p2 ].pnum + 1
				: fsp -> edges[j].p2 - terms -> n + sp_index + 1;

			if (Print_SteinLib_Format) {
				printf ("E ");
			}

			if (cip -> metric EQ EUCLIDEAN) {
				d = EDIST(p1, p2);
			}
			else {
				d = RDIST(p1, p2);
			}
			dist_to_string (buf1, d, &(cip -> scale));
			printf ("%d %d %s\n", i1, i2, buf1);
		}
		if (fsp -> steiners NE NULL) {
			sp_index += fsp -> steiners -> n;
		}
	}

	/* Write terminals (and coordinates in STP-format) */
	if (Print_ORLibrary_Format) {
		printf ("%d\n", cip -> num_verts);
		for (i = 0; i < cip -> num_verts; i++) {
			printf ("%d\n", i+1);
		}
	}

	if (Print_SteinLib_Format) {
		printf ("End\n\n"
			"Section Terminals\n"
			"Terminals %d\n",
			cip -> num_verts);
		for (i = 0; i < cip -> num_verts; i++) {
			printf ("T %d\n", i+1);
		}
		printf ("End\n\n"
			"Section Coordinates\n");
		for (i = 0; i < cip -> num_verts; i++) { /* terminals */
			dist_to_string (buf1,
					cip -> pts -> a[i].x,
					&(cip -> scale));
			dist_to_string (buf2,
					cip -> pts -> a[i].y,
					&(cip -> scale));
			printf ("DD %d %s %s\n", i+1, buf1, buf2);
		}
		sp_index = cip -> num_verts + 1;
		for (i = 0; i < nedges; i++) { /* Steiner points */
			fsp = cip -> full_trees [i];
			for (j = 0; j < fsp -> steiners -> n; j++) {
				dist_to_string (buf1,
						fsp -> steiners -> a[j].x,
						&(cip -> scale));
				dist_to_string (buf2,
						fsp -> steiners -> a[j].y,
						&(cip -> scale));
				printf ("DD %d %s %s\n", sp_index++, buf1, buf2);
			}
		}
		printf ("End\n\n"
			"EOF\n");
	}
}