📄 dip.c
字号:
}else{ if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); if ((unsigned)x * (unsigned)oy > MAXINT) overalloc(); outptr=mem_alloc(oy*x); inptr=in; *out=outptr; total=(iy-1)*(oy-1); if ((unsigned)x > MAXINT / sizeof(*row_buf)) overalloc(); row_buf=mem_alloc(x*sizeof(*row_buf)); bias_buf_gray(row_buf, x, half); out_pos=0; in_pos=0; again: in_begin=in_pos; in_end=in_pos+oy-1; add_row_gray(row_buf, inptr, x, in_end-out_pos); add_row_gray(row_buf, inptr+x, x, out_pos-in_begin); emit_and_bias_row_gray(row_buf, outptr, x, oy-1); outptr+=x; out_pos+=iy-1; if (out_pos>in_end){ in_pos=in_end; inptr+=x; } if (out_pos>total){ mem_free(in); mem_free(row_buf); return; } goto again; } }/* For magnification only. Does linear filtering *//* We assume unsigned holds at least 32 bits */inline static void enlarge_color_vertical(unsigned short *ina, int x, int iy, unsigned short **outa ,int oy){ unsigned *row_buf; int total,out_pos,in_pos,in_begin,in_end; int half=(oy-1)>>1; unsigned short *out, *in; if (iy==oy){ *outa=ina; return; } /* Rivendell */ if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); if ((unsigned)x * (unsigned)oy > MAXINT / 3 / sizeof(*out)) overalloc(); out=mem_alloc(sizeof(*out)*3*oy*x); *outa=out; in=ina; if (iy==1){ for (;oy;oy--){ memcpy(out,in,3*x*sizeof(*out)); out+=3*x; } mem_free(ina); return; } total=(iy-1)*(oy-1); if ((unsigned)x > MAXINT / 3 / sizeof(*row_buf)) overalloc(); row_buf=mem_alloc(x*3*sizeof(*row_buf)); bias_buf_color(row_buf,x,half); out_pos=0; in_pos=0; again: in_begin=in_pos; in_end=in_pos+oy-1; add_row_color(row_buf,in,x ,in_end-out_pos); add_row_color(row_buf,in+3*x,x ,out_pos-in_begin); emit_and_bias_row_color(row_buf,out,x,oy-1); out+=3*x; out_pos+=iy-1; if (out_pos>in_end){ in_pos=in_end; in+=3*x; } if (out_pos>total){ mem_free(ina); mem_free(row_buf); return; } goto again; } /* Both enlarges and diminishes. Linear filtering. * Automatically allocates output and frees input. * We assume unsigned holds at least 32 bits */inline static void scale_gray_vertical(unsigned char *in, int x, int iy, unsigned char ** out ,int oy){ unsigned *row_buf; int total=iy*oy; int out_pos,in_pos,in_begin,in_end,out_end; unsigned char *outptr; unsigned char *inptr; /* Snow White, Snow White... */ if (iy<oy){ enlarge_gray_vertical(in,x,iy,out,oy); return; } if (iy==oy){ *out=in; return; } if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); if ((unsigned)x * (unsigned)oy > MAXINT) overalloc(); outptr=mem_alloc(x*oy); inptr=in; *out=outptr; if ((unsigned)x > MAXINT / sizeof(*row_buf)) overalloc(); row_buf=mem_calloc(x*sizeof(*row_buf)); bias_buf_gray(row_buf, x, iy>>1); out_pos=0; in_pos=0; again: in_begin=in_pos; in_end=in_pos+oy; out_end=out_pos+iy; if (in_begin<out_pos)in_begin=out_pos; if (in_end>out_end)in_end=out_end; add_row_gray(row_buf,inptr,x,in_end-in_begin); in_end=in_pos+oy; if (out_end>=in_end){ in_pos=in_end; inptr+=x; } if (out_end<=in_end){ emit_and_bias_row_gray(row_buf,outptr,x,iy); out_pos=out_pos+iy; outptr+=x; } if (out_pos==total){ mem_free(in); mem_free(row_buf); return; } goto again;}/* Both enlarges and diminishes. Linear filtering. Sizes are in pixels. Sizes are not in bytes. 1 pixel=3 unsigned shorts. We assume unsigned short can hold at least 16 bits. We assume unsigned holds at least 32 bits. */inline static void scale_color_vertical(unsigned short *ina, int x, int iy ,unsigned short **outa, int oy){ unsigned *row_buf; int total=iy*oy; int out_pos,in_pos,in_begin,in_end,out_end; unsigned short *in, *out; if (iy==oy){ *outa=ina; return; } if (iy<oy){ enlarge_color_vertical(ina,x,iy,outa,oy); return; } if (x && (unsigned)x * (unsigned)oy / (unsigned)x != (unsigned)oy) overalloc(); if ((unsigned)x * (unsigned)oy > MAXINT / 3 / sizeof(*out)) overalloc(); out=mem_alloc(sizeof(*out)*3*oy*x); *outa=out; in=ina; if ((unsigned)x > MAXINT / 3 / sizeof(*row_buf)) overalloc(); row_buf=mem_alloc(x*3*sizeof(*row_buf)); bias_buf_color(row_buf,x,iy>>1); out_pos=0; in_pos=0; again: in_begin=in_pos; in_end=in_pos+oy; out_end=out_pos+iy; if (in_begin<out_pos)in_begin=out_pos; if (in_end>out_end)in_end=out_end; add_row_color(row_buf,in,x,in_end-in_begin); in_end=in_pos+oy; if (out_end>=in_end){ in_pos=in_end; in+=3*x; } if (out_end<=in_end){ emit_and_bias_row_color(row_buf,out,x,iy); out_pos=out_pos+iy; out+=3*x; } if (out_pos==total){ mem_free(ina); mem_free(row_buf); return; } goto again;}/* Scales grayscale 8-bit map. Both enlarges and diminishes. Uses either low * pass or bilinear filtering. Automatically mem_frees the "in". * Automatically allocates "out". */inline static void scale_gray(unsigned char *in, int ix, int iy, unsigned char **out ,int ox, int oy){ unsigned char *intermediate_buffer; if (!ix||!iy){ if (in) mem_free(in); if (ox && (unsigned)ox * (unsigned)oy / (unsigned)ox != (unsigned)oy) overalloc(); if ((unsigned)ox * (unsigned)oy > MAXINT) overalloc(); *out=mem_calloc(ox*oy); return; } if (ix*oy<ox*iy){ scale_gray_vertical(in,ix,iy,&intermediate_buffer,oy); scale_gray_horizontal(intermediate_buffer,ix,oy,out,ox); }else{ scale_gray_horizontal(in,ix,iy,&intermediate_buffer,ox); scale_gray_vertical(intermediate_buffer,ox,iy,out,oy); }}/* To be called only when global variable display_optimize is 1 or 2. * Performs a decimation according to this variable. Data shrink to 1/3 * and x is the smaller width. * There must be 9*x*y unsigned shorts of data. * x must be >=1. * Performs realloc onto the buffer after decimation to save memory. */void decimate_3(unsigned short **data0, int x, int y){ unsigned short *data=*data0; unsigned short *ahead=data; int i, futuresize; if (x && (unsigned)x * (unsigned)y / (unsigned)x != (unsigned)y) overalloc(); if ((unsigned)x * (unsigned)y > MAXINT / 3 / sizeof(**data0)) overalloc(); futuresize=x*y*3*sizeof(**data0); #ifdef DEBUG if (!(x>0&&y>0)) internal("zero width or height in decimate_3");#endif /* #Ifdef DEBUG */ if (display_optimize==1){ if (x==1){ for (;y;y--,ahead+=9,data+=3){ data[0]=(ahead[0]+ahead[0]+ahead[3])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[5]+ahead[8]+ahead[8])/3; } }else{ for (;y;y--){ data[0]=(ahead[0]+ahead[0]+ahead[3])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[5]+ahead[8]+ahead[11])/3; for (ahead+=9,data+=3,i=x-2;i;i--,ahead+=9,data+=3){ data[0]=(ahead[-3]+ahead[0]+ahead[3])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[5]+ahead[8]+ahead[11])/3; } data[0]=(ahead[-3]+ahead[0]+ahead[3])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[5]+ahead[8]+ahead[8])/3; ahead+=9,data+=3; } } }else{ /* display_optimize==2 */ if (x==1){ for (;y;y--,ahead+=9,data+=3){ data[0]=(ahead[3]+ahead[6]+ahead[6])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[2]+ahead[2]+ahead[5])/3; } }else{ for (;y;y--){ data[0]=(ahead[3]+ahead[6]+ahead[9])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[2]+ahead[2]+ahead[5])/3; for (ahead+=9,data+=3,i=x-2;i;i--,ahead+=9,data+=3){ data[0]=(ahead[3]+ahead[6]+ahead[9])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[-1]+ahead[2]+ahead[5])/3; } data[0]=(ahead[3]+ahead[6]+ahead[6])/3; data[1]=(ahead[1]+ahead[4]+ahead[7])/3; data[2]=(ahead[-1]+ahead[2]+ahead[5])/3; ahead+=9,data+=3; } } } *data0=mem_realloc(*data0,futuresize);}/* Scales color 48-bits-per-pixel bitmap. Both enlarges and diminishes. Uses * either low pass or bilinear filtering. The memory organization for both * input and output are red, green, blue. All three of them are unsigned shorts 0-65535. * Allocates output and frees input * We assume unsigned short holds at least 16 bits. */void scale_color(unsigned short *in, int ix, int iy, unsigned short **out, int ox, int oy){ unsigned short *intermediate_buffer; int do_optimize; int ox0=ox; if (!ix||!iy){ if (in) mem_free(in); if (ox && (unsigned)ox * (unsigned)oy / (unsigned)ox != (unsigned)oy) overalloc(); if ((unsigned)ox * (unsigned)oy > MAXINT / 3 / sizeof(**out)) overalloc(); *out=mem_calloc(ox*oy*sizeof(**out)*3); return; } if (display_optimize&&ox*3<=ix){ do_optimize=1; ox0=ox; ox*=3; }else do_optimize=0; if (ix*oy<ox*iy){ scale_color_vertical(in,ix,iy,&intermediate_buffer,oy); scale_color_horizontal(intermediate_buffer,ix,oy,out,ox); }else{ scale_color_horizontal(in,ix,iy,&intermediate_buffer,ox); scale_color_vertical(intermediate_buffer,ox,iy,out,oy); } if (do_optimize) decimate_3(out, ox0, oy);}/* Fills a block with given color. length is number of pixels. pixel is a * tribyte. 24 bits per pixel. */void mix_one_color_24(unsigned char *dest, int length, unsigned char r, unsigned char g, unsigned char b){ for (;length;length--){ dest[0]=r; dest[1]=g; dest[2]=b; dest+=3; }}/* Fills a block with given color. length is number of pixels. pixel is a * tribyte. 48 bits per pixel. * We assume unsigned short holds at least 16 bits. */void mix_one_color_48(unsigned short *dest, int length, unsigned short r, unsigned short g, unsigned short b){ for (;length;length--){ dest[0]=r; dest[1]=g; dest[2]=b; dest+=3; }}/* Mixes ink and paper of a letter, using alpha as alpha mask. * Only mixing in photon space makes physical sense so that the input values * must always be equivalent to photons and not to electrons! * length is number of pixels. pixel is a tribyte * alpha is 8-bit, rgb are all 16-bit * We assume unsigned short holds at least 16 bits. */inline static void mix_two_colors(unsigned short *dest, unsigned char *alpha, int length ,unsigned short r0, unsigned short g0, unsigned short b0, unsigned short r255, unsigned short g255, unsigned short b255){ unsigned mask,cmask; for (;length;length--){ mask=*alpha++; if (((unsigned char)(mask+1))>=2){ cmask=255-mask; dest[0]=(mask*r255+cmask*r0+127)/255; dest[1]=(mask*g255+cmask*g0+127)/255; dest[2]=(mask*b255+cmask*b0+127)/255; }else{ if (mask){ dest[0]=r255; dest[1]=g255; dest[2]=b255; }else{ dest[0]=r0; dest[1]=g0; dest[2]=b0; } } dest+=3; }}/* We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_and_undercolor_32_to_48_table(unsigned short *dest, unsigned char *src, int lenght, unsigned short *table ,unsigned short rb, unsigned short gb, unsigned short bb){ unsigned alpha, ri, gi, bi, calpha; for (;lenght;lenght--) { ri=table[src[0]]; gi=table[src[1]+256]; bi=table[src[2]+512]; alpha=src[3]; src+=4; if (((unsigned char)(alpha+1))>=2){ calpha=255U-alpha; dest[0]=(ri*alpha+calpha*rb+127)/255; dest[1]=(gi*alpha+calpha*gb+127)/255; dest[2]=(bi*alpha+calpha*bb+127)/255; }else{ if (alpha){ dest[0]=ri; dest[1]=gi; dest[2]=bi; }else{ dest[0]=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 *//* We assume unsigned short holds at least 16 bits. */void apply_gamma_exponent_and_undercolor_32_to_48(unsigned short *dest, unsigned char *src, int lenght, float red_gamma ,float green_gamma, float blue_gamma, unsigned short rb, unsigned short gb, unsigned short bb){ float r,g,b; unsigned alpha, calpha; unsigned ri,gi,bi; const float inv_255=1/255.0; for (;lenght;lenght--) { r=src[0]; g=src[1]; b=src[2]; alpha=src[3]; src+=4; r*=inv_255; g*=inv_255; b*=inv_255; r=pow(r,red_gamma); g=pow(g,green_gamma); b=pow(b,blue_gamma); ri=(r*65535)+0.5; gi=(g*65535)+0.5; bi=(b*65535)+0.5;#if SIZEOF_UNSIGNED_SHORT > 2 /* To prevent segfaults in case of crappy floating arithmetics */ if (ri>=65536) ri=65535; if (gi>=65536) gi=65535; if (bi>=65536) bi=65535;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */ if (((alpha+1U)&0xffU)>=2U){ calpha=255U-alpha; *dest=(ri*alpha+calpha*rb+127U)/255U; dest[1]=(gi*alpha+calpha*gb+127U)/255U; dest[2]=(bi*alpha+calpha*bb+127U)/255U; }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 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(unsigned short *dest, unsigned short *src, int lenght, float red_gamma ,float green_gamma, float blue_gamma, unsigned short rb, unsigned short gb, unsigned short bb){ float r,g,b; unsigned alpha, calpha; unsigned short ri,gi,bi; const float inv_65535=1/((float)65535); for (;lenght;lenght--) { r=src[0]; g=src[1]; b=src[2]; alpha=src[3]; src+=4; r*=inv_65535; g*=inv_65535; b*=inv_65535; r=pow(r,red_gamma); g=pow(g,green_gamma); b=pow(b,blue_gamma); ri=r*65535+0.5; gi=g*65535+0.5; bi=b*65535+0.5;#if SIZEOF_UNSIGNED_SHORT > 2 /* To prevent segfaults in case of crappy floating arithmetics */ if (ri>=65536) ri=65535; if (gi>=65536) gi=65535; if (bi>=65536) bi=65535;#endif /* #if SIZEOF_UNSIGNED_SHORT > 2 */ if (((alpha+1U)&255U)>=2U){ calpha=65535U-alpha; *dest=(ri*alpha+calpha*rb+32767U)/65535U; dest[1]=(gi*alpha+calpha*gb+32767U)/65535U; dest[2]=(bi*alpha+calpha*bb+32767U)/65535U; }else{ if (alpha){ *dest=ri; dest[1]=gi; dest[2]=bi; }else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -