Mercurial > geeqie
comparison src/histogram.c @ 290:4bbde8a38ad4
improved histogram drawing
author | nadvornik |
---|---|
date | Wed, 09 Apr 2008 20:49:32 +0000 |
parents | fd5c62403498 |
children | 4b2d7f9af171 |
comparison
equal
deleted
inserted
replaced
289:6a7298988a7a | 290:4bbde8a38ad4 |
---|---|
19 /* | 19 /* |
20 *---------------------------------------------------------------------------- | 20 *---------------------------------------------------------------------------- |
21 * image histogram | 21 * image histogram |
22 *---------------------------------------------------------------------------- | 22 *---------------------------------------------------------------------------- |
23 */ | 23 */ |
24 | |
25 #define HISTOGRAM_SIZE 256 | |
26 | |
27 struct _Histogram { | |
28 gulong histmap[HISTOGRAM_SIZE*4]; | |
29 gint histogram_chan; | |
30 gint histogram_logmode; | |
31 }; | |
24 | 32 |
25 | 33 |
26 Histogram *histogram_new() | 34 Histogram *histogram_new() |
27 { | 35 { |
28 Histogram *histogram; | 36 Histogram *histogram; |
103 h = gdk_pixbuf_get_height(imgpixbuf); | 111 h = gdk_pixbuf_get_height(imgpixbuf); |
104 srs = gdk_pixbuf_get_rowstride(imgpixbuf); | 112 srs = gdk_pixbuf_get_rowstride(imgpixbuf); |
105 s_pix = gdk_pixbuf_get_pixels(imgpixbuf); | 113 s_pix = gdk_pixbuf_get_pixels(imgpixbuf); |
106 has_alpha = gdk_pixbuf_get_has_alpha(imgpixbuf); | 114 has_alpha = gdk_pixbuf_get_has_alpha(imgpixbuf); |
107 | 115 |
108 for (i = 0; i < 256*4; i++) histogram->histmap[i] = 0; | 116 for (i = 0; i < HISTOGRAM_SIZE*4; i++) histogram->histmap[i] = 0; |
109 | 117 |
110 for (i = 0; i < h; i++) | 118 for (i = 0; i < h; i++) |
111 { | 119 { |
112 guchar *sp = s_pix + (i * srs); /* 8bit */ | 120 guchar *sp = s_pix + (i * srs); /* 8bit */ |
113 for (j = 0; j < w; j++) | 121 for (j = 0; j < w; j++) |
114 { | 122 { |
115 histogram->histmap[sp[0]+0]++; | 123 histogram->histmap[sp[0] + 0 * HISTOGRAM_SIZE]++; |
116 histogram->histmap[sp[1]+256]++; | 124 histogram->histmap[sp[1] + 1 * HISTOGRAM_SIZE]++; |
117 histogram->histmap[sp[2]+512]++; | 125 histogram->histmap[sp[2] + 2 * HISTOGRAM_SIZE]++; |
118 if (histogram->histogram_chan == HCHAN_MAX) | 126 if (histogram->histogram_chan == HCHAN_MAX) |
119 { | 127 { |
120 guchar t = sp[0]; | 128 guchar t = sp[0]; |
121 if (sp[1]>t) t = sp[1]; | 129 if (sp[1]>t) t = sp[1]; |
122 if (sp[2]>t) t = sp[2]; | 130 if (sp[2]>t) t = sp[2]; |
123 histogram->histmap[t+768]++; | 131 histogram->histmap[t + 3 * HISTOGRAM_SIZE]++; |
124 } | 132 } |
125 else | 133 else |
126 histogram->histmap[768+(sp[0]+sp[1]+sp[2])/3]++; | 134 histogram->histmap[3 * HISTOGRAM_SIZE + (sp[0]+sp[1]+sp[2])/3]++; |
127 sp += 3; | 135 sp += 3; |
128 if (has_alpha) sp++; | 136 if (has_alpha) sp++; |
129 } | 137 } |
130 } | 138 } |
131 | 139 |
156 } | 164 } |
157 if (flag && histogram->histmap[i] > max) max = histogram->histmap[i]; | 165 if (flag && histogram->histmap[i] > max) max = histogram->histmap[i]; |
158 } | 166 } |
159 | 167 |
160 logmax = log(max); | 168 logmax = log(max); |
161 for (i=0; i<256; i++) | 169 for (i=0; i<width; i++) |
162 { | 170 { |
163 gint j; | 171 gint j; |
164 glong v[4]; | 172 glong v[4] = {0, 0, 0, 0}; |
165 gint rplus = 0; | 173 gint rplus = 0; |
166 gint gplus = 0; | 174 gint gplus = 0; |
167 gint bplus = 0; | 175 gint bplus = 0; |
168 | 176 gint ii = i * HISTOGRAM_SIZE / width; |
169 v[0] = histogram->histmap[i+0*256]; // r | 177 gint combine = (HISTOGRAM_SIZE - 1) / width + 1; |
170 v[1] = histogram->histmap[i+1*256]; // g | 178 |
171 v[2] = histogram->histmap[i+2*256]; // b | 179 for (j = 0; j < combine; j++) |
172 v[3] = histogram->histmap[i+3*256]; // value, max | 180 { |
181 v[0] += histogram->histmap[ii + j + 0*HISTOGRAM_SIZE]; // r | |
182 v[1] += histogram->histmap[ii + j + 1*HISTOGRAM_SIZE]; // g | |
183 v[2] += histogram->histmap[ii + j + 2*HISTOGRAM_SIZE]; // b | |
184 v[3] += histogram->histmap[ii + j + 3*HISTOGRAM_SIZE]; // value, max | |
185 } | |
173 | 186 |
174 for (j=0; j<4; j++) | 187 for (j=0; j<4; j++) |
175 { | 188 { |
176 gint r = rplus; | 189 gint r = rplus; |
177 gint g = gplus; | 190 gint g = gplus; |
207 } | 220 } |
208 | 221 |
209 if (v[max2] == 0) | 222 if (v[max2] == 0) |
210 pt = 0; | 223 pt = 0; |
211 else if (histogram->histogram_logmode) | 224 else if (histogram->histogram_logmode) |
212 pt = ((float)log(v[max2]))/logmax*255; | 225 pt = ((float)log(v[max2])) / logmax * (height - 1); |
213 else | 226 else |
214 pt = ((float)v[max2])/max*255; | 227 pt = ((float)v[max2])/ max * (height - 1); |
215 if (histogram->histogram_chan >= HCHAN_RGB | 228 if (histogram->histogram_chan >= HCHAN_RGB |
216 || max2 == histogram->histogram_chan) | 229 || max2 == histogram->histogram_chan) |
217 pixbuf_draw_line(pixbuf, | 230 pixbuf_draw_line(pixbuf, |
218 0+5, height-255, 256, 256, | 231 x, y, width, height, |
219 i+5, height, i+5, height-pt, | 232 x + i, y + height, x + i, y + height-pt, |
220 r, g, b, 255); | 233 r, g, b, 255); |
221 v[max2] = -1; | 234 v[max2] = -1; |
222 } | 235 } |
223 } | 236 } |
224 return TRUE; | 237 return TRUE; |