root/modules/histogram.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clip
  2. identity
  3. logarithmic
  4. histogram_alloc
  5. histogram_sample_stage
  6. histogram_process
  7. gui_osd_draw_single_histo
  8. gui_osd_draw_blended_histo
  9. gui_osd_draw_histo
  10. _module_unloader
  11. _module_can_unload

   1 #include "camera_info.h"
   2 #include "conf.h"
   3 #include "math.h"
   4 #include "modes.h"
   5 #include "viewport.h"
   6 #include "gui.h"
   7 #include "gui_draw.h"
   8 #include "gui_osd.h"
   9 #include "shooting.h"
  10 #include "histogram.h"
  11 
  12 //-------------------------------------------------------------------
  13 
  14 // Indexes into the various arrays for calculating the histogram channels
  15 #define HISTO_R                     0       // Red channel
  16 #define HISTO_G                     1       // Green channel
  17 #define HISTO_B                     2       // Blue channel
  18 #define HISTO_RGB                   3       // Combined Red, Green and Blue
  19 #define HISTO_Y                     4       // Luminance (Y) from viewport
  20 
  21 // Define type of transform to be done to scale the histogram to fit the available height
  22 #define HISTO_MODE_LINEAR           0
  23 #define HISTO_MODE_LOG              1
  24 
  25 // Display modes
  26 #define OSD_HISTO_LAYOUT_A          0       // A - RGB
  27 #define OSD_HISTO_LAYOUT_Y          1
  28 #define OSD_HISTO_LAYOUT_A_Y        2
  29 #define OSD_HISTO_LAYOUT_R_G_B      3
  30 #define OSD_HISTO_LAYOUT_A_yrgb     4
  31 #define OSD_HISTO_LAYOUT_Y_argb     5
  32 #define OSD_HISTO_LAYOUT_BLEND      6
  33 #define OSD_HISTO_LAYOUT_BLEND_Y    7
  34 #ifndef THUMB_FW
  35 #define HISTO_DOT_SIZE  3
  36 #else
  37 // digic 6 CHDK screen is ~480 lines instead for 240
  38 #define HISTO_DOT_SIZE  5
  39 #endif
  40 #define HISTO_DOT_PAD   (HISTO_DOT_SIZE + 2)
  41 
  42 // Approximate number of pixels to sample, subject to minimums step sizes
  43 // Actual number of samples may exceed target due to rounding/truncation in step calculations
  44 // Actual total must be less than 64K to allow storing histogram counts in unsigned short
  45 // 20k based on typical number in earlier implementation
  46 // cameras typically process 250-600 px/ms uncached, 300-1200 cached
  47 // NOTE target could be adjusted based on cam_info.cam_digic
  48 #define HISTO_TARGET_SAMPLES 20000
  49 // Minimum X step is 4, for alignment with YUV tuples (could technically be 2 on Digic >=6 cams with UYVY viewports)
  50 #define HISTO_XSTEP_MIN 4
  51 // Minimum Y step is 2, no need to sample more densely
  52 #define HISTO_YSTEP_MIN 2
  53 
  54 static unsigned char histogram[5][HISTO_WIDTH];             // RGBYG
  55 static unsigned short *histogram_proc[5] = { 0,0,0,0,0 };   // RGBYG (logic in histogram_process stage 0 ensures unsigned short is large enough)
  56 unsigned int histo_max[5], histo_max_center[5];             // RGBYG
  57 static float histo_max_center_invw[5];                      // RGBYG
  58 
  59 static long histo_magnification;
  60 static long under_exposed;
  61 static long over_exposed;
  62 
  63 static long histogram_stage=0;
  64 
  65 //-------------------------------------------------------------------
  66 // Histogram calculation functions
  67 
  68 // Clip value to byte range (for YUV -> RGB conversion)
  69 static int clip(int v)
  70 {
  71     if (v<0) v=0;
  72     else if (v>255) v=255;
  73     return v;
  74 }
  75 
  76 // Transform functions
  77 static float identity(float x)      { return x; }
  78 static float logarithmic(float x)   { return log(x); }
  79 
  80 static void histogram_alloc()
  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 }
  95 
  96 
  97 /*
  98 do a single stage of reading YUV data from framebuffer
  99 Sampled area has margins of one step at top, right and left and bottom
 100 Each stage samples every 3rd ystep row
 101 */
 102 void histogram_sample_stage(unsigned char *img, int stage, int byte_width, int vis_byte_width, int height, int xstep_bytes, int ystep)
 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 }
 141 
 142 void histogram_process()
 143 {
 144     static unsigned char *img;
 145 
 146     static int viewport_byte_width, viewport_height;
 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
 171     if (conf.histo_layout == OSD_HISTO_LAYOUT_Y || conf.histo_layout == OSD_HISTO_LAYOUT_Y_argb)
 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: {
 188             img = vid_get_viewport_active_buffer();
 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 
 199             if(total_pixels <= HISTO_XSTEP_MIN*HISTO_YSTEP_MIN*HISTO_TARGET_SAMPLES) {
 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
 246                 histogram_proc[HISTO_Y][i] = histogram_proc[HISTO_Y][c] + histogram_proc[HISTO_Y][c+1];
 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];
 260                     if (histo_max_center[c]<histogram_proc[c][i] && i>=conf.histo_ignore_boundary && i<HISTO_WIDTH-conf.histo_ignore_boundary)
 261                         histo_max_center[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
 274                 under_exposed = (histogram_proc[HISTO_RGB][0]*8
 275                                 +histogram_proc[HISTO_RGB][1]*4
 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 
 300             histo_magnification = 0;
 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 }
 319 
 320 //-------------------------------------------------------------------
 321 // Histogram display functions
 322 
 323 static void gui_osd_draw_single_histo(int hist, coord x, coord y, int small)
 324 {
 325     twoColors hc = user_color(conf.histo_color);
 326     twoColors hc2 = user_color(conf.histo_color2);
 327 
 328     register int i, v, threshold;
 329     register color cl, cl_over, cl_bg = BG_COLOR(hc);
 330     coord w=HISTO_WIDTH, h=HISTO_HEIGHT;
 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 }
 377 
 378 //-------------------------------------------------------------------
 379 static void gui_osd_draw_blended_histo(coord x, coord y)
 380 {
 381     twoColors hc = user_color(conf.histo_color);
 382     twoColors hc2 = user_color(conf.histo_color2);
 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,
 391         COLOR_MAGENTA,
 392         COLOR_YELLOW,
 393         COLOR_WHITE
 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 }
 417 
 418 //-------------------------------------------------------------------
 419 void gui_osd_draw_histo(int is_osd_edit)
 420 {
 421     if (is_osd_edit ||
 422         ((camera_info.state.mode_play || !camera_info.state.mode_video) &&
 423          (
 424           ((conf.show_histo==SHOW_HISTO_HALF) && camera_info.state.is_shutter_half_press) ||
 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     {
 431         twoColors hc = user_color(conf.histo_color);
 432         twoColors hc2 = user_color(conf.histo_color2);
 433 
 434         switch (conf.histo_layout)
 435         {
 436             case OSD_HISTO_LAYOUT_Y:
 437                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y, 0);
 438                 break;
 439             case OSD_HISTO_LAYOUT_A_Y:
 440                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 441                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 442                 break;
 443             case OSD_HISTO_LAYOUT_R_G_B:
 444                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x, conf.histo_pos.y, 0);
 445                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 446                 gui_osd_draw_single_histo(HISTO_B, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT*2, 0);
 447                 break;
 448             case OSD_HISTO_LAYOUT_A_yrgb:
 449                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 450                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 1);
 451                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT, 1);
 452                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 453                 gui_osd_draw_single_histo(HISTO_B, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 454                 break;
 455             case OSD_HISTO_LAYOUT_Y_argb:
 456                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y, 0);
 457                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 1);
 458                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT, 1);
 459                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 460                 gui_osd_draw_single_histo(HISTO_B, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 461                 break;
 462             case OSD_HISTO_LAYOUT_BLEND:
 463                 gui_osd_draw_blended_histo(conf.histo_pos.x, conf.histo_pos.y);
 464                 break;
 465             case OSD_HISTO_LAYOUT_BLEND_Y:
 466                 gui_osd_draw_blended_histo(conf.histo_pos.x, conf.histo_pos.y);
 467                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 468                 break;
 469             case OSD_HISTO_LAYOUT_A:
 470             default:
 471                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 472                 break;
 473         }
 474 
 475         if (conf.histo_layout != OSD_HISTO_LAYOUT_R_G_B)
 476         {
 477             if (under_exposed && conf.show_overexp)
 478             {
 479                 draw_ellipse(conf.histo_pos.x+HISTO_DOT_PAD, conf.histo_pos.y+HISTO_DOT_PAD,
 480                                 HISTO_DOT_SIZE, HISTO_DOT_SIZE, BG_COLOR(hc2), DRAW_FILLED);
 481             }
 482             if (over_exposed && conf.show_overexp)
 483             {
 484                 draw_ellipse(conf.histo_pos.x+HISTO_WIDTH-HISTO_DOT_PAD, conf.histo_pos.y+HISTO_DOT_PAD,
 485                             HISTO_DOT_SIZE, HISTO_DOT_SIZE, BG_COLOR(hc2), DRAW_FILLED);
 486             }
 487         }
 488         if ((conf.show_overexp ) && camera_info.state.is_shutter_half_press && (under_exposed || over_exposed))
 489             draw_string(conf.histo_pos.x+HISTO_WIDTH-FONT_WIDTH*3, conf.histo_pos.y-FONT_HEIGHT, "EXP", hc);
 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);
 494                 draw_string(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, osd_buf, hc);
 495             } else if (is_osd_edit){
 496                 draw_string(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, " 9.99x ", hc);
 497             } else {
 498                 draw_rectangle(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, conf.histo_pos.x+8*FONT_WIDTH, conf.histo_pos.y-1, MAKE_COLOR(COLOR_TRANSPARENT, COLOR_TRANSPARENT), RECT_BORDER0|DRAW_FILLED);
 499             }
 500         }
 501     }
 502 }
 503 
 504 
 505 // =========  MODULE INIT =================
 506 
 507 /***************** BEGIN OF AUXILARY PART *********************
 508   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
 509  **************************************************************/
 510 
 511 //---------------------------------------------------------
 512 // PURPOSE: Finalize module operations (close allocs, etc)
 513 // RETURN VALUE: 0-ok, 1-fail
 514 //---------------------------------------------------------
 515 int _module_unloader()
 516 {
 517     return 0;
 518 }
 519 
 520 int _module_can_unload()
 521 {
 522     return conf.show_histo == 0;
 523 }
 524 
 525 /******************** Module Information structure ******************/
 526 
 527 libhisto_sym _libhisto =
 528 {
 529     {
 530          0, _module_unloader, _module_can_unload, 0, 0
 531     },
 532 
 533     histogram_process,
 534     gui_osd_draw_histo
 535 };
 536 
 537 ModuleInfo _module_info =
 538 {
 539     MODULEINFO_V1_MAGICNUM,
 540     sizeof(ModuleInfo),
 541     HISTO_VERSION,                              // Module version
 542 
 543     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,                       // Requirements of CHDK version
 544     ANY_PLATFORM_ALLOWED,               // Specify platform dependency
 545 
 546     (int32_t)"Histogram Overlay (dll)",
 547     MTYPE_EXTENSION,
 548 
 549     &_libhisto.base,
 550 
 551     CONF_VERSION,               // CONF version
 552     CAM_SCREEN_VERSION,         // CAM SCREEN version
 553     ANY_VERSION,                // CAM SENSOR version
 554     CAM_INFO_VERSION,           // CAM INFO version
 555 
 556     0,
 557 };
 558 
 559 /*************** END OF AUXILARY PART *******************/

/* [<][>][^][v][top][bottom][index][help] */