bayer_template.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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. #if defined(BAYER_BGGR) || defined(BAYER_RGGB)
  117. #define BAYER_TO_RGB48_COPY \
  118. R(0, 0) = \
  119. R(0, 1) = \
  120. R(1, 1) = \
  121. R(1, 0) = S(1, 1); \
  122. \
  123. G(0, 1) = S(0, 1); \
  124. G(0, 0) = \
  125. G(1, 1) = (T(0, 1) + T(1, 0)) >> 1; \
  126. G(1, 0) = S(1, 0); \
  127. \
  128. B(1, 1) = \
  129. B(0, 0) = \
  130. B(0, 1) = \
  131. B(1, 0) = S(0, 0);
  132. #define BAYER_TO_RGB48_INTERPOLATE \
  133. R(0, 0) = (T(-1, -1) + T(-1, 1) + T(1, -1) + T(1, 1)) >> 2; \
  134. G(0, 0) = (T(-1, 0) + T( 0, -1) + T(0, 1) + T(1, 0)) >> 2; \
  135. B(0, 0) = S(0, 0); \
  136. \
  137. R(0, 1) = (T(-1, 1) + T(1, 1)) >> 1; \
  138. G(0, 1) = S(0, 1); \
  139. B(0, 1) = (T(0, 0) + T(0, 2)) >> 1; \
  140. \
  141. R(1, 0) = (T(1, -1) + T(1, 1)) >> 1; \
  142. G(1, 0) = S(1, 0); \
  143. B(1, 0) = (T(0, 0) + T(2, 0)) >> 1; \
  144. \
  145. R(1, 1) = S(1, 1); \
  146. G(1, 1) = (T(0, 1) + T(1, 0) + T(1, 2) + T(2, 1)) >> 2; \
  147. B(1, 1) = (T(0, 0) + T(0, 2) + T(2, 0) + T(2, 2)) >> 2;
  148. #else
  149. #define BAYER_TO_RGB48_COPY \
  150. R(0, 0) = \
  151. R(0, 1) = \
  152. R(1, 1) = \
  153. R(1, 0) = S(1, 0); \
  154. \
  155. G(0, 0) = S(0, 0); \
  156. G(1, 1) = S(1, 1); \
  157. G(0, 1) = \
  158. G(1, 0) = (T(0, 0) + T(1, 1)) >> 1; \
  159. \
  160. B(1, 1) = \
  161. B(0, 0) = \
  162. B(0, 1) = \
  163. B(1, 0) = S(0, 1);
  164. #define BAYER_TO_RGB48_INTERPOLATE \
  165. R(0, 0) = (T(-1, 0) + T(1, 0)) >> 1; \
  166. G(0, 0) = S(0, 0); \
  167. B(0, 0) = (T(0, -1) + T(0, 1)) >> 1; \
  168. \
  169. R(0, 1) = (T(-1, 0) + T(-1, 2) + T(1, 0) + T(1, 2)) >> 2; \
  170. G(0, 1) = (T(-1, 1) + T(0, 0) + T(0, 2) + T(1, 1)) >> 2; \
  171. B(0, 1) = S(0, 1); \
  172. \
  173. R(1, 0) = S(1, 0); \
  174. G(1, 0) = (T(0, 0) + T(1, -1) + T(1, 1) + T(2, 0)) >> 2; \
  175. B(1, 0) = (T(0, -1) + T(0, 1) + T(2, -1) + T(2, 1)) >> 2; \
  176. \
  177. R(1, 1) = (T(1, 0) + T(1, 2)) >> 1; \
  178. G(1, 1) = S(1, 1); \
  179. B(1, 1) = (T(0, 1) + T(2, 1)) >> 1;
  180. #endif
  181. /**
  182. * invoke ff_rgb24toyv12 for 2x2 pixels
  183. */
  184. #define rgb24toyv12_2x2(src, dstY, dstU, dstV, luma_stride, src_stride, rgb2yuv) \
  185. ff_rgb24toyv12(src, dstY, dstV, dstU, 2, 2, luma_stride, 0, src_stride, rgb2yuv)
  186. static void BAYER_RENAME(rgb24_copy)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
  187. {
  188. int i;
  189. for (i = 0 ; i < width; i+= 2) {
  190. BAYER_TO_RGB24_COPY
  191. src += 2 * BAYER_SIZEOF;
  192. dst += 6;
  193. }
  194. }
  195. static void BAYER_RENAME(rgb24_interpolate)(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int width)
  196. {
  197. int i;
  198. BAYER_TO_RGB24_COPY
  199. src += 2 * BAYER_SIZEOF;
  200. dst += 6;
  201. for (i = 2 ; i < width - 2; i+= 2) {
  202. BAYER_TO_RGB24_INTERPOLATE
  203. src += 2 * BAYER_SIZEOF;
  204. dst += 6;
  205. }
  206. if (width > 2) {
  207. BAYER_TO_RGB24_COPY
  208. }
  209. }
  210. static void BAYER_RENAME(rgb48_copy)(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width)
  211. {
  212. uint16_t *dst = (uint16_t *)ddst;
  213. int i;
  214. dst_stride /= 2;
  215. for (i = 0 ; i < width; i+= 2) {
  216. BAYER_TO_RGB48_COPY
  217. src += 2 * BAYER_SIZEOF;
  218. dst += 6;
  219. }
  220. }
  221. static void BAYER_RENAME(rgb48_interpolate)(const uint8_t *src, int src_stride, uint8_t *ddst, int dst_stride, int width)
  222. {
  223. uint16_t *dst = (uint16_t *)ddst;
  224. int i;
  225. dst_stride /= 2;
  226. BAYER_TO_RGB48_COPY
  227. src += 2 * BAYER_SIZEOF;
  228. dst += 6;
  229. for (i = 2 ; i < width - 2; i+= 2) {
  230. BAYER_TO_RGB48_INTERPOLATE
  231. src += 2 * BAYER_SIZEOF;
  232. dst += 6;
  233. }
  234. if (width > 2) {
  235. BAYER_TO_RGB48_COPY
  236. }
  237. }
  238. 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)
  239. {
  240. uint8_t dst[12];
  241. const int dst_stride = 6;
  242. int i;
  243. for (i = 0 ; i < width; i+= 2) {
  244. BAYER_TO_RGB24_COPY
  245. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  246. src += 2 * BAYER_SIZEOF;
  247. dstY += 2;
  248. dstU++;
  249. dstV++;
  250. }
  251. }
  252. 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)
  253. {
  254. uint8_t dst[12];
  255. const int dst_stride = 6;
  256. int i;
  257. BAYER_TO_RGB24_COPY
  258. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  259. src += 2 * BAYER_SIZEOF;
  260. dstY += 2;
  261. dstU++;
  262. dstV++;
  263. for (i = 2 ; i < width - 2; i+= 2) {
  264. BAYER_TO_RGB24_INTERPOLATE
  265. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  266. src += 2 * BAYER_SIZEOF;
  267. dstY += 2;
  268. dstU++;
  269. dstV++;
  270. }
  271. if (width > 2) {
  272. BAYER_TO_RGB24_COPY
  273. rgb24toyv12_2x2(dst, dstY, dstU, dstV, luma_stride, dst_stride, rgb2yuv);
  274. }
  275. }
  276. #undef S
  277. #undef T
  278. #undef R
  279. #undef G
  280. #undef B
  281. #undef BAYER_TO_RGB24_COPY
  282. #undef BAYER_TO_RGB24_INTERPOLATE
  283. #undef BAYER_TO_RGB48_COPY
  284. #undef BAYER_TO_RGB48_INTERPOLATE
  285. #undef BAYER_RENAME
  286. #undef BAYER_R
  287. #undef BAYER_G
  288. #undef BAYER_B
  289. #undef BAYER_READ
  290. #undef BAYER_SIZEOF
  291. #undef BAYER_SHIFT
  292. #if defined(BAYER_BGGR)
  293. #undef BAYER_BGGR
  294. #endif
  295. #if defined(BAYER_RGGB)
  296. #undef BAYER_RGGB
  297. #endif
  298. #if defined(BAYER_GBRG)
  299. #undef BAYER_GBRG
  300. #endif
  301. #if defined(BAYER_GRBG)
  302. #undef BAYER_GRBG
  303. #endif
  304. #if defined(BAYER_8)
  305. #undef BAYER_8
  306. #endif
  307. #if defined(BAYER_16LE)
  308. #undef BAYER_16LE
  309. #endif
  310. #if defined(BAYER_16BE)
  311. #undef BAYER_16BE
  312. #endif