⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jquant2.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
 * placed in colorlist[].
 * This routine uses Heckbert's "locally sorted search" criterion to select
 * the colors that need further consideration.
 */
{
	int numcolors = cinfo->actual_number_of_colors;
	int maxc0, maxc1, maxc2;
	int centerc0, centerc1, centerc2;
	int i, x, ncolors;
	INT32 minmaxdist, min_dist, max_dist, tdist;
	INT32 mindist[MAXNUMCOLORS];	/* min distance to colormap entry i */

	/* Compute true coordinates of update box's upper corner and center.
	 * Actually we compute the coordinates of the center of the upper-corner
	 * histogram cell, which are the upper bounds of the volume we care about.
	 * Note that since ">>" rounds down, the "center" values may be closer to
	 * min than to max; hence comparisons to them must be "<=", not "<".
	 */
	maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
	centerc0 = (minc0 + maxc0) >> 1;
	maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
	centerc1 = (minc1 + maxc1) >> 1;
	maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
	centerc2 = (minc2 + maxc2) >> 1;

	/* For each color in colormap, find:
	 *  1. its minimum squared-distance to any point in the update box
	 *     (zero if color is within update box);
	 *  2. its maximum squared-distance to any point in the update box.
	 * Both of these can be found by considering only the corners of the box.
	 * We save the minimum distance for each color in mindist[];
	 * only the smallest maximum distance is of interest.
	 */
	minmaxdist = 0x7FFFFFFFL;

	for (i = 0; i < numcolors; i++)
	{
		/* We compute the squared-c0-distance term, then add in the other two. */
		x = GETJSAMPLE(cinfo->colormap[0][i]);
		if (x < minc0)
		{
			tdist = (x - minc0) * C0_SCALE;
			min_dist = tdist * tdist;
			tdist = (x - maxc0) * C0_SCALE;
			max_dist = tdist * tdist;
		}
		else if (x > maxc0)
		{
			tdist = (x - maxc0) * C0_SCALE;
			min_dist = tdist * tdist;
			tdist = (x - minc0) * C0_SCALE;
			max_dist = tdist * tdist;
		}
		else
		{
			/* within cell range so no contribution to min_dist */
			min_dist = 0;
			if (x <= centerc0)
			{
				tdist = (x - maxc0) * C0_SCALE;
				max_dist = tdist * tdist;
			}
			else
			{
				tdist = (x - minc0) * C0_SCALE;
				max_dist = tdist * tdist;
			}
		}

		x = GETJSAMPLE(cinfo->colormap[1][i]);
		if (x < minc1)
		{
			tdist = (x - minc1) * C1_SCALE;
			min_dist += tdist * tdist;
			tdist = (x - maxc1) * C1_SCALE;
			max_dist += tdist * tdist;
		}
		else if (x > maxc1)
		{
			tdist = (x - maxc1) * C1_SCALE;
			min_dist += tdist * tdist;
			tdist = (x - minc1) * C1_SCALE;
			max_dist += tdist * tdist;
		}
		else
		{
			/* within cell range so no contribution to min_dist */
			if (x <= centerc1)
			{
				tdist = (x - maxc1) * C1_SCALE;
				max_dist += tdist * tdist;
			}
			else
			{
				tdist = (x - minc1) * C1_SCALE;
				max_dist += tdist * tdist;
			}
		}

		x = GETJSAMPLE(cinfo->colormap[2][i]);
		if (x < minc2)
		{
			tdist = (x - minc2) * C2_SCALE;
			min_dist += tdist * tdist;
			tdist = (x - maxc2) * C2_SCALE;
			max_dist += tdist * tdist;
		}
		else if (x > maxc2)
		{
			tdist = (x - maxc2) * C2_SCALE;
			min_dist += tdist * tdist;
			tdist = (x - minc2) * C2_SCALE;
			max_dist += tdist * tdist;
		}
		else
		{
			/* within cell range so no contribution to min_dist */
			if (x <= centerc2)
			{
				tdist = (x - maxc2) * C2_SCALE;
				max_dist += tdist * tdist;
			}
			else
			{
				tdist = (x - minc2) * C2_SCALE;
				max_dist += tdist * tdist;
			}
		}

		mindist[i] = min_dist;	/* save away the results */
		if (max_dist < minmaxdist)
		{
			minmaxdist = max_dist;
		}
	}

	/* Now we know that no cell in the update box is more than minmaxdist
	 * away from some colormap entry.  Therefore, only colors that are
	 * within minmaxdist of some part of the box need be considered.
	 */
	ncolors = 0;
	for (i = 0; i < numcolors; i++)
	{
		if (mindist[i] <= minmaxdist)
		{
			colorlist[ncolors++] = (JSAMPLE) i;
		}
	}
	return ncolors;
}


LOCAL(void)
find_best_colors(j_decompress_ptr cinfo, int minc0, int minc1, int minc2, int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
/* Find the closest colormap entry for each cell in the update box,
 * given the list of candidate colors prepared by find_nearby_colors.
 * Return the indexes of the closest entries in the bestcolor[] array.
 * This routine uses Thomas' incremental distance calculation method to
 * find the distance from a colormap entry to successive cells in the box.
 */
{
	int ic0, ic1, ic2;
	int i, icolor;
	register INT32 * bptr;	/* pointer into bestdist[] array */
	JSAMPLE * cptr;		/* pointer into bestcolor[] array */
	INT32 dist0, dist1;		/* initial distance values */
	register INT32 dist2;		/* current distance in inner loop */
	INT32 xx0, xx1;		/* distance increments */
	register INT32 xx2;
	INT32 inc0, inc1, inc2;	/* initial values for increments */
	/* This array holds the distance to the nearest-so-far color for each cell */
	INT32 bestdist[BOX_C0_ELEMS *BOX_C1_ELEMS *BOX_C2_ELEMS];

	/* Initialize best-distance for each cell of the update box */
	bptr = bestdist;
	for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS - 1; i >= 0; i--)
	{
		*bptr++ = 0x7FFFFFFFL;
	}

	/* For each color selected by find_nearby_colors,
	 * compute its distance to the center of each cell in the box.
	 * If that's less than best-so-far, update best distance and color number.
	 */

	/* Nominal steps between cell centers ("x" in Thomas article) */
#define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
#define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
#define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)

	for (i = 0; i < numcolors; i++)
	{
		icolor = GETJSAMPLE(colorlist[i]);
		/* Compute (square of) distance from minc0/c1/c2 to this color */
		inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
		dist0 = inc0 * inc0;
		inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
		dist0 += inc1 * inc1;
		inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
		dist0 += inc2 * inc2;
		/* Form the initial difference increments */
		inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
		inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
		inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
		/* Now loop over all cells in box, updating distance per Thomas method */
		bptr = bestdist;
		cptr = bestcolor;
		xx0 = inc0;
		for (ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--)
		{
			dist1 = dist0;
			xx1 = inc1;
			for (ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--)
			{
				dist2 = dist1;
				xx2 = inc2;
				for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--)
				{
					if (dist2 < *bptr)
					{
						*bptr = dist2;
						*cptr = (JSAMPLE) icolor;
					}
					dist2 += xx2;
					xx2 += 2 * STEP_C2 * STEP_C2;
					bptr++;
					cptr++;
				}
				dist1 += xx1;
				xx1 += 2 * STEP_C1 * STEP_C1;
			}
			dist0 += xx0;
			xx0 += 2 * STEP_C0 * STEP_C0;
		}
	}
}


LOCAL(void)
fill_inverse_cmap(j_decompress_ptr cinfo, int c0, int c1, int c2)
/* Fill the inverse-colormap entries in the update box that contains */
/* histogram cell c0/c1/c2.  (Only that one cell MUST be filled, but */
/* we can fill as many others as we wish.) */
{
	my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
	hist3d histogram = cquantize->histogram;
	int minc0, minc1, minc2;	/* lower left corner of update box */
	int ic0, ic1, ic2;
	register JSAMPLE * cptr;	/* pointer into bestcolor[] array */
	register histptr cachep;	/* pointer into main cache array */
	/* This array lists the candidate colormap indexes. */
	JSAMPLE colorlist[MAXNUMCOLORS];
	int numcolors;		/* number of candidate colors */
	/* This array holds the actually closest colormap index for each cell. */
	JSAMPLE bestcolor[BOX_C0_ELEMS *BOX_C1_ELEMS *BOX_C2_ELEMS];

	/* Convert cell coordinates to update box ID */
	c0 >>= BOX_C0_LOG;
	c1 >>= BOX_C1_LOG;
	c2 >>= BOX_C2_LOG;

	/* Compute true coordinates of update box's origin corner.
	 * Actually we compute the coordinates of the center of the corner
	 * histogram cell, which are the lower bounds of the volume we care about.
	 */
	minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
	minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
	minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);

	/* Determine which colormap entries are close enough to be candidates
	 * for the nearest entry to some cell in the update box.
	 */
	numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);

	/* Determine the actually nearest colors. */
	find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, bestcolor);

	/* Save the best color numbers (plus 1) in the main cache array */
	c0 <<= BOX_C0_LOG;		/* convert ID back to base cell indexes */
	c1 <<= BOX_C1_LOG;
	c2 <<= BOX_C2_LOG;
	cptr = bestcolor;
	for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++)
	{
		for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++)
		{
			cachep = &histogram[c0 + ic0][c1 + ic1][c2];
			for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++)
			{
				*cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
			}
		}
	}
}


/*
 * Map some rows of pixels to the output colormapped representation.
 */

METHODDEF(void)
pass2_no_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
/* This version performs no dithering */
{
	my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
	hist3d histogram = cquantize->histogram;
	register JSAMPROW inptr, outptr;
	register histptr cachep;
	register int c0, c1, c2;
	int row;
	JDIMENSION col;
	JDIMENSION width = cinfo->output_width;

	for (row = 0; row < num_rows; row++)
	{
		inptr = input_buf[row];
		outptr = output_buf[row];
		for (col = width; col > 0; col--)
		{
			/* get pixel value and index into the cache */
			c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
			c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
			c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
			cachep = &histogram[c0][c1][c2];
			/* If we have not seen this color before, find nearest colormap entry */
			/* and update the cache */
			if (*cachep == 0)
			{
				fill_inverse_cmap(cinfo, c0, c1, c2);
			}
			/* Now emit the colormap index for this cell */
			*outptr++ = (JSAMPLE) (*cachep - 1);
		}
	}
}


METHODDEF(void)
pass2_fs_dither(j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
/* This version performs Floyd-Steinberg dithering */
{
	my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
	hist3d histogram = cquantize->histogram;
	register LOCFSERROR cur0, cur1, cur2;	/* current error or pixel value */
	LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
	LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
	register FSERRPTR errorptr;	/* => fserrors[] at column before current */
	JSAMPROW inptr;		/* => current input pixel */
	JSAMPROW outptr;		/* => current output pixel */
	histptr cachep;
	int dir;			/* +1 or -1 depending on direction */
	int dir3;			/* 3*dir, for advancing inptr & errorptr */
	int row;
	JDIMENSION col;
	JDIMENSION width = cinfo->output_width;
	JSAMPLE *range_limit = cinfo->sample_range_limit;
	int *error_limit = cquantize->error_limiter;
	JSAMPROW colormap0 = cinfo->colormap[0];
	JSAMPROW colormap1 = cinfo->colormap[1];
	JSAMPROW colormap2 = cinfo->colormap[2];
	SHIFT_TEMPS

	for (row = 0; row < num_rows; row++)
	{
		inptr = input_buf[row];
		outptr = output_buf[row];
		if (cquantize->on_odd_row)
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -