update source for tizen_2.1
[sdk/emulator/qemu.git] / tizen / src / hw / maru_camera_darwin_converter.c
1 /*
2  * Implementation of color conversion for MARU Virtual Camera device on MacOS.
3  *
4  * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  * Contact:
7  * Jun Tian <jun.j.tian@intel.com>
8  * JinHyung Jo <jinhyung.jo@samsung.com>
9  * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
24  * MA  02110-1301, USA.
25  *
26  * Contributors:
27  * - S-Core Co., Ltd
28  *
29  */
30
31 #include "qemu-common.h"
32 #include "maru_camera_darwin.h"
33 #include "tizen/src/debug_ch.h"
34
35 MULTI_DEBUG_CHANNEL(tizen, camera_darwin);
36
37 static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
38                          int width, int height);
39 static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
40                            int width, int height);
41 static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
42                          int width, int height);
43
44 /* Convert pixel format to YUV420 */
45 void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
46                    size_t frame_size, void *frame_pixels, void *video_buf)
47 {
48     switch (pixel_format) {
49     case V4L2_PIX_FMT_YUV420:
50         memcpy(video_buf, (void *)frame_pixels, (size_t)frame_size);
51         break;
52     case V4L2_PIX_FMT_YVU420:
53         YVU420ToYUV420(frame_pixels, video_buf, frame_width, frame_height);
54         break;
55     case V4L2_PIX_FMT_YUYV:
56         YUYVToYUV420(frame_pixels, video_buf, frame_width, frame_height);
57         break;
58     case V4L2_PIX_FMT_UYVY: /* Mac default format */
59         UYVYToYUV420(frame_pixels, video_buf, frame_width, frame_height);
60         break;
61     default:
62         ERR("Cannot convert the pixel format (%.4s)...\n",
63                (const char *)&pixel_format);
64         break;
65     }
66 }
67
68 static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
69                          int width, int height)
70 {
71     int i, j;
72
73     /* Source */
74     unsigned char *ptrsrcy1, *ptrsrcy2;
75     unsigned char *ptrsrcy3, *ptrsrcy4;
76     unsigned char *ptrsrccb1;
77     unsigned char *ptrsrccb3;
78     unsigned char *ptrsrccr1;
79     unsigned char *ptrsrccr3;
80     int srcystride, srcccstride;
81
82     ptrsrcy1  = bufsrc + 1;
83     ptrsrcy2  = bufsrc + (width << 1) + 1;
84     ptrsrcy3  = bufsrc + (width << 1) * 2 + 1;
85     ptrsrcy4  = bufsrc + (width << 1) * 3 + 1;
86
87     ptrsrccb1 = bufsrc;
88     ptrsrccb3 = bufsrc + (width << 1) * 2;
89
90     ptrsrccr1 = bufsrc + 2;
91     ptrsrccr3 = bufsrc + (width << 1) * 2 + 2;
92
93     srcystride  = (width << 1) * 3;
94     srcccstride = (width << 1) * 3;
95
96     /* Destination */
97     unsigned char *ptrdesty1, *ptrdesty2;
98     unsigned char *ptrdesty3, *ptrdesty4;
99     unsigned char *ptrdestcb1, *ptrdestcb2;
100     unsigned char *ptrdestcr1, *ptrdestcr2;
101     int destystride, destccstride;
102
103     ptrdesty1 = bufdest;
104     ptrdesty2 = bufdest + width;
105     ptrdesty3 = bufdest + width * 2;
106     ptrdesty4 = bufdest + width * 3;
107
108     ptrdestcb1 = bufdest + width * height;
109     ptrdestcb2 = bufdest + width * height + (width >> 1);
110
111     ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
112     ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
113                  + (width >> 1);
114
115     destystride  = (width)*3;
116     destccstride = (width>>1);
117
118     for (j = 0; j < (height / 4); j++) {
119         for (i = 0; i < (width / 2); i++) {
120             (*ptrdesty1++) = (*ptrsrcy1);
121             (*ptrdesty2++) = (*ptrsrcy2);
122             (*ptrdesty3++) = (*ptrsrcy3);
123             (*ptrdesty4++) = (*ptrsrcy4);
124
125             ptrsrcy1 += 2;
126             ptrsrcy2 += 2;
127             ptrsrcy3 += 2;
128             ptrsrcy4 += 2;
129
130             (*ptrdesty1++) = (*ptrsrcy1);
131             (*ptrdesty2++) = (*ptrsrcy2);
132             (*ptrdesty3++) = (*ptrsrcy3);
133             (*ptrdesty4++) = (*ptrsrcy4);
134
135             ptrsrcy1 += 2;
136             ptrsrcy2 += 2;
137             ptrsrcy3 += 2;
138             ptrsrcy4 += 2;
139
140             (*ptrdestcb1++) = (*ptrsrccb1);
141             (*ptrdestcb2++) = (*ptrsrccb3);
142
143             ptrsrccb1 += 4;
144             ptrsrccb3 += 4;
145
146             (*ptrdestcr1++) = (*ptrsrccr1);
147             (*ptrdestcr2++) = (*ptrsrccr3);
148
149             ptrsrccr1 += 4;
150             ptrsrccr3 += 4;
151
152         }
153
154         /* Update src pointers */
155         ptrsrcy1  += srcystride;
156         ptrsrcy2  += srcystride;
157         ptrsrcy3  += srcystride;
158         ptrsrcy4  += srcystride;
159
160         ptrsrccb1 += srcccstride;
161         ptrsrccb3 += srcccstride;
162
163         ptrsrccr1 += srcccstride;
164         ptrsrccr3 += srcccstride;
165
166         /* Update dest pointers */
167         ptrdesty1 += destystride;
168         ptrdesty2 += destystride;
169         ptrdesty3 += destystride;
170         ptrdesty4 += destystride;
171
172         ptrdestcb1 += destccstride;
173         ptrdestcb2 += destccstride;
174
175         ptrdestcr1 += destccstride;
176         ptrdestcr2 += destccstride;
177     }
178 }
179
180 static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
181                            int width, int height)
182 {
183     int i, j;
184
185     /* Source*/
186     unsigned char *ptrsrcy1, *ptrsrcy2;
187     unsigned char *ptrsrcy3, *ptrsrcy4;
188     unsigned char *ptrsrccb1, *ptrsrccb2;
189     unsigned char *ptrsrccr1, *ptrsrccr2;
190     int srcystride, srcccstride;
191
192     ptrsrcy1 = bufsrc;
193     ptrsrcy2 = bufsrc + width;
194     ptrsrcy3 = bufsrc + width*2;
195     ptrsrcy4 = bufsrc + width*3;
196
197     ptrsrccr1 = bufsrc + width*height;
198     ptrsrccr2 = bufsrc + width*height + (width>>1);
199
200     ptrsrccb1 = bufsrc + width*height + ((width*height) >> 2);
201     ptrsrccb2 = bufsrc + width*height + ((width*height) >> 2) + (width>>1);
202
203     srcystride  = (width)*3;
204     srcccstride = (width>>1);
205
206     /* Destination */
207     unsigned char *ptrdesty1, *ptrdesty2;
208     unsigned char *ptrdesty3, *ptrdesty4;
209     unsigned char *ptrdestcb1, *ptrdestcb2;
210     unsigned char *ptrdestcr1, *ptrdestcr2;
211     int destystride, destccstride;
212
213     ptrdesty1 = bufdest;
214     ptrdesty2 = bufdest + width;
215     ptrdesty3 = bufdest + width * 2;
216     ptrdesty4 = bufdest + width * 3;
217
218     ptrdestcb1 = bufdest + width * height;
219     ptrdestcb2 = bufdest + width * height + (width >> 1);
220
221     ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
222     ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
223                  + (width >> 1);
224
225     destystride  = (width)*3;
226     destccstride = (width>>1);
227
228     for (j = 0; j < (height / 4); j++) {
229         for (i = 0; i < (width / 2); i++) {
230
231             (*ptrdesty1++) = (*ptrsrcy1++);
232             (*ptrdesty2++) = (*ptrsrcy2++);
233             (*ptrdesty3++) = (*ptrsrcy3++);
234             (*ptrdesty4++) = (*ptrsrcy4++);
235             (*ptrdesty1++) = (*ptrsrcy1++);
236             (*ptrdesty2++) = (*ptrsrcy2++);
237             (*ptrdesty3++) = (*ptrsrcy3++);
238             (*ptrdesty4++) = (*ptrsrcy4++);
239
240             (*ptrdestcb1++) = (*ptrsrccb1++);
241             (*ptrdestcr1++) = (*ptrsrccr1++);
242             (*ptrdestcb2++) = (*ptrsrccb2++);
243             (*ptrdestcr2++) = (*ptrsrccr2++);
244
245         }
246
247         /* Update src pointers */
248         ptrsrcy1  += srcystride;
249         ptrsrcy2  += srcystride;
250         ptrsrcy3  += srcystride;
251         ptrsrcy4  += srcystride;
252
253         ptrsrccb1 += srcccstride;
254         ptrsrccb2 += srcccstride;
255
256         ptrsrccr1 += srcccstride;
257         ptrsrccr2 += srcccstride;
258
259         /* Update dest pointers */
260         ptrdesty1 += destystride;
261         ptrdesty2 += destystride;
262         ptrdesty3 += destystride;
263         ptrdesty4 += destystride;
264
265         ptrdestcb1 += destccstride;
266         ptrdestcb2 += destccstride;
267
268         ptrdestcr1 += destccstride;
269         ptrdestcr2 += destccstride;
270
271     }
272
273 }
274
275 static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
276                          int width, int height)
277 {
278     int i, j;
279
280     /* Source*/
281     unsigned char *ptrsrcy1, *ptrsrcy2;
282     unsigned char *ptrsrcy3, *ptrsrcy4;
283     unsigned char *ptrsrccb1;
284     unsigned char *ptrsrccb3;
285     unsigned char *ptrsrccr1;
286     unsigned char *ptrsrccr3;
287     int srcystride, srcccstride;
288
289     ptrsrcy1  = bufsrc ;
290     ptrsrcy2  = bufsrc + (width << 1);
291     ptrsrcy3  = bufsrc + (width << 1) * 2;
292     ptrsrcy4  = bufsrc + (width << 1) * 3;
293
294     ptrsrccb1 = bufsrc + 1;
295     ptrsrccb3 = bufsrc + (width << 1) * 2 + 1;
296
297     ptrsrccr1 = bufsrc + 3;
298     ptrsrccr3 = bufsrc + (width << 1) * 2 + 3;
299
300     srcystride  = (width << 1) * 3;
301     srcccstride = (width << 1) * 3;
302
303     /* Destination */
304     unsigned char *ptrdesty1, *ptrdesty2;
305     unsigned char *ptrdesty3, *ptrdesty4;
306     unsigned char *ptrdestcb1, *ptrdestcb2;
307     unsigned char *ptrdestcr1, *ptrdestcr2;
308     int destystride, destccstride;
309
310     ptrdesty1 = bufdest;
311     ptrdesty2 = bufdest + width;
312     ptrdesty3 = bufdest + width * 2;
313     ptrdesty4 = bufdest + width * 3;
314
315     ptrdestcb1 = bufdest + width * height;
316     ptrdestcb2 = bufdest + width * height + (width >> 1);
317
318     ptrdestcr1 = bufdest + width * height + ((width * height) >> 2);
319     ptrdestcr2 = bufdest + width * height + ((width * height) >> 2)
320                  + (width >> 1);
321
322     destystride  = width * 3;
323     destccstride = (width >> 1);
324
325     for (j = 0; j < (height / 4); j++) {
326         for (i = 0; i < (width / 2); i++) {
327             (*ptrdesty1++) = (*ptrsrcy1);
328             (*ptrdesty2++) = (*ptrsrcy2);
329             (*ptrdesty3++) = (*ptrsrcy3);
330             (*ptrdesty4++) = (*ptrsrcy4);
331
332             ptrsrcy1 += 2;
333             ptrsrcy2 += 2;
334             ptrsrcy3 += 2;
335             ptrsrcy4 += 2;
336
337             (*ptrdesty1++) = (*ptrsrcy1);
338             (*ptrdesty2++) = (*ptrsrcy2);
339             (*ptrdesty3++) = (*ptrsrcy3);
340             (*ptrdesty4++) = (*ptrsrcy4);
341
342             ptrsrcy1 += 2;
343             ptrsrcy2 += 2;
344             ptrsrcy3 += 2;
345             ptrsrcy4 += 2;
346
347             (*ptrdestcb1++) = (*ptrsrccb1);
348             (*ptrdestcb2++) = (*ptrsrccb3);
349
350             ptrsrccb1 += 4;
351             ptrsrccb3 += 4;
352
353             (*ptrdestcr1++) = (*ptrsrccr1);
354             (*ptrdestcr2++) = (*ptrsrccr3);
355
356             ptrsrccr1 += 4;
357             ptrsrccr3 += 4;
358
359         }
360
361         /* Update src pointers */
362         ptrsrcy1  += srcystride;
363         ptrsrcy2  += srcystride;
364         ptrsrcy3  += srcystride;
365         ptrsrcy4  += srcystride;
366
367         ptrsrccb1 += srcccstride;
368         ptrsrccb3 += srcccstride;
369
370         ptrsrccr1 += srcccstride;
371         ptrsrccr3 += srcccstride;
372
373         /* Update dest pointers */
374         ptrdesty1 += destystride;
375         ptrdesty2 += destystride;
376         ptrdesty3 += destystride;
377         ptrdesty4 += destystride;
378
379         ptrdestcb1 += destccstride;
380         ptrdestcb2 += destccstride;
381
382         ptrdestcr1 += destccstride;
383         ptrdestcr2 += destccstride;
384     }
385 }