| 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 | |
| 127 | static 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 | |
| 137 | static 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 | |
| 156 | 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) |
| 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 | |
| 171 | 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) |
| 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 |