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