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_process
  6. gui_osd_draw_single_histo
  7. gui_osd_draw_blended_histo
  8. gui_osd_draw_histo
  9. _module_unloader
  10. _module_can_unload

   1 #include "camera_info.h"
   2 #include "stdlib.h"
   3 #include "conf.h"
   4 #include "math.h"
   5 #include "modes.h"
   6 #include "viewport.h"
   7 #include "gui.h"
   8 #include "gui_draw.h"
   9 #include "gui_osd.h"
  10 #include "shooting.h"
  11 #include "histogram.h"
  12 
  13 //-------------------------------------------------------------------
  14 //  modify for digic 6
  15 // 62ndidiot. 2016.02.07
  16 // double histogram width height for better visibility...should not affect performance
  17 // since we no longer have to sum pairs of histogram channels
  18 
  19 #define HISTOGRAM_IDLE_STAGE        6
  20 
  21 // Indexes into the various arrays for calculating the histogram channels
  22 #define HISTO_R                     0       // Red channel
  23 #define HISTO_G                     1       // Green channel
  24 #define HISTO_B                     2       // Blue channel
  25 #define HISTO_RGB                   3       // Combined Red, Green and Blue
  26 #define HISTO_Y                     4       // Luminance (Y) from viewport
  27 
  28 // Define type of transform to be done to scale the histogram to fit the available height
  29 #define HISTO_MODE_LINEAR           0
  30 #define HISTO_MODE_LOG              1
  31 
  32 // Display modes
  33 #define OSD_HISTO_LAYOUT_A          0       // A - RGB
  34 #define OSD_HISTO_LAYOUT_Y          1
  35 #define OSD_HISTO_LAYOUT_A_Y        2
  36 #define OSD_HISTO_LAYOUT_R_G_B      3
  37 #define OSD_HISTO_LAYOUT_A_yrgb     4
  38 #define OSD_HISTO_LAYOUT_Y_argb     5
  39 #define OSD_HISTO_LAYOUT_BLEND      6
  40 #define OSD_HISTO_LAYOUT_BLEND_Y    7
  41 #ifndef THUMB_FW
  42 // Define how many viewport blocks to step in each loop iteration. Each block is 6 bytes (UYVYYY) or 4 image pixels
  43 #define HISTO_STEP_SIZE 6
  44 #else
  45 // Define how many viewport blocks to step in each loop iteration. Each block is 4 bytes (UYVY) or 2 image pixels
  46 #define HISTO_STEP_SIZE 4
  47 #endif
  48 
  49 static unsigned char histogram[5][HISTO_WIDTH];             // RGBYG
  50 static unsigned short *histogram_proc[5] = { 0,0,0,0,0 };   // RGBYG (unsigned short is large enough provided HISTO_STEP_SIZE >= 3)
  51 unsigned int histo_max[5], histo_max_center[5];             // RGBYG
  52 static float histo_max_center_invw[5];                      // RGBYG
  53 
  54 static long histo_magnification;
  55 static long under_exposed;
  56 static long over_exposed;
  57 
  58 static long histogram_stage=0;
  59 
  60 //-------------------------------------------------------------------
  61 // Histogram calculation functions
  62 
  63 // Clip value to byte range (for YUV -> RGB conversion)
  64 static int clip(int v)
  65 {
  66     if (v<0) v=0;
  67     else if (v>255) v=255;
  68     return v;
  69 }
  70 
  71 // Transform functions
  72 static float identity(float x)      { return x; }
  73 static float logarithmic(float x)   { return log(x); }
  74 
  75 static void histogram_alloc()
  76 {
  77     // Allocate arrays to store counts during processing
  78     // Each possible value is counted so the array sizes are set to 256, then these are summed to
  79     // convert down to desired width of 128.
  80     // This is faster than scaling each value as it is counted
  81     if (histogram_proc[0] == 0)
  82     {
  83         histogram_proc[0] = malloc(5 * 256 * sizeof(unsigned short));
  84         histogram_proc[1] = histogram_proc[0] + 256;
  85         histogram_proc[2] = histogram_proc[1] + 256;
  86         histogram_proc[3] = histogram_proc[2] + 256;
  87         histogram_proc[4] = histogram_proc[3] + 256;
  88     }
  89 }
  90 
  91 void histogram_process()
  92 {
  93     static unsigned char *img;
  94     static int viewport_size, viewport_width, viewport_row_offset, viewport_height, viewport_step_size;
  95 
  96     register int x, i, hi;
  97     int y, v, u, c;
  98     float (*histogram_transform)(float);
  99     unsigned int histo_fill[5];
 100     int histo_main;
 101 
 102     long exposition_thresh = camera_screen.size / 500;
 103 
 104     // Select transform function
 105     switch (conf.histo_mode)
 106     {
 107         case HISTO_MODE_LOG: 
 108             histogram_transform = logarithmic; 
 109             break;
 110         case HISTO_MODE_LINEAR: 
 111         default:
 112             histogram_transform = identity; 
 113             break;
 114     }
 115 
 116     // Select which calculated histogram channel determines magnification / scaling
 117     if (conf.histo_layout == OSD_HISTO_LAYOUT_Y || conf.histo_layout == OSD_HISTO_LAYOUT_Y_argb)
 118         histo_main = HISTO_Y;
 119     else
 120         histo_main = HISTO_RGB;
 121 
 122     histogram_alloc();
 123 
 124     // This function is called in the main spytask loop roughly every 20msec
 125     // To avoid hogging all the CPU it performs it's work in stages controlled by histogram-stage
 126     // Stage  Function
 127     //   0      Initialize global variables used in next stages
 128     //   1,2,3  Count number of values for a third of the viewport image at each stage
 129     //   4      Calculate max values, over and under exposure setting
 130     //   5      Calculate the histogram display values
 131     switch (histogram_stage)
 132     {
 133         case 0:
 134             img = vid_get_viewport_active_buffer();
 135             if (!img) return;
 136 
 137             img += vid_get_viewport_image_offset();             // offset into viewport for when image size != viewport size (e.g. 16:9 image on 4:3 LCD)
 138 
 139             viewport_height = vid_get_viewport_height_proper();
 140             viewport_size = viewport_height * vid_get_viewport_byte_width();
 141             // Viewport visible width in bytes
 142 #ifndef THUMB_FW
 143             viewport_width = vid_get_viewport_width_proper() * 6 / 4;
 144 #else
 145             viewport_width = vid_get_viewport_width_proper() * 4 / 2;
 146 #endif
 147             // Number of columns to scan - 30 for 720 pixel wide viewport, 40 for widescreen (960 wide).
 148             // This give 24 pixel increments between columns.
 149             // For pre Digic6 24 pixels = 24 * 6 / 4 bytes = 36 bytes (6 bytes = 4 pixels). Each 'stage' does a column @1/3rd of this width = 12 bytes = 8 pixels.
 150             // For Digic6 24 pixels = 24 * 4 / 2 bytes = 48 bytes (4 bytes = 2 pixels). Each 'stage' does a column @1/3rd of this width = 16 bytes = 8 pixels.
 151             // We offset all columns by 4 pixels so the first column is not hard against the left edge
 152             viewport_step_size = viewport_width / (vid_get_viewport_width_proper() / 24);
 153             // Increment to adjust for each row if physical width > visible width
 154             viewport_row_offset = vid_get_viewport_row_offset();
 155 
 156             for (c=0; c<5; ++c) {
 157                 memset(histogram_proc[c],0,256*sizeof(unsigned short));
 158                 histo_max[c] = histo_max_center[c] = 0;
 159             }
 160 
 161             histogram_stage=1;
 162             break;
 163 
 164         case 1:
 165         case 2:
 166         case 3:
 167             x = 0;  // count how many bytes we have done on the current row (to skip unused buffer space at end of each row)
 168 
 169             for (i=(histogram_stage-1)*(viewport_step_size/3)+(viewport_step_size/6); i<viewport_size; i+=viewport_step_size) {
 170 
 171                 y = img[i+1];
 172 #ifndef THUMB_FW
 173                 u = (signed char)img[i];
 174                 v = (signed char)img[i+2];
 175 #else
 176                 u = (int)img[i] - 128;
 177                 v = (int)img[i+2] - 128;
 178 #endif
 179 //                img[i+1] = img[i+3] = 255;    // Draw columns on screen for debugging
 180 
 181                 ++histogram_proc[HISTO_Y][y];                       // Y
 182                 hi = clip(((y<<12)          + v*5743 + 2048)>>12);  // R
 183                 ++histogram_proc[HISTO_R][hi];
 184                 hi = clip(((y<<12) - u*1411 - v*2925 + 2048)>>12);  // G
 185                 ++histogram_proc[HISTO_G][hi];
 186                 hi = clip(((y<<12) + u*7258          + 2048)>>12);  // B
 187                 ++histogram_proc[HISTO_B][hi];
 188 
 189                 // Handle case where viewport memory buffer is wider than the actual buffer.
 190                 x += viewport_step_size;
 191                 if (x == viewport_width)
 192                 {
 193                     i += viewport_row_offset;
 194                     x = 0;
 195                 }
 196             } //loop i
 197 
 198             ++histogram_stage;
 199             break;
 200 
 201         case 4:
 202             for (i=0, c=0; i<HISTO_WIDTH; ++i, c+=2) { // G
 203                 // Merge each pair of values into a single value (for width = 128)
 204                 // Warning: this is optimised for HISTO_WIDTH = 128, don't change the width unless you re-write this code as well.
 205 #ifndef THUMB_FW
 206                 histogram_proc[HISTO_Y][i] = histogram_proc[HISTO_Y][c] + histogram_proc[HISTO_Y][c+1];
 207                 histogram_proc[HISTO_R][i] = histogram_proc[HISTO_R][c] + histogram_proc[HISTO_R][c+1];
 208                 histogram_proc[HISTO_G][i] = histogram_proc[HISTO_G][c] + histogram_proc[HISTO_G][c+1];
 209                 histogram_proc[HISTO_B][i] = histogram_proc[HISTO_B][c] + histogram_proc[HISTO_B][c+1];
 210 #endif
 211                 // Calc combined RGB totals
 212                 histogram_proc[HISTO_RGB][i] = histogram_proc[HISTO_R][i] + histogram_proc[HISTO_G][i] + histogram_proc[HISTO_B][i];
 213             }
 214 
 215             // calculate maximums
 216             for (c=0; c<5; ++c) {
 217                 for (i=0; i<HISTO_WIDTH; ++i) {
 218                     if (histo_max[c]<histogram_proc[c][i])
 219                         histo_max[c]=histogram_proc[c][i];
 220                     if (histo_max_center[c]<histogram_proc[c][i] && i>=conf.histo_ignore_boundary && i<HISTO_WIDTH-conf.histo_ignore_boundary)
 221                         histo_max_center[c]=histogram_proc[c][i];
 222                 }
 223 
 224                 if (histo_max_center[c] > 0) {
 225                     histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max_center[c]);
 226                 } else if (histo_max[c] > 0) {
 227                     histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max[c]);
 228                 } else {
 229                     histo_max_center_invw[c] = 0.0f;
 230                 }
 231             }
 232 
 233             if (histo_max[HISTO_RGB] > 0) { // over- / under- expos
 234                 under_exposed = (histogram_proc[HISTO_RGB][0]*8
 235                                 +histogram_proc[HISTO_RGB][1]*4
 236                                 +histogram_proc[HISTO_RGB][2]) > exposition_thresh;
 237 
 238                 over_exposed  = (histogram_proc[HISTO_RGB][HISTO_WIDTH-3]
 239                                 +histogram_proc[HISTO_RGB][HISTO_WIDTH-2]*4
 240                                 +histogram_proc[HISTO_RGB][HISTO_WIDTH-1]*8) > exposition_thresh;
 241             } else {
 242                 over_exposed = 0;
 243                 under_exposed = 1;
 244             }
 245 
 246             histogram_stage=5;
 247             break;
 248 
 249         case 5:
 250             for (c=0; c<5; ++c) {
 251                 histo_fill[c]=0;
 252                 for (i=0; i<HISTO_WIDTH; ++i) {
 253                     histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c];
 254                     if (histogram[c][i] > HISTO_HEIGHT)
 255                         histogram[c][i] = HISTO_HEIGHT;
 256                     histo_fill[c]+=histogram[c][i];
 257                 }
 258             }
 259 
 260             histo_magnification = 0;
 261             if (conf.histo_auto_ajust) {
 262                 if (histo_fill[histo_main] < (HISTO_HEIGHT*HISTO_WIDTH)/5) { // try to ajust if average level is less than 20%
 263                     histo_magnification = (20*HISTO_HEIGHT*HISTO_WIDTH) / histo_fill[histo_main];
 264                     for (c=0; c<5; ++c) {
 265                         for (i=0;i<HISTO_WIDTH;i++) {
 266                             histogram[c][i] = histogram[c][i] * histo_magnification / 100;
 267                             if (histogram[c][i] > HISTO_HEIGHT)
 268                                 histogram[c][i] = HISTO_HEIGHT;
 269                         }
 270                     }
 271                 }
 272             }
 273 
 274             histogram_stage=0;
 275             break;
 276     }
 277 
 278 }
 279 
 280 //-------------------------------------------------------------------
 281 // Histogram display functions
 282 
 283 static void gui_osd_draw_single_histo(int hist, coord x, coord y, int small)
 284 {
 285     twoColors hc = user_color(conf.histo_color);
 286     twoColors hc2 = user_color(conf.histo_color2);
 287 
 288     register unsigned int i, v, threshold;
 289     register color cl, cl_over, cl_bg = BG_COLOR(hc);
 290     coord w=HISTO_WIDTH, h=HISTO_HEIGHT;
 291 
 292     switch (hist) 
 293     {
 294         case HISTO_R: 
 295             cl=COLOR_RED;
 296             break;
 297         case HISTO_G: 
 298             cl=COLOR_GREEN;
 299             break;
 300         case HISTO_B:
 301             cl=COLOR_BLUE;
 302             break;
 303         case HISTO_RGB:
 304         case HISTO_Y:
 305         default:
 306             cl=FG_COLOR(hc);
 307             break;
 308     }
 309 
 310     if (small) {
 311         h>>=1; w>>=1;
 312         for (i=0; i<w; ++i) {
 313             threshold = (histogram[hist][i<<1]+histogram[hist][(i<<1)+1])>>2;
 314 
 315             for (v=1; v<h-1; ++v)
 316                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl:cl_bg);
 317             cl_over = (threshold==h && conf.show_overexp)?BG_COLOR(hc2):cl;
 318             for (; v<h; ++v)
 319                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl_over:cl_bg);
 320         }
 321     } else {
 322         for (i=0; i<w; ++i) {
 323             threshold = histogram[hist][i];
 324 
 325             for (v=1; v<h-3; ++v)
 326                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl:cl_bg);
 327             cl_over = (threshold==h && conf.show_overexp)?BG_COLOR(hc2):cl;
 328             for (; v<h; ++v)
 329                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl_over:cl_bg);
 330         }
 331     }
 332 
 333     draw_rectangle(x, y, x+1+w, y+h, hc2, RECT_BORDER1);
 334     //Vertical Lines
 335     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));
 336 }
 337 
 338 //-------------------------------------------------------------------
 339 static void gui_osd_draw_blended_histo(coord x, coord y)
 340 {
 341     twoColors hc = user_color(conf.histo_color);
 342     twoColors hc2 = user_color(conf.histo_color2);
 343 
 344     register unsigned int i, v, red, grn, blu, sel;
 345     color cls[] = {
 346         BG_COLOR(hc),
 347         COLOR_BLUE,
 348         COLOR_GREEN,
 349         COLOR_CYAN,
 350         COLOR_RED,
 351         COLOR_MAGENTA,
 352         COLOR_YELLOW,
 353         COLOR_WHITE
 354     };
 355 
 356     for (i=0; i<HISTO_WIDTH; ++i) {
 357         red = histogram[HISTO_R][i];
 358         grn = histogram[HISTO_G][i];
 359         blu = histogram[HISTO_B][i];
 360 
 361         for (v=1; v<HISTO_HEIGHT; ++v) {
 362             sel = 0;
 363 
 364             if (v < red) sel = 4;
 365             if (v < grn) sel |= 2;
 366             if (v < blu) sel |= 1;
 367 
 368             draw_pixel(x+1+i, y+HISTO_HEIGHT-v, cls[sel]);
 369         }
 370     }
 371 
 372     draw_rectangle(x, y, x+1+HISTO_WIDTH, y+HISTO_HEIGHT, hc2, RECT_BORDER1);
 373     //Vertical lines
 374     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));
 375 
 376 }
 377 
 378 //-------------------------------------------------------------------
 379 void gui_osd_draw_histo(int is_osd_edit)
 380 {
 381     if (is_osd_edit ||
 382         ((camera_info.state.mode_play || !camera_info.state.mode_video) &&
 383          (
 384           ((conf.show_histo==SHOW_HISTO_HALF) && camera_info.state.is_shutter_half_press) ||
 385           ((conf.show_histo==SHOW_HISTO_REC) && camera_info.state.mode_rec && (recreview_hold==0)) ||
 386           ((conf.show_histo==SHOW_HISTO_ALWAYS) && (recreview_hold==0))
 387          )
 388         )
 389        )
 390     {
 391         twoColors hc = user_color(conf.histo_color);
 392         twoColors hc2 = user_color(conf.histo_color2);
 393 
 394         switch (conf.histo_layout)
 395         {
 396             case OSD_HISTO_LAYOUT_Y:
 397                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y, 0);
 398                 break;
 399             case OSD_HISTO_LAYOUT_A_Y:
 400                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 401                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 402                 break;
 403             case OSD_HISTO_LAYOUT_R_G_B:
 404                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x, conf.histo_pos.y, 0);
 405                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 406                 gui_osd_draw_single_histo(HISTO_B, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT*2, 0);
 407                 break;
 408             case OSD_HISTO_LAYOUT_A_yrgb:
 409                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 410                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 1);
 411                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT, 1);
 412                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 413                 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);
 414                 break;
 415             case OSD_HISTO_LAYOUT_Y_argb:
 416                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y, 0);
 417                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 1);
 418                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT, 1);
 419                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 420                 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);
 421                 break;
 422             case OSD_HISTO_LAYOUT_BLEND:
 423                 gui_osd_draw_blended_histo(conf.histo_pos.x, conf.histo_pos.y);
 424                 break;
 425             case OSD_HISTO_LAYOUT_BLEND_Y:
 426                 gui_osd_draw_blended_histo(conf.histo_pos.x, conf.histo_pos.y);
 427                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 428                 break;
 429             case OSD_HISTO_LAYOUT_A:
 430             default:
 431                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 432                 break;
 433         }
 434 
 435         if (conf.histo_layout != OSD_HISTO_LAYOUT_R_G_B)
 436         {
 437             if (under_exposed && conf.show_overexp)
 438             {
 439                 draw_ellipse(conf.histo_pos.x+5, conf.histo_pos.y+5, 3, 3, BG_COLOR(hc2), DRAW_FILLED);
 440             }
 441             if (over_exposed && conf.show_overexp)
 442             {
 443                 draw_ellipse(conf.histo_pos.x+HISTO_WIDTH-5, conf.histo_pos.y+5, 3, 3, BG_COLOR(hc2), DRAW_FILLED);
 444             }
 445         }
 446         if ((conf.show_overexp ) && camera_info.state.is_shutter_half_press && (under_exposed || over_exposed))
 447             draw_string(conf.histo_pos.x+HISTO_WIDTH-FONT_WIDTH*3, conf.histo_pos.y-FONT_HEIGHT, "EXP", hc);
 448         if (conf.histo_auto_ajust){
 449             if (histo_magnification) {
 450                 char osd_buf[64];
 451                 sprintf(osd_buf, " %d.%02dx ", histo_magnification/100, histo_magnification%100);
 452                 draw_string(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, osd_buf, hc);
 453             } else if (is_osd_edit){
 454                 draw_string(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, " 9.99x ", hc);
 455             } else {
 456                 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);
 457             }
 458         }
 459     }
 460 }
 461 
 462 
 463 // =========  MODULE INIT =================
 464 
 465 /***************** BEGIN OF AUXILARY PART *********************
 466   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
 467  **************************************************************/
 468 
 469 //---------------------------------------------------------
 470 // PURPOSE: Finalize module operations (close allocs, etc)
 471 // RETURN VALUE: 0-ok, 1-fail
 472 //---------------------------------------------------------
 473 int _module_unloader()
 474 {
 475     return 0;
 476 }
 477 
 478 int _module_can_unload()
 479 {
 480     return conf.show_histo == 0;
 481 }
 482 
 483 /******************** Module Information structure ******************/
 484 
 485 libhisto_sym _libhisto =
 486 {
 487     {
 488          0, _module_unloader, _module_can_unload, 0, 0
 489     },
 490 
 491     histogram_process,
 492     gui_osd_draw_histo
 493 };
 494 
 495 ModuleInfo _module_info =
 496 {
 497     MODULEINFO_V1_MAGICNUM,
 498     sizeof(ModuleInfo),
 499     HISTO_VERSION,                              // Module version
 500 
 501     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,                       // Requirements of CHDK version
 502     ANY_PLATFORM_ALLOWED,               // Specify platform dependency
 503 
 504     (int32_t)"Histogram Overlay (dll)",
 505     MTYPE_EXTENSION,
 506 
 507     &_libhisto.base,
 508 
 509     CONF_VERSION,               // CONF version
 510     CAM_SCREEN_VERSION,         // CAM SCREEN version
 511     ANY_VERSION,                // CAM SENSOR version
 512     CAM_INFO_VERSION,           // CAM INFO version
 513 };
 514 
 515 /*************** END OF AUXILARY PART *******************/

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