示例#1
0
bool photo_camera::photo_camera_capture_to_file( std::string filename )
{
  int fd, error_code;
  CameraFile *photo_file;
  CameraFilePath photo_file_path;

  // NOP: This gets overridden in the library to /capt0000.jpg
  strcpy( photo_file_path.folder, "/");
  strcpy( photo_file_path.name, "foo.jpg");

  error_code = gp_camera_capture( camera_, GP_CAPTURE_IMAGE, &photo_file_path, context_ );
  if( error_code < GP_OK )
  {
    photo_reporter::error( "gp_camera_capture()" );
    gp_context_error( context_, "Could not capture image  (error code %d)\n", error_code );
    return false;
  }

  fd = open( filename.c_str(), O_CREAT|O_WRONLY, 0644 );
  error_code = gp_file_new_from_fd( &photo_file, fd );
  if( error_code < GP_OK )
  {
    photo_reporter::error( "gp_file_new_from_fd()" );
    gp_context_error( context_, "Could not create a new image file from %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
    gp_file_free( photo_file );
    return false;
  }

  error_code = gp_camera_file_get( camera_, photo_file_path.folder, photo_file_path.name, GP_FILE_TYPE_NORMAL, photo_file, context_ );
  if( error_code < GP_OK )
  {
    photo_reporter::error( "gp_camera_file_get()" );
    gp_context_error( context_, "Could not get file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
    gp_file_free( photo_file );
    return false;
  }

  error_code = gp_camera_file_delete( camera_, photo_file_path.folder, photo_file_path.name, context_ );
  if( error_code < GP_OK )
  {
    photo_reporter::error( "gp_camera_file_delete()" );
    gp_context_error( context_, "Could delete file %s%s  (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
    gp_file_free( photo_file );
    return false;
  }

  gp_file_free( photo_file );
  return true;
}
示例#2
0
static void
capture_to_file(Camera *canon, GPContext *canoncontext, char *fn) {
	int fd, retval;
	CameraFile *canonfile;
	CameraFilePath camera_file_path;

	printf("Capturing.\n");

	retval = gp_camera_capture(canon, GP_CAPTURE_IMAGE, &camera_file_path, canoncontext);
	printf("  Retval: %d\n", retval);

	printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);

	fd = open(fn, O_CREAT | O_WRONLY | O_BINARY, 0644);
	retval = gp_file_new_from_fd(&canonfile, fd);
	printf("  Retval: %d\n", retval);
	retval = gp_camera_file_get(canon, camera_file_path.folder, camera_file_path.name,
		     GP_FILE_TYPE_NORMAL, canonfile, canoncontext);
	printf("  Retval: %d\n", retval);

	printf("Deleting.\n");
	retval = gp_camera_file_delete(canon, camera_file_path.folder, camera_file_path.name,
			canoncontext);
	printf("  Retval: %d\n", retval);

	gp_file_free(canonfile);
}
static void
capture_to_file(Camera *canon, GPContext *canoncontext, char *fn) {
	int fd, retval;
	CameraFile *canonfile;
	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(canon, GP_CAPTURE_IMAGE, &camera_file_path, canoncontext);
	printf("  Retval: %d\n", retval);

	printf("Pathname on the camera: %s/%s\n", camera_file_path.folder, camera_file_path.name);

	fd = open(fn, O_CREAT | O_WRONLY, 0644);
	retval = gp_file_new_from_fd(&canonfile, fd);
	printf("  Retval: %d\n", retval);
	retval = gp_camera_file_get(canon, camera_file_path.folder, camera_file_path.name,
		     GP_FILE_TYPE_NORMAL, canonfile, canoncontext);
	printf("  Retval: %d\n", retval);

	printf("Deleting.\n");
	retval = gp_camera_file_delete(canon, camera_file_path.folder, camera_file_path.name,
			canoncontext);
	printf("  Retval: %d\n", retval);

	gp_file_free(canonfile);
}
int main(int argc, char *argv[]){
        Camera		*camera;
        GPContext	*context = gp_context_new();
        int		retval;
	CameraEventType evttype;
	void    	*evtdata;
	CameraFile	*file;

        gp_camera_new(&camera);
	retval = gp_camera_init(camera, context);
        if(retval != GP_OK)
        {
                printf("Error: %s\n", gp_result_as_string(retval));
                return 1;
        }

	do {
		retval = gp_camera_wait_for_event (camera, 10, &evttype, &evtdata, context);
	} while ((retval == GP_OK) && (evttype != GP_EVENT_TIMEOUT));

	retval = gp_file_new(&file);
	if (retval != GP_OK) {
		printf("gp_file_new: %d\n", retval);
		return 1;
	}
	/*retval = gp_camera_capture_preview(camera, file, context); */
	if (retval != GP_OK) {
		printf("gp_camera_capture_preview: %d\n", retval);
		return 1;
	}
	gp_file_free (file);

        if(argc == 1)
        {
                retval = camera_auto_focus(camera, context);
		if(retval != GP_OK) {
			printf("Error: %s\n", gp_result_as_string(retval));
			return 1;
		}
        }
        else if(argc == 2)
        {
                int value = atoi(argv[1]);
                retval = camera_manual_focus(camera, value, context);
		if(retval != GP_OK) {
			printf("Error: %s\n", gp_result_as_string(retval));
			return 1;
		}
        }
	do {
		retval = gp_camera_wait_for_event (camera, 10, &evttype, &evtdata, context);
	} while ((retval == GP_OK) && (evttype != GP_EVENT_TIMEOUT));

        gp_camera_exit(camera, context);
        return 0;
}
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";
    }
}
示例#6
0
	int capture_to_file(std::string file_prefix, float exposure,
			std::string iso="1600", std::string aperture="0",
			bool gen_fits=true) {
		int aborted = 0;
		int fd, retval;
		CameraFile *canonfile;
		CameraFilePath camera_file_path;
		set_config_value_string(camera, "iso", iso.c_str(), context);
		if (aperture=="0")
			set_config_value_index(camera, "aperture", 0, context);
		else
			set_config_value_string(camera, "aperture", aperture.c_str(), context);

		printf("Capturing.\n");
		//press shutter, wait for "exposure" seconds, release shutter
		CameraEventType eventtype;
		void* eventdata;
		set_config_value_string(camera, "eosremoterelease", "Press Full", context);
		usleep(exposure*1e6);
		if (errno == EINTR) aborted = 1;
		set_config_value_string(camera, "eosremoterelease", "Release Full", context);

		std::cout << "Waiting for file...\n";
		eventtype = GP_EVENT_UNKNOWN;
		while (eventtype != GP_EVENT_FILE_ADDED) {
			gp_camera_wait_for_event(camera, TIMEOUT, &eventtype, &eventdata, context);
		}
		camera_file_path = *((CameraFilePath*) eventdata);

		printf("Pathname on the camera: %s/%s\n", camera_file_path.folder,
				camera_file_path.name);

		fd = open((file_prefix+".cr2").c_str(),
				O_CREAT | O_WRONLY, 0644);
		retval = gp_file_new_from_fd(&canonfile, fd);
		if (retval != GP_OK) return retval;

		retval = gp_camera_file_get(camera, camera_file_path.folder,
				camera_file_path.name, GP_FILE_TYPE_NORMAL, canonfile,
				context);
		if (retval != GP_OK) return retval;

		retval = gp_camera_file_delete(camera, camera_file_path.folder,
				camera_file_path.name, context);
		if (retval != GP_OK) return retval;

		gp_file_free(canonfile);
		if (gen_fits) produce_fits(file_prefix, aborted);
		return GP_OK;
	}
示例#7
0
//SAVE THREAD
//Saves Files from memory -> disk
void * SaveFiles(void*aaa){
    while(1){
        //Wait for Get Thread to tell us we have at least one file waiting
        //Put here to avoid busy waiting
        sem_wait(&NewFileSem);
        CF* my_CF = RemoveFile(); //Dequeue
        if(my_CF != NULL){
            printf("\nFile %s saved!\n", my_CF->filename);
            gp_file_save(my_CF -> my_File, my_CF -> filename);
            gp_file_free(my_CF -> my_File);
            free(my_CF -> filename);
            free(my_CF);
        }
    }
    return NULL;
}
void GPhotoCameraWorker::closeCamera()
{
    // Camera is already closed
    if (!m_camera)
        return;

    setStatus(QCamera::UnloadingStatus);

    // Close GPhoto camera session
    int ret = gp_camera_exit(m_camera, m_context);
    if (ret != GP_OK) {
        qWarning() << "Unable to close camera";
        setStatus(QCamera::LoadedStatus);
        emit error(QCamera::CameraError, tr("Unable to close camera"));
        return;
    }

    gp_file_free(m_file);
    m_file = 0;
    gp_camera_free(m_camera);
    m_camera = 0;
    setStatus(QCamera::UnloadedStatus);
}
示例#9
0
static int 
recursive_directory(Camera *camera, const char *folder, GPContext *context, int *foundfile) {
	int		i, ret;
	CameraList	*list;
	const char	*newfile;
	CameraFileInfo	fileinfo;
	CameraFile	*file;

	ret = gp_list_new (&list);
	if (ret < GP_OK) {
		printf ("Could not allocate list.\n");
		return ret;
	}

	ret = gp_camera_folder_list_folders (camera, folder, list, context);
	if (ret < GP_OK) {
		printf ("Could not list folders.\n");
		gp_list_free (list);
		return ret;
	}
	gp_list_sort (list);

	for (i = 0; i < gp_list_count (list); i++) {
		const char *newfolder;
		char *buf;
		int havefile = 0;

		gp_list_get_name (list, i, &newfolder);

		buf = malloc (strlen(folder) + 1 + strlen(newfolder) + 1);
		strcpy(buf, folder);
		if (strcmp(folder,"/"))		/* avoid double / */
			strcat(buf, "/");
		strcat(buf, newfolder);

		ret = recursive_directory (camera, buf, context, &havefile);
		free (buf);
		if (ret != GP_OK) {
			gp_list_free (list);
			printf ("Failed to recursively list folders.\n");
			return ret;
		}
		if (havefile) /* only look for the first directory with a file */
			break;
	}
	gp_list_reset (list);

	ret = gp_camera_folder_list_files (camera, folder, list, context);
	if (ret < GP_OK) {
		gp_list_free (list);
		printf ("Could not list files.\n");
		return ret;
	}
	gp_list_sort (list);
	if (gp_list_count (list) <= 0) {
		gp_list_free (list);
		return GP_OK;
	}

	gp_list_get_name (list, 0, &newfile); /* only entry 0 needed */
	ret = gp_camera_file_get_info (camera, folder, newfile, &fileinfo, context);
	if (ret != GP_OK) {
		gp_list_free (list);
		printf ("Could not get file info.\n");
		return ret;
	}

	/* Trigger the ptp things */
	gp_file_new (&file);
	ret = gp_camera_file_get (camera, folder, newfile, GP_FILE_TYPE_METADATA, file, context);
	if ((ret != GP_OK) && (ret != GP_ERROR_NOT_SUPPORTED)) {
		gp_list_free (list);
		printf ("Could not get file metadata.\n");
		return ret;
	}
	gp_file_free (file);
	if (foundfile) *foundfile = 1;
	gp_list_free (list);
	return GP_OK;
}
示例#10
0
static int
file_list_func (CameraFilesystem *fs, const char *folder,
		CameraList *list, void *data, GPContext *context)
{
	Camera *camera = data;
	unsigned int i, filecount, id, size, type;
	CameraFile *file;
	CameraFileInfo info;
	unsigned char *buffer = NULL;
	int ret, n_img=0, n_avi=0, n_wav=0;
	char fn[100];

	CHECK (pccam300_get_filecount (camera->port, &filecount));

	id = gp_context_progress_start (context, filecount,
			_("Getting file list..."));
	
	for (i = 0; i < filecount; i++) {
		/* Get information */
		gp_file_new (&file);
	
		ret = pccam300_get_file (camera->port, context, i,
		                          &buffer, &size, &type);
		if (ret < GP_OK) {
			gp_file_free (file);
			return ret;
		}

		info.audio.fields = GP_FILE_INFO_NONE;
		info.preview.fields = GP_FILE_INFO_NONE;

		info.file.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE;
		info.file.size = size;

		switch (type) {
			case PCCAM300_MIME_JPEG:
				strcpy (info.file.type, GP_MIME_JPEG);
				sprintf (fn, "Image%03i.jpeg", n_img++);
				break;
			case PCCAM300_MIME_AVI:
				strcpy (info.file.type, GP_MIME_AVI);
				sprintf (fn, "Movie%03i.UNUSABLE", n_avi++);
				break;
			case PCCAM300_MIME_WAV:
				strcpy (info.file.type, GP_MIME_WAV);
				sprintf (fn, "Audio%03i.UNUSABLE", n_wav++);
				break;
			default:
				break;
		}

		if (file)
			gp_file_set_data_and_size (file, buffer, size);
		else
			free (buffer);
		
		/*
		 * Append directly to the filesystem instead of to the list,
		 * because we have additional information. 
		 * */
		gp_filesystem_append (camera->fs, folder, fn, context);
		gp_filesystem_set_info_noop (camera->fs, folder, fn, info, context);
		gp_filesystem_set_file_noop (camera->fs, folder, fn, GP_FILE_TYPE_NORMAL,
					file, context);
		gp_file_unref (file);

		gp_context_idle (context);
		gp_context_progress_update (context, id, i + 1);
		if (gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL)
			return (GP_ERROR_CANCEL);
	}
	gp_context_progress_stop (context, id);
	return GP_OK;
}
示例#11
0
bool photo_camera::photo_camera_capture( photo_image* image )
{
  int fd, error_code;
  CameraFile *photo_file;
  CameraFilePath photo_file_path;
  char temp_file_name[20];

  // NOP: This gets overridden in the library to /capt0000.jpg
  strcpy( photo_file_path.folder, "/" );
  strcpy( photo_file_path.name, "foo.jpg" );

  error_code = gp_camera_capture( camera_, GP_CAPTURE_IMAGE, &photo_file_path, context_ );
  if( error_code < GP_OK )
  {
    photo_reporter::error( "gp_camera_capture()" );
    gp_context_error( context_, "Could not capture image  (error code %d)\n", error_code );
    return false;
  }

  // create temporary file
  strcpy( temp_file_name, "tmpfileXXXXXX" );
  fd = mkstemp( temp_file_name );
  error_code = gp_file_new_from_fd( &photo_file, fd );
  if( error_code < GP_OK )
  {
    close( fd );
    unlink( temp_file_name );

    photo_reporter::error( "gp_file_new_from_fd()" );
    gp_context_error( context_, "Could not create a new image file from %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
    gp_file_free( photo_file );
    return false;
  }

  // get image from camera and store in temporary file
  error_code = gp_camera_file_get( camera_, photo_file_path.folder, photo_file_path.name, GP_FILE_TYPE_NORMAL, photo_file, context_ );
  if( error_code < GP_OK )
  {
    gp_file_unref( photo_file );
    unlink( temp_file_name );
    photo_reporter::error( "gp_camera_file_get()" );
    gp_context_error( context_, "Could not get file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
    return false;
  }

  // delete image from camera's memory
  error_code = gp_camera_file_delete( camera_, photo_file_path.folder, photo_file_path.name, context_ );
  if( error_code < GP_OK )
  {
    unlink( temp_file_name );
    photo_reporter::error( "gp_camera_file_delete()" );
    gp_context_error( context_, "Could delete file %s%s  (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
    gp_file_free( photo_file );
    return false;
  }

  // load image from temporary file
  if( image->photo_image_read( std::string(temp_file_name) ) == true )
  {
    gp_file_free( photo_file );
    unlink( temp_file_name );
    return true;
  }

  photo_reporter::error( "photo_image_read()" );
  gp_file_free( photo_file );
  unlink( temp_file_name );
  return false;
}
示例#12
0
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);
}
示例#13
0
/* This function reads all thumbnails at once and initializes the whole
 * camera filesystem. This can be done, because finding out how much 
 * pictures are on the camera is done by reading the whole preview picture
 * stream anyway.
 * And since the file infos are static mostly, why not just set them too at
 * the same time.
 */
int
jd11_index_reader(GPPort *port, CameraFilesystem *fs, GPContext *context) {
    int		i, id, count, xsize, curread=0, ret=0;
    unsigned char	*indexbuf;

    ret = jd11_select_index(port);
    if (ret != GP_OK)
	return ret;
    xsize = jd11_imgsize(port);
    if (!xsize) { /* shortcut, no reading needed */
	return GP_OK;
    }
    count = xsize/(64*48);
    xsize = count * (64*48);
    indexbuf = malloc(xsize);
    if (!indexbuf) return GP_ERROR_NO_MEMORY;
    id = gp_context_progress_start (context, xsize,
				    _("Downloading thumbnail..."));
    _send_cmd(port,0xfff1);
    while (curread < xsize) {
	    int readsize = xsize-curread;
	    if (readsize>200) readsize = 200;
	    ret=getpacket(port,indexbuf+curread,readsize);
	    if (ret==0)
		    break;
	    curread+=ret;
	    if (ret<200)
		    break;
	    gp_context_progress_update (context, id, curread);
	    if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
		/* What to do...Just free the stuff we allocated for now.*/
		free(indexbuf);
		return GP_ERROR_CANCEL;
	    }
	    _send_cmd(port,0xfff1);
    }
    gp_context_progress_stop (context, id);
    for (i=0;i<count;i++) {
	CameraFile	*file;
	char		fn[20];
	unsigned char *src;
	unsigned char thumb[64*48];
	int y;
	CameraFileInfo	info;
	
	ret = gp_file_new(&file);
	if (ret!=GP_OK) {
	    free(indexbuf);
	    return ret;
	}
	sprintf(fn,"image%02i.pgm",i);
	gp_file_set_mime_type(file, GP_MIME_PGM);
	gp_file_append(file, THUMBHEADER, strlen(THUMBHEADER));
	src = indexbuf+(i*64*48);
	for (y=0;y<48;y++) {
	    int x,off = 64*y;
	    for (x=0;x<64;x++)
		thumb[47*64-off+(63-x)] = src[off+x];
	}
	ret = gp_file_append(file,(char*)thumb,sizeof(thumb));
	if (ret != GP_OK) {
		gp_file_free (file);
		return ret;
	}
	ret = gp_filesystem_append(fs, "/", fn, context);
	if (ret != GP_OK) {
		/* should perhaps remove the entry again */
		gp_file_free (file);
		return ret;
	}
	ret = gp_filesystem_set_file_noop(fs, "/", fn, GP_FILE_TYPE_PREVIEW, file, context);
	if (ret != GP_OK) return ret;

	/* 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;
	strcpy(info.file.type,GP_MIME_PNM);
	info.file.width		= 640;
	info.file.height	= 480;
	info.file.size		= 640*480*3+strlen(IMGHEADER);
	info.preview.fields = GP_FILE_INFO_TYPE |
			GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT | 
			GP_FILE_INFO_SIZE;
	strcpy(info.preview.type,GP_MIME_PGM);
	info.preview.width	= 64;
	info.preview.height	= 48;
	info.preview.size	= 64*48+strlen(THUMBHEADER);
	ret = gp_filesystem_set_info_noop(fs, "/", fn, info, context);
    }
    free(indexbuf);
    return GP_OK;
}
bool photoController::capture(const char *filename) 
{
	if(checkCameraDetection() == false)
	{
		DEBUG_PRINTF(V_WARNING, "No camera detected.\n");
		return false;
	}
	int fd, retval;
	CameraFile *file;
	CameraFilePath camera_file_path;
	START_CHRONOMETER();
	DEBUG_PRINTF(V_MESSAGE, "Deleting old files.\n");
	retval = gp_camera_folder_delete_all(camera, "/", context);
	if(retval != GP_OK) // Error.
	{
		DEBUG_PRINTF(V_WARNING, "ERROR: Couldn't delete old files in camera memory. Code: %d\n", retval);
		return false;
	}
	DEBUG_PRINTF(V_MESSAGE, "Camera capture.\n");

	retval = gp_camera_capture(camera, GP_CAPTURE_IMAGE, &camera_file_path, context);
	if(retval != GP_OK) // Error.
	{
		if(retval == GP_ERROR_NOT_SUPPORTED)
			DEBUG_PRINTF(V_WARNING, "ERROR: This camera can not capture.\n");
		else
		{
			DEBUG_PRINTF(V_WARNING, "ERROR: Unexpected gp_camera_capture return. Code: %d\n", retval);
			releaseCamera(&camera, context);
			camera_detected = false;
			initCamera();
		}
		return false;
	}
	DEBUG_PRINTF(V_MESSAGE, "camera_file_path.folder %s!\n", camera_file_path.folder);
	DEBUG_PRINTF(V_MESSAGE, "Open %s!\n", filename);
	fd = open(filename, O_CREAT | O_WRONLY, 0644);
	if(fd < 0)  // Error.
	{
		DEBUG_PRINTF(V_WARNING, "Error opening file: %s!\n", strerror(errno));
		return false;
	}
	DEBUG_PRINTF(V_MESSAGE, "Create new CameraFile object from a file descriptor FD: %d.\n", fd);
	retval = gp_file_new_from_fd(&file, fd);
	if(retval != GP_OK) // Error.
	{
		DEBUG_PRINTF(V_WARNING, "ERROR: Unexpected gp_file_new_from_fd return. Code: %d\n", retval);
		gp_file_free(file);
		close(fd);
		return false;
	}
	if(checkCameraDetection() == false)
	{
		DEBUG_PRINTF(V_WARNING, "No camera detected 2.\n");
		gp_file_free(file);
		close(fd);
		return false;
	}
	DEBUG_PRINTF(V_MESSAGE, "Copy file from camera.\n");
	retval = gp_camera_file_get(camera, camera_file_path.folder, camera_file_path.name, GP_FILE_TYPE_NORMAL, file, context);
	if(retval != GP_OK) // Error.
	{
		if(retval == GP_ERROR_DIRECTORY_NOT_FOUND)
			DEBUG_PRINTF(V_WARNING, "Photo directory not found.\n");
		else if(retval == GP_ERROR_FILE_NOT_FOUND)
			DEBUG_PRINTF(V_WARNING, "Photo file name not found.\n");
		else
			DEBUG_PRINTF(V_WARNING, "ERROR: Unexpected gp_camera_file_get return. Code: %d\n", retval);
		gp_file_free(file);
		close(fd);
		return false;
	}
	if(checkCameraDetection() == false)
	{
		DEBUG_PRINTF(V_WARNING, "No camera detected 3.\n");
		gp_file_free(file);
		close(fd);
		return false;
	}
	DEBUG_PRINTF(V_MESSAGE, "Delete file from camera.\n");
	retval = gp_camera_file_delete(camera, camera_file_path.folder, camera_file_path.name, context);
	if(retval != GP_OK) // Error.
	{
		DEBUG_PRINTF(V_WARNING, "ERROR: Unexpected gp_camera_file_delete return. Code: %d\n", retval);
		gp_file_free(file);
		close(fd);
		return false;
	}

	DEBUG_PRINTF(V_MESSAGE, "Free CameraFile object.\n");
	gp_file_unref(file);
	close(fd);

	cv::Mat raw = cv::imread(filename);
	if(raw.data == NULL)
	{
		DEBUG_PRINTF(V_WARNING, "ERROR: OpenCV failed to open image file.\n");
		return false;
	}
	cv::Size raw_size = raw.size();
	DEBUG_PRINTF(V_MESSAGE, "capture() cv::Mat total=%u width=%d height=%d refcount=%d\n", raw.total(), raw_size.width, raw_size.height, (int)(void*)raw.refcount);
	crop(raw);
	raw.release();

	STOP_CHRONOMETER("Capture");
	return true;
}