00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "libavutil/common.h"
00028
00029 #include "transform.h"
00030
00031 #define INTERPOLATE_METHOD(name) \
00032 static uint8_t name(float x, float y, const uint8_t *src, \
00033 int width, int height, int stride, uint8_t def)
00034
00035 #define PIXEL(img, x, y, w, h, stride, def) \
00036 ((x) < 0 || (y) < 0) ? (def) : \
00037 (((x) >= (w) || (y) >= (h)) ? (def) : \
00038 img[(x) + (y) * (stride)])
00039
00043 INTERPOLATE_METHOD(interpolate_nearest)
00044 {
00045 return PIXEL(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def);
00046 }
00047
00051 INTERPOLATE_METHOD(interpolate_bilinear)
00052 {
00053 int x_c, x_f, y_c, y_f;
00054 int v1, v2, v3, v4;
00055
00056 if (x < -1 || x > width || y < -1 || y > height) {
00057 return def;
00058 } else {
00059 x_f = (int)x;
00060 x_c = x_f + 1;
00061
00062 y_f = (int)y;
00063 y_c = y_f + 1;
00064
00065 v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
00066 v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
00067 v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
00068 v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
00069
00070 return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) +
00071 v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y)));
00072 }
00073 }
00074
00078 INTERPOLATE_METHOD(interpolate_biquadratic)
00079 {
00080 int x_c, x_f, y_c, y_f;
00081 uint8_t v1, v2, v3, v4;
00082 float f1, f2, f3, f4;
00083
00084 if (x < - 1 || x > width || y < -1 || y > height)
00085 return def;
00086 else {
00087 x_f = (int)x;
00088 x_c = x_f + 1;
00089 y_f = (int)y;
00090 y_c = y_f + 1;
00091
00092 v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
00093 v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
00094 v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
00095 v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
00096
00097 f1 = 1 - sqrt((x_c - x) * (y_c - y));
00098 f2 = 1 - sqrt((x_c - x) * (y - y_f));
00099 f3 = 1 - sqrt((x - x_f) * (y_c - y));
00100 f4 = 1 - sqrt((x - x_f) * (y - y_f));
00101 return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4);
00102 }
00103 }
00104
00105 void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix) {
00106 matrix[0] = zoom * cos(angle);
00107 matrix[1] = -sin(angle);
00108 matrix[2] = x_shift;
00109 matrix[3] = -matrix[1];
00110 matrix[4] = matrix[0];
00111 matrix[5] = y_shift;
00112 matrix[6] = 0;
00113 matrix[7] = 0;
00114 matrix[8] = 1;
00115 }
00116
00117 void avfilter_add_matrix(const float *m1, const float *m2, float *result)
00118 {
00119 int i;
00120 for (i = 0; i < 9; i++)
00121 result[i] = m1[i] + m2[i];
00122 }
00123
00124 void avfilter_sub_matrix(const float *m1, const float *m2, float *result)
00125 {
00126 int i;
00127 for (i = 0; i < 9; i++)
00128 result[i] = m1[i] - m2[i];
00129 }
00130
00131 void avfilter_mul_matrix(const float *m1, float scalar, float *result)
00132 {
00133 int i;
00134 for (i = 0; i < 9; i++)
00135 result[i] = m1[i] * scalar;
00136 }
00137
00138 void avfilter_transform(const uint8_t *src, uint8_t *dst,
00139 int src_stride, int dst_stride,
00140 int width, int height, const float *matrix,
00141 enum InterpolateMethod interpolate,
00142 enum FillMethod fill)
00143 {
00144 int x, y;
00145 float x_s, y_s;
00146 uint8_t def = 0;
00147 uint8_t (*func)(float, float, const uint8_t *, int, int, int, uint8_t) = NULL;
00148
00149 switch(interpolate) {
00150 case INTERPOLATE_NEAREST:
00151 func = interpolate_nearest;
00152 break;
00153 case INTERPOLATE_BILINEAR:
00154 func = interpolate_bilinear;
00155 break;
00156 case INTERPOLATE_BIQUADRATIC:
00157 func = interpolate_biquadratic;
00158 break;
00159 }
00160
00161 for (y = 0; y < height; y++) {
00162 for(x = 0; x < width; x++) {
00163 x_s = x * matrix[0] + y * matrix[1] + matrix[2];
00164 y_s = x * matrix[3] + y * matrix[4] + matrix[5];
00165
00166 switch(fill) {
00167 case FILL_ORIGINAL:
00168 def = src[y * src_stride + x];
00169 break;
00170 case FILL_CLAMP:
00171 y_s = av_clipf(y_s, 0, height - 1);
00172 x_s = av_clipf(x_s, 0, width - 1);
00173 def = src[(int)y_s * src_stride + (int)x_s];
00174 break;
00175 case FILL_MIRROR:
00176 y_s = (y_s < 0) ? -y_s : (y_s >= height) ? (height + height - y_s) : y_s;
00177 x_s = (x_s < 0) ? -x_s : (x_s >= width) ? (width + width - x_s) : x_s;
00178 def = src[(int)y_s * src_stride + (int)x_s];
00179 }
00180
00181 dst[y * dst_stride + x] = func(x_s, y_s, src, width, height, src_stride, def);
00182 }
00183 }
00184 }
00185