mirror of
https://github.com/eddyem/mytakepic.git
synced 2025-12-06 02:35:16 +03:00
rebuild fli_control. add image view
This commit is contained in:
parent
162e1987d8
commit
c604283024
@ -2,40 +2,49 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
set(PROJ fli_control)
|
set(PROJ fli_control)
|
||||||
project(${PROJ})
|
project(${PROJ})
|
||||||
set(MINOR_VERSION "0")
|
set(MINOR_VERSION "0")
|
||||||
set(MID_VERSION "2")
|
set(MID_VERSION "0")
|
||||||
set(MAJOR_VERSION "0")
|
set(MAJOR_VERSION "1")
|
||||||
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
|
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
|
||||||
|
|
||||||
message("VER: ${VERSION}")
|
message("VER: ${VERSION}")
|
||||||
|
|
||||||
# default flags
|
# default flags
|
||||||
set(CFLAGS -O2 -std=gnu99)
|
set(CFLAGS ${CFLAGS} -O2 -std=gnu99)
|
||||||
|
add_definitions(-D_XOPEN_SOURCE=666 -D_DEFAULT_SOURCE -D_GNU_SOURCE)
|
||||||
|
|
||||||
set(CMAKE_COLOR_MAKEFILE ON)
|
set(CMAKE_COLOR_MAKEFILE ON)
|
||||||
|
|
||||||
# here is one of two variants: all .c in directory or .c files in list
|
set(SOURCES main.c cmdlnopts.c flifunc.c)
|
||||||
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
|
|
||||||
#set(SOURCES list_of_c_files)
|
|
||||||
|
|
||||||
# cmake -DEBUG=1 -> debugging
|
# cmake -DDEBUG=yes -> debugging
|
||||||
if(DEFINED EBUG)
|
if(DEFINED DEBUG AND DEBUG STREQUAL "yes")
|
||||||
set(CFLAGS ${CFLAGS} -Wextra -Wall -Werror -W)
|
set(CFLAGS ${CFLAGS} -Wextra -Wall -Werror -W)
|
||||||
add_definitions(-DEBUG)
|
add_definitions(-DEBUG)
|
||||||
|
set(CMAKE_VERBOSE_MAKEFILE "ON")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||||
find_package(CFITSIO REQUIRED)
|
find_package(CFITSIO REQUIRED)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
set(MODULES fli>=1.71)
|
set(MODULES fli>=1.71 usefull_macros)
|
||||||
# additional modules on condition
|
# additional modules on condition
|
||||||
if(DEFINED USEPNG)
|
if(DEFINED USEPNG AND USEPNG STREQUAL "yes")
|
||||||
set(MODULES ${MODULES} libpng>=1.2)
|
set(MODULES ${MODULES} libpng>=1.2)
|
||||||
add_definitions(-DUSEPNG)
|
add_definitions(-DUSEPNG)
|
||||||
endif()
|
endif()
|
||||||
pkg_check_modules(${PROJ} REQUIRED ${MODULES})
|
pkg_check_modules(${PROJ} REQUIRED ${MODULES})
|
||||||
if(DEFINED USERAW)
|
if(DEFINED USERAW AND USERAW STREQUAL "yes")
|
||||||
add_definitions(-DUSERAW)
|
add_definitions(-DUSERAW)
|
||||||
endif()
|
endif()
|
||||||
|
if(DEFINED IMAGEVIEW AND IMAGEVIEW STREQUAL "yes")
|
||||||
|
list(APPEND SOURCES events.c imageview.c)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
find_package(GLUT REQUIRED)
|
||||||
|
find_package(X11 REQUIRED)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
list(APPEND ${PROJ}_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
add_definitions(-DIMAGEVIEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
# change wrong behaviour with install prefix
|
# change wrong behaviour with install prefix
|
||||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
|
||||||
@ -48,7 +57,7 @@ message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}")
|
|||||||
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
|
set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru)
|
||||||
|
|
||||||
if(NOT DEFINED LOCALEDIR)
|
if(NOT DEFINED LOCALEDIR)
|
||||||
if(DEFINED DEBUG)
|
if(DEFINED DEBUG AND DEBUG STREQUAL "yes")
|
||||||
set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale)
|
set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale)
|
||||||
else()
|
else()
|
||||||
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
|
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
|
||||||
@ -62,8 +71,8 @@ set(RU_FILE ${LCPATH}/ru.po)
|
|||||||
|
|
||||||
# exe file
|
# exe file
|
||||||
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
|
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
|
||||||
target_link_libraries(${PROJ} ${CFITSIO_LIBRARIES} ${${PROJ}_LIBRARIES})
|
target_link_libraries(${PROJ} ${CFITSIO_LIBRARIES} ${X11_LIBRARIES} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${${PROJ}_LIBRARIES} -lm)
|
||||||
include_directories(${${PROJ}_INCLUDE_DIRS})
|
include_directories(${${PROJ}_INCLUDE_DIRS} image_view_module)
|
||||||
link_directories(${${PROJ}_LIBRARY_DIRS} )
|
link_directories(${${PROJ}_LIBRARY_DIRS} )
|
||||||
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\"
|
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\"
|
||||||
-DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
-DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
||||||
@ -71,12 +80,8 @@ add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\"
|
|||||||
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
||||||
|
|
||||||
# Installation of the program
|
# Installation of the program
|
||||||
if(NOT DEFINED DEBUG)
|
INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES")
|
||||||
INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES")
|
INSTALL(TARGETS ${PROJ} DESTINATION "bin")
|
||||||
INSTALL(TARGETS ${PROJ} DESTINATION "bin")
|
|
||||||
else()
|
|
||||||
install(CODE "MESSAGE(\"Don't install in DEBUG mode! First run cmake without -DEBUG defined.\")")
|
|
||||||
endif(NOT DEFINED DEBUG)
|
|
||||||
|
|
||||||
find_package(Gettext REQUIRED)
|
find_package(Gettext REQUIRED)
|
||||||
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
|
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
|
||||||
|
|||||||
1
fli_control/FLI_control.cflags
Normal file
1
fli_control/FLI_control.cflags
Normal file
@ -0,0 +1 @@
|
|||||||
|
-std=c17
|
||||||
8
fli_control/FLI_control.config
Normal file
8
fli_control/FLI_control.config
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Add predefined macros for your project here. For example:
|
||||||
|
// #define THE_ANSWER 42
|
||||||
|
#define USEPNG
|
||||||
|
#define USERAW
|
||||||
|
#define IMAGEVIEW
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#define _XOPEN_SOURCE 666
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
1
fli_control/FLI_control.creator
Normal file
1
fli_control/FLI_control.creator
Normal file
@ -0,0 +1 @@
|
|||||||
|
[General]
|
||||||
167
fli_control/FLI_control.creator.user
Normal file
167
fli_control/FLI_control.creator.user
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 4.12.3, 2020-12-07T12:53:30. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{cf63021e-ef53-49b0-b03b-2f2570cdf3b6}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="int">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||||
|
<value type="QString" key="language">QmlJS</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<valuemap type="QVariantMap" key="ClangTools">
|
||||||
|
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||||
|
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||||
|
<value type="int" key="ClangTools.ParallelJobs">4</value>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||||
|
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||||
|
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/Docs/SAO/Cameras/FLI_camera/my/fli_control</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||||
|
<value type="QString">all</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
|
||||||
|
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
|
||||||
|
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||||
|
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Сборка</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
|
||||||
|
<value type="QString">clean</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">true</value>
|
||||||
|
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
|
||||||
|
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
|
||||||
|
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Очистка</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Развёртывание</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||||
|
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||||
|
<value type="QString" key="RunConfiguration.Arguments"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.Arguments.multi">false</value>
|
||||||
|
<value type="QString" key="RunConfiguration.OverrideDebuggerStartup"></value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
|
||||||
|
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">22</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
||||||
1
fli_control/FLI_control.cxxflags
Normal file
1
fli_control/FLI_control.cxxflags
Normal file
@ -0,0 +1 @@
|
|||||||
|
-std=c++17
|
||||||
13
fli_control/FLI_control.files
Normal file
13
fli_control/FLI_control.files
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
cmdlnopts.c
|
||||||
|
cmdlnopts.h
|
||||||
|
events.c
|
||||||
|
events.h
|
||||||
|
flifunc.c
|
||||||
|
flifunc.h
|
||||||
|
imageview.c
|
||||||
|
imageview.h
|
||||||
|
main.c
|
||||||
|
parseargs.c
|
||||||
|
parseargs.h
|
||||||
|
usefull_macros.c
|
||||||
|
usefull_macros.h
|
||||||
1
fli_control/FLI_control.includes
Normal file
1
fli_control/FLI_control.includes
Normal file
@ -0,0 +1 @@
|
|||||||
|
.
|
||||||
@ -19,12 +19,14 @@
|
|||||||
* MA 02110-1301, USA.
|
* MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <libfli.h>
|
#include <libfli.h>
|
||||||
|
|
||||||
#include "cmdlnopts.h"
|
#include "cmdlnopts.h"
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
@ -37,9 +39,8 @@
|
|||||||
*/
|
*/
|
||||||
static int help;
|
static int help;
|
||||||
static glob_pars G;
|
static glob_pars G;
|
||||||
|
glob_pars *GP = NULL;
|
||||||
|
|
||||||
int rewrite_ifexists = 0, // rewrite existing files == 0 or 1
|
|
||||||
verbose = 0; // each -v increments this value, e.g. -vvv sets it to 3
|
|
||||||
// DEFAULTS
|
// DEFAULTS
|
||||||
// default global parameters
|
// default global parameters
|
||||||
glob_pars const Gdefault = {
|
glob_pars const Gdefault = {
|
||||||
@ -63,18 +64,12 @@ glob_pars const Gdefault = {
|
|||||||
*/
|
*/
|
||||||
myoption cmdlnopts[] = {
|
myoption cmdlnopts[] = {
|
||||||
{"help", NO_ARGS, &help, 1, arg_none, NULL, N_("show this help")},
|
{"help", NO_ARGS, &help, 1, arg_none, NULL, N_("show this help")},
|
||||||
{"force", NO_ARGS, &rewrite_ifexists,1,arg_none,NULL, N_("rewrite output file if exists")},
|
{"rewrite", NO_ARGS, &G.rewrite,1, arg_none, NULL, N_("rewrite output file if exists")},
|
||||||
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&verbose), N_("verbose level (each -v increase it)")},
|
{"verbose", NO_ARGS, NULL, 'V', arg_none, APTR(&G.verbose), N_("verbose level (each -v increase it)")},
|
||||||
{"dark", NO_ARGS, NULL, 'd', arg_int, APTR(&G.dark), N_("not open shutter, when exposing (\"dark frames\")")},
|
{"dark", NO_ARGS, NULL, 'd', arg_int, APTR(&G.dark), N_("not open shutter, when exposing (\"dark frames\")")},
|
||||||
{"open-shutter",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_OPEN,arg_none,NULL, N_("open shutter")},
|
|
||||||
{"close-shutter",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_CLOSE,arg_none,NULL, N_("close shutter")},
|
|
||||||
{"shutter-on-low",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_LOW,arg_none,NULL, N_("run exposition on LOW @ pin5 I/O port")},
|
|
||||||
{"shutter-on-high",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH,arg_none,NULL, N_("run exposition on HIGH @ pin5 I/O port")},
|
|
||||||
{"get-ioport",NO_ARGS, NULL, 'i', arg_int, APTR(&G.getio), N_("get value of I/O port pins")},
|
|
||||||
{"async", NO_ARGS, &G.async,1, arg_none, NULL, N_("move stepper motor asynchronous")},
|
|
||||||
{"8bit", NO_ARGS, NULL, '8', arg_int, APTR(&G._8bit), N_("run in 8-bit mode")},
|
{"8bit", NO_ARGS, NULL, '8', arg_int, APTR(&G._8bit), N_("run in 8-bit mode")},
|
||||||
{"fast", NO_ARGS, NULL, 'F', arg_int, APTR(&G.fast), N_("fast (8MHz) readout mode")},
|
{"fast", NO_ARGS, NULL, 'F', arg_int, APTR(&G.fast), N_("fast (8MHz) readout mode")},
|
||||||
//{"", NO_ARGS, NULL, '', arg_int, APTR(&G.), N_("")},
|
{"set-temp",NEED_ARG, NULL, 't', arg_double, APTR(&G.temperature),N_("set CCD temperature to given value (degr C)")},
|
||||||
|
|
||||||
{"author", NEED_ARG, NULL, 'A', arg_string, APTR(&G.author), N_("program author")},
|
{"author", NEED_ARG, NULL, 'A', arg_string, APTR(&G.author), N_("program author")},
|
||||||
{"objtype", NEED_ARG, NULL, 'Y', arg_string, APTR(&G.objtype), N_("object type (neon, object, flat etc)")},
|
{"objtype", NEED_ARG, NULL, 'Y', arg_string, APTR(&G.objtype), N_("object type (neon, object, flat etc)")},
|
||||||
@ -83,7 +78,6 @@ myoption cmdlnopts[] = {
|
|||||||
{"obsname", NEED_ARG, NULL, 'N', arg_string, APTR(&G.observers), N_("observers' names")},
|
{"obsname", NEED_ARG, NULL, 'N', arg_string, APTR(&G.observers), N_("observers' names")},
|
||||||
{"prog-id", NEED_ARG, NULL, 'P', arg_string, APTR(&G.prog_id), N_("observing program name")},
|
{"prog-id", NEED_ARG, NULL, 'P', arg_string, APTR(&G.prog_id), N_("observing program name")},
|
||||||
{"addrec", MULT_PAR, NULL, 'r', arg_string, APTR(&G.addhdr), N_("add records to header from given file[s]")},
|
{"addrec", MULT_PAR, NULL, 'r', arg_string, APTR(&G.addhdr), N_("add records to header from given file[s]")},
|
||||||
//{"", NEED_ARG, NULL, '', arg_string, APTR(&G.), N_("")},
|
|
||||||
|
|
||||||
{"nflushes",NEED_ARG, NULL, 'f', arg_int, APTR(&G.nflushes), N_("N flushes before exposing")},
|
{"nflushes",NEED_ARG, NULL, 'f', arg_int, APTR(&G.nflushes), N_("N flushes before exposing")},
|
||||||
{"hbin", NEED_ARG, NULL, 'h', arg_int, APTR(&G.hbin), N_("horizontal binning to N pixels")},
|
{"hbin", NEED_ARG, NULL, 'h', arg_int, APTR(&G.hbin), N_("horizontal binning to N pixels")},
|
||||||
@ -95,15 +89,25 @@ myoption cmdlnopts[] = {
|
|||||||
{"Y0", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y0), N_("frame Y0 coordinate (-1 - all with overscan)")},
|
{"Y0", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y0), N_("frame Y0 coordinate (-1 - all with overscan)")},
|
||||||
{"X1", NEED_ARG, NULL, 0, arg_int, APTR(&G.X1), N_("frame X1 coordinate (-1 - all with overscan)")},
|
{"X1", NEED_ARG, NULL, 0, arg_int, APTR(&G.X1), N_("frame X1 coordinate (-1 - all with overscan)")},
|
||||||
{"Y1", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y1), N_("frame Y1 coordinate (-1 - all with overscan)")},
|
{"Y1", NEED_ARG, NULL, 0, arg_int, APTR(&G.Y1), N_("frame Y1 coordinate (-1 - all with overscan)")},
|
||||||
|
|
||||||
|
{"open-shutter",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_OPEN,arg_none,NULL, N_("open shutter")},
|
||||||
|
{"close-shutter",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_CLOSE,arg_none,NULL, N_("close shutter")},
|
||||||
|
{"shutter-on-low",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_LOW,arg_none,NULL, N_("run exposition on LOW @ pin5 I/O port")},
|
||||||
|
{"shutter-on-high",NO_ARGS,&G.shtr_cmd,FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH,arg_none,NULL, N_("run exposition on HIGH @ pin5 I/O port")},
|
||||||
|
{"get-ioport",NO_ARGS, NULL, 'i', arg_int, APTR(&G.getio), N_("get value of I/O port pins")},
|
||||||
|
{"async", NO_ARGS, &G.async,1, arg_none, NULL, N_("move stepper motor asynchronous")},
|
||||||
|
|
||||||
{"set-ioport",NEED_ARG, NULL, 's', arg_int, APTR(&G.setio), N_("set I/O port pins to given value (decimal number, pin1 is LSB)")},
|
{"set-ioport",NEED_ARG, NULL, 's', arg_int, APTR(&G.setio), N_("set I/O port pins to given value (decimal number, pin1 is LSB)")},
|
||||||
{"conf-ioport",NEED_ARG,NULL, 'c', arg_int, APTR(&G.confio), N_("configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == output, 0 == input)")},
|
{"conf-ioport",NEED_ARG,NULL, 'c', arg_int, APTR(&G.confio), N_("configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == output, 0 == input)")},
|
||||||
|
|
||||||
{"goto", NEED_ARG, NULL, 'g', arg_int, APTR(&G.gotopos), N_("move focuser to absolute position")},
|
{"goto", NEED_ARG, NULL, 'g', arg_int, APTR(&G.gotopos), N_("move focuser to absolute position")},
|
||||||
{"addsteps",NEED_ARG, NULL, 'a', arg_int, APTR(&G.addsteps), N_("move focuser to relative position")},
|
{"addsteps",NEED_ARG, NULL, 'a', arg_int, APTR(&G.addsteps), N_("move focuser to relative position")},
|
||||||
// {"wheel-get",NO_ARGS, NULL, 0, arg_none, APTR(&G.getwheel), N_("get current wheel position")},
|
|
||||||
{"wheel-set",NEED_ARG, NULL, 'w', arg_int, APTR(&G.setwheel), N_("set wheel position")},
|
|
||||||
//{"", NEED_ARG, NULL, '', arg_int, APTR(&G.), N_("")},
|
|
||||||
|
|
||||||
{"set-temp",NEED_ARG, NULL, 't', arg_double, APTR(&G.temperature),N_("set CCD temperature to given value (degr C)")},
|
{"wheel-set",NEED_ARG, NULL, 'w', arg_int, APTR(&G.setwheel), N_("set wheel position")},
|
||||||
|
|
||||||
|
#ifdef IMAGEVIEW
|
||||||
|
{"display", NO_ARGS, NULL, 'D', arg_int, APTR(&G.showimage), N_("Display image in OpenGL window")},
|
||||||
|
#endif
|
||||||
//{"", NEED_ARG, NULL, '', arg_double, APTR(&G.), N_("")},
|
//{"", NEED_ARG, NULL, '', arg_double, APTR(&G.), N_("")},
|
||||||
|
|
||||||
end_option
|
end_option
|
||||||
@ -133,6 +137,21 @@ glob_pars *parse_args(int argc, char **argv){
|
|||||||
printf("\t%4d: %s\n", i, argv[i]);
|
printf("\t%4d: %s\n", i, argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &G;
|
GP = &G;
|
||||||
|
return GP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief verbose - print additional messages depending of G.verbose
|
||||||
|
* @param levl - message level
|
||||||
|
* @param fmt - message
|
||||||
|
*/
|
||||||
|
void verbose(int levl, const char *fmt, ...){
|
||||||
|
va_list ar;
|
||||||
|
if(levl > G.verbose) return;
|
||||||
|
printf("%s: ", __progname);
|
||||||
|
va_start(ar, fmt);
|
||||||
|
vprintf(fmt, ar);
|
||||||
|
va_end(ar);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
#ifndef __CMDLNOPTS_H__
|
#ifndef __CMDLNOPTS_H__
|
||||||
#define __CMDLNOPTS_H__
|
#define __CMDLNOPTS_H__
|
||||||
|
|
||||||
#include "parseargs.h"
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* here are some typedef's for global data
|
* here are some typedef's for global data
|
||||||
@ -53,16 +53,19 @@ typedef struct{
|
|||||||
double temperature; // temperature of CCD
|
double temperature; // temperature of CCD
|
||||||
int gotopos; // move stepper motor of focuser to absolute position
|
int gotopos; // move stepper motor of focuser to absolute position
|
||||||
int addsteps; // move stepper motor of focuser to relative position
|
int addsteps; // move stepper motor of focuser to relative position
|
||||||
// int getwheel; // get position of wheel
|
|
||||||
int setwheel; // set wheel position
|
int setwheel; // set wheel position
|
||||||
int async; // asynchronous moving
|
int async; // asynchronous moving
|
||||||
|
int verbose; // each '-V' increases it
|
||||||
|
int rewrite; // rewrite file
|
||||||
|
int showimage; // show image preview
|
||||||
char **addhdr; // list of files from which to add header records
|
char **addhdr; // list of files from which to add header records
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|
||||||
|
|
||||||
// default & global parameters
|
// default & global parameters
|
||||||
extern glob_pars const Gdefault;
|
extern glob_pars const Gdefault;
|
||||||
extern int rewrite_ifexists, verbose;
|
extern glob_pars *GP;
|
||||||
|
|
||||||
glob_pars *parse_args(int argc, char **argv);
|
glob_pars *parse_args(int argc, char **argv);
|
||||||
|
void verbose(int levl, const char *fmt, ...);
|
||||||
#endif // __CMDLNOPTS_H__
|
#endif // __CMDLNOPTS_H__
|
||||||
|
|||||||
199
fli_control/events.c
Normal file
199
fli_control/events.c
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* events.c
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "events.h"
|
||||||
|
#include "imageview.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* manage pressed keys & menu items
|
||||||
|
*/
|
||||||
|
static void processKeybrd(unsigned char key, int mod, _U_ int x, _U_ int y){
|
||||||
|
windowData *win = getWin();
|
||||||
|
if(!win) return;
|
||||||
|
DBG("key=%d (%c), mod=%d", key, key, mod);
|
||||||
|
if(mod == GLUT_ACTIVE_CTRL){ // 'a' == 1, 'b' == 2...
|
||||||
|
key += 'a'-1;
|
||||||
|
DBG("CTRL+%c", key);
|
||||||
|
switch(key){
|
||||||
|
case 'r': // roll colorfun
|
||||||
|
win->winevt |= WINEVT_ROLLCOLORFUN;
|
||||||
|
break;
|
||||||
|
case 's': // save image
|
||||||
|
win->winevt |= WINEVT_SAVEIMAGE;
|
||||||
|
break;
|
||||||
|
case 'q': // exit case 17:
|
||||||
|
win->killthread = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}else if(mod == GLUT_ACTIVE_ALT){
|
||||||
|
; // ALT
|
||||||
|
}else switch(key){
|
||||||
|
case '0': // return zoom to 1 & image to 0
|
||||||
|
win->zoom = 1;
|
||||||
|
win->x = 0; win->y = 0;
|
||||||
|
break;
|
||||||
|
case 27: // esc - kill
|
||||||
|
win->killthread = 1;
|
||||||
|
break;
|
||||||
|
case 'c': // capture in pause mode
|
||||||
|
DBG("winevt = %d", win->winevt);
|
||||||
|
if(win->winevt & WINEVT_PAUSE)
|
||||||
|
win->winevt |= WINEVT_GETIMAGE;
|
||||||
|
break;
|
||||||
|
case 'l': // flip left-right
|
||||||
|
win->flip ^= WIN_FLIP_LR;
|
||||||
|
break;
|
||||||
|
case 'p': // pause capturing
|
||||||
|
win->winevt ^= WINEVT_PAUSE;
|
||||||
|
break;
|
||||||
|
case 'u': // flip up-down
|
||||||
|
win->flip ^= WIN_FLIP_UD;
|
||||||
|
break;
|
||||||
|
case 'Z': // zoom+
|
||||||
|
win->zoom *= 1.1f;
|
||||||
|
calc_win_props(NULL, NULL);
|
||||||
|
break;
|
||||||
|
case 'z': // zoom-
|
||||||
|
win->zoom /= 1.1f;
|
||||||
|
calc_win_props(NULL, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process keyboard
|
||||||
|
*/
|
||||||
|
void keyPressed(unsigned char key, int x, int y){
|
||||||
|
int mod = glutGetModifiers();
|
||||||
|
//mod: GLUT_ACTIVE_SHIFT, GLUT_ACTIVE_CTRL, GLUT_ACTIVE_ALT; result is their sum
|
||||||
|
DBG("Key pressed. mod=%d, keycode=%d (%c), point=(%d,%d)\n", mod, key, key, x,y);
|
||||||
|
processKeybrd(key, mod, x, y);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void keySpPressed(_U_ int key, _U_ int x, _U_ int y){
|
||||||
|
// int mod = glutGetModifiers();
|
||||||
|
DBG("Sp. key pressed. mod=%d, keycode=%d, point=(%d,%d)\n", glutGetModifiers(), key, x,y);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
static int oldx, oldy; // coordinates when mouse was pressed
|
||||||
|
static int movingwin = 0; // ==1 when user moves image by middle button
|
||||||
|
|
||||||
|
void mousePressed(int key, int state, int x, int y){
|
||||||
|
// key: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON
|
||||||
|
// state: GLUT_UP, GLUT_DOWN
|
||||||
|
int mod = glutGetModifiers();
|
||||||
|
windowData *win = getWin();
|
||||||
|
if(!win) return;
|
||||||
|
if(state == GLUT_DOWN){
|
||||||
|
oldx = x; oldy = y;
|
||||||
|
float X,Y, Zoom = win->zoom;
|
||||||
|
conv_mouse_to_image_coords(x,y,&X,&Y,win);
|
||||||
|
DBG("press in (%d, %d) == (%f, %f) on image; mod == %d", x,y,X,Y, mod);
|
||||||
|
if(key == GLUT_LEFT_BUTTON){
|
||||||
|
DBG("win->x=%g, win->y=%g", win->x, win->y);
|
||||||
|
win->x += Zoom * (win->w/2.f - (float)x);
|
||||||
|
win->y -= Zoom * (win->h/2.f - (float)y);
|
||||||
|
}else if(key == GLUT_MIDDLE_BUTTON) movingwin = 1;
|
||||||
|
else if(key == 3){ // wheel UP
|
||||||
|
if(mod == 0) win->y += 10.f*win->zoom; // nothing pressed - scroll up
|
||||||
|
else if(mod == GLUT_ACTIVE_SHIFT) win->x -= 10.f*Zoom; // shift pressed - scroll left
|
||||||
|
else if(mod == GLUT_ACTIVE_CTRL) win->zoom *= 1.1f; // ctrl+wheel up == zoom+
|
||||||
|
}else if(key == 4){ // wheel DOWN
|
||||||
|
if(mod == 0) win->y -= 10.f*win->zoom; // nothing pressed - scroll down
|
||||||
|
else if(mod == GLUT_ACTIVE_SHIFT) win->x += 10.f*Zoom; // shift pressed - scroll right
|
||||||
|
else if(mod == GLUT_ACTIVE_CTRL) win->zoom /= 1.1f; // ctrl+wheel down == zoom-
|
||||||
|
}
|
||||||
|
calc_win_props(NULL, NULL);
|
||||||
|
}else{
|
||||||
|
movingwin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouseMove(int x, int y){
|
||||||
|
windowData *win = getWin();
|
||||||
|
if(!win) return;
|
||||||
|
if(movingwin){
|
||||||
|
float X, Y, nx, ny, w2, h2;
|
||||||
|
float a = win->Daspect;
|
||||||
|
X = (x - oldx) * a; Y = (y - oldy) * a;
|
||||||
|
nx = win->x + X;
|
||||||
|
ny = win->y - Y;
|
||||||
|
w2 = win->image->w / 2.f * win->zoom;
|
||||||
|
h2 = win->image->h / 2.f * win->zoom;
|
||||||
|
if(nx < w2 && nx > -w2)
|
||||||
|
win->x = nx;
|
||||||
|
if(ny < h2 && ny > -h2)
|
||||||
|
win->y = ny;
|
||||||
|
oldx = x;
|
||||||
|
oldy = y;
|
||||||
|
calc_win_props(NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void menuEvents(int opt){
|
||||||
|
DBG("opt: %d, key: %d (%c), mod: %d", opt, opt&0xff, opt&0xff, opt>>8);
|
||||||
|
// just work as shortcut pressed
|
||||||
|
processKeybrd((unsigned char)(opt&0xff), opt>>8, 0, 0);
|
||||||
|
} // GLUT_ACTIVE_CTRL
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
char *name; // menu entry name
|
||||||
|
int symbol; // shortcut symbol + rolled modifier
|
||||||
|
} menuentry;
|
||||||
|
|
||||||
|
#define CTRL_K(key) ((key-'a'+1) | (GLUT_ACTIVE_CTRL<<8))
|
||||||
|
#define SHIFT_K(key) (key | (GLUT_ACTIVE_SHIFT<<8))
|
||||||
|
#define ALT_K(key) (key | (GLUT_ACTIVE_ALT<<8))
|
||||||
|
static const menuentry entries[] = {
|
||||||
|
{"Capture in pause mode (c)", 'c'},
|
||||||
|
{"Flip image LR (l)", 'l'},
|
||||||
|
{"Flip image UD (u)", 'u'},
|
||||||
|
{"Make a pause/continue (p)", 'p'},
|
||||||
|
{"Restore zoom (0)", '0'},
|
||||||
|
{"Roll colorfun (ctrl+r)", CTRL_K('r')},
|
||||||
|
{"Save image (ctrl+s)", CTRL_K('s')},
|
||||||
|
{"Close this window (ESC)", 27},
|
||||||
|
{"Quit (ctrl+q)", CTRL_K('q')},
|
||||||
|
{NULL, 0}
|
||||||
|
};
|
||||||
|
#undef CTRL_K
|
||||||
|
#undef SHIFT_K
|
||||||
|
#undef ALT_K
|
||||||
|
|
||||||
|
void createMenu(){
|
||||||
|
FNAME();
|
||||||
|
windowData *win = getWin();
|
||||||
|
if(!win) return;
|
||||||
|
DBG("menu for win ID %d", win->ID);
|
||||||
|
glutSetWindow(win->ID);
|
||||||
|
if(win->menu) glutDestroyMenu(win->menu);
|
||||||
|
win->menu = glutCreateMenu(menuEvents);
|
||||||
|
const menuentry *ptr = entries;
|
||||||
|
while(ptr->name){
|
||||||
|
glutAddMenuEntry(ptr->name, ptr->symbol);
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
DBG("created menu %d\n", win->menu);
|
||||||
|
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
||||||
|
}
|
||||||
|
|
||||||
42
fli_control/events.h
Normal file
42
fli_control/events.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* events.h
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __EVENTS_H__
|
||||||
|
#define __EVENTS_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#include <GL/glext.h>
|
||||||
|
#include <GL/freeglut.h>
|
||||||
|
|
||||||
|
extern float Z; // ËÏÏÒÄÉÎÁÔÁ Z (zoom)
|
||||||
|
|
||||||
|
void keyPressed(unsigned char key, int x, int y);
|
||||||
|
//void keySpPressed(int key, int x, int y);
|
||||||
|
void mousePressed(int key, int state, int x, int y);
|
||||||
|
void mouseMove(int x, int y);
|
||||||
|
void createMenu();
|
||||||
|
void menuEvents(int opt);
|
||||||
|
//void mouseWheel(int button, int dir, int x, int y);
|
||||||
|
|
||||||
|
#endif // __EVENTS_H__
|
||||||
817
fli_control/flifunc.c
Normal file
817
fli_control/flifunc.c
Normal file
@ -0,0 +1,817 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the FLI_control project.
|
||||||
|
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fitsio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
#ifdef USEPNG
|
||||||
|
#include <png.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#endif
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "flifunc.h"
|
||||||
|
#ifdef IMAGEVIEW
|
||||||
|
#include "imageview.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TRYFUNC(f, ...) \
|
||||||
|
do{ if((fli_err = f(__VA_ARGS__))) \
|
||||||
|
WARNX(#f "() failed"); \
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
#define TRYFITS(f, ...) \
|
||||||
|
do{ int status = 0; \
|
||||||
|
f(__VA_ARGS__, &status); \
|
||||||
|
if (status){ \
|
||||||
|
fits_report_error(stderr, status); \
|
||||||
|
return -1;} \
|
||||||
|
}while(0)
|
||||||
|
#define WRITEKEY(...) \
|
||||||
|
do{ int status = 0; \
|
||||||
|
fits_write_key(__VA_ARGS__, &status); \
|
||||||
|
if(status) fits_report_error(stderr, status);\
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
static long fli_err;
|
||||||
|
static char *camera = NULL;
|
||||||
|
static double t_ext, t_int; // external & CCD temperatures @exp. end
|
||||||
|
static time_t expStartsAt; // exposition start time (time_t)
|
||||||
|
static long filterpos = -1; // filter position
|
||||||
|
static long focuserpos = -1; // focuser position
|
||||||
|
|
||||||
|
static int writefits(char *filename, int width, int height, void *data);
|
||||||
|
#ifdef USEPNG
|
||||||
|
static int writepng(char *filename, int width, int height, void *data);
|
||||||
|
#endif
|
||||||
|
#ifdef USERAW
|
||||||
|
static int writeraw(char *filename, int width, int height, void *data);
|
||||||
|
#endif // USERAW
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
flidomain_t domain;
|
||||||
|
char *dname;
|
||||||
|
char *name;
|
||||||
|
}cam_t;
|
||||||
|
|
||||||
|
#define TMBUFSIZ 40
|
||||||
|
static char tm_buf[TMBUFSIZ]; // buffer for string with time value
|
||||||
|
|
||||||
|
static uint16_t max = 0, min = 65535; // max/min values for given image
|
||||||
|
static double avr, std; // stat values
|
||||||
|
static char viewfield[80];
|
||||||
|
static double pixX, pixY; // pixel size in um
|
||||||
|
|
||||||
|
static void print_stat(u_int16_t *img, long size);
|
||||||
|
|
||||||
|
static size_t curtime(char *s_time){ // current date/time
|
||||||
|
time_t tm = time(NULL);
|
||||||
|
return strftime(s_time, TMBUFSIZ, "%d/%m/%Y,%H:%M:%S", localtime(&tm));
|
||||||
|
}
|
||||||
|
|
||||||
|
static fliframe_t frametype = FLI_FRAME_TYPE_NORMAL;
|
||||||
|
|
||||||
|
static int check_filename(char *buff, char *outfile, char *ext){
|
||||||
|
struct stat filestat;
|
||||||
|
int num;
|
||||||
|
for(num = 1; num < 10000; num++){
|
||||||
|
if(snprintf(buff, BUFF_SIZ, "%s_%04d.%s", outfile, num, ext) < 1)
|
||||||
|
return 0;
|
||||||
|
if(stat(buff, &filestat)) // no such file or can't stat()
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0 if OK
|
||||||
|
int fli_init(){
|
||||||
|
char libver[LIBVERSIZ]; // FLI library version
|
||||||
|
// #ifdef EBUG
|
||||||
|
TRYFUNC(FLISetDebugLevel, NULL /* "NO HOST" */, FLIDEBUG_NONE);
|
||||||
|
/* #else
|
||||||
|
TRYFUNC(FLISetDebugLevel, NULL, FLIDEBUG_...);
|
||||||
|
#endif */
|
||||||
|
if(fli_err){
|
||||||
|
WARNX("Can't clear debug level");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
TRYFUNC(FLIGetLibVersion, libver, LIBVERSIZ);
|
||||||
|
// ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
||||||
|
if(!fli_err) verbose(1, _("Library version '%s'"), libver);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int findcams(flidomain_t domain, cam_t **cam){
|
||||||
|
char **tmplist;
|
||||||
|
int numcams = 0;
|
||||||
|
TRYFUNC(FLIList, domain, &tmplist);
|
||||||
|
if (tmplist && tmplist[0]){
|
||||||
|
int i, cams = 0;
|
||||||
|
for (i = 0; tmplist[i]; i++) cams++;
|
||||||
|
if ((*cam = realloc(*cam, (numcams + cams) * sizeof(cam_t))) == NULL)
|
||||||
|
ERR("realloc() failed");
|
||||||
|
for (i = 0; tmplist[i]; i++){
|
||||||
|
int j;
|
||||||
|
cam_t *tmpcam = *cam + i;
|
||||||
|
for (j = 0; tmplist[i][j] != '\0'; j++)
|
||||||
|
if (tmplist[i][j] == ';'){
|
||||||
|
tmplist[i][j] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmpcam->domain = domain;
|
||||||
|
tmpcam->name = strdup(tmplist[i]);
|
||||||
|
switch (domain & 0xff){
|
||||||
|
case FLIDOMAIN_PARALLEL_PORT:
|
||||||
|
tmpcam->dname = "parallel port";
|
||||||
|
break;
|
||||||
|
case FLIDOMAIN_USB:
|
||||||
|
tmpcam->dname = "USB";
|
||||||
|
;
|
||||||
|
break;
|
||||||
|
case FLIDOMAIN_SERIAL:
|
||||||
|
tmpcam->dname = "serial";
|
||||||
|
break;
|
||||||
|
case FLIDOMAIN_INET:
|
||||||
|
tmpcam->dname = "inet";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tmpcam->dname = "Unknown domain";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBG("found: %s @ %s", tmpcam->name, tmpcam->dname);
|
||||||
|
}
|
||||||
|
numcams += cams;
|
||||||
|
}
|
||||||
|
else DBG("No devices");
|
||||||
|
TRYFUNC(FLIFreeList, tmplist);
|
||||||
|
return numcams;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_stat(u_int16_t *img, long size){
|
||||||
|
long i, Noverld = 0L;
|
||||||
|
double pv, sum=0., sum2=0., sz = (double)size;
|
||||||
|
u_int16_t *ptr = img, val;
|
||||||
|
max = 0; min = 65535;
|
||||||
|
for(i = 0; i < size; i++, ptr++){
|
||||||
|
val = *ptr;
|
||||||
|
pv = (double) val;
|
||||||
|
sum += pv;
|
||||||
|
sum2 += (pv * pv);
|
||||||
|
if(max < val) max = val;
|
||||||
|
if(min > val) min = val;
|
||||||
|
if(val >= 65530) Noverld++;
|
||||||
|
}
|
||||||
|
// óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
||||||
|
printf(_("Image stat:\n"));
|
||||||
|
avr = sum/sz;
|
||||||
|
printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr,
|
||||||
|
std = sqrt(fabs(sum2/sz - avr*avr)), Noverld);
|
||||||
|
printf("max = %u, min = %u, size = %ld\n", max, min, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find focusers and work with each of them
|
||||||
|
*/
|
||||||
|
void focusers(){
|
||||||
|
flidev_t dev;
|
||||||
|
int nfocs = 0;
|
||||||
|
long ltmp;
|
||||||
|
char buff[BUFF_SIZ];
|
||||||
|
cam_t *cam = NULL;
|
||||||
|
int num = findcams(FLIDOMAIN_USB | FLIDEVICE_FOCUSER, &cam);
|
||||||
|
for(int i = 0; i < num; i++){
|
||||||
|
TRYFUNC(FLIOpen, &dev, cam[i].name, cam[i].domain);
|
||||||
|
if(fli_err) continue;
|
||||||
|
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
|
||||||
|
if(!fli_err){
|
||||||
|
if(!strcasestr(buff, "focuser")){ // not focuser
|
||||||
|
TRYFUNC(FLIClose, dev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// íÏÄÅÌØ:\t\t%s
|
||||||
|
verbose(1, _("Model:\t\t%s"), buff);
|
||||||
|
}
|
||||||
|
++nfocs;
|
||||||
|
verbose(1, _("Focuser '%s', domain %s"), cam[i].name, cam[i].dname);
|
||||||
|
TRYFUNC(FLIGetHWRevision, dev, <mp);
|
||||||
|
// áÐÐ. ×ÅÒÓÉÑ: %ld
|
||||||
|
if(!fli_err) verbose(1, _("HW revision: %ld"), ltmp);
|
||||||
|
TRYFUNC(FLIGetFWRevision, dev, <mp);
|
||||||
|
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
||||||
|
if(!fli_err) verbose(1, _("SW revision: %ld"), ltmp);
|
||||||
|
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_INTERNAL, &t_ext);
|
||||||
|
if(!fli_err) green("FOCTEMP=%.1f\n", t_ext);
|
||||||
|
long curpos = -1, maxpos = -1;
|
||||||
|
TRYFUNC(FLIGetStepperPosition, dev, <mp);
|
||||||
|
if(!fli_err){
|
||||||
|
curpos = ltmp;
|
||||||
|
}
|
||||||
|
TRYFUNC(FLIGetFocuserExtent, dev, <mp);
|
||||||
|
if(!fli_err){
|
||||||
|
green("FOCMAXPOS=%ld\n", ltmp);
|
||||||
|
maxpos = ltmp;
|
||||||
|
}
|
||||||
|
do{
|
||||||
|
if(GP->gotopos != INT_MAX && GP->addsteps != INT_MAX){
|
||||||
|
// îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
||||||
|
WARNX(_("You can't use both relative and absolute position"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(curpos < 0 || maxpos < 0){
|
||||||
|
// ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
||||||
|
WARNX(_("Error in position detection"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
long pos = -1, steps = 0;
|
||||||
|
if(GP->gotopos != INT_MAX){ // absolute pointing
|
||||||
|
pos = GP->gotopos;
|
||||||
|
steps = pos - curpos;
|
||||||
|
}else if(GP->addsteps != INT_MAX){ // relative pointing
|
||||||
|
steps = GP->addsteps;
|
||||||
|
pos = curpos + steps;
|
||||||
|
}else break;
|
||||||
|
if(!steps){
|
||||||
|
verbose(1, _("Already at position"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(pos > maxpos || pos < 0){
|
||||||
|
// ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
||||||
|
WARNX(_("Position should be in 0...%ld"), maxpos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(pos == 0){
|
||||||
|
// ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
||||||
|
verbose(1, _("Moving to home position"));
|
||||||
|
if(GP->async) TRYFUNC(FLIHomeDevice, dev);
|
||||||
|
else TRYFUNC(FLIHomeFocuser, dev);
|
||||||
|
}else{
|
||||||
|
// ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
||||||
|
verbose(1, _("Moving for %ld steps"), steps);
|
||||||
|
if(GP->async) TRYFUNC(FLIStepMotorAsync, dev, steps);
|
||||||
|
else TRYFUNC(FLIStepMotor, dev, steps);
|
||||||
|
}
|
||||||
|
}while(0);
|
||||||
|
TRYFUNC(FLIGetStepperPosition, dev, &focuserpos);
|
||||||
|
if(!fli_err){
|
||||||
|
green("FOCPOS=%ld\n", focuserpos);
|
||||||
|
curpos = focuserpos;
|
||||||
|
}else DBG("Error getting fpos: %ld", fli_err);
|
||||||
|
TRYFUNC(FLIClose, dev);
|
||||||
|
}
|
||||||
|
if(!nfocs) WARNX(_("No focusers found"));
|
||||||
|
for(int i = 0; i < num; i++) FREE(cam[i].name);
|
||||||
|
FREE(cam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find wheels and work with each of them
|
||||||
|
*/
|
||||||
|
void wheels(){
|
||||||
|
cam_t *cam = NULL;
|
||||||
|
flidev_t dev;
|
||||||
|
long ltmp;
|
||||||
|
char buff[BUFF_SIZ];
|
||||||
|
int nwheels = 0;
|
||||||
|
int num = findcams(FLIDOMAIN_USB | FLIDEVICE_FILTERWHEEL, &cam);
|
||||||
|
for(int i = 0; i < num; i++){
|
||||||
|
TRYFUNC(FLIOpen, &dev, cam[i].name, cam[i].domain);
|
||||||
|
if(fli_err) continue;
|
||||||
|
TRYFUNC(FLIGetFilterCount, dev, <mp);
|
||||||
|
if(fli_err || ltmp < 2){// not a wheel
|
||||||
|
TRYFUNC(FLIClose, dev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
verbose(1, _("Wheel '%s', domain %s"), cam[i].name, cam[i].dname);
|
||||||
|
green("WHEELTOTALPOS=%ld\n", ltmp);
|
||||||
|
int wheelmaxpos = (int)ltmp - 1;
|
||||||
|
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
|
||||||
|
// íÏÄÅÌØ:\t\t%s
|
||||||
|
if(!fli_err) verbose(1, _("Model:\t\t%s"), buff);
|
||||||
|
TRYFUNC(FLIGetHWRevision, dev, <mp);
|
||||||
|
// áÐÐ. ×ÅÒÓÉÑ: %ld
|
||||||
|
if(!fli_err) verbose(1, _("HW revision: %ld"), ltmp);
|
||||||
|
TRYFUNC(FLIGetFWRevision, dev, <mp);
|
||||||
|
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
||||||
|
if(!fli_err) verbose(1, _("SW revision: %ld"), ltmp);
|
||||||
|
else goto closewheeldev;
|
||||||
|
if(GP->setwheel > -1 && GP->setwheel >= ltmp){
|
||||||
|
GP->setwheel = -1;
|
||||||
|
WARNX(_("Wheel position should be from 0 to %ld"), ltmp - 1);
|
||||||
|
}
|
||||||
|
++nwheels;
|
||||||
|
if(GP->setwheel > -1){
|
||||||
|
ltmp = GP->setwheel;
|
||||||
|
if(ltmp > wheelmaxpos){
|
||||||
|
WARNX(_("Position is too big (max %d)"), wheelmaxpos);
|
||||||
|
goto closewheeldev;
|
||||||
|
}
|
||||||
|
TRYFUNC(FLISetFilterPos, dev, ltmp);
|
||||||
|
if(!fli_err) verbose(1, _("Arrive to position"));
|
||||||
|
}
|
||||||
|
// this function returns -1 every connection without SETpos!!!
|
||||||
|
TRYFUNC(FLIGetFilterPos, dev, &filterpos);
|
||||||
|
if(!fli_err && filterpos > -1){
|
||||||
|
green("WHEELPOS=%ld\n", filterpos);
|
||||||
|
}else{
|
||||||
|
filterpos = -1;
|
||||||
|
// so try to check current position by steps
|
||||||
|
TRYFUNC(FLIGetStepperPosition, dev, <mp);
|
||||||
|
if(ltmp < 0) ltmp = -ltmp;
|
||||||
|
DBG("steps: %ld", ltmp);
|
||||||
|
if(!fli_err){
|
||||||
|
int pos = (ltmp - WHEEL_POS0STPS+WHEEL_STEPPOS/2)/WHEEL_STEPPOS;
|
||||||
|
DBG("pos = %d", pos);
|
||||||
|
if(pos > -1 && pos <= wheelmaxpos){
|
||||||
|
filterpos = pos;
|
||||||
|
green("WHEELPOS=%ld\n", filterpos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closewheeldev:
|
||||||
|
TRYFUNC(FLIClose, dev);
|
||||||
|
}
|
||||||
|
if(!nwheels) WARNX(_("No wheels found"));
|
||||||
|
for (int i = 0; i < num; i++)
|
||||||
|
FREE(cam[i].name);
|
||||||
|
FREE(cam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief grabImage - grab image into `ima`
|
||||||
|
* @param ima (io) - prepared IMG structure with allocated data & initialized sizes
|
||||||
|
* @param dev - device
|
||||||
|
*/
|
||||||
|
static void grabImage(IMG *ima, flidev_t dev){
|
||||||
|
FNAME();
|
||||||
|
long ltmp;
|
||||||
|
TRYFUNC(FLIGetTemperature, dev, &GP->temperature); // temperature @ exp. start
|
||||||
|
TRYFUNC(FLIExposeFrame, dev);
|
||||||
|
expStartsAt = time(NULL); // ×ÒÅÍÑ ÎÁÞÁÌÁ ÜËÓÐÏÚÉÃÉÉ
|
||||||
|
do{
|
||||||
|
TRYFUNC(FLIGetTemperature, dev, &t_int);
|
||||||
|
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
|
||||||
|
if(curtime(tm_buf)){
|
||||||
|
// ÄÁÔÁ/×ÒÅÍÑ
|
||||||
|
verbose(1, "%s: %s\tText=%.2f\tTint=%.2f\n", _("date/time"), tm_buf, t_ext, t_int);
|
||||||
|
}
|
||||||
|
else WARNX("curtime() error");
|
||||||
|
TRYFUNC(FLIGetExposureStatus, dev, <mp);
|
||||||
|
if(fli_err) continue;
|
||||||
|
if(GP->shtr_cmd > 0 && GP->shtr_cmd & FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL && ltmp == GP->exptime){
|
||||||
|
// "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
||||||
|
printf(_("wait for external trigger...\n"));
|
||||||
|
sleep(1);
|
||||||
|
}else{
|
||||||
|
// %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
||||||
|
printf(_("%.3f seconds till exposition ends\n"), ((float)ltmp) / 1000.);
|
||||||
|
if(ltmp > 10000) sleep(10);
|
||||||
|
else usleep(ltmp * 1000);
|
||||||
|
}
|
||||||
|
}while(ltmp);
|
||||||
|
// óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
||||||
|
printf(_("Read image: "));
|
||||||
|
int portion = 0;
|
||||||
|
for(int row = 0; row < ima->h; row++){
|
||||||
|
TRYFUNC(FLIGrabRow, dev, &ima->data[row * ima->w], ima->w);
|
||||||
|
if(fli_err) break;
|
||||||
|
int progress = (int)(((float)row / (float)ima->h) * 100.);
|
||||||
|
if(progress/5 > portion){
|
||||||
|
if((++portion)%2) printf("..");
|
||||||
|
else printf("%d%%", portion*5);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("100%%\n");
|
||||||
|
curtime(tm_buf);
|
||||||
|
print_stat(ima->data, ima->h*ima->w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find CCDs and work with each of them
|
||||||
|
*/
|
||||||
|
void ccds(){
|
||||||
|
#ifdef IMAGEVIEW
|
||||||
|
windowData *mainwin = NULL;
|
||||||
|
if(GP->showimage) imageview_init();
|
||||||
|
#endif
|
||||||
|
cam_t *cam = NULL;
|
||||||
|
flidev_t dev;
|
||||||
|
long ltmp;
|
||||||
|
char buff[BUFF_SIZ];
|
||||||
|
int num = findcams(FLIDOMAIN_USB | FLIDEVICE_CAMERA, &cam);
|
||||||
|
if(!num) WARNX(_("No CCD found"));
|
||||||
|
for(int i = 0; i < num; i++){
|
||||||
|
long x0,x1, y0,y1, img_rows, row_width;
|
||||||
|
// ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
||||||
|
verbose(1, _("Camera '%s', domain %s"), cam[i].name, cam[i].dname);
|
||||||
|
TRYFUNC(FLIOpen, &dev, cam[i].name, cam[i].domain);
|
||||||
|
if(fli_err) continue;
|
||||||
|
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
|
||||||
|
// íÏÄÅÌØ:\t\t%s
|
||||||
|
if(!fli_err) verbose(1, _("Model:\t\t%s"), buff);
|
||||||
|
camera = strdup(buff);
|
||||||
|
TRYFUNC(FLIGetHWRevision, dev, <mp);
|
||||||
|
// áÐÐ. ×ÅÒÓÉÑ: %ld
|
||||||
|
if(!fli_err) verbose(1, _("HW revision: %ld"), ltmp);
|
||||||
|
TRYFUNC(FLIGetFWRevision, dev, <mp);
|
||||||
|
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
||||||
|
if(!fli_err) verbose(1, _("SW revision: %ld"), ltmp);
|
||||||
|
TRYFUNC(FLIGetPixelSize, dev, &pixX, &pixY);
|
||||||
|
// òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
||||||
|
if(!fli_err) verbose(1, _("Pixel size: %g x %g"), pixX, pixY);
|
||||||
|
TRYFUNC(FLIGetVisibleArea, dev, &x0, &y0, &x1, &y1);
|
||||||
|
snprintf(viewfield, 80, "(%ld, %ld)(%ld, %ld)", x0, y0, x1, y1);
|
||||||
|
// ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
||||||
|
if(!fli_err) verbose(1, _("Field of view: %s"), viewfield);
|
||||||
|
if(GP->X1 > x1) GP->X1 = x1;
|
||||||
|
if(GP->Y1 > y1) GP->Y1 = y1;
|
||||||
|
TRYFUNC(FLIGetArrayArea, dev, &x0, &y0, &x1, &y1);
|
||||||
|
// ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
||||||
|
if(!fli_err) verbose(1, _("Array field: (%ld, %ld)(%ld, %ld)"), x0, y0, x1, y1);
|
||||||
|
TRYFUNC(FLISetHBin, dev, GP->hbin);
|
||||||
|
TRYFUNC(FLISetVBin, dev, GP->vbin);
|
||||||
|
if(GP->X0 == -1) GP->X0 = x0; // default values
|
||||||
|
if(GP->Y0 == -1) GP->Y0 = y0;
|
||||||
|
if(GP->X1 == -1) GP->X1 = x1;
|
||||||
|
if(GP->Y1 == -1) GP->Y1 = y1;
|
||||||
|
row_width = (GP->X1 - GP->X0) / GP->hbin;
|
||||||
|
img_rows = (GP->Y1 - GP->Y0) / GP->vbin;
|
||||||
|
TRYFUNC(FLISetImageArea, dev, GP->X0, GP->Y0,
|
||||||
|
GP->X0 + (GP->X1 - GP->X0) / GP->hbin, GP->Y0 + (GP->Y1 - GP->Y0) / GP->vbin);
|
||||||
|
TRYFUNC(FLISetNFlushes, dev, GP->nflushes);
|
||||||
|
if(GP->temperature < 40.){
|
||||||
|
// "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
||||||
|
green(_("Set CCD temperature to %g degr.C\n"), GP->temperature);
|
||||||
|
TRYFUNC(FLISetTemperature, dev, GP->temperature);
|
||||||
|
}
|
||||||
|
TRYFUNC(FLIGetTemperature, dev, &t_int);
|
||||||
|
if(!fli_err) green("CCDTEMP=%.1f\n", t_int);
|
||||||
|
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
|
||||||
|
if(!fli_err) green("EXTTEMP=%.1f\n", t_ext);
|
||||||
|
if(GP->shtr_cmd > -1){
|
||||||
|
flishutter_t shtr = GP->shtr_cmd;
|
||||||
|
char *str = NULL;
|
||||||
|
switch(shtr){
|
||||||
|
case FLI_SHUTTER_CLOSE:
|
||||||
|
str = "close";
|
||||||
|
break;
|
||||||
|
case FLI_SHUTTER_OPEN:
|
||||||
|
str = "open";
|
||||||
|
break;
|
||||||
|
case FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_LOW:
|
||||||
|
str = "open @ LOW";
|
||||||
|
break;
|
||||||
|
case FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH:
|
||||||
|
str = "open @ HIGH";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str = "WTF?";
|
||||||
|
}
|
||||||
|
green(_("%s CCD shutter\n"), str);
|
||||||
|
TRYFUNC(FLIControlShutter, dev, shtr);
|
||||||
|
}
|
||||||
|
if(GP->confio > -1){
|
||||||
|
// "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
||||||
|
green(_("Try to convfigure I/O port as %d\n"), GP->confio);
|
||||||
|
TRYFUNC(FLIConfigureIOPort, dev, GP->confio);
|
||||||
|
}
|
||||||
|
if(GP->getio){
|
||||||
|
long iop;
|
||||||
|
TRYFUNC(FLIReadIOPort, dev, &iop);
|
||||||
|
if(!fli_err) green("CCDIOPORT=0x%02lx\n", iop);
|
||||||
|
}
|
||||||
|
if(GP->setio > -1){
|
||||||
|
// "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
||||||
|
green(_("Try to write %d to I/O port\n"), GP->setio);
|
||||||
|
TRYFUNC(FLIWriteIOPort, dev, GP->setio);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GP->exptime < DBL_EPSILON) continue;
|
||||||
|
TRYFUNC(FLISetExposureTime, dev, GP->exptime);
|
||||||
|
if(GP->dark) frametype = FLI_FRAME_TYPE_DARK;
|
||||||
|
TRYFUNC(FLISetFrameType, dev, frametype);
|
||||||
|
if(GP->_8bit){
|
||||||
|
TRYFUNC(FLISetBitDepth, dev, FLI_MODE_8BIT);
|
||||||
|
if(fli_err == 0) green(_("8 bit mode\n"));
|
||||||
|
}
|
||||||
|
TRYFUNC(FLISetCameraMode, dev, GP->fast ? 0 : 1);
|
||||||
|
if(GP->fast) green(_("Fast readout mode\n"));
|
||||||
|
if(!GP->outfile) red(_("Only show statistics\n"));
|
||||||
|
uint16_t *img = MALLOC(uint16_t, img_rows * row_width);
|
||||||
|
IMG ima = {.data = img, .w = row_width, .h = img_rows};
|
||||||
|
for(int j = 0; j < GP->nframes; j ++){
|
||||||
|
printf("\n\n");
|
||||||
|
// úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
||||||
|
printf(_("Capture frame %d\n"), j);
|
||||||
|
grabImage(&ima, dev);
|
||||||
|
saveImages(&ima, GP->outfile);
|
||||||
|
#ifdef IMAGEVIEW
|
||||||
|
if(GP->showimage){ // display image
|
||||||
|
if(!(mainwin = getWin())){
|
||||||
|
DBG("Create new win");
|
||||||
|
mainwin = createGLwin("Sample window", row_width, img_rows, NULL);
|
||||||
|
if(!mainwin){
|
||||||
|
WARNX("Can't open OpenGL window, image preview will be inaccessible");
|
||||||
|
}else
|
||||||
|
pthread_create(&mainwin->thread, NULL, &image_thread, (void*)&ima);
|
||||||
|
}
|
||||||
|
if((mainwin = getWin())){
|
||||||
|
DBG("change image");
|
||||||
|
change_displayed_image(mainwin, &ima);
|
||||||
|
while((mainwin = getWin())){ // test paused state & grabbing custom frames
|
||||||
|
if((mainwin->winevt & WINEVT_PAUSE) == 0) break;
|
||||||
|
if(mainwin->winevt & WINEVT_GETIMAGE){
|
||||||
|
mainwin->winevt &= ~WINEVT_GETIMAGE;
|
||||||
|
grabImage(&ima, dev);
|
||||||
|
change_displayed_image(mainwin, &ima);
|
||||||
|
}
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(GP->pause_len && j != (GP->nframes - 1)){
|
||||||
|
double delta, time1 = dtime() + GP->pause_len;
|
||||||
|
while((delta = time1 - dtime()) > 0.){
|
||||||
|
// %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
||||||
|
printf(_("%d seconds till pause ends\n"), (int)delta);
|
||||||
|
TRYFUNC(FLIGetTemperature, dev, &t_int);
|
||||||
|
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
|
||||||
|
if(curtime(tm_buf)){
|
||||||
|
// ÄÁÔÁ/×ÒÅÍÑ
|
||||||
|
verbose(1, "%s: %s\tText=%.2f\tTint=%.2f\n", _("date/time"), tm_buf, t_ext, t_int);
|
||||||
|
}
|
||||||
|
else verbose(1, "curtime() error");
|
||||||
|
if(delta > 10) sleep(10);
|
||||||
|
else sleep((int)delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef IMAGEVIEW
|
||||||
|
if(GP->showimage){
|
||||||
|
mainwin->winevt |= WINEVT_PAUSE;
|
||||||
|
DBG("Waiting");
|
||||||
|
while((mainwin = getWin())){
|
||||||
|
if(mainwin->killthread) break;
|
||||||
|
if(mainwin->winevt & WINEVT_GETIMAGE){
|
||||||
|
DBG("GRAB");
|
||||||
|
mainwin->winevt &= ~WINEVT_GETIMAGE;
|
||||||
|
grabImage(&ima, dev);
|
||||||
|
change_displayed_image(mainwin, &ima);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("Close window");
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
FREE(camera);
|
||||||
|
FREE(img);
|
||||||
|
TRYFUNC(FLIClose, dev);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < num; i++)
|
||||||
|
FREE(cam[i].name);
|
||||||
|
FREE(cam);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveImages(IMG *img, char *filename){
|
||||||
|
inline void WRITEIMG(int (*writefn)(char*,int,int,void*), char *ext){
|
||||||
|
char buff[BUFF_SIZ];
|
||||||
|
if(filename == NULL) return;
|
||||||
|
if(!check_filename(buff, filename, ext) && !GP->rewrite)
|
||||||
|
// îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
||||||
|
WARNX(_("Can't save file"));
|
||||||
|
else{
|
||||||
|
if(GP->rewrite){
|
||||||
|
DBG("REW");
|
||||||
|
char *p = "";
|
||||||
|
if(strcmp(ext, "fit") == 0) p = "!";
|
||||||
|
snprintf(buff, BUFF_SIZ, "%s%s.%s", p, filename, ext);
|
||||||
|
}
|
||||||
|
TRYFUNC(writefn, buff, img->w, img->h, (void*)img->data);
|
||||||
|
// æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
||||||
|
if (fli_err == 0) verbose(1, _("File saved as '%s'"), buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef USERAW
|
||||||
|
WRITEIMG(writeraw, "raw");
|
||||||
|
#endif
|
||||||
|
WRITEIMG(writefits, "fit");
|
||||||
|
#ifdef USEPNG
|
||||||
|
WRITEIMG(writepng, "png");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USERAW
|
||||||
|
static int writeraw(char *filename, int width, int height, void *data){
|
||||||
|
int fd, size, err;
|
||||||
|
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
||||||
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) == -1){
|
||||||
|
WARN("open(%s) failed", filename);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
size = width * height * sizeof(u_int16_t);
|
||||||
|
if ((err = write(fd, data, size)) != size){
|
||||||
|
WARN("write() failed");
|
||||||
|
err = -errno;
|
||||||
|
}
|
||||||
|
else err = 0;
|
||||||
|
close(fd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif // USERAW
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief addrec - add FITS records from file
|
||||||
|
* @param f (i) - FITS filename
|
||||||
|
* @param filename (i) - name of file
|
||||||
|
*/
|
||||||
|
static void addrec(fitsfile *f, char *filename){
|
||||||
|
FILE *fp = fopen(filename, "r");
|
||||||
|
if(!fp) return;
|
||||||
|
char buf[2*FLEN_CARD];
|
||||||
|
while(fgets(buf, 2*FLEN_CARD, fp)){
|
||||||
|
DBG("check record _%s_", buf);
|
||||||
|
int keytype, status = 0;
|
||||||
|
char newcard[FLEN_CARD], keyname[FLEN_CARD];
|
||||||
|
fits_parse_template(buf, newcard, &keytype, &status);
|
||||||
|
if(status){
|
||||||
|
fits_report_error(stderr, status);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
DBG("reformatted to _%s_", newcard);
|
||||||
|
strncpy(keyname, newcard, FLEN_CARD);
|
||||||
|
char *eq = strchr(keyname, '='); if(eq) *eq = 0;
|
||||||
|
eq = strchr(keyname, ' '); if(eq) *eq = 0;
|
||||||
|
DBG("keyname: %s", keyname);
|
||||||
|
fits_update_card(f, keyname, newcard, &status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int writefits(char *filename, int width, int height, void *data){
|
||||||
|
long naxes[2] = {width, height}, startTime;
|
||||||
|
double tmp = 0.0;
|
||||||
|
struct tm *tm_starttime;
|
||||||
|
char buf[FLEN_CARD];
|
||||||
|
time_t savetime = time(NULL);
|
||||||
|
fitsfile *fp;
|
||||||
|
TRYFITS(fits_create_file, &fp, filename);
|
||||||
|
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
||||||
|
// FILE / Input file original name
|
||||||
|
WRITEKEY(fp, TSTRING, "FILE", filename, "Input file original name");
|
||||||
|
// ORIGIN / organization responsible for the data
|
||||||
|
WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data");
|
||||||
|
// OBSERVAT / Observatory name
|
||||||
|
WRITEKEY(fp, TSTRING, "OBSERVAT", "Special Astrophysical Observatory, Russia", "Observatory name");
|
||||||
|
// DETECTOR / detector
|
||||||
|
if(camera){
|
||||||
|
WRITEKEY(fp, TSTRING, "DETECTOR", camera, "Detector model");
|
||||||
|
}
|
||||||
|
// INSTRUME / Instrument
|
||||||
|
if(GP->instrument){
|
||||||
|
WRITEKEY(fp, TSTRING, "INSTRUME", GP->instrument, "Instrument");
|
||||||
|
}else
|
||||||
|
WRITEKEY(fp, TSTRING, "INSTRUME", "direct imaging", "Instrument");
|
||||||
|
snprintf(buf, 80, "%.g x %.g", pixX, pixY);
|
||||||
|
// PXSIZE / pixel size
|
||||||
|
WRITEKEY(fp, TSTRING, "PXSIZE", buf, "Pixel size in m");
|
||||||
|
WRITEKEY(fp, TSTRING, "VIEWFLD", viewfield, "Camera field of view");
|
||||||
|
// CRVAL1, CRVAL2 / Offset in X, Y
|
||||||
|
if(GP->X0) WRITEKEY(fp, TINT, "X0", &GP->X0, "Subframe left border");
|
||||||
|
if(GP->Y0) WRITEKEY(fp, TINT, "Y0", &GP->Y0, "Subframe upper border");
|
||||||
|
if(GP->exptime < 2.*DBL_EPSILON) sprintf(buf, "bias");
|
||||||
|
else if(frametype == FLI_FRAME_TYPE_DARK) sprintf(buf, "dark");
|
||||||
|
else if(GP->objtype) strncpy(buf, GP->objtype, FLEN_CARD-1);
|
||||||
|
else sprintf(buf, "object");
|
||||||
|
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
|
||||||
|
WRITEKEY(fp, TSTRING, "IMAGETYP", buf, "Image type");
|
||||||
|
// DATAMAX, DATAMIN / Max,min pixel value
|
||||||
|
int itmp = 0;
|
||||||
|
WRITEKEY(fp, TINT, "DATAMIN", &itmp, "Min pixel value");
|
||||||
|
//itmp = GP->fast ? 255 : 65535;
|
||||||
|
itmp = 65535;
|
||||||
|
WRITEKEY(fp, TINT, "DATAMAX", &itmp, "Max pixel value");
|
||||||
|
WRITEKEY(fp, TUSHORT, "STATMAX", &max, "Max data value");
|
||||||
|
WRITEKEY(fp, TUSHORT, "STATMIN", &min, "Min data value");
|
||||||
|
WRITEKEY(fp, TDOUBLE, "STATAVR", &avr, "Average data value");
|
||||||
|
WRITEKEY(fp, TDOUBLE, "STATSTD", &std, "Std. of data value");
|
||||||
|
WRITEKEY(fp, TDOUBLE, "TEMP0", &GP->temperature, "Camera temperature at exp. start (degr C)");
|
||||||
|
WRITEKEY(fp, TDOUBLE, "TEMP1", &t_int, "Camera temperature at exp. end (degr C)");
|
||||||
|
WRITEKEY(fp, TDOUBLE, "TEMPBODY", &t_ext, "Camera body temperature at exp. end (degr C)");
|
||||||
|
tmp = (GP->temperature + t_int) / 2. + 273.15;
|
||||||
|
// CAMTEMP / Camera temperature (K)
|
||||||
|
WRITEKEY(fp, TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)");
|
||||||
|
// WHEEL & FOCUSER positions:
|
||||||
|
tmp = (double)focuserpos / FOCSCALE;
|
||||||
|
WRITEKEY(fp, TDOUBLE, "FOCUS", &tmp, "Current focuser position, mm");
|
||||||
|
if(filterpos > -1)
|
||||||
|
WRITEKEY(fp, TINT, "FILTER", &filterpos, "Current filter number");
|
||||||
|
// EXPTIME / actual exposition time (sec)
|
||||||
|
tmp = (double)GP->exptime / 1000.;
|
||||||
|
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmp, "Actual exposition time (sec)");
|
||||||
|
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
|
||||||
|
strftime(buf, 80, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
|
||||||
|
WRITEKEY(fp, TSTRING, "DATE", buf, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
|
||||||
|
startTime = (long)expStartsAt;
|
||||||
|
tm_starttime = localtime(&expStartsAt);
|
||||||
|
strftime(buf, 80, "Exposition start time (UNIX)", tm_starttime);
|
||||||
|
WRITEKEY(fp, TLONG, "UNIXTIME", &startTime, buf);
|
||||||
|
strftime(buf, 80, "%Y/%m/%d", tm_starttime);
|
||||||
|
// DATE-OBS / DATE (YYYY/MM/DD) OF OBS.
|
||||||
|
WRITEKEY(fp, TSTRING, "DATE-OBS", buf, "DATE OF OBS. (YYYY/MM/DD, local)");
|
||||||
|
strftime(buf, 80, "%H:%M:%S", tm_starttime);
|
||||||
|
// START / Measurement start time (local) (hh:mm:ss)
|
||||||
|
WRITEKEY(fp, TSTRING, "START", buf, "Measurement start time (hh:mm:ss, local)");
|
||||||
|
// OBJECT / Object name
|
||||||
|
if(GP->objname){
|
||||||
|
WRITEKEY(fp, TSTRING, "OBJECT", GP->objname, "Object name");
|
||||||
|
}
|
||||||
|
// BINNING / Binning
|
||||||
|
if(GP->hbin != 1 || GP->vbin != 1){
|
||||||
|
snprintf(buf, 80, "%d x %d", GP->hbin, GP->vbin);
|
||||||
|
WRITEKEY(fp, TSTRING, "BINNING", buf, "Binning (hbin x vbin)");
|
||||||
|
}
|
||||||
|
// OBSERVER / Observers
|
||||||
|
if(GP->observers){
|
||||||
|
WRITEKEY(fp, TSTRING, "OBSERVER", GP->observers, "Observers");
|
||||||
|
}
|
||||||
|
// PROG-ID / Observation program identifier
|
||||||
|
if(GP->prog_id){
|
||||||
|
WRITEKEY(fp, TSTRING, "PROG-ID", GP->prog_id, "Observation program identifier");
|
||||||
|
}
|
||||||
|
// AUTHOR / Author of the program
|
||||||
|
if(GP->author){
|
||||||
|
WRITEKEY(fp, TSTRING, "AUTHOR", GP->author, "Author of the program");
|
||||||
|
}
|
||||||
|
if(GP->addhdr){ // add records from files
|
||||||
|
char **nxtfile = GP->addhdr;
|
||||||
|
while(*nxtfile){
|
||||||
|
addrec(fp, *nxtfile++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data);
|
||||||
|
TRYFITS(fits_close_file, fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USEPNG
|
||||||
|
static int writepng(char *filename, int width, int height, void *data){
|
||||||
|
int err;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
png_structp pngptr = NULL;
|
||||||
|
png_infop infoptr = NULL;
|
||||||
|
void *row;
|
||||||
|
if ((fp = fopen(filename, "wb")) == NULL){
|
||||||
|
err = -errno;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||||
|
NULL, NULL, NULL)) == NULL){
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((infoptr = png_create_info_struct(pngptr)) == NULL){
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
png_init_io(pngptr, fp);
|
||||||
|
png_set_compression_level(pngptr, Z_BEST_COMPRESSION);
|
||||||
|
png_set_IHDR(pngptr, infoptr, width, height, 16, PNG_COLOR_TYPE_GRAY,
|
||||||
|
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||||
|
PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
png_write_info(pngptr, infoptr);
|
||||||
|
png_set_swap(pngptr);
|
||||||
|
for(row = data; height > 0; row += width * sizeof(u_int16_t), height--)
|
||||||
|
png_write_row(pngptr, row);
|
||||||
|
png_write_end(pngptr, infoptr);
|
||||||
|
err = 0;
|
||||||
|
done:
|
||||||
|
if(fp) fclose(fp);
|
||||||
|
if(pngptr) png_destroy_write_struct(&pngptr, &infoptr);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif /* USEPNG */
|
||||||
|
|
||||||
|
|
||||||
60
fli_control/flifunc.h
Normal file
60
fli_control/flifunc.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the FLI_control project.
|
||||||
|
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef FLIFUNC_H__
|
||||||
|
#define FLIFUNC_H__
|
||||||
|
|
||||||
|
#include <libfli.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define LIBVERSIZ 1024
|
||||||
|
#define BUFF_SIZ 4096
|
||||||
|
|
||||||
|
#ifndef FLIUSB_VENDORID
|
||||||
|
#define FLIUSB_VENDORID 0xf18
|
||||||
|
#endif
|
||||||
|
#ifndef FLIUSB_PROLINE_ID
|
||||||
|
#define FLIUSB_PROLINE_ID 0x0a
|
||||||
|
#endif
|
||||||
|
#ifndef FLIUSB_FILTER_ID
|
||||||
|
#define FLIUSB_FILTER_ID 0x07
|
||||||
|
#endif
|
||||||
|
#ifndef FLIUSB_FOCUSER_ID
|
||||||
|
#define FLIUSB_FOCUSER_ID 0x06
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// wheel position in steps = WHEEL_POS0STPS + WHEEL_STEPPOS*N
|
||||||
|
#define WHEEL_POS0STPS (239)
|
||||||
|
#define WHEEL_STEPPOS (48)
|
||||||
|
// 1mm == FOCSCALE steps of focuser
|
||||||
|
#define FOCSCALE (10000.)
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
uint16_t *data;
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
} IMG;
|
||||||
|
|
||||||
|
int fli_init();
|
||||||
|
void focusers();
|
||||||
|
void wheels();
|
||||||
|
void ccds();
|
||||||
|
void saveImages(IMG *img, char *filename);
|
||||||
|
|
||||||
|
#endif // FLIFUNC_H__
|
||||||
463
fli_control/imageview.c
Normal file
463
fli_control/imageview.c
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the FLI_control project.
|
||||||
|
* Copyright 2020 Edward V. Emelianov <edward.emelianoff@gmail.com>.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <X11/Xlib.h> // XInitThreads();
|
||||||
|
#include <math.h> // roundf(), log(), sqrt()
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "cmdlnopts.h"
|
||||||
|
#include "imageview.h"
|
||||||
|
|
||||||
|
static windowData *win = NULL; // main window
|
||||||
|
static pthread_t GLUTthread = 0; // main GLUT thread
|
||||||
|
|
||||||
|
static int initialized = 0; // ==1 if GLUT is initialized; ==0 after clear_GL_context
|
||||||
|
|
||||||
|
static void *Redraw(_U_ void *p);
|
||||||
|
static void createWindow();
|
||||||
|
static void RedrawWindow();
|
||||||
|
static void Resize(int width, int height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate window properties on creating & resizing
|
||||||
|
*/
|
||||||
|
void calc_win_props(GLfloat *Wortho, GLfloat *Hortho){
|
||||||
|
if(!win || ! win->image) return;
|
||||||
|
float a, A, w, h, W, H;
|
||||||
|
float Zoom = win->zoom;
|
||||||
|
w = (float)win->image->w / 2.f;
|
||||||
|
h = (float)win->image->h / 2.f;
|
||||||
|
W = (float)win->w;
|
||||||
|
H =(float) win->h;
|
||||||
|
A = W / H;
|
||||||
|
a = w / h;
|
||||||
|
if(A > a){ // now W & H are parameters for glOrtho
|
||||||
|
win->Daspect = (float)h / H * 2.f;
|
||||||
|
W = h * A; H = h;
|
||||||
|
}else{
|
||||||
|
win->Daspect = (float)w / W * 2.f;
|
||||||
|
H = w / A; W = w;
|
||||||
|
}
|
||||||
|
if(Wortho) *Wortho = W;
|
||||||
|
if(Hortho) *Hortho = H;
|
||||||
|
// calculate coordinates of center
|
||||||
|
win->x0 = W/Zoom - w + win->x / Zoom;
|
||||||
|
win->y0 = H/Zoom + h - win->y / Zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create window & run main loop
|
||||||
|
*/
|
||||||
|
static void createWindow(){
|
||||||
|
DBG("ini=%d, win %s", initialized, win ? "yes" : "no");
|
||||||
|
if(!initialized) return;
|
||||||
|
if(!win) return;
|
||||||
|
int w = win->w, h = win->h;
|
||||||
|
DBG("create window with title %s", win->title);
|
||||||
|
glutInitWindowSize(w, h);
|
||||||
|
win->ID = glutCreateWindow(win->title);
|
||||||
|
DBG("created GL_ID=%d", win->ID);
|
||||||
|
glutReshapeFunc(Resize);
|
||||||
|
glutDisplayFunc(RedrawWindow);
|
||||||
|
glutKeyboardFunc(keyPressed);
|
||||||
|
//glutSpecialFunc(keySpPressed);
|
||||||
|
//glutMouseWheelFunc(mouseWheel);
|
||||||
|
glutMouseFunc(mousePressed);
|
||||||
|
glutMotionFunc(mouseMove);
|
||||||
|
//glutIdleFunc(glutPostRedisplay);
|
||||||
|
glutIdleFunc(RedrawWindow);
|
||||||
|
DBG("init textures");
|
||||||
|
glGenTextures(1, &(win->Tex));
|
||||||
|
calc_win_props(NULL, NULL);
|
||||||
|
win->zoom = 1. / win->Daspect;
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
// the hext 4 lines need to unaligned storage
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||||
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, win->Tex);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, win->image->w, win->image->h, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
createMenu();
|
||||||
|
DBG("Window opened");
|
||||||
|
}
|
||||||
|
|
||||||
|
int killwindow(){
|
||||||
|
if(!win) return 0;
|
||||||
|
if(!win->killthread){
|
||||||
|
// say threads to die
|
||||||
|
win->killthread = 1;
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&win->mutex);
|
||||||
|
//pthread_join(win->thread, NULL); // wait while thread dies
|
||||||
|
if(win->menu) glutDestroyMenu(win->menu);
|
||||||
|
glutDestroyWindow(win->ID);
|
||||||
|
DBG("destroy menu, wundow & texture %d", win->Tex);
|
||||||
|
glDeleteTextures(1, &(win->Tex));
|
||||||
|
glutLeaveMainLoop();
|
||||||
|
DBG("Cancel");
|
||||||
|
windowData *old = win;
|
||||||
|
win = NULL;
|
||||||
|
DBG("free(rawdata)");
|
||||||
|
FREE(old->image->rawdata);
|
||||||
|
DBG("free(image)");
|
||||||
|
FREE(old->image);
|
||||||
|
pthread_mutex_unlock(&old->mutex);
|
||||||
|
DBG("free(win)");
|
||||||
|
FREE(old);
|
||||||
|
DBG("return");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color){
|
||||||
|
if(!initialized) return;
|
||||||
|
char *c;
|
||||||
|
int x1=x, W=0;
|
||||||
|
for(c = string; *c; c++){
|
||||||
|
W += glutBitmapWidth(font,*c);// + 1;
|
||||||
|
}
|
||||||
|
x1 -= W/2;
|
||||||
|
glColor3ubv(color);
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslatef(0.,0., -150);
|
||||||
|
//glTranslatef(x,y, -4000.);
|
||||||
|
for (c = string; *c != '\0'; c++){
|
||||||
|
glColor3ubv(color);
|
||||||
|
glRasterPos2f(x1,y);
|
||||||
|
glutBitmapCharacter(font, *c);
|
||||||
|
//glutStrokeCharacter(GLUT_STROKE_ROMAN, *c);
|
||||||
|
x1 = x1 + glutBitmapWidth(font,*c);// + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RedrawWindow(){
|
||||||
|
//DBG("ini=%d, win=%s", initialized, win ? "yes" : "no");
|
||||||
|
if(!initialized || !win || win->killthread) return;
|
||||||
|
if(pthread_mutex_trylock(&win->mutex)) return;
|
||||||
|
GLfloat w = win->image->w, h = win->image->h;
|
||||||
|
glutSetWindow(win->ID);
|
||||||
|
glClearColor(0.0, 0.0, 0.5, 1.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslatef(win->x, win->y, 0.);
|
||||||
|
glScalef(-win->zoom, -win->zoom, 1.);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, win->Tex);
|
||||||
|
if(win->image->changed){
|
||||||
|
DBG("Image changed!");
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, win->image->w, win->image->h, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata);
|
||||||
|
/* glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win->image->w, win->image->h,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata);*/
|
||||||
|
win->image->changed = 0;
|
||||||
|
}
|
||||||
|
w /= 2.f; h /= 2.f;
|
||||||
|
float lr = 1., ud = 1.; // flipping coefficients
|
||||||
|
if(win->flip & WIN_FLIP_LR) lr = -1.;
|
||||||
|
if(win->flip & WIN_FLIP_UD) ud = -1.;
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(1.0f, 1.0f); glVertex2f( -1.f*lr*w, ud*h ); // top right
|
||||||
|
glTexCoord2f(1.0f, 0.0f); glVertex2f( -1.f*lr*w, -1.f*ud*h ); // bottom right
|
||||||
|
glTexCoord2f(0.0f, 0.0f); glVertex2f(lr*w, -1.f*ud*h ); // bottom left
|
||||||
|
glTexCoord2f(0.0f, 1.0f); glVertex2f(lr*w, ud*h ); // top left
|
||||||
|
glEnd();
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glFinish();
|
||||||
|
glutSwapBuffers();
|
||||||
|
pthread_mutex_unlock(&win->mutex);
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* main freeGLUT loop
|
||||||
|
* waits for global signals to create windows & make other actions
|
||||||
|
*/
|
||||||
|
static void *Redraw(_U_ void *arg){
|
||||||
|
FNAME();
|
||||||
|
createWindow();
|
||||||
|
glutMainLoop();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Resize(int width, int height){
|
||||||
|
FNAME();
|
||||||
|
if(!initialized || !win || win->killthread) return;
|
||||||
|
glutReshapeWindow(width, height);
|
||||||
|
win->w = width;
|
||||||
|
win->h = height;
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
GLfloat W, H;
|
||||||
|
calc_win_props(&W, &H);
|
||||||
|
glOrtho(-W,W, -H,H, -1., 1.);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create new window, run thread & return pointer to its structure or NULL
|
||||||
|
* asynchroneous call from outside
|
||||||
|
* wait for window creating & return its data
|
||||||
|
* @param title - header (copyed inside this function)
|
||||||
|
* @param w,h - image size
|
||||||
|
* @param rawdata - NULL (then the memory will be allocated here with size w x h)
|
||||||
|
* or allocated outside data
|
||||||
|
*/
|
||||||
|
windowData *createGLwin(char *title, int w, int h, rawimage *rawdata){
|
||||||
|
FNAME();
|
||||||
|
if(!initialized) imageview_init();
|
||||||
|
if(win) killwindow();
|
||||||
|
win = MALLOC(windowData, 1);
|
||||||
|
rawimage *raw;
|
||||||
|
if(rawdata){
|
||||||
|
raw = rawdata;
|
||||||
|
}else{
|
||||||
|
raw = MALLOC(rawimage, 1);
|
||||||
|
if(raw){
|
||||||
|
raw->rawdata = MALLOC(GLubyte, w*h*3);
|
||||||
|
raw->w = w;
|
||||||
|
raw->h = h;
|
||||||
|
raw->changed = 1;
|
||||||
|
// raw->protected is zero automatically
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!raw || !raw->rawdata){
|
||||||
|
free(raw);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
win->title = strdup(title);
|
||||||
|
win->image = raw;
|
||||||
|
if(pthread_mutex_init(&win->mutex, NULL)){
|
||||||
|
WARN(_("Can't init mutex!"));
|
||||||
|
killwindow();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
win->w = w;
|
||||||
|
win->h = h;
|
||||||
|
pthread_create(&GLUTthread, NULL, &Redraw, NULL);
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init freeGLUT
|
||||||
|
*/
|
||||||
|
void imageview_init(){
|
||||||
|
FNAME();
|
||||||
|
char *v[] = {"Image view window", NULL};
|
||||||
|
int c = 1;
|
||||||
|
if(initialized){
|
||||||
|
WARNX(_("Already initialized!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XInitThreads(); // we need it for threaded windows
|
||||||
|
glutInit(&c, v);
|
||||||
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||||
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
||||||
|
initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close all opened windows and terminate main GLUT thread
|
||||||
|
*/
|
||||||
|
void clear_GL_context(){
|
||||||
|
FNAME();
|
||||||
|
if(!initialized) return;
|
||||||
|
initialized = 0;
|
||||||
|
DBG("kill");
|
||||||
|
killwindow();
|
||||||
|
DBG("join");
|
||||||
|
if(GLUTthread) pthread_join(GLUTthread, NULL); // wait while main thread exits
|
||||||
|
DBG("main GL thread cancelled");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Coordinates transformation from CS of drawingArea into CS of picture
|
||||||
|
* x,y - pointer coordinates
|
||||||
|
* X,Y - coordinates of appropriate point at picture
|
||||||
|
*/
|
||||||
|
void conv_mouse_to_image_coords(int x, int y,
|
||||||
|
float *X, float *Y,
|
||||||
|
windowData *window){
|
||||||
|
float a = window->Daspect / window->zoom;
|
||||||
|
*X = (float)x * a - window->x0;
|
||||||
|
*Y = window->y0 - (float)y * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void conv_image_to_mouse_coords(float X, float Y,
|
||||||
|
int *x, int *y,
|
||||||
|
windowData *window){
|
||||||
|
float a = window->zoom / window->Daspect;
|
||||||
|
*x = (int)roundf((X + window->x0) * a);
|
||||||
|
*y = (int)roundf((window->y0 - Y) * a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
windowData *getWin(){
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert gray (unsigned short) into RGB components (GLubyte)
|
||||||
|
* @argument L - gray level (0..1)
|
||||||
|
* @argument rgb - rgb array (GLubyte [3])
|
||||||
|
*/
|
||||||
|
static void gray2rgb(double gray, GLubyte *rgb){
|
||||||
|
int i = gray * 4.;
|
||||||
|
double x = (gray - (double)i * .25) * 4.;
|
||||||
|
GLubyte r = 0, g = 0, b = 0;
|
||||||
|
//r = g = b = (gray < 1) ? gray * 256 : 255;
|
||||||
|
switch(i){
|
||||||
|
case 0:
|
||||||
|
g = (GLubyte)(255. * x);
|
||||||
|
b = 255;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
g = 255;
|
||||||
|
b = (GLubyte)(255. * (1. - x));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
r = (GLubyte)(255. * x);
|
||||||
|
g = 255;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
r = 255;
|
||||||
|
g = (GLubyte)(255. * (1. - x));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
r = 255;
|
||||||
|
}
|
||||||
|
*rgb++ = r;
|
||||||
|
*rgb++ = g;
|
||||||
|
*rgb = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
COLORFN_LINEAR, // linear
|
||||||
|
COLORFN_LOG, // ln
|
||||||
|
COLORFN_SQRT, // sqrt
|
||||||
|
COLORFN_MAX // end of list
|
||||||
|
} colorfn_type;
|
||||||
|
|
||||||
|
static colorfn_type ft = COLORFN_LINEAR;
|
||||||
|
|
||||||
|
// all colorfun's should get argument in [0, 1] and return in [0, 1]
|
||||||
|
static double linfun(double arg){ return arg; } // bung for PREVIEW_LINEAR
|
||||||
|
static double logfun(double arg){ return log(1.+arg) / 0.6931472; } // for PREVIEW_LOG [log_2(x+1)]
|
||||||
|
static double (*colorfun)(double) = linfun; // default function to convert color
|
||||||
|
|
||||||
|
static void change_colorfun(colorfn_type f){
|
||||||
|
DBG("New colorfn: %d", f);
|
||||||
|
switch (f){
|
||||||
|
case COLORFN_LOG:
|
||||||
|
colorfun = logfun;
|
||||||
|
ft = COLORFN_LOG;
|
||||||
|
break;
|
||||||
|
case COLORFN_SQRT:
|
||||||
|
colorfun = sqrt;
|
||||||
|
ft = COLORFN_SQRT;
|
||||||
|
break;
|
||||||
|
default: // linear
|
||||||
|
colorfun = linfun;
|
||||||
|
ft = COLORFN_LINEAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cycle switch between palettes
|
||||||
|
static void roll_colorfun(){
|
||||||
|
colorfn_type t = ++ft;
|
||||||
|
if(t == COLORFN_MAX) t = COLORFN_LINEAR;
|
||||||
|
change_colorfun(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief equalize - hystogram equalization
|
||||||
|
* @param ori (io) - input/output data
|
||||||
|
* @param w,h - image width and height
|
||||||
|
* @return data allocated here
|
||||||
|
*/
|
||||||
|
static uint8_t *equalize(uint16_t *ori, int w, int h){
|
||||||
|
uint8_t *retn = MALLOC(uint8_t, w*h);
|
||||||
|
double orig_hysto[0x10000] = {0.}; // original hystogram
|
||||||
|
uint8_t eq_levls[0x10000] = {0}; // levels to convert: newpix = eq_levls[oldpix]
|
||||||
|
int s = w*h;
|
||||||
|
for(int i = 0; i < s; ++i) ++orig_hysto[ori[i]];
|
||||||
|
double part = (double)(s + 1) / 0x100, N = 0.;
|
||||||
|
for(int i = 0; i <= 0xffff; ++i){
|
||||||
|
N += orig_hysto[i];
|
||||||
|
eq_levls[i] = (uint8_t)(N/part);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < s; ++i){
|
||||||
|
retn[i] = eq_levls[ori[i]];
|
||||||
|
}
|
||||||
|
return retn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void change_displayed_image(windowData *win, IMG *img){
|
||||||
|
if(!win || !win->image) return;
|
||||||
|
rawimage *im = win->image;
|
||||||
|
DBG("imh=%d, imw=%d, ch=%u, cw=%u", im->h, im->w, img->w, img->h);
|
||||||
|
pthread_mutex_lock(&win->mutex);
|
||||||
|
int w = img->w, h = img->h, s = w*h;
|
||||||
|
uint8_t *newima = equalize(img->data, w, h);
|
||||||
|
GLubyte *dst = im->rawdata;
|
||||||
|
for(int i = 0; i < s; ++i, dst += 3){
|
||||||
|
gray2rgb(colorfun(newima[i] / 256.), dst);
|
||||||
|
}
|
||||||
|
FREE(newima);
|
||||||
|
win->image->changed = 1;
|
||||||
|
pthread_mutex_unlock(&win->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* image_thread(_U_ void *data){
|
||||||
|
FNAME();
|
||||||
|
IMG *img = (IMG*) data;
|
||||||
|
while(1){
|
||||||
|
windowData *win = getWin();
|
||||||
|
if(!win || win->killthread){
|
||||||
|
DBG("got killthread");
|
||||||
|
clear_GL_context();
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
if(win && win->winevt){
|
||||||
|
if(win->winevt & WINEVT_SAVEIMAGE){ // save image
|
||||||
|
verbose(2, "Make screenshot\n");
|
||||||
|
saveImages(img, "ScreenShot");
|
||||||
|
win->winevt &= ~WINEVT_SAVEIMAGE;
|
||||||
|
}
|
||||||
|
if(win->winevt & WINEVT_ROLLCOLORFUN){
|
||||||
|
roll_colorfun();
|
||||||
|
win->winevt &= ~WINEVT_ROLLCOLORFUN;
|
||||||
|
change_displayed_image(win, img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
91
fli_control/imageview.h
Normal file
91
fli_control/imageview.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* imageview.h
|
||||||
|
*
|
||||||
|
* Copyright 2015 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#ifndef __BMPVIEW_H__
|
||||||
|
#define __BMPVIEW_H__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "events.h"
|
||||||
|
#include "flifunc.h"
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
GLubyte *rawdata; // raw image data
|
||||||
|
int w; // size of image
|
||||||
|
int h;
|
||||||
|
int changed; // == 1 if data was changed outside (to redraw)
|
||||||
|
} rawimage;
|
||||||
|
|
||||||
|
// events from menu:
|
||||||
|
// temporaly stop capture of regular sequence
|
||||||
|
#define WINEVT_PAUSE (1<<0)
|
||||||
|
// capture one image in pause mode
|
||||||
|
#define WINEVT_GETIMAGE (1<<1)
|
||||||
|
// save current image
|
||||||
|
#define WINEVT_SAVEIMAGE (1<<2)
|
||||||
|
// change color palette function
|
||||||
|
#define WINEVT_ROLLCOLORFUN (1<<3)
|
||||||
|
|
||||||
|
// flip image
|
||||||
|
#define WIN_FLIP_LR (1<<0)
|
||||||
|
#define WIN_FLIP_UD (1<<1)
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int ID; // identificator of OpenGL window
|
||||||
|
char *title; // title of window
|
||||||
|
GLuint Tex; // texture for image inside window
|
||||||
|
rawimage *image; // raw image data
|
||||||
|
int w; int h; // window size
|
||||||
|
float x; float y; // image offset coordinates
|
||||||
|
float x0; float y0; // center of window for coords conversion
|
||||||
|
float zoom; // zoom aspect
|
||||||
|
float Daspect; // aspect ratio between image & window sizes
|
||||||
|
int menu; // window menu identifier
|
||||||
|
uint32_t winevt; // window menu events
|
||||||
|
uint8_t flip; // flipping settings
|
||||||
|
pthread_t thread; // identificator of thread that changes window data
|
||||||
|
pthread_mutex_t mutex;// mutex for operations with image
|
||||||
|
int killthread; // flag for killing data changing thread & also signal that there's no threads
|
||||||
|
} windowData;
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
INNER,
|
||||||
|
OPENGL
|
||||||
|
} winIdType;
|
||||||
|
|
||||||
|
void imageview_init();
|
||||||
|
windowData *createGLwin(char *title, int w, int h, rawimage *rawdata);
|
||||||
|
windowData *getWin();
|
||||||
|
int killwindow();
|
||||||
|
void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color);
|
||||||
|
void clear_GL_context();
|
||||||
|
|
||||||
|
void calc_win_props(GLfloat *Wortho, GLfloat *Hortho);
|
||||||
|
|
||||||
|
void conv_mouse_to_image_coords(int x, int y, float *X, float *Y, windowData *window);
|
||||||
|
void conv_image_to_mouse_coords(float X, float Y, int *x, int *y, windowData *window);
|
||||||
|
|
||||||
|
void* image_thread(void *data);
|
||||||
|
void change_displayed_image(windowData *win, IMG *img);
|
||||||
|
#endif // __BMPVIEW_H__
|
||||||
Binary file not shown.
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-02-22 20:05+0300\n"
|
"POT-Creation-Date: 2020-12-07 19:35+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,433 +17,358 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:65
|
#: cmdlnopts.c:66
|
||||||
msgid "show this help"
|
msgid "show this help"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:66
|
#: cmdlnopts.c:67
|
||||||
msgid "rewrite output file if exists"
|
msgid "rewrite output file if exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:67
|
#: cmdlnopts.c:68
|
||||||
msgid "verbose level (each -v increase it)"
|
msgid "verbose level (each -v increase it)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:68
|
#: cmdlnopts.c:69
|
||||||
msgid "not open shutter, when exposing (\"dark frames\")"
|
msgid "not open shutter, when exposing (\"dark frames\")"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:69
|
#: cmdlnopts.c:70
|
||||||
msgid "open shutter"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:70
|
|
||||||
msgid "close shutter"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:71
|
|
||||||
msgid "run exposition on LOW @ pin5 I/O port"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:72
|
|
||||||
msgid "run exposition on HIGH @ pin5 I/O port"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:73
|
|
||||||
msgid "get value of I/O port pins"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:74
|
|
||||||
msgid "move stepper motor asynchronous"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:75
|
|
||||||
msgid "run in 8-bit mode"
|
msgid "run in 8-bit mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:76
|
#: cmdlnopts.c:71
|
||||||
msgid "fast (8MHz) readout mode"
|
msgid "fast (8MHz) readout mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. {"", NO_ARGS, NULL, '', arg_int, APTR(&G.), N_("")},
|
#: cmdlnopts.c:72
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:79
|
msgid "set CCD temperature to given value (degr C)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:74
|
||||||
msgid "program author"
|
msgid "program author"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:80
|
#: cmdlnopts.c:75
|
||||||
msgid "object type (neon, object, flat etc)"
|
msgid "object type (neon, object, flat etc)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:81
|
#: cmdlnopts.c:76
|
||||||
msgid "instrument name"
|
msgid "instrument name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:82
|
#: cmdlnopts.c:77
|
||||||
msgid "object name"
|
msgid "object name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:83
|
#: cmdlnopts.c:78
|
||||||
msgid "observers' names"
|
msgid "observers' names"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:84
|
#: cmdlnopts.c:79
|
||||||
msgid "observing program name"
|
msgid "observing program name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:85
|
#: cmdlnopts.c:80
|
||||||
msgid "add records to header from given file[s]"
|
msgid "add records to header from given file[s]"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. {"", NEED_ARG, NULL, '', arg_string, APTR(&G.), N_("")},
|
#: cmdlnopts.c:82
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:88
|
|
||||||
msgid "N flushes before exposing"
|
msgid "N flushes before exposing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:89
|
#: cmdlnopts.c:83
|
||||||
msgid "horizontal binning to N pixels"
|
msgid "horizontal binning to N pixels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:90
|
#: cmdlnopts.c:84
|
||||||
msgid "vertical binning to N pixels"
|
msgid "vertical binning to N pixels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:91
|
#: cmdlnopts.c:85
|
||||||
msgid "make series of N frames"
|
msgid "make series of N frames"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:92
|
#: cmdlnopts.c:86
|
||||||
msgid "make pause for N seconds between expositions"
|
msgid "make pause for N seconds between expositions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:93
|
#: cmdlnopts.c:87
|
||||||
msgid "set exposure time to given value (ms)"
|
msgid "set exposure time to given value (ms)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:94
|
#: cmdlnopts.c:88
|
||||||
msgid "frame X0 coordinate (-1 - all with overscan)"
|
msgid "frame X0 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:95
|
#: cmdlnopts.c:89
|
||||||
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:96
|
#: cmdlnopts.c:90
|
||||||
msgid "frame X1 coordinate (-1 - all with overscan)"
|
msgid "frame X1 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:97
|
#: cmdlnopts.c:91
|
||||||
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:98
|
#: cmdlnopts.c:93
|
||||||
|
msgid "open shutter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:94
|
||||||
|
msgid "close shutter"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:95
|
||||||
|
msgid "run exposition on LOW @ pin5 I/O port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:96
|
||||||
|
msgid "run exposition on HIGH @ pin5 I/O port"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:97
|
||||||
|
msgid "get value of I/O port pins"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:98
|
||||||
|
msgid "move stepper motor asynchronous"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cmdlnopts.c:100
|
||||||
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:99
|
#: cmdlnopts.c:101
|
||||||
msgid ""
|
msgid ""
|
||||||
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
|
"configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == "
|
||||||
"output, 0 == input)"
|
"output, 0 == input)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:100
|
#: cmdlnopts.c:103
|
||||||
msgid "move focuser to absolute position"
|
msgid "move focuser to absolute position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:101
|
#: cmdlnopts.c:104
|
||||||
msgid "move focuser to relative position"
|
msgid "move focuser to relative position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. {"wheel-get",NO_ARGS, NULL, 0, arg_none, APTR(&G.getwheel), N_("get current wheel position")},
|
#: cmdlnopts.c:106
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:103
|
|
||||||
msgid "set wheel position"
|
msgid "set wheel position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. {"", NEED_ARG, NULL, '', arg_int, APTR(&G.), N_("")},
|
#: cmdlnopts.c:109
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:106
|
msgid "Display image in OpenGL window"
|
||||||
msgid "set CCD temperature to given value (degr C)"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
#. ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:130
|
#: flifunc.c:123
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Library version '%s'"
|
msgid "Library version '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
||||||
|
#: flifunc.c:188
|
||||||
|
#, c-format
|
||||||
|
msgid "Image stat:\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. íÏÄÅÌØ:\t\t%s
|
#. íÏÄÅÌØ:\t\t%s
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:146
|
#: flifunc.c:215 flifunc.c:312 flifunc.c:434
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:237
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:318
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Model:\t\t%s"
|
msgid "Model:\t\t%s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:149
|
#: flifunc.c:218
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Focuser '%s', domain %s"
|
msgid "Focuser '%s', domain %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. áÐÐ. ×ÅÒÓÉÑ: %ld
|
#. áÐÐ. ×ÅÒÓÉÑ: %ld
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:152
|
#: flifunc.c:221 flifunc.c:315 flifunc.c:438
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:240
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:322
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "HW revision: %ld"
|
msgid "HW revision: %ld"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
#. ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:155
|
#: flifunc.c:224 flifunc.c:318 flifunc.c:441
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:243
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:325
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "SW revision: %ld"
|
msgid "SW revision: %ld"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
#. îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:171
|
#: flifunc.c:240
|
||||||
msgid "You can't use both relative and absolute position"
|
msgid "You can't use both relative and absolute position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
#. ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:176
|
#: flifunc.c:245
|
||||||
msgid "Error in position detection"
|
msgid "Error in position detection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:188
|
#: flifunc.c:257
|
||||||
msgid "Already at position"
|
msgid "Already at position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
#. ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:193
|
#: flifunc.c:262
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Position should be in 0...%ld"
|
msgid "Position should be in 0...%ld"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
#. ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:198
|
#: flifunc.c:267
|
||||||
msgid "Moving to home position"
|
msgid "Moving to home position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
#. ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:203
|
#: flifunc.c:272
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Moving for %ld steps"
|
msgid "Moving for %ld steps"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:215
|
#: flifunc.c:284
|
||||||
msgid "No focusers found"
|
msgid "No focusers found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:232
|
#: flifunc.c:307
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wheel '%s', domain %s"
|
msgid "Wheel '%s', domain %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:247
|
#: flifunc.c:322
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wheel position should be from 0 to %ld"
|
msgid "Wheel position should be from 0 to %ld"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:271
|
#: flifunc.c:328
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Position is too big (max %d)"
|
msgid "Position is too big (max %d)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:275
|
#: flifunc.c:332
|
||||||
msgid "Arrive to position"
|
msgid "Arrive to position"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:299
|
#: flifunc.c:356
|
||||||
msgid "No wheels found"
|
msgid "No wheels found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:307
|
|
||||||
msgid "No CCD found"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:313
|
|
||||||
#, c-format
|
|
||||||
msgid "Camera '%s', domain %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:328
|
|
||||||
#, c-format
|
|
||||||
msgid "Pixel size: %g x %g"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:332
|
|
||||||
#, c-format
|
|
||||||
msgid "Field of view: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:337
|
|
||||||
#, c-format
|
|
||||||
msgid "Array field: (%ld, %ld)(%ld, %ld)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:351
|
|
||||||
#, c-format
|
|
||||||
msgid "Set CCD temperature to %g degr.C\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:377
|
|
||||||
#, c-format
|
|
||||||
msgid "%s CCD shutter\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:388
|
|
||||||
#, c-format
|
|
||||||
msgid "Try to convfigure I/O port as %d\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:398
|
|
||||||
#, c-format
|
|
||||||
msgid "Try to write %d to I/O port\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:419
|
|
||||||
msgid "8 bit mode\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:422
|
|
||||||
msgid "Fast readout mode\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:423
|
|
||||||
msgid "Only show statistics\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:429
|
|
||||||
#, c-format
|
|
||||||
msgid "Capture frame %d\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. ÄÁÔÁ/×ÒÅÍÑ
|
#. ÄÁÔÁ/×ÒÅÍÑ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:437
|
#: flifunc.c:378 flifunc.c:565
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:501
|
|
||||||
msgid "date/time"
|
msgid "date/time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
#. "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:444
|
#: flifunc.c:385
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "wait for external trigger...\n"
|
msgid "wait for external trigger...\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
#. %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:448
|
#: flifunc.c:389
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%.3f seconds till exposition ends\n"
|
msgid "%.3f seconds till exposition ends\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
#. óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:454
|
#: flifunc.c:395
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Read image: "
|
msgid "Read image: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
#: flifunc.c:425
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:473
|
msgid "No CCD found"
|
||||||
msgid "Can't save file"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
#. ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:482
|
#: flifunc.c:429
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "File saved as '%s'"
|
msgid "Camera '%s', domain %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
||||||
|
#: flifunc.c:444
|
||||||
|
#, c-format
|
||||||
|
msgid "Pixel size: %g x %g"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
||||||
|
#: flifunc.c:448
|
||||||
|
#, c-format
|
||||||
|
msgid "Field of view: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
||||||
|
#: flifunc.c:453
|
||||||
|
#, c-format
|
||||||
|
msgid "Array field: (%ld, %ld)(%ld, %ld)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
||||||
|
#: flifunc.c:467
|
||||||
|
#, c-format
|
||||||
|
msgid "Set CCD temperature to %g degr.C\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: flifunc.c:493
|
||||||
|
#, c-format
|
||||||
|
msgid "%s CCD shutter\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
||||||
|
#: flifunc.c:498
|
||||||
|
#, c-format
|
||||||
|
msgid "Try to convfigure I/O port as %d\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
||||||
|
#: flifunc.c:508
|
||||||
|
#, c-format
|
||||||
|
msgid "Try to write %d to I/O port\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: flifunc.c:518
|
||||||
|
msgid "8 bit mode\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: flifunc.c:521
|
||||||
|
msgid "Fast readout mode\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: flifunc.c:522
|
||||||
|
msgid "Only show statistics\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
||||||
|
#: flifunc.c:528
|
||||||
|
#, c-format
|
||||||
|
msgid "Capture frame %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
#. %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:496
|
#: flifunc.c:560
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d seconds till pause ends\n"
|
msgid "%d seconds till pause ends\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
#. îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:770
|
#: flifunc.c:605
|
||||||
|
msgid "Can't save file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#. æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
||||||
|
#: flifunc.c:615
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Image stat:\n"
|
msgid "File saved as '%s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. amount of pcount and/or scount wrong
|
#: imageview.c:257
|
||||||
#. / "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
msgid "Can't init mutex!"
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:56
|
|
||||||
msgid "Wrong helpstring!"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. / "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
#: imageview.c:275
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:86
|
msgid "Already initialized!"
|
||||||
msgid "Integer out of range"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:480
|
|
||||||
#, c-format
|
|
||||||
msgid "Wrong parameter: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:485
|
|
||||||
#, c-format
|
|
||||||
msgid "%s: argument needed!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:490
|
|
||||||
#, c-format
|
|
||||||
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:173
|
|
||||||
msgid "No filename given!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:178
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't open %s for reading"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:183
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't stat %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "ïÛÉÂËÁ mmap"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:190
|
|
||||||
msgid "Mmap error for input"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:195
|
|
||||||
msgid "Can't close mmap'ed file"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ munmap"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:205
|
|
||||||
msgid "Can't munmap"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:231
|
|
||||||
msgid "Can't setup console"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. Get settings
|
|
||||||
#. / "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÎÁÓÔÒÏÊËÉ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:301
|
|
||||||
msgid "Can't get settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:312
|
|
||||||
msgid "Can't set settings"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-02-22 20:05+0300\n"
|
"POT-Creation-Date: 2020-12-07 19:35+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,431 +17,356 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#. %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
#. %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:448
|
#: flifunc.c:389
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%.3f seconds till exposition ends\n"
|
msgid "%.3f seconds till exposition ends\n"
|
||||||
msgstr ""
|
msgstr "%.3f секунд до окончания экспозиции\n"
|
||||||
|
|
||||||
#. %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
#. %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:496
|
#: flifunc.c:560
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%d seconds till pause ends\n"
|
msgid "%d seconds till pause ends\n"
|
||||||
msgstr ""
|
msgstr "%d секунд до окончания паузы\n"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:377
|
#: flifunc.c:493
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s CCD shutter\n"
|
msgid "%s CCD shutter\n"
|
||||||
msgstr ""
|
msgstr "%s затвор ПЗС\n"
|
||||||
|
|
||||||
#. / "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
#: flifunc.c:518
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:485
|
|
||||||
#, c-format
|
|
||||||
msgid "%s: argument needed!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:419
|
|
||||||
msgid "8 bit mode\n"
|
msgid "8 bit mode\n"
|
||||||
msgstr ""
|
msgstr "режим 8 бит\n"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:188
|
#: flifunc.c:257
|
||||||
msgid "Already at position"
|
msgid "Already at position"
|
||||||
msgstr ""
|
msgstr "Уже на позиции"
|
||||||
|
|
||||||
|
#: imageview.c:275
|
||||||
|
msgid "Already initialized!"
|
||||||
|
msgstr "Уже инициализировано!"
|
||||||
|
|
||||||
#. ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
#. ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:337
|
#: flifunc.c:453
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Array field: (%ld, %ld)(%ld, %ld)"
|
msgid "Array field: (%ld, %ld)(%ld, %ld)"
|
||||||
msgstr ""
|
msgstr "Поле изображения: (%ld, %ld)(%ld, %ld)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:275
|
#: flifunc.c:332
|
||||||
msgid "Arrive to position"
|
msgid "Arrive to position"
|
||||||
msgstr ""
|
msgstr "Прибыл на позицию"
|
||||||
|
|
||||||
#. ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
#. ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:313
|
#: flifunc.c:429
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Camera '%s', domain %s"
|
msgid "Camera '%s', domain %s"
|
||||||
msgstr ""
|
msgstr "Камера '%s' из домена %s"
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
#: imageview.c:257
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:195
|
msgid "Can't init mutex!"
|
||||||
msgid "Can't close mmap'ed file"
|
msgstr "Не могу инициализировать мьютекс!"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. Get settings
|
|
||||||
#. / "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÎÁÓÔÒÏÊËÉ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:301
|
|
||||||
msgid "Can't get settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ munmap"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:205
|
|
||||||
msgid "Can't munmap"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:178
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't open %s for reading"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
#. îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:473
|
#: flifunc.c:605
|
||||||
msgid "Can't save file"
|
msgid "Can't save file"
|
||||||
msgstr ""
|
msgstr "Не могу сохранить файл"
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:312
|
|
||||||
msgid "Can't set settings"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:231
|
|
||||||
msgid "Can't setup console"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:183
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't stat %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
#. úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:429
|
#: flifunc.c:528
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Capture frame %d\n"
|
msgid "Capture frame %d\n"
|
||||||
msgstr ""
|
msgstr "Захват кадра %d\n"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:109
|
||||||
|
msgid "Display image in OpenGL window"
|
||||||
|
msgstr "Отобразить изобрежение в окне OpenGL"
|
||||||
|
|
||||||
#. ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
#. ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:176
|
#: flifunc.c:245
|
||||||
msgid "Error in position detection"
|
msgid "Error in position detection"
|
||||||
msgstr ""
|
msgstr "Ошибка определения позиции"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:422
|
#: flifunc.c:521
|
||||||
msgid "Fast readout mode\n"
|
msgid "Fast readout mode\n"
|
||||||
msgstr ""
|
msgstr "Быстрый режим считывания\n"
|
||||||
|
|
||||||
#. ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
#. ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:332
|
#: flifunc.c:448
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Field of view: %s"
|
msgid "Field of view: %s"
|
||||||
msgstr ""
|
msgstr "Видимое поле: %s"
|
||||||
|
|
||||||
#. æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
#. æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:482
|
#: flifunc.c:615
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "File saved as '%s'"
|
msgid "File saved as '%s'"
|
||||||
msgstr ""
|
msgstr "Файл записан в '%s'"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:149
|
#: flifunc.c:218
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Focuser '%s', domain %s"
|
msgid "Focuser '%s', domain %s"
|
||||||
msgstr ""
|
msgstr "Фокусер '%s', домен %s"
|
||||||
|
|
||||||
#. áÐÐ. ×ÅÒÓÉÑ: %ld
|
#. áÐÐ. ×ÅÒÓÉÑ: %ld
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:152
|
#: flifunc.c:221 flifunc.c:315 flifunc.c:438
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:240
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:322
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "HW revision: %ld"
|
msgid "HW revision: %ld"
|
||||||
msgstr ""
|
msgstr "Апп. версия: %ld"
|
||||||
|
|
||||||
#. óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
#. óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:770
|
#: flifunc.c:188
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Image stat:\n"
|
msgid "Image stat:\n"
|
||||||
msgstr ""
|
msgstr "Статистика по изображению:\n"
|
||||||
|
|
||||||
#. / "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:86
|
|
||||||
msgid "Integer out of range"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
#. ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:130
|
#: flifunc.c:123
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Library version '%s'"
|
msgid "Library version '%s'"
|
||||||
msgstr ""
|
msgstr "Версия библиотеки '%s'"
|
||||||
|
|
||||||
#. / "ïÛÉÂËÁ mmap"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:190
|
|
||||||
msgid "Mmap error for input"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. íÏÄÅÌØ:\t\t%s
|
#. íÏÄÅÌØ:\t\t%s
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:146
|
#: flifunc.c:215 flifunc.c:312 flifunc.c:434
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:237
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:318
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Model:\t\t%s"
|
msgid "Model:\t\t%s"
|
||||||
msgstr ""
|
msgstr "Модель:\t\t%s"
|
||||||
|
|
||||||
#. ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
#. ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:203
|
#: flifunc.c:272
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Moving for %ld steps"
|
msgid "Moving for %ld steps"
|
||||||
msgstr ""
|
msgstr "Перемещение на %ld шагов"
|
||||||
|
|
||||||
#. ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
#. ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:198
|
#: flifunc.c:267
|
||||||
msgid "Moving to home position"
|
msgid "Moving to home position"
|
||||||
msgstr ""
|
msgstr "Перемещение в нулевую позицию"
|
||||||
|
|
||||||
#. {"", NEED_ARG, NULL, '', arg_string, APTR(&G.), N_("")},
|
#: cmdlnopts.c:82
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:88
|
|
||||||
msgid "N flushes before exposing"
|
msgid "N flushes before exposing"
|
||||||
msgstr ""
|
msgstr "N сбросов перед экспозицией"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:307
|
#: flifunc.c:425
|
||||||
msgid "No CCD found"
|
msgid "No CCD found"
|
||||||
msgstr ""
|
msgstr "ПЗС не обнаружена"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/usefull_macros.c:173
|
#: flifunc.c:284
|
||||||
msgid "No filename given!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:215
|
|
||||||
msgid "No focusers found"
|
msgid "No focusers found"
|
||||||
msgstr ""
|
msgstr "Фокусер не обнаружен"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:299
|
#: flifunc.c:356
|
||||||
msgid "No wheels found"
|
msgid "No wheels found"
|
||||||
msgstr ""
|
msgstr "Турель не обнаружена"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:423
|
#: flifunc.c:522
|
||||||
msgid "Only show statistics\n"
|
msgid "Only show statistics\n"
|
||||||
msgstr ""
|
msgstr "Только отобразить статистику\n"
|
||||||
|
|
||||||
#. òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
#. òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:328
|
#: flifunc.c:444
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Pixel size: %g x %g"
|
msgid "Pixel size: %g x %g"
|
||||||
msgstr ""
|
msgstr "Размер пикселя: %g x %g"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:271
|
#: flifunc.c:328
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Position is too big (max %d)"
|
msgid "Position is too big (max %d)"
|
||||||
msgstr ""
|
msgstr "Позиция слишком велика (макс. %d)"
|
||||||
|
|
||||||
#. ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
#. ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:193
|
#: flifunc.c:262
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Position should be in 0...%ld"
|
msgid "Position should be in 0...%ld"
|
||||||
msgstr ""
|
msgstr "Позиция не должна выходить за пределы 0...%ld"
|
||||||
|
|
||||||
#. óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
#. óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:454
|
#: flifunc.c:395
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Read image: "
|
msgid "Read image: "
|
||||||
msgstr ""
|
msgstr "Считывание изображения:"
|
||||||
|
|
||||||
#. ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
#. ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:155
|
#: flifunc.c:224 flifunc.c:318 flifunc.c:441
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:243
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:325
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "SW revision: %ld"
|
msgid "SW revision: %ld"
|
||||||
msgstr ""
|
msgstr "Прогр. версия: %ld"
|
||||||
|
|
||||||
#. "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
#. "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:351
|
#: flifunc.c:467
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Set CCD temperature to %g degr.C\n"
|
msgid "Set CCD temperature to %g degr.C\n"
|
||||||
msgstr ""
|
msgstr "Установка температуры ПЗС: %g градусов Цельсия\n"
|
||||||
|
|
||||||
#. "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
#. "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:388
|
#: flifunc.c:498
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to convfigure I/O port as %d\n"
|
msgid "Try to convfigure I/O port as %d\n"
|
||||||
msgstr ""
|
msgstr "Попытка сконфигурировать порт I/O как %d\n"
|
||||||
|
|
||||||
#. "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
#. "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:398
|
#: flifunc.c:508
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Try to write %d to I/O port\n"
|
msgid "Try to write %d to I/O port\n"
|
||||||
msgstr ""
|
msgstr "Попытка записи %d в порт I/O\n"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:232
|
#: flifunc.c:307
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wheel '%s', domain %s"
|
msgid "Wheel '%s', domain %s"
|
||||||
msgstr ""
|
msgstr "Турель '%s', домен %s"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:247
|
#: flifunc.c:322
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wheel position should be from 0 to %ld"
|
msgid "Wheel position should be from 0 to %ld"
|
||||||
msgstr ""
|
msgstr "Позиция колеса нумеруется от 0 до %ld"
|
||||||
|
|
||||||
#. / "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:490
|
|
||||||
#, c-format
|
|
||||||
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. amount of pcount and/or scount wrong
|
|
||||||
#. / "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:56
|
|
||||||
msgid "Wrong helpstring!"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. / "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/parseargs.c:480
|
|
||||||
#, c-format
|
|
||||||
msgid "Wrong parameter: %s"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#. îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
#. îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:171
|
#: flifunc.c:240
|
||||||
msgid "You can't use both relative and absolute position"
|
msgid "You can't use both relative and absolute position"
|
||||||
msgstr ""
|
msgstr "Нельзя одновременно указывать относительную и абсолютную позицию"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:85
|
#: cmdlnopts.c:80
|
||||||
msgid "add records to header from given file[s]"
|
msgid "add records to header from given file[s]"
|
||||||
msgstr ""
|
msgstr "добавить записи в шапку из данных файлов"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:70
|
#: cmdlnopts.c:94
|
||||||
msgid "close shutter"
|
msgid "close shutter"
|
||||||
msgstr ""
|
msgstr "закрыть затвор"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:99
|
#: cmdlnopts.c:101
|
||||||
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
|
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
|
||||||
"1 == output, 0 == input)"
|
"1 == output, 0 == input)"
|
||||||
msgstr ""
|
msgstr "конфигурация портов ввода/вывода на заданное значение (десятичное число, пин1 - младший, 1 - выход, 0 - вход)"
|
||||||
|
|
||||||
#. ÄÁÔÁ/×ÒÅÍÑ
|
#. ÄÁÔÁ/×ÒÅÍÑ
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:437
|
#: flifunc.c:378 flifunc.c:565
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:501
|
|
||||||
msgid "date/time"
|
msgid "date/time"
|
||||||
msgstr ""
|
msgstr "дата/время"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:76
|
#: cmdlnopts.c:71
|
||||||
msgid "fast (8MHz) readout mode"
|
msgid "fast (8MHz) readout mode"
|
||||||
msgstr ""
|
msgstr "быстрый (8МГц) режим считывания"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:94
|
#: cmdlnopts.c:88
|
||||||
msgid "frame X0 coordinate (-1 - all with overscan)"
|
msgid "frame X0 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr "координата элемента изображения X0 (-1 - включая оверскан)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:96
|
#: cmdlnopts.c:90
|
||||||
msgid "frame X1 coordinate (-1 - all with overscan)"
|
msgid "frame X1 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr "координата элемента изображения X1 (-1 - включая оверскан)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:95
|
#: cmdlnopts.c:89
|
||||||
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr "координата элемента изображения Y0 (-1 - включая оверскан)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:97
|
#: cmdlnopts.c:91
|
||||||
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
||||||
msgstr ""
|
msgstr "координата элемента изображения Y1 (-1 - включая оверскан)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:73
|
#: cmdlnopts.c:97
|
||||||
msgid "get value of I/O port pins"
|
msgid "get value of I/O port pins"
|
||||||
msgstr ""
|
msgstr "состояние портов ввода/вывода"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:89
|
#: cmdlnopts.c:83
|
||||||
msgid "horizontal binning to N pixels"
|
msgid "horizontal binning to N pixels"
|
||||||
msgstr ""
|
msgstr "горизонтальный биннинг на N пикселей"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:81
|
#: cmdlnopts.c:76
|
||||||
msgid "instrument name"
|
msgid "instrument name"
|
||||||
msgstr ""
|
msgstr "название прибора"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:92
|
#: cmdlnopts.c:86
|
||||||
msgid "make pause for N seconds between expositions"
|
msgid "make pause for N seconds between expositions"
|
||||||
msgstr ""
|
msgstr "пауза в N секунд между экспозициями"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:91
|
#: cmdlnopts.c:85
|
||||||
msgid "make series of N frames"
|
msgid "make series of N frames"
|
||||||
msgstr ""
|
msgstr "последовательность из N кадров"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:100
|
#: cmdlnopts.c:103
|
||||||
msgid "move focuser to absolute position"
|
msgid "move focuser to absolute position"
|
||||||
msgstr ""
|
msgstr "переместить фокусер в абсолютное положение"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:101
|
#: cmdlnopts.c:104
|
||||||
msgid "move focuser to relative position"
|
msgid "move focuser to relative position"
|
||||||
msgstr ""
|
msgstr "переместить фокусер в относительное положение"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:74
|
#: cmdlnopts.c:98
|
||||||
msgid "move stepper motor asynchronous"
|
msgid "move stepper motor asynchronous"
|
||||||
msgstr ""
|
msgstr "не дожидаться окончания движения мотора"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:68
|
#: cmdlnopts.c:69
|
||||||
msgid "not open shutter, when exposing (\"dark frames\")"
|
msgid "not open shutter, when exposing (\"dark frames\")"
|
||||||
msgstr ""
|
msgstr "не открывать затвор при экспозиции (\"темновые\")"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:82
|
#: cmdlnopts.c:77
|
||||||
msgid "object name"
|
msgid "object name"
|
||||||
msgstr ""
|
msgstr "название объекта"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:80
|
#: cmdlnopts.c:75
|
||||||
msgid "object type (neon, object, flat etc)"
|
msgid "object type (neon, object, flat etc)"
|
||||||
msgstr ""
|
msgstr "тип объекта (neon, object, flat и т.п.)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:83
|
#: cmdlnopts.c:78
|
||||||
msgid "observers' names"
|
msgid "observers' names"
|
||||||
msgstr ""
|
msgstr "имена наблюдателей"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:84
|
#: cmdlnopts.c:79
|
||||||
msgid "observing program name"
|
msgid "observing program name"
|
||||||
msgstr ""
|
msgstr "название программы наблюдений"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:69
|
#: cmdlnopts.c:93
|
||||||
msgid "open shutter"
|
msgid "open shutter"
|
||||||
msgstr ""
|
msgstr "открыть затвор"
|
||||||
|
|
||||||
#. {"", NO_ARGS, NULL, '', arg_int, APTR(&G.), N_("")},
|
#: cmdlnopts.c:74
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:79
|
|
||||||
msgid "program author"
|
msgid "program author"
|
||||||
msgstr ""
|
msgstr "автор программы"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:66
|
#: cmdlnopts.c:67
|
||||||
msgid "rewrite output file if exists"
|
msgid "rewrite output file if exists"
|
||||||
msgstr ""
|
msgstr "перезаписать выходной файл, если существует"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:72
|
#: cmdlnopts.c:96
|
||||||
msgid "run exposition on HIGH @ pin5 I/O port"
|
msgid "run exposition on HIGH @ pin5 I/O port"
|
||||||
msgstr ""
|
msgstr "запуск экспозиции при высоком уровне пина 5"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:71
|
#: cmdlnopts.c:95
|
||||||
msgid "run exposition on LOW @ pin5 I/O port"
|
msgid "run exposition on LOW @ pin5 I/O port"
|
||||||
msgstr ""
|
msgstr "запуск экспозиции при низком уровне пина 5"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:75
|
#: cmdlnopts.c:70
|
||||||
msgid "run in 8-bit mode"
|
msgid "run in 8-bit mode"
|
||||||
msgstr ""
|
msgstr "8-битный режим"
|
||||||
|
|
||||||
#. {"", NEED_ARG, NULL, '', arg_int, APTR(&G.), N_("")},
|
#: cmdlnopts.c:72
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:106
|
|
||||||
msgid "set CCD temperature to given value (degr C)"
|
msgid "set CCD temperature to given value (degr C)"
|
||||||
msgstr ""
|
msgstr "установка температуры ПЗС (в гардусах Цельсия)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:98
|
#: cmdlnopts.c:100
|
||||||
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
||||||
msgstr ""
|
msgstr "установить пины порта ввода-вывода в заданную величину (десятичное число, pin1 младший)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:93
|
#: cmdlnopts.c:87
|
||||||
msgid "set exposure time to given value (ms)"
|
msgid "set exposure time to given value (ms)"
|
||||||
msgstr ""
|
msgstr "установить время экспозиции (миллисекунды)"
|
||||||
|
|
||||||
#. {"wheel-get",NO_ARGS, NULL, 0, arg_none, APTR(&G.getwheel), N_("get current wheel position")},
|
#: cmdlnopts.c:106
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:103
|
|
||||||
msgid "set wheel position"
|
msgid "set wheel position"
|
||||||
msgstr ""
|
msgstr "установить позицию турели"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:65
|
#: cmdlnopts.c:66
|
||||||
msgid "show this help"
|
msgid "show this help"
|
||||||
msgstr ""
|
msgstr "показать эту справку"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:67
|
#: cmdlnopts.c:68
|
||||||
msgid "verbose level (each -v increase it)"
|
msgid "verbose level (each -v increase it)"
|
||||||
msgstr ""
|
msgstr "уровень информативности (каждая -V повышает)"
|
||||||
|
|
||||||
#: /home/eddy/Doc/FLI/fli_control/cmdlnopts.c:90
|
#: cmdlnopts.c:84
|
||||||
msgid "vertical binning to N pixels"
|
msgid "vertical binning to N pixels"
|
||||||
msgstr ""
|
msgstr "вертикальный биннинг в N пикселей"
|
||||||
|
|
||||||
#. "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
#. "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
||||||
#: /home/eddy/Doc/FLI/fli_control/main.c:444
|
#: flifunc.c:385
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "wait for external trigger...\n"
|
msgid "wait for external trigger...\n"
|
||||||
msgstr ""
|
msgstr "ожидаю внешний триггер...\n"
|
||||||
|
|||||||
372
fli_control/locale/ru/ru.po.bkp
Normal file
372
fli_control/locale/ru/ru.po.bkp
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2020-12-07 19:35+0300\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"Language: \n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#. %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
||||||
|
#: flifunc.c:389
|
||||||
|
#, c-format
|
||||||
|
msgid "%.3f seconds till exposition ends\n"
|
||||||
|
msgstr "%.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n"
|
||||||
|
|
||||||
|
#. %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
||||||
|
#: flifunc.c:560
|
||||||
|
#, c-format
|
||||||
|
msgid "%d seconds till pause ends\n"
|
||||||
|
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
|
||||||
|
|
||||||
|
#: flifunc.c:493
|
||||||
|
#, c-format
|
||||||
|
msgid "%s CCD shutter\n"
|
||||||
|
msgstr "%s ÚÁÔ×ÏÒ ðúó\n"
|
||||||
|
|
||||||
|
#: flifunc.c:518
|
||||||
|
msgid "8 bit mode\n"
|
||||||
|
msgstr "ÒÅÖÉÍ 8 ÂÉÔ\n"
|
||||||
|
|
||||||
|
#: flifunc.c:257
|
||||||
|
msgid "Already at position"
|
||||||
|
msgstr "õÖÅ ÎÁ ÐÏÚÉÃÉÉ"
|
||||||
|
|
||||||
|
#: imageview.c:275
|
||||||
|
msgid "Already initialized!"
|
||||||
|
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
|
||||||
|
|
||||||
|
#. ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
||||||
|
#: flifunc.c:453
|
||||||
|
#, c-format
|
||||||
|
msgid "Array field: (%ld, %ld)(%ld, %ld)"
|
||||||
|
msgstr "ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)"
|
||||||
|
|
||||||
|
#: flifunc.c:332
|
||||||
|
msgid "Arrive to position"
|
||||||
|
msgstr "ðÒÉÂÙÌ ÎÁ ÐÏÚÉÃÉÀ"
|
||||||
|
|
||||||
|
#. ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
||||||
|
#: flifunc.c:429
|
||||||
|
#, c-format
|
||||||
|
msgid "Camera '%s', domain %s"
|
||||||
|
msgstr "ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s"
|
||||||
|
|
||||||
|
#: imageview.c:257
|
||||||
|
msgid "Can't init mutex!"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
|
||||||
|
|
||||||
|
#. îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
||||||
|
#: flifunc.c:605
|
||||||
|
msgid "Can't save file"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ"
|
||||||
|
|
||||||
|
#. úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
||||||
|
#: flifunc.c:528
|
||||||
|
#, c-format
|
||||||
|
msgid "Capture frame %d\n"
|
||||||
|
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d\n"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:109
|
||||||
|
msgid "Display image in OpenGL window"
|
||||||
|
msgstr "ïÔÏÂÒÁÚÉÔØ ÉÚÏÂÒÅÖÅÎÉÅ × ÏËÎÅ OpenGL"
|
||||||
|
|
||||||
|
#. ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
||||||
|
#: flifunc.c:245
|
||||||
|
msgid "Error in position detection"
|
||||||
|
msgstr "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ"
|
||||||
|
|
||||||
|
#: flifunc.c:521
|
||||||
|
msgid "Fast readout mode\n"
|
||||||
|
msgstr "âÙÓÔÒÙÊ ÒÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ\n"
|
||||||
|
|
||||||
|
#. ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
||||||
|
#: flifunc.c:448
|
||||||
|
#, c-format
|
||||||
|
msgid "Field of view: %s"
|
||||||
|
msgstr "÷ÉÄÉÍÏÅ ÐÏÌÅ: %s"
|
||||||
|
|
||||||
|
#. æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
||||||
|
#: flifunc.c:615
|
||||||
|
#, c-format
|
||||||
|
msgid "File saved as '%s'"
|
||||||
|
msgstr "æÁÊÌ ÚÁÐÉÓÁÎ × '%s'"
|
||||||
|
|
||||||
|
#: flifunc.c:218
|
||||||
|
#, c-format
|
||||||
|
msgid "Focuser '%s', domain %s"
|
||||||
|
msgstr "æÏËÕÓÅÒ '%s', ÄÏÍÅÎ %s"
|
||||||
|
|
||||||
|
#. áÐÐ. ×ÅÒÓÉÑ: %ld
|
||||||
|
#: flifunc.c:221 flifunc.c:315 flifunc.c:438
|
||||||
|
#, c-format
|
||||||
|
msgid "HW revision: %ld"
|
||||||
|
msgstr "áÐÐ. ×ÅÒÓÉÑ: %ld"
|
||||||
|
|
||||||
|
#. óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
||||||
|
#: flifunc.c:188
|
||||||
|
#, c-format
|
||||||
|
msgid "Image stat:\n"
|
||||||
|
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n"
|
||||||
|
|
||||||
|
#. ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
||||||
|
#: flifunc.c:123
|
||||||
|
#, c-format
|
||||||
|
msgid "Library version '%s'"
|
||||||
|
msgstr "÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'"
|
||||||
|
|
||||||
|
#. íÏÄÅÌØ:\t\t%s
|
||||||
|
#: flifunc.c:215 flifunc.c:312 flifunc.c:434
|
||||||
|
#, c-format
|
||||||
|
msgid "Model:\t\t%s"
|
||||||
|
msgstr "íÏÄÅÌØ:\t\t%s"
|
||||||
|
|
||||||
|
#. ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
||||||
|
#: flifunc.c:272
|
||||||
|
#, c-format
|
||||||
|
msgid "Moving for %ld steps"
|
||||||
|
msgstr "ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×"
|
||||||
|
|
||||||
|
#. ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
||||||
|
#: flifunc.c:267
|
||||||
|
msgid "Moving to home position"
|
||||||
|
msgstr "ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:82
|
||||||
|
msgid "N flushes before exposing"
|
||||||
|
msgstr "N ÓÂÒÏÓÏ× ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ"
|
||||||
|
|
||||||
|
#: flifunc.c:425
|
||||||
|
msgid "No CCD found"
|
||||||
|
msgstr "ðúó ÎÅ ÏÂÎÁÒÕÖÅÎÁ"
|
||||||
|
|
||||||
|
#: flifunc.c:284
|
||||||
|
msgid "No focusers found"
|
||||||
|
msgstr "æÏËÕÓÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎ"
|
||||||
|
|
||||||
|
#: flifunc.c:356
|
||||||
|
msgid "No wheels found"
|
||||||
|
msgstr "ôÕÒÅÌØ ÎÅ ÏÂÎÁÒÕÖÅÎÁ"
|
||||||
|
|
||||||
|
#: flifunc.c:522
|
||||||
|
msgid "Only show statistics\n"
|
||||||
|
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ\n"
|
||||||
|
|
||||||
|
#. òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
||||||
|
#: flifunc.c:444
|
||||||
|
#, c-format
|
||||||
|
msgid "Pixel size: %g x %g"
|
||||||
|
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
|
||||||
|
|
||||||
|
#: flifunc.c:328
|
||||||
|
#, c-format
|
||||||
|
msgid "Position is too big (max %d)"
|
||||||
|
msgstr "ðÏÚÉÃÉÑ ÓÌÉÛËÏÍ ×ÅÌÉËÁ (ÍÁËÓ. %d)"
|
||||||
|
|
||||||
|
#. ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
||||||
|
#: flifunc.c:262
|
||||||
|
#, c-format
|
||||||
|
msgid "Position should be in 0...%ld"
|
||||||
|
msgstr "ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld"
|
||||||
|
|
||||||
|
#. óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
||||||
|
#: flifunc.c:395
|
||||||
|
#, c-format
|
||||||
|
msgid "Read image: "
|
||||||
|
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:"
|
||||||
|
|
||||||
|
#. ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
||||||
|
#: flifunc.c:224 flifunc.c:318 flifunc.c:441
|
||||||
|
#, c-format
|
||||||
|
msgid "SW revision: %ld"
|
||||||
|
msgstr "ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld"
|
||||||
|
|
||||||
|
#. "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
||||||
|
#: flifunc.c:467
|
||||||
|
#, c-format
|
||||||
|
msgid "Set CCD temperature to %g degr.C\n"
|
||||||
|
msgstr "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
||||||
|
|
||||||
|
#. "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
||||||
|
#: flifunc.c:498
|
||||||
|
#, c-format
|
||||||
|
msgid "Try to convfigure I/O port as %d\n"
|
||||||
|
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
||||||
|
|
||||||
|
#. "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
||||||
|
#: flifunc.c:508
|
||||||
|
#, c-format
|
||||||
|
msgid "Try to write %d to I/O port\n"
|
||||||
|
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
||||||
|
|
||||||
|
#: flifunc.c:307
|
||||||
|
#, c-format
|
||||||
|
msgid "Wheel '%s', domain %s"
|
||||||
|
msgstr "ôÕÒÅÌØ '%s', ÄÏÍÅÎ %s"
|
||||||
|
|
||||||
|
#: flifunc.c:322
|
||||||
|
#, c-format
|
||||||
|
msgid "Wheel position should be from 0 to %ld"
|
||||||
|
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÎÕÍÅÒÕÅÔÓÑ ÏÔ 0 ÄÏ %ld"
|
||||||
|
|
||||||
|
#. îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
||||||
|
#: flifunc.c:240
|
||||||
|
msgid "You can't use both relative and absolute position"
|
||||||
|
msgstr "îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:80
|
||||||
|
msgid "add records to header from given file[s]"
|
||||||
|
msgstr "ÄÏÂÁ×ÉÔØ ÚÁÐÉÓÉ × ÛÁÐËÕ ÉÚ ÄÁÎÎÙÈ ÆÁÊÌÏ×"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:94
|
||||||
|
msgid "close shutter"
|
||||||
|
msgstr "ÚÁËÒÙÔØ ÚÁÔ×ÏÒ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:101
|
||||||
|
msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, "
|
||||||
|
"1 == output, 0 == input)"
|
||||||
|
msgstr "ËÏÎÆÉÇÕÒÁÃÉÑ ÐÏÒÔÏ× ××ÏÄÁ/×Ù×ÏÄÁ ÎÁ ÚÁÄÁÎÎÏÅ ÚÎÁÞÅÎÉÅ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, ÐÉÎ1 - ÍÌÁÄÛÉÊ, 1 - ×ÙÈÏÄ, 0 - ×ÈÏÄ)"
|
||||||
|
|
||||||
|
#. ÄÁÔÁ/×ÒÅÍÑ
|
||||||
|
#: flifunc.c:378 flifunc.c:565
|
||||||
|
msgid "date/time"
|
||||||
|
msgstr "ÄÁÔÁ/×ÒÅÍÑ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:71
|
||||||
|
msgid "fast (8MHz) readout mode"
|
||||||
|
msgstr "ÂÙÓÔÒÙÊ (8íçÃ) ÒÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:88
|
||||||
|
msgid "frame X0 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr "ËÏÏÒÄÉÎÁÔÁ ÜÌÅÍÅÎÔÁ ÉÚÏÂÒÁÖÅÎÉÑ X0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:90
|
||||||
|
msgid "frame X1 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr "ËÏÏÒÄÉÎÁÔÁ ÜÌÅÍÅÎÔÁ ÉÚÏÂÒÁÖÅÎÉÑ X1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:89
|
||||||
|
msgid "frame Y0 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr "ËÏÏÒÄÉÎÁÔÁ ÜÌÅÍÅÎÔÁ ÉÚÏÂÒÁÖÅÎÉÑ Y0 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:91
|
||||||
|
msgid "frame Y1 coordinate (-1 - all with overscan)"
|
||||||
|
msgstr "ËÏÏÒÄÉÎÁÔÁ ÜÌÅÍÅÎÔÁ ÉÚÏÂÒÁÖÅÎÉÑ Y1 (-1 - ×ËÌÀÞÁÑ Ï×ÅÒÓËÁÎ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:97
|
||||||
|
msgid "get value of I/O port pins"
|
||||||
|
msgstr "ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÏ× ××ÏÄÁ/×Ù×ÏÄÁ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:83
|
||||||
|
msgid "horizontal binning to N pixels"
|
||||||
|
msgstr "ÇÏÒÉÚÏÎÔÁÌØÎÙÊ ÂÉÎÎÉÎÇ ÎÁ N ÐÉËÓÅÌÅÊ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:76
|
||||||
|
msgid "instrument name"
|
||||||
|
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÉÂÏÒÁ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:86
|
||||||
|
msgid "make pause for N seconds between expositions"
|
||||||
|
msgstr "ÐÁÕÚÁ × N ÓÅËÕÎÄ ÍÅÖÄÕ ÜËÓÐÏÚÉÃÉÑÍÉ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:85
|
||||||
|
msgid "make series of N frames"
|
||||||
|
msgstr "ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ ÉÚ N ËÁÄÒÏ×"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:103
|
||||||
|
msgid "move focuser to absolute position"
|
||||||
|
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÁÂÓÏÌÀÔÎÏÅ ÐÏÌÏÖÅÎÉÅ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:104
|
||||||
|
msgid "move focuser to relative position"
|
||||||
|
msgstr "ÐÅÒÅÍÅÓÔÉÔØ ÆÏËÕÓÅÒ × ÏÔÎÏÓÉÔÅÌØÎÏÅ ÐÏÌÏÖÅÎÉÅ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:98
|
||||||
|
msgid "move stepper motor asynchronous"
|
||||||
|
msgstr "ÎÅ ÄÏÖÉÄÁÔØÓÑ ÏËÏÎÞÁÎÉÑ Ä×ÉÖÅÎÉÑ ÍÏÔÏÒÁ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:69
|
||||||
|
msgid "not open shutter, when exposing (\"dark frames\")"
|
||||||
|
msgstr "ÎÅ ÏÔËÒÙ×ÁÔØ ÚÁÔ×ÏÒ ÐÒÉ ÜËÓÐÏÚÉÃÉÉ (\"ÔÅÍÎÏ×ÙÅ\")"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:77
|
||||||
|
msgid "object name"
|
||||||
|
msgstr "ÎÁÚ×ÁÎÉÅ ÏÂßÅËÔÁ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:75
|
||||||
|
msgid "object type (neon, object, flat etc)"
|
||||||
|
msgstr "ÔÉÐ ÏÂßÅËÔÁ (neon, object, flat É Ô.Ð.)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:78
|
||||||
|
msgid "observers' names"
|
||||||
|
msgstr "ÉÍÅÎÁ ÎÁÂÌÀÄÁÔÅÌÅÊ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:79
|
||||||
|
msgid "observing program name"
|
||||||
|
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ ÎÁÂÌÀÄÅÎÉÊ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:93
|
||||||
|
msgid "open shutter"
|
||||||
|
msgstr "ÏÔËÒÙÔØ ÚÁÔ×ÏÒ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:74
|
||||||
|
msgid "program author"
|
||||||
|
msgstr "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:67
|
||||||
|
msgid "rewrite output file if exists"
|
||||||
|
msgstr "ÐÅÒÅÚÁÐÉÓÁÔØ ×ÙÈÏÄÎÏÊ ÆÁÊÌ, ÅÓÌÉ ÓÕÝÅÓÔ×ÕÅÔ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:96
|
||||||
|
msgid "run exposition on HIGH @ pin5 I/O port"
|
||||||
|
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÒÉ ×ÙÓÏËÏÍ ÕÒÏ×ÎÅ ÐÉÎÁ 5"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:95
|
||||||
|
msgid "run exposition on LOW @ pin5 I/O port"
|
||||||
|
msgstr "ÚÁÐÕÓË ÜËÓÐÏÚÉÃÉÉ ÐÒÉ ÎÉÚËÏÍ ÕÒÏ×ÎÅ ÐÉÎÁ 5"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:70
|
||||||
|
msgid "run in 8-bit mode"
|
||||||
|
msgstr "8-ÂÉÔÎÙÊ ÒÅÖÉÍ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:72
|
||||||
|
msgid "set CCD temperature to given value (degr C)"
|
||||||
|
msgstr "ÕÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó (× ÇÁÒÄÕÓÁÈ ãÅÌØÓÉÑ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:100
|
||||||
|
msgid "set I/O port pins to given value (decimal number, pin1 is LSB)"
|
||||||
|
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÉÎÙ ÐÏÒÔÁ ××ÏÄÁ-×Ù×ÏÄÁ × ÚÁÄÁÎÎÕÀ ×ÅÌÉÞÉÎÕ (ÄÅÓÑÔÉÞÎÏÅ ÞÉÓÌÏ, pin1 ÍÌÁÄÛÉÊ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:87
|
||||||
|
msgid "set exposure time to given value (ms)"
|
||||||
|
msgstr "ÕÓÔÁÎÏ×ÉÔØ ×ÒÅÍÑ ÜËÓÐÏÚÉÃÉÉ (ÍÉÌÌÉÓÅËÕÎÄÙ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:106
|
||||||
|
msgid "set wheel position"
|
||||||
|
msgstr "ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ ÔÕÒÅÌÉ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:66
|
||||||
|
msgid "show this help"
|
||||||
|
msgstr "ÐÏËÁÚÁÔØ ÜÔÕ ÓÐÒÁ×ËÕ"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:68
|
||||||
|
msgid "verbose level (each -v increase it)"
|
||||||
|
msgstr "ÕÒÏ×ÅÎØ ÉÎÆÏÒÍÁÔÉ×ÎÏÓÔÉ (ËÁÖÄÁÑ -V ÐÏ×ÙÛÁÅÔ)"
|
||||||
|
|
||||||
|
#: cmdlnopts.c:84
|
||||||
|
msgid "vertical binning to N pixels"
|
||||||
|
msgstr "×ÅÒÔÉËÁÌØÎÙÊ ÂÉÎÎÉÎÇ × N ÐÉËÓÅÌÅÊ"
|
||||||
|
|
||||||
|
#. "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
||||||
|
#: flifunc.c:385
|
||||||
|
#, c-format
|
||||||
|
msgid "wait for external trigger...\n"
|
||||||
|
msgstr "ÏÖÉÄÁÀ ×ÎÅÛÎÉÊ ÔÒÉÇÇÅÒ...\n"
|
||||||
@ -21,755 +21,33 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// for strcasestr
|
#include <stdio.h>
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fitsio.h>
|
#include <usefull_macros.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "main.h"
|
#include "cmdlnopts.h"
|
||||||
|
#include "flifunc.h"
|
||||||
#ifndef FLIUSB_VENDORID
|
#ifdef IMAGEVIEW
|
||||||
#define FLIUSB_VENDORID 0xf18
|
#include "imageview.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef FLIUSB_PROLINE_ID
|
|
||||||
#define FLIUSB_PROLINE_ID 0x0a
|
|
||||||
#endif
|
|
||||||
#ifndef FLIUSB_FILTER_ID
|
|
||||||
#define FLIUSB_FILTER_ID 0x07
|
|
||||||
#endif
|
|
||||||
#ifndef FLIUSB_FOCUSER_ID
|
|
||||||
#define FLIUSB_FOCUSER_ID 0x06
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static long fli_err;
|
|
||||||
#define TRYFUNC(f, ...) \
|
|
||||||
do{ if((fli_err = f(__VA_ARGS__))) \
|
|
||||||
WARNX(#f "() failed"); \
|
|
||||||
}while(0)
|
|
||||||
|
|
||||||
#ifdef USEPNG
|
|
||||||
int writepng(char *filename, int width, int height, void *data);
|
|
||||||
#endif /* USEPNG */
|
|
||||||
|
|
||||||
#define BUFF_SIZ 4096
|
|
||||||
|
|
||||||
#define TMBUFSIZ 40
|
|
||||||
static char tm_buf[TMBUFSIZ]; // buffer for string with time value
|
|
||||||
|
|
||||||
static glob_pars *G = NULL; // default parameters see in cmdlnopts.c
|
|
||||||
|
|
||||||
static uint16_t max = 0, min = 65535; // max/min values for given image
|
|
||||||
static double avr, std; // stat values
|
|
||||||
static char *camera = NULL, viewfield[80];
|
|
||||||
static double pixX, pixY; // pixel size in um
|
|
||||||
|
|
||||||
static void print_stat(u_int16_t *img, long size);
|
|
||||||
|
|
||||||
static size_t curtime(char *s_time){ // current date/time
|
|
||||||
time_t tm = time(NULL);
|
|
||||||
return strftime(s_time, TMBUFSIZ, "%d/%m/%Y,%H:%M:%S", localtime(&tm));
|
|
||||||
}
|
|
||||||
|
|
||||||
static fliframe_t frametype = FLI_FRAME_TYPE_NORMAL;
|
|
||||||
static double t_ext, t_int; // external & CCD temperatures @exp. end
|
|
||||||
static time_t expStartsAt; // exposition start time (time_t)
|
|
||||||
|
|
||||||
static long filterpos = -1; // filter position
|
|
||||||
static long focuserpos = -1; // focuser position
|
|
||||||
|
|
||||||
static int check_filename(char *buff, char *outfile, char *ext){
|
|
||||||
struct stat filestat;
|
|
||||||
int num;
|
|
||||||
for(num = 1; num < 10000; num++){
|
|
||||||
if(snprintf(buff, BUFF_SIZ, "%s_%04d.%s", outfile, num, ext) < 1)
|
|
||||||
return 0;
|
|
||||||
if(stat(buff, &filestat)) // no such file or can't stat()
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void signals(int signo){
|
void signals(int signo){
|
||||||
exit(signo);
|
exit(signo);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
static void info(const char *fmt, ...){
|
|
||||||
va_list ar;
|
|
||||||
if(!verbose) return;
|
|
||||||
printf("%s: ", __progname);
|
|
||||||
va_start(ar, fmt);
|
|
||||||
vprintf(fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
int i, num;
|
|
||||||
long ltmp;
|
|
||||||
char libver[LIBVERSIZ]; // FLI library version
|
|
||||||
cam_t *cam = NULL; // list of CCDs available
|
|
||||||
flidev_t dev;
|
|
||||||
char buff[BUFF_SIZ];
|
|
||||||
initial_setup();
|
initial_setup();
|
||||||
G = parse_args(argc, argv);
|
parse_args(argc, argv);
|
||||||
// #ifdef EBUG
|
if(fli_init()) return 1;
|
||||||
TRYFUNC(FLISetDebugLevel, NULL /* "NO HOST" */, FLIDEBUG_NONE);
|
focusers();
|
||||||
/* #else
|
wheels();
|
||||||
TRYFUNC(FLISetDebugLevel, NULL, FLIDEBUG_NONE);
|
ccds();
|
||||||
#endif */
|
|
||||||
TRYFUNC(FLIGetLibVersion, libver, LIBVERSIZ);
|
|
||||||
// ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
|
|
||||||
if(!fli_err) info(_("Library version '%s'"), libver);
|
|
||||||
/*
|
|
||||||
* Find focusers and work with each of them
|
|
||||||
*/
|
|
||||||
num = findcams(FLIDOMAIN_USB | FLIDEVICE_FOCUSER, &cam);
|
|
||||||
int nfocs = 0;
|
|
||||||
for (i = 0; i < num; i++){
|
|
||||||
TRYFUNC(FLIOpen, &dev, cam[i].name, cam[i].domain);
|
|
||||||
if(fli_err) continue;
|
|
||||||
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
|
|
||||||
if(!fli_err){
|
|
||||||
if(!strcasestr(buff, "focuser")){ // not focuser
|
|
||||||
TRYFUNC(FLIClose, dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// íÏÄÅÌØ:\t\t%s
|
|
||||||
info(_("Model:\t\t%s"), buff);
|
|
||||||
}
|
|
||||||
++nfocs;
|
|
||||||
info(_("Focuser '%s', domain %s"), cam[i].name, cam[i].dname);
|
|
||||||
TRYFUNC(FLIGetHWRevision, dev, <mp);
|
|
||||||
// áÐÐ. ×ÅÒÓÉÑ: %ld
|
|
||||||
if(!fli_err) info(_("HW revision: %ld"), ltmp);
|
|
||||||
TRYFUNC(FLIGetFWRevision, dev, <mp);
|
|
||||||
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
|
||||||
if(!fli_err) info(_("SW revision: %ld"), ltmp);
|
|
||||||
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_INTERNAL, &t_ext);
|
|
||||||
if(!fli_err) green("FOCTEMP=%.1f\n", t_ext);
|
|
||||||
long curpos = -1, maxpos = -1;
|
|
||||||
TRYFUNC(FLIGetStepperPosition, dev, <mp);
|
|
||||||
if(!fli_err){
|
|
||||||
curpos = ltmp;
|
|
||||||
}
|
|
||||||
TRYFUNC(FLIGetFocuserExtent, dev, <mp);
|
|
||||||
if(!fli_err){
|
|
||||||
green("FOCMAXPOS=%ld\n", ltmp);
|
|
||||||
maxpos = ltmp;
|
|
||||||
}
|
|
||||||
do{
|
|
||||||
if(G->gotopos != INT_MAX && G->addsteps != INT_MAX){
|
|
||||||
// îÅÌØÚÑ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕËÁÚÙ×ÁÔØ ÏÔÎÏÓÉÔÅÌØÎÕÀ É ÁÂÓÏÌÀÔÎÕÀ ÐÏÚÉÃÉÀ
|
|
||||||
WARNX(_("You can't use both relative and absolute position"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(curpos < 0 || maxpos < 0){
|
|
||||||
// ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÐÏÚÉÃÉÉ
|
|
||||||
WARNX(_("Error in position detection"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
long pos = -1, steps = 0;
|
|
||||||
if(G->gotopos != INT_MAX){ // absolute pointing
|
|
||||||
pos = G->gotopos;
|
|
||||||
steps = pos - curpos;
|
|
||||||
}else if(G->addsteps != INT_MAX){ // relative pointing
|
|
||||||
steps = G->addsteps;
|
|
||||||
pos = curpos + steps;
|
|
||||||
}else break;
|
|
||||||
if(!steps){
|
|
||||||
info(_("Already at position"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(pos > maxpos || pos < 0){
|
|
||||||
// ðÏÚÉÃÉÑ ÎÅ ÄÏÌÖÎÁ ×ÙÈÏÄÉÔØ ÚÁ ÐÒÅÄÅÌÙ 0...%ld
|
|
||||||
WARNX(_("Position should be in 0...%ld"), maxpos);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(pos == 0){
|
|
||||||
// ðÅÒÅÍÅÝÅÎÉÅ × ÎÕÌÅ×ÕÀ ÐÏÚÉÃÉÀ
|
|
||||||
info(_("Moving to home position"));
|
|
||||||
if(G->async) TRYFUNC(FLIHomeDevice, dev);
|
|
||||||
else TRYFUNC(FLIHomeFocuser, dev);
|
|
||||||
}else{
|
|
||||||
// ðÅÒÅÍÅÝÅÎÉÅ ÎÁ %ld ÛÁÇÏ×
|
|
||||||
info(_("Moving for %ld steps"), steps);
|
|
||||||
if(G->async) TRYFUNC(FLIStepMotorAsync, dev, steps);
|
|
||||||
else TRYFUNC(FLIStepMotor, dev, steps);
|
|
||||||
}
|
|
||||||
}while(0);
|
|
||||||
TRYFUNC(FLIGetStepperPosition, dev, &focuserpos);
|
|
||||||
if(!fli_err){
|
|
||||||
green("FOCPOS=%ld\n", focuserpos);
|
|
||||||
curpos = focuserpos;
|
|
||||||
}else DBG("Error getting fpos: %ld", fli_err);
|
|
||||||
TRYFUNC(FLIClose, dev);
|
|
||||||
}
|
|
||||||
if(!nfocs) WARNX(_("No focusers found"));
|
|
||||||
for (i = 0; i < num; i++)
|
|
||||||
FREE(cam[i].name);
|
|
||||||
FREE(cam);
|
|
||||||
/*
|
|
||||||
* Find wheels and work with each of them
|
|
||||||
*/
|
|
||||||
num = findcams(FLIDOMAIN_USB | FLIDEVICE_FILTERWHEEL, &cam);
|
|
||||||
int nwheels = 0;
|
|
||||||
for (i = 0; i < num; i++){
|
|
||||||
TRYFUNC(FLIOpen, &dev, cam[i].name, cam[i].domain);
|
|
||||||
if(fli_err) continue;
|
|
||||||
TRYFUNC(FLIGetFilterCount, dev, <mp);
|
|
||||||
if(fli_err || ltmp < 2){// not a wheel
|
|
||||||
TRYFUNC(FLIClose, dev);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
info(_("Wheel '%s', domain %s"), cam[i].name, cam[i].dname);
|
|
||||||
green("WHEELTOTALPOS=%ld\n", ltmp);
|
|
||||||
int wheelmaxpos = (int)ltmp - 1;
|
|
||||||
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
|
|
||||||
// íÏÄÅÌØ:\t\t%s
|
|
||||||
if(!fli_err) info(_("Model:\t\t%s"), buff);
|
|
||||||
TRYFUNC(FLIGetHWRevision, dev, <mp);
|
|
||||||
// áÐÐ. ×ÅÒÓÉÑ: %ld
|
|
||||||
if(!fli_err) info(_("HW revision: %ld"), ltmp);
|
|
||||||
TRYFUNC(FLIGetFWRevision, dev, <mp);
|
|
||||||
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
|
||||||
if(!fli_err) info(_("SW revision: %ld"), ltmp);
|
|
||||||
else goto closewheeldev;
|
|
||||||
if(G->setwheel > -1 && G->setwheel >= ltmp){
|
|
||||||
G->setwheel = -1;
|
|
||||||
WARNX(_("Wheel position should be from 0 to %ld"), ltmp - 1);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
TRYFUNC(FLIHomeDevice, dev);
|
|
||||||
int ii;
|
|
||||||
for(ii = 0; ii < 100; ++ii){
|
|
||||||
TRYFUNC(FLIGetStepperPosition, dev, <mp);
|
|
||||||
if(!fli_err) printf("%ld\t", ltmp);
|
|
||||||
TRYFUNC( FLIGetStepsRemaining, dev, <mp);
|
|
||||||
if(!fli_err) printf("%ld\t", ltmp);
|
|
||||||
TRYFUNC(FLIGetFilterPos, dev, <mp);
|
|
||||||
if(!fli_err) printf("%ld\n", ltmp);
|
|
||||||
usleep(50000);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRYFUNC(FLIGetActiveWheel, dev, <mp);
|
|
||||||
if(!fli_err) info(_("Wheel number: %ld"), ltmp);
|
|
||||||
TRYFUNC(FLIGetStepperPosition, dev, <mp);
|
|
||||||
if(!fli_err) info(_("stepper position: %ld"), ltmp);
|
|
||||||
*/
|
|
||||||
++nwheels;
|
|
||||||
if(G->setwheel > -1){
|
|
||||||
ltmp = G->setwheel;
|
|
||||||
if(ltmp > wheelmaxpos){
|
|
||||||
WARNX(_("Position is too big (max %d)"), wheelmaxpos);
|
|
||||||
goto closewheeldev;
|
|
||||||
}
|
|
||||||
TRYFUNC(FLISetFilterPos, dev, ltmp);
|
|
||||||
if(!fli_err) info(_("Arrive to position"));
|
|
||||||
}
|
|
||||||
// this function returns -1 every connection without SETpos!!!
|
|
||||||
TRYFUNC(FLIGetFilterPos, dev, &filterpos);
|
|
||||||
if(!fli_err && filterpos > -1){
|
|
||||||
green("WHEELPOS=%ld\n", filterpos);
|
|
||||||
}else{
|
|
||||||
filterpos = -1;
|
|
||||||
// so try to check current position by steps
|
|
||||||
TRYFUNC(FLIGetStepperPosition, dev, <mp);
|
|
||||||
if(ltmp < 0) ltmp = -ltmp;
|
|
||||||
DBG("steps: %ld", ltmp);
|
|
||||||
if(!fli_err){
|
|
||||||
int pos = (ltmp - WHEEL_POS0STPS+WHEEL_STEPPOS/2)/WHEEL_STEPPOS;
|
|
||||||
DBG("pos = %d", pos);
|
|
||||||
if(pos > -1 && pos <= wheelmaxpos){
|
|
||||||
filterpos = pos;
|
|
||||||
green("WHEELPOS=%ld\n", filterpos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closewheeldev:
|
|
||||||
TRYFUNC(FLIClose, dev);
|
|
||||||
}
|
|
||||||
if(!nwheels) WARNX(_("No wheels found"));
|
|
||||||
for (i = 0; i < num; i++)
|
|
||||||
FREE(cam[i].name);
|
|
||||||
FREE(cam);
|
|
||||||
/*
|
|
||||||
* Find CCDs and work with each of them
|
|
||||||
*/
|
|
||||||
num = findcams(FLIDOMAIN_USB | FLIDEVICE_CAMERA, &cam);
|
|
||||||
if(!num) WARNX(_("No CCD found"));
|
|
||||||
for (i = 0; i < num; i++){
|
|
||||||
long x0,x1, y0,y1, row, img_rows, row_width;
|
|
||||||
u_int16_t *img;
|
|
||||||
int j;
|
|
||||||
// ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
|
|
||||||
info(_("Camera '%s', domain %s"), cam[i].name, cam[i].dname);
|
|
||||||
TRYFUNC(FLIOpen, &dev, cam[i].name, cam[i].domain);
|
|
||||||
if(fli_err) continue;
|
|
||||||
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
|
|
||||||
// íÏÄÅÌØ:\t\t%s
|
|
||||||
if(!fli_err) info(_("Model:\t\t%s"), buff);
|
|
||||||
camera = strdup(buff);
|
|
||||||
TRYFUNC(FLIGetHWRevision, dev, <mp);
|
|
||||||
// áÐÐ. ×ÅÒÓÉÑ: %ld
|
|
||||||
if(!fli_err) info(_("HW revision: %ld"), ltmp);
|
|
||||||
TRYFUNC(FLIGetFWRevision, dev, <mp);
|
|
||||||
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
|
|
||||||
if(!fli_err) info(_("SW revision: %ld"), ltmp);
|
|
||||||
TRYFUNC(FLIGetPixelSize, dev, &pixX, &pixY);
|
|
||||||
// òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
|
|
||||||
if(!fli_err) info(_("Pixel size: %g x %g"), pixX, pixY);
|
|
||||||
TRYFUNC(FLIGetVisibleArea, dev, &x0, &y0, &x1, &y1);
|
|
||||||
snprintf(viewfield, 80, "(%ld, %ld)(%ld, %ld)", x0, y0, x1, y1);
|
|
||||||
// ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
|
|
||||||
if(!fli_err) info(_("Field of view: %s"), viewfield);
|
|
||||||
if(G->X1 > x1) G->X1 = x1;
|
|
||||||
if(G->Y1 > y1) G->Y1 = y1;
|
|
||||||
TRYFUNC(FLIGetArrayArea, dev, &x0, &y0, &x1, &y1);
|
|
||||||
// ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
|
|
||||||
if(!fli_err) info(_("Array field: (%ld, %ld)(%ld, %ld)"), x0, y0, x1, y1);
|
|
||||||
TRYFUNC(FLISetHBin, dev, G->hbin);
|
|
||||||
TRYFUNC(FLISetVBin, dev, G->vbin);
|
|
||||||
if(G->X0 == -1) G->X0 = x0; // default values
|
|
||||||
if(G->Y0 == -1) G->Y0 = y0;
|
|
||||||
if(G->X1 == -1) G->X1 = x1;
|
|
||||||
if(G->Y1 == -1) G->Y1 = y1;
|
|
||||||
row_width = (G->X1 - G->X0) / G->hbin;
|
|
||||||
img_rows = (G->Y1 - G->Y0) / G->vbin;
|
|
||||||
TRYFUNC(FLISetImageArea, dev, G->X0, G->Y0,
|
|
||||||
G->X0 + (G->X1 - G->X0) / G->hbin, G->Y0 + (G->Y1 - G->Y0) / G->vbin);
|
|
||||||
TRYFUNC(FLISetNFlushes, dev, G->nflushes);
|
|
||||||
if(G->temperature < 40.){
|
|
||||||
// "õÓÔÁÎÏ×ËÁ ÔÅÍÐÅÒÁÔÕÒÙ ðúó: %g ÇÒÁÄÕÓÏ× ãÅÌØÓÉÑ\n"
|
|
||||||
green(_("Set CCD temperature to %g degr.C\n"), G->temperature);
|
|
||||||
TRYFUNC(FLISetTemperature, dev, G->temperature);
|
|
||||||
}
|
|
||||||
TRYFUNC(FLIGetTemperature, dev, &t_int);
|
|
||||||
if(!fli_err) green("CCDTEMP=%.1f\n", t_int);
|
|
||||||
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
|
|
||||||
if(!fli_err) green("EXTTEMP=%.1f\n", t_ext);
|
|
||||||
if(G->shtr_cmd > -1){
|
|
||||||
flishutter_t shtr = G->shtr_cmd;
|
|
||||||
char *str = NULL;
|
|
||||||
switch(shtr){
|
|
||||||
case FLI_SHUTTER_CLOSE:
|
|
||||||
str = "close";
|
|
||||||
break;
|
|
||||||
case FLI_SHUTTER_OPEN:
|
|
||||||
str = "open";
|
|
||||||
break;
|
|
||||||
case FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_LOW:
|
|
||||||
str = "open @ LOW";
|
|
||||||
break;
|
|
||||||
case FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL|FLI_SHUTTER_EXTERNAL_TRIGGER_HIGH:
|
|
||||||
str = "open @ HIGH";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
str = "WTF?";
|
|
||||||
}
|
|
||||||
green(_("%s CCD shutter\n"), str);
|
|
||||||
TRYFUNC(FLIControlShutter, dev, shtr);
|
|
||||||
/*for(int i = 0; i < 100; ++i){
|
|
||||||
long iop;
|
|
||||||
TRYFUNC(FLIReadIOPort, dev, &iop);
|
|
||||||
if(!r) printf("I/O port data: 0x%02lx\n", iop);
|
|
||||||
sleep(1);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
if(G->confio > -1){
|
|
||||||
// "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d\n"
|
|
||||||
green(_("Try to convfigure I/O port as %d\n"), G->confio);
|
|
||||||
TRYFUNC(FLIConfigureIOPort, dev, G->confio);
|
|
||||||
}
|
|
||||||
if(G->getio){
|
|
||||||
long iop;
|
|
||||||
TRYFUNC(FLIReadIOPort, dev, &iop);
|
|
||||||
if(!fli_err) green("CCDIOPORT=0x%02lx\n", iop);
|
|
||||||
}
|
|
||||||
if(G->setio > -1){
|
|
||||||
// "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O\n"
|
|
||||||
green(_("Try to write %d to I/O port\n"), G->setio);
|
|
||||||
TRYFUNC(FLIWriteIOPort, dev, G->setio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(G->exptime < DBL_EPSILON) continue;
|
|
||||||
/*
|
|
||||||
char str[256];
|
|
||||||
flimode_t m = 0;
|
|
||||||
int ret;
|
|
||||||
while((ret = FLIGetCameraModeString (dev, m, str, 255)) == 0){
|
|
||||||
str[255] = 0;
|
|
||||||
red("String %ld: %s", m, str);
|
|
||||||
m++;
|
|
||||||
}*/
|
|
||||||
// TRYFUNC(FLIGetCameraModeString, dev, m, str, 255);
|
|
||||||
|
|
||||||
TRYFUNC(FLISetExposureTime, dev, G->exptime);
|
|
||||||
if(G->dark) frametype = FLI_FRAME_TYPE_DARK;
|
|
||||||
TRYFUNC(FLISetFrameType, dev, frametype);
|
|
||||||
if(G->_8bit){
|
|
||||||
TRYFUNC(FLISetBitDepth, dev, FLI_MODE_8BIT);
|
|
||||||
if(fli_err == 0) green(_("8 bit mode\n"));
|
|
||||||
}
|
|
||||||
TRYFUNC(FLISetCameraMode, dev, G->fast ? 0 : 1);
|
|
||||||
if(G->fast) green(_("Fast readout mode\n"));
|
|
||||||
if(!G->outfile) red(_("Only show statistics\n"));
|
|
||||||
img = MALLOC(uint16_t, img_rows * row_width);
|
|
||||||
for (j = 0; j < G->nframes; j ++){
|
|
||||||
TRYFUNC(FLIGetTemperature, dev, &G->temperature); // temperature @ exp. start
|
|
||||||
printf("\n\n");
|
|
||||||
// úÁÈ×ÁÔ ËÁÄÒÁ %d\n
|
|
||||||
printf(_("Capture frame %d\n"), j);
|
|
||||||
TRYFUNC(FLIExposeFrame, dev);
|
|
||||||
expStartsAt = time(NULL); // ×ÒÅÍÑ ÎÁÞÁÌÁ ÜËÓÐÏÚÉÃÉÉ
|
|
||||||
do{
|
|
||||||
TRYFUNC(FLIGetTemperature, dev, &t_int);
|
|
||||||
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
|
|
||||||
if(curtime(tm_buf)){
|
|
||||||
// ÄÁÔÁ/×ÒÅÍÑ
|
|
||||||
info("%s: %s\tText=%.2f\tTint=%.2f\n", _("date/time"), tm_buf, t_ext, t_int);
|
|
||||||
}
|
|
||||||
else WARNX("curtime() error");
|
|
||||||
TRYFUNC(FLIGetExposureStatus, dev, <mp);
|
|
||||||
if(fli_err) continue;
|
|
||||||
if(G->shtr_cmd > 0 && G->shtr_cmd & FLI_SHUTTER_EXTERNAL_EXPOSURE_CONTROL && ltmp == G->exptime){
|
|
||||||
// "ÏÖÉÄÁÎÉÅ ×ÎÅÛÎÅÇÏ ÔÒÉÇÇÅÒÁ"
|
|
||||||
printf(_("wait for external trigger...\n"));
|
|
||||||
sleep(1);
|
|
||||||
}else{
|
|
||||||
// %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
|
|
||||||
printf(_("%.3f seconds till exposition ends\n"), ((float)ltmp) / 1000.);
|
|
||||||
if(ltmp > 10000) sleep(10);
|
|
||||||
else usleep(ltmp * 1000);
|
|
||||||
}
|
|
||||||
}while(ltmp);
|
|
||||||
// óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
|
|
||||||
printf(_("Read image: "));
|
|
||||||
int portion = 0;
|
|
||||||
for (row = 0; row < img_rows; row++){
|
|
||||||
TRYFUNC(FLIGrabRow, dev, &img[row * row_width], row_width);
|
|
||||||
if(fli_err) break;
|
|
||||||
int progress = (int)(((float)row / (float)img_rows) * 100.);
|
|
||||||
if(progress/5 > portion){
|
|
||||||
if((++portion)%2) printf("..");
|
|
||||||
else printf("%d%%", portion*5);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("100%%\n");
|
|
||||||
curtime(tm_buf);
|
|
||||||
print_stat(img, row_width * img_rows);
|
|
||||||
inline void WRITEIMG(int (*writefn)(char*,int,int,void*), char *ext){
|
|
||||||
if(G->outfile == NULL) return;
|
|
||||||
if(!check_filename(buff, G->outfile, ext) && !rewrite_ifexists)
|
|
||||||
// îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
|
|
||||||
WARNX(_("Can't save file"));
|
|
||||||
else{
|
|
||||||
if(rewrite_ifexists){
|
|
||||||
char *p = "";
|
|
||||||
if(strcmp(ext, "fit") == 0) p = "!";
|
|
||||||
snprintf(buff, BUFF_SIZ, "%s%s.%s", p, G->outfile, ext);
|
|
||||||
}
|
|
||||||
TRYFUNC(writefn, buff, row_width, img_rows, img);
|
|
||||||
// æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
|
|
||||||
if (fli_err == 0) info(_("File saved as '%s'"), buff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef USERAW
|
|
||||||
WRITEIMG(writeraw, "raw");
|
|
||||||
#endif // USERAW
|
|
||||||
WRITEIMG(writefits, "fit");
|
|
||||||
#ifdef USEPNG
|
|
||||||
WRITEIMG(writepng, "png");
|
|
||||||
#endif /* USEPNG */
|
|
||||||
if(G->pause_len){
|
|
||||||
double delta, time1 = dtime() + G->pause_len;
|
|
||||||
while((delta = time1 - dtime()) > 0.){
|
|
||||||
// %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
|
|
||||||
printf(_("%d seconds till pause ends\n"), (int)delta);
|
|
||||||
TRYFUNC(FLIGetTemperature, dev, &t_int);
|
|
||||||
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
|
|
||||||
if(curtime(tm_buf)){
|
|
||||||
// ÄÁÔÁ/×ÒÅÍÑ
|
|
||||||
info("%s: %s\tText=%.2f\tTint=%.2f\n", _("date/time"), tm_buf, t_ext, t_int);
|
|
||||||
}
|
|
||||||
else info("curtime() error");
|
|
||||||
if(delta > 10) sleep(10);
|
|
||||||
else sleep((int)delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FREE(camera);
|
|
||||||
FREE(img);
|
|
||||||
TRYFUNC(FLIClose, dev);
|
|
||||||
}
|
|
||||||
for (i = 0; i < num; i++)
|
|
||||||
FREE(cam[i].name);
|
|
||||||
FREE(cam);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int findcams(flidomain_t domain, cam_t **cam){
|
|
||||||
char **tmplist;
|
|
||||||
int numcams = 0;
|
|
||||||
TRYFUNC(FLIList, domain, &tmplist);
|
|
||||||
if (tmplist && tmplist[0]){
|
|
||||||
int i, cams = 0;
|
|
||||||
for (i = 0; tmplist[i]; i++) cams++;
|
|
||||||
if ((*cam = realloc(*cam, (numcams + cams) * sizeof(cam_t))) == NULL)
|
|
||||||
ERR("realloc() failed");
|
|
||||||
for (i = 0; tmplist[i]; i++){
|
|
||||||
int j;
|
|
||||||
cam_t *tmpcam = *cam + i;
|
|
||||||
for (j = 0; tmplist[i][j] != '\0'; j++)
|
|
||||||
if (tmplist[i][j] == ';'){
|
|
||||||
tmplist[i][j] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tmpcam->domain = domain;
|
|
||||||
tmpcam->name = strdup(tmplist[i]);
|
|
||||||
switch (domain & 0xff){
|
|
||||||
case FLIDOMAIN_PARALLEL_PORT:
|
|
||||||
tmpcam->dname = "parallel port";
|
|
||||||
break;
|
|
||||||
case FLIDOMAIN_USB:
|
|
||||||
tmpcam->dname = "USB";
|
|
||||||
;
|
|
||||||
break;
|
|
||||||
case FLIDOMAIN_SERIAL:
|
|
||||||
tmpcam->dname = "serial";
|
|
||||||
break;
|
|
||||||
case FLIDOMAIN_INET:
|
|
||||||
tmpcam->dname = "inet";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tmpcam->dname = "Unknown domain";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DBG("found: %s @ %s", tmpcam->name, tmpcam->dname);
|
|
||||||
}
|
|
||||||
numcams += cams;
|
|
||||||
}
|
|
||||||
else DBG("No devices");
|
|
||||||
TRYFUNC(FLIFreeList, tmplist);
|
|
||||||
return numcams;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USERAW
|
|
||||||
static int writeraw(char *filename, int width, int height, void *data){
|
|
||||||
int fd, size, err;
|
|
||||||
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
|
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) == -1){
|
|
||||||
WARN("open(%s) failed", filename);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
size = width * height * sizeof(u_int16_t);
|
|
||||||
if ((err = write(fd, data, size)) != size){
|
|
||||||
WARN("write() failed");
|
|
||||||
err = -errno;
|
|
||||||
}
|
|
||||||
else err = 0;
|
|
||||||
close(fd);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif // USERAW
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief addrec - add FITS records from file
|
|
||||||
* @param f (i) - FITS filename
|
|
||||||
* @param filename (i) - name of file
|
|
||||||
*/
|
|
||||||
static void addrec(fitsfile *f, char *filename){
|
|
||||||
FILE *fp = fopen(filename, "r");
|
|
||||||
if(!fp) return;
|
|
||||||
char buf[2*FLEN_CARD];
|
|
||||||
while(fgets(buf, 2*FLEN_CARD, fp)){
|
|
||||||
DBG("check record _%s_", buf);
|
|
||||||
int keytype, status = 0;
|
|
||||||
char newcard[FLEN_CARD], keyname[FLEN_CARD];
|
|
||||||
fits_parse_template(buf, newcard, &keytype, &status);
|
|
||||||
if(status){
|
|
||||||
fits_report_error(stderr, status);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
DBG("reformatted to _%s_", newcard);
|
|
||||||
strncpy(keyname, newcard, FLEN_CARD);
|
|
||||||
char *eq = strchr(keyname, '='); if(eq) *eq = 0;
|
|
||||||
eq = strchr(keyname, ' '); if(eq) *eq = 0;
|
|
||||||
DBG("keyname: %s", keyname);
|
|
||||||
fits_update_card(f, keyname, newcard, &status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int writefits(char *filename, int width, int height, void *data){
|
|
||||||
long naxes[2] = {width, height}, startTime;
|
|
||||||
double tmp = 0.0;
|
|
||||||
struct tm *tm_starttime;
|
|
||||||
char buf[FLEN_CARD];
|
|
||||||
time_t savetime = time(NULL);
|
|
||||||
fitsfile *fp;
|
|
||||||
TRYFITS(fits_create_file, &fp, filename);
|
|
||||||
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
|
||||||
// FILE / Input file original name
|
|
||||||
WRITEKEY(fp, TSTRING, "FILE", filename, "Input file original name");
|
|
||||||
// ORIGIN / organization responsible for the data
|
|
||||||
WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data");
|
|
||||||
// OBSERVAT / Observatory name
|
|
||||||
WRITEKEY(fp, TSTRING, "OBSERVAT", "Special Astrophysical Observatory, Russia", "Observatory name");
|
|
||||||
// DETECTOR / detector
|
|
||||||
if(camera){
|
|
||||||
WRITEKEY(fp, TSTRING, "DETECTOR", camera, "Detector model");
|
|
||||||
}
|
|
||||||
// INSTRUME / Instrument
|
|
||||||
if(G->instrument){
|
|
||||||
WRITEKEY(fp, TSTRING, "INSTRUME", G->instrument, "Instrument");
|
|
||||||
}else
|
|
||||||
WRITEKEY(fp, TSTRING, "INSTRUME", "direct imaging", "Instrument");
|
|
||||||
snprintf(buf, 80, "%.g x %.g", pixX, pixY);
|
|
||||||
// PXSIZE / pixel size
|
|
||||||
WRITEKEY(fp, TSTRING, "PXSIZE", buf, "Pixel size in m");
|
|
||||||
WRITEKEY(fp, TSTRING, "VIEWFLD", viewfield, "Camera field of view");
|
|
||||||
// CRVAL1, CRVAL2 / Offset in X, Y
|
|
||||||
if(G->X0) WRITEKEY(fp, TINT, "X0", &G->X0, "Subframe left border");
|
|
||||||
if(G->Y0) WRITEKEY(fp, TINT, "Y0", &G->Y0, "Subframe upper border");
|
|
||||||
if(G->exptime < 2.*DBL_EPSILON) sprintf(buf, "bias");
|
|
||||||
else if(frametype == FLI_FRAME_TYPE_DARK) sprintf(buf, "dark");
|
|
||||||
else if(G->objtype) strncpy(buf, G->objtype, FLEN_CARD-1);
|
|
||||||
else sprintf(buf, "object");
|
|
||||||
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
|
|
||||||
WRITEKEY(fp, TSTRING, "IMAGETYP", buf, "Image type");
|
|
||||||
// DATAMAX, DATAMIN / Max,min pixel value
|
|
||||||
int itmp = 0;
|
|
||||||
WRITEKEY(fp, TINT, "DATAMIN", &itmp, "Min pixel value");
|
|
||||||
//itmp = G->fast ? 255 : 65535;
|
|
||||||
itmp = 65535;
|
|
||||||
WRITEKEY(fp, TINT, "DATAMAX", &itmp, "Max pixel value");
|
|
||||||
WRITEKEY(fp, TUSHORT, "STATMAX", &max, "Max data value");
|
|
||||||
WRITEKEY(fp, TUSHORT, "STATMIN", &min, "Min data value");
|
|
||||||
WRITEKEY(fp, TDOUBLE, "STATAVR", &avr, "Average data value");
|
|
||||||
WRITEKEY(fp, TDOUBLE, "STATSTD", &std, "Std. of data value");
|
|
||||||
WRITEKEY(fp, TDOUBLE, "TEMP0", &G->temperature, "Camera temperature at exp. start (degr C)");
|
|
||||||
WRITEKEY(fp, TDOUBLE, "TEMP1", &t_int, "Camera temperature at exp. end (degr C)");
|
|
||||||
WRITEKEY(fp, TDOUBLE, "TEMPBODY", &t_ext, "Camera body temperature at exp. end (degr C)");
|
|
||||||
tmp = (G->temperature + t_int) / 2. + 273.15;
|
|
||||||
// CAMTEMP / Camera temperature (K)
|
|
||||||
WRITEKEY(fp, TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)");
|
|
||||||
// WHEEL & FOCUSER positions:
|
|
||||||
tmp = (double)focuserpos / FOCSCALE;
|
|
||||||
WRITEKEY(fp, TDOUBLE, "FOCUS", &tmp, "Current focuser position, mm");
|
|
||||||
if(filterpos > -1)
|
|
||||||
WRITEKEY(fp, TINT, "FILTER", &filterpos, "Current filter number");
|
|
||||||
// EXPTIME / actual exposition time (sec)
|
|
||||||
tmp = (double)G->exptime / 1000.;
|
|
||||||
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmp, "Actual exposition time (sec)");
|
|
||||||
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
|
|
||||||
strftime(buf, 80, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
|
|
||||||
WRITEKEY(fp, TSTRING, "DATE", buf, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
|
|
||||||
startTime = (long)expStartsAt;
|
|
||||||
tm_starttime = localtime(&expStartsAt);
|
|
||||||
strftime(buf, 80, "Exposition start time (UNIX)", tm_starttime);
|
|
||||||
WRITEKEY(fp, TLONG, "UNIXTIME", &startTime, buf);
|
|
||||||
strftime(buf, 80, "%Y/%m/%d", tm_starttime);
|
|
||||||
// DATE-OBS / DATE (YYYY/MM/DD) OF OBS.
|
|
||||||
WRITEKEY(fp, TSTRING, "DATE-OBS", buf, "DATE OF OBS. (YYYY/MM/DD, local)");
|
|
||||||
strftime(buf, 80, "%H:%M:%S", tm_starttime);
|
|
||||||
// START / Measurement start time (local) (hh:mm:ss)
|
|
||||||
WRITEKEY(fp, TSTRING, "START", buf, "Measurement start time (hh:mm:ss, local)");
|
|
||||||
// OBJECT / Object name
|
|
||||||
if(G->objname){
|
|
||||||
WRITEKEY(fp, TSTRING, "OBJECT", G->objname, "Object name");
|
|
||||||
}
|
|
||||||
// BINNING / Binning
|
|
||||||
if(G->hbin != 1 || G->vbin != 1){
|
|
||||||
snprintf(buf, 80, "%d x %d", G->hbin, G->vbin);
|
|
||||||
WRITEKEY(fp, TSTRING, "BINNING", buf, "Binning (hbin x vbin)");
|
|
||||||
}
|
|
||||||
// OBSERVER / Observers
|
|
||||||
if(G->observers){
|
|
||||||
WRITEKEY(fp, TSTRING, "OBSERVER", G->observers, "Observers");
|
|
||||||
}
|
|
||||||
// PROG-ID / Observation program identifier
|
|
||||||
if(G->prog_id){
|
|
||||||
WRITEKEY(fp, TSTRING, "PROG-ID", G->prog_id, "Observation program identifier");
|
|
||||||
}
|
|
||||||
// AUTHOR / Author of the program
|
|
||||||
if(G->author){
|
|
||||||
WRITEKEY(fp, TSTRING, "AUTHOR", G->author, "Author of the program");
|
|
||||||
}
|
|
||||||
if(G->addhdr){ // add records from files
|
|
||||||
char **nxtfile = G->addhdr;
|
|
||||||
while(*nxtfile){
|
|
||||||
addrec(fp, *nxtfile++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data);
|
|
||||||
TRYFITS(fits_close_file, fp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USEPNG
|
|
||||||
static int writepng(char *filename, int width, int height, void *data){
|
|
||||||
int err;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
png_structp pngptr = NULL;
|
|
||||||
png_infop infoptr = NULL;
|
|
||||||
void *row;
|
|
||||||
if ((fp = fopen(filename, "wb")) == NULL){
|
|
||||||
err = -errno;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
|
||||||
NULL, NULL, NULL)) == NULL){
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if ((infoptr = png_create_info_struct(pngptr)) == NULL){
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
png_init_io(pngptr, fp);
|
|
||||||
png_set_compression_level(pngptr, Z_BEST_COMPRESSION);
|
|
||||||
png_set_IHDR(pngptr, infoptr, width, height, 16, PNG_COLOR_TYPE_GRAY,
|
|
||||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
|
||||||
PNG_FILTER_TYPE_DEFAULT);
|
|
||||||
png_write_info(pngptr, infoptr);
|
|
||||||
png_set_swap(pngptr);
|
|
||||||
for(row = data; height > 0; row += width * sizeof(u_int16_t), height--)
|
|
||||||
png_write_row(pngptr, row);
|
|
||||||
png_write_end(pngptr, infoptr);
|
|
||||||
err = 0;
|
|
||||||
done:
|
|
||||||
if(fp) fclose(fp);
|
|
||||||
if(pngptr) png_destroy_write_struct(&pngptr, &infoptr);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
#endif /* USEPNG */
|
|
||||||
|
|
||||||
static void print_stat(u_int16_t *img, long size){
|
|
||||||
long i, Noverld = 0L;
|
|
||||||
double pv, sum=0., sum2=0., sz = (double)size;
|
|
||||||
u_int16_t *ptr = img, val;
|
|
||||||
max = 0; min = 65535;
|
|
||||||
for(i = 0; i < size; i++, ptr++){
|
|
||||||
val = *ptr;
|
|
||||||
pv = (double) val;
|
|
||||||
sum += pv;
|
|
||||||
sum2 += (pv * pv);
|
|
||||||
if(max < val) max = val;
|
|
||||||
if(min > val) min = val;
|
|
||||||
if(val >= 65530) Noverld++;
|
|
||||||
}
|
|
||||||
// óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n
|
|
||||||
printf(_("Image stat:\n"));
|
|
||||||
avr = sum/sz;
|
|
||||||
printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr,
|
|
||||||
std = sqrt(fabs(sum2/sz - avr*avr)), Noverld);
|
|
||||||
printf("max = %u, min = %u, size = %ld\n", max, min, size);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* geany_encoding=koi8-r
|
|
||||||
* main.h
|
|
||||||
*
|
|
||||||
* Copyright 2017 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#ifndef __MAIN_H__
|
|
||||||
#define __MAIN_H__
|
|
||||||
|
|
||||||
#include "usefull_macros.h"
|
|
||||||
#include "cmdlnopts.h"
|
|
||||||
|
|
||||||
#ifdef USEPNG
|
|
||||||
#include <png.h>
|
|
||||||
static int writepng(char *filename, int width, int height, void *data);
|
|
||||||
#endif /* USEPNG */
|
|
||||||
|
|
||||||
#include <libfli.h>
|
|
||||||
|
|
||||||
#define LIBVERSIZ 1024
|
|
||||||
|
|
||||||
// wheel position in steps = WHEEL_POS0STPS + WHEEL_STEPPOS*N
|
|
||||||
#define WHEEL_POS0STPS (239)
|
|
||||||
#define WHEEL_STEPPOS (48)
|
|
||||||
// 1mm == FOCSCALE steps of focuser
|
|
||||||
#define FOCSCALE (10000.)
|
|
||||||
|
|
||||||
typedef struct{
|
|
||||||
flidomain_t domain;
|
|
||||||
char *dname;
|
|
||||||
char *name;
|
|
||||||
}cam_t;
|
|
||||||
|
|
||||||
static int findcams(flidomain_t domain, cam_t **cam);
|
|
||||||
|
|
||||||
#ifdef USERAW
|
|
||||||
static int writeraw(char *filename, int width, int height, void *data);
|
|
||||||
#endif // USERAW
|
|
||||||
|
|
||||||
#define TRYFITS(f, ...) \
|
|
||||||
do{ int status = 0; \
|
|
||||||
f(__VA_ARGS__, &status); \
|
|
||||||
if (status){ \
|
|
||||||
fits_report_error(stderr, status); \
|
|
||||||
return -1;} \
|
|
||||||
}while(0)
|
|
||||||
#define WRITEKEY(...) \
|
|
||||||
do{ int status = 0; \
|
|
||||||
fits_write_key(__VA_ARGS__, &status); \
|
|
||||||
if(status) fits_report_error(stderr, status);\
|
|
||||||
}while(0)
|
|
||||||
static int writefits(char *filename, int width, int height, void *data);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __MAIN_H__
|
|
||||||
@ -1,497 +0,0 @@
|
|||||||
/* geany_encoding=koi8-r
|
|
||||||
* parseargs.c - parsing command line arguments & print help
|
|
||||||
*
|
|
||||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h> // printf
|
|
||||||
#include <getopt.h> // getopt_long
|
|
||||||
#include <stdlib.h> // calloc, exit, strtoll
|
|
||||||
#include <assert.h> // assert
|
|
||||||
#include <string.h> // strdup, strchr, strlen
|
|
||||||
#include <strings.h>// strcasecmp
|
|
||||||
#include <limits.h> // INT_MAX & so on
|
|
||||||
#include <libintl.h>// gettext
|
|
||||||
#include <ctype.h> // isalpha
|
|
||||||
#include "parseargs.h"
|
|
||||||
#include "usefull_macros.h"
|
|
||||||
|
|
||||||
char *helpstring = "%s\n";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change standard help header
|
|
||||||
* MAY consist ONE "%s" for progname
|
|
||||||
* @param str (i) - new format
|
|
||||||
*/
|
|
||||||
void change_helpstring(char *s){
|
|
||||||
int pcount = 0, scount = 0;
|
|
||||||
char *str = s;
|
|
||||||
// check `helpstring` and set it to default in case of error
|
|
||||||
for(; pcount < 2; str += 2){
|
|
||||||
if(!(str = strchr(str, '%'))) break;
|
|
||||||
if(str[1] != '%') pcount++; // increment '%' counter if it isn't "%%"
|
|
||||||
else{
|
|
||||||
str += 2; // pass next '%'
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(str[1] == 's') scount++; // increment "%s" counter
|
|
||||||
};
|
|
||||||
if(pcount > 1 || pcount != scount){ // amount of pcount and/or scount wrong
|
|
||||||
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
|
||||||
ERRX(_("Wrong helpstring!"));
|
|
||||||
}
|
|
||||||
helpstring = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Carefull atoll/atoi
|
|
||||||
* @param num (o) - returning value (or NULL if you wish only check number) - allocated by user
|
|
||||||
* @param str (i) - string with number must not be NULL
|
|
||||||
* @param t (i) - T_INT for integer or T_LLONG for long long (if argtype would be wided, may add more)
|
|
||||||
* @return TRUE if conversion sone without errors, FALSE otherwise
|
|
||||||
*/
|
|
||||||
static bool myatoll(void *num, char *str, argtype t){
|
|
||||||
long long tmp, *llptr;
|
|
||||||
int *iptr;
|
|
||||||
char *endptr;
|
|
||||||
assert(str);
|
|
||||||
assert(num);
|
|
||||||
tmp = strtoll(str, &endptr, 0);
|
|
||||||
if(endptr == str || *str == '\0' || *endptr != '\0')
|
|
||||||
return FALSE;
|
|
||||||
switch(t){
|
|
||||||
case arg_longlong:
|
|
||||||
llptr = (long long*) num;
|
|
||||||
*llptr = tmp;
|
|
||||||
break;
|
|
||||||
case arg_int:
|
|
||||||
default:
|
|
||||||
if(tmp < INT_MIN || tmp > INT_MAX){
|
|
||||||
/// "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
|
||||||
WARNX(_("Integer out of range"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
iptr = (int*)num;
|
|
||||||
*iptr = (int)tmp;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the same as myatoll but for double
|
|
||||||
// There's no NAN & INF checking here (what if they would be needed?)
|
|
||||||
static bool myatod(void *num, const char *str, argtype t){
|
|
||||||
double tmp, *dptr;
|
|
||||||
float *fptr;
|
|
||||||
char *endptr;
|
|
||||||
assert(str);
|
|
||||||
tmp = strtod(str, &endptr);
|
|
||||||
if(endptr == str || *str == '\0' || *endptr != '\0')
|
|
||||||
return FALSE;
|
|
||||||
switch(t){
|
|
||||||
case arg_double:
|
|
||||||
dptr = (double *) num;
|
|
||||||
*dptr = tmp;
|
|
||||||
break;
|
|
||||||
case arg_float:
|
|
||||||
default:
|
|
||||||
fptr = (float *) num;
|
|
||||||
*fptr = (float)tmp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get index of current option in array options
|
|
||||||
* @param opt (i) - returning val of getopt_long
|
|
||||||
* @param options (i) - array of options
|
|
||||||
* @return index in array
|
|
||||||
*/
|
|
||||||
static int get_optind(int opt, myoption *options){
|
|
||||||
int oind;
|
|
||||||
myoption *opts = options;
|
|
||||||
assert(opts);
|
|
||||||
for(oind = 0; opts->name && opts->val != opt; oind++, opts++);
|
|
||||||
if(!opts->name || opts->val != opt) // no such parameter
|
|
||||||
showhelp(-1, options);
|
|
||||||
return oind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* reallocate new value in array of multiple repeating arguments
|
|
||||||
* @arg paptr - address of pointer to array (**void)
|
|
||||||
* @arg type - its type (for realloc)
|
|
||||||
* @return pointer to new (next) value
|
|
||||||
*/
|
|
||||||
void *get_aptr(void *paptr, argtype type){
|
|
||||||
int i = 1;
|
|
||||||
void **aptr = *((void***)paptr);
|
|
||||||
if(aptr){ // there's something in array
|
|
||||||
void **p = aptr;
|
|
||||||
while(*p++) ++i;
|
|
||||||
}
|
|
||||||
size_t sz = 0;
|
|
||||||
switch(type){
|
|
||||||
default:
|
|
||||||
case arg_none:
|
|
||||||
/// "îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÎÅÓËÏÌØËÏ ÐÁÒÁÍÅÔÒÏ× ÂÅÚ ÁÒÇÕÍÅÎÔÏ×!"
|
|
||||||
ERRX("Can't use multiple args with arg_none!");
|
|
||||||
break;
|
|
||||||
case arg_int:
|
|
||||||
sz = sizeof(int);
|
|
||||||
break;
|
|
||||||
case arg_longlong:
|
|
||||||
sz = sizeof(long long);
|
|
||||||
break;
|
|
||||||
case arg_double:
|
|
||||||
sz = sizeof(double);
|
|
||||||
break;
|
|
||||||
case arg_float:
|
|
||||||
sz = sizeof(float);
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
sz = 0;
|
|
||||||
break;
|
|
||||||
/* case arg_function:
|
|
||||||
sz = sizeof(argfn *);
|
|
||||||
break;*/
|
|
||||||
}
|
|
||||||
aptr = realloc(aptr, (i + 1) * sizeof(void*));
|
|
||||||
*((void***)paptr) = aptr;
|
|
||||||
aptr[i] = NULL;
|
|
||||||
if(sz){
|
|
||||||
aptr[i - 1] = malloc(sz);
|
|
||||||
}else
|
|
||||||
aptr[i - 1] = &aptr[i - 1];
|
|
||||||
return aptr[i - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse command line arguments
|
|
||||||
* ! If arg is string, then value will be strdup'ed!
|
|
||||||
*
|
|
||||||
* @param argc (io) - address of argc of main(), return value of argc stay after `getopt`
|
|
||||||
* @param argv (io) - address of argv of main(), return pointer to argv stay after `getopt`
|
|
||||||
* BE CAREFUL! if you wanna use full argc & argv, save their original values before
|
|
||||||
* calling this function
|
|
||||||
* @param options (i) - array of `myoption` for arguments parcing
|
|
||||||
*
|
|
||||||
* @exit: in case of error this function show help & make `exit(-1)`
|
|
||||||
*/
|
|
||||||
void parseargs(int *argc, char ***argv, myoption *options){
|
|
||||||
char *short_options, *soptr;
|
|
||||||
struct option *long_options, *loptr;
|
|
||||||
size_t optsize, i;
|
|
||||||
myoption *opts = options;
|
|
||||||
// check whether there is at least one options
|
|
||||||
assert(opts);
|
|
||||||
assert(opts[0].name);
|
|
||||||
// first we count how much values are in opts
|
|
||||||
for(optsize = 0; opts->name; optsize++, opts++);
|
|
||||||
// now we can allocate memory
|
|
||||||
short_options = calloc(optsize * 3 + 1, 1); // multiply by three for '::' in case of args in opts
|
|
||||||
long_options = calloc(optsize + 1, sizeof(struct option));
|
|
||||||
opts = options; loptr = long_options; soptr = short_options;
|
|
||||||
// in debug mode check the parameters are not repeated
|
|
||||||
#ifdef EBUG
|
|
||||||
char **longlist = MALLOC(char*, optsize);
|
|
||||||
char *shortlist = MALLOC(char, optsize);
|
|
||||||
#endif
|
|
||||||
// fill short/long parameters and make a simple checking
|
|
||||||
for(i = 0; i < optsize; i++, loptr++, opts++){
|
|
||||||
// check
|
|
||||||
assert(opts->name); // check name
|
|
||||||
#ifdef EBUG
|
|
||||||
longlist[i] = strdup(opts->name);
|
|
||||||
#endif
|
|
||||||
if(opts->has_arg){
|
|
||||||
assert(opts->type != arg_none); // check error with arg type
|
|
||||||
assert(opts->argptr); // check pointer
|
|
||||||
}
|
|
||||||
if(opts->type != arg_none) // if there is a flag without arg, check its pointer
|
|
||||||
assert(opts->argptr);
|
|
||||||
// fill long_options
|
|
||||||
// don't do memcmp: what if there would be different alignment?
|
|
||||||
loptr->name = opts->name;
|
|
||||||
loptr->has_arg = (opts->has_arg < MULT_PAR) ? opts->has_arg : 1;
|
|
||||||
loptr->flag = opts->flag;
|
|
||||||
loptr->val = opts->val;
|
|
||||||
// fill short options if they are:
|
|
||||||
if(!opts->flag && opts->val){
|
|
||||||
#ifdef EBUG
|
|
||||||
shortlist[i] = (char) opts->val;
|
|
||||||
#endif
|
|
||||||
*soptr++ = opts->val;
|
|
||||||
if(loptr->has_arg) // add ':' if option has required argument
|
|
||||||
*soptr++ = ':';
|
|
||||||
if(loptr->has_arg == 2) // add '::' if option has optional argument
|
|
||||||
*soptr++ = ':';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sort all lists & check for repeating
|
|
||||||
#ifdef EBUG
|
|
||||||
int cmpstringp(const void *p1, const void *p2){
|
|
||||||
return strcmp(* (char * const *) p1, * (char * const *) p2);
|
|
||||||
}
|
|
||||||
int cmpcharp(const void *p1, const void *p2){
|
|
||||||
return (int)(*(char * const)p1 - *(char *const)p2);
|
|
||||||
}
|
|
||||||
qsort(longlist, optsize, sizeof(char *), cmpstringp);
|
|
||||||
qsort(shortlist,optsize, sizeof(char), cmpcharp);
|
|
||||||
char *prevl = longlist[0], prevshrt = shortlist[0];
|
|
||||||
for(i = 1; i < optsize; ++i){
|
|
||||||
if(longlist[i]){
|
|
||||||
if(prevl){
|
|
||||||
if(strcmp(prevl, longlist[i]) == 0) ERRX("double long arguments: --%s", prevl);
|
|
||||||
}
|
|
||||||
prevl = longlist[i];
|
|
||||||
}
|
|
||||||
if(shortlist[i]){
|
|
||||||
if(prevshrt){
|
|
||||||
if(prevshrt == shortlist[i]) ERRX("double short arguments: -%c", prevshrt);
|
|
||||||
}
|
|
||||||
prevshrt = shortlist[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// now we have both long_options & short_options and can parse `getopt_long`
|
|
||||||
while(1){
|
|
||||||
int opt;
|
|
||||||
int oindex = 0, optind = 0; // oindex - number of option in argv, optind - number in options[]
|
|
||||||
if((opt = getopt_long(*argc, *argv, short_options, long_options, &oindex)) == -1) break;
|
|
||||||
if(opt == '?'){
|
|
||||||
opt = optopt;
|
|
||||||
optind = get_optind(opt, options);
|
|
||||||
if(options[optind].has_arg == NEED_ARG || options[optind].has_arg == MULT_PAR)
|
|
||||||
showhelp(optind, options); // need argument
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(opt == 0 || oindex > 0) optind = oindex;
|
|
||||||
else optind = get_optind(opt, options);
|
|
||||||
}
|
|
||||||
opts = &options[optind];
|
|
||||||
// if(opt == 0 && opts->has_arg == NO_ARGS) continue; // only long option changing integer flag
|
|
||||||
// now check option
|
|
||||||
if(opts->has_arg == NEED_ARG || opts->has_arg == MULT_PAR)
|
|
||||||
if(!optarg) showhelp(optind, options); // need argument
|
|
||||||
void *aptr;
|
|
||||||
if(opts->has_arg == MULT_PAR){
|
|
||||||
aptr = get_aptr(opts->argptr, opts->type);
|
|
||||||
}else
|
|
||||||
aptr = opts->argptr;
|
|
||||||
bool result = TRUE;
|
|
||||||
// even if there is no argument, but argptr != NULL, think that optarg = "1"
|
|
||||||
if(!optarg) optarg = "1";
|
|
||||||
switch(opts->type){
|
|
||||||
default:
|
|
||||||
case arg_none:
|
|
||||||
if(opts->argptr) *((int*)aptr) += 1; // increment value
|
|
||||||
break;
|
|
||||||
case arg_int:
|
|
||||||
result = myatoll(aptr, optarg, arg_int);
|
|
||||||
break;
|
|
||||||
case arg_longlong:
|
|
||||||
result = myatoll(aptr, optarg, arg_longlong);
|
|
||||||
break;
|
|
||||||
case arg_double:
|
|
||||||
result = myatod(aptr, optarg, arg_double);
|
|
||||||
break;
|
|
||||||
case arg_float:
|
|
||||||
result = myatod(aptr, optarg, arg_float);
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
result = (*((void**)aptr) = (void*)strdup(optarg));
|
|
||||||
break;
|
|
||||||
case arg_function:
|
|
||||||
result = ((argfn)aptr)(optarg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!result){
|
|
||||||
showhelp(optind, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*argc -= optind;
|
|
||||||
*argv += optind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* compare function for qsort
|
|
||||||
* first - sort by short options; second - sort arguments without sort opts (by long options)
|
|
||||||
*/
|
|
||||||
static int argsort(const void *a1, const void *a2){
|
|
||||||
const myoption *o1 = (myoption*)a1, *o2 = (myoption*)a2;
|
|
||||||
const char *l1 = o1->name, *l2 = o2->name;
|
|
||||||
int s1 = o1->val, s2 = o2->val;
|
|
||||||
int *f1 = o1->flag, *f2 = o2->flag;
|
|
||||||
// check if both options has short arg
|
|
||||||
if(f1 == NULL && f2 == NULL && s1 && s2){ // both have short arg
|
|
||||||
return (s1 - s2);
|
|
||||||
}else if((f1 != NULL || !s1) && (f2 != NULL || !s2)){ // both don't have short arg - sort by long
|
|
||||||
return strcmp(l1, l2);
|
|
||||||
}else{ // only one have short arg -- return it
|
|
||||||
if(f2 || !s2) return -1; // a1 have short - it is 'lesser'
|
|
||||||
else return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show help information based on myoption->help values
|
|
||||||
* @param oindex (i) - if non-negative, show only help by myoption[oindex].help
|
|
||||||
* @param options (i) - array of `myoption`
|
|
||||||
*
|
|
||||||
* @exit: run `exit(-1)` !!!
|
|
||||||
*/
|
|
||||||
void showhelp(int oindex, myoption *options){
|
|
||||||
int max_opt_len = 0; // max len of options substring - for right indentation
|
|
||||||
const int bufsz = 255;
|
|
||||||
char buf[bufsz+1];
|
|
||||||
myoption *opts = options;
|
|
||||||
assert(opts);
|
|
||||||
assert(opts[0].name); // check whether there is at least one options
|
|
||||||
if(oindex > -1){ // print only one message
|
|
||||||
opts = &options[oindex];
|
|
||||||
printf(" ");
|
|
||||||
if(!opts->flag && isalpha(opts->val)) printf("-%c, ", opts->val);
|
|
||||||
printf("--%s", opts->name);
|
|
||||||
if(opts->has_arg == 1) printf("=arg");
|
|
||||||
else if(opts->has_arg == 2) printf("[=arg]");
|
|
||||||
printf(" %s\n", _(opts->help));
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
// header, by default is just "progname\n"
|
|
||||||
printf("\n");
|
|
||||||
if(strstr(helpstring, "%s")) // print progname
|
|
||||||
printf(helpstring, __progname);
|
|
||||||
else // only text
|
|
||||||
printf("%s", helpstring);
|
|
||||||
printf("\n");
|
|
||||||
// count max_opt_len
|
|
||||||
do{
|
|
||||||
int L = strlen(opts->name);
|
|
||||||
if(max_opt_len < L) max_opt_len = L;
|
|
||||||
}while((++opts)->name);
|
|
||||||
max_opt_len += 14; // format: '-S , --long[=arg]' - get addition 13 symbols
|
|
||||||
opts = options;
|
|
||||||
// count amount of options
|
|
||||||
int N; for(N = 0; opts->name; ++N, ++opts);
|
|
||||||
if(N == 0) exit(-2);
|
|
||||||
// Now print all help (sorted)
|
|
||||||
opts = options;
|
|
||||||
qsort(opts, N, sizeof(myoption), argsort);
|
|
||||||
do{
|
|
||||||
int p = sprintf(buf, " "); // a little indent
|
|
||||||
if(!opts->flag && opts->val) // .val is short argument
|
|
||||||
p += snprintf(buf+p, bufsz-p, "-%c, ", opts->val);
|
|
||||||
p += snprintf(buf+p, bufsz-p, "--%s", opts->name);
|
|
||||||
if(opts->has_arg == 1) // required argument
|
|
||||||
p += snprintf(buf+p, bufsz-p, "=arg");
|
|
||||||
else if(opts->has_arg == 2) // optional argument
|
|
||||||
p += snprintf(buf+p, bufsz-p, "[=arg]");
|
|
||||||
assert(p < max_opt_len); // there would be magic if p >= max_opt_len
|
|
||||||
printf("%-*s%s\n", max_opt_len+1, buf, _(opts->help)); // write options & at least 2 spaces after
|
|
||||||
++opts;
|
|
||||||
}while(--N);
|
|
||||||
printf("\n\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get suboptions from parameter string
|
|
||||||
* @param str - parameter string
|
|
||||||
* @param opt - pointer to suboptions structure
|
|
||||||
* @return TRUE if all OK
|
|
||||||
*/
|
|
||||||
bool get_suboption(char *str, mysuboption *opt){
|
|
||||||
int findsubopt(char *par, mysuboption *so){
|
|
||||||
int idx = 0;
|
|
||||||
if(!par) return -1;
|
|
||||||
while(so[idx].name){
|
|
||||||
if(strcasecmp(par, so[idx].name) == 0) return idx;
|
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
return -1; // badarg
|
|
||||||
}
|
|
||||||
bool opt_setarg(mysuboption *so, int idx, char *val){
|
|
||||||
mysuboption *soptr = &so[idx];
|
|
||||||
bool result = FALSE;
|
|
||||||
void *aptr = soptr->argptr;
|
|
||||||
switch(soptr->type){
|
|
||||||
default:
|
|
||||||
case arg_none:
|
|
||||||
if(soptr->argptr) *((int*)aptr) += 1; // increment value
|
|
||||||
result = TRUE;
|
|
||||||
break;
|
|
||||||
case arg_int:
|
|
||||||
result = myatoll(aptr, val, arg_int);
|
|
||||||
break;
|
|
||||||
case arg_longlong:
|
|
||||||
result = myatoll(aptr, val, arg_longlong);
|
|
||||||
break;
|
|
||||||
case arg_double:
|
|
||||||
result = myatod(aptr, val, arg_double);
|
|
||||||
break;
|
|
||||||
case arg_float:
|
|
||||||
result = myatod(aptr, val, arg_float);
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
result = (*((void**)aptr) = (void*)strdup(val));
|
|
||||||
break;
|
|
||||||
case arg_function:
|
|
||||||
result = ((argfn)aptr)(val);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
char *tok;
|
|
||||||
bool ret = FALSE;
|
|
||||||
char *tmpbuf;
|
|
||||||
tok = strtok_r(str, ":,", &tmpbuf);
|
|
||||||
do{
|
|
||||||
char *val = strchr(tok, '=');
|
|
||||||
int noarg = 0;
|
|
||||||
if(val == NULL){ // no args
|
|
||||||
val = "1";
|
|
||||||
noarg = 1;
|
|
||||||
}else{
|
|
||||||
*val++ = '\0';
|
|
||||||
if(!*val || *val == ':' || *val == ','){ // no argument - delimeter after =
|
|
||||||
val = "1"; noarg = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int idx = findsubopt(tok, opt);
|
|
||||||
if(idx < 0){
|
|
||||||
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
|
||||||
WARNX(_("Wrong parameter: %s"), tok);
|
|
||||||
goto returning;
|
|
||||||
}
|
|
||||||
if(noarg && opt[idx].has_arg == NEED_ARG){
|
|
||||||
/// "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
|
||||||
WARNX(_("%s: argument needed!"), tok);
|
|
||||||
goto returning;
|
|
||||||
}
|
|
||||||
if(!opt_setarg(opt, idx, val)){
|
|
||||||
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
|
||||||
WARNX(_("Wrong argument \"%s\" of parameter \"%s\""), val, tok);
|
|
||||||
goto returning;
|
|
||||||
}
|
|
||||||
}while((tok = strtok_r(NULL, ":,", &tmpbuf)));
|
|
||||||
ret = TRUE;
|
|
||||||
returning:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* parseargs.h - headers for parsing command line arguments
|
|
||||||
*
|
|
||||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#ifndef __PARSEARGS_H__
|
|
||||||
#define __PARSEARGS_H__
|
|
||||||
|
|
||||||
#include <stdbool.h>// bool
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE true
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// macro for argptr
|
|
||||||
#define APTR(x) ((void*)x)
|
|
||||||
|
|
||||||
// if argptr is a function:
|
|
||||||
typedef bool(*argfn)(void *arg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* type of getopt's argument
|
|
||||||
* WARNING!
|
|
||||||
* My function change value of flags by pointer, so if you want to use another type
|
|
||||||
* make a latter conversion, example:
|
|
||||||
* char charg;
|
|
||||||
* int iarg;
|
|
||||||
* myoption opts[] = {
|
|
||||||
* {"value", 1, NULL, 'v', arg_int, &iarg, "char val"}, ..., end_option};
|
|
||||||
* ..(parse args)..
|
|
||||||
* charg = (char) iarg;
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
arg_none = 0, // no arg
|
|
||||||
arg_int, // integer
|
|
||||||
arg_longlong, // long long
|
|
||||||
arg_double, // double
|
|
||||||
arg_float, // float
|
|
||||||
arg_string, // char *
|
|
||||||
arg_function // parse_args will run function `bool (*fn)(char *optarg, int N)`
|
|
||||||
} argtype;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Structure for getopt_long & help
|
|
||||||
* BE CAREFUL: .argptr is pointer to data or pointer to function,
|
|
||||||
* conversion depends on .type
|
|
||||||
*
|
|
||||||
* ATTENTION: string `help` prints through macro PRNT(), bu default it is gettext,
|
|
||||||
* but you can redefine it before `#include "parseargs.h"`
|
|
||||||
*
|
|
||||||
* if arg is string, then value wil be strdup'ed like that:
|
|
||||||
* char *str;
|
|
||||||
* myoption opts[] = {{"string", 1, NULL, 's', arg_string, &str, "string val"}, ..., end_option};
|
|
||||||
* *(opts[1].str) = strdup(optarg);
|
|
||||||
* in other cases argptr should be address of some variable (or pointer to allocated memory)
|
|
||||||
*
|
|
||||||
* NON-NULL argptr should be written inside macro APTR(argptr) or directly: (void*)argptr
|
|
||||||
*
|
|
||||||
* !!!LAST VALUE OF ARRAY SHOULD BE `end_option` or ZEROS !!!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef enum{
|
|
||||||
NO_ARGS = 0, // first three are the same as in getopt_long
|
|
||||||
NEED_ARG = 1,
|
|
||||||
OPT_ARG = 2,
|
|
||||||
MULT_PAR
|
|
||||||
} hasarg;
|
|
||||||
|
|
||||||
typedef struct{
|
|
||||||
// these are from struct option:
|
|
||||||
const char *name; // long option's name
|
|
||||||
hasarg has_arg; // 0 - no args, 1 - nesessary arg, 2 - optionally arg, 4 - need arg & key can repeat (args are stored in null-terminated array)
|
|
||||||
int *flag; // NULL to return val, pointer to int - to set its value of val (function returns 0)
|
|
||||||
int val; // short opt name (if flag == NULL) or flag's value
|
|
||||||
// and these are mine:
|
|
||||||
argtype type; // type of argument
|
|
||||||
void *argptr; // pointer to variable to assign optarg value or function `bool (*fn)(char *optarg, int N)`
|
|
||||||
const char *help; // help string which would be shown in function `showhelp` or NULL
|
|
||||||
} myoption;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Suboptions structure, almost the same like myoption
|
|
||||||
* used in parse_subopts()
|
|
||||||
*/
|
|
||||||
typedef struct{
|
|
||||||
const char *name;
|
|
||||||
hasarg has_arg;
|
|
||||||
argtype type;
|
|
||||||
void *argptr;
|
|
||||||
} mysuboption;
|
|
||||||
|
|
||||||
// last string of array (all zeros)
|
|
||||||
#define end_option {0,0,0,0,0,0,0}
|
|
||||||
#define end_suboption {0,0,0,0}
|
|
||||||
|
|
||||||
extern const char *__progname;
|
|
||||||
|
|
||||||
void showhelp(int oindex, myoption *options);
|
|
||||||
void parseargs(int *argc, char ***argv, myoption *options);
|
|
||||||
void change_helpstring(char *s);
|
|
||||||
bool get_suboption(char *str, mysuboption *opt);
|
|
||||||
|
|
||||||
#endif // __PARSEARGS_H__
|
|
||||||
@ -1,369 +0,0 @@
|
|||||||
/*
|
|
||||||
* usefull_macros.h - a set of usefull functions: memory, color etc
|
|
||||||
*
|
|
||||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "usefull_macros.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* function for different purposes that need to know time intervals
|
|
||||||
* @return double value: time in seconds
|
|
||||||
*/
|
|
||||||
double dtime(){
|
|
||||||
double t;
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* Coloured terminal
|
|
||||||
\******************************************************************************/
|
|
||||||
int globErr = 0; // errno for WARN/ERR
|
|
||||||
|
|
||||||
// pointers to coloured output printf
|
|
||||||
int (*red)(const char *fmt, ...);
|
|
||||||
int (*green)(const char *fmt, ...);
|
|
||||||
int (*_WARN)(const char *fmt, ...);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* format red / green messages
|
|
||||||
* name: r_pr_, g_pr_
|
|
||||||
* @param fmt ... - printf-like format
|
|
||||||
* @return number of printed symbols
|
|
||||||
*/
|
|
||||||
int r_pr_(const char *fmt, ...){
|
|
||||||
va_list ar; int i;
|
|
||||||
printf(RED);
|
|
||||||
va_start(ar, fmt);
|
|
||||||
i = vprintf(fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
printf(OLDCOLOR);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
int g_pr_(const char *fmt, ...){
|
|
||||||
va_list ar; int i;
|
|
||||||
printf(GREEN);
|
|
||||||
va_start(ar, fmt);
|
|
||||||
i = vprintf(fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
printf(OLDCOLOR);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* print red error/warning messages (if output is a tty)
|
|
||||||
* @param fmt ... - printf-like format
|
|
||||||
* @return number of printed symbols
|
|
||||||
*/
|
|
||||||
int r_WARN(const char *fmt, ...){
|
|
||||||
va_list ar; int i = 1;
|
|
||||||
fprintf(stderr, RED);
|
|
||||||
va_start(ar, fmt);
|
|
||||||
if(globErr){
|
|
||||||
errno = globErr;
|
|
||||||
vwarn(fmt, ar);
|
|
||||||
errno = 0;
|
|
||||||
}else
|
|
||||||
i = vfprintf(stderr, fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
i++;
|
|
||||||
fprintf(stderr, OLDCOLOR "\n");
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char stars[] = "****************************************";
|
|
||||||
/*
|
|
||||||
* notty variants of coloured printf
|
|
||||||
* name: s_WARN, r_pr_notty
|
|
||||||
* @param fmt ... - printf-like format
|
|
||||||
* @return number of printed symbols
|
|
||||||
*/
|
|
||||||
int s_WARN(const char *fmt, ...){
|
|
||||||
va_list ar; int i;
|
|
||||||
i = fprintf(stderr, "\n%s\n", stars);
|
|
||||||
va_start(ar, fmt);
|
|
||||||
if(globErr){
|
|
||||||
errno = globErr;
|
|
||||||
vwarn(fmt, ar);
|
|
||||||
errno = 0;
|
|
||||||
}else
|
|
||||||
i = +vfprintf(stderr, fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
i += fprintf(stderr, "\n%s\n", stars);
|
|
||||||
i += fprintf(stderr, "\n");
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
int r_pr_notty(const char *fmt, ...){
|
|
||||||
va_list ar; int i;
|
|
||||||
i = printf("\n%s\n", stars);
|
|
||||||
va_start(ar, fmt);
|
|
||||||
i += vprintf(fmt, ar);
|
|
||||||
va_end(ar);
|
|
||||||
i += printf("\n%s\n", stars);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run this function in the beginning of main() to setup locale & coloured output
|
|
||||||
*/
|
|
||||||
void initial_setup(){
|
|
||||||
// setup coloured output
|
|
||||||
if(isatty(STDOUT_FILENO)){ // make color output in tty
|
|
||||||
red = r_pr_; green = g_pr_;
|
|
||||||
}else{ // no colors in case of pipe
|
|
||||||
red = r_pr_notty; green = printf;
|
|
||||||
}
|
|
||||||
if(isatty(STDERR_FILENO)) _WARN = r_WARN;
|
|
||||||
else _WARN = s_WARN;
|
|
||||||
// Setup locale
|
|
||||||
setlocale(LC_ALL, "");
|
|
||||||
setlocale(LC_NUMERIC, "C");
|
|
||||||
#if defined GETTEXT_PACKAGE && defined LOCALEDIR
|
|
||||||
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
|
||||||
textdomain(GETTEXT_PACKAGE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* Memory
|
|
||||||
\******************************************************************************/
|
|
||||||
/*
|
|
||||||
* safe memory allocation for macro ALLOC
|
|
||||||
* @param N - number of elements to allocate
|
|
||||||
* @param S - size of single element (typically sizeof)
|
|
||||||
* @return pointer to allocated memory area
|
|
||||||
*/
|
|
||||||
void *my_alloc(size_t N, size_t S){
|
|
||||||
void *p = calloc(N, S);
|
|
||||||
if(!p) ERR("malloc");
|
|
||||||
//assert(p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mmap file to a memory area
|
|
||||||
*
|
|
||||||
* @param filename (i) - name of file to mmap
|
|
||||||
* @return stuct with mmap'ed file or die
|
|
||||||
*/
|
|
||||||
mmapbuf *My_mmap(char *filename){
|
|
||||||
int fd;
|
|
||||||
char *ptr;
|
|
||||||
size_t Mlen;
|
|
||||||
struct stat statbuf;
|
|
||||||
/// "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
|
|
||||||
if(!filename){
|
|
||||||
WARNX(_("No filename given!"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if((fd = open(filename, O_RDONLY)) < 0){
|
|
||||||
/// "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
|
||||||
WARN(_("Can't open %s for reading"), filename);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(fstat (fd, &statbuf) < 0){
|
|
||||||
/// "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
|
||||||
WARN(_("Can't stat %s"), filename);
|
|
||||||
close(fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Mlen = statbuf.st_size;
|
|
||||||
if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED){
|
|
||||||
/// "ïÛÉÂËÁ mmap"
|
|
||||||
WARN(_("Mmap error for input"));
|
|
||||||
close(fd);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/// "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
|
||||||
if(close(fd)) WARN(_("Can't close mmap'ed file"));
|
|
||||||
mmapbuf *ret = MALLOC(mmapbuf, 1);
|
|
||||||
ret->data = ptr;
|
|
||||||
ret->len = Mlen;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void My_munmap(mmapbuf *b){
|
|
||||||
if(munmap(b->data, b->len)){
|
|
||||||
/// "îÅ ÍÏÇÕ munmap"
|
|
||||||
WARN(_("Can't munmap"));
|
|
||||||
}
|
|
||||||
FREE(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* Terminal in no-echo mode
|
|
||||||
\******************************************************************************/
|
|
||||||
static struct termios oldt, newt; // terminal flags
|
|
||||||
static int console_changed = 0;
|
|
||||||
// run on exit:
|
|
||||||
void restore_console(){
|
|
||||||
if(console_changed)
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // return terminal to previous state
|
|
||||||
console_changed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initial setup:
|
|
||||||
void setup_con(){
|
|
||||||
if(console_changed) return;
|
|
||||||
tcgetattr(STDIN_FILENO, &oldt);
|
|
||||||
newt = oldt;
|
|
||||||
newt.c_lflag &= ~(ICANON | ECHO);
|
|
||||||
if(tcsetattr(STDIN_FILENO, TCSANOW, &newt) < 0){
|
|
||||||
/// "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
|
||||||
WARN(_("Can't setup console"));
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
|
||||||
signals(0); //quit?
|
|
||||||
}
|
|
||||||
console_changed = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read character from console without echo
|
|
||||||
* @return char readed
|
|
||||||
*/
|
|
||||||
int read_console(){
|
|
||||||
int rb;
|
|
||||||
struct timeval tv;
|
|
||||||
int retval;
|
|
||||||
fd_set rfds;
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(STDIN_FILENO, &rfds);
|
|
||||||
tv.tv_sec = 0; tv.tv_usec = 10000;
|
|
||||||
retval = select(1, &rfds, NULL, NULL, &tv);
|
|
||||||
if(!retval) rb = 0;
|
|
||||||
else {
|
|
||||||
if(FD_ISSET(STDIN_FILENO, &rfds)) rb = getchar();
|
|
||||||
else rb = 0;
|
|
||||||
}
|
|
||||||
return rb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getchar() without echo
|
|
||||||
* wait until at least one character pressed
|
|
||||||
* @return character readed
|
|
||||||
*/
|
|
||||||
int mygetchar(){ // getchar() without need of pressing ENTER
|
|
||||||
int ret;
|
|
||||||
do ret = read_console();
|
|
||||||
while(ret == 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
* TTY with select()
|
|
||||||
\******************************************************************************/
|
|
||||||
static struct termio oldtty, tty; // TTY flags
|
|
||||||
static int comfd = -1; // TTY fd
|
|
||||||
|
|
||||||
// run on exit:
|
|
||||||
void restore_tty(){
|
|
||||||
if(comfd == -1) return;
|
|
||||||
ioctl(comfd, TCSANOW, &oldtty ); // return TTY to previous state
|
|
||||||
close(comfd);
|
|
||||||
comfd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef BAUD_RATE
|
|
||||||
#define BAUD_RATE B9600
|
|
||||||
#endif
|
|
||||||
// init:
|
|
||||||
void tty_init(char *comdev){
|
|
||||||
DBG("\nOpen port...\n");
|
|
||||||
if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){
|
|
||||||
WARN("Can't use port %s\n",comdev);
|
|
||||||
ioctl(comfd, TCSANOW, &oldtty); // return TTY to previous state
|
|
||||||
close(comfd);
|
|
||||||
signals(0); // quit?
|
|
||||||
}
|
|
||||||
DBG(" OK\nGet current settings... ");
|
|
||||||
if(ioctl(comfd,TCGETA,&oldtty) < 0){ // Get settings
|
|
||||||
/// "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÎÁÓÔÒÏÊËÉ"
|
|
||||||
WARN(_("Can't get settings"));
|
|
||||||
signals(0);
|
|
||||||
}
|
|
||||||
tty = oldtty;
|
|
||||||
tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG)
|
|
||||||
tty.c_oflag = 0;
|
|
||||||
tty.c_cflag = BAUD_RATE|CS8|CREAD|CLOCAL; // 9.6k, 8N1, RW, ignore line ctrl
|
|
||||||
tty.c_cc[VMIN] = 0; // non-canonical mode
|
|
||||||
tty.c_cc[VTIME] = 5;
|
|
||||||
if(ioctl(comfd,TCSETA,&tty) < 0){
|
|
||||||
/// "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ"
|
|
||||||
WARN(_("Can't set settings"));
|
|
||||||
signals(0);
|
|
||||||
}
|
|
||||||
DBG(" OK\n");
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Read data from TTY
|
|
||||||
* @param buff (o) - buffer for data read
|
|
||||||
* @param length - buffer len
|
|
||||||
* @return amount of readed bytes
|
|
||||||
*/
|
|
||||||
size_t read_tty(uint8_t *buff, size_t length){
|
|
||||||
ssize_t L = 0;
|
|
||||||
fd_set rfds;
|
|
||||||
struct timeval tv;
|
|
||||||
int retval;
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(comfd, &rfds);
|
|
||||||
tv.tv_sec = 0; tv.tv_usec = 50000; // wait for 50ms
|
|
||||||
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
|
|
||||||
if (!retval) return 0;
|
|
||||||
if(FD_ISSET(comfd, &rfds)){
|
|
||||||
if((L = read(comfd, buff, length)) < 1) return 0;
|
|
||||||
}
|
|
||||||
return (size_t)L;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_tty(uint8_t *buff, size_t length){
|
|
||||||
ssize_t L = write(comfd, buff, length);
|
|
||||||
if((size_t)L != length){
|
|
||||||
/// "ïÛÉÂËÁ ÚÁÐÉÓÉ!"
|
|
||||||
WARN("Write error!");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely convert data from string to double
|
|
||||||
*
|
|
||||||
* @param num (o) - double number read from string
|
|
||||||
* @param str (i) - input string
|
|
||||||
* @return 1 if success, 0 if fails
|
|
||||||
*/
|
|
||||||
int str2double(double *num, const char *str){
|
|
||||||
double res;
|
|
||||||
char *endptr;
|
|
||||||
if(!str) return 0;
|
|
||||||
res = strtod(str, &endptr);
|
|
||||||
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
|
||||||
/// "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÞÉÓÌÁ double!"
|
|
||||||
WARNX("Wrong double number format!");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if(num) *num = res; // you may run it like myatod(NULL, str) to test wether str is double number
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* usefull_macros.h - a set of usefull macros: memory, color etc
|
|
||||||
*
|
|
||||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
||||||
* MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef __USEFULL_MACROS_H__
|
|
||||||
#define __USEFULL_MACROS_H__
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include <locale.h>
|
|
||||||
#if defined GETTEXT_PACKAGE && defined LOCALEDIR
|
|
||||||
/*
|
|
||||||
* GETTEXT
|
|
||||||
*/
|
|
||||||
#include <libintl.h>
|
|
||||||
#define _(String) gettext(String)
|
|
||||||
#define gettext_noop(String) String
|
|
||||||
#define N_(String) gettext_noop(String)
|
|
||||||
#else
|
|
||||||
#define _(String) (String)
|
|
||||||
#define N_(String) (String)
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <termio.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
// unused arguments with -Wall -Werror
|
|
||||||
#define _U_ __attribute__((__unused__))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Coloured messages output
|
|
||||||
*/
|
|
||||||
#define RED "\033[1;31;40m"
|
|
||||||
#define GREEN "\033[1;32;40m"
|
|
||||||
#define OLDCOLOR "\033[0;0;0m"
|
|
||||||
|
|
||||||
#ifndef FALSE
|
|
||||||
#define FALSE (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TRUE
|
|
||||||
#define TRUE (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ERROR/WARNING messages
|
|
||||||
*/
|
|
||||||
extern int globErr;
|
|
||||||
extern void signals(int sig);
|
|
||||||
#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); signals(9);}while(0)
|
|
||||||
#define ERRX(...) do{globErr=0; _WARN(__VA_ARGS__); signals(9);}while(0)
|
|
||||||
#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)
|
|
||||||
#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* print function name, debug messages
|
|
||||||
* debug mode, -DEBUG
|
|
||||||
*/
|
|
||||||
#ifdef EBUG
|
|
||||||
#define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__)
|
|
||||||
#define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \
|
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
|
||||||
fprintf(stderr, "\n");} while(0)
|
|
||||||
#else
|
|
||||||
#define FNAME() do{}while(0)
|
|
||||||
#define DBG(...) do{}while(0)
|
|
||||||
#endif //EBUG
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Memory allocation
|
|
||||||
*/
|
|
||||||
#define ALLOC(type, var, size) type * var = ((type *)my_alloc(size, sizeof(type)))
|
|
||||||
#define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type)))
|
|
||||||
#define FREE(ptr) do{if(ptr){free(ptr); ptr = NULL;}}while(0)
|
|
||||||
|
|
||||||
#ifndef DBL_EPSILON
|
|
||||||
#define DBL_EPSILON (2.2204460492503131e-16)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
double dtime();
|
|
||||||
|
|
||||||
// functions for color output in tty & no-color in pipes
|
|
||||||
extern int (*red)(const char *fmt, ...);
|
|
||||||
extern int (*_WARN)(const char *fmt, ...);
|
|
||||||
extern int (*green)(const char *fmt, ...);
|
|
||||||
void * my_alloc(size_t N, size_t S);
|
|
||||||
void initial_setup();
|
|
||||||
|
|
||||||
// mmap file
|
|
||||||
typedef struct{
|
|
||||||
char *data;
|
|
||||||
size_t len;
|
|
||||||
} mmapbuf;
|
|
||||||
mmapbuf *My_mmap(char *filename);
|
|
||||||
void My_munmap(mmapbuf *b);
|
|
||||||
|
|
||||||
void restore_console();
|
|
||||||
void setup_con();
|
|
||||||
int read_console();
|
|
||||||
int mygetchar();
|
|
||||||
|
|
||||||
void restore_tty();
|
|
||||||
void tty_init(char *comdev);
|
|
||||||
size_t read_tty(uint8_t *buff, size_t length);
|
|
||||||
int write_tty(uint8_t *buff, size_t length);
|
|
||||||
|
|
||||||
int str2double(double *num, const char *str);
|
|
||||||
|
|
||||||
#endif // __USEFULL_MACROS_H__
|
|
||||||
Loading…
x
Reference in New Issue
Block a user