summaryrefslogtreecommitdiff
path: root/camlibs/soundvision
diff options
context:
space:
mode:
authorVince Weaver <vince@deater.net>2003-02-11 17:24:53 +0000
committerVince Weaver <vince@deater.net>2003-02-11 17:24:53 +0000
commit97c46af2ff120702f3935af45af64859b0f1d054 (patch)
treeb08c88da7ee5c5c9d67efcc1b9252a3627260336 /camlibs/soundvision
parent05c2f608b0c464e9d318516b990aacf6d87c6986 (diff)
downloadlibgphoto2-97c46af2ff120702f3935af45af64859b0f1d054.tar.gz
Big re-write of soundvision core with much better support for tiger-fastflicks class cameras
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@6197 67ed7778-7388-44ab-90cf-0a291f65f57c
Diffstat (limited to 'camlibs/soundvision')
-rw-r--r--camlibs/soundvision/BUGS14
-rw-r--r--camlibs/soundvision/ChangeLog11
-rw-r--r--camlibs/soundvision/agfa_cl18.c173
-rw-r--r--camlibs/soundvision/commands.c401
-rw-r--r--camlibs/soundvision/soundvision.c275
-rw-r--r--camlibs/soundvision/soundvision.h56
-rw-r--r--camlibs/soundvision/tiger_fastflicks.c443
7 files changed, 998 insertions, 375 deletions
diff --git a/camlibs/soundvision/BUGS b/camlibs/soundvision/BUGS
index d46213074..5aafbae1d 100644
--- a/camlibs/soundvision/BUGS
+++ b/camlibs/soundvision/BUGS
@@ -1,2 +1,12 @@
-Every-other command might time out on CL18.
-Not sure why, we are copying windows traces exactly.
+Known Bugs:
+
+overall:
+* Long timeout (and usb read error) on alternate runnings of gphoto2.
+ All attempts to track this down so far have failed.
+
+agfa-specific:
+
+
+tiger-fastflicks specific:
+* File upload for tiger doesn't work [even though it should].
+* Delete-all on tiger sometimes causes problems.
diff --git a/camlibs/soundvision/ChangeLog b/camlibs/soundvision/ChangeLog
index 5bb198238..d0dc9c859 100644
--- a/camlibs/soundvision/ChangeLog
+++ b/camlibs/soundvision/ChangeLog
@@ -1,3 +1,14 @@
+2002-02-11 Vince Weaver <vince@deater.net>
+ * Completely redid tiger support. Involved separating out
+ more functions from Agfa, extensive looking at usb-traces, etc.
+ delete and image-capture should now work on Tiger. File upload
+ should work but doesn't.
+ * All attempts to fix the stall upon
+ subsequent re-running of gphoto2 failed. It seems to be
+ somewhat arbitrary. Sometimes a reset helps, sometimes not.
+ * Agfa-CL18 should work more or less same as before.
+ * Cleaned up a lot of the code.
+
2002-01-23 Vince Weaver <vince@deater.net>
* Add Argus DC-2200
diff --git a/camlibs/soundvision/agfa_cl18.c b/camlibs/soundvision/agfa_cl18.c
index d7534abbe..eb3d70863 100644
--- a/camlibs/soundvision/agfa_cl18.c
+++ b/camlibs/soundvision/agfa_cl18.c
@@ -32,10 +32,10 @@ int agfa_capture(CameraPrivateLibrary *dev, CameraFilePath *path) {
int ret,taken;
- ret=soundvision_send_command(SOUNDVISION_TAKEPIC2,0,dev);
- ret=soundvision_send_command(SOUNDVISION_TAKEPIC1,0,dev);
+ ret=soundvision_send_command(SOUNDVISION_SETPC1,0,dev);
+ ret=soundvision_send_command(SOUNDVISION_SETPC2,0,dev);
ret=soundvision_send_command(SOUNDVISION_TAKEPIC3,0,dev);
- ret=soundvision_send_command(SOUNDVISION_TAKEPIC2,0,dev);
+ ret=soundvision_send_command(SOUNDVISION_SETPC2,0,dev);
/*Not sure if this delay is necessary, but it was used in the windows driver*/
/*delay(20); */
@@ -155,3 +155,170 @@ int agfa_delete_picture(CameraPrivateLibrary *dev, const char *filename) {
return GP_OK;
}
+
+
+
+int agfa_get_file_list(CameraPrivateLibrary *dev) {
+
+ char *buffer;
+ int32_t ret, taken, buflen,i;
+
+
+ /* It seems we need to do a "reset" packet before reading names?? */
+
+ soundvision_reset(dev,NULL,NULL);
+
+ if ( (taken=soundvision_photos_taken(dev)) < 0)
+ return taken;
+
+ dev->num_pictures = taken;
+
+
+ buflen = (taken * 13)+1; /* 12 char filenames and space for each */
+ /* plus trailing NULL */
+
+ buffer = malloc(buflen);
+
+ if (!buffer) {
+ GP_DEBUG("Could not allocate %i bytes!",
+ buflen);
+ return GP_ERROR_NO_MEMORY;
+ }
+
+ ret=soundvision_send_command(SOUNDVISION_GET_NAMES, buflen, dev);
+ if (ret < 0) {
+ free(buffer);
+ return ret;
+ }
+
+ ret = soundvision_read(dev, (void *)buffer, buflen);
+ if (ret < 0) {
+ free(buffer);
+ return ret;
+ }
+
+ if (dev->file_list) free(dev->file_list);
+
+ dev->file_list = malloc(taken * 13);
+ if (!dev->file_list) {
+ GP_DEBUG("Could not allocate %i bytes!",
+ taken*13);
+ free(buffer);
+ return (GP_ERROR_NO_MEMORY);
+ }
+
+ for(i=0;i<taken*13;i++) if (buffer[i]==' ') buffer[i]='\0';
+ memcpy(dev->file_list, buffer, taken * 13);
+ free(buffer);
+
+#if 0
+ taken=soundvision_photos_taken(dev);
+ soundvision_get_thumb_size(dev,dev->file_list);
+#endif
+ return GP_OK;
+}
+
+int agfa_get_pic(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size) {
+
+ int32_t ret,temp;
+
+ ret = soundvision_send_command(SOUNDVISION_GET_PIC,0,dev);
+ if (ret<0) return ret;
+
+ /* always returns ff 0f 00 00 ??? */
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) return ret;
+
+ ret=soundvision_send_file_command(filename,dev);
+ if (ret<0) return ret;
+
+ ret = soundvision_read(dev, data, size);
+ if (ret<0) return ret;
+
+#if 0
+ /* Have to do this after getting pic ? */
+ ret=soundvision_send_command(SOUNDVISION_DONE_PIC,0,dev);
+ if (ret<0) return ret;
+#endif
+
+ return GP_OK;
+
+}
+
+int agfa_get_pic_size(CameraPrivateLibrary *dev, const char *filename) {
+
+ int32_t ret,temp;
+ uint32_t size;
+
+ ret=soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
+ if (ret<0) return ret;
+
+ /* always returns ff 0f 00 00 ??? */
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) return ret;
+
+ ret=soundvision_send_file_command(filename,dev);
+ if (ret<0) return ret;
+
+ ret = soundvision_read(dev, &size, sizeof(size));
+ if (ret<0) return ret;
+
+ return le32toh(size);
+
+}
+
+
+int agfa_get_thumb_size(CameraPrivateLibrary *dev, const char *filename) {
+
+ int32_t ret,temp;
+ uint32_t size;
+
+ ret=soundvision_send_command(SOUNDVISION_GET_THUMB_SIZE,0,dev);
+ if (ret<0) return ret;
+
+ /* always returns ff 0f 00 00 ??? */
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) return ret;
+
+ soundvision_send_file_command(filename,dev);
+ if (ret<0) return ret;
+
+ ret = soundvision_read(dev, &size, sizeof(size));
+ if (ret<0) return ret;
+
+ return le32toh(size);
+
+}
+
+int agfa_get_thumb(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size) {
+
+ int32_t ret,temp;
+
+ ret = soundvision_send_command(SOUNDVISION_GET_THUMB,0,dev);
+ if (ret<0) return ret;
+
+ /* always returns ff 0f 00 00 ??? */
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) return ret;
+
+ ret=soundvision_send_file_command(filename,dev);
+ if (ret<0) return ret;
+
+ ret = soundvision_read(dev, data, size);
+ if (ret<0) return ret;
+#if 0
+ /* Is this needed? */
+ soundvision_photos_taken(dev,&ret);
+
+ ret=soundvision_send_command(SOUNDVISION_END_OF_THUMB,0,dev);
+ if (ret<0) return ret;
+
+ ret = soundvision_read(dev, temp_string, 8);
+ if (ret<0) return ret;
+#endif
+
+ return GP_OK;
+
+}
diff --git a/camlibs/soundvision/commands.c b/camlibs/soundvision/commands.c
index 8db086018..b848204ec 100644
--- a/camlibs/soundvision/commands.c
+++ b/camlibs/soundvision/commands.c
@@ -3,8 +3,9 @@
*
* Command set for the soundvision cameras
*
- * Copyright 2001-2002 Vince Weaver <vince@deater.net>
+ * Copyright 2001-2003 Vince Weaver <vince@deater.net>
*/
+
#include "config.h"
#include <stdio.h>
@@ -47,8 +48,8 @@ int32_t soundvision_send_file_command(const char *filename,
uint8_t file_cmd[16];
int result;
- htole32a(&file_cmd[0],0xc); /* Length is "C" little-endian 32 bits */
- strncpy(&file_cmd[4],filename,12);/* Filename is 12 bytes at the end */
+ htole32a(&file_cmd[0],0xc); /* Length is 12 little-endian 32 bits */
+ strncpy(&file_cmd[4],filename,12); /* Filename is 12 bytes at the end */
result=gp_port_write(dev->gpdev,(char *)&file_cmd,sizeof(file_cmd));
if (result<0) return result;
@@ -62,65 +63,114 @@ int32_t soundvision_read(CameraPrivateLibrary *dev, void *buffer, int len) {
}
-int soundvision_reset(CameraPrivateLibrary *dev) {
- int ret;
+ /* Reset the camera */
+int soundvision_reset(CameraPrivateLibrary *dev,char *revision, char *status) {
- ret=soundvision_send_command(SOUNDVISION_RESET,0,dev);
- if (ret<0) return ret;
+ int ret,attempts=0;
+
+retry_reset:
+
+ /* This prevents lockups on tiger !!!! */
+ ret=soundvision_send_command(SOUNDVISION_START_TRANSACTION,0,dev);
+ if (ret<0) goto reset_error;
+
+ /* First get firmware revision */
+ ret=soundvision_get_revision(dev,revision);
+
+ /* If camera out of whack, this is where it will hang */
+ /* If we retry a few times usually after a few timeouts */
+ /* It will get going again */
+ if (ret<0) {
+ if (attempts<2) {
+ attempts++;
+ goto retry_reset;
+ }
+ else goto reset_error;
+ }
+
+
+ /* Dshot 3 camera does 2 extra steps */
+ /* Seems to enable extra info in status */
+ /* What does it do? It works w/o it */
+ /* And other tiger cameras might not */
+ /* need it. */
+#if 0
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS) {
+
+ char result[12];
+
+ /* What does 0x405 signify? */
+ ret=soundvision_send_command(SOUNDVISION_SETPC2,0x405,dev);
+ if (ret<0) goto reset_error;
+
+ ret=soundvision_send_command(SOUNDVISION_INIT2,0,dev);
+ if (ret<0) goto reset_error;
+
+ /* Read returned value. Why 0x140,0xf,0x5 ? */
+ ret = soundvision_read(dev, &result, sizeof(result));
+ if (ret<0) goto reset_error;
+ }
+#endif
+
+ /* Read the status registers */
+ dev->reset_times++;
+ ret=soundvision_get_status(dev,status);
+ if (ret<0) goto reset_error;
return GP_OK;
+
+reset_error:
+
+ GP_DEBUG("Error in soundvision_reset\n");
+ return ret;
+
}
int soundvision_get_revision(CameraPrivateLibrary *dev, char *revision) {
int ret;
- char version[8];
- /* uint32_t temp; */
-
- ret = soundvision_send_command(SOUNDVISION_DONE_TRANSACTION,0,dev);
+ char version[9];
ret = soundvision_send_command(SOUNDVISION_GET_VERSION,0,dev);
if (ret<0) return ret;
- ret = soundvision_read(dev, &version, sizeof(version));
+ ret = soundvision_read(dev, &version, sizeof(version)-1);
if (ret<0) return ret;
- strncpy(revision,version,8);
-
- ret=soundvision_reset(dev);
- if (ret<0) return ret;
+ /* If null we don't care */
+ if (revision!=NULL) {
+ strncpy(revision,version,8);
+ revision[8]=0;
+ }
-/* ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret; */
-
return GP_OK;
}
- /* Status is a 60 byte array. I have no clue what it does */
-int soundvision_get_status(CameraPrivateLibrary *dev, int *taken,
- int *available, int *rawcount) {
+ /* Status is a 96 byte array. */
+ /* Haven't been able to decode it yet */
+ /* It changes with every read though */
+int soundvision_get_status(CameraPrivateLibrary *dev, char *status) {
uint8_t ss[0x60];
int32_t ret;
-
ret=soundvision_send_command(SOUNDVISION_STATUS, 0, dev);
-
- if (ret < 0) {
- fprintf(stderr, "soundvision_get_storage_status: error sending command\n");
- return ret;
- }
+ if (ret < 0) goto get_status_error;
ret = soundvision_read(dev, (unsigned char *)&ss, sizeof(ss));
- if (ret < 0) {
- fprintf(stderr, "soundvision_get_storage_status: error getting count\n");
- return ret;
+ if (ret < 0) goto get_status_error;
+
+ if (status!=NULL) {
+ memcpy(status,ss,0x60);
}
-
- soundvision_reset(dev);
return GP_OK;
+
+get_status_error:
+ GP_DEBUG("Error getting camera status\n");
+ return ret;
+
}
int soundvision_photos_taken(CameraPrivateLibrary *dev) {
@@ -129,285 +179,98 @@ int soundvision_photos_taken(CameraPrivateLibrary *dev) {
uint32_t numpics;
ret=soundvision_send_command(SOUNDVISION_GET_NUM_PICS, 0, dev);
-
- if (ret < 0) {
- fprintf(stderr, "soundvision_get_storage_status: error sending command\n");
- return ret;
- }
+ if (ret < 0) goto error_photos_taken;
ret = soundvision_read(dev, &numpics, sizeof(numpics));
- if (ret < 0) {
- fprintf(stderr, "soundvision_get_storage_status: error getting count\n");
- return ret;
- }
+ if (ret < 0) goto error_photos_taken;
+
return le32toh(numpics);
-
+
+error_photos_taken:
+ GP_DEBUG("Error getting number of photos taken.\n");
+ return ret;
+
}
int soundvision_get_file_list(CameraPrivateLibrary *dev) {
- char *buffer;
- int32_t ret, taken, buflen;
-
-
- /* It seems we need to do a "reset" packet before reading names?? */
-
- soundvision_reset(dev);
-
- if ( (taken=soundvision_photos_taken(dev)) < 0)
- return taken;
+ int result;
- dev->num_pictures = taken;
-
-
- buflen = (taken * 13)+1; /* 12 char filenames and space for each */
- /* plus trailing NULL */
-
- buffer = malloc(buflen);
-
- if (!buffer) {
- GP_DEBUG("Could not allocate %i bytes!",
- buflen);
- return GP_ERROR_NO_MEMORY;
- }
-
- ret=soundvision_send_command(SOUNDVISION_GET_NAMES, buflen, dev);
- if (ret < 0) {
- free(buffer);
- return ret;
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS) {
+ result=tiger_get_file_list(dev);
}
-
- ret = soundvision_read(dev, (void *)buffer, buflen);
- if (ret < 0) {
- free(buffer);
- return ret;
- }
-
- if (dev->file_list) free(dev->file_list);
-
- dev->file_list = malloc(taken * 13);
- if (!dev->file_list) {
- GP_DEBUG("Could not allocate %i bytes!",
- taken*13);
- free(buffer);
- return (GP_ERROR_NO_MEMORY);
+ else {
+ result=agfa_get_file_list(dev);
}
-
- memcpy(dev->file_list, buffer, taken * 13);
- free(buffer);
-
-#if 0
- taken=soundvision_photos_taken(dev);
- soundvision_get_thumb_size(dev,dev->file_list);
-#endif
- return GP_OK;
+
+ return result;
+
}
int soundvision_get_thumb_size(CameraPrivateLibrary *dev, const char *filename) {
- int32_t ret,temp;
- uint32_t size;
-
- ret=soundvision_send_command(SOUNDVISION_GET_THUMB_SIZE,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
+ int32_t ret;
+
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS)
+ ret=tiger_get_thumb_size(dev,filename);
+ else
+ ret=agfa_get_thumb_size(dev,filename);
- ret = soundvision_read(dev, &size, sizeof(size));
- if (ret<0) return ret;
-
- return le32toh(size);
+ return ret;
}
int soundvision_get_thumb(CameraPrivateLibrary *dev, const char *filename,
unsigned char *data,int size) {
- int32_t ret,temp;
-
- ret = soundvision_send_command(SOUNDVISION_GET_THUMB,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
-
- ret = soundvision_read(dev, data, size);
- if (ret<0) return ret;
-#if 0
- /* Is this needed? */
- soundvision_photos_taken(dev,&ret);
-
- ret=soundvision_send_command(SOUNDVISION_END_OF_THUMB,0,dev);
- if (ret<0) return ret;
-
- ret = soundvision_read(dev, temp_string, 8);
- if (ret<0) return ret;
-#endif
+ int32_t ret;
+
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS)
+ ret=tiger_get_thumb(dev,filename,data,size);
+ else
+ ret=agfa_get_thumb(dev,filename,data,size);
- return GP_OK;
+ return ret;
}
int soundvision_get_pic_size(CameraPrivateLibrary *dev, const char *filename) {
- int32_t ret,temp;
- uint32_t size;
-
- ret=soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
+ int32_t ret;
+
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS)
+ ret=tiger_get_pic_size(dev,filename);
+ else
+ ret=agfa_get_pic_size(dev,filename);
- ret = soundvision_read(dev, &size, sizeof(size));
- if (ret<0) return ret;
-
- return le32toh(size);
+ return ret;
}
int soundvision_get_pic(CameraPrivateLibrary *dev, const char *filename,
unsigned char *data,int size) {
- int32_t ret,temp;
+ int32_t ret;
- ret = soundvision_send_command(SOUNDVISION_GET_PIC,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
-
- ret = soundvision_read(dev, data, size);
- if (ret<0) return ret;
-
-#if 0
- /* Have to do this after getting pic ? */
- ret=soundvision_send_command(SOUNDVISION_DONE_PIC,0,dev);
- if (ret<0) return ret;
-#endif
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS)
+ ret=tiger_get_pic(dev,filename,data,size);
+ else
+ ret=agfa_get_pic(dev,filename,data,size);
- return GP_OK;
+ return ret;
}
- /* thanks to heathhey3@hotmail.com for sending me the trace */
- /* to implement this */
int soundvision_delete_picture(CameraPrivateLibrary *dev, const char *filename) {
- int32_t ret,temp,taken;
- uint8_t data[4],*buffer;
- uint32_t size=4,buflen;
-
- /* yes, we do this twice?? */
- taken=soundvision_photos_taken(dev);
- taken=soundvision_photos_taken(dev);
-
- ret = soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- /* Some traces show sending other than the file we want deleted? */
- ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
-
- ret = soundvision_read(dev, data, size);
- if (ret<0) return ret;
-
- /* Check num taken AGAIN */
- taken=soundvision_photos_taken(dev);
-
- ret = soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
-
- ret = soundvision_read(dev, data, size);
- if (ret<0) return ret;
-
- /* Check num taken AGAIN */
- taken=soundvision_photos_taken(dev);
-
- ret=soundvision_send_command(SOUNDVISION_DELETE,0,dev);
- if (ret<0) return ret;
-
- /* read ff 0f ??? */
- ret = soundvision_read(dev, data, size);
- if (ret<0) return ret;
-
- ret = soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
-
- /* This is the point we notices that in fact a pic is missing */
- /* Why do it 4 times??? Timing?? Who knows */
- taken=soundvision_photos_taken(dev);
- taken=soundvision_photos_taken(dev);
- taken=soundvision_photos_taken(dev);
- taken=soundvision_photos_taken(dev);
-
- buflen = (taken * 13)+1; /* 12 char filenames and space for each */
- /* plus trailing NULL */
- buffer = malloc(buflen);
-
- if (!buffer) {
- GP_DEBUG("Could not allocate %i bytes!",
- buflen);
- return (GP_ERROR_NO_MEMORY);
- }
-
- ret=soundvision_send_command(SOUNDVISION_GET_NAMES, buflen,dev);
- if (ret < 0) {
- free(buffer);
- return ret;
- }
-
- ret = soundvision_read(dev, (void *)buffer, buflen);
- if (ret < 0) {
- free(buffer);
- return ret;
- }
-
- if (dev->file_list) free(dev->file_list);
- dev->file_list = buffer;
-
- ret=soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
- if (ret<0) return ret;
-
- /* always returns ff 0f 00 00 ??? */
- ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
-
- ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
+ int result;
- ret = soundvision_read(dev, data, size);
- if (ret<0) return ret;
+ if (dev->device_type==SOUNDVISION_TIGERFASTFLICKS)
+ result=tiger_delete_picture(dev,filename);
+ else
+ result=agfa_delete_picture(dev,filename);
- return GP_OK;
+ return result;
}
diff --git a/camlibs/soundvision/soundvision.c b/camlibs/soundvision/soundvision.c
index aba83f484..b29570c38 100644
--- a/camlibs/soundvision/soundvision.c
+++ b/camlibs/soundvision/soundvision.c
@@ -1,11 +1,14 @@
/*
* soundvision.c
*
+ * For cameras using the Clarity2 chip made by Soundvision Inc.
+ * Made entirely w/o Soundvision's help. They would not give
+ * documentation. Reverse-engineered from usb-traces.
+ *
* Copyright © 2002-2003 Vince Weaver <vince@deater.net>
*
- * based on the digita driver
- * Copyright © 1999-2000 Johannes Erdfelt
- * Copyright © 1999-2000 VA Linux Systems
+ * Originally based on the digita driver
+ * Copyright © 1999-2000 Johannes Erdfelt, VA Linux Systems
*/
#include "config.h"
@@ -87,20 +90,32 @@ int camera_abilities(CameraAbilitiesList *list) {
for(i=0; models[i].name; i++) {
memset(&a, 0, sizeof(a));
strcpy(a.model, models[i].name);
- if (i==1)
- a.status = GP_DRIVER_STATUS_EXPERIMENTAL;
- else
+
+ /* Agfa and Dshot types owned by author and tested */
+ /* Others the testing not quite certain */
+ if ( (models[i].idVendor==0x06bd) || (models[i].idVendor==0x0919))
a.status = GP_DRIVER_STATUS_PRODUCTION;
+ else
+ a.status = GP_DRIVER_STATUS_EXPERIMENTAL;
+
+ /* For now all are USB. Have the spec for Serial */
+ /* If ever one shows up */
a.port = GP_PORT_USB;
a.speed[0] = 0;
a.usb_vendor = models[i].idVendor;
a.usb_product= models[i].idProduct;
- if (i==1)
- a.operations = GP_OPERATION_NONE;
- else
- a.operations = GP_OPERATION_CAPTURE_IMAGE;
+
+ /* All should support image capture */
+ a.operations = GP_OPERATION_CAPTURE_IMAGE;
+
+ /* Folders not supported on any */
a.folder_operations = GP_FOLDER_OPERATION_NONE;
- /* f_ops will (hopefully) be PUT_FILE for i==1 eventually */
+
+ /* Dshot compat can upload files */
+ if (models[i].idVendor==0x0919) {
+ a.file_operations|=GP_FOLDER_OPERATION_PUT_FILE;
+ }
+
a.file_operations = GP_FILE_OPERATION_PREVIEW |
GP_FILE_OPERATION_DELETE;
@@ -110,7 +125,30 @@ int camera_abilities(CameraAbilitiesList *list) {
}
static int camera_exit (Camera *camera, GPContext *context) {
+
+ GP_DEBUG("MAKE ME GP_DEBUG Reset: %i pics: %i odd_command: %i\n",
+ camera->pl->reset_times,
+ camera->pl->num_pictures,
+ camera->pl->odd_command);
+
+ /* We _must_ reset an even number of times ?? */
+ /* It's more complicated than that. *sigh* */
+ if (camera->pl->reset_times==1) {
+ soundvision_reset (camera->pl,NULL,NULL);
+#if 0
+ /* Odd number of pics */
+ if (camera->pl->num_pictures%2==1) {
+ if (!camera->pl->odd_command)
+ soundvision_reset (camera->pl,NULL,NULL);
+ }
+ else {
+ if (camera->pl->odd_command)
+ soundvision_reset (camera->pl,NULL,NULL);
+ }
+#endif
+ }
+
if (camera->pl) {
if (camera->pl->file_list) {
free(camera->pl->file_list);
@@ -150,60 +188,82 @@ static int soundvision_file_get (Camera *camera, const char *filename, int thumb
unsigned char **data, int *size) {
int buflen,throwaway,result;
-
- GP_DEBUG( "Getting file '%s'...",filename);
-
- soundvision_reset(camera->pl);
- /* Always have to check num photos,
- * then pic size no matter what. Otherwise
- * the camera will stop responding
- */
- throwaway=soundvision_photos_taken(camera->pl);
- if (throwaway<0) return throwaway;
+ if (thumbnail) GP_DEBUG( "Getting thumbnail '%s'...",filename);
+ else GP_DEBUG( "Getting file '%s'...",filename);
+
+ if (camera->pl->device_type==SOUNDVISION_TIGERFASTFLICKS) {
+ result=tiger_set_pc_mode(camera->pl);
+ if (thumbnail) buflen=soundvision_get_thumb_size(camera->pl,filename);
+ else buflen=soundvision_get_pic_size(camera->pl,filename);
+ }
+ else {
+ soundvision_reset(camera->pl,NULL,NULL);
+
+ /* Always have to check num photos,
+ * then pic size no matter what. Otherwise
+ * the camera will stop responding
+ */
+ throwaway=soundvision_photos_taken(camera->pl);
+ if (throwaway<0) {
+ result=throwaway;
+ goto file_get_error;
+ }
+
+
+ /* The below two lines might look wrong, but they aren't! */
+ buflen = soundvision_get_pic_size(camera->pl,filename);
+ if (thumbnail) buflen=soundvision_get_thumb_size(camera->pl,filename);
+ }
- /* The below two lines might look wrong, but they aren't! */
- buflen = soundvision_get_pic_size(camera->pl,filename);
- if (thumbnail) buflen = soundvision_get_thumb_size(camera->pl,filename);
+
+
/* Don't try to download if size equals zero! */
if (buflen) {
*data = malloc(buflen+1);
- if (!*data) return (GP_ERROR_NO_MEMORY);
-
+ if (!*data) {
+ result=GP_ERROR_NO_MEMORY;
+ goto file_get_error;
+ }
+
memset(*data, 0, buflen);
-
+
if (thumbnail) {
result=soundvision_get_thumb(camera->pl, filename, *data, buflen);
if (result < 0) {
- free (*data);
GP_DEBUG("soundvision_get_thumb_failed!");
- return result;
- }
+ goto file_get_error;
+ }
}
- else {
+ else {
result=soundvision_get_pic(camera->pl, filename, *data, buflen);
if (result < 0) {
- free(*data);
GP_DEBUG("soundvision_get_pic_failed!");
- return result;
- }
+ goto file_get_error;
+ }
}
+
+ if (size)
+ *size = buflen;
}
- if (size)
- *size = buflen;
-
+
return GP_OK;
+file_get_error:
+
+ if (*data!=NULL) free(*data);
+ return result;
}
static int get_file_func (CameraFilesystem *fs, const char *folder,
const char *filename, CameraFileType type,
CameraFile *file, void *user_data,
GPContext *context) {
-
+ char *pos;
+
Camera *camera = user_data;
unsigned char *data = NULL;
int size,ret;
@@ -224,9 +284,21 @@ static int get_file_func (CameraFilesystem *fs, const char *folder,
if (!data) return GP_ERROR;
gp_file_set_data_and_size (file, data, size);
+ /* Maybe skip below if EXIF data present? */
gp_file_set_name (file, filename);
- gp_file_set_mime_type (file, GP_MIME_JPEG);
-
+
+ /* As far as I know we only support JPG and MOV */
+ /* Maybe some have MP3??? */
+ pos=strchr (filename, '.');
+ if (pos) {
+ if ((!strcmp(pos,".JPG")) || ((!strcmp(pos,".jpg"))))
+ gp_file_set_mime_type (file, GP_MIME_JPEG);
+ else if (!strcmp(pos,".MOV"))
+ gp_file_set_mime_type (file, GP_MIME_QUICKTIME);
+ else
+ gp_file_set_mime_type (file, GP_MIME_UNKNOWN);
+ }
+
return GP_OK;
}
@@ -235,10 +307,24 @@ static int camera_summary(Camera *camera, CameraText *summary,
char revision[9];
- soundvision_get_revision(camera->pl,revision);
+ soundvision_reset(camera->pl,revision,NULL);
+
+ if (camera->pl->device_type==SOUNDVISION_TIGERFASTFLICKS) {
+
+ int mem_total,mem_free,num_pics;
+ tiger_get_mem(camera->pl,&num_pics,&mem_total,&mem_free);
+
+ sprintf(summary->text, _("Firmware Revision: %8s\n"
+ "Pictures: %i\n"
+ "Memory Total: %ikB\n"
+ "Memory Free: %ikB\n"),
+ revision,num_pics,mem_total,mem_free);
+ }
+
+ else {
+ sprintf(summary->text, _("Firmware Revision: %8s"), revision);
+ }
- sprintf(summary->text, _("Revision: %8s"), revision);
-
return GP_OK;
}
@@ -252,15 +338,34 @@ static int camera_about(Camera *camera, CameraText *about, GPContext *context) {
/* Below contributed by Ben Hague <benhague@btinternet.com> */
static int camera_capture (Camera *camera, CameraCaptureType type,
- CameraFilePath *path, GPContext *context)
-{
- /* this is broken. We capture image to the camera, but
- * we don't detect the new filename. We should detect
- * it and gp_filesystem_append and return
- */
+ CameraFilePath *path, GPContext *context) {
+
+ int result;
+
if (camera->pl->device_type==SOUNDVISION_AGFACL18)
- return (agfa_capture(camera->pl,path));
- return GP_ERROR_NOT_SUPPORTED;
+ result=agfa_capture(camera->pl,path);
+ else if (camera->pl->device_type==SOUNDVISION_TIGERFASTFLICKS) {
+ result=tiger_capture(camera->pl,path);
+ }
+ else return GP_ERROR_NOT_SUPPORTED;
+
+
+ soundvision_get_file_list(camera->pl);
+
+ /* For some reason last taken picture is first on tiger? */
+ /* Might be last on Agfa. Who knows. Craziness. */
+ if (camera->pl->num_pictures<1) return GP_ERROR;
+
+ sprintf(path->name,camera->pl->file_list);
+ strcpy (path->folder, "/");
+
+
+/* gp_filesystem_append (camera->fs, path->folder,
+ path->name, context);*/
+
+
+
+ return GP_OK;
}
@@ -281,6 +386,48 @@ static int delete_file_func (CameraFilesystem *fs, const char *folder,
}
+static int put_file_func (CameraFilesystem *fs, const char *folder,
+ CameraFile *file, void *data, GPContext *context) {
+
+ Camera *camera=data;
+ const char *filename;
+ const char *data_file;
+ long data_size;
+
+ /*
+ * Upload the file to the camera. Use gp_file_get_data_and_size,
+ * gp_file_get_name, etc.
+ */
+
+ gp_file_get_name(file, &filename);
+
+ GP_DEBUG ("*** put_file_func");
+ GP_DEBUG ("*** folder: %s", folder);
+ GP_DEBUG ("*** filename: %s", filename);
+
+ gp_file_get_data_and_size (file, &data_file, &data_size);
+ if ( data_size == 0) {
+ gp_context_error (context,
+ _("The file to be uploaded has a null length"));
+ return GP_ERROR_BAD_PARAMETERS;
+ }
+
+ /* Should check memory here */
+
+ /* if (available_memory < data_size) {
+ gp_context_error (context,
+ _("Not enough memory available on the memory card"));
+ return GP_ERROR_NO_MEMORY;
+ }
+ */
+
+ tiger_upload_file (camera->pl, filename,data_file,data_size);
+
+ return GP_OK;
+}
+
+
+
int camera_init(Camera *camera, GPContext *context) {
GPPortSettings settings;
@@ -303,9 +450,9 @@ int camera_init(Camera *camera, GPContext *context) {
/* Use the defaults the core parsed */
ret=gp_port_set_settings(camera->port,settings);
- if (ret<0) return ret;
-
+ if (ret<0) return ret;
break;
+
case GP_PORT_SERIAL:
return GP_ERROR_IO_SUPPORTED_SERIAL;
default:
@@ -314,19 +461,28 @@ int camera_init(Camera *camera, GPContext *context) {
+ /* Set up camera private library */
camera->pl = malloc (sizeof (CameraPrivateLibrary));
if (!camera->pl) return (GP_ERROR_NO_MEMORY);
memset (camera->pl, 0, sizeof (CameraPrivateLibrary));
camera->pl->gpdev = camera->port;
+
+ /* Set up the sub-architectures */
+ /* Default to Agfa. Should we default otherwise? */
camera->pl->device_type=SOUNDVISION_AGFACL18;
-
gp_camera_get_abilities (camera, &a);
- if ((a.usb_vendor==0x919) && (a.usb_product==0x0100)) {
+
+ if ((a.usb_vendor==0x0919) && (a.usb_product==0x0100)) {
camera->pl->device_type=SOUNDVISION_TIGERFASTFLICKS;
}
-
- ret = soundvision_reset (camera->pl);
+
+ /* Keep track. We _must_ reset an even number of times */
+ camera->pl->reset_times=0;
+ camera->pl->odd_command=0;
+
+ /* Reset the camera */
+ ret = soundvision_reset (camera->pl,NULL,NULL);
if (ret < 0) {
free (camera->pl);
camera->pl = NULL;
@@ -337,6 +493,11 @@ int camera_init(Camera *camera, GPContext *context) {
gp_filesystem_set_list_funcs (camera->fs, file_list_func, NULL, camera);
gp_filesystem_set_file_funcs (camera->fs, get_file_func, delete_file_func,
camera);
+ gp_filesystem_set_folder_funcs (camera->fs, put_file_func,
+ NULL, NULL, NULL, camera);
+
+
return GP_OK;
}
+
diff --git a/camlibs/soundvision/soundvision.h b/camlibs/soundvision/soundvision.h
index a3c635b93..954ab1f4f 100644
--- a/camlibs/soundvision/soundvision.h
+++ b/camlibs/soundvision/soundvision.h
@@ -1,22 +1,34 @@
#ifndef soundvision_H
#define soundvision_H
-#define SOUNDVISION_RESET 0x0001
#define SOUNDVISION_START_TRANSACTION 0x0001
-#define SOUNDVISION_TAKEPIC1 0x0004
+
+#define SOUNDVISION_SETPC2 0x0004
+
+#define SOUNDVISION_GET_MEM_TOTAL 0x0065
+
+#define SOUNDVISION_GET_MEM_FREE 0x0069
+
#define SOUNDVISION_TAKEPIC3 0x0092
-#define SOUNDVISION_TAKEPIC2 0x0094
+
+#define SOUNDVISION_SETPC1 0x0094
+
#define SOUNDVISION_DELETE 0x0100
#define SOUNDVISION_GET_PIC 0x0101
#define SOUNDVISION_GET_PIC_SIZE 0x0102
#define SOUNDVISION_GET_NUM_PICS 0x0103
+
#define SOUNDVISION_DELETE_ALL2 0x0105
#define SOUNDVISION_GET_VERSION 0x0106
+
#define SOUNDVISION_GET_NAMES 0x0108
+#define SOUNDVISION_PUT_FILE 0x0109
#define SOUNDVISION_GET_THUMB_SIZE 0x010A
#define SOUNDVISION_GET_THUMB 0x010B
+
#define SOUNDVISION_STATUS 0x0114
-#define SOUNDVISION_DONE_PIC 0x01FF
+#define SOUNDVISION_INIT2 0x0115
+
#define SOUNDVISION_DONE_TRANSACTION 0x01FF
#define SOUNDVISION_AGFACL18 0
@@ -26,20 +38,21 @@ struct _CameraPrivateLibrary {
GPPort *gpdev;
int device_type;
+ int reset_times,odd_command;
int num_pictures;
char *file_list;
};
/* commands.c */
-
-int soundvision_reset(CameraPrivateLibrary *dev);
+int32_t soundvision_send_command(uint32_t command, uint32_t argument,
+ CameraPrivateLibrary *dev);
+int soundvision_reset(CameraPrivateLibrary *dev, char *revision, char *status);
int soundvision_get_revision(CameraPrivateLibrary *dev,char *revision);
-int soundvision_get_status(CameraPrivateLibrary *dev, int *taken,
- int *available, int *rawcount);
+int soundvision_get_status(CameraPrivateLibrary *dev, char *status);
int soundvision_photos_taken(CameraPrivateLibrary *dev);
@@ -58,11 +71,32 @@ int soundvision_get_pic(CameraPrivateLibrary *dev, const char *filename,
int agfa_capture(CameraPrivateLibrary *dev, CameraFilePath *path);
int agfa_delete_picture(CameraPrivateLibrary *dev, const char *filename);
+int agfa_get_file_list(CameraPrivateLibrary *dev);
+int agfa_get_pic(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size);
+int agfa_get_pic_size(CameraPrivateLibrary *dev, const char *filename);
+int agfa_get_thumb(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size);
+int agfa_get_thumb_size(CameraPrivateLibrary *dev, const char *filename);
+
+
+
+
+
/* tiger_fastflicks.c */
-int tiger_upload_file(CameraPrivateLibrary *dev, const char *filename);
+int tiger_set_pc_mode(CameraPrivateLibrary *dev);
+int tiger_upload_file(CameraPrivateLibrary *dev, const char *filename,
+ const char *data, long data_size);
int tiger_delete_picture(CameraPrivateLibrary *dev, const char *filename);
-
-
+int tiger_capture(CameraPrivateLibrary *dev, CameraFilePath *path);
+int tiger_get_mem(CameraPrivateLibrary *dev, int *num_pics, int *mem_total, int *mem_free);
+int tiger_get_file_list(CameraPrivateLibrary *dev);
+int tiger_get_pic(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size);
+int tiger_get_pic_size(CameraPrivateLibrary *dev, const char *filename);
+int tiger_get_thumb(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size);
+int tiger_get_thumb_size(CameraPrivateLibrary *dev, const char *filename);
#endif
diff --git a/camlibs/soundvision/tiger_fastflicks.c b/camlibs/soundvision/tiger_fastflicks.c
index 8285f90fb..8b9748055 100644
--- a/camlibs/soundvision/tiger_fastflicks.c
+++ b/camlibs/soundvision/tiger_fastflicks.c
@@ -1,20 +1,23 @@
/*
* tiger_fastflicks.c
*
- * Commands specific to Tiger FastFlicks cameras
- * Fast Flicks camera, made by Tiger Electronics.
+ * Commands specific to soundvision camears with usbid
+ * 0x0919:0x0100 and possibly others.
+ *
+ * Tiger FastFlicks was first camera of this type
+ * to be supported.
+ *
* Initial Support added by Dr. William Bland <wjb@abstractnonsense.com>
* Other help from Adrien Hernot <amh@BSD-DK.dk>
*
- * Copyright 2002 Vince Weaver <vince@deater.net>
+ * Vince Weaver got such a camera in Jan 2003 and massively
+ * re-wrote things.
+ *
+ * Copyright 2002-2003 Vince Weaver <vince@deater.net>
*/
-
-/* the fastflicks seems to use version 5.x of the soundvision protocol */
-/* it will work properly with version 2.16b that Agfa Cl18 uses, but */
-/* the native updated commands might work better. They can be added */
-/* here and be pointed to in the soundvision.c file. You just have to */
-/* track down the traces and test them out. */
+/* Routines for the 0x919:0x100 cameras that aren't compatible */
+/* with the others go in this file */
#include "config.h"
@@ -35,44 +38,418 @@
#define GP_MODULE "soundvision"
- /* This is possible, traces exist. If someone adds support */
- /* e-mail the maintainer. */
- /* be sure to put */
- /* PUT_FILE for i==1 eventually under f_ops in camera_abilities */
- /* in soundvision.c */
-int tiger_upload_file(CameraPrivateLibrary *dev, const char *filename) {
-
- return 0;
+
+ /* Used at start of most tiger commands. Also */
+ /* Seems to set the camera into "PC" mode */
+int tiger_set_pc_mode(CameraPrivateLibrary *dev) {
+
+ int result;
+
+ GP_DEBUG("tiger_set_pc_mode");
+
+ result=soundvision_send_command(SOUNDVISION_START_TRANSACTION,0,dev);
+ if (result<0) goto set_pc_error;
+
+ result=soundvision_get_revision(dev,NULL);
+ if (result<0) goto set_pc_error;
+
+ result=soundvision_send_command(SOUNDVISION_SETPC1,0,dev);
+ if (result<0) goto set_pc_error;
+
+ result=soundvision_send_command(SOUNDVISION_SETPC2,0,dev);
+ if (result<0) goto set_pc_error;
+
+ return GP_OK;
+
+set_pc_error:
+ return result;
+}
+
+
+
+
+ /* This is packet-for-packet what windows does */
+ /* The camera takes it all in stride. */
+ /* Yet uploaded file never appears. Why?? */
+int tiger_upload_file(CameraPrivateLibrary *dev,
+ const char *filename,
+ const char *data,
+ long size) {
+ int result=0;
+ char return_value[4];
+
+ uint32_t our_size;
+ char *our_data=NULL;
+
+ /* When we upload, the first 3 bytes are little-endian */
+ /* File-size followed by the actual file */
+ our_size=size+4;
+ our_data=calloc(our_size,sizeof(char));
+ if (our_data==NULL) {
+ goto upload_error;
+ }
+
+ htole32a(&our_data[0],size);
+ memcpy(our_data+4,data,size);
+
+
+ GP_DEBUG("File: %s Size=%i\n",filename,size);
+/* for(result=0;result<our_size;result++) {
+ printf("%x ",our_data[result]);
+ }
+*/
+
+ result=tiger_set_pc_mode(dev);
+ if (result<0) goto upload_error;
+
+ result=soundvision_get_revision(dev,NULL);
+ if (result<0) goto upload_error;
+
+ result=soundvision_send_command(SOUNDVISION_GET_MEM_FREE,0,dev);
+ if (result<0) goto upload_error;
+
+ result=soundvision_read(dev, &return_value, sizeof(return_value));
+ if (result<0) goto upload_error;
+
+ result=soundvision_send_command(SOUNDVISION_PUT_FILE,size,dev);
+ if (result<0) goto upload_error;
+
+ result=soundvision_read(dev, &return_value, sizeof(return_value));
+ if (result<0) goto upload_error;
+
+ result=gp_port_write(dev->gpdev,our_data,our_size);
+ if (result<0) goto upload_error;
+
+ free(our_data);
+ our_data=NULL;
+
+#if 0
+ /* Some traces show the following, though most likely */
+ /* this is just the windows driver updating the file list */
+
+ result=soundvision_photos_taken(dev);
+ result=soundvision_get_file_list(dev);
+
+ result=soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
+ if (result<0) goto upload_error;
+
+ result=soundvision_read(dev, &return_value, sizeof(return_value));
+ if (result<0) goto upload_error;
+
+ result=soundvision_send_file_command("000VINCE.JPG",dev);
+
+ result=soundvision_read(dev, &return_value, sizeof(return_value));
+ if (result<0) goto upload_error;
+
+ result=soundvision_send_command(SOUNDVISION_DONE_TRANSACTION,0,dev);
+ if (result<0) goto upload_error;
+#endif
+ return GP_OK;
+
+upload_error:
+ if (our_data!=NULL) free(our_data);
+ GP_DEBUG("Error in tiger_upload_file");
+ return result;
}
- /* This is just a start, from the traces I have */
- /* Hopefully someone who has the camera will finish this */
- /* as it is impossible to test w/o the camera */
int tiger_delete_picture(CameraPrivateLibrary *dev, const char *filename) {
- int32_t ret,temp,taken,ascii_status[2];
+ int32_t ret,temp;
+
+ ret = tiger_set_pc_mode(dev);
+ if (ret<0) goto delete_pic_error;
+
+ ret = soundvision_send_command(SOUNDVISION_DELETE,0,dev);
+ if (ret<0) goto delete_pic_error;
+
+ /* should get fff if all is well */
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) goto delete_pic_error;
+
+ ret=soundvision_send_file_command(filename,dev);
+ if (ret<0) goto delete_pic_error;
+
+ ret = soundvision_send_command(SOUNDVISION_DONE_TRANSACTION,0,dev);
+ if (ret<0) goto delete_pic_error;
+
+ return GP_OK;
+
+delete_pic_error:
+ return ret;
+
+}
+
+int tiger_get_mem(CameraPrivateLibrary *dev, int *num_pics, int *mem_total, int *mem_free) {
+
+ int result=0;
+ int temp_result;
+
+ *num_pics=soundvision_photos_taken(dev);
+ if (*num_pics<0) goto get_mem_error;
+
+ result=soundvision_get_revision(dev,NULL);
+ if (result<0) goto get_mem_error;
+
+ result=soundvision_send_command(SOUNDVISION_GET_MEM_TOTAL,0,dev);
+ if (result<0) goto get_mem_error;
+
+ result=soundvision_read(dev, &temp_result, sizeof(temp_result));
+ if (result<0) goto get_mem_error;
+
+ *mem_total=le32toh(temp_result);
+
+ result=soundvision_send_command(SOUNDVISION_GET_MEM_FREE,0,dev);
+ if (result<0) goto get_mem_error;
+
+ result=soundvision_read(dev, &temp_result, sizeof(temp_result));
+ if (result<0) goto get_mem_error;
+
+ *mem_free=le32toh(temp_result);
+
+ return GP_OK;
+
+get_mem_error:
+ GP_DEBUG("Error in tiger_get_mem");
+ return result;
+
+}
+
+
+int tiger_capture(CameraPrivateLibrary *dev, CameraFilePath *path) {
+
+ int result=0,start_pics,num_pics,mem_total,mem_free;
+
+ result=soundvision_send_command(SOUNDVISION_START_TRANSACTION,0,dev);
+ if (result<0) goto tiger_capture_error;
+
+ result=soundvision_get_revision(dev,NULL);
+ if (result<0) goto tiger_capture_error;
+
+ result=tiger_get_mem(dev,&start_pics,&mem_total,&mem_free);
+ if (result<0) goto tiger_capture_error;
+
+ result=soundvision_send_command(SOUNDVISION_SETPC2,0,dev);
+ if (result<0) goto tiger_capture_error;
+
+ result=soundvision_send_command(SOUNDVISION_TAKEPIC3,0,dev);
+ if (result<0) goto tiger_capture_error;
+
+ result=soundvision_send_command(SOUNDVISION_SETPC1,0,dev);
+ if (result<0) goto tiger_capture_error;
+
+ result=tiger_get_mem(dev,&num_pics,&mem_total,&mem_free);
+ if (result<0) goto tiger_capture_error;
+
+ while(num_pics==start_pics) {
+ sleep(4);
+ result=tiger_get_mem(dev,&num_pics,&mem_total,&mem_free);
+ if (result<0) goto tiger_capture_error;
+ }
+
+ result=tiger_get_mem(dev,&num_pics,&mem_total,&mem_free);
+ if (result<0) goto tiger_capture_error;
+
+ return GP_OK;
+
+tiger_capture_error:
+ GP_DEBUG("ERROR with tiger_capture");
+ return result;
- ret = soundvision_send_command(SOUNDVISION_START_TRANSACTION,0,dev);
- if (ret<0) return ret;
+}
+
+
+
+int tiger_get_file_list(CameraPrivateLibrary *dev) {
+
+ char *buffer=NULL;
+ int32_t ret, taken, buflen,i;
+
+ ret=tiger_set_pc_mode(dev);
+ if (ret<0) goto list_files_error;
- ret = soundvision_send_command(SOUNDVISION_GET_VERSION,0,dev);
- if (ret<0) return ret;
+ if ( (taken=soundvision_photos_taken(dev)) < 0) {
+ ret=taken;
+ goto list_files_error;
+ }
+
+ dev->num_pictures = taken;
+
+ if (taken>0) {
+
+ buflen = (taken * 13)+1; /* 12 char filenames and space for each */
+ /* plus trailing NULL */
+
+ buffer = malloc(buflen);
- ret = soundvision_read(dev, &ascii_status, sizeof(ascii_status));
- if (ret<0) return ret;
+ if (!buffer) {
+ GP_DEBUG("Could not allocate %i bytes!",buflen);
+ ret=GP_ERROR_NO_MEMORY;
+ goto list_files_error;
+ }
+
+ ret=soundvision_send_command(SOUNDVISION_GET_NAMES, buflen, dev);
+ if (ret < 0) {
+ goto list_files_error;
+ }
+
+
+ ret = soundvision_read(dev, (void *)buffer, buflen);
+ if (ret < 0) {
+ goto list_files_error;
+ }
+
+
+ if (dev->file_list) free(dev->file_list);
+
+ dev->file_list = malloc(taken * 13);
+
+ if (!dev->file_list) {
+ GP_DEBUG("Could not allocate %i bytes!",taken*13);
+ ret=GP_ERROR_NO_MEMORY;
+ goto list_files_error;
+ }
+
+ for(i=0;i<taken*13;i++) if (buffer[i]==' ') buffer[i]='\0';
+ memcpy(dev->file_list, buffer, taken * 13);
+ free(buffer);
+ buffer=NULL;
+
+
+
+ }
+
+
+ ret=soundvision_send_command(SOUNDVISION_DONE_TRANSACTION, 0, dev);
+ if (ret<0) goto list_files_error;
+
+ /* If we have >1 pics we should stat a file?*/
+ /* Some traces do, some don't... */
+/* if (taken>0)
+ soundvision_get_pic_size(dev,dev->file_list);
+ */
+
+ return GP_OK;
+
+list_files_error:
+
+ if (buffer!=NULL) free(buffer);
+ return ret;
+}
+
+int tiger_get_pic(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size) {
+
+ int32_t ret,temp;
+
+ GP_DEBUG("tiger_get_pic");
+
+ dev->odd_command=1;
+
+ ret=soundvision_get_revision(dev,NULL);
+
+ ret = soundvision_send_command(SOUNDVISION_GET_PIC,0,dev);
+ if (ret<0) goto get_pic_error;
+
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) goto get_pic_error;
+
+ ret=soundvision_send_file_command(filename,dev);
+ if (ret<0) goto get_pic_error;
+
+ ret = soundvision_read(dev, data, size);
+ if (ret<0) goto get_pic_error;
+
+ ret=soundvision_send_command(SOUNDVISION_DONE_TRANSACTION,0,dev);
+ if (ret<0) goto get_pic_error;
- ret = soundvision_send_command(SOUNDVISION_START_TRANSACTION,0,dev);
- if (ret<0) return ret;
+ return GP_OK;
+
+get_pic_error:
+ return ret;
+
+
+}
+
+int tiger_get_pic_size(CameraPrivateLibrary *dev, const char *filename) {
+
+ int32_t ret,temp;
+ uint32_t size;
+
+ GP_DEBUG("tiger_get_pic_size");
+
+ ret=soundvision_send_command(SOUNDVISION_GET_PIC_SIZE,0,dev);
+ if (ret<0) goto pic_size_error;
+
+ /* should check that we get 0x0fff */
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) goto pic_size_error;
+ ret=soundvision_send_file_command(filename,dev);
+ if (ret<0) goto pic_size_error;
+
+ ret = soundvision_read(dev, &size, sizeof(size));
+ if (ret<0) goto pic_size_error;
+
+ return le32toh(size);
+
+pic_size_error:
+ return ret;
+
+}
+
+
+int tiger_get_thumb_size(CameraPrivateLibrary *dev, const char *filename) {
+
+ int32_t ret,temp;
+ uint32_t size;
+
+
+ GP_DEBUG("tiger_get_thumb_size");
+
+ ret=soundvision_send_command(SOUNDVISION_GET_THUMB_SIZE,0,dev);
+ if (ret<0) goto thumb_size_error;
+
ret = soundvision_read(dev, &temp, sizeof(temp));
- if (ret<0) return ret;
+ if (ret<0) goto thumb_size_error;
+
+ soundvision_send_file_command(filename,dev);
+ if (ret<0) goto thumb_size_error;
+
+ ret = soundvision_read(dev, &size, sizeof(size));
+ if (ret<0) goto thumb_size_error;
+
+ return le32toh(size);
+
+thumb_size_error:
+ return ret;
+}
+
+int tiger_get_thumb(CameraPrivateLibrary *dev, const char *filename,
+ unsigned char *data,int size) {
+ int32_t ret,temp;
+
+ ret=soundvision_get_revision(dev,NULL);
+
+ ret = soundvision_send_command(SOUNDVISION_GET_THUMB,0,dev);
+ if (ret<0) goto get_thumb_error;
+
+ ret = soundvision_read(dev, &temp, sizeof(temp));
+ if (ret<0) goto get_thumb_error;
+
ret=soundvision_send_file_command(filename,dev);
- if (ret<0) return ret;
+ if (ret<0) goto get_thumb_error;
- taken=soundvision_photos_taken(dev);
+ ret = soundvision_read(dev, data, size);
+ if (ret<0) goto get_thumb_error;
+ ret=soundvision_send_command(SOUNDVISION_DONE_TRANSACTION,0,dev);
+ if (ret<0) goto get_thumb_error;
+
return GP_OK;
+
+get_thumb_error:
+ return ret;
+
}
-