6 #include "../guicast/linklist.h"
11 void fit(int *dat, int n, double &a, double &b);
13 void eq(unsigned char *dp, int len);
18 double mean(uint8_t *dat, int n)
21 for( int i=0; i<n; ++i ) s += *dat++;
25 double variance(uint8_t *dat, int n, double m=-1)
27 if( m < 0 ) m = mean(dat, n);
29 for( int i=0; i<n; ++i ) {
33 return (ss - s*s / n) / (n-1);
36 double std_dev(uint8_t *dat, int n, double m=-1)
38 return sqrt(variance(dat, n, m));
41 static inline int clip(int v, int mn, int mx)
43 return v<mn ? mn : v>mx ? mx : v;
47 fit(int *dat, int n, double &a, double &b)
49 double st2 = 0, sb = 0;
51 for( int i=0; i<n; ++i ) sy += dat[i];
52 double mx = (n-1)/2., my = (double)sy / n;
53 for( int i=0; i<n; ++i ) {
63 eq(uint8_t *dp, int len)
65 int hist[256], wts[256], map[256];
66 for( int i=0; i<256; ++i ) hist[i] = 0;
68 for( int i=len; --i>=0; ++bp ) ++hist[*bp];
70 for( int i=0; i<256; ++i ) { t += hist[i]; wts[i] = t; }
71 int lmn = len/20, lmx = len-lmn;
72 int mn = 0; while( mn < 256 && wts[mn] < lmn ) ++mn;
73 int mx = 255; while( mx > mn && wts[mx] > lmx ) --mx;
75 fit(&wts[mn], mx-mn, a, b);
77 double a1 = (a - b*mn) * r, b1 = b * r;
78 for( int i=0 ; i<256; ++i ) map[i] = clip(a1 + i*b1, 0, 255);
80 for( int i=len; --i>=0; ++bp ) *bp = map[*bp];
84 int main(int ac, char **av)
86 FILE *ifp = !strcmp(av[1],"-") ? stdin : fopen(av[1],"r");
87 FILE *ofp = !strcmp(av[2],"-") ? stdout : fopen(av[2],"w");
89 fgets(line,sizeof(line),ifp); fputs(line,ofp);
90 fgets(line,sizeof(line),ifp); fputs(line,ofp);
91 int w, h; if( sscanf(line,"%d %d\n",&w,&h) != 2 ) exit(1);
92 fgets(line,sizeof(line),ifp); fputs(line,ofp);
94 unsigned char data[len], *bp = data;
95 for( int ch, i=len; --i>=0 && (ch=getc(ifp)) >= 0; ++bp ) *bp = ch;
96 HistEq().eq(data,len);
98 for( int i=len; --i>=0; ++bp ) putc(*bp,ofp);
100 if( ifp != stdin ) fclose(ifp);
101 if( ofp != stdout ) fclose(ofp);