diff options
author | Marcus Meissner <marcus@jet.franken.de> | 2019-06-25 15:00:06 +0200 |
---|---|---|
committer | Marcus Meissner <marcus@jet.franken.de> | 2019-06-25 15:00:06 +0200 |
commit | 42c1e7170bddca6e07e407c08ea030f8bd288f33 (patch) | |
tree | 085823e0699ab1fa1d5a0e1cd3406d13c5aae313 | |
parent | 41dda378cacaea6bea2098b170989ed67c8facbd (diff) | |
download | libgphoto2-42c1e7170bddca6e07e407c08ea030f8bd288f33.tar.gz |
more decoding of images
rewrote the image download function to work via memory and not with
files
-rw-r--r-- | camlibs/lumix/lumix.c | 205 |
1 files changed, 144 insertions, 61 deletions
diff --git a/camlibs/lumix/lumix.c b/camlibs/lumix/lumix.c index b37a499b1..da74d77e2 100644 --- a/camlibs/lumix/lumix.c +++ b/camlibs/lumix/lumix.c @@ -102,8 +102,17 @@ typedef struct { size_t size; } LumixMemoryBuffer; +typedef struct { + char *url_large; + char *url_medium; + char *url_thumb; +} LumixPicture; + struct _CameraPrivateLibrary { /* all private data */ + + int numpics; + LumixPicture *pics; }; @@ -356,7 +365,7 @@ write_callback(char *contents, size_t size, size_t nmemb, void *userp) lmb->data = realloc(lmb->data, lmb->size+realsize); lmb->size += realsize; - gp_log (GP_LOG_DATA, "read from camera", contents, realsize); + GP_LOG_DATA(contents, realsize, "lumix read from url"); memcpy(lmb->data+oldsize,contents,realsize); return realsize; @@ -563,39 +572,40 @@ traverse_tree (int depth, xmlNodePtr node) /* * retrieves the XML doc with the last num pictures avail in the camera. */ -static char* GetPix(Camera *camera,int num) { +static char* +GetPix(Camera *camera,int num) { + long NumPix; + xmlDocPtr docin, docin2; + xmlNodePtr docroot, docroot2, output, next; + xmlChar *xchar; + char* SoapMsg; + CURL *curl; + CURLcode res; + struct curl_slist *list = NULL; + GPPortInfo info; + char *xpath; + LumixMemoryBuffer lmb; + char URL[1000]; + loadCmd(camera,PLAYMODE); - int Start = 0; - long NumPix = NumberPix(camera); + NumPix = NumberPix(camera); //GP_LOG_D("NumPix is %d \n", NumPix); - xmlDocPtr docin; - xmlNodePtr docroot, output, next; - xmlChar *xchar; - if (NumPix < GP_OK) return NULL; - char* SoapMsg = SoapEnvelop((NumPix - num)> 0?(NumPix - num):0, num); + SoapMsg = SoapEnvelop((NumPix - num)> 0?(NumPix - num):0, num); //GP_LOG_D("SoapMsg is %s \n", SoapMsg); - CURL *curl; curl = curl_easy_init(); - CURLcode res; - struct curl_slist *list = NULL; - GPPortInfo info; - char *xpath; - LumixMemoryBuffer lmb; list = curl_slist_append(list, "SOAPaction: urn:schemas-upnp-org:service:ContentDirectory:1#Browse"); list = curl_slist_append(list, "Content-Type: text/xml; charset=\"utf-8\""); list = curl_slist_append(list, "Accept: text/xml"); - char URL[1000]; gp_port_get_info (camera->port, &info); gp_port_info_get_path (info, &xpath); /* xpath now contains tcp:192.168.1.1 */ - snprintf( URL,1000, "http://%s%s",xpath+4, CDS_Control); + snprintf( URL, 1000, "http://%s%s",xpath+4, CDS_Control); curl_easy_setopt(curl, CURLOPT_URL, URL); - - + lmb.size = 0; lmb.data = malloc(0); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); @@ -605,9 +615,10 @@ static char* GetPix(Camera *camera,int num) { curl_easy_setopt(curl, CURLOPT_POST,1); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(SoapMsg)); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, SoapMsg); + GP_LOG_D("camera url is %s", URL); + GP_LOG_D("posting %s", SoapMsg); res = curl_easy_perform(curl); if(res != CURLE_OK) { @@ -616,6 +627,8 @@ static char* GetPix(Camera *camera,int num) { curl_easy_cleanup(curl); return NULL; } + curl_easy_cleanup(curl); + docin = xmlReadMemory (lmb.data, lmb.size, "http://gphoto.org/", "utf-8", 0); if (!docin) return NULL; docroot = xmlDocGetRootElement (docin); @@ -668,7 +681,29 @@ static char* GetPix(Camera *camera,int num) { </DIDL-Lite> */ - curl_easy_cleanup(curl); + docin2 = xmlReadMemory ((char*)xchar, strlen((char*)xchar), "http://gphoto.org/", "utf-8", 0); + if (!docin2) return NULL; + docroot2 = xmlDocGetRootElement (docin2); + if (!docroot) { + xmlFreeDoc (docin2); + return NULL; + } + if (strcmp((char*)docroot2->name,"DIDL-Lite")) { + GP_LOG_E("expected DIDL-Lite, got %s", docroot->name); + xmlFreeDoc (docin2); + return NULL; + } + output = xmlFirstElementChild (docroot2); + if (strcmp((char*)output->name,"item")) { + GP_LOG_E("expected item, got %s", output->name); + xmlFreeDoc (docin2); + return NULL; + } + next = output; + do { + GP_LOG_D("got %s", next->name); + } while ((next = xmlNextElementSibling (next))); + return strdup((char*)xchar); } @@ -787,11 +822,70 @@ case RAW: </s:Envelope> */ -static CameraFilePath * ReadImageFromCamera(Camera *camera) { - char *Images; //the array of the urls in the camera - long nRead; - int SendStatus = -1; - int length = 0; +static int +add_objectid_and_upload (Camera *camera, CameraFilePath *path, GPContext *context, char *ximage, size_t size) { + int ret; + CameraFile *file = NULL; + CameraFileInfo info; + + ret = gp_file_new(&file); + if (ret!=GP_OK) return ret; + gp_file_set_mtime (file, time(NULL)); + strcpy(info.file.type, GP_MIME_JPEG); + + GP_LOG_D ("setting size"); + ret = gp_file_set_data_and_size(file, ximage, size); + if (ret != GP_OK) { + gp_file_free (file); + return ret; + } + GP_LOG_D ("append to fs"); + ret = gp_filesystem_append(camera->fs, path->folder, path->name, context); + if (ret != GP_OK) { + gp_file_free (file); + return ret; + } + GP_LOG_D ("adding filedata to fs"); + ret = gp_filesystem_set_file_noop(camera->fs, path->folder, path->name, GP_FILE_TYPE_NORMAL, file, context); + if (ret != GP_OK) { + gp_file_free (file); + return ret; + } + + /* We have now handed over the file, disclaim responsibility by unref. */ + gp_file_unref (file); + + /* we also get the fs info for free, so just set it */ + info.file.fields = GP_FILE_INFO_TYPE | + /*GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT |*/ + GP_FILE_INFO_SIZE /*| GP_FILE_INFO_MTIME */ ; + strcpy(info.file.type, GP_MIME_JPEG); + + info.preview.fields = 0; /* so far none */ +/* + info.file.width = oi->ImagePixWidth; + info.file.height = oi->ImagePixHeight; + info.file.size = oi->ObjectCompressedSize; + info.file.mtime = time(NULL); + + info.preview.fields = GP_FILE_INFO_TYPE | + GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT | + GP_FILE_INFO_SIZE; + strcpy_mime (info.preview.type, params->deviceinfo.VendorExtensionID, oi->ThumbFormat); + info.preview.width = oi->ThumbPixWidth; + info.preview.height = oi->ThumbPixHeight; + info.preview.size = oi->ThumbCompressedSize; +*/ + + GP_LOG_D ("setting fileinfo in fs"); + return gp_filesystem_set_info_noop(camera->fs, path->folder, path->name, info, context); +} + +static int +ReadImageFromCamera(Camera *camera, CameraFilePath *path, GPContext *context) { + char *image; + long nRead; + LumixMemoryBuffer lmb; loadCmd(camera,PLAYMODE); // 'making sure the camera is in Playmode char* xmlimageName; @@ -801,9 +895,7 @@ static CameraFilePath * ReadImageFromCamera(Camera *camera) { char* imageURL=""; xmlTextReaderPtr reader; - reader = xmlReaderForDoc(GetPix(camera,1), NULL,"noname.xml", - XML_PARSE_DTDATTR | /* default DTD attributes */ - XML_PARSE_NOENT); + reader = xmlReaderForDoc(GetPix(camera,1), NULL,"noname.xml", XML_PARSE_DTDATTR | /* default DTD attributes */ XML_PARSE_NOENT); ret = xmlTextReaderRead(reader); while (ret == 1) { imageURL = processNode(reader); @@ -813,48 +905,40 @@ static CameraFilePath * ReadImageFromCamera(Camera *camera) { } GP_DEBUG("the image URL is %s\n",imageURL); - Images = strdup(imageURL); + image = strdup(imageURL); nRead = 0; CURL* imageUrl; imageUrl = curl_easy_init(); CURLcode res; double bytesread = 0; - FILE* imageFile; char filename[100]; - char* tempPath = "./"; long http_response; int ret_val=0; + + while (ret_val!=2) { - snprintf(filename,100,"%s%s",tempPath,&Images[strlen(Images)- 13]); - imageFile = fopen(filename,"ab"); - GP_DEBUG("reading stream %s position %ld", Images, nRead); + GP_DEBUG("reading stream %s position %ld", image, nRead); - curl_easy_setopt(imageUrl, CURLOPT_URL, Images); + curl_easy_setopt(imageUrl, CURLOPT_URL, image); //curl_easy_setopt(imageUrl,CURLOPT_TCP_KEEPALIVE,1L); //curl_easy_setopt(imageUrl, CURLOPT_TCP_KEEPIDLE, 120L); //curl_easy_setopt(imageUrl, CURLOPT_TCP_KEEPINTVL, 60L); - //curl_easy_setopt(imageUrl, CURLOPT_WRITEFUNCTION, dl_write); if (nRead) { curl_easy_setopt(imageUrl, CURLOPT_RESUME_FROM, nRead); GetPix(camera,1);//'if the file not found happened then this trick is to get the camera in a readmode again and making sure it remembers the filename - GP_DEBUG("continuing the read where it stopped %s position %ld", Images, nRead); + GP_DEBUG("continuing the read where it stopped %s position %ld", image, nRead); } - curl_easy_setopt(imageUrl, CURLOPT_WRITEDATA, imageFile); + lmb.size = 0; + lmb.data = malloc(0); + curl_easy_setopt(imageUrl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(imageUrl, CURLOPT_WRITEDATA, &lmb); res = curl_easy_perform(imageUrl); - if(res != CURLE_OK) { - - //double x; - //curl_easy_getinfo(imageUrl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &x); - //nRead = x; - fseek(imageFile, 0, SEEK_END); // seek to end of file - nRead= ftell(imageFile); // get current file pointer - - fprintf(stderr, "curl_easy_perform() failed: %s\n", - curl_easy_strerror(res)); - GP_DEBUG("error in reading stream %s position %ld", Images, nRead); + if (res != CURLE_OK) { + GP_LOG_E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); + GP_DEBUG("error in reading stream %s position %ld", image, nRead); curl_easy_getinfo(imageUrl, CURLINFO_RESPONSE_CODE, &http_response); GP_DEBUG("CURLINFO_RESPONSE_CODE:%ld\n", http_response); } else { @@ -863,8 +947,9 @@ static CameraFilePath * ReadImageFromCamera(Camera *camera) { } } curl_easy_cleanup(imageUrl); - fclose(imageFile); - return (CameraFilePath *) strdup(filename); + strcpy(path->name, strrchr(image,'/')+1); + strcpy(path->folder, "/"); + return add_objectid_and_upload (camera, path, context, lmb.data, lmb.size); } @@ -881,12 +966,9 @@ int camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path if (strcmp(cameraShutterSpeed, "B")!=0) { waitBulb(camera,captureDuration);//trying captureDuration sec to start before we know how to make a bulb capture of x sec .... } - path = ReadImageFromCamera(camera); - return GP_OK; + return ReadImageFromCamera(camera, path, context); } - - /** * Fill out the summary with textual information about the current * state of the camera (like pictures taken, etc.). @@ -1060,9 +1142,8 @@ int camera_abilities (CameraAbilitiesList *list) { memset(&a, 0, sizeof(a)); strcpy(a.model, "Panasonic:LumixGSeries"); a.status = GP_DRIVER_STATUS_EXPERIMENTAL; - a.port = GP_PORT_TCP; - a.speed[0] = 0; - a.operations = GP_CAPTURE_IMAGE| GP_OPERATION_CAPTURE_VIDEO| GP_OPERATION_CONFIG; + a.port = GP_PORT_TCP; + a.operations = GP_CAPTURE_IMAGE| GP_OPERATION_CAPTURE_VIDEO | GP_OPERATION_CONFIG; a.file_operations = GP_FILE_OPERATION_PREVIEW ; /* it should be possible to browse and DL images the files using the ReadImageFromCamera() function but for now lets keep it simple*/ a.folder_operations = GP_FOLDER_OPERATION_NONE; @@ -1128,12 +1209,14 @@ camera_init (Camera *camera, GPContext *context) gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera); if (loadCmd(camera,RECMODE)!= NULL) { + int numpix; + Set_quality(camera,"raw_fine"); loadCmd(camera,PLAYMODE); // 'making sure the camera is in Playmode - NumberPix(camera); - GetPix(camera,651); + numpix = NumberPix(camera); + GetPix(camera,numpix); return GP_OK; } else |