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;