add network image transporting (pre-alpha yet: many bugs)

This commit is contained in:
Edward Emelianov 2023-02-28 17:18:07 +03:00
parent 764aa50ccc
commit 644de638ca
20 changed files with 847 additions and 698 deletions

View File

@ -1,476 +1,479 @@
/*
* This file is part of the CCD_Capture project.
* Copyright 2023 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 <C/FlyCapture2_C.h>
#include <C/FlyCapture2Defs_C.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <usefull_macros.h>
#include "basestructs.h"
#include "omp.h"
extern Camera camera;
static fc2Context context;
static fc2PGRGuid guid;
static fc2Error err = FC2_ERROR_OK;
static int isopened = FALSE, is16bit = FALSE;
static char camname[BUFSIZ] = {0};
#ifndef Stringify
#define Stringify(x) #x
#endif
#define FC2FN(fn, ...) do{err = FC2_ERROR_OK; if(FC2_ERROR_OK != (err=fn(context __VA_OPT__(,) __VA_ARGS__))){ \
WARNX(Stringify(fn) "(): %s", fc2ErrorToDescription(err)); return FALSE;}}while(0)
static void disconnect(){
FNAME();
if(!isopened) return;
fc2DestroyContext(context);
isopened = FALSE;
}
static int getfloat(fc2PropertyType t, float *f){
fc2Property prop = {0};
prop.type = t;
FC2FN(fc2GetProperty, &prop);
if(!prop.present){
DBG("No property %d", t);
return FALSE;
}
DBG("property %d: abs=%f, vala=%u, valb=%u", t,
prop.absValue, prop.valueA, prop.valueB);
if(f) *f = prop.absValue;
return TRUE;
}
/**
* @brief setfloat - set absolute property value (float)
* @param t - type of property
* @param f - new value
* @return 1 if all OK
*/
static int setfloat(fc2PropertyType t, float f){
fc2Property prop = {0};
prop.type = t;
fc2PropertyInfo i = {0};
i.type = t;
FC2FN(fc2GetProperty, &prop);
FC2FN(fc2GetPropertyInfo, &i);
if(!prop.present || !i.present) return 0;
if(prop.autoManualMode){
if(!i.manualSupported){
WARNX("Can't set auto-only property");
return FALSE;
}
prop.autoManualMode = false;
}
if(!prop.absControl){
if(!i.absValSupported){
WARNX("Can't set non-absolute property to absolute value");
return FALSE;
}
prop.absControl = true;
}
if(!prop.onOff){
if(!i.onOffSupported){
WARNX("Can't set property ON");
return FALSE;
}
prop.onOff = true;
}
if(prop.onePush && i.onePushSupported) prop.onePush = false;
prop.valueA = prop.valueB = 0;
prop.absValue = f;
FC2FN(fc2SetProperty, &prop);
// now check
FC2FN(fc2GetProperty, &prop);
if(fabsf(prop.absValue - f) > 0.02f){
WARNX("Can't set property! Got %g instead of %g.", prop.absValue, f);
return FALSE;
}
return TRUE;
}
static int propOnOff(fc2PropertyType t, BOOL onOff){
fc2Property prop = {0};
prop.type = t;
fc2PropertyInfo i = {0};
i.type = t;
FC2FN(fc2GetPropertyInfo, &i);
FC2FN(fc2GetProperty, &prop);
if(!prop.present || !i.present) return 0;
if(prop.onOff == onOff) return 0;
if(!i.onOffSupported){
WARNX("Property doesn't support state OFF");
return 0;
}
prop.onOff = onOff;
FC2FN(fc2SetProperty, &prop);
FC2FN(fc2GetProperty, &prop);
if(prop.onOff != onOff){
WARNX("Can't change property OnOff state");
return 0;
}
return 1;
}
static void disableauto(){
if(!isopened) return;
propOnOff(FC2_AUTO_EXPOSURE, false);
propOnOff(FC2_WHITE_BALANCE, false);
propOnOff(FC2_GAMMA, false);
propOnOff(FC2_TRIGGER_MODE, false);
propOnOff(FC2_TRIGGER_DELAY, false);
propOnOff(FC2_FRAME_RATE, false);
}
static int connect(){
FNAME();
unsigned int numDevices;
disconnect();
DBG("fc2CreateContext");
if(FC2_ERROR_OK != (err = fc2CreateContext(&context))){
WARNX("fc2CreateContext(): %s", fc2ErrorToDescription(err));
return FALSE;
}
DBG("fc2GetNumOfCameras");
FC2FN(fc2GetNumOfCameras, &numDevices);
DBG("test");
if(numDevices == 0){
WARNX("No cameras detected!");
fc2DestroyContext(context);
return FALSE;
}
camera.Ndevices = numDevices;
DBG("Found %d camera[s]", numDevices);
return TRUE;
}
static int getbin(int *binh, int *binv){
//unsigned int h, v;
//FC2FN(fc2GetGigEImageBinningSettings, &h, &v);
//green("got: %u x %u", h, v);
if(binh) *binh = 1;
if(binv) *binv = 1;
return TRUE;
}
static int getformat(frameformat *fmt){
if(!fmt) return FALSE;
unsigned int packsz; float pc;
fc2Format7ImageSettings f7;
FC2FN(fc2GetFormat7Configuration, &f7, &packsz, &pc);
fmt->h = f7.height; fmt->w = f7.width;
fmt->xoff = f7.offsetX; fmt->yoff = f7.offsetY;
if(f7.pixelFormat != FC2_PIXEL_FORMAT_MONO16){
is16bit = FALSE;
DBG("8 bit");
}else{
is16bit = TRUE;
DBG("16 bit");
}
return TRUE;
}
static int getgeom(){
FNAME();
if(!isopened) return FALSE;
fc2Format7Info f = {.mode = FC2_MODE_0};
BOOL b;
FC2FN(fc2GetFormat7Info, &f, &b);
if(!b) return FALSE;
camera.array.h = f.maxHeight;
camera.array.w = f.maxWidth;
camera.array.xoff = camera.array.yoff = 0;
camera.field = camera.array;
getformat(&camera.geometry);
return TRUE;
}
static int geometrylimits(frameformat *max, frameformat *step){
FNAME();
if(!isopened || !max || !step) return FALSE;
fc2Format7Info f = {.mode = FC2_MODE_0};
BOOL b;
fc2Format7Info i = {0};
FC2FN(fc2GetFormat7Info, &i, &b);
if(!b) return FALSE;
max->h = f.maxHeight; max->w = f.maxWidth;
max->xoff = f.maxWidth - f.offsetHStepSize;
max->yoff = f.maxHeight - f.offsetVStepSize;
step->w = f.imageHStepSize;
step->h = f.imageVStepSize;
step->xoff = f.offsetHStepSize;
step->yoff = f.offsetVStepSize;
return TRUE;
}
static int setdevno(int N){
if(N > camera.Ndevices - 1) return FALSE;
FC2FN(fc2GetCameraFromIndex, 0, &guid);
FC2FN(fc2Connect, &guid);
isopened = TRUE;
disableauto();
fc2CameraInfo caminfo;
FC2FN(fc2GetCameraInfo, &caminfo);
if(err == FC2_ERROR_OK){
strncpy(camname, caminfo.modelName, BUFSIZ-1);
DBG("Using camera %s\n", camname);
}else strcpy(camname, "Unknown camera");
if(!getbin(NULL, NULL)) WARNX("Can't get current binning");
if(!getgeom()) WARNX("Can't get current frame format");
return TRUE;
}
// stub function: the capture process is blocking
static int pollcapt(capture_status *st, float *remain){
if(st) *st = CAPTURE_READY;
if(remain) *remain = 0.f;
return TRUE;
}
static int GrabImage(fc2Image *convertedImage){
if(!convertedImage) return FALSE;
int ret = FALSE;
fc2Image rawImage;
// start capture
FC2FN(fc2StartCapture);
err = fc2CreateImage(&rawImage);
if(err != FC2_ERROR_OK){
WARNX("Error in fc2CreateImage: %s", fc2ErrorToDescription(err));
fc2StopCapture(context);
return FALSE;
}
// Retrieve the image
err = fc2RetrieveBuffer(context, &rawImage);
if(err != FC2_ERROR_OK){
WARNX("Error in fc2RetrieveBuffer: %s", fc2ErrorToDescription(err));
goto rtn;
}
// Convert image to gray (we need to convert RAW into same bitpix
fc2PixelFormat fmt = (is16bit) ? FC2_PIXEL_FORMAT_MONO16 : FC2_PIXEL_FORMAT_MONO8;
err = fc2ConvertImageTo(fmt, &rawImage, convertedImage);
if(err != FC2_ERROR_OK){
WARNX("Error in fc2ConvertImageTo: %s", fc2ErrorToDescription(err));
goto rtn;
}
ret = TRUE;
DBG("raw: ds=%u, rds=%u, str=%u; conv: ds=%u, rds=%u, str=%u", rawImage.dataSize, rawImage.receivedDataSize, rawImage.stride,
convertedImage->dataSize, convertedImage->receivedDataSize, convertedImage->stride);
rtn:
fc2StopCapture(context);
fc2DestroyImage(&rawImage);
return ret;
}
static int capture(IMG *ima){
FNAME();
if(!ima || !ima->data || !isopened) return FALSE;
static int toohot = FALSE;
float f;
if(getfloat(FC2_TEMPERATURE, &f)){
DBG("Temperature: %.1f", f);
if(f > 80.){
WARNX("Device is too hot");
toohot = TRUE;
}else if(toohot && f < 75.){
DBG("Device temperature is normal");
toohot = FALSE;
}
}
fc2Image convertedImage;
err = fc2CreateImage(&convertedImage);
if(err != FC2_ERROR_OK){
WARNX("capture_grasshopper(): can't create image, %s", fc2ErrorToDescription(err));
return FALSE;
}
if(!GrabImage(&convertedImage)){
WARNX("Can't grab image");
fc2DestroyImage(&convertedImage);
return FALSE;
}
int width = convertedImage.cols, height = convertedImage.rows, stride = convertedImage.stride;
DBG("w=%d, h=%d, s=%d", width, height, stride);
if(is16bit){
int w2 = width<<1;
OMP_FOR()
for(int y = 0; y < height; ++y){
uint16_t *Out = &ima->data[y*width];
const uint8_t *In = &convertedImage.pData[y*stride];
memcpy(Out, In, w2);
}
}else{
OMP_FOR()
for(int y = 0; y < height; ++y){
uint16_t *Out = &ima->data[y*width];
const uint8_t *In = &convertedImage.pData[y*stride];
for(int x = 0; x < width; ++x){
*Out++ = *In++;
}
}
}
ima->bitpix = is16bit ? 16 : 8;
fc2DestroyImage(&convertedImage);
return TRUE;
}
static int setbrightness(float b){
return setfloat(FC2_BRIGHTNESS, b);
}
static int setexp(float e){
FNAME();
if(!isopened) return FALSE;
e *= 1e3f;
if(!setfloat(FC2_SHUTTER, e)){
WARNX("Can't set expose time %g", e);
return FALSE;
}
return TRUE;
}
static int setgain(float e){
FNAME();
if(!isopened) return FALSE;
if(!setfloat(FC2_GAIN, e)){
WARNX("Can't set gain %g", e);
return FALSE;
}
DBG("GAIN -> %f", e);
return TRUE;
}
static int changeformat(frameformat *fmt){
FNAME();
if(!isopened) return FALSE;
DBG("set geom %dx%d (off: %dx%d)", fmt->w, fmt->h, fmt->xoff, fmt->yoff);
BOOL b;
fc2Format7ImageSettings f7;
f7.mode = FC2_MODE_0;
f7.offsetX = fmt->xoff;
f7.offsetY = fmt->yoff;
f7.width = fmt->w;
f7.height = fmt->h;
DBG("offx=%d, offy=%d, w=%d, h=%d ", f7.offsetX, f7.offsetY, f7.width, f7.height);
f7.pixelFormat = (is16bit) ? FC2_PIXEL_FORMAT_MONO16 : FC2_PIXEL_FORMAT_MONO8;
fc2Format7PacketInfo f7p;
FC2FN(fc2ValidateFormat7Settings, &f7, &b, &f7p);
if(!b) return FALSE; // invalid
FC2FN(fc2SetFormat7Configuration, &f7, f7p.recommendedBytesPerPacket);
getformat(&camera.geometry);
return TRUE;
}
static int setbitdepth(int i){
frameformat fmt;
getformat(&fmt);
int o16bit = is16bit;
if(i == 0) is16bit = FALSE; // 8 bit
else is16bit = TRUE;
if(!changeformat(&fmt)){
is16bit = o16bit;
return FALSE;
}
return TRUE;
}
static int getgain(float *g){
return getfloat(FC2_GAIN, g);
}
static int gainmax(float *g){
if(g) *g = 32.f;
return TRUE;
}
static int modelname(char *buf, int bufsz){
strncpy(buf, camname, bufsz);
return TRUE;
}
// can't do binning
static int setbin(int binh, int binv){
//FC2FN(fc2SetGigEImageBinningSettings, binh, binv);
//getbin(&binh, &binv);
if(binh != 1 || binv != 1) return FALSE;
return TRUE;
}
static int gett(float *t){
return getfloat(FC2_TEMPERATURE, t);
}
static int setfanspd(_U_ fan_speed s){
return FALSE;
}
static int shutter(_U_ shutter_op cmd){
return FALSE;
}
static int ffalse(_U_ float f){ return FALSE; }
static int fpfalse(_U_ float *f){ return FALSE; }
static int ifalse(_U_ int i){ return FALSE; }
static int vtrue(){ return TRUE; }
static int ipfalse(_U_ int *i){ return FALSE; }
static void vstub(){ return ;}
/*
* Global objects: camera, focuser and wheel
*/
Camera camera = {
.check = connect,
.close = disconnect,
.pollcapture = pollcapt,
.capture = capture,
.cancel = vstub,
.startexposition = vtrue,
// setters:
.setDevNo = setdevno,
.setbrightness = setbrightness,
.setexp = setexp,
.setgain = setgain,
.setT = ffalse,
.setbin = setbin,
.setnflushes = ifalse,
.shuttercmd = shutter,
.confio = ifalse,
.setio = ifalse,
.setframetype = ifalse, // set DARK or NORMAL: no shutter -> no darks
.setbitdepth = setbitdepth,
.setfastspeed = ifalse,
.setgeometry = changeformat,
.setfanspeed = setfanspd,
// getters:
.getbrightness = fpfalse,
.getModelName = modelname,
.getgain = getgain,
.getmaxgain = gainmax,
.getgeomlimits = geometrylimits,
.getTcold = fpfalse,
.getThot = fpfalse,
.getTbody = gett,
.getbin = getbin,
.getio = ipfalse,
};
/*
* This file is part of the CCD_Capture project.
* Copyright 2023 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 <C/FlyCapture2_C.h>
#include <C/FlyCapture2Defs_C.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <usefull_macros.h>
#include "basestructs.h"
#include "omp.h"
extern Camera camera;
static fc2Context context;
static fc2PGRGuid guid;
static fc2Error err = FC2_ERROR_OK;
static int isopened = FALSE, is16bit = FALSE;
static char camname[BUFSIZ] = {0};
#ifndef Stringify
#define Stringify(x) #x
#endif
#define FC2FN(fn, ...) do{err = FC2_ERROR_OK; if(FC2_ERROR_OK != (err=fn(context __VA_OPT__(,) __VA_ARGS__))){ \
WARNX(Stringify(fn) "(): %s", fc2ErrorToDescription(err)); return FALSE;}}while(0)
static void disconnect(){
FNAME();
if(!isopened) return;
fc2DestroyContext(context);
isopened = FALSE;
}
static int getfloat(fc2PropertyType t, float *f){
fc2Property prop = {0};
prop.type = t;
FC2FN(fc2GetProperty, &prop);
if(!prop.present){
DBG("No property %d", t);
return FALSE;
}
DBG("property %d: abs=%f, vala=%u, valb=%u", t,
prop.absValue, prop.valueA, prop.valueB);
if(f) *f = prop.absValue;
return TRUE;
}
/**
* @brief setfloat - set absolute property value (float)
* @param t - type of property
* @param f - new value
* @return 1 if all OK
*/
static int setfloat(fc2PropertyType t, float f){
fc2Property prop = {0};
prop.type = t;
fc2PropertyInfo i = {0};
i.type = t;
FC2FN(fc2GetProperty, &prop);
FC2FN(fc2GetPropertyInfo, &i);
if(!prop.present || !i.present) return 0;
if(prop.autoManualMode){
if(!i.manualSupported){
WARNX("Can't set auto-only property");
return FALSE;
}
prop.autoManualMode = false;
}
if(!prop.absControl){
if(!i.absValSupported){
WARNX("Can't set non-absolute property to absolute value");
return FALSE;
}
prop.absControl = true;
}
if(!prop.onOff){
if(!i.onOffSupported){
WARNX("Can't set property ON");
return FALSE;
}
prop.onOff = true;
}
if(prop.onePush && i.onePushSupported) prop.onePush = false;
prop.valueA = prop.valueB = 0;
prop.absValue = f;
FC2FN(fc2SetProperty, &prop);
// now check
FC2FN(fc2GetProperty, &prop);
if(fabsf(prop.absValue - f) > 0.02f){
WARNX("Can't set property! Got %g instead of %g.", prop.absValue, f);
return FALSE;
}
return TRUE;
}
static int propOnOff(fc2PropertyType t, BOOL onOff){
fc2Property prop = {0};
prop.type = t;
fc2PropertyInfo i = {0};
i.type = t;
FC2FN(fc2GetPropertyInfo, &i);
FC2FN(fc2GetProperty, &prop);
if(!prop.present || !i.present) return 0;
if(prop.onOff == onOff) return 0;
if(!i.onOffSupported){
WARNX("Property doesn't support state OFF");
return 0;
}
prop.onOff = onOff;
FC2FN(fc2SetProperty, &prop);
FC2FN(fc2GetProperty, &prop);
if(prop.onOff != onOff){
WARNX("Can't change property OnOff state");
return 0;
}
return 1;
}
static void disableauto(){
if(!isopened) return;
propOnOff(FC2_AUTO_EXPOSURE, false);
propOnOff(FC2_WHITE_BALANCE, false);
propOnOff(FC2_GAMMA, false);
propOnOff(FC2_TRIGGER_MODE, false);
propOnOff(FC2_TRIGGER_DELAY, false);
propOnOff(FC2_FRAME_RATE, false);
}
static int connect(){
FNAME();
unsigned int numDevices;
disconnect();
DBG("fc2CreateContext");
if(FC2_ERROR_OK != (err = fc2CreateContext(&context))){
WARNX("fc2CreateContext(): %s", fc2ErrorToDescription(err));
return FALSE;
}
DBG("fc2GetNumOfCameras");
FC2FN(fc2GetNumOfCameras, &numDevices);
DBG("test");
if(numDevices == 0){
WARNX("No cameras detected!");
fc2DestroyContext(context);
return FALSE;
}
camera.Ndevices = numDevices;
DBG("Found %d camera[s]", numDevices);
return TRUE;
}
static int getbin(int *binh, int *binv){
//unsigned int h, v;
//FC2FN(fc2GetGigEImageBinningSettings, &h, &v);
//green("got: %u x %u", h, v);
if(binh) *binh = 1;
if(binv) *binv = 1;
return TRUE;
}
static int getformat(frameformat *fmt){
if(!fmt) return FALSE;
unsigned int packsz; float pc;
fc2Format7ImageSettings f7;
FC2FN(fc2GetFormat7Configuration, &f7, &packsz, &pc);
fmt->h = f7.height; fmt->w = f7.width;
fmt->xoff = f7.offsetX; fmt->yoff = f7.offsetY;
if(f7.pixelFormat != FC2_PIXEL_FORMAT_MONO16){
is16bit = FALSE;
DBG("8 bit");
}else{
is16bit = TRUE;
DBG("16 bit");
}
return TRUE;
}
static int getgeom(){
FNAME();
if(!isopened) return FALSE;
fc2Format7Info f = {.mode = FC2_MODE_0};
BOOL b;
FC2FN(fc2GetFormat7Info, &f, &b);
if(!b) return FALSE;
camera.array.h = f.maxHeight;
camera.array.w = f.maxWidth;
camera.array.xoff = camera.array.yoff = 0;
camera.field = camera.array;
getformat(&camera.geometry);
return TRUE;
}
static int geometrylimits(frameformat *max, frameformat *step){
FNAME();
if(!isopened || !max || !step) return FALSE;
fc2Format7Info f = {.mode = FC2_MODE_0};
BOOL b;
//fc2Format7Info i = {0};
FC2FN(fc2GetFormat7Info, &f, &b);
if(!b) return FALSE;
max->h = f.maxHeight; max->w = f.maxWidth;
max->xoff = f.maxWidth - f.offsetHStepSize;
max->yoff = f.maxHeight - f.offsetVStepSize;
step->w = f.imageHStepSize;
step->h = f.imageVStepSize;
step->xoff = f.offsetHStepSize;
step->yoff = f.offsetVStepSize;
DBG("Got max w/h: %d/%d", f.maxWidth, f.maxHeight);
return TRUE;
}
static int setdevno(int N){
if(N > camera.Ndevices - 1) return FALSE;
FC2FN(fc2GetCameraFromIndex, 0, &guid);
FC2FN(fc2Connect, &guid);
isopened = TRUE;
disableauto();
fc2CameraInfo caminfo;
FC2FN(fc2GetCameraInfo, &caminfo);
if(err == FC2_ERROR_OK){
strncpy(camname, caminfo.modelName, BUFSIZ-1);
DBG("Using camera %s\n", camname);
}else strcpy(camname, "Unknown camera");
if(!getbin(NULL, NULL)) WARNX("Can't get current binning");
if(!getgeom()) WARNX("Can't get current frame format");
return TRUE;
}
// stub function: the capture process is blocking
static int pollcapt(capture_status *st, float *remain){
if(st) *st = CAPTURE_READY;
if(remain) *remain = 0.f;
return TRUE;
}
static int GrabImage(fc2Image *convertedImage){
if(!convertedImage) return FALSE;
int ret = FALSE;
fc2Image rawImage;
// start capture
FC2FN(fc2StartCapture);
err = fc2CreateImage(&rawImage);
if(err != FC2_ERROR_OK){
WARNX("Error in fc2CreateImage: %s", fc2ErrorToDescription(err));
fc2StopCapture(context);
return FALSE;
}
// Retrieve the image
err = fc2RetrieveBuffer(context, &rawImage);
if(err != FC2_ERROR_OK){
WARNX("Error in fc2RetrieveBuffer: %s", fc2ErrorToDescription(err));
goto rtn;
}
// Convert image to gray (we need to convert RAW into same bitpix
fc2PixelFormat fmt = (is16bit) ? FC2_PIXEL_FORMAT_MONO16 : FC2_PIXEL_FORMAT_MONO8;
err = fc2ConvertImageTo(fmt, &rawImage, convertedImage);
if(err != FC2_ERROR_OK){
WARNX("Error in fc2ConvertImageTo: %s", fc2ErrorToDescription(err));
goto rtn;
}
ret = TRUE;
DBG("raw: ds=%u, rds=%u, str=%u; conv: ds=%u, rds=%u, str=%u", rawImage.dataSize, rawImage.receivedDataSize, rawImage.stride,
convertedImage->dataSize, convertedImage->receivedDataSize, convertedImage->stride);
rtn:
fc2StopCapture(context);
fc2DestroyImage(&rawImage);
return ret;
}
static int capture(IMG *ima){
FNAME();
if(!ima || !ima->data || !isopened) return FALSE;
static int toohot = FALSE;
float f;
if(getfloat(FC2_TEMPERATURE, &f)){
DBG("Temperature: %.1f", f);
if(f > 80.){
WARNX("Device is too hot");
toohot = TRUE;
}else if(toohot && f < 75.){
DBG("Device temperature is normal");
toohot = FALSE;
}
}
fc2Image convertedImage;
err = fc2CreateImage(&convertedImage);
if(err != FC2_ERROR_OK){
WARNX("capture_grasshopper(): can't create image, %s", fc2ErrorToDescription(err));
return FALSE;
}
if(!GrabImage(&convertedImage)){
WARNX("Can't grab image");
fc2DestroyImage(&convertedImage);
return FALSE;
}
int width = convertedImage.cols, height = convertedImage.rows, stride = convertedImage.stride;
DBG("w=%d, h=%d, s=%d", width, height, stride);
if(is16bit){
int w2 = width<<1;
OMP_FOR()
for(int y = 0; y < height; ++y){
uint16_t *Out = &ima->data[y*width];
const uint8_t *In = &convertedImage.pData[y*stride];
memcpy(Out, In, w2);
//DBG("Row %d copied. First byte: %d", y, *((uint16_t*)In));
}
}else{
OMP_FOR()
for(int y = 0; y < height; ++y){
uint16_t *Out = &ima->data[y*width];
const uint8_t *In = &convertedImage.pData[y*stride];
for(int x = 0; x < width; ++x){
*Out++ = *In++;
}
//DBG("Row %d copied. Last byte: %d", y, *((uint16_t*)In));
}
}
ima->bitpix = is16bit ? 16 : 8;
fc2DestroyImage(&convertedImage);
return TRUE;
}
static int setbrightness(float b){
return setfloat(FC2_BRIGHTNESS, b);
}
static int setexp(float e){
FNAME();
if(!isopened) return FALSE;
e *= 1e3f;
if(!setfloat(FC2_SHUTTER, e)){
WARNX("Can't set expose time %g", e);
return FALSE;
}
return TRUE;
}
static int setgain(float e){
FNAME();
if(!isopened) return FALSE;
if(!setfloat(FC2_GAIN, e)){
WARNX("Can't set gain %g", e);
return FALSE;
}
DBG("GAIN -> %f", e);
return TRUE;
}
static int changeformat(frameformat *fmt){
FNAME();
if(!isopened) return FALSE;
DBG("set geom %dx%d (off: %dx%d)", fmt->w, fmt->h, fmt->xoff, fmt->yoff);
BOOL b;
fc2Format7ImageSettings f7;
f7.mode = FC2_MODE_0;
f7.offsetX = fmt->xoff;
f7.offsetY = fmt->yoff;
f7.width = fmt->w;
f7.height = fmt->h;
DBG("offx=%d, offy=%d, w=%d, h=%d ", f7.offsetX, f7.offsetY, f7.width, f7.height);
f7.pixelFormat = (is16bit) ? FC2_PIXEL_FORMAT_MONO16 : FC2_PIXEL_FORMAT_MONO8;
fc2Format7PacketInfo f7p;
FC2FN(fc2ValidateFormat7Settings, &f7, &b, &f7p);
if(!b) return FALSE; // invalid
FC2FN(fc2SetFormat7Configuration, &f7, f7p.recommendedBytesPerPacket);
getformat(&camera.geometry);
return TRUE;
}
static int setbitdepth(int i){
frameformat fmt;
getformat(&fmt);
int o16bit = is16bit;
if(i == 0) is16bit = FALSE; // 8 bit
else is16bit = TRUE;
if(!changeformat(&fmt)){
is16bit = o16bit;
return FALSE;
}
return TRUE;
}
static int getgain(float *g){
return getfloat(FC2_GAIN, g);
}
static int gainmax(float *g){
if(g) *g = 32.f;
return TRUE;
}
static int modelname(char *buf, int bufsz){
strncpy(buf, camname, bufsz);
return TRUE;
}
// can't do binning
static int setbin(int binh, int binv){
//FC2FN(fc2SetGigEImageBinningSettings, binh, binv);
//getbin(&binh, &binv);
if(binh != 1 || binv != 1) return FALSE;
return TRUE;
}
static int gett(float *t){
return getfloat(FC2_TEMPERATURE, t);
}
static int setfanspd(_U_ fan_speed s){
return FALSE;
}
static int shutter(_U_ shutter_op cmd){
return FALSE;
}
static int ffalse(_U_ float f){ return FALSE; }
static int fpfalse(_U_ float *f){ return FALSE; }
static int ifalse(_U_ int i){ return FALSE; }
static int vtrue(){ return TRUE; }
static int ipfalse(_U_ int *i){ return FALSE; }
static void vstub(){ return ;}
/*
* Global objects: camera, focuser and wheel
*/
Camera camera = {
.check = connect,
.close = disconnect,
.pollcapture = pollcapt,
.capture = capture,
.cancel = vstub,
.startexposition = vtrue,
// setters:
.setDevNo = setdevno,
.setbrightness = setbrightness,
.setexp = setexp,
.setgain = setgain,
.setT = ffalse,
.setbin = setbin,
.setnflushes = ifalse,
.shuttercmd = shutter,
.confio = ifalse,
.setio = ifalse,
.setframetype = ifalse, // set DARK or NORMAL: no shutter -> no darks
.setbitdepth = setbitdepth,
.setfastspeed = ifalse,
.setgeometry = changeformat,
.setfanspeed = setfanspd,
// getters:
.getbrightness = fpfalse,
.getModelName = modelname,
.getgain = getgain,
.getmaxgain = gainmax,
.getgeomlimits = geometrylimits,
.getTcold = fpfalse,
.getThot = fpfalse,
.getTbody = gett,
.getbin = getbin,
.getio = ipfalse,
};

View File

@ -17,9 +17,6 @@
*/
#pragma once
#ifndef BASESTRUCTS_H__
#define BASESTRUCTS_H__
#include <stdint.h>
typedef struct{
@ -136,4 +133,3 @@ typedef struct{
int (*getMaxPos)(int *p); // amount of positions
} Wheel;
#endif // BASESTRUCTS_H__

View File

@ -186,8 +186,7 @@ int saveFITS(IMG *img, char **outp){
}
char buff[PATH_MAX+1], fnam[PATH_MAX+1];
if(!GP->outfile && !GP->outfileprefix){
LOGERR("Can't save image: neither filename nor filename prefix pointed");
WARNX(_("Neither filename nor filename prefix pointed!"));
LOGWARN("Image not saved: neither filename nor filename prefix pointed");
return FALSE;
}
if(GP->outfile){ // pointed specific output file name like "file.fits", check it
@ -819,6 +818,8 @@ void cancel(){
}
}
#ifdef IMAGEVIEW
static volatile int grabends = 1;
static void *grabnext(void *arg){
FNAME();
@ -845,6 +846,8 @@ eof:
DBG("EXIT");
}
/**
* @brief ccdcaptured - get new image data for viewer
* @param img - pointer to IMG* (if IMG* is NULL, will be allocated here)
@ -894,3 +897,4 @@ int ccdcaptured(IMG **imgptr){
}
return FALSE;
}
#endif

View File

@ -17,9 +17,6 @@
*/
#pragma once
#ifndef CCDFUNC_H__
#define CCDFUNC_H__
#include "basestructs.h"
extern Camera *camera;
@ -40,6 +37,7 @@ int startFocuser(void **dlh);
void focclose();
void closewheel();
void closecam();
#ifdef IMAGEVIEW
int ccdcaptured(IMG **img);
#endif
#endif // CCDFUNC_H__

126
client.c
View File

@ -17,6 +17,7 @@
*/
// client-side functions
#include <stdatomic.h>
#include <math.h> // isnan
#include <stdio.h>
#include <string.h>
@ -30,9 +31,15 @@
static char sendbuf[BUFSIZ];
#define SENDMSG(...) do{snprintf(sendbuf, BUFSIZ-1, __VA_ARGS__); verbose(2, "\t> %s", sendbuf); sendstrmessage(sock, sendbuf); getans(sock);}while(0)
static int expstate = CAMERA_CAPTURE;
static volatile atomic_int expstate = CAMERA_CAPTURE;
static int xm0,ym0,xm1,ym1; // max format
#ifdef IMAGEVIEW
static IMG ima = {0};
static volatile atomic_int grabends = 0;
static int imdatalen = 0, imbufsz = 0;
#endif
/**
* check data from fd (polling function for client)
* @param fd - file descriptor
@ -104,6 +111,17 @@ static int parseans(char *ans){
sscanf(val, "%d,%d,%d,%d", &xm0, &ym0, &xm1, &ym1);
DBG("Got maxformat: %d,%d,%d,%d", xm0, ym0, xm1, ym1);
}
#ifdef IMAGEVIEW
else if(0 == strcmp(CMD_IMWIDTH, ans)){
ima.w = atoi(val);
DBG("Get width: %d", ima.w);
imdatalen = ima.w * ima.h * 2;
}else if(0 == strcmp(CMD_IMHEIGHT, ans)){
ima.h = atoi(val);
DBG("Get height: %d", ima.h);
imdatalen = ima.w * ima.h * 2;
}
#endif
return FALSE;
}
@ -130,7 +148,7 @@ static int getans(int sock){
/**
* @brief processData - process here some actions and make messages for server
*/
static void process_data(int sock){
static void send_headers(int sock){
// common information
SENDMSG(CMD_INFO);
// focuser
@ -178,11 +196,15 @@ static void process_data(int sock){
else SENDMSG(CMD_DARK "=0");
}
if(GP->outfile){
SENDMSG(CMD_FILENAME "=%s", makeabspath(GP->outfile, FALSE));
if(!*GP->outfile) SENDMSG(CMD_FILENAME "=");
else SENDMSG(CMD_FILENAME "=%s", makeabspath(GP->outfile, FALSE));
if(GP->rewrite) SENDMSG(CMD_REWRITE "=1");
else SENDMSG(CMD_REWRITE "=0");
}
if(GP->outfileprefix) SENDMSG(CMD_FILENAMEPREFIX "=%s", makeabspath(GP->outfileprefix, FALSE));
if(GP->outfileprefix){
if(!*GP->outfileprefix) SENDMSG(CMD_FILENAMEPREFIX "=");
else SENDMSG(CMD_FILENAMEPREFIX "=%s", makeabspath(GP->outfileprefix, FALSE));
}
if(GP->exptime > -DBL_EPSILON) SENDMSG(CMD_EXPOSITION "=%g", GP->exptime);
// FITS header keywords:
#define CHKHDR(x, cmd) do{if(x) SENDMSG(cmd "=%s", x);}while(0)
@ -213,16 +235,16 @@ void client(int sock){
SENDMSG(CMD_RESTART);
return;
}
process_data(sock);
send_headers(sock);
double t0 = dtime(), tw = t0;
int Nremain = 0, nframe = 1;
// if client gives filename/prefix or Nframes, make exposition
if(GP->outfile || GP->outfileprefix || GP->nframes > 0){
if((GP->outfile && *GP->outfile) || (GP->outfileprefix && *GP->outfileprefix) || GP->nframes > 0){
Nremain = GP->nframes - 1;
if(Nremain < 1) Nremain = 0;
else GP->waitexpend = TRUE; // N>1 - wait for exp ends
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE);
} else {
}else{
while(getans(sock));
DBG("RETURN: no more data");
return;
@ -276,3 +298,93 @@ void client(int sock){
if(GP->waitexpend) WARNX(_("Server timeout"));
DBG("Timeout");
}
#ifdef IMAGEVIEW
static int grabsockfd = -1;
void init_grab_sock(int sock){
grabsockfd = sock;
send_headers(sock);
}
static void *grabnext(void _U_ *arg){ // daemon grabbing images through the net
FNAME();
if(grabsockfd < 0) return NULL;
int sock = grabsockfd;
while(1){
while(grabends); // wait until image processed
SENDMSG(CMD_IMWIDTH);
SENDMSG(CMD_IMHEIGHT);
expstate = CAMERA_CAPTURE;
SENDMSG(CMD_EXPSTATE "=%d", CAMERA_CAPTURE); // start capture
double timeout = GP->exptime + CLIENT_TIMEOUT, t0 = dtime();
while(dtime() - t0 < timeout){
SENDMSG(CMD_EXPSTATE);
if(expstate != CAMERA_CAPTURE) break;
}
if(dtime() - t0 >= timeout || expstate != CAMERA_FRAMERDY){
WARNX("Image wasn't received");
continue;
}
DBG("Frame ready");
sendstrmessage(sock, CMD_GETIMAGE);
if(imbufsz < imdatalen){
DBG("Reallocate memory from %d to %d", imbufsz, imdatalen);
ima.data = realloc(ima.data, imdatalen);
imbufsz = imdatalen;
}
t0 = dtime();
int got = 0;
while(dtime() - t0 < CLIENT_TIMEOUT){
if(!canberead(sock)) continue;
int rd = read(sock, ((uint8_t*)ima.data)+got, imdatalen - got);
if(rd <= 0){
WARNX("Server disconnected");
signals(1);
}
got += rd;
DBG("Read %d bytes; total read %d from %d", rd, got, imdatalen);
if(got == imdatalen){
DBG("Got image");
grabends = 1;
break;
}
}
if(dtime() - t0 > CLIENT_TIMEOUT) WARNX("Timeout, image didn't received");
}
return NULL;
}
// try to capture images through socket
int sockcaptured(IMG **imgptr){
if(!imgptr) return FALSE;
static pthread_t grabthread = 0;
if(grabsockfd < 0) return FALSE;
if(imgptr == (void*)-1){ // kill `grabnext`
DBG("Kill grabbing thread");
if(grabthread){
pthread_cancel(grabthread);
pthread_join(grabthread, NULL);
grabthread = 0;
}
DBG("Killed");
return FALSE;
}
if(!grabthread){ // start new grab
DBG("\n\n\nStart new grab");
if(pthread_create(&grabthread, NULL, &grabnext, NULL)){
WARN("Can't create grabbing thread");
grabthread = 0;
}
}else{ // grab in process
if(grabends){ // image is ready
DBG("Image ready");
if(*imgptr && (*imgptr != &ima)) free(*imgptr);
*imgptr = &ima;
grabends = 0;
return TRUE;
}
}
return FALSE;
}
// IMAGEVIEW
#endif

View File

@ -17,10 +17,12 @@
*/
#pragma once
#ifndef CLIENT_H__
#define CLIENT_H__
#include "basestructs.h"
// client-side functions
void client(int fd);
#endif // CLIENT_H__
#ifdef IMAGEVIEW
void init_grab_sock(int sock);
int sockcaptured(IMG **img);
#endif

View File

@ -17,9 +17,6 @@
*/
#pragma once
#ifndef CMDLNOPTS_H__
#define CMDLNOPTS_H__
#include <usefull_macros.h>
/*
@ -86,4 +83,4 @@ extern glob_pars *GP;
glob_pars *parse_args(int argc, char **argv);
void verbose(int levl, const char *fmt, ...);
#endif // CMDLNOPTS_H__

View File

@ -90,11 +90,6 @@ void keyPressed(unsigned char key, int x, int y){
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
@ -153,7 +148,7 @@ 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

View File

@ -17,8 +17,6 @@
*/
#pragma once
#ifndef EVENTS_H__
#define EVENTS_H__
#include <stdlib.h>
#include <stdio.h>
@ -26,14 +24,10 @@
#include <GL/glext.h>
#include <GL/freeglut.h>
extern float Z; // ËÏÏÒÄÉÎÁÔÁ Z (zoom)
extern float Z; // Z coordinate (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__

View File

@ -26,6 +26,7 @@
#include "ccdfunc.h"
#include "cmdlnopts.h"
#include "imageview.h"
#include "events.h"
#include "omp.h"
windowData *win = NULL; // main window (common variable for events.c)
@ -531,6 +532,7 @@ void closeGL(){
/**
* @brief viewer - main viewer process
* @param newimage - image refresh function
* it shouldn't `free` it's argument!!!
* @return 0 if all OK
*/
int viewer(imagefunc newimage){

View File

@ -17,16 +17,14 @@
*/
#pragma once
#ifndef IMAGEVIEW_H__
#define IMAGEVIEW_H__
#include <GL/gl.h>
#include <math.h>
#include <pthread.h>
#include <stdbool.h>
#include <string.h>
#include "ccdfunc.h"
#include "events.h"
// events from menu:
// temporaly stop capture of regular sequence
@ -87,5 +85,3 @@ windowData* getWin();
typedef int (*imagefunc)(IMG**);
int viewer(imagefunc);
#endif // IMAGEVIEW_H__

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-07 16:55+0300\n"
"POT-Creation-Date: 2023-02-28 17:05+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"
@ -269,326 +269,322 @@ msgstr ""
msgid "Camera device unknown"
msgstr ""
#: ccdfunc.c:190
msgid "Neither filename nor filename prefix pointed!"
msgstr ""
#. Не могу сохранить файл
#: ccdfunc.c:209
#: ccdfunc.c:208
#, c-format
msgid "Can't save file with prefix %s"
msgstr ""
#: ccdfunc.c:357
#: ccdfunc.c:356
#, c-format
msgid "File saved as '%s'"
msgstr ""
#: ccdfunc.c:366
#: ccdfunc.c:365
msgid "Error saving file"
msgstr ""
#: ccdfunc.c:406
#: ccdfunc.c:405
#, c-format
msgid "Image stat:\n"
msgstr ""
#: ccdfunc.c:414
#: ccdfunc.c:413
msgid "Focuser device not pointed"
msgstr ""
#: ccdfunc.c:421
#: ccdfunc.c:420
msgid "No focusers found"
msgstr ""
#: ccdfunc.c:452
#: ccdfunc.c:451
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr ""
#: ccdfunc.c:456
#: ccdfunc.c:455
msgid "Can't set active focuser number"
msgstr ""
#: ccdfunc.c:470
#: ccdfunc.c:469
msgid "Can't get focuser limit positions"
msgstr ""
#: ccdfunc.c:477
#: ccdfunc.c:476
msgid "Can't get current focuser position"
msgstr ""
#: ccdfunc.c:491
#: ccdfunc.c:490
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr ""
#: ccdfunc.c:495
#: ccdfunc.c:494
msgid "Can't home focuser"
msgstr ""
#: ccdfunc.c:497
#: ccdfunc.c:496
#, c-format
msgid "Can't set position %g"
msgstr ""
#: ccdfunc.c:505
#: ccdfunc.c:504
msgid "Wheel device not pointed"
msgstr ""
#: ccdfunc.c:512
#: ccdfunc.c:511
msgid "No wheels found"
msgstr ""
#: ccdfunc.c:543
#: ccdfunc.c:542
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr ""
#: ccdfunc.c:547
#: ccdfunc.c:546
msgid "Can't set active wheel number"
msgstr ""
#: ccdfunc.c:563
#: ccdfunc.c:562
msgid "Can't get max wheel position"
msgstr ""
#: ccdfunc.c:570
#: ccdfunc.c:569
#, c-format
msgid "Wheel position should be from 0 to %d"
msgstr ""
#: ccdfunc.c:574
#: ccdfunc.c:573
#, c-format
msgid "Can't set wheel position %d"
msgstr ""
#: ccdfunc.c:591
#: ccdfunc.c:590
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr ""
#: ccdfunc.c:605
#: ccdfunc.c:604
msgid "Camera device not pointed"
msgstr ""
#: ccdfunc.c:612 ccdfunc.c:613
#: ccdfunc.c:611 ccdfunc.c:612
msgid "No cameras found"
msgstr ""
#: ccdfunc.c:643
#: ccdfunc.c:642
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr ""
#: ccdfunc.c:647
#: ccdfunc.c:646
msgid "Can't set active camera number"
msgstr ""
#: ccdfunc.c:653
#: ccdfunc.c:652
msgid "Can't set fan speed"
msgstr ""
#: ccdfunc.c:654
#: ccdfunc.c:653
#, c-format
msgid "Set fan speed to %d"
msgstr ""
#: ccdfunc.c:659
#: ccdfunc.c:658
#, c-format
msgid "Camera model: %s"
msgstr ""
#: ccdfunc.c:660
#: ccdfunc.c:659
#, c-format
msgid "Pixel size: %g x %g"
msgstr ""
#: ccdfunc.c:666
#: ccdfunc.c:665
#, c-format
msgid "Full array: %s"
msgstr ""
#: ccdfunc.c:669
#: ccdfunc.c:668
#, c-format
msgid "Field of view: %s"
msgstr ""
#: ccdfunc.c:672
#: ccdfunc.c:671
#, c-format
msgid "Current format: %s"
msgstr ""
#: ccdfunc.c:675
#: ccdfunc.c:674
#, c-format
msgid "Can't set T to %g degC"
msgstr ""
#: ccdfunc.c:683
#: ccdfunc.c:682
#, c-format
msgid "Shutter command: %s\n"
msgstr ""
#: ccdfunc.c:685
#: ccdfunc.c:684
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr ""
#. "Попытка сконфигурировать порт I/O как %d\n"
#: ccdfunc.c:689
#: ccdfunc.c:688
#, c-format
msgid "Try to configure I/O port as %d"
msgstr ""
#: ccdfunc.c:691
#: ccdfunc.c:690
msgid "Can't configure (unsupported?)"
msgstr ""
#: ccdfunc.c:698
#: ccdfunc.c:697
msgid "Can't get IOport state (unsupported?)"
msgstr ""
#. "Попытка записи %d в порт I/O\n"
#: ccdfunc.c:702
#: ccdfunc.c:701
#, c-format
msgid "Try to write %d to I/O port"
msgstr ""
#: ccdfunc.c:704
#: ccdfunc.c:703
msgid "Can't set IOport"
msgstr ""
#: ccdfunc.c:711
#: ccdfunc.c:710
#, c-format
msgid "Set gain to %g"
msgstr ""
#: ccdfunc.c:712
#: ccdfunc.c:711
#, c-format
msgid "Can't set gain to %g"
msgstr ""
#: ccdfunc.c:717
#: ccdfunc.c:716
#, c-format
msgid "Set brightness to %g"
msgstr ""
#: ccdfunc.c:718
#: ccdfunc.c:717
#, c-format
msgid "Can't set brightness to %g"
msgstr ""
#: ccdfunc.c:726 server.c:223
#: ccdfunc.c:725 server.c:230
#, c-format
msgid "Can't set binning %dx%d"
msgstr ""
#: ccdfunc.c:738 server.c:224
#: ccdfunc.c:737 server.c:231
msgid "Can't set given geometry"
msgstr ""
#: ccdfunc.c:742
#: ccdfunc.c:741
#, c-format
msgid "Can't set %d flushes"
msgstr ""
#: ccdfunc.c:746
#: ccdfunc.c:745
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr ""
#: ccdfunc.c:749
#: ccdfunc.c:748
msgid "Can't change frame type"
msgstr ""
#: ccdfunc.c:752
#: ccdfunc.c:751
msgid "Can't set bit depth"
msgstr ""
#: ccdfunc.c:754
#: ccdfunc.c:753
msgid "Can't set readout speed"
msgstr ""
#: ccdfunc.c:755
#: ccdfunc.c:754
#, c-format
msgid "Readout mode: %s"
msgstr ""
#: ccdfunc.c:756
#: ccdfunc.c:755
msgid "Only show statistics"
msgstr ""
#. GET binning should be AFTER setgeometry!
#: ccdfunc.c:758
#: ccdfunc.c:757
msgid "Can't get current binning"
msgstr ""
#. Захват кадра %d\n
#: ccdfunc.c:780
#: ccdfunc.c:779
#, c-format
msgid "Capture frame %d"
msgstr ""
#: ccdfunc.c:782 ccdfunc.c:830 server.c:121
#: ccdfunc.c:781 ccdfunc.c:831 server.c:125
msgid "Can't start exposition"
msgstr ""
#: ccdfunc.c:786
#: ccdfunc.c:785
msgid "Can't capture image"
msgstr ""
#: ccdfunc.c:789
#: ccdfunc.c:788
msgid "Read grabbed image"
msgstr ""
#: ccdfunc.c:792 ccdfunc.c:838
#: ccdfunc.c:791 ccdfunc.c:839
msgid "Can't grab image"
msgstr ""
#. %d секунд до окончания паузы\n
#: ccdfunc.c:801 client.c:260
#: ccdfunc.c:800 client.c:282
#, c-format
msgid "%d seconds till pause ends\n"
msgstr ""
#: server.c:163
#: server.c:168
msgid "No camera device"
msgstr ""
#: client.c:247
#: client.c:269
msgid "Can't make exposition"
msgstr ""
#: client.c:276
#: client.c:298
msgid "Server timeout"
msgstr ""
#: imageview.c:49
#: imageview.c:50
msgid "Already initialized!"
msgstr ""
#: imageview.c:285
#: imageview.c:286
msgid "Can't init mutex!"
msgstr ""
#: imageview.c:387
#: imageview.c:388
#, c-format
msgid "Histogram conversion: %s"
msgstr ""
#: imageview.c:507 imageview.c:579
#: imageview.c:508 imageview.c:581
#, c-format
msgid "Equalization of histogram: %s"
msgstr ""
#: imageview.c:507 imageview.c:579
#: imageview.c:508 imageview.c:581
msgid "on"
msgstr ""
#: imageview.c:507 imageview.c:579
#: imageview.c:508 imageview.c:581
msgid "off"
msgstr ""
#: imageview.c:545
#: imageview.c:547
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr ""

View File

@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-07 16:54+0300\n"
"POT-Creation-Date: 2023-02-28 17:05+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"
@ -16,18 +16,18 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Content-Type: text/plain; charset=koi8-r\n"
"Content-Transfer-Encoding: 8bit\n"
#: ccdfunc.c:591
#: ccdfunc.c:590
#, c-format
msgid "%.1f seconds till exposition ends"
msgstr "%.1f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ"
#. %d Ñ<>екунд до окончаниÑ<C2B8> паузы\n
#: ccdfunc.c:801 client.c:260
#: ccdfunc.c:800 client.c:282
#, c-format
msgid "%d seconds till pause ends\n"
msgstr "%d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n"
#: imageview.c:49
#: imageview.c:50
msgid "Already initialized!"
msgstr "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
@ -39,7 +39,7 @@ msgstr "
msgid "CMOS gain level"
msgstr "ÕÒÏ×ÅÎØ Gain CMOS"
#: ccdfunc.c:605
#: ccdfunc.c:604
msgid "Camera device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÐÏÄËÌÀÞÅÎÏ"
@ -47,20 +47,20 @@ msgstr "
msgid "Camera device unknown"
msgstr "õÓÔÒÏÊÓÔ×Ï Ó×ÅÏÐÒÉÅÍÎÉËÁ ÎÅ ÏÐÏÚÎÁÎÏ"
#: ccdfunc.c:659
#: ccdfunc.c:658
#, c-format
msgid "Camera model: %s"
msgstr "íÏÄÅÌØ Ó×ÅÔÏÐÒÉÅÍÎÉËÁ: %s"
#: ccdfunc.c:786
#: ccdfunc.c:785
msgid "Can't capture image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:749
#: ccdfunc.c:748
msgid "Can't change frame type"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÔÉÐ ËÁÄÒÁ"
#: ccdfunc.c:691
#: ccdfunc.c:690
msgid "Can't configure (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ (ÏÐÃÉÑ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
@ -84,146 +84,146 @@ msgstr "
msgid "Can't find wheel in plugin %s: %s"
msgstr "îÅ ÍÏÇÕ ÎÁÊÔÉ ÐÌÁÇÉÎ ÔÕÒÅÌÉ %s: %s"
#: ccdfunc.c:698
#: ccdfunc.c:697
msgid "Can't get IOport state (unsupported?)"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÓÏÓÔÏÑÎÉÅ ÐÏÒÔÁ I/O (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#. GET binning should be AFTER setgeometry!
#: ccdfunc.c:758
#: ccdfunc.c:757
msgid "Can't get current binning"
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ ÂÉÎÎÉÎÇÁ"
#: ccdfunc.c:477
#: ccdfunc.c:476
msgid "Can't get current focuser position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÔÅËÕÝÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:470
#: ccdfunc.c:469
msgid "Can't get focuser limit positions"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:563
#: ccdfunc.c:562
msgid "Can't get max wheel position"
msgstr "îÅ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ ÐÒÅÄÅÌØÎÕÀ ÐÏÚÉÃÉÀ ËÏÌÅÓÁ"
#: ccdfunc.c:792 ccdfunc.c:838
#: ccdfunc.c:791 ccdfunc.c:839
msgid "Can't grab image"
msgstr "îÅ ÍÏÇÕ ÚÁÈ×ÁÔÉÔØ ÉÚÏÂÒÁÖÅÎÉÅ"
#: ccdfunc.c:495
#: ccdfunc.c:494
msgid "Can't home focuser"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÆÏËÕÓÅÒ × ÎÕÌØ"
#: imageview.c:285
#: imageview.c:286
msgid "Can't init mutex!"
msgstr "îÅ ÍÏÇÕ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÔØ ÍØÀÔÅËÓ!"
#: client.c:247
#: client.c:269
msgid "Can't make exposition"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ÜËÓÐÏÚÉÃÉÀ"
#: imageview.c:545
#: imageview.c:547
msgid "Can't open OpenGL window, image preview will be inaccessible"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÏËÎÏ OpenGL, ÏÔÏÂÒÁÖÅÎÉÅ ÂÕÄÅÔ ÎÅÄÏÓÔÕÐÎÏ"
#: ccdfunc.c:685
#: ccdfunc.c:684
#, c-format
msgid "Can't run shutter command %s (unsupported?)"
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ ÚÁÔ×ÏÒÁ %s (ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔÓÑ?)"
#. Ð<>е могу Ñ<>охраниÑÑŒ файл
#: ccdfunc.c:209
#: ccdfunc.c:208
#, c-format
msgid "Can't save file with prefix %s"
msgstr "îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ Ó ÐÒÅÆÉËÓÏÍ %s"
#: ccdfunc.c:742
#: ccdfunc.c:741
#, c-format
msgid "Can't set %d flushes"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ %d ÓÂÒÏÓÏ×"
#: ccdfunc.c:704
#: ccdfunc.c:703
msgid "Can't set IOport"
msgstr "îÅ ÍÏÇÕ ÐÏÍÅÎÑÔØ ÚÎÁÞÅÎÉÑ ÐÏÒÔÁ I/O"
#: ccdfunc.c:675
#: ccdfunc.c:674
#, c-format
msgid "Can't set T to %g degC"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÔÅÍÐÅÒÁÔÕÒÕ × %g ÇÒÁÄã"
#: ccdfunc.c:647
#: ccdfunc.c:646
msgid "Can't set active camera number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÊ ËÁÍÅÒÙ"
#: ccdfunc.c:456
#: ccdfunc.c:455
msgid "Can't set active focuser number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ÆÏËÕÓÅÒÁ"
#: ccdfunc.c:547
#: ccdfunc.c:546
msgid "Can't set active wheel number"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÎÏÍÅÒ ÁËÔÉ×ÎÏÇÏ ËÏÌÅÓÁ"
#: ccdfunc.c:726 server.c:223
#: ccdfunc.c:725 server.c:230
#, c-format
msgid "Can't set binning %dx%d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÂÉÎÎÉÎÇ %dx%d"
#: ccdfunc.c:752
#: ccdfunc.c:751
msgid "Can't set bit depth"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÒÁÚÒÑÄÎÏÓÔØ áãð"
#: ccdfunc.c:718
#: ccdfunc.c:717
#, c-format
msgid "Can't set brightness to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:746
#: ccdfunc.c:745
#, c-format
msgid "Can't set exposure time to %f seconds"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÜËÓÐÏÚÉÃÉÀ × %f ÓÅËÕÎÄ"
#: ccdfunc.c:653
#: ccdfunc.c:652
msgid "Can't set fan speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ×"
#: ccdfunc.c:712
#: ccdfunc.c:711
#, c-format
msgid "Can't set gain to %g"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:738 server.c:224
#: ccdfunc.c:737 server.c:231
msgid "Can't set given geometry"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÇÅÏÍÅÔÒÉÀ"
#: ccdfunc.c:497
#: ccdfunc.c:496
#, c-format
msgid "Can't set position %g"
msgstr "îÅ ÍÏÇÕ ÉÚÍÅÎÉÔØ ÐÏÚÉÃÉÀ ÎÁ %g"
#: ccdfunc.c:491
#: ccdfunc.c:490
#, c-format
msgid "Can't set position %g: out of limits [%g, %g]"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÚÉÃÉÀ %g: ×ÎÅ ÐÒÅÄÅÌÏ× [%g, %g]"
#: ccdfunc.c:754
#: ccdfunc.c:753
msgid "Can't set readout speed"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ÓÞÉÔÙ×ÁÎÉÑ"
#: ccdfunc.c:574
#: ccdfunc.c:573
#, c-format
msgid "Can't set wheel position %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÐÏÌÏÖÅÎÉÅ ËÏÌÅÓÁ %d"
#: ccdfunc.c:782 ccdfunc.c:830 server.c:121
#: ccdfunc.c:781 ccdfunc.c:831 server.c:125
msgid "Can't start exposition"
msgstr "îÅ ÍÏÇÕ ÎÁÞÁÔØ ÜËÓÐÏÚÉÃÉÀ"
#. Захват кадра %d\n
#: ccdfunc.c:780
#: ccdfunc.c:779
#, c-format
msgid "Capture frame %d"
msgstr "úÁÈ×ÁÔ ËÁÄÒÁ %d"
#: ccdfunc.c:672
#: ccdfunc.c:671
#, c-format
msgid "Current format: %s"
msgstr ""
@ -232,55 +232,55 @@ msgstr ""
msgid "Display image in OpenGL window"
msgstr "ïÔÏÂÒÁÖÅÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ × ÏËÎÅ OpenGL"
#: imageview.c:507 imageview.c:579
#: imageview.c:508 imageview.c:581
#, c-format
msgid "Equalization of histogram: %s"
msgstr "üË×ÁÌÉÚÁÃÉÑ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:366
#: ccdfunc.c:365
msgid "Error saving file"
msgstr "ïÛÉÂËÁ ÓÏÈÒÁÎÅÎÉÑ ÆÁÊÌÁ"
#: ccdfunc.c:669
#: ccdfunc.c:668
#, c-format
msgid "Field of view: %s"
msgstr "ðÏÌÅ ÚÒÅÎÉÑ: %s"
#: ccdfunc.c:357
#: ccdfunc.c:356
#, c-format
msgid "File saved as '%s'"
msgstr "æÁÊÌ ÓÏÈÒÁÎÅÎ ËÁË '%s'"
#: ccdfunc.c:414
#: ccdfunc.c:413
msgid "Focuser device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÆÏËÕÓÅÒÁ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:643
#: ccdfunc.c:642
#, c-format
msgid "Found %d cameras, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÁÍÅÒ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:452
#: ccdfunc.c:451
#, c-format
msgid "Found %d focusers, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ÆÏËÕÓÅÒÏ×, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:543
#: ccdfunc.c:542
#, c-format
msgid "Found %d wheels, you point number %d"
msgstr "ïÂÎÁÒÕÖÅÎÏ %d ËÏÌÅÓ, ×Ù ÕËÁÚÁÌÉ %d"
#: ccdfunc.c:666
#: ccdfunc.c:665
#, c-format
msgid "Full array: %s"
msgstr "ðÏÌÎÙÊ ÆÏÒÍÁÔ: %s"
#: imageview.c:387
#: imageview.c:388
#, c-format
msgid "Histogram conversion: %s"
msgstr "ðÒÅÏÂÒÁÚÏ×ÁÎÉÅ ÇÉÓÔÏÇÒÁÍÍÙ: %s"
#: ccdfunc.c:406
#: ccdfunc.c:405
#, c-format
msgid "Image stat:\n"
msgstr "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ: \n"
@ -289,27 +289,23 @@ msgstr "
msgid "N flushes before exposing (default: 1)"
msgstr "N ÚÁÓ×ÅÞÉ×ÁÎÉÊ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ (ÐÏ ÕÍÏÌÞÁÎÉÀ: 1)"
#: ccdfunc.c:190
msgid "Neither filename nor filename prefix pointed!"
msgstr "鐱 ノヘム ニチハフチ, ホノ ミメナニノヒモ ホナ ユヒチレチホル!"
#: server.c:163
#: server.c:168
msgid "No camera device"
msgstr "îÅ ÕËÁÚÁÎÏ ÕÓÔÒÏÊÓÔ×Ï ËÁÍÅÒÙ"
#: ccdfunc.c:612 ccdfunc.c:613
#: ccdfunc.c:611 ccdfunc.c:612
msgid "No cameras found"
msgstr "ëÁÍÅÒ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:421
#: ccdfunc.c:420
msgid "No focusers found"
msgstr "æÏËÕÓÅÒÏ× ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:512
#: ccdfunc.c:511
msgid "No wheels found"
msgstr "ôÕÒÅÌÅÊ ÎÅ ÏÂÎÁÒÕÖÅÎÏ"
#: ccdfunc.c:756
#: ccdfunc.c:755
msgid "Only show statistics"
msgstr "ôÏÌØËÏ ÏÔÏÂÒÁÚÉÔØ ÓÔÁÔÉÓÔÉËÕ"
@ -317,52 +313,52 @@ msgstr "
msgid "PID file (default: "
msgstr "PID-ÆÁÊÌ (ÐÏ ÕÍÏÌÞÁÎÉÀ: "
#: ccdfunc.c:660
#: ccdfunc.c:659
#, c-format
msgid "Pixel size: %g x %g"
msgstr "òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g"
#: ccdfunc.c:789
#: ccdfunc.c:788
msgid "Read grabbed image"
msgstr "óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ"
#: ccdfunc.c:755
#: ccdfunc.c:754
#, c-format
msgid "Readout mode: %s"
msgstr "òÅÖÉÍ ÓÞÉÔÙ×ÁÎÉÑ: %s"
#: client.c:276
#: client.c:298
msgid "Server timeout"
msgstr "ôÁÊÍÁÕÔ ÓÅÒ×ÅÒÁ"
#: ccdfunc.c:717
#: ccdfunc.c:716
#, c-format
msgid "Set brightness to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ ÑÒËÏÓÔØ × %g"
#: ccdfunc.c:654
#: ccdfunc.c:653
#, c-format
msgid "Set fan speed to %d"
msgstr "îÅ ÍÏÇÕ ÕÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × %d"
#: ccdfunc.c:711
#: ccdfunc.c:710
#, c-format
msgid "Set gain to %g"
msgstr "õÓÔÁÎÏ×ÉÔØ Gain × %g"
#: ccdfunc.c:683
#: ccdfunc.c:682
#, c-format
msgid "Shutter command: %s\n"
msgstr "ëÏÍÁÎÄÁ ÚÁÔ×ÏÒÁ: %s\n"
#. "Попытка Ñ<>конфигурироваÑÑŒ порт I/O как %d\n"
#: ccdfunc.c:689
#: ccdfunc.c:688
#, c-format
msgid "Try to configure I/O port as %d"
msgstr "ðÏÐÙÔËÁ ÓËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ ÐÏÒÔ I/O ËÁË %d"
#. "Попытка запиÑ<C2B8>и %d в порт I/O\n"
#: ccdfunc.c:702
#: ccdfunc.c:701
#, c-format
msgid "Try to write %d to I/O port"
msgstr "ðÏÐÙÔËÁ ÚÁÐÉÓÉ %d × ÐÏÒÔ I/O"
@ -371,11 +367,11 @@ msgstr "
msgid "UNIX socket name"
msgstr "éÍÑ UNIX-ÓÏËÅÔÁ"
#: ccdfunc.c:505
#: ccdfunc.c:504
msgid "Wheel device not pointed"
msgstr "õÓÔÒÏÊÓÔ×Ï ÔÕÒÅÌÉ ÎÅ ÕËÁÚÁÎÏ"
#: ccdfunc.c:570
#: ccdfunc.c:569
#, c-format
msgid "Wheel position should be from 0 to %d"
msgstr "ðÏÚÉÃÉÑ ËÏÌÅÓÁ ÄÏÌÖÎÁ ÂÙÔØ ÏÔ 0 ÄÏ %d"
@ -509,11 +505,11 @@ msgstr "
msgid "observing program name"
msgstr "ÎÁÚ×ÁÎÉÅ ÐÒÏÇÒÁÍÍÙ"
#: imageview.c:507 imageview.c:579
#: imageview.c:508 imageview.c:581
msgid "off"
msgstr "×ÙËÌ"
#: imageview.c:507 imageview.c:579
#: imageview.c:508 imageview.c:581
msgid "on"
msgstr "×ËÌ"
@ -592,3 +588,6 @@ msgstr "
#: cmdlnopts.c:46
msgid "wheel device plugin (e.g. devdummy.so)"
msgstr "ÐÌÁÇÉÎ ÕÓÔÒÏÊÓÔ×Á ÔÕÒÅÌÉ (ÎÁÐÒÉÍÅÒ, devdummy.so)"
#~ msgid "Neither filename nor filename prefix pointed!"
#~ msgstr "鐱 ノヘム ニチハフチ, ホノ ミメナニノヒモ ホナ ユヒチレチホル!"

4
main.c
View File

@ -131,12 +131,8 @@ int main(int argc, char **argv){
wheels();
camerainit = prepare_ccds();
}else{ // client mode
#ifdef IMAGEVIEW
if(GP->showimage) return viewer(NULL); // TODO
#endif
if(GP->path) return start_socket(isserver, GP->path, FALSE);
if(GP->port) return start_socket(isserver, GP->port, TRUE);
}
#ifdef IMAGEVIEW
if(GP->showimage){ // activate image vindow in capture or simple viewer mode

3
omp.h
View File

@ -17,8 +17,6 @@
*/
#pragma once
#ifndef OMP_H__
#define OMP_H__
#ifdef OMP_FOUND
#include <omp.h>
@ -34,4 +32,3 @@
#endif
#endif // OMP_H__

View File

@ -70,9 +70,12 @@ strpair allcommands[] = {
{ CMD_FGOTO, "focuser position" },
{ CMD_FRAMEFORMAT, "camera frame format (X0,Y0,X1,Y1)" },
{ CMD_GAIN, "camera gain" },
{ CMD_GETIMAGE, "get image (binary data 2*w*h bytes)" },
{ CMD_HBIN, "horizontal binning" },
{ CMD_HEADERFILES, "add FITS records from these files (comma-separated list)" },
{ CMD_HELP, "show this help" },
{ CMD_IMHEIGHT, "last image height" },
{ CMD_IMWIDTH, "last image width" },
{ CMD_INFO, "connected devices state" },
{ CMD_INSTRUMENT, "FITS 'INSTRUME' field" },
{ CMD_IO, "get/set camera IO" },
@ -141,17 +144,18 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends
// now save frame
if(!ima.data) LOGERR("Can't save image: not initialized");
else{
if(!camera->capture(&ima)) LOGERR("Can't capture image");
else{
if(!camera->capture(&ima)){
LOGERR("Can't capture image");
camstate = CAMERA_ERROR;
return;
}else{
calculate_stat(&ima);
if(saveFITS(&ima, &lastfile)){
DBG("LAST file name changed");
camstate = CAMERA_FRAMERDY;
return;
}
}
}
camstate = CAMERA_ERROR;
camstate = CAMERA_FRAMERDY;
}
}
}
@ -217,6 +221,8 @@ static int camdevini(int n){
frameformat step;
camera->getgeomlimits(&frmformatmax, &step);
curformat = frmformatmax;
DBG("\n\nGeometry format (offx/offy) w/h: (%d/%d) %d/%d", curformat.xoff, curformat.yoff,
curformat.w, curformat.h);
if(GP->hbin < 1) GP->hbin = 1;
if(GP->vbin < 1) GP->vbin = 1;
fixima();
@ -302,14 +308,17 @@ static hresult exphandler(int fd, _U_ const char *key, const char *val){
// show last filename of saved FITS
static hresult lastfnamehandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[PATH_MAX+32];
snprintf(buf, PATH_MAX+31, CMD_LASTFNAME "=%s", lastfile);
if(lastfile && *lastfile) snprintf(buf, PATH_MAX+31, CMD_LASTFNAME "=%s", lastfile);
else snprintf(buf, PATH_MAX+31, CMD_LASTFNAME "=");
if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_SILENCE;
}
// filename setter/getter
static hresult namehandler(int fd, _U_ const char *key, const char *val){
char buf[PATH_MAX+32];
if(val){
DBG("filename=%s", val);
if(val && *val){
DBG("Make abs path");
char *path = makeabspath(val, FALSE);
if(!path){
LOGERR("Can't create file '%s'", val);
@ -319,6 +328,11 @@ static hresult namehandler(int fd, _U_ const char *key, const char *val){
outfile = strdup(path);
GP->outfile = outfile;
GP->outfileprefix = NULL;
}else{ // clear names
DBG("Clear names");
GP->outfileprefix = NULL;
GP->outfile = NULL;
return RESULT_OK;
}
if(!GP->outfile) return RESULT_FAIL;
snprintf(buf, PATH_MAX+31, CMD_FILENAME "=%s", GP->outfile);
@ -328,6 +342,7 @@ static hresult namehandler(int fd, _U_ const char *key, const char *val){
// filename prefix
static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *val){
char buf[PATH_MAX+32];
DBG("filename prefix=%s", val);
if(val){
char *path = makeabspath(val, FALSE);
if(!path){
@ -339,6 +354,10 @@ static hresult nameprefixhandler(_U_ int fd, _U_ const char *key, const char *va
outfile = strdup(path);
GP->outfileprefix = outfile;
GP->outfile = NULL;
}else{ // clear names
GP->outfileprefix = NULL;
GP->outfile = NULL;
return RESULT_OK;
}
if(!GP->outfileprefix) return RESULT_FAIL;
snprintf(buf, PATH_MAX+31, CMD_FILENAMEPREFIX "=%s", GP->outfileprefix);
@ -378,7 +397,7 @@ static hresult binhandler(_U_ int fd, const char *key, const char *val){
}
return RESULT_FAIL;
}
static hresult temphandler(_U_ int fd, _U_ const char *key, const char *val){
static hresult temphandler(int fd, _U_ const char *key, const char *val){
float f;
char buf[64];
int r;
@ -408,7 +427,7 @@ static hresult temphandler(_U_ int fd, _U_ const char *key, const char *val){
return RESULT_SILENCE;
}else return RESULT_FAIL;
}
static hresult camfanhandler(_U_ int fd, _U_ const char *key, _U_ const char *val){
static hresult camfanhandler(int fd, _U_ const char *key, _U_ const char *val){
char buf[64];
if(val){
int spd = atoi(val);
@ -497,7 +516,7 @@ static hresult formathandler(int fd, const char *key, const char *val){
char buf[64];
frameformat fmt;
if(val){
if(strcmp(key, CMD_FRAMEFORMAT)) return RESULT_BADKEY; // can't set maxformat
if(strcmp(key, CMD_FRAMEMAX)) return RESULT_BADKEY; // can't set maxformat
if(4 != sscanf(val, "%d,%d,%d,%d", &fmt.xoff, &fmt.yoff, &fmt.w, &fmt.h)) return RESULT_BADVAL;
fmt.w -= fmt.xoff; fmt.h -= fmt.yoff;
int r = camera->setgeometry(&fmt);
@ -861,6 +880,23 @@ static hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){
return RESULT_SILENCE;
}
// sent to client last image
static hresult imsendhandler(int fd, _U_ const char *key, _U_ const char *val){
if(!ima.data || !ima.h || !ima.w) return RESULT_FAIL;
// send image as raw data w*h*2
if(!sendimage(fd, ima.data, 2*ima.h*ima.w)) return RESULT_DISCONNECTED;
return RESULT_OK;
}
static hresult imsizehandler(int fd, const char *key, _U_ const char *val){
char buf[64];
// send image width/height in pixels
if(0 == strcmp(key, CMD_IMHEIGHT)) snprintf(buf, 63, CMD_IMHEIGHT "=%d", ima.h);
else snprintf(buf, 63, CMD_IMWIDTH "=%d", ima.w);
if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED;
return RESULT_OK;
}
// for setters: do nothing when camera not in idle state
static int CAMbusy(){
if(camera && camstate != CAMERA_IDLE){
@ -909,6 +945,9 @@ static handleritem items[] = {
{chkcam, formathandler, CMD_FRAMEMAX},
{chkcam, nflusheshandler, CMD_NFLUSHES},
{NULL, expstatehandler, CMD_EXPSTATE},
{NULL, imsendhandler, CMD_GETIMAGE},
{NULL, imsizehandler, CMD_IMWIDTH},
{NULL, imsizehandler, CMD_IMHEIGHT},
{chkcam, nameprefixhandler, CMD_FILENAMEPREFIX},
{chkcam, rewritefilehandler, CMD_REWRITE},
{chkcam, _8bithandler, CMD_8BIT},

View File

@ -17,8 +17,6 @@
*/
#pragma once
#ifndef SERVER_H__
#define SERVER_H__
typedef enum{
CAMERA_IDLE, // idle state, client send this to cancel capture
@ -39,6 +37,11 @@ char *makeabspath(const char *path, int shouldbe);
#define CMD_HELP "help"
// restart server
#define CMD_RESTART "restartTheServer"
// get last exposed image
#define CMD_GETIMAGE "getimage"
// get image size in pixels
#define CMD_IMWIDTH "imheight"
#define CMD_IMHEIGHT "imwidth"
// CCD/CMOS
#define CMD_CAMLIST "camlist"
@ -85,5 +88,3 @@ char *makeabspath(const char *path, int shouldbe);
#define CMD_WLIST "wlist"
#define CMD_WDEVNO "wdevno"
#define CMD_WPOS "wpos"
#endif // SERVER_H__

View File

@ -24,8 +24,11 @@
#include <sys/un.h> // unix socket
#include <usefull_macros.h>
#include "cmdlnopts.h"
#include "client.h"
#include "cmdlnopts.h"
#ifdef IMAGEVIEW
#include "imageview.h"
#endif
#include "server.h"
#include "socket.h"
@ -114,13 +117,34 @@ int start_socket(int isserver, char *path, int isnet){
}
if(isnet) freeaddrinfo(res);
if(isserver) server(sock);
else client(sock);
else{
#ifdef IMAGEVIEW
if(GP->showimage){
init_grab_sock(sock);
viewer(sockcaptured); // start viewer with socket client parser
}else
#endif
client(sock);
}
DBG("Close socket");
close(sock);
if(isserver) signals(0);
return 0;
}
int sendimage(int fd, uint16_t *data, int l){
if(fd < 1 || !data || l < 1) return TRUE; // empty message
DBG("send new image (size=%d) to fd %d", l, fd);
if(l != send(fd, data, l, MSG_NOSIGNAL)){
WARN("write()");
LOGWARN("write()");
return FALSE;
}
DBG("success");
if(globlog) LOGDBG("SEND image (size=%d) to fd %d", l, fd);
return TRUE;
}
// simple wrapper over write: add missed newline and log data
int sendmessage(int fd, const char *msg, int l){
if(fd < 1 || !msg || l < 1) return TRUE; // empty message
@ -173,7 +197,7 @@ const char *hresult2str(hresult r){
* @return `val`
*/
char *get_keyval(char *keyval){
//DBG("Got string %s", keyval);
DBG("Got string %s", keyval);
// remove starting spaces in key
while(isspace(*keyval)) ++keyval;
char *val = strchr(keyval, '=');
@ -181,6 +205,7 @@ char *get_keyval(char *keyval){
*val++ = 0;
while(isspace(*val)) ++val;
}
DBG("val = %s (%zd bytes)", val, (val)?strlen(val):0);
// remove trailing spaces in key
char *e = keyval + strlen(keyval) - 1; // last key symbol
while(isspace(*e) && e > keyval) --e;

View File

@ -17,10 +17,8 @@
*/
#pragma once
#ifndef SERSOCK_H__
#define SERSOCK_H__
#include <pthread.h>
#include <stdint.h>
// max & min TCP socket port number
#define PORTN_MAX (65535)
@ -64,10 +62,9 @@ typedef struct{
} handleritem;
int start_socket(int server, char *path, int isnet);
int sendimage(int fd, uint16_t *data, int l);
int sendmessage(int fd, const char *msg, int l);
int sendstrmessage(int fd, const char *msg);
char *get_keyval(char *keyval);
int processData(int fd, handleritem *handlers, char *buf, int buflen);
#endif // SERSOCK_H__