root/modules/shot_histogram.c

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

DEFINITIONS

This source file includes following definitions.
  1. shot_histogram_set
  2. build_shot_histogram
  3. write_to_file
  4. shot_histogram_get_range
  5. _module_loader
  6. _module_unloader
  7. _module_can_unload

   1 #include "camera_info.h"
   2 #include "conf.h"
   3 #include "shot_histogram.h"
   4 #include "raw.h"
   5 #include "file_counter.h"
   6 
   7 #define SHOT_HISTOGRAM_STEP     31
   8 
   9 // we could use sensor bitdepth here. For now, we just discard low bits if > 10bpp
  10 #define SHOT_HISTOGRAM_SAMPLES  1024
  11 #define SHOT_HISTOGRAM_SIZE     (SHOT_HISTOGRAM_SAMPLES*sizeof(short))
  12 
  13 int running = 0;
  14 
  15 // Buffer to sum raw luminance values
  16 unsigned short shot_histogram[SHOT_HISTOGRAM_SAMPLES];
  17 
  18 // Sensor area to process (not used)
  19 unsigned short shot_margin_left = 0, shot_margin_top = 0, shot_margin_right = 0, shot_margin_bottom = 0;
  20 
  21 // enable or disable shot histogram
  22 int shot_histogram_set(int enable)
  23 {
  24     // If turning shot histogram off, mark module as unloadable
  25     if (!enable)
  26         running = 0;
  27 
  28     return 1;
  29 }
  30 
  31 void build_shot_histogram()
  32 {
  33     // read samples from RAW memory and build an histogram of its luminosity
  34     // actually, it' just reading pixels, ignoring difference between R, G and B,
  35     // we just need an estimate of luminance
  36     if (!running)
  37         return;
  38 
  39     int x, y, x0, x1, y0, y1;
  40 
  41     short p;
  42     memset(shot_histogram,0,SHOT_HISTOGRAM_SIZE);
  43 
  44     // Use sensor active area only
  45     int width  = camera_sensor.active_area.x2 - camera_sensor.active_area.x1;
  46     int height = camera_sensor.active_area.y2 - camera_sensor.active_area.y1;
  47 
  48     // In future, support definition of a sort of "spot metering"
  49     x0 = camera_sensor.active_area.x1 + ((shot_margin_left   * width)  / 10);
  50     x1 = camera_sensor.active_area.x2 - ((shot_margin_right  * width)  / 10);
  51     y0 = camera_sensor.active_area.y1 + ((shot_margin_top    * height) / 10);
  52     y1 = camera_sensor.active_area.y2 - ((shot_margin_bottom * height) / 10);
  53 
  54     // just read one pixel out of SHOT_HISTOGRAM_STEP, one line out of SHOT_HISTOGRAM_STEP
  55     if (camera_sensor.bits_per_pixel == 10)
  56     {
  57         for (y = y0; y < y1; y += SHOT_HISTOGRAM_STEP)
  58             for (x = x0; x < x1; x += SHOT_HISTOGRAM_STEP)
  59             {
  60                 p = get_raw_pixel(x,y);
  61                 shot_histogram[p]++;
  62             }
  63     }
  64     else
  65     {
  66         // > 10bpp compatibility: discard the lowest N bits
  67         int shift = (camera_sensor.bits_per_pixel - 10);
  68         for (y = y0; y < y1; y += SHOT_HISTOGRAM_STEP )
  69             for (x = x0; x < x1; x += SHOT_HISTOGRAM_STEP )
  70             {
  71                 p = get_raw_pixel(x,y) >> shift;
  72                 shot_histogram[p]++;
  73             }
  74     }
  75 }
  76 
  77 void write_to_file()
  78 {
  79     // dump last histogram to file
  80     // for each shoot, creates a HST_nnnn.DAT file containing 2*1024 bytes
  81 
  82     char fn[64];
  83 
  84     // Get path to save raw files
  85     raw_get_path(fn);
  86 
  87     sprintf(fn+strlen(fn), "HST_%04d.DAT", get_target_file_num());
  88 
  89     int fd = open(fn, O_WRONLY|O_CREAT, 0777);
  90     if (fd >= 0)
  91     {
  92         write(fd, shot_histogram, SHOT_HISTOGRAM_SIZE);
  93         close(fd);
  94     }
  95 }
  96 
  97 int shot_histogram_get_range(int histo_from, int histo_to)
  98 {
  99     // Examines the histogram, and returns the percentage of pixels that
 100     // have luminance between histo_from and histo_to
 101     int x, tot, rng;
 102     tot=0;
 103     rng=0;
 104  
 105     if (!running)
 106         return -1;
 107 
 108     for (x = 0 ; x < SHOT_HISTOGRAM_SAMPLES; x++)
 109     {
 110         tot += shot_histogram[x];
 111         if (x>=histo_from && x <= histo_to)
 112         {
 113             rng += shot_histogram[x];
 114         }
 115     }
 116 
 117     return (rng*100+tot/2)/tot;
 118 }
 119 
 120 //-----------------------------------------------------------------------------
 121 int _module_loader()
 122 {
 123     running = 1;
 124     return 0;
 125 }
 126 
 127 int _module_unloader()
 128 {
 129     return 0;
 130 }
 131 
 132 int _module_can_unload()
 133 {
 134     return running == 0;
 135 }
 136 
 137 // =========  MODULE INIT =================
 138 
 139 libshothisto_sym _libshothisto =
 140 {
 141     {
 142          _module_loader, _module_unloader, _module_can_unload, 0, 0
 143     },
 144 
 145     shot_histogram_set,
 146     shot_histogram_get_range,
 147     build_shot_histogram,
 148     write_to_file,
 149 };
 150 
 151 ModuleInfo _module_info =
 152 {
 153     MODULEINFO_V1_MAGICNUM,
 154     sizeof(ModuleInfo),
 155     SHOT_HISTO_VERSION,         // Module version
 156 
 157     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,        // Requirements of CHDK version
 158     ANY_PLATFORM_ALLOWED,       // Specify platform dependency
 159 
 160     (int32_t)"Shot Histogram",
 161     MTYPE_EXTENSION,
 162 
 163     &_libshothisto.base,
 164 
 165     ANY_VERSION,                // CONF version
 166     ANY_VERSION,                // CAM SCREEN version
 167     CAM_SENSOR_VERSION,         // CAM SENSOR version
 168     ANY_VERSION,                // CAM INFO version
 169 
 170     0,
 171 };

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