Camera: SD700IS (should build on any of the juciphox supported cameras)
First off, thanks to [NW]reyalP in #CHDK for helping me pull this off.
If you are not familiar with Eye-fi, it is a special SD card that allows you to upload photos over wireless as you take them. It does not, however, upload videos as you take them. This is because it only looks for valid JPGs. We were able to achieve video uploading by creating a spoofed JPG which embedded the video. Eye-fi uploaded the JPG, then the AVI was decoded client side.
In UNIX terms, the spoofed JPG was created by doing:
cat spoofed.jpg MVI_0XXX.AVI > FAKED_IMAGE.JPG
This was sufficient to get the Eye-fi card to send the image.
Here is my implementation. I would love feedback, as this is my first CHDK patch and my C is a bit rusty.
juciphox polvi$ svn diff
Index: core/curves.h
===================================================================
--- core/curves.h (revision 499)
+++ core/curves.h (working copy)
@@ -12,7 +12,7 @@
extern void curve_load();
extern void drcurve_load(const char *fn);
extern void curve_apply();
-extern unsigned short drcurve0[][];
+extern unsigned short drcurve0[][CURVE_SIZE];
// extern void default_curve(int n);
//-------------------------------------------------------------------
Index: core/main.c
===================================================================
--- core/main.c (revision 499)
+++ core/main.c (working copy)
@@ -9,6 +9,9 @@
#include "motion_detector.h"
#include "edgeoverlay.h"
+#define RAW_TARGET_DIRECTORY "A/DCIM/%03dCANON"
+#define RAW_TARGET_FILENAME "%s%04d%s"
+
static int raw_need_postprocess;
static volatile int spytask_can_start;
@@ -72,6 +75,14 @@
int cnt = 1;
int i=0;
+ static char dir[32];
+ static char fn_spoof[64];
+ static char fn_real[64];
+ static char fn_target[64];
+ int fd_spoof, fd_real, fd_target, numr, numw, file_counter;
+ int target_exists = 0;
+ unsigned char *buff;
+
raw_need_postprocess = 0;
spytask_can_start=0;
@@ -112,6 +123,38 @@
}
while (1){
+ file_counter = ((get_file_counter()>>4)&0x3FFF);
+ sprintf(dir, RAW_TARGET_DIRECTORY, 110);
+ sprintf(fn_target, "%s/", dir);
+ sprintf(fn_target+strlen(fn_target), "%04dFAKE%s", file_counter, ".JPG");
+
+ fd_target = fopen(fn_target, "rb");
+ if (fd_target)
+ target_exists = 1;
+ else
+ target_exists = 0;
+ fclose(fd_target);
+
+ if (movie_status <=1 && !target_exists) {
+ sprintf(fn_spoof, "A/spoof.jpg");
+ sprintf(fn_real, "%s/", dir);
+ sprintf(fn_real+strlen(fn_real), RAW_TARGET_FILENAME, "MVI_", file_counter, ".AVI");
+ fd_spoof = fopen(fn_spoof, "rb");
+ fd_real = fopen(fn_real, "rb");
+ if (fd_spoof && fd_real){
+ fd_target = fopen(fn_target, "wb");
+ buff = malloc(sizeof *buff * 100);
+ while ((numr = fread(buff, 1, 100, fd_spoof)))
+ fwrite(buff, 1, numr, fd_target);
+ while ((numr = fread(buff, 1, 100, fd_real)))
+ fwrite(buff, 1, numr, fd_target);
+ free(buff);
+ fclose(fd_target);
+ }
+ fclose(fd_spoof);
+ fclose(fd_real);
+ }
+
if (raw_data_available){
raw_need_postprocess = raw_savefile();
hook_raw_save_complete();