diff --git a/camlibs/ptp/library.c b/camlibs/ptp/library.c index 4b594675d..40c049ac6 100644 --- a/camlibs/ptp/library.c +++ b/camlibs/ptp/library.c @@ -132,6 +132,8 @@ translate_gp_result (int result) } #define CPR(camera,result) {short r=(result); if (r!=PTP_RC_OK) {report_result ((camera), r); return (translate_ptp_result (r));}} +#define CHECK(c,r) {int ret=(r);if(ret<0){log_error(c,ret);return(ret);}} + static struct { const char *model; @@ -218,7 +220,7 @@ camera_abilities (CameraAbilitiesList *list) a.usb_vendor = models[i].usb_vendor; a.usb_product= models[i].usb_product; a.operations = GP_OPERATION_NONE; - a.file_operations = GP_FILE_OPERATION_NONE; + a.file_operations = GP_FILE_OPERATION_PREVIEW; a.folder_operations = GP_FOLDER_OPERATION_NONE; CR (gp_abilities_list_append (list, a)); } @@ -289,6 +291,8 @@ static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *data) { +// XXX Hacked version works properly for JPG files only! +// Will be changed in future Camera *camera = data; unsigned char *fdata = NULL; char image_id_string[] = {0, 0, 0, 0, 0}; @@ -296,7 +300,7 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, PTPObjectInfo ptp_objectinfo; - if (strlen (filename) != 14) + if (strlen (filename) != 13) return (GP_ERROR_FILE_NOT_FOUND); if (strcmp (folder, "/")) return (GP_ERROR_DIRECTORY_NOT_FOUND); @@ -306,22 +310,30 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, strncpy (image_id_string, filename+5,4); image_id = atol (image_id_string); - switch (type) { case GP_FILE_TYPE_NORMAL: CPR (camera, ptp_getobjectinfo(&camera->pl->params, &camera->pl->params.handles, image_id, &ptp_objectinfo)); - fdata=malloc(ptp_objectinfo.ObjectCompressedSize+PTP_REQ_HDR_LEN); + fdata=malloc(ptp_objectinfo.ObjectCompressedSize); CPR (camera, ptp_getobject(&camera->pl->params, &camera->pl->params.handles, &ptp_objectinfo, image_id, fdata)); break; + case GP_FILE_TYPE_PREVIEW: + CPR (camera, ptp_getobjectinfo(&camera->pl->params, + &camera->pl->params.handles, image_id, &ptp_objectinfo)); + fdata=malloc(ptp_objectinfo.ObjectCompressedSize); + CPR (camera, ptp_getthumb(&camera->pl->params, + &camera->pl->params.handles, &ptp_objectinfo, image_id, fdata)); + break; + + default: - return (GP_ERROR_NOT_SUPPORTED); + } - CPR (camera, gp_file_set_data_and_size (file, fdata+PTP_REQ_HDR_LEN, ptp_objectinfo.ObjectCompressedSize)); - CPR (camera, gp_file_set_mime_type (file, GP_MIME_JPEG)); + CHECK (camera, gp_file_set_data_and_size (file, fdata, ptp_objectinfo.ObjectCompressedSize)); + CHECK (camera, gp_file_set_mime_type (file, GP_MIME_JPEG)); return (GP_OK); } diff --git a/camlibs/ptp/ptp.c b/camlibs/ptp/ptp.c index 8c2d966d0..b8775636c 100644 --- a/camlibs/ptp/ptp.c +++ b/camlibs/ptp/ptp.c @@ -408,7 +408,9 @@ ptp_getobject(PTPParams* params, PTPObjectHandles* objecthandles, free(req); return PTP_ERROR_IO; } - ptr=req; req=(PTPReq*)object; + { + char* obj_tmp=malloc(objectinfo->ObjectCompressedSize+PTP_REQ_HDR_LEN); + ptr=req; req=(PTPReq*)obj_tmp; ret=params->read_func((unsigned char *) req, objectinfo->ObjectCompressedSize+PTP_REQ_HDR_LEN, params->data); @@ -424,10 +426,81 @@ ptp_getobject(PTPParams* params, PTPObjectHandles* objecthandles, if (ret!=PTP_RC_OK) ret=PTP_ERROR_IO; else ret=(req->type==PTP_TYPE_DATA)? req->code:PTP_ERROR_DATA_EXPECTED; + free(obj_tmp); req=ptr; free(req); return ret; } + memcpy(object, req->data, objectinfo->ObjectCompressedSize); + free(obj_tmp); + } + req=ptr; + ret=ptp_getresp(params, req); + if ((ret!=PTP_RC_OK) || + (req->type!=PTP_TYPE_RESP) || + (req->code!=PTP_RC_OK)) { + ptp_error (params, "ptp_getobject getting resp"); +#ifdef DEBUG + ptp_error (params, "GetObject data returned:\nlen=0x%8.8x" + "type=0x%4.4x code=0x%4.4x ID=0x%8.8x\n", + req->len, req->type, req->code, req->trans_id); +#endif + free(req); + return ret; + } + free(req); + } + return PTP_RC_OK; +} + + +short +ptp_getthumb(PTPParams* params, PTPObjectHandles* objecthandles, + PTPObjectInfo* objectinfo, int n, + char* object) +{ + short ret; + if ((objecthandles==NULL)||(objectinfo==NULL)||((object==NULL))) + return PTP_ERROR_BADPARAM; + + { + PTPReq* req=malloc(sizeof(PTPReq)); + PTPReq* ptr; + + memset(req, 0, PTP_RESP_LEN); + *(int *)(req->data)=objecthandles->handler[n]; + ret=ptp_sendreq(params, req, PTP_OC_GetThumb); + if (ret!=PTP_RC_OK) { + ptp_error (params, "ptp_getobject sending req"); + free(req); + return PTP_ERROR_IO; + } + { + char* obj_tmp=malloc(objectinfo->ObjectCompressedSize+PTP_REQ_HDR_LEN); + ptr=req; req=(PTPReq*)obj_tmp; + ret=params->read_func((unsigned char *) req, + objectinfo->ObjectCompressedSize+PTP_REQ_HDR_LEN, + params->data); + if ((ret!=PTP_RC_OK) || + (req->type!=PTP_TYPE_DATA) || + (req->code!=PTP_OC_GetThumb)) { + ptp_error (params, "ptp_getobject getting data"); +#ifdef DEBUG + ptp_error (params, "GetObject data returned:\nlen=0x%8.8x" + "type=0x%4.4x code=0x%4.4x ID=0x%8.8x\n", + req->len, req->type, req->code, req->trans_id); +#endif + if (ret!=PTP_RC_OK) ret=PTP_ERROR_IO; else + ret=(req->type==PTP_TYPE_DATA)? + req->code:PTP_ERROR_DATA_EXPECTED; + free(obj_tmp); + req=ptr; + free(req); + return ret; + } + memcpy(object, req->data, objectinfo->ObjectCompressedSize); + free(obj_tmp); + } req=ptr; ret=ptp_getresp(params, req); if ((ret!=PTP_RC_OK) || diff --git a/camlibs/ptp/ptp.h b/camlibs/ptp/ptp.h index aaeec9e8f..2186a99fd 100644 --- a/camlibs/ptp/ptp.h +++ b/camlibs/ptp/ptp.h @@ -190,5 +190,8 @@ short ptp_getobjectinfo (PTPParams *params, PTPObjectHandles* objecthandles, short ptp_getobject (PTPParams *params, PTPObjectHandles* objecthandles, PTPObjectInfo* objectinfoarray, int n, char* object); +short ptp_getthumb (PTPParams *params, PTPObjectHandles* objecthandles, + PTPObjectInfo* objectinfoarray, int n, + char* object); #endif /* __PTP_H__ */