00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <cstdio>
00038 #include <fcntl.h>
00039 #include <cstdlib>
00040 #include <cstring>
00041
00042 #include "photo/photo_reporter.hpp"
00043
00044 #include "photo/photo_camera.hpp"
00045
00046
00047 photo_camera::photo_camera( void ) :
00048 camera_(NULL),
00049 context_(NULL),
00050 mode_(DIRECT)
00051 {
00052
00053
00054 }
00055
00056 photo_camera::~photo_camera( void )
00057 {
00058 gp_camera_unref( camera_ );
00059 gp_context_unref( context_ );
00060 }
00061
00062
00063 GPContext* photo_camera::photo_camera_create_context( void )
00064 {
00065 context_ = gp_context_new();
00066
00067
00068 gp_context_set_error_func( context_, photo_reporter::contextError, NULL );
00069 gp_context_set_status_func( context_, photo_reporter::contextStatus, NULL );
00070 return context_;
00071 }
00072
00073
00074 bool photo_camera::photo_camera_open( photo_camera_list* list, const std::string model_name, const std::string port_name )
00075 {
00076
00077 if( context_ == NULL )
00078 {
00079 context_ = photo_camera_create_context();
00080 }
00081
00082
00083 if( gp_camera_new( &camera_ ) != GP_OK )
00084 {
00085 photo_reporter::error( "gp_camera_new()" );
00086 return false;
00087 }
00088
00089
00090
00091 if( list->lookupAbilities( model_name, &abilities_ ) == true )
00092 {
00093
00094 if( gp_camera_set_abilities( camera_, abilities_ ) != GP_OK )
00095 {
00096 photo_reporter::error( "gp_camera_set_abilities()" );
00097 return false;
00098 }
00099 }
00100 else
00101 {
00102 return false;
00103 }
00104
00105
00106 if( list->lookupPortInfo( port_name, &port_info_ ) == true )
00107 {
00108 if( gp_camera_set_port_info( camera_, port_info_ ) != GP_OK )
00109 {
00110 photo_reporter::error( "gp_camera_set_port_info()" );
00111 return false;
00112 }
00113 }
00114 else
00115 {
00116 return false;
00117 }
00118
00119
00120 return true;
00121 }
00122
00123
00124
00125 bool photo_camera::photo_camera_open( photo_camera_list* list, int n )
00126 {
00127 const char *name, *value;
00128
00129 gp_list_get_name( list->getCameraList(), n, &name);
00130 gp_list_get_value( list->getCameraList(), n, &value);
00131
00132 std::cout << "Opening camera " << n << " by name (" << name << ") and value (" << value << ")" << std::endl;
00133
00134 if( photo_camera_open( list, name, value ) == false )
00135 {
00136 photo_reporter::error( "photo_camera_open()" );
00137 return false;
00138 }
00139 return true;
00140 }
00141
00142
00143 bool photo_camera::photo_camera_close( void )
00144 {
00145 if( gp_camera_exit( camera_, context_ ) != GP_OK )
00146 {
00147 photo_reporter::error( "gp_camera_exit()", "Could not close photo_camera.");
00148 return false;
00149 }
00150 return true;
00151 }
00152
00153
00154
00155
00156 int photo_camera::photo_camera_find_widget_by_name( std::string name, CameraWidget **child, CameraWidget **root)
00157 {
00158 int error_code;
00159
00160
00161 error_code = gp_camera_get_config( camera_, root, context_ );
00162 if (error_code != GP_OK)
00163 {
00164 photo_reporter::error( "gp_camera_get_config()");
00165 return error_code;
00166 }
00167
00168
00169 if( gp_widget_get_child_by_name( *root, name.c_str(), child ) == GP_OK )
00170 {
00171 return GP_OK;
00172 }
00173
00174
00175 if( gp_widget_get_child_by_label( *root, name.c_str(), child ) == GP_OK )
00176 {
00177 return GP_OK;
00178 }
00179
00180
00181
00182 size_t found_index = name.length();
00183 while( found_index == name.length() )
00184 {
00185 found_index = name.rfind( '/' );
00186
00187 if( found_index == std::string::npos )
00188 {
00189 gp_context_error( context_,"%s not found in configuration tree.", name.c_str() );
00190 gp_widget_free( *root );
00191 return GP_ERROR;
00192 }
00193
00194 if( found_index == name.length() - 1 )
00195 {
00196 name = name.substr( 0, found_index );
00197 }
00198 }
00199 name = name.substr( found_index, name.length() - 1 );
00200
00201
00202 if( gp_widget_get_child_by_name( *root, name.c_str(), child ) == GP_OK )
00203 {
00204 return GP_OK;
00205 }
00206 if( gp_widget_get_child_by_label( *root, name.c_str(), child ) == GP_OK )
00207 {
00208 return GP_OK;
00209 }
00210
00211
00212 gp_context_error( context_, "%s not found in configuration tree.", name.c_str() );
00213 gp_widget_free( *root );
00214 return GP_ERROR;
00215 }
00216
00222 bool photo_camera::photo_camera_check_toggle_value( std::string value_in, bool* value_out )
00223 {
00224 std::string toggle_positive[] = { "on", "yes", "true", "ON", "YES", "TRUE"};
00225 std::string toggle_negative[] = { "off", "no", "false", "OFF", "NO", "FALSE" };
00226
00227
00228
00229 if( value_in.compare( "0" ) == 0 )
00230 {
00231 *value_out = false;
00232 return true;
00233 }
00234 if( value_in.compare( "0" ) == 0 )
00235 {
00236 *value_out = true;
00237 return true;
00238 }
00239
00240
00241 for( int i = 0; i < 6; i++ )
00242 {
00243 if( value_in.compare( toggle_positive[i] ) == 0 )
00244 {
00245 *value_out = true;
00246 return true;
00247 }
00248 }
00249
00250
00251 for( int i = 0; i < 6; i++ )
00252 {
00253 if( value_in.compare( toggle_negative[i] ) == 0 )
00254 {
00255 *value_out = false;
00256 return true;
00257 }
00258 }
00259 return false;
00260 }
00261
00262
00263
00264 bool photo_camera::photo_camera_set_config( std::string param, std::string value )
00265 {
00266 CameraWidget *root, *child;
00267 int error_code;
00268 const char *label;
00269 CameraWidgetType type;
00270
00271
00272 if( photo_camera_find_widget_by_name( param, &child, &root ) != GP_OK )
00273 {
00274 photo_reporter::error( "photo_camera_find_widget_by_name()");
00275 return false;
00276 }
00277
00278
00279 if( gp_widget_get_label(child, &label) != GP_OK )
00280 {
00281 photo_reporter::error( "gp_widget_get_label()");
00282 gp_widget_free( root );
00283 return false;
00284 }
00285
00286
00287 if( gp_widget_get_type( child, &type ) != GP_OK )
00288 {
00289 photo_reporter::error( "gp_widget_get_type()");
00290 gp_widget_free( root );
00291 return false;
00292 }
00293
00294 switch( type )
00295 {
00296
00297 case GP_WIDGET_TEXT:
00298 if( gp_widget_set_value(child, value.c_str()) != GP_OK )
00299 {
00300 photo_reporter::error( "gp_widget_set_value()");
00301 gp_context_error( context_, "Failed to set the value of text widget %s to %s.", param.c_str(), value.c_str() );
00302 gp_widget_free( root );
00303 return false;
00304 }
00305 break;
00306
00307 case GP_WIDGET_RANGE:
00308 float f, t, b, s;
00309
00310 if( gp_widget_get_range( child, &b, &t, &s) != GP_OK )
00311 {
00312 photo_reporter::error( "gp_widget_get_range()" );
00313 gp_widget_free( root );
00314 return false;
00315 }
00316 if( !sscanf( value.c_str(), "%f", &f ) )
00317 {
00318 gp_context_error( context_, "The passed value %s is not a floating point value.", value.c_str() );
00319 gp_widget_free( root );
00320 return false;
00321 }
00322 if( (f < b) || (f > t) )
00323 {
00324 gp_context_error( context_ , "The passed value %f is not within the expected range of %f -- %f.", f, b, t );
00325 gp_widget_free( root );
00326 return false;
00327 }
00328 if( gp_widget_set_value( child, &f ) != GP_OK )
00329 {
00330 photo_reporter::error( "gp_widget_set_value()" );
00331 gp_context_error( context_, "Failed to set the value of range widget %s to %f.", param.c_str(), f );
00332 gp_widget_free( root );
00333 return false;
00334 }
00335 break;
00336
00337 case GP_WIDGET_TOGGLE:
00338 bool tog;
00339 if( photo_camera_check_toggle_value( value, &tog ) == false )
00340 {
00341 gp_context_error(context_, "The passed value %s is not a valid toggle value.", value.c_str() );
00342 gp_widget_free( root );
00343 return false;
00344 }
00345 if( gp_widget_set_value( child, &tog ) != GP_OK )
00346 {
00347 photo_reporter::error( "gp_widget_set_value()" );
00348 gp_context_error( context_, "Failed to set values %s of toggle widget %s.", value.c_str(), param.c_str() );
00349 gp_widget_free( root );
00350 return false;
00351 }
00352 break;
00353
00354 case GP_WIDGET_DATE:
00355 {
00356 int time = -1;
00357 #ifdef HAVE_STRPTIME
00358 struct tm xtm;
00359
00360 if( strptime( value.c_str(), "%c", &xtm ) || strptime( value.c_str(), "%Ec", &xtm ) )
00361 {
00362 time = mktime( &xtm );
00363 }
00364 #endif
00365 if( time == -1 )
00366 {
00367 if( !sscanf( value.c_str(), "%d", &time ) )
00368 {
00369 gp_context_error( context_, "The passed value %s is neither a valid time nor an integer.", value.c_str() );
00370 gp_widget_free( root );
00371 return false;
00372 }
00373 }
00374 if( gp_widget_set_value(child, &time) != GP_OK )
00375 {
00376 photo_reporter::error( "gp_widget_set_value()" );
00377 gp_context_error( context_, "Failed to set new time of date/time widget %s to %s.", param.c_str(), value.c_str() );
00378 gp_widget_free( root );
00379 return false;
00380 }
00381 break;
00382 }
00383
00384 case GP_WIDGET_MENU:
00385 case GP_WIDGET_RADIO:
00386 int count, i;
00387 count = gp_widget_count_choices( child );
00388 if( count < GP_OK )
00389 {
00390 photo_reporter::error( "gp_widget_count_choices()" );
00391 gp_widget_free( root );
00392 return false;
00393 }
00394
00395 error_code = GP_ERROR_BAD_PARAMETERS;
00396 for( i = 0; i < count; i++ )
00397 {
00398 const char *choice;
00399 if( gp_widget_get_choice( child, i, &choice ) == GP_OK )
00400 {
00401 if( value.compare( choice ) == 0 )
00402 {
00403 if( gp_widget_set_value( child, value.c_str() ) == GP_OK )
00404 {
00405 break;
00406 }
00407 }
00408 }
00409 }
00410
00411 if( sscanf( value.c_str(), "%d", &i ) )
00412 {
00413 if( (i >= 0) && (i < count) )
00414 {
00415 const char *choice;
00416 if( gp_widget_get_choice( child, i, &choice ) == GP_OK )
00417 {
00418 if( gp_widget_set_value( child, choice ) == GP_OK )
00419 {
00420 break;
00421 }
00422 }
00423 }
00424 }
00425 gp_context_error( context_, "Choice %s not found within list of choices.", value.c_str() );
00426 gp_widget_free( root );
00427 return false;
00428
00429 case GP_WIDGET_WINDOW:
00430 case GP_WIDGET_SECTION:
00431 case GP_WIDGET_BUTTON:
00432 default:
00433 gp_context_error( context_,"The %s widget is not configurable.", param.c_str() );
00434 gp_widget_free( root );
00435 return false;
00436 }
00437
00438
00439
00440 if( gp_camera_set_config( camera_, root, context_ ) != GP_OK )
00441 {
00442 photo_reporter::error( "gp_camera_set_config()" );
00443 gp_context_error( context_, "Failed to set new configuration value %s for configuration entry %s.", value.c_str(), param.c_str() );
00444 gp_widget_free( root );
00445 return false;
00446 }
00447
00448 gp_widget_free( root );
00449 return true;
00450 }
00451
00452
00453
00454 bool photo_camera::photo_camera_get_config( std::string param, char** value )
00455 {
00456 CameraWidget *root, *child;
00457 const char *label;
00458 CameraWidgetType type;
00459
00460
00461 if( photo_camera_find_widget_by_name( param, &child, &root ) != GP_OK )
00462 {
00463 photo_reporter::error( "photo_camera_find_widget_by_name()");
00464 return false;
00465 }
00466
00467
00468 if( gp_widget_get_label(child, &label) != GP_OK )
00469 {
00470 photo_reporter::error( "gp_widget_get_label()");
00471 gp_widget_free( root );
00472 return false;
00473 }
00474
00475
00476 if( gp_widget_get_type( child, &type ) != GP_OK )
00477 {
00478 photo_reporter::error( "gp_widget_get_type()");
00479 gp_widget_free( root );
00480 return false;
00481 }
00482
00483 switch( type )
00484 {
00485 case GP_WIDGET_TEXT:
00486 char *txt;
00487 if( gp_widget_get_value( child, &txt ) != GP_OK )
00488 {
00489 gp_context_error( context_, "Failed to retrieve value of text widget %s.", param.c_str() );
00490 }
00491 *value = txt;
00492 break;
00493
00494 case GP_WIDGET_RANGE:
00495 float f, t,b,s;
00496 if( gp_widget_get_range( child, &b, &t, &s ) != GP_OK )
00497 {
00498 gp_context_error( context_, "Failed to retrieve values of range widget %s.", param.c_str() );
00499 }
00500 if( gp_widget_get_value( child, &f ) != GP_OK )
00501 {
00502 gp_context_error( context_, "Failed to value of range widget %s.", param.c_str() );
00503 }
00504 sprintf( *value, "%f", f );
00505 break;
00506
00507 case GP_WIDGET_TOGGLE:
00508 {
00509 int t;
00510 if( gp_widget_get_value( child, &t ) != GP_OK )
00511 {
00512 gp_context_error( context_,"Failed to retrieve values of toggle widget %s.", param.c_str() );
00513 }
00514 sprintf( *value, "%d", t );
00515 break;
00516 }
00517
00518 case GP_WIDGET_DATE:
00519 {
00520 int error_code, t;
00521 time_t working_time;
00522 struct tm *localtm;
00523 char timebuf[200];
00524
00525 if( gp_widget_get_value( child, &t ) != GP_OK )
00526 {
00527 gp_context_error( context_,"Failed to retrieve values of date/time widget %s.", param.c_str() );
00528 break;
00529 }
00530 working_time = t;
00531 localtm = localtime( &working_time );
00532 error_code = strftime( timebuf, sizeof(timebuf), "%c", localtm );
00533 sprintf( *value, "%s", timebuf );
00534 break;
00535 }
00536
00537 case GP_WIDGET_MENU:
00538 case GP_WIDGET_RADIO:
00539 char *current;
00540 if( gp_widget_get_value (child, ¤t) != GP_OK )
00541 {
00542 gp_context_error( context_,"Failed to retrieve values of radio widget %s.", param.c_str() );
00543 }
00544 sprintf( *value, "%s", current );
00545 break;
00546
00547
00548 case GP_WIDGET_WINDOW:
00549 case GP_WIDGET_SECTION:
00550 case GP_WIDGET_BUTTON:
00551 default:
00552 break;
00553 }
00554
00555 gp_widget_free( root );
00556 return true;
00557 }
00558
00559
00560 bool photo_camera::photo_camera_capture_to_file( std::string filename )
00561 {
00562 int fd, error_code;
00563 CameraFile *photo_file;
00564 CameraFilePath photo_file_path;
00565
00566
00567 strcpy( photo_file_path.folder, "/");
00568 strcpy( photo_file_path.name, "foo.jpg");
00569
00570 error_code = gp_camera_capture( camera_, GP_CAPTURE_IMAGE, &photo_file_path, context_ );
00571 if( error_code < GP_OK )
00572 {
00573 photo_reporter::error( "gp_camera_capture()" );
00574 gp_context_error( context_, "Could not capture image (error code %d)\n", error_code );
00575 return false;
00576 }
00577
00578 fd = open( filename.c_str(), O_CREAT|O_WRONLY, 0644 );
00579 error_code = gp_file_new_from_fd( &photo_file, fd );
00580 if( error_code < GP_OK )
00581 {
00582 photo_reporter::error( "gp_file_new_from_fd()" );
00583 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 );
00584 gp_file_free( photo_file );
00585 return false;
00586 }
00587
00588 error_code = gp_camera_file_get( camera_, photo_file_path.folder, photo_file_path.name, GP_FILE_TYPE_NORMAL, photo_file, context_ );
00589 if( error_code < GP_OK )
00590 {
00591 photo_reporter::error( "gp_camera_file_get()" );
00592 gp_context_error( context_, "Could not get file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
00593 gp_file_free( photo_file );
00594 return false;
00595 }
00596
00597 error_code = gp_camera_file_delete( camera_, photo_file_path.folder, photo_file_path.name, context_ );
00598 if( error_code < GP_OK )
00599 {
00600 photo_reporter::error( "gp_camera_file_delete()" );
00601 gp_context_error( context_, "Could delete file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
00602 gp_file_free( photo_file );
00603 return false;
00604 }
00605
00606 gp_file_free( photo_file );
00607 return true;
00608 }
00609
00610
00611 bool photo_camera::photo_camera_capture( photo_image* image )
00612 {
00613 int fd, error_code;
00614 CameraFile *photo_file;
00615 CameraFilePath photo_file_path;
00616 char temp_file_name[20];
00617
00618
00619 strcpy( photo_file_path.folder, "/" );
00620 strcpy( photo_file_path.name, "foo.jpg" );
00621
00622 error_code = gp_camera_capture( camera_, GP_CAPTURE_IMAGE, &photo_file_path, context_ );
00623 if( error_code < GP_OK )
00624 {
00625 photo_reporter::error( "gp_camera_capture()" );
00626 gp_context_error( context_, "Could not capture image (error code %d)\n", error_code );
00627 return false;
00628 }
00629
00630
00631 strcpy( temp_file_name, "tmpfileXXXXXX" );
00632 fd = mkstemp( temp_file_name );
00633 error_code = gp_file_new_from_fd( &photo_file, fd );
00634 if( error_code < GP_OK )
00635 {
00636 close( fd );
00637 unlink( temp_file_name );
00638
00639 photo_reporter::error( "gp_file_new_from_fd()" );
00640 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 );
00641 gp_file_free( photo_file );
00642 return false;
00643 }
00644
00645
00646 error_code = gp_camera_file_get( camera_, photo_file_path.folder, photo_file_path.name, GP_FILE_TYPE_NORMAL, photo_file, context_ );
00647 if( error_code < GP_OK )
00648 {
00649 gp_file_unref( photo_file );
00650 unlink( temp_file_name );
00651 photo_reporter::error( "gp_camera_file_get()" );
00652 gp_context_error( context_, "Could not get file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
00653 return false;
00654 }
00655
00656
00657 error_code = gp_camera_file_delete( camera_, photo_file_path.folder, photo_file_path.name, context_ );
00658 if( error_code < GP_OK )
00659 {
00660 unlink( temp_file_name );
00661 photo_reporter::error( "gp_camera_file_delete()" );
00662 gp_context_error( context_, "Could delete file %s%s (error code %d)\n", photo_file_path.folder, photo_file_path.name, error_code );
00663 gp_file_free( photo_file );
00664 return false;
00665 }
00666
00667
00668 if( image->photo_image_read( std::string(temp_file_name) ) == true )
00669 {
00670 gp_file_free( photo_file );
00671 unlink( temp_file_name );
00672 return true;
00673 }
00674
00675 photo_reporter::error( "photo_image_read()" );
00676 gp_file_free( photo_file );
00677 unlink( temp_file_name );
00678 return false;
00679 }
00680
00681
00682