Fix variable definition warnings occurring when DEBUG=0. This patch should resolve...
[Ale.git] / ale.cc
blob71dea1440a89b2c256b8f88d37a47e989f3bd02d
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.
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <assert.h>
33 #include <time.h>
34 #include <math.h>
37 * Types
40 #include "ale_pos.h"
41 #include "ale_real.h"
44 * Interface files
47 #include "ui/ui.h"
48 #include "unsupported.h"
49 #include "implication.h"
52 * 2D include files
55 #include "d2.h"
58 * 3D include files
61 #include "d3.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"
77 * Help files
80 #include "help.h"
83 * Version Information
86 char *short_version = "0.8.4";
88 char *version = "ALE Version: 0.8.4\n"
89 #ifdef USE_MAGICK
90 "File handler: ImageMagick\n"
91 #else
92 "File handler: PPM\n"
93 #endif
94 "Color data: " ALE_REAL_PRECISION_STRING "\n"
95 "Coordinate data: " ALE_POS_PRECISION_STRING "\n"
96 #ifdef USE_FFTW
97 "DFT: FFTW3\n"
98 #else
99 "DFT: Built-in\n"
100 #endif
101 #if defined NDEBUG && !defined DEBUG
102 "Assertions: Disabled\n"
103 #elif defined DEBUG && !defined NDEBUG
104 "Assertions: Enabled\n"
105 #elif defined NDEBUG
106 "Assertions: Probably disabled\n"
107 #else
108 "Assertions: Probably enabled\n"
109 #endif
110 #if OPTIMIZATIONS == 1
111 "Optimizations: Enabled\n"
112 #else
113 "Optimizations: Disabled\n"
114 #endif
118 * Argument counter.
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))
126 count++;
127 else if (!strcmp(argv[i], "--"))
128 return count;
130 return count;
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)))
142 count++;
143 else if (!strcmp(argv[i], "--"))
144 return count;
146 return count;
150 * Reallocation function
152 void *local_realloc(void *ptr, size_t size) {
153 void *new_ptr = realloc(ptr, size);
155 if (new_ptr == NULL)
156 ui::get()->memory_error_location("main()");
158 return new_ptr;
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);
176 * Main function.
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")) {
202 * Output the version
205 fprintf(stdout, "%s", version);
207 return 0;
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"));
218 int found_help = 0;
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)
252 hi.usage();
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("--"))
261 || i == argc - 1)
262 return 0;
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;
275 printf("> ");
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");
281 exit(1);
284 d2::image *i = new d2::image_ale_real((int)h, (int)w, 3);
285 d2::transformation t = d2::transformation::gpt_identity(i, 1);
286 d2::point q[4] = {
287 d2::point(tly, tlx),
288 d2::point(bly, blx),
289 d2::point(bry, brx),
290 d2::point(tr_y, trx)
292 t.gpt_set(q);
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]);
304 exit(0);
308 * Flags and variables
311 double scale_factor = 1;
312 double vise_scale_factor = 1;
313 #if 0
314 double usm_multiplier = 0.0;
315 #endif
316 int extend = 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;
326 int psf_match = 0;
327 double psf_match_args[6];
328 int inc = 1;
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;
334 int d3px_count = 0;
335 int *ex_parameters = NULL;
336 int ex_count = 0;
337 int ex_show = 0;
338 d2::render *achain;
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;
345 int oc_count = 0;
346 const char **visp = NULL;
347 int vise_count = 0;
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";
370 oc_count = 1;
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";
382 d2::align::mc(0.3);
383 ip_iterations = 0;
384 d2::image_rw::exp_noscale();
385 cx_parameter = 0;
386 } else if (arg_count(argc, argv, "--qn")) {
387 ochain_types[0] = "sinc*lanc:6";
388 achain_type = "sinc*lanc:6";
389 d2::align::mc(0.5);
390 ip_iterations = 0;
391 d2::image_rw::exp_noscale();
392 cx_parameter = 0;
393 } else if (arg_count(argc, argv, "--q1")) {
394 ochain_types[0] = "median:fine:sinc*lanc:8,triangle:2";
395 achain_type = "triangle:2";
396 d2::align::mc(0.5);
397 ip_iterations = 0;
398 d2::image_rw::exp_noscale();
399 cx_parameter = 0;
400 } else if (arg_count(argc, argv, "--q2")) {
401 ochain_types[0] = "sinc*lanc:8";
402 achain_type = "sinc*lanc:8";
403 d2::align::no_mc();
404 ip_iterations = 4;
405 d2::image_rw::exp_noscale();
406 cx_parameter = 0;
407 } else if (arg_count(argc, argv, "--qr")) {
408 ochain_types[0] = "sinc*lanc:8";
409 achain_type = "sinc*lanc:8";
410 d2::align::no_mc();
411 ip_iterations = 6;
412 d2::image_rw::exp_scale();
413 cx_parameter = 0.7;
414 } else {
416 * Same as --q0
418 ochain_types[0] = "fine:box:1,triangle:2";
419 achain_type = "triangle:2";
420 d2::align::mc(0.3);
421 ip_iterations = 0;
422 d2::image_rw::exp_noscale();
423 cx_parameter = 0;
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")) {
460 d2::align::all();
461 } else if (!strcmp(argv[i], "--align-green")) {
462 d2::align::green();
463 } else if (!strcmp(argv[i], "--align-sum")) {
464 d2::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")) {
484 extend = 0;
485 } else if (!strcmp(argv[i], "--extend")) {
486 extend = 1;
487 } else if (!strcmp(argv[i], "--no-mc")) {
488 d2::align::no_mc();
489 } else if (!strcmp(argv[i], "--oc")) {
490 d3::scene::oc();
491 } else if (!strcmp(argv[i], "--no-oc")) {
492 d3::scene::no_oc();
493 } else if (!strcmp(argv[i], "--gs")) {
494 if (i + 1 >= argc)
495 not_enough("--gs");
497 d2::align::gs(argv[i+1]);
498 i += 1;
500 } else if (!strcmp(argv[i], "--gs-mo")) {
501 if (i + 1 >= argc)
502 not_enough("--gs-mo");
504 unsigned int mo_parameter;
505 if (sscanf(argv[i+1], "%u", &mo_parameter) != 1)
506 bad_arg("--gs-mo");
508 d2::align::gs_mo(mo_parameter);
509 i += 1;
511 } else if (!strcmp(argv[i], "--focus")) {
514 * Check for argument availability
517 if (i + 1 >= argc)
518 not_enough(argv[i]);
520 double one = +1;
521 double zero = +0;
522 double inf = one / zero;
524 assert (isinf(inf) == +1);
527 * Focus type
530 unsigned int type = 0;
531 double distance;
532 double px, py;
534 if (!strcmp(argv[i+1], "d")) {
536 type = 0;
538 if (i + 2 > argc)
539 not_enough("--focus d");
541 if (sscanf(argv[i+2], "%lf", &distance) != 1)
542 bad_arg("--focus d");
544 i += 2;
546 } else if (!strcmp(argv[i+1], "p")) {
548 type = 1;
550 if (i + 3 > argc)
551 not_enough("--focus");
553 if (sscanf(argv[i+2], "%lf", &px) != 1
554 || sscanf(argv[i+3], "%lf", &py) != 1)
555 bad_arg("--focus");
557 i += 3;
559 } else {
560 bad_arg(argv[i]);
564 * Options
567 unsigned int ci = 0;
568 double fr = 0;
569 double ht = 0;
570 double vt = 0;
571 double sd = 0;
572 double ed = inf;
573 double sx = -inf;
574 double ex = inf;
575 double sy = -inf;
576 double ey = inf;
577 double ap = 3;
578 unsigned int sc = 3;
579 unsigned int fs = 0;
580 unsigned int sr = 0;
582 int options = 1;
584 i++;
586 while (options && i < argc) {
587 if (!strncmp(argv[i], "ci=", 3)) {
588 if(sscanf(argv[i] + 3, "%u", &ci) != 1)
589 bad_arg("--focus");
590 } else if (!strncmp(argv[i], "fr=", 3)) {
591 if(sscanf(argv[i] + 3, "%lf", &fr) != 1)
592 bad_arg("--focus");
593 } else if (!strncmp(argv[i], "ht=", 3)) {
594 if(sscanf(argv[i] + 3, "%lf", &ht) != 1)
595 bad_arg("--focus");
596 } else if (!strncmp(argv[i], "vt=", 3)) {
597 if(sscanf(argv[i] + 3, "%lf", &vt) != 1)
598 bad_arg("--focus");
599 } else if (!strncmp(argv[i], "sy=", 3)) {
600 if(sscanf(argv[i] + 3, "%lf", &sy) != 1)
601 bad_arg("--focus");
602 } else if (!strncmp(argv[i], "ey=", 3)) {
603 if(sscanf(argv[i] + 3, "%lf", &ey) != 1)
604 bad_arg("--focus");
605 } else if (!strncmp(argv[i], "sx=", 3)) {
606 if(sscanf(argv[i] + 3, "%lf", &sx) != 1)
607 bad_arg("--focus");
608 } else if (!strncmp(argv[i], "ex=", 3)) {
609 if(sscanf(argv[i] + 3, "%lf", &ex) != 1)
610 bad_arg("--focus");
611 } else if (!strncmp(argv[i], "sd=", 3)) {
612 if(sscanf(argv[i] + 3, "%lf", &sd) != 1)
613 bad_arg("--focus");
614 } else if (!strncmp(argv[i], "ed=", 3)) {
615 if(sscanf(argv[i] + 3, "%lf", &ed) != 1)
616 bad_arg("--focus");
617 } else if (!strncmp(argv[i], "ap=", 3)) {
618 if(sscanf(argv[i] + 3, "%lf", &ap) != 1)
619 bad_arg("--focus");
620 } else if (!strncmp(argv[i], "sc=", 3)) {
621 if(sscanf(argv[i] + 3, "%u", &sc) != 1)
622 bad_arg("--focus");
623 } else if (!strncmp(argv[i], "sr=", 3)) {
624 if (!strcmp(argv[i], "sr=aperture")) {
625 sr = 0;
626 } else if (!strcmp(argv[i], "sr=pixel")) {
627 sr = 1;
628 } else
629 bad_arg("--focus");
631 } else if (!strncmp(argv[i], "fs=", 3)) {
632 if (!strcmp(argv[i], "fs=mean")) {
633 fs = 0;
634 } else if (!strcmp(argv[i], "fs=median")) {
635 fs = 1;
636 } else
637 bad_arg("--focus");
638 } else
639 options = 0;
641 if (options)
642 i++;
645 i--;
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")) {
650 d2::align::keep();
653 * Unsupported configurations
656 if (ip_iterations)
657 unsupported::fornow("3D modeling with Irani-Peleg rendering");
659 #if 0
660 if (usm_multiplier)
661 unsupported::fornow("3D modeling with unsharp mask");
662 #endif
665 * Check for argument availability
668 if (i + 10 >= argc)
669 not_enough(argv[i]);
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;
686 double view_angle;
687 double x, y, z;
688 double P, Y, R;
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)
699 bad_arg(argv[i]);
701 view_angle *= M_PI / 180;
702 P *= M_PI / 180;
703 Y *= M_PI / 180;
704 R *= 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;
715 } else {
716 assert(0);
719 i+=10;
720 } else if (!strcmp(argv[i], "--3dv")) {
721 d2::align::keep();
723 unsigned int frame_no;
726 * Unsupported configurations
729 if (ip_iterations)
730 unsupported::fornow("3D modeling with Irani-Peleg rendering");
732 #if 0
733 if (usm_multiplier)
734 unsupported::fornow("3D modeling with unsharp mask");
735 #endif
738 * Check for argument availability
741 if (i + 2 >= argc)
742 not_enough("--3dv");
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];
766 i+=2;
767 } else if (!strcmp(argv[i], "--3dd")) {
768 d2::align::keep();
770 unsigned int frame_no;
773 * Unsupported configurations
776 if (ip_iterations)
777 unsupported::fornow("3D modeling with Irani-Peleg rendering");
779 #if 0
780 if (usm_multiplier)
781 unsupported::fornow("3D modeling with unsharp mask");
782 #endif
785 * Check for argument availability
788 if (i + 2 >= argc)
789 not_enough("--3dd");
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];
813 i+=2;
815 } else if (!strcmp(argv[i], "--view-angle")) {
816 if (i + 1 >= argc)
817 not_enough("--view-angle");
819 double va_parameter;
820 sscanf(argv[i+1], "%lf", &va_parameter);
821 i += 1;
822 user_view_angle = va_parameter * M_PI / 180;
823 } else if (!strcmp(argv[i], "--cpf-load")) {
824 if (i + 1 >= argc)
825 not_enough("--cpf-load");
827 d3::cpf::init_loadfile(argv[i+1]);
828 i += 1;
829 } else if (!strcmp(argv[i], "--ui=stream")) {
830 ui::set_stream();
831 } else if (!strcmp(argv[i], "--ui=tty")) {
832 ui::set_tty();
833 } else if (!strcmp(argv[i], "--3d-fmr")) {
835 if (i + 1 >= argc)
836 not_enough("--3d-fmr");
838 double fmr_parameter;
839 sscanf(argv[i+1], "%lf", &fmr_parameter);
840 i += 1;
841 d3::scene::fmr(fmr_parameter);
843 } else if (!strcmp(argv[i], "--3d-dmr")) {
845 if (i + 1 >= argc)
846 not_enough("--3d-dmr");
848 double dmr_parameter;
849 sscanf(argv[i+1], "%lf", &dmr_parameter);
850 i += 1;
851 d3::scene::dmr(dmr_parameter);
853 } else if (!strcmp(argv[i], "--et")) {
855 if (i + 1 >= argc)
856 not_enough("--et");
858 double et_parameter;
859 sscanf(argv[i+1], "%lf", &et_parameter);
860 i += 1;
861 d3::scene::et(et_parameter);
863 } else if (!strcmp(argv[i], "--st")) {
864 if (i + 1 >= argc)
865 not_enough("--st");
867 double st_parameter;
868 sscanf(argv[i+1], "%lf", &st_parameter);
869 i += 1;
870 d3::cpf::st(st_parameter);
871 } else if (!strcmp(argv[i], "--di-lower")) {
872 if (i + 1 >= argc)
873 not_enough("--di-lower");
875 double di_parameter;
876 sscanf(argv[i+1], "%lf", &di_parameter);
877 i += 1;
878 d3::scene::di_lower(di_parameter);
879 } else if (!strcmp(argv[i], "--rc")) {
880 if (i + 1 >= argc)
881 not_enough("--rc");
883 double rc_parameter;
884 sscanf(argv[i+1], "%lf", &rc_parameter);
885 i += 1;
886 d3::scene::rc(rc_parameter);
887 } else if (!strcmp(argv[i], "--do-try")) {
888 if (i + 1 >= argc)
889 not_enough("--do-try");
891 double do_parameter;
892 sscanf(argv[i+1], "%lf", &do_parameter);
893 i += 1;
894 d3::scene::do_try(do_parameter);
895 } else if (!strcmp(argv[i], "--di-upper")) {
896 if (i + 1 >= argc)
897 not_enough("--di-upper");
899 double dgi_parameter;
900 sscanf(argv[i+1], "%lf", &dgi_parameter);
901 i += 1;
902 d3::scene::di_upper(dgi_parameter);
903 } else if (!strcmp(argv[i], "--fc")) {
904 if (i + 1 >= argc)
905 not_enough("--fc");
907 double fc_parameter;
908 sscanf(argv[i+1], "%lf", &fc_parameter);
909 i += 1;
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")) {
916 if (i + 1 >= argc)
917 not_enough("--def-nn");
919 double nn_parameter;
920 sscanf(argv[i+1], "%lf", &nn_parameter);
921 i += 1;
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")) {
930 if (i + 1 >= argc)
931 not_enough("--mc");
933 double mc_parameter;
934 sscanf(argv[i+1], "%lf", &mc_parameter);
935 mc_parameter /= 100;
936 i += 1;
937 d2::align::mc(mc_parameter);
939 } else if (!strcmp(argv[i], "--fx")) {
941 if (i + 1 >= argc)
942 not_enough("--fx");
944 double fx_parameter;
945 sscanf(argv[i+1], "%lf", &fx_parameter);
946 i += 1;
947 d3::scene::fx(fx_parameter);
949 } else if (!strcmp(argv[i], "--tcem")) {
951 if (i + 1 >= argc)
952 not_enough("--tcem");
954 double tcem_parameter;
955 sscanf(argv[i+1], "%lf", &tcem_parameter);
956 i += 1;
957 d3::scene::tcem(tcem_parameter);
959 } else if (!strcmp(argv[i], "--oui")) {
961 if (i + 1 >= argc)
962 not_enough("--oui");
964 unsigned int oui_parameter;
965 sscanf(argv[i+1], "%u", &oui_parameter);
966 i += 1;
967 d3::scene::oui(oui_parameter);
969 } else if (!strcmp(argv[i], "--pa")) {
971 if (i + 1 >= argc)
972 not_enough("--pa");
974 unsigned int pa_parameter;
975 sscanf(argv[i+1], "%u", &pa_parameter);
976 i += 1;
977 d3::scene::pa(pa_parameter);
979 } else if (!strcmp(argv[i], "--pc")) {
981 if (i + 1 >= argc)
982 not_enough("--pc");
984 d3::scene::pc(argv[i+1]);
985 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");
995 if (i + 3 >= argc)
996 not_enough("--wm");
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");
1005 i += 3;
1007 } else if (!strcmp(argv[i], "--fl")) {
1008 if (i + 3 >= argc)
1009 not_enough("--fl");
1010 double h, v, a;
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");
1017 i += 3;
1018 #ifdef USE_FFTW
1019 d2::align::set_frequency_cut(h, v, a);
1020 #else
1021 ui::get()->error_hint("--fl is not supported", "rebuild ALE with FFTW=1");
1022 #endif
1023 } else if (!strcmp(argv[i], "--wmx")) {
1024 if (i + 3 >= argc)
1025 not_enough("--wmx");
1026 #ifdef USE_UNIX
1027 d2::align::set_wmx(argv[i+1], argv[i+2], argv[i+3]);
1028 #else
1029 ui::get()->error_hint("--wmx is not supported", "rebuild ALE with POSIX=1");
1030 #endif
1031 i += 3;
1032 } else if (!strcmp(argv[i], "--flshow")) {
1033 if (i + 1 >= argc)
1034 not_enough("--flshow");
1035 d2::align::set_fl_show(argv[i+1]);
1036 i++;
1037 } else if (!strcmp(argv[i], "--3dpx")) {
1038 if (i + 6 >= argc)
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)
1045 bad_arg("--d3px");
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
1062 d3px_count++;
1063 i += 6;
1064 } else if (!strcmp(argv[i], "--ex")) {
1065 if (i + 6 >= argc)
1066 not_enough("--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)
1072 bad_arg("--ex");
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
1089 ex_count++;
1090 i += 6;
1091 } else if (!strcmp(argv[i], "--crop")) {
1092 if (i + 6 >= argc)
1093 not_enough("--crop");
1095 ex_parameters = (int *) local_realloc(ex_parameters, (ex_count + 4) * 6 * sizeof(int));
1096 int crop_args[6];
1098 for (int param = 0; param < 6; param++)
1099 if (sscanf(argv[i + param + 1], "%d", &(crop_args[param])) != 1)
1100 bad_arg("--crop");
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
1156 ex_count += 4;
1157 i += 6;
1158 } else if (!strcmp(argv[i], "--exshow")) {
1159 ex_show = 1;
1160 } else if (!strcmp(argv[i], "--wt")) {
1161 if (i + 1 >= argc)
1162 not_enough("--wt");
1164 double wt;
1166 if (sscanf(argv[i + 1], "%lf", &wt) != 1)
1167 bad_arg("--wt");
1169 d2::render::set_wt(wt);
1170 i++;
1171 } else if (!strcmp(argv[i], "--3d-chain")) {
1172 if (i + 1 >= argc)
1173 not_enough("--3d-chain");
1174 d3chain_type = argv[i+1];
1175 i++;
1176 } else if (!strcmp(argv[i], "--dchain")) {
1177 if (i + 1 >= argc)
1178 not_enough("--dchain");
1179 ochain_types[0] = argv[i+1];
1180 i++;
1181 } else if (!strcmp(argv[i], "--achain")) {
1182 if (i + 1 >= argc)
1183 not_enough("--achain");
1184 achain_type = argv[i+1];
1185 i++;
1186 } else if (!strcmp(argv[i], "--afilter")) {
1187 if (i + 1 >= argc)
1188 not_enough("--afilter");
1189 afilter_type = argv[i+1];
1190 i++;
1191 } else if (!strcmp(argv[i], "--ochain")) {
1192 if (i + 2 >= argc)
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];
1205 oc_count++;
1206 i+=2;
1207 } else if (!strcmp(argv[i], "--visp")) {
1208 if (i + 5 >= argc)
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];
1217 vise_count++;
1218 i+=4;
1219 } else if (!strcmp(argv[i], "--cx")) {
1221 if (i + 1 >= argc)
1222 not_enough("--cx");
1224 sscanf(argv[i+1], "%lf", &cx_parameter);
1225 i += 1;
1227 } else if (!strcmp(argv[i], "--no-cx")) {
1228 cx_parameter = 0;
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")) {
1232 if (i + 1 >= argc)
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;
1250 } else {
1251 bad_arg("--bayer");
1253 i++;
1254 } else if (!strcmp(argv[i], "--lpsf")) {
1255 if (i + 1 >= argc)
1256 not_enough("--lpsf");
1258 psf[psf_linear] = argv[i+1];
1259 i++;
1260 } else if (!strcmp(argv[i], "--nlpsf")) {
1261 if (i + 1 >= argc)
1262 not_enough("--nlpsf");
1264 psf[psf_nonlinear] = argv[i+1];
1265 i++;
1267 } else if (!strcmp(argv[i], "--psf-match")) {
1268 if (i + 6 >= argc)
1269 not_enough("--psf-match");
1271 psf_match = 1;
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");
1276 i++;
1279 } else if (!strcmp(argv[i], "--device")) {
1280 if (i + 1 >= argc)
1281 not_enough("--device");
1283 device = argv[i+1];
1284 i++;
1286 #if 0
1287 } else if (!strcmp(argv[i], "--usm")) {
1289 if (d3_output != NULL)
1290 unsupported::fornow("3D modeling with unsharp mask");
1292 if (i + 1 >= argc)
1293 not_enough("--usm");
1295 sscanf(argv[i+1], "%lf", &usm_multiplier);
1296 i++;
1297 #endif
1299 } else if (!strcmp(argv[i], "--ipr")) {
1301 if (i + 1 >= argc)
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");
1308 i++;
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")) {
1323 ip_use_median = 0;
1324 } else if (!strcmp(argv[i], "--ip-median")) {
1325 ip_use_median = 1;
1326 } else if (!strcmp(argv[i], "--ips")) {
1328 if (i + 1 >= argc)
1329 not_enough("--ips");
1331 if (sscanf(argv[i+1], "%d", &ip_iterations) != 1)
1332 ui::get()->error("--ips requires an integer argument");
1333 i++;
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")) {
1359 d3::scene::nw();
1360 } else if (!strcmp(argv[i], "--occ-nonorm")) {
1361 d3::scene::no_nw();
1362 } else if (!strcmp(argv[i], "--inc")) {
1363 inc = 1;
1364 } else if (!strcmp(argv[i], "--no-inc")) {
1365 inc = 0;
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="))) {
1391 double 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;
1404 int characters;
1405 sscanf(argv[i] + strlen("--perturb-upper="), "%lf%n", &perturb_upper,
1406 &characters);
1407 if (*(argv[i] + strlen("--perturb-upper=") + characters) == '%')
1408 d2::align::set_perturb_upper(perturb_upper, 1);
1409 else
1410 d2::align::set_perturb_upper(perturb_upper, 0);
1411 } else if (!strncmp(argv[i], "--perturb-lower=", strlen("--perturb-lower="))) {
1412 double perturb_lower;
1413 int characters;
1414 sscanf(argv[i] + strlen("--perturb-lower="), "%lf%n", &perturb_lower,
1415 &characters);
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);
1421 else
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="))) {
1429 double va_upper;
1430 int characters;
1431 sscanf(argv[i] + strlen("--va-upper="), "%lf%n", &va_upper,
1432 &characters);
1433 if (*(argv[i] + strlen("--va-upper=") + characters) == '%')
1434 ui::get()->error("--va-upper= does not accept '%' arguments\n");
1435 else
1436 d3::cpf::set_va_upper(va_upper);
1437 } else if (!strncmp(argv[i], "--cpp-upper=", strlen("--cpp-upper="))) {
1438 double perturb_upper;
1439 int characters;
1440 sscanf(argv[i] + strlen("--cpp-upper="), "%lf%n", &perturb_upper,
1441 &characters);
1442 if (*(argv[i] + strlen("--cpp-upper=") + characters) == '%')
1443 ui::get()->error("--cpp-upper= does not currently accept '%' arguments\n");
1444 else
1445 d3::cpf::set_cpp_upper(perturb_upper);
1446 } else if (!strncmp(argv[i], "--cpp-lower=", strlen("--cpp-lower="))) {
1447 double perturb_lower;
1448 int characters;
1449 sscanf(argv[i] + strlen("--cpp-lower="), "%lf%n", &perturb_lower,
1450 &characters);
1451 if (*(argv[i] + strlen("--cpp-lower=") + characters) == '%')
1452 ui::get()->error("--cpp-lower= does not currently accept '%' arguments\n");
1453 else
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="))) {
1458 double rot_max;
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="))) {
1462 double 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="))) {
1466 double 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="))) {
1470 double 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="));
1475 #if 0
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="));
1480 #endif
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);
1497 } else {
1500 * Trap illegal options and end-of-option indicators.
1503 if (!strcmp(argv[i], "--"))
1504 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.",
1515 "--extend");
1516 extend = 1;
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");
1526 #if 0
1527 if (extend == 0 && d3_output != NULL) {
1528 implication::changed("3D modeling requires increased image extents.",
1529 "Image extension is now enabled.",
1530 "--extend");
1531 extend = 1;
1533 #endif
1535 if (cx_parameter != 0 && !exposure_register) {
1536 implication::changed("Certainty-based rendering requires exposure registration.",
1537 "Exposure registration is now enabled.",
1538 "--exp-register");
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);
1556 * Set confidence
1559 d2::exposure::set_confidence(cx_parameter);
1562 * Keep transformations for Irani-Peleg, psf-match, and
1563 * VISE
1566 if (ip_iterations > 0 || psf_match || vise_count > 0) {
1567 d2::align::keep();
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();
1634 } else {
1635 ui::get()->unknown_device(device);
1637 } else {
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.
1657 if (psf_match) {
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];
1688 } else {
1691 * Default point-spread function.
1694 if (n == psf_linear) {
1697 * Default lpsf is a box filter
1698 * of diameter 1.0 (radius
1699 * 0.5).
1702 response[n] = new d2::box(0.5);
1704 } else if (n == psf_nonlinear) {
1707 * nlpsf is disabled by default.
1710 response[n] = NULL;
1716 * First file argument. Print general file information as well
1717 * as information specific to this argument. Initialize image
1718 * file handler.
1722 * There should be at least two file arguments.
1725 if (i >= argc - 1) {
1726 hi.usage();
1727 exit(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.
1744 if (psf_match) {
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
1762 * have one.
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
1788 * alignment.
1791 d2::align::set_reference(achain);
1794 * Tell the alignment class about the scale factor.
1797 d2::align::set_scale(scale_factor);
1800 * Initialize visp.
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]),
1807 visp[opt * 4 + 1],
1808 visp[opt * 4 + 2],
1809 visp[opt * 4 + 3]);
1813 * Initialize non-incremental renderers
1816 #if 0
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]);
1827 #endif
1829 if (psf_match) {
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],
1842 psf_match_args);
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);
1865 if (inc) {
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);
1902 if (inc) {
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();
1938 if (d3_count > 0) {
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);
1971 int view_count = 0;
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);
1980 delete im;
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);
1988 delete im;
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);
1999 delete im;
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);
2011 delete im;
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
2034 * exist.
2037 tsave_delete(tsave);
2038 tload_delete(tload);
2041 * We're done.
2044 exit(0);
2049 * If there was no output, the user might need more information.
2052 hi.usage();
2053 exit(1);