diff --git a/BASLER_cameras/basler.c b/BASLER_cameras/basler.c index bf82be5..80ff5c1 100644 --- a/BASLER_cameras/basler.c +++ b/BASLER_cameras/basler.c @@ -293,10 +293,10 @@ static int setdevno(int N){ return TRUE; } -static int setbitdepth(int i){ +static int setbitdepth(int depth){ #define MONON 4 const char *fmts[MONON] = {"Mono16", "Mono14", "Mono12", "Mono10"}; - if(i == 0){ // 8 bit + if(depth == 0){ // 8 bit if(!PylonDeviceFeatureIsAvailable( hDev, "EnumEntry_PixelFormat_Mono8" )) return FALSE; PYLONFN(PylonDeviceFeatureFromString, hDev, "PixelFormat", "Mono8"); green("Pixel format: Mono8\n"); @@ -370,21 +370,21 @@ static int capture(IMG *ima){ int width = grabResult.SizeX, height = grabResult.SizeY, stride = grabResult.SizeX + grabResult.PaddingX; //TIMESTAMP("start converting"); if(is16bit){ - int s2 = stride<<1, w2 = width<<1; + int s2 = stride<<1; OMP_FOR() for(int y = 0; y < height; ++y){ - uint16_t *Out = &ima->data[y*width]; + uint8_t *Out = &((uint8_t*)ima->data)[y*width]; const uint8_t *In = &imgBuf[y*s2]; - memcpy(Out, In, w2); + for(int x = 0; x < width; ++x){ + *Out++ = *In; In += 2; + } } }else{ OMP_FOR() for(int y = 0; y < height; ++y){ - uint16_t *Out = &ima->data[y*width]; + uint16_t *Out = &((uint16_t*)ima->data)[y*width]; const uint8_t *In = &imgBuf[y*stride]; - for(int x = 0; x < width; ++x){ - *Out++ = *In++; - } + memcpy(Out, In, width); } } //TIMESTAMP("image ready"); diff --git a/Dummy_cameras/dummyfunc.c b/Dummy_cameras/dummyfunc.c index 795139b..73eaa98 100644 --- a/Dummy_cameras/dummyfunc.c +++ b/Dummy_cameras/dummyfunc.c @@ -40,6 +40,7 @@ static float focuserpos = 1., brightness = 1., gain = 0.; static float camtemp = -30., exptime = 0.; static capture_status capstat = CAPTURE_NO; static double texpstart = 0.; +static uint8_t bitpix = 16; // bit depth: 8 or 16 static int campoll(capture_status *st, float *remain){ if(capstat != CAPTURE_PROCESS){ @@ -68,16 +69,37 @@ static int startexp(){ static int camcapt(IMG *ima){ static int n = 0; if(!ima || !ima->data) return FALSE; - OMP_FOR() - for(int y = 0; y < ima->h; ++y){ - uint16_t *d = &ima->data[y*ima->w]; - for(int x = 0; x < ima->w; ++x){ // sinusoide 100x200 - //*d++ = (uint16_t)(((n+x)%100)/99.*65535.); - *d++ = (uint16_t)((1. + sin((n+x) * M_PI/50.)*sin((n+y) * M_PI/100.))*32767.); + if(bitpix == 16){ + OMP_FOR() + for(int y = 0; y < ima->h; ++y){ + uint16_t *d = &((uint16_t*)ima->data)[y*ima->w]; + for(int x = 0; x < ima->w; ++x){ // sinusoide 100x200 + //*d++ = (uint16_t)(((n+x)%100)/99.*65535.); + *d++ = (uint16_t)((1. + sin((n+x) * M_PI/50.)*sin((n+y) * M_PI/100.))*32767.); + } + } + }else{ + OMP_FOR() + for(int y = 0; y < ima->h; ++y){ + uint8_t *d = &((uint8_t*)ima->data)[y*ima->w]; + for(int x = 0; x < ima->w; ++x){ // sinusoide 100x200 + //*d++ = (uint16_t)(((n+x)%100)/99.*65535.); + *d++ = (uint8_t)((1. + sin((n+x) * M_PI/50.)*sin((n+y) * M_PI/100.))*127.); + } } } ++n; - ima->bitpix = 16; + ima->bitpix = bitpix; + return TRUE; +} + +static int camsetbit(int b){ + bitpix = (b) ? 16 : 8; + return TRUE; +} + +static int camgetbp(uint8_t *bp){ + if(bp) *bp = bitpix; return TRUE; } @@ -105,7 +127,6 @@ static int camsetexp(float t){ exptime = t; return TRUE; } - static int camsetgain(float g){ gain = g; return TRUE; @@ -261,11 +282,12 @@ __attribute__ ((visibility("default"))) Camera camera = { .confio = istub, .setio = istub, .setframetype = istub, - .setbitdepth = istub, + .setbitdepth = camsetbit, .setfastspeed = istub, .setgeometry = camsetgeom, .setfanspeed = camfan, // getters: + .getbitpix = camgetbp, .getbrightness = camgetbrig, .getModelName = camgetnam, .getgain = camgetgain, diff --git a/FLI_cameras/flifunc.c b/FLI_cameras/flifunc.c index b58291f..9f0786a 100644 --- a/FLI_cameras/flifunc.c +++ b/FLI_cameras/flifunc.c @@ -463,7 +463,8 @@ retn: static int fli_capt(IMG *ima){ if(!ima || !ima->data) return FALSE; for(int row = 0; row < ima->h; row++){ - TRYFUNC(FLIGrabRow, camdev, &ima->data[row * ima->w], ima->w); + void *ptr = (void*)((is16bit) ? ((uint16_t*)ima->data) + row * ima->w : ((uint8_t*)ima->data) + row * ima->w); + TRYFUNC(FLIGrabRow, camdev, ptr, ima->w); if(fli_err) return FALSE; } ima->bitpix = is16bit ? 16 : 8; diff --git a/HIKROBOT_cameras/mvsfunc.c b/HIKROBOT_cameras/mvsfunc.c index 83353dc..483eb62 100644 --- a/HIKROBOT_cameras/mvsfunc.c +++ b/HIKROBOT_cameras/mvsfunc.c @@ -445,36 +445,27 @@ retn: static int cam_capt(IMG *ima){ if(!handle || !pdata) return FALSE; if(!ima || !ima->data) return FALSE; - ; - int bytes = ima->h*ima->w * 2, stbytes = stImageInfo.nWidth * stImageInfo.nHeight * 2; - if(bytes > pdatasz) bytes = pdatasz; - if(bytes != stbytes) WARNX("Different sizes of image buffer & grabbed image"); - if(stbytes > bytes) bytes = stbytes; - DBG("Copy %d bytes (stbytes=%d)", bytes, stbytes); MVCC_ENUMVALUE EnumValue; TRY(GetEnumValue, "PixelSize", &EnumValue); DBG("PixelSize = %u", EnumValue.nCurValue); ONOK(){ -//green("pixsize=%d\n", EnumValue.nCurValue); + int bytes = ima->h*ima->w * ((7 + ima->bitpix) / 8), stbytes = stImageInfo.nWidth * stImageInfo.nHeight; if(EnumValue.nCurValue == 16){ - memcpy(ima->data, pdata, bytes); ima->bitpix = 12; - return TRUE; - }else if(EnumValue.nCurValue != 8){ + stbytes *= 2; + }else if(EnumValue.nCurValue == 8){ + ima->bitpix = 8; + }else{ WARNX("Unsupported pixel size"); return FALSE; } + if(bytes > pdatasz) bytes = pdatasz; + if(bytes != stbytes) WARNX("Different sizes of image buffer & grabbed image"); + DBG("Copy %d bytes (stbytes=%d)", bytes, stbytes); + memcpy(ima->data, pdata, bytes); + return TRUE; } - // transform 8bits to 16 - DBG("TRANSFORM 8 bit to 16"); - bytes /= 2; - uint8_t *ptr = (uint8_t*) pdata; - OMP_FOR() - for(int i = 0; i < bytes; ++i){ - ima->data[i] = (uint16_t) *ptr++; - } - ima->bitpix = 8; - return TRUE; + return FALSE; } static int cam_modelname(char *buf, int bufsz){ diff --git a/ZWO_cameras/zwofunc.c b/ZWO_cameras/zwofunc.c index a4916df..da300fd 100644 --- a/ZWO_cameras/zwofunc.c +++ b/ZWO_cameras/zwofunc.c @@ -101,7 +101,8 @@ static int campoll(capture_status *st, float *remain){ break; default: // failed DBG("Failed: %d", s); - *st = CAPTURE_ABORTED; + //*st = CAPTURE_ABORTED; + *st = CAPTURE_READY; } if(remain){ float diff = exptime - (dtime() - starttime); @@ -392,6 +393,7 @@ static int setfspd(int spd){ // set fast speed (0..3): 0 - 40% bandwidthovrl, 3 if(spd > 2) bw = 100.; else if(spd > 0) bw += 20. * spd; DBG("set BANDWIDTH to %g", bw); + zwo_setfloat(1, ASI_HIGH_SPEED_MODE); if(ASI_SUCCESS != zwo_setfloat(bw, ASI_BANDWIDTHOVERLOAD)){ DBG("Can't set"); return FALSE; diff --git a/basestructs.h b/basestructs.h index de934a0..91e8a03 100644 --- a/basestructs.h +++ b/basestructs.h @@ -18,13 +18,22 @@ #pragma once #include +#include // for size_t -typedef struct{ - uint16_t *data; // image data +// magic to mark our SHM +#define SHM_MAGIC (0xdeadbeef) + +// base image parameters - sent by socket and stored in shared memory +typedef struct __attribute__((packed, aligned(4))){ + uint32_t MAGICK; // magick (DEADBEEF) - to mark our shm + double timestamp; // timestamp of image taken uint8_t bitpix; // bits per pixel (8 or 16) int w, h; // image size uint16_t max, min; // min/max values float avr, std; // statistics + size_t bytelen; // size of image in bytes + void *data; // pointer to data (next byte after this struct) - only for server + /* `data` is uint8_t or uint16_t depending on `bitpix` */ } IMG; // format of single frame @@ -78,12 +87,13 @@ typedef struct{ int (*confio)(int s); // configure IO-port int (*setio)(int s); // set IO-port to given state int (*setframetype)(int l); // set frametype: 1 - light, 0 - dark - int (*setbitdepth)(int h); // set bit depth: 1 - high, 0 - low + int (*setbitdepth)(int h); // set bit depth : 1 - high (16 bit), 0 - low (8 bit) int (*setfastspeed)(int s); // set readout speed: 1 - fast, 0 - low // geometry (if TRUE, all args are changed to suitable values) int (*setgeometry)(frameformat *fmt); // set geometry in UNBINNED coordinates int (*setfanspeed)(fan_speed spd); // set fan speed // getters: + int (*getbitpix)(uint8_t *bp); // get bit depth in bits per pixel (8, 12, 16 etc) int (*getbrightness)(float *b);// get brightnes level int (*getModelName)(char *n, int l);// string with model name (l - length of n in bytes) int (*getgain)(float *g); // get gain value diff --git a/ccdfunc.c b/ccdfunc.c index 6cc3737..85662e1 100644 --- a/ccdfunc.c +++ b/ccdfunc.c @@ -211,7 +211,6 @@ int saveFITS(IMG *img, char **outp){ } } int width = img->w, height = img->h; - void *data = (void*) img->data; long naxes[2] = {width, height}; double tmpd = 0.0; float tmpf = 0.0; @@ -224,7 +223,9 @@ int saveFITS(IMG *img, char **outp){ fitserror = 0; TRYFITS(fits_create_file, &fp, fnam); if(fitserror) goto cloerr; - TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes); + int nbytes = getNbytes(img); + if(nbytes == 1) TRYFITS(fits_create_img, fp, BYTE_IMG, 2, naxes); + else TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes); if(fitserror) goto cloerr; // ORIGIN / organization responsible for the data WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data"); @@ -348,7 +349,8 @@ int saveFITS(IMG *img, char **outp){ // INSTRUME / Instrument if(GP->instrument) WRITEKEY(fp, TSTRING, "INSTRUME", GP->instrument, "Instrument"); - TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data); + if(nbytes == 1) TRYFITS(fits_write_img, fp, TBYTE, 1, width * height, img->data); + else TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, img->data); if(fitserror) goto cloerr; TRYFITS(fits_close_file, fp); cloerr: @@ -369,24 +371,23 @@ cloerr: return ret; } -void calculate_stat(IMG *image){ - uint64_t Noverld = 0L, size = image->h*image->w; +static void stat8(IMG *image){ double sum = 0., sum2 = 0.; - uint16_t max = 0, min = 65535; + size_t size = image->w * image->h; + uint8_t max = 0, min = UINT8_MAX; + uint8_t *idata = (uint8_t*)image->data; #pragma omp parallel { - uint16_t maxpriv = 0, minpriv = 65535; - uint64_t ovrpriv = 0; + uint8_t maxpriv = 0, minpriv = UINT8_MAX; double sumpriv = 0., sum2priv = 0.; #pragma omp for nowait - for(uint64_t i = 0; i < size; ++i){ - uint16_t val = image->data[i]; + for(size_t i = 0; i < size; ++i){ + uint8_t val = idata[i]; float pv = (float) val; sum += pv; sum2 += (pv * pv); if(max < val) max = val; if(min > val) min = val; - if(val >= 65530) ovrpriv++; } #pragma omp critical { @@ -394,7 +395,6 @@ void calculate_stat(IMG *image){ if(min > minpriv) min = minpriv; sum += sumpriv; sum2 += sum2priv; - Noverld += ovrpriv; } } double sz = (float)size; @@ -402,10 +402,49 @@ void calculate_stat(IMG *image){ image->avr = avr; image->std = sqrt(fabs(sum2/sz - avr*avr)); image->max = max; image->min = min; +} +static void stat16(IMG *image){ + double sum = 0., sum2 = 0.; + size_t size = image->w * image->h; + uint16_t max = 0, min = UINT16_MAX; + uint16_t *idata = (uint16_t*)image->data; +#pragma omp parallel +{ + uint16_t maxpriv = 0, minpriv = UINT16_MAX; + double sumpriv = 0., sum2priv = 0.; + #pragma omp for nowait + for(size_t i = 0; i < size; ++i){ + uint16_t val = idata[i]; + float pv = (float) val; + sum += pv; + sum2 += (pv * pv); + if(max < val) max = val; + if(min > val) min = val; + } + #pragma omp critical + { + if(max < maxpriv) max = maxpriv; + if(min > minpriv) min = minpriv; + sum += sumpriv; + sum2 += sum2priv; + } +} + double sz = (float)size; + double avr = sum/sz; + image->avr = avr; + image->std = sqrt(fabs(sum2/sz - avr*avr)); + image->max = max; image->min = min; +} + + +void calculate_stat(IMG *image){ + int nbytes = ((7 + image->bitpix) / 8); + if(nbytes == 1) stat8(image); + else stat16(image); if(GP->verbose){ printf(_("Image stat:\n")); - printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr, image->std, Noverld); - printf("max = %u, min = %u, size = %ld\n", max, min, size); + printf("avr = %.1f, std = %.1f\n", image->avr, image->std); + printf("max = %u, min = %u, size = %d pix\n", image->max, image->min, image->w * image->h); } } @@ -770,6 +809,7 @@ void ccds(){ frameformat fmt = camera->geometry; int raw_width = fmt.w / GP->hbin, raw_height = fmt.h / GP->vbin; DBG("w=%d, h=%d", raw_width, raw_height); + // allocate maximum available memory - for 16bit image uint16_t *img = MALLOC(uint16_t, raw_width * raw_height); DBG("\n\nAllocated image 2x%dx%d=%d", raw_width, raw_height, 2 * raw_width * raw_height); IMG ima = {.data = img, .w = raw_width, .h = raw_height}; @@ -827,6 +867,17 @@ void camstop(){ } } +/** + * @brief getNbytes - calculate amount of bytes to store bitpix (1/2) + * @param image - image + * @return 1 for bitpix<8 or 2 + */ +int getNbytes(IMG *image){ + int n = (image->bitpix + 7) / 8; + if(n < 1) n = 1; + if(n > 2) n = 2; + return n; +} #ifdef IMAGEVIEW #define NFRM (10) diff --git a/ccdfunc.h b/ccdfunc.h index 63eed0e..f3aa659 100644 --- a/ccdfunc.h +++ b/ccdfunc.h @@ -31,6 +31,8 @@ int prepare_ccds(); void ccds(); void camstop(); +int getNbytes(IMG *image); + int startCCD(void **dlh); int startWheel(void **dlh); int startFocuser(void **dlh); diff --git a/client.c b/client.c index f1d201b..758473e 100644 --- a/client.c +++ b/client.c @@ -46,7 +46,8 @@ static int xc0,yc0,xc1,yc1; // current format #ifdef IMAGEVIEW static IMG ima = {0}; static volatile atomic_int grabno = 0, oldgrabno = 0; -static int imdatalen = 0, imbufsz = 0; +static size_t imbufsz = 0; +static uint8_t *imbuf = NULL; #endif static char *readmsg(int fd){ @@ -100,6 +101,7 @@ static int parseans(char *ans){ DBG("Got current format: %d,%d,%d,%d", xc0, yc0, xc1, yc1); return TRUE; } + /* #ifdef IMAGEVIEW else if(0 == strcmp(CMD_IMWIDTH, ans)){ ima.w = atoi(val); @@ -113,6 +115,7 @@ static int parseans(char *ans){ return TRUE; } #endif +*/ //TIMESTAMP("parseans() end"); return FALSE; } @@ -313,40 +316,56 @@ void init_grab_sock(int sock){ send_headers(sock); } -static void getimage(){ - FNAME(); - int sock = controlfd; - TIMESTAMP("Get image sizes"); - SENDCMDW(CMD_IMWIDTH); - SENDCMDW(CMD_IMHEIGHT); - int imsock = open_socket(FALSE, GP->imageport, TRUE); - if(imsock < 0) ERRX("getimage(): can't open image transport socket"); - if(imbufsz < imdatalen){ - DBG("Reallocate memory from %d to %d", imbufsz, imdatalen); - ima.data = realloc(ima.data, imdatalen); - imbufsz = imdatalen; - } +/** + * @brief readNbytes - read `N` bytes from descriptor `fd` into buffer *buf + * @return false if failed + */ +static int readNbytes(int fd, size_t N, uint8_t *buf){ + size_t got = 0, need = N; double t0 = dtime(); - int got = 0; - TIMESTAMP("Start of data read"); - while(dtime() - t0 < CLIENT_TIMEOUT){ - if(!canberead(imsock)) continue; - uint8_t *target = ((uint8_t*)ima.data)+got; - int rd = read(imsock, target, imdatalen - got); + while(dtime() - t0 < CLIENT_TIMEOUT && canberead(fd) && need){ + ssize_t rd = read(fd, buf + got, need); if(rd <= 0){ WARNX("Server disconnected"); signals(1); } - got += rd; - //DBG("Read %d bytes; total read %d from %d; first: %x %x %x %x", rd, got, imdatalen, target[0], - // target[1], target[2], target[3]); - if(got == imdatalen){ - break; - } + got += rd; need -= rd; + } + if(need) return FALSE; // didn't got whole packet + return TRUE; +} + +static void getimage(){ + FNAME(); + TIMESTAMP("Get image sizes"); + /*SENDCMDW(CMD_IMWIDTH); + SENDCMDW(CMD_IMHEIGHT);*/ + int imsock = open_socket(FALSE, GP->imageport, TRUE); + if(imsock < 0) ERRX("getimage(): can't open image transport socket"); + // get image size + if(!readNbytes(imsock, sizeof(IMG), (uint8_t*)&ima)){ + WARNX("Can't read image header"); + goto eofg; + } + if(ima.bytelen < 1){ + WARNX("Wrong image size"); + goto eofg; + } + if(imbufsz < ima.bytelen){ + size_t newsz = 1024 * (1 + ima.bytelen / 1024); + DBG("Reallocate memory from %zd to %zd", imbufsz, newsz); + imbufsz = newsz; + imbuf = realloc(imbuf, imbufsz); + } + ima.data = imbuf; // renew this value each time after getting `ima` from server + TIMESTAMP("Start of data read"); + if(!readNbytes(imsock, ima.bytelen, imbuf)){ + WARNX("Can't read image data"); + goto eofg; } - if(dtime() - t0 > CLIENT_TIMEOUT) WARNX("Timeout, image didn't received"); TIMESTAMP("Got image"); ++grabno; +eofg: close(imsock); } diff --git a/cmdlnopts.c b/cmdlnopts.c index 21e704f..fcbdd7b 100644 --- a/cmdlnopts.c +++ b/cmdlnopts.c @@ -30,6 +30,7 @@ static glob_pars G = { .brightness = NAN, .gain = NAN, .setwheel = -1, .fanspeed = -1, + .shmkey = 7777777 }; /* @@ -102,6 +103,8 @@ myoption cmdlnopts[] = { {"viewer", NO_ARGS, &G.viewer,1, arg_none, NULL, N_("passive viewer (only get last images)")}, {"restart", NO_ARGS, &G.restart,1, arg_none, NULL, N_("restart image server")}, + {"shmkey", NEED_ARG, NULL, 'k', arg_int, APTR(&G.shmkey), N_("shared memory (with image data) key (default: 7777777")}, + #ifdef IMAGEVIEW {"display", NO_ARGS, NULL, 'D', arg_int, APTR(&G.showimage), N_("Display image in OpenGL window")}, #endif diff --git a/cmdlnopts.h b/cmdlnopts.h index 122a5da..25a477d 100644 --- a/cmdlnopts.h +++ b/cmdlnopts.h @@ -69,6 +69,7 @@ typedef struct{ int verbose; // each '-V' increases it int rewrite; // rewrite file int showimage; // show image preview + int shmkey; // shared memory (with image data) key float gain; // gain level (only for CMOS) float brightness; // brightness (only for CMOS) double exptime; // time of exposition in seconds diff --git a/imageview.c b/imageview.c index 8eb4ae6..005b9d3 100644 --- a/imageview.c +++ b/imageview.c @@ -427,6 +427,7 @@ static void roll_colorfun(){ if(t == COLORFN_MAX) t = COLORFN_BWLINEAR; change_colorfun(t); } + /* no omp histo: 0.000675201s @@ -444,7 +445,7 @@ result: 0.0014689s * @param w,h - image width and height * @return data allocated here */ -static uint8_t *equalize(uint16_t *ori, int w, int h){ +static uint8_t *equalize(IMG *img, int w, int h){ uint8_t *retn = MALLOC(uint8_t, w*h); double orig_hysto[0x10000] = {0.}; // original hystogram uint8_t eq_levls[0x10000] = {0}; // levels to convert: newpix = eq_levls[oldpix] @@ -464,19 +465,39 @@ static uint8_t *equalize(uint16_t *ori, int w, int h){ for(int i = 0; i < 0x10000; ++i) orig_hysto[i] += histogram_private[i]; } }*/ - for(int i = 0; i < s; ++i){ - ++orig_hysto[ori[i]]; + int bytes = getNbytes(img); + + if(bytes == 1){ + uint8_t *data = (uint8_t*) img->data; + for(int i = 0; i < s; ++i){ + ++orig_hysto[data[i]]; + } + }else{ + uint16_t *data = (uint16_t*) img->data; + for(int i = 0; i < s; ++i){ + ++orig_hysto[data[i]]; + } } + //WARNX("histo: %gs", dtime()-t0); + int max = (bytes == 1) ? 0xff : 0xffff; double part = (double)(s + 1) / 0x100, N = 0.; - for(int i = 0; i <= 0xffff; ++i){ + for(int i = 0; i <= max; ++i){ N += orig_hysto[i]; eq_levls[i] = (uint8_t)(N/part); } //WARNX("equal: %gs", dtime()-t0); //OMP_FOR() -- takes the same time! - for(int i = 0; i < s; ++i){ - retn[i] = eq_levls[ori[i]]; + if(bytes == 1){ + uint8_t *data = (uint8_t*) img->data; + for(int i = 0; i < s; ++i){ + retn[i] = eq_levls[data[i]]; + } + }else{ + uint16_t *data = (uint16_t*) img->data; + for(int i = 0; i < s; ++i){ + retn[i] = eq_levls[data[i]]; + } } //WARNX("result: %gs", dtime()-t0); return retn; @@ -493,20 +514,42 @@ cuts: 0.00188208s */ // count image cuts as [median-sigma median+5sigma] -static uint8_t *mkcuts(uint16_t *ori, int w, int h){ +static uint8_t *mkcuts(IMG *img, int w, int h){ uint8_t *retn = MALLOC(uint8_t, w*h); int orig_hysto[0x10000] = {0.}; // original hystogram int s = w*h; double sum = 0., sum2 = 0.; -//double t0 = dtime(); + int bytes = getNbytes(img); + if(bytes == 1){ + uint8_t *data = (uint8_t*) img->data; +#pragma omp parallel +{ + size_t histogram_private[0x100] = {0}; + double sm = 0., sm2 = 0.; + #pragma omp for nowait + for(int i = 0; i < s; ++i){ + ++histogram_private[data[i]]; + double b = data[i]; + sm += b; + sm2 += b*b; + } + #pragma omp critical + { + for(int i = 0; i < 0x100; ++i) orig_hysto[i] += histogram_private[i]; + sum += sm; + sum2 += sm2; + } +} + }else{ + uint16_t *data = (uint16_t*) img->data; #pragma omp parallel { size_t histogram_private[0x10000] = {0}; double sm = 0., sm2 = 0.; #pragma omp for nowait for(int i = 0; i < s; ++i){ - ++histogram_private[ori[i]]; - double b = ori[i]; + ++histogram_private[data[i]]; + double b = data[i]; sm += b; sm2 += b*b; } @@ -517,36 +560,42 @@ static uint8_t *mkcuts(uint16_t *ori, int w, int h){ sum2 += sm2; } } -/* - for(int i = 0; i < s; ++i){ - double b = ori[i]; - ++orig_hysto[ori[i]]; - sum += b; - sum2 += b*b; } -*/ + //WARNX("histo: %gs", dtime()-t0); // get median level - int counts = s/2, median = 0; - for(; median < 0xffff; ++median){ + int counts = s/2, median = 0, max = (bytes == 1) ? 0xff : 0xffff; + for(; median < max; ++median){ if((counts -= orig_hysto[median]) < 0) break; } sum /= s; double sigma = sqrt(sum2/s - sum*sum); int low = median - sigma, high = median + 5.*sigma; if(low < 0) low = 0; - if(high > 0xffff) high = 0xffff; + if(high > max) high = max; double A = 255./(high - low); DBG("Got: sigma=%.1f, low=%d, high=%d, A=%g", sigma, low, high, A); // now we can recalculate values: new = (old - low)*A //WARNX("stat: %gs", dtime()-t0); // DEBUG: 2ms without OMP; 0.7ms with - OMP_FOR() - for(int i = 0; i < s; ++i){ - uint16_t old = ori[i]; - if(old > high){ retn[i] = 255; continue; } - else if(old < low){ retn[i] = 0; continue; } - retn[i] = (uint8_t)(A*(old - low)); + if(bytes == 1){ + uint8_t *data = (uint8_t*) img->data; + OMP_FOR() + for(int i = 0; i < s; ++i){ + uint16_t old = data[i]; + if(old > high){ retn[i] = 255; continue; } + else if(old < low){ retn[i] = 0; continue; } + retn[i] = (uint8_t)(A*(old - low)); + } + }else{ + uint16_t *data = (uint16_t*) img->data; + OMP_FOR() + for(int i = 0; i < s; ++i){ + uint16_t old = data[i]; + if(old > high){ retn[i] = 255; continue; } + else if(old < low){ retn[i] = 0; continue; } + retn[i] = (uint8_t)(A*(old - low)); + } } //WARNX("cuts: %gs", dtime()-t0); return retn; @@ -569,10 +618,10 @@ static void change_displayed_image(IMG *img){ uint8_t *newima; if(imequalize){ DBG("equalize"); - newima = equalize(img->data, w, h); + newima = equalize(img, w, h); }else{ DBG("cuts"); - newima = mkcuts(img->data, w, h); + newima = mkcuts(img, w, h); } GLubyte *dst = im->rawdata; //double t0 = dtime(); diff --git a/locale/ru/LC_MESSAGES/ccd_capture.mo b/locale/ru/LC_MESSAGES/ccd_capture.mo index e920416..610c50f 100644 Binary files a/locale/ru/LC_MESSAGES/ccd_capture.mo and b/locale/ru/LC_MESSAGES/ccd_capture.mo differ diff --git a/locale/ru/messages.po b/locale/ru/messages.po index 8e6c950..048947b 100644 --- a/locale/ru/messages.po +++ b/locale/ru/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-31 16:14+0300\n" +"POT-Creation-Date: 2023-12-14 16:53+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,235 +17,239 @@ msgstr "" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8bit\n" -#: cmdlnopts.c:40 +#: cmdlnopts.c:41 msgid "common device plugin (e.g devfli.so)" msgstr "" -#: cmdlnopts.c:41 +#: cmdlnopts.c:42 msgid "camera device plugin (e.g. devfli.so)" msgstr "" -#: cmdlnopts.c:42 +#: cmdlnopts.c:43 msgid "focuser device plugin (e.g. devzwo.so)" msgstr "" -#: cmdlnopts.c:43 +#: cmdlnopts.c:44 msgid "wheel device plugin (e.g. devdummy.so)" msgstr "" -#: cmdlnopts.c:44 +#: cmdlnopts.c:45 msgid "list connected devices" msgstr "" -#: cmdlnopts.c:45 +#: cmdlnopts.c:46 msgid "camera device number (if many: 0, 1, 2 etc)" msgstr "" -#: cmdlnopts.c:46 +#: cmdlnopts.c:47 msgid "filter wheel device number (if many: 0, 1, 2 etc)" msgstr "" -#: cmdlnopts.c:47 +#: cmdlnopts.c:48 msgid "focuser device number (if many: 0, 1, 2 etc)" msgstr "" -#: cmdlnopts.c:48 +#: cmdlnopts.c:49 msgid "show this help" msgstr "" -#: cmdlnopts.c:49 +#: cmdlnopts.c:50 msgid "rewrite output file if exists" msgstr "" -#: cmdlnopts.c:50 +#: cmdlnopts.c:51 msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" msgstr "" -#: cmdlnopts.c:51 +#: cmdlnopts.c:52 msgid "not open shutter, when exposing (\"dark frames\")" msgstr "" -#: cmdlnopts.c:52 +#: cmdlnopts.c:53 msgid "run in 8-bit mode" msgstr "" -#: cmdlnopts.c:53 +#: cmdlnopts.c:54 msgid "fast readout mode" msgstr "" -#: cmdlnopts.c:54 +#: cmdlnopts.c:55 msgid "set CCD temperature to given value (degr C)" msgstr "" -#: cmdlnopts.c:55 +#: cmdlnopts.c:56 msgid "set fan speed (0 - off, 1 - low, 2 - high)" msgstr "" -#: cmdlnopts.c:57 +#: cmdlnopts.c:58 msgid "program author" msgstr "" -#: cmdlnopts.c:58 +#: cmdlnopts.c:59 msgid "object type (neon, object, flat etc)" msgstr "" -#: cmdlnopts.c:59 +#: cmdlnopts.c:60 msgid "instrument name" msgstr "" -#: cmdlnopts.c:60 +#: cmdlnopts.c:61 msgid "object name" msgstr "" -#: cmdlnopts.c:61 +#: cmdlnopts.c:62 msgid "observers' names" msgstr "" -#: cmdlnopts.c:62 +#: cmdlnopts.c:63 msgid "observing program name" msgstr "" -#: cmdlnopts.c:63 +#: cmdlnopts.c:64 msgid "add records to header from given file[s]" msgstr "" -#: cmdlnopts.c:64 +#: cmdlnopts.c:65 msgid "output file name" msgstr "" -#: cmdlnopts.c:65 +#: cmdlnopts.c:66 msgid "wait while exposition ends" msgstr "" -#: cmdlnopts.c:67 +#: cmdlnopts.c:68 msgid "N flushes before exposing (default: 1)" msgstr "" -#: cmdlnopts.c:68 +#: cmdlnopts.c:69 msgid "horizontal binning to N pixels" msgstr "" -#: cmdlnopts.c:69 +#: cmdlnopts.c:70 msgid "vertical binning to N pixels" msgstr "" -#: cmdlnopts.c:70 +#: cmdlnopts.c:71 msgid "make series of N frames" msgstr "" -#: cmdlnopts.c:71 +#: cmdlnopts.c:72 msgid "make pause for N seconds between expositions" msgstr "" -#: cmdlnopts.c:72 +#: cmdlnopts.c:73 msgid "set exposure time to given value (seconds!)" msgstr "" -#: cmdlnopts.c:73 +#: cmdlnopts.c:74 msgid "cancel current exposition" msgstr "" -#: cmdlnopts.c:74 +#: cmdlnopts.c:75 msgid "" "absolute (not divided by binning!) frame X0 coordinate (-1 - all with " "overscan)" msgstr "" -#: cmdlnopts.c:75 +#: cmdlnopts.c:76 msgid "absolute frame Y0 coordinate (-1 - all with overscan)" msgstr "" -#: cmdlnopts.c:76 +#: cmdlnopts.c:77 msgid "absolute frame X1 coordinate (-1 - all with overscan)" msgstr "" -#: cmdlnopts.c:77 +#: cmdlnopts.c:78 msgid "absolute frame Y1 coordinate (-1 - all with overscan)" msgstr "" -#: cmdlnopts.c:79 +#: cmdlnopts.c:80 msgid "open shutter" msgstr "" -#: cmdlnopts.c:80 +#: cmdlnopts.c:81 msgid "close shutter" msgstr "" -#: cmdlnopts.c:81 +#: cmdlnopts.c:82 msgid "run exposition on LOW @ pin5 I/O port" msgstr "" -#: cmdlnopts.c:82 +#: cmdlnopts.c:83 msgid "run exposition on HIGH @ pin5 I/O port" msgstr "" -#: cmdlnopts.c:83 +#: cmdlnopts.c:84 msgid "get value of I/O port pins" msgstr "" -#: cmdlnopts.c:84 +#: cmdlnopts.c:85 msgid "move stepper motor asynchronous" msgstr "" -#: cmdlnopts.c:86 +#: cmdlnopts.c:87 msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" msgstr "" -#: cmdlnopts.c:87 +#: cmdlnopts.c:88 msgid "" "configure I/O port pins to given value (decimal number, pin1 is LSB, 1 == " "output, 0 == input)" msgstr "" -#: cmdlnopts.c:89 +#: cmdlnopts.c:90 msgid "move focuser to absolute position, mm" msgstr "" -#: cmdlnopts.c:90 +#: cmdlnopts.c:91 msgid "move focuser to relative position, mm (only for standalone)" msgstr "" -#: cmdlnopts.c:92 +#: cmdlnopts.c:93 msgid "set wheel position" msgstr "" -#: cmdlnopts.c:94 +#: cmdlnopts.c:95 msgid "CMOS gain level" msgstr "" -#: cmdlnopts.c:95 +#: cmdlnopts.c:96 msgid "CMOS brightness level" msgstr "" -#: cmdlnopts.c:97 +#: cmdlnopts.c:98 msgid "logging file name (if run as server)" msgstr "" -#: cmdlnopts.c:98 +#: cmdlnopts.c:99 msgid "UNIX socket name" msgstr "" -#: cmdlnopts.c:99 +#: cmdlnopts.c:100 msgid "local INET socket port" msgstr "" -#: cmdlnopts.c:100 +#: cmdlnopts.c:101 msgid "local INET socket port to send/receive images" msgstr "" -#: cmdlnopts.c:101 +#: cmdlnopts.c:102 msgid "run as client" msgstr "" -#: cmdlnopts.c:102 +#: cmdlnopts.c:103 msgid "passive viewer (only get last images)" msgstr "" -#: cmdlnopts.c:103 +#: cmdlnopts.c:104 msgid "restart image server" msgstr "" #: cmdlnopts.c:106 +msgid "shared memory (with image data) key (default: 7777777" +msgstr "" + +#: cmdlnopts.c:109 msgid "Display image in OpenGL window" msgstr "" @@ -279,291 +283,291 @@ msgstr "" msgid "Can't save file with prefix %s" msgstr "" -#: ccdfunc.c:357 +#: ccdfunc.c:359 #, c-format msgid "File saved as '%s'" msgstr "" -#: ccdfunc.c:366 +#: ccdfunc.c:368 msgid "Error saving file" msgstr "" -#: ccdfunc.c:406 +#: ccdfunc.c:445 #, c-format msgid "Image stat:\n" msgstr "" -#: ccdfunc.c:414 +#: ccdfunc.c:453 msgid "Focuser device not pointed" msgstr "" -#: ccdfunc.c:421 +#: ccdfunc.c:460 msgid "No focusers found" msgstr "" -#: ccdfunc.c:452 -#, c-format -msgid "Found %d focusers, you point number %d" -msgstr "" - -#: ccdfunc.c:456 -msgid "Can't set active focuser number" -msgstr "" - -#: ccdfunc.c:470 -msgid "Can't get focuser limit positions" -msgstr "" - -#: ccdfunc.c:477 -msgid "Can't get current focuser position" -msgstr "" - #: ccdfunc.c:491 #, c-format -msgid "Can't set position %g: out of limits [%g, %g]" +msgid "Found %d focusers, you point number %d" msgstr "" #: ccdfunc.c:495 +msgid "Can't set active focuser number" +msgstr "" + +#: ccdfunc.c:509 +msgid "Can't get focuser limit positions" +msgstr "" + +#: ccdfunc.c:516 +msgid "Can't get current focuser position" +msgstr "" + +#: ccdfunc.c:530 +#, c-format +msgid "Can't set position %g: out of limits [%g, %g]" +msgstr "" + +#: ccdfunc.c:534 msgid "Can't home focuser" msgstr "" -#: ccdfunc.c:497 +#: ccdfunc.c:536 #, c-format msgid "Can't set position %g" msgstr "" -#: ccdfunc.c:505 +#: ccdfunc.c:544 msgid "Wheel device not pointed" msgstr "" -#: ccdfunc.c:512 +#: ccdfunc.c:551 msgid "No wheels found" msgstr "" -#: ccdfunc.c:543 +#: ccdfunc.c:582 #, c-format msgid "Found %d wheels, you point number %d" msgstr "" -#: ccdfunc.c:547 +#: ccdfunc.c:586 msgid "Can't set active wheel number" msgstr "" -#: ccdfunc.c:563 +#: ccdfunc.c:602 msgid "Can't get max wheel position" msgstr "" -#: ccdfunc.c:570 +#: ccdfunc.c:609 #, c-format msgid "Wheel position should be from 0 to %d" msgstr "" -#: ccdfunc.c:574 +#: ccdfunc.c:613 #, c-format msgid "Can't set wheel position %d" msgstr "" -#: ccdfunc.c:591 +#: ccdfunc.c:630 #, c-format msgid "%.1f seconds till exposition ends" msgstr "" -#: ccdfunc.c:606 +#: ccdfunc.c:645 msgid "Camera device not pointed" msgstr "" -#: ccdfunc.c:613 ccdfunc.c:614 +#: ccdfunc.c:652 ccdfunc.c:653 msgid "No cameras found" msgstr "" -#: ccdfunc.c:644 +#: ccdfunc.c:683 #, c-format msgid "Found %d cameras, you point number %d" msgstr "" -#: ccdfunc.c:648 +#: ccdfunc.c:687 msgid "Can't set active camera number" msgstr "" -#: ccdfunc.c:654 +#: ccdfunc.c:693 msgid "Can't set fan speed" msgstr "" -#: ccdfunc.c:655 +#: ccdfunc.c:694 #, c-format msgid "Set fan speed to %d" msgstr "" -#: ccdfunc.c:660 +#: ccdfunc.c:699 #, c-format msgid "Camera model: %s" msgstr "" -#: ccdfunc.c:661 +#: ccdfunc.c:700 #, c-format msgid "Pixel size: %g x %g" msgstr "" -#: ccdfunc.c:667 +#: ccdfunc.c:706 #, c-format msgid "Full array: %s" msgstr "" -#: ccdfunc.c:670 +#: ccdfunc.c:709 #, c-format msgid "Field of view: %s" msgstr "" -#: ccdfunc.c:673 +#: ccdfunc.c:712 #, c-format msgid "Current format: %s" msgstr "" -#: ccdfunc.c:676 +#: ccdfunc.c:715 #, c-format msgid "Can't set T to %g degC" msgstr "" -#: ccdfunc.c:684 +#: ccdfunc.c:723 #, c-format msgid "Shutter command: %s\n" msgstr "" -#: ccdfunc.c:686 +#: ccdfunc.c:725 #, c-format msgid "Can't run shutter command %s (unsupported?)" msgstr "" #. "Попытка сконфигурировать порт I/O как %d\n" -#: ccdfunc.c:690 +#: ccdfunc.c:729 #, c-format msgid "Try to configure I/O port as %d" msgstr "" -#: ccdfunc.c:692 +#: ccdfunc.c:731 msgid "Can't configure (unsupported?)" msgstr "" -#: ccdfunc.c:699 +#: ccdfunc.c:738 msgid "Can't get IOport state (unsupported?)" msgstr "" #. "Попытка записи %d в порт I/O\n" -#: ccdfunc.c:703 +#: ccdfunc.c:742 #, c-format msgid "Try to write %d to I/O port" msgstr "" -#: ccdfunc.c:705 +#: ccdfunc.c:744 msgid "Can't set IOport" msgstr "" -#: ccdfunc.c:712 +#: ccdfunc.c:751 #, c-format msgid "Set gain to %g" msgstr "" -#: ccdfunc.c:713 +#: ccdfunc.c:752 #, c-format msgid "Can't set gain to %g" msgstr "" -#: ccdfunc.c:718 +#: ccdfunc.c:757 #, c-format msgid "Set brightness to %g" msgstr "" -#: ccdfunc.c:719 +#: ccdfunc.c:758 #, c-format msgid "Can't set brightness to %g" msgstr "" -#: ccdfunc.c:725 server.c:251 +#: ccdfunc.c:764 server.c:312 #, c-format msgid "Can't set binning %dx%d" msgstr "" -#: ccdfunc.c:737 server.c:252 +#: ccdfunc.c:776 server.c:313 msgid "Can't set given geometry" msgstr "" -#: ccdfunc.c:741 +#: ccdfunc.c:780 #, c-format msgid "Can't set %d flushes" msgstr "" -#: ccdfunc.c:745 +#: ccdfunc.c:784 #, c-format msgid "Can't set exposure time to %f seconds" msgstr "" -#: ccdfunc.c:748 +#: ccdfunc.c:787 msgid "Can't change frame type" msgstr "" -#: ccdfunc.c:751 +#: ccdfunc.c:790 msgid "Can't set bit depth" msgstr "" -#: ccdfunc.c:753 +#: ccdfunc.c:792 msgid "Can't set readout speed" msgstr "" -#: ccdfunc.c:754 +#: ccdfunc.c:793 #, c-format msgid "Readout mode: %s" msgstr "" -#: ccdfunc.c:755 +#: ccdfunc.c:794 msgid "Only show statistics" msgstr "" #. GET binning should be AFTER setgeometry! -#: ccdfunc.c:757 +#: ccdfunc.c:796 msgid "Can't get current binning" msgstr "" #. Захват кадра %d\n -#: ccdfunc.c:781 +#: ccdfunc.c:821 #, c-format msgid "Capture frame %d" msgstr "" -#: ccdfunc.c:783 ccdfunc.c:857 server.c:137 +#: ccdfunc.c:823 ccdfunc.c:908 server.c:198 msgid "Can't start exposition" msgstr "" -#: ccdfunc.c:788 +#: ccdfunc.c:828 msgid "Can't capture image" msgstr "" -#: ccdfunc.c:791 +#: ccdfunc.c:831 msgid "Read grabbed image" msgstr "" -#: ccdfunc.c:795 ccdfunc.c:870 +#: ccdfunc.c:835 ccdfunc.c:921 msgid "Can't grab image" msgstr "" #. %d секунд до окончания паузы\n -#: ccdfunc.c:807 client.c:288 +#: ccdfunc.c:847 client.c:291 #, c-format msgid "%d seconds till pause ends\n" msgstr "" -#: ccdfunc.c:868 +#: ccdfunc.c:919 msgid "Some error when capture" msgstr "" -#: server.c:185 +#: server.c:246 msgid "No camera device" msgstr "" -#: client.c:275 +#: client.c:278 msgid "Can't make exposition" msgstr "" -#: client.c:304 +#: client.c:307 msgid "Server timeout" msgstr "" @@ -580,19 +584,19 @@ msgstr "" msgid "Histogram conversion: %s" msgstr "" -#: imageview.c:640 +#: imageview.c:689 msgid "Can't open OpenGL window, image preview will be inaccessible" msgstr "" -#: imageview.c:682 +#: imageview.c:731 #, c-format msgid "Equalization of histogram: %s" msgstr "" -#: imageview.c:682 +#: imageview.c:731 msgid "on" msgstr "" -#: imageview.c:682 +#: imageview.c:731 msgid "off" msgstr "" diff --git a/locale/ru/ru.po b/locale/ru/ru.po index 9f8b9e1..d5dc058 100644 --- a/locale/ru/ru.po +++ b/locale/ru/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" - "POT-Creation-Date: 2023-05-31 16:14+0300\n" + "POT-Creation-Date: 2023-12-14 16:52+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,13 +16,13 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n" "Content-Type: text/plain; charset=koi8-r\n" "Content-Transfer-Encoding: 8bit\n" -#: ccdfunc.c:591 +#: ccdfunc.c:630 #, c-format msgid "%.1f seconds till exposition ends" msgstr "%.1f " #. %d секунд до окончания паузы\n -#: ccdfunc.c:807 client.c:288 +#: ccdfunc.c:847 client.c:291 #, c-format msgid "%d seconds till pause ends\n" msgstr "%d \n" @@ -31,15 +31,15 @@ msgstr "%d msgid "Already initialized!" msgstr " !" -#: cmdlnopts.c:95 +#: cmdlnopts.c:96 msgid "CMOS brightness level" msgstr " CMOS" -#: cmdlnopts.c:94 +#: cmdlnopts.c:95 msgid "CMOS gain level" msgstr " Gain CMOS" -#: ccdfunc.c:606 +#: ccdfunc.c:645 msgid "Camera device not pointed" msgstr " " @@ -47,20 +47,20 @@ msgstr " msgid "Camera device unknown" msgstr " " -#: ccdfunc.c:660 +#: ccdfunc.c:699 #, c-format msgid "Camera model: %s" msgstr " : %s" -#: ccdfunc.c:788 +#: ccdfunc.c:828 msgid "Can't capture image" msgstr " " -#: ccdfunc.c:748 +#: ccdfunc.c:787 msgid "Can't change frame type" msgstr " " -#: ccdfunc.c:692 +#: ccdfunc.c:731 msgid "Can't configure (unsupported?)" msgstr " ( ?)" @@ -84,32 +84,32 @@ msgstr " msgid "Can't find wheel in plugin %s: %s" msgstr " %s: %s" -#: ccdfunc.c:699 +#: ccdfunc.c:738 msgid "Can't get IOport state (unsupported?)" msgstr " I/O ( ?)" #. GET binning should be AFTER setgeometry! -#: ccdfunc.c:757 +#: ccdfunc.c:796 msgid "Can't get current binning" msgstr " " -#: ccdfunc.c:477 +#: ccdfunc.c:516 msgid "Can't get current focuser position" msgstr " " -#: ccdfunc.c:470 +#: ccdfunc.c:509 msgid "Can't get focuser limit positions" msgstr " " -#: ccdfunc.c:563 +#: ccdfunc.c:602 msgid "Can't get max wheel position" msgstr " " -#: ccdfunc.c:795 ccdfunc.c:870 +#: ccdfunc.c:835 ccdfunc.c:921 msgid "Can't grab image" msgstr " " -#: ccdfunc.c:495 +#: ccdfunc.c:534 msgid "Can't home focuser" msgstr " " @@ -117,15 +117,15 @@ msgstr " msgid "Can't init mutex!" msgstr " !" -#: client.c:275 +#: client.c:278 msgid "Can't make exposition" msgstr " " -#: imageview.c:640 +#: imageview.c:689 msgid "Can't open OpenGL window, image preview will be inaccessible" msgstr " OpenGL, " -#: ccdfunc.c:686 +#: ccdfunc.c:725 #, c-format msgid "Can't run shutter command %s (unsupported?)" msgstr " %s ( ?)" @@ -136,141 +136,141 @@ msgstr " msgid "Can't save file with prefix %s" msgstr " %s" -#: ccdfunc.c:741 +#: ccdfunc.c:780 #, c-format msgid "Can't set %d flushes" msgstr " %d " -#: ccdfunc.c:705 +#: ccdfunc.c:744 msgid "Can't set IOport" msgstr " I/O" -#: ccdfunc.c:676 +#: ccdfunc.c:715 #, c-format msgid "Can't set T to %g degC" msgstr " %g " -#: ccdfunc.c:648 +#: ccdfunc.c:687 msgid "Can't set active camera number" msgstr " " -#: ccdfunc.c:456 +#: ccdfunc.c:495 msgid "Can't set active focuser number" msgstr " " -#: ccdfunc.c:547 +#: ccdfunc.c:586 msgid "Can't set active wheel number" msgstr " " -#: ccdfunc.c:725 server.c:251 +#: ccdfunc.c:764 server.c:312 #, c-format msgid "Can't set binning %dx%d" msgstr " %dx%d" -#: ccdfunc.c:751 +#: ccdfunc.c:790 msgid "Can't set bit depth" msgstr " " -#: ccdfunc.c:719 +#: ccdfunc.c:758 #, c-format msgid "Can't set brightness to %g" msgstr " %g" -#: ccdfunc.c:745 +#: ccdfunc.c:784 #, c-format msgid "Can't set exposure time to %f seconds" msgstr " %f " -#: ccdfunc.c:654 +#: ccdfunc.c:693 msgid "Can't set fan speed" msgstr " " -#: ccdfunc.c:713 +#: ccdfunc.c:752 #, c-format msgid "Can't set gain to %g" msgstr " Gain %g" -#: ccdfunc.c:737 server.c:252 +#: ccdfunc.c:776 server.c:313 msgid "Can't set given geometry" msgstr " " -#: ccdfunc.c:497 +#: ccdfunc.c:536 #, c-format msgid "Can't set position %g" msgstr " %g" -#: ccdfunc.c:491 +#: ccdfunc.c:530 #, c-format msgid "Can't set position %g: out of limits [%g, %g]" msgstr " %g: [%g, %g]" -#: ccdfunc.c:753 +#: ccdfunc.c:792 msgid "Can't set readout speed" msgstr " " -#: ccdfunc.c:574 +#: ccdfunc.c:613 #, c-format msgid "Can't set wheel position %d" msgstr " %d" -#: ccdfunc.c:783 ccdfunc.c:857 server.c:137 +#: ccdfunc.c:823 ccdfunc.c:908 server.c:198 msgid "Can't start exposition" msgstr " " #. Захват кадра %d\n -#: ccdfunc.c:781 +#: ccdfunc.c:821 #, c-format msgid "Capture frame %d" msgstr " %d" -#: ccdfunc.c:673 +#: ccdfunc.c:712 #, c-format msgid "Current format: %s" msgstr "" -#: cmdlnopts.c:106 +#: cmdlnopts.c:109 msgid "Display image in OpenGL window" msgstr " OpenGL" -#: imageview.c:682 +#: imageview.c:731 #, c-format msgid "Equalization of histogram: %s" msgstr " : %s" -#: ccdfunc.c:366 +#: ccdfunc.c:368 msgid "Error saving file" msgstr " " -#: ccdfunc.c:670 +#: ccdfunc.c:709 #, c-format msgid "Field of view: %s" msgstr " : %s" -#: ccdfunc.c:357 +#: ccdfunc.c:359 #, c-format msgid "File saved as '%s'" msgstr " '%s'" -#: ccdfunc.c:414 +#: ccdfunc.c:453 msgid "Focuser device not pointed" msgstr " " -#: ccdfunc.c:644 +#: ccdfunc.c:683 #, c-format msgid "Found %d cameras, you point number %d" msgstr " %d , %d" -#: ccdfunc.c:452 +#: ccdfunc.c:491 #, c-format msgid "Found %d focusers, you point number %d" msgstr " %d , %d" -#: ccdfunc.c:543 +#: ccdfunc.c:582 #, c-format msgid "Found %d wheels, you point number %d" msgstr " %d , %d" -#: ccdfunc.c:667 +#: ccdfunc.c:706 #, c-format msgid "Full array: %s" msgstr " : %s" @@ -280,321 +280,325 @@ msgstr " msgid "Histogram conversion: %s" msgstr " : %s" -#: ccdfunc.c:406 +#: ccdfunc.c:445 #, c-format msgid "Image stat:\n" msgstr " : \n" -#: cmdlnopts.c:67 +#: cmdlnopts.c:68 msgid "N flushes before exposing (default: 1)" msgstr "N ( : 1)" -#: server.c:185 +#: server.c:246 msgid "No camera device" msgstr " " -#: ccdfunc.c:613 ccdfunc.c:614 +#: ccdfunc.c:652 ccdfunc.c:653 msgid "No cameras found" msgstr " " -#: ccdfunc.c:421 +#: ccdfunc.c:460 msgid "No focusers found" msgstr " " -#: ccdfunc.c:512 +#: ccdfunc.c:551 msgid "No wheels found" msgstr " " -#: ccdfunc.c:755 +#: ccdfunc.c:794 msgid "Only show statistics" msgstr " " -#: ccdfunc.c:661 +#: ccdfunc.c:700 #, c-format msgid "Pixel size: %g x %g" msgstr " : %g x %g" -#: ccdfunc.c:791 +#: ccdfunc.c:831 msgid "Read grabbed image" msgstr " " -#: ccdfunc.c:754 +#: ccdfunc.c:793 #, c-format msgid "Readout mode: %s" msgstr " : %s" -#: client.c:304 +#: client.c:307 msgid "Server timeout" msgstr " " -#: ccdfunc.c:718 +#: ccdfunc.c:757 #, c-format msgid "Set brightness to %g" msgstr " %g" -#: ccdfunc.c:655 +#: ccdfunc.c:694 #, c-format msgid "Set fan speed to %d" msgstr " %d" -#: ccdfunc.c:712 +#: ccdfunc.c:751 #, c-format msgid "Set gain to %g" msgstr " Gain %g" -#: ccdfunc.c:684 +#: ccdfunc.c:723 #, c-format msgid "Shutter command: %s\n" msgstr " : %s\n" -#: ccdfunc.c:868 +#: ccdfunc.c:919 msgid "Some error when capture" msgstr "" #. "Попытка сконфигурировать порт I/O как %d\n" -#: ccdfunc.c:690 +#: ccdfunc.c:729 #, c-format msgid "Try to configure I/O port as %d" msgstr " I/O %d" #. "Попытка записи %d в порт I/O\n" -#: ccdfunc.c:703 +#: ccdfunc.c:742 #, c-format msgid "Try to write %d to I/O port" msgstr " %d I/O" -#: cmdlnopts.c:98 +#: cmdlnopts.c:99 msgid "UNIX socket name" msgstr " UNIX-" -#: ccdfunc.c:505 +#: ccdfunc.c:544 msgid "Wheel device not pointed" msgstr " " -#: ccdfunc.c:570 +#: ccdfunc.c:609 #, c-format msgid "Wheel position should be from 0 to %d" msgstr " 0 %d" -#: cmdlnopts.c:74 +#: cmdlnopts.c:75 msgid "absolute (not divided by binning!) frame X0 coordinate (-1 - all " "with overscan)" msgstr " ( !) X0 (-1 - " ")" -#: cmdlnopts.c:76 +#: cmdlnopts.c:77 msgid "absolute frame X1 coordinate (-1 - all with overscan)" msgstr " X1 (-1 - )" -#: cmdlnopts.c:75 +#: cmdlnopts.c:76 msgid "absolute frame Y0 coordinate (-1 - all with overscan)" msgstr " Y0 (-1 - )" -#: cmdlnopts.c:77 +#: cmdlnopts.c:78 msgid "absolute frame Y1 coordinate (-1 - all with overscan)" msgstr " Y1 (-1 - )" -#: cmdlnopts.c:63 +#: cmdlnopts.c:64 msgid "add records to header from given file[s]" msgstr " FITS- " -#: cmdlnopts.c:45 +#: cmdlnopts.c:46 msgid "camera device number (if many: 0, 1, 2 etc)" msgstr " " -#: cmdlnopts.c:41 +#: cmdlnopts.c:42 msgid "camera device plugin (e.g. devfli.so)" msgstr " (, devfli.so)" -#: cmdlnopts.c:73 +#: cmdlnopts.c:74 msgid "cancel current exposition" msgstr " " -#: cmdlnopts.c:80 +#: cmdlnopts.c:81 msgid "close shutter" msgstr " " -#: cmdlnopts.c:40 +#: cmdlnopts.c:41 msgid "common device plugin (e.g devfli.so)" msgstr " (, devfli.so)" -#: cmdlnopts.c:87 +#: cmdlnopts.c:88 msgid "configure I/O port pins to given value (decimal number, pin1 is LSB, " "1 == output, 0 == input)" msgstr " I/O ( , " "pin1 - , 1 - , 0 - )" -#: cmdlnopts.c:53 +#: cmdlnopts.c:54 msgid "fast readout mode" msgstr " " -#: cmdlnopts.c:46 +#: cmdlnopts.c:47 msgid "filter wheel device number (if many: 0, 1, 2 etc)" msgstr " " -#: cmdlnopts.c:47 +#: cmdlnopts.c:48 msgid "focuser device number (if many: 0, 1, 2 etc)" msgstr " " -#: cmdlnopts.c:42 +#: cmdlnopts.c:43 msgid "focuser device plugin (e.g. devzwo.so)" msgstr " (, devzwo.so)" -#: cmdlnopts.c:83 +#: cmdlnopts.c:84 msgid "get value of I/O port pins" msgstr " I/O" -#: cmdlnopts.c:68 +#: cmdlnopts.c:69 msgid "horizontal binning to N pixels" msgstr " N " -#: cmdlnopts.c:59 +#: cmdlnopts.c:60 msgid "instrument name" msgstr " " -#: cmdlnopts.c:44 +#: cmdlnopts.c:45 msgid "list connected devices" msgstr " " -#: cmdlnopts.c:99 +#: cmdlnopts.c:100 msgid "local INET socket port" msgstr " " -#: cmdlnopts.c:100 +#: cmdlnopts.c:101 #, fuzzy msgid "local INET socket port to send/receive images" msgstr " " -#: cmdlnopts.c:97 +#: cmdlnopts.c:98 msgid "logging file name (if run as server)" msgstr " ( )" -#: cmdlnopts.c:71 +#: cmdlnopts.c:72 msgid "make pause for N seconds between expositions" msgstr " N " -#: cmdlnopts.c:70 +#: cmdlnopts.c:71 msgid "make series of N frames" msgstr " N " -#: cmdlnopts.c:89 +#: cmdlnopts.c:90 msgid "move focuser to absolute position, mm" msgstr " , " -#: cmdlnopts.c:90 +#: cmdlnopts.c:91 msgid "move focuser to relative position, mm (only for standalone)" msgstr " , ( /" ")" -#: cmdlnopts.c:84 +#: cmdlnopts.c:85 msgid "move stepper motor asynchronous" msgstr " " -#: cmdlnopts.c:51 +#: cmdlnopts.c:52 msgid "not open shutter, when exposing (\"dark frames\")" msgstr " (\"\")" -#: cmdlnopts.c:60 +#: cmdlnopts.c:61 msgid "object name" msgstr " " -#: cmdlnopts.c:58 +#: cmdlnopts.c:59 msgid "object type (neon, object, flat etc)" msgstr " (neon, object, flat ..)" -#: cmdlnopts.c:61 +#: cmdlnopts.c:62 msgid "observers' names" msgstr " " -#: cmdlnopts.c:62 +#: cmdlnopts.c:63 msgid "observing program name" msgstr " " -#: imageview.c:682 +#: imageview.c:731 msgid "off" msgstr "" -#: imageview.c:682 +#: imageview.c:731 msgid "on" msgstr "" -#: cmdlnopts.c:79 +#: cmdlnopts.c:80 msgid "open shutter" msgstr " " -#: cmdlnopts.c:64 +#: cmdlnopts.c:65 msgid "output file name" msgstr " " -#: cmdlnopts.c:102 +#: cmdlnopts.c:103 msgid "passive viewer (only get last images)" msgstr "" -#: cmdlnopts.c:57 +#: cmdlnopts.c:58 msgid "program author" msgstr " " -#: cmdlnopts.c:103 +#: cmdlnopts.c:104 msgid "restart image server" msgstr " " -#: cmdlnopts.c:49 +#: cmdlnopts.c:50 msgid "rewrite output file if exists" msgstr " " -#: cmdlnopts.c:101 +#: cmdlnopts.c:102 msgid "run as client" msgstr " " -#: cmdlnopts.c:82 +#: cmdlnopts.c:83 msgid "run exposition on HIGH @ pin5 I/O port" msgstr "" -#: cmdlnopts.c:81 +#: cmdlnopts.c:82 msgid "run exposition on LOW @ pin5 I/O port" msgstr "" -#: cmdlnopts.c:52 +#: cmdlnopts.c:53 msgid "run in 8-bit mode" msgstr "8- " -#: cmdlnopts.c:54 +#: cmdlnopts.c:55 msgid "set CCD temperature to given value (degr C)" msgstr " ()" -#: cmdlnopts.c:86 +#: cmdlnopts.c:87 msgid "set I/O port pins to given value (decimal number, pin1 is LSB)" msgstr " I/O ( , pin1 - )" -#: cmdlnopts.c:72 +#: cmdlnopts.c:73 msgid "set exposure time to given value (seconds!)" msgstr " (!)" -#: cmdlnopts.c:55 +#: cmdlnopts.c:56 msgid "set fan speed (0 - off, 1 - low, 2 - high)" msgstr " (0 - , 1 - , 2 - )" -#: cmdlnopts.c:92 +#: cmdlnopts.c:93 msgid "set wheel position" msgstr " " -#: cmdlnopts.c:48 +#: cmdlnopts.c:106 +msgid "shared memory (with image data) key (default: 7777777" +msgstr "" + +#: cmdlnopts.c:49 msgid "show this help" msgstr " " -#: cmdlnopts.c:50 +#: cmdlnopts.c:51 msgid "verbose level (-V - messages, -VV - debug, -VVV - all shit)" msgstr " (-V - , -VV - , -VVV - )" -#: cmdlnopts.c:69 +#: cmdlnopts.c:70 msgid "vertical binning to N pixels" msgstr " N " -#: cmdlnopts.c:65 +#: cmdlnopts.c:66 msgid "wait while exposition ends" msgstr ", " -#: cmdlnopts.c:43 +#: cmdlnopts.c:44 msgid "wheel device plugin (e.g. devdummy.so)" msgstr " (, devdummy.so)" diff --git a/server.c b/server.c index 09df7a2..3ea18b2 100644 --- a/server.c +++ b/server.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include @@ -46,6 +48,9 @@ static float focmaxpos = 0., focminpos = 0.; // focuser extremal positions static int wmaxpos = 0.; // wheel max pos static float tremain = 0.; // time when capture done +// IPC key for shared memory +static key_t shmkey = IPC_PRIVATE; + typedef struct{ const char *key; const char *help; @@ -88,6 +93,7 @@ strpair allcommands[] = { { CMD_PROGRAM, "FITS 'PROG-ID' field" }, { CMD_RESTART, "restart server" }, { CMD_REWRITE, "rewrite file (if give `filename`, not `filenameprefix`" }, + { CMD_SHMEMKEY, "get shared memory key" }, { CMD_SHUTTER, "camera shutter's operations" }, { CMD_CAMTEMPER, "camera chip temperature" }, { CMD_TREMAIN, "time (in seconds) of exposition remained" }, @@ -112,16 +118,71 @@ static void unlock(){ if(pthread_mutex_unlock(&locmutex)) ERR("Can't unlock mutex"); } -static IMG ima = {0}; +static IMG *ima = NULL; + +/** + * @brief getshm - get shared memory segment for image + * @param imsize - size of image data (in bytes) + * @return + */ +static IMG *getshm(key_t key, size_t imsize){ + size_t shmsize = sizeof(IMG) + imsize; + shmsize = 1024 * (1 + shmsize / 1024); + DBG("Allocate %zd bytes in shared memory", shmsize); + int shmid = -1; + int flags = (imsize) ? IPC_CREAT | 0666 : 0; + shmid = shmget(key, 0, flags); + if(shmid < 0){ + WARN("Can't get shared memory segment %d", key); + return NULL; + } + if(imsize){ // check if segment exists and its size equal to needs + struct shmid_ds buf; + if(shmctl(shmid, IPC_STAT, &buf) > -1 && shmsize != buf.shm_segsz){ // remove already existing segment + DBG("Need to remove already existing segment"); + shmctl(shmid, IPC_RMID, NULL); + } + shmid = shmget(key, shmsize, flags); + if(shmid < 0){ + WARN("Can't create shared memory segment %d", key); + return NULL; + } + } + flags = (imsize) ? 0 : SHM_RDONLY; // client opens memory in readonly mode + IMG *ptr = shmat(shmid, NULL, flags); + if(ptr == (void*)-1){ + WARN("Can't attach SHM segment %d", key); + return NULL; + } + if(!imsize){ + if(ptr->MAGICK != SHM_MAGIC){ + WARNX("Shared memory %d isn't belongs to image server", key); + shmdt(ptr); + return NULL; + } + return ptr; + } + bzero(ptr, sizeof(IMG)); + ptr->data = (void*)((uint8_t*)ptr + sizeof(IMG)); + ptr->MAGICK = SHM_MAGIC; + shmkey = key; + return ptr; +} + static void fixima(){ FNAME(); if(!camera) return; int raw_width = curformat.w / GP->hbin, raw_height = curformat.h / GP->vbin; - if(!ima.data) ima.data = MALLOC(uint16_t, camera->array.h * camera->array.w); - if(ima.data && raw_width == ima.w && raw_height == ima.h) return; // all OK + // allocate memory for largest possible image + if(!ima) ima = getshm(GP->shmkey, camera->array.h * camera->array.w * 2); + if(!ima) ERRX("Can't allocate memory for image"); + if(raw_width == ima->w && raw_height == ima->h) return; // all OK DBG("curformat: %dx%d", curformat.w, curformat.h); - ima.h = raw_height; - ima.w = raw_width; + ima->h = raw_height; + ima->w = raw_width; + if(!camera->getbitpix(&ima->bitpix)) ima->bitpix = 16; + if(ima->bitpix < 8 || ima->bitpix > 16) ima->bitpix = 16; // use maximum in any strange cases + ima->bytelen = raw_height * raw_width * getNbytes(ima); DBG("new image: %dx%d", raw_width, raw_height); } @@ -155,19 +216,19 @@ static inline void cameracapturestate(){ // capturing - wait for exposition ends TIMESTAMP("Capture ready"); tremain = 0.; // now save frame - if(!ima.data) LOGERR("Can't save image: not initialized"); + if(!ima->data) LOGERR("Can't save image: not initialized"); else{ TIMESTAMP("start capture"); - if(!camera->capture(&ima)){ + if(!camera->capture(ima)){ LOGERR("Can't capture image"); camstate = CAMERA_ERROR; return; }else{ if(lastfile){ TIMESTAMP("Calc stat"); - calculate_stat(&ima); + calculate_stat(ima); } - if(saveFITS(&ima, &lastfile)){ + if(saveFITS(ima, &lastfile)){ DBG("LAST file name changed"); } TIMESTAMP("Image saved"); @@ -287,6 +348,15 @@ static hresult restarthandler(_U_ int fd, _U_ const char *key, _U_ const char *v /******************************************************************************* *************************** CCD/CMOS handlers ********************************* ******************************************************************************/ +// image size +static hresult imsizehandler(int fd, const char *key, _U_ const char *val){ + char buf[64]; + // send image width/height in pixels + if(0 == strcmp(key, CMD_IMHEIGHT)) snprintf(buf, 63, CMD_IMHEIGHT "=%d", ima->h); + else snprintf(buf, 63, CMD_IMWIDTH "=%d", ima->w); + if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED; + return RESULT_SILENCE; +} static hresult camlisthandler(int fd, _U_ const char *key, _U_ const char *val){ char buf[BUFSIZ], modname[256]; for(int i = 0; i < camera->Ndevices; ++i){ @@ -910,11 +980,11 @@ static hresult helphandler(int fd, _U_ const char *key, _U_ const char *val){ return RESULT_SILENCE; } -static hresult imsizehandler(int fd, const char *key, _U_ const char *val){ +// shared memory key +static hresult shmemkeyhandler(int fd, _U_ const char *key, _U_ const char *val){ char buf[64]; - // send image width/height in pixels - if(0 == strcmp(key, CMD_IMHEIGHT)) snprintf(buf, 63, CMD_IMHEIGHT "=%d", ima.h); - else snprintf(buf, 63, CMD_IMWIDTH "=%d", ima.w); + if(shmkey == IPC_PRIVATE) return RESULT_FAIL; + snprintf(buf, 63, CMD_SHMEMKEY "=%d", shmkey); if(!sendstrmessage(fd, buf)) return RESULT_DISCONNECTED; return RESULT_SILENCE; } @@ -971,6 +1041,7 @@ static handleritem items[] = { {chkcc, formathandler, CMD_FRAMEMAX}, {chkcc, nflusheshandler, CMD_NFLUSHES}, {chkcam, expstatehandler, CMD_EXPSTATE}, + {chktrue,shmemkeyhandler, CMD_SHMEMKEY}, {chktrue,imsizehandler, CMD_IMWIDTH}, {chktrue,imsizehandler, CMD_IMHEIGHT}, {chkcc, nameprefixhandler, CMD_FILENAMEPREFIX}, @@ -998,6 +1069,17 @@ static handleritem items[] = { #define CLBUFSZ BUFSIZ +// send image as raw data +static void sendimage(int client){ + if(ima->h < 1 || ima->w < 1) return; + senddata(client, ima, sizeof(IMG)); + senddata(client, ima->data, ima->bytelen); + /*void *mem = malloc(ima->bytelen); + memcpy(mem, ima->data, ima->bytelen); + senddata(client, mem, ima->bytelen); + FREE(mem);*/ +} + void server(int sock, int imsock){ DBG("sockfd=%d, imsockfd=%d", sock, imsock); if(sock < 0) ERRX("server(): need at least command socket fd"); @@ -1046,9 +1128,7 @@ void server(int sock, int imsock){ DBG("client=%d", client); if(client > -1){ DBG("client fd: %d", client); - // send image as raw data w*h*2 - if(ima.data && ima.h > 0 && ima.w > 0) - sendimage(client, ima.data, 2*ima.h*ima.w); + sendimage(client); close(client); DBG("%d closed", client); }else{WARN("accept()"); DBG("disconnected");} @@ -1075,6 +1155,7 @@ void server(int sock, int imsock){ } // process some data & send messages to ALL if(camstate == CAMERA_FRAMERDY || camstate == CAMERA_ERROR){ + if(camstate == CAMERA_FRAMERDY) ima->timestamp = time(NULL); // set timestamp char buff[PATH_MAX+32]; snprintf(buff, PATH_MAX, CMD_EXPSTATE "=%d", camstate); DBG("Send %s to %d clients", buff, nfd - 2); diff --git a/server.h b/server.h index 97bad25..a2ba9d9 100644 --- a/server.h +++ b/server.h @@ -40,6 +40,8 @@ char *makeabspath(const char *path, int shouldbe); // get image size in pixels #define CMD_IMWIDTH "imwidth" #define CMD_IMHEIGHT "imheight" +// get shared memory key +#define CMD_SHMEMKEY "shmemkey" // CCD/CMOS #define CMD_CAMLIST "camlist" diff --git a/socket.c b/socket.c index cbb22ac..253ea4f 100644 --- a/socket.c +++ b/socket.c @@ -161,13 +161,13 @@ int start_socket(int isserver){ } // send image data to client -int sendimage(int fd, uint16_t *data, int l){ - DBG("fd=%d, l=%d", fd, l); +int senddata(int fd, void *data, size_t l){ + DBG("fd=%d, l=%zd", fd, l); if(fd < 1 || !data || l < 1) return TRUE; // empty message - DBG("send new image (size=%d) to fd %d", l, fd); + DBG("send new data (size=%zd) to fd %d", l, fd); //strncpy((char*)data, "TEST image data\n", 17); //l = 16; - if(l != send(fd, data, l, MSG_NOSIGNAL)){ + if(l != (size_t)send(fd, data, l, MSG_NOSIGNAL)){ WARN("write()"); LOGWARN("write()"); return FALSE; @@ -183,7 +183,7 @@ int sendmessage(int fd, const char *msg, int l){ static char *tmpbuf = NULL; static int buflen = 0; if(l + 1 > buflen){ - buflen += 1024; + buflen = 1024 * (1 + l/1024); tmpbuf = realloc(tmpbuf, buflen); } DBG("send to fd %d: %s [%d]", fd, msg, l); diff --git a/socket.h b/socket.h index ff759d4..0d7764b 100644 --- a/socket.h +++ b/socket.h @@ -71,7 +71,7 @@ typedef struct{ int open_socket(int isserver, char *path, int isnet); int start_socket(int server); -int sendimage(int fd, uint16_t *data, int l); +int senddata(int fd, void *data, size_t l); int sendmessage(int fd, const char *msg, int l); int sendstrmessage(int fd, const char *msg); char *get_keyval(char *keyval);