source: src/filter/scale0tilt/scale0tilt.c @ fb31c3

Revision fb31c3, 7.3 KB checked in by Jaromil <jaromil@…>, 4 years ago (diff)

patch contributed by Burkhard Plaum
 http://thread.gmane.org/gmane.comp.video.frei0r.devel/585

  • Property mode set to 100644
Line 
1/* scale0tilt.c
2 * Copyright (C) 2007 Richard Spindler (richard.spindler@gmail.com)
3 * This file is a Frei0r plugin.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <math.h>
21#include "frei0r.h"
22#include <gavl/gavl.h>
23#include <stdlib.h>
24#include <string.h>
25
26typedef struct scale0tilt_instance {
27        double cl, ct, cr, cb;
28        double sx, sy;
29        double tx, ty;
30        int w, h;
31        gavl_video_scaler_t* video_scaler;
32        gavl_video_frame_t* frame_src;
33        gavl_video_frame_t* frame_dst;
34} scale0tilt_instance_t;
35
36void update_scaler( scale0tilt_instance_t* inst )
37{
38        float dst_x, dst_y, dst_w, dst_h;
39        float src_x, src_y, src_w, src_h;
40
41        src_x = inst->w * inst->cl;
42        src_y = inst->h * inst->ct;
43        src_w = inst->w * (1.0 - inst->cl - inst->cr );
44        src_h = inst->h * (1.0 - inst->ct - inst->cb );
45
46        dst_x = inst->w * inst->cl * inst->sx + inst->tx * inst->w;
47        dst_y = inst->h * inst->ct * inst->sy + inst->ty * inst->h;
48        dst_w = inst->w * (1.0 - inst->cl - inst->cr) * inst->sx;
49        dst_h = inst->h * (1.0 - inst->ct - inst->cb) * inst->sy;
50
51        if ( dst_x + dst_w > inst->w ) {
52                src_w = src_w * ( (inst->w-dst_x) / dst_w );
53                dst_w = inst->w - dst_x;
54        }
55        if ( dst_y + dst_h > inst->h ) {
56                src_h = src_h * ( (inst->h-dst_y) / dst_h );
57                dst_h = inst->h - dst_y;
58        }
59        if ( dst_x < 0 ) {
60                src_x = src_x - dst_x * ( src_w / dst_w );
61                src_w = src_w * ( (dst_w+dst_x) / dst_w );
62                dst_w = dst_w + dst_x;
63                dst_x = 0;
64        }
65        if ( dst_y < 0 ) {
66                src_y = src_y - dst_y * ( src_h / dst_h );
67                src_h = src_h * ( (dst_h+dst_y) / dst_h );
68                dst_h = dst_h + dst_y;
69                dst_y = 0;
70        }
71        gavl_video_options_t* options = gavl_video_scaler_get_options( inst->video_scaler );
72
73        gavl_video_format_t format_src;
74        gavl_video_format_t format_dst;
75
76        memset(&format_src, 0, sizeof(format_src));
77        memset(&format_dst, 0, sizeof(format_dst));
78
79        format_dst.frame_width  = inst->w;
80        format_dst.frame_height = inst->h;
81        format_dst.image_width  = inst->w;
82        format_dst.image_height = inst->h;
83        format_dst.pixel_width = 1;
84        format_dst.pixel_height = 1;
85        format_dst.pixelformat = GAVL_RGBA_32;
86       
87        format_src.frame_width  = inst->w;
88        format_src.frame_height = inst->h;
89        format_src.image_width  = inst->w;
90        format_src.image_height = inst->h;
91        format_src.pixel_width = 1;
92        format_src.pixel_height = 1;
93        format_src.pixelformat = GAVL_RGBA_32;
94
95        gavl_rectangle_f_t src_rect;
96        gavl_rectangle_i_t dst_rect;
97
98        src_rect.x = src_x;
99        src_rect.y = src_y;
100        src_rect.w = src_w;
101        src_rect.h = src_h;
102
103        dst_rect.x = lroundf(dst_x);
104        dst_rect.y = lroundf(dst_y);
105        dst_rect.w = lroundf(dst_w);
106        dst_rect.h = lroundf(dst_h);
107       
108        gavl_video_options_set_rectangles( options, &src_rect, &dst_rect );
109        gavl_video_scaler_init( inst->video_scaler, &format_src, &format_dst );
110}
111
112int f0r_init()
113{
114  return 1;
115}
116void f0r_deinit()
117{ /* empty */ }
118
119void f0r_get_plugin_info( f0r_plugin_info_t* info )
120{
121        info->name = "Scale0Tilt";
122        info->author = "Richard Spindler";
123        info->plugin_type = F0R_PLUGIN_TYPE_FILTER;
124        info->color_model = F0R_COLOR_MODEL_RGBA8888;
125        info->frei0r_version = FREI0R_MAJOR_VERSION;
126        info->major_version = 0;
127        info->minor_version = 1;
128        info->num_params =  8;
129        info->explanation = "Scales, Tilts and Crops an Image";
130
131}
132void f0r_get_param_info( f0r_param_info_t* info, int param_index )
133{
134        switch ( param_index ) {
135                case 0:
136                        info->name = "Clip left";
137                        info->type = F0R_PARAM_DOUBLE;
138                        info->explanation = "";
139                        break;
140                case 1:
141                        info->name = "Clip right";
142                        info->type = F0R_PARAM_DOUBLE;
143                        info->explanation = "";
144                        break;
145                case 2:
146                        info->name = "Clip top";
147                        info->type = F0R_PARAM_DOUBLE;
148                        info->explanation = "";
149                        break;
150                case 3:
151                        info->name = "Clip bottom";
152                        info->type = F0R_PARAM_DOUBLE;
153                        info->explanation = "";
154                        break;
155                case 4:
156                        info->name = "Scale X";
157                        info->type = F0R_PARAM_DOUBLE;
158                        info->explanation = "";
159                        break;
160                case 5:
161                        info->name = "Scale Y";
162                        info->type = F0R_PARAM_DOUBLE;
163                        info->explanation = "";
164                        break;
165                case 6:
166                        info->name = "Tilt X";
167                        info->type = F0R_PARAM_DOUBLE;
168                        info->explanation = "";
169                        break;
170                case 7:
171                        info->name = "Tilt Y";
172                        info->type = F0R_PARAM_DOUBLE;
173                        info->explanation = "";
174                        break;
175        }
176}
177
178f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
179{
180        scale0tilt_instance_t* inst = calloc(1, sizeof(*inst));
181        inst->w = width;
182        inst->h = height;
183        inst->sx = 1.0;
184        inst->sy = 1.0;
185        inst->video_scaler = gavl_video_scaler_create();
186        inst->frame_src = gavl_video_frame_create( 0 );
187        inst->frame_dst = gavl_video_frame_create( 0 );
188        inst->frame_src->strides[0] = width * 4;
189        inst->frame_dst->strides[0] = width * 4;
190        update_scaler(inst);
191        return (f0r_instance_t)inst;
192}
193void f0r_destruct(f0r_instance_t instance)
194{
195        scale0tilt_instance_t* inst = (scale0tilt_instance_t*)instance;
196        gavl_video_scaler_destroy(inst->video_scaler);
197        gavl_video_frame_null( inst->frame_src );
198        gavl_video_frame_destroy( inst->frame_src );
199        gavl_video_frame_null( inst->frame_dst );
200        gavl_video_frame_destroy( inst->frame_dst );
201        free(instance);
202}
203void f0r_set_param_value(f0r_instance_t instance,
204                         f0r_param_t param, int param_index)
205{
206        scale0tilt_instance_t* inst = (scale0tilt_instance_t*)instance;
207        switch ( param_index ) {
208                case 0:
209                        inst->cl = *((double*)param);
210                        break;
211                case 1:
212                        inst->cr = *((double*)param);
213                        break;
214                case 2:
215                        inst->ct = *((double*)param);
216                        break;
217                case 3:
218                        inst->cb = *((double*)param);
219                        break;
220                case 4:
221                        inst->sx = *((double*)param) * 2.0;
222                        break;
223                case 5:
224                        inst->sy = *((double*)param) * 2.0;
225                        break;
226                case 6:
227                        inst->tx = *((double*)param) * 2.0 - 1.0;
228                        break;
229                case 7:
230                        inst->ty = *((double*)param) * 2.0 - 1.0;
231                        break;
232        }
233        update_scaler( inst );
234}
235void f0r_get_param_value(f0r_instance_t instance,
236                         f0r_param_t param, int param_index)
237{
238        scale0tilt_instance_t* inst = (scale0tilt_instance_t*)instance;
239        switch ( param_index ) {
240                case 0:
241                        *((double*)param) = inst->cl;
242                        break;
243                case 1:
244                        *((double*)param) = inst->cr;
245                        break;
246                case 2:
247                        *((double*)param) = inst->ct;
248                        break;
249                case 3:
250                        *((double*)param) = inst->cb;
251                        break;
252                case 4:
253                        *((double*)param) = inst->sx / 2.0;
254                        break;
255                case 5:
256                        *((double*)param) = inst->sy / 2.0;
257                        break;
258                case 6:
259                        *((double*)param) = (inst->tx + 1.0) / 2.0;
260                        break;
261                case 7:
262                        *((double*)param) = (inst->ty + 1.0) / 2.0;
263                        break;
264        }
265}
266void f0r_update(f0r_instance_t instance, double time,
267                const uint32_t* inframe, uint32_t* outframe)
268{
269        scale0tilt_instance_t* inst = (scale0tilt_instance_t*)instance;
270        inst->frame_src->planes[0] = (uint8_t *)inframe;
271        inst->frame_dst->planes[0] = (uint8_t *)outframe;
272        int len = inst->w * inst->h;
273        int i;
274        for ( i = 0; i < len; i++ ) {
275                outframe[i] = 0;
276        }
277        gavl_video_scaler_scale( inst->video_scaler, inst->frame_src, inst->frame_dst );
278}
279
Note: See TracBrowser for help on using the repository browser.