Fawkes API  Fawkes Development Version
scaled_viewer.cpp
00001 
00002 /***************************************************************************
00003  *  scale_viewer.cpp - Generic scale viewer tool
00004  *
00005  *  Created: Thu Aug 25 16:13:34 2011 (based on fvviewer)
00006  *  Copyright  2005-2011  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 
00024 #include <core/exceptions/software.h>
00025 #include <utils/system/argparser.h>
00026 #include <utils/time/tracker.h>
00027 
00028 #include <fvcams/factory.h>
00029 #ifdef HAVE_SHMEM_CAM
00030 #include <fvcams/shmem.h>
00031 #endif
00032 #ifdef HAVE_NETWORK_CAM
00033 #include <fvcams/net.h>
00034 #endif
00035 #ifdef HAVE_FILELOADER_CAM
00036 #include <fvcams/fileloader.h>
00037 #endif
00038 
00039 #include <cstring>
00040 #include <cstdio>
00041 #include <stdint.h>
00042 
00043 #include <gtkmm.h>
00044 
00045 #include <fvutils/color/conversions.h>
00046 
00047 using namespace fawkes;
00048 using namespace firevision;
00049 
00050 Gtk::Image *img_image;
00051 Camera     *cam;
00052 
00053 TimeTracker tt;
00054 int ttc_capture;
00055 int ttc_convert;
00056 int ttc_draw;
00057 int ttc_interloop;
00058 unsigned int loop_count = 0;
00059 
00060 static bool
00061 timeout_handler()
00062 {
00063   tt.ping_end(ttc_interloop);
00064 
00065   tt.ping_start(ttc_capture);
00066   cam->capture();
00067   tt.ping_end(ttc_capture);
00068 
00069   tt.ping_start(ttc_convert);
00070   unsigned int orig_width  = cam->pixel_width();
00071   unsigned int orig_height = cam->pixel_height();
00072 
00073   unsigned char *rgb_buffer = malloc_buffer(RGB, orig_width, orig_height);
00074 
00075   convert(cam->colorspace(), RGB, cam->buffer(), rgb_buffer,
00076           orig_width, orig_height);
00077   tt.ping_end(ttc_convert);
00078 
00079   tt.ping_start(ttc_draw);
00080   Glib::RefPtr<Gdk::Pixbuf> image =
00081     Gdk::Pixbuf::create_from_data( rgb_buffer, Gdk::COLORSPACE_RGB, false,
00082                                    8, orig_width, orig_height, 3 * orig_width);
00083 
00084   int width = img_image->get_width();
00085   int height = img_image->get_height();
00086   Glib::RefPtr<Gdk::Pixbuf> scaled = image->scale_simple(width, height,
00087                                                          Gdk::INTERP_NEAREST);
00088 
00089   img_image->set(scaled);
00090   img_image->queue_draw();
00091 
00092   tt.ping_end(ttc_draw);
00093 
00094   cam->dispose_buffer();
00095 
00096   free(rgb_buffer);
00097 
00098   if (++loop_count >= 10) {
00099     loop_count = 0;
00100     tt.print_to_stdout();
00101   }
00102 
00103   tt.ping_start(ttc_interloop);
00104   return true;
00105 }
00106 
00107 
00108 
00109 void
00110 print_usage(const char *program_name)
00111 {
00112   printf("Usage: %s -n host[:port]/image_id [-j] [-d delay] [-v]\n\n"
00113          "  -n net_string  Open network camera, the camera string is of the form\n"
00114          "                 host[:port]/image_id. You have to specify at least the host\n"
00115          "                 and the image_id, the port is optional and defaults to 5000\n"
00116          "  -j             Receive JPEG images, only valid with -n\n"
00117          "  -d delay       Delay in ms before a new image is capture.\n",
00118          program_name);
00119 }
00120 
00121 
00122 
00123 int
00124 main(int argc, char **argv)
00125 {
00126   ArgumentParser argp(argc, argv, "hn:jd:");
00127 
00128   Gtk::Main gtk_main(argc, argv);
00129 
00130   //bool verbose = argp.has_arg("v");
00131   int delay = 300;
00132 
00133   if ( argp.has_arg("d") ) {
00134     delay = atoi(argp.arg("d"));
00135     if ( delay < 0 )  delay = 300;
00136   }
00137 
00138   if ( argp.has_arg("h") ) {
00139     print_usage(argp.program_name());
00140     exit(0);
00141   } else if ( argp.has_arg("n") ) {
00142     char *net_string = strdup(argp.arg("n"));
00143     char *image_id = NULL, *host = NULL, *port = NULL, *save_ptr = NULL;
00144     int port_num = 2208;
00145     char *hostport;
00146 
00147     hostport = strtok_r(net_string, "/", &save_ptr);
00148     image_id = strtok_r(NULL, "", &save_ptr);
00149 
00150     if ( strchr(hostport, ':') != NULL ) {
00151       host = strtok_r(hostport, ":", &save_ptr);
00152       port = strtok_r(NULL, "", &save_ptr);
00153     } else {
00154       host = hostport;
00155     }
00156 
00157     if ( port != NULL ) {
00158       port_num = atoi(port);
00159       if ( (port_num < 0) || (port_num > 0xFFFF) ) {
00160         throw OutOfBoundsException("Invalid port", port_num, 0, 0xFFFF);
00161       }
00162     }
00163 
00164     if( image_id == NULL ) {
00165       throw IllegalArgumentException("Image ID must be specified");
00166     }
00167 
00168     cam = new NetworkCamera(host, port_num, image_id, argp.has_arg("j"));
00169     free(net_string);
00170   } else {
00171     print_usage(argp.program_name());
00172     exit(1);
00173   }  
00174 
00175   try {
00176     cam->open();
00177     cam->start();
00178   } catch (Exception &e) {
00179     printf("Failed to open camera\n");
00180     e.print_trace();
00181     delete cam;
00182     exit(-2);
00183   }
00184 
00185   ttc_capture   = tt.add_class("Capture");
00186   ttc_convert   = tt.add_class("Convert");
00187   ttc_draw      = tt.add_class("Draw");
00188   ttc_interloop = tt.add_class("InterLoop");
00189   tt.ping_start(ttc_interloop);
00190 
00191   Glib::RefPtr<Gtk::Builder> builder;
00192   builder =
00193     Gtk::Builder::create_from_file(RESDIR"/guis/scale_viewer/scale_viewer.ui");
00194 
00195   Gtk::Window *window;
00196 
00197   builder->get_widget("wnd_main", window);
00198   builder->get_widget("img_image", img_image);
00199 
00200   Glib::signal_timeout().connect(sigc::ptr_fun(&timeout_handler), delay);
00201 
00202   window->set_size_request(320, 240);
00203   Gtk::Main::run(*window);
00204 
00205   cam->close();
00206   delete cam;
00207 
00208   return 0;
00209 }
00210