Mercurial > geeqie.yaz
comparison src/histogram.c @ 1310:ef05743535e3
Fix and simplify histogram code, drop histogram based on mean value.
author | zas_ |
---|---|
date | Sun, 22 Feb 2009 17:40:32 +0000 |
parents | 2320339ca8be |
children | fcf0e7a6143e |
comparison
equal
deleted
inserted
replaced
1309:55ea4962887a | 1310:ef05743535e3 |
---|---|
27 | 27 |
28 struct _HistMap { | 28 struct _HistMap { |
29 gulong r[HISTMAP_SIZE]; | 29 gulong r[HISTMAP_SIZE]; |
30 gulong g[HISTMAP_SIZE]; | 30 gulong g[HISTMAP_SIZE]; |
31 gulong b[HISTMAP_SIZE]; | 31 gulong b[HISTMAP_SIZE]; |
32 gulong avg[HISTMAP_SIZE]; | |
33 gulong max[HISTMAP_SIZE]; | 32 gulong max[HISTMAP_SIZE]; |
34 }; | 33 }; |
35 | 34 |
36 struct _Histogram { | 35 struct _Histogram { |
37 gint channel_mode; /* drawing mode for histogram */ | 36 gint channel_mode; /* drawing mode for histogram */ |
108 switch (histogram->channel_mode) | 107 switch (histogram->channel_mode) |
109 { | 108 { |
110 case HCHAN_R: t1 = _("logarithmical histogram on red"); break; | 109 case HCHAN_R: t1 = _("logarithmical histogram on red"); break; |
111 case HCHAN_G: t1 = _("logarithmical histogram on green"); break; | 110 case HCHAN_G: t1 = _("logarithmical histogram on green"); break; |
112 case HCHAN_B: t1 = _("logarithmical histogram on blue"); break; | 111 case HCHAN_B: t1 = _("logarithmical histogram on blue"); break; |
113 case HCHAN_VAL: t1 = _("logarithmical histogram on value"); break; | |
114 case HCHAN_RGB: t1 = _("logarithmical histogram on RGB"); break; | 112 case HCHAN_RGB: t1 = _("logarithmical histogram on RGB"); break; |
115 case HCHAN_MAX: t1 = _("logarithmical histogram on max value"); break; | 113 case HCHAN_MAX: t1 = _("logarithmical histogram on max value"); break; |
116 } | 114 } |
117 else | 115 else |
118 switch (histogram->channel_mode) | 116 switch (histogram->channel_mode) |
119 { | 117 { |
120 case HCHAN_R: t1 = _("linear histogram on red"); break; | 118 case HCHAN_R: t1 = _("linear histogram on red"); break; |
121 case HCHAN_G: t1 = _("linear histogram on green"); break; | 119 case HCHAN_G: t1 = _("linear histogram on green"); break; |
122 case HCHAN_B: t1 = _("linear histogram on blue"); break; | 120 case HCHAN_B: t1 = _("linear histogram on blue"); break; |
123 case HCHAN_VAL: t1 = _("linear histogram on value"); break; | |
124 case HCHAN_RGB: t1 = _("linear histogram on RGB"); break; | 121 case HCHAN_RGB: t1 = _("linear histogram on RGB"); break; |
125 case HCHAN_MAX: t1 = _("linear histogram on max value"); break; | 122 case HCHAN_MAX: t1 = _("linear histogram on max value"); break; |
126 } | 123 } |
127 return t1; | 124 return t1; |
128 } | 125 } |
129 | 126 |
130 static HistMap *histmap_read(GdkPixbuf *imgpixbuf) | 127 static HistMap *histmap_read(GdkPixbuf *imgpixbuf) |
131 { | 128 { |
132 gint w, h, i, j, srs, has_alpha, step; | 129 gint w, h, i, j, srs, has_alpha, step; |
133 guchar *s_pix; | 130 guchar *s_pix; |
134 | |
135 HistMap *histmap; | 131 HistMap *histmap; |
136 | 132 |
137 w = gdk_pixbuf_get_width(imgpixbuf); | 133 w = gdk_pixbuf_get_width(imgpixbuf); |
138 h = gdk_pixbuf_get_height(imgpixbuf); | 134 h = gdk_pixbuf_get_height(imgpixbuf); |
139 srs = gdk_pixbuf_get_rowstride(imgpixbuf); | 135 srs = gdk_pixbuf_get_rowstride(imgpixbuf); |
146 for (i = 0; i < h; i++) | 142 for (i = 0; i < h; i++) |
147 { | 143 { |
148 guchar *sp = s_pix + (i * srs); /* 8bit */ | 144 guchar *sp = s_pix + (i * srs); /* 8bit */ |
149 for (j = 0; j < w; j++) | 145 for (j = 0; j < w; j++) |
150 { | 146 { |
151 guint avg = (sp[0] + sp[1] + sp[2]) / 3; | |
152 guint max = sp[0]; | 147 guint max = sp[0]; |
153 if (sp[1] > max) max = sp[1]; | 148 if (sp[1] > max) max = sp[1]; |
154 if (sp[2] > max) max = sp[2]; | 149 if (sp[2] > max) max = sp[2]; |
155 | 150 |
156 histmap->r[sp[0]]++; | 151 histmap->r[sp[0]]++; |
157 histmap->g[sp[1]]++; | 152 histmap->g[sp[1]]++; |
158 histmap->b[sp[2]]++; | 153 histmap->b[sp[2]]++; |
159 histmap->avg[avg]++; | |
160 histmap->max[max]++; | 154 histmap->max[max]++; |
161 | 155 |
162 sp += step; | 156 sp += step; |
163 } | 157 } |
164 } | 158 } |
165 | 159 |
166 return histmap; | 160 return histmap; |
168 | 162 |
169 const HistMap *histmap_get(FileData *fd) | 163 const HistMap *histmap_get(FileData *fd) |
170 { | 164 { |
171 if (fd->histmap) return fd->histmap; | 165 if (fd->histmap) return fd->histmap; |
172 | 166 |
173 if (fd->pixbuf) | 167 if (fd->pixbuf) |
174 { | 168 { |
175 fd->histmap = histmap_read(fd->pixbuf); | 169 fd->histmap = histmap_read(fd->pixbuf); |
176 return fd->histmap; | 170 return fd->histmap; |
177 } | 171 } |
178 return NULL; | 172 return NULL; |
226 gint i; | 220 gint i; |
227 gulong max = 0; | 221 gulong max = 0; |
228 gdouble logmax; | 222 gdouble logmax; |
229 gint combine = (HISTMAP_SIZE - 1) / width + 1; | 223 gint combine = (HISTMAP_SIZE - 1) / width + 1; |
230 gint ypos = y + height; | 224 gint ypos = y + height; |
231 | 225 |
232 if (!histogram || !histmap) return 0; | 226 if (!histogram || !histmap) return 0; |
233 | 227 |
234 /* Draw the grid */ | 228 /* Draw the grid */ |
235 histogram_vgrid(histogram, pixbuf, x, y, width, height); | 229 histogram_vgrid(histogram, pixbuf, x, y, width, height); |
236 histogram_hgrid(histogram, pixbuf, x, y, width, height); | 230 histogram_hgrid(histogram, pixbuf, x, y, width, height); |
237 | 231 |
238 switch (histogram->channel_mode) | 232 for (i = 0; i < HISTMAP_SIZE; i++) |
239 { | 233 { |
240 case HCHAN_VAL: | 234 if (histmap->r[i] > max) max = histmap->r[i]; |
241 case HCHAN_MAX: | 235 if (histmap->g[i] > max) max = histmap->g[i]; |
242 case HCHAN_RGB: | 236 if (histmap->b[i] > max) max = histmap->b[i]; |
243 for (i = 0; i < HISTMAP_SIZE; i++) | 237 } |
244 { | 238 |
245 if (histmap->r[i] > max) max = histmap->r[i]; | 239 if (max > 0) |
246 if (histmap->g[i] > max) max = histmap->g[i]; | 240 logmax = log(max); |
247 if (histmap->b[i] > max) max = histmap->b[i]; | 241 else |
248 } | 242 logmax = 1.0; |
249 break; | 243 |
250 case HCHAN_R: for (i = 0; i < HISTMAP_SIZE; i++) if (histmap->r[i] > max) max = histmap->r[i]; break; | |
251 case HCHAN_G: for (i = 0; i < HISTMAP_SIZE; i++) if (histmap->g[i] > max) max = histmap->g[i]; break; | |
252 case HCHAN_B: for (i = 0; i < HISTMAP_SIZE; i++) if (histmap->b[i] > max) max = histmap->b[i]; break; | |
253 } | |
254 | |
255 logmax = log(max); | |
256 for (i = 0; i < width; i++) | 244 for (i = 0; i < width; i++) |
257 { | 245 { |
258 gint j; | 246 gint j; |
259 glong v[4] = {0, 0, 0, 0}; | 247 glong v[4] = {0, 0, 0, 0}; |
260 gint rplus = 0; | 248 gint rplus = 0; |
267 { | 255 { |
268 guint p = ii + j; | 256 guint p = ii + j; |
269 v[0] += histmap->r[p]; | 257 v[0] += histmap->r[p]; |
270 v[1] += histmap->g[p]; | 258 v[1] += histmap->g[p]; |
271 v[2] += histmap->b[p]; | 259 v[2] += histmap->b[p]; |
272 if (histogram->channel_mode == HCHAN_VAL) | 260 v[3] += histmap->max[p]; |
273 { | 261 } |
274 v[3] += histmap->avg[p]; | 262 |
275 } | 263 for (j = 0; combine > 1 && j < 4; j++) |
276 else | 264 v[j] /= combine; |
277 { | 265 |
278 v[3] += histmap->max[p]; | |
279 } | |
280 } | |
281 | |
282 for (j = 0; j < 4; j++) | 266 for (j = 0; j < 4; j++) |
283 { | 267 { |
284 gint k; | 268 gint k; |
285 gint chanmax = 0; | 269 gint chanmax = 0; |
286 | 270 |
287 for (k = 1; k < 4; k++) | 271 for (k = 1; k < 3; k++) |
288 if (v[k] > v[chanmax]) chanmax = k; | 272 if (v[k] > v[chanmax]) |
273 chanmax = k; | |
289 | 274 |
290 if (histogram->channel_mode >= HCHAN_RGB | 275 if (histogram->channel_mode >= HCHAN_RGB |
291 || chanmax == histogram->channel_mode) | 276 || chanmax == histogram->channel_mode) |
292 { | 277 { |
293 gulong pt; | 278 gulong pt; |
308 if (r == 255 && g == 255 && b == 255) | 293 if (r == 255 && g == 255 && b == 255) |
309 { | 294 { |
310 r = 0; b = 0; g = 0; | 295 r = 0; b = 0; g = 0; |
311 } | 296 } |
312 break; | 297 break; |
313 case HCHAN_R: b = 0; g = 0; break; | 298 case HCHAN_R: b = 0; g = 0; break; |
314 case HCHAN_G: r = 0; b = 0; break; | 299 case HCHAN_G: r = 0; b = 0; break; |
315 case HCHAN_B: r = 0; g = 0; break; | 300 case HCHAN_B: r = 0; g = 0; break; |
316 case HCHAN_MAX: | 301 case HCHAN_MAX: r = 0; b = 0; g = 0; break; |
317 case HCHAN_VAL: r = 0; b = 0; g = 0; break; | |
318 } | 302 } |
319 | 303 |
320 if (v[chanmax] == 0) | 304 if (v[chanmax] == 0) |
321 pt = 0; | 305 pt = 0; |
322 else if (histogram->log_mode) | 306 else if (histogram->log_mode) |