root/core/lib_thumb.c

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

DEFINITIONS

This source file includes following definitions.
  1. opendir
  2. opendir_chdk
  3. readdir
  4. readdir
  5. closedir
  6. _ctype
  7. isdigit
  8. isspace
  9. isalpha
  10. isupper
  11. islower
  12. ispunct
  13. isxdigit
  14. iscntrl
  15. tolower
  16. toupper
  17. iscntrl
  18. isalnum
  19. strpbrk
  20. strstr
  21. memchr
  22. get_localtime
  23. GetJpgCount
  24. GetRawCount
  25. vid_get_viewport_image_offset
  26. vid_get_viewport_row_offset
  27. pal_clean
  28. pal_restore
  29. handle_clean_overlay
  30. handle_analog_av_in_rec

   1 // routines compiled as thumb
   2 #include "platform.h"
   3 #include "conf.h"
   4 #include "gui_draw.h"
   5 #include "keyboard.h"
   6 #include "dirent.h"
   7 #include "ctype.h"
   8 
   9 #if defined(CAM_DRYOS)
  10 #include "chdk-dir.c"
  11 #endif
  12 
  13 //---------------------------------------------------------------------
  14 
  15 // CHDK dir functions
  16 
  17 extern int   fw_closedir(void *d);
  18 extern void *fw_opendir(const char* name);
  19 
  20 DIR *opendir(const char* name)
  21 {
  22     return opendir_chdk(name,OPENDIR_FL_NONE);
  23 }
  24 
  25 DIR *opendir_chdk(const char* name, unsigned flags)
  26 {
  27     // Create CHDK DIR structure
  28     DIR *dir = malloc(sizeof(DIR));
  29     // If malloc failed return failure
  30     if (dir == 0) return NULL;
  31 
  32 #if defined(CAM_DRYOS)
  33     extern int get_fstype(void);
  34     // try built-in routine first, but only on FAT
  35     if ((get_fstype() < 4) && (flags & OPENDIR_FL_CHDK_LFN))
  36     {
  37         dir->fw_dir = 0;
  38         dir->cam_DIR = CHDKOpenDir(name);
  39     }
  40     else
  41     {
  42         dir->cam_DIR = NULL;
  43     }
  44     if (!dir->cam_DIR)
  45     {
  46         // try firmware routine if built-in failed
  47         dir->fw_dir = 1;
  48         dir->cam_DIR = fw_opendir(name);
  49     }
  50 #else
  51     (void)flags;
  52     dir->cam_DIR = fw_opendir(name);
  53 #endif
  54 
  55     // Init readdir return value
  56     dir->dir.d_name[0] = 0;
  57 
  58     // If failed clean up and return failure
  59     if (!dir->cam_DIR)
  60     {
  61         free(dir);
  62         return NULL;
  63     }
  64 
  65     return dir;
  66 }
  67 
  68 #ifndef CAM_DRYOS
  69 
  70 // Internal VxWorks dirent structure returned by readdir
  71 struct __dirent
  72 {
  73     char            d_name[100];
  74 };
  75 
  76 struct dirent* readdir(DIR *d)
  77 {
  78     if (d && d->cam_DIR)
  79     {
  80         // Get next entry from firmware function
  81         extern void *fw_readdir(void *d);
  82         struct __dirent *de = fw_readdir(d->cam_DIR);
  83         // Return next directory name if present, else return 0 (end of list)
  84         if (de)
  85         {
  86             strcpy(d->dir.d_name,de->d_name);
  87             return &d->dir;
  88         }
  89         else
  90         {
  91             d->dir.d_name[0] = 0;
  92         }
  93     }
  94     return NULL;
  95 }
  96 
  97 #else // dryos
  98 
  99 struct dirent * readdir(DIR *d)
 100 {
 101     if (d && d->cam_DIR)
 102     {
 103         if (d->fw_dir == 0)
 104         {
 105             CHDKReadDir(d->cam_DIR, d->dir.d_name);
 106         }
 107         else
 108         {
 109             extern int fw_readdir(void *d, void* dd); // DRYOS
 110             fw_readdir(d->cam_DIR, d->dir.d_name);
 111         }
 112         return d->dir.d_name[0]? &d->dir : NULL;
 113     }
 114     return NULL;
 115 }
 116 
 117 #endif // dryos dir functions
 118 
 119 int closedir(DIR *d)
 120 {
 121     int rv = -1;
 122     if (d && d->cam_DIR)
 123     {
 124 #if defined(CAM_DRYOS)
 125         if (d->fw_dir == 0)
 126         {
 127             rv = CHDKCloseDir(d->cam_DIR);
 128         }
 129         else
 130 #endif
 131         rv = fw_closedir(d->cam_DIR);
 132 
 133         // Mark closed (just in case)
 134         d->cam_DIR = 0;
 135         // Free allocated memory
 136         free(d);    
 137     }
 138     return rv;
 139 }
 140 
 141 //----------------------------------------------------------------------------
 142 // Char Wrappers (ARM stubs not required)
 143 
 144 #if CAM_DRYOS
 145 
 146 #define _U      0x01    /* upper */
 147 #define _L      0x02    /* lower */
 148 #define _D      0x04    /* digit */
 149 #define _C      0x20    /* cntrl */
 150 #define _P      0x10    /* punct */
 151 #define _S      0x40    /* white space (space/lf/tab) */
 152 #define _X      0x80    /* hex digit */
 153 #define _SP     0x08    /* hard space (0x20) */
 154 static int _ctype(int c,int t) {
 155     extern unsigned char ctypes[];  // Firmware ctypes table (in stubs_entry.S)
 156     return ctypes[c&0xFF] & t;
 157 }
 158 
 159 int isdigit(int c) { return _ctype(c,_D); }
 160 int isspace(int c) { return _ctype(c,_S); }
 161 int isalpha(int c) { return _ctype(c,(_U|_L)); }
 162 int isupper(int c) { return _ctype(c,_U); }
 163 int islower(int c) { return _ctype(c,_L); }
 164 int ispunct(int c) { return _ctype(c,_P); }
 165 int isxdigit(int c) { return _ctype(c,(_X|_D)); }
 166 int iscntrl(int c) { return _ctype(c,_C); }
 167 
 168 int tolower(int c) { return isupper(c) ? c | 0x20 : c; }
 169 int toupper(int c) { return islower(c) ? c & ~0x20 : c; }
 170 
 171 #else
 172 
 173 // don't want to require the whole ctype table on vxworks just for this one
 174 int iscntrl(int c) { return ((c >=0 && c <32) || c == 127); }
 175 
 176 #endif
 177 
 178 int isalnum(int c) { return (isdigit(c) || isalpha(c)); }
 179 
 180 //----------------------------------------------------------------------------
 181 
 182 #if CAM_DRYOS
 183 char *strpbrk(const char *s, const char *accept)
 184 {
 185     const char *sc1,*sc2;
 186 
 187     for (sc1 = s; *sc1 != '\0'; ++sc1)
 188     {
 189         for (sc2 = accept; *sc2 != '\0'; ++sc2)
 190         {
 191             if (*sc1 == *sc2)
 192                 return (char*)sc1;
 193         }
 194     }
 195     return 0;
 196 }
 197 #endif
 198 
 199 char *strstr(const char *s1, const char *s2)
 200 {
 201     const char *p = s1;
 202     const int len = strlen(s2);
 203 
 204     for (; (p = strchr(p, *s2)) != 0; p++)
 205     {
 206         if (strncmp(p, s2, len) == 0)
 207             return (char*)p;
 208     }
 209     return (0);
 210 }
 211 
 212 #if CAM_DRYOS
 213 void *memchr(const void *s, int c, int n)
 214 {
 215     while (n-- > 0)
 216     {
 217         if (*(char *)s == c)
 218             return (void *)s;
 219         s++;
 220     }
 221     return (void *)0;
 222 }
 223 #endif
 224 
 225 //----------------------------------------------------------------------------
 226 
 227 struct tm *get_localtime()
 228 {
 229     time_t t = time(NULL);
 230     return localtime(&t);
 231 }
 232 
 233 //----------------------------------------------------------------------------
 234 
 235 unsigned int GetJpgCount(void)
 236 {
 237     return strtol(camera_jpeg_count_str(),((void*)0),0);
 238 }
 239 
 240 unsigned int GetRawCount(void)
 241 {
 242     unsigned free_kb = GetFreeCardSpaceKb();
 243     unsigned raw_kb =  camera_sensor.raw_size/1024;
 244     unsigned jpgcount = GetJpgCount();
 245     unsigned avg_jpg_kb = (jpgcount>0)? free_kb/jpgcount : 0;
 246 
 247     // 0.25 raw margin
 248     unsigned margin_kb = raw_kb/4;
 249     if(free_kb <= raw_kb + margin_kb) {
 250         return 0;
 251     }
 252     free_kb -= margin_kb;
 253     return free_kb/(raw_kb+avg_jpg_kb);
 254 }
 255 
 256 //----------------------------------------------------------------------------
 257 
 258 // viewport image offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
 259 // returns the byte offset into the viewport buffer where the image pixels start (to skip any black borders)
 260 // see G12 port for sample implementation
 261 int vid_get_viewport_image_offset() {
 262     return (vid_get_viewport_yoffset() * vid_get_viewport_byte_width() * vid_get_viewport_yscale()) + (vid_get_viewport_xoffset() * 3);
 263 }
 264 
 265 // viewport image offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
 266 // returns the byte offset to skip at the end of a viewport buffer row to get to the next row.
 267 // see G12 port for sample implementation
 268 int vid_get_viewport_row_offset() {
 269 #ifndef THUMB_FW
 270     return (vid_get_viewport_byte_width() * vid_get_viewport_yscale()) - (vid_get_viewport_width_proper() * 6 / 4);
 271 #else
 272     return (vid_get_viewport_byte_width() * vid_get_viewport_yscale()) - (vid_get_viewport_width_proper() * 4 / 2);
 273 #endif
 274 }
 275 
 276 //----------------------------------------------------------------------------
 277 
 278 #ifdef CAM_CLEAN_OVERLAY
 279 /*
 280  * Making the Canon overlay invisible under selected conditions
 281  * Meant to be used on DIGIC 6 models that allow HDMI output in rec mode
 282  * On m3 and m10, same palette (0) is used in rec mode and during recording
 283  * Issues:
 284  * - regardless of setting, modes with color submode icon (such as hybrid auto) continue to display that (blue) icon
 285  * - when exposure controls are used, drop shadow of invisible osd elements may appear on screen
 286  */
 287 extern char **palette_buffer_ptr[];
 288 extern char active_palette_buffer;
 289 extern char palette_control;
 290 static char *palbackup = NULL;      // backup for the original palette
 291 static int palette_is_clean = 0;
 292 static long pending_screenerase = 0;
 293 const unsigned int handled_palette = 0; // model dependent constant, 0 for m3 and m10
 294 void pal_clean() {
 295     if (palette_is_clean) return;
 296     if (active_palette_buffer == handled_palette) {
 297         if (palbackup == NULL) {
 298             palbackup = malloc(256*4); // 256 entries, 4 bytes each
 299             if (palbackup) {
 300                 memcpy(palbackup, *palette_buffer_ptr[handled_palette]+4, 256*4);
 301             }
 302         }
 303         if (palbackup) {
 304             memset(*palette_buffer_ptr[handled_palette]+4, 0, 256*4);
 305             pending_screenerase = get_tick_count() + 50; // arbitrary 50msec delay
 306             palette_is_clean = 1;
 307         }
 308     }
 309 }
 310 void pal_restore() {
 311     if (!palette_is_clean || (palbackup == NULL)) return;
 312     memcpy(*palette_buffer_ptr[handled_palette]+4, palbackup, 256*4);
 313     pending_screenerase = get_tick_count() + 10; // arbitrary 10msec delay
 314     palette_is_clean = 0;
 315 }
 316 void handle_clean_overlay() {
 317     if ((conf.clean_overlay == 1) && camera_info.state.mode_rec) { // clean during rec mode
 318         pal_clean();
 319     }
 320     else if ((conf.clean_overlay == 2) && is_video_recording()) { // clean during video recording only
 321         pal_clean();
 322     }
 323     else {
 324         pal_restore();
 325     }
 326     if (pending_screenerase && (get_tick_count()>=pending_screenerase) && !draw_is_suspended()) {
 327         pending_screenerase = 0;
 328 
 329 #if 1
 330         // following seems to be effective for removing/redrawing Canon overlay
 331         palette_control |= 3; // magic constant, valid for m10 and m3
 332         vid_bitmap_refresh();
 333 #else
 334         // following is for the case when palette_control + vid_bitmap_refresh is not effective
 335         extern void _displayblankscreen();
 336         extern void _undisplayblankscreen();
 337         _displayblankscreen();
 338         _undisplayblankscreen();
 339 #endif
 340     }
 341 }
 342 #endif // CAM_CLEAN_OVERLAY
 343 
 344 #ifdef CAM_UNLOCK_ANALOG_AV_IN_REC
 345 void handle_analog_av_in_rec(void) {
 346     extern void SetVideoOutType(int);
 347     extern int GetVideoOutType(void);
 348     if (!camera_info.state.mode_rec) {
 349         return;
 350     }
 351     int vot = GetVideoOutType();
 352     if(conf.unlock_av_out_in_rec) {
 353         if(get_analog_av_physw_mod() && vot == 0) {
 354             SetVideoOutType(shooting_get_analog_video_standard());
 355         } else if(!get_analog_av_physw_mod() && vot != 0) {
 356             SetVideoOutType(0);
 357         }
 358     } else {
 359         if(vot != 0) {
 360             SetVideoOutType(0);
 361         }
 362     }
 363 }
 364 #endif  // CAM_UNLOCK_ANALOG_AV_IN_REC
 365 //----------------------------------------------------------------------------

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