int main(int argc, char *argv[]) { /* current configuration */ LedPrefs *p = NULL; /** current setup */ LedSetup *s = NULL; /** list of LED hardware adapters */ LedHardware *hw = NULL; /* input pixel-frame buffer */ LedFrame *frame = NULL; /** width of map */ LedFrameCord width; /** height of map */ LedFrameCord height; /* check libniftyled binary version compatibility */ NFT_LED_CHECK_VERSION /* set default loglevel to INFO */ nft_log_level_set(L_INFO); /* initialize exit handlers */ #if WIN32 int signals[] = { SIGINT, SIGABRT }; #else int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT }; #endif unsigned int i; for(i=0; i<sizeof(signals)/sizeof(int); i++) { if(signal(signals[i], _exit_signal_handler) == SIG_ERR) { NFT_LOG_PERROR("signal()"); return -1; } } /* default result of main() function */ int res = -1; /* default fps */ _c.fps = 25; /* default endianess */ _c.is_big_endian = FALSE; #if HAVE_IMAGEMAGICK == 1 /* default handle-input-as-raw */ _c.raw = FALSE; #endif /* default looping */ _c.do_loop = FALSE; /* set "running" flag */ _c.running = TRUE; /* default pixel-format */ strncpy(_c.pixelformat, "RGB u8", sizeof(_c.pixelformat)); /* default prefs-filename */ if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcat.xml")) return -1; /* parse commandline arguments */ if(!_parse_args(argc, argv)) return -1; /* print welcome msg */ NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcat_version_long()); NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get())); #if HAVE_IMAGEMAGICK == 1 /* initialize imagemagick */ if(!_c.raw) { if(!im_init(&_c)) { NFT_LOG(L_ERROR, "Failed to initialize ImageMagick"); return -1; } } #endif /* initialize preferences context */ if(!(p = led_prefs_init())) return -1; /* parse prefs-file */ LedPrefsNode *pnode; if(!(pnode = led_prefs_node_from_file(_c.prefsfile))) { NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"", _c.prefsfile); goto m_deinit; } /* create setup from prefs-node */ if(!(s = led_prefs_setup_from_node(p, pnode))) { NFT_LOG(L_ERROR, "No valid setup found in preferences file."); led_prefs_node_free(pnode); goto m_deinit; } /* free preferences node */ led_prefs_node_free(pnode); /* determine width of input-frames */ if(!_c.width) /* width of mapped chain */ width = led_setup_get_width(s); else /* use value from cmdline arguments */ width = _c.width; /* determine height of input-frames */ if(!_c.height) /* height of mapped chain */ height = led_setup_get_height(s); else height = _c.height; /* validate dimensions */ if(width <= 0 || height <= 0) { NFT_LOG(L_ERROR, "Dimensions %dx%d not possible in this universe. Exiting.", width, height); goto m_deinit; } /* allocate frame (where our pixelbuffer resides) */ NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)", width, height, _c.pixelformat); LedPixelFormat *format = led_pixel_format_from_string(_c.pixelformat); if(!(frame = led_frame_new(width, height, format))) goto m_deinit; /* get first toplevel hardware */ if(!(hw = led_setup_get_hardware(s))) goto m_deinit; /* initialize hardware */ /*if(!(led_hardware_init(hw, ledcount, (LedGreyscaleFormat) format))) { NFT_LOG(L_ERROR, "failed to initialize hardware."); goto m_deinit; }*/ /* initialize pixel->led mapping */ if(!led_hardware_list_refresh_mapping(hw)) goto m_deinit; /* precalc memory offsets for actual mapping */ LedHardware *ch; for(ch = hw; ch; ch = led_hardware_list_get_next(ch)) { if(!led_chain_map_from_frame(led_hardware_get_chain(ch), frame)) goto m_deinit; } /* set correct gain to hardware */ if(!led_hardware_list_refresh_gain(hw)) goto m_deinit; #if HAVE_IMAGEMAGICK == 1 /* determine format that ImageMagick should provide */ if(!_c.raw) { if(!(im_format(&_c, format))) { NFT_LOG(L_ERROR, "Failed to determine valid ImageMagick format"); goto m_deinit; } } #endif /* do we have at least one filename? */ if(!_c.files[0]) { NFT_LOG(L_ERROR, "No input file(s) given"); goto m_deinit; } /* initially sample time for frame-timing */ if(!led_fps_sample()) goto m_deinit; #if ! WIN32 /* initialize alarm-signal handler for periodical fps output */ { struct sigaction sa; struct itimerval timer; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &_alarm_signal_handler; sigaction(SIGALRM, &sa, NULL); timer.it_value.tv_sec = 1; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 1; timer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &timer, NULL); } #endif /* get data-buffer of frame to write our pixels to */ char *buf; if(!(buf = led_frame_get_buffer(frame))) { NFT_LOG(L_ERROR, "Frame has NULL buffer"); goto m_deinit; } /* walk all files (supplied as commandline arguments) and output them */ int filecount; for(filecount = 0; _c.files[filecount]; filecount++) { NFT_LOG(L_VERBOSE, "Getting pixels from \"%s\"", _c.files[filecount]); /* open file */ if(_c.files[filecount][0] == '-' && strlen(_c.files[filecount]) == 1) { _c.fd = STDIN_FILENO; } else { if((_c.fd = open(_c.files[filecount], O_RDONLY)) < 0) { NFT_LOG(L_ERROR, "Failed to open \"%s\": %s", _c.files[filecount], strerror(errno)); continue; } } #if HAVE_IMAGEMAGICK == 1 /** initialize stream for ImageMagick */ if(!_c.raw) { if(!(im_open_stream(&_c))) continue; } #endif /* output file frame-by-frame */ while(_c.running) { #if HAVE_IMAGEMAGICK == 1 /* use imagemagick to load file if we're not in "raw-mode" */ if(!_c.raw) { /* load frame to buffer using ImageMagick */ if(!im_read_frame(&_c, width, height, buf)) break; } else { #endif /* read raw frame */ if(raw_read_frame(&_c.running, buf, _c.fd, led_pixel_format_get_buffer_size( led_frame_get_format(frame), led_frame_get_width(frame)*led_frame_get_height(frame))) == 0) continue; #if HAVE_IMAGEMAGICK == 1 } #endif /* set endianess (flag will be changed when conversion occurs) */ led_frame_set_big_endian(frame, _c.is_big_endian); /* print frame for debugging */ //nft_frame_buffer_print(frame); /* fill chain of every hardware from frame */ LedHardware *h; for(h = hw; h; h = led_hardware_list_get_next(h)) { if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame)) { NFT_LOG(L_ERROR, "Error while mapping frame"); break; } } /* send frame to hardware(s) */ NFT_LOG(L_DEBUG, "Sending frame"); led_hardware_list_send(hw); /* delay in respect to fps */ if(!led_fps_delay(_c.fps)) break; /* latch hardware */ NFT_LOG(L_DEBUG, "Showing frame"); led_hardware_list_show(hw); /* save time when frame is displayed */ if(!led_fps_sample()) break; /* clear frame */ //nft_frame_clear_buffer(frame); } #if HAVE_IMAGEMAGICK == 1 if(!_c.raw) im_close_stream(&_c); #else close(_c.fd); #endif /* loop endlessly? */ if((_c.running) && (!_c.files[filecount+1]) && _c.do_loop) { /* start over by resetting the for-loop */ filecount = -1; } } /* all ok */ res = 0; m_deinit: /* free setup */ led_setup_destroy(s); /* free frame */ led_frame_destroy(frame); /* destroy config */ led_prefs_deinit(p); #if HAVE_IMAGEMAGICK == 1 /* deinitialize ImageMagick */ im_deinit(&_c); #endif return res; }
int main(int argc, char *argv[]) { /** return value of main() */ int res = 1; /* current configuration */ LedPrefs *prefs = NULL; /* current setup */ LedSetup *setup = NULL; /** framebuffer for captured image */ LedFrame *frame = NULL; /* check binary version compatibility */ NFT_LED_CHECK_VERSION /* set default loglevel to INFO */ nft_log_level_set(L_INFO); /* initialize exit handlers */ int signals[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT }; unsigned int i; for(i=0; i<sizeof(signals)/sizeof(int); i++) { if(signal(signals[i], _exit_signal_handler) == SIG_ERR) { NFT_LOG_PERROR("signal()"); goto _m_exit; } } /* default fps */ _c.fps = 25; /* default mechanism */ _c.method = METHOD_MIN+1; /* default config-filename */ if(!led_prefs_default_filename(_c.prefsfile, sizeof(_c.prefsfile), ".ledcap.xml")) goto _m_exit; /* parse cmdline-arguments */ if(!_parse_args(argc, argv)) goto _m_exit; /* print welcome msg */ NFT_LOG(L_INFO, "%s %s (c) D.Hiepler 2006-2012", PACKAGE_NAME, ledcap_version_long()); NFT_LOG(L_VERBOSE, "Loglevel: %s", nft_log_level_to_string(nft_log_level_get())); /* initialize preferences context */ if(!(prefs = led_prefs_init())) return -1; /* parse prefs-file */ LedPrefsNode *pnode; if(!(pnode = led_prefs_node_from_file(_c.prefsfile))) { NFT_LOG(L_ERROR, "Failed to open configfile \"%s\"", _c.prefsfile); goto _m_exit; } /* create setup from prefs-node */ if(!(setup = led_prefs_setup_from_node(prefs, pnode))) { NFT_LOG(L_ERROR, "No valid setup found in preferences file."); led_prefs_node_free(pnode); goto _m_exit; } /* free preferences node */ led_prefs_node_free(pnode); /* determine width of input-frames */ LedFrameCord width, height; if((width = led_setup_get_width(setup)) > _c.width) { NFT_LOG(L_WARNING, "LED-Setup width (%d) > our width (%d). Using setup-value", width,_c.width); /* use dimensions of mapped chain */ _c.width = width; } /* determine height of input-frames */ if((height = led_setup_get_height(setup)) > _c.height) { NFT_LOG(L_WARNING, "LED-Setup height (%d) > our height (%d). Using setup-value.", height, _c.height); /* use dimensions of mapped chain */ _c.height = height; } if(_c.width < 0) { NFT_LOG(L_ERROR, "width (%d) < 0", _c.width); goto _m_exit; } if(_c.height < 0) { NFT_LOG(L_ERROR, "height (%d) < 0", _c.height); goto _m_exit; } /* sanitize x-offset @todo check for maximum */ if(_c.x < 0) { NFT_LOG(L_ERROR, "Invalid x coordinate: %d, using 0", _c.x); _c.x = 0; } /* sanitize y-offset @todo check for maximum */ if(_c.y < 0) { NFT_LOG(L_ERROR, "Invalid y coordinate: %d, using 0", _c.y); _c.y = 0; } /* initialize capture mechanism (only imlib for now) */ if(!capture_init(_c.method)) goto _m_exit; /* allocate framebuffer */ NFT_LOG(L_INFO, "Allocating frame: %dx%d (%s)", _c.width, _c.height, capture_format()); if(!(frame = led_frame_new(_c.width, _c.height, led_pixel_format_from_string(capture_format())))) goto _m_exit; /* respect endianess */ led_frame_set_big_endian(frame, capture_is_big_endian()); /* get first hardware */ LedHardware *hw; if(!(hw = led_setup_get_hardware(setup))) goto _m_exit; /* initialize pixel->led mapping */ if(!led_hardware_list_refresh_mapping(hw)) goto _m_exit; /* precalc memory offsets for actual mapping */ if(!led_chain_map_from_frame(led_hardware_get_chain(hw), frame)) goto _m_exit; /* set saved gain to all registered hardware instances */ if(!led_hardware_list_refresh_gain(hw)) goto _m_exit; /* print some debug-info */ led_frame_print(frame, L_VERBOSE); led_hardware_print(hw, L_VERBOSE); /* initially sample time for frametiming */ if(!led_fps_sample()) goto _m_exit; /* output some useful info */ NFT_LOG(L_INFO, "Capturing %dx%d pixels at position x/y: %d/%d", _c.width, _c.height, _c.x, _c.y); /* loop until _c.running is set to FALSE */ _c.running = TRUE; while(_c.running) { /* capture frame */ if(!(capture_frame(frame, _c.x, _c.y))) break; /* print frame for debugging */ //led_frame_buffer_print(frame); /* map from frame */ LedHardware *h; for(h = hw; h; h = led_hardware_list_get_next(h)) { if(!led_chain_fill_from_frame(led_hardware_get_chain(h), frame)) { NFT_LOG(L_ERROR, "Error while mapping frame"); break; } } /* send frame to hardware(s) */ led_hardware_list_send(hw); /* delay in respect to fps */ if(!led_fps_delay(_c.fps)) break; /* show frame */ led_hardware_list_show(hw); /* save time when frame is displayed */ if(!led_fps_sample()) break; } /* mark success */ res = 0; _m_exit: /* deinitialize capture mechanism */ capture_deinit(); /* free frame */ led_frame_destroy(frame); /* destroy config */ led_setup_destroy(setup); /* destroy config */ led_prefs_deinit(prefs); return res; }