#define VALUE_B (bval) #define VALUE_S (val) #define VALUE_I atoi(val) #define VALUE_F atof(val) #define BOOLEAN(x) ((x)=(bval==1?1:0)) #define RETURN return(1) #define FAIL return(-1) global char *CurrentFile = NULL; global int StackCount = 0; global int cur_Sub_x = 0; global int cur_Sub_y = 0; global int HaveWindow = 0; help int i; Print("\nUsage: ninox [ switches] [files or directories]\n\n"); Print("Switches: \n\n"); for(i=0; Names[i].func != NULL; ++i) if (! strstr(Names[i].option,"help-")) Print("-%s ",Names[i].option); Print("\n\n"); Print("Use \"ninox -help-X\" to see detailed help about switch X\n\n"); exit(0); config inifile ini global int LoadedConfig = 0; char *params[32],*vals[32]; char *c,*str,*cfgfile; int i,n,rval; cfgfile = strtok(val,","); if (! cfgfile || cfgfile[0]==0) { printf("Error: Invalid filename for -config\n"); exit(1); } if (access(cfgfile,R_OK)) { printf("Error: Cannot find config file '%s'\n",cfgfile); exit(1); } // parse remainder of val into var=value tokens n=0; while(str = strtok(NULL,",")) { char *c = strchr(str,'='); if (c) { *c=0; params[n] = strdup(str); vals[n++] = strdup(c+1); } } params[n]=NULL; vals[n]=NULL; rval=LoadConfigFile(cfgfile,params,vals); return rval; inputfilter # Enables an input filter algorithm which replaces pixels that are too bright/dark # when compared to their neighbors. favours dark pixels. global int InputFilter = 0; global double InputFilter_ThreshHold = 0.2; if (InputFilter==0 && VALUE_F > 0) InputFilter_ThreshHold = VALUE_F; ++InputFilter; inputfilter-display ifd # Display the action of the input filter global int InputFilter_Display = 0; BOOLEAN(InputFilter_Display); fft-ref global char *FFT_Ref = NULL; FFT_Ref = strdup(VALUE_S); DoFFT = 1; dofft global int DoFFT = 0; global double FFT_LPF_Radius1 = 0; global double FFT_LPF_Radius2 = 0; global double FFT_LPF_Pow = 0; double r1,r2,p; if (sscanf(VALUE_S,"%lf,%lf,%lf",&r1,&r2,&p) == 3) { /* 3 operand version, all params given */ FFT_LPF_Radius1 = r1; FFT_LPF_Radius2 = r2; FFT_LPF_Pow = p; } else if (sscanf(VALUE_S,"%lf,%lf",&r1,&r2) == 2) { /* 2 operand version, assume p = 1 */ FFT_LPF_Radius1 = r1; FFT_LPF_Radius2 = r2; FFT_LPF_Pow = 1.0; } else if (sscanf(VALUE_S,"%lf",&r1) == 1) { /* single operand version, assume r2 = r1 * 2 and p = 1 */ FFT_LPF_Radius1 = r1; FFT_LPF_Radius2 = r1 * 2.0; FFT_LPF_Pow = 1.0; } else { FFT_LPF_Radius1 = 0; FFT_LPF_Radius2 = 0; FFT_LPF_Pow = 0; } DoFFT = 1; fft-filter global int FFT_Filter=0; double r1,r2,p; if (sscanf(VALUE_S,"%lf,%lf,%lf",&r1,&r2,&p) == 3) { /* 3 operand version, all params given */ FFT_LPF_Radius1 = r1; FFT_LPF_Radius2 = r2; FFT_LPF_Pow = p; } else if (sscanf(VALUE_S,"%lf,%lf",&r1,&r2) == 2) { /* 2 operand version, assume p = 1 */ FFT_LPF_Radius1 = r1; FFT_LPF_Radius2 = r2; FFT_LPF_Pow = 1.0; } else if (sscanf(VALUE_S,"%lf",&r1) == 1) { /* single operand version, assume r2 = r1 * 2 and p = 1 */ FFT_LPF_Radius1 = r1; FFT_LPF_Radius2 = r1 * 2.0; FFT_LPF_Pow = 1.0; } else { Print("fft-filter: Error, usage is fft-filter=r1,r2,p\n"); exit(1); } FFT_Filter = 1; flux global int SumFlux = 0; global char * FluxFile = NULL; SumFlux = 1; FluxFile = VALUE_S; fft_scan fft-scan global int FFT_Region = 10; FFT_Region = VALUE_I; mean3 # Enable a 3x3 mean smoothing on the image global int Do3x3Smooth=0; BOOLEAN(Do3x3Smooth); chain # When playing or processing FITS Archive files (.fta), automatically # chain from the end of one archive to the start of the next global int ChainArchives=1; BOOLEAN(ChainArchives); amean # Enable the alpha-trimmed-mean smoothing algorithm global int AMean=0; BOOLEAN(AMean); i # Enter interactive mode global int InteractiveMode=0; BOOLEAN(InteractiveMode); archiveoverridefilenames # no help available global int ArchiveOverrideFilenames=0; BOOLEAN(ArchiveOverrideFilenames); enablecutout cutout # ninox will attempt to locate and centre the dominant object in the # frame by finding the centre of brightness and "cutting out" a rectangle # around that point and moving it to the centre of the image. global int DoCutout=1; BOOLEAN(DoCutout); if (! VALUE_B) ForceProcess=1; detectbrokenframes dbf # ninox will use an algorithm to detect corrupted (broken) frames # by comparing each frame to its predecessor. Sudden large-scale # changes are interpreted as corruption and the frame is skipped. global int DetectBrokenFrames = 0; global int DBF_TYPE = DBF_PLANET; if (!strcasecmp(VALUE_S,"planet")) DBF_TYPE = DBF_PLANET; else if (!strcasecmp(VALUE_S,"lunar")) DBF_TYPE = DBF_LUNAR; else if (!strcasecmp(VALUE_S,"moon")) DBF_TYPE = DBF_LUNAR; DetectBrokenFrames = 1; dbfedgecount # With detectbrokenframes, this sets a threshhold for detecting # broken frames. global int DBF_EDGE_COUNT = 50; DBF_EDGE_COUNT = VALUE_I; detecthotpixels dhp global int DetectHotPixels = 0; BOOLEAN(DetectHotPixels); process # Useful on multi-core or multi-processor machines. Allows you to specify # a subset of the available images to be processed on the assumption that # another invocation of ninox will be processing the skipped images. # # Usage: -process=offset,skip # # Offset is the starting image number (0 = first) # Skip is the number of images to skip after processing an image (default=0) # # eg, to run 2 copies of ninox, use: # # ninox -process=0,1 ... # and # ninox -process=1,1 ... # # with all other switches identical. The first invocation here will process # images 0,2,4,6,... and the second will process images 1,3,5,7 ... global int ProcessOffset = 0; global int ProcessSkip = 0; // process=Offset,Skip for cooperatively processing a video sequence if (sscanf(VALUE_S,"%d,%d",&ProcessOffset,&ProcessSkip) != 2) { printf("process: invalid argument, wanted process=offset,skip\n"); FAIL; } scan global int Sub_x = 0; global int Sub_y = 0; // give a non-central place to start scanning for FindCentre() int x1,y1; char fname[512]; if (sscanf(VALUE_S,"%d,%d",&x1,&y1) != 2) { printf("-scan: invalid format, should be -scan=x,y\n"); FAIL; } Sub_x = x1; Sub_y = y1; centrefunc # Determines how ninox finds the centre of an image to be cut out. The default # (ie if centrefunc is omitted) is to find the centre of brightness of the whole image # known as the barycentre. # # If you give centrefunc=left then this process is modified to only count the "first" # object found in the frame (scanning left -> right). # # If you give centrefunc=right then the process is modified to only count the "first" # object found in the frame scanning from right -> left. # # The "left" and "right" modes are useful when you want to lock onto one particular object # in a frame that contains other objects that are moving relative to the one you want, and # you want to ignore everything other than the first object (looking from either left or right). # global int CentreMode = CENTRE_BARYCENTRE; if (! strcasecmp(VALUE_S,"left")) CentreMode = CENTRE_LEFT; if (! strcasecmp(VALUE_S,"right")) CentreMode = CENTRE_RIGHT; subregion global int EnableSubRegion = 0; global int SR_X1 = 0; global int SR_Y1 = 0; global int SR_X2 = 0; global int SR_Y2 = 0; // subregion specifies a region to be used after the image has been centered // and cutout. This subregion replaces the centered image int x1,y1,x2,y2; char fname[512]; if (sscanf(val,"%d,%d,%d,%d",&x1,&y1,&x2,&y2) != 4) { printf("-subregion: Invalid format, should be -subregion=x1,y1,x2,y2\n"); FAIL; } EnableSubRegion = 1; SR_X1 = x1; SR_X2 = x2; SR_Y1 = y1; SR_Y2 = y2; DoCutout=0; darkframe global char *DarkFrame = NULL; global double DarkFrame_Scale = 1.0; double scale; char fname[512]; if (sscanf(VALUE_S,"%lf,%s",&scale,fname) == 2) { DarkFrame = strdup(fname); DarkFrame_Scale = scale; } else { DarkFrame = strdup(VALUE_S); DarkFrame_Scale = 1.0; } levels global int LevelsMin = 0; global int LevelsMax = 0; global int doLevelsAdjust = 0; int min,max; if (sscanf(val,"%d,%d",&min,&max) != 2) { printf("syntax error on 'levels'\n"); FAIL; } LevelsMin = min; LevelsMax = max; doLevelsAdjust = 1; dbf-diff global int DBF_DIFF = 15; DBF_DIFF = VALUE_I; count global int ImageCount= IMAGECOUNT_MAX; // How many images to process ImageCount=VALUE_I; nocutout DoCutout=0; ForceProcess = 1; # Flip the image horizontally mirror hinvert global int doMirrorImage = 0; BOOLEAN(doMirrorImage); # Flip the image vertically invert global int doInvertImage = 1; BOOLEAN(doInvertImage); forceprocess global int ForceProcess = 0; BOOLEAN(ForceProcess); protect global int HistoProtect = 1; BOOLEAN(HistoProtect); stretch global int HistoStretch = 0; HistoStretch = VALUE_I; if (HistoStretch==0) HistoStretch = 200; istretch global int InputHistoStretch = -1; BOOLEAN(InputHistoStretch); quiet global int Quiet = 0; Quiet = bval; debayer global int DoDeBayer = 0; if (VALUE_I) DoDeBayer = VALUE_I; else { if (! strcasecmp(VALUE_S,"gbg")) DoDeBayer=1; if (! strcasecmp(VALUE_S,"rgr")) DoDeBayer=2; if (! strcasecmp(VALUE_S,"bgb")) DoDeBayer=3; if (! strcasecmp(VALUE_S,"grg")) DoDeBayer=4; } bayer_x global int BayerX = 1; BayerX = VALUE_I; bayer_y global int BayerY = 1; BayerY = VALUE_I; bayer8 global int Bayer8 = 0; BOOLEAN(Bayer8); cutx global int CutX = 360; CutX = VALUE_I; if (CutX < 100) { Print("-cutx: minimum supported size 100 pixels\n"); FAIL; } cuty global int CutY = 360; CutY = VALUE_I; if (CutY < 100) { Print("-cutx: minimum supported size 100 pixels\n"); FAIL; } cut global int newWidth = -1; global int newHeight = -1; int x,y; if (sscanf(VALUE_S,"%d,%d",&x,&y)==2) { CutX = x; CutY = y; } else { if (VALUE_I < 100 || VALUE_I>10000) { Print("%d: Outside valid bounds 100..10000\n",VALUE_I); FAIL; } CutX = VALUE_I; CutY = VALUE_I; newWidth = CutX; newHeight = CutY; } white global int White = 255; White = VALUE_I; smoothing global int UpScale_Smoothing_When = SMOOTHING_BEFORE; global int UpScale_Smoothing = -1; if (!strcasecmp(VALUE_S,"before")) { UpScale_Smoothing_When = SMOOTHING_BEFORE; UpScale_Smoothing = 1; } else if (!strcasecmp(VALUE_S,"after")) { UpScale_Smoothing_When = SMOOTHING_AFTER; UpScale_Smoothing = 1; } else BOOLEAN(UpScale_Smoothing); upscale upsample resample rescale global int UpScale = 1; global int DownScale = 1; char *ptr = strstr(VALUE_S,"/"); int up=1,down=1; if (ptr) { *ptr = 0; down = atoi(ptr+1); } up = VALUE_I; if (up < 1 || up > 6 || down<1 || down>6) { Print("UpScale: %d/%d out of accepted range (1..6)/(1..6) \n",up,down); FAIL; } UpScale = up; DownScale = down; if (UpScale_Smoothing < 0) { double scalef = (double)UpScale / (double) DownScale; if (scalef <= 2) UpScale_Smoothing = 0; else UpScale_Smoothing = 1; } popfilter global int PopFilter_When = POPFILTER_BEFORE; global int PopFilter = 0; char when[32]; int sz = 5; if (sscanf(VALUE_S,"%d,%s",&sz,when) == 2) { if (!strcasecmp(when,"before")) PopFilter_When = POPFILTER_BEFORE; else if (!strcasecmp(when,"after")) PopFilter_When = POPFILTER_AFTER; else { Print("Unknown option '%s' to popfilter\n",when); FAIL; } if (sz<=0) { Print("invalid size arg '%d' to popfilter\n",sz); FAIL; } PopFilter = sz; } else if (! strcasecmp(VALUE_S,"before")) { PopFilter_When = POPFILTER_BEFORE; PopFilter = 5; } else if (! strcasecmp(VALUE_S,"after")) { PopFilter_When = POPFILTER_AFTER; PopFilter = 5; } else if (VALUE_I > 0) { PopFilter = VALUE_I; PopFilter_When = POPFILTER_BEFORE; } else { PopFilter = 5; PopFilter_When = POPFILTER_BEFORE; } gain global double Gain = 1.0; global int ChangeGain = 0; Gain = VALUE_F; if (Gain != 1.0) ChangeGain = 1; gamma global double Gamma = 1.0; global int ChangeGamma = 0; double g = VALUE_F; if (g < 0.3 || g > 1.5) { Print("Gamma value %f is outside accepted range 0.3 <= gamma <= 1.5\n",g); FAIL; } Gamma = g; if (Gamma != 1.0) ChangeGamma = 1; streamfilter global int StreamFilter = 0; global int StreamFilter_History = 5; StreamFilter = 1; if (VALUE_I) StreamFilter_History = VALUE_I; bayerboost global double BayerBoost = 1.0; BayerBoost = VALUE_F; if (BayerBoost == 0) BayerBoost = 1.0; overwrite global int AllowOverwrite = 0; BOOLEAN(AllowOverwrite); outdir global char * OutDir = NULL; int i; OutDir = strdup(VALUE_S); for(i=0; OutDir[i]; ++i) if (OutDir[i]=='\\') OutDir[i]='/'; if (MkDirs) { char *strtmp = strdup(OutDir); char *ptr = strchr(strtmp,'/'); while(ptr) { *ptr = 0; if (! isDirectory(strtmp)) { Print("Creating directory '%s'\n",strtmp); Mkdir(strtmp); if (! isDirectory(strtmp)) { Print("Mkdir on '%s' failed, cannot continue\n"); exit(0); } } else { Print("Directory '%s' exists\n",strtmp); } *ptr = '/'; ptr = strchr(ptr+1,'/'); } free(strtmp); } nosave global int NoSave = 0; BOOLEAN(NoSave); threshhold global int ThreshHold = 30; int t = VALUE_I; if (t<5 || t > 250) { Print("Threshhold %d out of allowed range 5..250\n",t); FAIL; } ThreshHold = t; minpixels global int MinPixels = 250; MinPixels = VALUE_I; if (MinPixels<10 || MinPixels > 1000) { Print("Minpixels: %d out of alloed range 10..1000\n",MinPixels); FAIL; } width newWidth = VALUE_I; if (newWidth < 100 || newWidth>10000) { Print("Width must be 100..10000\n"); FAIL; } height newHeight = VALUE_I; if (newHeight < 100 || newHeight > 10000) { Print("Height must be 100..10000\n"); FAIL; } stack stackfile global char *StackFile = NULL; StackFile = strdup(VALUE_S); stackcount global int StackMax = 100000; StackMax = VALUE_I; mergefile global char * MergeFile = NULL; MergeFile = strdup(VALUE_S); mergethreshhold global double MergeThreshHold = 0.2; MergeThreshHold = VALUE_F; writeemptyfiles global int forceWriteEmptyFiles = 0; global int WriteEmptyFiles = 1; BOOLEAN(forceWriteEmptyFiles); BOOLEAN(WriteEmptyFiles); qestimator qe global int QEstimator = 0; global int QSUBSAMPLE_MIN = 3; global int QSUBSAMPLE_MAX = 5; global int QSUBSAMPLE_INC = 1; int min,max,ch,step; BOOLEAN(QEstimator); // Possible value "n,m" representing min and max subsampling // or "n,m,i" for sampling between n and m with increment i if (sscanf(val,"%d%c%d%c%d",&min,&ch,&max,&ch,&step)==5) { QSUBSAMPLE_MIN = min; QSUBSAMPLE_MAX = max; QSUBSAMPLE_INC = step; QEstimator = 1; } else if (sscanf(val,"%d%c%d",&min,&ch,&max)==3) { QSUBSAMPLE_MIN = min; QSUBSAMPLE_MAX = max; QEstimator = 1; } qcount qc global int QualityMaxCount = 0; QualityMaxCount = VALUE_I; qfunc qf maxq global int QualityFunction = GRADIENT; if (! strncasecmp(VALUE_S,"hist",4)) QualityFunction = HISTO; else if (! strncasecmp(VALUE_S,"grad",4)) QualityFunction = GRADIENT; // default else if (! strncasecmp(VALUE_S,"thresh",4)) QualityFunction = BR_THRESH; // default else { printf("Unknown quality function '%s'\n",val); FAIL; } qmargin global double QMargin = 0.1; // -qmargin=0.25 for 25% margin on all borders QMargin = VALUE_F; qhistfile global char *QHISTO_FILE = ".ninox/histo.txt"; QHISTO_FILE = strdup(VALUE_S); qhisto global int QHISTO_MIN = -1; global int QHISTO_MAX = -1; int x1,y1,x2,y2,min,max; if (sscanf(val,"%d,%d-%d,%d:%d-%d",&x1,&y1,&x2,&y2,&min,&max)==6) QAddRegion(x1,y1,x2,y2,min,max); if (sscanf(val,"%d,%d",&min,&max)==2) { QHISTO_MIN = min; QHISTO_MAX = max; } else { printf("Usage: -qhisto=min,max (8 bit values)\n"); FAIL; } qtrim trim global int QTrim_Before = 5; global int QTrim_After = 20; int b,a; if (sscanf(val,"%d,%d",&b,&a) == 2) { QTrim_Before = b; QTrim_After = a; } else { QTrim_Before = QTrim_After = VALUE_I; } renumber qrenumber qsort global int QRenumberFiles = 0; BOOLEAN(QRenumberFiles); if (!strcasecmp(VALUE_S,"last")) QRenumberFiles = QRENUMBER_LAST; qwrite global int QWriteIntermediateFiles = 0; BOOLEAN(QWriteIntermediateFiles); hnoisefilter global int HNoiseFilter = 0; BOOLEAN(HNoiseFilter); subdirs global int SubDirs = 1; BOOLEAN(SubDirs); default-config ShowGlobals(); exit(1); debug global int DEBUG=0; BOOLEAN(DEBUG); morphing global int Morphing = 0; Morphing = atoi(val); morph-ref morph_ref mr global char *Morph_Ref = NULL; Morph_Ref = strdup(VALUE_S); if (access(Morph_Ref,0)) { Print("morph_ref: Reference image '%s' does not exist\n",val); FAIL; } morph-across morph_across ma global int Morph_Across = -1; // Number of control points across the image Morph_Across = VALUE_I; morph-down morph_down md global int Morph_Down = -1; // Number of control points down the image Morph_Down = VALUE_I; morph-it morph_it mi morph-iterations morph_iterations global int Morph_Iterations = 1; // Number of morph iterations to run Morph_Iterations = VALUE_I; morph-dr morph-drift morph_drift global int Morph_Drift = 2; Morph_Drift = VALUE_I; morph-max-translate mx morph_max_translate global int Morph_MaxTranslate = 100; Morph_MaxTranslate = VALUE_I; morph-de mdebug mdbg morph_debug global int Morph_Debug = 0; // Enable extra debugging Morph_Debug = VALUE_I; printf("[%d]\n",Morph_Debug); morph-min-divisor morph_min_divisor global int Morph_Min_Divisor = 5; Morph_Min_Divisor = VALUE_I; input-type ift global int InputFileType = -1; if (!strcasecmp(VALUE_S,"bmp")) InputFileType = IMG_BMP; else if (!strncasecmp(VALUE_S,"fit",3)) InputFileType = IMG_FIT; else if (!strcasecmp(VALUE_S,"ppm")) InputFileType = IMG_PPM; else { Print("input file type '%s' not understood\n",VALUE_S); FAIL; } output-type oft global int OutputFileType = -1; if (!strcasecmp(VALUE_S,"bmp")) OutputFileType = IMG_BMP; else if (!strncasecmp(VALUE_S,"fit",3)) OutputFileType = IMG_FIT; else if (!strcasecmp(VALUE_S,"ppm")) OutputFileType = IMG_PPM; else { Print("output file type '%s' not understood\n",VALUE_S); FAIL; } output-depth od global int OutputFileDepth = -1; OutputFileDepth = VALUE_I; rotate global double RotateAngle = 0; global int do_Rotate=0; RotateAngle = VALUE_F; if (RotateAngle != 0) do_Rotate=1; rotatecutoff global int RotateCutoff = 45; RotateCutoff = VALUE_I; display global int DisplayFrames = 0; global int DisplayPause=0; DisplayFrames = 1; if (! strcasecmp(VALUE_S,"pause")) DisplayPause=1; gaincomp global int ApplyGainComp = 0; BOOLEAN(ApplyGainComp); if (ApplyGainComp && ! LoadGainCompRef(VALUE_S)) { Print("Error loading gain compensation reference\n"); FAIL; } subsamplemode global int SubsampleMode = 0; SubsampleMode = VALUE_I; NoSave = 1; subsample_pixel_width global int Subsample_pixel_width = 10; Subsample_pixel_width = VALUE_I; subsample_pixel_height global int Subsample_pixel_height = 10; Subsample_pixel_height = VALUE_I; subsample_pixel_size Subsample_pixel_height = Subsample_pixel_width = VALUE_I; subsample_xpixels global int Subsample_xpixels= 640; Subsample_xpixels= VALUE_I; Subsample_ypixels global int Subsample_ypixels= 480; Subsample_ypixels= VALUE_I; subsample_nframes global int Subsample_nframes = 100; Subsample_nframes = VALUE_I; subsample_min_offset global double Subsample_min_offset = 0; Subsample_min_offset = VALUE_F; subsample_max_offset global double Subsample_max_offset = 5; Subsample_max_offset = VALUE_F; subsample_upscale global int Subsample_upscale = 0; Subsample_upscale = VALUE_I; subsample_smooth global int Subsample_smooth = 0; Subsample_smooth = VALUE_I; subsample_noise global int Subsample_noise = 0; Subsample_noise = VALUE_I; subsample_scan global int Subsample_scan = 0; BOOLEAN(Subsample_scan); subsample_prefix global char *Subsample_prefix = "sample_"; Subsample_prefix = strdup(VALUE_S); runfile global char *RunFile = NULL; RunFile = strdup(VALUE_S); iquant global int IQuant = 0; IQuant = VALUE_I; zblack # Used when decompressing .ftz archives, sets the background default # pixel brightness. range 0..255 global int ZBlack = 0; ZBlack = VALUE_I; mkdirs # Usage: -mkdirs=yes # Creates all parent directories for the -outdir directory global int MkDirs = 0; BOOLEAN(MkDirs); histo-warning overbright ob # Usage: -histo-warning=off OR -nohisto-warning global int EnableHistoWarning = 1; BOOLEAN(EnableHistoWarning); grey # Converts 24bpp input into 8bpp monochrome global int Grey = 0; BOOLEAN(Grey);