23#include <core/exceptions/software.h>
24#include <core/threading/mutex.h>
25#include <core/threading/wait_condition.h>
26#include <fvutils/color/colorspaces.h>
27#include <fvutils/colormap/cmfile.h>
28#include <fvutils/colormap/yuvcm.h>
29#include <fvutils/net/fuse.h>
30#include <fvutils/net/fuse_client.h>
31#include <fvutils/net/fuse_client_handler.h>
32#include <fvutils/net/fuse_image_content.h>
33#include <fvutils/net/fuse_imagelist_content.h>
34#include <fvutils/net/fuse_lut_content.h>
35#include <fvutils/net/fuse_lutlist_content.h>
36#include <fvutils/net/fuse_message.h>
37#include <fvutils/writers/fvraw.h>
38#include <netcomm/service_discovery/browse_handler.h>
39#include <utils/system/argparser.h>
40#include <utils/system/console_colors.h>
42# include <netcomm/dns-sd/avahi_thread.h>
47#include <netinet/in.h>
54using namespace firevision;
67 explore_waitcond_ = NULL;
73 printf(
"Invalid version received (local: %u, remote: %u)\n", local_version, remote_version);
96 if (ic->
format() == FUSE_IF_RAW) {
104 }
else if (ic->
format() == FUSE_IF_JPEG) {
105 FILE *f = fopen(file_,
"w");
107 printf(
"Failed to write data to file");
111 printf(
"Image of unknown format (%u) received.\n", ic->
format());
115 printf(
"Received message cannot be casted to FuseImageMessage\n");
120 case FUSE_MT_IMAGE_LIST:
124 printf(
"Available images:\n");
127 char tmp[IMAGE_ID_MAX_LENGTH + 1];
128 tmp[IMAGE_ID_MAX_LENGTH] = 0;
129 strncpy(tmp, ii->
image_id, IMAGE_ID_MAX_LENGTH);
130 printf(
" %s (%u x %u, %s)\n",
134 colorspace_to_string((colorspace_t)ntohs(ii->
colorspace)));
137 printf(
"No images available\n");
141 printf(
"Received message cannot be casted to FuseImageListMessage\n");
145 case FUSE_MT_LUT_LIST:
149 printf(
"Available lookup tables:\n");
152 char tmp[LUT_ID_MAX_LENGTH + 1];
153 tmp[LUT_ID_MAX_LENGTH] = 0;
154 strncpy(tmp, li->
lut_id, LUT_ID_MAX_LENGTH);
155 printf(
" %s (%u x %u x %u, %u bpc)\n",
163 printf(
"No lookup tables available\n");
167 printf(
"Received message cannot be casted to FuseImageListMessage\n");
178 if (lc->
width() != 256) {
179 printf(
"Invalid dimensions for LUT received, colormap width %u != 256", lc->
width());
180 }
else if (lc->
height() != 256) {
181 printf(
"Invalid dimensions for LUT received, colormap height %u != 256", lc->
height());
182 }
else if (lc->
depth() > 256) {
183 printf(
"Invalid dimensions for LUT received, colormap depth %u > 256", lc->
depth());
192 e.
append(
"Failed to save colormap");
198 printf(
"Received message cannot be casted to FuseLutMessage\n");
204 case FUSE_MT_SET_LUT_SUCCEEDED: {
206 char lut_id[LUT_ID_MAX_LENGTH + 1];
207 lut_id[LUT_ID_MAX_LENGTH] = 0;
208 strncpy(lut_id, lutdesc->
lut_id, LUT_ID_MAX_LENGTH);
209 printf(
"LUT %s has been uploaded successfully.\n", lut_id);
213 case FUSE_MT_SET_LUT_FAILED: {
215 char lut_id[LUT_ID_MAX_LENGTH + 1];
216 lut_id[LUT_ID_MAX_LENGTH] = 0;
217 strncpy(lut_id, lutdesc->
lut_id, LUT_ID_MAX_LENGTH);
218 printf(
"LUT upload of %s has failed.\n", lut_id);
223 printf(
"Unhandled message of type %u received\n", m->type());
232 printf(
"All for now\n");
233 explore_mutex_->
lock();
246 printf(
"Browsing for %s failed\n", type);
253 const char * host_name,
254 const char * interface,
255 const struct sockaddr * addr,
256 const socklen_t addr_size,
258 std::list<std::string> &txt,
261 struct sockaddr_in *s;
262 if (addr_size ==
sizeof(
struct sockaddr_in)) {
263 s = (
struct sockaddr_in *)addr;
265 printf(
"%s socket data not IPv4, ignoring\n", name);
269 char addrp[INET_ADDRSTRLEN];
270 inet_ntop(AF_INET, &(s->sin_addr), addrp,
sizeof(addrp));
272 "Found %s%s%s (%s/%s on %hu), querying\n", c_blue, name, c_normal, host_name, addrp, port);
274 client_ =
new FuseClient(host_name, port,
this);
294 printf(
"Usage: %s -i/-c/-C/-s/-e [-n host[:port]/id file]\n"
296 " -j Get JPEG-compressed image\n"
298 " -C Set colormap from file\n"
299 " -s Show available images and LUTs\n"
300 " -e Explore network. Will query all instances of Fountain\n"
301 " found on the network for all available images and LUTs.\n"
302 " -n net_string Open network camera, the camera string is of the form\n"
303 " host[:port]/id. You have to specify at least the host\n"
304 " and the id, the port is optional and defaults to 5000\n"
305 " Depending on the operation id is the image or the LUT ID\n"
306 " file File to write incoming data to or to read data to send from\n",
320 strncpy(idm->
image_id, image_id, IMAGE_ID_MAX_LENGTH - 1);
321 idm->
format = (jpeg ? FUSE_IF_JPEG : FUSE_IF_RAW);
333 strncpy(ldm->
lut_id, lut_id, LUT_ID_MAX_LENGTH - 1);
361 client_->
enqueue(FUSE_MT_GET_IMAGE_LIST);
362 client_->
enqueue(FUSE_MT_GET_LUT_LIST);
375 explore_mutex_ =
new Mutex();
378 explore_mutex_->
lock();
381 avahi_thread_->start();
383 avahi_thread_->watch_service(
"_fountain._tcp",
this);
385 explore_waitcond_->
wait();
386 delete explore_waitcond_;
388 delete explore_mutex_;
389 avahi_thread_->cancel();
390 avahi_thread_->join();
391 delete avahi_thread_;
393 printf(
"\nExploration is not available because Avahi support is missing. "
394 "Install avahi-devel and recompile.\n\n");
408 net_string = strdup(argp_->
arg(
"n"));
410 net_string = strdup(
"localhost");
415 char *save_ptr = NULL;
419 hostport = strtok_r(net_string,
"/", &save_ptr);
420 id = strtok_r(NULL,
"", &save_ptr);
422 if (strchr(hostport,
':') != NULL) {
423 host = strtok_r(hostport,
":", &save_ptr);
424 port = strtok_r(NULL,
"", &save_ptr);
430 port_num = atoi(port);
431 if ((port_num < 0) || (port_num > 0xFFFF)) {
440 printf(
"\nFile name missing\n\n");
443 file_ = argp_->
items()[0];
448 printf(
"\nNo Image/LUT ID given, needed for -i/-c/-C\n\n");
454 client_ =
new FuseClient(host, port_num,
this);
462 }
else if (argp_->
has_arg(
"j")) {
464 }
else if (argp_->
has_arg(
"c")) {
466 }
else if (argp_->
has_arg(
"C")) {
468 }
else if (argp_->
has_arg(
"s")) {
470 }
else if (argp_->
has_arg(
"e")) {
493 Mutex * explore_mutex_;
502main(
int argc,
char **argv)
Parse command line arguments.
const char * program_name() const
Get name of program.
const std::vector< const char * > & items() const
Get non-option items.
const char * arg(const char *argn)
Get argument value.
std::vector< constchar * >::size_type num_items() const
Get number of non-option items.
bool has_arg(const char *argn)
Check if argument has been supplied.
Base class for exceptions in Fawkes.
void print_trace() noexcept
Prints trace to stderr.
void append(const char *format,...) noexcept
Append messages to the message list.
Mutex mutual exclusion lock.
void lock()
Lock this mutex.
void unlock()
Unlock the mutex.
Interface for class that process browse results.
void start(bool wait=true)
Call this method to start the thread.
void join()
Join the thread.
void cancel()
Cancel a thread.
Wait until a given condition holds.
void wait()
Wait for the condition forever.
void wake_all()
Wake up all waiting threads.
Colormap * get_colormap()
Get a freshly generated colormap based on current file content.
void add_colormap(Colormap *colormap)
Add colormap.
virtual unsigned int depth() const =0
Get depth of colormap.
virtual unsigned char * get_buffer() const =0
Get the raw buffer of this colormap.
virtual unsigned int height() const =0
Get height of colormap.
virtual unsigned int width() const =0
Get width of colormap.
virtual void read(const char *file_name)
Read file.
virtual void write(const char *file_name)
Write file.
void wait_greeting()
Wait for greeting message.
void enqueue(FuseNetworkMessage *m)
Enqueue message.
unsigned int format() const
Get image format.
size_t buffer_size() const
Get size of buffer.
unsigned int colorspace() const
Get colorspace.
unsigned char * buffer() const
Image buffer.
unsigned int pixel_height() const
Get image height.
unsigned int pixel_width() const
Get image width.
bool has_next()
Check if another image info is available.
FUSE_imageinfo_t * next()
Get next image info.
FUSE lookup table content.
unsigned char * buffer() const
Get buffer.
unsigned int height() const
Height of LUT.
unsigned int depth() const
Depth of LUT.
unsigned int width() const
Width of LUT.
FUSE lookup table list content.
bool has_next()
Check if another LUT info is available.
FUSE_lutinfo_t * next()
Get next LUT info.
FvRaw Writer implementation.
virtual void write()
Write to file.
virtual void set(unsigned int y, unsigned int u, unsigned int v, color_t c)
Set color class for given YUV value.
Fawkes library namespace.
uint32_t colorspace
color space
uint32_t height
height in pixels
uint32_t width
width in pixels
char image_id[IMAGE_ID_MAX_LENGTH]
image ID
char image_id[IMAGE_ID_MAX_LENGTH]
image ID
uint32_t format
requested image format, see FUSE_image_format_t
char lut_id[LUT_ID_MAX_LENGTH]
LUT ID.
uint32_t height
height of LUT
uint32_t bytes_per_cell
bytes per cell
uint32_t width
width of LUT
uint32_t depth
depth of LUT
char lut_id[LUT_ID_MAX_LENGTH]
LUT ID.