transform.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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. * @file
  23. * transform input video
  24. */
  25. #include "libavutil/common.h"
  26. #include "transform.h"
  27. #define INTERPOLATE_METHOD(name) \
  28. static uint8_t name(float x, float y, const uint8_t *src, \
  29. int width, int height, int stride, uint8_t def)
  30. #define PIXEL(img, x, y, w, h, stride, def) \
  31. ((x) < 0 || (y) < 0) ? (def) : \
  32. (((x) >= (w) || (y) >= (h)) ? (def) : \
  33. img[(x) + (y) * (stride)])
  34. /**
  35. * Nearest neighbor interpolation
  36. */
  37. INTERPOLATE_METHOD(interpolate_nearest)
  38. {
  39. return PIXEL(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def);
  40. }
  41. /**
  42. * Bilinear interpolation
  43. */
  44. INTERPOLATE_METHOD(interpolate_bilinear)
  45. {
  46. int x_c, x_f, y_c, y_f;
  47. int v1, v2, v3, v4;
  48. if (x < -1 || x > width || y < -1 || y > height) {
  49. return def;
  50. } else {
  51. x_f = (int)x;
  52. x_c = x_f + 1;
  53. y_f = (int)y;
  54. y_c = y_f + 1;
  55. v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
  56. v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
  57. v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
  58. v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
  59. return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) +
  60. v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y)));
  61. }
  62. }
  63. /**
  64. * Biquadratic interpolation
  65. */
  66. INTERPOLATE_METHOD(interpolate_biquadratic)
  67. {
  68. int x_c, x_f, y_c, y_f;
  69. uint8_t v1, v2, v3, v4;
  70. float f1, f2, f3, f4;
  71. if (x < - 1 || x > width || y < -1 || y > height)
  72. return def;
  73. else {
  74. x_f = (int)x;
  75. x_c = x_f + 1;
  76. y_f = (int)y;
  77. y_c = y_f + 1;
  78. v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
  79. v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
  80. v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
  81. v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
  82. f1 = 1 - sqrt((x_c - x) * (y_c - y));
  83. f2 = 1 - sqrt((x_c - x) * (y - y_f));
  84. f3 = 1 - sqrt((x - x_f) * (y_c - y));
  85. f4 = 1 - sqrt((x - x_f) * (y - y_f));
  86. return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4);
  87. }
  88. }
  89. void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix) {
  90. matrix[0] = zoom * cos(angle);
  91. matrix[1] = -sin(angle);
  92. matrix[2] = x_shift;
  93. matrix[3] = -matrix[1];
  94. matrix[4] = matrix[0];
  95. matrix[5] = y_shift;
  96. matrix[6] = 0;
  97. matrix[7] = 0;
  98. matrix[8] = 1;
  99. }
  100. void avfilter_add_matrix(const float *m1, const float *m2, float *result)
  101. {
  102. int i;
  103. for (i = 0; i < 9; i++)
  104. result[i] = m1[i] + m2[i];
  105. }
  106. void avfilter_sub_matrix(const float *m1, const float *m2, float *result)
  107. {
  108. int i;
  109. for (i = 0; i < 9; i++)
  110. result[i] = m1[i] - m2[i];
  111. }
  112. void avfilter_mul_matrix(const float *m1, float scalar, float *result)
  113. {
  114. int i;
  115. for (i = 0; i < 9; i++)
  116. result[i] = m1[i] * scalar;
  117. }
  118. void avfilter_transform(const uint8_t *src, uint8_t *dst,
  119. int src_stride, int dst_stride,
  120. int width, int height, const float *matrix,
  121. enum InterpolateMethod interpolate,
  122. enum FillMethod fill)
  123. {
  124. int x, y;
  125. float x_s, y_s;
  126. uint8_t def = 0;
  127. uint8_t (*func)(float, float, const uint8_t *, int, int, int, uint8_t) = NULL;
  128. switch(interpolate) {
  129. case INTERPOLATE_NEAREST:
  130. func = interpolate_nearest;
  131. break;
  132. case INTERPOLATE_BILINEAR:
  133. func = interpolate_bilinear;
  134. break;
  135. case INTERPOLATE_BIQUADRATIC:
  136. func = interpolate_biquadratic;
  137. break;
  138. }
  139. for (y = 0; y < height; y++) {
  140. for(x = 0; x < width; x++) {
  141. x_s = x * matrix[0] + y * matrix[1] + matrix[2];
  142. y_s = x * matrix[3] + y * matrix[4] + matrix[5];
  143. switch(fill) {
  144. case FILL_ORIGINAL:
  145. def = src[y * src_stride + x];
  146. break;
  147. case FILL_CLAMP:
  148. y_s = av_clipf(y_s, 0, height - 1);
  149. x_s = av_clipf(x_s, 0, width - 1);
  150. def = src[(int)y_s * src_stride + (int)x_s];
  151. break;
  152. case FILL_MIRROR:
  153. y_s = (y_s < 0) ? -y_s : (y_s >= height) ? (height + height - y_s) : y_s;
  154. x_s = (x_s < 0) ? -x_s : (x_s >= width) ? (width + width - x_s) : x_s;
  155. def = src[(int)y_s * src_stride + (int)x_s];
  156. }
  157. dst[y * dst_stride + x] = func(x_s, y_s, src, width, height, src_stride, def);
  158. }
  159. }
  160. }