root/core/raw.c

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

DEFINITIONS

This source file includes following definitions.
  1. raw_prepare_develop
  2. get_raw_image_addr
  3. get_alt_raw_image_addr
  4. raw_get_path
  5. raw_createfile
  6. raw_closefile
  7. raw_savefile
  8. raw_process
  9. set_raw_pixel
  10. get_raw_pixel
  11. patch_bad_pixel
  12. patch_bad_pixels
  13. make_pixel_list

   1 #include "platform.h"
   2 #include "raw_buffer.h"
   3 #include "conf.h"
   4 #include "stdlib.h"
   5 #include "raw.h"
   6 #include "console.h"
   7 #include "math.h"
   8 #include "modules.h"
   9 #include "shot_histogram.h"
  10 #include "gui_lang.h"
  11 #include "gui_mbox.h"
  12 #include "cachebit.h"
  13 #include "remotecap_core.h"
  14 #include "ptp.h" // for remotecap constants
  15 #include "script_api.h" // for script hook
  16 
  17 //-------------------------------------------------------------------
  18 #ifdef CAM_DATE_FOLDER_NAMING
  19   #define RAW_TARGET_DIRECTORY    "A/DCIM/101___01"
  20 #else
  21   #define RAW_TARGET_DIRECTORY    "A/DCIM/100CANON"
  22 #endif
  23 
  24 //#define RAW_TMP_FILENAME        "HDK_RAW.TMP"
  25 #define RAW_TARGET_FILENAME     "%s%04d%s"
  26 #define RAW_BRACKETING_FILENAME "%s%04d_%02d%s" 
  27 
  28 //-------------------------------------------------------------------
  29 #define RAW_DEVELOP_OFF     0
  30 #define RAW_DEVELOP_RAW     1
  31 #define RAW_DEVELOP_DNG     2
  32 
  33 static char fn[64];
  34 static int develop_raw = RAW_DEVELOP_OFF;
  35 
  36 //-------------------------------------------------------------------
  37 void raw_prepare_develop(const char* filename, int prompt)
  38 {
  39     develop_raw = RAW_DEVELOP_OFF;
  40     if (filename)
  41     {
  42         struct stat st;
  43         if ((stat(filename,&st) != 0) || (st.st_size < camera_sensor.raw_size))
  44             return;
  45         if (prompt)
  46             gui_mbox_init((int)"", LANG_RAW_DEVELOP_MESSAGE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
  47         if (st.st_size == camera_sensor.raw_size)
  48             develop_raw = RAW_DEVELOP_RAW;
  49         else
  50             develop_raw = RAW_DEVELOP_DNG;
  51         strcpy(fn,filename);
  52     }
  53 }
  54 
  55 //-------------------------------------------------------------------
  56 void patch_bad_pixels(void);
  57 //-------------------------------------------------------------------
  58 
  59 char* get_raw_image_addr(void) {
  60     char *r=hook_raw_image_addr();
  61     if (!conf.raw_cache) return r;
  62     else return ADR_TO_CACHED(r);
  63 }
  64 
  65 char* get_alt_raw_image_addr(void) {    // return inactive buffer for cameras with multiple RAW buffers (otherwise return active buffer)
  66     char *r=hook_alt_raw_image_addr();
  67     if (!conf.raw_cache) return r;
  68     else return ADR_TO_CACHED(r);
  69 }
  70 //-------------------------------------------------------------------
  71 // Get path to save raw files based on user settings
  72 void raw_get_path(char *path)
  73 {
  74     char rdir[32];
  75 
  76     switch ( conf.raw_in_dir )
  77     {
  78         case 2:
  79             strcpy(path,"A/RAW");
  80             mkdir_if_not_exist(path);
  81             get_target_dir_name(rdir);
  82             strcat(path, &rdir[6]) ;
  83             break ;
  84         case 1:
  85             mkdir_if_not_exist("A/DCIM");
  86             get_target_dir_name(path);
  87             break ;
  88         default:
  89             mkdir_if_not_exist("A/DCIM");
  90             strcpy(path, RAW_TARGET_DIRECTORY);
  91             break ;
  92     }
  93     mkdir_if_not_exist(path);
  94     strcat(path, "/");
  95 }
  96 
  97 /*
  98 create a new raw file and return the file descriptor from open
  99 name and 
 100 create directories as need
 101 should only be called in raw hook
 102 modifies global fn
 103 returns -1 if not enough space for one raw
 104 */
 105 static int raw_create_time; // time raw file was opened, for time stamp
 106 static int raw_br_counter;  // bracketing counter for raw suffix
 107 int raw_createfile(void)
 108 {
 109     int fd;
 110 
 111     // fail if less than one raw + jpeg space free
 112     if(GetRawCount() < 1) {
 113         return -1;
 114     }
 115     raw_create_time = time(NULL);
 116     
 117     raw_get_path(fn);
 118 
 119     if(raw_br_counter && conf.bracketing_add_raw_suffix && (shooting_get_drive_mode()==1)) {
 120         sprintf(fn+strlen(fn), 
 121                 RAW_BRACKETING_FILENAME,
 122                 img_prefixes[conf.raw_prefix],
 123                 get_target_file_num(),
 124                 raw_br_counter,
 125                 conf.dng_raw&&conf.raw_dng_ext ? ".DNG" : img_exts[conf.raw_ext]);
 126     } else {
 127         sprintf(fn+strlen(fn),
 128                 RAW_TARGET_FILENAME,
 129                 img_prefixes[conf.raw_prefix],
 130                 get_target_file_num(),
 131                 conf.dng_raw&&conf.raw_dng_ext ? ".DNG" : img_exts[conf.raw_ext]);
 132     }
 133     fd = open(fn, O_WRONLY|O_CREAT, 0777);
 134 
 135     return fd;
 136 }
 137 
 138 /*
 139 close filed opened by raw_createfile, set timestamp
 140 */
 141 void raw_closefile(int fd)
 142 {
 143     if(fd < 0) {
 144         return;
 145     }
 146 
 147     struct utimbuf t;
 148     t.actime = t.modtime = raw_create_time;
 149     close(fd);
 150     utime(fn, &t);
 151 
 152 }
 153 
 154 // Set in raw_process and used in get_raw_pixel & set_raw_pixel (for performance)
 155 // Don't call set/get_raw_pixel until this value is initialised
 156 static char *rawadr;    // Pointer to current raw image buffer
 157 
 158 // handle actual raw / dng saving to SD
 159 // returns 1 on successful save, otherwise 0
 160 static int raw_savefile(char *rawadr, char *altrawadr) {
 161     int ret = 0;
 162     started();
 163     int timer=get_tick_count();
 164     if (conf.dng_raw)
 165     {
 166         ret = libdng->write_dng(rawadr, altrawadr);
 167     }
 168     else 
 169     {
 170         int fd = raw_createfile();
 171         if(fd >= 0) {
 172             // Write active RAW buffer
 173             write(fd, ADR_TO_UNCACHED(rawadr), camera_sensor.raw_size);
 174             ret = 1;
 175             raw_closefile(fd);
 176         }
 177     }
 178 
 179     if (conf.raw_timer) {
 180         char txt[30];
 181         timer=get_tick_count()-timer;
 182         sprintf(txt, "saving time=%d", timer);
 183         console_add_line(txt);
 184     }
 185 
 186     finished();
 187     return ret;
 188 }
 189 
 190 // processing done when raw hook runs available
 191 void raw_process(void)
 192 {
 193     // Get pointers to RAW buffers (will be the same on cameras that don't have two or more buffers)
 194     rawadr = get_raw_image_addr();
 195     char *altrawadr = get_alt_raw_image_addr();
 196 
 197 #if defined(CAM_CALC_BLACK_LEVEL)
 198     int v1 = get_raw_pixel(4, 4);
 199     int v2 = get_raw_pixel(4, 5);
 200     int v3 = get_raw_pixel(5, 4);
 201     int v4 = get_raw_pixel(5, 5);
 202     int raw_calc_black_level = (v1 + v2 + v3 + v4) / 4;
 203     if (raw_calc_black_level > CAM_BLACK_LEVEL * 2)
 204         camera_sensor.black_level = raw_calc_black_level;
 205     else
 206         camera_sensor.black_level = CAM_BLACK_LEVEL;
 207 #endif
 208 
 209     if ((conf.save_raw && conf.dng_raw && is_raw_enabled()) 
 210         || (remotecap_get_target() & PTP_CHDK_CAPTURE_DNGHDR))
 211     {                             
 212         libdng->capture_data_for_exif();
 213         }
 214 
 215     if (camera_info.state.state_kbd_script_run)
 216         libshothisto->build_shot_histogram();
 217 
 218     libscriptapi->shoot_hook(SCRIPT_SHOOT_HOOK_RAW);
 219 
 220     // count/save badpixels if requested
 221     if (libdng->raw_init_badpixel_bin())
 222     {
 223         return;
 224     }
 225 
 226     if (develop_raw != RAW_DEVELOP_OFF)
 227     {
 228         started();
 229         if (develop_raw == RAW_DEVELOP_DNG)
 230         {
 231             libdng->load_dng_to_rawbuffer(fn, rawadr);
 232         }
 233         else
 234         {
 235             int fd = open(fn, O_RDONLY, 0777);
 236             if (fd >= 0) {
 237                 read(fd, rawadr, camera_sensor.raw_size);
 238                 close(fd);
 239             }
 240         }
 241 #ifdef OPT_CURVES
 242         if (conf.curve_enable)
 243             libcurves->curve_apply();
 244 #endif
 245         finished();
 246         develop_raw = RAW_DEVELOP_OFF;
 247         return;
 248     }
 249 
 250     if (conf.bad_pixel_removal) patch_bad_pixels();
 251 
 252     shooting_bracketing();
 253 
 254     if (conf.tv_bracket_value || conf.av_bracket_value || conf.iso_bracket_value || conf.subj_dist_bracket_value)
 255     {
 256         if (camera_info.state.state_shooting_progress != SHOOTING_PROGRESS_PROCESSING)
 257             raw_br_counter = 1;
 258         else
 259             raw_br_counter++;
 260     }
 261     else
 262         raw_br_counter=0;
 263 
 264     // if any remote cap targets, skip local raw
 265     if (remotecap_get_target())
 266     {
 267         camera_info.state.state_shooting_progress = SHOOTING_PROGRESS_PROCESSING;
 268         remotecap_raw_available(rawadr);
 269     }
 270     else if (!(conf.raw_save_first_only && camera_info.state.state_shooting_progress == SHOOTING_PROGRESS_PROCESSING))
 271     {
 272         camera_info.state.state_shooting_progress = SHOOTING_PROGRESS_PROCESSING;
 273 
 274         if (conf.save_raw && is_raw_enabled())
 275         {
 276             raw_savefile(rawadr,altrawadr);
 277         }
 278     }
 279 
 280 #ifdef OPT_CURVES
 281     if (conf.curve_enable)
 282         libcurves->curve_apply();
 283 #endif
 284 }
 285 
 286 //-------------------------------------------------------------------
 287 
 288 void set_raw_pixel(unsigned int x, unsigned int y, unsigned short value) {
 289 #if CAM_SENSOR_BITS_PER_PIXEL==10
 290     unsigned char* addr=(unsigned char*)rawadr+y*camera_sensor.raw_rowlen+(x/8)*10;
 291     switch (x%8) {
 292         case 0: addr[0]=(addr[0]&0x3F)|(value<<6); addr[1]=value>>2;                  break;
 293         case 1: addr[0]=(addr[0]&0xC0)|(value>>4); addr[3]=(addr[3]&0x0F)|(value<<4); break;
 294         case 2: addr[2]=(addr[2]&0x03)|(value<<2); addr[3]=(addr[3]&0xF0)|(value>>6); break;
 295         case 3: addr[2]=(addr[2]&0xFC)|(value>>8); addr[5]=value;                     break;
 296         case 4: addr[4]=value>>2;                  addr[7]=(addr[7]&0x3F)|(value<<6); break;
 297         case 5: addr[6]=(addr[6]&0x0F)|(value<<4); addr[7]=(addr[7]&0xC0)|(value>>4); break;
 298         case 6: addr[6]=(addr[6]&0xF0)|(value>>6); addr[9]=(addr[9]&0x03)|(value<<2); break;
 299         case 7: addr[8]=value;                     addr[9]=(addr[9]&0xFC)|(value>>8); break;
 300     }
 301 #elif CAM_SENSOR_BITS_PER_PIXEL==12
 302     unsigned char* addr=(unsigned char*)rawadr+y*camera_sensor.raw_rowlen+(x/4)*6;
 303     switch (x%4) {
 304         case 0: addr[0] = (addr[0]&0x0F) | (unsigned char)(value << 4);  addr[1] = (unsigned char)(value >> 4);  break;
 305         case 1: addr[0] = (addr[0]&0xF0) | (unsigned char)(value >> 8);  addr[3] = (unsigned char)value;         break;
 306         case 2: addr[2] = (unsigned char)(value >> 4);  addr[5] = (addr[5]&0x0F) | (unsigned char)(value << 4);  break;
 307         case 3: addr[4] = (unsigned char)value; addr[5] = (addr[5]&0xF0) | (unsigned char)(value >> 8);  break;
 308     }
 309 #elif CAM_SENSOR_BITS_PER_PIXEL==14
 310     unsigned char* addr=(unsigned char*)rawadr+y*camera_sensor.raw_rowlen+(x/8)*14;
 311     switch (x%8) {
 312         case 0: addr[ 0]=(addr[0]&0x03)|(value<< 2); addr[ 1]=value>>6;                                                         break;
 313         case 1: addr[ 0]=(addr[0]&0xFC)|(value>>12); addr[ 2]=(addr[ 2]&0x0F)|(value<< 4); addr[ 3]=value>>4;                   break;
 314         case 2: addr[ 2]=(addr[2]&0xF0)|(value>>10); addr[ 4]=(addr[ 4]&0x3F)|(value<< 6); addr[ 5]=value>>2;                   break;
 315         case 3: addr[ 4]=(addr[4]&0xC0)|(value>> 8); addr[ 7]=value;                                                            break;
 316         case 4: addr[ 6]=value>>6;                   addr[ 9]=(addr[ 9]&0x03)|(value<< 2);                                      break;
 317         case 5: addr[ 8]=value>>4;                   addr[ 9]=(addr[ 9]&0xFC)|(value>>12); addr[11]=(addr[11]&0x0F)|(value<<4); break;
 318         case 6: addr[10]=value>>2;                   addr[11]=(addr[11]&0xF0)|(value>>10); addr[13]=(addr[13]&0x3F)|(value<<6); break;
 319         case 7: addr[12]=value;                      addr[13]=(addr[13]&0xC0)|(value>> 8);                                      break;
 320     }
 321 #else 
 322     #error define set_raw_pixel for sensor bit depth
 323 #endif
 324 }
 325 
 326 //-------------------------------------------------------------------
 327 unsigned short get_raw_pixel(unsigned int x,unsigned  int y) {
 328 #if CAM_SENSOR_BITS_PER_PIXEL==10
 329     unsigned char* addr=(unsigned char*)rawadr+y*camera_sensor.raw_rowlen+(x/8)*10;
 330     switch (x%8) {
 331         case 0: return ((0x3fc&(((unsigned short)addr[1])<<2)) | (addr[0] >> 6));
 332         case 1: return ((0x3f0&(((unsigned short)addr[0])<<4)) | (addr[3] >> 4));
 333         case 2: return ((0x3c0&(((unsigned short)addr[3])<<6)) | (addr[2] >> 2));
 334         case 3: return ((0x300&(((unsigned short)addr[2])<<8)) | (addr[5]));
 335         case 4: return ((0x3fc&(((unsigned short)addr[4])<<2)) | (addr[7] >> 6));
 336         case 5: return ((0x3f0&(((unsigned short)addr[7])<<4)) | (addr[6] >> 4));
 337         case 6: return ((0x3c0&(((unsigned short)addr[6])<<6)) | (addr[9] >> 2));
 338         case 7: return ((0x300&(((unsigned short)addr[9])<<8)) | (addr[8]));
 339     }
 340 #elif CAM_SENSOR_BITS_PER_PIXEL==12
 341     unsigned char* addr=(unsigned char*)rawadr+y*camera_sensor.raw_rowlen+(x/4)*6;
 342     switch (x%4) {
 343         case 0: return ((unsigned short)(addr[1])        << 4) | (addr[0] >> 4);
 344         case 1: return ((unsigned short)(addr[0] & 0x0F) << 8) | (addr[3]);
 345         case 2: return ((unsigned short)(addr[2])        << 4) | (addr[5] >> 4);
 346         case 3: return ((unsigned short)(addr[5] & 0x0F) << 8) | (addr[4]);
 347     }
 348 #elif CAM_SENSOR_BITS_PER_PIXEL==14
 349     unsigned char* addr=(unsigned char*)rawadr+y*camera_sensor.raw_rowlen+(x/8)*14;
 350     switch (x%8) {
 351         case 0: return ((unsigned short)(addr[ 1])        <<  6) | (addr[ 0] >> 2);
 352         case 1: return ((unsigned short)(addr[ 0] & 0x03) << 12) | (addr[ 3] << 4) | (addr[ 2] >> 4);
 353         case 2: return ((unsigned short)(addr[ 2] & 0x0F) << 10) | (addr[ 5] << 2) | (addr[ 4] >> 6);
 354         case 3: return ((unsigned short)(addr[ 4] & 0x3F) <<  8) | (addr[ 7]);
 355         case 4: return ((unsigned short)(addr[ 6])        <<  6) | (addr[ 9] >> 2);
 356         case 5: return ((unsigned short)(addr[ 9] & 0x03) << 12) | (addr[ 8] << 4) | (addr[11] >> 4);
 357         case 6: return ((unsigned short)(addr[11] & 0x0F) << 10) | (addr[10] << 2) | (addr[13] >> 6);
 358         case 7: return ((unsigned short)(addr[13] & 0x3F) <<  8) | (addr[12]);
 359     }
 360 #else 
 361     #error define get_raw_pixel for sensor bit depth
 362 #endif
 363     return 0;
 364 }
 365 
 366 //-------------------------------------------------------------------
 367 void patch_bad_pixel(unsigned int x,unsigned  int y) {
 368     int sum=0;
 369     int nzero=0;
 370     int i,j;
 371     int val;
 372     if ((x>=2) && (x<camera_sensor.raw_rowpix-2) && (y>=2) && (y<camera_sensor.raw_rows-2)) {
 373         if ((conf.bad_pixel_removal==1) || (conf.save_raw && conf.dng_raw)) {  // interpolation or DNG saving
 374             for (i=-2; i<=2; i+=2)
 375                 for (j=-2; j<=2; j+=2)
 376                     if ((i!=0) && (j!=0)) {
 377                         val=get_raw_pixel(x+i, y+j);
 378                         if (val) {sum+=val; nzero++;}
 379                     }
 380                 if (nzero) set_raw_pixel(x,y,sum/nzero);
 381         } else if (conf.bad_pixel_removal==2)  // or this makes RAW converter (internal/external)
 382             set_raw_pixel(x,y,0);
 383     }
 384 }
 385 
 386 struct point{
 387     int x;
 388     int y;
 389     struct point *next;
 390 } *pixel_list=NULL;
 391 
 392 void patch_bad_pixels(void) {
 393     struct point *pixel=pixel_list;
 394     while (pixel) {
 395         patch_bad_pixel((*pixel).x,(*pixel).y);
 396         pixel=(*pixel).next;
 397     }
 398 }
 399 
 400 int make_pixel_list(char * ptr, int size) {
 401     int x,y;
 402     struct point *pixel;
 403     char *endptr;
 404 
 405     if ( size <=0 ) return 0;
 406 
 407     while(*ptr) {
 408         while (*ptr==' ' || *ptr=='\t') ++ptr;    // whitespaces
 409         x=strtol(ptr, &endptr, 0);
 410         if (endptr != ptr) {
 411             ptr = endptr;
 412             if (*ptr++==',') {
 413                 while (*ptr==' ' || *ptr=='\t') ++ptr;    // whitespaces
 414                 if (*ptr!='\n' && *ptr!='\r') {
 415                     y=strtol(ptr, &endptr, 0);
 416                     if (endptr != ptr) {
 417                         ptr = endptr;
 418                         pixel=malloc(sizeof(struct point));
 419                         if (pixel) {
 420                             (*pixel).x=x;
 421                             (*pixel).y=y;
 422                             (*pixel).next=pixel_list;
 423                             pixel_list=pixel;
 424                         }
 425                     }
 426                 }
 427             }
 428         }
 429         while (*ptr && *ptr!='\n') ++ptr;    // unless end of line
 430         if (*ptr) ++ptr;
 431     }
 432     return 0;
 433 }

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