- Timestamp:
- 09/02/10 21:21:27 (3 years ago)
- Location:
- trunk
- Files:
-
- 11 modified
-
Makefile (modified) (5 diffs)
-
core/bitvector.c (modified) (5 diffs)
-
core/bitvector.h (modified) (2 diffs)
-
core/edgeoverlay.c (modified) (28 diffs)
-
core/gui.c (modified) (2 diffs)
-
include/camera.h (modified) (1 diff)
-
platform/sx20/sub/102b/boot.c (modified) (3 diffs)
-
platform/sx20/sub/102b/capt_seq.c (modified) (3 diffs)
-
platform/sx20/sub/102b/stubs_auto.S (modified) (1 diff)
-
platform/sx20/sub/102d/boot.c (modified) (1 diff)
-
platform/sx20/sub/102d/stubs_entry_2.S (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Makefile
r928 r931 235 235 $(MAKE) -s --no-print-directory PLATFORM=s90 PLATFORMSUB=101a NO_INC_BUILD=1 firzipsub 236 236 $(MAKE) -s --no-print-directory PLATFORM=s90 PLATFORMSUB=101c NO_INC_BUILD=1 firzipsub 237 #$(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102b NO_INC_BUILD=1 firzipsub237 $(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102b NO_INC_BUILD=1 firzipsub 238 238 $(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102d NO_INC_BUILD=1 firzipsub 239 239 $(MAKE) -s --no-print-directory PLATFORM=ixus85_sd770 PLATFORMSUB=100a NO_INC_BUILD=1 firzipsub … … 275 275 mv $(topdir)bin/$(VER)-s90-101c-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-s90-101c-$(BUILD_NUMBER)_BETA.zip 276 276 mv $(topdir)bin/$(VER)-ixus100_sd780-100c-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-ixus100_sd780-100c-$(BUILD_NUMBER)_BETA.zip 277 #mv $(topdir)bin/$(VER)-sx20-102b-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-sx20-102b-$(BUILD_NUMBER)_BETA.zip278 mv $(topdir)bin/$(VER)-sx20-102d-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-sx20-102d-$(BUILD_NUMBER) _BETA.zip277 mv $(topdir)bin/$(VER)-sx20-102b-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-sx20-102b-$(BUILD_NUMBER).zip 278 mv $(topdir)bin/$(VER)-sx20-102d-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-sx20-102d-$(BUILD_NUMBER).zip 279 279 mv $(topdir)bin/$(VER)-ixus85_sd770-100a-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-ixus85_sd770-100a-$(BUILD_NUMBER)_BETA.zip 280 280 #mv $(topdir)bin/$(VER)-ixus95_sd1200-100c-$(BUILD_NUMBER).zip $(topdir)bin/$(VER)-ixus95_sd1200-100c-$(BUILD_NUMBER)_BETA.zip … … 385 385 $(MAKE) -s --no-print-directory PLATFORM=s90 PLATFORMSUB=101a NO_INC_BUILD=1 firzipsubcomplete 386 386 $(MAKE) -s --no-print-directory PLATFORM=s90 PLATFORMSUB=101c NO_INC_BUILD=1 firzipsubcomplete 387 #$(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102b NO_INC_BUILD=1 firzipsubcomplete387 $(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102b NO_INC_BUILD=1 firzipsubcomplete 388 388 $(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102d NO_INC_BUILD=1 firzipsubcomplete 389 389 $(MAKE) -s --no-print-directory PLATFORM=ixus85_sd770 PLATFORMSUB=100a NO_INC_BUILD=1 firzipsubcomplete … … 458 458 mv $(topdir)bin/s90-101c-$(BUILD_NUMBER)-full.zip $(topdir)bin/s90-101c-$(BUILD_NUMBER)-full_BETA.zip 459 459 mv $(topdir)bin/s90-101c-$(BUILD_NUMBER).zip $(topdir)bin/s90-101c-$(BUILD_NUMBER)_BETA.zip 460 #mv $(topdir)bin/sx20-102b-$(BUILD_NUMBER)-full.zip $(topdir)bin/sx20-102b-$(BUILD_NUMBER)-full_BETA.zip461 #mv $(topdir)bin/sx20-102b-$(BUILD_NUMBER).zip $(topdir)bin/sx20-102b-$(BUILD_NUMBER)_BETA.zip462 mv $(topdir)bin/sx20-102d-$(BUILD_NUMBER)-full.zip $(topdir)bin/sx20-102d-$(BUILD_NUMBER)-full _BETA.zip463 mv $(topdir)bin/sx20-102d-$(BUILD_NUMBER).zip $(topdir)bin/sx20-102d-$(BUILD_NUMBER) _BETA.zip460 mv $(topdir)bin/sx20-102b-$(BUILD_NUMBER)-full.zip $(topdir)bin/sx20-102b-$(BUILD_NUMBER)-full.zip 461 mv $(topdir)bin/sx20-102b-$(BUILD_NUMBER).zip $(topdir)bin/sx20-102b-$(BUILD_NUMBER).zip 462 mv $(topdir)bin/sx20-102d-$(BUILD_NUMBER)-full.zip $(topdir)bin/sx20-102d-$(BUILD_NUMBER)-full.zip 463 mv $(topdir)bin/sx20-102d-$(BUILD_NUMBER).zip $(topdir)bin/sx20-102d-$(BUILD_NUMBER).zip 464 464 mv $(topdir)bin/ixus85_sd770-100a-$(BUILD_NUMBER)-full.zip $(topdir)bin/ixus85_sd770-100a-$(BUILD_NUMBER)-full_BETA.zip 465 465 mv $(topdir)bin/ixus85_sd770-100a-$(BUILD_NUMBER).zip $(topdir)bin/ixus85_sd770-100a-$(BUILD_NUMBER)_BETA.zip … … 569 569 $(MAKE) -s --no-print-directory PLATFORM=s90 PLATFORMSUB=101a NO_INC_BUILD=1 clean 570 570 $(MAKE) -s --no-print-directory PLATFORM=s90 PLATFORMSUB=101c NO_INC_BUILD=1 clean 571 #$(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102b NO_INC_BUILD=1 clean571 $(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102b NO_INC_BUILD=1 clean 572 572 $(MAKE) -s --no-print-directory PLATFORM=sx20 PLATFORMSUB=102d NO_INC_BUILD=1 clean 573 573 $(MAKE) -s --no-print-directory PLATFORM=ixus85_sd770 PLATFORMSUB=100a NO_INC_BUILD=1 clean -
trunk/core/bitvector.c
r928 r931 23 23 24 24 // Utility function. Use bv_set instead. 25 static inline void bv_setbit( bit_vector_t* bm, int pos, int val)25 static inline void bv_setbit(const bit_vector_t* bm, int pos, int val) 26 26 { 27 27 int bp = pos - ((pos >> 3) << 3); … … 30 30 else 31 31 bm->ptr[pos >> 3] |= (1 << bp); 32 33 // Following ASM code is bad. It crashes the camera, but why?34 // It'd be very nice to replace this function with an inline35 // assembly macro in the future (the same for bv_getbit()).36 // The compiler seems to generate suboptimal ASM for me,37 // but this is performance critical code.38 //39 // char t = bm->ptr[pos >> 3];40 // asm volatile (41 // ".syntax unified\n"42 // "MOV %[pos], %[pos], lsr #3\n" // r1 = pos >> 343 // "SUB %[pos], %[pos], %[pos], lsl #3\n" // pos -= pos<<344 // "MOV r2, #1\n" // r2 = 145 // "MOV r2, r2, lsl %[pos]\n" // r2 <<= pos46 // "CMP %[val], #0\n" // val == 047 // "ITE EQ\n" // if48 // "BICEQ %[t], %[t], r2\n" // &= ~(1 << bp)49 // "ORRNE %[t], %[t], r2\n" // |= (1 << bp)50 // ".syntax divided"51 // : [t]"+r"(t)52 // : [val]"r"(val), [pos]"r"(pos)53 // : "r2", "cc"54 // );55 // bm->ptr[pos >> 3] = t;56 57 32 } 58 33 59 34 // Utility function. Use bv_get instead. 60 static inline int bv_getbit( bit_vector_t* bm, int pos)35 static inline int bv_getbit(const bit_vector_t* bm, int pos) 61 36 { 62 37 // Note: bv_get() and other code rely on this … … 66 41 67 42 int bp = pos - ((pos >> 3) << 3); 68 return ( (bm->ptr[pos >> 3] & (1 << bp)) > 0) ? 1 : 0;43 return (bm->ptr[pos >> 3] & (1 << bp)) >> bp; 69 44 } 70 45 71 void bv_set( bit_vector_t* bm, int pos, int val)46 void bv_set(const bit_vector_t* bm, int pos, int val) 72 47 { 73 int i ;48 int i = bm->nBits - 1; 74 49 int bitpos = pos * bm->nBits; 75 for (i = 0; i < bm->nBits; ++i)50 do 76 51 { 77 52 bv_setbit(bm, bitpos + i, val & (1<<i)); 78 } 53 }while(--i >= 0); 79 54 } 80 55 81 56 // Same as bv_set, but sets val to two consecutive elements 82 57 // instead of just one. 83 void bv_set2( bit_vector_t* bm, int pos, int val)58 void bv_set2(const bit_vector_t* bm, int pos, int val) 84 59 { 85 60 int i; … … 95 70 // Same as bv_set, but sets val to four consecutive elements 96 71 // instead of just one. 97 void bv_set4( bit_vector_t* bm, int pos, int val)72 void bv_set4(const bit_vector_t* bm, int pos, int val) 98 73 { 99 74 int i; … … 109 84 } 110 85 111 int bv_get( bit_vector_t* bm, int pos)86 int bv_get(const bit_vector_t* bm, int pos) 112 87 { 113 int i;114 88 int ret = 0; 89 int i = bm->nBits - 1; 115 90 int bitpos = pos * bm->nBits; 116 for (i = 0; i < bm->nBits; ++i)91 do 117 92 { 118 93 ret |= (bv_getbit(bm, bitpos + i) << i); 119 } 94 }while(--i >= 0); 120 95 121 96 return ret; -
trunk/core/bitvector.h
r928 r931 5 5 { 6 6 int nBits; 7 char* ptr;7 unsigned char* ptr; 8 8 int ptrLen; 9 9 int nElem; … … 11 11 12 12 bit_vector_t* bv_create(int len, int nbits); 13 void bv_set( bit_vector_t* bm, int pos, int val);14 void bv_set2( bit_vector_t* bm, int pos, int val);15 void bv_set4( bit_vector_t* bm, int pos, int val);16 int bv_get( bit_vector_t* bm, int pos);13 void bv_set(const bit_vector_t* bm, int pos, int val); 14 void bv_set2(const bit_vector_t* bm, int pos, int val); 15 void bv_set4(const bit_vector_t* bm, int pos, int val); 16 int bv_get(const bit_vector_t* bm, int pos) __attribute__((pure)); 17 17 void bv_free(bit_vector_t* bm); 18 18 -
trunk/core/edgeoverlay.c
r928 r931 6 6 #include "gui_draw.h" 7 7 #include "bitvector.h" 8 8 9 9 // the way we save edge overlays on their own... 10 10 #define EDGE_FILE_PREFIX "EDG_" 11 11 #define EDGE_FILE_FORMAT EDGE_FILE_PREFIX "%04d.edg" 12 12 #define EDGE_SLICES 2 13 13 14 typedef enum _edge_fsm_state 14 15 { … … 16 17 EDGE_FROZEN 17 18 } edge_fsm_state_t; 18 19 19 20 static edge_fsm_state_t fsm_state = EDGE_LIVE; 20 21 static bit_vector_t* edgebuf = NULL; 21 22 static int xoffset = 0, yoffset = 0; 22 23 static unsigned char* smbuf = NULL; 24 25 static int slice = 0; // the current slice of the frame we are calculating/drawing 26 static int slice_height; // the height of a single slice 27 23 28 static int viewport_size; // whole viewport size in bytes ?? 24 29 static int viewport_width; // screenwidth * 3, width in bytes of one viewport line ?? … … 27 32 static int viewportw; //nandoide , width of viewport (not necessarily equal to width of screen) 28 33 #endif 29 34 30 35 static void get_viewport_size() 31 36 { 32 37 // since screen_height is used in the drawing downwards, we should use it 33 38 // here too to calculate the buffer we need... 34 39 35 40 #if CAM_USES_ASPECT_CORRECTION//nandoide sept-2009 get the viewport dimensions, not the screen dimensions, on sx200is they aren't the same. 36 41 viewport_height = vid_get_viewport_height()-EDGE_HMARGIN*2; //don't trace bottom lines 37 42 viewportw = vid_get_viewport_width(); 38 43 viewport_width = viewportw * 3; 39 viewport_size = viewport_height * viewport_width;40 44 #else 41 45 viewport_height = screen_height;//vid_get_viewport_height(); 42 46 viewport_width = screen_width * 3; 43 viewport_size = viewport_height * screen_width * 3;44 47 #endif 45 } 46 48 49 viewport_size = viewport_height * viewport_width; 50 slice_height = viewport_height / EDGE_SLICES; 51 52 } 53 47 54 static void ensure_allocate_imagebuffer() 48 55 { … … 50 57 { 51 58 edgebuf = bv_create(viewport_size, 1); 52 } 53 } 54 59 if (edgebuf != NULL) 60 memset(edgebuf->ptr, 0, edgebuf->ptrLen); 61 } 62 if (conf.edge_overlay_filter && (smbuf == NULL)) 63 { 64 smbuf = (unsigned char*)malloc(viewport_width*3); 65 if (smbuf != NULL) 66 memset(smbuf, 0, viewport_width*3); 67 else 68 { 69 // Disable filtering if we do not have enough memory for it 70 conf.edge_overlay_filter = 0; 71 } 72 } 73 } 74 55 75 static void reset_edge_overlay() 56 76 { 77 if (smbuf != NULL) 78 { 79 free(smbuf); 80 smbuf = NULL; 81 } 82 57 83 bv_free(edgebuf); 58 84 edgebuf = NULL; 59 85 fsm_state = EDGE_LIVE; 60 } 61 86 slice = 0; 87 } 88 62 89 static int is_buffer_ready() 63 90 { … … 66 93 return 1; 67 94 } 68 95 69 96 // scans a filename for the number of the edge detection file it contains 70 97 static int get_edge_file_num(const char* fn) … … 89 116 return num; 90 117 } 91 118 92 119 // saves the actual active overlay data to a file. 93 120 void save_edge_overlay(void) 94 121 { 95 122 96 123 char fn[64]; 97 124 char msg[64]; … … 104 131 static struct utimbuf t; 105 132 // nothing to save? then dont save 106 133 107 134 if( !is_buffer_ready() ) 108 135 { … … 110 137 return; 111 138 } 112 139 113 140 zoom = shooting_get_zoom(); 114 141 115 142 // first figure out the most appropriate filename to use 116 143 d = opendir(EDGE_SAVE_DIR); … … 119 146 return; 120 147 } 121 148 122 149 while( (de = readdir(d)) ) 123 150 { … … 146 173 closedir(d); 147 174 } 148 175 149 176 // load the edge overlay from a file 150 177 void load_edge_overlay(const char* fn) 151 178 { 152 179 FILE *fd; 153 int ret,ret2;154 180 int zoom; 155 181 156 182 get_viewport_size(); 157 183 ensure_allocate_imagebuffer( ); … … 159 185 if( fd != NULL ) 160 186 { 161 ret = fread(edgebuf->ptr,edgebuf->ptrLen,1,fd);162 ret2 = fread (&zoom,sizeof(zoom),1,fd);187 int ret = fread(edgebuf->ptr,edgebuf->ptrLen,1,fd); 188 int ret2 = fread (&zoom,sizeof(zoom),1,fd); 163 189 fclose(fd); 164 190 if( (ret == 1) && (ret2 == 1) ) … … 172 198 } 173 199 } 174 175 static void average_filter_row(const unsigned char* ptrh1, // previous row176 const unsigned char* ptrh2, // current row177 const unsigned char* ptrh3, // next row178 unsigned char* smptr ) // write results here200 201 static void average_filter_row(const unsigned char* ptrh1, // previous row 202 const unsigned char* ptrh2, // current row 203 const unsigned char* ptrh3, // next row 204 unsigned char* smptr ) // write results here 179 205 { 180 206 int x; 181 207 #if CAM_USES_ASPECT_CORRECTION 182 for (x=12; x<(viewportw - 4) * 3; x+=6)208 const int x_max = (viewportw - 2) * 3; 183 209 #else 184 for (x=12; x<(screen_width - 4) * 3; x+=6)210 const int x_max = (screen_width - 2) * 3; 185 211 #endif 212 213 for (x=6; x<x_max; x+=6) 186 214 { 187 215 *(smptr + x + 1) = (*(ptrh1 + x - 1) + 188 216 *(ptrh1 + x + 1) + 189 217 *(ptrh1 + x + 3) + 190 218 191 219 *(ptrh2 + x - 1) + 192 220 *(ptrh2 + x + 1) + 193 221 *(ptrh2 + x + 3) + 194 222 195 223 *(ptrh3 + x - 1) + 196 224 *(ptrh3 + x + 1) + 197 *(ptrh3 + x + 3)) / 9 ;198 225 *(ptrh3 + x + 3)) / 9u; 226 199 227 *(smptr + x + 3) = (*(ptrh1 + x + 1) + 200 228 *(ptrh1 + x + 3) + 201 229 *(ptrh1 + x + 4) + 202 230 203 231 *(ptrh2 + x + 1) + 204 232 *(ptrh2 + x + 3) + 205 233 *(ptrh2 + x + 4) + 206 234 207 235 *(ptrh3 + x + 1) + 208 236 *(ptrh3 + x + 3) + 209 *(ptrh3 + x + 4)) / 9 ;210 237 *(ptrh3 + x + 4)) / 9u; 238 211 239 *(smptr + x + 4) = (*(ptrh1 + x + 3) + 212 240 *(ptrh1 + x + 4) + 213 241 *(ptrh1 + x + 5) + 214 242 215 243 *(ptrh2 + x + 3) + 216 244 *(ptrh2 + x + 4) + 217 245 *(ptrh2 + x + 5) + 218 246 219 247 *(ptrh3 + x + 3) + 220 248 *(ptrh3 + x + 4) + 221 *(ptrh3 + x + 5)) / 9 ;222 249 *(ptrh3 + x + 5)) / 9u; 250 223 251 *(smptr + x + 5) = (*(ptrh1 + x + 4) + 224 252 *(ptrh1 + x + 5) + 225 253 *(ptrh1 + x + 7) + 226 254 227 255 *(ptrh2 + x + 4) + 228 256 *(ptrh2 + x + 5) + 229 257 *(ptrh2 + x + 7) + 230 258 231 259 *(ptrh3 + x + 4) + 232 260 *(ptrh3 + x + 5) + 233 *(ptrh3 + x + 7)) / 9 ;234 } 235 } 236 261 *(ptrh3 + x + 7)) / 9u; 262 } 263 } 264 237 265 // Sobel edge detector 238 static void calc_edge_overlay() 239 { 266 static int calc_edge_overlay() 267 { 268 int shutter_fullpress = kbd_is_key_pressed(KEY_SHOOT_FULL); 269 240 270 const int bPlayMode = (mode_get() & MODE_MASK) == MODE_PLAY; 241 271 const unsigned char* img = bPlayMode ? vid_get_viewport_fb_d() : vid_get_viewport_fb(); 242 const unsigned char * ptrh1 = NULL; // previous pixel line 243 const unsigned char * ptrh2 = NULL; // current pixel line 244 const unsigned char * ptrh3 = NULL; // next pixel line 245 unsigned char* smbuf = NULL; 246 unsigned char * smptr = NULL; // pointer to line in smbuf 247 int x, y; 272 const unsigned char* ptrh1 = NULL; // previous pixel line 273 const unsigned char* ptrh2 = NULL; // current pixel line 274 const unsigned char* ptrh3 = NULL; // next pixel line 275 unsigned char* smptr = NULL; // pointer to line in smbuf 276 int x, y, xdiv3; 248 277 int conv1, conv2; 249 250 const int y_min = EDGE_HMARGIN ;251 const int y_max = EDGE_HMARGIN + viewport_height;278 279 const int y_min = EDGE_HMARGIN+ slice *slice_height; 280 const int y_max = EDGE_HMARGIN+(slice+1)*slice_height; 252 281 const int x_min = 6; 253 282 #if CAM_USES_ASPECT_CORRECTION 254 const int x_max = (viewportw - 4) * 3;283 const int x_max = (viewportw - 2) * 3; 255 284 #else 256 const int x_max = (screen_width - 4) * 3;285 const int x_max = (screen_width - 2) * 3; 257 286 #endif 258 287 259 xoffset =0; 260 yoffset =0; 261 288 const int vp_width = viewport_width; 289 290 xoffset = 0; 291 yoffset = 0; 292 262 293 // Reserve buffers 263 294 ensure_allocate_imagebuffer(); 264 if( !is_buffer_ready() ) return; 265 266 // Clear all edges, if any 267 memset(edgebuf->ptr, 0, edgebuf->ptrLen); 268 269 // In every 6 bytes four pixels are described in the 295 if( !is_buffer_ready() ) return 0; 296 297 // In every 6 bytes the Y of four pixels are described in the 270 298 // viewport (UYVYYY format). For edge detection we only 271 299 // consider the second in the current and the first 272 300 // in the next pixel. 273 274 301 302 // Clear all edges in the current slice 303 int compressed_slice = edgebuf->ptrLen / EDGE_SLICES; 304 memset(edgebuf->ptr + slice*compressed_slice, 0, compressed_slice); 305 275 306 if (conf.edge_overlay_filter) 276 307 { 277 smbuf = (unsigned char*)malloc(viewport_width*3);278 memset(smbuf, 0, viewport_width*3);279 if (smbuf==NULL)280 return;281 282 308 // Prefill smbuf with three lines of avergae-filtered data. 283 309 // This looks much more complex then it actually is. … … 287 313 for (y = -1; y <= 1; ++y) 288 314 { 289 ptrh1 = img + (EDGE_HMARGIN+y-1) * viewport_width; 290 ptrh2 = img + (EDGE_HMARGIN+y ) * viewport_width; 291 ptrh3 = img + (EDGE_HMARGIN+y+1) * viewport_width; 292 smptr = smbuf + (y+1) * viewport_width; 293 315 shutter_fullpress |= kbd_is_key_pressed(KEY_SHOOT_FULL); 316 317 ptrh1 = img + (y_min+y-1) * vp_width; 318 ptrh2 = img + (y_min+y ) * vp_width; 319 ptrh3 = img + (y_min+y+1) * vp_width; 320 smptr = smbuf + (y+1) * vp_width; 321 294 322 average_filter_row(ptrh1, ptrh2, ptrh3, smptr); 295 323 } 296 324 } 297 325 298 326 for (y = y_min; y < y_max; ++y) 299 327 { 328 shutter_fullpress |= kbd_is_key_pressed(KEY_SHOOT_FULL); 329 300 330 if (conf.edge_overlay_filter) 301 331 { … … 305 335 // By storing only three lines of smoothed picture 306 336 // in memory, we save memory. 307 337 308 338 // Shift 309 memcpy(smbuf+v iewport_width*0, smbuf+viewport_width*1, viewport_width);310 memcpy(smbuf+v iewport_width*1, smbuf+viewport_width*2, viewport_width);311 339 memcpy(smbuf+vp_width*0, smbuf+vp_width*1, vp_width); 340 memcpy(smbuf+vp_width*1, smbuf+vp_width*2, vp_width); 341 312 342 // Filter new line 313 ptrh1 = img + y * v iewport_width;314 ptrh2 = img + (y+1) * viewport_width;315 ptrh3 = img + (y+2) * v iewport_width;316 smptr = smbuf + 2 * viewport_width;343 ptrh1 = img + y * vp_width; 344 ptrh2 = img + (y+1) * vp_width; 345 ptrh3 = img + (y+2) * vp_width; 346 smptr = smbuf + 2 * vp_width; 317 347 average_filter_row(ptrh1, ptrh2, ptrh3, smptr); 318 319 ptrh1 = smbuf + 0 * v iewport_width;320 ptrh2 = smbuf + 1 * v iewport_width;321 ptrh3 = smbuf + 2 * v iewport_width;348 349 ptrh1 = smbuf + 0 * vp_width; 350 ptrh2 = smbuf + 1 * vp_width; 351 ptrh3 = smbuf + 2 * vp_width; 322 352 } 323 353 else 324 354 { 325 ptrh1 = img + (y-1) * v iewport_width;326 ptrh2 = img + y * v iewport_width;327 ptrh3 = img + (y+1) * v iewport_width;328 } 329 355 ptrh1 = img + (y-1) * vp_width; 356 ptrh2 = img + y * vp_width; 357 ptrh3 = img + (y+1) * vp_width; 358 } 359 330 360 // Now we do sobel on the current line 331 332 for (x = x_min ; x < x_max; x += 6)361 362 for (x = x_min, xdiv3 = x_min/3; x < x_max; x += 6, xdiv3 += 2) 333 363 { 334 364 // convolve vert (second Y) 335 365 conv1 = *(ptrh1 + x + 1) * ( 1) + 336 366 *(ptrh1 + x + 4) * (-1) + 337 367 338 368 *(ptrh2 + x + 1) * ( 2) + 339 369 *(ptrh2 + x + 4) * (-2) + 340 370 341 371 *(ptrh3 + x + 1) * ( 1) + 342 372 *(ptrh3 + x + 4) * (-1); 343 373 if (conv1 < 0) // abs() 344 374 conv1 = -conv1; 345 375 346 376 // convolve vert (first Y of next pixel) 347 377 conv2 = *(ptrh1 + x + 1) * ( 1) + 348 378 *(ptrh1 + x + 3) * ( 2) + 349 379 *(ptrh1 + x + 4) * ( 1) + 350 380 351 381 *(ptrh3 + x + 1) * (-1) + 352 382 *(ptrh3 + x + 3) * (-2) + … … 354 384 if (conv2 < 0) // abs() 355 385 conv2 = -conv2; 356 386 357 387 if (conv1 + conv2 > conf.edge_overlay_thresh) 358 388 { 359 bv_set(edgebuf, (y-EDGE_HMARGIN)*v iewport_width + x/3, 1);389 bv_set(edgebuf, (y-EDGE_HMARGIN)*vp_width + xdiv3, 1); 360 390 } 361 391 362 392 // Do it once again for the next 'pixel' 363 393 364 394 // convolve vert (second Y) 365 395 conv1 = *(ptrh1 + x + 5) * ( 1) + 366 396 *(ptrh1 + x + 9) * (-1) + 367 397 368 398 *(ptrh2 + x + 5) * ( 2) + 369 399 *(ptrh2 + x + 9) * (-2) + 370 400 371 401 *(ptrh3 + x + 5) * ( 1) + 372 402 *(ptrh3 + x + 9) * (-1); 373 403 if (conv1 < 0) // abs() 374 404 conv1 = -conv1; 375 405 376 406 // convolve vert (first Y of next pixel) 377 407 conv2 = *(ptrh1 + x + 5) * ( 1) + 378 408 *(ptrh1 + x + 7) * ( 2) + 379 409 *(ptrh1 + x + 9) * ( 1) + 380 410 381 411 *(ptrh3 + x + 5) * (-1) + 382 412 *(ptrh3 + x + 7) * (-2) + … … 384 414 if (conv2 < 0) // abs() 385 415 conv2 = -conv2; 386 416 387 417 if (conv1 + conv2 > conf.edge_overlay_thresh) 388 418 { 389 bv_set(edgebuf, (y-EDGE_HMARGIN)*v iewport_width + x/3+1, 1);419 bv_set(edgebuf, (y-EDGE_HMARGIN)*vp_width + xdiv3+1, 1); 390 420 } 391 421 } // for x 392 422 } // for y 393 394 if (smbuf != NULL) 395 { 396 free(smbuf); 397 smbuf = NULL; 398 } 399 400 // For an even more improved edge overlay, enabling the following lines will 423 424 425 // For an even more improved edge overlay, enabling the following lines will 401 426 // post-filter the results of the edge detection, removing false edge 'dots' 402 427 // from the display. However, the speed hit is large. In the developer's opinion 403 // this code is not needed, but if you want that additional quality and do not 428 // this code is not needed, but if you want that additional quality and do not 404 429 // care so much about performance, you can enable it. 405 // 430 // 406 431 // if (conf.edge_overlay_filter) 407 432 // { … … 418 443 // for (y = 1; y < viewport_height-1; ++y) 419 444 // { 445 // shutter_fullpress |= kbd_is_key_pressed(KEY_SHOOT_FULL); 446 // 420 447 //#if CAM_USES_ASPECT_CORRECTION 421 448 // for (x=12; x<(viewportw - 4); ++x) … … 458 485 // } // NULL-check 459 486 // } // if filtering 460 461 } 462 463 static void draw_edge_overlay() 464 { 487 488 return shutter_fullpress; 489 } 490 491 static int draw_edge_overlay() 492 { 493 int shutter_fullpress = kbd_is_key_pressed(KEY_SHOOT_FULL); 494 465 495 int x, y; 466 496 int x_off, y_off; 467 497 498 const color cl = conf.edge_overlay_color; 499 const int y_slice_min = EDGE_HMARGIN+ slice *slice_height; 500 const int y_slice_max = EDGE_HMARGIN+(slice+1)*slice_height; 468 501 const int y_min = EDGE_HMARGIN; 469 502 const int y_max = EDGE_HMARGIN+viewport_height; 470 const int x_min = 6;503 const int x_min = 2; 471 504 #if CAM_USES_ASPECT_CORRECTION 472 const int x_max = (viewportw - 4);505 const int x_max = (viewportw - 2); 473 506 #else 474 const int x_max = (screen_width - 4);507 const int x_max = (screen_width - 2); 475 508 #endif 476 509 477 if( !is_buffer_ready() ) return ;478 479 for (y = y_ min; y < y_max; ++y)510 if( !is_buffer_ready() ) return 0; 511 512 for (y = y_slice_min; y < y_slice_max; ++y) 480 513 { 481 514 y_off = y + yoffset; 482 483 if ((y_off > y_min) && (y_off < y_max)) // do not draw outside of allowed area 484 { 515 516 shutter_fullpress |= kbd_is_key_pressed(KEY_SHOOT_FULL); 517 518 if ((unsigned)(y_off-y_min) < (y_max-y_min)) // is the same as ((y_off > y_min) && (y_off < y_max)) // do not draw outside of allowed area 519 { 520 const int y_edgebuf = (y-y_min) * viewport_width; 521 485 522 for (x = x_min; x < x_max; ++x) 486 523 { 487 524 x_off = x + xoffset; 488 489 if (( x_off > x_min) && (x_off < x_max)) // do not draw outside of allowed area525 526 if ((unsigned)(x_off-x_min) < (x_max-x_min)) // is the same as ((x_off > x_min) && (x_off < x_max)) // do not draw outside of allowed area 490 527 { 491 528 // Draw a pixel to the screen wherever we detected an edge. 492 529 // If there is no edge based on the newest data, but there is one painted on the screen 493 530 // from previous calls, delete it from the screen. 494 if (bv_get(edgebuf, (y-y_min)*viewport_width + x)) 495 draw_pixel(ASPECT_VIEWPORT_XCORRECTION(x_off), y_off, conf.edge_overlay_color ); 496 else if (draw_get_pixel(ASPECT_VIEWPORT_XCORRECTION(x_off), y_off) == conf.edge_overlay_color) 497 draw_pixel(ASPECT_VIEWPORT_XCORRECTION(x_off), y_off, 0 ); 531 const int aspect_correct_x_off = ASPECT_VIEWPORT_XCORRECTION(x_off); 532 const int bEdge = bv_get(edgebuf, y_edgebuf + x); 533 const int bDraw = bEdge || (draw_get_pixel(aspect_correct_x_off, y_off) == conf.edge_overlay_color); 534 const color cl = bEdge ? conf.edge_overlay_color : 0; 535 if (bEdge || bDraw) 536 draw_pixel(aspect_correct_x_off, y_off, cl); 537 498 538 } 499 539 } // for x 500 540 } 501 541 } // for y 502 503 542 543 504 544 // Drawing the overlay is over. 505 545 // But as a finishing touch we clear up garbage on the screen 506 546 // by clearing those parts that the overlay has left. 507 547 508 548 if (xoffset != 0) 509 549 { 510 550 // Cleans up leftover from horizontal motion 511 551 512 552 const int x_min_c = (xoffset < 0) ? x_max + xoffset : x_min; 513 553 const int x_max_c = (xoffset > 0) ? x_min + xoffset : x_max; 514 554 515 555 for (y = y_min; y < y_max; ++y) 516 556 { 517 557 for (x = x_min_c; x < x_max_c; ++x) 518 558 { 519 if (draw_get_pixel(ASPECT_VIEWPORT_XCORRECTION(x), y) == conf.edge_overlay_color) // if there is an edge drawn on the screen but there is no edge there based on the newest data, delete it from the screen 520 draw_pixel(ASPECT_VIEWPORT_XCORRECTION(x), y, 0 ); 559 const int aspect_correct_x = ASPECT_VIEWPORT_XCORRECTION(x); 560 if (draw_get_pixel(aspect_correct_x, y) == cl) // if there is an edge drawn on the screen but there is no edge there based on the newest data, delete it from the screen 561 draw_pixel(aspect_correct_x, y, 0 ); 521 562 } 522 563 } 523 564 } 524 565 525 566 if (yoffset != 0) 526 567 { 527 568 // Cleans up leftover from vertical motion 528 569 529 570 const int y_min_c = (yoffset < 0) ? y_max + yoffset : y_min; 530 571 const int y_max_c = (yoffset > 0) ? y_min + yoffset : y_max; 531 572 532 573 for (y = y_min_c; y < y_max_c; ++y) 533 574 { 534 575 for (x = x_min; x < x_max; ++x) 535 576 { 536 if (draw_get_pixel(ASPECT_VIEWPORT_XCORRECTION(x), y) == conf.edge_overlay_color) // if there is an edge drawn on the screen but there is no edge there based on the newest data, delete it from the screen 537 draw_pixel(ASPECT_VIEWPORT_XCORRECTION(x), y, 0 ); 577 const int aspect_correct_x = ASPECT_VIEWPORT_XCORRECTION(x); 578 if (draw_get_pixel(aspect_correct_x, y) == cl) // if there is an edge drawn on the screen but there is no edge there based on the newest data, delete it from the screen 579 draw_pixel(aspect_correct_x, y, 0 ); 538 580 } 539 581 } 540 582 } 583 584 return shutter_fullpress; 541 585 } 542 586 … … 545 589 const int y_max = viewport_height; 546 590 #if CAM_USES_ASPECT_CORRECTION 547 const int x_max = (viewportw - 4);591 const int x_max = (viewportw - 2); 548 592 #else 549 const int x_max = (screen_width - 4);593 const int x_max = (screen_width - 2); 550 594 #endif 551 595 … … 575 619 } 576 620 } 577 578 621 622 579 623 // Main edge overlay function. 580 624 // It works by detecting edges using the Sobel operator … … 586 630 void edge_overlay() 587 631 { 632 588 633 // Was the shutter fully pressed the last time we ran? 589 634 // We use this to make sure that the user has released … … 592 637 // per press. 593 638 static int bFullPress_prev = 0; 594 639 595 640 // Have we already started taking pictures in panorama mode? 596 641 // We use this variable to be able to detect if panorama 597 642 // mode has been turned off. 598 643 static int bPanoInProgress = 0; 599 644 600 645 // Precalculate some values to make the rest of the 601 646 // code easier to read. 647 int bFullPress = kbd_is_key_pressed(KEY_SHOOT_FULL); 602 648 const int bHalfPress = kbd_is_key_pressed(KEY_SHOOT_HALF); 603 const int bFullPress = kbd_is_key_pressed(KEY_SHOOT_FULL);604 649 const int bPlayMode = (mode_get() & MODE_MASK) == MODE_PLAY; 605 650 const int bPanoramaMode = (conf.edge_overlay_pano != 0); … … 612 657 ( bPlayMode && bDisplayInPlay) // or we are in play-mode with the right settings 613 658 ); 614 659 615 660 if (bPanoInProgress && !bPanoramaMode) 616 661 { … … 621 666 bPanoInProgress = 0; 622 667 } 623 668 624 669 get_viewport_size(); 625 670 … … 633 678 // In this state we assume no edge overlay in memory, 634 679 // but we are ready to create one if the user presses wishes so. 635 636 if (bFullPress && !bFullPress_prev && bGuiModeNone) 637 { 638 calc_edge_overlay(); 680 681 int bRealtimeUpdate = bCanDisplay && (bGuiModeAlt || bGuiModeNone); 682 if (bRealtimeUpdate) 683 { 684 // We try to detect button presses during the lengthy 685 // calculations. 686 bFullPress |= calc_edge_overlay(); 687 bFullPress |= draw_edge_overlay(); 688 } 689 690 int bSwitch2Frozen = bFullPress && !bFullPress_prev && bGuiModeNone; 691 if (bSwitch2Frozen) 692 { 693 // Switch to Frozen mode 694 695 // Make sure we have one whole consistent frame 696 for (slice = 0; slice < EDGE_SLICES; ++slice) 697 calc_edge_overlay(); 698 639 699 set_offset_from_overlap(); 640 700 fsm_state = EDGE_FROZEN; 641 642 701 bPanoInProgress = bPanoramaMode; 643 702 } 644 else if (bCanDisplay && (bGuiModeAlt || bGuiModeNone)) 645 { 646 calc_edge_overlay(); 647 draw_edge_overlay(); 648 } 649 else 703 704 if (!bRealtimeUpdate && !bSwitch2Frozen) 650 705 { 651 706 // Nothing happens. So do nothing. 652 707 // Or rather, we could clean up if we are that bored. 653 bv_free(edgebuf); 654 edgebuf = NULL; 655 } 656 708 reset_edge_overlay(); 709 } 657 710 break; 658 711 } … … 661 714 // We have a stored edge overlay in memory and we display 662 715 // it on screen in 'frozen' mode. 663 716 664 717 // Move edge overlay around. 665 718 if (gui_get_mode() == GUI_MODE_ALT) … … 674 727 yoffset -=YINC; 675 728 } 676 729 730 if (bCanDisplay && (bGuiModeAlt || bGuiModeNone)) 731 { 732 // We try to detect button presses during the lengthy 733 // calculations. 734 bFullPress |= draw_edge_overlay(); 735 draw_string(0, 0, "Frozen", conf.osd_color); 736 } 737 677 738 // In event of a FullPress, we either capture a new 678 739 // overlay and stay frozen, OR we go back to live mode. 679 740 if (bFullPress && !bFullPress_prev && bGuiModeNone) 680 741 { 742 // Possible mode switch 681 743 if (bPanoramaMode) 682 744 { 683 calc_edge_overlay(); 745 // Make sure we have one whole consistent frame 746 for (slice = 0; slice < EDGE_SLICES; ++slice) 747 calc_edge_overlay(); 748 684 749 set_offset_from_overlap(); 685 750 bPanoInProgress = 1; … … 688 753 fsm_state = EDGE_LIVE; 689 754 } 690 else if (bCanDisplay && (bGuiModeAlt || bGuiModeNone)) 691 { 692 draw_edge_overlay(); 693 draw_string(0, 0, "Frozen", conf.osd_color); 694 } 695 755 696 756 break; 697 757 } // case 698 758 } // switch 699 759 760 700 761 bFullPress_prev = bFullPress; 762 763 if (++slice >= EDGE_SLICES) 764 slice = 0; 765 701 766 } // function 702 703 704 705 -
trunk/core/gui.c
r928 r931 638 638 {0x5c,LANG_MENU_EDGE_OVERLAY_ENABLE, MENUITEM_BOOL, &conf.edge_overlay_enable }, 639 639 {0x5c,LANG_MENU_EDGE_FILTER, MENUITEM_BOOL, &conf.edge_overlay_filter }, 640 {0x5 c,LANG_MENU_EDGE_PANO, MENUITEM_ENUM, (int*)gui_edge_pano_enum },641 {0x 7f,LANG_MENU_EDGE_PANO_OVERLAP, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_pano_overlap, MENU_MINMAX(0, 100)},640 {0x5f,LANG_MENU_EDGE_PANO, MENUITEM_ENUM, (int*)gui_edge_pano_enum }, 641 {0x5e,LANG_MENU_EDGE_PANO_OVERLAP, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_pano_overlap, MENU_MINMAX(0, 100)}, 642 642 {0x5c,LANG_MENU_EDGE_SHOW, MENUITEM_BOOL, &conf.edge_overlay_show }, 643 {0x 7f,LANG_MENU_EDGE_OVERLAY_TRESH, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255)},643 {0x5e,LANG_MENU_EDGE_OVERLAY_TRESH, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255)}, 644 644 {0x65,LANG_MENU_EDGE_OVERLAY_COLOR, MENUITEM_COLOR_FG, (int*)&conf.edge_overlay_color }, 645 645 {0x5c,LANG_MENU_EDGE_PLAY, MENUITEM_BOOL, &conf.edge_overlay_play }, //does not work on cams like s-series, which dont have a real "hardware" play/rec switch, need a workaround, probably another button … … 3420 3420 3421 3421 conf.edge_overlay_pano+=change; 3422 if (conf.edge_overlay_pano<0) 3423 conf.edge_overlay_pano=0; 3424 else if (conf.edge_overlay_pano>=(sizeof(modes)/sizeof(modes[0]))) 3425 conf.edge_overlay_pano=sizeof(modes)/sizeof(modes[0])-1; 3426 3422 if (conf.edge_overlay_pano<0) 3423 conf.edge_overlay_pano=(sizeof(modes)/sizeof(modes[0]))-1; 3424 else if (conf.edge_overlay_pano>=(sizeof(modes)/sizeof(modes[0]))) 3425 conf.edge_overlay_pano=0; 3427 3426 return modes[conf.edge_overlay_pano]; 3428 3427 } -
trunk/include/camera.h
r930 r931 845 845 #define CAM_EV_IN_VIDEO 1 846 846 #define DNG_SUPPORT 1 847 #define CAM_REAR_CURTAIN 1 // http://chdk.setepontos.com/index.php/topic,650.msg54434.html#msg54434 847 848 // pattern 848 849 #define cam_CFAPattern 0x02010100 // Red Green Green Blue -
trunk/platform/sx20/sub/102b/boot.c
r900 r931 15 15 if (p[0]==0xff85f3cc) p[0]=(int)JogDial_task_my; 16 16 if (p[0]==0xFF879034) p[0]=(int)movie_record_task; 17 } 18 void taskCreateHook2(int *p) { 19 p-=17; 20 if (p[0]==0xFF89A8CC) p[0]=(int)init_file_modules_task; 21 if (p[0]==0xFF8C1430) p[0]=(int)exp_drv_task; 17 22 } 18 23 … … 119 124 void __attribute__((naked,noinline)) sub_FF810354_my() { 120 125 //http://chdk.setepontos.com/index.php/topic,4194.0.html 126 *(int*)0x1934 = (int)taskCreateHook2; // this is inferred, but not actually tested 121 127 *(int*)0x1938 = (int)taskCreateHook3; 128 *(int*)(0x2564)= (*(int*)0xC0220134)&1 ? 0x2000000 : 0x1000000; // replacement of sub_FF8331CC for correct power-on. 122 129 123 130 asm volatile ( … … 265 272 "B loc_FF81F89C\n" 266 273 "loc_FF81F8A0:\n" 267 "BL sub_FF8331CC\n" 274 // "BL sub_FF8331CC\n" // see begin of sub_FF810354_my 268 275 // "BL j_nullsub_235\n" 269 276 "BL sub_FF8388E4\n" -
trunk/platform/sx20/sub/102b/capt_seq.c
r900 r931 4 4 #include "conf.h" 5 5 6 static long *nrflag = (long*)0x 9B40;6 static long *nrflag = (long*)0x7910; 7 7 8 8 #include "../../../generic/capt_seq.c" … … 373 373 "SUB R3, R3, #8\n" 374 374 "BL sub_FF96481C\n" 375 "LDR R0, [R4,#0x1C]\n" 376 "CMP R0, #0\n" // get here! 377 "MOVNE R0, #1\n" 378 "STRNE R0, [R5]\n" 379 "LDR R0, [R5,#4]\n" 380 "BL sub_FF9254CC\n" 381 "LDR R0, [R5,#8]\n" 382 "BL sub_FF8C83DC\n" 383 "MOV R0, #1\n" 384 "BL sub_FF8C83E8\n" // BX LR 385 "LDR R0, =0xFF961D60\n" 386 "MOV R1, R4\n" 387 "BL sub_FF8C83B8\n" 388 "LDR R0, [R5]\n" 389 "CMP R0, #5\n" // get here! 390 "ADDLS PC, PC, R0,LSL#2\n" // badly wrong setting pc here 391 "BL wait_until_remote_button_is_released\n" 392 "BL capt_seq_hook_set_nr\n" // + 393 "B sub_FF96251C\n" // continue function in firmware 375 "BL wait_until_remote_button_is_released\n" 376 "BL capt_seq_hook_set_nr\n" // + 377 "B sub_FF962410\n" // continue function in firmware 378 // "LDR R0, [R4,#0x1C]\n" 379 // "CMP R0, #0\n" // get here! 380 // "MOVNE R0, #1\n" 381 // "STRNE R0, [R5]\n" 382 // "LDR R0, [R5,#4]\n" 383 // "BL sub_FF9254CC\n" 384 // "LDR R0, [R5,#8]\n" 385 // "BL sub_FF8C83DC\n" 386 // "MOV R0, #1\n" 387 // "BL sub_FF8C83E8\n" // BX LR 388 // "LDR R0, =0xFF961D60\n" 389 // "MOV R1, R4\n" 390 // "BL sub_FF8C83B8\n" 391 // "LDR R0, [R5]\n" 392 // "CMP R0, #5\n" // get here! 393 // "ADDLS PC, PC, R0,LSL#2\n" // badly wrong setting pc here 394 // "BL wait_until_remote_button_is_released\n" 395 // "BL capt_seq_hook_set_nr\n" // + 396 // "B sub_FF96251C\n" // continue function in firmware 394 397 ); 395 398 … … 523 526 "BL sub_FF962CF4\n" // changed 524 527 "MOV R0, R4\n" 525 "BL sub_FF962364 \n" //changed sub_FF962364_my - badly wrong if we use _my528 "BL sub_FF962364_my\n" 526 529 "MOV R7, R0\n" 527 530 "BL capt_seq_hook_raw_here\n" // + -
trunk/platform/sx20/sub/102b/stubs_auto.S
r900 r931 218 218 STUB(FF96227C) 219 219 STUB(FF962364) 220 STUB(FF962410) 220 221 STUB(FF96251C) 221 222 STUB(FF962618) -
trunk/platform/sx20/sub/102d/boot.c
r928 r931 24 24 void CreateTask_spytask() { 25 25 _CreateTask("SpyTask", 0x19, 0x2000, core_spytask, 0); 26 #ifdef CAM_CHDK_PTP 27 _CreateTask("InitCHDKPTP", 0x19, 0x2000, init_chdk_ptp, 0); 28 #endif 26 29 }; 27 30 -
trunk/platform/sx20/sub/102d/stubs_entry_2.S
r919 r931 47 47 NHSTUB(RenameFile_Fut, 0xFF834B74) // doesn't look like SX10 but works 48 48 NHSTUB(strrchr, 0xFF813FE4) // incorrectly detected 49 NHSTUB(add_ptp_handler, 0xFFA49320) 49 50 50 51 # Might be wrong