CHDK_DE Vorschauversion  Trunk Rev. 6014
 Alle Datenstrukturen Dateien Funktionen Variablen Typdefinitionen Aufzählungen Aufzählungswerte Makrodefinitionen
histogram.c-Dateireferenz
#include "camera_info.h"
#include "conf.h"
#include "math.h"
#include "modes.h"
#include "viewport.h"
#include "gui.h"
#include "gui_draw.h"
#include "gui_osd.h"
#include "shooting.h"
#include "histogram.h"
+ Include-Abhängigkeitsdiagramm für histogram.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define HISTO_R   0
 
#define HISTO_G   1
 
#define HISTO_B   2
 
#define HISTO_RGB   3
 
#define HISTO_Y   4
 
#define HISTO_MODE_LINEAR   0
 
#define HISTO_MODE_LOG   1
 
#define OSD_HISTO_LAYOUT_A   0
 
#define OSD_HISTO_LAYOUT_Y   1
 
#define OSD_HISTO_LAYOUT_A_Y   2
 
#define OSD_HISTO_LAYOUT_R_G_B   3
 
#define OSD_HISTO_LAYOUT_A_yrgb   4
 
#define OSD_HISTO_LAYOUT_Y_argb   5
 
#define OSD_HISTO_LAYOUT_BLEND   6
 
#define OSD_HISTO_LAYOUT_BLEND_Y   7
 
#define HISTO_DOT_SIZE   3
 
#define HISTO_DOT_PAD   (HISTO_DOT_SIZE + 2)
 
#define HISTO_TARGET_SAMPLES   20000
 
#define HISTO_XSTEP_MIN   4
 
#define HISTO_YSTEP_MIN   2
 

Funktionen

static int clip (int v)
 
static float identity (float x)
 
static float logarithmic (float x)
 
static void histogram_alloc ()
 
void histogram_sample_stage (unsigned char *img, int stage, int byte_width, int vis_byte_width, int height, int xstep_bytes, int ystep)
 
void histogram_process ()
 
static void gui_osd_draw_single_histo (int hist, coord x, coord y, int small)
 
static void gui_osd_draw_blended_histo (coord x, coord y)
 
void gui_osd_draw_histo (int is_osd_edit)
 
int _module_unloader ()
 
int _module_can_unload ()
 

Variablen

static unsigned char histogram [5][HISTO_WIDTH]
 
static unsigned short * histogram_proc [5] = { 0,0,0,0,0 }
 
unsigned int histo_max [5]
 
unsigned int histo_max_center [5]
 
static float histo_max_center_invw [5]
 
static long histo_magnification
 
static long under_exposed
 
static long over_exposed
 
static long histogram_stage =0
 
libhisto_sym _libhisto
 
ModuleInfo _module_info
 

Makro-Dokumentation

#define HISTO_B   2

Definiert in Zeile 17 der Datei histogram.c.

#define HISTO_DOT_PAD   (HISTO_DOT_SIZE + 2)

Definiert in Zeile 40 der Datei histogram.c.

#define HISTO_DOT_SIZE   3

Definiert in Zeile 35 der Datei histogram.c.

#define HISTO_G   1

Definiert in Zeile 16 der Datei histogram.c.

#define HISTO_MODE_LINEAR   0

Definiert in Zeile 22 der Datei histogram.c.

#define HISTO_MODE_LOG   1

Definiert in Zeile 23 der Datei histogram.c.

#define HISTO_R   0

Definiert in Zeile 15 der Datei histogram.c.

#define HISTO_RGB   3

Definiert in Zeile 18 der Datei histogram.c.

#define HISTO_TARGET_SAMPLES   20000

Definiert in Zeile 48 der Datei histogram.c.

#define HISTO_XSTEP_MIN   4

Definiert in Zeile 50 der Datei histogram.c.

#define HISTO_Y   4

Definiert in Zeile 19 der Datei histogram.c.

#define HISTO_YSTEP_MIN   2

Definiert in Zeile 52 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_A   0

Definiert in Zeile 26 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_A_Y   2

Definiert in Zeile 28 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_A_yrgb   4

Definiert in Zeile 30 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_BLEND   6

Definiert in Zeile 32 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_BLEND_Y   7

Definiert in Zeile 33 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_R_G_B   3

Definiert in Zeile 29 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_Y   1

Definiert in Zeile 27 der Datei histogram.c.

#define OSD_HISTO_LAYOUT_Y_argb   5

Definiert in Zeile 31 der Datei histogram.c.

Dokumentation der Funktionen

int _module_can_unload ( )

Definiert in Zeile 520 der Datei histogram.c.

521 {
522  return conf.show_histo == 0;
523 }
int _module_unloader ( )

Definiert in Zeile 515 der Datei histogram.c.

516 {
517  return 0;
518 }
static int clip ( int  v)
static

Definiert in Zeile 69 der Datei histogram.c.

70 {
71  if (v<0) v=0;
72  else if (v>255) v=255;
73  return v;
74 }
static void gui_osd_draw_blended_histo ( coord  x,
coord  y 
)
static

Definiert in Zeile 379 der Datei histogram.c.

380 {
383 
384  register unsigned int i, v, red, grn, blu, sel;
385  color cls[] = {
386  BG_COLOR(hc),
387  COLOR_BLUE,
388  COLOR_GREEN,
389  COLOR_CYAN,
390  COLOR_RED,
392  COLOR_YELLOW,
394  };
395 
396  for (i=0; i<HISTO_WIDTH; ++i) {
397  red = histogram[HISTO_R][i];
398  grn = histogram[HISTO_G][i];
399  blu = histogram[HISTO_B][i];
400 
401  for (v=1; v<HISTO_HEIGHT; ++v) {
402  sel = 0;
403 
404  if (v < red) sel = 4;
405  if (v < grn) sel |= 2;
406  if (v < blu) sel |= 1;
407 
408  draw_pixel(x+1+i, y+HISTO_HEIGHT-v, cls[sel]);
409  }
410  }
411 
412  draw_rectangle(x, y, x+1+HISTO_WIDTH, y+HISTO_HEIGHT, hc2, RECT_BORDER1);
413  //Vertical lines
414  if (conf.histo_show_ev_grid) for (i=1;i<=4;i++) draw_line(x+(1+HISTO_WIDTH)*i/5, y, x+(1+HISTO_WIDTH)*i/5, y+HISTO_HEIGHT, FG_COLOR(hc2));
415 
416 }
void gui_osd_draw_histo ( int  is_osd_edit)

Definiert in Zeile 419 der Datei histogram.c.

420 {
421  if (is_osd_edit ||
423  (
425  ((conf.show_histo==SHOW_HISTO_REC) && camera_info.state.mode_rec && (recreview_hold==0)) ||
426  ((conf.show_histo==SHOW_HISTO_ALWAYS) && (recreview_hold==0))
427  )
428  )
429  )
430  {
433 
434  switch (conf.histo_layout)
435  {
436  case OSD_HISTO_LAYOUT_Y:
438  break;
442  break;
447  break;
454  break;
461  break;
464  break;
468  break;
469  case OSD_HISTO_LAYOUT_A:
470  default:
472  break;
473  }
474 
476  {
478  {
481  }
483  {
486  }
487  }
490  if (conf.histo_auto_ajust){
491  if (histo_magnification) {
492  char osd_buf[64];
493  sprintf(osd_buf, " %d.%02dx ", histo_magnification/100, histo_magnification%100);
495  } else if (is_osd_edit){
497  } else {
499  }
500  }
501  }
502 }
static void gui_osd_draw_single_histo ( int  hist,
coord  x,
coord  y,
int  small 
)
static

Definiert in Zeile 323 der Datei histogram.c.

324 {
327 
328  register int i, v, threshold;
329  register color cl, cl_over, cl_bg = BG_COLOR(hc);
331 
332  switch (hist)
333  {
334  case HISTO_R:
335  cl=COLOR_RED;
336  break;
337  case HISTO_G:
338  cl=COLOR_GREEN;
339  break;
340  case HISTO_B:
341  cl=COLOR_BLUE;
342  break;
343  case HISTO_RGB:
344  case HISTO_Y:
345  default:
346  cl=FG_COLOR(hc);
347  break;
348  }
349 
350  if (small) {
351  h>>=1; w>>=1;
352  for (i=0; i<w; ++i) {
353  threshold = (histogram[hist][i<<1]+histogram[hist][(i<<1)+1])>>2;
354 
355  for (v=1; v<h-1; ++v)
356  draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl:cl_bg);
357  cl_over = (threshold==h && conf.show_overexp)?BG_COLOR(hc2):cl;
358  for (; v<h; ++v)
359  draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl_over:cl_bg);
360  }
361  } else {
362  for (i=0; i<w; ++i) {
363  threshold = histogram[hist][i];
364 
365  for (v=1; v<h-3; ++v)
366  draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl:cl_bg);
367  cl_over = (threshold==h && conf.show_overexp)?BG_COLOR(hc2):cl;
368  for (; v<h; ++v)
369  draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl_over:cl_bg);
370  }
371  }
372 
373  draw_rectangle(x, y, x+1+w, y+h, hc2, RECT_BORDER1);
374  //Vertical Lines
375  if (conf.histo_show_ev_grid) for (i=1;i<=4;i++) draw_line(x+(1+w)*i/5, y, x+(1+w)*i/5, y+h, FG_COLOR(hc2));
376 }
static void histogram_alloc ( )
static

Definiert in Zeile 80 der Datei histogram.c.

81 {
82  // Allocate arrays to store counts during processing
83  // Each possible value is counted so the array sizes are set to 256, then these are summed to
84  // convert down to desired width of 128.
85  // This is faster than scaling each value as it is counted
86  if (histogram_proc[0] == 0)
87  {
88  histogram_proc[0] = malloc(5 * 256 * sizeof(unsigned short));
89  histogram_proc[1] = histogram_proc[0] + 256;
90  histogram_proc[2] = histogram_proc[1] + 256;
91  histogram_proc[3] = histogram_proc[2] + 256;
92  histogram_proc[4] = histogram_proc[3] + 256;
93  }
94 }
void histogram_process ( )

Definiert in Zeile 142 der Datei histogram.c.

143 {
144  static unsigned char *img;
145 
147 
148  static int viewport_vis_byte_width;
149  static int xstep_bytes, ystep;
150 
151  int i, c;
152  float (*histogram_transform)(float);
153  unsigned int histo_fill[5];
154  int histo_main;
155 
156  long exposition_thresh = camera_screen.size / 500;
157 
158  // Select transform function
159  switch (conf.histo_mode)
160  {
161  case HISTO_MODE_LOG:
162  histogram_transform = logarithmic;
163  break;
164  case HISTO_MODE_LINEAR:
165  default:
166  histogram_transform = identity;
167  break;
168  }
169 
170  // Select which calculated histogram channel determines magnification / scaling
172  histo_main = HISTO_Y;
173  else
174  histo_main = HISTO_RGB;
175 
176  histogram_alloc();
177 
178  // This function is called in the main spytask loop roughly every 20msec
179  // To avoid hogging all the CPU it performs it's work in stages controlled by histogram-stage
180  // Stage Function
181  // 0 Initialize global variables used in next stages
182  // 1,2,3 Count number of values for a third of the viewport image at each stage
183  // 4 Calculate max values, over and under exposure setting
184  // 5 Calculate the histogram display values
185  switch (histogram_stage)
186  {
187  case 0: {
189  if (!img) return;
190 
191  img += vid_get_viewport_image_offset(); // offset into viewport for when image size != viewport size (e.g. 16:9 image on 4:3 LCD)
192 
193  viewport_height = vid_get_viewport_height_proper();
194  viewport_byte_width = vid_get_viewport_byte_width();
195  int viewport_pix_width = vid_get_viewport_width_proper();
196  int total_pixels = viewport_pix_width * viewport_height;
197  int xstep;
198 
200  xstep = HISTO_XSTEP_MIN;
201  ystep = HISTO_YSTEP_MIN;
202  } else {
203  // initial y step based on min x step and total samples
204  ystep = total_pixels/(HISTO_XSTEP_MIN*HISTO_TARGET_SAMPLES);
205  // if Y step is large, redistribute some to X, keeping multiple of 4
206  // in practice only hit for FHD HDMI
207  if(ystep >= 5*HISTO_YSTEP_MIN) {
208  xstep = 2*HISTO_XSTEP_MIN;
209  ystep >>= 1;
210  } else {
211  xstep = HISTO_XSTEP_MIN;
212  }
213  }
214 
215 
216 #ifndef THUMB_FW
217  xstep_bytes = (xstep*3)/2; // 4 pixels = 6 bytes, step is multiple of 4
218  viewport_vis_byte_width = (viewport_pix_width*3)/2;
219 #else
220  xstep_bytes = xstep*2;
221  viewport_vis_byte_width = viewport_pix_width*2;
222 #endif
223 
224  for (c=0; c<5; ++c) {
225  memset(histogram_proc[c],0,256*sizeof(unsigned short));
226  histo_max[c] = histo_max_center[c] = 0;
227  }
228 
229  histogram_stage=1;
230  break;
231  }
232 
233  case 1:
234  case 2:
235  case 3: {
236  histogram_sample_stage(img, histogram_stage, viewport_byte_width, viewport_vis_byte_width, viewport_height, xstep_bytes, ystep);
237  ++histogram_stage;
238  break;
239  }
240 
241  case 4:
242  for (i=0, c=0; i<HISTO_WIDTH; ++i, c+=2) { // G
243  // Merge each pair of values into a single value (for width = 128)
244  // Warning: this is optimised for HISTO_WIDTH = 128, don't change the width unless you re-write this code as well.
245 #ifndef THUMB_FW
247  histogram_proc[HISTO_R][i] = histogram_proc[HISTO_R][c] + histogram_proc[HISTO_R][c+1];
248  histogram_proc[HISTO_G][i] = histogram_proc[HISTO_G][c] + histogram_proc[HISTO_G][c+1];
249  histogram_proc[HISTO_B][i] = histogram_proc[HISTO_B][c] + histogram_proc[HISTO_B][c+1];
250 #endif
251  // Calc combined RGB totals
252  histogram_proc[HISTO_RGB][i] = histogram_proc[HISTO_R][i] + histogram_proc[HISTO_G][i] + histogram_proc[HISTO_B][i];
253  }
254 
255  // calculate maximums
256  for (c=0; c<5; ++c) {
257  for (i=0; i<HISTO_WIDTH; ++i) {
258  if (histo_max[c]<histogram_proc[c][i])
259  histo_max[c]=histogram_proc[c][i];
262  }
263 
264  if (histo_max_center[c] > 0) {
265  histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max_center[c]);
266  } else if (histo_max[c] > 0) {
267  histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max[c]);
268  } else {
269  histo_max_center_invw[c] = 0.0f;
270  }
271  }
272 
273  if (histo_max[HISTO_RGB] > 0) { // over- / under- expos
276  +histogram_proc[HISTO_RGB][2]) > exposition_thresh;
277 
278  over_exposed = (histogram_proc[HISTO_RGB][HISTO_WIDTH-3]
279  +histogram_proc[HISTO_RGB][HISTO_WIDTH-2]*4
280  +histogram_proc[HISTO_RGB][HISTO_WIDTH-1]*8) > exposition_thresh;
281  } else {
282  over_exposed = 0;
283  under_exposed = 1;
284  }
285 
286  histogram_stage=5;
287  break;
288 
289  case 5:
290  for (c=0; c<5; ++c) {
291  histo_fill[c]=0;
292  for (i=0; i<HISTO_WIDTH; ++i) {
293  histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c];
294  if (histogram[c][i] > HISTO_HEIGHT)
295  histogram[c][i] = HISTO_HEIGHT;
296  histo_fill[c]+=histogram[c][i];
297  }
298  }
299 
301  if (conf.histo_auto_ajust) {
302  if (histo_fill[histo_main] < (HISTO_HEIGHT*HISTO_WIDTH)/5) { // try to adjust if average level is less than 20%
303  histo_magnification = (20*HISTO_HEIGHT*HISTO_WIDTH) / histo_fill[histo_main];
304  for (c=0; c<5; ++c) {
305  for (i=0;i<HISTO_WIDTH;i++) {
306  histogram[c][i] = histogram[c][i] * histo_magnification / 100;
307  if (histogram[c][i] > HISTO_HEIGHT)
308  histogram[c][i] = HISTO_HEIGHT;
309  }
310  }
311  }
312  }
313 
314  histogram_stage=0;
315  break;
316  }
317 
318 }
void histogram_sample_stage ( unsigned char *  img,
int  stage,
int  byte_width,
int  vis_byte_width,
int  height,
int  xstep_bytes,
int  ystep 
)

Definiert in Zeile 102 der Datei histogram.c.

103 {
104  // start at stage'th ystep (1-3), plus one step in x
105  unsigned char *p_row = img + stage*ystep*byte_width + xstep_bytes;
106  // end one step short of height
107  unsigned char *p_max = img + byte_width*(height-ystep);
108  // number of from start to end of sampled row
109  // -2 xstep_bytes for margins
110  int row_sample_len = vis_byte_width - 2*xstep_bytes;
111 
112  // every 3rd ystep for each stage
113  int ystep_bytes = ystep*byte_width*3;
114 
115  for(;p_row < p_max; p_row += ystep_bytes) {
116  // start sample 1 step after start
117  unsigned char *p = p_row;
118  unsigned char *p_row_end = p_row + row_sample_len;
119  for(;p < p_row_end; p+= xstep_bytes) {
120  int y, v, u, hi;
121  y = p[1];
122 #ifndef THUMB_FW
123  u = (signed char)p[0];
124  v = (signed char)p[2];
125 #else
126  u = (int)p[0] - 128;
127  v = (int)p[2] - 128;
128 #endif
129 // p[1] = p[3] = 255; // Draw columns on screen for debugging
130 
131  ++histogram_proc[HISTO_Y][y]; // Y
132  hi = clip(((y<<12) + v*5743 + 2048)>>12); // R
133  ++histogram_proc[HISTO_R][hi];
134  hi = clip(((y<<12) - u*1411 - v*2925 + 2048)>>12); // G
135  ++histogram_proc[HISTO_G][hi];
136  hi = clip(((y<<12) + u*7258 + 2048)>>12); // B
137  ++histogram_proc[HISTO_B][hi];
138  }
139  }
140 }
static float identity ( float  x)
static

Definiert in Zeile 77 der Datei histogram.c.

77 { return x; }
static float logarithmic ( float  x)
static

Definiert in Zeile 78 der Datei histogram.c.

78 { return log(x); }

Variablen-Dokumentation

libhisto_sym _libhisto
Initialisierung:

Definiert in Zeile 527 der Datei histogram.c.

ModuleInfo _module_info
Initialisierung:

Definiert in Zeile 537 der Datei histogram.c.

long histo_magnification
static

Definiert in Zeile 59 der Datei histogram.c.

unsigned int histo_max[5]

Definiert in Zeile 56 der Datei histogram.c.

unsigned int histo_max_center[5]

Definiert in Zeile 56 der Datei histogram.c.

float histo_max_center_invw[5]
static

Definiert in Zeile 57 der Datei histogram.c.

unsigned char histogram[5][HISTO_WIDTH]
static

Definiert in Zeile 54 der Datei histogram.c.

unsigned short* histogram_proc[5] = { 0,0,0,0,0 }
static

Definiert in Zeile 55 der Datei histogram.c.

long histogram_stage =0
static

Definiert in Zeile 63 der Datei histogram.c.

long over_exposed
static

Definiert in Zeile 61 der Datei histogram.c.

long under_exposed
static

Definiert in Zeile 60 der Datei histogram.c.