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)