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_byte_width;
  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             viewport_height = vid_get_viewport_height();
 139             viewport_byte_width = vid_get_viewport_byte_width();
 140             viewport_size = viewport_height * viewport_byte_width * vid_get_viewport_yscale();
 141             viewport_width = vid_get_viewport_width();
 142             viewport_row_offset = vid_get_viewport_row_offset();
 143             for (c=0; c<5; ++c) {
 144                 memset(histogram_proc[c],0,256*sizeof(unsigned short));
 145                 histo_max[c] = histo_max_center[c] = 0;
 146             }
 147 
 148             histogram_stage=1;
 149             break;
 150 
 151         case 1:
 152         case 2:
 153         case 3:
 154             x = 0;  // count how many blocks we have done on the current row (to skip unused buffer space at end of each row)
 155 #ifndef THUMB_FW
 156 
 157             for (i=(histogram_stage-1)*6; i<viewport_size; i+=HISTO_STEP_SIZE*6) {
 158 #else
 159 
 160 //digic 6
 161 // 16:9     f:8 vh:360 vw:640 vbw:1280 vxo:0 vyo:60
 162 //1x1        f:8 vh:480 vw:480 vbw:1280 vxo:80 vyo:0
 163             int  yp;
 164 //for yp=0,3,6...
 165 //then yp=1,4,7...
 166 //then yp=2,5,8....
 167 
 168             for (yp=(histogram_stage - 1); yp< viewport_height;yp+=3) {
 169               for (x=0;x<viewport_width*2 ;x+=HISTO_STEP_SIZE*4) {
 170                i = x + yp * viewport_byte_width;
 171 #endif
 172 
 173 #ifndef THUMB_FW
 174                 y = img[i+1];
 175                 u = *(signed char*)(&img[i]);
 176                 //if (u&0x00000080) u|=0xFFFFFF00;  // Compiler should handle the unsigned -> signed conversion
 177                 v = *(signed char*)(&img[i+2]);
 178 #else
 179                 unsigned int ibuf = *(unsigned int*)(&img[i&0xfffffffc]);
 180                 u =(signed char)((ibuf&0xff)-128);
 181                 v =(signed char)(((ibuf>>16)&0xff)-128);
 182                 y = (unsigned char)((ibuf>>8)&0xff);
 183 
 184 #endif
 185                 //if (v&0x00000080) v|=0xFFFFFF00;  // Compiler should handle the unsigned -> signed conversion
 186 
 187                 ++histogram_proc[HISTO_Y][y];                       // Y
 188                 hi = clip(((y<<12)          + v*5743 + 2048)>>12);  // R
 189                 ++histogram_proc[HISTO_R][hi];
 190                 hi = clip(((y<<12) - u*1411 - v*2925 + 2048)>>12);  // G
 191                 ++histogram_proc[HISTO_G][hi];
 192                 hi = clip(((y<<12) + u*7258          + 2048)>>12);  // B
 193                 ++histogram_proc[HISTO_B][hi];
 194 
 195 
 196 #ifndef THUMB_FW
 197                 // Handle case where viewport memory buffer is wider than the actual buffer.
 198                 x += HISTO_STEP_SIZE * 2;       // viewport width is measured in blocks of three bytes each even though the data is stored in six byte chunks !
 199                 if (x == viewport_width)
 200                 {
 201                     i += viewport_row_offset;
 202                     x = 0;
 203                 }
 204             } //loop i
 205 #else
 206               }
 207             }
 208 #endif
 209 
 210 
 211 
 212             ++histogram_stage;
 213             break;
 214 
 215         case 4:
 216             for (i=0, c=0; i<HISTO_WIDTH; ++i, c+=2) { // G
 217                 // Merge each pair of values into a single value (for width = 128)
 218                 // Warning: this is optimised for HISTO_WIDTH = 128, don't change the width unless you re-write this code as well.
 219 #ifndef THUMB_FW
 220                 histogram_proc[HISTO_Y][i] = histogram_proc[HISTO_Y][c] + histogram_proc[HISTO_Y][c+1];
 221                 histogram_proc[HISTO_R][i] = histogram_proc[HISTO_R][c] + histogram_proc[HISTO_R][c+1];
 222                 histogram_proc[HISTO_G][i] = histogram_proc[HISTO_G][c] + histogram_proc[HISTO_G][c+1];
 223                 histogram_proc[HISTO_B][i] = histogram_proc[HISTO_B][c] + histogram_proc[HISTO_B][c+1];
 224 #endif
 225                 // Calc combined RGB totals
 226                 histogram_proc[HISTO_RGB][i] = histogram_proc[HISTO_R][i] + histogram_proc[HISTO_G][i] + histogram_proc[HISTO_B][i];
 227             }
 228 
 229             // calculate maximums
 230             for (c=0; c<5; ++c) {
 231                 for (i=0; i<HISTO_WIDTH; ++i) {
 232                     if (histo_max[c]<histogram_proc[c][i])
 233                         histo_max[c]=histogram_proc[c][i];
 234                     if (histo_max_center[c]<histogram_proc[c][i] && i>=conf.histo_ignore_boundary && i<HISTO_WIDTH-conf.histo_ignore_boundary)
 235                         histo_max_center[c]=histogram_proc[c][i];
 236                 }
 237 
 238                 if (histo_max_center[c] > 0) {
 239                     histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max_center[c]);
 240                 } else if (histo_max[c] > 0) {
 241                     histo_max_center_invw[c] = ((float)HISTO_HEIGHT)/histogram_transform((float)histo_max[c]);
 242                 } else {
 243                     histo_max_center_invw[c] = 0.0f;
 244                 }
 245             }
 246 
 247             if (histo_max[HISTO_RGB] > 0) { // over- / under- expos
 248                 under_exposed = (histogram_proc[HISTO_RGB][0]*8
 249                                 +histogram_proc[HISTO_RGB][1]*4
 250                                 +histogram_proc[HISTO_RGB][2]) > exposition_thresh;
 251 
 252                 over_exposed  = (histogram_proc[HISTO_RGB][HISTO_WIDTH-3]
 253                                 +histogram_proc[HISTO_RGB][HISTO_WIDTH-2]*4
 254                                 +histogram_proc[HISTO_RGB][HISTO_WIDTH-1]*8) > exposition_thresh;
 255             } else {
 256                 over_exposed = 0;
 257                 under_exposed = 1;
 258             }
 259 
 260             histogram_stage=5;
 261             break;
 262 
 263         case 5:
 264             for (c=0; c<5; ++c) {
 265                 histo_fill[c]=0;
 266                 for (i=0; i<HISTO_WIDTH; ++i) {
 267                     histogram[c][i] = (histogram_transform((float)histogram_proc[c][i]))*histo_max_center_invw[c];
 268                     if (histogram[c][i] > HISTO_HEIGHT)
 269                         histogram[c][i] = HISTO_HEIGHT;
 270                     histo_fill[c]+=histogram[c][i];
 271                 }
 272             }
 273 
 274             histo_magnification = 0;
 275             if (conf.histo_auto_ajust) {
 276                 if (histo_fill[histo_main] < (HISTO_HEIGHT*HISTO_WIDTH)/5) { // try to ajust if average level is less than 20%
 277                     histo_magnification = (20*HISTO_HEIGHT*HISTO_WIDTH) / histo_fill[histo_main];
 278                     for (c=0; c<5; ++c) {
 279                         for (i=0;i<HISTO_WIDTH;i++) {
 280                             histogram[c][i] = histogram[c][i] * histo_magnification / 100;
 281                             if (histogram[c][i] > HISTO_HEIGHT)
 282                                 histogram[c][i] = HISTO_HEIGHT;
 283                         }
 284                     }
 285                 }
 286             }
 287 
 288             histogram_stage=0;
 289             break;
 290     }
 291 
 292 }
 293 
 294 //-------------------------------------------------------------------
 295 // Histogram display functions
 296 
 297 static void gui_osd_draw_single_histo(int hist, coord x, coord y, int small)
 298 {
 299     twoColors hc = user_color(conf.histo_color);
 300     twoColors hc2 = user_color(conf.histo_color2);
 301 
 302     register unsigned int i, v, threshold;
 303     register color cl, cl_over, cl_bg = BG_COLOR(hc);
 304     coord w=HISTO_WIDTH, h=HISTO_HEIGHT;
 305 
 306     switch (hist) 
 307     {
 308         case HISTO_R: 
 309             cl=COLOR_RED;
 310             break;
 311         case HISTO_G: 
 312             cl=COLOR_GREEN;
 313             break;
 314         case HISTO_B:
 315             cl=COLOR_BLUE;
 316             break;
 317         case HISTO_RGB:
 318         case HISTO_Y:
 319         default:
 320             cl=FG_COLOR(hc);
 321             break;
 322     }
 323 
 324     if (small) {
 325         h>>=1; w>>=1;
 326         for (i=0; i<w; ++i) {
 327             threshold = (histogram[hist][i<<1]+histogram[hist][(i<<1)+1])>>2;
 328 
 329             for (v=1; v<h-1; ++v)
 330                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl:cl_bg);
 331             cl_over = (threshold==h && conf.show_overexp)?BG_COLOR(hc2):cl;
 332             for (; v<h; ++v)
 333                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl_over:cl_bg);
 334         }
 335     } else {
 336         for (i=0; i<w; ++i) {
 337             threshold = histogram[hist][i];
 338 
 339             for (v=1; v<h-3; ++v)
 340                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl:cl_bg);
 341             cl_over = (threshold==h && conf.show_overexp)?BG_COLOR(hc2):cl;
 342             for (; v<h; ++v)
 343                 draw_pixel(x+1+i, y+h-v, (v<=threshold)?cl_over:cl_bg);
 344         }
 345     }
 346 
 347     draw_rectangle(x, y, x+1+w, y+h, hc2, RECT_BORDER1);
 348     //Vertical Lines
 349     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));
 350 }
 351 
 352 //-------------------------------------------------------------------
 353 static void gui_osd_draw_blended_histo(coord x, coord y)
 354 {
 355     twoColors hc = user_color(conf.histo_color);
 356     twoColors hc2 = user_color(conf.histo_color2);
 357 
 358     register unsigned int i, v, red, grn, blu, sel;
 359     color cls[] = {
 360         BG_COLOR(hc),
 361         COLOR_BLUE,
 362         COLOR_GREEN,
 363         COLOR_CYAN,
 364         COLOR_RED,
 365         COLOR_MAGENTA,
 366         COLOR_YELLOW,
 367         COLOR_WHITE
 368     };
 369 
 370     for (i=0; i<HISTO_WIDTH; ++i) {
 371         red = histogram[HISTO_R][i];
 372         grn = histogram[HISTO_G][i];
 373         blu = histogram[HISTO_B][i];
 374 
 375         for (v=1; v<HISTO_HEIGHT; ++v) {
 376             sel = 0;
 377 
 378             if (v < red) sel = 4;
 379             if (v < grn) sel |= 2;
 380             if (v < blu) sel |= 1;
 381 
 382             draw_pixel(x+1+i, y+HISTO_HEIGHT-v, cls[sel]);
 383         }
 384     }
 385 
 386     draw_rectangle(x, y, x+1+HISTO_WIDTH, y+HISTO_HEIGHT, hc2, RECT_BORDER1);
 387     //Vertical lines
 388     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));
 389 
 390 }
 391 
 392 //-------------------------------------------------------------------
 393 void gui_osd_draw_histo(int is_osd_edit)
 394 {
 395     if (is_osd_edit ||
 396         ((camera_info.state.mode_play || !camera_info.state.mode_video) &&
 397          (
 398           ((conf.show_histo==SHOW_HISTO_HALF) && camera_info.state.is_shutter_half_press) ||
 399           ((conf.show_histo==SHOW_HISTO_REC) && camera_info.state.mode_rec && (recreview_hold==0)) ||
 400           ((conf.show_histo==SHOW_HISTO_ALWAYS) && (recreview_hold==0))
 401          )
 402         )
 403        )
 404     {
 405         twoColors hc = user_color(conf.histo_color);
 406         twoColors hc2 = user_color(conf.histo_color2);
 407 
 408         switch (conf.histo_layout)
 409         {
 410             case OSD_HISTO_LAYOUT_Y:
 411                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y, 0);
 412                 break;
 413             case OSD_HISTO_LAYOUT_A_Y:
 414                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 415                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 416                 break;
 417             case OSD_HISTO_LAYOUT_R_G_B:
 418                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x, conf.histo_pos.y, 0);
 419                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 0);
 420                 gui_osd_draw_single_histo(HISTO_B, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT*2, 0);
 421                 break;
 422             case OSD_HISTO_LAYOUT_A_yrgb:
 423                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 424                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 1);
 425                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT, 1);
 426                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 427                 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);
 428                 break;
 429             case OSD_HISTO_LAYOUT_Y_argb:
 430                 gui_osd_draw_single_histo(HISTO_Y, conf.histo_pos.x, conf.histo_pos.y, 0);
 431                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT, 1);
 432                 gui_osd_draw_single_histo(HISTO_R, conf.histo_pos.x+HISTO_WIDTH/2+1, conf.histo_pos.y+HISTO_HEIGHT, 1);
 433                 gui_osd_draw_single_histo(HISTO_G, conf.histo_pos.x, conf.histo_pos.y+HISTO_HEIGHT+HISTO_HEIGHT/2, 1);
 434                 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);
 435                 break;
 436             case OSD_HISTO_LAYOUT_BLEND:
 437                 gui_osd_draw_blended_histo(conf.histo_pos.x, conf.histo_pos.y);
 438                 break;
 439             case OSD_HISTO_LAYOUT_BLEND_Y:
 440                 gui_osd_draw_blended_histo(conf.histo_pos.x, conf.histo_pos.y);
 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_A:
 444             default:
 445                 gui_osd_draw_single_histo(HISTO_RGB, conf.histo_pos.x, conf.histo_pos.y, 0);
 446                 break;
 447         }
 448 
 449         if (conf.histo_layout != OSD_HISTO_LAYOUT_R_G_B)
 450         {
 451             if (under_exposed && conf.show_overexp)
 452             {
 453                 draw_ellipse(conf.histo_pos.x+5, conf.histo_pos.y+5, 3, 3, BG_COLOR(hc2), DRAW_FILLED);
 454             }
 455             if (over_exposed && conf.show_overexp)
 456             {
 457                 draw_ellipse(conf.histo_pos.x+HISTO_WIDTH-5, conf.histo_pos.y+5, 3, 3, BG_COLOR(hc2), DRAW_FILLED);
 458             }
 459         }
 460         if ((conf.show_overexp ) && camera_info.state.is_shutter_half_press && (under_exposed || over_exposed))
 461             draw_string(conf.histo_pos.x+HISTO_WIDTH-FONT_WIDTH*3, conf.histo_pos.y-FONT_HEIGHT, "EXP", hc);
 462         if (conf.histo_auto_ajust){
 463             if (histo_magnification) {
 464                 char osd_buf[64];
 465                 sprintf(osd_buf, " %d.%02dx ", histo_magnification/100, histo_magnification%100);
 466                 draw_string(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, osd_buf, hc);
 467             } else if (is_osd_edit){
 468                 draw_string(conf.histo_pos.x, conf.histo_pos.y-FONT_HEIGHT, " 9.99x ", hc);
 469             } else {
 470                 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);
 471             }
 472         }
 473     }
 474 }
 475 
 476 
 477 // =========  MODULE INIT =================
 478 
 479 /***************** BEGIN OF AUXILARY PART *********************
 480   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
 481  **************************************************************/
 482 
 483 //---------------------------------------------------------
 484 // PURPOSE: Finalize module operations (close allocs, etc)
 485 // RETURN VALUE: 0-ok, 1-fail
 486 //---------------------------------------------------------
 487 int _module_unloader()
 488 {
 489     return 0;
 490 }
 491 
 492 int _module_can_unload()
 493 {
 494     return conf.show_histo == 0;
 495 }
 496 
 497 /******************** Module Information structure ******************/
 498 
 499 libhisto_sym _libhisto =
 500 {
 501     {
 502          0, _module_unloader, _module_can_unload, 0, 0
 503     },
 504 
 505     histogram_process,
 506     gui_osd_draw_histo
 507 };
 508 
 509 ModuleInfo _module_info =
 510 {
 511     MODULEINFO_V1_MAGICNUM,
 512     sizeof(ModuleInfo),
 513     HISTO_VERSION,                              // Module version
 514 
 515     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,                       // Requirements of CHDK version
 516     ANY_PLATFORM_ALLOWED,               // Specify platform dependency
 517 
 518     (int32_t)"Histogram Overlay (dll)",
 519     MTYPE_EXTENSION,
 520 
 521     &_libhisto.base,
 522 
 523     CONF_VERSION,               // CONF version
 524     CAM_SCREEN_VERSION,         // CAM SCREEN version
 525     ANY_VERSION,                // CAM SENSOR version
 526     CAM_INFO_VERSION,           // CAM INFO version
 527 };
 528 
 529 /*************** END OF AUXILARY PART *******************/

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