From 8c1a9df4c9c19db699890db59eedcbdd09aa8a95 Mon Sep 17 00:00:00 2001 From: Hubert Figuiere Date: Wed, 7 Jun 2006 04:49:32 +0000 Subject: [PATCH] Commit e01_return_photographic_status.patch git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@8854 67ed7778-7388-44ab-90cf-0a291f65f57c --- camlibs/canon/ChangeLog | 5 +++++ camlibs/canon/canon.c | 32 ++++++++++++++++++++++++++++---- camlibs/canon/library.c | 11 +++++++---- camlibs/canon/usb.c | 12 ++++++++++-- camlibs/canon/usb.h | 2 +- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/camlibs/canon/ChangeLog b/camlibs/canon/ChangeLog index be3f693cd..c9deaa443 100644 --- a/camlibs/canon/ChangeLog +++ b/camlibs/canon/ChangeLog @@ -1,5 +1,10 @@ 2006-06-07 Paul Walmsley + * canon.c, usb.[ch], library.c: When the camera cannot capture an + image due to a 'photographic failure,' return a gphoto2 error code + resembling the actual failure code, rather than simply returning a + generic error. Tested on the Canon EOS 5D. + * canon.[ch], usb.[ch]: Adds support for downloading "secondary images" -- the JPEGs created when the capture resolution is set to the "RAW + JPEG" modes -- for the Canon EOS 5D camera. diff --git a/camlibs/canon/canon.c b/camlibs/canon/canon.c index 76b7e2907..577dd23a9 100644 --- a/camlibs/canon/canon.c +++ b/camlibs/canon/canon.c @@ -1100,6 +1100,8 @@ canon_int_capture_preview (Camera *camera, unsigned char **data, int *length, unsigned char *b_data_orig = NULL; unsigned char **b_data = &b_data_orig; + int photo_status; + /* Should we download the thumbnail, or the full image ? */ if (camera->pl->capture_size == CAPTURE_FULL_IMAGE) transfermode = REMOTE_CAPTURE_FULL_TO_PC; @@ -1172,11 +1174,21 @@ canon_int_capture_preview (Camera *camera, unsigned char **data, int *length, Can't use normal "canon_int_do_control_command", as we must read the interrupt pipe before the response comes back for this commmand. */ - *data = canon_usb_capture_dialogue ( camera, &status, context ); + *data = canon_usb_capture_dialogue ( camera, &status, &photo_status, context ); if ( *data == NULL ) { /* Try to leave camera in a usable state. */ canon_int_end_remote_control (camera, context); - return GP_ERROR_OS_FAILURE; + + /* XXX It would be nice if we had a way to + decode the camera error state for the caller + application. For example, + photo_status == 0x01 seems to mean + "autofocus failure" on the EOS 5D. */ + if (photo_status != 0) + return GP_ERROR_CAMERA_ERROR; + else + return GP_ERROR_OS_FAILURE; + } if (transfermode == REMOTE_CAPTURE_FULL_TO_PC) { @@ -1420,6 +1432,8 @@ canon_int_capture_image (Camera *camera, CameraFilePath *path, * directories */ int initial_state_len, final_state_len; + int photo_status; + /* Should we save the thumbnail, or the full image ? */ if (camera->pl->capture_size == CAPTURE_THUMB) transfermode = REMOTE_CAPTURE_THUMB_TO_DRIVE; @@ -1541,11 +1555,21 @@ canon_int_capture_image (Camera *camera, CameraFilePath *path, Can't use normal "canon_int_do_control_command", as we must read the interrupt pipe before the response comes back for this commmand. */ - data = canon_usb_capture_dialogue ( camera, &status, context ); + data = canon_usb_capture_dialogue ( camera, &status, &photo_status, context ); if ( data == NULL ) { /* Try to leave camera in a usable state. */ canon_int_end_remote_control (camera, context); - return GP_ERROR_OS_FAILURE; + + /* XXX It would be nice if we had a way to + decode the camera error state for the caller + application. For example, + photo_status == 0x01 seems to mean + "autofocus failure" on the EOS 5D. */ + if (photo_status != 0) + return GP_ERROR_CAMERA_ERROR; + else + return GP_ERROR_OS_FAILURE; + } /* End release mode */ diff --git a/camlibs/canon/library.c b/camlibs/canon/library.c index 97466d228..e8569ac4e 100644 --- a/camlibs/canon/library.c +++ b/camlibs/canon/library.c @@ -431,7 +431,7 @@ camera_exit (Camera *camera, GPContext *context) * downloads its thumbnail to the host computer without storing it on * the camera. * - * Returns: GP_OK + * Returns: gphoto2 error code * */ static int @@ -445,7 +445,7 @@ camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context) code = canon_int_capture_preview (camera, &data, &size, context); if ( code != GP_OK) { gp_context_error (context, _("Error capturing image")); - return GP_ERROR; + return code; } gp_file_set_data_and_size ( file, data, size ); gp_file_set_mime_type (file, GP_MIME_JPEG); /* always */ @@ -471,15 +471,18 @@ static int camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path, GPContext *context) { + int code; + GP_DEBUG ("canon_capture() called"); if (type != GP_CAPTURE_IMAGE) { return GP_ERROR_NOT_SUPPORTED; } - if (canon_int_capture_image (camera, path, context) != GP_OK) { + code = canon_int_capture_image (camera, path, context); + if (code != GP_OK) { gp_context_error (context, _("Error capturing image")); - return GP_ERROR; + return code; } return GP_OK; diff --git a/camlibs/canon/usb.c b/camlibs/canon/usb.c index 48a69fe0f..d6f763c3d 100644 --- a/camlibs/canon/usb.c +++ b/camlibs/canon/usb.c @@ -925,6 +925,9 @@ int canon_usb_poll_interrupt_multiple ( Camera *camera[], int n_cameras, * canon_usb_capture_dialogue: * @camera: the Camera to work with * @return_length: number of bytes to read from the camera as response + * @photo_status: a pointer to an int that returns a photographic status + * error codes from the camera (if any) if this function + * returns NULL * @context: context for error reporting * * Handles the "capture image" command, where we must read the @@ -935,11 +938,12 @@ int canon_usb_poll_interrupt_multiple ( Camera *camera[], int n_cameras, * * Returns: a char * that points to the data read from the camera (or * NULL on failure), and sets what @return_length points to to the number - * of bytes read. + * of bytes read. If this function returns NULL, return any photographic + * failure error codes in what @photo_status points to. * */ unsigned char * -canon_usb_capture_dialogue (Camera *camera, int *return_length, GPContext *context ) +canon_usb_capture_dialogue (Camera *camera, int *return_length, int *photo_status, GPContext *context ) { int status; unsigned char payload[9]; /* used for sending data to camera */ @@ -954,6 +958,9 @@ canon_usb_capture_dialogue (Camera *camera, int *return_length, GPContext *conte GP_DEBUG ("canon_usb_capture_dialogue()"); + *photo_status = 0; /* This should only be checked by the caller + if canon_usb_capture_dialogue() returns null */ + /* Build payload for command, which contains subfunction code */ memset (payload, 0x00, sizeof (payload)); payload[0] = 4; @@ -1114,6 +1121,7 @@ canon_usb_capture_dialogue (Camera *camera, int *return_length, GPContext *conte GP_LOG ( GP_LOG_ERROR, _("canon_usb_capture_dialogue:" " photographic failure signaled, code = 0x%08x"), le32atoh ( buf2+16 ) ); + *photo_status = le32atoh ( buf2+16 ); goto FAIL2; } else { diff --git a/camlibs/canon/usb.h b/camlibs/canon/usb.h index 9d6d9f3c3..bd5245a5e 100644 --- a/camlibs/canon/usb.h +++ b/camlibs/canon/usb.h @@ -257,7 +257,7 @@ int canon_usb_camera_init (Camera *camera, GPContext *context); int canon_usb_set_file_time ( Camera *camera, char *camera_filename, time_t time, GPContext *context); int canon_usb_put_file (Camera *camera, CameraFile *file, char *destname, char *destpath, GPContext *context); -unsigned char *canon_usb_capture_dialogue (Camera *camera, int *return_length, GPContext *context ); +unsigned char *canon_usb_capture_dialogue (Camera *camera, int *return_length, int *photo_status, GPContext *context ); unsigned char *canon_usb_dialogue_full (Camera *camera, canonCommandIndex canon_funct, int *return_length, const char *payload, int payload_length); unsigned char *canon_usb_dialogue (Camera *camera, canonCommandIndex canon_funct,