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

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