From 13d623fc8afdb560251c80f0cb26bc96fd770f8b Mon Sep 17 00:00:00 2001 From: eddyem Date: Thu, 2 Feb 2017 18:25:59 +0300 Subject: [PATCH] little fixes --- Makefile | 2 +- cmdlnopts.c | 4 ++- cmdlnopts.h | 1 + imfunctions.c | 98 ++++++++++++++++++++++++++++++++++++++++----------- imfunctions.h | 3 ++ main.c | 17 +++++++-- parseargs.c | 2 +- term.c | 29 +++++++++------ 8 files changed, 119 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index f479fd9..82d7581 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # run `make DEF=...` to add extra defines PROGRAM := sbig340 -LDFLAGS := -ltiff -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all +LDFLAGS := -ltiff -lm -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all SRCS := $(wildcard *.c) DEFINES := $(DEF) -D_XOPEN_SOURCE=1111 -DEBUG OBJDIR := mk diff --git a/cmdlnopts.c b/cmdlnopts.c index bc58dd6..52a4235 100644 --- a/cmdlnopts.c +++ b/cmdlnopts.c @@ -54,7 +54,8 @@ glob_pars const Gdefault = { .takeimg = 0, .imtype = "a", .imstoretype = NULL, - .outpfname = "output.tiff" + .outpfname = "output.tiff", + .dumpbin = 0 }; /* @@ -81,6 +82,7 @@ myoption cmdlnopts[] = { {"imtype", NEED_ARG, NULL, 'T', arg_string, APTR(&G.imtype), _("image type: light (l, L), autodark (a, A), dark (d, D)")}, {"storetype",NEED_ARG, NULL, 'S', arg_string, APTR(&G.imstoretype),_("'overwrite'/'rewrite' to rewrite existing image, 'enumerate'/'numerate' to use given filename as base for series")}, {"output", NEED_ARG, NULL, 'o', arg_string, APTR(&G.outpfname), _("output file name (default: output.tiff)")}, + {"dump", NO_ARGS, NULL, 0, arg_none, APTR(&G.dumpbin), _("dump binary data into file `dump.bin`")}, // simple integer parameter with obligatory arg: end_option }; diff --git a/cmdlnopts.h b/cmdlnopts.h index 5c400b1..55ca722 100644 --- a/cmdlnopts.h +++ b/cmdlnopts.h @@ -46,6 +46,7 @@ typedef struct{ char *imtype; // image type (light, autodark, dark) char *imstoretype; // "overwrite" (or "rewrite"), "normal" (or NULL), "enumerate" (or "numerate") char *outpfname; // output filename for image storing + int dumpbin; // dump raw binary data char** rest_pars; // the rest parameters: array of char* } glob_pars; diff --git a/imfunctions.c b/imfunctions.c index 8dc1394..dd7bbec 100644 --- a/imfunctions.c +++ b/imfunctions.c @@ -26,7 +26,7 @@ #include "term.h" #include // strncasecmp #include // save tiff - +#include // find the first non-exists filename char *make_filename(char *outfile, char *ext){ @@ -111,18 +111,13 @@ int writetiff(imstorage *img){ TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 16); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1); - TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT); + TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE); - //tstrip_t strip = 0; for (y = 0; y < H; ++y, data += W){ -TIFFWriteScanline(image, data, y, 0); - /* if(TIFFWriteEncodedStrip(image, strip, data, W) < 0){ - ret = 0; - goto done; - }*/ + TIFFWriteScanline(image, data, y, 0); } done: @@ -130,6 +125,64 @@ done: return ret; } +void print_stat(imstorage *img){ + size_t size = img->W*img->H, i, Noverld = 0L, N = 0L; + double pv, sum=0., sum2=0., sz = (double)size, tres; + uint16_t *ptr = img->imdata, val, valoverld; + uint16_t max = 0, min = 65535; + valoverld = min - 5; + for(i = 0; i < size; i++, ptr++){ + val = *ptr; + pv = (double) val; + sum += pv; + sum2 += (pv * pv); + if(max < val) max = val; + if(min > val) min = val; + if(val >= valoverld) Noverld++; + } + printf(_("Image stat:\n")); + double avr = sum/sz, std = sqrt(fabs(sum2/sz - avr*avr)); + printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr, std, Noverld); + printf("max = %u, min = %u, W*H = %ld\n", max, min, size); + Noverld = 0L; + ptr = img->imdata; sum = 0.; sum2 = 0.; + tres = avr + 3. * std; // max treshold == 3sigma + for(i = 0; i < size; i++, ptr++){ + val = *ptr; + pv = (double) val; + if(pv > tres){ + Noverld++; // now this is an amount of overload pixels + continue; + } + sum += pv; + sum2 += (pv * pv); + N++; + } + if(!N){ + printf("All pixels are over 3sigma threshold!\n"); + return; + } + sz = (double)N; + avr = sum/sz; std = sqrt(fabs(sum2/sz - avr*avr)); + printf("At 3sigma: Noverload = %ld, avr = %.3f, std = %.3f\n", Noverld, avr, std); +} + + +/** + * Receive image data & fill img->imdata + * @return imdata or NULL if failed + */ +uint16_t *get_imdata(imstorage *img){ + if(wait4image()) return NULL; + DBG("OK, get image"); + uint16_t *imdata = get_image(img); + if(!imdata){ + WARNX(_("Error readout")); + return NULL; + } + img->imdata = imdata; + return imdata; +} /** * Save image @@ -137,20 +190,23 @@ done: * @return 0 if all OK */ int store_image(imstorage *img){ - if(wait4image()) return 1; - DBG("OK, get image"); - uint16_t *imdata = get_image(img); - if(!imdata){ - WARNX(_("Error readout")); - return 2; - } - img->imdata = imdata; + if(!img->imdata && !get_imdata(img)) return 1; green("Save image into %s\n", img->imname); - /*int f = open(img->imname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if(f){ - DBG("%zd", write(f, img->imdata, img->W*img->H*2)); - close(f); - }*/ if(!writetiff(img)) return 3; + if(img->dump){ + int f = open("dump.bin", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if(f){ + size_t S = img->W*img->H*2; + if(S != (size_t)write(f, img->imdata, S)){ + WARN(_("Error writting `dump.bin`")); + return 4; + } + green(_("Image dump stored in `dump.bin`\n")); + close(f); + }else{ + WARN(_("Can't make dump")); + return 5; + } + } return 0; } diff --git a/imfunctions.h b/imfunctions.h index 5376c59..9f27669 100644 --- a/imfunctions.h +++ b/imfunctions.h @@ -49,6 +49,7 @@ typedef struct{ int binning; image_type imtype; double exptime; + int dump; imsubframe *subframe; size_t W, H; // image size uint16_t *imdata; // image data itself @@ -56,5 +57,7 @@ typedef struct{ imstorage *chk_storeimg(char *filename, char* store); int store_image(imstorage *filename); +void print_stat(imstorage *img); +uint16_t *get_imdata(imstorage *img); #endif // __IMFUNCTIONS_H__ diff --git a/main.c b/main.c index 2662db2..0be9199 100644 --- a/main.c +++ b/main.c @@ -65,13 +65,21 @@ int main(int argc, char **argv){ } imstorage *img = chk_storeimg(G->outpfname, G->imstoretype); if(img){ + if(G->dumpbin) img->dump = 1; img->subframe = F; img->exptime = G->exptime; img->binning = G->binning; - if(start_exposition(img, G->imtype)) + if(start_exposition(img, G->imtype)){ WARNX(_("Error starting exposition")); - else if(store_image(img)) - WARNX(_("Error storing image %s"), img->imname); + }else{ + if(!get_imdata(img)){ + WARNX(_("Error image transfer")); + }else{ + print_stat(img); + if(store_image(img)) + WARNX(_("Error storing image %s"), img->imname); + } + } FREE(img->imname); FREE(img->imdata); FREE(img); @@ -83,4 +91,7 @@ int main(int argc, char **argv){ if(G->terminal) run_terminal(); // non-echo terminal mode if(G->daemon) daemonize(); } + if(!G->shutter_cmd){ // close shutter if there wasn't direct command to do something else + shutter_command("ck"); + } } diff --git a/parseargs.c b/parseargs.c index 10959bb..b235752 100644 --- a/parseargs.c +++ b/parseargs.c @@ -286,7 +286,7 @@ void parseargs(int *argc, char ***argv, myoption *options){ else optind = get_optind(opt, options); } opts = &options[optind]; - if(opt == 0 && opts->has_arg == NO_ARGS) continue; // only long option changing integer flag + // if(opt == 0 && opts->has_arg == NO_ARGS) continue; // only long option changing integer flag // now check option if(opts->has_arg == NEED_ARG || opts->has_arg == MULT_PAR) if(!optarg) showhelp(optind, options); // need argument diff --git a/term.c b/term.c index 1d35cf9..3e564aa 100644 --- a/term.c +++ b/term.c @@ -506,9 +506,11 @@ int start_exposition(imstorage *im, char *imtype){ WARNX(_("Wrong image type: %s, should be \"autodark\", \"light\" or \"dark\""), imtype); return 6; } - if(shutter_command("ok")){ // open shutter - WARNX(_("Can't open shutter")); - return 8; + if(it != IMTYPE_DARK){ + if(shutter_command("ok")){ // open shutter + WARNX(_("Can't open shutter")); + return 8; + } } green("Start expose for %gseconds, mode \"%s\", %s image\n", exptime, m, b); if(send_data(cmd, 6)){ @@ -543,13 +545,13 @@ int start_exposition(imstorage *im, char *imtype){ return 0; } +static char indi[] = "|/-\\"; /** * Wait till image ready * @return 0 if all OK */ int wait4image(){ uint8_t rd = 0; - char indi[] = "|/-\\"; char *iptr = indi; int stage = 1; // 1 - exp in progress, 2 - readout, 3 - done printf("\nExposure in progress "); @@ -591,6 +593,7 @@ int wait4image(){ * @return array with image data (allocated here) or NULL */ uint16_t *get_image(imstorage *img){ + char *iptr = indi; size_t L = img->W * img->H, rest = L * 2; // rest is datasize in bytes uint16_t *buff = MALLOC(uint16_t, L); if(TRANS_SUCCEED != send_cmd_cs(CMD_XFER_IMAGE)){ @@ -617,7 +620,7 @@ uint16_t *get_image(imstorage *img){ l -= r; } }while(l && dtime() - d0 < IMTRANS_TMOUT); - DBG("got: %zd", got); + //DBG("got: %zd", got); if(got < 3){ cs = IMTRANS_STOP; write_tty(&cs, 1); @@ -625,9 +628,9 @@ uint16_t *get_image(imstorage *img){ } --ptr; // *ptr is checksum while(start < ptr) cs ^= *start++; - DBG("got checksum: %x, calc: %x", *ptr, cs); + //DBG("got checksum: %x, calc: %x", *ptr, cs); if(*ptr == cs){ // all OK - DBG("Checksum good"); + //DBG("Checksum good"); cs = IMTRANS_CONTINUE; write_tty(&cs, 1); return ptr; @@ -643,24 +646,30 @@ uint16_t *get_image(imstorage *img){ return NULL; } uint8_t *bptr = (uint8_t*) buff; - int i = 0; + //int i = 0; // size of single block: 4096 pix in full frame or 1x1bin mode, 1024 in binned mode, subfrmsize in subframe mode size_t dpsize = 4096*2 + 1; if(img->binning == 2) dpsize = 1024*2 + 1; else if(img->binning == 0xff) dpsize = 2*img->subframe->size + 1; + printf("Transfer data "); fflush(stdout); do{ size_t need = (rest > dpsize) ? dpsize : rest + 1; - DBG("I want %zd bytes", need); + //DBG("I want %zd bytes", need); + printf("\b%c", *iptr++); // rotating line + fflush(stdout); + if(!*iptr) iptr = indi; uint8_t *ptr = getdataportion(bptr, need); if(!ptr){ + printf("\n"); WARNX(_("Error receiving data")); FREE(buff); return NULL; } - DBG("portion %d", ++i); + //DBG("portion %d", ++i); rest -= need - 1; bptr = ptr; }while(rest); + printf("\b Done!\n"); DBG("Got full data packet, capture time: %.1f seconds", dtime() - tstart); return buff; }