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