]> git.sesse.net Git - kdenlive/blob - src/v4l/dec_yuv.c
6336ce5ed7a2afd650f82702d2aac0ab22691906
[kdenlive] / src / v4l / dec_yuv.c
1 /* fswebcam - Small and simple webcam for *nix                */
2 /*============================================================*/
3 /* Copyright (C)2005-2010 Philip Heron <phil@sanslogic.co.uk> */
4 /*                                                            */
5 /* This program is distributed under the terms of the GNU     */
6 /* General Public License, version 2. You may use, modify,    */
7 /* and redistribute it under the terms of this license. A     */
8 /* copy should be included with this source.                  */
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include <stdint.h>
15
16 #include "src.h"
17
18 /* The following YUV functions are based on code by Vincent Hourdin.
19  * http://vinvin.dyndns.org/projects/
20  *
21  * Faster integer maths from camE by Tom Gilbert.
22  * http://linuxbrit.co.uk/camE/
23 */
24
25 int fswc_add_image_yuyv(src_t *src, avgbmp_t *abitmap)
26 {
27         uint8_t *ptr;
28         uint32_t x, y, z;
29         
30         if(src->length < (src->width * src->height * 2)) return(-1);
31         
32         /* YUYV and UYVY are very similar and so  *
33          * are both handled by this one function. */
34         
35         ptr = (uint8_t *) src->img;
36         z = 0;
37         
38         for(y = 0; y < src->height; y++)
39         {
40                 for(x = 0; x < src->width; x++)
41                 {
42                         int r, g, b;
43                         int y, u, v;
44                         
45                         if(src->palette == SRC_PAL_UYVY)
46                         {
47                                 if(!z) y = ptr[1] << 8;
48                                 else   y = ptr[3] << 8;
49                                 
50                                 u = ptr[0] - 128;
51                                 v = ptr[2] - 128;
52                         }
53                         else /* SRC_PAL_YUYV */
54                         {
55                                 if(!z) y = ptr[0] << 8;
56                                 else   y = ptr[2] << 8;
57                                 
58                                 u = ptr[1] - 128;
59                                 v = ptr[3] - 128;
60                         }
61                         
62                         r = (y + (359 * v)) >> 8;
63                         g = (y - (88 * u) - (183 * v)) >> 8;
64                         b = (y + (454 * u)) >> 8;
65                         
66                         *(abitmap++) += CLIP(r, 0x00, 0xFF);
67                         *(abitmap++) += CLIP(g, 0x00, 0xFF);
68                         *(abitmap++) += CLIP(b, 0x00, 0xFF);
69                         
70                         if(z++)
71                         {
72                                 z = 0;
73                                 ptr += 4;
74                         }
75                 }
76         }
77         
78         return(0);
79 }
80
81 int fswc_add_image_yuv420p(src_t *src, avgbmp_t *abitmap)
82 {
83         uint8_t *yptr, *uptr, *vptr;
84         uint32_t x, y, p, o;
85         
86         if(src->length < (src->width * src->height * 3) / 2) return(-1);
87         
88         /* Setup pointers to Y, U and V buffers. */
89         yptr = (uint8_t *) src->img;
90         uptr = yptr + (src->width * src->height);
91         vptr = uptr + (src->width * src->height / 4);
92         o = 0;
93         p = 0;
94         
95         for(y = 0; y < src->height; y++)
96         {
97                 for(x = 0; x < src->width; x++)
98                 {
99                         int r, g, b;
100                         int y, u, v;
101                         
102                         y = *(yptr++) << 8;
103                         u = uptr[p] - 128;
104                         v = vptr[p] - 128;
105                         
106                         r = (y + (359 * v)) >> 8;
107                         g = (y - (88 * u) - (183 * v)) >> 8;
108                         b = (y + (454 * u)) >> 8;
109                         
110                         *(abitmap++) += CLIP(r, 0x00, 0xFF);
111                         *(abitmap++) += CLIP(g, 0x00, 0xFF);
112                         *(abitmap++) += CLIP(b, 0x00, 0xFF);
113                         
114                         if(x & 1) p++;
115                 }
116                 
117                 if(!(y & 1)) p -= src->width / 2;
118         }
119         
120         return(0);
121 }
122
123 int fswc_add_image_nv12mb(src_t *src, avgbmp_t *abitmap)
124 {
125         uint32_t x, y;
126         uint32_t bw;
127         
128         if(src->length != (src->width * src->height * 3) / 2) return(-1);
129         
130         bw = src->width >> 4;
131         
132         for(y = 0; y < src->height; y++)
133         {
134                 for(x = 0; x < src->width; x++)
135                 {
136                         uint32_t bx, by;
137                         int cy, cu, cv;
138                         int cr, cg, cb;
139                         uint8_t *py, *puv;
140                         
141                         bx = x >> 4;
142                         by = y >> 4;
143                         
144                         py  = src->img;
145                         py += ((by * bw) + bx) * 0x100;
146                         py += ((y - (by << 4)) * 0x10) + (x - (bx << 4));
147                         
148                         by /= 2;
149                         
150                         puv  = (avgbmp_t *)src->img + (src->width * src->height);
151                         puv += ((by * bw) + bx) * 0x100;
152                         puv += (((y / 2) - (by << 4)) * 0x10) + ((x - (bx << 4)) &~ 1);
153                         
154                         cy = *py << 8;
155                         cu = puv[0] - 128;
156                         cv = puv[1] - 128;
157                         
158                         cr = (cy + (359 * cv)) >> 8;
159                         cg = (cy - (88 * cu) - (183 * cv)) >> 8;
160                         cb = (cy + (454 * cu)) >> 8;
161                         
162                         *(abitmap++) += CLIP(cr, 0x00, 0xFF);
163                         *(abitmap++) += CLIP(cg, 0x00, 0xFF);
164                         *(abitmap++) += CLIP(cb, 0x00, 0xFF);
165                 }
166         }
167         
168         return(0);
169 }
170