photo_camera.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2012, Robert Bosch LLC.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the Robert Bosch nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *********************************************************************/
00036 
00037 #include <cstdio>  // sscanf, printf, etc.
00038 #include <fcntl.h> // C file I/O
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   //port_info_(NULL);
00053   //abilities_(NULL);
00054 }
00055 
00056 photo_camera::~photo_camera( void )
00057 {
00058   gp_camera_unref( camera_ ); //delete camera_;
00059   gp_context_unref( context_ ); //delete context_;
00060 }
00061 
00062 
00063 GPContext* photo_camera::photo_camera_create_context( void )
00064 {
00065   context_ = gp_context_new();
00066 
00067   // Optional debugging and status output
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   // Create a context if necessary
00077   if( context_ == NULL )
00078   {
00079     context_ = photo_camera_create_context();
00080   }
00081 
00082   // Create new camera
00083   if( gp_camera_new( &camera_ ) != GP_OK )
00084   {
00085     photo_reporter::error( "gp_camera_new()" );
00086     return false;
00087   }
00088 
00089   // Find and set camera abilities based on model
00090   //std::cout << "Model name: " << model_name << " == " << std::endl;
00091   if( list->lookupAbilities( model_name, &abilities_ ) == true )
00092   {
00093     // Set the camera's abilities
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   // Associate camera with port
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   // Camera is open!
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   // Get camera configuration
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   // Find child of configuration by name
00169   if( gp_widget_get_child_by_name( *root, name.c_str(), child ) == GP_OK )
00170   {
00171     return GP_OK;
00172   }
00173 
00174   // Find child of configuration  by label
00175   if( gp_widget_get_child_by_label( *root, name.c_str(), child ) == GP_OK )
00176   {
00177     return GP_OK;
00178   }
00179 
00180   // If full name is not found, search for last subname.
00181   // name delimeter is '/'
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 ) // No subname, we already failed this search above
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 ) // end of string, cut it off
00195     {
00196       name = name.substr( 0, found_index );
00197     }
00198   }
00199   name = name.substr( found_index, name.length() - 1 );
00200 
00201   // Find child using 
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   // all matches have failed
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   // first check numeric values: "1" and "0"
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   // check values in toggle_positive
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   // check values in toggle_negative
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   // Locate the widget that corresponds to this parameter
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   // Get the widget label
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   // Get the widget type
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: // char*
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: // float
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: // int
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: // int
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: // char*
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     // attemt a different method for setting a radio button
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   // Configuration parameters are correct, so set the camera
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   // Locate the widget that corresponds to this parameter
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   // Get the widget label
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   // Get the widget type
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: // char*
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: // float
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: // int
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: // int
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: //char*
00539     char *current;
00540     if( gp_widget_get_value (child, &current) != 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   // No values, so nothing to return
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   // NOP: This gets overridden in the library to /capt0000.jpg
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   // NOP: This gets overridden in the library to /capt0000.jpg
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   // create temporary file
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   // get image from camera and store in temporary file
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   // delete image from camera's memory
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   // load image from temporary file
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 


photo
Author(s): Benjamin Pitzer
autogenerated on Mon Oct 6 2014 10:09:43