/** * Retrieves information about a file. * * @param camera a #Camera * @param folder a folder * @param file the name of the file * @param info * @param context a #GPContext * @return a gphoto2 error code * **/ int gp_camera_file_get_info (Camera *camera, const char *folder, const char *file, CameraFileInfo *info, GPContext *context) { int result = GP_OK; const char *mime_type; const char *data; /* long int size; */ CameraFile *cfile; gp_log (GP_LOG_DEBUG, "gphoto2-camera", "Getting file info for '%s' " "in '%s'...", file, folder); CHECK_NULL (camera && folder && file && info); CHECK_INIT (camera, context); memset (info, 0, sizeof (CameraFileInfo)); /* Check first if the camera driver supports the filesystem */ CHECK_OPEN (camera, context); result = gp_filesystem_get_info (camera->fs, folder, file, info, context); CHECK_CLOSE (camera, context); if (result != GP_ERROR_NOT_SUPPORTED) { CAMERA_UNUSED (camera, context); return (result); } /* * The CameraFilesystem doesn't support file info. We simply get * the preview and the file and look for ourselves... */ /* It takes too long to get the file */ info->file.fields = GP_FILE_INFO_NONE; /* Get the preview */ info->preview.fields = GP_FILE_INFO_NONE; CRS (camera, gp_file_new (&cfile), context); if (gp_camera_file_get (camera, folder, file, GP_FILE_TYPE_PREVIEW, cfile, context) == GP_OK) { unsigned long size; info->preview.fields |= GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE; gp_file_get_data_and_size (cfile, &data, &size); info->preview.size = size; gp_file_get_mime_type (cfile, &mime_type); strncpy (info->preview.type, mime_type, sizeof (info->preview.type)); } gp_file_unref (cfile); /* We don't trust the camera libraries */ info->file.fields |= GP_FILE_INFO_NAME; strncpy (info->file.name, file, sizeof (info->file.name)); info->preview.fields &= ~GP_FILE_INFO_NAME; CAMERA_UNUSED (camera, context); return (GP_OK); }
static int put_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *data, GPContext *context) { Camera *camera=data; const char *data_file; long unsigned int data_size; /* * Upload the file to the camera. Use gp_file_get_data_and_size, etc. */ 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; }
void capture_preview(Camera *camera, GPContext *context, const char **ptr, unsigned long int *size) { int retval; CameraFile *file; CameraFilePath camera_file_path; printf("Capturing.\n"); /* NOP: This gets overridden in the library to /capt0000.jpg */ strcpy(camera_file_path.folder, "/"); strcpy(camera_file_path.name, "foo.jpg"); retval = gp_camera_capture_preview(camera, &camera_file_path, context); printf(" Retval: %d\n", retval); printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name); retval = gp_file_new(&file); printf(" Retval: %d\n", retval); retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name, GP_FILE_TYPE_NORMAL, file, context); printf(" Retval: %d\n", retval); gp_file_get_data_and_size (file, ptr, size); printf("Deleting.\n"); retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name, context); printf(" Retval: %d\n", retval); /*gp_file_free(file); */ }
std::vector<char> Camera::read_image(const std::string& folder, const std::string& name, bool delete_from_cam) { std::lock_guard<std::mutex> g(mutex); // TODO: needed? int ret; CameraFile *filep; if ((ret = gp_file_new(&filep)) < GP_OK) throw Exception("gp_file_new", ret); // Will unref the CameraFile as soon as this method returns (for whatever reason) std::unique_ptr<CameraFile, int (*)(CameraFile*)> file(filep, gp_file_unref); if ((ret = gp_camera_file_get(camera, folder.c_str(), name.c_str(), GP_FILE_TYPE_NORMAL, filep, ctx->context)) < GP_OK) throw Exception("gp_camera_file_get", ret); const char* data; unsigned long int size; if ((ret = gp_file_get_data_and_size(filep, &data, &size)) < GP_OK) throw Exception("gp_file_get_data_and_size", ret); std::vector<char> buffer(size); std::copy(data, data + size, buffer.begin()); if (delete_from_cam) { if ((ret = gp_camera_file_delete(camera, folder.c_str(), name.c_str(), ctx->context)) < GP_OK) throw Exception("gp_camera_file_delete", ret); } return buffer; }
static GnomeVFSResult do_seek ( GnomeVFSMethod* method, GnomeVFSMethodHandle* handle, GnomeVFSSeekPosition position, GnomeVFSFileOffset offset, GnomeVFSContext* context) { FileHandle *file_handle = (FileHandle *) handle; const char *data; long int size; G_LOCK (cameras); gp_file_get_data_and_size (file_handle->file, &data, &size); switch (position) { case GNOME_VFS_SEEK_START: file_handle->pos = MIN (size, offset); break; case GNOME_VFS_SEEK_CURRENT: file_handle->pos = MIN (file_handle->pos + offset, size); break; case GNOME_VFS_SEEK_END: file_handle->pos = MAX (size - 1 - offset,0); break; } G_LOCK (cameras); return (GNOME_VFS_OK); }
static void on_view_as_activate (GtkMenuItem *item, ViewAsData *d) { GtkWidget *w, *c, *s; Bonobo_Control control; CORBA_Environment ev; CameraFile *f; int result; Bonobo_PersistStream pstream; BonoboObject *stream; const char *data = NULL; unsigned long int size; const char *type; g_return_if_fail (d->iid != NULL); CORBA_exception_init (&ev); control = bonobo_get_object (d->iid, "IDL:Bonobo/Control:1.0", &ev); if (BONOBO_EX (&ev) || (control == CORBA_OBJECT_NIL)) { CORBA_exception_free (&ev); g_warning ("Could not get control from '%s'.", d->iid); return; } w = bonobo_window_new (d->file, d->file); c = bonobo_widget_new_control_from_objref (control, CORBA_OBJECT_NIL); gtk_widget_show (c); bonobo_window_set_contents (BONOBO_WINDOW (w), c); gtk_widget_show (w); s = gtkam_status_new (_("Downloading '%s' from '%s'..."), d->file, d->folder); g_signal_emit (G_OBJECT (d->list), signals[NEW_STATUS], 0, s); gp_file_new (&f); result = gp_camera_file_get (d->camera->camera, d->folder, d->file, GP_FILE_TYPE_NORMAL, f, GTKAM_STATUS (s)->context->context); if (d->camera->multi) gp_camera_exit (d->camera->camera, NULL); if (result >= 0) { CORBA_exception_init (&ev); pstream = Bonobo_Unknown_queryInterface (control, "IDL:Bonobo/PersistStream:1.0", &ev); if (!BONOBO_EX (&ev) && (pstream != CORBA_OBJECT_NIL)) { gp_file_get_data_and_size (f, &data, &size); gp_file_get_mime_type (f, &type); stream = bonobo_stream_mem_create (data, size, TRUE, FALSE); Bonobo_PersistStream_load (pstream, bonobo_object_corba_objref (stream), type, &ev); g_object_unref (G_OBJECT (stream)); bonobo_object_release_unref (pstream, NULL); } CORBA_exception_free (&ev); } gp_file_unref (f); gtk_object_destroy (GTK_OBJECT (s)); }
static int camera_capture (Camera* camera, CameraCaptureType type, CameraFilePath* path, GPContext *context) { int r; CameraFile *file = NULL; CameraFileInfo info; KncCamRes cr; KncCntrlRes cntrl_res; KncImageInfo i; C_NULL (camera && path); /* We only support capturing of images */ if (type != GP_CAPTURE_IMAGE) return (GP_ERROR_NOT_SUPPORTED); /* Stop the timeout, take the picture, and restart the timeout. */ gp_camera_stop_timeout (camera, camera->pl->timeout); gp_file_new (&file); knc_cntrl_set_func_data (camera->pl->c, data_func, file); cntrl_res = knc_take_picture (camera->pl->c, &cr, KNC_SOURCE_CARD, &i); camera->pl->timeout = gp_camera_start_timeout (camera, PING_TIMEOUT, timeout_func); if (cntrl_res) gp_file_unref (file); CR (cntrl_res, context); sprintf (path->name, "%06i.jpeg", (int) i.id); strcpy (path->folder, "/"); r = gp_filesystem_append (camera->fs, path->folder, path->name, context); if (r < 0) { gp_file_unref (file); return r; } info.preview.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE; gp_file_get_data_and_size (file, NULL, &info.preview.size); strcpy (info.preview.type, GP_MIME_JPEG); info.file.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_PERMISSIONS | GP_FILE_INFO_TYPE | GP_FILE_INFO_NAME; info.file.size = i.size; info.file.permissions = GP_FILE_PERM_READ; if (!i.prot) info.file.permissions |= GP_FILE_PERM_DELETE; strcpy (info.file.type, GP_MIME_JPEG); snprintf (info.file.name, sizeof (info.file.name), "%06i.jpeg", (int) i.id); gp_filesystem_set_info_noop (camera->fs, path->folder, info, context); gp_file_set_name (file, info.file.name); gp_file_set_mime_type (file, GP_MIME_JPEG); gp_file_set_type (file, GP_FILE_TYPE_EXIF); gp_filesystem_set_file_noop (camera->fs, path->folder, file, context); gp_file_unref (file); return (GP_OK); }
void data_serv_working_loop(t_serv_comm *s) { CameraFile *file; const char *data; char *header; unsigned long size; int len = 0; struct timeval time_beggining; struct timeval time_final; FD_ZERO(&(s->rd_fds)); FD_SET(s->sock_serv, &(s->rd_fds)); if (s->sock_serv > s->bigger_fd) s->bigger_fd = s->sock_serv; if (select((s->bigger_fd + 1), &(s->rd_fds), NULL, NULL, NULL) == -1) fprintf(stderr, "Select Error"); if (FD_ISSET(s->sock_serv, &(s->rd_fds))) serv_accept_new_connections_data(s); gp_file_new(&file); while (1) { gettimeofday(&time_beggining, NULL); if (!s->c->liveview) { if (len != 0) gp_camera_exit(s->c->camera, s->c->context); pthread_mutex_lock(&s->c->liveview_mutex); pthread_cond_wait(&s->c->liveview_condvar, &s->c->liveview_mutex); pthread_mutex_unlock(&s->c->liveview_mutex); } gp_camera_capture_preview(s->c->camera, file, s->c->context); gp_file_get_data_and_size(file, &data, &size); len = asprintf(&header, "||>>%li>>||", size); gettimeofday(&time_final, NULL); check_time(s->c, &time_beggining, &time_final); if (write(s->first_client->sock, header, len) < 0) { s->c->liveview = 0; gp_camera_exit(s->c->camera, s->c->context); client_diconnected(s, s->first_client->sock); return; } if (write(s->first_client->sock, data, size) < 0) { s->c->liveview = 0; gp_camera_exit(s->c->camera, s->c->context); client_diconnected(s, s->first_client->sock); return; } free(header); } }
static int put_file_func (CameraFilesystem *fs, const char *folder, const char *name, CameraFileType type, CameraFile *file, void *user_data, GPContext *context) { const char *data; unsigned long int size; Camera *camera = user_data; if (type != GP_FILE_TYPE_NORMAL) return GP_ERROR_BAD_PARAMETERS; CR (gp_file_get_data_and_size (file, &data, &size)); return ricoh_put_file (camera, context, name, data, size); }
void GPhotoCameraWorker::capturePhoto(int id, const QString &fileName) { // Focusing if (parameter("viewfinder").isValid()) { if (!setParameter("viewfinder", false)) qWarning() << "Failed to flap down camera mirror"; } else { if (parameter("autofocusedrive").isValid()) setParameter("autofocusedrive", true); } // Capture the frame from camera CameraFilePath filePath; int ret = gp_camera_capture(m_camera, GP_CAPTURE_IMAGE, &filePath, m_context); if (ret < GP_OK) { qWarning() << "Failed to capture frame:" << ret; emit imageCaptureError(id, QCameraImageCapture::ResourceError, "Failed to capture frame"); } else { qDebug() << "Captured frame:" << filePath.folder << filePath.name; // Download the file CameraFile* file; ret = gp_file_new(&file); ret = gp_camera_file_get(m_camera, filePath.folder, filePath.name, GP_FILE_TYPE_NORMAL, file, m_context); if (ret < GP_OK) { qWarning() << "Failed to get file from camera:" << ret; emit imageCaptureError(id, QCameraImageCapture::ResourceError, "Failed to download file from camera"); } else { const char* data; unsigned long int size = 0; ret = gp_file_get_data_and_size(file, &data, &size); if (ret < GP_OK) { qWarning() << "Failed to get file data and size from camera:" << ret; emit imageCaptureError(id, QCameraImageCapture::ResourceError, "Failed to download file from camera"); } else { emit imageCaptured(id, QByteArray(data, int(size)), fileName); } } gp_file_free(file); waitForOperationCompleted(); } if (parameter("viewfinder").isValid()) { if (!setParameter("viewfinder", true)) qWarning() << "Failed to flap up camera mirror"; } }
static int put_file_func (CameraFilesystem *fs, const char *folder, const char *name, CameraFileType type, CameraFile *file, void *data, GPContext *context) { Camera *camera = data; const char *d; unsigned long int d_len; if (type != GP_FILE_TYPE_NORMAL) return GP_ERROR_BAD_PARAMETERS; CR (gp_file_get_data_and_size (file, &d, &d_len)); CR (fuji_upload_init (camera, name, context)); return fuji_upload (camera, (unsigned char *)d, d_len, context); }
void* capture(void* arg) { int res; int i = 0; CameraFile* file; pthread_cleanup_push(cleanup, NULL); while(!global->stop) { unsigned long int xsize; const char* xdata; pthread_mutex_lock(&control_mutex); res = gp_file_new(&file); CAMERA_CHECK_GP(res, "gp_file_new"); res = gp_camera_capture_preview(camera, file, context); CAMERA_CHECK_GP(res, "gp_camera_capture_preview"); pthread_mutex_lock(&global->in[plugin_id].db); res = gp_file_get_data_and_size(file, &xdata, &xsize); if(xsize == 0) { if(i++ > 3) { IPRINT("Restarted too many times; giving up\n"); return NULL; } int value = 0; IPRINT("Read 0 bytes from camera; restarting it\n"); camera_set("capture", &value); sleep(3); value = 1; camera_set("capture", &value); } else i = 0; CAMERA_CHECK_GP(res, "gp_file_get_data_and_size"); memcpy(global->in[plugin_id].buf, xdata, xsize); res = gp_file_unref(file); pthread_mutex_unlock(&control_mutex); CAMERA_CHECK_GP(res, "gp_file_unref"); global->in[plugin_id].size = xsize; DBG("Read %d bytes from camera.\n", global->in[plugin_id].size); pthread_cond_broadcast(&global->in[plugin_id].db_update); pthread_mutex_unlock(&global->in[plugin_id].db); usleep(delay); } pthread_cleanup_pop(1); return NULL; }
/** * Image file reader. * * @FUTURE: RAW format reader. */ void DigitalCameraCapture::readFrameFromFile(CameraFile * file, OutputArray outputFrame) { // FUTURE: OpenCV cannot read RAW files right now. const char * data; unsigned long int size; CR(gp_file_get_data_and_size(file, &data, &size)); if (size > 0) { Mat buf = Mat(1, size, CV_8UC1, (void *) data); if(!buf.empty()) { frame = imdecode(buf, CV_LOAD_IMAGE_UNCHANGED); } frame.copyTo(outputFrame); } }
bool GPCamera::getThumbnail(const QString& folder, const QString& itemName, QImage& thumbnail) { #ifdef HAVE_GPHOTO2 int errorCode; CameraFile* cfile = 0; const char* data = 0; unsigned long int size; gp_file_new(&cfile); d->status->cancel = false; errorCode = gp_camera_file_get(d->camera, QFile::encodeName(folder).constData(), QFile::encodeName(itemName).constData(), GP_FILE_TYPE_PREVIEW, cfile, d->status->context); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get camera item!" << folder << itemName; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } errorCode = gp_file_get_data_and_size(cfile, &data, &size); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get thumbnail from camera item!" << folder << itemName; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } thumbnail.loadFromData((const uchar*) data, (uint) size); gp_file_unref(cfile); return !thumbnail.isNull(); #else Q_UNUSED(folder); Q_UNUSED(itemName); Q_UNUSED(thumbnail); return false; #endif /* HAVE_GPHOTO2 */ }
std::vector<char> Camera::preview() { std::lock_guard<std::mutex> g(mutex); auto file = GP_NEW_UNIQUE(CameraFile, gp_file); int ret; if ((ret = gp_camera_capture_preview(camera, file.get(), ctx->context)) < GP_OK) throw Exception("gp_camera_capture_preview", ret); const char *rawbuf; size_t nbytes; if ((ret = gp_file_get_data_and_size(file.get(), &rawbuf, &nbytes)) < GP_OK) throw Exception("gp_file_get_data_and_size", ret); std::vector<char> buf(nbytes); std::copy(rawbuf, rawbuf + nbytes, &buf[0]); return buf; }
bool GPCamera::getPreview(QImage& preview) { #ifdef HAVE_GPHOTO2 int errorCode; CameraFile* cfile = 0; const char* data = 0; unsigned long int size; d->status->cancel = false; gp_file_new(&cfile); errorCode = gp_camera_capture_preview(d->camera, cfile, d->status->context); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to initialize camera preview mode!"; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } errorCode = gp_file_get_data_and_size(cfile, &data, &size); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get preview from camera!"; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } preview.loadFromData((const uchar*) data, (uint) size); gp_file_unref(cfile); return true; #else Q_UNUSED(preview); return false; #endif /* HAVE_GPHOTO2 */ }
void GPhotoCameraWorker::capturePreview() { openCamera(); if (m_status != QCamera::ActiveStatus) { setStatus(QCamera::StartingStatus); } gp_file_clean(m_file); int ret = gp_camera_capture_preview(m_camera, m_file, m_context); if (GP_OK == ret) { const char* data; unsigned long int size = 0; ret = gp_file_get_data_and_size(m_file, &data, &size); if (GP_OK == ret) { m_capturingFailCount = 0; const QImage &result = QImage::fromData(QByteArray(data, int(size))); setStatus(QCamera::ActiveStatus); emit previewCaptured(result); return; } } qWarning() << "Failed retrieving preview" << ret; ++m_capturingFailCount; if (m_capturingFailCount >= capturingFailLimit) { qWarning() << "Closing camera because of capturing fail"; emit error(QCamera::CameraError, tr("Unable to capture frame")); setStatus(QCamera::UnloadedStatus); closeCamera(); } }
static void _camera_process_job(const dt_camctl_t *c,const dt_camera_t *camera, gpointer job) { dt_camera_t *cam=(dt_camera_t *)camera; _camctl_camera_job_t *j = (_camctl_camera_job_t *)job; switch( j->type ) { case _JOB_TYPE_EXECUTE_CAPTURE: { dt_print (DT_DEBUG_CAMCTL,"[camera_control] executing remote camera capture job\n"); CameraFilePath fp; int res=GP_OK; if( (res = gp_camera_capture (camera->gpcam, GP_CAPTURE_IMAGE,&fp, c->gpcontext)) == GP_OK ) { CameraFile *destination; const char *output_path = _dispatch_request_image_path(c,camera); if( !output_path ) output_path="/tmp"; const char *fname = _dispatch_request_image_filename(c,fp.name,cam); if( !fname ) fname=fp.name; char *output = g_build_filename (output_path,fname,(char *)NULL); int handle = open (output, O_CREAT | O_WRONLY,0666); gp_file_new_from_fd (&destination , handle); gp_camera_file_get (camera->gpcam, fp.folder , fp.name, GP_FILE_TYPE_NORMAL, destination, c->gpcontext); close (handle); // Notify listerners of captured image _dispatch_camera_image_downloaded (c,camera,output); g_free (output); } else dt_print (DT_DEBUG_CAMCTL,"[camera_control] capture job failed to capture image: %s\n",gp_result_as_string(res)); } break; case _JOB_TYPE_EXECUTE_LIVE_VIEW: { CameraFile *fp = NULL; int res = GP_OK; const gchar* data = NULL; unsigned long int data_size = 0; gp_file_new(&fp); if( (res = gp_camera_capture_preview (cam->gpcam, fp, c->gpcontext)) != GP_OK ) { dt_print (DT_DEBUG_CAMCTL,"[camera_control] live view failed to capture preview: %s\n", gp_result_as_string(res)); } else if( (res = gp_file_get_data_and_size(fp, &data, &data_size)) != GP_OK ) { dt_print (DT_DEBUG_CAMCTL,"[camera_control] live view failed to get preview data: %s\n", gp_result_as_string(res)); } else { // everything worked GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); if(gdk_pixbuf_loader_write(loader, (guchar*)data, data_size, NULL) == TRUE) { dt_pthread_mutex_lock(&cam->live_view_pixbuf_mutex); if(cam->live_view_pixbuf != NULL) g_object_unref(cam->live_view_pixbuf); cam->live_view_pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); dt_pthread_mutex_unlock(&cam->live_view_pixbuf_mutex); } gdk_pixbuf_loader_close(loader, NULL); } if(fp) gp_file_free(fp); dt_pthread_mutex_unlock(&cam->live_view_synch); dt_control_queue_redraw_center(); } break; case _JOB_TYPE_SET_PROPERTY: { _camctl_camera_set_property_job_t *spj=(_camctl_camera_set_property_job_t *)job; dt_print(DT_DEBUG_CAMCTL,"[camera_control] executing set camera config job %s=%s\n",spj->name,spj->value); CameraWidget *config; // Copy of camera configuration CameraWidget *widget; gp_camera_get_config( cam->gpcam, &config, c->gpcontext ); if( gp_widget_get_child_by_name ( config, spj->name, &widget) == GP_OK) { gp_widget_set_value ( widget , spj->value); gp_camera_set_config( cam->gpcam, config, c->gpcontext ); } /* dt_pthread_mutex_lock( &cam->config_lock ); CameraWidget *widget; if( gp_widget_get_child_by_name ( camera->configuration, spj->name, &widget) == GP_OK) { gp_widget_set_value ( widget , spj->value); //gp_widget_set_changed( widget, 1 ); cam->config_changed=TRUE; } dt_pthread_mutex_unlock( &cam->config_lock);*/ } break; default: dt_print(DT_DEBUG_CAMCTL,"[camera_control] process of unknown job type %lx\n",(unsigned long int)j->type); break; } g_free(j); }
static int _camera_storage_image_filename(const dt_camera_t *camera, const char *filename, CameraFile *preview, CameraFile *exif, void *user_data) { _camera_import_dialog_t *data = (_camera_import_dialog_t *)user_data; const char *img; unsigned long size; GdkPixbuf *pixbuf = NULL; GdkPixbuf *thumb = NULL; /* stop fetching previews if job is cancelled */ if(data->preview_job && dt_control_job_get_state(data->preview_job) == DT_JOB_STATE_CANCELLED) return 0; char exif_info[1024] = { 0 }; if(preview) { gp_file_get_data_and_size(preview, &img, &size); if(size > 0) { // we got preview image data lets create a pixbuf from image blob GError *err = NULL; GInputStream *stream; if((stream = g_memory_input_stream_new_from_data(img, size, NULL)) != NULL) pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, &err); } if(pixbuf) { // Scale pixbuf to a thumbnail double sw = gdk_pixbuf_get_width(pixbuf); double scale = 75.0 / gdk_pixbuf_get_height(pixbuf); thumb = gdk_pixbuf_scale_simple(pixbuf, sw * scale, 75, GDK_INTERP_BILINEAR); } } #if 0 // libgphoto only supports fetching exif in jpegs, not raw char buffer[1024]= {0}; if ( exif ) { const char *exif_data; char *value=NULL; gp_file_get_data_and_size(exif, &exif_data, &size); if( size > 0 ) { void *exif=dt_exif_data_new((uint8_t *)exif_data,size); if( (value=g_strdup( dt_exif_data_get_value(exif,"Exif.Photo.ExposureTime",buffer,1024) ) ) != NULL); snprintf(exif_info, sizeof(exif_info), "exposure: %s\n", value); } else fprintf(stderr,"No exifdata read\n"); } #endif _image_filename_t *params = (_image_filename_t *)malloc(sizeof(_image_filename_t)); if(!params) { if(pixbuf) g_object_unref(pixbuf); if(thumb) g_object_unref(thumb); return 0; } // filename\n 1/60 f/2.8 24mm iso 160 params->file_info = g_strdup_printf("%s%c%s", filename, *exif_info ? '\n' : '\0', *exif_info ? exif_info : ""); params->thumb = thumb; params->store = data->store; g_main_context_invoke(NULL, _camera_storage_image_filename_gui_thread, params); if(pixbuf) g_object_unref(pixbuf); return 1; }
bool GPCamera::getMetadata(const QString& folder, const QString& itemName, DMetadata& meta) { #ifdef HAVE_GPHOTO2 int errorCode; CameraFile* cfile = 0; const char* data = 0; unsigned long int size; gp_file_new(&cfile); d->status->cancel = false; errorCode = gp_camera_file_get(d->camera, QFile::encodeName(folder).constData(), QFile::encodeName(itemName).constData(), GP_FILE_TYPE_EXIF, cfile, d->status->context); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get camera item!"; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } errorCode = gp_file_get_data_and_size(cfile, &data, &size); if (errorCode != GP_OK) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Failed to get Exif data from camera item!"; printGphotoErrorDescription(errorCode); gp_file_unref(cfile); return false; } QByteArray exifData(data, size); gp_file_unref(cfile); // Sometimes, GPhoto2 drivers return complete APP1 JFIF section. Exiv2 cannot // decode (yet) exif metadata from APP1. We will find Exif header to get data at this place // to please with Exiv2... qCDebug(DIGIKAM_IMPORTUI_LOG) << "Size of Exif metadata from camera = " << exifData.size(); if (!exifData.isEmpty()) { char exifHeader[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 }; int i = exifData.indexOf(*exifHeader); if (i != -1) { qCDebug(DIGIKAM_IMPORTUI_LOG) << "Exif header found at position " << i; i = i + sizeof(exifHeader); QByteArray data; data.resize(exifData.size() - i); memcpy(data.data(), exifData.data() + i, data.size()); meta.setExif(data); return true; } } return false; #else Q_UNUSED(folder); Q_UNUSED(itemName); Q_UNUSED(meta); return false; #endif /* HAVE_GPHOTO2 */ }
/* * Upload an image to the camera */ static int put_file_func (CameraFilesystem *fs, const char *folder, const char *name, CameraFileType type, CameraFile *file, void *data, GPContext *context) { Camera *camera = data; unsigned char cmd[2], buf[DATA_BUFFER],ack,sum,state; const char *d; unsigned long int len, len_sent=0; unsigned int id; int ret,i; GP_DEBUG ("*** ENTER: put_file_func ***"); /* Send function */ cmd[0] = ESC; cmd[1] = UPLOADDATA; ret = gp_port_write (camera->port, (char*)cmd, sizeof(cmd)); if (ret<GP_OK) return ret; gp_file_get_data_and_size(file, &d, &len); id = gp_context_progress_start (context, len, _("Uploading image...")); for (i=0; i < ((len+DATA_BUFFER-1) / DATA_BUFFER); i++) { ret = gp_port_read (camera->port, (char*)&ack, ACK_LEN); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } if (ack != ACK) { gp_context_progress_stop (context, id); gp_context_error(context, _("Can't upload this image to the camera. " "An error has occurred.")); return (GP_ERROR); } state = NEXTFRAME; ret = gp_port_write (camera->port, (char*)&state, STATE_LEN); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } if ((len - len_sent) <= DATA_BUFFER) { /* Send the last datas */ ret = gp_port_write (camera->port, (char*)&d[i*DATA_BUFFER], (len - len_sent)); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } /* and complete with zeros */ memset(buf,0,DATA_BUFFER); ret = gp_port_write (camera->port, (char*)buf, (DATA_BUFFER - (len - len_sent))); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } /* Calculate the checksum */ sum = k_calculate_checksum( (unsigned char *)&d[i*DATA_BUFFER], (len-len_sent)); len_sent += (len - len_sent); } else { /* Just send the datas */ ret = gp_port_write (camera->port, &d[i*DATA_BUFFER], DATA_BUFFER); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } len_sent += DATA_BUFFER; sum = k_calculate_checksum( (unsigned char *)&d[i*DATA_BUFFER], DATA_BUFFER); } ret = gp_port_write (camera->port, (char*)&sum, CSUM_LEN); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } gp_context_progress_update (context, id, len_sent); } state = EOT; ret = gp_port_write (camera->port, (char*)&state, STATE_LEN); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } ret = gp_port_read (camera->port, (char*)&ack, ACK_LEN); if (ret<GP_OK) { gp_context_progress_stop (context, id); return ret; } if (ack != ACK) { gp_context_progress_stop (context, id); gp_context_error(context, _("Can't upload this image to the " "camera. An error has occurred.")); return (GP_ERROR); } gp_context_progress_stop (context, id); return (GP_OK); }
static gboolean get_thumbnail_idle (gpointer data) { GtkamList *list = GTKAM_LIST (data); GetThumbnailData *d; CameraFile *file; GtkWidget *s; GdkPixbuf *pixbuf; GdkPixbufLoader *loader; int result; const char *fd; unsigned long fs; gfloat factor; d = list->priv->head; if (d == NULL) return (FALSE); s = gtkam_status_new (_("Downloading thumbnail of '%s' from " "folder '%s'..."), d->name, d->folder); g_signal_emit (G_OBJECT (list), signals[NEW_STATUS], 0, s); gp_file_new (&file); result = gp_camera_file_get (d->camera->camera, d->folder, d->name, GP_FILE_TYPE_PREVIEW, file, GTKAM_STATUS (s)->context->context); if (d->camera->multi) gp_camera_exit (d->camera->camera, NULL); if (result >= 0) { gp_file_get_data_and_size (file, &fd, &fs); loader = gdk_pixbuf_loader_new (); gdk_pixbuf_loader_write (loader, fd, fs, NULL); gdk_pixbuf_loader_close (loader, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); gtk_list_store_set (list->priv->store, d->iter, PREVIEW_ORIG_COLUMN, pixbuf, -1); factor = gtkam_list_get_zoom_factor (list); pixbuf = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * factor, gdk_pixbuf_get_height (pixbuf) * factor, GDK_INTERP_BILINEAR); g_object_unref (G_OBJECT (loader)); gtk_list_store_set (list->priv->store, d->iter, PREVIEW_COLUMN, pixbuf, -1); g_object_unref (G_OBJECT (pixbuf)); } gp_file_unref (file); gtk_object_destroy (GTK_OBJECT (s)); if (result == GP_ERROR_CAMERA_BUSY) return (TRUE); g_object_unref (G_OBJECT (d->camera)); g_free (d->name); g_free (d->folder); gtk_tree_iter_free (d->iter); list->priv->head = d->next; g_free (d); if (!list->priv->head) list->priv->tail = NULL; gtk_widget_destroy (s); if (list->priv->head == NULL) return (FALSE); else return (TRUE); }
static int put_file_func (CameraFilesystem *fs, const char *folder, const char *name, CameraFileType type, CameraFile *file, void *data, GPContext *context) { #ifdef HAVE_GD Camera *camera = data; char *c, *in_name, *out_name, *filedata = NULL; int ret, in_width, in_height, in_x, in_y; size_t inc, outc; double aspect_in, aspect_out; #ifdef HAVE_ICONV char *in, *out; #endif unsigned long filesize = 0; gdImagePtr rotated, im_out, im_in = NULL; if (strcmp (folder, "/")) return GP_ERROR_DIRECTORY_NOT_FOUND; inc = strlen (name); in_name = strdup (name); outc = inc; out_name = malloc (outc + 1); if (!in_name || !out_name) { free (in_name); free (out_name); return GP_ERROR_NO_MEMORY; } /* Convert name to ASCII */ #ifdef HAVE_ICONV in = in_name; out = out_name; if (iconv (camera->pl->cd, &in, &inc, &out, &outc) == -1) { free (in_name); free (out_name); gp_log (GP_LOG_ERROR, "iconv", "Failed to convert filename to ASCII"); return GP_ERROR_OS_FAILURE; } outc = out - out_name; out_name[outc] = 0; #else for (i = 0; i < inc; i++) { if ((uint8_t)in_name[i] < 0x20 || (uint8_t)in_name[i] > 0x7E) out_name[i] = '?'; else out_name[i] = in_name[i]; } out_name[i] = 0; #endif free (in_name); /* Remove file extension, and if necessary truncate the name */ c = strrchr (out_name, '.'); if (c) *c = 0; if (outc > ST2205_FILENAME_LENGTH) out_name[ST2205_FILENAME_LENGTH] = 0; ret = gp_file_get_data_and_size (file, (const char **)&filedata, &filesize); if (ret < 0) { free (out_name); return ret; } /* Try loading the file using gd, starting with the most often used types first */ /* gdImageCreateFromJpegPtr is chatty on error, don't call it on non JPEG files */ if (filesize > 2 && (uint8_t)filedata[0] == 0xff && (uint8_t)filedata[1] == 0xd8) im_in = gdImageCreateFromJpegPtr(filesize, filedata); if (im_in == NULL) im_in = gdImageCreateFromPngPtr(filesize, filedata); if (im_in == NULL) im_in = gdImageCreateFromGifPtr(filesize, filedata); if (im_in == NULL) im_in = gdImageCreateFromWBMPPtr(filesize, filedata); if (im_in == NULL) { gp_log (GP_LOG_ERROR, "st2205", "Unrecognized file format for file: %s%s", folder, name); free (out_name); return GP_ERROR_BAD_PARAMETERS; } if (needs_rotation (camera)) { rotated = gdImageCreateTrueColor (im_in->sy, im_in->sx); if (rotated == NULL) { gdImageDestroy (im_in); free (out_name); return GP_ERROR_NO_MEMORY; } rotate90 (im_in, rotated); gdImageDestroy (im_in); im_in = rotated; } im_out = gdImageCreateTrueColor(camera->pl->width, camera->pl->height); if (im_out == NULL) { gdImageDestroy (im_in); free (out_name); return GP_ERROR_NO_MEMORY; } /* Keep aspect */ aspect_in = (double)im_in->sx / im_in->sy; aspect_out = (double)im_out->sx / im_out->sy; if (aspect_in > aspect_out) { /* Reduce in width (crop left and right) */ in_width = (im_in->sx / aspect_in) * aspect_out; in_x = (im_in->sx - in_width) / 2; in_height = im_in->sy; in_y = 0; } else { /* Reduce in height (crop top and bottom) */ in_width = im_in->sx; in_x = 0; in_height = (im_in->sy * aspect_in) / aspect_out; in_y = (im_in->sy - in_height) / 2; } gdImageCopyResampled (im_out, im_in, 0, 0, in_x, in_y, im_out->sx, im_out->sy, in_width, in_height); if (im_in->sx != im_out->sx || im_in->sy != im_out->sy) gdImageSharpen(im_out, 100); ret = st2205_write_file (camera, out_name, im_out->tpixels); if (ret >= 0) { /* Add to our filenames list */ ST2205_SET_FILENAME(camera->pl->filenames[ret], out_name, ret); /* And commit the changes to the device */ ret = st2205_commit(camera); } gdImageDestroy (im_in); gdImageDestroy (im_out); free (out_name); return ret; #else gp_log(GP_LOG_ERROR,"st2205", "GD compression not supported - no libGD present during build"); return GP_ERROR_NOT_SUPPORTED; #endif }
TW_UINT16 _get_gphoto2_file_as_DIB( const char *folder, const char *filename, CameraFileType type, HWND hwnd, HBITMAP *hDIB ) { const unsigned char *filedata; unsigned long filesize; int ret; CameraFile *file; struct jpeg_source_mgr xjsm; struct jpeg_decompress_struct jd; struct jpeg_error_mgr jerr; HDC dc; BITMAPINFO bmpInfo; LPBYTE bits; JSAMPROW samprow, oldsamprow; if(!libjpeg_handle) { if(!load_libjpeg()) { FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); filedata = NULL; return TWRC_FAILURE; } } gp_file_new (&file); ret = gp_camera_file_get(activeDS.camera, folder, filename, type, file, activeDS.context); if (ret < GP_OK) { FIXME("Failed to get file?\n"); gp_file_unref (file); return TWRC_FAILURE; } ret = gp_file_get_data_and_size (file, (const char**)&filedata, &filesize); if (ret < GP_OK) { FIXME("Failed to get file data?\n"); return TWRC_FAILURE; } /* FIXME: Actually we might get other types than JPEG ... But only handle JPEG for now */ if (filedata[0] != 0xff) { ERR("File %s/%s might not be JPEG, cannot decode!\n", folder, filename); } /* This is basically so we can use in-memory data for jpeg decompression. * We need to have all the functions. */ xjsm.next_input_byte = filedata; xjsm.bytes_in_buffer = filesize; xjsm.init_source = _jpeg_init_source; xjsm.fill_input_buffer = _jpeg_fill_input_buffer; xjsm.skip_input_data = _jpeg_skip_input_data; xjsm.resync_to_restart = _jpeg_resync_to_restart; xjsm.term_source = _jpeg_term_source; jd.err = pjpeg_std_error(&jerr); /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h * jpeg_create_decompress(&jd); */ pjpeg_CreateDecompress(&jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct)); jd.src = &xjsm; ret=pjpeg_read_header(&jd,TRUE); jd.out_color_space = JCS_RGB; pjpeg_start_decompress(&jd); if (ret != JPEG_HEADER_OK) { ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret); gp_file_unref (file); return TWRC_FAILURE; } ZeroMemory (&bmpInfo, sizeof (BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof (BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = jd.output_width; bmpInfo.bmiHeader.biHeight = -jd.output_height; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = jd.output_components*8; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biSizeImage = 0; bmpInfo.bmiHeader.biXPelsPerMeter = 0; bmpInfo.bmiHeader.biYPelsPerMeter = 0; bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; *hDIB = CreateDIBSection ((dc = GetDC(hwnd)), &bmpInfo, DIB_RGB_COLORS, (LPVOID)&bits, 0, 0); if (!*hDIB) { FIXME("Failed creating DIB.\n"); gp_file_unref (file); return TWRC_FAILURE; } samprow = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components); oldsamprow = samprow; while ( jd.output_scanline<jd.output_height ) { int i, x = pjpeg_read_scanlines(&jd,&samprow,1); if (x != 1) { FIXME("failed to read current scanline?\n"); break; } /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */ for(i=0;i<jd.output_width;i++,samprow+=jd.output_components) { *(bits++) = *(samprow+2); *(bits++) = *(samprow+1); *(bits++) = *(samprow); } bits = (LPBYTE)(((UINT_PTR)bits + 3) & ~3); samprow = oldsamprow; } if (hwnd) ReleaseDC (hwnd, dc); HeapFree (GetProcessHeap(), 0, samprow); gp_file_unref (file); return TWRC_SUCCESS; }
static TW_UINT16 _get_image_and_startup_jpeg(void) { const char *folder = NULL, *filename = NULL; struct gphoto2_file *file; const unsigned char *filedata; unsigned long filesize; int ret; if (activeDS.file) /* Already loaded. */ return TWRC_SUCCESS; if(!libjpeg_handle) { if(!load_libjpeg()) { FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); filedata = NULL; return TWRC_FAILURE; } } LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) { if (strstr(file->filename,".JPG") || strstr(file->filename,".jpg")) { filename = file->filename; folder = file->folder; TRACE("downloading %s/%s\n", folder, filename); if (file->download) { file->download = FALSE; /* mark as done */ break; } } } gp_file_new (&activeDS.file); ret = gp_camera_file_get(activeDS.camera, folder, filename, GP_FILE_TYPE_NORMAL, activeDS.file, activeDS.context); if (ret < GP_OK) { FIXME("Failed to get file?\n"); activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } ret = gp_file_get_data_and_size (activeDS.file, (const char**)&filedata, &filesize); if (ret < GP_OK) { FIXME("Failed to get file data?\n"); activeDS.twCC = TWCC_SEQERROR; return TWRC_FAILURE; } /* This is basically so we can use in-memory data for jpeg decompression. * We need to have all the functions. */ activeDS.xjsm.next_input_byte = filedata; activeDS.xjsm.bytes_in_buffer = filesize; activeDS.xjsm.init_source = _jpeg_init_source; activeDS.xjsm.fill_input_buffer = _jpeg_fill_input_buffer; activeDS.xjsm.skip_input_data = _jpeg_skip_input_data; activeDS.xjsm.resync_to_restart = _jpeg_resync_to_restart; activeDS.xjsm.term_source = _jpeg_term_source; activeDS.jd.err = pjpeg_std_error(&activeDS.jerr); /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h * jpeg_create_decompress(&jd); */ pjpeg_CreateDecompress(&activeDS.jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct)); activeDS.jd.src = &activeDS.xjsm; ret=pjpeg_read_header(&activeDS.jd,TRUE); activeDS.jd.out_color_space = JCS_RGB; pjpeg_start_decompress(&activeDS.jd); if (ret != JPEG_HEADER_OK) { ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret); gp_file_unref (activeDS.file); activeDS.file = NULL; return TWRC_FAILURE; } return TWRC_SUCCESS; }
int _camera_storage_image_filename(const dt_camera_t *camera,const char *filename,CameraFile *preview,CameraFile *exif,void *user_data) { _camera_import_dialog_t *data=(_camera_import_dialog_t*)user_data; GtkTreeIter iter; const char *img; unsigned long size; GdkPixbuf *pixbuf=NULL; GdkPixbuf *thumb=NULL; /* stop fetching previews if job is cancelled */ if (data->preview_job && dt_control_job_get_state(data->preview_job) == DT_JOB_STATE_CANCELLED ) return 0; gboolean i_own_lock = dt_control_gdk_lock(); char exif_info[1024]= {0}; char file_info[4096]= {0}; if( preview ) { gp_file_get_data_and_size(preview, &img, &size); if( size > 0 ) { // we got preview image data lets create a pixbuf from image blob GError *err=NULL; GInputStream *stream; if( (stream = g_memory_input_stream_new_from_data(img, size,NULL)) !=NULL) pixbuf = gdk_pixbuf_new_from_stream( stream, NULL, &err ); } if(pixbuf) { // Scale pixbuf to a thumbnail double sw=gdk_pixbuf_get_width( pixbuf ); double scale=75.0/gdk_pixbuf_get_height( pixbuf ); thumb = gdk_pixbuf_scale_simple( pixbuf, sw*scale,75 , GDK_INTERP_BILINEAR ); } } #if 0 // libgphoto only supports fetching exif in jpegs, not raw char buffer[1024]= {0}; if ( exif ) { const char *exif_data; char *value=NULL; gp_file_get_data_and_size(exif, &exif_data, &size); if( size > 0 ) { void *exif=dt_exif_data_new((uint8_t *)exif_data,size); if( (value=g_strdup( dt_exif_data_get_value(exif,"Exif.Photo.ExposureTime",buffer,1024) ) ) != NULL); snprintf(exif_info, sizeof(exif_info), "exposure: %s\n", value); } else fprintf(stderr,"No exifdata read\n"); } #endif // filename\n 1/60 f/2.8 24mm iso 160 snprintf(file_info, sizeof(file_info), "%s%c%s",filename,strlen(exif_info)?'\n':'\0',strlen(exif_info)?exif_info:""); gtk_list_store_append(data->store,&iter); gtk_list_store_set(data->store,&iter,0,thumb,1,file_info,-1); if(pixbuf) g_object_unref(pixbuf); if(thumb) g_object_ref(thumb); if (i_own_lock) dt_control_gdk_unlock(); return 1; }
bool GPhotoCCD::capturePreview() { if (sim) return false; int rc = GP_OK; char errMsg[MAXRBUF]; const char* previewData; unsigned long int previewSize; CameraFile* previewFile = NULL; rc = gp_file_new(&previewFile); if (rc != GP_OK) { DEBUGF(INDI::Logger::DBG_ERROR, "Error creating gphoto file: %s", gp_result_as_string(rc)); return false; } for (int i=0; i < MAX_RETRIES; i++) { rc = gphoto_capture_preview(gphotodrv, previewFile, errMsg); if (rc == true) break; } if (rc != GP_OK) { DEBUGF(INDI::Logger::DBG_ERROR, "%s", errMsg); return false; } if (rc >= GP_OK) { rc = gp_file_get_data_and_size(previewFile, &previewData, &previewSize); if (rc != GP_OK) { DEBUGF(INDI::Logger::DBG_ERROR, "Error getting preview image data and size: %s", gp_result_as_string(rc)); return false; } } //DEBUGF(INDI::Logger::DBG_DEBUG, "Preview capture size %d bytes.", previewSize); char *previewBlob = (char *) previewData; imageB->blob = previewBlob; imageB->bloblen = previewSize; imageB->size = previewSize; strncpy(imageB->format, "stream_jpeg", MAXINDIBLOBFMT); IDSetBLOB (imageBP, NULL); if (previewFile) { gp_file_unref(previewFile); previewFile = NULL; } return true; }
static int put_file_func (CameraFilesystem *fs, const char *folder, CameraFile *file, void *data, GPContext *context) { #ifdef HAVE_GD Camera *camera = data; char *filedata = NULL; const char *name; int ret, in_width, in_height, in_x, in_y; double aspect_in, aspect_out; unsigned long filesize = 0; gdImagePtr im_out, im_in = NULL; if (strcmp (folder, "/")) return GP_ERROR_DIRECTORY_NOT_FOUND; CHECK (gp_file_get_name (file, &name)) CHECK (gp_file_get_data_and_size (file, (const char **)&filedata, &filesize)) /* Try loading the file using gd, starting with the most often used types first */ /* gdImageCreateFromJpegPtr is chatty on error, don't call it on non JPEG files */ if (filesize > 2 && (uint8_t)filedata[0] == 0xff && (uint8_t)filedata[1] == 0xd8) im_in = gdImageCreateFromJpegPtr(filesize, filedata); if (im_in == NULL) im_in = gdImageCreateFromPngPtr(filesize, filedata); if (im_in == NULL) im_in = gdImageCreateFromGifPtr(filesize, filedata); if (im_in == NULL) im_in = gdImageCreateFromWBMPPtr(filesize, filedata); if (im_in == NULL) { gp_log (GP_LOG_ERROR, "tp6801", "Unrecognized file format for file: %s%s", folder, name); return GP_ERROR_BAD_PARAMETERS; } im_out = gdImageCreateTrueColor(camera->pl->width, camera->pl->height); if (im_out == NULL) { gdImageDestroy (im_in); return GP_ERROR_NO_MEMORY; } /* Keep aspect */ aspect_in = (double)im_in->sx / im_in->sy; aspect_out = (double)im_out->sx / im_out->sy; if (aspect_in > aspect_out) { /* Reduce in width (crop left and right) */ in_width = (im_in->sx / aspect_in) * aspect_out; in_x = (im_in->sx - in_width) / 2; in_height = im_in->sy; in_y = 0; } else { /* Reduce in height (crop top and bottom) */ in_width = im_in->sx; in_x = 0; in_height = (im_in->sy * aspect_in) / aspect_out; in_y = (im_in->sy - in_height) / 2; } gdImageCopyResampled (im_out, im_in, 0, 0, in_x, in_y, im_out->sx, im_out->sy, in_width, in_height); if (im_in->sx != im_out->sx || im_in->sy != im_out->sy) gdImageSharpen(im_out, 100); ret = tp6801_write_file (camera, im_out->tpixels); if (ret >= 0) { /* Commit the changes to the device */ ret = tp6801_commit(camera); } gdImageDestroy (im_in); gdImageDestroy (im_out); return ret; #else gp_log(GP_LOG_ERROR,"tp6801", "GD compression not supported - no libGD present during build"); return GP_ERROR_NOT_SUPPORTED; #endif }