photo_camera.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2012, Robert Bosch LLC.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of the Robert Bosch nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  *********************************************************************/
36 
37 #include <cstdio> // sscanf, printf, etc.
38 #include <fcntl.h> // C file I/O
39 #include <unistd.h>
40 #include <cstdlib>
41 #include <cstring>
42 
43 #include "photo/photo_reporter.hpp"
44 
45 #include "photo/photo_camera.hpp"
46 
47 
49  camera_(NULL),
50  context_(NULL),
51  mode_(DIRECT)
52 {
53  //port_info_(NULL);
54  //abilities_(NULL);
55 }
56 
58 {
59  if( camera_ )
60  {
61  gp_camera_unref( camera_ ); //delete camera_;
62  }
63 
64  gp_context_unref( context_ ); //delete context_;
65 }
66 
67 
69 {
70  context_ = gp_context_new();
71 
72  // Optional debugging and status output
73  gp_context_set_error_func( context_, photo_reporter::contextError, NULL );
74  gp_context_set_status_func( context_, photo_reporter::contextStatus, NULL );
75  return context_;
76 }
77 
78 
79 bool photo_camera::photo_camera_open( photo_camera_list* list, const std::string& model_name,
80  const std::string& port_name )
81 {
82  // Create a context if necessary
83  if( context_ == NULL )
84  {
86  }
87 
88  // Create new camera
89  if( gp_camera_new( &camera_ ) != GP_OK )
90  {
91  photo_reporter::error( "gp_camera_new()" );
92  return false;
93  }
94 
95  // Find and set camera abilities based on model
96  //std::cout << "Model name: " << model_name << " == " << std::endl;
97  if( list->lookupAbilities( model_name, &abilities_ ) == true )
98  {
99  // Set the camera's abilities
100  if( gp_camera_set_abilities( camera_, abilities_ ) != GP_OK )
101  {
102  photo_reporter::error( "gp_camera_set_abilities()" );
103  return false;
104  }
105  }
106  else
107  {
108  return false;
109  }
110 
111  // Associate camera with port
112  if( list->lookupPortInfo( port_name, &port_info_ ) == true )
113  {
114  if( gp_camera_set_port_info( camera_, port_info_ ) != GP_OK )
115  {
116  photo_reporter::error( "gp_camera_set_port_info()" );
117  return false;
118  }
119  }
120  else
121  {
122  return false;
123  }
124 
125  // Camera is open!
126  return true;
127 }
128 
129 
130 
132 {
133  const char *name = NULL;
134  const char *value = NULL;
135 
136  gp_list_get_name( list->getCameraList(), n, &name );
137  if( name == NULL )
138  {
139  photo_reporter::error( "could not get name of camera" );
140  return false;
141  }
142 
143  gp_list_get_value( list->getCameraList(), n, &value );
144  if( value == NULL )
145  {
146  photo_reporter::error( "could not get value of camera" );
147  return false;
148  }
149 
150  std::cout << "Opening camera " << n << " by name (" << name << ") and value (" << value << ")" << std::endl;
151 
152  if( photo_camera_open( list, name, value ) == false )
153  {
154  photo_reporter::error( "photo_camera_open()" );
155  return false;
156  }
157  return true;
158 }
159 
160 
162 {
163  if( camera_ )
164  {
165  if( gp_camera_exit( camera_, context_ ) != GP_OK )
166  {
167  photo_reporter::error( "gp_camera_exit()", "Could not close photo_camera.");
168  return false;
169  }
170  }
171  return true;
172 }
173 
174 
175 
176 
177 int photo_camera::photo_camera_find_widget_by_name( std::string name, CameraWidget **child,
178  CameraWidget **root)
179  {
180  int error_code;
181 
182  // Get camera configuration
183  error_code = gp_camera_get_config( camera_, root, context_ );
184  if (error_code != GP_OK)
185  {
186  photo_reporter::error( "gp_camera_get_config()");
187  return error_code;
188  }
189 
190  // Find child of configuration by name
191  if( gp_widget_get_child_by_name( *root, name.c_str(), child ) == GP_OK )
192  {
193  return GP_OK;
194  }
195 
196  // Find child of configuration by label
197  if( gp_widget_get_child_by_label( *root, name.c_str(), child ) == GP_OK )
198  {
199  return GP_OK;
200  }
201 
202  // If full name is not found, search for last subname.
203  // name delimeter is '/'
204  size_t found_index = name.length();
205  while( found_index == name.length() )
206  {
207  found_index = name.rfind( '/' );
208 
209  if( found_index == std::string::npos ) // No subname, we already failed this search above
210  {
211  gp_context_error( context_,"%s not found in configuration tree.", name.c_str() );
212  gp_widget_free( *root );
213  return GP_ERROR;
214  }
215 
216  if( found_index == name.length() - 1 ) // end of string, cut it off
217  {
218  name = name.substr( 0, found_index );
219  }
220  }
221  name = name.substr( found_index, name.length() - 1 );
222 
223  // Find child using
224  if( gp_widget_get_child_by_name( *root, name.c_str(), child ) == GP_OK )
225  {
226  return GP_OK;
227  }
228  if( gp_widget_get_child_by_label( *root, name.c_str(), child ) == GP_OK )
229  {
230  return GP_OK;
231  }
232 
233  // all matches have failed
234  gp_context_error( context_, "%s not found in configuration tree.", name.c_str() );
235  gp_widget_free( *root );
236  return GP_ERROR;
237 }
238 
244 bool photo_camera::photo_camera_check_toggle_value( const std::string& value_in, int* value_out )
245 {
246  std::string toggle_positive[] = { "on", "yes", "true", "ON", "YES", "TRUE"};
247  std::string toggle_negative[] = { "off", "no", "false", "OFF", "NO", "FALSE" };
248 
249 
250  // first check numeric values: "1" and "0"
251  if( value_in.compare( "0" ) == 0 )
252  {
253  *value_out = 0;
254  return true;
255  }
256  if( value_in.compare( "0" ) == 0 )
257  {
258  *value_out = 1;
259  return true;
260  }
261 
262  // check values in toggle_positive
263  for( int i = 0; i < 6; i++ )
264  {
265  if( value_in.compare( toggle_positive[i] ) == 0 )
266  {
267  *value_out = 1;
268  return true;
269  }
270  }
271 
272  // check values in toggle_negative
273  for( int i = 0; i < 6; i++ )
274  {
275  if( value_in.compare( toggle_negative[i] ) == 0 )
276  {
277  *value_out = 0;
278  return true;
279  }
280  }
281  return false;
282 }
283 
284 
285 
286 bool photo_camera::photo_camera_set_config( const std::string& param, const std::string& value )
287 {
288  CameraWidget *root, *child;
289  int error_code;
290  const char *label;
291  CameraWidgetType type;
292 
293  // Locate the widget that corresponds to this parameter
294  if( photo_camera_find_widget_by_name( param, &child, &root ) != GP_OK )
295  {
296  photo_reporter::error( "photo_camera_find_widget_by_name()");
297  return false;
298  }
299 
300  // Get the widget label
301  if( gp_widget_get_label(child, &label) != GP_OK )
302  {
303  photo_reporter::error( "gp_widget_get_label()");
304  gp_widget_free( root );
305  return false;
306  }
307 
308  // Get the widget type
309  if( gp_widget_get_type( child, &type ) != GP_OK )
310  {
311  photo_reporter::error( "gp_widget_get_type()");
312  gp_widget_free( root );
313  return false;
314  }
315 
316  switch( type )
317  {
318 
319  case GP_WIDGET_TEXT: // char*
320  if( gp_widget_set_value(child, value.c_str()) != GP_OK )
321  {
322  photo_reporter::error( "gp_widget_set_value()");
323  gp_context_error( context_, "Failed to set the value of text widget %s to %s.", param.c_str(), value.c_str() );
324  gp_widget_free( root );
325  return false;
326  }
327  break;
328 
329  case GP_WIDGET_RANGE: // float
330  float f, t, b, s;
331 
332  if( gp_widget_get_range( child, &b, &t, &s) != GP_OK )
333  {
334  photo_reporter::error( "gp_widget_get_range()" );
335  gp_widget_free( root );
336  return false;
337  }
338  if( !sscanf( value.c_str(), "%f", &f ) )
339  {
340  gp_context_error( context_, "The passed value %s is not a floating point value.", value.c_str() );
341  gp_widget_free( root );
342  return false;
343  }
344  if( (f < b) || (f > t) )
345  {
346  gp_context_error( context_ , "The passed value %f is not within the expected range of %f -- %f.", f, b, t );
347  gp_widget_free( root );
348  return false;
349  }
350  if( gp_widget_set_value( child, &f ) != GP_OK )
351  {
352  photo_reporter::error( "gp_widget_set_value()" );
353  gp_context_error( context_, "Failed to set the value of range widget %s to %f.", param.c_str(), f );
354  gp_widget_free( root );
355  return false;
356  }
357  break;
358 
359  case GP_WIDGET_TOGGLE: // int
360  int tog;
361  if( photo_camera_check_toggle_value( value, &tog ) == false )
362  {
363  gp_context_error(context_, "The passed value %s is not a valid toggle value.", value.c_str() );
364  gp_widget_free( root );
365  return false;
366  }
367  if( gp_widget_set_value( child, &tog ) != GP_OK )
368  {
369  photo_reporter::error( "gp_widget_set_value()" );
370  gp_context_error( context_, "Failed to set values %s of toggle widget %s.", value.c_str(), param.c_str() );
371  gp_widget_free( root );
372  return false;
373  }
374  break;
375 
376  case GP_WIDGET_DATE: // int
377  {
378  int time = -1;
379 #ifdef HAVE_STRPTIME
380  struct tm xtm;
381 
382  if( strptime( value.c_str(), "%c", &xtm ) || strptime( value.c_str(), "%Ec", &xtm ) )
383  {
384  time = mktime( &xtm );
385  }
386 #endif
387  if( time == -1 )
388  {
389  if( !sscanf( value.c_str(), "%d", &time ) )
390  {
391  gp_context_error( context_, "The passed value %s is neither a valid time nor an integer.", value.c_str() );
392  gp_widget_free( root );
393  return false;
394  }
395  }
396  if( gp_widget_set_value(child, &time) != GP_OK )
397  {
398  photo_reporter::error( "gp_widget_set_value()" );
399  gp_context_error( context_, "Failed to set new time of date/time widget %s to %s.", param.c_str(), value.c_str() );
400  gp_widget_free( root );
401  return false;
402  }
403  break;
404  }
405 
406  case GP_WIDGET_MENU:
407  case GP_WIDGET_RADIO: // char*
408  int count, i;
409  count = gp_widget_count_choices( child );
410  if( count < GP_OK )
411  {
412  photo_reporter::error( "gp_widget_count_choices()" );
413  gp_widget_free( root );
414  return false;
415  }
416 
417  error_code = GP_ERROR_BAD_PARAMETERS;
418  for( i = 0; i < count; i++ )
419  {
420  const char *choice;
421  if( gp_widget_get_choice( child, i, &choice ) == GP_OK )
422  {
423  if( value.compare( choice ) == 0 )
424  {
425  if( gp_widget_set_value( child, value.c_str() ) == GP_OK )
426  {
427  break;
428  }
429  }
430  }
431  }
432  // attemt a different method for setting a radio button
433  if( sscanf( value.c_str(), "%d", &i ) )
434  {
435  if( (i >= 0) && (i < count) )
436  {
437  const char *choice;
438  if( gp_widget_get_choice( child, i, &choice ) == GP_OK )
439  {
440  if( gp_widget_set_value( child, choice ) == GP_OK )
441  {
442  break;
443  }
444  }
445  }
446  }
447  gp_context_error( context_, "Choice %s not found within list of choices.", value.c_str() );
448  gp_widget_free( root );
449  return false;
450 
451  case GP_WIDGET_WINDOW:
452  case GP_WIDGET_SECTION:
453  case GP_WIDGET_BUTTON:
454  default:
455  gp_context_error( context_,"The %s widget is not configurable.", param.c_str() );
456  gp_widget_free( root );
457  return false;
458  }
459 
460 
461  // Configuration parameters are correct, so set the camera
462  if( gp_camera_set_config( camera_, root, context_ ) != GP_OK )
463  {
464  photo_reporter::error( "gp_camera_set_config()" );
465  gp_context_error( context_, "Failed to set new configuration value %s for configuration entry %s.", value.c_str(), param.c_str() );
466  gp_widget_free( root );
467  return false;
468  }
469 
470  gp_widget_free( root );
471  return true;
472 }
473 
474 
475 
476 bool photo_camera::photo_camera_get_config( const std::string& param, char** value )
477 {
478  CameraWidget *root, *child;
479  const char *label;
480  CameraWidgetType type;
481 
482  // Locate the widget that corresponds to this parameter
483  if( photo_camera_find_widget_by_name( param, &child, &root ) != GP_OK )
484  {
485  photo_reporter::error( "photo_camera_find_widget_by_name()");
486  return false;
487  }
488 
489  // Get the widget label
490  if( gp_widget_get_label(child, &label) != GP_OK )
491  {
492  photo_reporter::error( "gp_widget_get_label()");
493  gp_widget_free( root );
494  return false;
495  }
496 
497  // Get the widget type
498  if( gp_widget_get_type( child, &type ) != GP_OK )
499  {
500  photo_reporter::error( "gp_widget_get_type()");
501  gp_widget_free( root );
502  return false;
503  }
504 
505  switch( type )
506  {
507  case GP_WIDGET_TEXT: // char*
508  char *txt;
509  if( gp_widget_get_value( child, &txt ) != GP_OK )
510  {
511  gp_context_error( context_, "Failed to retrieve value of text widget %s.", param.c_str() );
512  }
513  sprintf(*value, "%s", txt);
514  break;
515 
516  case GP_WIDGET_RANGE: // float
517  float f, t,b,s;
518  if( gp_widget_get_range( child, &b, &t, &s ) != GP_OK )
519  {
520  gp_context_error( context_, "Failed to retrieve values of range widget %s.", param.c_str() );
521  }
522  if( gp_widget_get_value( child, &f ) != GP_OK )
523  {
524  gp_context_error( context_, "Failed to value of range widget %s.", param.c_str() );
525  }
526  sprintf( *value, "%f", f );
527  break;
528 
529  case GP_WIDGET_TOGGLE: // int
530  {
531  int t;
532  if( gp_widget_get_value( child, &t ) != GP_OK )
533  {
534  gp_context_error( context_,"Failed to retrieve values of toggle widget %s.", param.c_str() );
535  }
536  sprintf( *value, "%d", t );
537  break;
538  }
539 
540  case GP_WIDGET_DATE: // int
541  {
542  int error_code, t;
543  time_t working_time;
544  struct tm *localtm;
545  char timebuf[200];
546 
547  if( gp_widget_get_value( child, &t ) != GP_OK )
548  {
549  gp_context_error( context_,"Failed to retrieve values of date/time widget %s.", param.c_str() );
550  break;
551  }
552  working_time = t;
553  localtm = localtime( &working_time );
554  error_code = strftime( timebuf, sizeof(timebuf), "%c", localtm );
555  sprintf( *value, "%s", timebuf );
556  break;
557  }
558 
559  case GP_WIDGET_MENU:
560  case GP_WIDGET_RADIO: //char*
561  char *current;
562  if( gp_widget_get_value (child, &current) != GP_OK )
563  {
564  gp_context_error( context_,"Failed to retrieve values of radio widget %s.", param.c_str() );
565  }
566  sprintf( *value, "%s", current );
567  break;
568 
569  // No values, so nothing to return
570  case GP_WIDGET_WINDOW:
571  case GP_WIDGET_SECTION:
572  case GP_WIDGET_BUTTON:
573  default:
574  break;
575  }
576 
577  gp_widget_free( root );
578  return true;
579 }
580 
581 
582 bool photo_camera::photo_camera_capture_to_file( const std::string& filename )
583 {
584  int fd, error_code;
585  CameraFile *photo_file;
586  CameraFilePath photo_file_path;
587 
588  // NOP: This gets overridden in the library to /capt0000.jpg
589  strcpy( photo_file_path.folder, "/");
590  strcpy( photo_file_path.name, "foo.jpg");
591 
592  error_code = gp_camera_capture( camera_, GP_CAPTURE_IMAGE, &photo_file_path, context_ );
593  if( error_code < GP_OK )
594  {
595  photo_reporter::error( "gp_camera_capture()" );
596  gp_context_error( context_, "Could not capture image (error code %d)\n", error_code );
597  return false;
598  }
599 
600  fd = open( filename.c_str(), O_CREAT|O_WRONLY, 0644 );
601  error_code = gp_file_new_from_fd( &photo_file, fd );
602  if( error_code < GP_OK )
603  {
604  photo_reporter::error( "gp_file_new_from_fd()" );
605  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 );
606  gp_file_free( photo_file );
607  return false;
608  }
609 
610  error_code = gp_camera_file_get( camera_, photo_file_path.folder, photo_file_path.name, GP_FILE_TYPE_NORMAL, photo_file, context_ );
611  if( error_code < GP_OK )
612  {
613  photo_reporter::error( "gp_camera_file_get()" );
614  gp_context_error( context_, "Could not get file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
615  gp_file_free( photo_file );
616  return false;
617  }
618 
619  error_code = gp_camera_file_delete( camera_, photo_file_path.folder, photo_file_path.name, context_ );
620  if( error_code < GP_OK )
621  {
622  photo_reporter::error( "gp_camera_file_delete()" );
623  gp_context_error( context_, "Could delete file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
624  gp_file_free( photo_file );
625  return false;
626  }
627 
628  gp_file_free( photo_file );
629  return true;
630 }
631 
632 
634 {
635  int fd, error_code;
636  CameraFile *photo_file;
637  CameraFilePath photo_file_path;
638  char temp_file_name[20];
639 
640  // NOP: This gets overridden in the library to /capt0000.jpg
641  strcpy( photo_file_path.folder, "/" );
642  strcpy( photo_file_path.name, "foo.jpg" );
643 
644  error_code = gp_camera_capture( camera_, GP_CAPTURE_IMAGE, &photo_file_path, context_ );
645  if( error_code < GP_OK )
646  {
647  photo_reporter::error( "gp_camera_capture()" );
648  gp_context_error( context_, "Could not capture image (error code %d)\n", error_code );
649  return false;
650  }
651 
652  // create temporary file
653  strcpy( temp_file_name, "tmpfileXXXXXX" );
654  fd = mkstemp( temp_file_name );
655  error_code = gp_file_new_from_fd( &photo_file, fd );
656  if( error_code < GP_OK )
657  {
658  close( fd );
659  unlink( temp_file_name );
660 
661  photo_reporter::error( "gp_file_new_from_fd()" );
662  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 );
663  gp_file_free( photo_file );
664  return false;
665  }
666 
667  // get image from camera and store in temporary file
668  error_code = gp_camera_file_get( camera_, photo_file_path.folder, photo_file_path.name, GP_FILE_TYPE_NORMAL, photo_file, context_ );
669  if( error_code < GP_OK )
670  {
671  gp_file_unref( photo_file );
672  unlink( temp_file_name );
673  photo_reporter::error( "gp_camera_file_get()" );
674  gp_context_error( context_, "Could not get file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
675  return false;
676  }
677 
678  // delete image from camera's memory
679  error_code = gp_camera_file_delete( camera_, photo_file_path.folder, photo_file_path.name, context_ );
680  if( error_code < GP_OK )
681  {
682  unlink( temp_file_name );
683  photo_reporter::error( "gp_camera_file_delete()" );
684  gp_context_error( context_, "Could delete file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
685  gp_file_free( photo_file );
686  return false;
687  }
688 
689  // load image from temporary file
690  if( image->photo_image_read( std::string(temp_file_name) ) == true )
691  {
692  gp_file_free( photo_file );
693  unlink( temp_file_name );
694  return true;
695  }
696 
697  photo_reporter::error( "photo_image_read()" );
698  gp_file_free( photo_file );
699  unlink( temp_file_name );
700  return false;
701 }
702 
703 
704 
bool photo_camera_get_config(const std::string &, char **value)
f
bool photo_camera_capture(photo_image *image)
~photo_camera(void)
GPContext * photo_camera_create_context(void)
bool photo_camera_set_config(const std::string &param, const std::string &value)
XmlRpcServer s
void error(const std::string &function_name)
CameraList * getCameraList(void)
bool photo_image_read(const std::string &filename)
Definition: photo_image.cpp:97
bool photo_camera_open(photo_camera_list *list, int n)
int photo_camera_find_widget_by_name(std::string name, CameraWidget **child, CameraWidget **rootconfig)
void contextError(GPContext *context, const char *error_string, void *data)
GPPortInfo port_info_
CameraAbilities abilities_
bool photo_camera_capture_to_file(const std::string &filename)
bool photo_camera_check_toggle_value(const std::string &value_in, int *value_out)
bool photo_camera_close(void)
bool lookupAbilities(const std::string &model_name, CameraAbilities *abilities)
GPContext * context_
void contextStatus(GPContext *context, const char *status_string, void *data)
Camera * camera_
photo_camera(void)
bool lookupPortInfo(const std::string &port_name, GPPortInfo *port_info)


photo
Author(s): Benjamin Pitzer
autogenerated on Mon Feb 28 2022 23:12:30