From f68362a8b303dd69461f057a78dad5edd8a0ca21 Mon Sep 17 00:00:00 2001 From: eddyem Date: Wed, 1 Jun 2016 13:59:47 +0300 Subject: [PATCH] add my own simple JSON parser instead of json-c --- .gitignore | 4 + mask/README.fmt.RU | 22 + mask/holes.json | 6 +- mask/make_mask.m | 10 +- src/CMakeLists.txt | 2 +- src/CPU.c | 24 +- src/CUDA.cu | 44 +- src/README | 3 +- src/cmdlnopts.c | 55 +- src/diaphragm.c | 185 ++--- src/include/cmdlnopts.h | 9 +- src/include/diaphragm.h | 2 +- src/include/json.h | 64 ++ src/include/mkHartmann.h | 27 - src/include/{parceargs.h => parseargs.h} | 44 +- src/include/usefull_macros.h | 124 ++++ src/json.c | 361 +++++++++ src/locale/ru/messages.po | 269 ++++--- src/locale/ru/ru.po | 248 +++++-- src/locale/ru/ru.po~ | 906 +++++++++++++++++------ src/mkHartmann.c | 267 ++----- src/{parceargs.c => parseargs.c} | 293 ++++++-- src/saveimg.c | 20 +- src/usefull_macros.c | 327 ++++++++ src/wrapper.c | 70 +- 25 files changed, 2449 insertions(+), 937 deletions(-) create mode 100644 .gitignore create mode 100644 mask/README.fmt.RU create mode 100644 src/include/json.h rename src/include/{parceargs.h => parseargs.h} (73%) create mode 100644 src/include/usefull_macros.h create mode 100644 src/json.c rename src/{parceargs.c => parseargs.c} (53%) create mode 100644 src/usefull_macros.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c514bfd --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.hg* +*.tgz +*~ +.dropbox.attr diff --git a/mask/README.fmt.RU b/mask/README.fmt.RU new file mode 100644 index 0000000..3526e97 --- /dev/null +++ b/mask/README.fmt.RU @@ -0,0 +1,22 @@ +формат JSON для файла описания диафрагмы: + +Файл состоит из некоторого количества глобальных параметров и одного массива с описанием отверстий +в диафрагме +В глобальных объектах обязательно должен находиться параметр "Z" или "maskz" (это одно и то же) - +координата Z (от вершины зеркала) расположения диафрагмы Гартманна +Также можно объявить глобальные параметры - одну или несколько характеристик отверстий диафрагмы, +в этом случае в тех отверстиях массива, где данный параметр опущен, он будет браться из глобальных. + +Центр диафрагмы располагается на оптической оси зеркала. Считается, что диафрагма строго +перпендикулярна оптической оси. + +Массив, задающий параметры отверстий диафрагмы, именуется "holes", каждый член массива может +содержать следующие поля (они могут быть и описаны в глобальных): + "shape" - форма отверстия ("square" - квадрат, "round" -круг, "ellipse" - эллипс) + "radius" - скаляр или массив из двух значений - радиус отверстия + "center" - массив из двух значений - координаты центра отверстия (относительно центра диафрагмы) + "bbox" - массив из четырех значений - координаты двух противоположных углов прямоугольника, описывающего отверстие + +Независимо от формы отверстия его можно задать двумя способами: либо комбинацией "radius" и "center", +либо одним полем "bbox". Если заданы оба параметра, учитывается лишь первый. + \ No newline at end of file diff --git a/mask/holes.json b/mask/holes.json index 526f124..19cab44 100644 --- a/mask/holes.json +++ b/mask/holes.json @@ -1,5 +1,5 @@ { - "maskz": 20.0, + "maskz": 20.017, "shape": "round", "radius": 0.007500, "holes": [ { "ring": 0, "number": 0, "center": [ 0.1742, 0.0172 ] }, @@ -258,7 +258,7 @@ { "ring": 7, "number": 29, "center": [ 0.4216, -0.2253 ] }, { "ring": 7, "number": 30, "center": [ 0.4574, -0.1388 ] }, { "ring": 7, "number": 31, "center": [ 0.4757, -0.0469 ] }, - { "mark": 1, "number": 0, "center": [ 0.3141, -0.1301 ] }, - { "mark": 1, "number": 1, "center": [ 0.0933, -0.4688 ] }, + { "mark": 1, "number": 0, "center": [ 0.4416, -0.1829 ] }, + { "mark": 1, "number": 1, "center": [ 0.0576, -0.2893 ] }, ] } diff --git a/mask/make_mask.m b/mask/make_mask.m index a164145..7385d30 100644 --- a/mask/make_mask.m +++ b/mask/make_mask.m @@ -3,6 +3,7 @@ function make_mask() % построение гартмановской маски % SS - размер маски f = fopen("holes.json", "w"); + X = []; Y = []; R = [175 247 295 340 379 414 448 478] * 1e-3; % радиусы колец на гартманограмме HoleR = 7.5e-3; % радиус отверстий - 7.5мм R0 = .6; % радиус самой гартманограммы @@ -11,20 +12,23 @@ function make_mask() % для того, чтобы разместить на маске окружности, создадим маску % окружности: zeros(15) с единицами там, где должна быть дырка. Затем % пометим единицами в mask те точки, куда должен попадать левый верхний - fprintf(f, "{\n\t\"shape\": \"round\", \"radius\": %f,\n\t\"holes\": [\n" , HoleR); + fprintf(f, "{\n\t\"maskz\": 20.017,\n\t\"shape\": \"round\", \"radius\": %f,\n\t\"holes\": [\n" , HoleR); for i = [1 : size(R,2)] % цикл по кольцам x = R(i) * cos(Angles); y = R(i) * sin(Angles); + X = [X x]; Y = [Y y]; %fprintf(f, "\t\t{\"ring\": %d, \"center\": [%f, %f]\n", i, x[j], y[j]]); printR(f, sprintf("\"ring\": %d", i-1), x, y); endfor % помечаем маркеры - x = R([4 8]) .* cos([-2 -7]* 2 * alpha0); - y = R([4 8]) .* sin([-2 -7]* 2 * alpha0); + x = R([8 3]) .* cos([-2 -7]* 2 * alpha0); + y = R([8 3]) .* sin([-2 -7]* 2 * alpha0); + X = [X x]; Y = [Y y]; %fprintf(f, "\t\t{\"marker\", \"center\": [%f, %f]\n", x, y); printR(f, sprintf("\"mark\": 1"), x, y); fprintf(f, "\t]\n}\n"); fclose(f); + plot(X, Y, 'o'); axis square; endfunction function printR(f, msg, x, y) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c406e20..891be50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ pkg_check_modules(${PROJ} REQUIRED # gtkglext-1.0>=0.7.0 # gtkglext-x11-1.0>=0.7.0 cfitsio>=3.0 - json>=0.9 +# json>=0.9 # libpng>=1.5 # fftw3>=3.2.0 ) diff --git a/src/CPU.c b/src/CPU.c index 9318fb9..762caeb 100644 --- a/src/CPU.c +++ b/src/CPU.c @@ -21,6 +21,7 @@ #define CPU_C #include "mkHartmann.h" +#include "usefull_macros.h" #include "wrapper.h" // RANDOM NUMBER generation block ============================================> @@ -93,9 +94,22 @@ int CPUbicubic_interp(float *out, float *in, } // <========================================= end of BICUBIC interpolation block -int CPUmkmirDeviat(float *map _U_, size_t mapWH _U_, float mirSZ _U_, - mirDeviations * mirDev _U_){ +/** + * Compute matrices of mirror surface deviation + * @param map, mapWH - square matrix of surface deviations (in meters) and its size + * @param mirDia - mirror diameter + * @param mirDev - deviations: + * .mirWH - size of output square matrices (mirWH x mirWH) + * .mirZ - matrix of mirror Z variations (add to mirror Z) + * .mirDX, .mirDY - partial derivatives dZ/dx & dZ/dy (add to mirror der.) + * @return 0 if fails + */ +int CPUmkmirDeviat(float *map, size_t mapWH, float mirDia, + mirDeviations * mirDev){ FNAME(); + size_t mirWH = mirDev->mirWH; + if(!CPUbicubic_interp(mirDev->mirZ,map,mirWH,mirWH,mapWH,mapWH)) return 0; + ; return 0; } @@ -105,9 +119,3 @@ int CPUgetPhotonXY(float *xout _U_, float *yout _U_, int R _U_ ,mirDeviations *D return 0; } -/* -int CPUfillImage(float *phX _U_, float *phY _U_, size_t ph_sz _U_, - float *image _U_, size_t imW _U_, size_t imH _U_, BBox *imbox _U_){ - return 0; -} -*/ diff --git a/src/CUDA.cu b/src/CUDA.cu index 3b46d6e..e3e557f 100644 --- a/src/CUDA.cu +++ b/src/CUDA.cu @@ -32,6 +32,7 @@ #define EXTERN extern "C" #define CUDA_CU #include "mkHartmann.h" +#include "usefull_macros.h" #include "wrapper.h" int SHMEMSZ = 16383; // default constants, changed runtime @@ -102,7 +103,7 @@ static int ret; if(CUERROR("CUDA: can't copy data to device")){\ FREERETMACRO; \ }}while(0) -#define CUFREE(var) do{cudaFree(var); var = NULL; }while(0) +#define CUFREE(var) do{if(var){cudaFree(var); var = NULL; }}while(0) #define CUFFTCALL(fn) do{ \ cufftResult fres = fn; \ if(CUFFT_SUCCESS != fres){ \ @@ -420,11 +421,12 @@ free_all: */ // 1./sqrt(2) #define DIVSQ2 0.7071068f -// 2*(1+2/sqrt(2)) -#define WEIGHT 482.842712f +// 2*(1+2/sqrt(2)) -- (1+2/sqrt(2)) taken from linear gradient: +// 1 = (2 + 4/sqrt(2)) / (2*x) ==> x = 1 + 2/sqrt(2) +#define WEIGHT 4.82842712f __global__ void calcMir_dXdY(size_t Sz, float mirPixSZ, float *dZdX, float *dZdY){ - #define TEX(X,Y) tex2D(TEXTURE(), X0+(X), Y0+(Y))*100.f + #define TEX(X,Y) tex2D(TEXTURE(), X0+(X), Y0+(Y)) #define PAIR(X,Y) (TEX((X),(Y))-TEX(-(X),-(Y))) int X0,Y0; X0 = threadIdx.x + blockDim.x * blockIdx.x; @@ -445,9 +447,10 @@ __global__ void calcMir_dXdY(size_t Sz, float mirPixSZ, * Compute matrices of mirror surface deviation * @param map, mapWH - square matrix of surface deviations (in meters) and its size * @param mirDia - mirror diameter - * @param mirWH - size of output square matrices (mirWH x mirWH) - * @param mirZ - matrix of mirror Z variations (add to mirror Z) - * @param mirDX, mirDY - partial derivatives dZ/dx & dZ/dy (add to mirror der.) + * @param mirDev - deviations: + * .mirWH - size of output square matrices (mirWH x mirWH) + * .mirZ - matrix of mirror Z variations (add to mirror Z) + * .mirDX, .mirDY - partial derivatives dZ/dx & dZ/dy (add to mirror der.) * @return 0 if fails */ EXTERN int CUmkmirDeviat(float *map, size_t mapWH, float mirDia, @@ -529,9 +532,8 @@ typedef struct{ * in: coordinates in diapazone [0,1) * @param photonSZ - size of prevoius arrays * @param Z0 - Z-coordinate of image plane - * @param M - mirror rotation matrix or NULL if rotation is absent + * @param mpb - rotmatrix, mirror parameters, bbox where photons falling and diaphragm * @param mir_WH - mirror derivations matrix size - * @param Parms - mirror parameters * @param f - light direction vector * * @param holes - array with @@ -547,15 +549,15 @@ __global__ void getXY(float *photonX, float *photonY, size_t photonSZ, BBox *box = &mpb->B; float _2F = Parms->F * 2.f, R = Parms->D / 2.f; float x,y,z; // coordinates on mirror in meters - x = box->x0 + photonX[IDX] * box->w; // coords of photons + x = box->x0 + photonX[IDX] * box->w; // coords of photons on mirror y = box->y0 + photonY[IDX] * box->h; float r2 = x*x + y*y; z = r2 / _2F / 2.f; // we don't mean large inclination so check border by non-inclinated mirror if(r2 > R*R) BADPHOTON(); - float pixSZ = Parms->D / float(mir_WH-1); // "pixel" size on mirror + float pixSZ = Parms->D / float(mir_WH-1); // "pixel" size on mirror's normales matrix // coordinates on deviation matrix, don't forget about y-mirroring! - float xOnMat = (x + R) / pixSZ, yOnMat = (R - y) / pixSZ; + float xOnMat = (x + R) / pixSZ, yOnMat = (y + R) / pixSZ; //yOnMat = (R - y) / pixSZ; // now add z-deviations, linear interpolation of pre-computed matrix z += tex2D(TZ, xOnMat, yOnMat); // point on unrotated mirror @@ -576,17 +578,18 @@ __global__ void getXY(float *photonX, float *photonY, size_t photonSZ, float K; if(mpb->D.Nholes){ // there is a diaphragm - test it Diaphragm *D = &(mpb->D); - int S = D->mask->WH; // size of diaphragm matrix + int S = D->mask->WH; // size of matrix mask + pixSZ = Parms->D / (float)S; K = (D->Z - point.z) / refl.z; // scale to convert normal to vector - float xleft = D->box.x0, ybot = D->box.y0; // left bottom angle of dia box - float scalex = D->box.w/(float)S, scaley = D->box.h/(float)S; - x = point.x + K*refl.x; - y = point.y + K*refl.y; - int curX = (int)((x - xleft) / scalex + 0.5f); // coords on dia matrix - int curY = (int)((y - ybot) / scaley + 0.5f); + //float xleft = D->box.x0, ybot = D->box.y0; // left bottom angle of dia box + //float scalex = D->box.w/(float)S, scaley = D->box.h/(float)S; + int curX = (int)((x + R) / pixSZ + 0.5f); // coords on mirror mask + int curY = (int)((y + R) / pixSZ + 0.5f); if(curX < 0 || curX >= S || curY < 0 || curY >= S) BADPHOTON(); uint16_t mark = D->mask->data[curY*S + curX]; if(!mark) BADPHOTON(); + x = point.x + K*refl.x; // coords on diaphragm + y = point.y + K*refl.y; do{ int t = D->holes[mark-1].type; BBox *b = &D->holes[mark-1].box; @@ -699,7 +702,8 @@ EXTERN int CUgetPhotonXY(float *xout, float *yout, int R, mirDeviations *D, Diaphragm tmpd; mirMask tmpM; memcpy(&tmpd, mirParms->dia, sizeof(Diaphragm)); - memcpy(&tmpM, mirParms->dia->mask, sizeof(mirMask)); + //memcpy(&tmpM, mirParms->dia->mask, sizeof(mirMask)); + tmpM.WH = mirParms->dia->mask->WH; size_t S = sizeof(aHole) * mirParms->dia->Nholes; CUALLOC(hdev, S); CUMOV2DEV(hdev, mirParms->dia->holes, S); diff --git a/src/README b/src/README index e81d625..fc287ca 100644 --- a/src/README +++ b/src/README @@ -10,4 +10,5 @@ ВСЕ ПРОСТРАНСТВЕННЫЕ КООРДИНАТЫ ПРАВОВИНТОВЫЕ -НА ИЗОБРАЖЕНИЯХ ОСЬ Y Н +НА ИЗОБРАЖЕНИЯХ ОСЬ Y НАПРАВЛЕНА ВВЕРХ! + diff --git a/src/cmdlnopts.c b/src/cmdlnopts.c index 6869398..19737ff 100644 --- a/src/cmdlnopts.c +++ b/src/cmdlnopts.c @@ -1,5 +1,5 @@ /* - * cmdlnopts.c - the only function that parce cmdln args and returns glob parameters + * cmdlnopts.c - the only function that parse cmdln args and returns glob parameters * * Copyright 2013 Edward V. Emelianoff * @@ -20,10 +20,11 @@ */ /* #include -#include -#include */ -#include "cmdlnopts.h" +#include */ +#include "cmdlnopts.h" +#include "usefull_macros.h" +#include // global variables for parsing glob_pars G; @@ -37,6 +38,7 @@ extern int rewrite_ifexists; extern char *outpfile; // output file name for saving matrixes extern int printDebug; // print tabulars with data on screen or to file extern int save_images;// save intermediate results to images +extern int forceCPU; // force using CPU even if videocard available // suboptions structure for get_suboptions // in array last MUST BE {0,0,0} @@ -49,15 +51,20 @@ typedef struct{ // DEFAULTS // default global parameters glob_pars const Gdefault = { - 8, // size of initial array of surface deviations - 100, // size of interpolated S0 - 1000, // resulting image size - 10000, // amount of photons falled to one pixel of S1 by one iteration - 0, // add to mask random numbers - 1e-8, // amplitude of added random noice - IT_FITS,// output image type - NULL, // input deviations file name - NULL // mirror + .S_dev = 8, // size of initial array of surface deviations + .S_interp = 100, // size of interpolated S0 + .S_image = 1024, // resulting image size + .N_phot = 10000, // amount of photons falled to one pixel of S1 by one iteration + .N_iter = 1000, // iterations number + .randMask = 0, // add to mask random numbers + .randAmp = -1., // amplitude of added random noice + .CCDW = 30., // CCD width + .CCDH = 30., // CD height + .it = IT_FITS, // output image type + .dev_filename = NULL, // input deviations file name + .holes_filename = NULL, // input holes file name + .outfile = "image", // output file name + .Mirror = NULL // mirror }; //default mirror parameters mirPar const Mdefault = { @@ -74,7 +81,7 @@ mirPar const Mdefault = { bool get_mir_par(void *arg, int N); bool get_imtype(void *arg, int N); -char MirPar[] = N_("set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:Ao=ang:Zo=ang:C=num]\n" \ +char MirPar[] = N_("set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:Aobj=ang:Zoobj=ang:CCD=num]\n" \ "\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like -10m13.4 !\n" \ "\t\tdiam - diameter of mirror\n" \ "\t\tfoc - mirror focus ratio\n" \ @@ -87,19 +94,25 @@ char MirPar[] = N_("set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl // name has_arg flag val type argptr help myoption cmdlnopts[] = { {"help", 0, NULL, 'h', arg_int, APTR(&help), N_("show this help")}, - {"dev-size",1, NULL, 'd', arg_int, APTR(&G.S_dev), N_("size of initial array of surface deviations")}, + {"dev-size",1, NULL, 's', arg_int, APTR(&G.S_dev), N_("size of initial array of surface deviations")}, {"int-size",1, NULL, 'i', arg_int, APTR(&G.S_interp), N_("size of interpolated array of surface deviations")}, - {"image-size",1,NULL, 'I', arg_int, APTR(&G.S_image), N_("resulting image size")}, + {"image-size",1,NULL, 'S', arg_int, APTR(&G.S_image), N_("resulting image size")}, {"N-photons",1,NULL, 'N', arg_int, APTR(&G.N_phot), N_("amount of photons falled to one pixel of matrix by one iteration")}, {"mir-parameters",1,NULL,'M', arg_function,APTR(&get_mir_par),MirPar}, {"add-noice",0, &G.randMask,1, arg_none, NULL, N_("add random noice to mirror surface deviations")}, {"noice-amp",1, NULL, 'a', arg_float, APTR(&G.randAmp), N_("amplitude of random noice (default: 1e-8)")}, {"dev-file", 1, NULL, 'F', arg_string, APTR(&G.dev_filename),N_("filename for mirror surface deviations (in microns!)")}, - {"force", 0, &rewrite_ifexists,1,arg_none,NULL, N_("rewrite output file if exists")}, + {"force", 0, NULL, 'f', arg_int, APTR(&rewrite_ifexists),N_("rewrite output file if exists")}, {"log-file",1, NULL, 'l', arg_string, APTR(&outpfile), N_("save matrices to file arg")}, {"print-matr",0,&printDebug,1, arg_none, NULL, N_("print matrices on screen")}, - {"save-images",0,&save_images,1,arg_none, NULL, N_("save intermediate results to images")}, + {"debug-images",0,NULL, 'd', arg_int, APTR(&save_images), N_("save intermediate results to images")}, {"image-type",1,NULL, 'T', arg_function,APTR(&get_imtype), N_("image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)")}, + {"holes-file",1,NULL, 'j', arg_string, APTR(&G.holes_filename),N_("name of JSON file with holes description")}, + {"N-iter", 1, NULL, 'I', arg_int, APTR(&G.N_iter), N_("amount of iterations by N-photons")}, + {"ccd-w", 1, NULL, 'W', arg_float, APTR(&G.CCDW), N_("CCD width (in millimeters)")}, + {"ccd-h", 1, NULL, 'H', arg_float, APTR(&G.CCDH), N_("CCD height (in millimeters)")}, + {"outfile", 1, NULL, 'o', arg_string, APTR(&G.outfile), N_("output image file name")}, + {"force-cpu",0, &forceCPU,1, arg_none, NULL, N_("force CPU using iven if have videocard")}, end_option }; @@ -239,13 +252,13 @@ bool get_mir_par(void *arg, int N _U_){ } /** - * Parce command line options and return dynamically allocated structure + * Parse command line options and return dynamically allocated structure * to global parameters * @param argc - copy of argc from main * @param argv - copy of argv from main * @return allocated structure with global parameters */ -glob_pars *parce_args(int argc, char **argv){ +glob_pars *parse_args(int argc, char **argv){ int i; void *ptr; ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr); @@ -254,7 +267,7 @@ glob_pars *parce_args(int argc, char **argv){ // format of help: "Usage: progname [args]\n" change_helpstring("Usage: %s [args]\n\n\tWhere args are:\n"); // parse arguments - parceargs(&argc, &argv, cmdlnopts); + parseargs(&argc, &argv, cmdlnopts); if(help) showhelp(-1, cmdlnopts); if(argc > 0){ printf("\nIgnore argument[s]:\n"); diff --git a/src/diaphragm.c b/src/diaphragm.c index a517d84..1a954be 100644 --- a/src/diaphragm.c +++ b/src/diaphragm.c @@ -20,30 +20,20 @@ */ #include "mkHartmann.h" +#include "usefull_macros.h" #include "wrapper.h" #include "diaphragm.h" #include -#include +#include "json.h" /** * Get double value from object * @param jobj (i) - object * @return double value */ -double get_jdouble(json_object *jobj){ - enum json_type type = json_object_get_type(jobj); - double val; - switch(type){ - case json_type_double: - val = json_object_get_double(jobj); - break; - case json_type_int: - val = json_object_get_int(jobj); - break; - default: - ERRX(_("Wrong value! Get non-number!\n")); - } - return val; +double get_jdouble(json_pair *val){ + if(val->type != json_type_number) ERRX(_("Wrong value! Get non-number!\n")); + return json_pair_get_number(val); } /** @@ -53,26 +43,19 @@ double get_jdouble(json_object *jobj){ * @param getLen (o) - array length or NULL * @return filled array */ -double *json_get_array(json_object *jobj, int *getLen){ - enum json_type type; - json_object *jarray = jobj; - int arraylen = json_object_array_length(jarray); - double *arr = calloc(arraylen, sizeof(double)); +double *json_get_array(json_pair *pair, int *getLen){ + if(pair->type != json_type_data_array) return NULL; + size_t i, arraylen = pair->len; + if(arraylen < 1) return NULL; + double *arr = MALLOC(double, arraylen); int L = 0; - int i; - json_object *jvalue; - for (i=0; i< arraylen; i++){ - jvalue = json_object_array_get_idx(jarray, i); - type = json_object_get_type(jvalue); - if(type == json_type_array){ // nested arrays is error - ERRX(_("Invalid file format! Found nested arrays!\n")); - } - else if (type != json_type_object){ - arr[L++] = get_jdouble(jvalue); - } - else{ // non-numerical data? - ERRX(_("Invalid file format! Non-numerical data in array!\n")); - } + char *jvalue; + for (i = 0; i< arraylen; i++){ + jvalue = json_array_get_data(pair, i); + //DBG("get arr val[%zd]: %s",i, jvalue); + if(!jvalue) break; + arr[L++] = strtod(jvalue, NULL); + FREE(jvalue); } if(L == 0) FREE(arr); if(getLen) *getLen = L; @@ -84,18 +67,20 @@ double *json_get_array(json_object *jobj, int *getLen){ * * @param B (o) - output BBox (allocated outside) * @param jobj (i) - JSON object (array with BBox params) + * @return 0 if all OK */ -void json_get_bbox(BBox *B, json_object *jobj){ +int json_get_bbox(BBox *B, json_object *jobj){ double *arr = NULL; int Len; assert(B); assert(jobj); - json_object *o = json_object_object_get(jobj, "bbox"); - if(!o) return; + json_pair *o = json_object_get_pair(jobj, "bbox"); + if(!o) return 1; if(!(arr = json_get_array(o, &Len)) || Len != 4){ ERRX(_("\"bbox\" must contain an array of four doubles!\n")); } B->x0 = arr[0]; B->y0 = arr[1]; B->w = arr[2]; B->h = arr[3]; FREE(arr); + return 0; } aHole globHole; // global parameters for all holes (in beginning of diafragm JSON) @@ -103,29 +88,32 @@ aHole globHole; // global parameters for all holes (in beginning of diafragm JSO * Fills aHole object by data in JSON * @param jobj (i) - JSON data for hole * @param H (o) - output hole object + * @return 0 if all OK */ -void get_obj_params(json_object *jobj, aHole *H){ +int get_obj_params(json_object *jobj, aHole *H){ double *arr = NULL; + if(!jobj) return 1; int Len; - enum json_type type; if(!H){ ERRX( _("Error: NULL instead of aHole structure!\n")); } memcpy(H, &globHole, sizeof(aHole)); // initialize hole by global values - json_object *o = json_object_object_get(jobj, "shape"); + json_pair *o = json_object_get_pair(jobj, "shape"); if(o){ - const char *ptr = json_object_get_string(o); + char *ptr = json_pair_get_string(o); + if(!ptr) ERRX(_("Wrong \"shape\" value")); if(strcmp(ptr, "square") == 0) H->type = H_SQUARE; else if(strcmp(ptr, "round") == 0 || strcmp(ptr, "ellipse") == 0 ) H->type = H_ELLIPSE; else H->type = H_UNDEF; + //DBG("shape: %s", ptr); } - o = json_object_object_get(jobj, "radius"); + o = json_object_get_pair(jobj, "radius"); if(o){ - type = json_object_get_type(o); - if(type == json_type_int || type == json_type_double){ // circle / square - double R = json_object_get_double(o); + //DBG("radius: %s", o->value); + if(o->type == json_type_number){ // circle / square + double R = strtod(o->value, NULL); H->box.w = H->box.h = R * 2.; - }else if(type == json_type_array){ // ellipse / rectangle + }else if(o->type == json_type_data_array){ // ellipse / rectangle if(!(arr = json_get_array(o, &Len)) || Len != 2){ ERRX(_("\"radius\" array must consist of two doubles!\n")); } @@ -135,8 +123,9 @@ void get_obj_params(json_object *jobj, aHole *H){ ERRX(_("\"radius\" must be a number or an array of two doubles!\n")); } } - o = json_object_object_get(jobj, "center"); + o = json_object_get_pair(jobj, "center"); if(o){ + //DBG("center"); if(!(arr = json_get_array(o, &Len)) || Len != 2){ ERRX(_("\"center\" must contain an array of two doubles!\n")); } @@ -144,16 +133,9 @@ void get_obj_params(json_object *jobj, aHole *H){ H->box.y0 = arr[1] - H->box.h/2.; FREE(arr); }else{ - json_get_bbox(&H->box, jobj); - /* o = json_object_object_get(jobj, "bbox"); - if(o){ - if(!(arr = json_get_array(o, &Len)) || Len != 4){ - ERRX(_("\"bbox\" must contain an array of four doubles!\n")); - } - H->box.x0 = arr[0]; H->box.y0 = arr[1]; H->box.w = arr[2]; H->box.h = arr[3]; - FREE(arr); - }*/ + return json_get_bbox(&H->box, jobj); } + return 0; } /** @@ -163,22 +145,19 @@ void get_obj_params(json_object *jobj, aHole *H){ * @param getLen (o) - length of array or NULL * @return holes array */ -aHole *json_parse_holesarray(json_object *jobj, int *getLen){ - enum json_type type; - json_object *jarray = jobj; - int arraylen = json_object_array_length(jarray), i; +aHole *json_parse_holesarray(json_pair *jobj, int *getLen){ + int arraylen = jobj->len, i; + if(!arraylen || jobj->type != json_type_obj_array) return NULL; aHole *H = calloc(arraylen, sizeof(aHole)); json_object *jvalue; - for (i=0; i < arraylen; i++){ - jvalue = json_object_array_get_idx(jarray, i); - type = json_object_get_type(jvalue); - if(type == json_type_object){ - get_obj_params(jvalue, &H[i]); - }else{ - ERRX(_("Invalid holes array format!\n")); - } + for (i = 0; i < arraylen; i++){ + jvalue = json_array_get_object(jobj, i); + if(!jvalue) break; + if(get_obj_params(jvalue, &H[i])) + ERRX(_("Invalid format for hole #%d!\n"), i); + json_free_obj(&jvalue); } - if(getLen) *getLen = arraylen; + if(getLen) *getLen = i; return H; } @@ -199,73 +178,56 @@ char *gettype(aHole *H){ } #endif -/** - * Try to mmap a file - * - * @param filename (i) - name of file to mmap - * @return pointer with mmap'ed file or die - */ -char *My_mmap(char *filename, size_t *Mlen){ - int fd; - char *ptr; - struct stat statbuf; - if(!filename) ERRX(_("No filename given!")); - if((fd = open(filename, O_RDONLY)) < 0) - ERR(_("Can't open %s for reading"), filename); - if(fstat (fd, &statbuf) < 0) - ERR(_("Can't stat %s"), filename); - *Mlen = statbuf.st_size; - if((ptr = mmap (0, *Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) - ERR(_("Mmap error for input")); - if(close(fd)) ERR(_("Can't close mmap'ed file")); - return ptr; -} - /** * Read holes array for diaphragm structure from file * * file should * * @param filename - name of file - * @return readed structure or NULL if failed + * @return read structure or NULL if failed */ aHole *readHoles(char *filename, Diaphragm *dia){ - char *ptr; - enum json_type type; - json_object *o, *jobj; - int i, HolesNum; - aHole *HolesArray; + FNAME(); + mmapbuf *map; + json_pair *o; + json_object *jobj; + int i, HolesNum = -1; + aHole *HolesArray = NULL; BBox Dbox = {100.,100.,-200.,-200.}; // bounding box of diaphragm - size_t Mlen; if(dia) memset(dia, 0, sizeof(Diaphragm)); - ptr = My_mmap(filename, &Mlen); - jobj = json_tokener_parse(ptr); + map = My_mmap(filename); + jobj = json_tokener_parse(map->data); + if(!jobj) ERRX(_("Wrong JSON file")); get_obj_params(jobj, &globHole); // read global parameters // now try to find diaphragm bounding box & Z-coordinate json_get_bbox(&Dbox, jobj); // check for Z-coordinate if(dia){ - o = json_object_object_get(jobj, "Z"); - if(!o) o = json_object_object_get(jobj, "maskz"); + o = json_object_get_pair(jobj, "Z"); + if(!o) o = json_object_get_pair(jobj, "maskz"); if(!o) ERRX(_("JSON file MUST contain floating point field \"Z\" or \"maskz\" with mask's coordinate")); dia->Z = get_jdouble(o); // read mask Z } - o = json_object_object_get(jobj, "holes"); + o = json_object_get_pair(jobj, "holes"); if(!o) ERRX(_("Corrupted file: no holes found!")); - type = json_object_get_type(o); - if(type == json_type_object){ // single hole - HolesArray = calloc(1, sizeof(aHole)); - assert(HolesArray); + if(o->type == json_type_object){ // single hole + HolesArray = MALLOC(aHole, 1); HolesNum = 1; - get_obj_params(o, HolesArray); - }else{ // array of holes + json_object *obj = json_pair_get_object(o); + if(!obj) ERRX(_("Wrong hole descriptor")); + get_obj_params(obj, HolesArray); + json_free_obj(&obj); + }else if(o->type == json_type_obj_array){ // array of holes + //DBG("array of holes"); HolesArray = json_parse_holesarray(o, &HolesNum); + }else{ + ERRX(_("Corrupted file: bad holes format!")); } if(!HolesArray || HolesNum < 1) ERRX(_("Didn't find any holes in json file!")); - DBG("Readed %d holes", HolesNum); + //DBG("Read %d holes", HolesNum); // check bbox of diafragm (or make it if none) float minx=100., miny=100., maxx=-100., maxy=-100.; for(i = 0; i < HolesNum; i++){ @@ -287,12 +249,13 @@ aHole *readHoles(char *filename, Diaphragm *dia){ if(Dbox.y0 > miny) Dbox.y0 = miny; if(Dbox.w < wdth) Dbox.w = wdth; if(Dbox.h < hght) Dbox.h = hght; - munmap(ptr, Mlen); + My_munmap(map); if(dia){ dia->holes = HolesArray; dia->Nholes = HolesNum; memcpy(&dia->box, &Dbox, sizeof(BBox)); } + json_free_obj(&jobj); return HolesArray; } diff --git a/src/include/cmdlnopts.h b/src/include/cmdlnopts.h index d8cbe51..260aa18 100644 --- a/src/include/cmdlnopts.h +++ b/src/include/cmdlnopts.h @@ -23,7 +23,7 @@ #ifndef __CMDLNOPTS_H__ #define __CMDLNOPTS_H__ -#include "parceargs.h" +#include "parseargs.h" #include "mkHartmann.h" #include "saveimg.h" @@ -32,10 +32,15 @@ typedef struct{ int S_interp; // size of interpolated S0 int S_image; // resulting image size int N_phot; // amount of photons falled to one pixel of S1 by one iteration + int N_iter; // iterations number int randMask; // add to mask random numbers float randAmp; // amplitude of added random noice + float CCDW; // CCD width + float CCDH; // and height (in millimeters) imtype it; // output image type char *dev_filename;// input deviations file name + char *holes_filename;// input holes file name + char *outfile; // output file name mirPar *Mirror; // mirror parameters } glob_pars; @@ -43,6 +48,6 @@ typedef struct{ extern glob_pars const Gdefault; extern mirPar const Mdefault; -glob_pars *parce_args(int argc, char **argv); +glob_pars *parse_args(int argc, char **argv); #endif // __CMDLNOPTS_H__ diff --git a/src/include/diaphragm.h b/src/include/diaphragm.h index 0b45367..87bce5a 100644 --- a/src/include/diaphragm.h +++ b/src/include/diaphragm.h @@ -26,6 +26,6 @@ #include "wrapper.h" aHole *readHoles(char *filename, Diaphragm *dia); -char *My_mmap(char *filename, size_t *Mlen); +//char *My_mmap(char *filename, size_t *Mlen); #endif // __DIAPHRAGM_H__ diff --git a/src/include/json.h b/src/include/json.h new file mode 100644 index 0000000..8886b67 --- /dev/null +++ b/src/include/json.h @@ -0,0 +1,64 @@ +/* + * json.h + * + * Copyright 2016 Edward V. Emelianov + * + * 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 __JSON_H__ +#define __JSON_H__ + +enum json_type{ + json_type_object, // compound object + json_type_obj_array, // array of objects + json_type_data_array, // array of data + json_type_number, // number + json_type_string // string +}; + +// JSON pair (name - value): +typedef struct{ + char *name; + char *value; + enum json_type type; + size_t len; // amount of objects in array +}json_pair; + + +typedef struct{ + size_t len; // amount of pairs + size_t max_len; // max amount of pairs + char *original_data; // contains string with data + json_pair *objs;// objects themself +}json_object; + +#define JSON_BLKSZ (128) + +// JSON object + + +json_object *json_tokener_parse(char *data); +void json_free_obj(json_object **obj); +char *json_pair_get_string(json_pair *pair); +double json_pair_get_number(json_pair *pair); +json_object *json_pair_get_object(json_pair *pair); +json_pair *json_object_get_pair(json_object *obj, char *name); +json_object *json_array_get_object(json_pair *pair, int idx); +char *json_array_get_data(json_pair *pair, int idx); + +#endif // __JSON_H__ diff --git a/src/include/mkHartmann.h b/src/include/mkHartmann.h index dd8dedd..e795bb8 100644 --- a/src/include/mkHartmann.h +++ b/src/include/mkHartmann.h @@ -61,12 +61,6 @@ #define LOCALEDIR "/usr/share/locale/" #endif -#define _(String) gettext(String) -#define gettext_noop(String) String -#define N_(String) gettext_noop(String) - -#define _U_ __attribute__((__unused__)) - #ifndef THREAD_NUMBER #define THREAD_NUMBER 2 #endif @@ -81,27 +75,6 @@ #define OMP_FOR(x) #endif // OMP -extern int globErr; -#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0) -#define ERRX(...) do{globErr=0; _WARN(__VA_ARGS__); exit(-1);}while(0) -#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0) -#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0) - -// 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 - -#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{free(ptr); ptr = NULL;}while(0) - #ifndef EXTERN // file wasn't included from CUDA.cu #define EXTERN extern #endif diff --git a/src/include/parceargs.h b/src/include/parseargs.h similarity index 73% rename from src/include/parceargs.h rename to src/include/parseargs.h index e5c2479..b8351d9 100644 --- a/src/include/parceargs.h +++ b/src/include/parseargs.h @@ -1,5 +1,5 @@ /* - * parceargs.h - headers for parcing command line arguments + * parseargs.h - headers for parsing command line arguments * * Copyright 2013 Edward V. Emelianoff * @@ -19,10 +19,11 @@ * MA 02110-1301, USA. */ #pragma once -#ifndef __PARCEARGS_H__ -#define __PARCEARGS_H__ +#ifndef __PARSEARGS_H__ +#define __PARSEARGS_H__ #include // bool +#include #ifndef TRUE #define TRUE true @@ -36,7 +37,7 @@ #define APTR(x) ((void*)x) // if argptr is a function: -typedef bool(*argfn)(void *arg, int N); +typedef bool(*argfn)(void *arg); /* * type of getopt's argument @@ -47,7 +48,7 @@ typedef bool(*argfn)(void *arg, int N); * int iarg; * myoption opts[] = { * {"value", 1, NULL, 'v', arg_int, &iarg, "char val"}, ..., end_option}; - * ..(parce args).. + * ..(parse args).. * charg = (char) iarg; */ typedef enum { @@ -57,7 +58,7 @@ typedef enum { arg_double, // double arg_float, // float arg_string, // char * - arg_function // parce_args will run function `bool (*fn)(char *optarg, int N)` + arg_function // parse_args will run function `bool (*fn)(char *optarg, int N)` } argtype; /* @@ -66,7 +67,7 @@ typedef enum { * conversion depends on .type * * ATTENTION: string `help` prints through macro PRNT(), bu default it is gettext, - * but you can redefine it before `#include "parceargs.h"` + * but you can redefine it before `#include "parseargs.h"` * * if arg is string, then value wil be strdup'ed like that: * char *str; @@ -79,26 +80,45 @@ typedef enum { * !!!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 - int has_arg; // 0 - no args, 1 - nesessary arg, 2 - optionally arg + 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)` - char *help; // help string which would be shown in function `showhelp` or NULL + 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 parceargs(int *argc, char ***argv, myoption *options); +void parseargs(int *argc, char ***argv, myoption *options); void change_helpstring(char *s); +bool get_suboption(char *str, mysuboption *opt); -#endif // __PARCEARGS_H__ +#endif // __PARSEARGS_H__ diff --git a/src/include/usefull_macros.h b/src/include/usefull_macros.h new file mode 100644 index 0000000..6fdf849 --- /dev/null +++ b/src/include/usefull_macros.h @@ -0,0 +1,124 @@ +/* + * usefull_macros.h - a set of usefull macros: memory, color etc + * + * Copyright 2013 Edward V. Emelianoff + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined GETTEXT_PACKAGE && defined LOCALEDIR +/* + * GETTEXT + */ +#include +#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 +#include +#include +#include +#include +#include + + +// 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" + +/* + * 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) + +double dtime(); + +// pointers to 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); + +#endif // __USEFULL_MACROS_H__ diff --git a/src/json.c b/src/json.c new file mode 100644 index 0000000..6eb966e --- /dev/null +++ b/src/json.c @@ -0,0 +1,361 @@ +/* + * json.c - simple JSON parser + * + * Copyright 2016 Edward V. Emelianov + * + * 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 "json.h" + +/** + * don't understand hex and octal numbers + * don't understand mixed arrays + */ + +static json_object *json_collect(char *data); + +static char *skipspaces(char *data){ + while(*data){ + char ch = *data; + switch (ch){ + case '\r': case '\n': case '\t': case ' ': + ++data; + break; + default: + goto ret; + } + } +ret: + return data; +} + +static json_object *json_ini(){ + json_object *ret = MALLOC(json_object, 1); + ret->objs = MALLOC(json_pair, JSON_BLKSZ); + ret->max_len = JSON_BLKSZ; ret->len = 0; + return ret; +} + +void json_free_obj(json_object **obj){ + FREE((*obj)->objs); + FREE((*obj)->original_data); + FREE(*obj); +} + +/** + * find end of compound object & set last brace to zero + * @return first symbol after object's end + */ +static char *find_obj_end(char *data){ + int opening = 0; + while(*data && opening != -1){ + switch(*data++){ + case '{': + ++opening; + break; + case '}': + --opening; + break; + default: break; + } + } + if(opening != -1) return NULL; + data[-1] = 0; + return data; +} + +/** + * count objects in array + * @return first symbol after array's end + */ +static char *count_objs(json_pair *pair){ + int a_closing = 0, o_opening = 0, commas = 0, objects = 0, valstart = 1, values = 0; // counts ']' & '{', ',' & objects + char *data = pair->value; + if(!data) return NULL; + while(*data && a_closing != 1){ + switch(*data++){ + case '{': + ++o_opening; valstart = 0; + break; + case '}': + if(--o_opening == 0) ++objects; + break; + case '[': + --a_closing; + break; + case ']': + ++a_closing; + break; + case ',': + if(o_opening == 0){ + ++commas; // count commas separating objects + valstart = 1; + } + break; + case '\t': case '\n': case '\r': case ' ': + break; + default: + if(valstart) ++values; + valstart = 0; + break; + } + } + if(a_closing != 1) return NULL; + //DBG("find array with %d objects & %d values, commas: %d", objects, values, commas); + if((objects && commas < objects-1) || (values && commas < values-1)) return NULL; // delimeter omit + if(objects && values) return NULL; // mixed array + pair->len = objects + values; + data[-1] = 0; + pair->type = objects ? json_type_obj_array : json_type_data_array; + return data; +} + +/** + * skip '.', numbers, signs & '[e|E]' + * return first non-number + */ +static char *skipnumbers(char *data){ + while(*data){ + char ch = *data; + if(ch < '0' || ch > '9'){ + if(ch != '.' && ch != 'e' && ch != 'E' && ch != '-' && ch !='+') + break; + } + ++data; + } + return data; +} + +/** + * read and add object from string + */ +int json_add_object(json_object *obj, char **data){ + //FNAME(); + if(!obj || !data || !*data || !**data) return 0; + char *str = skipspaces(*data); + json_pair pair; + memset(&pair, 0, sizeof(pair)); + if(*str == '}') return 0; // no objects + if(*str != '"') return -1; // err - not an object's name + char *eptr = strchr(++str, '"'); + if(!eptr) return -1; + *eptr = 0; + pair.name = str; + str = eptr + 1; + str = skipspaces(str); + if(*str != ':') return -1; // no delimeter + str = skipspaces(str+1); + if(*str == '"'){ // string + pair.type = json_type_string; + pair.value = ++str; + eptr = strchr(str, '"'); + if(!eptr) return -1; + *eptr = 0; + str = eptr + 1; + }else if(*str == '{'){ // compound object + pair.type = json_type_object; + pair.value = skipspaces(++str); + str = find_obj_end(pair.value); + }else if(*str == '['){ // array + pair.value = skipspaces(++str); + str = count_objs(&pair); + }else{ // number ? + pair.type = json_type_number; + pair.value = str; + str = skipnumbers(str); + if(pair.value == str) return -1; // not a number + } + // skip comma & spaces, but leave '}' & add object + if(!str) return -1; + str = skipspaces(str); + //DBG("char: %c", *str); + int meetcomma = 0; + if(*str == ','){ + *str++ = 0; + meetcomma = 1; + str = skipspaces(str); + } + if(*str == '}') --str; + else if(!meetcomma && *str) return -1; + *data = str; + // add pair + if(obj->len == obj->max_len){ // no space left - realloc + obj->max_len += JSON_BLKSZ; + obj->objs = realloc(obj->objs, sizeof(json_pair)*obj->max_len); + if(!obj->objs) return -1; + } + memcpy(&(obj->objs[obj->len]), &pair, sizeof(json_pair)); + ++obj->len; +/* + #ifdef EBUG + fprintf(stderr, "pair %zd, nm: %s, val: %s, type: %d", obj->len, pair.name, pair.value, pair.type); + if(pair.len) fprintf(stderr, "; array length: %zd", pair.len); + fprintf(stderr, "\n"); + #endif + */ + return 1; +} + + +static json_object *json_collect(char *data){ + //FNAME(); + json_object *ret = json_ini(); + ret->original_data = strdup(data); + data = skipspaces(ret->original_data); + int r; + while((r = json_add_object(ret, &data)) > 0); + if(r < 0) goto errjson; + return ret; +errjson: + json_free_obj(&ret); + return NULL; +} + +/** + * get global object + */ +json_object *json_tokener_parse(char *data){ + data = skipspaces(data); + if(*data != '{') return NULL; + data = strdup(data+1); + if(!data) return NULL; + if(!find_obj_end(data)){ + free(data); + return NULL; + } + json_object *jobj = json_collect(data); + free(data); + return jobj; +} + +/** + * return double value of number pair + */ +double json_pair_get_number(json_pair *pair){ + if(pair->type != json_type_number) return 0.; + char *endptr; + return strtod(pair->value, &endptr); +} +/** + * return string value of string pair + */ +char *json_pair_get_string(json_pair *pair){ + if(pair->type != json_type_string) return NULL; + return pair->value; +} +/** + * create object from compound pair + */ +json_object *json_pair_get_object(json_pair *pair){ + if(pair->type != json_type_object) return NULL; + return json_collect(pair->value); +} + +/** + * find pair with name @name + */ +json_pair *json_object_get_pair(json_object *obj, char *name){ + //DBG("search pair named %s", name); + if(!obj || !name) return NULL; + json_pair *pairs = obj->objs; + size_t i, L = obj->len; + for(i = 0; i < L; ++i){ + if(strcmp(name, pairs[i].name) == 0){ + //DBG("Find, val = %s", pairs[i].value); + return &pairs[i]; + } + } + return NULL; +} + +/** + * return new object with index idx from array + */ +json_object *json_array_get_object(json_pair *pair, int idx){ + //DBG("get %d object from array type %d, len %zd", idx, pair->type, pair->len); + if(pair->type != json_type_obj_array) return NULL; + if(pair->len < 1 || idx > pair->len) return NULL; + int opening = 0, curidx = 0; + char *data = pair->value, *start = NULL; + json_object *obj = NULL; + while(*data && curidx <= idx){ + switch(*data++){ + case '{': + if(++opening == 1 && curidx == idx) start = data; + break; + case '}': + if(--opening == 0){ + ++curidx; + if(start){ // found + data[-1] = 0; + obj = json_collect(start); + //DBG("found data with idx %d, val: %s", idx, start); + data[-1] = '}'; + } + } + break; + default: break; + } + } + if(!start || opening || !obj->original_data){ + json_free_obj(&obj); + return NULL; + } + return obj; +} + +/** + * return allocated memory - must be free'd + * @return - string with data + */ +char *json_array_get_data(json_pair *pair, int idx){ + if(pair->type != json_type_data_array) return NULL; + if(pair->len < 1 || idx > pair->len) return NULL; + char *data = pair->value, *eptr, *val = NULL; + int curidx = 0; + while(*data && curidx <= idx){ + data = skipspaces(data); + char ch = *data; + if(!ch) return NULL; + if(ch != ','){ + if(curidx == idx){ + if(ch == '"'){ // string + eptr = strchr(++data, '"'); + if(!eptr) return NULL; + *eptr = 0; + val = strdup(data); + *eptr = '"'; + return val; + }else{ // number + eptr = skipnumbers(data); + if(!eptr || eptr == data) return NULL; + char oldval = *eptr; + *eptr = 0; val = strdup(data); + *eptr = oldval; + return val; + } + }else data = strchr(data, ','); + }else{ + do{ + data = skipspaces(data+1); + }while(*data == ','); + ++curidx; + } + } + return NULL; +} diff --git a/src/locale/ru/messages.po b/src/locale/ru/messages.po index 3ddd56b..4c86ece 100644 --- a/src/locale/ru/messages.po +++ b/src/locale/ru/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-04-02 17:54+0400\n" +"POT-Creation-Date: 2016-06-01 13:49+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,187 +17,244 @@ msgstr "" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8bit\n" -#: mkHartmann.c:168 +#. amount of pcount and/or scount wrong +#. / "Неправильный формат строки помощи" +#: parseargs.c:56 +msgid "Wrong helpstring!" +msgstr "" + +#. / "Целое вне допустимого диапазона" +#: parseargs.c:86 +msgid "Integer out of range" +msgstr "" + +#. / "Неправильный параметр: %s" +#: parseargs.c:480 +#, c-format +msgid "Wrong parameter: %s" +msgstr "" + +#. / "%s: необходим аргумент!" +#: parseargs.c:485 +#, c-format +msgid "%s: argument needed!" +msgstr "" + +#. / "Неправильный аргумент \"%s\" параметра \"%s\"" +#: parseargs.c:490 +#, c-format +msgid "Wrong argument \"%s\" of parameter \"%s\"" +msgstr "" + +#: mkHartmann.c:69 #, c-format msgid "Can't write to %s" msgstr "" #. file not exist but some error occured -#: mkHartmann.c:172 diaphragm.c:216 +#: mkHartmann.c:73 usefull_macros.c:177 #, c-format msgid "Can't stat %s" msgstr "" -#: mkHartmann.c:178 +#: mkHartmann.c:79 msgid "No output filename given" msgstr "" -#: mkHartmann.c:185 +#: mkHartmann.c:86 #, c-format msgid "Can't open file %s" msgstr "" -#: mkHartmann.c:199 +#: mkHartmann.c:102 #, c-format msgid "Can't close file %s" msgstr "" -#: mkHartmann.c:229 +#: mkHartmann.c:134 msgid "Wrong file: should be matrix of float data separated by spaces" msgstr "" #. update old width counter #. check it -#: mkHartmann.c:237 +#: mkHartmann.c:142 msgid "All rows must contain equal number of columns" msgstr "" -#: mkHartmann.c:243 +#: mkHartmann.c:148 msgid "Matrix must be square" msgstr "" -#: mkHartmann.c:254 -msgid "Input file was modified in runtime!" +#: mkHartmann.c:156 +msgid "File modified in runtime?" msgstr "" -#: mkHartmann.c:259 +#: mkHartmann.c:163 #, c-format -msgid "Error reading data: read %d numbers instaed of %d" +msgid "Error reading data: read %d numbers instead of %d" msgstr "" #. / "Не могу построить матрицу случайных чисел" -#: mkHartmann.c:316 +#: mkHartmann.c:211 msgid "Can't build random matrix" msgstr "" -#: mkHartmann.c:323 +#: mkHartmann.c:221 msgid "Can't build mirror dZ arrays" msgstr "" -#: diaphragm.c:44 -msgid "Wrong value! Get non-number!\n" -msgstr "" - -#. nested arrays is error -#: diaphragm.c:68 -msgid "Invalid file format! Found nested arrays!\n" -msgstr "" - -#. non-numerical data? -#: diaphragm.c:74 -msgid "Invalid file format! Non-numerical data in array!\n" -msgstr "" - -#: diaphragm.c:95 -msgid "\"bbox\" must contain an array of four doubles!\n" -msgstr "" - -#: diaphragm.c:112 -msgid "Error: NULL instead of aHole structure!\n" -msgstr "" - -#: diaphragm.c:130 -msgid "\"radius\" array must consist of two doubles!\n" -msgstr "" - -#: diaphragm.c:135 -msgid "\"radius\" must be a number or an array of two doubles!\n" -msgstr "" - -#: diaphragm.c:141 -msgid "\"center\" must contain an array of two doubles!\n" -msgstr "" - -#: diaphragm.c:178 -msgid "Invalid holes array format!\n" -msgstr "" - -#: diaphragm.c:212 +#: usefull_macros.c:173 msgid "No filename given!" msgstr "" -#: diaphragm.c:214 +#: usefull_macros.c:175 #, c-format msgid "Can't open %s for reading" msgstr "" -#: diaphragm.c:219 +#: usefull_macros.c:180 msgid "Mmap error for input" msgstr "" -#: diaphragm.c:220 +#: usefull_macros.c:181 msgid "Can't close mmap'ed file" msgstr "" -#: diaphragm.c:251 +#: usefull_macros.c:190 +msgid "Can't munmap" +msgstr "" + +#: usefull_macros.c:214 +msgid "Can't setup console" +msgstr "" + +#. Get settings +#: usefull_macros.c:283 +msgid "Can't get settings" +msgstr "" + +#: usefull_macros.c:293 +msgid "Can't set settings" +msgstr "" + +#: diaphragm.c:35 +msgid "Wrong value! Get non-number!\n" +msgstr "" + +#: diaphragm.c:79 +msgid "\"bbox\" must contain an array of four doubles!\n" +msgstr "" + +#: diaphragm.c:98 +msgid "Error: NULL instead of aHole structure!\n" +msgstr "" + +#: diaphragm.c:104 +msgid "Wrong \"shape\" value" +msgstr "" + +#: diaphragm.c:118 +msgid "\"radius\" array must consist of two doubles!\n" +msgstr "" + +#: diaphragm.c:123 +msgid "\"radius\" must be a number or an array of two doubles!\n" +msgstr "" + +#: diaphragm.c:130 +msgid "\"center\" must contain an array of two doubles!\n" +msgstr "" + +#: diaphragm.c:157 +#, c-format +msgid "Invalid format for hole #%d!\n" +msgstr "" + +#: diaphragm.c:200 +msgid "Wrong JSON file" +msgstr "" + +#: diaphragm.c:209 msgid "" "JSON file MUST contain floating point field \"Z\" or \"maskz\" with mask's " "coordinate" msgstr "" -#: diaphragm.c:256 +#: diaphragm.c:214 msgid "Corrupted file: no holes found!" msgstr "" -#: diaphragm.c:267 +#: diaphragm.c:219 +msgid "Wrong hole descriptor" +msgstr "" + +#: diaphragm.c:226 +msgid "Corrupted file: bad holes format!" +msgstr "" + +#: diaphragm.c:229 msgid "Didn't find any holes in json file!" msgstr "" #. / "Приложение скомпилировано без поддержки CUDA" -#: wrapper.c:39 wrapper.c:48 wrapper.c:58 +#: wrapper.c:41 wrapper.c:50 wrapper.c:60 msgid "Tool was compiled without CUDA support" msgstr "" #. / "В вычислениях по возможности будет использоваться GPU\n" -#: wrapper.c:74 +#: wrapper.c:68 msgid "In computations will try to use GPU\n" msgstr "" #. / "Ошибка получения свойств видеоядра" -#: wrapper.c:79 +#: wrapper.c:73 msgid "Can't get properties" msgstr "" #. / "Ошибка определения доступной памяти" -#: wrapper.c:81 +#: wrapper.c:75 msgid "Can't determine free memory" msgstr "" #. / "Ошибка выделения памяти" -#: wrapper.c:83 +#: wrapper.c:77 msgid "Can't allocate memory" msgstr "" +#: wrapper.c:91 +msgid "Can't run CUDA!" +msgstr "" + #. / "Ошибка в инициализации CUDA!" -#: wrapper.c:99 +#: wrapper.c:94 msgid "Error in CUDA initialisation!" msgstr "" #. / "ПАМЯТЬ: свободная = " -#: wrapper.c:103 +#: wrapper.c:98 #, c-format msgid "MEMORY: free = " msgstr "" #. / " суммарная = " -#: wrapper.c:106 +#: wrapper.c:101 #, c-format msgid " total= " msgstr "" #. / "В вычислениях используется только CPU\n" -#: wrapper.c:112 +#: wrapper.c:122 msgid "Will use only CPU in computations\n" msgstr "" #. / "Тест выделения 100МБ памяти пройден успешно\n" -#: wrapper.c:120 +#: wrapper.c:133 #, c-format msgid "Allocation test for 100MB of memory passed\n" msgstr "" #. / "\n\nВсе тесты пройдены успешно" -#: wrapper.c:123 +#: wrapper.c:136 msgid "" "\n" "\n" @@ -205,19 +262,19 @@ msgid "" msgstr "" #. / "Не могу открыть" -#: wrapper.c:154 +#: wrapper.c:155 msgid "Can't open" msgstr "" #. / "Не могу прочесть" -#: wrapper.c:159 +#: wrapper.c:160 msgid "Can't read" msgstr "" -#: cmdlnopts.c:77 +#: cmdlnopts.c:84 msgid "" -"set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:Ao=ang:" -"Zo=ang:C=num]\n" +"set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:Aobj=ang:" +"Zoobj=ang:CCD=num]\n" "\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like -10m13.4 !\n" "\t\tdiam - diameter of mirror\n" "\t\tfoc - mirror focus ratio\n" @@ -228,77 +285,101 @@ msgid "" "\t\tccd - Z-coordinate of light receiver" msgstr "" -#: cmdlnopts.c:89 +#: cmdlnopts.c:96 msgid "show this help" msgstr "" -#: cmdlnopts.c:90 +#: cmdlnopts.c:97 msgid "size of initial array of surface deviations" msgstr "" -#: cmdlnopts.c:91 +#: cmdlnopts.c:98 msgid "size of interpolated array of surface deviations" msgstr "" -#: cmdlnopts.c:92 +#: cmdlnopts.c:99 msgid "resulting image size" msgstr "" -#: cmdlnopts.c:93 +#: cmdlnopts.c:100 msgid "amount of photons falled to one pixel of matrix by one iteration" msgstr "" -#: cmdlnopts.c:95 +#: cmdlnopts.c:102 msgid "add random noice to mirror surface deviations" msgstr "" -#: cmdlnopts.c:96 +#: cmdlnopts.c:103 msgid "amplitude of random noice (default: 1e-8)" msgstr "" -#: cmdlnopts.c:97 +#: cmdlnopts.c:104 msgid "filename for mirror surface deviations (in microns!)" msgstr "" -#: cmdlnopts.c:98 +#: cmdlnopts.c:105 msgid "rewrite output file if exists" msgstr "" -#: cmdlnopts.c:99 +#: cmdlnopts.c:106 msgid "save matrices to file arg" msgstr "" -#: cmdlnopts.c:100 +#: cmdlnopts.c:107 msgid "print matrices on screen" msgstr "" -#: cmdlnopts.c:101 +#: cmdlnopts.c:108 msgid "save intermediate results to images" msgstr "" -#: cmdlnopts.c:102 +#: cmdlnopts.c:109 msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)" msgstr "" -#: cmdlnopts.c:119 +#: cmdlnopts.c:110 +msgid "name of JSON file with holes description" +msgstr "" + +#: cmdlnopts.c:111 +msgid "amount of iterations by N-photons" +msgstr "" + +#: cmdlnopts.c:112 +msgid "CCD width (in millimeters)" +msgstr "" + +#: cmdlnopts.c:113 +msgid "CCD height (in millimeters)" +msgstr "" + +#: cmdlnopts.c:114 +msgid "output image file name" +msgstr "" + +#: cmdlnopts.c:115 +msgid "force CPU using iven if have videocard" +msgstr "" + +#: cmdlnopts.c:132 msgid "Wrong float number format!" msgstr "" -#: cmdlnopts.c:147 +#: cmdlnopts.c:160 msgid "Degrees should be less than 360" msgstr "" #. wrong format -#: cmdlnopts.c:193 +#: cmdlnopts.c:206 msgid "Wrong format: no value for keyword" msgstr "" #. nothing found - wrong format -#: cmdlnopts.c:213 +#: cmdlnopts.c:226 msgid "Bad keyword!" msgstr "" -#: cmdlnopts.c:294 +#: cmdlnopts.c:307 #, c-format msgid "Wrong format of image type: %c" msgstr "" diff --git a/src/locale/ru/ru.po b/src/locale/ru/ru.po index 7c669ab..3dee871 100644 --- a/src/locale/ru/ru.po +++ b/src/locale/ru/ru.po @@ -6,7 +6,7 @@ msgid "" msgstr "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2013-04-02 16:58+0400\n" + "POT-Creation-Date: 2016-06-01 13:48+0300\n" "PO-Revision-Date: 2013-01-14 18:49+0400\n" "Last-Translator: Edward V. Emelianov \n" "Language-Team: LANGUAGE \n" @@ -16,7 +16,7 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n" "Content-Transfer-Encoding: 8bit\n" #. / "\n\nВсе тесты пройдены успешно" -#: wrapper.c:123 +#: wrapper.c:136 #, fuzzy msgid "\n" "\n" @@ -27,260 +27,344 @@ msgstr "\n" "\n" #. / " суммарная = " -#: wrapper.c:106 +#: wrapper.c:101 #, c-format msgid " total= " msgstr " суммарная = " -#: diaphragm.c:95 +#: diaphragm.c:79 msgid "\"bbox\" must contain an array of four doubles!\n" msgstr "" -#: diaphragm.c:141 +#: diaphragm.c:130 msgid "\"center\" must contain an array of two doubles!\n" msgstr "" -#: diaphragm.c:130 +#: diaphragm.c:118 msgid "\"radius\" array must consist of two doubles!\n" msgstr "" -#: diaphragm.c:135 +#: diaphragm.c:123 msgid "\"radius\" must be a number or an array of two doubles!\n" msgstr "" +#. / "%s: необходим аргумент!" +#: parseargs.c:485 +#, c-format +msgid "%s: argument needed!" +msgstr "" + #. update old width counter #. check it -#: mkHartmann.c:237 +#: mkHartmann.c:142 msgid "All rows must contain equal number of columns" msgstr "" #. / "Тест выделения 100МБ памяти пройден успешно\n" -#: wrapper.c:120 +#: wrapper.c:133 #, c-format msgid "Allocation test for 100MB of memory passed\n" msgstr "Тест выделения 100МБ памяти пройден успешно\n" #. nothing found - wrong format -#: cmdlnopts.c:213 +#: cmdlnopts.c:226 msgid "Bad keyword!" msgstr "" +#: cmdlnopts.c:113 +msgid "CCD height (in millimeters)" +msgstr "" + +#: cmdlnopts.c:112 +msgid "CCD width (in millimeters)" +msgstr "" + #. / "Ошибка выделения памяти" -#: wrapper.c:83 +#: wrapper.c:77 msgid "Can't allocate memory" msgstr "Ошибка выделения памяти" -#: mkHartmann.c:323 +#: mkHartmann.c:221 msgid "Can't build mirror dZ arrays" msgstr "" #. / "Не могу построить матрицу случайных чисел" -#: mkHartmann.c:316 +#: mkHartmann.c:211 msgid "Can't build random matrix" msgstr "" -#: mkHartmann.c:199 +#: mkHartmann.c:102 #, c-format msgid "Can't close file %s" msgstr "" -#: diaphragm.c:220 +#: usefull_macros.c:181 msgid "Can't close mmap'ed file" msgstr "" #. / "Ошибка определения доступной памяти" -#: wrapper.c:81 +#: wrapper.c:75 msgid "Can't determine free memory" msgstr "Ошибка определения доступной памяти" #. / "Ошибка получения свойств видеоядра" -#: wrapper.c:79 +#: wrapper.c:73 msgid "Can't get properties" msgstr "Ошибка получения свойств видеоядра" +#. Get settings +#: usefull_macros.c:283 +#, fuzzy +msgid "Can't get settings" +msgstr "Ошибка получения свойств видеоядра" + +#: usefull_macros.c:190 +#, fuzzy +msgid "Can't munmap" +msgstr "Ошибка получения свойств видеоядра" + #. / "Не могу открыть" -#: wrapper.c:154 +#: wrapper.c:155 #, fuzzy msgid "Can't open" msgstr "Ошибка получения свойств видеоядра" -#: diaphragm.c:214 +#: usefull_macros.c:175 #, c-format msgid "Can't open %s for reading" msgstr "" -#: mkHartmann.c:185 +#: mkHartmann.c:86 #, fuzzy, c-format msgid "Can't open file %s" msgstr "Ошибка получения свойств видеоядра" #. / "Не могу прочесть" -#: wrapper.c:159 +#: wrapper.c:160 msgid "Can't read" msgstr "" +#: wrapper.c:91 +msgid "Can't run CUDA!" +msgstr "" + +#: usefull_macros.c:293 +#, fuzzy +msgid "Can't set settings" +msgstr "Ошибка получения свойств видеоядра" + +#: usefull_macros.c:214 +msgid "Can't setup console" +msgstr "" + #. file not exist but some error occured -#: mkHartmann.c:172 diaphragm.c:216 +#: mkHartmann.c:73 usefull_macros.c:177 #, c-format msgid "Can't stat %s" msgstr "" -#: mkHartmann.c:168 +#: mkHartmann.c:69 #, c-format msgid "Can't write to %s" msgstr "" -#: diaphragm.c:256 +#: diaphragm.c:226 +msgid "Corrupted file: bad holes format!" +msgstr "" + +#: diaphragm.c:214 msgid "Corrupted file: no holes found!" msgstr "" -#: cmdlnopts.c:147 +#: cmdlnopts.c:160 msgid "Degrees should be less than 360" msgstr "" -#: diaphragm.c:267 +#: diaphragm.c:229 msgid "Didn't find any holes in json file!" msgstr "" #. / "Ошибка в инициализации CUDA!" -#: wrapper.c:99 +#: wrapper.c:94 msgid "Error in CUDA initialisation!" msgstr "Ошибка в инициализации CUDA!" -#: mkHartmann.c:259 +#: mkHartmann.c:163 #, c-format -msgid "Error reading data: read %d numbers instaed of %d" +msgid "Error reading data: read %d numbers instead of %d" msgstr "" -#: diaphragm.c:112 +#: diaphragm.c:98 msgid "Error: NULL instead of aHole structure!\n" msgstr "" +#: mkHartmann.c:156 +msgid "File modified in runtime?" +msgstr "" + #. / "В вычислениях по возможности будет использоваться GPU\n" -#: wrapper.c:74 +#: wrapper.c:68 msgid "In computations will try to use GPU\n" msgstr "В вычислениях по возможности будет использоваться GPU\n" -#: mkHartmann.c:254 -msgid "Input file was modified in runtime!" +#. / "Целое вне допустимого диапазона" +#: parseargs.c:86 +msgid "Integer out of range" msgstr "" -#. nested arrays is error -#: diaphragm.c:68 -msgid "Invalid file format! Found nested arrays!\n" +#: diaphragm.c:157 +#, c-format +msgid "Invalid format for hole #%d!\n" msgstr "" -#. non-numerical data? -#: diaphragm.c:74 -msgid "Invalid file format! Non-numerical data in array!\n" -msgstr "" - -#: diaphragm.c:178 -msgid "Invalid holes array format!\n" -msgstr "" - -#: diaphragm.c:251 +#: diaphragm.c:209 msgid "JSON file MUST contain floating point field \"Z\" or \"maskz\" with " "mask's coordinate" msgstr "" #. / "ПАМЯТЬ: свободная = " -#: wrapper.c:103 +#: wrapper.c:98 #, c-format msgid "MEMORY: free = " msgstr "ПАМЯТЬ: свободная = " -#: mkHartmann.c:243 +#: mkHartmann.c:148 msgid "Matrix must be square" msgstr "" -#: diaphragm.c:219 +#: usefull_macros.c:180 msgid "Mmap error for input" msgstr "" -#: diaphragm.c:212 +#: usefull_macros.c:173 msgid "No filename given!" msgstr "" -#: mkHartmann.c:178 +#: mkHartmann.c:79 msgid "No output filename given" msgstr "" #. / "Приложение скомпилировано без поддержки CUDA" -#: wrapper.c:39 wrapper.c:48 wrapper.c:58 +#: wrapper.c:41 wrapper.c:50 wrapper.c:60 msgid "Tool was compiled without CUDA support" msgstr "" #. / "В вычислениях используется только CPU\n" -#: wrapper.c:112 +#: wrapper.c:122 msgid "Will use only CPU in computations\n" msgstr "В вычислениях используется только CPU\n" -#: mkHartmann.c:229 +#: diaphragm.c:104 +msgid "Wrong \"shape\" value" +msgstr "" + +#: diaphragm.c:200 +msgid "Wrong JSON file" +msgstr "" + +#. / "Неправильный аргумент \"%s\" параметра \"%s\"" +#: parseargs.c:490 +#, c-format +msgid "Wrong argument \"%s\" of parameter \"%s\"" +msgstr "" + +#: mkHartmann.c:134 msgid "Wrong file: should be matrix of float data separated by spaces" msgstr "" -#: cmdlnopts.c:119 +#: cmdlnopts.c:132 msgid "Wrong float number format!" msgstr "" -#: cmdlnopts.c:294 +#: cmdlnopts.c:307 #, c-format msgid "Wrong format of image type: %c" msgstr "" #. wrong format -#: cmdlnopts.c:193 +#: cmdlnopts.c:206 msgid "Wrong format: no value for keyword" msgstr "" -#: diaphragm.c:44 +#. amount of pcount and/or scount wrong +#. / "Неправильный формат строки помощи" +#: parseargs.c:56 +msgid "Wrong helpstring!" +msgstr "" + +#: diaphragm.c:219 +msgid "Wrong hole descriptor" +msgstr "" + +#. / "Неправильный параметр: %s" +#: parseargs.c:480 +#, c-format +msgid "Wrong parameter: %s" +msgstr "" + +#: diaphragm.c:35 msgid "Wrong value! Get non-number!\n" msgstr "" -#: cmdlnopts.c:95 +#: cmdlnopts.c:102 msgid "add random noice to mirror surface deviations" msgstr "" -#: cmdlnopts.c:93 -msgid "amount of photons falled to one pixel of matrix by one iteration" -msgstr "" - -#: cmdlnopts.c:96 -msgid "amplitude of random noice (default: 1e-8)" -msgstr "" - -#: cmdlnopts.c:97 -msgid "filename for mirror surface deviations (in microns!)" -msgstr "" - -#: cmdlnopts.c:102 -msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)" +#: cmdlnopts.c:111 +msgid "amount of iterations by N-photons" msgstr "" #: cmdlnopts.c:100 +msgid "amount of photons falled to one pixel of matrix by one iteration" +msgstr "" + +#: cmdlnopts.c:103 +msgid "amplitude of random noice (default: 1e-8)" +msgstr "" + +#: cmdlnopts.c:104 +msgid "filename for mirror surface deviations (in microns!)" +msgstr "" + +#: cmdlnopts.c:115 +msgid "force CPU using iven if have videocard" +msgstr "" + +#: cmdlnopts.c:109 +msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)" +msgstr "" + +#: cmdlnopts.c:110 +msgid "name of JSON file with holes description" +msgstr "" + +#: cmdlnopts.c:114 +msgid "output image file name" +msgstr "" + +#: cmdlnopts.c:107 msgid "print matrices on screen" msgstr "" -#: cmdlnopts.c:92 +#: cmdlnopts.c:99 msgid "resulting image size" msgstr "" -#: cmdlnopts.c:98 +#: cmdlnopts.c:105 msgid "rewrite output file if exists" msgstr "" -#: cmdlnopts.c:101 +#: cmdlnopts.c:108 msgid "save intermediate results to images" msgstr "" -#: cmdlnopts.c:99 +#: cmdlnopts.c:106 msgid "save matrices to file arg" msgstr "" -#: cmdlnopts.c:77 +#: cmdlnopts.c:84 msgid "set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:" - "Ao=ang:Zo=ang:C=num]\n" + "Aobj=ang:Zoobj=ang:CCD=num]\n" "\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like " "-10m13.4 !\n" "\t\tdiam - diameter of mirror\n" @@ -292,14 +376,14 @@ msgid "set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:" "\t\tccd - Z-coordinate of light receiver" msgstr "" -#: cmdlnopts.c:89 +#: cmdlnopts.c:96 msgid "show this help" msgstr "" -#: cmdlnopts.c:90 +#: cmdlnopts.c:97 msgid "size of initial array of surface deviations" msgstr "" -#: cmdlnopts.c:91 +#: cmdlnopts.c:98 msgid "size of interpolated array of surface deviations" msgstr "" diff --git a/src/locale/ru/ru.po~ b/src/locale/ru/ru.po~ index a8febaf..d47b75c 100644 --- a/src/locale/ru/ru.po~ +++ b/src/locale/ru/ru.po~ @@ -3,299 +3,745 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # +#, fuzzy msgid "" msgstr "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2013-04-02 16:46+0400\n" - "PO-Revision-Date: 2013-01-14 18:49+0400\n" - "Last-Translator: Edward V. Emelianov \n" + "POT-Creation-Date: 2015-05-05 10:39+0300\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" - "Language: Russian\n" + "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8bit\n" + "#-#-#-#-# ru.po (PACKAGE VERSION) #-#-#-#-#\n" + "#-#-#-#-# ruru.po (PACKAGE VERSION) #-#-#-#-#\n" -#. / "\n\nВсе тесты пройдены успешно" -#: wrapper.c:123 -#, fuzzy +#. "\tОпции:\n" +#: usage.c:128 +#, c-format +msgid "\tOptions:\n" +msgstr "\tОпции:\n" + +#. "Обнаружен работающий процесс (pid=%d), выход.\n" +#: takepic.c:222 takepic.c:234 +#, c-format msgid "\n" - "\n" - "All tests succeed" + "Found running process (pid=%d), exit.\n" msgstr "\n" - "\n" - "Все тесты пройдены успешно\n" - "\n" + "Обнаружен работающий процесс (pid=%d), выход.\n" -#. / " суммарная = " -#: wrapper.c:106 +#. "\nЗатвор " +#: takepic.c:409 #, c-format -msgid " total= " -msgstr " суммарная = " +msgid "\n" + "The shutter is " +msgstr "\n" + "Затвор " -#: diaphragm.c:95 -msgid "\"bbox\" must contain an array of four doubles!\n" -msgstr "" - -#: diaphragm.c:141 -msgid "\"center\" must contain an array of two doubles!\n" -msgstr "" - -#: diaphragm.c:130 -msgid "\"radius\" array must consist of two doubles!\n" -msgstr "" - -#: diaphragm.c:135 -msgid "\"radius\" must be a number or an array of two doubles!\n" -msgstr "" - -#. update old width counter -#. check it -#: mkHartmann.c:237 -msgid "All rows must contain equal number of columns" -msgstr "" - -#. / "Тест выделения 100МБ памяти пройден успешно\n" -#: wrapper.c:120 +#. "%d секунд до окончания паузы\n" +#: takepic.c:658 #, c-format -msgid "Allocation test for 100MB of memory passed\n" -msgstr "Тест выделения 100МБ памяти пройден успешно\n" +msgid "%d seconds till pause ends\n" +msgstr "%d секунд до окончания паузы\n" -#. nothing found - wrong format -#: cmdlnopts.c:213 -msgid "Bad keyword!" -msgstr "" +#. "Не введено никаких параметров" +#: usage.c:311 +msgid "Any parameters are absent" +msgstr "Не введено никаких параметров" -#. / "Ошибка выделения памяти" -#: wrapper.c:83 -msgid "Can't allocate memory" -msgstr "Ошибка выделения памяти" - -#. / "Не могу построить матрицу случайных чисел" -#: mkHartmann.c:317 -msgid "Can't build random matrix" -msgstr "" - -#: mkHartmann.c:199 +#. "Поле изображения: (0, %d)(0, %d)" +#: takepic.c:442 #, c-format -msgid "Can't close file %s" -msgstr "" +msgid "Array field: (0, %d)(0, %d)" +msgstr "Поле изображения: (0, %d)(0, %d)" -#: diaphragm.c:220 +#: macros.c:183 msgid "Can't close mmap'ed file" -msgstr "" +msgstr "Не могу закрыть mmap'нутый файл" -#. / "Ошибка определения доступной памяти" -#: wrapper.c:81 -msgid "Can't determine free memory" -msgstr "Ошибка определения доступной памяти" +#. "Не могу удалить PID-файл" +#: takepic.c:136 +msgid "Can't delete PIDfile" +msgstr "Не могу удалить PID-файл" -#. / "Ошибка получения свойств видеоядра" -#: wrapper.c:79 -msgid "Can't get properties" -msgstr "Ошибка получения свойств видеоядра" +#. "Не могу переместить турель" +#: takepic.c:268 +msgid "Can't move turret" +msgstr "Не могу переместить турель" -#. / "Не могу открыть" -#: wrapper.c:154 -#, fuzzy -msgid "Can't open" -msgstr "Ошибка получения свойств видеоядра" +#: macros.c:192 +msgid "Can't munmap" +msgstr "Не могу вызывать munmap" -#: diaphragm.c:214 +#: macros.c:177 #, c-format msgid "Can't open %s for reading" -msgstr "" +msgstr "Не могу открыть %s для чтения" -#: mkHartmann.c:185 -#, fuzzy, c-format -msgid "Can't open file %s" -msgstr "Ошибка получения свойств видеоядра" +#. "Не могу открыть окно OpenGL, просмотр будет недоступен!" +#: takepic.c:631 +msgid "Can't open OpenGL window, image preview will be inaccessible" +msgstr "Не могу открыть окно OpenGL, просмотр будет недоступен!" -#. / "Не могу прочесть" -#: wrapper.c:159 -msgid "Can't read" -msgstr "" +#. "Не могу открыть камеру, завершаю" +#: takepic.c:347 +msgid "Can't open camera device, exit" +msgstr "Не могу открыть камеру, завершаю" -#. file not exist but some error occured -#: mkHartmann.c:172 diaphragm.c:216 +#. "Не могу открыть файл устройства %s: %s" +#: takepic.c:116 +#, c-format +msgid "Can't open device file %s: %s" +msgstr "Не могу открыть файл устройства %s: %s" + +#. "Не могу открыть файл журнала статистики" +#: takepic.c:400 +msgid "Can't open statistics log file" +msgstr "Не могу открыть журнал статистики" + +#. "Не могу открыть файл журнала температур" +#: takepic.c:386 +msgid "Can't open temperature log file" +msgstr "Не могу открыть журнал температур" + +#. "Не могу открыть турель" +#: takepic.c:251 +msgid "Can't open turret" +msgstr "Не могу открыть турель" + +#. "Не могу сохранить файл" +#: takepic.c:618 +msgid "Can't save file" +msgstr "Не могу сохранить файл" + +#: macros.c:179 #, c-format msgid "Can't stat %s" -msgstr "" +msgstr "Не могу выполнить stat для %s" -#: mkHartmann.c:168 +#. "Захват кадра %d, время экспозиции - %g секунд\n" +#: takepic.c:546 #, c-format -msgid "Can't write to %s" -msgstr "" +msgid "Capture frame %d, exp time - %g sec\n" +msgstr "Захват кадра %d, время экспозиции - %g секунд\n" -#: diaphragm.c:256 -msgid "Corrupted file: no holes found!" -msgstr "" +#. "Изменение температуры холодильника" +#: takepic.c:428 +msgid "Changing of cooler setpoint" +msgstr "Изменение температуры холодильника" -#: cmdlnopts.c:147 -msgid "Degrees should be less than 360" -msgstr "" +#. "Холодильник отключен" +#: camtools.c:137 +msgid "Cooler is off" +msgstr "Холодильник отключен" -#: diaphragm.c:267 -msgid "Didn't find any holes in json file!" -msgstr "" - -#. / "Ошибка в инициализации CUDA!" -#: wrapper.c:99 -msgid "Error in CUDA initialisation!" -msgstr "Ошибка в инициализации CUDA!" - -#: mkHartmann.c:259 +#. "Целевая температура: %g\n" +#: camtools.c:132 #, c-format -msgid "Error reading data: read %d numbers instaed of %d" -msgstr "" +msgid "Cooler setpoint: %g\n" +msgstr "Целевая температура: %g\n" -#: diaphragm.c:112 -msgid "Error: NULL instead of aHole structure!\n" -msgstr "" +#. "Съемка темновых" +#: usage.c:335 +msgid "Dark frames" +msgstr "Съемка темновых" -#. / "В вычислениях по возможности будет использоваться GPU\n" -#: wrapper.c:74 -msgid "In computations will try to use GPU\n" -msgstr "В вычислениях по возможности будет использоваться GPU\n" +#. "Устройство не найдено" +#: takepic.c:108 +msgid "Device not found" +msgstr "Устройство не найдено" -#: mkHartmann.c:254 -msgid "Input file was modified in runtime!" -msgstr "" +#. "Отобразить на экране полученное изображение" +#: usage.c:140 +msgid "Display last image" +msgstr "Отобразить на экране полученное изображение" -#. nested arrays is error -#: diaphragm.c:68 -msgid "Invalid file format! Found nested arrays!\n" -msgstr "" +#. "не засвечивать матрицу перед экспозицией" +#: usage.c:143 +msgid "Don't flash CCD chip before expose" +msgstr "не засвечивать матрицу перед экспозицией" -#. non-numerical data? -#: diaphragm.c:74 -msgid "Invalid file format! Non-numerical data in array!\n" -msgstr "" +#. "Не могу вызывать ioctl" +#: takepic.c:123 +msgid "Error in ioctl" +msgstr "Не могу вызывать ioctl" -#: diaphragm.c:178 -msgid "Invalid holes array format!\n" -msgstr "" +#. "Ошибка перехода в спящий режим!" +#: takepic.c:372 +msgid "Error: sleepless night!" +msgstr "Ошибка перехода в спящий режим!" -#: diaphragm.c:251 -msgid "JSON file MUST contain floating point field \"Z\" or \"maskz\" with " - "mask's coordinate" -msgstr "" +#. "Не заданы параметры экспозиции, отключаюсь" +#: takepic.c:339 +msgid "Expose parameters aren't specified, exit" +msgstr "Не заданы параметры экспозиции, отключаюсь" -#. / "ПАМЯТЬ: свободная = " -#: wrapper.c:103 +#. "Время экспозиции: %dмс" +#: usage.c:517 #, c-format -msgid "MEMORY: free = " -msgstr "ПАМЯТЬ: свободная = " +msgid "Exposure time: %dms" +msgstr "Время экспозиции: %dмс" -#: mkHartmann.c:243 -msgid "Matrix must be square" -msgstr "" +#. "Скорость вентилятора должна быть в пределе 0..3" +#: usage.c:354 +msgid "Fan speed should be in interval 0..3" +msgstr "Скорость вентилятора должна быть в пределе 0..3" -#: diaphragm.c:219 +#. "Установить скорость вращения вентиляторов в %d" +#: usage.c:356 +#, c-format +msgid "Fan speed would be set to %d" +msgstr "Установить скорость вращения вентиляторов в %d" + +#. "Видимое поле: %s" +#: takepic.c:440 +#, c-format +msgid "Field of view: %s" +msgstr "Видимое поле: %s" + +#. "Файл записан в '%s'" +#: takepic.c:622 +#, c-format +msgid "File saved as '%s'" +msgstr "Файл записан в '%s'" + +#. "Обнаружена камера '%s' с датчиком '%s'" +#: takepic.c:354 +#, c-format +msgid "Find camera '%s' with sensor '%s'" +msgstr "Обнаружена камера '%s' с датчиком '%s'" + +#. Полное журналирование статистики +#: usage.c:400 +msgid "Full statistics logging" +msgstr "Полное журналирование статистики" + +#. "Получен сигнал %d, отключаюсь.\n" +#: takepic.c:133 +#, c-format +msgid "Get signal %d, quit.\n" +msgstr "Получен сигнал %d, отключаюсь.\n" + +#. "Получить информацию о турели" +#: usage.c:362 +msgid "Get turret's info" +msgstr "Получить информацию о турели" + +#. "Установка заданной температуры" +#: camtools.c:140 +msgid "Go to setpoint" +msgstr "Установка заданной температуры" + +#. "Спящий режим" +#: usage.c:465 +msgid "Go to sleep" +msgstr "Спящий режим" + +#. "Гор. биннинг: %d" +#: usage.c:385 +#, c-format +msgid "Horisontal binning: %d" +msgstr "Гор. биннинг: %d" + +#. "Игнорирую аргумент[ы]:\n" +#: usage.c:545 +#, c-format +msgid "Ignore argument[s]:\n" +msgstr "Игнорирую аргумент[ы]:\n" + +#. "Статистика по изображению:\n" +#: camtools.c:170 +#, c-format +msgid "Image stat:\n" +msgstr "Статистика по изображению\n" + +#. "Тип изображения - %s" +#: usage.c:390 +#, c-format +msgid "Image type - %s" +msgstr "Тип изображения - %s" + +#. "Название прибора - %s" +#: usage.c:395 +#, c-format +msgid "Instrument name - %s" +msgstr "Название прибора - %s" + +#. "Поддержание заданной температуры" +#: camtools.c:143 +msgid "Keeping setpoint" +msgstr "Поддержание заданной температуры" + +#: macros.c:182 msgid "Mmap error for input" -msgstr "" +msgstr "Ошибка mmap для входных данных" -#: diaphragm.c:212 -msgid "No filename given!" -msgstr "" - -#: mkHartmann.c:178 -msgid "No output filename given" -msgstr "" - -#. / "Приложение скомпилировано без поддержки CUDA" -#: wrapper.c:39 wrapper.c:48 wrapper.c:58 -msgid "Tool was compiled without CUDA support" -msgstr "" - -#. / "В вычислениях используется только CPU\n" -#: wrapper.c:112 -msgid "Will use only CPU in computations\n" -msgstr "В вычислениях используется только CPU\n" - -#: mkHartmann.c:229 -msgid "Wrong file: should be matrix of float data separated by spaces" -msgstr "" - -#: cmdlnopts.c:119 -msgid "Wrong float number format!" -msgstr "" - -#: cmdlnopts.c:294 +#. "Переместить турель в позицию %d" +#: usage.c:370 #, c-format -msgid "Wrong format of image type: %c" -msgstr "" +msgid "Move turret into %d" +msgstr "Переместить турель в позицию %d" -#. wrong format -#: cmdlnopts.c:193 -msgid "Wrong format: no value for keyword" -msgstr "" +#: macros.c:175 +msgid "No filename given!" +msgstr "Не указано имя файла!" -#: diaphragm.c:44 -msgid "Wrong value! Get non-number!\n" -msgstr "" +#. "Не засвечивать камеру до экспозиции" +#: usage.c:349 +msgid "No pre-expose flash" +msgstr "Не засвечивать камеру до экспозиции" -#: cmdlnopts.c:95 -msgid "add random noice to mirror surface deviations" -msgstr "" +#. "Имя объекта - %s" +#: usage.c:428 +#, c-format +msgid "Object name - %s" +msgstr "Имя объекта - %s" -#: cmdlnopts.c:93 -msgid "amount of photons falled to one pixel of matrix by one iteration" -msgstr "" +#. "Наблюдатели: %s" +#: usage.c:433 +#, c-format +msgid "Observers: %s" +msgstr "Наблюдатели: %s" -#: cmdlnopts.c:96 -msgid "amplitude of random noice (default: 1e-8)" -msgstr "" +#. "Работать с камерой номер %d" +#: usage.c:415 +#, c-format +msgid "Open camera number %d" +msgstr "Работать с камерой номер %d" -#: cmdlnopts.c:97 -msgid "filename for mirror surface deviations (in microns!)" -msgstr "" +#. "Пауза: %dс" +#: usage.c:446 +#, c-format +msgid "Pause: %ds" +msgstr "Пауза: %dс" -#: cmdlnopts.c:102 -msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)" -msgstr "" +#. "Номер позиции должен быть больше 0" +#: usage.c:368 +msgid "Position number should be positive value" +msgstr "Номер позиции должен быть больше 0" -#: cmdlnopts.c:100 -msgid "print matrices on screen" -msgstr "" +#. pre-expose +#. "Предварительная экспозиция" +#: takepic.c:466 +msgid "Pre-expose" +msgstr "Предварительная экспозиция" -#: cmdlnopts.c:92 -msgid "resulting image size" -msgstr "" +#. "Нажмите Ctrl+C еще %d раз[а], чтобы прервать считывание\n" +#: takepic.c:154 +#, c-format +msgid "Press Ctrl+C %d time[s] more to interrupt reading\n" +msgstr "Нажмите Ctrl+C еще %d раз[а], чтобы прервать считывание\n" -#: cmdlnopts.c:98 -msgid "rewrite output file if exists" -msgstr "" +#. "Автор программы: %s" +#: usage.c:323 +#, c-format +msgid "Program author: %s" +msgstr "Автор программы: %s" -#: cmdlnopts.c:101 -msgid "save intermediate results to images" -msgstr "" +#. "Название программы: %s" +#: usage.c:438 +#, c-format +msgid "Program name: %s" +msgstr "Название программы: %s" -#: cmdlnopts.c:99 -msgid "save matrices to file arg" -msgstr "" +#. "Считывание изображения:" +#: takepic.c:575 +#, c-format +msgid "Read image: " +msgstr "Считывание изображения: " -#: cmdlnopts.c:77 -msgid "set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:" - "Ao=ang:Zo=ang:C=num]\n" - "\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like " - "-10m13.4 !\n" - "\t\tdiam - diameter of mirror\n" - "\t\tfoc - mirror focus ratio\n" - "\t\tZincl - inclination from Z axe\n" - "\t\tAincl - azimuth of inclination\n" - "\t\tAobj - azimuth of object\n" - "\t\tZobj - zenith of object\n" - "\t\tccd - Z-coordinate of light receiver" -msgstr "" +#. "Ошибка считывания: %s\n" +#: takepic.c:490 takepic.c:581 +#, c-format +msgid "Readout error: %s\n" +msgstr "Ошибка считывания: %s\n" -#: cmdlnopts.c:89 -msgid "show this help" -msgstr "" +#. "Скорость считывания - беззнаковое целое!" +#: usage.c:451 +msgid "Readout speed should be unsigned int!" +msgstr "Скорость считывания - беззнаковое целое!" -#: cmdlnopts.c:90 -msgid "size of initial array of surface deviations" -msgstr "" +#. "Требуемая позиция больше максимальной" +#: takepic.c:263 +msgid "Required position greater then max" +msgstr "ребуемая позиция больше максимальной" -#: cmdlnopts.c:91 -msgid "size of interpolated array of surface deviations" -msgstr "" +#. "Полный сброс" +#: usage.c:459 +msgid "Reset" +msgstr "Полный сброс" + +#. "Сохранение журнала температур" +#: usage.c:406 +msgid "Save temperature log" +msgstr "Сохранение журнала температур" + +#. "Серия из %d кадров" +#: usage.c:423 +#, c-format +msgid "Series of %d frames" +msgstr "Серия из %d кадров" + +#. "отключить холодильник" +#: usage.c:134 usage.c:329 +msgid "Set cooler off" +msgstr "отключить холодильник" + +#. "Устанавливаю скорость вращения вентиляторов в %d\n" +#: camtools.c:119 +#, c-format +msgid "Set fan speed %d\n" +msgstr "Устанавливаю скорость вращения вентиляторов в %d\n" + +#. "Установить скорость вентиляторов в F (0..3)" +#: usage.c:146 +msgid "Set fan speed to F (0..3)" +msgstr "Установить скорость вентиляторов в F (0..3)" + +#. "Установить интервал логгирования в %d секунд" +#: usage.c:377 +#, c-format +msgid "Set logging interval to %d seconds" +msgstr "Установить интервал логгирования в %d секунд" + +#. "Установить температуру: %.3f" +#: usage.c:486 +#, c-format +msgid "Set temperature: %.3f" +msgstr "Установить температуру: %.3f" + +#. "Отключение холодильника" +#: takepic.c:422 +msgid "Switch cooler off" +msgstr "Отключение холодильника" + +#. "Температура ниже допустимой" +#: takepic.c:431 +msgid "The temperature setpoint is too low" +msgstr "Температура ниже допустимой" + +#. "Максимальная (MAX) и текущая (CUR) позиции турели:\n" +#: takepic.c:258 +#, c-format +msgid "Turret MAXimum position and CURrent position:\n" +msgstr "Максимальная (MAX) и текущая (CUR) позиции турели:\n" + +#. "Номер турели должен быть больше 0" +#: usage.c:500 +msgid "Turret number should be positive value" +msgstr "Номер турели должен быть больше 0" + +#. "Статус неизвестен" +#: camtools.c:146 +msgid "Unknown status" +msgstr "Хрен знает что" + +#. "Использование:\t%s [опции] [префикс выходных файлов]\n" +#: usage.c:125 +#, c-format +msgid "Usage:\t%s [options] [output files prefix]\n" +msgstr "Использование:\t%s [опции] [префикс выходных файлов]\n" + +#. "Значение time-interval должно быть натуральным числом" +#: usage.c:375 +msgid "Value of time-interval must be non-zero positive" +msgstr "Значение time-interval должно быть натуральным числом" + +#. "Верт. биннинг: %d" +#: usage.c:494 +#, c-format +msgid "Vertical binning: %d" +msgstr "Верт. биннинг: %d" + +#. "Подождите завершения перемещения турели " +#: takepic.c:273 +#, c-format +msgid "Wait, while turret is moving " +msgstr "Подождите завершения перемещения турели " + +#. "Активировать камеру" +#: usage.c:508 +msgid "Wakeup camera" +msgstr "Активировать камеру" + +#. "Отображение снятых кадров" +#: usage.c:341 +msgid "Will show images" +msgstr "Отображение снятых кадров" + +#. "Работать с турелью %d" +#: usage.c:502 +#, c-format +msgid "Work with turret %d" +msgstr "Работать с турелью %d" + +#. "Неверный" +#: usage.c:382 usage.c:491 +msgid "Wrong" +msgstr "Неверный" + +#. "Неверный номер камеры: %s" +#: usage.c:412 +#, c-format +msgid "Wrong camera number: %s" +msgstr "Неверный номер камеры: %s" + +#. "Неверное время экспозиции: %s" +#: usage.c:514 +#, c-format +msgid "Wrong exposure time: %s" +msgstr "Неверное время экспозиции: %s" + +#. "Неверное кол-во кадров: %s" +#: usage.c:420 +#, c-format +msgid "Wrong frames number in series: %s" +msgstr "Неверное кол-во кадров: %s" + +#. "Неверная нижняя граница: %s" +#: usage.c:104 +#, c-format +msgid "Wrong lower border: %s" +msgstr "Неверная нижняя граница: %s" + +#. "Неверная пауза: %s" +#: usage.c:443 +#, c-format +msgid "Wrong pause length: %s" +msgstr "Неверная пауза: %s" + +#. "Неверное значение температуры: %s (должно быть от -35 до 30)" +#: usage.c:482 +#, c-format +msgid "Wrong temperature: %s (must be from -35 to 30)" +msgstr "Неверное значение температуры: %s (должно быть от -35 до 30)" + +#. "Неверная верхняя граница: %s" +#: usage.c:109 +#, c-format +msgid "Wrong upper border: %s" +msgstr "Неверная верхняя граница: %s" + +#. "Диапазон по X: [%d, %d]" +#: usage.c:522 +#, c-format +msgid "X range: [%d, %d]" +msgstr "Диапазон по X: [%d, %d]" + +#. "Диапазон по Y: [%d, %d]" +#: usage.c:527 +#, c-format +msgid "Y range: [%d, %d]" +msgstr "Диапазон по Y: [%d, %d]" + +#. -255. - there's no thermometer on hot side +#. "В вашем светоприемнике нет \"горячего\" термометра" +#: camtools.c:105 +msgid "Your camera have no hot temperature sensor\n" +msgstr "В вашем светоприемнике нет \"горячего\" термометра\n" + +#. "заткрыть затвор" +#: usage.c:243 +msgid "close shutter" +msgstr "заткрыть затвор" + +#. "закрыт\n" +#: takepic.c:415 +#, c-format +msgid "closed\n" +msgstr "закрыт\n" + +#. "не очищать матрицу после считывания" +#: usage.c:234 +msgid "don't flush ccd after expose" +msgstr "не очищать матрицу после считывания" + +#. "не открывать устройство, лишь отобразить шапку FITS" +#: usage.c:246 +msgid "don't open camera device, just show FITS header" +msgstr "не открывать устройство, лишь отобразить шапку FITS" + +#. "не сохранять изображения, лишь вести запись статистки" +#: usage.c:167 +msgid "don't save images, only make all-stat log" +msgstr "не сохранять изображения, лишь вести запись статистки" + +#. "отразить изображение горизонтально (относительно оси Y)" +#: usage.c:231 +msgid "flip image horizontally (around Y axe)" +msgstr "отразить изображение горизонтально (относительно оси Y)" + +#. "отразить изображение вертикально (относительно оси X)" +#: usage.c:228 +msgid "flip image vertically (around X axe)" +msgstr "отразить изображение вертикально (относительно оси X)" + +#. "Полный сброс" +#: usage.c:194 +msgid "full reset" +msgstr "Полный сброс" + +#. получить сведения о турели +#: usage.c:149 +msgid "get turret's parameters" +msgstr "получить сведения о турели" + +#. "перейти в спящий режим" +#: usage.c:197 +msgid "go to sleeping mode" +msgstr "перейти в спящий режим" + +#. "биннинг N пикселей по горизонтали" +#: usage.c:158 +msgid "horizontal binning to N pixels" +msgstr "биннинг N пикселей по горизонтали" + +#. "тип изображения" +#: usage.c:161 +msgid "image type" +msgstr "тип изображения" + +#. "название прибора" +#: usage.c:164 +msgid "instrument name" +msgstr "название прибора" + +#. "выполнить предварительную нулевую экспозицию для очистки матрицы" +#: usage.c:237 +msgid "make a preliminary zero exposition for cleaning CCD" +msgstr "выполнить предварительную нулевую экспозицию для очистки матрицы" + +#. "выдержать ptime секунд между экспозициями" +#: usage.c:188 +msgid "make pause for ptime seconds between expositions" +msgstr "выдержать ptime секунд между экспозициями" + +#. "N кадров в серии" +#: usage.c:176 +msgid "make series of N frames" +msgstr "N кадров в серии" + +#. "вести запись рабочих температур в файл temp_log" +#: usage.c:170 +msgid "make temperatures logging to file temp_log" +msgstr "вести запись рабочих температур в файл temp_log" + +#. "Ошибка выделения памяти!" +#: takepic.c:480 takepic.c:509 +msgid "malloc() failed!" +msgstr "Ошибка выделения памяти!" + +#. "не открывать затвор при экспозиции (\"темновые\")" +#: usage.c:137 +msgid "not open shutter when exposing (\"dark frames\")" +msgstr "не открывать затвор при экспозиции (\"темновые\")" + +#. "не сохранять изображение, а только отобразить статистику" +#: usage.c:200 +msgid "not save image, just show statistics" +msgstr "не сохранять изображение, а только отобразить статистику" + +#. "название объекта" +#: usage.c:179 +msgid "object name" +msgstr "название объекта" + +#. "имена наблюдателей" +#: usage.c:182 +msgid "observers' names" +msgstr "имена наблюдателей" + +#. "название программы наблюдений" +#: usage.c:185 +msgid "observing program name" +msgstr "название программы наблюдений" + +#. "только задать/получить температуру" +#. "только отобразить/задать температуру" +#: usage.c:203 usage.c:475 +msgid "only set/get temperature" +msgstr "только задать/получить температуру" + +#. "открыт\n" +#: takepic.c:412 +#, c-format +msgid "open\n" +msgstr "открыт\n" + +#. "открыть затвор" +#: usage.c:240 +msgid "open shutter" +msgstr "открыть затвор" + +#. "автор программы" +#: usage.c:131 +msgid "program author" +msgstr "автор программы" + +#. "возобновить питание" +#: usage.c:215 +msgid "resume system" +msgstr "возобновить питание" + +#. "выбрать диапазон для считывания" +#: usage.c:221 usage.c:224 +msgid "select clip region" +msgstr "выбрать диапазон для считывания" + +#. "время экспозиции exptime мс" +#: usage.c:218 +msgid "set exposure time to exptime ms" +msgstr "время экспозиции exptime мс" + +#. "установить скорость считывания в N" +#: usage.c:191 +msgid "set readout speed to N" +msgstr "установить скорость считывания в N" + +#. переместить турель в N-ю позицию +#: usage.c:152 +msgid "set turret to Nth position" +msgstr "переместить турель в N-ю позицию" + +#. установить номер турели в N +#: usage.c:212 +msgid "set turret's number to N" +msgstr "установить номер турели в N" + +#. "задать рабочую температуру degr градусов" +#: usage.c:206 +msgid "set work temperature to degr C" +msgstr "задать рабочую температуру degr градусов" + +#. "интервал времени между последовательными записями в лог и HISTORY (в секундах)" +#: usage.c:155 +msgid "time interval between sequential writings to log & HISTORY (in " + "seconds)" +msgstr "интервал времени между последовательными записями в лог и HISTORY (в " + "секундах)" + +#. "биннинг N пикселей по вертикали" +#: usage.c:209 +msgid "vertical binning to N pixels" +msgstr "биннинг N пикселей по вертикали" + +#. "работать в 12-битном режиме" +#: usage.c:249 +msgid "work in a 12-bit ADC mode" +msgstr "работать в 12-битном режиме" + +#. "работать с N-й камерой" +#: usage.c:173 +msgid "work with Nth camera" +msgstr "работать с N-й камерой" + +msgid "Can't init mutex!" +msgstr "Не могу инициировать взаимное исключение!" + +msgid "Error removing from list" +msgstr "Ошибка удаления из списка" + +msgid "can't cancel a thread!" +msgstr "Не могу отменить выполнение потока!" diff --git a/src/mkHartmann.c b/src/mkHartmann.c index 9e59023..6259210 100644 --- a/src/mkHartmann.c +++ b/src/mkHartmann.c @@ -26,116 +26,17 @@ #include "wrapper.h" #include "saveimg.h" #include "diaphragm.h" +#include "usefull_macros.h" -/* - * Coloured messages output - */ -#define RED "\033[1;31;40m" -#define GREEN "\033[1;32;40m" -#define OLDCOLOR "\033[0;0;0m" - - -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; - globErr = 0; - }else - i = vfprintf(stderr, fmt, ar); - va_end(ar); - i++; - fprintf(stderr, OLDCOLOR "\n"); - return i; -} - -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; - globErr = 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; -} - -/* - * 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; -} char *outpfile = NULL; // filename for data output in octave text format int printDebug = 0; // print tab bool firstRun = TRUE; // first run: create new file +int forceCPU = 0; + +void signals(int sig){exit (sig);} + + /** * Print tabular on screen (if outpfile == NULL) or to outpfile * in octave text format @@ -190,7 +91,9 @@ void printTAB(size_t W, size_t H, float *data, char *mask, char *comment){ // now put out matrix itself (upside down - for octave/matlab) for(y = 0; y < H; y++){ for(x = 0; x < W; x++){ - PR(" %g", *data++); + //PR(" %g", *data++); + float d = data[H*(H-y-1) + x]; + PR(" %g", d); } PR("\n"); } @@ -212,7 +115,8 @@ float *read_deviations(char *filename, size_t *Size){ float *ret = NULL; int W = 0, W0 = 0, H0 = 0, i; size_t Mlen; - char *Mem = NULL, *endptr, *ptr; + mmapbuf *map; + char *endptr, *ptr, *dstart; if(!filename){ assert(Size); ret = MALLOC(float, (*Size) * (*Size)); // allocate matrix with given size @@ -220,15 +124,16 @@ float *read_deviations(char *filename, size_t *Size){ return ret; } // there was filename given: try to read data from it - Mem = My_mmap(filename, &Mlen); // from diaphragm.c - ptr = Mem; + map = My_mmap(filename); + ptr = dstart = map->data; + Mlen = map->len; do{ errno = 0; strtof(ptr, &endptr); if(errno || (endptr == ptr && *ptr)) - ERRX(_("Wrong file: should be matrix of float data separated by spaces")); + ERR(_("Wrong file: should be matrix of float data separated by spaces")); W++; - if(endptr >= Mem + Mlen) break; // eptr out of range - EOF? + if(endptr >= dstart + Mlen) break; // eptr out of range - EOF? if(*endptr == '\n'){ H0++; ptr = endptr + 1; @@ -237,27 +142,26 @@ float *read_deviations(char *filename, size_t *Size){ ERRX(_("All rows must contain equal number of columns")); W = 0; }else ptr = endptr; - }while(endptr && endptr < Mem + Mlen); + }while(endptr && endptr < dstart + Mlen); if(W > 1) H0++; // increase number of rows if there's no trailing '\n' in last line if(W0 != H0) ERRX(_("Matrix must be square")); *Size = W0; - DBG("here"); ret = MALLOC(float, W0*W0); - DBG("there"); - ptr = Mem; + ptr = dstart; for(i = 0, H0 = 0; H0 < W0; H0++) for(W = 0; W < W0; W++, i++){ - DBG("%d ", i); ret[W0*(W0-H0-1) + W] = strtof(ptr, &endptr) * 1e-6; - if(errno || (endptr == ptr && *ptr) || endptr >= Mem + Mlen) - ERRX(_("Input file was modified in runtime!")); + if(errno || (endptr == ptr && *ptr)) + ERR(_("File modified in runtime?")); + if(endptr > dstart + Mlen) goto ex_for; ptr = endptr; } +ex_for: W0 *= W0; if(i != W0) - ERRX(_("Error reading data: read %d numbers instaed of %d"), W-1, W0); - munmap(Mem, Mlen); + ERRX(_("Error reading data: read %d numbers instead of %d"), i, W0); + My_munmap(map); return ret; } @@ -279,21 +183,10 @@ int main(int argc, char **argv){ glob_pars *G = NULL; // default parameters see in cmdlnopts.c mirPar *M = NULL; // default mirror parameters int x, y _U_; - // 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"); - bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); - textdomain(GETTEXT_PACKAGE); - G = parce_args(argc, argv); + initial_setup(); + G = parse_args(argc, argv); M = G->Mirror; + if(forceCPU) noCUDA(); // Run simple initialisation of CUDA and/or memory test getprops(); size_t S0 = G->S_dev, S1 = G->S_interp, Sim = G->S_image, N_phot = G->N_phot; @@ -310,10 +203,15 @@ int main(int argc, char **argv){ ALLOC(float, mirZ, masksize); // mirror Z coordinate ALLOC(float, mirDX, masksize); // projections of normale to mirror ALLOC(float, mirDY, masksize); - if(G->randMask || G->randAmp != Gdefault.randAmp){ // add random numbers to mask - if(!fillrandarr(S0*S0, idata, G->randAmp)) + if(G->randMask || G->randAmp > 0.){ // add random numbers to mask + size_t Ss = S0*S0; + ALLOC(float, tmpf, Ss); + if(!fillrandarr(Ss, tmpf, G->randAmp)) /// "Не могу построить матрицу случайных чисел" ERR(_("Can't build random matrix")); + OMP_FOR() + for(x = 0; x < Ss; x++) idata[x] += tmpf[x]; + FREE(tmpf); } // initialize structure of mirror deviations mirDeviations mD; @@ -332,9 +230,9 @@ int main(int argc, char **argv){ {{-0.1,-0.45,0.6,0.6}, H_ELLIPSE}}; */ // Hartmann mask - Diaphragm dia; //{{-0.5, -0.5, 1., 1.}, NULL, 0, 20., NULL}; + Diaphragm dia = {{-0.5, -0.5, 1., 1.}, NULL, 0, 20., NULL}; mirMask *mask; - readHoles("holes.json", &dia); + if(G->holes_filename) readHoles(G->holes_filename, &dia); #ifdef EBUG green("Dia: "); printf("(%g, %g, %g, %g); %d holes, Z = %g\n", dia.box.x0, dia.box.y0, @@ -347,100 +245,29 @@ int main(int argc, char **argv){ float *dm = MALLOC(float, S2); for(x=0; xdata[x]; writeimg("mirror_mask", imt, S, S, NULL, M, dm); - free(dm); + FREE(dm); } // coordinates of photons ALLOC(float, xout, N_phot); ALLOC(float, yout, N_phot); // resulting image ALLOC(float, image, Sim*Sim); -/* -//for(int i = 0; i < 100; i++){ - box.x0 = -3.; box.y0 = -3.; box.w = 6.; box.h = 6.; - if(!getPhotonXY(xout, yout, 1, &mD, M, N_phot, &box)) - ERR("Can't build photon map"); - box.x0 = -15e-3; box.y0 = -15e-3; box.w = 30e-3; box.h = 30e-3; - //box.x0 = -5e-3; box.y0 = .8365; box.w = 10e-3; box.h = 10e-3; - if(!fillImage(xout, yout, N_phot, image, Sim, Sim, &box)) - ERR("Can't fill output image"); -//} - writeimg("image", imt, Sim, Sim, &box, M, image); - FREE(xout); FREE(yout); FREE(image); -*/ + // CCD bounding box - BBox CCD = {-15e-3, -15e-3, 30e-3, 30e-3}; - for(x = 0; x < 100; x++){ + BBox CCD = {-5e-4*G->CCDW, -5e-4*G->CCDH, 1e-3*G->CCDW, 1e-3*G->CCDH}; + + green("Make %d iterations by %d photons on each", G->N_iter, N_phot); + printf("\n"); + for(x = 0; x < G->N_iter; ++x){ + if(x%1000 == 999) printf("Iteration %d\n", x+1); if(!getPhotonXY(xout, yout, 1, &mD, M, N_phot, &box)) ERR("Can't build photon map"); if(!fillImage(xout, yout, N_phot, image, Sim, Sim, &CCD)) ERR("Can't fill output image"); } -/* int S = mask->WH; - double R = M->D / 2., scale = M->D / (double)S; - uint16_t *dptr = mask->data; - box.w = box.h = scale; - // check mask's pixels & throw photons to holes - for(y = 0; y < S; y++){ - for(x = 0; x < S; x++, dptr++){ - if(!*dptr) continue; - DBG("x = %d, Y=%d\n", x,y); - box.x0 = -R + scale*(double)x; - box.y0 = -R + scale*(double)y; - if(!getPhotonXY(xout, yout, 1, &mD, M, N_phot, &box)) - ERR("Can't build photon map"); - if(!fillImage(xout, yout, N_phot, image, Sim, Sim, &CCD)) - ERR("Can't fill output image"); - } - } -*/ - writeimg("image", imt, Sim, Sim, &CCD, M, image); - FREE(xout); FREE(yout); FREE(image); - // if rand() is good, amount of photons on image should be 785398 on every 1000000 - //printTAB(Sim, Sim, image, NULL, "\n\nResulting image:"); -/* for(x = 0; x < N_phot; x++) - if(fabs(xout[x]) < M->D/2. && fabs(yout[x]) < M->D/2.) - printf("photon #%4d:\t\t(%g, %g)\n", x, xout[x]*1e6, yout[x]*1e6);*/ + FREE(xout); FREE(yout); -/* FILE *F = fopen("TESTs", "w"); - if(!F) ERR("Can't open"); - fprintf(F,"S1\tGPU\t\tCPU\n"); - - - for(S1 = 100; ; S1 += S1*drand48()){ - float *odata = my_alloc(S1*S1, sizeof(float)); - double t0; - fprintf(F,"%zd", S1); - forceCUDA(); - */ -/* int x, y; float *ptr = idata; - printf("Original array:\n"); - for(y = 0; y < 5; y++){ - for(x = 0; x < 5; x++){ - *ptr *= 2.; - *ptr += x; - printf("%4.3f ", (*ptr++)); - } - printf("\n"); - } - t0 = dtime(); - if(!bicubic_interp(odata, idata, S1,S1, S0,S0)) fprintf(F,"\tnan"); - else fprintf(F,"\t%g", dtime() - t0); - - printf("Enlarged array:\n"); - ptr = odata; - for(y = 0; y < 20; y++){ - for(x = 0; x < 20; x++) - printf("%4.3f ", (*ptr++)); - printf("\n"); - } - * - noCUDA(); - t0 = dtime(); - /// "Не могу построить интерполяцию" - if(!bicubic_interp(odata, idata, S1,S1, S0,S0)) ERR(_("Can't do interpolation")); - fprintf(F,"\t%g\n", dtime() - t0); - fflush(F); - free(odata); - }*/ + writeimg(G->outfile, imt, Sim, Sim, &CCD, M, image); + FREE(image); return 0; } diff --git a/src/parceargs.c b/src/parseargs.c similarity index 53% rename from src/parceargs.c rename to src/parseargs.c index d388ab0..2f57be9 100644 --- a/src/parceargs.c +++ b/src/parseargs.c @@ -1,5 +1,5 @@ /* - * parceargs.c - parcing command line arguments & print help + * parseargs.c - parsing command line arguments & print help * * Copyright 2013 Edward V. Emelianoff * @@ -19,26 +19,17 @@ * MA 02110-1301, USA. */ -#include // DBG +#include // printf #include // getopt_long #include // calloc, exit, strtoll #include // assert #include // strdup, strchr, strlen +#include // strcasecmp #include // INT_MAX & so on #include // gettext #include // isalpha -#include "parceargs.h" - -#ifdef EBUG - #define DBG(...) printf(__VA_ARGS__) -#else - #define DBG(...) -#endif - -// macro to print help messages -#ifndef PRNT - #define PRNT(x) gettext(x) -#endif +#include "parseargs.h" +#include "usefull_macros.h" char *helpstring = "%s\n"; @@ -47,7 +38,6 @@ char *helpstring = "%s\n"; * MAY consist ONE "%s" for progname * @param str (i) - new format */ - void change_helpstring(char *s){ int pcount = 0, scount = 0; char *str = s; @@ -61,13 +51,11 @@ void change_helpstring(char *s){ } if(str[1] == 's') scount++; // increment "%s" counter }; - DBG("pc: %d, sc: %d\n", pcount, scount); if(pcount > 1 || pcount != scount){ // amount of pcount and/or scount wrong - fprintf(stderr, "Wrong helpstring!\n"); - exit(-1); + /// "Неправильный формат строки помощи" + ERRX(_("Wrong helpstring!")); } helpstring = s; - DBG("hs: %s\n", helpstring); } /** @@ -77,7 +65,7 @@ void change_helpstring(char *s){ * @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 */ -bool myatoll(void *num, char *str, argtype t){ +static bool myatoll(void *num, char *str, argtype t){ long long tmp, *llptr; int *iptr; char *endptr; @@ -94,7 +82,8 @@ bool myatoll(void *num, char *str, argtype t){ case arg_int: default: if(tmp < INT_MIN || tmp > INT_MAX){ - fprintf(stderr, "Integer out of range\n"); + /// "Целое вне допустимого диапазона" + WARNX(_("Integer out of range")); return FALSE; } iptr = (int*)num; @@ -105,7 +94,7 @@ bool myatoll(void *num, char *str, argtype t){ // the same as myatoll but for double // There's no NAN & INF checking here (what if they would be needed?) -bool myatod(void *num, const char *str, argtype t){ +static bool myatod(void *num, const char *str, argtype t){ double tmp, *dptr; float *fptr; char *endptr; @@ -133,7 +122,7 @@ bool myatod(void *num, const char *str, argtype t){ * @param options (i) - array of options * @return index in array */ -int get_optind(int opt, myoption *options){ +static int get_optind(int opt, myoption *options){ int oind; myoption *opts = options; assert(opts); @@ -144,7 +133,57 @@ int get_optind(int opt, myoption *options){ } /** - * Parce command line arguments + * 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` @@ -155,7 +194,7 @@ int get_optind(int opt, myoption *options){ * * @exit: in case of error this function show help & make `exit(-1)` */ -void parceargs(int *argc, char ***argv, myoption *options){ +void parseargs(int *argc, char ***argv, myoption *options){ char *short_options, *soptr; struct option *long_options, *loptr; size_t optsize, i; @@ -169,10 +208,18 @@ void parceargs(int *argc, char ***argv, myoption *options){ 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 @@ -182,18 +229,47 @@ void parceargs(int *argc, char ***argv, myoption *options){ // fill long_options // don't do memcmp: what if there would be different alignment? loptr->name = opts->name; - loptr->has_arg = opts->has_arg; + 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){ +#ifdef EBUG + shortlist[i] = (char) opts->val; +#endif *soptr++ = opts->val; - if(opts->has_arg) // add ':' if option has required argument + if(loptr->has_arg) // add ':' if option has required argument *soptr++ = ':'; - if(opts->has_arg == 2) // add '::' if option has optional argument + 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; @@ -202,55 +278,51 @@ void parceargs(int *argc, char ***argv, myoption *options){ if(opt == '?'){ opt = optopt; optind = get_optind(opt, options); - if(options[optind].has_arg == 1) showhelp(optind, options); // need argument + 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]; -DBG ("\n*******\noption %s (oindex = %d / optind = %d)", options[optind].name, oindex, optind); -if(optarg) DBG (" with arg %s", optarg); -DBG ("\n"); - if(opt == 0 && opts->has_arg == 0) continue; // only long option changing integer flag -DBG("opt = %c, arg type: ", opt); + if(opt == 0 && opts->has_arg == NO_ARGS) continue; // only long option changing integer flag // now check option - if(opts->has_arg == 1) assert(optarg); + 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: -DBG("none\n"); + if(opts->argptr) *((int*)aptr) += 1; // increment value break; case arg_int: -DBG("integer\n"); - result = myatoll(opts->argptr, optarg, arg_int); + result = myatoll(aptr, optarg, arg_int); break; case arg_longlong: -DBG("long long\n"); - result = myatoll(opts->argptr, optarg, arg_longlong); + result = myatoll(aptr, optarg, arg_longlong); break; case arg_double: -DBG("double\n"); - result = myatod(opts->argptr, optarg, arg_double); + result = myatod(aptr, optarg, arg_double); break; case arg_float: -DBG("double\n"); - result = myatod(opts->argptr, optarg, arg_float); + result = myatod(aptr, optarg, arg_float); break; case arg_string: -DBG("string\n"); - result = (*((char **)opts->argptr) = strdup(optarg)); + result = (*((void**)aptr) = (void*)strdup(optarg)); break; case arg_function: -DBG("function\n"); - result = ((argfn)opts->argptr)(optarg, optind); + result = ((argfn)aptr)(optarg); break; } if(!result){ -DBG("OOOPS! Error in result\n"); showhelp(optind, options); } } @@ -258,6 +330,26 @@ DBG("OOOPS! Error in result\n"); *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){ // both have short arg + return (s1 - s2); + }else if(f1 != NULL && f2 != NULL){ // both don't have short arg - sort by long + return strcmp(l1, l2); + }else{ // only one have short arg -- return it + if(f2) 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 @@ -266,8 +358,6 @@ DBG("OOOPS! Error in result\n"); * @exit: run `exit(-1)` !!! */ void showhelp(int oindex, myoption *options){ - // ATTENTION: string `help` prints through macro PRNT(), bu default it is gettext, - // but you can redefine it before `#include "parceargs.h"` int max_opt_len = 0; // max len of options substring - for right indentation const int bufsz = 255; char buf[bufsz+1]; @@ -281,7 +371,7 @@ void showhelp(int oindex, myoption *options){ printf("--%s", opts->name); if(opts->has_arg == 1) printf("=arg"); else if(opts->has_arg == 2) printf("[=arg]"); - printf(" %s\n", PRNT(opts->help)); + printf(" %s\n", _(opts->help)); exit(-1); } // header, by default is just "progname\n" @@ -298,10 +388,15 @@ void showhelp(int oindex, myoption *options){ }while((++opts)->name); max_opt_len += 14; // format: '-S , --long[=arg]' - get addition 13 symbols opts = options; - // Now print all help + // 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 && isalpha(opts->val)) // .val is short argument + if(!opts->flag) // .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 @@ -309,8 +404,94 @@ void showhelp(int oindex, myoption *options){ 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, PRNT(opts->help)); // write options & at least 2 spaces after - }while((++opts)->name); + 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; +} diff --git a/src/saveimg.c b/src/saveimg.c index 885245f..61730eb 100644 --- a/src/saveimg.c +++ b/src/saveimg.c @@ -20,6 +20,7 @@ */ #include "mkHartmann.h" +#include "usefull_macros.h" #include "cmdlnopts.h" // for flag "-f", which will tell to rewrite existing file #include "saveimg.h" #if defined __PNG && __PNG == TRUE @@ -118,6 +119,7 @@ void get_stat(float *img, size_t size){ if(max < pv) max = pv; if(min > pv) min = pv; } + glob_stat.image = img; glob_stat.avr = sum/sz; glob_stat.std = sqrt(fabs(sum2/sz - glob_stat.avr*glob_stat.avr)); glob_stat.max = max; @@ -137,6 +139,7 @@ int writefits(char *filename, size_t width, size_t height, BBox *imbox, mirPar *mirror, float *data){ FNAME(); long naxes[2] = {width, height}; + static char* newname = NULL; char buf[80]; int ret = 1; double dX, dY; @@ -146,15 +149,13 @@ int writefits(char *filename, size_t width, size_t height, BBox *imbox, } time_t savetime = time(NULL); fitsfile *fp; - get_stat(data, width*height); assert(filename); - char* newname = MALLOC(char, strlen(filename + 2)); + newname = realloc(newname, strlen(filename + 2)); sprintf(newname, "!%s", filename); // say cfitsio that file could be rewritten TRYFITS(fits_create_file, &fp, newname); TRYFITS(fits_create_img, fp, FLOAT_IMG, 2, naxes); // FILE / Input file original name WRITEKEY(TSTRING, "FILE", filename, "Input file original name"); - free(newname); WRITEKEY(TSTRING, "DETECTOR", "Hartmann model", "Detector model"); if(imbox){ snprintf(buf, 79, "%.2g x %.2g", dX * 1e6, dY * 1e6); @@ -198,6 +199,7 @@ int writefits(char *filename, size_t width, size_t height, BBox *imbox, WRITEKEY(TFLOAT, "Z", &mirror->objZ, "Object's zenith distance"); WRITEKEY(TFLOAT, "FOCUS", &mirror->foc, "Z-coordinate of light receiver"); } + TRYFITS(fits_write_img, fp, TFLOAT, 1, width * height, data); TRYFITS(fits_close_file, fp); @@ -212,13 +214,12 @@ uint8_t *processRow(float *irow, size_t width, float min, float wd){ rowptr = MALLOC(uint8_t, width * 3); OMP_FOR() for(size_t i = 0; i < width; i++){ - //*ptr = (uint16_t)(umax*(*irow - min)/wd); double gray = ((double)(irow[i] - min))/((double)wd); if(gray == 0.) continue; int G = (int)(gray * 4.); double x = 4.*gray - (double)G; - uint8_t r = 0, g = 0, b = 0; uint8_t *ptr = &rowptr[i*3]; + uint8_t r = 0, g = 0, b = 0; switch(G){ case 0: g = (uint8_t)(255. * x + 0.5); @@ -253,7 +254,6 @@ int writepng(char *filename, size_t width, size_t height, BBox *imbox, FILE *fp = NULL; png_structp pngptr = NULL; png_infop infoptr = NULL; - get_stat(data, width*height); float min = glob_stat.min, wd = glob_stat.max - min; float *row; @@ -297,7 +297,6 @@ int writejpg(char *filename, size_t width, size_t height, BBox *imbox, FNAME(); int ret = 1; #if defined __JPEG && __JPEG == TRUE - get_stat(data, width*height); float min = glob_stat.min, wd = glob_stat.max - min; float *row; FILE* outfile = fopen(filename, "w"); @@ -337,7 +336,6 @@ int writetiff(char *filename, size_t width, size_t height, BBox *imbox, FNAME(); int ret = 1; #if defined __TIFF && __TIFF == TRUE - get_stat(data, width*height); float min = glob_stat.min, wd = glob_stat.max - min; float *row; TIFF *image = TIFFOpen(filename, "w"); @@ -399,6 +397,7 @@ int writeimg(char *name, imtype t, size_t width, size_t height, BBox *imbox, char *filename = NULL, *suffix; int ret = 0; itsuff *suf = suffixes; + get_stat(data, width*height); while(t && suf->t){ if(!(t & suf->t)){ suf++; @@ -406,18 +405,17 @@ int writeimg(char *name, imtype t, size_t width, size_t height, BBox *imbox, } t ^= suf->t; suffix = suf->s; - FREE(filename); if(name) filename = createfilename(name, suffix); else filename = createfilename("out", suffix); + DBG("Filename: %s", filename); if(!filename){ fprintf(stderr, "Create file with name %s and suffix %s failed,\n", name, suffix); - perror("can't make filename"); continue; } if(suf->writefn(filename, width, height, imbox, mirror, data)) ret++; + FREE(filename); } - FREE(filename); return ret; } diff --git a/src/usefull_macros.c b/src/usefull_macros.c new file mode 100644 index 0000000..a3654f6 --- /dev/null +++ b/src/usefull_macros.c @@ -0,0 +1,327 @@ +/* + * usefull_macros.h - a set of usefull functions: memory, color etc + * + * Copyright 2013 Edward V. Emelianoff + * + * 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; + globErr = 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; + globErr = 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) ERRX(_("No filename given!")); + if((fd = open(filename, O_RDONLY)) < 0) + ERR(_("Can't open %s for reading"), filename); + if(fstat (fd, &statbuf) < 0) + ERR(_("Can't stat %s"), filename); + Mlen = statbuf.st_size; + if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) + ERR(_("Mmap error for input")); + if(close(fd)) ERR(_("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)) + ERR(_("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 read + */ +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 read + */ +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 read 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; +} diff --git a/src/wrapper.c b/src/wrapper.c index 0582b4c..2002852 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -21,6 +21,8 @@ #define WRAPPER_C #include "wrapper.h" +#include "usefull_macros.h" +#include "cmdlnopts.h" #ifdef EBUG #include "saveimg.h" #endif @@ -55,21 +57,13 @@ void forceCUDA(){ // not run on CPU even if GPU failed CUforce = 1; #else /// "Приложение скомпилировано без поддержки CUDA" - WARN(_("Tool was compiled without CUDA support")); + ERRX(_("Tool was compiled without CUDA support")); #endif } -// Init function ==============================================================> -/* - * Init CUDA context and/or test memory allocation - * name: getprops - */ -void getprops(){ - FNAME(); - size_t mem = 100 * MB; - /// "Тест на выделение как минимум 100МБ памяти\n" - printf("Make a test for allocation at least 100MB memory\n"); #ifdef CUDA_FOUND +int testCUDA(){ + size_t mem = 100 * MB; /// "В вычислениях по возможности будет использоваться GPU\n" red(_("In computations will try to use GPU\n")); int status = 0; @@ -94,6 +88,7 @@ void getprops(){ #undef _TEST }while(0); if(status){ + if(CUforce) ERRX(_("Can't run CUDA!")); Only_CPU = 1; /// "Ошибка в инициализации CUDA!" WARN(_("Error in CUDA initialisation!")); @@ -106,11 +101,29 @@ void getprops(){ printf(_(" total= ")); green("%zdMB\n", theTotal / MB); } + return status; +} #endif + + +// Init function ==============================================================> +/* + * Init CUDA context and/or test memory allocation + * name: getprops + */ +void getprops(){ + FNAME(); + size_t mem = 100 * MB; + int status = 0; + /// "Тест на выделение как минимум 100МБ памяти\n" + printf("Make a test for allocation at least 100MB memory\n"); if(Only_CPU){ /// "В вычислениях используется только CPU\n" green(_("Will use only CPU in computations\n")); } +#ifdef CUDA_FOUND + else status = testCUDA(); +#endif // at last step - try to allocate main memory char *ptr = (char *) malloc(mem); /// "Ошибка выделения памяти" @@ -126,18 +139,6 @@ void getprops(){ } // Functions for pseudo-random number generators initialisation ===============> -/* - * Current time in seconds since UNIX epoch - * name: dtime - * @return time in seconds - */ -double dtime(){ - double t; - struct timeval tv; - gettimeofday(&tv, NULL); - t = tv.tv_sec + ((double)tv.tv_usec)/1e6; - return t; -} /* * Generate a quasy-random number to initialize PRNG * name: throw_random_seed @@ -306,7 +307,7 @@ mirMask *makeDmask(Diaphragm *d, size_t minSz, mirPar *M, mirDeviations *D){ for(x = 0; x < d->Nholes; x++) if(!histo[x]){ DBG("Oooops! Missed a hole!"); - FREE(mdata); + FREE(mdata); FREE(histo); return makeDmask(d, minSz*2, M, D); } #ifdef EBUG @@ -343,31 +344,32 @@ void freeDmask(mirMask *m){ */ int fillImage(float *phX, float *phY, size_t ph_sz, float *image, size_t imW, size_t imH, BBox *imbox){ - FNAME(); + //FNAME(); float x0 = imbox->x0, y0 = imbox->y0, x1 = imbox->x0 + imbox->w, y1 = imbox->y0 + imbox->h; float dX = imbox->w / (float)(imW - 1), dY = imbox->h / (float)(imH - 1), x=0,y=0; size_t N; - #ifdef EBUG +/* #ifdef EBUG float sum = 0., miss = 0., Xc = 0., Yc = 0.; - #endif + #endif */ for(N = 0; N < ph_sz; N++){ x = phX[N]; y = phY[N]; size_t X,Y; if(x < x0 || x > x1 || y < y0 || y > y1){ - #ifdef EBUG +/* #ifdef EBUG miss += 1.; - #endif + #endif */ }else{ X = (size_t)((x - x0) / dX + 0.5); - Y = (size_t)((y1 - y) / dY + 0.5); + //Y = (size_t)((y1 - y) / dY + 0.5); + Y = (size_t)((y - y0) / dY + 0.5); image[Y*imW + X] += 1.f; - #ifdef EBUG +/* #ifdef EBUG sum += 1.; Xc += x; Yc += y; - #endif + #endif*/ } } - DBG("Photons on image: %g, missed: %g; TOTAL: %g\ncenter: Xc=%gmm, Yc=%gmm\nPI=%g", - sum,miss, sum+miss, Xc/sum*1000., Yc/sum*1000., 4.*sum/(sum+miss)); +// DBG("Photons on image: %g, missed: %g; TOTAL: %g\ncenter: Xc=%gmm, Yc=%gmm\nPI=%g", +// sum,miss, sum+miss, Xc/sum*1000., Yc/sum*1000., 4.*sum/(sum+miss)); return 1; }