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