bugs: Consider info format for help pages.
[Ale.git] / d2 / vise / sf.h
blobbb4a1da0953d1b371a0fe24c0e8b55d8cfd2fa16
1 // Copyright 2004 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 3 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 * sf.h: A video stabilizer that uses a single frame's transformation.
25 #ifndef __sf_h__
26 #define __sf_h__
28 #include "../vise.h"
29 #include "../image.h"
30 #include "../point.h"
33 * Stabilize to the viewpoint of a single frame.
36 class sf : public vise {
37 unsigned int frame;
38 public:
39 sf(render *r, unsigned int frame, const char *prefix, const char *suffix,
40 ale_real scale_factor) : vise(r, prefix, suffix, scale_factor) {
41 if (frame > 10) {
42 fprintf(stderr, "\n\n*** Warning: large values <x> for VISE sf:<x> are not recommended ***\n\n");
44 r->extend_queue(frame);
45 this->frame = frame;
49 * Accept an image for rendering.
52 void render_frame(unsigned int frame_number) {
54 const image *im = r->get_image(frame_number);
55 int replace = 0; // Are image regions being replaced?
56 int replace_ex = 0; // If image regions are being replaced, are we honoring exclusion regions?
57 unsigned int rx_count = render::get_rx_count();
58 const filter::scaled_filter *scf = NULL;
59 const exclusion *rx_parameters = render::get_rx_parameters();
60 int rx_show = render::is_rx_show();
63 * Determine, for single-invariant chains, whether replacement
64 * is occurring, and, if so, determine whether we are honoring
65 * exclusion regions.
67 if (typeid(*r) == typeid(incremental)
68 && ((incremental *)r)->get_invariant()->is_last()) {
69 scf = ((incremental *)r)->get_invariant()->ssfe()->get_scaled_filter();
70 assert(scf);
71 if (scf->is_coarse() && scf->get_filter()->support() >= 1) {
72 replace = 1;
73 replace_ex = ((incremental *)r)->get_invariant()->ssfe()->ex_is_honored();
78 * Generate the desired transformation.
80 transformation t = align::of(frame_number);
81 transformation s = align::of(frame);
82 unsigned int new_height = (unsigned int)
83 floor(s.unscaled_height() * scale_factor);
84 unsigned int new_width = (unsigned int)
85 floor(s.unscaled_width() * scale_factor);
86 s.set_domain(new_height, new_width);
88 image *rendered = new_image_ale_real(new_height, new_width, 3);
90 const image *replace_image = NULL;
92 if (replace) {
93 replace_image = image_rw::open(frame_number);
94 scf->set_parameters(t, s, replace_image);
97 for (unsigned int i = 0; i < rendered->height(); i++)
98 for (unsigned int j = 0; j < rendered->width(); j++) {
99 point unoffset_p = s.transform_scaled(point(i, j));
100 point p = unoffset_p - im->offset();
101 double shading = 1;
103 if (rx_show || (replace && replace_ex))
104 for (unsigned int param = 0; param < rx_count; param++) {
105 if (rx_parameters[param].type == exclusion::RENDER
106 && unoffset_p[0] >= rx_parameters[param].x[0]
107 && unoffset_p[0] <= rx_parameters[param].x[1]
108 && unoffset_p[1] >= rx_parameters[param].x[2]
109 && unoffset_p[1] <= rx_parameters[param].x[3]
110 && frame_number >= (unsigned) rx_parameters[param].x[4]
111 && frame_number <= (unsigned) rx_parameters[param].x[5])
112 shading *= 0.5;
114 if (rx_parameters[param].type == exclusion::FRAME
115 && i >= rx_parameters[param].x[0] * (ale_pos) scale_factor
116 && i <= rx_parameters[param].x[1] * (ale_pos) scale_factor
117 && j >= rx_parameters[param].x[2] * (ale_pos) scale_factor
118 && j <= rx_parameters[param].x[3] * (ale_pos) scale_factor
119 && frame_number >= (unsigned) rx_parameters[param].x[4]
120 && frame_number <= (unsigned) rx_parameters[param].x[5])
121 shading *= 0.5;
124 if (shading < 1 && !rx_show && replace && replace_ex)
125 continue;
127 if (replace) {
128 pixel value, weight;
130 scf->filtered(i, j, &value, &weight, replace_ex, frame_number);
132 if (weight.min_norm() > ale_real_weight_floor) {
133 rendered->set_pixel(i, j, shading * (value / weight));
134 continue;
138 if (p[0] >= 0
139 && p[0] <= im->height() - 1
140 && p[1] >= 0
141 && p[1] <= im->width() - 1)
142 rendered->set_pixel(i, j, shading * im->get_bl(p));
143 else
144 rendered->set_pixel(i, j, pixel(0, 0, 0));
147 if (replace)
148 image_rw::close(frame_number);
150 write_frame(rendered, frame_number);
152 delete rendered;
156 * Report the frame lag for this stabilizer.
159 unsigned int lag() {
160 return frame;
164 #endif