bayer_template.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * Bayer-to-RGB/YV12 template
  3. * Copyright (c) 2011-2014 Peter Ross <pross@xvid.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. #if defined(BAYER_BGGR) || defined(BAYER_GBRG)
  22. #define BAYER_R 0
  23. #define BAYER_G 1
  24. #define BAYER_B 2
  25. #endif
  26. #if defined(BAYER_RGGB) || defined(BAYER_GRBG)
  27. #define BAYER_R 2
  28. #define BAYER_G 1
  29. #define BAYER_B 0
  30. #endif
  31. #if defined(BAYER_8)
  32. #define BAYER_READ(x) (x)
  33. #define BAYER_SIZEOF 1
  34. #define BAYER_SHIFT 0
  35. #endif
  36. #if defined(BAYER_16LE)
  37. #define BAYER_READ(x) AV_RL16(&(x))
  38. #define BAYER_SIZEOF 2
  39. #define BAYER_SHIFT 8
  40. #endif
  41. #if defined(BAYER_16BE)
  42. #define BAYER_READ(x) AV_RB16(&(x))
  43. #define BAYER_SIZEOF 2
  44. #define BAYER_SHIFT 8
  45. #endif
  46. #define S(y, x) BAYER_READ(src[(y)*src_stride + BAYER_SIZEOF*(x)])
  47. #define T(y, x) (unsigned int)S(y, x)
  48. #define R(y, x) dst[(y)*dst_stride + (x)*3 + BAYER_R]
  49. #define G(y, x) dst[(y)*dst_stride + (x)*3 + BAYER_G]
  50. #define B(y, x) dst[(y)*dst_stride + (x)*3 + BAYER_B]
  51. #if defined(BAYER_BGGR) || defined(BAYER_RGGB)
  52. #define BAYER_TO_RGB24_COPY \
  53. R(0, 0) = \
  54. R(0, 1) = \
  55. R(1, 1) = \
  56. R(1, 0) = S(1, 1) >> BAYER_SHIFT; \
  57. \
  58. G(0, 1) = S(0, 1) >> BAYER_SHIFT; \
  59. G(0, 0) = \
  60. G(1, 1) = (T(0, 1) + T(1, 0)) >> (1 + BAYER_SHIFT); \
  61. G(1, 0) = S(1, 0) >> BAYER_SHIFT; \
  62. \
  63. B(1, 1) = \
  64. B(0, 0) = \
  65. B(0, 1) = \
  66. B(1, 0) = S(0, 0) >> BAYER_SHIFT;
  67. #define BAYER_TO_RGB24_INTERPOLATE \
  68. R(0, 0) = (T(-1, -1) + T(-1, 1) + T(1, -1) + T(1, 1)) >> (2 + BAYER_SHIFT); \
  69. G(0, 0) = (T(-1, 0) + T( 0, -1) + T(0, 1) + T(1, 0)) >> (2 + BAYER_SHIFT); \
  70. B(0, 0) = S(0, 0) >> BAYER_SHIFT; \
  71. \
  72. R(0, 1) = (T(-1, 1) + T(1, 1)) >> (1 + BAYER_SHIFT); \
  73. G(0, 1) = S(0, 1) >> BAYER_SHIFT; \
  74. B(0, 1) = (T(0, 0) + T(0, 2)) >> (1 + BAYER_SHIFT); \
  75. \
  76. R(1, 0) = (T(1, -1) + T(1, 1)) >> (1 + BAYER_SHIFT); \
  77. G(1, 0) = S(1, 0) >> BAYER_SHIFT; \
  78. B(1, 0) = (T(0, 0) + T(2, 0)) >> (1 + BAYER_SHIFT); \
  79. \
  80. R(1, 1) = S(1, 1) >> BAYER_SHIFT; \
  81. G(1, 1) = (T(0, 1) + T(1, 0) + T(1, 2) + T(2, 1)) >> (2 + BAYER_SHIFT); \
  82. B(1, 1) = (T(0, 0) + T(0, 2) + T(2, 0) + T(2, 2)) >> (2 + BAYER_SHIFT);
  83. #else
  84. #define BAYER_TO_RGB24_COPY \
  85. R(0, 0) = \
  86. R(0, 1) = \
  87. R(1, 1) = \
  88. R(1, 0) = S(1, 0) >> BAYER_SHIFT; \
  89. \
  90. G(0, 0) = S(0, 0) >> BAYER_SHIFT; \
  91. G(1, 1) = S(1, 1) >> BAYER_SHIFT; \
  92. G(0, 1) = \
  93. G(1, 0) = (T(0, 0) + T(1, 1)) >> (1 + BAYER_SHIFT); \
  94. \
  95. B(1, 1) = \
  96. B(0, 0) = \
  97. B(0, 1) = \
  98. B(1, 0) = S(0, 1) >> BAYER_SHIFT;
  99. #define BAYER_TO_RGB24_INTERPOLATE \
  100. R(0, 0) = (T(-1, 0) + T(1, 0)) >> (1 + BAYER_SHIFT); \
  101. G(0, 0) = S(0, 0) >> BAYER_SHIFT; \
  102. B(0, 0) = (T(0, -1) + T(0, 1)) >> (1 + BAYER_SHIFT); \
  103. \
  104. R(0, 1) = (T(-1, 0) + T(-1, 2) + T(1, 0) + T(1, 2)) >> (2 + BAYER_SHIFT); \
  105. G(0, 1) = (T(-1, 1) + T(0, 0) + T(0, 2) + T(1, 1)) >> (2 + BAYER_SHIFT); \
  106. B(0, 1) = S(0, 1) >> BAYER_SHIFT; \
  107. \
  108. R(1, 0) = S(1, 0) >> BAYER_SHIFT; \
  109. G(1, 0) = (T(0, 0) + T(1, -1) + T(1, 1) + T(2, 0)) >> (2 + BAYER_SHIFT); \
  110. B(1, 0) = (T(0, -1) + T(0, 1) + T(2, -1) + T(2, 1)) >> (2 + BAYER_SHIFT); \
  111. \
  112. R(1, 1) = (T(1, 0) + T(1, 2)) >> (1 + BAYER_SHIFT); \
  113. G(1, 1) = S(1, 1) >> BAYER_SHIFT; \
  114. B(1, 1) = (T(0, 1) + T(2, 1)) >> (1 + BAYER_SHIFT);
  115. #endif
  116. /**
  117. * invoke ff_rgb24toyv12 for 2x2 pixels
  118. */
  119. #define rgb24toyv12_2x2(src, dstY, dstU, dstV, luma_stride, src_stride, rgb2yuv) \
  120. ff_rgb24toyv12(src, dstY, dstV, dstU, 2, 2, luma_stride, 0, src_stride, rgb2yuv)
  121. static void BAYER_RENAME(rgb24_copy)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
  122. {
  123. int i;
  124. for (i = 0 ; i < width; i+= 2) {
  125. BAYER_TO_RGB24_COPY
  126. src += 2 * BAYER_SIZEOF;
  127. dst += 6;
  128. }
  129. }
  130. static void BAYER_RENAME(rgb24_interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
  131. {
  132. int i;
  133. BAYER_TO_RGB24_COPY
  134. src += 2 * BAYER_SIZEOF;
  135. dst += 6;
  136. for (i = 2 ; i < width - 2; i+= 2) {
  137. BAYER_TO_RGB24_INTERPOLATE
  138. src += 2 * BAYER_SIZEOF;
  139. dst += 6;
  140. }
  141. if (width > 2) {
  142. BAYER_TO_RGB24_COPY
  143. }
  144. }
  145. static void BAYER_RENAME(yv12_copy)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv)
  146. {
  147. uint8_t dst[12];
  148. const int dst_stride = 6;
  149. int i;
  150. for (i = 0 ; i < width; i+= 2) {
  151. BAYER_TO_RGB24_COPY
  152. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  153. src += 2 * BAYER_SIZEOF;
  154. dstY += 2;
  155. dstU++;
  156. dstV++;
  157. }
  158. }
  159. static void BAYER_RENAME(yv12_interpolate)(const uint8_t *src, int src_stride, uint8_t *dstY, uint8_t *dstU, uint8_t *dstV, int luma_stride, int width, int32_t *rgb2yuv)
  160. {
  161. uint8_t dst[12];
  162. const int dst_stride = 6;
  163. int i;
  164. BAYER_TO_RGB24_COPY
  165. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  166. src += 2 * BAYER_SIZEOF;
  167. dstY += 2;
  168. dstU++;
  169. dstV++;
  170. for (i = 2 ; i < width - 2; i+= 2) {
  171. BAYER_TO_RGB24_INTERPOLATE
  172. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  173. src += 2 * BAYER_SIZEOF;
  174. dstY += 2;
  175. dstU++;
  176. dstV++;
  177. }
  178. if (width > 2) {
  179. BAYER_TO_RGB24_COPY
  180. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  181. }
  182. }
  183. #undef S
  184. #undef T
  185. #undef R
  186. #undef G
  187. #undef B
  188. #undef BAYER_TO_RGB24_COPY
  189. #undef BAYER_TO_RGB24_INTERPOLATE
  190. #undef BAYER_RENAME
  191. #undef BAYER_R
  192. #undef BAYER_G
  193. #undef BAYER_B
  194. #undef BAYER_READ
  195. #undef BAYER_SIZEOF
  196. #undef BAYER_SHIFT
  197. #if defined(BAYER_BGGR)
  198. #undef BAYER_BGGR
  199. #endif
  200. #if defined(BAYER_RGGB)
  201. #undef BAYER_RGGB
  202. #endif
  203. #if defined(BAYER_GBRG)
  204. #undef BAYER_GBRG
  205. #endif
  206. #if defined(BAYER_GRBG)
  207. #undef BAYER_GRBG
  208. #endif
  209. #if defined(BAYER_8)
  210. #undef BAYER_8
  211. #endif
  212. #if defined(BAYER_16LE)
  213. #undef BAYER_16LE
  214. #endif
  215. #if defined(BAYER_16BE)
  216. #undef BAYER_16BE
  217. #endif