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

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