1 // Copyright 2002, 2003 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * ale.cc: The main loop of ALE, including the user interface.
26 * ANSI C and POSIX include files.
48 #include "unsupported.h"
49 #include "implication.h"
64 * Device configuration files
67 #include "device/xvp610_320x240.h"
68 #include "device/xvp610_640x480.h"
69 #include "device/ov7620_raw_linear.h"
70 #include "device/canon_300d_raw_linear.h"
71 #include "device/canon_300d_raw_linear_85mm_1_8.h"
72 #include "device/canon_300d_raw_linear_50mm_1_8.h"
73 #include "device/canon_300d_raw_linear_50mm_1_4.h"
74 #include "device/canon_300d_raw_linear_50mm_1_4_1_4.h"
86 char *short_version
= "0.8.4";
88 char *version
= "ALE Version: 0.8.4\n"
90 "File handler: ImageMagick\n"
94 "Color data: " ALE_REAL_PRECISION_STRING
"\n"
95 "Coordinate data: " ALE_POS_PRECISION_STRING
"\n"
101 #if defined NDEBUG && !defined DEBUG
102 "Assertions: Disabled\n"
103 #elif defined DEBUG && !defined NDEBUG
104 "Assertions: Enabled\n"
106 "Assertions: Probably disabled\n"
108 "Assertions: Probably enabled\n"
110 #if OPTIMIZATIONS == 1
111 "Optimizations: Enabled\n"
113 "Optimizations: Disabled\n"
120 * Counts instances of a given option.
122 unsigned int arg_count(int argc
, const char *argv
[], const char *arg
) {
123 unsigned int count
= 0;
124 for (int i
= 0; i
< argc
; i
++) {
125 if (!strcmp(argv
[i
], arg
))
127 else if (!strcmp(argv
[i
], "--"))
134 * Argument prefix counter.
136 * Counts instances of a given option prefix.
138 unsigned int arg_prefix_count(int argc
, const char *argv
[], const char *pfix
) {
139 unsigned int count
= 0;
140 for (int i
= 0; i
< argc
; i
++) {
141 if (!strncmp(argv
[i
], pfix
, strlen(pfix
)))
143 else if (!strcmp(argv
[i
], "--"))
150 * Reallocation function
152 void *local_realloc(void *ptr
, size_t size
) {
153 void *new_ptr
= realloc(ptr
, size
);
156 ui::get()->memory_error_location("main()");
162 * Not enough arguments function.
164 void not_enough(const char *opt_name
) {
165 ui::get()->cli_not_enough(opt_name
);
169 * Bad argument function
171 void bad_arg(const char *opt_name
) {
172 ui::get()->cli_bad_arg(opt_name
);
178 * Does one of two things:
180 * (1) Output version information if called with '--version'
182 * (2) Read options and file arguments, and if the arguments are correct,
183 * write output. If an error is detected, print the usage statement.
187 int main(int argc
, const char *argv
[]){
190 * Initialize help object
193 help
hi(argv
[0], short_version
);
196 * Output version information if --version appears
197 * on the command line.
200 if (arg_count(argc
, argv
, "--version")) {
205 fprintf(stdout
, "%s", version
);
211 * Handle help options
214 if (arg_prefix_count(argc
, argv
, "--h"))
215 for (int i
= 1; i
< argc
; i
++) {
216 int all
= !strcmp(argv
[i
], "--hA");
217 int is_help_option
= !strncmp(argv
[i
], "--h", strlen("--h"));
220 if (!strcmp(argv
[i
], "--hu") || all
)
221 hi
.usage(), found_help
= 1;
222 if (!strcmp(argv
[i
], "--hq") || all
)
223 hi
.defaults(), found_help
= 1;
224 if (!strcmp(argv
[i
], "--hf") || all
)
225 hi
.file(), found_help
= 1;
226 if (!strcmp(argv
[i
], "--he") || all
)
227 hi
.exclusion(), found_help
= 1;
228 if (!strcmp(argv
[i
], "--ha") || all
)
229 hi
.alignment(), found_help
= 1;
230 if (!strcmp(argv
[i
], "--hr") || all
)
231 hi
.rendering(), found_help
= 1;
232 if (!strcmp(argv
[i
], "--hx") || all
)
233 hi
.exposure(), found_help
= 1;
234 if (!strcmp(argv
[i
], "--ht") || all
)
235 hi
.tdf(), found_help
= 1;
236 if (!strcmp(argv
[i
], "--hl") || all
)
237 hi
.filtering(), found_help
= 1;
238 if (!strcmp(argv
[i
], "--hd") || all
)
239 hi
.device(), found_help
= 1;
240 if (!strcmp(argv
[i
], "--hi") || all
)
241 hi
.interface(), found_help
= 1;
242 if (!strcmp(argv
[i
], "--hv") || all
)
243 hi
.visp(), found_help
= 1;
244 if (!strcmp(argv
[i
], "--hc") || all
)
245 hi
.cp(), found_help
= 1;
246 if (!strcmp(argv
[i
], "--h3") || all
)
247 hi
.d3(), found_help
= 1;
248 if (!strcmp(argv
[i
], "--hz") || all
)
249 hi
.undocumented(), found_help
= 1;
251 if (is_help_option
&& !found_help
)
255 * Check for the end-of-options marker, a non-option argument,
256 * or the end of arguments. In all of these cases, we exit.
259 if (!strcmp(argv
[i
], "--")
260 || strncmp(argv
[i
], "--", strlen("--"))
266 * Undocumented projective transformation utility
269 if (arg_count(argc
, argv
, "--ptcalc") > 0) {
270 fprintf(stderr
, "\n\n*** Warning: this feature is not documented ***\n\n");
271 printf("Enter: w h tlx tly blx bly brx bry trx try x y\n\n");
273 double w
, h
, tlx
, tly
, blx
, bly
, brx
, bry
, trx
, tr_y
, x
, y
;
277 if (scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",
278 &w
, &h
, &tlx
, &tly
, &blx
, &bly
, &brx
, &bry
, &trx
, &tr_y
, &x
, &y
) != 12) {
280 fprintf(stderr
, "Error reading input.\n");
284 d2::image
*i
= new d2::image_ale_real((int)h
, (int)w
, 3);
285 d2::transformation t
= d2::transformation::gpt_identity(i
, 1);
294 d2::point
a(y
, x
), b
;
296 b
= t
.transform_scaled(a
);
298 printf("TRANSFORM t(a): (%f, %f)\n", (double) b
[1], (double) b
[0]);
300 b
= t
.scaled_inverse_transform(a
);
302 printf("INVERSE t^-1(a): (%f, %f)\n", (double) b
[1], (double) b
[0]);
308 * Flags and variables
311 double scale_factor
= 1;
312 double vise_scale_factor
= 1;
314 double usm_multiplier
= 0.0;
317 struct d2::tload_t
*tload
= NULL
;
318 struct d2::tsave_t
*tsave
= NULL
;
319 struct d3::tload_t
*d3_tload
= NULL
;
320 struct d3::tsave_t
*d3_tsave
= NULL
;
321 int ip_iterations
= 0;
322 int ip_use_median
= 0;
323 enum { psf_linear
, psf_nonlinear
, psf_N
};
324 const char *psf
[psf_N
] = {NULL
, NULL
};
325 const char *device
= NULL
;
327 double psf_match_args
[6];
329 int exposure_register
= 1;
330 const char *wm_filename
= NULL
;
331 int wm_offsetx
, wm_offsety
;
332 double cx_parameter
= 0;
333 double *d3px_parameters
= NULL
;
335 int *ex_parameters
= NULL
;
339 const char *achain_type
= "triangle:2";
340 const char *afilter_type
= "internal";
341 d2::render
**ochain
= NULL
;
342 const char **ochain_names
= NULL
;
343 const char **ochain_types
= NULL
;
344 const char *d3chain_type
= NULL
;
346 const char **visp
= NULL
;
348 const char **d3_output
= NULL
;
349 const char **d3_depth
= NULL
;
350 unsigned int d3_count
= 0;
351 double user_view_angle
= 0;
352 int user_bayer
= IMAGE_BAYER_DEFAULT
;
353 d2::pixel exp_mult
= d2::pixel(1, 1, 1);
354 std::map
<const char *, d3::pt
> d3_output_pt
;
355 std::map
<const char *, d3::pt
> d3_depth_pt
;
358 * dchain is ochain[0].
361 ochain
= (d2::render
**) local_realloc(ochain
,
362 (oc_count
+ 1) * sizeof(d2::render
*));
363 ochain_names
= (const char **) local_realloc((void *)ochain_names
,
364 (oc_count
+ 1) * sizeof(const char *));
365 ochain_types
= (const char **) local_realloc((void *)ochain_types
,
366 (oc_count
+ 1) * sizeof(const char *));
368 ochain_types
[0] = "sinc*lanc:8";
373 * Handle default settings
376 if (arg_prefix_count(argc
, argv
, "--q") > 1)
377 ui::get()->error("more than one default setting option --q* was specified");
379 if (arg_count(argc
, argv
, "--q0")) {
380 ochain_types
[0] = "fine:box:1,triangle:2";
381 achain_type
= "triangle:2";
384 d2::image_rw::exp_noscale();
386 } else if (arg_count(argc
, argv
, "--qn")) {
387 ochain_types
[0] = "sinc*lanc:6";
388 achain_type
= "sinc*lanc:6";
391 d2::image_rw::exp_noscale();
393 } else if (arg_count(argc
, argv
, "--q1")) {
394 ochain_types
[0] = "median:fine:sinc*lanc:8,triangle:2";
395 achain_type
= "triangle:2";
398 d2::image_rw::exp_noscale();
400 } else if (arg_count(argc
, argv
, "--q2")) {
401 ochain_types
[0] = "sinc*lanc:8";
402 achain_type
= "sinc*lanc:8";
405 d2::image_rw::exp_noscale();
407 } else if (arg_count(argc
, argv
, "--qr")) {
408 ochain_types
[0] = "sinc*lanc:8";
409 achain_type
= "sinc*lanc:8";
412 d2::image_rw::exp_scale();
418 ochain_types
[0] = "fine:box:1,triangle:2";
419 achain_type
= "triangle:2";
422 d2::image_rw::exp_noscale();
427 * Set default d3chain to default ochain[0].
430 d3chain_type
= ochain_types
[0];
433 * Iterate through arguments until we reach the first file
434 * argument. After the first file argument, we assume that
435 * all following arguments are files.
438 for (int i
= 1; i
< argc
- 1; i
++) {
441 if (!strcmp(argv
[i
], "--q0")
442 || !strcmp(argv
[i
], "--q1")
443 || !strcmp(argv
[i
], "--q2")
444 || !strcmp(argv
[i
], "--qr")
445 || !strcmp(argv
[i
], "--qn")) {
447 * Do nothing. Defaults have already been set.
449 } else if (!strcmp(argv
[i
], "--8bpc")) {
450 d2::image_rw::depth8();
451 } else if (!strcmp(argv
[i
], "--16bpc")) {
452 d2::image_rw::depth16();
453 } else if (!strcmp(argv
[i
], "--plain")) {
454 d2::image_rw::ppm_plain();
455 } else if (!strcmp(argv
[i
], "--raw")) {
456 d2::image_rw::ppm_raw();
457 } else if (!strcmp(argv
[i
], "--auto")) {
458 d2::image_rw::ppm_auto();
459 } else if (!strcmp(argv
[i
], "--align-all")) {
461 } else if (!strcmp(argv
[i
], "--align-green")) {
463 } else if (!strcmp(argv
[i
], "--align-sum")) {
465 } else if (!strcmp(argv
[i
], "--translation")) {
466 d2::align::class_translation();
467 } else if (!strcmp(argv
[i
], "--euclidean")) {
468 d2::align::class_euclidean();
469 } else if (!strcmp(argv
[i
], "--projective")) {
470 d2::align::class_projective();
471 } else if (!strcmp(argv
[i
], "--identity")) {
472 d2::align::initial_default_identity();
473 } else if (!strcmp(argv
[i
], "--follow")) {
474 d2::align::initial_default_follow();
475 } else if (!strcmp(argv
[i
], "--perturb-output")) {
476 d2::align::perturb_output();
477 } else if (!strcmp(argv
[i
], "--perturb-source")) {
478 d2::align::perturb_source();
479 } else if (!strcmp(argv
[i
], "--fail-optimal")) {
480 d2::align::fail_optimal();
481 } else if (!strcmp(argv
[i
], "--fail-default")) {
482 d2::align::fail_default();
483 } else if (!strcmp(argv
[i
], "--no-extend")) {
485 } else if (!strcmp(argv
[i
], "--extend")) {
487 } else if (!strcmp(argv
[i
], "--no-mc")) {
489 } else if (!strcmp(argv
[i
], "--oc")) {
491 } else if (!strcmp(argv
[i
], "--no-oc")) {
493 } else if (!strcmp(argv
[i
], "--gs")) {
497 d2::align::gs(argv
[i
+1]);
500 } else if (!strcmp(argv
[i
], "--gs-mo")) {
502 not_enough("--gs-mo");
504 unsigned int mo_parameter
;
505 if (sscanf(argv
[i
+1], "%u", &mo_parameter
) != 1)
508 d2::align::gs_mo(mo_parameter
);
511 } else if (!strcmp(argv
[i
], "--focus")) {
514 * Check for argument availability
522 double inf
= one
/ zero
;
524 assert (isinf(inf
) == +1);
530 unsigned int type
= 0;
534 if (!strcmp(argv
[i
+1], "d")) {
539 not_enough("--focus d");
541 if (sscanf(argv
[i
+2], "%lf", &distance
) != 1)
542 bad_arg("--focus d");
546 } else if (!strcmp(argv
[i
+1], "p")) {
551 not_enough("--focus");
553 if (sscanf(argv
[i
+2], "%lf", &px
) != 1
554 || sscanf(argv
[i
+3], "%lf", &py
) != 1)
586 while (options
&& i
< argc
) {
587 if (!strncmp(argv
[i
], "ci=", 3)) {
588 if(sscanf(argv
[i
] + 3, "%u", &ci
) != 1)
590 } else if (!strncmp(argv
[i
], "fr=", 3)) {
591 if(sscanf(argv
[i
] + 3, "%lf", &fr
) != 1)
593 } else if (!strncmp(argv
[i
], "ht=", 3)) {
594 if(sscanf(argv
[i
] + 3, "%lf", &ht
) != 1)
596 } else if (!strncmp(argv
[i
], "vt=", 3)) {
597 if(sscanf(argv
[i
] + 3, "%lf", &vt
) != 1)
599 } else if (!strncmp(argv
[i
], "sy=", 3)) {
600 if(sscanf(argv
[i
] + 3, "%lf", &sy
) != 1)
602 } else if (!strncmp(argv
[i
], "ey=", 3)) {
603 if(sscanf(argv
[i
] + 3, "%lf", &ey
) != 1)
605 } else if (!strncmp(argv
[i
], "sx=", 3)) {
606 if(sscanf(argv
[i
] + 3, "%lf", &sx
) != 1)
608 } else if (!strncmp(argv
[i
], "ex=", 3)) {
609 if(sscanf(argv
[i
] + 3, "%lf", &ex
) != 1)
611 } else if (!strncmp(argv
[i
], "sd=", 3)) {
612 if(sscanf(argv
[i
] + 3, "%lf", &sd
) != 1)
614 } else if (!strncmp(argv
[i
], "ed=", 3)) {
615 if(sscanf(argv
[i
] + 3, "%lf", &ed
) != 1)
617 } else if (!strncmp(argv
[i
], "ap=", 3)) {
618 if(sscanf(argv
[i
] + 3, "%lf", &ap
) != 1)
620 } else if (!strncmp(argv
[i
], "sc=", 3)) {
621 if(sscanf(argv
[i
] + 3, "%u", &sc
) != 1)
623 } else if (!strncmp(argv
[i
], "sr=", 3)) {
624 if (!strcmp(argv
[i
], "sr=aperture")) {
626 } else if (!strcmp(argv
[i
], "sr=pixel")) {
631 } else if (!strncmp(argv
[i
], "fs=", 3)) {
632 if (!strcmp(argv
[i
], "fs=mean")) {
634 } else if (!strcmp(argv
[i
], "fs=median")) {
647 d3::focus::add_region(type
, distance
, px
, py
, ci
, fr
, ht
, vt
, sd
, ed
, sx
, ex
, sy
, ey
, ap
, sc
, fs
, sr
);
649 } else if (!strcmp(argv
[i
], "--3ddp") || !strcmp(argv
[i
], "--3dvp")) {
653 * Unsupported configurations
657 unsupported::fornow("3D modeling with Irani-Peleg rendering");
661 unsupported::fornow("3D modeling with unsharp mask");
665 * Check for argument availability
672 * Initialize if necessary
674 * Note: because their existence is checked as an
675 * indicator of the presence of 3D arguments, we
676 * initialize these structures here.
679 if (d3_output
== NULL
) {
680 d3_count
= argc
- (i
+ 2) - 1;
681 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
682 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
685 unsigned int width
, height
;
690 if (sscanf(argv
[i
+1], "%u", &width
) != 1
691 || sscanf(argv
[i
+2], "%u", &height
) != 1
692 || sscanf(argv
[i
+3], "%lf", &view_angle
) != 1
693 || sscanf(argv
[i
+4], "%lf", &x
) != 1
694 || sscanf(argv
[i
+5], "%lf", &y
) != 1
695 || sscanf(argv
[i
+6], "%lf", &z
) != 1
696 || sscanf(argv
[i
+7], "%lf", &P
) != 1
697 || sscanf(argv
[i
+8], "%lf", &Y
) != 1
698 || sscanf(argv
[i
+9], "%lf", &R
) != 1)
701 view_angle
*= M_PI
/ 180;
706 d2::transformation t
=
707 d2::transformation::eu_identity();
708 t
.set_domain(height
, width
);
709 d3::pt
_pt(t
, d3::et(y
, x
, z
, Y
, P
, R
), view_angle
);
711 if (!strcmp(argv
[i
], "--3dvp")) {
712 d3_output_pt
[argv
[i
+10]] = _pt
;
713 } else if (!strcmp(argv
[i
], "--3ddp")) {
714 d3_depth_pt
[argv
[i
+10]] = _pt
;
720 } else if (!strcmp(argv
[i
], "--3dv")) {
723 unsigned int frame_no
;
726 * Unsupported configurations
730 unsupported::fornow("3D modeling with Irani-Peleg rendering");
734 unsupported::fornow("3D modeling with unsharp mask");
738 * Check for argument availability
745 * Initialize if necessary
748 if (d3_output
== NULL
) {
749 d3_count
= argc
- (i
+ 2) - 1;
750 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
751 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
754 if (sscanf(argv
[i
+1], "%d", &frame_no
) != 1)
755 ui::get()->error("--3dv argument 0 must be an integer");
757 if (frame_no
>= d3_count
)
758 ui::get()->error("--3dv argument 0 is too large");
760 if (d3_output
[frame_no
] != NULL
) {
761 unsupported::fornow ("Writing a single 3D view to more than one output file");
764 d3_output
[frame_no
] = argv
[i
+2];
767 } else if (!strcmp(argv
[i
], "--3dd")) {
770 unsigned int frame_no
;
773 * Unsupported configurations
777 unsupported::fornow("3D modeling with Irani-Peleg rendering");
781 unsupported::fornow("3D modeling with unsharp mask");
785 * Check for argument availability
792 * Initialize if necessary
795 if (d3_output
== NULL
) {
796 d3_count
= argc
- (i
+ 2) - 1;
797 d3_output
= (const char **) calloc(d3_count
, sizeof(char *));
798 d3_depth
= (const char **) calloc(d3_count
, sizeof(char *));
801 if (sscanf(argv
[i
+1], "%d", &frame_no
) != 1)
802 ui::get()->error("--3dd argument 0 must be an integer");
804 if (frame_no
>= d3_count
)
805 ui::get()->error("--3dd argument 0 is too large");
807 if (d3_depth
[frame_no
] != NULL
) {
808 unsupported::fornow ("Writing a single frame's depth info to more than one output file");
811 d3_depth
[frame_no
] = argv
[i
+2];
815 } else if (!strcmp(argv
[i
], "--view-angle")) {
817 not_enough("--view-angle");
820 sscanf(argv
[i
+1], "%lf", &va_parameter
);
822 user_view_angle
= va_parameter
* M_PI
/ 180;
823 } else if (!strcmp(argv
[i
], "--cpf-load")) {
825 not_enough("--cpf-load");
827 d3::cpf::init_loadfile(argv
[i
+1]);
829 } else if (!strcmp(argv
[i
], "--ui=stream")) {
831 } else if (!strcmp(argv
[i
], "--ui=tty")) {
833 } else if (!strcmp(argv
[i
], "--3d-fmr")) {
836 not_enough("--3d-fmr");
838 double fmr_parameter
;
839 sscanf(argv
[i
+1], "%lf", &fmr_parameter
);
841 d3::scene::fmr(fmr_parameter
);
843 } else if (!strcmp(argv
[i
], "--3d-dmr")) {
846 not_enough("--3d-dmr");
848 double dmr_parameter
;
849 sscanf(argv
[i
+1], "%lf", &dmr_parameter
);
851 d3::scene::dmr(dmr_parameter
);
853 } else if (!strcmp(argv
[i
], "--et")) {
859 sscanf(argv
[i
+1], "%lf", &et_parameter
);
861 d3::scene::et(et_parameter
);
863 } else if (!strcmp(argv
[i
], "--st")) {
868 sscanf(argv
[i
+1], "%lf", &st_parameter
);
870 d3::cpf::st(st_parameter
);
871 } else if (!strcmp(argv
[i
], "--di-lower")) {
873 not_enough("--di-lower");
876 sscanf(argv
[i
+1], "%lf", &di_parameter
);
878 d3::scene::di_lower(di_parameter
);
879 } else if (!strcmp(argv
[i
], "--rc")) {
884 sscanf(argv
[i
+1], "%lf", &rc_parameter
);
886 d3::scene::rc(rc_parameter
);
887 } else if (!strcmp(argv
[i
], "--do-try")) {
889 not_enough("--do-try");
892 sscanf(argv
[i
+1], "%lf", &do_parameter
);
894 d3::scene::do_try(do_parameter
);
895 } else if (!strcmp(argv
[i
], "--di-upper")) {
897 not_enough("--di-upper");
899 double dgi_parameter
;
900 sscanf(argv
[i
+1], "%lf", &dgi_parameter
);
902 d3::scene::di_upper(dgi_parameter
);
903 } else if (!strcmp(argv
[i
], "--fc")) {
908 sscanf(argv
[i
+1], "%lf", &fc_parameter
);
910 d3::scene::fc(fc_parameter
);
911 } else if (!strcmp(argv
[i
], "--ecm")) {
912 unsupported::discontinued("--ecm <x>");
913 } else if (!strcmp(argv
[i
], "--acm")) {
914 unsupported::discontinued("--acm <x>");
915 } else if (!strcmp(argv
[i
], "--def-nn")) {
917 not_enough("--def-nn");
920 sscanf(argv
[i
+1], "%lf", &nn_parameter
);
922 d2::image_rw::def_nn(nn_parameter
);
924 if (nn_parameter
> 2) {
925 fprintf(stderr
, "\n\n*** Warning: --def-nn implementation is currently "
926 "inefficient for large radii. ***\n\n");
929 } else if (!strcmp(argv
[i
], "--mc")) {
934 sscanf(argv
[i
+1], "%lf", &mc_parameter
);
937 d2::align::mc(mc_parameter
);
939 } else if (!strcmp(argv
[i
], "--fx")) {
945 sscanf(argv
[i
+1], "%lf", &fx_parameter
);
947 d3::scene::fx(fx_parameter
);
949 } else if (!strcmp(argv
[i
], "--tcem")) {
952 not_enough("--tcem");
954 double tcem_parameter
;
955 sscanf(argv
[i
+1], "%lf", &tcem_parameter
);
957 d3::scene::tcem(tcem_parameter
);
959 } else if (!strcmp(argv
[i
], "--oui")) {
964 unsigned int oui_parameter
;
965 sscanf(argv
[i
+1], "%u", &oui_parameter
);
967 d3::scene::oui(oui_parameter
);
969 } else if (!strcmp(argv
[i
], "--pa")) {
974 unsigned int pa_parameter
;
975 sscanf(argv
[i
+1], "%u", &pa_parameter
);
977 d3::scene::pa(pa_parameter
);
979 } else if (!strcmp(argv
[i
], "--pc")) {
984 d3::scene::pc(argv
[i
+1]);
987 } else if (!strcmp(argv
[i
], "--cw")) {
988 d2::align::certainty_weighted(1);
989 } else if (!strcmp(argv
[i
], "--no-cw")) {
990 d2::align::certainty_weighted(0);
991 } else if (!strcmp(argv
[i
], "--wm")) {
992 if (wm_filename
!= NULL
)
993 ui::get()->error("only one weight map can be specified");
997 wm_filename
= argv
[i
+1];
999 if (sscanf(argv
[i
+2], "%d", &wm_offsetx
) != 1)
1000 ui::get()->error("--wm x-argument must be an integer");
1002 if (sscanf(argv
[i
+3], "%d", &wm_offsety
) != 1)
1003 ui::get()->error("--wm y-argument must be an integer");
1007 } else if (!strcmp(argv
[i
], "--fl")) {
1011 if (sscanf(argv
[i
+1], "%lf", &h
) != 1)
1012 ui::get()->error("--fl h-argument must be numerical");
1013 if (sscanf(argv
[i
+2], "%lf", &v
) != 1)
1014 ui::get()->error("--fl v-argument must be numerical");
1015 if (sscanf(argv
[i
+3], "%lf", &a
) != 1)
1016 ui::get()->error("--fl a-argument must be numerical");
1019 d2::align::set_frequency_cut(h
, v
, a
);
1021 ui::get()->error_hint("--fl is not supported", "rebuild ALE with FFTW=1");
1023 } else if (!strcmp(argv
[i
], "--wmx")) {
1025 not_enough("--wmx");
1027 d2::align::set_wmx(argv
[i
+1], argv
[i
+2], argv
[i
+3]);
1029 ui::get()->error_hint("--wmx is not supported", "rebuild ALE with POSIX=1");
1032 } else if (!strcmp(argv
[i
], "--flshow")) {
1034 not_enough("--flshow");
1035 d2::align::set_fl_show(argv
[i
+1]);
1037 } else if (!strcmp(argv
[i
], "--3dpx")) {
1039 not_enough("--3dpx");
1041 d3px_parameters
= (double *) local_realloc(d3px_parameters
, (d3px_count
+ 1) * 6 * sizeof(double));
1043 for (int param
= 0; param
< 6; param
++)
1044 if (sscanf(argv
[i
+ param
+ 1], "%lf", &(d3px_parameters
[6 * d3px_count
+ param
])) != 1)
1048 * Swap x and y, since their internal meanings differ from their external meanings.
1051 for (int param
= 0; param
< 2; param
++) {
1052 double temp
= d3px_parameters
[6 * d3px_count
+ 2 + param
];
1053 d3px_parameters
[6 * d3px_count
+ 2 + param
] = d3px_parameters
[6 * d3px_count
+ 0 + param
];
1054 d3px_parameters
[6 * d3px_count
+ 0 + param
] = temp
;
1059 * Increment counters
1064 } else if (!strcmp(argv
[i
], "--ex")) {
1068 ex_parameters
= (int *) local_realloc(ex_parameters
, (ex_count
+ 1) * 6 * sizeof(int));
1070 for (int param
= 0; param
< 6; param
++)
1071 if (sscanf(argv
[i
+ param
+ 1], "%d", &(ex_parameters
[6 * ex_count
+ param
])) != 1)
1075 * Swap x and y, since their internal meanings differ from their external meanings.
1078 for (int param
= 0; param
< 2; param
++) {
1079 int temp
= ex_parameters
[6 * ex_count
+ 2 + param
];
1080 ex_parameters
[6 * ex_count
+ 2 + param
] = ex_parameters
[6 * ex_count
+ 0 + param
];
1081 ex_parameters
[6 * ex_count
+ 0 + param
] = temp
;
1086 * Increment counters
1091 } else if (!strcmp(argv
[i
], "--crop")) {
1093 not_enough("--crop");
1095 ex_parameters
= (int *) local_realloc(ex_parameters
, (ex_count
+ 4) * 6 * sizeof(int));
1098 for (int param
= 0; param
< 6; param
++)
1099 if (sscanf(argv
[i
+ param
+ 1], "%d", &(crop_args
[param
])) != 1)
1103 * Construct exclusion regions from the crop area,
1104 * swapping x and y, since their internal meanings
1105 * differ from their external meanings.
1109 * Exclusion region 1: low x
1112 ex_parameters
[6 * ex_count
+ 0] = INT_MIN
;
1113 ex_parameters
[6 * ex_count
+ 1] = crop_args
[2] - 1;
1114 ex_parameters
[6 * ex_count
+ 2] = INT_MIN
;
1115 ex_parameters
[6 * ex_count
+ 3] = INT_MAX
;
1116 ex_parameters
[6 * ex_count
+ 4] = crop_args
[4];
1117 ex_parameters
[6 * ex_count
+ 5] = crop_args
[5];
1120 * Exclusion region 2: low y
1123 ex_parameters
[6 * ex_count
+ 6] = INT_MIN
;
1124 ex_parameters
[6 * ex_count
+ 7] = INT_MAX
;
1125 ex_parameters
[6 * ex_count
+ 8] = INT_MIN
;
1126 ex_parameters
[6 * ex_count
+ 9] = crop_args
[0] - 1;
1127 ex_parameters
[6 * ex_count
+ 10] = crop_args
[4];
1128 ex_parameters
[6 * ex_count
+ 11] = crop_args
[5];
1131 * Exclusion region 3: high y
1134 ex_parameters
[6 * ex_count
+ 12] = INT_MIN
;
1135 ex_parameters
[6 * ex_count
+ 13] = INT_MAX
;
1136 ex_parameters
[6 * ex_count
+ 14] = crop_args
[1] + 1;
1137 ex_parameters
[6 * ex_count
+ 15] = INT_MAX
;
1138 ex_parameters
[6 * ex_count
+ 16] = crop_args
[4];
1139 ex_parameters
[6 * ex_count
+ 17] = crop_args
[5];
1142 * Exclusion region 4: high x
1145 ex_parameters
[6 * ex_count
+ 18] = crop_args
[3] + 1;
1146 ex_parameters
[6 * ex_count
+ 19] = INT_MAX
;
1147 ex_parameters
[6 * ex_count
+ 20] = INT_MIN
;
1148 ex_parameters
[6 * ex_count
+ 21] = INT_MAX
;
1149 ex_parameters
[6 * ex_count
+ 22] = crop_args
[4];
1150 ex_parameters
[6 * ex_count
+ 23] = crop_args
[5];
1153 * Increment counters
1158 } else if (!strcmp(argv
[i
], "--exshow")) {
1160 } else if (!strcmp(argv
[i
], "--wt")) {
1166 if (sscanf(argv
[i
+ 1], "%lf", &wt
) != 1)
1169 d2::render::set_wt(wt
);
1171 } else if (!strcmp(argv
[i
], "--3d-chain")) {
1173 not_enough("--3d-chain");
1174 d3chain_type
= argv
[i
+1];
1176 } else if (!strcmp(argv
[i
], "--dchain")) {
1178 not_enough("--dchain");
1179 ochain_types
[0] = argv
[i
+1];
1181 } else if (!strcmp(argv
[i
], "--achain")) {
1183 not_enough("--achain");
1184 achain_type
= argv
[i
+1];
1186 } else if (!strcmp(argv
[i
], "--afilter")) {
1188 not_enough("--afilter");
1189 afilter_type
= argv
[i
+1];
1191 } else if (!strcmp(argv
[i
], "--ochain")) {
1193 not_enough("--ochain");
1195 ochain
= (d2::render
**) local_realloc(ochain
,
1196 (oc_count
+ 1) * sizeof(d2::render
*));
1197 ochain_names
= (const char **) local_realloc((void *)ochain_names
,
1198 (oc_count
+ 1) * sizeof(const char *));
1199 ochain_types
= (const char **) local_realloc((void *)ochain_types
,
1200 (oc_count
+ 1) * sizeof(const char *));
1202 ochain_types
[oc_count
] = argv
[i
+1];
1203 ochain_names
[oc_count
] = argv
[i
+2];
1207 } else if (!strcmp(argv
[i
], "--visp")) {
1209 not_enough("--visp");
1211 visp
= (const char **) local_realloc((void *)visp
, 4 *
1212 (vise_count
+ 1) * sizeof(const char *));
1214 for (int param
= 0; param
< 4; param
++)
1215 visp
[vise_count
* 4 + param
] = argv
[i
+ 1 + param
];
1219 } else if (!strcmp(argv
[i
], "--cx")) {
1224 sscanf(argv
[i
+1], "%lf", &cx_parameter
);
1227 } else if (!strcmp(argv
[i
], "--no-cx")) {
1229 } else if (!strcmp(argv
[i
], "--ip")) {
1230 unsupported::discontinued("--ip <r> <i>", "--lpsf box=<r> --ips <i>");
1231 } else if (!strcmp(argv
[i
], "--bayer")) {
1233 not_enough("--bayer");
1236 * External order is clockwise from top-left. Internal
1237 * order is counter-clockwise from top-left.
1240 if (!strcmp(argv
[i
+1], "rgbg")) {
1241 user_bayer
= IMAGE_BAYER_RGBG
;
1242 } else if (!strcmp(argv
[i
+1], "bgrg")) {
1243 user_bayer
= IMAGE_BAYER_BGRG
;
1244 } else if (!strcmp(argv
[i
+1], "gbgr")) {
1245 user_bayer
= IMAGE_BAYER_GRGB
;
1246 } else if (!strcmp(argv
[i
+1], "grgb")) {
1247 user_bayer
= IMAGE_BAYER_GBGR
;
1248 } else if (!strcmp(argv
[i
+1], "none")) {
1249 user_bayer
= IMAGE_BAYER_NONE
;
1254 } else if (!strcmp(argv
[i
], "--lpsf")) {
1256 not_enough("--lpsf");
1258 psf
[psf_linear
] = argv
[i
+1];
1260 } else if (!strcmp(argv
[i
], "--nlpsf")) {
1262 not_enough("--nlpsf");
1264 psf
[psf_nonlinear
] = argv
[i
+1];
1267 } else if (!strcmp(argv
[i
], "--psf-match")) {
1269 not_enough("--psf-match");
1273 for (int index
= 0; index
< 6; index
++) {
1274 if (sscanf(argv
[i
+ 1], "%lf", &psf_match_args
[index
]) != 1)
1275 bad_arg("--psf-match");
1279 } else if (!strcmp(argv
[i
], "--device")) {
1281 not_enough("--device");
1287 } else if (!strcmp(argv
[i
], "--usm")) {
1289 if (d3_output
!= NULL
)
1290 unsupported::fornow("3D modeling with unsharp mask");
1293 not_enough("--usm");
1295 sscanf(argv
[i
+1], "%lf", &usm_multiplier
);
1299 } else if (!strcmp(argv
[i
], "--ipr")) {
1302 not_enough("--ipr");
1304 if (sscanf(argv
[i
+1], "%d", &ip_iterations
) != 1)
1305 ui::get()->error("--ipr requires an integer argument");
1307 ui::get()->warn("--ipr is deprecated. Use --ips instead");
1310 } else if (!strcmp(argv
[i
], "--cpp-err-median")) {
1311 d3::cpf::err_median();
1312 } else if (!strcmp(argv
[i
], "--cpp-err-mean")) {
1313 d3::cpf::err_mean();
1314 } else if (!strcmp(argv
[i
], "--vp-adjust")) {
1315 d3::align::vp_adjust();
1316 } else if (!strcmp(argv
[i
], "--vp-noadjust")) {
1317 d3::align::vp_noadjust();
1318 } else if (!strcmp(argv
[i
], "--vo-adjust")) {
1319 d3::align::vo_adjust();
1320 } else if (!strcmp(argv
[i
], "--vo-noadjust")) {
1321 d3::align::vo_noadjust();
1322 } else if (!strcmp(argv
[i
], "--ip-mean")) {
1324 } else if (!strcmp(argv
[i
], "--ip-median")) {
1326 } else if (!strcmp(argv
[i
], "--ips")) {
1329 not_enough("--ips");
1331 if (sscanf(argv
[i
+1], "%d", &ip_iterations
) != 1)
1332 ui::get()->error("--ips requires an integer argument");
1334 } else if (!strcmp(argv
[i
], "--ipc")) {
1335 unsupported::discontinued("--ipc <c> <i>", "--ips <i> --lpsf <c>", "--ips <i> --device <c>");
1336 } else if (!strcmp(argv
[i
], "--exp-extend")) {
1337 d2::image_rw::exp_scale();
1338 } else if (!strcmp(argv
[i
], "--exp-noextend")) {
1339 d2::image_rw::exp_noscale();
1340 } else if (!strcmp(argv
[i
], "--exp-register")) {
1341 exposure_register
= 1;
1342 d2::align::exp_register();
1343 } else if (!strcmp(argv
[i
], "--exp-noregister")) {
1344 exposure_register
= 0;
1345 d2::align::exp_noregister();
1346 } else if (!strcmp(argv
[i
], "--exp-meta-only")) {
1347 exposure_register
= 2;
1348 d2::align::exp_meta_only();
1349 } else if (!strcmp(argv
[i
], "--drizzle-only")) {
1350 unsupported::discontinued("--drizzle-only", "--dchain box:1");
1351 } else if (!strcmp(argv
[i
], "--subspace-traverse")) {
1352 unsupported::undocumented("--subspace-traverse");
1353 d3::scene::set_subspace_traverse();
1354 } else if (!strcmp(argv
[i
], "--3d-nofilter")) {
1355 d3::scene::nofilter();
1356 } else if (!strcmp(argv
[i
], "--3d-filter")) {
1357 d3::scene::filter();
1358 } else if (!strcmp(argv
[i
], "--occ-norm")) {
1360 } else if (!strcmp(argv
[i
], "--occ-nonorm")) {
1362 } else if (!strcmp(argv
[i
], "--inc")) {
1364 } else if (!strcmp(argv
[i
], "--no-inc")) {
1366 } else if (!strncmp(argv
[i
], "--exp-mult=", strlen("--exp-mult="))) {
1367 double exp_c
, exp_r
, exp_b
;
1368 sscanf(argv
[i
] + strlen("--exp-mult="), "%lf,%lf,%lf", &exp_c
, &exp_r
, &exp_b
);
1369 exp_mult
= d2::pixel(1/(exp_r
* exp_c
), 1/exp_c
, 1/(exp_b
* exp_c
));
1370 } else if (!strncmp(argv
[i
], "--visp-scale=", strlen("--visp-scale="))) {
1372 sscanf(argv
[i
] + strlen("--visp-scale="), "%lf", &vise_scale_factor
);
1374 if (vise_scale_factor
<= 0.0)
1375 ui::get()->error("VISP scale must be greater than zero");
1377 if (!finite(vise_scale_factor
))
1378 ui::get()->error("VISP scale must be finite");
1380 } else if (!strncmp(argv
[i
], "--scale=", strlen("--scale="))) {
1382 sscanf(argv
[i
] + strlen("--scale="), "%lf", &scale_factor
);
1384 if (scale_factor
<= 0)
1385 ui::get()->error("Scale factor must be greater than zero");
1387 if (!finite(scale_factor
))
1388 ui::get()->error("Scale factor must be finite");
1390 } else if (!strncmp(argv
[i
], "--metric=", strlen("--metric="))) {
1392 sscanf(argv
[i
] + strlen("--metric="), "%lf", &metric
);
1393 d2::align::set_metric_exponent(metric
);
1394 } else if (!strncmp(argv
[i
], "--threshold=", strlen("--threshold="))) {
1395 double match_threshold
;
1396 sscanf(argv
[i
] + strlen("--threshold="), "%lf", &match_threshold
);
1397 d2::align::set_match_threshold(match_threshold
);
1398 } else if (!strncmp(argv
[i
], "--drizzle-diam=", strlen("--drizzle-diam="))) {
1399 unsupported::discontinued("--drizzle-diam=<x>", "--dchain box:1");
1400 // sscanf(argv[i] + strlen("--drizzle-diam="), "%lf", &drizzle_radius);
1401 // drizzle_radius /= 2;
1402 } else if (!strncmp(argv
[i
], "--perturb-upper=", strlen("--perturb-upper="))) {
1403 double perturb_upper
;
1405 sscanf(argv
[i
] + strlen("--perturb-upper="), "%lf%n", &perturb_upper
,
1407 if (*(argv
[i
] + strlen("--perturb-upper=") + characters
) == '%')
1408 d2::align::set_perturb_upper(perturb_upper
, 1);
1410 d2::align::set_perturb_upper(perturb_upper
, 0);
1411 } else if (!strncmp(argv
[i
], "--perturb-lower=", strlen("--perturb-lower="))) {
1412 double perturb_lower
;
1414 sscanf(argv
[i
] + strlen("--perturb-lower="), "%lf%n", &perturb_lower
,
1416 if (perturb_lower
<= 0)
1417 ui::get()->error("--perturb-lower= value is non-positive");
1419 if (*(argv
[i
] + strlen("--perturb-lower=") + characters
) == '%')
1420 d2::align::set_perturb_lower(perturb_lower
, 1);
1422 d2::align::set_perturb_lower(perturb_lower
, 0);
1423 } else if (!strncmp(argv
[i
], "--stepsize=", strlen("--stepsize="))) {
1424 double perturb_lower
;
1425 ui::get()->warn("--stepsize is deprecated. Use --perturb-lower instead");
1426 sscanf(argv
[i
] + strlen("--stepsize="), "%lf", &perturb_lower
);
1427 d2::align::set_perturb_lower(perturb_lower
, 0);
1428 } else if (!strncmp(argv
[i
], "--va-upper=", strlen("--va-upper="))) {
1431 sscanf(argv
[i
] + strlen("--va-upper="), "%lf%n", &va_upper
,
1433 if (*(argv
[i
] + strlen("--va-upper=") + characters
) == '%')
1434 ui::get()->error("--va-upper= does not accept '%' arguments\n");
1436 d3::cpf::set_va_upper(va_upper
);
1437 } else if (!strncmp(argv
[i
], "--cpp-upper=", strlen("--cpp-upper="))) {
1438 double perturb_upper
;
1440 sscanf(argv
[i
] + strlen("--cpp-upper="), "%lf%n", &perturb_upper
,
1442 if (*(argv
[i
] + strlen("--cpp-upper=") + characters
) == '%')
1443 ui::get()->error("--cpp-upper= does not currently accept '%' arguments\n");
1445 d3::cpf::set_cpp_upper(perturb_upper
);
1446 } else if (!strncmp(argv
[i
], "--cpp-lower=", strlen("--cpp-lower="))) {
1447 double perturb_lower
;
1449 sscanf(argv
[i
] + strlen("--cpp-lower="), "%lf%n", &perturb_lower
,
1451 if (*(argv
[i
] + strlen("--cpp-lower=") + characters
) == '%')
1452 ui::get()->error("--cpp-lower= does not currently accept '%' arguments\n");
1454 d3::cpf::set_cpp_lower(perturb_lower
);
1455 } else if (!strncmp(argv
[i
], "--hf-enhance=", strlen("--hf-enhance="))) {
1456 unsupported::discontinued("--hf-enhance=<x>");
1457 } else if (!strncmp(argv
[i
], "--rot-upper=", strlen("--rot-upper="))) {
1459 sscanf(argv
[i
] + strlen("--rot-upper="), "%lf", &rot_max
);
1460 d2::align::set_rot_max((int) floor(rot_max
));
1461 } else if (!strncmp(argv
[i
], "--bda-mult=", strlen("--bda-mult="))) {
1463 sscanf(argv
[i
] + strlen("--bda-mult="), "%lf", &bda_mult
);
1464 d2::align::set_bda_mult(bda_mult
);
1465 } else if (!strncmp(argv
[i
], "--bda-rate=", strlen("--bda-rate="))) {
1467 sscanf(argv
[i
] + strlen("--bda-rate="), "%lf", &bda_rate
);
1468 d2::align::set_bda_rate(bda_rate
);
1469 } else if (!strncmp(argv
[i
], "--lod-max=", strlen("--lod-max="))) {
1471 sscanf(argv
[i
] + strlen("--lod-max="), "%lf", &lod_max
);
1472 d2::align::set_lod_max((int) floor(lod_max
));
1473 } else if (!strncmp(argv
[i
], "--cpf-load=", strlen("--cpf-load="))) {
1474 d3::cpf::init_loadfile(argv
[i
] + strlen("--cpf-load="));
1476 } else if (!strncmp(argv
[i
], "--model-load=", strlen("--model-load="))) {
1477 d3::scene::load_model(argv
[i
] + strlen("--model-load="));
1478 } else if (!strncmp(argv
[i
], "--model-save=", strlen("--model-save="))) {
1479 d3::scene::save_model(argv
[i
] + strlen("--model-save="));
1481 } else if (!strncmp(argv
[i
], "--trans-load=", strlen("--trans-load="))) {
1482 d2::tload_delete(tload
);
1483 tload
= d2::tload_new(argv
[i
] + strlen("--trans-load="));
1484 d2::align::set_tload(tload
);
1485 } else if (!strncmp(argv
[i
], "--trans-save=", strlen("--trans-save="))) {
1486 tsave_delete(tsave
);
1487 tsave
= d2::tsave_new(argv
[i
] + strlen("--trans-save="));
1488 d2::align::set_tsave(tsave
);
1489 } else if (!strncmp(argv
[i
], "--3d-trans-load=", strlen("--3d-trans-load="))) {
1490 d3::tload_delete(d3_tload
);
1491 d3_tload
= d3::tload_new(argv
[i
] + strlen("--3d-trans-load="));
1492 d3::align::set_tload(d3_tload
);
1493 } else if (!strncmp(argv
[i
], "--3d-trans-save=", strlen("--3d-trans-save="))) {
1494 d3::tsave_delete(d3_tsave
);
1495 d3_tsave
= d3::tsave_new(argv
[i
] + strlen("--3d-trans-save="));
1496 d3::align::set_tsave(d3_tsave
);
1500 * Trap illegal options and end-of-option indicators.
1503 if (!strcmp(argv
[i
], "--"))
1505 else if (!strncmp(argv
[i
], "--", strlen("--")))
1506 ui::get()->illegal_option(argv
[i
]);
1509 * Apply implication logic.
1512 if (extend
== 0 && vise_count
!= 0) {
1513 implication::changed("VISP requires increased image extents.",
1514 "Image extension is now enabled.",
1519 if (psf_match
&& ex_count
)
1520 unsupported::fornow("PSF calibration with exclusion regions.");
1523 if (d3_output
!= NULL
&& ip_iterations
!= 0)
1524 unsupported::fornow("3D modeling with Irani-Peleg rendering");
1527 if (extend
== 0 && d3_output
!= NULL
) {
1528 implication::changed("3D modeling requires increased image extents.",
1529 "Image extension is now enabled.",
1535 if (cx_parameter
!= 0 && !exposure_register
) {
1536 implication::changed("Certainty-based rendering requires exposure registration.",
1537 "Exposure registration is now enabled.",
1539 d2::align::exp_register();
1540 exposure_register
= 1;
1544 * Set alignment class exclusion region static variables
1547 d2::align::set_exclusion(ex_parameters
, ex_count
);
1550 * Initialize renderer class statics.
1553 d2::render::render_init(ex_count
, ex_parameters
, ex_show
, extend
, scale_factor
);
1559 d2::exposure::set_confidence(cx_parameter
);
1562 * Keep transformations for Irani-Peleg, psf-match, and
1566 if (ip_iterations
> 0 || psf_match
|| vise_count
> 0) {
1571 * Initialize device-specific variables
1574 d2::psf
*device_response
[psf_N
] = { NULL
, NULL
};
1575 d2::exposure
**input_exposure
= NULL
;
1576 ale_pos view_angle
= 43.7 * M_PI
/ 180;
1577 // ale_pos view_angle = 90 * M_PI / 180;
1578 input_exposure
= (d2::exposure
**)
1579 malloc((argc
- i
- 1) * sizeof(d2::exposure
*));
1581 if (device
!= NULL
) {
1582 if (!strcmp(device
, "xvp610_640x480")) {
1583 device_response
[psf_linear
] = new xvp610_640x480::lpsf();
1584 device_response
[psf_nonlinear
] = new xvp610_640x480::nlpsf();
1585 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1586 input_exposure
[ii
] = new xvp610_640x480::exposure();
1587 view_angle
= xvp610_640x480::view_angle();
1588 } else if (!strcmp(device
, "xvp610_320x240")) {
1589 device_response
[psf_linear
] = new xvp610_320x240::lpsf();
1590 device_response
[psf_nonlinear
] = new xvp610_320x240::nlpsf();
1591 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1592 input_exposure
[ii
] = new xvp610_320x240::exposure();
1593 view_angle
= xvp610_320x240::view_angle();
1594 } else if (!strcmp(device
, "ov7620_raw_linear")) {
1595 device_response
[psf_linear
] = new ov7620_raw_linear::lpsf();
1596 device_response
[psf_nonlinear
] = NULL
;
1597 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1598 input_exposure
[ii
] = new ov7620_raw_linear::exposure();
1599 d2::image_rw::set_default_bayer(IMAGE_BAYER_BGRG
);
1600 } else if (!strcmp(device
, "canon_300d_raw_linear")) {
1601 device_response
[psf_linear
] = new canon_300d_raw_linear::lpsf();
1602 device_response
[psf_nonlinear
] = NULL
;
1603 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1604 input_exposure
[ii
] = new canon_300d_raw_linear::exposure();
1605 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1606 } else if (!strcmp(device
, "canon_300d_raw_linear+85mm_1.8")) {
1607 device_response
[psf_linear
] = new canon_300d_raw_linear_85mm_1_8::lpsf();
1608 device_response
[psf_nonlinear
] = NULL
;
1609 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1610 input_exposure
[ii
] = new canon_300d_raw_linear_85mm_1_8::exposure();
1611 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1612 view_angle
= canon_300d_raw_linear_85mm_1_8::view_angle();
1613 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.8")) {
1614 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_8::lpsf();
1615 device_response
[psf_nonlinear
] = NULL
;
1616 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1617 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_8::exposure();
1618 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1619 view_angle
= canon_300d_raw_linear_50mm_1_8::view_angle();
1620 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.4")) {
1621 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_4::lpsf();
1622 device_response
[psf_nonlinear
] = NULL
;
1623 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1624 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_4::exposure();
1625 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1626 view_angle
= canon_300d_raw_linear_50mm_1_4::view_angle();
1627 } else if (!strcmp(device
, "canon_300d_raw_linear+50mm_1.4@1.4")) {
1628 device_response
[psf_linear
] = new canon_300d_raw_linear_50mm_1_4_1_4::lpsf();
1629 device_response
[psf_nonlinear
] = NULL
;
1630 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1631 input_exposure
[ii
] = new canon_300d_raw_linear_50mm_1_4_1_4::exposure();
1632 d2::image_rw::set_default_bayer(IMAGE_BAYER_RGBG
);
1633 view_angle
= canon_300d_raw_linear_50mm_1_4_1_4::view_angle();
1635 ui::get()->unknown_device(device
);
1638 for (int ii
= 0; ii
< argc
- i
- 1; ii
++)
1639 input_exposure
[ii
] = new d2::exposure_default();
1643 * User-specified variables.
1646 if (user_view_angle
!= 0) {
1647 view_angle
= user_view_angle
;
1650 if (user_bayer
!= IMAGE_BAYER_DEFAULT
) {
1651 d2::image_rw::set_default_bayer(user_bayer
);
1655 * PSF-match exposure.
1658 delete input_exposure
[argc
- i
- 2];
1659 input_exposure
[argc
- i
- 2] = new d2::exposure_default();
1663 * Initialize output exposure
1666 d2::exposure
*output_exposure
= new d2::exposure_default();
1667 output_exposure
->set_multiplier(exp_mult
);
1670 * Configure the response function.
1673 d2::psf
*response
[2] = {NULL
, NULL
};
1675 for (int n
= 0; n
< psf_N
; n
++ ) {
1676 if (psf
[n
] != NULL
) {
1678 response
[n
] = d2::psf_parse::get((n
== psf_linear
), psf
[n
]);
1680 } else if (device_response
[n
] != NULL
) {
1683 * Device-specific response
1686 response
[n
] = device_response
[n
];
1691 * Default point-spread function.
1694 if (n
== psf_linear
) {
1697 * Default lpsf is a box filter
1698 * of diameter 1.0 (radius
1702 response
[n
] = new d2::box(0.5);
1704 } else if (n
== psf_nonlinear
) {
1707 * nlpsf is disabled by default.
1716 * First file argument. Print general file information as well
1717 * as information specific to this argument. Initialize image
1722 * There should be at least two file arguments.
1725 if (i
>= argc
- 1) {
1730 d2::image_rw::init(argc
- i
- 1, argv
+ i
, argv
[argc
- 1], input_exposure
, output_exposure
);
1731 ochain_names
[0] = argv
[argc
- 1];
1734 * Handle control point data for alignment
1736 d2::align::set_cp_count(d3::cpf::count());
1737 for (unsigned int ii
= 0; ii
< d3::cpf::count(); ii
++)
1738 d2::align::set_cp(ii
, d3::cpf::get_2d(ii
));
1741 * PSF-match bayer patterns.
1745 d2::image_rw::set_specific_bayer(argc
- i
- 2, IMAGE_BAYER_NONE
);
1749 * Handle alignment weight map, if necessary
1752 if (wm_filename
!= NULL
) {
1753 d2::image
*weight_map
;
1754 weight_map
= d2::image_rw::read_image(wm_filename
, new d2::exposure_linear());
1755 weight_map
->set_offset(wm_offsety
, wm_offsetx
);
1756 d2::align::set_weight_map(weight_map
);
1760 * Write comment information about original frame and
1761 * target image to the transformation save file, if we
1765 const d2::image
*im
= d2::image_rw::open(0);
1766 tsave_orig(tsave
, argv
[i
], im
->avg_channel_magnitude());
1767 tsave_target(tsave
, argv
[argc
- 1]);
1768 d2::image_rw::close(0);
1771 * Initialize alignment interpolant.
1774 if (afilter_type
!= "internal")
1775 d2::align::set_interpolant(d2::render_parse::get_SSF(afilter_type
));
1778 * Initialize achain and ochain.
1781 achain
= d2::render_parse::get(achain_type
);
1783 for (int chain
= 0; chain
< oc_count
; chain
++)
1784 ochain
[chain
] = d2::render_parse::get(ochain_types
[chain
]);
1787 * Use merged renderings as reference images in
1791 d2::align::set_reference(achain
);
1794 * Tell the alignment class about the scale factor.
1797 d2::align::set_scale(scale_factor
);
1803 d2::vise_core::set_scale(vise_scale_factor
);
1805 for (int opt
= 0; opt
< vise_count
; opt
++) {
1806 d2::vise_core::add(d2::render_parse::get(visp
[opt
* 4 + 0]),
1813 * Initialize non-incremental renderers
1817 if (usm_multiplier
!= 0) {
1820 * Unsharp Mask renderer
1823 ochain
[0] = new d2::usm(ochain
[0], scale_factor
,
1824 usm_multiplier
, inc
, response
[psf_linear
],
1825 response
[psf_nonlinear
], &input_exposure
[0]);
1832 * Point-spread function calibration renderer.
1833 * This renderer does not produce image output.
1834 * It is reserved for use with the point-spread
1835 * function calibration script
1836 * ale-psf-calibrate.
1839 ochain
[0] = new d2::psf_calibrate(ochain
[0],
1840 1, inc
, response
[psf_linear
],
1841 response
[psf_nonlinear
],
1844 } else if (ip_iterations
!= 0) {
1847 * Irani-Peleg renderer
1850 ochain
[0] = new d2::ipc( ochain
[0], ip_iterations
,
1851 inc
, response
[psf_linear
],
1852 response
[psf_nonlinear
],
1853 (exposure_register
== 1), ip_use_median
);
1857 * Handle the original frame.
1860 ui::get()->original_frame_start(argv
[i
]);
1862 for (int opt
= 0; opt
< oc_count
; opt
++) {
1863 ui::get()->set_orender_current(opt
);
1864 ochain
[opt
]->sync(0);
1866 ui::get()->writing_output(opt
);
1867 d2::image_rw::write_image(ochain_names
[opt
],
1868 ochain
[opt
]->get_image(0));
1872 d2::vise_core::frame_queue_add(0);
1874 ui::get()->original_frame_done();
1877 * Handle supplemental frames.
1880 for (unsigned int j
= 1; j
< d2::image_rw::count(); j
++) {
1882 const char *name
= d2::image_rw::name(j
);
1884 ui::get()->supplemental_frame_start(name
);
1887 * Write comment information about the
1888 * supplemental frame to the transformation
1889 * save file, if we have one.
1892 tsave_info (tsave
, name
);
1894 const d2::image
*im
= d2::image_rw::open(j
);
1895 d2::pixel apm
= im
->avg_channel_magnitude();
1896 tsave_apm(tsave
, apm
[0], apm
[1], apm
[2]);
1897 d2::image_rw::close(j
);
1899 for (int opt
= 0; opt
< oc_count
; opt
++) {
1900 ui::get()->set_orender_current(opt
);
1901 ochain
[opt
]->sync(j
);
1903 ui::get()->writing_output(opt
);
1904 d2::image_rw::write_image(ochain_names
[opt
],
1905 ochain
[opt
]->get_image(j
));
1909 d2::vise_core::frame_queue_add(j
);
1911 ui::get()->supplemental_frame_done();
1915 * Do any post-processing and output final image
1917 * XXX: note that non-incremental renderers currently
1918 * return zero for ochain[0]->sync(), since they write
1919 * output internally when inc != 0.
1922 for (int opt
= 0; opt
< oc_count
; opt
++)
1923 if ((ochain
[opt
]->sync() || !inc
) && !psf_match
)
1924 d2::image_rw::write_image(ochain_names
[opt
], ochain
[opt
]->get_image());
1927 * Output a summary match statistic.
1930 ui::get()->ale_2d_done((double) d2::align::match_summary());
1933 * Perform any 3D tasks
1936 optimizations::begin_3d_work();
1940 ui::get()->d3_start();
1942 d3::align::init_angle(view_angle
);
1944 ui::get()->d3_init_view_angle(view_angle
/ M_PI
* 180);
1946 d3::align::init_from_d2();
1948 if (d3::cpf::count() > 0) {
1949 ui::get()->d3_control_point_solve();
1950 d3::cpf::solve_3d();
1951 ui::get()->d3_control_point_solve_done();
1954 ui::get()->d3_final_view_angle(d3::align::angle_of(0) / M_PI
* 180);
1956 d3::align::write_alignments();
1958 d3::scene::set_filter_type(d3chain_type
);
1960 d3::scene::init_from_d2();
1962 ui::get()->d3_subdividing_space();
1963 d3::scene::make_space(d3_depth
, d3_output
, &d3_depth_pt
, &d3_output_pt
);
1964 ui::get()->d3_subdividing_space_done();
1966 ui::get()->d3_updating_occupancy();
1967 d3::scene::reduce_cost_to_search_depth(output_exposure
, inc
);
1968 ui::get()->d3_updating_occupancy_done();
1970 d3::scene::d3px(d3px_count
, d3px_parameters
);
1972 for (unsigned int i
= 0; i
< d2::image_rw::count(); i
++) {
1973 assert (i
< d3_count
);
1975 if (d3_depth
[i
] != NULL
) {
1976 ui::get()->d3_writing_output(d3_depth
[i
]);
1977 ui::get()->d3_render_status(0, 0, -1, -1, -1, -1, 0);
1978 const d2::image
*im
= d3::scene::depth(i
);
1979 d2::image_rw::write_image(d3_depth
[i
], im
, output_exposure
, 1, 1);
1981 ui::get()->d3_writing_output_done();
1984 if (d3_output
[i
] != NULL
) {
1985 ui::get()->d3_writing_output(d3_output
[i
]);
1986 const d2::image
*im
= d3::scene::view(i
);
1987 d2::image_rw::write_image(d3_output
[i
], im
, output_exposure
);
1989 d3::focus::set_camera(view_count
++);
1990 ui::get()->d3_writing_output_done();
1993 for (std::map
<const char *, d3::pt
>::iterator i
= d3_output_pt
.begin();
1994 i
!= d3_output_pt
.end(); i
++) {
1996 ui::get()->d3_writing_output(i
->first
);
1997 const d2::image
*im
= d3::scene::view(i
->second
);
1998 d2::image_rw::write_image(i
->first
, im
, output_exposure
);
2000 d3::focus::set_camera(view_count
++);
2001 ui::get()->d3_writing_output_done();
2004 for (std::map
<const char *, d3::pt
>::iterator i
= d3_depth_pt
.begin();
2005 i
!= d3_depth_pt
.end(); i
++) {
2007 ui::get()->d3_writing_output(i
->first
);
2008 ui::get()->d3_render_status(0, 0, -1, -1, -1, -1, 0);
2009 const d2::image
*im
= d3::scene::depth(i
->second
);
2010 d2::image_rw::write_image(i
->first
, im
, output_exposure
, 1, 1);
2012 ui::get()->d3_writing_output_done();
2016 for (unsigned int i
= d2::image_rw::count(); i
< d3_count
; i
++) {
2017 if (d3_depth
[i
] != NULL
) {
2018 fprintf(stderr
, "\n\n*** Frame number for --3dd too high. ***\n\n");
2020 if (d3_output
[i
] != NULL
) {
2021 fprintf(stderr
, "\n\n*** Frame number for --3dv too high. ***\n\n");
2027 * Destroy the image file handler
2030 d2::image_rw::destroy();
2033 * Delete the transformation file structures, if any
2037 tsave_delete(tsave
);
2038 tload_delete(tload
);
2049 * If there was no output, the user might need more information.