little fixes

This commit is contained in:
eddyem 2017-02-02 18:25:59 +03:00
parent 06d0ad7082
commit 13d623fc8a
8 changed files with 119 additions and 37 deletions

View File

@ -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

View File

@ -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
};

View File

@ -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;

View File

@ -26,7 +26,7 @@
#include "term.h"
#include <strings.h> // strncasecmp
#include <tiffio.h> // save tiff
#include <math.h>
// 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;
}

View File

@ -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__

15
main.c
View File

@ -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))
}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");
}
}

View File

@ -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

23
term.c
View File

@ -506,10 +506,12 @@ int start_exposition(imstorage *im, char *imtype){
WARNX(_("Wrong image type: %s, should be \"autodark\", \"light\" or \"dark\""), imtype);
return 6;
}
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)){
WARNX(_("Error sending command"));
@ -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;
}