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

📄 dip.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
				*dest=rb;				dest[1]=gb;				dest[2]=bb;			}		}		dest+=3;	}}/* src is a block of four-bytes RGBA. All bytes are gamma corrected. length is * number of pixels. output is input powered to the given gamma, passed into * dest. src and dest may be identical and it will work. rb, gb, bb are 0-65535 * in linear monitor output photon space. alpha 255 means full image no background. * We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_and_undercolor_64_to_48_table(unsigned short *dest		,unsigned short *src, int lenght, unsigned short *gamma_table		,unsigned short rb, unsigned short gb, unsigned short bb){	unsigned alpha, calpha;	unsigned short ri,gi,bi;	for (;lenght;lenght--)	{		ri=gamma_table[*src];		gi=gamma_table[src[1]+65536];		bi=gamma_table[src[2]+131072];		alpha=src[3];		src+=4;		if (((alpha+1)&0xffff)>=2){			calpha=65535-alpha;			*dest=(ri*alpha+calpha*rb+32767)/65535;			dest[1]=(gi*alpha+calpha*gb+32767)/65535;			dest[2]=(bi*alpha+calpha*bb+32767)/65535;		}else{			if (alpha){				*dest=ri;				dest[1]=gi;				dest[2]=bi;			}else{				*dest=rb;				dest[1]=gb;				dest[2]=bb;			}		}		dest+=3;	}}/* src is a block of three-bytes. All bytes are gamma corrected. length is * number of triplets. output is input powered to the given gamma, passed into * dest. src and dest may be identical and it will work. * We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_48_to_48(unsigned short *dest,		unsigned short *src, int lenght, float red_gamma		,float green_gamma, float blue_gamma){	float a, inv_65535=1/((float)65535);	for (;lenght;lenght--,src+=3,dest+=3)	{		a=*src;		a*=inv_65535;		a=pow(a,red_gamma);		*dest=(a*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		if (*dest>=0x10000) *dest=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		a=src[1];		a*=inv_65535;		a=pow(a,green_gamma);		dest[1]=(a*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		if (dest[1]>=0x10000) dest[1]=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		a=src[2];		a*=inv_65535;		a=pow(a,blue_gamma);		dest[2]=(a*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		if (dest[2]>=0x10000) dest[2]=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */	}}/* src is a block of three-bytes. All bytes are gamma corrected. length is * number of triples. output is input powered to the given gamma, passed into * dest. src and dest may be identical and it will work. * We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_48_to_48_table(unsigned short *dest,		unsigned short *src, int lenght, unsigned short *table){	for (;lenght;lenght--,src+=3,dest+=3)	{		*dest=table[*src];		dest[1]=table[src[1]+65536];		dest[2]=table[src[2]+131072];	}}/* src is a block of three-bytes. All bytes are gamma corrected. length is * number of triples. output is input powered to the given gamma, passed into * dest. src and dest may be identical and it will work. * We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_24_to_48(unsigned short *dest, unsigned char *src, int			  lenght, float red_gamma, float green_gamma, float			  blue_gamma){	float a;	float inv_255=1/((float)255);		for (;lenght;lenght--,src+=3,dest+=3)	{		a=*src;		a*=inv_255;		a=pow(a,red_gamma);		*dest=(a*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		if (*dest>=0x10000) *dest=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		a=src[1];		a*=inv_255;		a=pow(a,green_gamma);		dest[1]=(a*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		if (dest[1]>=0x10000) dest[1]=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		a=src[2];		a*=inv_255;		a=pow(a,blue_gamma);		dest[2]=(a*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		if (dest[2]>=0x10000) dest[2]=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */	}}/* Allocates new gamma_table and fills it with mapping 8 bits -> * power to user_gamma/cimg->*_gamma -> 16 bits  * We assume unsigned short holds at least 16 bits. */void make_gamma_table(struct cached_image *cimg){	double rg=user_gamma/cimg->red_gamma;	double gg=user_gamma/cimg->green_gamma;	double bg=user_gamma/cimg->blue_gamma;	double inv;	int a;	unsigned short *ptr_16;	if (cimg->buffer_bytes_per_pixel<=4){		/* 8-bit */		inv=1/((double)255);		ptr_16=mem_alloc(768*sizeof(*(cimg->gamma_table)));		cimg->gamma_table=ptr_16;		for (a=0;a<256;a++,ptr_16++){			*ptr_16=65535*pow(((double)a)*inv,rg)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2		/* To test against crappy arithmetics */			if (*ptr_16>=0x10000) *ptr_16=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		}		for (a=0;a<256;a++,ptr_16++){			*ptr_16=65535*pow(((double)a)*inv,gg)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (*ptr_16>=0x10000) *ptr_16=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		}		for (a=0;a<256;a++,ptr_16++){			*ptr_16=65535*pow(((double)a)*inv,bg)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (*ptr_16>=0x10000) *ptr_16=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		}	}else{		/* 16-bit */		inv=1/((double)65535);		ptr_16=mem_alloc(196608*sizeof(*(cimg->gamma_table)));		cimg->gamma_table=ptr_16;		for (a=0;a<0x10000;a++,ptr_16++){			*ptr_16=65535*pow(((double)a)*inv,rg)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (*ptr_16>=0x10000) *ptr_16=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		}		for (a=0;a<0x10000;a++,ptr_16++){			*ptr_16=65535*pow(((double)a)*inv,gg)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (*ptr_16>=0x10000) *ptr_16=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		}		for (a=0;a<0x10000;a++,ptr_16++){			*ptr_16=65535*pow(((double)a)*inv,bg)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (*ptr_16>=0x10000) *ptr_16=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */		}	}}/* We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_24_to_48_table(unsigned short *dest, unsigned char *src, int			  lenght, unsigned short *table){	for (;lenght;lenght--,src+=3,dest+=3)	{		dest[0]=table[src[0]];		dest[1]=table[src[1]+256];		dest[2]=table[src[2]+512];	}}/* Input is 0-255 (8-bit). Output is 0-255 (8-bit)*/unsigned char apply_gamma_single_8_to_8(unsigned char input, float gamma){	return 255*pow(((float) input)/255,gamma)+0.5;}/* Input is 0-255 (8-bit). Output is 0-65535 (16-bit)*//* We assume unsigned short holds at least 16 bits. */unsigned short apply_gamma_single_8_to_16(unsigned char input, float gamma){	float a=input;	unsigned short retval;	a/=255;	a=pow(a,gamma);	a*=65535;	retval = a+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (retval>=0x10000) retval=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */	return retval;}/* Input is 0-65535 (16-bit). Output is 0-255 (8-bit)*//* We assume unsigned short holds at least 16 bits. */unsigned char apply_gamma_single_16_to_8(unsigned short input, float gamma){	return pow(((float)input)/65535,gamma)*255+0.5;}/* Input is 0-65535 (16-bit). Output is 0-255 (8-bit)*/unsigned short apply_gamma_single_16_to_16(unsigned short input, float gamma){	unsigned short retval;		retval = 65535*pow(((float)input)/65535,gamma)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2			if (retval>=0x10000) retval=0xffff;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */	return retval;}/* Points to the next unread byte from png data block */extern unsigned char font_data[];extern struct letter letter_data[];extern struct font font_table[];extern int n_fonts; /* Number of fonts. font number 0 is system_font (it's		     * images are in system_font/ directory) and is used		     * for special purpose.		     *//* Returns a pointer to a structure describing the letter found or NULL * if the letter is not found. Tries all possibilities in the style table * before returning NULL. */struct letter *find_stored_letter(int *style_table, int letter_number){	int first, last, half, diff, font_index, font_number;	for (font_index=n_fonts-1;font_index;font_index--)	{		font_number=*style_table++;		first=font_table[font_number].begin;		last=font_table[font_number].length+first-1;		while(first<=last){			half=(first+last)>>1;			diff=letter_data[half].code-letter_number;			if (diff>=0){				if (diff==0){					return letter_data+half;				}else{					/* Value in table is bigger */					last=half-1;				}			}else{				/* Value in the table is smaller */				first=half+1;			}		}	}		/* 0 is system font, 0 is blotch char. This must be present	 * or we segfault :) */#ifdef REPORT_UNKNOWN	fprintf(stderr,"letter 0x%04x not found\n",letter_number);#endif /* #ifdef REPORT_UNKNOWN */	return letter_data+font_table[0].begin;}void read_stored_data(png_structp png_ptr, png_bytep data, png_uint_32 length){	struct read_work *work;	work=png_get_io_ptr(png_ptr);	if (length>(png_uint_32)work->length) png_error(png_ptr,"Ran out of input data");	memcpy(data,work->pointer,length);	work->length-=length;	work->pointer+=length;}void my_png_warning(png_structp a, png_const_charp b){}void my_png_error(png_structp a, png_const_charp error_string){	error("Error when loading compiled-in font: %s.",error_string);}/* Loads width and height of the PNG (nothing is scaled). Style table is * already incremented. */inline static void load_metric(int *x, int *y, int char_number, int *style_table){	struct letter *l;	l=find_stored_letter(style_table,char_number);	if (!l){		*x=0;		*y=0;	}else{		*x=l->xsize;		*y=l->ysize;	}	return;}/* The data tha fall out of this function express this: 0 is paper. 255 is ink. 34 * is 34/255ink+(255-34)paper. No gamma is involved in this formula, as you can see. * The multiplications and additions take place in photon space. */static void load_char(unsigned char **dest, int *x, int *y, unsigned char *png_data, int png_length, struct style *style){	png_structp png_ptr;	png_infop info_ptr;	double gamma;	int y1,number_of_passes;	unsigned char **ptrs;	struct read_work work;	work.pointer = png_data;	work.length = png_length;		png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,			NULL, my_png_error, my_png_warning);	info_ptr=png_create_info_struct(png_ptr);	png_set_read_fn(png_ptr,&work,(png_rw_ptr)&read_stored_data);	png_read_info(png_ptr, info_ptr);	*x=png_get_image_width(png_ptr,info_ptr);	*y=png_get_image_height(png_ptr,info_ptr);	if (png_get_gAMA(png_ptr,info_ptr, &gamma))		png_set_gamma(png_ptr, 1.0, gamma);	else		png_set_gamma(png_ptr, 1.0, sRGB_gamma);	{		int bit_depth;		int color_type;		color_type=png_get_color_type(png_ptr, info_ptr);		bit_depth=png_get_bit_depth(png_ptr, info_ptr);		if (color_type==PNG_COLOR_TYPE_GRAY){			if (bit_depth<8){				 png_set_expand(png_ptr);			}			if (bit_depth==16){				 png_set_strip_16(png_ptr);			}		}		if (color_type==PNG_COLOR_TYPE_PALETTE){			png_set_expand(png_ptr);#ifdef HAVE_PNG_SET_RGB_TO_GRAY			png_set_rgb_to_gray(png_ptr,1,54.0*256,183.0*256);#else			goto end;#endif		}		if (color_type & PNG_COLOR_MASK_ALPHA){			png_set_strip_alpha(png_ptr);		}		if (color_type==PNG_COLOR_TYPE_RGB ||			color_type==PNG_COLOR_TYPE_RGB_ALPHA){#ifdef HAVE_PNG_SET_RGB_TO_GRAY			png_set_rgb_to_gray(png_ptr, 1, 54.0*256, 183.0*256);#else			goto end;#endif		}			}	/* If the depth is different from 8 bits/gray, make the libpng expand	 * it to 8 bit gray.	 */	number_of_passes=png_set_interlace_handling(png_ptr);	png_read_update_info(png_ptr,info_ptr);	if (*x && (unsigned)*x * (unsigned)*y / (unsigned)*x != (unsigned)*y) overalloc();	if ((unsigned)*x * (unsigned)*y > MAXINT) overalloc();	*dest=mem_alloc(*x*(*y));	if ((unsigned)*y > MAXINT / sizeof(*ptrs)) overalloc();	ptrs=mem_alloc(*y*sizeof(*ptrs));	for (y1=0;y1<*y;y1++) ptrs[y1]=*dest+*x*y1;	for (;number_of_passes;number_of_passes--){		png_read_rows(png_ptr, ptrs, NULL, *y);	}	png_read_end(png_ptr, NULL);	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);	mem_free(ptrs);	return;#ifndef HAVE_PNG_SET_RGB_TO_GRAY	end:	if (*x && (unsigned)*x * (unsigned)*y / (unsigned)*x != (unsigned)*y) overalloc();	if ((unsigned)*x * (unsigned)*y > MAXINT) overalloc();	*dest=mem_calloc(*x*(*y));	return;#endif}/* Like load_char, but we dictate the y. */static void load_scaled_char(void **dest, int *x, int y,unsigned char *png_data, int png_length, struct style *style){	unsigned char *interm;	unsigned char *interm2;	unsigned char *i2ptr,*dptr;	int ix, iy, y0, x0, c;	float conv0, conv1,sharpness,contrast;	load_char(&interm, &ix,&iy,png_data, png_length,style);	if (style->mono_space>=0)		*x=compute_width(style->mono_space, style->mono_height, y);	else		*x=compute_width(ix,iy,y);	if (display_optimize) *x*=3;	scale_gray(interm, ix,iy, (unsigned char **)dest, *x, y);	if (y>32||y<=0) return ; /* No convolution */	ix=*x+2; /* There is one-pixel border around */	iy=y+2;	if (ix && (unsigned)ix * (unsigned)iy / (unsigned)ix != (unsigned)iy) overalloc();	if ((unsigned)ix * (unsigned)iy > MAXINT) overalloc();	interm2=mem_alloc(ix*iy);	i2ptr=interm2+ix+1;	dptr=*dest;	memset(interm2,0,ix);	memset(interm2+(iy-1)*ix,0,ix);	for (y0=y;y0;y0--){		i2ptr[-1]=0;		memcpy(i2ptr,dptr,*x);		i2ptr[ix-1]=0;		i2ptr+=ix;		dptr+=*x;	}	i2ptr=interm2+ix+1;	dptr=*dest;	/* Determine the sharpness and contrast */	sharpness=fancy_constants[2*y-2];	contrast=fancy_constants[2*y-1];	/* Compute the matrix constants from contrast and sharpness */	conv0=(1+sharpness)*contrast;	conv1=-sharpness*0.25*contrast;		for (y0=y;y0;y0--){		for (x0=*x;x0;x0--){			/* Convolution */			c=((*i2ptr)*conv0)+i2ptr[-ix]*conv1+i2ptr[-1]*conv1+i2ptr[1]*conv1+i2ptr[ix]*conv1+0.5;			if (((unsigned)c)>=256) c=c<0?0:255;			*dptr=c;			dptr++;			i2ptr++;		}		i2ptr+=2;	}	mem_free(interm2);}/* Adds required entry into font_cache and returns pointer to the entry. * We assume the entry is FC_COLOR. */struct font_cache_entry *supply_color_cache_entry (struct graphics_driver*gd, struct style *style, struct letter *letter){	struct font_cache_entry *found, *new;	unsigned short *primary_data;	int do_free=0;	struct font_cache_entry template;	unsigned short red, green, blue;	unsigned bytes_consumed;	template.bitmap.y=style->height;	template.type=FC_BW;	/* The BW entries will be added only for background images which	 * are not yet implemented, but will be in the future.	 */	found=lru_lookup(&font_cache, &template, letter->bw_list);	if (!found){		found=mem_alloc(sizeof(*found));		found->bitmap.y=style->height;		load_scaled_char(&(found->bitmap.data),&(found->bitmap.x),			found->bitmap.y, font_data+letter->begin,			letter->length, style);		do_free=1;	}	new=mem_alloc(sizeof(*new));	new->type=FC_COLOR;	new->bitmap=found->bitmap;	new->r0=style->r0;	new->g0=style->g0;	new->b0=style->b0;	new->r1=style->r1;	new->g1=style->g1;	new->b1=style->b1;	new->mono_space=style->mono_space;	new->mono_height=style->mono_height;	if (new->bitmap.x && (unsigned)new->bitmap.x * (unsigned)new->bitmap.y / (unsigned)new->bitmap.x != (unsigned)new->bitmap.y) overalloc();	if ((unsigned)new->bitmap.x * (unsigned)new->bitmap.y > MAXINT / 3 / sizeof(*primary_data)) overalloc();	primary_data=mem_alloc(3			*new->bitmap.x*new->bitmap.y*sizeof(*primary_data));	/* We assume the gamma of HTML styles is in sRGB space */	round_color_sRGB_to_48(&red, &green, &blue,		((style->r0)<<16)|((style->g0)<<8)|(style->b0));	mix_two_colors(primary_data, found->bitmap.data,		found->bitmap.x*found->bitmap.y,		red,green,blue,

⌨️ 快捷键说明

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