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

📄 dip.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
/* dip.c * Digital Image Processing routines * (c) 2000-2002 Karel 'Clock' Kulhavy * This file is a part of the Links program, released under GPL. * This does various utilities for digital image processing including font * rendering. */#include "cfg.h"#ifdef G#include "links.h"#ifdef HAVE_MATH_H#include <math.h>#endif /* HAVE_MATH_H */#endifint dither_letters=1;double user_gamma=1.0; /* 1.0 for 64 lx. This is the number user directly changes in the menu */			  double display_red_gamma=2.2; /* Red gamma exponent of the display */double display_green_gamma=2.2; /* Green gamma exponent of the display */double display_blue_gamma=2.2; /* Blue gamma exponent of the display */#ifdef G/* #define this if you want to report missing letters to stderr. * Leave it commented up for normal operation and releases! *//* #define REPORT_UNKNOWN 1 */double sRGB_gamma=0.45455;      /* For HTML, which runs				 * according to sRGB standard. Number				 * in HTML tag is linear to photons raised				 * to this power.				 */unsigned long aspect=65536; /* aspect=65536 for 320x240		        * aspect=157286 for 640x200 (tall pixels)                        * Defines aspect ratio of screen pixels. 		        * aspect=(196608*xsize+ysize<<1)/(ysize<<1);		        * Default is 65536 because we assume square pixel			* when not specified otherwise. Aspect is ratio of			* the pixel height (in milimeters) to pixel width,			* multiplied by 65536. */unsigned long aspect_native=65536; /* Like aspect, but not influenced by			* user, just determined by graphics driver.			*//* Limitation: No input image's dimension may exceed 2^(32-1-8) pixels. *//* Each input byte represents 1 byte (gray). The question whether 0 is * black or 255 is black doesn't matter. *//* These constants represent contrast-enhancement and sharpen filter (which is one filter * together) that is applied onto the letters to enhance their appearance at low height. * They were determined by experiment for several values, interpolated, checked and tuned. * If you change them, don't wonder if the letters start to look strange. * The numers in the comments denote which height the line applies for. */float fancy_constants[64]={	0,3,		/*  1 */	.1,3,   	/*  2 */	.2,3,   	/*  3 */	.3,2.9,   	/*  4 */	.4,2.7,   	/*  5 */	.4,2.5,   	/*  6 */	.4,2,   	/*  7 */	.5,2, 		/*  8 */	.4,2, 		/*  9 */	.38,1.9, 	/* 10 */	.36,1.8, 	/* 11 */	.33,1.7, 	/* 12 */	.30,1.6, 	/* 13 */	.25,1.5, 	/* 14 */	.20,1.5, 	/* 15 */	.15,1.5, 	/* 16 */	.14,1.5, 	/* 17 */	.13,1.5, 	/* 18 */	.12,1.5, 	/* 19 */	.12,1.5, 	/* 20 */	.12,1.5, 	/* 21 */	.12,1.5, 	/* 22 */	.11,1.5, 	/* 23 */	.10,1.4, 	/* 24 */	.09,1.3, 	/* 25 */	.08,1.3, 	/* 26 */	.04,1.2, 	/* 27 */	.04,1.2, 	/* 28 */	.02,1.1, 	/* 29 */	.02,1.1, 	/* 30 */	.01,1, 		/* 31 */	.01,1  		/* 32 */};/* prototypes */void decimate_3(unsigned short **, int, int);struct letter *find_stored_letter(int *, int);void read_stored_data(png_structp, png_bytep, png_uint_32);void my_png_warning(png_structp, png_const_charp);void my_png_error(png_structp, png_const_charp);struct font_cache_entry *supply_color_cache_entry (struct graphics_driver *, struct style *, struct letter *);void get_underline_pos(int, int *, int *);int compare_font_entries(void *, void *);void init_font_cache(int);void recode_font_name(unsigned char **);int compare_family(unsigned char *, unsigned char *);int fill_style_table(int *, unsigned char *);/* This shall be hopefully reasonably fast and portable * We assume ix is <65536. If not, the letters will be smaller in * horizontal dimension (because of overflow) but this will not cause * a segfault. 65536 pixels wide bitmaps are not normal and will anyway * exhaust the memory. */static inline int compute_width (int ix, int iy, int required_height){	int width;	unsigned long reg;		reg=(unsigned long)aspect*(unsigned long)required_height;		if (reg>=0x1000000UL){		/* It's big */		reg=(reg+32768)>>16;		width=(reg*ix+(iy>>1))/iy;	}else{		/* It's small */		reg=(reg+128)>>8;		iy<<=8;		width=(reg*ix+(iy>>1))/iy;	}	if (width<1) width=1;	return width;}struct lru font_cache; /* This is a cache for screen-ready colored bitmaps                        * of lettrs and/or alpha channels for these (are the			* same size, only one byte per pixel and are used			* for letters with an image under them )			*//* Each input byte represents 1 byte (gray). The question whether 0 is * black or 255 is black doesn't matter. */inline static void add_col_gray(unsigned *col_buf, unsigned char *ptr, int		line_skip, int n, unsigned weight){	for (;n;n--){		*col_buf+=weight*(*ptr);		ptr+=line_skip;		col_buf++;	}}/* line_skip is in pixels. The column contains the whole pixels (R G B) * We assume unsigned short holds at least 16 bits. */inline static void add_col_color(unsigned *col_buf, unsigned short *ptr	, int line_skip, int n, unsigned weight){	for (;n;n--){		*col_buf+=weight*(*ptr);		col_buf[1]+=weight*ptr[1];		col_buf[2]+=weight*ptr[2];		ptr+=line_skip;		col_buf+=3;	}} /* We assume unsigned short holds at least 16 bits. */inline static void add_row_gray(unsigned *row_buf, unsigned char *ptr, int n,	unsigned weight){	for (;n;n--){		*row_buf+=weight**ptr;		ptr++;		row_buf++;	}}/* n is in pixels. pixel is 3 unsigned shorts in series */ /* We assume unsigned short holds at least 16 bits. */inline static void add_row_color(unsigned *row_buf, unsigned short *ptr, int n, unsigned weight){	for (;n;n--){		*row_buf+=weight**ptr;		row_buf[1]+=weight*ptr[1];		row_buf[2]+=weight*ptr[2];		ptr+=3;		row_buf+=3;	}}/* We assume unsigned holds at least 32 bits */inline static void emit_and_bias_col_gray(unsigned *col_buf, unsigned char *out, int		line_skip, int n, unsigned weight){	unsigned half=weight>>1;	for (;n;n--){		*out=*col_buf/weight;		out+=line_skip;		*col_buf++=half;	}}/* We assume unsigned holds at least 32 bits */static inline void bias_buf_gray(unsigned *col_buf, int n, unsigned half){	for (;n;n--) *col_buf++=half;}/* We assume unsigned holds at least 32 bits */inline static void bias_buf_color(unsigned *col_buf, int n, unsigned half){	for (;n;n--){		*col_buf=half;		col_buf[1]=half;		col_buf[2]=half;		col_buf+=3;	}	/* System activated */}		/* line skip is in pixels. Pixel is 3*unsigned short *//* We assume unsigned holds at least 32 bits *//* We assume unsigned short holds at least 16 bits. */inline static void emit_and_bias_col_color(unsigned *col_buf	, unsigned short *out, int line_skip, int n, unsigned weight){	unsigned half=weight>>1;	for (;n;n--){		*out=(*col_buf)/weight;		*col_buf=half;		out[1]=col_buf[1]/weight;		col_buf[1]=half;		/* The following line is an enemy of the State and will be		 * prosecuted according to the Constitution of The United States		 * Cap. 20/3 ix. Sel. Bill 12/1920		 * Moses 12/20 Erizea farizea 2:2:1:14		 */		out[2]=col_buf[2]/weight;		col_buf[2]=half;		out+=line_skip;		col_buf+=3;	}}		/* We assume unsigned holds at least 32 bits */inline static void emit_and_bias_row_gray(unsigned *row_buf, unsigned char *out, int n		,unsigned weight){	unsigned half=weight>>1;		for (;n;n--){		*out++=*row_buf/weight;		*row_buf++=half;	}}/* n is in pixels. pixel is 3 unsigned shorts in series. *//* We assume unsigned holds at least 32 bits *//* We assume unsigned short holds at least 16 bits. */inline static void emit_and_bias_row_color(unsigned *row_buf, unsigned short		*out, int n, unsigned weight){	unsigned half=weight>>1;	for (;n;n--){		*out=*row_buf/weight;		*row_buf=half;		out[1]=row_buf[1]/weight;		row_buf[1]=half;		out[2]=row_buf[2]/weight;		row_buf[2]=half;		out+=3;		row_buf+=3;	}}		/* For enlargement only -- does linear filtering. * Allocates output and frees input. * We assume unsigned holds at least 32 bits */inline static void enlarge_gray_horizontal(unsigned char *in, int ix, int y	,unsigned char ** out, int ox){	unsigned *col_buf;	int total;	int out_pos,in_pos,in_begin,in_end;	unsigned half=(ox-1)>>1;	unsigned char *outptr;	unsigned char *inptr;	if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc();	if ((unsigned)ox * (unsigned)y > MAXINT) overalloc();	outptr=mem_alloc(ox*y);	inptr=in;	*out=outptr;	if (ix==1){		/* Dull copying */		for (;y;y--){			memset(outptr,*inptr,ox);			outptr+=ox;			inptr++;		}		mem_free(in);	}else{		total=(ix-1)*(ox-1);		if ((unsigned)y > MAXINT / sizeof(*col_buf)) overalloc();		col_buf=mem_alloc(y*sizeof(*col_buf));		bias_buf_gray(col_buf, y, half);		out_pos=0;		in_pos=0;		again:		in_begin=in_pos;		in_end=in_pos+ox-1;		add_col_gray(col_buf,inptr, ix, y, in_end-out_pos);		add_col_gray(col_buf,inptr+1, ix, y, out_pos-in_begin);		emit_and_bias_col_gray(col_buf,outptr,ox,y,ox-1);		outptr++;		out_pos+=ix-1;		if (out_pos>in_end){			in_pos=in_end;			inptr++;		}		if (out_pos>total){			mem_free(in);			mem_free(col_buf);			return;		}		goto again;	}	/* Rohan, oh Rohan... */	/* ztracena zeme :) */}/* For enlargement only -- does linear filtering * Frees input and allocates output. * We assume unsigned holds at least 32 bits */static inline void enlarge_color_horizontal(unsigned short *ina, int ix, int y,	unsigned short ** outa, int ox){	unsigned *col_buf;	int total,a,out_pos,in_pos,in_begin,in_end;	unsigned half=(ox-1)>>1;	unsigned skip=3*ix;	unsigned oskip=3*ox;	unsigned short *out, *in;	if (ix==ox){		*outa=ina;		return;	}	if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc();	if ((unsigned)ox * (unsigned)y > MAXINT / 3 / sizeof(*out)) overalloc();	out=mem_alloc(sizeof(*out)*3*ox*y);	*outa=out;	in=ina;	if (ix==1){		for (;y;y--,in+=3) for (a=ox;a;a--,out+=3){			*out=*in;			out[1]=in[1];			out[2]=in[2];		}		mem_free(ina);		return;	}	total=(ix-1)*(ox-1);	if ((unsigned)y > MAXINT / 3 / sizeof(*col_buf)) overalloc();	col_buf=mem_alloc(y*3*sizeof(*col_buf));	bias_buf_color(col_buf,y,half);	out_pos=0;	in_pos=0;	again:	in_begin=in_pos;	in_end=in_pos+ox-1;	add_col_color(col_buf,in,skip,y		,in_end-out_pos);	add_col_color(col_buf,in+3,skip,y		,out_pos-in_begin);	emit_and_bias_col_color(col_buf,out,oskip,y,ox-1);	out+=3;	out_pos+=ix-1;	if (out_pos>in_end){		in_pos=in_end;		in+=3;	}	if (out_pos>total){		mem_free(col_buf);		mem_free(ina);		return;	}	goto again;}/* Works for both enlarging and diminishing. Linear resample, no low pass. * Automatically mem_frees the "in" and allocates "out". *//* We assume unsigned holds at least 32 bits */inline static void scale_gray_horizontal(unsigned char *in, int ix, int y	,unsigned char ** out, int ox){	unsigned *col_buf;	int total=ix*ox;	int out_pos,in_pos,in_begin,in_end,out_end;	unsigned char *outptr;	unsigned char *inptr;	if (ix<ox){		enlarge_gray_horizontal(in,ix,y,out,ox);		return;	}else if (ix==ox){		*out=in;		return;	}	if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc();	if ((unsigned)ox * (unsigned)y > MAXINT) overalloc();	outptr=mem_alloc(ox*y);	inptr=in;	*out=outptr;	if ((unsigned)y > MAXINT / sizeof(*col_buf)) overalloc();	col_buf=mem_alloc(y*sizeof(*col_buf));	bias_buf_gray(col_buf, y, ix>>1);	out_pos=0;	in_pos=0;	again:	in_begin=in_pos;	in_end=in_pos+ox;	out_end=out_pos+ix;	if (in_begin<out_pos)in_begin=out_pos;	if (in_end>out_end)in_end=out_end;	add_col_gray(col_buf,inptr,ix,y,in_end-in_begin);	in_end=in_pos+ox;	if (out_end>=in_end){		in_pos=in_end;		inptr++;	}	if (out_end<=in_end){			emit_and_bias_col_gray(col_buf,outptr,ox,y,ix);			out_pos=out_pos+ix;			outptr++;	}	if (out_pos==total) {		mem_free(in);		mem_free(col_buf);		return;	}	goto again;}/* Works for both enlarging and diminishing. Linear resample, no low pass. * Does only one color component. * Frees ina and allocates outa. * If ox*3<=ix, and display_optimize, performs optimization for LCD. */inline static void scale_color_horizontal(unsigned short *ina, int ix, int y,		unsigned short **outa, int ox){	unsigned *col_buf;	int total=ix*ox;	int out_pos,in_pos,in_begin,in_end,out_end;	unsigned skip=3*ix;	unsigned oskip=3*ox;	unsigned short *in, *out;	if (ix==ox){		*outa=ina;		return;	}	if (ix<ox){		enlarge_color_horizontal(ina,ix,y,outa,ox);		return;	}else if (ix==ox){		*outa=ina;		return;	}	if (ox && (unsigned)ox * (unsigned)y / (unsigned)ox != (unsigned)y) overalloc();	if ((unsigned)ox * (unsigned)y > MAXINT / 3 / sizeof(*out)) overalloc();	out=mem_alloc(sizeof(*out)*3*ox*y);	*outa=out;	in=ina;	if ((unsigned)y > MAXINT / 3 / sizeof(*col_buf)) overalloc();	col_buf=mem_alloc(y*3*sizeof(*col_buf));	bias_buf_color(col_buf,y,ix>>1);	out_pos=0;	in_pos=0;	again:	in_begin=in_pos;	in_end=in_pos+ox;	out_end=out_pos+ix;	if (in_begin<out_pos)in_begin=out_pos;	if (in_end>out_end)in_end=out_end;	add_col_color(col_buf,in,skip,y,in_end-in_begin);	in_end=in_pos+ox;	if (out_end>=in_end){		in_pos=in_end;		in+=3;	}	if (out_end<=in_end){			emit_and_bias_col_color(col_buf,out,oskip,y,ix);			out_pos=out_pos+ix;			out+=3;	}	if (out_pos==total) {		mem_free(ina);		mem_free(col_buf);		return;	}	goto again;}/* For magnification only. Does linear filtering. *//* We assume unsigned holds at least 32 bits */inline static void enlarge_gray_vertical(unsigned char *in, int x, int iy,	unsigned char ** out ,int oy){	unsigned *row_buf;	int total;	int out_pos,in_pos,in_begin,in_end;	int half=(oy-1)>>1;	unsigned char *outptr;	unsigned char *inptr;	if (iy==1){		if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc();		if ((unsigned)x * (unsigned)oy > MAXINT) overalloc();		outptr=mem_alloc(oy*x);		*out=outptr;		for(;oy;oy--,outptr+=x)			memcpy(outptr,in,x);		mem_free(in);	}	else if (iy==oy){		*out=in;

⌨️ 快捷键说明

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