transform.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Georg Martius <georg.martius@web.de>
3  * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * transform input video
25  */
26 
27 #include "libavutil/common.h"
28 #include "libavutil/avassert.h"
29 
30 #include "transform.h"
31 
32 #define INTERPOLATE_METHOD(name) \
33  static uint8_t name(float x, float y, const uint8_t *src, \
34  int width, int height, int stride, uint8_t def)
35 
36 #define PIXEL(img, x, y, w, h, stride, def) \
37  ((x) < 0 || (y) < 0) ? (def) : \
38  (((x) >= (w) || (y) >= (h)) ? (def) : \
39  img[(x) + (y) * (stride)])
40 
41 /**
42  * Nearest neighbor interpolation
43  */
44 INTERPOLATE_METHOD(interpolate_nearest)
45 {
46  return PIXEL(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def);
47 }
48 
49 /**
50  * Bilinear interpolation
51  */
52 INTERPOLATE_METHOD(interpolate_bilinear)
53 {
54  int x_c, x_f, y_c, y_f;
55  int v1, v2, v3, v4;
56 
57  if (x < -1 || x > width || y < -1 || y > height) {
58  return def;
59  } else {
60  x_f = (int)x;
61  x_c = x_f + 1;
62 
63  y_f = (int)y;
64  y_c = y_f + 1;
65 
66  v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
67  v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
68  v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
69  v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
70 
71  return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) +
72  v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y)));
73  }
74 }
75 
76 /**
77  * Biquadratic interpolation
78  */
79 INTERPOLATE_METHOD(interpolate_biquadratic)
80 {
81  int x_c, x_f, y_c, y_f;
82  uint8_t v1, v2, v3, v4;
83  float f1, f2, f3, f4;
84 
85  if (x < - 1 || x > width || y < -1 || y > height)
86  return def;
87  else {
88  x_f = (int)x;
89  x_c = x_f + 1;
90  y_f = (int)y;
91  y_c = y_f + 1;
92 
93  v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
94  v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
95  v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
96  v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
97 
98  f1 = 1 - sqrt((x_c - x) * (y_c - y));
99  f2 = 1 - sqrt((x_c - x) * (y - y_f));
100  f3 = 1 - sqrt((x - x_f) * (y_c - y));
101  f4 = 1 - sqrt((x - x_f) * (y - y_f));
102  return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4);
103  }
104 }
105 
106 void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix) {
107  matrix[0] = zoom * cos(angle);
108  matrix[1] = -sin(angle);
109  matrix[2] = x_shift;
110  matrix[3] = -matrix[1];
111  matrix[4] = matrix[0];
112  matrix[5] = y_shift;
113  matrix[6] = 0;
114  matrix[7] = 0;
115  matrix[8] = 1;
116 }
117 
118 void avfilter_add_matrix(const float *m1, const float *m2, float *result)
119 {
120  int i;
121  for (i = 0; i < 9; i++)
122  result[i] = m1[i] + m2[i];
123 }
124 
125 void avfilter_sub_matrix(const float *m1, const float *m2, float *result)
126 {
127  int i;
128  for (i = 0; i < 9; i++)
129  result[i] = m1[i] - m2[i];
130 }
131 
132 void avfilter_mul_matrix(const float *m1, float scalar, float *result)
133 {
134  int i;
135  for (i = 0; i < 9; i++)
136  result[i] = m1[i] * scalar;
137 }
138 
139 static inline int mirror(int v, int m)
140 {
141  while ((unsigned)v > (unsigned)m) {
142  v = -v;
143  if (v < 0)
144  v += 2 * m;
145  }
146  return v;
147 }
148 
150  int src_stride, int dst_stride,
151  int width, int height, const float *matrix,
153  enum FillMethod fill)
154 {
155  int x, y;
156  float x_s, y_s;
157  uint8_t def = 0;
158  uint8_t (*func)(float, float, const uint8_t *, int, int, int, uint8_t) = NULL;
159 
160  switch(interpolate) {
161  case INTERPOLATE_NEAREST:
162  func = interpolate_nearest;
163  break;
165  func = interpolate_bilinear;
166  break;
168  func = interpolate_biquadratic;
169  break;
170  default:
171  return AVERROR(EINVAL);
172  }
173 
174  for (y = 0; y < height; y++) {
175  for(x = 0; x < width; x++) {
176  x_s = x * matrix[0] + y * matrix[1] + matrix[2];
177  y_s = x * matrix[3] + y * matrix[4] + matrix[5];
178 
179  switch(fill) {
180  case FILL_ORIGINAL:
181  def = src[y * src_stride + x];
182  break;
183  case FILL_CLAMP:
184  y_s = av_clipf(y_s, 0, height - 1);
185  x_s = av_clipf(x_s, 0, width - 1);
186  def = src[(int)y_s * src_stride + (int)x_s];
187  break;
188  case FILL_MIRROR:
189  x_s = mirror(x_s, width-1);
190  y_s = mirror(y_s, height-1);
191 
192  av_assert2(x_s >= 0 && y_s >= 0);
193  av_assert2(x_s < width && y_s < height);
194  def = src[(int)y_s * src_stride + (int)x_s];
195  }
196 
197  dst[y * dst_stride + x] = func(x_s, y_s, src, width, height, src_stride, def);
198  }
199  }
200  return 0;
201 }
202 
float v
void avfilter_sub_matrix(const float *m1, const float *m2, float *result)
Subtract one matrix from another.
Definition: transform.c:125
int stride
Definition: mace.c:144
InterpolateMethod
Definition: transform.h:39
#define INTERPOLATE_METHOD(name)
Definition: transform.c:32
uint8_t
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:63
window constants for m
int avfilter_transform(const uint8_t *src, uint8_t *dst, int src_stride, int dst_stride, int width, int height, const float *matrix, enum InterpolateMethod interpolate, enum FillMethod fill)
Do an affine transformation with the given interpolation method.
Definition: transform.c:149
void avfilter_add_matrix(const float *m1, const float *m2, float *result)
Add two matrices together.
Definition: transform.c:118
static void interpolate(float *out, float v1, float v2, int size)
Definition: twinvq.c:280
integer sqrt
Definition: avutil.txt:2
f2
Definition: genspecsines3.m:4
Discrete Time axis x
simple assert() macros that are a bit more flexible than ISO C assert().
FillMethod
Definition: transform.h:51
transform input video
#define PIXEL(img, x, y, w, h, stride, def)
Definition: transform.c:36
NULL
Definition: eval.c:55
static int width
Definition: tests/utils.c:158
f3
Definition: genspecsines3.m:5
AVS_Value src
Definition: avisynth_c.h:523
spectrum bins to fill(1-based indexing) for m
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
int(* func)(AVBPrint *dst, const char *in, const char *arg)
synthesis window for stochastic i
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
void avfilter_mul_matrix(const float *m1, float scalar, float *result)
Multiply a matrix by a scalar value.
Definition: transform.c:132
common internal and external API header
function y
Definition: D.m:1
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix)
Get an affine transformation matrix from a given translation, rotation, and zoom factor.
Definition: transform.c:106
static int mirror(int v, int m)
Definition: transform.c:139
f1
Definition: genspecsines3.m:3