diff options
author | Vince Weaver <vince@deater.net> | 2003-02-11 17:24:53 +0000 |
---|---|---|
committer | Vince Weaver <vince@deater.net> | 2003-02-11 17:24:53 +0000 |
commit | 97c46af2ff120702f3935af45af64859b0f1d054 (patch) | |
tree | b08c88da7ee5c5c9d67efcc1b9252a3627260336 /camlibs/soundvision | |
parent | 05c2f608b0c464e9d318516b990aacf6d87c6986 (diff) | |
download | libgphoto2-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/BUGS | 14 | ||||
-rw-r--r-- | camlibs/soundvision/ChangeLog | 11 | ||||
-rw-r--r-- | camlibs/soundvision/agfa_cl18.c | 173 | ||||
-rw-r--r-- | camlibs/soundvision/commands.c | 401 | ||||
-rw-r--r-- | camlibs/soundvision/soundvision.c | 275 | ||||
-rw-r--r-- | camlibs/soundvision/soundvision.h | 56 | ||||
-rw-r--r-- | camlibs/soundvision/tiger_fastflicks.c | 443 |
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; + } - |