Libmv: Fix missing virtual destructor in frame access sub-class
[blender.git] / intern / libmv / intern / frame_accessor.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2014 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation,
22  *                 Sergey Sharybin
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 #include "intern/frame_accessor.h"
28 #include "intern/image.h"
29 #include "intern/utildefines.h"
30 #include "libmv/autotrack/frame_accessor.h"
31 #include "libmv/autotrack/region.h"
32 #include "libmv/image/image.h"
33
34 namespace {
35
36 using libmv::FloatImage;
37 using mv::FrameAccessor;
38 using mv::Region;
39
40 struct LibmvFrameAccessor : public FrameAccessor {
41   LibmvFrameAccessor(libmv_FrameAccessorUserData* user_data,
42                      libmv_GetImageCallback get_image_callback,
43                      libmv_ReleaseImageCallback release_image_callback)
44     : user_data_(user_data),
45       get_image_callback_(get_image_callback),
46       release_image_callback_(release_image_callback) { }
47
48   virtual ~LibmvFrameAccessor() {
49   }
50
51   libmv_InputMode get_libmv_input_mode(InputMode input_mode) {
52     switch (input_mode) {
53 #define CHECK_INPUT_MODE(mode) \
54       case mode: \
55         return LIBMV_IMAGE_MODE_ ## mode;
56       CHECK_INPUT_MODE(MONO)
57       CHECK_INPUT_MODE(RGBA)
58 #undef CHECK_INPUT_MODE
59     }
60     assert(!"unknown input mode passed from Libmv.");
61     // TODO(sergey): Proper error handling here in the future.
62     return LIBMV_IMAGE_MODE_MONO;
63   }
64
65   void get_libmv_region(const Region& region,
66                         libmv_Region* libmv_region) {
67     libmv_region->min[0] = region.min(0);
68     libmv_region->min[1] = region.min(1);
69     libmv_region->max[0] = region.max(0);
70     libmv_region->max[1] = region.max(1);
71   }
72
73   Key GetImage(int clip,
74                int frame,
75                InputMode input_mode,
76                int downscale,
77                const Region* region,
78                const Transform* transform,
79                FloatImage* destination) {
80     float *float_buffer;
81     int width, height, channels;
82     libmv_Region libmv_region;
83     if (region) {
84       get_libmv_region(*region, &libmv_region);
85     }
86     Key cache_key = get_image_callback_(user_data_,
87                                         clip,
88                                         frame,
89                                         get_libmv_input_mode(input_mode),
90                                         downscale,
91                                         region != NULL ? &libmv_region : NULL,
92                                         (libmv_FrameTransform*) transform,
93                                         &float_buffer,
94                                         &width,
95                                         &height,
96                                         &channels);
97
98     // TODO(sergey): Dumb code for until we can set data directly.
99     FloatImage temp_image(float_buffer,
100                           height,
101                           width,
102                           channels);
103     destination->CopyFrom(temp_image);
104
105     return cache_key;
106   }
107
108   void ReleaseImage(Key cache_key) {
109     release_image_callback_(cache_key);
110   }
111
112   bool GetClipDimensions(int /*clip*/, int * /*width*/, int * /*height*/) {
113     return false;
114   }
115
116   int NumClips() {
117     return 1;
118   }
119
120   int NumFrames(int /*clip*/) {
121     return 0;
122   }
123
124   libmv_FrameAccessorUserData* user_data_;
125   libmv_GetImageCallback get_image_callback_;
126   libmv_ReleaseImageCallback release_image_callback_;
127 };
128
129 }  // namespace
130
131 libmv_FrameAccessor* libmv_FrameAccessorNew(
132     libmv_FrameAccessorUserData* user_data,
133     libmv_GetImageCallback get_image_callback,
134     libmv_ReleaseImageCallback release_image_callback) {
135   return (libmv_FrameAccessor*) LIBMV_OBJECT_NEW(LibmvFrameAccessor,
136                                                  user_data,
137                                                  get_image_callback,
138                                                  release_image_callback);
139 }
140
141 void libmv_FrameAccessorDestroy(libmv_FrameAccessor* frame_accessor) {
142   LIBMV_OBJECT_DELETE(frame_accessor, LibmvFrameAccessor);
143 }
144
145 int64_t libmv_frameAccessorgetTransformKey(const libmv_FrameTransform *transform) {
146   return ((FrameAccessor::Transform*) transform)->key();
147 }
148
149 void libmv_frameAccessorgetTransformRun(const libmv_FrameTransform *transform,
150                                         const libmv_FloatImage *input_image,
151                                         libmv_FloatImage *output_image) {
152   const FloatImage input(input_image->buffer,
153                          input_image->height,
154                          input_image->width,
155                          input_image->channels);
156
157   FloatImage output;
158   ((FrameAccessor::Transform*) transform)->run(input,
159                                                &output);
160
161   int num_pixels = output.Width() *output.Height() * output.Depth();
162   output_image->buffer = new float[num_pixels];
163   memcpy(output_image->buffer, output.Data(), num_pixels * sizeof(float));
164   output_image->width = output.Width();
165   output_image->height = output.Height();
166   output_image->channels = output.Depth();
167 }