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

📄 tiffmedian.c

📁 tiff文件开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
				iptr = &histogram[ir][ig][ptr->bmin];				for (ib = ptr->bmin; ib <= ptr->bmax; ++ib)					*histp += *iptr++;			}			histp++;	        }	        first = ptr->gmin;		last = ptr->gmax;	        break;	case BLUE:	        histp = &hist2[ptr->bmin];	        for (ib = ptr->bmin; ib <= ptr->bmax; ++ib) {			*histp = 0;			for (ir = ptr->rmin; ir <= ptr->rmax; ++ir) {				iptr = &histogram[ir][ptr->gmin][ib];				for (ig = ptr->gmin; ig <= ptr->gmax; ++ig) {					*histp += *iptr;					iptr += B_LEN;				}			}			histp++;	        }	        first = ptr->bmin;		last = ptr->bmax;	        break;	}	/* find median point */	sum2 = ptr->total / 2;	histp = &hist2[first];	sum = 0;	for (i = first; i <= last && (sum += *histp++) < sum2; ++i)		;	if (i == first)		i++;	/* Create new box, re-allocate points */	new = freeboxes;	freeboxes = new->next;	if (freeboxes)		freeboxes->prev = NULL;	if (usedboxes)		usedboxes->prev = new;	new->next = usedboxes;	usedboxes = new;	histp = &hist2[first];	for (sum1 = 0, j = first; j < i; j++)		sum1 += *histp++;	for (sum2 = 0, j = i; j <= last; j++)	    sum2 += *histp++;	new->total = sum1;	ptr->total = sum2;	new->rmin = ptr->rmin;	new->rmax = ptr->rmax;	new->gmin = ptr->gmin;	new->gmax = ptr->gmax;	new->bmin = ptr->bmin;	new->bmax = ptr->bmax;	switch (axis) {	case RED:		new->rmax = i-1;	        ptr->rmin = i;	        break;	case GREEN:	        new->gmax = i-1;	        ptr->gmin = i;	        break;	case BLUE:	        new->bmax = i-1;	        ptr->bmin = i;	        break;	}	shrinkbox(new);	shrinkbox(ptr);}static voidshrinkbox(Colorbox* box){	register uint32 *histp;	register int	ir, ig, ib;	if (box->rmax > box->rmin) {		for (ir = box->rmin; ir <= box->rmax; ++ir)			for (ig = box->gmin; ig <= box->gmax; ++ig) {				histp = &histogram[ir][ig][box->bmin];			        for (ib = box->bmin; ib <= box->bmax; ++ib)					if (*histp++ != 0) {						box->rmin = ir;						goto have_rmin;					}			}	have_rmin:		if (box->rmax > box->rmin)			for (ir = box->rmax; ir >= box->rmin; --ir)				for (ig = box->gmin; ig <= box->gmax; ++ig) {					histp = &histogram[ir][ig][box->bmin];					ib = box->bmin;					for (; ib <= box->bmax; ++ib)						if (*histp++ != 0) {							box->rmax = ir;							goto have_rmax;						}			        }	}have_rmax:	if (box->gmax > box->gmin) {		for (ig = box->gmin; ig <= box->gmax; ++ig)			for (ir = box->rmin; ir <= box->rmax; ++ir) {				histp = &histogram[ir][ig][box->bmin];			        for (ib = box->bmin; ib <= box->bmax; ++ib)				if (*histp++ != 0) {					box->gmin = ig;					goto have_gmin;				}			}	have_gmin:		if (box->gmax > box->gmin)			for (ig = box->gmax; ig >= box->gmin; --ig)				for (ir = box->rmin; ir <= box->rmax; ++ir) {					histp = &histogram[ir][ig][box->bmin];					ib = box->bmin;					for (; ib <= box->bmax; ++ib)						if (*histp++ != 0) {							box->gmax = ig;							goto have_gmax;						}			        }	}have_gmax:	if (box->bmax > box->bmin) {		for (ib = box->bmin; ib <= box->bmax; ++ib)			for (ir = box->rmin; ir <= box->rmax; ++ir) {				histp = &histogram[ir][box->gmin][ib];			        for (ig = box->gmin; ig <= box->gmax; ++ig) {					if (*histp != 0) {						box->bmin = ib;						goto have_bmin;					}					histp += B_LEN;			        }		        }	have_bmin:		if (box->bmax > box->bmin)			for (ib = box->bmax; ib >= box->bmin; --ib)				for (ir = box->rmin; ir <= box->rmax; ++ir) {					histp = &histogram[ir][box->gmin][ib];					ig = box->gmin;					for (; ig <= box->gmax; ++ig) {						if (*histp != 0) {							box->bmax = ib;							goto have_bmax;						}						histp += B_LEN;					}			        }	}have_bmax:	;}static C_cell *create_colorcell(int red, int green, int blue){	register int ir, ig, ib, i;	register C_cell *ptr;	int mindist, next_n;	register int tmp, dist, n;	ir = red >> (COLOR_DEPTH-C_DEPTH);	ig = green >> (COLOR_DEPTH-C_DEPTH);	ib = blue >> (COLOR_DEPTH-C_DEPTH);	ptr = (C_cell *)_TIFFmalloc(sizeof (C_cell));	*(ColorCells + ir*C_LEN*C_LEN + ig*C_LEN + ib) = ptr;	ptr->num_ents = 0;	/*	 * Step 1: find all colors inside this cell, while we're at	 *	   it, find distance of centermost point to furthest corner	 */	mindist = 99999999;	for (i = 0; i < num_colors; ++i) {		if (rm[i]>>(COLOR_DEPTH-C_DEPTH) != ir  ||		    gm[i]>>(COLOR_DEPTH-C_DEPTH) != ig  ||		    bm[i]>>(COLOR_DEPTH-C_DEPTH) != ib)			continue;		ptr->entries[ptr->num_ents][0] = i;		ptr->entries[ptr->num_ents][1] = 0;		++ptr->num_ents;	        tmp = rm[i] - red;	        if (tmp < (MAX_COLOR/C_LEN/2))			tmp = MAX_COLOR/C_LEN-1 - tmp;	        dist = tmp*tmp;	        tmp = gm[i] - green;	        if (tmp < (MAX_COLOR/C_LEN/2))			tmp = MAX_COLOR/C_LEN-1 - tmp;	        dist += tmp*tmp;	        tmp = bm[i] - blue;	        if (tmp < (MAX_COLOR/C_LEN/2))			tmp = MAX_COLOR/C_LEN-1 - tmp;	        dist += tmp*tmp;	        if (dist < mindist)			mindist = dist;	}	/*	 * Step 3: find all points within that distance to cell.	 */	for (i = 0; i < num_colors; ++i) {		if (rm[i] >> (COLOR_DEPTH-C_DEPTH) == ir  &&		    gm[i] >> (COLOR_DEPTH-C_DEPTH) == ig  &&		    bm[i] >> (COLOR_DEPTH-C_DEPTH) == ib)			continue;		dist = 0;	        if ((tmp = red - rm[i]) > 0 ||		    (tmp = rm[i] - (red + MAX_COLOR/C_LEN-1)) > 0 )			dist += tmp*tmp;	        if ((tmp = green - gm[i]) > 0 ||		    (tmp = gm[i] - (green + MAX_COLOR/C_LEN-1)) > 0 )			dist += tmp*tmp;	        if ((tmp = blue - bm[i]) > 0 ||		    (tmp = bm[i] - (blue + MAX_COLOR/C_LEN-1)) > 0 )			dist += tmp*tmp;	        if (dist < mindist) {			ptr->entries[ptr->num_ents][0] = i;			ptr->entries[ptr->num_ents][1] = dist;			++ptr->num_ents;	        }	}	/*	 * Sort color cells by distance, use cheap exchange sort	 */	for (n = ptr->num_ents - 1; n > 0; n = next_n) {		next_n = 0;		for (i = 0; i < n; ++i)			if (ptr->entries[i][1] > ptr->entries[i+1][1]) {				tmp = ptr->entries[i][0];				ptr->entries[i][0] = ptr->entries[i+1][0];				ptr->entries[i+1][0] = tmp;				tmp = ptr->entries[i][1];				ptr->entries[i][1] = ptr->entries[i+1][1];				ptr->entries[i+1][1] = tmp;				next_n = i;		        }	}	return (ptr);}static voidmap_colortable(void){	register uint32 *histp = &histogram[0][0][0];	register C_cell *cell;	register int j, tmp, d2, dist;	int ir, ig, ib, i;	for (ir = 0; ir < B_LEN; ++ir)		for (ig = 0; ig < B_LEN; ++ig)			for (ib = 0; ib < B_LEN; ++ib, histp++) {				if (*histp == 0) {					*histp = -1;					continue;				}				cell = *(ColorCells +				    (((ir>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) +				    ((ig>>(B_DEPTH-C_DEPTH)) << C_DEPTH) +				    (ib>>(B_DEPTH-C_DEPTH))));				if (cell == NULL )					cell = create_colorcell(					    ir << COLOR_SHIFT,					    ig << COLOR_SHIFT,					    ib << COLOR_SHIFT);				dist = 9999999;				for (i = 0; i < cell->num_ents &&				    dist > cell->entries[i][1]; ++i) {					j = cell->entries[i][0];					d2 = rm[j] - (ir << COLOR_SHIFT);					d2 *= d2;					tmp = gm[j] - (ig << COLOR_SHIFT);					d2 += tmp*tmp;					tmp = bm[j] - (ib << COLOR_SHIFT);					d2 += tmp*tmp;					if (d2 < dist) {						dist = d2;						*histp = j;					}				}			}}/* * straight quantization.  Each pixel is mapped to the colors * closest to it.  Color values are rounded to the nearest color * table entry. */static voidquant(TIFF* in, TIFF* out){	unsigned char	*outline, *inputline;	register unsigned char	*outptr, *inptr;	register uint32 i, j;	register int red, green, blue;	inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));	outline = (unsigned char *)_TIFFmalloc(imagewidth);	for (i = 0; i < imagelength; i++) {		if (TIFFReadScanline(in, inputline, i, 0) <= 0)			break;		inptr = inputline;		outptr = outline;		for (j = 0; j < imagewidth; j++) {			red = *inptr++ >> COLOR_SHIFT;			green = *inptr++ >> COLOR_SHIFT;			blue = *inptr++ >> COLOR_SHIFT;			*outptr++ = histogram[red][green][blue];		}		if (TIFFWriteScanline(out, outline, i, 0) < 0)			break;	}	_TIFFfree(inputline);	_TIFFfree(outline);}#define	SWAP(type,a,b)	{ type p; p = a; a = b; b = p; }#define	GetInputLine(tif, row, bad)				\	if (TIFFReadScanline(tif, inputline, row, 0) <= 0)	\		bad;						\	inptr = inputline;					\	nextptr = nextline;					\	for (j = 0; j < imagewidth; ++j) {			\		*nextptr++ = *inptr++;				\		*nextptr++ = *inptr++;				\		*nextptr++ = *inptr++;				\	}#define	GetComponent(raw, cshift, c)				\	cshift = raw;						\	if (cshift < 0)						\		cshift = 0;					\	else if (cshift >= MAX_COLOR)				\		cshift = MAX_COLOR-1;				\	c = cshift;						\	cshift >>= COLOR_SHIFT;static voidquant_fsdither(TIFF* in, TIFF* out){	unsigned char *outline, *inputline, *inptr;	short *thisline, *nextline;	register unsigned char	*outptr;	register short *thisptr, *nextptr;	register uint32 i, j;	uint32 imax, jmax;	int lastline, lastpixel;	imax = imagelength - 1;	jmax = imagewidth - 1;	inputline = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));	thisline = (short *)_TIFFmalloc(imagewidth * 3 * sizeof (short));	nextline = (short *)_TIFFmalloc(imagewidth * 3 * sizeof (short));	outline = (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out));	GetInputLine(in, 0, goto bad);		/* get first line */	for (i = 1; i <= imagelength; ++i) {		SWAP(short *, thisline, nextline);		lastline = (i >= imax);		if (i <= imax)			GetInputLine(in, i, break);		thisptr = thisline;		nextptr = nextline;		outptr = outline;		for (j = 0; j < imagewidth; ++j) {			int red, green, blue;			register int oval, r2, g2, b2;			lastpixel = (j == jmax);			GetComponent(*thisptr++, r2, red);			GetComponent(*thisptr++, g2, green);			GetComponent(*thisptr++, b2, blue);			oval = histogram[r2][g2][b2];			if (oval == -1) {				int ci;				register int cj, tmp, d2, dist;				register C_cell	*cell;				cell = *(ColorCells +				    (((r2>>(B_DEPTH-C_DEPTH)) << C_DEPTH*2) +				    ((g2>>(B_DEPTH-C_DEPTH)) << C_DEPTH ) +				    (b2>>(B_DEPTH-C_DEPTH))));				if (cell == NULL)					cell = create_colorcell(red,					    green, blue);				dist = 9999999;				for (ci = 0; ci < cell->num_ents && dist > cell->entries[ci][1]; ++ci) {					cj = cell->entries[ci][0];					d2 = (rm[cj] >> COLOR_SHIFT) - r2;					d2 *= d2;					tmp = (gm[cj] >> COLOR_SHIFT) - g2;					d2 += tmp*tmp;					tmp = (bm[cj] >> COLOR_SHIFT) - b2;					d2 += tmp*tmp;					if (d2 < dist) {						dist = d2;						oval = cj;					}				}				histogram[r2][g2][b2] = oval;			}			*outptr++ = oval;			red -= rm[oval];			green -= gm[oval];			blue -= bm[oval];			if (!lastpixel) {				thisptr[0] += blue * 7 / 16;				thisptr[1] += green * 7 / 16;				thisptr[2] += red * 7 / 16;			}			if (!lastline) {				if (j != 0) {					nextptr[-3] += blue * 3 / 16;					nextptr[-2] += green * 3 / 16;					nextptr[-1] += red * 3 / 16;				}				nextptr[0] += blue * 5 / 16;				nextptr[1] += green * 5 / 16;				nextptr[2] += red * 5 / 16;				if (!lastpixel) {					nextptr[3] += blue / 16;				        nextptr[4] += green / 16;				        nextptr[5] += red / 16;				}				nextptr += 3;			}		}		if (TIFFWriteScanline(out, outline, i-1, 0) < 0)			break;	}bad:	_TIFFfree(inputline);	_TIFFfree(thisline);	_TIFFfree(nextline);	_TIFFfree(outline);}

⌨️ 快捷键说明

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