Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / common tools sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 :
27 : #include <gpac/tools.h>
28 : #include <gpac/constants.h>
29 : #include <gpac/color.h>
30 :
31 : #ifndef GPAC_DISABLE_PLAYER
32 :
33 : static GF_Err color_write_nv12_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_up);
34 : static GF_Err color_write_yv12_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, const GF_Window *_src_wnd, Bool swap_up);
35 : static GF_Err color_write_yuv422_10_to_yuv422(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_up);
36 : static GF_Err color_write_yuv422_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_up);
37 : static GF_Err color_write_yuv444_10_to_yuv444(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_up);
38 : static GF_Err color_write_yuv444_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_up);
39 : static GF_Err color_write_yuv420_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv);
40 : static GF_Err color_write_yuv422_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv);
41 : static GF_Err color_write_yuv444_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv);
42 : static GF_Err color_write_yvyu_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv);
43 : static GF_Err color_write_rgb_to_24(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd);
44 : static GF_Err color_write_rgb_to_32(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd);
45 :
46 :
47 : static GFINLINE u8 colmask(s32 a, s32 n)
48 : {
49 : s32 mask = (1 << n) - 1;
50 118248 : return (u8) (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
51 : }
52 :
53 :
54 : /* YUV -> RGB conversion loading two lines at each call */
55 :
56 : #define col_clip(a) MAX(0, MIN(255, a))
57 : #define SCALEBITS_OUT 13
58 : #define FIX_OUT(x) ((unsigned short) ((x) * (1L<<SCALEBITS_OUT) + 0.5))
59 :
60 : static s32 RGB_Y[256];
61 : static s32 B_U[256];
62 : static s32 G_U[256];
63 : static s32 G_V[256];
64 : static s32 R_V[256];
65 :
66 :
67 : static s32 yuv2rgb_is_init = 0;
68 3411 : static void yuv2rgb_init(void)
69 : {
70 : s32 i;
71 3411 : if (yuv2rgb_is_init) return;
72 52 : yuv2rgb_is_init = 1;
73 :
74 13364 : for(i = 0; i < 256; i++) {
75 13312 : RGB_Y[i] = FIX_OUT(1.164) * (i - 16);
76 13312 : B_U[i] = FIX_OUT(2.018) * (i - 128);
77 13312 : G_U[i] = FIX_OUT(0.391) * (i - 128);
78 13312 : G_V[i] = FIX_OUT(0.813) * (i - 128);
79 13312 : R_V[i] = FIX_OUT(1.596) * (i - 128);
80 : }
81 : }
82 :
83 256181 : static void yuv_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
84 : {
85 : u32 hw, x;
86 256181 : unsigned char *dst2 = (unsigned char *) dst + dststride;
87 256181 : unsigned char *y_src2 = (unsigned char *) y_src + y_stride;
88 :
89 256181 : hw = width / 2;
90 256181 : if (dst_yuv) {
91 0 : for (x = 0; x < hw; x++) {
92 0 : dst[0] = dst[4] = dst2[0] = dst2[4] = v_src[x];
93 0 : dst[1] = dst[5] = dst2[1] = dst2[5] = u_src[x];
94 :
95 0 : dst[2] = *y_src;
96 0 : dst[3] = 0xFF;
97 : y_src++;
98 :
99 0 : dst[6] = *y_src;
100 0 : dst[7] = 0xFF;
101 0 : y_src++;
102 :
103 0 : dst2[2] = *y_src2;
104 0 : dst2[3] = 0xFF;
105 : y_src2++;
106 :
107 0 : dst2[6] = *y_src2;
108 0 : dst2[7] = 0xFF;
109 0 : y_src2++;
110 :
111 0 : dst += 8;
112 0 : dst2 += 8;
113 : }
114 : return;
115 : }
116 15924996 : for (x = 0; x < hw; x++) {
117 : s32 u, v;
118 : s32 b_u, g_uv, r_v, rgb_y;
119 :
120 15924996 : u = u_src[x];
121 15924996 : v = v_src[x];
122 :
123 15924996 : b_u = B_U[u];
124 15924996 : g_uv = G_U[u] + G_V[v];
125 15924996 : r_v = R_V[v];
126 :
127 15924996 : rgb_y = RGB_Y[*y_src];
128 15924996 : dst[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
129 15924996 : dst[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
130 15924996 : dst[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
131 15924996 : dst[3] = 0xFF;
132 : y_src++;
133 :
134 15924996 : rgb_y = RGB_Y[*y_src];
135 15924996 : dst[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
136 15924996 : dst[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
137 15924996 : dst[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
138 15924996 : dst[7] = 0xFF;
139 15924996 : y_src++;
140 :
141 15924996 : rgb_y = RGB_Y[*y_src2];
142 15924996 : dst2[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
143 15924996 : dst2[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
144 15924996 : dst2[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
145 15924996 : dst2[3] = 0xFF;
146 : y_src2++;
147 :
148 15924996 : rgb_y = RGB_Y[*y_src2];
149 15924996 : dst2[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
150 15924996 : dst2[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
151 15924996 : dst2[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
152 15924996 : dst2[7] = 0xFF;
153 15924996 : y_src2++;
154 :
155 15924996 : dst += 8;
156 15924996 : dst2 += 8;
157 : }
158 : }
159 64 : static void yuv422_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
160 : {
161 : u32 hw, x;
162 64 : unsigned char *dst2 = (unsigned char *)dst + dststride;
163 64 : unsigned char *y_src2 = (unsigned char *)y_src + y_stride;
164 64 : unsigned char *u_src2 = (unsigned char *)u_src + uv_stride;
165 64 : unsigned char *v_src2 = (unsigned char *)v_src + uv_stride;
166 :
167 64 : hw = width / 2;
168 64 : if (dst_yuv) {
169 0 : for (x = 0; x < hw; x++) {
170 0 : dst[0] = dst[4] = *v_src;
171 0 : dst[1] = dst[5] = *u_src;
172 0 : dst[2] = *y_src;
173 : y_src++;
174 0 : dst[3] = 0xFF;
175 0 : dst[6] = *y_src;
176 0 : y_src++;
177 0 : dst[7] = 0xFF;
178 :
179 0 : u_src++;
180 0 : v_src++;
181 :
182 0 : dst2[0] = dst2[4] = *v_src2;
183 0 : dst2[1] = dst2[5] = *u_src2;
184 0 : dst2[2] = *y_src;
185 : y_src2++;
186 0 : dst2[3] = 0xFF;
187 0 : dst2[6] = *y_src;
188 : y_src2++;
189 0 : dst2[7] = 0xFF;
190 :
191 0 : u_src2++;
192 0 : v_src2++;
193 :
194 0 : dst += 8;
195 0 : dst2 += 8;
196 : }
197 : return;
198 : }
199 :
200 4096 : for (x = 0; x < hw; x++) {
201 : s32 b_u, g_uv, r_v, rgb_y;
202 :
203 4096 : b_u = B_U[*u_src];
204 4096 : g_uv = G_U[*u_src] + G_V[*v_src];
205 4096 : r_v = R_V[*v_src];
206 4096 : rgb_y = RGB_Y[*y_src];
207 4096 : dst[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
208 4096 : dst[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
209 4096 : dst[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
210 4096 : dst[3] = 0xFF;
211 : y_src++;
212 :
213 4096 : rgb_y = RGB_Y[*y_src];
214 4096 : dst[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
215 4096 : dst[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
216 4096 : dst[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
217 4096 : dst[7] = 0xFF;
218 4096 : y_src++;
219 4096 : u_src++;
220 4096 : v_src++;
221 :
222 4096 : b_u = B_U[*u_src2];
223 4096 : g_uv = G_U[*u_src2] + G_V[*v_src2];
224 4096 : r_v = R_V[*v_src2];
225 4096 : rgb_y = RGB_Y[*y_src2];
226 4096 : dst2[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
227 4096 : dst2[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
228 4096 : dst2[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
229 4096 : dst2[3] = 0xFF;
230 : y_src2++;
231 :
232 4096 : rgb_y = RGB_Y[*y_src2];
233 4096 : dst2[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
234 4096 : dst2[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
235 4096 : dst2[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
236 4096 : dst2[7] = 0xFF;
237 4096 : y_src2++;
238 4096 : u_src2++;
239 4096 : v_src2++;
240 :
241 4096 : dst += 8;
242 4096 : dst2 += 8;
243 : }
244 : }
245 64 : static void yuv444_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
246 : {
247 : u32 hw, x;
248 64 : unsigned char *dst2 = (unsigned char *)dst + dststride;
249 64 : unsigned char *y_src2 = (unsigned char *)y_src + y_stride;
250 64 : unsigned char *u_src2 = (unsigned char *)u_src + uv_stride;
251 64 : unsigned char *v_src2 = (unsigned char *)v_src + uv_stride;
252 :
253 64 : hw = width / 2;
254 :
255 64 : if (dst_yuv) {
256 0 : for (x = 0; x < hw; x++) {
257 0 : dst[0] = *v_src;
258 0 : dst[1] = *u_src;
259 0 : dst[2] = *y_src;
260 0 : dst[3] = 0xFF;
261 :
262 : y_src++;
263 : u_src++;
264 : v_src++;
265 :
266 0 : dst[4] = *v_src;
267 0 : dst[5] = *u_src;
268 0 : dst[6] = *y_src;
269 0 : dst[7] = 0xFF;
270 :
271 0 : y_src++;
272 0 : u_src++;
273 0 : v_src++;
274 :
275 0 : dst2[0] = *v_src2;
276 0 : dst2[1] = *u_src2;
277 0 : dst2[2] = *y_src2;
278 0 : dst2[3] = 0xFF;
279 :
280 : y_src2++;
281 : u_src2++;
282 : v_src2++;
283 :
284 0 : dst2[4] = *v_src2;
285 0 : dst2[5] = *u_src2;
286 0 : dst2[6] = *y_src2;
287 0 : dst2[7] = 0xFF;
288 :
289 0 : y_src2++;
290 0 : u_src2++;
291 0 : v_src2++;
292 :
293 0 : dst += 8;
294 0 : dst2 += 8;
295 : }
296 : return;
297 : }
298 :
299 4096 : for (x = 0; x < hw; x++) {
300 : s32 b_u, g_uv, r_v, rgb_y;
301 :
302 :
303 4096 : b_u = B_U[*u_src];
304 4096 : g_uv = G_U[*u_src] + G_V[*v_src];
305 4096 : r_v = R_V[*v_src];
306 4096 : rgb_y = RGB_Y[*y_src];
307 4096 : dst[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
308 4096 : dst[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
309 4096 : dst[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
310 4096 : dst[3] = 0xFF;
311 : y_src++;
312 : u_src++;
313 : v_src++;
314 :
315 :
316 4096 : b_u = B_U[*u_src];
317 4096 : g_uv = G_U[*u_src] + G_V[*v_src];
318 4096 : r_v = R_V[*v_src];
319 4096 : rgb_y = RGB_Y[*y_src];
320 4096 : dst[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
321 4096 : dst[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
322 4096 : dst[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
323 4096 : dst[7] = 0xFF;
324 4096 : y_src++;
325 4096 : u_src++;
326 4096 : v_src++;
327 :
328 :
329 4096 : b_u = B_U[*u_src2];
330 4096 : g_uv = G_U[*u_src2] + G_V[*v_src2];
331 4096 : r_v = R_V[*v_src2];
332 4096 : rgb_y = RGB_Y[*y_src2];
333 4096 : dst2[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
334 4096 : dst2[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
335 4096 : dst2[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
336 4096 : dst2[3] = 0xFF;
337 : y_src2++;
338 : u_src2++;
339 : v_src2++;
340 :
341 :
342 4096 : b_u = B_U[*u_src2];
343 4096 : g_uv = G_U[*u_src2] + G_V[*v_src2];
344 4096 : r_v = R_V[*v_src2];
345 4096 : rgb_y = RGB_Y[*y_src2];
346 :
347 4096 : dst2[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
348 4096 : dst2[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
349 4096 : dst2[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
350 4096 : dst2[7] = 0xFF;
351 4096 : y_src2++;
352 4096 : u_src2++;
353 4096 : v_src2++;
354 :
355 4096 : dst += 8;
356 4096 : dst2 += 8;
357 : }
358 : }
359 :
360 64 : static void yuv_10_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *_y_src, unsigned char *_u_src, unsigned char *_v_src, s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
361 : {
362 : u32 hw, x;
363 64 : unsigned char *dst2 = (unsigned char *) dst + dststride;
364 64 : unsigned short *y_src2 = (unsigned short *) (_y_src + y_stride);
365 : unsigned short *y_src = (unsigned short *)_y_src;
366 : unsigned short *u_src = (unsigned short *)_u_src;
367 : unsigned short *v_src = (unsigned short *)_v_src;
368 :
369 :
370 64 : hw = width / 2;
371 64 : if (dst_yuv) {
372 0 : for (x = 0; x < hw; x++) {
373 0 : dst[0] = dst[4] = dst2[0] = dst2[4] = v_src[x] >> 2;
374 0 : dst[1] = dst[5] = dst2[1] = dst2[5] = u_src[x] >> 2;
375 0 : dst[2] = *y_src >> 2;
376 : y_src++;
377 0 : dst[3] = 0xFF;
378 :
379 0 : dst[6] = *y_src >> 2;
380 0 : y_src++;
381 0 : dst[7] = 0xFF;
382 :
383 0 : dst2[2] = *y_src2 >> 2;
384 : y_src2++;
385 0 : dst2[3] = 0xFF;
386 :
387 0 : dst2[6] = *y_src2 >> 2;
388 0 : y_src2++;
389 0 : dst2[7] = 0xFF;
390 :
391 0 : dst += 8;
392 0 : dst2 += 8;
393 : }
394 : return;
395 : }
396 4096 : for (x = 0; x < hw; x++) {
397 : s32 u, v;
398 : s32 b_u, g_uv, r_v, rgb_y;
399 :
400 4096 : u = u_src[x] >> 2;
401 4096 : v = v_src[x] >> 2;
402 :
403 4096 : b_u = B_U[u];
404 4096 : g_uv = G_U[u] + G_V[v];
405 4096 : r_v = R_V[v];
406 :
407 4096 : rgb_y = RGB_Y[*y_src >> 2];
408 4096 : dst[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
409 4096 : dst[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
410 4096 : dst[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
411 4096 : dst[3] = 0xFF;
412 : y_src++;
413 :
414 4096 : rgb_y = RGB_Y[*y_src >> 2];
415 4096 : dst[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
416 4096 : dst[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
417 4096 : dst[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
418 4096 : dst[7] = 0xFF;
419 4096 : y_src++;
420 :
421 4096 : rgb_y = RGB_Y[*y_src2 >> 2];
422 4096 : dst2[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
423 4096 : dst2[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
424 4096 : dst2[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
425 4096 : dst2[3] = 0xFF;
426 : y_src2++;
427 :
428 4096 : rgb_y = RGB_Y[*y_src2 >> 2];
429 4096 : dst2[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
430 4096 : dst2[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
431 4096 : dst2[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
432 4096 : dst2[7] = 0xFF;
433 4096 : y_src2++;
434 :
435 4096 : dst += 8;
436 4096 : dst2 += 8;
437 : }
438 : }
439 64 : static void yuv422_10_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *_y_src, unsigned char *_u_src, unsigned char *_v_src, s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
440 : {
441 : u32 hw, x;
442 64 : unsigned char *dst2 = (unsigned char *)dst + dststride;
443 64 : unsigned short *y_src2 = (unsigned short *)(_y_src + y_stride);
444 64 : unsigned short *u_src2 = (unsigned short *)(_u_src + uv_stride);
445 64 : unsigned short *v_src2 = (unsigned short *)(_v_src + uv_stride);
446 : unsigned short *y_src = (unsigned short *)_y_src;
447 : unsigned short *u_src = (unsigned short *)_u_src;
448 : unsigned short *v_src = (unsigned short *)_v_src;
449 :
450 64 : hw = width / 2;
451 :
452 64 : if (dst_yuv) {
453 0 : for (x = 0; x < hw; x++) {
454 0 : dst[0] = dst[4] = *v_src >> 2;
455 0 : dst[1] = dst[5] = *u_src >> 2;
456 0 : dst[2] = *y_src >> 2;
457 : y_src++;
458 0 : dst[3] = 0xFF;
459 :
460 0 : dst[6] = *y_src >> 2;
461 0 : y_src++;
462 0 : dst[7] = 0xFF;
463 :
464 0 : dst2[0] = dst2[4] = *v_src2 >> 2;
465 0 : dst2[1] = dst2[5] = *u_src2 >> 2;
466 0 : dst2[2] = *y_src2 >> 2;
467 : y_src2++;
468 0 : dst2[3] = 0xFF;
469 :
470 0 : dst2[6] = *y_src2 >> 2;
471 : y_src2++;
472 0 : dst2[7] = 0xFF;
473 :
474 0 : y_src2++;
475 0 : u_src2++;
476 0 : v_src2++;
477 :
478 0 : dst += 8;
479 0 : dst2 += 8;
480 : }
481 : return;
482 : }
483 4096 : for (x = 0; x < hw; x++) {
484 : s32 b_u, g_uv, r_v, rgb_y;
485 :
486 4096 : b_u = B_U[*u_src >> 2];
487 4096 : g_uv = G_U[*u_src >> 2] + G_V[*v_src >> 2];
488 4096 : r_v = R_V[*v_src >> 2];
489 4096 : rgb_y = RGB_Y[*y_src >> 2];
490 4096 : dst[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
491 4096 : dst[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
492 4096 : dst[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
493 4096 : dst[3] = 0xFF;
494 : y_src++;
495 :
496 :
497 :
498 :
499 4096 : rgb_y = RGB_Y[*y_src >> 2];
500 4096 : dst[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
501 4096 : dst[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
502 4096 : dst[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
503 4096 : dst[7] = 0xFF;
504 4096 : y_src++;
505 4096 : u_src++;
506 4096 : v_src++;
507 :
508 :
509 4096 : b_u = B_U[*u_src2 >> 2];
510 4096 : g_uv = G_U[*u_src2 >> 2] + G_V[*v_src2 >> 2];
511 4096 : r_v = R_V[*v_src2 >> 2];
512 4096 : rgb_y = RGB_Y[*y_src2 >> 2];
513 4096 : dst2[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
514 4096 : dst2[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
515 4096 : dst2[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
516 4096 : dst2[3] = 0xFF;
517 : y_src2++;
518 :
519 4096 : rgb_y = RGB_Y[*y_src2 >> 2];
520 4096 : dst2[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
521 4096 : dst2[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
522 4096 : dst2[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
523 4096 : dst2[7] = 0xFF;
524 4096 : y_src2++;
525 4096 : u_src2++;
526 4096 : v_src2++;
527 :
528 4096 : dst += 8;
529 4096 : dst2 += 8;
530 : }
531 : }
532 64 : static void yuv444_10_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *_y_src, unsigned char *_u_src, unsigned char *_v_src, s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
533 : {
534 : u32 hw, x;
535 64 : unsigned char *dst2 = (unsigned char *)dst + dststride;
536 64 : unsigned short * y_src2 = (unsigned short *)(_y_src + y_stride);
537 64 : unsigned short * u_src2 = (unsigned short *)(_u_src + uv_stride);
538 64 : unsigned short * v_src2 = (unsigned short *)(_v_src + uv_stride);
539 : unsigned short * y_src = (unsigned short *)_y_src;
540 : unsigned short * u_src = (unsigned short *)_u_src;
541 : unsigned short * v_src = (unsigned short *)_v_src;
542 :
543 64 : hw = width / 2;
544 64 : if (dst_yuv) {
545 0 : for (x = 0; x < hw; x++) {
546 0 : dst[0] = *v_src >> 2;
547 0 : dst[1] = *u_src >> 2;
548 0 : dst[2] = *y_src >> 2;
549 0 : dst[3] = 0xFF;
550 : y_src++;
551 : u_src++;
552 : v_src++;
553 :
554 0 : dst[4] = *v_src >> 2;
555 0 : dst[5] = *u_src >> 2;
556 0 : dst[6] = *y_src >> 2;
557 0 : dst[7] = 0xFF;
558 0 : y_src++;
559 0 : u_src++;
560 0 : v_src++;
561 :
562 0 : dst2[0] = *v_src2 >> 2;
563 0 : dst2[1] = *u_src2 >> 2;
564 0 : dst2[2] = *y_src2 >> 2;
565 0 : dst2[3] = 0xFF;
566 : y_src2++;
567 : u_src2++;
568 : v_src2++;
569 :
570 0 : dst2[4] = *v_src2 >> 2;
571 0 : dst2[5] = *u_src2 >> 2;
572 0 : dst2[6] = *y_src2 >> 2;
573 0 : dst2[7] = 0xFF;
574 0 : y_src2++;
575 0 : u_src2++;
576 0 : v_src2++;
577 :
578 0 : dst += 8;
579 0 : dst2 += 8;
580 : }
581 : return;
582 : }
583 4096 : for (x = 0; x < hw; x++) {
584 : s32 b_u, g_uv, r_v, rgb_y;
585 :
586 :
587 4096 : b_u = B_U[*u_src >> 2];
588 4096 : g_uv = G_U[*u_src >> 2] + G_V[*v_src >> 2];
589 4096 : r_v = R_V[*v_src >> 2];
590 4096 : rgb_y = RGB_Y[*y_src >> 2];
591 4096 : dst[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
592 4096 : dst[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
593 4096 : dst[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
594 4096 : dst[3] = 0xFF;
595 : y_src++;
596 : u_src++;
597 : v_src++;
598 :
599 :
600 4096 : b_u = B_U[*u_src >> 2];
601 4096 : g_uv = G_U[*u_src >> 2] + G_V[*v_src >> 2];
602 4096 : r_v = R_V[*v_src >> 2];
603 4096 : rgb_y = RGB_Y[*y_src >> 2];
604 4096 : dst[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
605 4096 : dst[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
606 4096 : dst[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
607 4096 : dst[7] = 0xFF;
608 4096 : y_src++;
609 4096 : u_src++;
610 4096 : v_src++;
611 :
612 :
613 4096 : b_u = B_U[*u_src2 >> 2];
614 4096 : g_uv = G_U[*u_src2 >> 2] + G_V[*v_src2 >> 2];
615 4096 : r_v = R_V[*v_src2 >> 2];
616 4096 : rgb_y = RGB_Y[*y_src2 >> 2];
617 4096 : dst2[0] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
618 4096 : dst2[1] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
619 4096 : dst2[2] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
620 4096 : dst2[3] = 0xFF;
621 : y_src2++;
622 : u_src2++;
623 : v_src2++;
624 :
625 :
626 4096 : b_u = B_U[*u_src2 >> 2];
627 4096 : g_uv = G_U[*u_src2 >> 2] + G_V[*v_src2 >> 2];
628 4096 : r_v = R_V[*v_src2 >> 2];
629 4096 : rgb_y = RGB_Y[*y_src2 >> 2];
630 :
631 4096 : dst2[4] = col_clip((rgb_y + r_v) >> SCALEBITS_OUT);
632 4096 : dst2[5] = col_clip((rgb_y - g_uv) >> SCALEBITS_OUT);
633 4096 : dst2[6] = col_clip((rgb_y + b_u) >> SCALEBITS_OUT);
634 4096 : dst2[7] = 0xFF;
635 4096 : y_src2++;
636 4096 : u_src2++;
637 4096 : v_src2++;
638 :
639 4096 : dst += 8;
640 4096 : dst2 += 8;
641 : }
642 : }
643 :
644 512 : static void yuv_load_lines_packed(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 width, Bool dst_yuv)
645 : {
646 : u32 hw;
647 :
648 512 : hw = width / 2;
649 512 : if (dst_yuv) {
650 0 : while (hw) {
651 0 : hw--;
652 :
653 0 : dst[0] = dst[4] = *u_src;
654 0 : dst[1] = dst[5] = *v_src;
655 0 : dst[2] = *y_src;
656 0 : dst[3] = 0xFF;
657 0 : dst[6] = *(y_src+2);
658 0 : dst[7] = 0xFF;
659 :
660 0 : dst += 8;
661 0 : y_src += 4;
662 0 : u_src += 4;
663 0 : v_src += 4;
664 : }
665 : return;
666 : }
667 33280 : while (hw) {
668 : s32 b_u, g_uv, r_v, rgb_y;
669 32768 : hw--;
670 :
671 32768 : b_u = B_U[*u_src];
672 32768 : g_uv = G_U[*u_src] + G_V[*v_src];
673 32768 : r_v = R_V[*v_src];
674 :
675 32768 : rgb_y = RGB_Y[*y_src];
676 32768 : dst[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
677 32768 : dst[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
678 32768 : dst[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
679 32768 : dst[3] = 0xFF;
680 :
681 32768 : rgb_y = RGB_Y[*(y_src+2)];
682 32768 : dst[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
683 32768 : dst[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
684 32768 : dst[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
685 32768 : dst[7] = 0xFF;
686 :
687 32768 : dst += 8;
688 32768 : y_src += 4;
689 32768 : u_src += 4;
690 32768 : v_src += 4;
691 : }
692 : }
693 :
694 :
695 0 : static void yuva_load_lines(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char *v_src, unsigned char *a_src,
696 : s32 y_stride, s32 uv_stride, s32 width, Bool dst_yuv)
697 : {
698 : u32 hw, x;
699 0 : unsigned char *dst2 = dst + dststride;
700 0 : unsigned char *y_src2 = y_src + y_stride;
701 0 : unsigned char *a_src2 = a_src + y_stride;
702 :
703 0 : yuv2rgb_init();
704 :
705 0 : hw = width / 2;
706 0 : if (dst_yuv) {
707 0 : for (x = 0; x < hw; x++) {
708 :
709 0 : dst[0] = dst[4] = dst2[0] = dst2[4] = v_src[x];
710 0 : dst[1] = dst[5] = dst2[1] = dst2[5] = u_src[x];
711 :
712 0 : dst[2] = *y_src;
713 0 : dst[3] = *a_src;
714 : y_src++;
715 : a_src++;
716 :
717 0 : dst[6] = *y_src;
718 0 : dst[7] = *a_src;
719 0 : y_src++;
720 0 : a_src++;
721 :
722 0 : dst2[2] = *y_src2;
723 0 : dst2[3] = *a_src2;
724 : y_src2++;
725 : a_src2++;
726 :
727 0 : dst2[6] = *y_src2;
728 0 : dst2[7] = *a_src2;
729 0 : y_src2++;
730 0 : a_src2++;
731 :
732 0 : dst += 8;
733 0 : dst2 += 8;
734 : }
735 : return;
736 : }
737 0 : for (x = 0; x < hw; x++) {
738 : s32 u, v;
739 : s32 b_u, g_uv, r_v, rgb_y;
740 :
741 0 : u = u_src[x];
742 0 : v = v_src[x];
743 :
744 0 : b_u = B_U[u];
745 0 : g_uv = G_U[u] + G_V[v];
746 0 : r_v = R_V[v];
747 :
748 0 : rgb_y = RGB_Y[*y_src];
749 0 : dst[0] = col_clip ( (rgb_y + r_v) >> SCALEBITS_OUT );
750 0 : dst[1] = col_clip ( (rgb_y - g_uv) >> SCALEBITS_OUT );
751 0 : dst[2] = col_clip ( (rgb_y + b_u) >> SCALEBITS_OUT );
752 0 : dst[3] = *a_src;
753 : y_src++;
754 : a_src++;
755 :
756 0 : rgb_y = RGB_Y[*y_src];
757 0 : dst[4] = col_clip ( (rgb_y + r_v) >> SCALEBITS_OUT );
758 0 : dst[5] = col_clip ( (rgb_y - g_uv) >> SCALEBITS_OUT );
759 0 : dst[6] = col_clip ( (rgb_y + b_u) >> SCALEBITS_OUT );
760 0 : dst[7] = *a_src;
761 0 : y_src++;
762 0 : a_src++;
763 :
764 0 : rgb_y = RGB_Y[*y_src2];
765 0 : dst2[0] = col_clip ( (rgb_y + r_v) >> SCALEBITS_OUT );
766 0 : dst2[1] = col_clip ( (rgb_y - g_uv) >> SCALEBITS_OUT );
767 0 : dst2[2] = col_clip ( (rgb_y + b_u) >> SCALEBITS_OUT );
768 0 : dst2[3] = *a_src2;
769 : y_src2++;
770 : a_src2++;
771 :
772 0 : rgb_y = RGB_Y[*y_src2];
773 0 : dst2[4] = col_clip ( (rgb_y + r_v) >> SCALEBITS_OUT );
774 0 : dst2[5] = col_clip ( (rgb_y - g_uv) >> SCALEBITS_OUT );
775 0 : dst2[6] = col_clip ( (rgb_y + b_u) >> SCALEBITS_OUT );
776 0 : dst2[7] = *a_src2;
777 0 : y_src2++;
778 0 : a_src2++;
779 :
780 0 : dst += 8;
781 0 : dst2 += 8;
782 : }
783 : }
784 :
785 : static s32 mul255(s32 a, s32 b)
786 : {
787 14462393 : return ((a+1) * b) >> 8;
788 : }
789 :
790 : typedef void (*copy_row_proto)(u8 *src, u32 src_w, u8 *_dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height);
791 : typedef void (*load_line_proto)(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 src_width, u32 src_height, u8 *dst_bits, Bool dst_yuv);
792 :
793 130 : static void copy_row_rgb_555(u8 *src, u32 src_w, u8 *_dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
794 : {
795 : s32 pos;
796 : u16 *dst = (u16 *)_dst;
797 : u8 a=0, r=0, g=0, b=0;
798 130 : x_pitch /= 2;
799 : pos = 0x10000;
800 16900 : while (dst_w) {
801 33026 : while ( pos >= 0x10000L ) {
802 16386 : r = *src++;
803 16386 : g = *src++;
804 16386 : b = *src++;
805 16386 : a = *src++;
806 16386 : pos -= 0x10000L;
807 : }
808 16640 : if (a) *dst = GF_COL_555(r, g, b);
809 16640 : dst += x_pitch;
810 16640 : pos += h_inc;
811 16640 : dst_w--;
812 : }
813 130 : }
814 :
815 130 : static void copy_row_rgb_565(u8 *src, u32 src_w, u8 *_dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
816 : {
817 : s32 pos;
818 : u16 *dst = (u16 *)_dst;
819 : u8 a=0, r=0, g=0, b=0;
820 130 : x_pitch /= 2;
821 : pos = 0x10000;
822 16900 : while (dst_w) {
823 33026 : while ( pos >= 0x10000L ) {
824 16386 : r = *src++;
825 16386 : g = *src++;
826 16386 : b = *src++;
827 16386 : a = *src++;
828 16386 : pos -= 0x10000L;
829 : }
830 16640 : if (a) *dst = GF_COL_565(r, g, b);
831 16640 : dst += x_pitch;
832 16640 : pos += h_inc;
833 16640 : dst_w--;
834 : }
835 130 : }
836 :
837 :
838 401426 : static void copy_row_rgb_24(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
839 : {
840 : s32 pos;
841 : u8 a=0, r=0, g=0, b=0;
842 :
843 : pos = 0x10000;
844 38714418 : while (dst_w) {
845 96767385 : while ( pos >= 0x10000L ) {
846 58855819 : r = *src++;
847 58855819 : g = *src++;
848 58855819 : b = *src++;
849 58855819 : a = *src++;
850 58855819 : pos -= 0x10000L;
851 : }
852 37911566 : if (a) {
853 36314451 : dst[0] = r;
854 36314451 : dst[1] = g;
855 36314451 : dst[2] = b;
856 : }
857 37911566 : dst += x_pitch;
858 37911566 : pos += h_inc;
859 37911566 : dst_w--;
860 : }
861 401426 : }
862 :
863 3202 : static void copy_row_bgr_24(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
864 : {
865 : s32 pos;
866 : u8 a=0, r=0, g=0, b=0;
867 :
868 : pos = 0x10000;
869 416260 : while (dst_w) {
870 819458 : while ( pos >= 0x10000L ) {
871 409602 : r = *src++;
872 409602 : g = *src++;
873 409602 : b = *src++;
874 409602 : a = *src++;
875 409602 : pos -= 0x10000L;
876 : }
877 409856 : if (a) {
878 409856 : dst[0] = b;
879 409856 : dst[1] = g;
880 409856 : dst[2] = r;
881 : }
882 409856 : dst += x_pitch;
883 409856 : pos += h_inc;
884 409856 : dst_w--;
885 : }
886 3202 : }
887 :
888 132 : static void copy_row_bgrx(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
889 : {
890 : u8 a=0, r=0, g=0, b=0;
891 : s32 pos = 0x10000L;
892 :
893 17160 : while (dst_w) {
894 33284 : while ( pos >= 0x10000L ) {
895 16388 : r = *src++;
896 16388 : g = *src++;
897 16388 : b = *src++;
898 16388 : a = *src++;
899 16388 : pos -= 0x10000L;
900 : }
901 16896 : if (a) {
902 16896 : dst[0] = b;
903 16896 : dst[1] = g;
904 16896 : dst[2] = r;
905 16896 : dst[3] = 0xFF;
906 : }
907 16896 : dst += x_pitch;
908 16896 : pos += h_inc;
909 16896 : dst_w--;
910 : }
911 132 : }
912 :
913 :
914 130 : static void copy_row_argb(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
915 : {
916 : u8 a=0, r=0, g=0, b=0;
917 : s32 pos = 0x10000L;
918 :
919 16900 : while (dst_w) {
920 33026 : while ( pos >= 0x10000L ) {
921 16386 : r = *src++;
922 16386 : g = *src++;
923 16386 : b = *src++;
924 16386 : a = *src++;
925 16386 : pos -= 0x10000L;
926 : }
927 16640 : if (a) {
928 16640 : dst[0] = 0xFF;
929 16640 : dst[1] = r;
930 16640 : dst[2] = g;
931 16640 : dst[3] = b;
932 : }
933 16640 : dst += x_pitch;
934 16640 : pos += h_inc;
935 16640 : dst_w--;
936 : }
937 130 : }
938 :
939 190 : static void copy_row_rgbx(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
940 : {
941 : u8 a=0, r=0, g=0, b=0;
942 : s32 pos = 0x10000L;
943 :
944 24004 : while ( dst_w) {
945 47378 : while ( pos >= 0x10000L ) {
946 23754 : r = *src++;
947 23754 : g = *src++;
948 23754 : b = *src++;
949 23754 : a = *src++;
950 23754 : pos -= 0x10000L;
951 : }
952 23624 : if (a) {
953 23624 : dst[0] = r;
954 23624 : dst[1] = g;
955 23624 : dst[2] = b;
956 23624 : dst[3] = 0xFF;
957 : }
958 23624 : dst+=x_pitch;
959 23624 : pos += h_inc;
960 23624 : dst_w--;
961 : }
962 190 : }
963 :
964 0 : static void copy_row_rgbd(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
965 : {
966 : u8 a=0, r=0, g=0, b=0;
967 : s32 pos = 0x10000L;
968 :
969 0 : while ( dst_w) {
970 0 : while ( pos >= 0x10000L ) {
971 0 : r = *src++;
972 0 : g = *src++;
973 0 : b = *src++;
974 0 : a = *src++;
975 0 : pos -= 0x10000L;
976 : }
977 0 : dst[0] = r;
978 0 : dst[1] = g;
979 0 : dst[2] = b;
980 0 : dst[3] = a;
981 :
982 0 : dst+=x_pitch;
983 0 : pos += h_inc;
984 0 : dst_w--;
985 : }
986 0 : }
987 : #if 0
988 : static void copy_row_yuv444(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
989 : {
990 : s32 pos;
991 : u8 *dY, *dU, *dV;
992 : u8 a=0, y=0, u=0, v=0;
993 :
994 : dY = dst;
995 : dU = dst + dst_height * dst_pitch;
996 : dV = dU + dst_height * dst_pitch;
997 :
998 : pos = 0x10000;
999 : while (dst_w) {
1000 : while ( pos >= 0x10000L ) {
1001 : v = *src++;
1002 : u = *src++;
1003 : y = *src++;
1004 : a = *src++;
1005 : pos -= 0x10000L;
1006 : }
1007 : if (a) {
1008 : *dV = v;
1009 : *dU = u;
1010 : *dY = y;
1011 : }
1012 : dY++;
1013 : dU++;
1014 : dV++;
1015 :
1016 : pos += h_inc;
1017 : dst_w--;
1018 : }
1019 : }
1020 : #endif
1021 :
1022 128 : static void merge_row_rgb_555(u8 *src, u32 src_w, u8 *_dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1023 : {
1024 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1025 : s32 pos;
1026 : u16 col, *dst = (u16 *)_dst;
1027 128 : x_pitch /= 2;
1028 : pos = 0x10000;
1029 16640 : while (dst_w) {
1030 32768 : while ( pos >= 0x10000L ) {
1031 16384 : r = *src++;
1032 16384 : g = *src++;
1033 16384 : b = *src++;
1034 16384 : a = *src++;
1035 16384 : pos -= 0x10000L;
1036 32768 : a = mul255(a, alpha);
1037 : }
1038 16384 : if (a && alpha) {
1039 6648 : col = *dst;
1040 13296 : _r = colmask(col >> (10 - 3), 3);
1041 13296 : _g = colmask(col >> (5 - 3), 3);
1042 13296 : _b = colmask(col << 3, 3);
1043 :
1044 13296 : _r = mul255(a, r - _r) + _r;
1045 13296 : _g = mul255(a, g - _g) + _g;
1046 13296 : _b = mul255(a, b - _b) + _b;
1047 6648 : *dst = GF_COL_555(_r, _g, _b);
1048 : }
1049 16384 : dst += x_pitch;
1050 16384 : pos += h_inc;
1051 16384 : dst_w--;
1052 : }
1053 128 : }
1054 :
1055 128 : static void merge_row_rgb_565(u8 *src, u32 src_w, u8 *_dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1056 : {
1057 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1058 : s32 pos;
1059 : u16 col, *dst = (u16 *)_dst;
1060 128 : x_pitch /= 2;
1061 : pos = 0x10000;
1062 16640 : while (dst_w) {
1063 32768 : while ( pos >= 0x10000L ) {
1064 16384 : r = *src++;
1065 16384 : g = *src++;
1066 16384 : b = *src++;
1067 16384 : a = *src++;
1068 16384 : pos -= 0x10000L;
1069 32768 : a = mul255(a, alpha);
1070 : }
1071 16384 : if (a) {
1072 6648 : col = *dst;
1073 6648 : _r = (col >> 8) & 0xf8;
1074 6648 : _g = (col >> 3) & 0xfc;
1075 6648 : _b = (col << 3) & 0xf8;
1076 13296 : _r = mul255(a, r - _r) + _r;
1077 13296 : _g = mul255(a, g - _g) + _g;
1078 13296 : _b = mul255(a, b - _b) + _b;
1079 6648 : *dst = GF_COL_565(_r, _g, _b);
1080 : }
1081 16384 : dst += x_pitch;
1082 16384 : pos += h_inc;
1083 16384 : dst_w--;
1084 : }
1085 128 : }
1086 :
1087 :
1088 36464 : static void merge_row_rgb_24(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1089 : {
1090 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1091 : s32 pos;
1092 :
1093 : pos = 0x10000;
1094 3549435 : while (dst_w) {
1095 9831027 : while ( pos >= 0x10000L ) {
1096 6354520 : r = *src++;
1097 6354520 : g = *src++;
1098 6354520 : b = *src++;
1099 6354520 : a = *src++;
1100 6354520 : pos -= 0x10000L;
1101 12709040 : a = mul255(a, alpha);
1102 : }
1103 3476507 : if (a) {
1104 2595699 : _r = dst[0];
1105 : _g = dst[0];
1106 : _b = dst[0];
1107 5191398 : dst[0] = mul255(a, r - _r) + _r;
1108 5191398 : dst[1] = mul255(a, g - _g) + _g;
1109 5191398 : dst[2] = mul255(a, b - _b) + _b;
1110 : }
1111 3476507 : dst += x_pitch;
1112 3476507 : pos += h_inc;
1113 3476507 : dst_w--;
1114 : }
1115 36464 : }
1116 :
1117 :
1118 : #if 0
1119 : static void merge_row_yuv444(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1120 : {
1121 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1122 : s32 pos;
1123 : u8 *dY, *dU, *dV;
1124 :
1125 : dY = dst;
1126 : dU = dst + dst_height * dst_pitch;
1127 : dV = dU + dst_height * dst_pitch;
1128 :
1129 : pos = 0x10000;
1130 : while (dst_w) {
1131 : while ( pos >= 0x10000L ) {
1132 : r = *src++;
1133 : g = *src++;
1134 : b = *src++;
1135 : a = *src++;
1136 : pos -= 0x10000L;
1137 : a = mul255(a, alpha);
1138 : }
1139 : if (a) {
1140 : _r = dY[0];
1141 : _g = dU[0];
1142 : _b = dV[0];
1143 : dY[0] = mul255(a, r - _r) + _r;
1144 : dU[1] = mul255(a, g - _g) + _g;
1145 : dV[2] = mul255(a, b - _b) + _b;
1146 : }
1147 : dY++;
1148 : dU++;
1149 : dV++;
1150 :
1151 : pos += h_inc;
1152 : dst_w--;
1153 : }
1154 : }
1155 : #endif
1156 :
1157 128 : static void merge_row_bgr_24(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1158 : {
1159 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1160 : s32 pos;
1161 :
1162 : pos = 0x10000;
1163 16640 : while (dst_w) {
1164 32768 : while ( pos >= 0x10000L ) {
1165 16384 : r = *src++;
1166 16384 : g = *src++;
1167 16384 : b = *src++;
1168 16384 : a = *src++;
1169 16384 : pos -= 0x10000L;
1170 : }
1171 :
1172 16384 : if (a && alpha) {
1173 6648 : _b = dst[0];
1174 6648 : _g = dst[1];
1175 6648 : _r = dst[2];
1176 13296 : a = mul255(a, alpha);
1177 13296 : dst[0] = mul255(a, b - _b) + _b;
1178 13296 : dst[1] = mul255(a, g - _g) + _g;
1179 13296 : dst[2] = mul255(a, r - _r) + _r;
1180 : }
1181 16384 : dst += x_pitch;
1182 16384 : pos += h_inc;
1183 16384 : dst_w--;
1184 : }
1185 128 : }
1186 :
1187 :
1188 128 : static void merge_row_bgrx(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1189 : {
1190 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1191 : s32 pos;
1192 :
1193 : pos = 0x10000;
1194 16640 : while (dst_w) {
1195 32768 : while ( pos >= 0x10000L ) {
1196 16384 : r = *src++;
1197 16384 : g = *src++;
1198 16384 : b = *src++;
1199 16384 : a = *src++;
1200 32768 : a = mul255(a, alpha);
1201 16384 : pos -= 0x10000L;
1202 : }
1203 :
1204 16384 : if (a) {
1205 6648 : _b = dst[0];
1206 6648 : _g = dst[1];
1207 6648 : _r = dst[2];
1208 :
1209 13296 : _r = mul255(a, r - _r) + _r;
1210 13296 : _g = mul255(a, g - _g) + _g;
1211 13296 : _b = mul255(a, b - _b) + _b;
1212 :
1213 6648 : dst[0] = _b;
1214 6648 : dst[1] = _g;
1215 6648 : dst[2] = _r;
1216 6648 : dst[3] = 0xFF;
1217 : }
1218 16384 : dst += x_pitch;
1219 16384 : pos += h_inc;
1220 16384 : dst_w--;
1221 : }
1222 128 : }
1223 :
1224 128 : static void merge_row_rgbx(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1225 : {
1226 : u32 _r, _g, _b, a=0, r=0, g=0, b=0;
1227 : s32 pos;
1228 :
1229 : pos = 0x10000;
1230 16640 : while (dst_w) {
1231 32768 : while ( pos >= 0x10000L ) {
1232 16384 : r = *src++;
1233 16384 : g = *src++;
1234 16384 : b = *src++;
1235 16384 : a = *src++;
1236 32768 : a = mul255(a, alpha);
1237 16384 : pos -= 0x10000L;
1238 : }
1239 :
1240 16384 : if (a) {
1241 6648 : _r = dst[0];
1242 6648 : _g = dst[1];
1243 6648 : _b = dst[2];
1244 13296 : _r = mul255(a, r - _r) + _r;
1245 13296 : _g = mul255(a, g - _g) + _g;
1246 13296 : _b = mul255(a, b - _b) + _b;
1247 6648 : dst[0] = _r;
1248 6648 : dst[1] = _g;
1249 6648 : dst[2] = _b;
1250 6648 : dst[3] = 0xFF;
1251 : }
1252 16384 : dst += x_pitch;
1253 16384 : pos += h_inc;
1254 16384 : dst_w--;
1255 : }
1256 128 : }
1257 :
1258 :
1259 128 : static void merge_row_bgra(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1260 : {
1261 : u32 _a, _r, _g, _b, a=0, r=0, g=0, b=0;
1262 : s32 pos;
1263 :
1264 : pos = 0x10000;
1265 16640 : while (dst_w) {
1266 32768 : while ( pos >= 0x10000L ) {
1267 16384 : r = *src++;
1268 16384 : g = *src++;
1269 16384 : b = *src++;
1270 16384 : a = *src++;
1271 16384 : pos -= 0x10000L;
1272 32768 : a = mul255(a, alpha);
1273 : }
1274 :
1275 16384 : if (a) {
1276 6648 : _b = dst[0];
1277 6648 : _g = dst[1];
1278 6648 : _r = dst[2];
1279 6648 : if (dst[3]) {
1280 19944 : _a = mul255(a, a) + mul255(0xFF-a, 0xFF);
1281 13296 : _r = mul255(a, r - _r) + _r;
1282 13296 : _g = mul255(a, g - _g) + _g;
1283 13296 : _b = mul255(a, b - _b) + _b;
1284 6648 : dst[0] = _b;
1285 6648 : dst[1] = _g;
1286 6648 : dst[2] = _r;
1287 6648 : dst[3] = _a;
1288 : } else {
1289 0 : dst[0] = b;
1290 0 : dst[1] = g;
1291 0 : dst[2] = r;
1292 0 : dst[3] = a;
1293 : }
1294 : }
1295 16384 : dst += x_pitch;
1296 16384 : pos += h_inc;
1297 16384 : dst_w--;
1298 : }
1299 128 : }
1300 :
1301 :
1302 128 : static void merge_row_argb(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1303 : {
1304 : u32 _a, _r, _g, _b, a=0, r=0, g=0, b=0;
1305 : s32 pos;
1306 :
1307 : pos = 0x10000;
1308 16640 : while (dst_w) {
1309 32768 : while ( pos >= 0x10000L ) {
1310 16384 : r = *src++;
1311 16384 : g = *src++;
1312 16384 : b = *src++;
1313 16384 : a = *src++;
1314 16384 : pos -= 0x10000L;
1315 32768 : a = mul255(a, alpha);
1316 : }
1317 :
1318 16384 : if (a) {
1319 6648 : _r = dst[1];
1320 6648 : _g = dst[2];
1321 6648 : _b = dst[3];
1322 6648 : if (dst[0]) {
1323 19944 : _a = mul255(a, a) + mul255(0xFF-a, 0xFF);
1324 13296 : _r = mul255(a, r - _r) + _r;
1325 13296 : _g = mul255(a, g - _g) + _g;
1326 13296 : _b = mul255(a, b - _b) + _b;
1327 6648 : dst[0] = _a;
1328 6648 : dst[1] = _r;
1329 6648 : dst[2] = _g;
1330 6648 : dst[3] = _b;
1331 : } else {
1332 0 : dst[0] = a;
1333 0 : dst[1] = b;
1334 0 : dst[2] = g;
1335 0 : dst[3] = r;
1336 : }
1337 : }
1338 16384 : dst += x_pitch;
1339 16384 : pos += h_inc;
1340 16384 : dst_w--;
1341 : }
1342 128 : }
1343 :
1344 128 : static void merge_row_rgba(u8 *src, u32 src_w, u8 *dst, u32 dst_w, s32 h_inc, s32 x_pitch, u8 alpha, u32 dst_pitch, u32 dst_height)
1345 : {
1346 : u32 _a, _r, _g, _b, a=0, r=0, g=0, b=0;
1347 : s32 pos;
1348 : pos = 0x10000;
1349 16640 : while (dst_w) {
1350 32768 : while ( pos >= 0x10000L ) {
1351 16384 : r = *src++;
1352 16384 : g = *src++;
1353 16384 : b = *src++;
1354 16384 : a = *src++;
1355 16384 : pos -= 0x10000L;
1356 32768 : a = mul255(a, alpha);
1357 : }
1358 :
1359 16384 : if (a) {
1360 6648 : _r = dst[0];
1361 6648 : _g = dst[1];
1362 6648 : _b = dst[2];
1363 6648 : if (dst[3]) {
1364 19944 : _a = mul255(a, a) + mul255(0xFF-a, 0xFF);
1365 13296 : _r = mul255(a, r - _r) + _r;
1366 13296 : _g = mul255(a, g - _g) + _g;
1367 13296 : _b = mul255(a, b - _b) + _b;
1368 6648 : dst[0] = _r;
1369 6648 : dst[1] = _g;
1370 6648 : dst[2] = _b;
1371 6648 : dst[3] = _a;
1372 : } else {
1373 0 : dst[0] = r;
1374 0 : dst[1] = g;
1375 0 : dst[2] = b;
1376 0 : dst[3] = a;
1377 : }
1378 : }
1379 16384 : dst += x_pitch;
1380 16384 : pos += h_inc;
1381 16384 : dst_w--;
1382 : }
1383 128 : }
1384 :
1385 :
1386 128 : static void load_line_grey(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1387 : {
1388 : u32 i;
1389 128 : src_bits += x_offset + y_offset*y_pitch;
1390 16512 : for (i=0; i<width; i++) {
1391 16384 : dst_bits[0] = dst_bits[1] = dst_bits[2] = *src_bits++;
1392 16384 : dst_bits[3] = 0xFF;
1393 16384 : dst_bits+=4;
1394 : }
1395 128 : }
1396 :
1397 128 : static void load_line_alpha_grey(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1398 : {
1399 : u32 i;
1400 128 : src_bits += x_offset*2 + y_offset*y_pitch;
1401 16512 : for (i=0; i<width; i++) {
1402 16384 : dst_bits[0] = dst_bits[1] = dst_bits[2] = *src_bits++;
1403 16384 : dst_bits[3] = *src_bits++;
1404 16384 : dst_bits+=4;
1405 : }
1406 128 : }
1407 :
1408 128 : static void load_line_grey_alpha(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1409 : {
1410 : u32 i;
1411 128 : src_bits += x_offset*2 + y_offset*y_pitch;
1412 16512 : for (i=0; i<width; i++) {
1413 16384 : dst_bits[3] = *src_bits++;
1414 16384 : dst_bits[0] = dst_bits[1] = dst_bits[2] = *src_bits++;
1415 16384 : dst_bits+=4;
1416 : }
1417 128 : }
1418 :
1419 128 : static void load_line_rgb_555(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1420 : {
1421 : u32 i;
1422 128 : src_bits += x_offset*3 + y_offset*y_pitch;
1423 16512 : for (i=0; i<width; i++) {
1424 16384 : u16 c = *((u16*)src_bits + i);
1425 32768 : dst_bits[0] = colmask(c >> (10 - 3), 3);
1426 32768 : dst_bits[1] = colmask(c >> (5 - 3), 3);
1427 32768 : dst_bits[2] = colmask(c << 3, 3);
1428 16384 : dst_bits[3] = 0xFF;
1429 16384 : dst_bits+=4;
1430 : }
1431 128 : }
1432 :
1433 128 : static void load_line_rgb_565(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1434 : {
1435 : u32 i;
1436 128 : src_bits += x_offset*3 + y_offset*y_pitch;
1437 16512 : for (i=0; i<width; i++) {
1438 16384 : u16 c = *((u16*)src_bits + i);
1439 32768 : dst_bits[0] = colmask(c >> (11 - 3), 3);
1440 32768 : dst_bits[1] = colmask(c >> (5 - 2), 2);
1441 32768 : dst_bits[2] = colmask(c << 3, 3);
1442 16384 : dst_bits[3] = 0xFF;
1443 16384 : dst_bits+=4;
1444 : }
1445 128 : }
1446 :
1447 150067 : static void load_line_rgb_24(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1448 : {
1449 : u32 i;
1450 150067 : src_bits += x_offset*3 + y_offset*y_pitch;
1451 29839615 : for (i=0; i<width; i++) {
1452 29689548 : dst_bits[0] = *src_bits++;
1453 29689548 : dst_bits[1] = *src_bits++;
1454 29689548 : dst_bits[2] = *src_bits++;
1455 29689548 : dst_bits[3] = 0xFF;
1456 29689548 : dst_bits+=4;
1457 : }
1458 150067 : }
1459 :
1460 128 : static void load_line_bgr_24(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1461 : {
1462 : u32 i;
1463 128 : src_bits += x_offset*3 + y_offset*y_pitch;
1464 16512 : for (i=0; i<width; i++) {
1465 16384 : dst_bits[2] = *src_bits++;
1466 16384 : dst_bits[1] = *src_bits++;
1467 16384 : dst_bits[0] = *src_bits++;
1468 16384 : dst_bits[3] = 0xFF;
1469 16384 : dst_bits+=4;
1470 : }
1471 128 : }
1472 :
1473 7263 : static void load_line_rgb_32(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1474 : {
1475 : u32 i;
1476 7263 : src_bits += x_offset*4 + y_offset*y_pitch;
1477 933343 : for (i=0; i<width; i++) {
1478 926080 : dst_bits[0] = *src_bits++;
1479 926080 : dst_bits[1] = *src_bits++;
1480 926080 : dst_bits[2] = *src_bits++;
1481 926080 : dst_bits[3] = *src_bits++;
1482 926080 : dst_bits += 4;
1483 : }
1484 7263 : }
1485 128 : static void load_line_xrgb(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1486 : {
1487 : u32 i;
1488 128 : src_bits += x_offset*4 + y_offset*y_pitch;
1489 16512 : for (i=0; i<width; i++) {
1490 : src_bits++;
1491 16384 : dst_bits[0] = *src_bits++;
1492 16384 : dst_bits[1] = *src_bits++;
1493 16384 : dst_bits[2] = *src_bits++;
1494 16384 : dst_bits[3] = 0xFF;
1495 16384 : dst_bits += 4;
1496 : }
1497 128 : }
1498 128 : static void load_line_bgrx(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1499 : {
1500 : u32 i;
1501 128 : src_bits += x_offset*4 + y_offset*y_pitch;
1502 16512 : for (i=0; i<width; i++) {
1503 16384 : dst_bits[2] = *src_bits++;
1504 16384 : dst_bits[1] = *src_bits++;
1505 16384 : dst_bits[0] = *src_bits++;
1506 16384 : dst_bits[3] = 0xFF;
1507 16384 : src_bits++;
1508 16384 : dst_bits += 4;
1509 : }
1510 128 : }
1511 :
1512 0 : static void load_line_rgbd(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1513 : {
1514 : u32 i;
1515 0 : src_bits += x_offset*4 + y_offset*y_pitch;
1516 0 : for (i=0; i<width; i++) {
1517 0 : dst_bits[0] = *src_bits++;
1518 0 : dst_bits[1] = *src_bits++;
1519 0 : dst_bits[2] = *src_bits++;
1520 0 : dst_bits[3] = 0xFF;
1521 0 : src_bits++;
1522 0 : dst_bits += 4;
1523 : }
1524 0 : }
1525 :
1526 0 : static void load_line_rgbds(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1527 : {
1528 : u32 i;
1529 0 : src_bits += x_offset*4 + y_offset*y_pitch;
1530 0 : for (i=0; i<width; i++) {
1531 0 : dst_bits[0] = *src_bits++;
1532 0 : dst_bits[1] = *src_bits++;
1533 0 : dst_bits[2] = *src_bits++;
1534 0 : dst_bits[3] = (( *src_bits++) & 0x80) ? 255 : 0;
1535 0 : dst_bits += 4;
1536 : }
1537 0 : }
1538 :
1539 128 : static void load_line_bgra(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1540 : {
1541 : u32 i;
1542 128 : src_bits += x_offset*4 + y_offset*y_pitch;
1543 16512 : for (i=0; i<width; i++) {
1544 16384 : dst_bits[2] = *src_bits++;
1545 16384 : dst_bits[1] = *src_bits++;
1546 16384 : dst_bits[0] = *src_bits++;
1547 16384 : dst_bits[3] = *src_bits++;
1548 16384 : dst_bits += 4;
1549 : }
1550 128 : }
1551 :
1552 24389 : static void load_line_argb(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1553 : {
1554 : u32 i;
1555 24389 : src_bits += x_offset*4 + y_offset*y_pitch;
1556 3387021 : for (i=0; i<width; i++) {
1557 3362632 : dst_bits[3] = *src_bits++;
1558 3362632 : dst_bits[0] = *src_bits++;
1559 3362632 : dst_bits[1] = *src_bits++;
1560 3362632 : dst_bits[2] = *src_bits++;
1561 3362632 : dst_bits += 4;
1562 : }
1563 24389 : }
1564 256181 : static void load_line_yv12(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, Bool dst_yuv)
1565 : {
1566 : u8 *pY;
1567 : pY = (u8 *)src_bits;
1568 256181 : if (!pU) {
1569 256181 : pU = (u8 *)src_bits + y_pitch*height;
1570 256181 : pV = (u8 *)src_bits + 5*y_pitch*height/4;
1571 : }
1572 :
1573 256181 : pY += x_offset + y_offset*y_pitch;
1574 256181 : pU += x_offset/2 + y_offset*y_pitch/4;
1575 256181 : pV += x_offset/2 + y_offset*y_pitch/4;
1576 256181 : yuv_load_lines_planar((unsigned char*)dst_bits, 4*width, pY, pU, pV, y_pitch, y_pitch/2, width, dst_yuv);
1577 256181 : }
1578 64 : static void load_line_yuv422(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, Bool dst_yuv)
1579 : {
1580 : u8 *pY;
1581 : pY = (u8 *)src_bits;
1582 64 : if (!pU) {
1583 64 : pU = (u8 *)src_bits + y_pitch*height;
1584 64 : pV = (u8 *)src_bits + 3 * y_pitch*height / 2;
1585 : }
1586 :
1587 64 : pY += x_offset + y_offset*y_pitch;
1588 64 : pU += x_offset / 2 + y_offset*y_pitch / 2;
1589 64 : pV += x_offset / 2 + y_offset*y_pitch / 2;
1590 64 : yuv422_load_lines_planar((unsigned char*)dst_bits, 4 * width, pY, pU, pV, y_pitch, y_pitch / 2, width, dst_yuv);
1591 64 : }
1592 64 : static void load_line_yuv444(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, Bool dst_yuv)
1593 : {
1594 : u8 *pY;
1595 : pY = (u8 *)src_bits;
1596 64 : if (!pU) {
1597 64 : pU = (u8 *)src_bits + y_pitch*height;
1598 64 : pV = (u8 *)src_bits + 2 * y_pitch*height;
1599 : }
1600 :
1601 :
1602 64 : pY += x_offset + y_offset*y_pitch;
1603 64 : pU += x_offset + y_offset*y_pitch;
1604 64 : pV += x_offset + y_offset*y_pitch;
1605 64 : yuv444_load_lines_planar((unsigned char*)dst_bits, 4 * width, pY, pU, pV, y_pitch, y_pitch, width, dst_yuv);
1606 64 : }
1607 64 : static void load_line_yv12_10(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, Bool dst_yuv)
1608 : {
1609 : u8 *pY;
1610 : pY = (u8 *)src_bits;
1611 64 : if (!pU) {
1612 64 : pU = (u8 *)src_bits + y_pitch*height;
1613 64 : pV = (u8 *)src_bits + 5*y_pitch*height/4;
1614 : }
1615 :
1616 64 : pY += x_offset + y_offset*y_pitch;
1617 64 : pU += x_offset/2 + y_offset*y_pitch/4;
1618 64 : pV += x_offset/2 + y_offset*y_pitch/4;
1619 64 : yuv_10_load_lines_planar((unsigned char*)dst_bits, 4*width, pY, pU, pV, y_pitch, y_pitch/2, width, dst_yuv);
1620 64 : }
1621 64 : static void load_line_yuv422_10(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, Bool dst_yuv)
1622 : {
1623 : u8 *pY;
1624 : u16 *src_y, *src_u, *src_v;
1625 : pY = (u8 *)src_bits;
1626 64 : if (!pU) {
1627 64 : pU = (u8 *)src_bits + y_pitch*height;
1628 64 : pV = (u8 *)src_bits + 3 * y_pitch*height / 2;
1629 : }
1630 64 : src_y = (u16 *)pY + x_offset;
1631 64 : src_u = (u16 *)pU + x_offset / 2;
1632 : src_v = (u16 *)pV + x_offset / 2;
1633 :
1634 :
1635 64 : pY = (u8 *)src_y + y_offset*y_pitch;
1636 64 : pU = (u8 *)src_u + y_offset*y_pitch / 2;
1637 64 : pV = (u8 *)src_v + y_offset*y_pitch / 2;
1638 64 : yuv422_10_load_lines_planar((unsigned char*)dst_bits, 4 * width, pY, pU, pV, y_pitch, y_pitch / 2, width, dst_yuv);
1639 64 : }
1640 64 : static void load_line_yuv444_10(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, Bool dst_yuv)
1641 : {
1642 : u8 *pY;
1643 : u16 *src_y, *src_u, *src_v;
1644 : pY = (u8 *)src_bits;
1645 64 : if (!pU) {
1646 64 : pU = (u8 *)src_bits + y_pitch*height;
1647 64 : pV = (u8 *)src_bits + 2 * y_pitch*height;
1648 : }
1649 64 : src_y = (u16 *)pY + x_offset;
1650 : src_u = (u16 *)pU + x_offset;
1651 : src_v = (u16 *)pV + x_offset;
1652 :
1653 :
1654 64 : pY = (u8 *)src_y + y_offset*y_pitch;
1655 64 : pU = (u8 *)src_u + y_offset*y_pitch;
1656 64 : pV = (u8 *)src_v + y_offset*y_pitch;
1657 64 : yuv444_10_load_lines_planar((unsigned char*)dst_bits, 4 * width, pY, pU, pV, y_pitch, y_pitch, width, dst_yuv);
1658 64 : }
1659 0 : static void load_line_yuva(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, u8 *pV, u8 *pA, Bool dst_yuv)
1660 : {
1661 : u8 *pY;
1662 : pY = (u8*)src_bits;
1663 0 : if (!pU) {
1664 0 : pU = (u8*)src_bits + y_pitch*height;
1665 0 : pV = (u8*)src_bits + 5*y_pitch*height/4;
1666 0 : pA = (u8*)src_bits + 3*y_pitch*height/2;
1667 : }
1668 :
1669 0 : pY += x_offset + y_offset*y_pitch;
1670 0 : pU += x_offset/2 + y_offset*y_pitch/4;
1671 0 : pV += x_offset/2 + y_offset*y_pitch/4;
1672 0 : pA += x_offset + y_offset*y_pitch;
1673 0 : yuva_load_lines(dst_bits, 4*width, pY, pU, pV, pA, y_pitch, y_pitch/2, width, dst_yuv);
1674 0 : }
1675 :
1676 128 : static void load_line_yuyv(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1677 : {
1678 : u8 *pY, *pU, *pV;
1679 128 : pY = (u8 *)src_bits + x_offset + y_offset*y_pitch;
1680 128 : pU = (u8 *)pY + 1;
1681 128 : pV = (u8 *)pY + 3;
1682 128 : yuv_load_lines_packed((unsigned char*)dst_bits, 4*width, pY, pU, pV, width, dst_yuv);
1683 128 : }
1684 128 : static void load_line_uyvy(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1685 : {
1686 : u8 *pY, *pU, *pV;
1687 128 : pU = (u8 *)src_bits + x_offset + y_offset*y_pitch;
1688 128 : pY = (u8 *)pU + 1;
1689 128 : pV = (u8 *)pU + 2;
1690 128 : yuv_load_lines_packed((unsigned char*)dst_bits, 4*width, pY, pU, pV, width, dst_yuv);
1691 128 : }
1692 128 : static void load_line_yvyu(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1693 : {
1694 : u8 *pY, *pU, *pV;
1695 128 : pY = (u8 *)src_bits + x_offset + y_offset*y_pitch;
1696 128 : pV = (u8 *)pY + 1;
1697 128 : pU = (u8 *)pY + 3;
1698 128 : yuv_load_lines_packed((unsigned char*)dst_bits, 4*width, pY, pU, pV, width, dst_yuv);
1699 128 : }
1700 128 : static void load_line_vyuy(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, Bool dst_yuv)
1701 : {
1702 : u8 *pY, *pU, *pV;
1703 128 : pV = (u8 *)src_bits + x_offset + y_offset*y_pitch;
1704 128 : pY = (u8 *)pV + 1;
1705 128 : pU = (u8 *)pV + 2;
1706 128 : yuv_load_lines_packed((unsigned char*)dst_bits, 4*width, pY, pU, pV, width, dst_yuv);
1707 128 : }
1708 :
1709 :
1710 128 : static void gf_yuv_load_lines_nv12_nv21(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char *v_src, s32 y_stride, s32 width, Bool dst_yuv)
1711 : {
1712 : u32 hw, x;
1713 128 : unsigned char *dst2 = (unsigned char *) dst + dststride;
1714 128 : unsigned char *y_src2 = (unsigned char *) y_src + y_stride;
1715 :
1716 128 : hw = width / 2;
1717 128 : if (dst_yuv) {
1718 0 : for (x = 0; x < hw; x++) {
1719 :
1720 0 : dst[0] = dst[4] = dst2[0] = dst2[4] = v_src[2*x];
1721 0 : dst[1] = dst[5] = dst2[1] = dst2[5] = u_src[2*x];
1722 0 : dst[2] = *y_src;
1723 : y_src++;
1724 0 : dst[3] = 0xFF;
1725 :
1726 0 : dst[6] = *y_src;
1727 0 : y_src++;
1728 0 : dst[7] = 0xFF;
1729 :
1730 0 : dst2[2] = *y_src2;
1731 : y_src2++;
1732 0 : dst2[3] = 0xFF;
1733 :
1734 0 : dst2[6] = *y_src2;
1735 0 : y_src2++;
1736 0 : dst2[7] = 0xFF;
1737 :
1738 0 : dst += 8;
1739 0 : dst2 += 8;
1740 : }
1741 : return;
1742 : }
1743 8192 : for (x = 0; x < hw; x++) {
1744 : s32 u, v;
1745 : s32 b_u, g_uv, r_v, rgb_y;
1746 :
1747 8192 : u = u_src[2*x];
1748 8192 : v = v_src[2*x];
1749 :
1750 8192 : b_u = B_U[u];
1751 8192 : g_uv = G_U[u] + G_V[v];
1752 8192 : r_v = R_V[v];
1753 :
1754 8192 : rgb_y = RGB_Y[*y_src];
1755 8192 : dst[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
1756 8192 : dst[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
1757 8192 : dst[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
1758 8192 : dst[3] = 0xFF;
1759 : y_src++;
1760 :
1761 8192 : rgb_y = RGB_Y[*y_src];
1762 8192 : dst[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
1763 8192 : dst[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
1764 8192 : dst[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
1765 8192 : dst[7] = 0xFF;
1766 8192 : y_src++;
1767 :
1768 8192 : rgb_y = RGB_Y[*y_src2];
1769 8192 : dst2[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
1770 8192 : dst2[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
1771 8192 : dst2[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
1772 8192 : dst2[3] = 0xFF;
1773 : y_src2++;
1774 :
1775 8192 : rgb_y = RGB_Y[*y_src2];
1776 8192 : dst2[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT);
1777 8192 : dst2[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT);
1778 8192 : dst2[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT);
1779 8192 : dst2[7] = 0xFF;
1780 8192 : y_src2++;
1781 :
1782 8192 : dst += 8;
1783 8192 : dst2 += 8;
1784 : }
1785 : }
1786 :
1787 64 : static void load_line_nv12(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, Bool dst_yuv)
1788 : {
1789 : u8 *pY = (u8*)src_bits;
1790 64 : if (!pU) {
1791 64 : pU = (u8*)src_bits + y_pitch*height;
1792 : }
1793 :
1794 64 : pY += x_offset + y_offset*y_pitch;
1795 64 : pU += x_offset + y_offset*y_pitch/2; //half vertical sampling
1796 64 : gf_yuv_load_lines_nv12_nv21(dst_bits, 4*width, pY, pU, pU + 1, y_pitch, width, dst_yuv);
1797 64 : }
1798 64 : static void load_line_nv21(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits, u8 *pU, Bool dst_yuv)
1799 : {
1800 : u8 *pY = (u8*)src_bits;
1801 64 : if (!pU) {
1802 64 : pU = (u8*)src_bits + y_pitch*height;
1803 : }
1804 :
1805 64 : pY += x_offset + y_offset*y_pitch;
1806 64 : pU += x_offset + y_offset*y_pitch/2; //half vertical sampling
1807 64 : gf_yuv_load_lines_nv12_nv21(dst_bits, 4*width, pY, pU+1, pU, y_pitch, width, dst_yuv);
1808 64 : }
1809 :
1810 : //#define COLORKEY_MPEG4_STRICT
1811 :
1812 23219 : static Bool format_is_yuv(u32 in_pf)
1813 : {
1814 23219 : switch (in_pf) {
1815 : case GF_PIXEL_YUYV:
1816 : case GF_PIXEL_YVYU:
1817 : case GF_PIXEL_UYVY:
1818 : case GF_PIXEL_VYUY:
1819 : case GF_PIXEL_YUV:
1820 : case GF_PIXEL_YVU:
1821 : case GF_PIXEL_YUV_10:
1822 : case GF_PIXEL_YUV422:
1823 : case GF_PIXEL_YUV422_10:
1824 : case GF_PIXEL_YUV444:
1825 : case GF_PIXEL_YUV444_10:
1826 : return GF_TRUE;
1827 : /*not supported yet*/
1828 23128 : case GF_PIXEL_YUVA:
1829 : default:
1830 23128 : return GF_FALSE;
1831 : }
1832 : }
1833 :
1834 : GF_EXPORT
1835 23712 : GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *dst_wnd, GF_Window *src_wnd, u8 alpha, Bool flip, GF_ColorKey *key, GF_ColorMatrix *cmat)
1836 : {
1837 : u8 *tmp, *rows;
1838 : u8 ka=0, kr=0, kg=0, kb=0, kl=0, kh=0;
1839 : s32 src_row;
1840 : u32 i, yuv_planar_type = 0;
1841 : Bool no_memcpy, dst_yuv = GF_FALSE;
1842 : Bool force_load_odd_yuv_lines = GF_FALSE;
1843 : Bool yuv_init = GF_FALSE;
1844 23712 : Bool has_alpha = (alpha!=0xFF) ? GF_TRUE : GF_FALSE;
1845 : u32 dst_bpp, dst_w_size;
1846 : s32 pos_y, inc_y, inc_x, prev_row, x_off;
1847 : u32 src_w, src_h, dst_w, dst_h;
1848 : u8 *dst_bits = NULL, *dst_bits_prev = NULL, *dst_temp_bits = NULL;
1849 23712 : s32 dst_x_pitch = dst->pitch_x;
1850 : copy_row_proto copy_row = NULL;
1851 : load_line_proto load_line = NULL;
1852 :
1853 23712 : if (cmat && (cmat->m[15] || cmat->m[16] || cmat->m[17] || (cmat->m[18]!=FIX_ONE) || cmat->m[19] )) has_alpha = GF_TRUE;
1854 23566 : else if (key && (key->alpha<0xFF)) has_alpha = GF_TRUE;
1855 :
1856 : //check if we have a dedicated copy/conv when no stretch nor blending (avoids line load while copying)
1857 23712 : if ((alpha==0xFF) && !flip && !key && !cmat) {
1858 : Bool no_stretch = GF_FALSE;
1859 23219 : Bool output_yuv = format_is_yuv(dst->pixel_format);
1860 : GF_Err e = GF_NOT_SUPPORTED;
1861 :
1862 23219 : if (!dst_wnd) no_stretch = GF_TRUE;
1863 23219 : else if (src_wnd) {
1864 23219 : if (!dst_wnd->x && !dst_wnd->y && (dst_wnd->w==src_wnd->w) && (dst_wnd->h==src_wnd->h))
1865 : no_stretch = GF_TRUE;
1866 : } else {
1867 0 : if ((dst_wnd->w==src->width) && (dst_wnd->h==src->height))
1868 : no_stretch = GF_TRUE;
1869 : }
1870 23219 : if (no_stretch && output_yuv) {
1871 : //check YUV10->8, YUV->YUV
1872 44 : switch (src->pixel_format) {
1873 3 : case GF_PIXEL_NV12_10:
1874 3 : e = color_write_nv12_10_to_yuv(dst, src, src_wnd, GF_FALSE);
1875 3 : break;
1876 3 : case GF_PIXEL_NV21_10:
1877 3 : e = color_write_nv12_10_to_yuv(dst, src, src_wnd, GF_TRUE);
1878 3 : break;
1879 3 : case GF_PIXEL_YUV_10:
1880 3 : e = color_write_yv12_10_to_yuv(dst, src, src_wnd, GF_FALSE);
1881 3 : break;
1882 3 : case GF_PIXEL_YUV422_10:
1883 3 : if (dst->pixel_format == GF_PIXEL_YUV422)
1884 1 : e = color_write_yuv422_10_to_yuv422(dst, src, src_wnd, GF_FALSE);
1885 2 : else if (dst->pixel_format == GF_PIXEL_YUV)
1886 1 : e = color_write_yuv422_10_to_yuv(dst, src, src_wnd, GF_FALSE);
1887 1 : else if (dst->pixel_format == GF_PIXEL_YVU)
1888 0 : e = color_write_yuv422_10_to_yuv(dst, src, src_wnd, GF_TRUE);
1889 : break;
1890 3 : case GF_PIXEL_YUV444_10:
1891 3 : if (dst->pixel_format == GF_PIXEL_YUV444)
1892 1 : e = color_write_yuv444_10_to_yuv444(dst, src, src_wnd, GF_FALSE);
1893 2 : else if (dst->pixel_format == GF_PIXEL_YUV)
1894 1 : e = color_write_yuv444_10_to_yuv(dst, src, src_wnd, GF_FALSE);
1895 1 : else if (dst->pixel_format == GF_PIXEL_YVU)
1896 0 : e = color_write_yuv444_10_to_yuv(dst, src, src_wnd, GF_TRUE);
1897 : break;
1898 1 : case GF_PIXEL_YUV:
1899 1 : e = color_write_yuv420_to_yuv(dst, src, src_wnd, GF_FALSE);
1900 1 : break;
1901 0 : case GF_PIXEL_YVU:
1902 0 : e = color_write_yuv420_to_yuv(dst, src, src_wnd, GF_TRUE);
1903 0 : break;
1904 1 : case GF_PIXEL_YUV422:
1905 1 : e = color_write_yuv422_to_yuv(dst, src, src_wnd, GF_FALSE);
1906 1 : break;
1907 1 : case GF_PIXEL_YUV444:
1908 1 : e = color_write_yuv444_to_yuv(dst, src, src_wnd, GF_FALSE);
1909 1 : break;
1910 4 : case GF_PIXEL_YUYV:
1911 : case GF_PIXEL_YVYU:
1912 : case GF_PIXEL_UYVY:
1913 : case GF_PIXEL_VYUY:
1914 4 : e = color_write_yvyu_to_yuv(dst, src, src_wnd, GF_FALSE);
1915 4 : break;
1916 : }
1917 : }
1918 23175 : else if (no_stretch && !output_yuv) {
1919 : //check rgb->rgb copy
1920 103 : switch (dst->pixel_format) {
1921 69 : case GF_PIXEL_RGB:
1922 : case GF_PIXEL_RGBS:
1923 : case GF_PIXEL_BGR:
1924 69 : e = color_write_rgb_to_24(dst, src, src_wnd);
1925 69 : break;
1926 8 : case GF_PIXEL_RGBX:
1927 : case GF_PIXEL_XRGB:
1928 : case GF_PIXEL_RGBD:
1929 : case GF_PIXEL_RGBDS:
1930 : case GF_PIXEL_BGRX:
1931 : case GF_PIXEL_XBGR:
1932 8 : e = color_write_rgb_to_32(dst, src, src_wnd);
1933 8 : break;
1934 : default:
1935 : break;
1936 : }
1937 23072 : }
1938 97 : if (e == GF_OK) return GF_OK;
1939 : }
1940 :
1941 :
1942 23686 : switch (src->pixel_format) {
1943 : case GF_PIXEL_GREYSCALE:
1944 : load_line = load_line_grey;
1945 : break;
1946 1 : case GF_PIXEL_ALPHAGREY:
1947 : load_line = load_line_alpha_grey;
1948 : has_alpha = GF_TRUE;
1949 1 : break;
1950 1 : case GF_PIXEL_GREYALPHA:
1951 : load_line = load_line_grey_alpha;
1952 : has_alpha = GF_TRUE;
1953 1 : break;
1954 1 : case GF_PIXEL_RGB_555:
1955 : load_line = load_line_rgb_555;
1956 1 : break;
1957 1 : case GF_PIXEL_RGB_565:
1958 : load_line = load_line_rgb_565;
1959 1 : break;
1960 19637 : case GF_PIXEL_RGB:
1961 : case GF_PIXEL_RGBS:
1962 : load_line = load_line_rgb_24;
1963 19637 : break;
1964 1 : case GF_PIXEL_BGR:
1965 : load_line = load_line_bgr_24;
1966 1 : break;
1967 464 : case GF_PIXEL_ARGB:
1968 : has_alpha = GF_TRUE;
1969 : load_line = load_line_argb;
1970 464 : break;
1971 1 : case GF_PIXEL_BGRA:
1972 : has_alpha = GF_TRUE;
1973 : load_line = load_line_bgra;
1974 1 : break;
1975 160 : case GF_PIXEL_RGBA:
1976 : case GF_PIXEL_RGBAS:
1977 : has_alpha = GF_TRUE;
1978 : case GF_PIXEL_RGBX:
1979 : load_line = load_line_rgb_32;
1980 : break;
1981 1 : case GF_PIXEL_XRGB:
1982 : load_line = load_line_xrgb;
1983 1 : break;
1984 1 : case GF_PIXEL_BGRX:
1985 : load_line = load_line_bgrx;
1986 1 : break;
1987 0 : case GF_PIXEL_RGBDS:
1988 : load_line = load_line_rgbds;
1989 : has_alpha = GF_TRUE;
1990 0 : break;
1991 0 : case GF_PIXEL_RGBD:
1992 : load_line = load_line_rgbd;
1993 0 : break;
1994 3396 : case GF_PIXEL_YUV:
1995 : case GF_PIXEL_YVU:
1996 3396 : yuv2rgb_init();
1997 : yuv_planar_type = 1;
1998 3396 : break;
1999 1 : case GF_PIXEL_YUV422:
2000 1 : yuv2rgb_init();
2001 : yuv_planar_type = 4;
2002 1 : break;
2003 1 : case GF_PIXEL_YUV444:
2004 1 : yuv2rgb_init();
2005 : yuv_planar_type = 5;
2006 1 : break;
2007 :
2008 1 : case GF_PIXEL_YUV_10:
2009 1 : yuv2rgb_init();
2010 : yuv_planar_type = 3;
2011 1 : break;
2012 2 : case GF_PIXEL_YUV422_10:
2013 2 : yuv2rgb_init();
2014 : yuv_planar_type = 6;
2015 2 : break;
2016 2 : case GF_PIXEL_YUV444_10:
2017 2 : yuv2rgb_init();
2018 : yuv_planar_type = 7;
2019 2 : break;
2020 2 : case GF_PIXEL_NV21:
2021 2 : yuv2rgb_init();
2022 : yuv_planar_type = 8;
2023 2 : break;
2024 2 : case GF_PIXEL_NV12:
2025 2 : yuv2rgb_init();
2026 : yuv_planar_type = 9;
2027 2 : break;
2028 0 : case GF_PIXEL_YUVA:
2029 : has_alpha = GF_TRUE;
2030 0 : case GF_PIXEL_YUVD:
2031 : yuv_planar_type = 2;
2032 0 : yuv2rgb_init();
2033 0 : break;
2034 1 : case GF_PIXEL_YUYV:
2035 : yuv_planar_type = 0;
2036 1 : yuv2rgb_init();
2037 : load_line = load_line_yuyv;
2038 1 : break;
2039 1 : case GF_PIXEL_UYVY:
2040 : yuv_planar_type = 0;
2041 1 : yuv2rgb_init();
2042 : load_line = load_line_uyvy;
2043 1 : break;
2044 1 : case GF_PIXEL_YVYU:
2045 : yuv_planar_type = 0;
2046 1 : yuv2rgb_init();
2047 : load_line = load_line_yvyu;
2048 1 : break;
2049 1 : case GF_PIXEL_VYUY:
2050 : yuv_planar_type = 0;
2051 1 : yuv2rgb_init();
2052 : load_line = load_line_vyuy;
2053 1 : break;
2054 4 : default:
2055 4 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Source pixel format %s not supported by gf_stretch_bits\n", gf_pixel_fmt_name(src->pixel_format) ));
2056 : return GF_NOT_SUPPORTED;
2057 : }
2058 :
2059 : /*only RGB output supported*/
2060 23682 : switch (dst->pixel_format) {
2061 4 : case GF_PIXEL_RGB_555:
2062 : dst_bpp = sizeof(unsigned char)*2;
2063 4 : copy_row = has_alpha ? merge_row_rgb_555 : copy_row_rgb_555;
2064 : break;
2065 4 : case GF_PIXEL_RGB_565:
2066 : dst_bpp = sizeof(unsigned char)*2;
2067 4 : copy_row = has_alpha ? merge_row_rgb_565 : copy_row_rgb_565;
2068 : break;
2069 23518 : case GF_PIXEL_RGB:
2070 : dst_bpp = sizeof(unsigned char)*3;
2071 23518 : copy_row = has_alpha ? merge_row_rgb_24 : copy_row_rgb_24;
2072 : break;
2073 28 : case GF_PIXEL_BGR:
2074 : dst_bpp = sizeof(unsigned char)*3;
2075 28 : copy_row = has_alpha ? merge_row_bgr_24 : copy_row_bgr_24;
2076 : break;
2077 3 : case GF_PIXEL_RGBX:
2078 : dst_bpp = sizeof(unsigned char)*4;
2079 3 : copy_row = has_alpha ? merge_row_bgrx : copy_row_bgrx;
2080 : break;
2081 4 : case GF_PIXEL_ARGB:
2082 : dst_bpp = sizeof(unsigned char)*4;
2083 4 : copy_row = has_alpha ? merge_row_argb : copy_row_argb;
2084 : break;
2085 4 : case GF_PIXEL_BGRA:
2086 : dst_bpp = sizeof(unsigned char)*4;
2087 4 : copy_row = has_alpha ? merge_row_bgra : copy_row_bgrx;
2088 : break;
2089 0 : case GF_PIXEL_RGBD:
2090 : dst_bpp = sizeof(unsigned char)*4;
2091 0 : copy_row = has_alpha ? merge_row_bgrx : copy_row_rgbd;
2092 : break;
2093 5 : case GF_PIXEL_RGBA:
2094 : dst_bpp = sizeof(unsigned char)*4;
2095 5 : copy_row = has_alpha ? merge_row_rgba : copy_row_rgbx;
2096 : break;
2097 3 : case GF_PIXEL_BGRX:
2098 : dst_bpp = sizeof(unsigned char)*4;
2099 3 : copy_row = has_alpha ? merge_row_rgbx : copy_row_rgbx;
2100 : break;
2101 : #if 0
2102 : //yuv dest not yet supported
2103 : case GF_PIXEL_YUV444:
2104 : dst_bpp = sizeof(unsigned char)*3;
2105 : copy_row = has_alpha ? merge_row_yuv444 : copy_row_yuv444;
2106 : dst_yuv = GF_TRUE;
2107 : break;
2108 : #endif
2109 109 : default:
2110 109 : GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Destination pixel format %s not supported by gf_stretch_bits, patch welcome\n", gf_pixel_fmt_name(dst->pixel_format) ));
2111 : return GF_NOT_SUPPORTED;
2112 : }
2113 : /*x_pitch 0 means linear framebuffer*/
2114 23573 : if (!dst_x_pitch) dst_x_pitch = dst_bpp;
2115 :
2116 :
2117 23573 : src_w = src_wnd ? src_wnd->w : src->width;
2118 23573 : src_h = src_wnd ? src_wnd->h : src->height;
2119 23573 : dst_w = dst_wnd ? dst_wnd->w : dst->width;
2120 23573 : dst_h = dst_wnd ? dst_wnd->h : dst->height;
2121 :
2122 23573 : if (!src_w || !src_h || !dst_w || !dst_h)
2123 : return GF_OK;
2124 :
2125 23563 : if (yuv_planar_type && (src_w%2)) src_w++;
2126 :
2127 23563 : tmp = (u8 *) gf_malloc(sizeof(u8) * src_w * (yuv_planar_type ? 8 : 4) );
2128 : rows = tmp;
2129 :
2130 23563 : if ( (src_h / dst_h) * dst_h != src_h) force_load_odd_yuv_lines = GF_TRUE;
2131 :
2132 : pos_y = 0x10000;
2133 23563 : inc_y = (src_h << 16) / dst_h;
2134 23563 : inc_x = (src_w << 16) / dst_w;
2135 23563 : x_off = src_wnd ? src_wnd->x : 0;
2136 23563 : src_row = src_wnd ? src_wnd->y : 0;
2137 :
2138 : prev_row = -1;
2139 :
2140 23563 : dst_bits = (u8 *) dst->video_buffer;
2141 23563 : if (dst_wnd) dst_bits += ((s32)dst_wnd->x) * dst_x_pitch + ((s32)dst_wnd->y) * dst->pitch_y;
2142 :
2143 23563 : dst_w_size = dst_bpp*dst_w;
2144 :
2145 23563 : if (key) {
2146 121 : ka = key->alpha;
2147 121 : kr = key->r;
2148 121 : kg = key->g;
2149 121 : kb = key->b;
2150 121 : kl = key->low;
2151 121 : kh = key->high;
2152 121 : if (kh==kl) kh++;
2153 : }
2154 :
2155 : /*do NOT use memcpy if the target buffer is not in systems memory*/
2156 23563 : no_memcpy = (has_alpha || dst->is_hardware_memory || (dst_bpp!=dst_x_pitch)) ? GF_TRUE : GF_FALSE;
2157 :
2158 1516318 : while (dst_h) {
2159 2311022 : while ( pos_y >= 0x10000L ) {
2160 841830 : src_row++;
2161 841830 : pos_y -= 0x10000L;
2162 : }
2163 : /*new row, check if conversion is needed*/
2164 1469192 : if (prev_row != src_row) {
2165 442828 : u32 the_row = src_row - 1;
2166 442828 : if (yuv_planar_type) {
2167 259445 : if (the_row % 2) {
2168 123703 : if (!yuv_init || force_load_odd_yuv_lines) {
2169 : yuv_init = GF_TRUE;
2170 120887 : the_row--;
2171 120887 : if (flip) the_row = src->height - 2 - the_row;
2172 120887 : if (yuv_planar_type == 1) {
2173 120887 : load_line_yv12(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2174 : }
2175 0 : else if (yuv_planar_type == 4) {
2176 0 : load_line_yuv422(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2177 : }
2178 0 : else if (yuv_planar_type == 5) {
2179 0 : load_line_yuv444(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2180 : }
2181 0 : else if (yuv_planar_type == 3) {
2182 0 : load_line_yv12_10((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2183 : }
2184 0 : else if (yuv_planar_type == 6) {
2185 0 : load_line_yuv422_10((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2186 : }
2187 0 : else if (yuv_planar_type == 7) {
2188 0 : load_line_yuv444_10((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2189 : }
2190 0 : else if (yuv_planar_type == 8) {
2191 0 : load_line_nv21((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, dst_yuv);
2192 : }
2193 0 : else if (yuv_planar_type == 9) {
2194 0 : load_line_nv12((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, dst_yuv);
2195 : }
2196 : else {
2197 0 : load_line_yuva(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, (u8 *)src->a_ptr, dst_yuv);
2198 : }
2199 :
2200 120887 : if (cmat) {
2201 0 : for (i=0; i<2*src_w; i++) {
2202 0 : u32 idx = 4*i;
2203 0 : gf_cmx_apply_argb(cmat, (u8 *) &tmp[idx+3], (u8 *) &tmp[idx], (u8 *) &tmp[idx+1], (u8 *) &tmp[idx+2]);
2204 : }
2205 : }
2206 120887 : if (key) {
2207 1393920 : for (i=0; i<2*src_w; i++) {
2208 1393920 : u32 idx = 4*i;
2209 : s32 thres, v;
2210 1393920 : v = tmp[idx]-kr;
2211 1393920 : thres = ABS(v);
2212 1393920 : v = tmp[idx+1]-kg;
2213 1393920 : thres += ABS(v);
2214 1393920 : v = tmp[idx+2]-kb;
2215 1393920 : thres += ABS(v);
2216 1393920 : thres/=3;
2217 : #ifdef COLORKEY_MPEG4_STRICT
2218 : if (thres < kl) tmp[idx+3] = 0;
2219 : else if (thres <= kh) tmp[idx+3] = (thres-kl)*ka / (kh-kl);
2220 : #else
2221 1393920 : if (thres < kh) tmp[idx+3] = 0;
2222 : #endif
2223 63161 : else tmp[idx+3] = ka;
2224 : }
2225 : }
2226 : }
2227 123703 : rows = flip ? tmp : tmp + src_w * 4;
2228 : }
2229 : else {
2230 135742 : if (flip) the_row = src->height - 2 - the_row;
2231 135742 : if (yuv_planar_type == 1) {
2232 135294 : load_line_yv12(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2233 : }
2234 448 : else if (yuv_planar_type == 4) {
2235 64 : load_line_yuv422(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2236 : }
2237 384 : else if (yuv_planar_type == 5) {
2238 64 : load_line_yuv444(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2239 : }
2240 320 : else if (yuv_planar_type == 3) {
2241 64 : load_line_yv12_10((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2242 : }
2243 256 : else if (yuv_planar_type == 6) {
2244 64 : load_line_yuv422_10((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2245 : }
2246 192 : else if (yuv_planar_type == 7) {
2247 64 : load_line_yuv444_10((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, dst_yuv);
2248 : }
2249 128 : else if (yuv_planar_type == 8) {
2250 64 : load_line_nv21((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, dst_yuv);
2251 : }
2252 64 : else if (yuv_planar_type == 9) {
2253 64 : load_line_nv12((char *)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, dst_yuv);
2254 : }
2255 : else {
2256 0 : load_line_yuva(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, (u8 *)src->u_ptr, (u8 *)src->v_ptr, (u8 *)src->a_ptr, dst_yuv);
2257 : }
2258 : yuv_init = GF_TRUE;
2259 135742 : rows = flip ? tmp + src_w * 4 : tmp;
2260 :
2261 135742 : if (cmat) {
2262 0 : for (i=0; i<2*src_w; i++) {
2263 0 : u32 idx = 4*i;
2264 0 : gf_cmx_apply_argb(cmat, &tmp[idx+3], &tmp[idx], &tmp[idx+1], &tmp[idx+2]);
2265 : }
2266 : }
2267 135742 : if (key) {
2268 1393920 : for (i=0; i<2*src_w; i++) {
2269 1393920 : u32 idx = 4*i;
2270 : s32 thres, v;
2271 1393920 : v = tmp[idx]-kr;
2272 1393920 : thres = ABS(v);
2273 1393920 : v = tmp[idx+1]-kg;
2274 1393920 : thres += ABS(v);
2275 1393920 : v = tmp[idx+2]-kb;
2276 1393920 : thres += ABS(v);
2277 1393920 : thres/=3;
2278 : #ifdef COLORKEY_MPEG4_STRICT
2279 : if (thres < kl) tmp[idx+3] = 0;
2280 : else if (thres <= kh) tmp[idx+3] = (thres-kl)*ka / (kh-kl);
2281 : #else
2282 1393920 : if (thres < kh) tmp[idx+3] = 0;
2283 : #endif
2284 63161 : else tmp[idx+3] = ka;
2285 : }
2286 : }
2287 : }
2288 : } else {
2289 183383 : if (flip) the_row = src->height-1 - the_row;
2290 183383 : load_line((u8*)src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp, dst_yuv);
2291 : rows = tmp;
2292 183383 : if (cmat) {
2293 2249600 : for (i=0; i<src_w; i++) {
2294 2249600 : u32 idx = 4*i;
2295 2249600 : gf_cmx_apply_argb(cmat, &tmp[idx+3], &tmp[idx], &tmp[idx+1], &tmp[idx+2]);
2296 : }
2297 : }
2298 183383 : if (key) {
2299 0 : for (i=0; i<src_w; i++) {
2300 0 : u32 idx = 4*i;
2301 : s32 thres, v;
2302 0 : v = tmp[idx]-kr;
2303 0 : thres = ABS(v);
2304 0 : v = tmp[idx+1]-kg;
2305 0 : thres += ABS(v);
2306 0 : v = tmp[idx+2]-kb;
2307 0 : thres += ABS(v);
2308 0 : thres/=3;
2309 : #ifdef COLORKEY_MPEG4_STRICT
2310 : if (thres < kl) tmp[idx+3] = 0;
2311 : else if (thres <= kh) tmp[idx+3] = (thres-kl)*ka / (kh-kl);
2312 : #else
2313 0 : if (thres < kh) tmp[idx+3] = 0;
2314 : #endif
2315 0 : else tmp[idx+3] = ka;
2316 : }
2317 : }
2318 : }
2319 442828 : copy_row(rows, src_w, dst_bits, dst_w, inc_x, dst_x_pitch, alpha, dst->pitch_y, dst->height);
2320 : }
2321 : /*do NOT use memcpy if the target buffer is not in systems memory*/
2322 1026364 : else if (no_memcpy) {
2323 0 : copy_row(rows, src_w, dst_bits, dst_w, inc_x, dst_x_pitch, alpha, dst->pitch_y, dst->height);
2324 1026364 : } else if (dst_bits && dst_bits_prev) {
2325 1026364 : memcpy(dst_bits, dst_bits_prev, dst_w_size);
2326 : }
2327 :
2328 1469192 : pos_y += inc_y;
2329 : prev_row = src_row;
2330 :
2331 : dst_bits_prev = dst_bits;
2332 1469192 : dst_bits += dst->pitch_y;
2333 1469192 : dst_h--;
2334 : }
2335 : if (dst_temp_bits) gf_free(dst_temp_bits);
2336 23563 : gf_free(tmp);
2337 23563 : return GF_OK;
2338 : }
2339 :
2340 : #endif // GPAC_DISABLE_PLAYER
2341 :
2342 :
2343 : /*
2344 : COLOR MATRIX TOOLS
2345 : */
2346 :
2347 : GF_EXPORT
2348 109082 : void gf_cmx_init(GF_ColorMatrix *_this)
2349 : {
2350 109082 : if (!_this) return;
2351 109082 : memset(_this->m, 0, sizeof(Fixed)*20);
2352 109082 : _this->m[0] = _this->m[6] = _this->m[12] = _this->m[18] = FIX_ONE;
2353 109082 : _this->identity = 1;
2354 : }
2355 :
2356 :
2357 82732 : static void gf_cmx_identity(GF_ColorMatrix *_this)
2358 : {
2359 : GF_ColorMatrix mat;
2360 82732 : gf_cmx_init(&mat);
2361 82732 : _this->identity = memcmp(_this->m, mat.m, sizeof(Fixed)*20) ? 0 : 1;
2362 82732 : }
2363 :
2364 : GF_EXPORT
2365 1048 : void gf_cmx_set(GF_ColorMatrix *_this,
2366 : Fixed c1, Fixed c2, Fixed c3, Fixed c4, Fixed c5,
2367 : Fixed c6, Fixed c7, Fixed c8, Fixed c9, Fixed c10,
2368 : Fixed c11, Fixed c12, Fixed c13, Fixed c14, Fixed c15,
2369 : Fixed c16, Fixed c17, Fixed c18, Fixed c19, Fixed c20)
2370 : {
2371 1048 : if (!_this) return;
2372 1048 : _this->m[0] = c1;
2373 1048 : _this->m[1] = c2;
2374 1048 : _this->m[2] = c3;
2375 1048 : _this->m[3] = c4;
2376 1048 : _this->m[4] = c5;
2377 1048 : _this->m[5] = c6;
2378 1048 : _this->m[6] = c7;
2379 1048 : _this->m[7] = c8;
2380 1048 : _this->m[8] = c9;
2381 1048 : _this->m[9] = c10;
2382 1048 : _this->m[10] = c11;
2383 1048 : _this->m[11] = c12;
2384 1048 : _this->m[12] = c13;
2385 1048 : _this->m[13] = c14;
2386 1048 : _this->m[14] = c15;
2387 1048 : _this->m[15] = c16;
2388 1048 : _this->m[16] = c17;
2389 1048 : _this->m[17] = c18;
2390 1048 : _this->m[18] = c19;
2391 1048 : _this->m[19] = c20;
2392 1048 : gf_cmx_identity(_this);
2393 : }
2394 :
2395 : GF_EXPORT
2396 81681 : void gf_cmx_copy(GF_ColorMatrix *_this, GF_ColorMatrix *from)
2397 : {
2398 81681 : if (!_this || !from) return;
2399 81681 : memcpy(_this->m, from->m, sizeof(Fixed)*20);
2400 81681 : gf_cmx_identity(_this);
2401 : }
2402 :
2403 :
2404 : GF_EXPORT
2405 24061 : void gf_cmx_multiply(GF_ColorMatrix *_this, GF_ColorMatrix *w)
2406 : {
2407 : Fixed res[20];
2408 48119 : if (!_this || !w || w->identity) return;
2409 24061 : if (_this->identity) {
2410 24058 : gf_cmx_copy(_this, w);
2411 24058 : return;
2412 : }
2413 :
2414 3 : res[0] = gf_mulfix(_this->m[0], w->m[0]) + gf_mulfix(_this->m[1], w->m[5]) + gf_mulfix(_this->m[2], w->m[10]) + gf_mulfix(_this->m[3], w->m[15]);
2415 3 : res[1] = gf_mulfix(_this->m[0], w->m[1]) + gf_mulfix(_this->m[1], w->m[6]) + gf_mulfix(_this->m[2], w->m[11]) + gf_mulfix(_this->m[3], w->m[16]);
2416 3 : res[2] = gf_mulfix(_this->m[0], w->m[2]) + gf_mulfix(_this->m[1], w->m[7]) + gf_mulfix(_this->m[2], w->m[12]) + gf_mulfix(_this->m[3], w->m[17]);
2417 3 : res[3] = gf_mulfix(_this->m[0], w->m[3]) + gf_mulfix(_this->m[1], w->m[8]) + gf_mulfix(_this->m[2], w->m[13]) + gf_mulfix(_this->m[3], w->m[18]);
2418 3 : res[4] = gf_mulfix(_this->m[0], w->m[4]) + gf_mulfix(_this->m[1], w->m[9]) + gf_mulfix(_this->m[2], w->m[14]) + gf_mulfix(_this->m[3], w->m[19]) + _this->m[4];
2419 :
2420 3 : res[5] = gf_mulfix(_this->m[5], w->m[0]) + gf_mulfix(_this->m[6], w->m[5]) + gf_mulfix(_this->m[7], w->m[10]) + gf_mulfix(_this->m[8], w->m[15]);
2421 3 : res[6] = gf_mulfix(_this->m[5], w->m[1]) + gf_mulfix(_this->m[6], w->m[6]) + gf_mulfix(_this->m[7], w->m[11]) + gf_mulfix(_this->m[8], w->m[16]);
2422 3 : res[7] = gf_mulfix(_this->m[5], w->m[2]) + gf_mulfix(_this->m[6], w->m[7]) + gf_mulfix(_this->m[7], w->m[12]) + gf_mulfix(_this->m[8], w->m[17]);
2423 3 : res[8] = gf_mulfix(_this->m[5], w->m[3]) + gf_mulfix(_this->m[6], w->m[8]) + gf_mulfix(_this->m[7], w->m[13]) + gf_mulfix(_this->m[8], w->m[18]);
2424 3 : res[9] = gf_mulfix(_this->m[5], w->m[4]) + gf_mulfix(_this->m[6], w->m[9]) + gf_mulfix(_this->m[7], w->m[14]) + gf_mulfix(_this->m[8], w->m[19]) + _this->m[9];
2425 :
2426 3 : res[10] = gf_mulfix(_this->m[10], w->m[0]) + gf_mulfix(_this->m[11], w->m[5]) + gf_mulfix(_this->m[12], w->m[10]) + gf_mulfix(_this->m[13], w->m[15]);
2427 3 : res[11] = gf_mulfix(_this->m[10], w->m[1]) + gf_mulfix(_this->m[11], w->m[6]) + gf_mulfix(_this->m[12], w->m[11]) + gf_mulfix(_this->m[13], w->m[16]);
2428 3 : res[12] = gf_mulfix(_this->m[10], w->m[2]) + gf_mulfix(_this->m[11], w->m[7]) + gf_mulfix(_this->m[12], w->m[12]) + gf_mulfix(_this->m[13], w->m[17]);
2429 3 : res[13] = gf_mulfix(_this->m[10], w->m[3]) + gf_mulfix(_this->m[11], w->m[8]) + gf_mulfix(_this->m[12], w->m[13]) + gf_mulfix(_this->m[13], w->m[18]);
2430 3 : res[14] = gf_mulfix(_this->m[10], w->m[4]) + gf_mulfix(_this->m[11], w->m[9]) + gf_mulfix(_this->m[12], w->m[14]) + gf_mulfix(_this->m[13], w->m[19]) + _this->m[14];
2431 :
2432 3 : res[15] = gf_mulfix(_this->m[15], w->m[0]) + gf_mulfix(_this->m[16], w->m[5]) + gf_mulfix(_this->m[17], w->m[10]) + gf_mulfix(_this->m[18], w->m[15]);
2433 3 : res[16] = gf_mulfix(_this->m[15], w->m[1]) + gf_mulfix(_this->m[16], w->m[6]) + gf_mulfix(_this->m[17], w->m[11]) + gf_mulfix(_this->m[18], w->m[16]);
2434 3 : res[17] = gf_mulfix(_this->m[15], w->m[2]) + gf_mulfix(_this->m[16], w->m[7]) + gf_mulfix(_this->m[17], w->m[12]) + gf_mulfix(_this->m[18], w->m[17]);
2435 3 : res[18] = gf_mulfix(_this->m[15], w->m[3]) + gf_mulfix(_this->m[16], w->m[8]) + gf_mulfix(_this->m[17], w->m[13]) + gf_mulfix(_this->m[18], w->m[18]);
2436 3 : res[19] = gf_mulfix(_this->m[15], w->m[4]) + gf_mulfix(_this->m[16], w->m[9]) + gf_mulfix(_this->m[17], w->m[14]) + gf_mulfix(_this->m[18], w->m[19]) + _this->m[19];
2437 3 : memcpy(_this->m, res, sizeof(Fixed)*20);
2438 3 : gf_cmx_identity(_this);
2439 : }
2440 :
2441 : #define CLIP_COMP(val) { if (val<0) { val=0; } else if (val>FIX_ONE) { val=FIX_ONE;} }
2442 :
2443 : GF_EXPORT
2444 2249600 : void gf_cmx_apply_argb(GF_ColorMatrix *_this, u8 *a_, u8 *r_, u8 *g_, u8 *b_)
2445 : {
2446 : Fixed _a, _r, _g, _b, a, r, g, b;
2447 2249600 : if (!_this || _this->identity) return;
2448 :
2449 2249600 : a = INT2FIX(*a_)/255;
2450 2249600 : r = INT2FIX(*r_)/255;
2451 2249600 : g = INT2FIX(*g_)/255;
2452 2249600 : b = INT2FIX(*b_)/255;
2453 2249600 : _r = gf_mulfix(r, _this->m[0]) + gf_mulfix(g, _this->m[1]) + gf_mulfix(b, _this->m[2]) + gf_mulfix(a, _this->m[3]) + _this->m[4];
2454 2249600 : _g = gf_mulfix(r, _this->m[5]) + gf_mulfix(g, _this->m[6]) + gf_mulfix(b, _this->m[7]) + gf_mulfix(a, _this->m[8]) + _this->m[9];
2455 2249600 : _b = gf_mulfix(r, _this->m[10]) + gf_mulfix(g, _this->m[11]) + gf_mulfix(b, _this->m[12]) + gf_mulfix(a, _this->m[13]) + _this->m[14];
2456 2249600 : _a = gf_mulfix(r, _this->m[15]) + gf_mulfix(g, _this->m[16]) + gf_mulfix(b, _this->m[17]) + gf_mulfix(a, _this->m[18]) + _this->m[19];
2457 2249600 : CLIP_COMP(_a);
2458 2249600 : CLIP_COMP(_r);
2459 2249600 : CLIP_COMP(_g);
2460 2249600 : CLIP_COMP(_b);
2461 :
2462 2249600 : *a_ = FIX2INT(_a*255);
2463 2249600 : *r_ = FIX2INT(_r*255);
2464 2249600 : *g_ = FIX2INT(_g*255);
2465 2249600 : *b_ = FIX2INT(_b*255);
2466 : }
2467 :
2468 :
2469 : GF_EXPORT
2470 1239807 : GF_Color gf_cmx_apply(GF_ColorMatrix *_this, GF_Color col)
2471 : {
2472 : Fixed _a, _r, _g, _b, a, r, g, b;
2473 1239807 : if (!_this || _this->identity) return col;
2474 :
2475 1239807 : a = INT2FIX(col>>24);
2476 1239807 : a /= 255;
2477 1239807 : r = INT2FIX((col>>16)&0xFF);
2478 1239807 : r /= 255;
2479 1239807 : g = INT2FIX((col>>8)&0xFF);
2480 1239807 : g /= 255;
2481 1239807 : b = INT2FIX((col)&0xFF);
2482 1239807 : b /= 255;
2483 1239807 : _r = gf_mulfix(r, _this->m[0]) + gf_mulfix(g, _this->m[1]) + gf_mulfix(b, _this->m[2]) + gf_mulfix(a, _this->m[3]) + _this->m[4];
2484 1239807 : _g = gf_mulfix(r, _this->m[5]) + gf_mulfix(g, _this->m[6]) + gf_mulfix(b, _this->m[7]) + gf_mulfix(a, _this->m[8]) + _this->m[9];
2485 1239807 : _b = gf_mulfix(r, _this->m[10]) + gf_mulfix(g, _this->m[11]) + gf_mulfix(b, _this->m[12]) + gf_mulfix(a, _this->m[13]) + _this->m[14];
2486 1239807 : _a = gf_mulfix(r, _this->m[15]) + gf_mulfix(g, _this->m[16]) + gf_mulfix(b, _this->m[17]) + gf_mulfix(a, _this->m[18]) + _this->m[19];
2487 1239807 : CLIP_COMP(_a);
2488 1239807 : CLIP_COMP(_r);
2489 1239807 : CLIP_COMP(_g);
2490 1239807 : CLIP_COMP(_b);
2491 1239807 : return GF_COL_ARGB(FIX2INT(_a*255),FIX2INT(_r*255),FIX2INT(_g*255),FIX2INT(_b*255));
2492 : }
2493 :
2494 : GF_EXPORT
2495 5541 : u64 gf_cmx_apply_wide(GF_ColorMatrix *_this, u64 col)
2496 : {
2497 : u64 res;
2498 : Fixed _a, _r, _g, _b, a, r, g, b;
2499 5541 : if (!_this || _this->identity) return col;
2500 :
2501 5541 : a = INT2FIX(col>>48);
2502 5541 : a /= 0xFFFF;
2503 5541 : r = INT2FIX((col>>32)&0xFFFF);
2504 5541 : r /= 0xFFFF;
2505 5541 : g = INT2FIX((col>>16)&0xFFFF);
2506 5541 : g /= 0xFFFF;
2507 5541 : b = INT2FIX((col)&0xFFFF);
2508 5541 : b /= 0xFFFF;
2509 5541 : _r = gf_mulfix(r, _this->m[0]) + gf_mulfix(g, _this->m[1]) + gf_mulfix(b, _this->m[2]) + gf_mulfix(a, _this->m[3]) + _this->m[4];
2510 5541 : _g = gf_mulfix(r, _this->m[5]) + gf_mulfix(g, _this->m[6]) + gf_mulfix(b, _this->m[7]) + gf_mulfix(a, _this->m[8]) + _this->m[9];
2511 5541 : _b = gf_mulfix(r, _this->m[10]) + gf_mulfix(g, _this->m[11]) + gf_mulfix(b, _this->m[12]) + gf_mulfix(a, _this->m[13]) + _this->m[14];
2512 5541 : _a = gf_mulfix(r, _this->m[15]) + gf_mulfix(g, _this->m[16]) + gf_mulfix(b, _this->m[17]) + gf_mulfix(a, _this->m[18]) + _this->m[19];
2513 5541 : CLIP_COMP(_a);
2514 5541 : CLIP_COMP(_r);
2515 5541 : CLIP_COMP(_g);
2516 5541 : CLIP_COMP(_b);
2517 5541 : res = (u32) (_a*0xFFFF)&0xFFFF;
2518 5541 : res<<=16;
2519 5541 : res |= (u32) (_r*0xFFFF)&0xFFFF;
2520 5541 : res<<=16;
2521 5541 : res |= (u32) (_g*0xFFFF)&0xFFFF;
2522 5541 : res<<=16;
2523 5541 : res |= (u32) (_b*0xFFFF)&0xFFFF;
2524 5541 : return res;
2525 : }
2526 :
2527 : GF_EXPORT
2528 1 : void gf_cmx_apply_fixed(GF_ColorMatrix *_this, Fixed *a, Fixed *r, Fixed *g, Fixed *b)
2529 : {
2530 1 : u32 col = GF_COL_ARGB_FIXED(*a, *r, *g, *b);
2531 1 : col = gf_cmx_apply(_this, col);
2532 1 : *a = INT2FIX(GF_COL_A(col)) / 255;
2533 1 : *r = INT2FIX(GF_COL_R(col)) / 255;
2534 1 : *g = INT2FIX(GF_COL_G(col)) / 255;
2535 1 : *b = INT2FIX(GF_COL_B(col)) / 255;
2536 1 : }
2537 :
2538 :
2539 : #ifndef GPAC_DISABLE_PLAYER
2540 :
2541 :
2542 : //intrinsic code segfaults on 32 bit, need to check why
2543 : #if defined(GPAC_64_BITS)
2544 : # if defined(WIN32) && !defined(__GNUC__)
2545 : # include <intrin.h>
2546 : # define GPAC_HAS_SSE2
2547 : # else
2548 : # ifdef __SSE2__
2549 : # include <emmintrin.h>
2550 : # define GPAC_HAS_SSE2
2551 : # endif
2552 : # endif
2553 : #endif
2554 :
2555 : #ifdef GPAC_HAS_SSE2
2556 :
2557 3 : static GF_Err color_write_yv12_10_to_yuv_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd, Bool swap_uv)
2558 : {
2559 : u32 i, j, w, h;
2560 : __m128i val1, val2, val_dst, *src1, *src2, *dst;
2561 3 : if (!pY) return GF_BAD_PARAM;
2562 :
2563 3 : if (!pU) {
2564 0 : pU = pY + src_stride * src_height;
2565 0 : pV = pY + 5*src_stride * src_height/4;
2566 : }
2567 :
2568 3 : if (_src_wnd) {
2569 3 : pY = pY + src_stride * _src_wnd->y + _src_wnd->x;
2570 : /*because of U and V downsampling by 2x2, working with odd Y offset will lead to a half-line shift between Y and UV components. We
2571 : therefore force an even Y offset for U and V planes.*/
2572 3 : pU = pU + (src_stride * (_src_wnd->y / 2) + _src_wnd->x) / 2;
2573 3 : pV = pV + (src_stride * (_src_wnd->y / 2) + _src_wnd->x) / 2;
2574 3 : w = _src_wnd->w;
2575 3 : h = _src_wnd->h;
2576 : } else {
2577 : w = src_width;
2578 : h = src_height;
2579 : }
2580 :
2581 3 : if (swap_uv) {
2582 : u8 *t = pV;
2583 : pV = pU;
2584 : pU = t;
2585 : }
2586 :
2587 :
2588 :
2589 387 : for (i=0; i<h; i++) {
2590 384 : src1 = (__m128i *)(pY + i*src_stride);
2591 384 : src2 = src1+1;
2592 384 : dst = (__m128i *)(vs_dst->video_buffer + i*vs_dst->pitch_y);
2593 :
2594 3456 : for (j=0; j<w/16; j++, src1+=2, src2+=2, dst++) {
2595 : val1 = _mm_load_si128(src1);
2596 : val1 = _mm_srli_epi16(val1, 2);
2597 : val2 = _mm_load_si128(src2);
2598 : val2 = _mm_srli_epi16(val2, 2);
2599 : val_dst = _mm_packus_epi16(val1, val2);
2600 : _mm_store_si128(dst, val_dst);
2601 : }
2602 : }
2603 :
2604 192 : for (i=0; i<h/2; i++) {
2605 192 : src1 = (__m128i *) (pU + i*src_stride/2);
2606 192 : src2 = src1+1;
2607 192 : if (vs_dst->u_ptr) dst = (__m128i *) (vs_dst->u_ptr + i*vs_dst->pitch_y/2);
2608 192 : else dst = (__m128i *)(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y/2);
2609 :
2610 768 : for (j=0; j<w/32; j++, src1+=2, src2+=2, dst++) {
2611 : val1 = _mm_load_si128(src1);
2612 : val1 = _mm_srli_epi16(val1, 2);
2613 : val2 = _mm_load_si128(src2);
2614 : val2 = _mm_srli_epi16(val2, 2);
2615 : val_dst = _mm_packus_epi16(val1, val2);
2616 : _mm_store_si128(dst, val_dst);
2617 : }
2618 : }
2619 :
2620 192 : for (i=0; i<h/2; i++) {
2621 192 : src1 = (__m128i *) (pV + i*src_stride/2);
2622 192 : src2 = src1+1;
2623 192 : if (vs_dst->v_ptr) dst = (__m128i *) (vs_dst->v_ptr + i*vs_dst->pitch_y/2);
2624 192 : else dst = (__m128i *)(vs_dst->video_buffer + 5*vs_dst->pitch_y * vs_dst->height/4 + i*vs_dst->pitch_y/2);
2625 :
2626 768 : for (j=0; j<w/32; j++, src1+=2, src2+=2, dst++) {
2627 : val1 = _mm_load_si128(src1);
2628 : val1 = _mm_srli_epi16(val1, 2);
2629 : val2 = _mm_load_si128(src2);
2630 : val2 = _mm_srli_epi16(val2, 2);
2631 : val_dst = _mm_packus_epi16(val1, val2);
2632 : _mm_store_si128(dst, val_dst);
2633 : }
2634 : }
2635 : return GF_OK;
2636 :
2637 : }
2638 :
2639 1 : static GF_Err color_write_yuv422_10_to_yuv422_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd, Bool swap_uv)
2640 : {
2641 : u32 i, j, w, h;
2642 : __m128i val1, val2, val_dst, *src1, *src2, *dst;
2643 1 : if (!pU) {
2644 1 : pU = pY + src_stride * src_height;
2645 1 : pV = pY + 3*src_stride * src_height/2;
2646 : }
2647 :
2648 1 : if (_src_wnd) {
2649 1 : pY = pY + src_stride * _src_wnd->y + _src_wnd->x;
2650 1 : pU = pU + (src_stride * _src_wnd->y + _src_wnd->x) / 2;
2651 1 : pV = pV + (src_stride * _src_wnd->y + _src_wnd->x) / 2;
2652 1 : w = _src_wnd->w;
2653 1 : h = _src_wnd->h;
2654 : } else {
2655 : w = src_width;
2656 : h = src_height;
2657 : }
2658 :
2659 1 : if (swap_uv) {
2660 : u8 *t = pV;
2661 : pV = pU;
2662 : pU = t;
2663 : }
2664 :
2665 :
2666 :
2667 129 : for (i=0; i<h; i++) {
2668 128 : src1 = (__m128i *)(pY + i*src_stride);
2669 128 : src2 = src1+1;
2670 128 : dst = (__m128i *)(vs_dst->video_buffer + i*vs_dst->pitch_y);
2671 :
2672 1152 : for (j=0; j<w/16; j++, src1+=2, src2+=2, dst++) {
2673 : val1 = _mm_load_si128(src1);
2674 : val1 = _mm_srli_epi16(val1, 2);
2675 : val2 = _mm_load_si128(src2);
2676 : val2 = _mm_srli_epi16(val2, 2);
2677 : val_dst = _mm_packus_epi16(val1, val2);
2678 : _mm_store_si128(dst, val_dst);
2679 : }
2680 : }
2681 :
2682 128 : for (i=0; i<h; i++) {
2683 128 : src1 = (__m128i *) (pU + i*src_stride/2);
2684 128 : src2 = src1+1;
2685 128 : if (vs_dst->u_ptr) dst = (__m128i *) (vs_dst->u_ptr + i*vs_dst->pitch_y/2);
2686 128 : else dst = (__m128i *)(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y/2);
2687 :
2688 512 : for (j=0; j<w/32; j++, src1+=2, src2+=2, dst++) {
2689 : val1 = _mm_load_si128(src1);
2690 : val1 = _mm_srli_epi16(val1, 2);
2691 : val2 = _mm_load_si128(src2);
2692 : val2 = _mm_srli_epi16(val2, 2);
2693 : val_dst = _mm_packus_epi16(val1, val2);
2694 : _mm_store_si128(dst, val_dst);
2695 : }
2696 : }
2697 :
2698 128 : for (i=0; i<h; i++) {
2699 128 : src1 = (__m128i *) (pV + i*src_stride/2);
2700 128 : src2 = src1+1;
2701 128 : if (vs_dst->v_ptr) dst = (__m128i *) (vs_dst->v_ptr + i*vs_dst->pitch_y/2);
2702 128 : else dst = (__m128i *)(vs_dst->video_buffer + 3*vs_dst->pitch_y * vs_dst->height/2 + i*vs_dst->pitch_y/2);
2703 :
2704 512 : for (j=0; j<w/32; j++, src1+=2, src2+=2, dst++) {
2705 : val1 = _mm_load_si128(src1);
2706 : val1 = _mm_srli_epi16(val1, 2);
2707 : val2 = _mm_load_si128(src2);
2708 : val2 = _mm_srli_epi16(val2, 2);
2709 : val_dst = _mm_packus_epi16(val1, val2);
2710 : _mm_store_si128(dst, val_dst);
2711 : }
2712 : }
2713 1 : return GF_OK;
2714 :
2715 : }
2716 :
2717 1 : static GF_Err color_write_yuv444_10_to_yuv444_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd, Bool swap_uv)
2718 : {
2719 : u32 i, j, w, h;
2720 : __m128i val1, val2, val_dst, *src1, *src2, *dst;
2721 1 : if (!pU) {
2722 1 : pU = pY + src_stride * src_height;
2723 1 : pV = pY + 2 * src_stride * src_height ;
2724 : }
2725 :
2726 1 : if (_src_wnd) {
2727 1 : pY = pY + src_stride * _src_wnd->y + _src_wnd->x;
2728 1 : pU = pU + src_stride * _src_wnd->y + _src_wnd->x;
2729 1 : pV = pV + src_stride * _src_wnd->y + _src_wnd->x;
2730 1 : w = _src_wnd->w;
2731 1 : h = _src_wnd->h;
2732 : }
2733 : else {
2734 : w = src_width;
2735 : h = src_height;
2736 : }
2737 :
2738 1 : if (swap_uv) {
2739 : u8 *t = pV;
2740 : pV = pU;
2741 : pU = t;
2742 : }
2743 :
2744 :
2745 129 : for (i = 0; i<h; i++) {
2746 128 : src1 = (__m128i *)(pY + i*src_stride);
2747 128 : src2 = src1 + 1;
2748 128 : dst = (__m128i *)(vs_dst->video_buffer + i*vs_dst->pitch_y);
2749 :
2750 1152 : for (j = 0; j<w / 16; j++, src1 += 2, src2 += 2, dst++) {
2751 : val1 = _mm_load_si128(src1);
2752 : val1 = _mm_srli_epi16(val1, 2);
2753 : val2 = _mm_load_si128(src2);
2754 : val2 = _mm_srli_epi16(val2, 2);
2755 : val_dst = _mm_packus_epi16(val1, val2);
2756 : _mm_store_si128(dst, val_dst);
2757 : }
2758 : }
2759 :
2760 128 : for (i = 0; i<h; i++) {
2761 128 : src1 = (__m128i *) (pU + i*src_stride );
2762 128 : src2 = src1 + 1;
2763 128 : if (vs_dst->u_ptr) dst = (__m128i *) (vs_dst->u_ptr + i*vs_dst->pitch_y );
2764 128 : else dst = (__m128i *)(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y );
2765 :
2766 1024 : for (j = 0; j<w / 16; j++, src1 += 2, src2 += 2, dst++) {
2767 : val1 = _mm_load_si128(src1);
2768 : val1 = _mm_srli_epi16(val1, 2);
2769 : val2 = _mm_load_si128(src2);
2770 : val2 = _mm_srli_epi16(val2, 2);
2771 : val_dst = _mm_packus_epi16(val1, val2);
2772 : _mm_store_si128(dst, val_dst);
2773 : }
2774 : }
2775 :
2776 128 : for (i = 0; i<h ; i++) {
2777 128 : src1 = (__m128i *) (pV + i*src_stride );
2778 128 : src2 = src1 + 1;
2779 128 : if (vs_dst->v_ptr) dst = (__m128i *) (vs_dst->v_ptr + i*vs_dst->pitch_y);
2780 128 : else dst = (__m128i *)(vs_dst->video_buffer + 2 * vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y );
2781 :
2782 1024 : for (j = 0; j<w / 16; j++, src1 += 2, src2 += 2, dst++) {
2783 : val1 = _mm_load_si128(src1);
2784 : val1 = _mm_srli_epi16(val1, 2);
2785 : val2 = _mm_load_si128(src2);
2786 : val2 = _mm_srli_epi16(val2, 2);
2787 : val_dst = _mm_packus_epi16(val1, val2);
2788 : _mm_store_si128(dst, val_dst);
2789 : }
2790 : }
2791 1 : return GF_OK;
2792 :
2793 : }
2794 1 : static GF_Err color_write_yuv422_10_to_yuv_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd, Bool swap_uv)
2795 : {
2796 : u32 i, j, w, h;
2797 : __m128i val1, val2, val_dst, *src1, *src2, *dst;
2798 1 : if (!pU) {
2799 1 : pU = pY + src_stride * src_height;
2800 1 : pV = pY + 3 * src_stride * src_height / 2;
2801 : }
2802 :
2803 1 : if (_src_wnd) {
2804 1 : pY = pY + src_stride * _src_wnd->y + _src_wnd->x;
2805 1 : pU = pU + (src_stride * _src_wnd->y + _src_wnd->x) / 2;
2806 1 : pV = pV + (src_stride * _src_wnd->y + _src_wnd->x) / 2;
2807 1 : w = _src_wnd->w;
2808 1 : h = _src_wnd->h;
2809 : }
2810 : else {
2811 : w = src_width;
2812 : h = src_height;
2813 : }
2814 :
2815 1 : if (swap_uv) {
2816 : u8 *t = pV;
2817 : pV = pU;
2818 : pU = t;
2819 : }
2820 :
2821 :
2822 :
2823 129 : for (i = 0; i<h; i++) {
2824 128 : src1 = (__m128i *)(pY + i*src_stride);
2825 128 : src2 = src1 + 1;
2826 128 : dst = (__m128i *)(vs_dst->video_buffer + i*vs_dst->pitch_y);
2827 :
2828 1152 : for (j = 0; j<w / 16; j++, src1 += 2, src2 += 2, dst++) {
2829 : val1 = _mm_load_si128(src1);
2830 : val1 = _mm_srli_epi16(val1, 2);
2831 : val2 = _mm_load_si128(src2);
2832 : val2 = _mm_srli_epi16(val2, 2);
2833 : val_dst = _mm_packus_epi16(val1, val2);
2834 : _mm_store_si128(dst, val_dst);
2835 : }
2836 : }
2837 :
2838 64 : for (i = 0; i<h / 2; i++) {
2839 64 : src1 = (__m128i *) (pU + i*src_stride);
2840 64 : src2 = src1 + 1;
2841 64 : if (vs_dst->u_ptr) dst = (__m128i *) (vs_dst->u_ptr + i*vs_dst->pitch_y / 2);
2842 64 : else dst = (__m128i *)(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y / 2);
2843 :
2844 256 : for (j = 0; j<w / 32; j++, src1 += 2, src2 += 2, dst++) {
2845 : val1 = _mm_load_si128(src1);
2846 : val1 = _mm_srli_epi16(val1, 2);
2847 : val2 = _mm_load_si128(src2);
2848 : val2 = _mm_srli_epi16(val2, 2);
2849 : val_dst = _mm_packus_epi16(val1, val2);
2850 : _mm_store_si128(dst, val_dst);
2851 : }
2852 : }
2853 :
2854 64 : for (i = 0; i<h / 2; i++) {
2855 64 : src1 = (__m128i *) (pV + i*src_stride);
2856 64 : src2 = src1 + 1;
2857 64 : if (vs_dst->v_ptr) dst = (__m128i *) (vs_dst->v_ptr + i*vs_dst->pitch_y / 2);
2858 64 : else dst = (__m128i *)(vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4 + i*vs_dst->pitch_y / 2);
2859 :
2860 256 : for (j = 0; j<w / 32; j++, src1 += 2, src2 += 2, dst++) {
2861 : val1 = _mm_load_si128(src1);
2862 : val1 = _mm_srli_epi16(val1, 2);
2863 : val2 = _mm_load_si128(src2);
2864 : val2 = _mm_srli_epi16(val2, 2);
2865 : val_dst = _mm_packus_epi16(val1, val2);
2866 : _mm_store_si128(dst, val_dst);
2867 : }
2868 : }
2869 1 : return GF_OK;
2870 :
2871 : }
2872 1 : static GF_Err color_write_yuv444_10_to_yuv_intrin(GF_VideoSurface *vs_dst, unsigned char *pY, unsigned char *pU, unsigned char*pV, u32 src_stride, u32 src_width, u32 src_height, const GF_Window *_src_wnd, Bool swap_uv)
2873 : {
2874 : u32 i, j, w, h;
2875 : __m128i val1, val2,val3,val4, val12, val34, val_dst, *src1, *src2,*src3,*src4, *dst;
2876 :
2877 1 : if (!pU) {
2878 1 : pU = pY + src_stride * src_height;
2879 1 : pV = pY + 2 * src_stride * src_height;
2880 : }
2881 :
2882 1 : if (_src_wnd) {
2883 1 : pY = pY + src_stride * _src_wnd->y + _src_wnd->x;
2884 1 : pU = pU + src_stride * _src_wnd->y + _src_wnd->x;
2885 1 : pV = pV + src_stride * _src_wnd->y + _src_wnd->x;
2886 1 : w = _src_wnd->w;
2887 1 : h = _src_wnd->h;
2888 : }
2889 : else {
2890 : w = src_width;
2891 : h = src_height;
2892 : }
2893 :
2894 1 : if (swap_uv) {
2895 : u8 *t = pV;
2896 : pV = pU;
2897 : pU = t;
2898 : }
2899 :
2900 :
2901 129 : for (i = 0; i<h; i++) {
2902 128 : src1 = (__m128i *)(pY + i*src_stride);
2903 128 : src2 = src1 + 1;
2904 128 : dst = (__m128i *)(vs_dst->video_buffer + i*vs_dst->pitch_y);
2905 :
2906 1152 : for (j = 0; j<w / 16; j++, src1 += 2, src2 += 2, dst++) {
2907 : val1 = _mm_load_si128(src1);
2908 : val1 = _mm_srli_epi16(val1, 2);
2909 : val2 = _mm_load_si128(src2);
2910 : val2 = _mm_srli_epi16(val2, 2);
2911 : val_dst = _mm_packus_epi16(val1, val2);
2912 : _mm_store_si128(dst, val_dst);
2913 : }
2914 : }
2915 :
2916 64 : for (i = 0; i<h / 2; i++) {
2917 64 : src1 = (__m128i *) (pU + 2*i*src_stride);
2918 64 : src2 = src1 + 1;
2919 64 : src3 = src2 + 1;
2920 64 : src4 = src3 + 1;
2921 64 : if (vs_dst->u_ptr) dst = (__m128i *) (vs_dst->u_ptr + i*vs_dst->pitch_y / 2);
2922 64 : else dst = (__m128i *)(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y / 2);
2923 :
2924 256 : for (j = 0; j<w /32; j++, src1 += 4, src2 += 4,src3 +=4, src4+=4, dst++) {
2925 : val1 = _mm_load_si128(src1);
2926 : val1 = _mm_srli_epi32(val1, 16);
2927 : val2 = _mm_load_si128(src2);
2928 : val2 = _mm_srli_epi32(val2, 16);
2929 : val12 = _mm_packs_epi32(val1, val2);
2930 : val12 = _mm_srli_epi16(val12, 2);
2931 :
2932 : val3 = _mm_load_si128(src3);
2933 :
2934 : val3 = _mm_srli_epi32(val3, 16);
2935 : val4 = _mm_load_si128(src4);
2936 :
2937 : val4 = _mm_srli_epi32(val4, 16);
2938 : val34 = _mm_packs_epi32(val3, val4);
2939 : val34 = _mm_srli_epi16(val34, 2);
2940 :
2941 : val_dst = _mm_packus_epi16(val12, val34);
2942 : _mm_store_si128(dst, val_dst);
2943 :
2944 : }
2945 : }
2946 :
2947 64 : for (i = 0; i<h / 2; i++) {
2948 64 : src1 = (__m128i *) (pV + 2*i*src_stride );
2949 64 : src2 = src1 + 1;
2950 64 : src3 = src1 + 2;
2951 64 : src4 = src1 + 3;
2952 64 : if (vs_dst->v_ptr) dst = (__m128i *) (vs_dst->v_ptr + i*vs_dst->pitch_y / 2);
2953 64 : else dst = (__m128i *)(vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4 + i*vs_dst->pitch_y / 2);
2954 :
2955 256 : for (j = 0; j<w / 32; j++, src1 += 4, src2 += 4, src3 += 4, src4 += 4, dst++) {
2956 : val1 = _mm_load_si128(src1);
2957 :
2958 : val1 = _mm_srli_epi32(val1, 16);
2959 : val2 = _mm_load_si128(src2);
2960 :
2961 : val2 = _mm_srli_epi32(val2, 16);
2962 : val12 = _mm_packs_epi32(val1, val2);
2963 : val12 = _mm_srli_epi16(val12, 2);
2964 :
2965 : val3 = _mm_load_si128(src3);
2966 :
2967 : val3 = _mm_srli_epi32(val3, 16);
2968 : val4 = _mm_load_si128(src4);
2969 :
2970 : val4 = _mm_srli_epi32(val4, 16);
2971 : val34 = _mm_packs_epi32(val3, val4);
2972 : val34 = _mm_srli_epi16(val34, 2);
2973 :
2974 : val_dst = _mm_packus_epi16(val12, val34);
2975 : _mm_store_si128(dst, val_dst);
2976 : }
2977 : }
2978 :
2979 1 : return GF_OK;
2980 :
2981 : }
2982 : #endif
2983 :
2984 :
2985 3 : static GF_Err color_write_yv12_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, const GF_Window *_src_wnd, Bool swap_uv)
2986 : {
2987 : u32 i, j, w, h;
2988 3 : u8 *pY = vs_src->video_buffer;
2989 3 : u8 *pU = vs_src->u_ptr;
2990 3 : u8 *pV = vs_src->v_ptr;
2991 :
2992 3 : if (_src_wnd) {
2993 3 : w = _src_wnd->w;
2994 3 : h = _src_wnd->h;
2995 : } else {
2996 0 : w = vs_src->width;
2997 0 : h = vs_src->height;
2998 : }
2999 :
3000 3 : if (!pU) {
3001 3 : pU = pY + vs_src->pitch_y * vs_src->height;
3002 3 : pV = pY + 5 * vs_src->pitch_y * vs_src->height/4;
3003 : }
3004 :
3005 : #ifdef GPAC_HAS_SSE2
3006 :
3007 : #ifdef GPAC_64_BITS
3008 : #define GFINTCAST (u64)
3009 : #else
3010 : #define GFINTCAST (u32)
3011 : #endif
3012 :
3013 3 : if ( (w%32 == 0)
3014 3 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y)%8 == 0)
3015 3 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + vs_dst->pitch_y/2)%8 == 0)
3016 3 : && (GFINTCAST (pU + vs_src->pitch_y/2)%8 == 0)
3017 3 : && (GFINTCAST (pV + vs_src->pitch_y/2)%8 == 0)
3018 : ) {
3019 3 : return color_write_yv12_10_to_yuv_intrin(vs_dst, pY, pU, pV, vs_src->pitch_y, vs_src->width, vs_src->height, _src_wnd, swap_uv);
3020 : }
3021 : #endif
3022 :
3023 0 : if (_src_wnd) {
3024 0 : pY = pY + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3025 : /*because of U and V downsampling by 2x2, working with odd Y offset will lead to a half-line shift between Y and UV components. We
3026 : therefore force an even Y offset for U and V planes.*/
3027 0 : pU = pU + (vs_src->pitch_y * (_src_wnd->y / 2) + _src_wnd->x) / 2;
3028 0 : pV = pV + (vs_src->pitch_y * (_src_wnd->y / 2) + _src_wnd->x) / 2;
3029 : }
3030 :
3031 0 : if (swap_uv) {
3032 : u8 *t = pV;
3033 : pV = pU;
3034 : pU = t;
3035 : }
3036 :
3037 :
3038 0 : for (i=0; i<h; i++) {
3039 0 : u16 *src = (u16 *) (pY + i*vs_src->pitch_y);
3040 0 : u8 *dst = (u8 *) vs_dst->video_buffer + i*vs_dst->pitch_y;
3041 :
3042 0 : for (j=0; j<w; j++) {
3043 0 : *dst = (*src) >> 2;
3044 0 : dst++;
3045 0 : src++;
3046 : }
3047 : }
3048 :
3049 0 : for (i=0; i<h/2; i++) {
3050 0 : u16 *src = (u16 *) (pU + i*vs_src->pitch_y/2);
3051 0 : u8 *dst = (u8 *) vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y/2;
3052 0 : if (vs_dst->u_ptr) dst = (u8 *) (vs_dst->u_ptr + i*vs_dst->pitch_y/2);
3053 :
3054 0 : for (j=0; j<w/2; j++) {
3055 0 : *dst = (*src) >> 2;
3056 0 : dst++;
3057 0 : src++;
3058 : }
3059 : }
3060 :
3061 0 : for (i=0; i<h/2; i++) {
3062 0 : u16 *src = (u16 *) (pV + i*vs_src->pitch_y/2);
3063 0 : u8 *dst = (u8 *) vs_dst->video_buffer + 5*vs_dst->pitch_y * vs_dst->height/4 + i*vs_dst->pitch_y/2;
3064 0 : if (vs_dst->v_ptr) dst = (u8 *) (vs_dst->v_ptr + i*vs_dst->pitch_y/2);
3065 :
3066 0 : for (j=0; j<w/2; j++) {
3067 0 : *dst = (*src) >> 2;
3068 0 : dst++;
3069 0 : src++;
3070 : }
3071 : }
3072 : return GF_OK;
3073 : }
3074 :
3075 6 : static GF_Err color_write_nv12_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3076 : {
3077 : u32 i, j, w, h;
3078 6 : u8 *pY = vs_src->video_buffer;
3079 6 : u8 *pUV = vs_src->u_ptr;
3080 :
3081 6 : if (_src_wnd) {
3082 6 : w = _src_wnd->w;
3083 6 : h = _src_wnd->h;
3084 : } else {
3085 0 : w = vs_src->width;
3086 0 : h = vs_src->height;
3087 : }
3088 :
3089 :
3090 : //#ifdef GPAC_HAS_SSE2
3091 : #if 0
3092 :
3093 : #ifdef GPAC_64_BITS
3094 : #define GFINTCAST (u64)
3095 : #else
3096 : #define GFINTCAST (u32)
3097 : #endif
3098 :
3099 : if ( (w%32 == 0)
3100 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y)%8 == 0)
3101 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + vs_dst->pitch_y/2)%8 == 0)
3102 : && (GFINTCAST (pU + src_stride/2)%8 == 0)
3103 : && (GFINTCAST (pV + src_stride/2)%8 == 0)
3104 : ) {
3105 : return gf_color_write_yv12_10_to_yuv_intrin(vs_dst, pY, pU, pV, src_stride, src_width, src_height, _src_wnd, swap_uv);
3106 : }
3107 : #endif
3108 :
3109 6 : if (!pUV) {
3110 6 : pUV = pY + vs_src->pitch_y * vs_src->height;
3111 : }
3112 :
3113 6 : if (_src_wnd) {
3114 6 : pY = pY + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3115 : /*because of U and V downsampling by 2x2, working with odd Y offset will lead to a half-line shift between Y and UV components. We
3116 : therefore force an even Y offset for U and V planes.*/
3117 6 : pUV = pUV + (vs_src->pitch_y * (_src_wnd->y / 2) + _src_wnd->x) / 2;
3118 : }
3119 :
3120 774 : for (i=0; i<h; i++) {
3121 768 : u16 *src = (u16 *) (pY + i*vs_src->pitch_y);
3122 768 : u8 *dst = (u8 *) vs_dst->video_buffer + i*vs_dst->pitch_y;
3123 :
3124 99072 : for (j=0; j<w; j++) {
3125 98304 : *dst = (*src) >> 2;
3126 98304 : dst++;
3127 98304 : src++;
3128 : }
3129 : }
3130 :
3131 384 : for (i=0; i<h/2; i++) {
3132 384 : u16 *src = (u16 *) (pUV + i*vs_src->pitch_y/2);
3133 384 : u8 *dst = (u8 *) vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y/2;
3134 384 : if (vs_dst->u_ptr) dst = (u8 *) (vs_dst->u_ptr + i*vs_dst->pitch_y/2);
3135 384 : if (swap_uv) src += 1;
3136 :
3137 24576 : for (j=0; j<w/2; j++) {
3138 24576 : *dst = (*src) >> 2;
3139 24576 : dst++;
3140 24576 : src++;
3141 : }
3142 : }
3143 :
3144 384 : for (i=0; i<h/2; i++) {
3145 384 : u16 *src = (u16 *) (pUV + i*vs_src->pitch_y/2);
3146 384 : u8 *dst = (u8 *) vs_dst->video_buffer + 5*vs_dst->pitch_y * vs_dst->height/4 + i*vs_dst->pitch_y/2;
3147 384 : if (vs_dst->v_ptr) dst = (u8 *) (vs_dst->v_ptr + i*vs_dst->pitch_y/2);
3148 384 : if (!swap_uv) src += 1;
3149 :
3150 24576 : for (j=0; j<w/2; j++) {
3151 24576 : *dst = (*src) >> 2;
3152 24576 : dst++;
3153 24576 : src++;
3154 : }
3155 : }
3156 6 : return GF_OK;
3157 :
3158 : }
3159 :
3160 1 : static GF_Err color_write_yuv422_10_to_yuv422(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3161 : {
3162 : u32 i, j, w, h;
3163 1 : u8 *pY = vs_src->video_buffer;
3164 1 : u8 *pU = vs_src->u_ptr;
3165 1 : u8 *pV = vs_src->v_ptr;
3166 :
3167 1 : if (_src_wnd) {
3168 1 : w = _src_wnd->w;
3169 1 : h = _src_wnd->h;
3170 : } else {
3171 0 : w = vs_src->width;
3172 0 : h = vs_src->height;
3173 : }
3174 :
3175 :
3176 : #ifdef GPAC_HAS_SSE2
3177 :
3178 : #ifdef GPAC_64_BITS
3179 : #define GFINTCAST (u64)
3180 : #else
3181 : #define GFINTCAST (u32)
3182 : #endif
3183 :
3184 1 : if ( (w%32 == 0)
3185 1 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y)%8 == 0)
3186 1 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + vs_dst->pitch_y/2)%8 == 0)
3187 1 : && (GFINTCAST (pU + vs_src->pitch_y/2)%8 == 0)
3188 1 : && (GFINTCAST (pV + vs_src->pitch_y/2)%8 == 0)
3189 : ) {
3190 1 : return color_write_yuv422_10_to_yuv422_intrin(vs_dst, pY, pU, pV, vs_src->pitch_y, vs_src->width, vs_src->height, _src_wnd, swap_uv);
3191 : }
3192 : #endif
3193 :
3194 0 : if (!pU) {
3195 0 : pU = pY + vs_src->pitch_y * vs_src->height;
3196 0 : pV = pY + 3*vs_src->pitch_y * vs_src->height/2;
3197 : }
3198 :
3199 0 : if (_src_wnd) {
3200 0 : pY = pY + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3201 0 : pU = pU + (vs_src->pitch_y * _src_wnd->y + _src_wnd->x) / 2;
3202 0 : pV = pV + (vs_src->pitch_y * _src_wnd->y + _src_wnd->x) / 2;
3203 : }
3204 :
3205 0 : if (swap_uv) {
3206 : u8 *t = pV;
3207 : pV = pU;
3208 : pU = t;
3209 : }
3210 :
3211 0 : for (i=0; i<h; i++) {
3212 0 : u16 *src_y = (u16 *) (pY + i*vs_src->pitch_y);
3213 0 : u8 *dst_y = (u8 *) vs_dst->video_buffer + i*vs_dst->pitch_y;
3214 :
3215 0 : for (j=0; j<w; j++) {
3216 0 : *dst_y = (*src_y) >> 2;
3217 0 : dst_y++;
3218 0 : src_y++;
3219 : }
3220 : }
3221 0 : for (i=0; i<h; i++) {
3222 0 : u16 *src_u = (u16 *) (pU + i*vs_src->pitch_y/2);
3223 0 : u16 *src_v = (u16 *) (pV + i*vs_src->pitch_y/2);
3224 0 : u8 *dst_u = (u8 *) vs_dst->video_buffer + vs_dst->width * vs_dst->height + i*vs_dst->pitch_y/2;
3225 0 : u8 *dst_v = (u8 *) vs_dst->video_buffer + 3*vs_dst->pitch_y * vs_dst->height/2 + i*vs_dst->pitch_y/2;
3226 0 : if (vs_dst->u_ptr) dst_u = (u8 *) (vs_dst->u_ptr + i*vs_dst->pitch_y/2);
3227 0 : if (vs_dst->v_ptr) dst_v = (u8 *) (vs_dst->v_ptr + i*vs_dst->pitch_y/2);
3228 :
3229 0 : for (j=0; j<w/2; j++) {
3230 0 : *dst_u = (*src_u) >> 2;
3231 0 : dst_u++;
3232 0 : src_u++;
3233 :
3234 0 : *dst_v = (*src_v) >> 2;
3235 0 : dst_v++;
3236 0 : src_v++;
3237 : }
3238 : }
3239 : return GF_OK;
3240 : }
3241 :
3242 1 : static GF_Err color_write_yuv444_10_to_yuv444(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3243 : {
3244 : u32 i, j, w, h;
3245 1 : u8 *pY = vs_src->video_buffer;
3246 1 : u8 *pU = vs_src->u_ptr;
3247 1 : u8 *pV = vs_src->v_ptr;
3248 :
3249 1 : if (_src_wnd) {
3250 1 : w = _src_wnd->w;
3251 1 : h = _src_wnd->h;
3252 : } else {
3253 0 : w = vs_src->width;
3254 0 : h = vs_src->height;
3255 : }
3256 :
3257 :
3258 : #ifdef GPAC_HAS_SSE2
3259 :
3260 : #ifdef GPAC_64_BITS
3261 : #define GFINTCAST (u64)
3262 : #else
3263 : #define GFINTCAST (u32)
3264 : #endif
3265 :
3266 1 : if ( (w%32 == 0)
3267 1 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y)%8 == 0)
3268 1 : && (GFINTCAST (vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + vs_dst->pitch_y)%8 == 0)
3269 1 : && (GFINTCAST (pU + vs_src->pitch_y)%8 == 0)
3270 1 : && (GFINTCAST (pV + vs_src->pitch_y)%8 == 0)
3271 : ) {
3272 1 : return color_write_yuv444_10_to_yuv444_intrin(vs_dst, pY, pU, pV, vs_src->pitch_y, vs_src->width, vs_src->height, _src_wnd, swap_uv);
3273 : }
3274 : #endif
3275 :
3276 0 : if (!pU) {
3277 0 : pU = pY + vs_src->pitch_y * vs_src->height;
3278 0 : pV = pY + 2*vs_src->pitch_y * vs_src->height;
3279 : }
3280 :
3281 0 : if (_src_wnd) {
3282 0 : pY = pY + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3283 0 : pU = pU + vs_src->pitch_y * _src_wnd->y + _src_wnd->x ;
3284 0 : pV = pV + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3285 : }
3286 :
3287 0 : if (swap_uv) {
3288 : u8 *t = pV;
3289 : pV = pU;
3290 : pU = t;
3291 : }
3292 :
3293 0 : for (i=0; i<h; i++) {
3294 0 : u16 *src_y = (u16 *) (pY + i*vs_src->pitch_y);
3295 0 : u8 *dst_y = (u8 *) vs_dst->video_buffer + i*vs_dst->pitch_y;
3296 :
3297 0 : u16 *src_u= (u16 *) (pU + i*vs_src->pitch_y);
3298 0 : u8 *dst_u = (u8 *) vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height+ i*vs_dst->pitch_y;
3299 :
3300 0 : u16 *src_v = (u16 *) (pV + i*vs_src->pitch_y);
3301 0 : u8 *dst_v = (u8 *) vs_dst->video_buffer + 2*vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y;
3302 :
3303 0 : if (vs_dst->u_ptr) dst_u = (u8 *)(vs_dst->u_ptr + i*vs_dst->pitch_y);
3304 0 : if (vs_dst->v_ptr) dst_v = (u8 *)(vs_dst->v_ptr + i*vs_dst->pitch_y);
3305 :
3306 0 : for (j=0; j<w; j++) {
3307 0 : *dst_y = (*src_y) >> 2;
3308 0 : dst_y++;
3309 0 : src_y++;
3310 :
3311 0 : *dst_u = (*src_u) >> 2;
3312 0 : dst_u++;
3313 0 : src_u++;
3314 :
3315 0 : *dst_v= (*src_v) >> 2;
3316 0 : dst_v++;
3317 0 : src_v++;
3318 : }
3319 : }
3320 : return GF_OK;
3321 : }
3322 :
3323 1 : static GF_Err color_write_yuv422_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3324 : {
3325 : u32 i, j, w, h;
3326 1 : u8 *pY = vs_src->video_buffer;
3327 1 : u8 *pU = vs_src->u_ptr;
3328 1 : u8 *pV = vs_src->v_ptr;
3329 :
3330 1 : if (_src_wnd) {
3331 1 : w = _src_wnd->w;
3332 1 : h = _src_wnd->h;
3333 : } else {
3334 0 : w = vs_src->width;
3335 0 : h = vs_src->height;
3336 : }
3337 :
3338 :
3339 : #ifdef GPAC_HAS_SSE2
3340 :
3341 : #ifdef GPAC_64_BITS
3342 : #define GFINTCAST (u64)
3343 : #else
3344 : #define GFINTCAST (u32)
3345 : #endif
3346 :
3347 1 : if ((w % 32 == 0)
3348 1 : && (GFINTCAST(vs_dst->video_buffer + vs_dst->pitch_y) % 8 == 0)
3349 1 : && (GFINTCAST(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + vs_dst->pitch_y / 2) % 8 == 0)
3350 1 : && (GFINTCAST(pU + vs_src->pitch_y / 2) % 8 == 0)
3351 1 : && (GFINTCAST(pV + vs_src->pitch_y / 2) % 8 == 0)
3352 : ) {
3353 1 : return color_write_yuv422_10_to_yuv_intrin(vs_dst, pY, pU, pV, vs_src->pitch_y, vs_src->width, vs_src->height, _src_wnd, swap_uv);
3354 : }
3355 : #endif
3356 :
3357 0 : if (!pU) {
3358 0 : pU = pY + vs_src->pitch_y * vs_src->height;
3359 0 : pV = pY + 3 * vs_src->pitch_y * vs_src->height/2;
3360 : }
3361 :
3362 0 : if (_src_wnd) {
3363 0 : pY = pY + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3364 0 : pU = pU + (vs_src->pitch_y * _src_wnd->y + _src_wnd->x) / 2;
3365 0 : pV = pV + (vs_src->pitch_y * _src_wnd->y + _src_wnd->x) / 2;
3366 : }
3367 :
3368 0 : if (swap_uv) {
3369 : u8 *t = pV;
3370 : pV = pU;
3371 : pU = t;
3372 : }
3373 :
3374 :
3375 0 : for (i = 0; i<h; i++) {
3376 0 : u16 *src = (u16 *)(pY + i*vs_src->pitch_y);
3377 0 : u8 *dst = (u8 *)vs_dst->video_buffer + i*vs_dst->pitch_y;
3378 :
3379 0 : for (j = 0; j<w; j++) {
3380 0 : *dst = (*src) >> 2;
3381 0 : dst++;
3382 0 : src++;
3383 : }
3384 : }
3385 :
3386 0 : for (i = 0; i<h/2; i++) {
3387 0 : u16 *srcu = (u16 *)(pU + i*vs_src->pitch_y);
3388 0 : u16 *srcv = (u16 *)(pV + i*vs_src->pitch_y);
3389 : u8 *dstu, *dstv;
3390 :
3391 0 : if (vs_dst->u_ptr)
3392 0 : dstu = (u8 *)(vs_dst->u_ptr + i*vs_dst->pitch_y / 2);
3393 : else
3394 0 : dstu = (u8 *)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y / 2;
3395 :
3396 0 : if (vs_dst->v_ptr)
3397 0 : dstv = (u8 *)(vs_dst->v_ptr + i*vs_dst->pitch_y / 2);
3398 : else
3399 0 : dstv = (u8 *)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4 + i*vs_dst->pitch_y / 2;
3400 :
3401 0 : for (j = 0; j<w / 2; j++) {
3402 0 : *dstu = ( (srcu[0] + srcu[1]) / 2) >> 2;
3403 0 : dstu++;
3404 0 : srcu+=2;
3405 :
3406 0 : *dstv = ( (srcv[0] + srcv[1]) / 2) >> 2;
3407 0 : dstv++;
3408 0 : srcv+=2;
3409 : }
3410 : }
3411 :
3412 : return GF_OK;
3413 : }
3414 :
3415 1 : static GF_Err color_write_yuv444_10_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3416 : {
3417 : u32 i, j, w, h;
3418 1 : u8 *pY = vs_src->video_buffer;
3419 1 : u8 *pU = vs_src->u_ptr;
3420 1 : u8 *pV = vs_src->v_ptr;
3421 :
3422 1 : if (_src_wnd) {
3423 1 : w = _src_wnd->w;
3424 1 : h = _src_wnd->h;
3425 : } else {
3426 0 : w = vs_src->width;
3427 0 : h = vs_src->height;
3428 : }
3429 :
3430 :
3431 : #ifdef GPAC_HAS_SSE2
3432 :
3433 : #ifdef GPAC_64_BITS
3434 : #define GFINTCAST (u64)
3435 : #else
3436 : #define GFINTCAST (u32)
3437 : #endif
3438 :
3439 1 : if ( (w % 32 == 0)
3440 1 : && (GFINTCAST(vs_dst->video_buffer + vs_dst->pitch_y) % 8 == 0)
3441 1 : && (GFINTCAST(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + vs_dst->pitch_y) % 8 == 0)
3442 1 : && (GFINTCAST(pU + vs_src->pitch_y) % 8 == 0)
3443 1 : && (GFINTCAST(pV + vs_src->pitch_y) % 8 == 0)
3444 : ) {
3445 1 : return color_write_yuv444_10_to_yuv_intrin(vs_dst, pY, pU, pV, vs_src->pitch_y, vs_src->width, vs_src->height, _src_wnd, swap_uv);
3446 : }
3447 : #endif
3448 :
3449 :
3450 0 : if (!pU) {
3451 0 : pU = pY + vs_src->pitch_y * vs_src->height;
3452 0 : pV = pY + 2 * vs_src->pitch_y * vs_src->height;
3453 : }
3454 :
3455 0 : if (_src_wnd) {
3456 0 : pY = pY + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3457 0 : pU = pU + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3458 0 : pV = pV + vs_src->pitch_y * _src_wnd->y + _src_wnd->x;
3459 : }
3460 :
3461 0 : if (swap_uv) {
3462 : u8 *t = pV;
3463 : pV = pU;
3464 : pU = t;
3465 : }
3466 :
3467 0 : for (i = 0; i<h; i++) {
3468 0 : u16 *src = (u16 *)(pY + i*vs_src->pitch_y);
3469 0 : u8 *dst = (u8 *)vs_dst->video_buffer + i*vs_dst->pitch_y;
3470 :
3471 0 : for (j = 0; j<w; j++) {
3472 0 : *dst = (*src) >> 2;
3473 0 : dst++;
3474 0 : src++;
3475 : }
3476 : }
3477 :
3478 0 : for (i = 0; i<h/2; i++) {
3479 0 : u16 *srcu1 = (u16 *)(pU + 2*i*vs_src->pitch_y );
3480 0 : u16 *srcu2 = (u16 *)(pU + 2*(i+1)*vs_src->pitch_y );
3481 0 : u16 *srcv1 = (u16 *)(pV + 2*i*vs_src->pitch_y );
3482 0 : u16 *srcv2 = (u16 *)(pV + 2*(i+1)*vs_src->pitch_y );
3483 : u8 *dstu, *dstv;
3484 :
3485 0 : if (vs_dst->u_ptr)
3486 0 : dstu = (u8 *)(vs_dst->u_ptr + i*vs_dst->pitch_y / 2);
3487 : else
3488 0 : dstu = (u8 *)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i*vs_dst->pitch_y / 2;
3489 :
3490 0 : if (vs_dst->v_ptr)
3491 0 : dstv = (u8 *)(vs_dst->v_ptr + i*vs_dst->pitch_y / 2);
3492 : else
3493 0 : dstv = (u8 *)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4 + i*vs_dst->pitch_y / 2;
3494 :
3495 0 : for (j = 0; j<w/2 ;j++) {
3496 : u32 u, v;
3497 0 : u = (srcu1[0] + srcu1[1] + srcu2[0] + srcu2[1] ) / 4;
3498 0 : *dstu = u>>2;
3499 0 : dstu++;
3500 0 : srcu1+=2;
3501 0 : srcu2+=2;
3502 :
3503 0 : v = (srcv1[0] + srcv1[1] + srcv2[0] + srcv2[1] ) / 4;
3504 0 : *dstv = v>>2;
3505 0 : dstv++;
3506 0 : srcv1+=2;
3507 0 : srcv2+=2;
3508 : }
3509 : }
3510 : return GF_OK;
3511 : }
3512 :
3513 : static Bool is_planar_yuv(u32 pf)
3514 : {
3515 7 : switch (pf) {
3516 : case GF_PIXEL_YUV:
3517 : case GF_PIXEL_YVU:
3518 : case GF_PIXEL_YUV_10:
3519 : case GF_PIXEL_YUV422:
3520 : case GF_PIXEL_YUV422_10:
3521 : case GF_PIXEL_YUV444:
3522 : case GF_PIXEL_YUV444_10:
3523 : return GF_TRUE;
3524 : }
3525 : return GF_FALSE;
3526 : }
3527 :
3528 :
3529 1 : static GF_Err color_write_yuv420_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3530 : {
3531 : u32 w, h, ox, oy;
3532 1 : u8 *pY = vs_src->video_buffer;
3533 1 : u8 *pU = vs_src->u_ptr;
3534 1 : u8 *pV = vs_src->v_ptr;
3535 :
3536 1 : if (_src_wnd) {
3537 1 : w = _src_wnd->w;
3538 1 : h = _src_wnd->h;
3539 1 : ox = _src_wnd->x;
3540 1 : oy = _src_wnd->y;
3541 : } else {
3542 0 : w = vs_src->width;
3543 0 : h = vs_src->height;
3544 : ox = oy = 0;
3545 : }
3546 :
3547 1 : if (!pU) {
3548 1 : pU = pY + vs_src->pitch_y * vs_src->height;
3549 1 : pV = pY + 5 * vs_src->pitch_y * vs_src->height / 4;
3550 : }
3551 :
3552 :
3553 1 : pY = pY + vs_src->pitch_y * oy + ox;
3554 : /*because of U and V downsampling by 2x2, working with odd Y offset will lead to a half-line shift between Y and UV components. We
3555 : therefore force an even Y offset for U and V planes.*/
3556 1 : pU = pU + (vs_src->pitch_y * (oy / 2) + ox) / 2;
3557 1 : pV = pV + (vs_src->pitch_y * (oy / 2) + ox) / 2;
3558 :
3559 :
3560 1 : if (is_planar_yuv(vs_dst->pixel_format)) {
3561 : /*complete source copy*/
3562 2 : if ((vs_dst->pitch_y == (s32)vs_src->pitch_y) && (w == vs_src->width) && (h == vs_src->height)) {
3563 : assert(!ox);
3564 : assert(!oy);
3565 1 : memcpy(vs_dst->video_buffer, pY, sizeof(u8)*w*h);
3566 1 : if (vs_dst->pixel_format == GF_PIXEL_YUV) {
3567 1 : memcpy(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height, pV, sizeof(u8)*w*h/ 4);
3568 1 : memcpy(vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4, pU, sizeof(u8)*w*h/ 4);
3569 : }
3570 : else {
3571 0 : memcpy(vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height, pU, sizeof(u8)*w*h / 4);
3572 0 : memcpy(vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4, pV, sizeof(u8)*w*h/ 4);
3573 : }
3574 : } else {
3575 : u32 i;
3576 : u8 *dst, *src, *dst2, *src2, *dst3, *src3;
3577 :
3578 : src = pY;
3579 0 : dst = (u8*)vs_dst->video_buffer;
3580 :
3581 0 : src2 = (vs_dst->pixel_format != GF_PIXEL_YUV) ? pU : pV;
3582 0 : dst2 = (u8*)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height;
3583 0 : src3 = (vs_dst->pixel_format != GF_PIXEL_YUV) ? pV : pU;
3584 0 : dst3 = (u8*)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4;
3585 0 : for (i = 0; i<h; i++) {
3586 0 : memcpy(dst, src, w);
3587 0 : src += vs_src->pitch_y;
3588 0 : dst += vs_dst->pitch_y;
3589 0 : if (i<h / 2) {
3590 0 : memcpy(dst2, src2, w / 2);
3591 0 : src2 += vs_src->pitch_y/ 2;
3592 0 : dst2 += vs_dst->pitch_y / 2;
3593 : memcpy(dst3, src3, w / 2);
3594 0 : src3 += vs_src->pitch_y / 2;
3595 0 : dst3 += vs_dst->pitch_y / 2;
3596 : }
3597 : }
3598 : }
3599 : }
3600 0 : else if (vs_dst->pixel_format == GF_PIXEL_UYVY) {
3601 : u32 i, j;
3602 0 : for (i = 0; i<h; i++) {
3603 : u8 *dst, *y, *u, *v;
3604 0 : y = pY + i*vs_src->pitch_y;
3605 0 : u = pU + (i / 2) * vs_src->pitch_y / 2;
3606 0 : v = pV + (i / 2) * vs_src->pitch_y / 2;
3607 0 : dst = (u8 *)vs_dst->video_buffer + i*vs_dst->pitch_y;
3608 :
3609 0 : for (j = 0; j<w / 2; j++) {
3610 0 : *dst = *u;
3611 : dst++;
3612 0 : u++;
3613 0 : *dst = *y;
3614 : dst++;
3615 : y++;
3616 0 : *dst = *v;
3617 : dst++;
3618 0 : v++;
3619 0 : *dst = *y;
3620 0 : dst++;
3621 0 : y++;
3622 : }
3623 : }
3624 : }
3625 0 : else if (vs_dst->pixel_format == GF_PIXEL_VYUY) {
3626 : u32 i, j;
3627 0 : for (i = 0; i<h; i++) {
3628 : u8 *dst, *y, *u, *v;
3629 0 : y = pY + i*vs_src->pitch_y;
3630 0 : u = pU + (i / 2) * vs_src->pitch_y / 2;
3631 0 : v = pV + (i / 2) * vs_src->pitch_y / 2;
3632 0 : dst = (u8 *)vs_dst->video_buffer + i*vs_dst->pitch_y;
3633 :
3634 0 : for (j = 0; j<w / 2; j++) {
3635 0 : *dst = *v;
3636 : dst++;
3637 0 : v++;
3638 0 : *dst = *y;
3639 : dst++;
3640 : y++;
3641 0 : *dst = *u;
3642 : dst++;
3643 0 : u++;
3644 0 : *dst = *y;
3645 0 : dst++;
3646 0 : y++;
3647 : }
3648 : }
3649 : }
3650 0 : else if (vs_dst->pixel_format == GF_PIXEL_YUYV) {
3651 : u32 i, j;
3652 0 : for (i = 0; i<h; i++) {
3653 : u8 *dst, *y, *u, *v;
3654 0 : y = pY + i*vs_src->pitch_y;
3655 0 : u = pU + (i / 2) * vs_src->pitch_y / 2;
3656 0 : v = pV + (i / 2) * vs_src->pitch_y / 2;
3657 0 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
3658 :
3659 0 : for (j = 0; j<w / 2; j++) {
3660 0 : *dst = *y;
3661 : dst++;
3662 : y++;
3663 0 : *dst = *u;
3664 : dst++;
3665 0 : u++;
3666 0 : *dst = *y;
3667 : dst++;
3668 0 : y++;
3669 0 : *dst = *v;
3670 0 : dst++;
3671 0 : v++;
3672 : }
3673 : }
3674 : }
3675 0 : else if (vs_dst->pixel_format == GF_PIXEL_YVYU) {
3676 : u32 i, j;
3677 0 : for (i = 0; i<h; i++) {
3678 : u8 *dst, *y, *u, *v;
3679 0 : y = pY + i*vs_src->pitch_y;
3680 0 : u = pU + (i / 2) * vs_src->pitch_y / 2;
3681 0 : v = pV + (i / 2) * vs_src->pitch_y / 2;
3682 0 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
3683 :
3684 0 : for (j = 0; j<w / 2; j++) {
3685 0 : *dst = *y;
3686 : dst++;
3687 : y++;
3688 0 : *dst = *v;
3689 : dst++;
3690 0 : v++;
3691 0 : *dst = *y;
3692 : dst++;
3693 0 : y++;
3694 0 : *dst = *u;
3695 0 : dst++;
3696 0 : u++;
3697 : }
3698 : }
3699 : }
3700 : else {
3701 : return GF_NOT_SUPPORTED;
3702 : }
3703 : return GF_OK;
3704 : }
3705 :
3706 1 : static GF_Err color_write_yuv422_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3707 : {
3708 : u32 w, h, ox, oy;
3709 1 : u8 *pY = vs_src->video_buffer;
3710 1 : u8 *pU = vs_src->u_ptr;
3711 1 : u8 *pV = vs_src->v_ptr;
3712 :
3713 1 : if (_src_wnd) {
3714 1 : w = _src_wnd->w;
3715 1 : h = _src_wnd->h;
3716 1 : ox = _src_wnd->x;
3717 1 : oy = _src_wnd->y;
3718 : }
3719 : else {
3720 0 : w = vs_src->width;
3721 0 : h = vs_src->height;
3722 : ox = oy = 0;
3723 : }
3724 :
3725 1 : if (!pU) {
3726 1 : pU = pY + vs_src->pitch_y * vs_src->height;
3727 1 : pV = pY + 3 * vs_src->pitch_y * vs_src->height / 2;
3728 : }
3729 :
3730 :
3731 1 : pY = pY + vs_src->pitch_y * oy + ox;
3732 1 : pU = pU + (vs_src->pitch_y * oy + ox) / 2;
3733 1 : pV = pV + (vs_src->pitch_y * oy + ox) / 2;
3734 :
3735 :
3736 1 : if (is_planar_yuv(vs_dst->pixel_format)) {
3737 : /*complete source copy*/
3738 : u32 i;
3739 : u8 *dst, *src, *dst2, *src2, *dst3, *src3, *_src2, *_src3;
3740 :
3741 : src = pY;
3742 1 : _src2 = (vs_dst->pixel_format != GF_PIXEL_YUV) ? pU : pV;
3743 1 : _src3 = (vs_dst->pixel_format != GF_PIXEL_YUV) ? pV : pU;
3744 1 : dst = (u8*)vs_dst->video_buffer;
3745 1 : dst2 = (u8*)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height;
3746 1 : dst3 = (u8*)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4;
3747 128 : for (i = 0; i<h; i++) {
3748 128 : memcpy(dst, src, w);
3749 128 : src += vs_src->pitch_y;
3750 128 : dst += vs_dst->pitch_y;
3751 128 : if (i < h / 2) {
3752 64 : src2 = _src2 + i*vs_src->pitch_y;
3753 64 : src3 = _src3 + i*vs_src->pitch_y;
3754 64 : memcpy(dst2, src2, w / 2);
3755 : memcpy(dst3, src3, w / 2);
3756 64 : dst2 += vs_dst->pitch_y / 2;
3757 64 : dst3 += vs_dst->pitch_y / 2;
3758 : }
3759 : }
3760 : return GF_OK;
3761 : }
3762 : return GF_NOT_SUPPORTED;
3763 : }
3764 :
3765 :
3766 1 : static GF_Err color_write_yuv444_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3767 : {
3768 : u32 w, h, ox, oy;
3769 1 : u8 *pY = vs_src->video_buffer;
3770 1 : u8 *pU = vs_src->u_ptr;
3771 1 : u8 *pV = vs_src->v_ptr;
3772 :
3773 1 : if (_src_wnd) {
3774 1 : w = _src_wnd->w;
3775 1 : h = _src_wnd->h;
3776 1 : ox = _src_wnd->x;
3777 1 : oy = _src_wnd->y;
3778 : }
3779 : else {
3780 0 : w = vs_src->width;
3781 0 : h = vs_src->height;
3782 : ox = oy = 0;
3783 : }
3784 :
3785 1 : if (!pU) {
3786 1 : pU = pY + vs_src->pitch_y* vs_src->height;
3787 1 : pV = pY + 2 * vs_src->pitch_y * vs_src->height;
3788 : }
3789 :
3790 1 : pY = pY + vs_src->pitch_y * oy + ox;
3791 1 : pU = pU + vs_src->pitch_y * oy + ox;
3792 1 : pV = pV + vs_src->pitch_y * oy + ox;
3793 :
3794 1 : if (is_planar_yuv(vs_dst->pixel_format)) {
3795 : /*complete source copy*/
3796 : u32 i, j;
3797 : u8 *dst, *src, *_src2, *_src3;
3798 :
3799 : src = pY;
3800 1 : _src2 = (vs_dst->pixel_format != GF_PIXEL_YUV) ? pU : pV;
3801 1 : _src3 = (vs_dst->pixel_format != GF_PIXEL_YUV) ? pV : pU;
3802 1 : dst = (u8*)vs_dst->video_buffer;
3803 :
3804 128 : for (i = 0; i<h; i++) {
3805 128 : memcpy(dst, src, w);
3806 128 : src += vs_src->pitch_y;
3807 128 : dst += vs_dst->pitch_y;
3808 :
3809 : }
3810 64 : for (i = 0; i < h / 2; i++) {
3811 : u8 *dst2, *src2, *dst3, *src3;
3812 64 : src2 = _src2 + 2 * i*vs_src->pitch_y;
3813 64 : dst2 = (u8*)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height + i* vs_dst->pitch_y / 2;
3814 64 : src3 = _src3 + 2 * i*vs_src->pitch_y;
3815 64 : dst3 = (u8*)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4 + i* vs_dst->pitch_y / 2;
3816 4096 : for (j = 0; j<w / 2; j++) {
3817 4096 : *dst2 = *src2;
3818 4096 : dst2++;
3819 4096 : src2 += 2;
3820 :
3821 4096 : *dst3 = *src3;
3822 4096 : dst3++;
3823 4096 : src3 += 2;
3824 : }
3825 : }
3826 : return GF_OK;
3827 : }
3828 : return GF_NOT_SUPPORTED;
3829 : }
3830 :
3831 4 : static GF_Err color_write_yvyu_to_yuv(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd, Bool swap_uv)
3832 : {
3833 : u32 i, j;
3834 : u32 w, h, ox, oy;
3835 : u8 *pY, *pU, *pV;
3836 :
3837 4 : if (_src_wnd) {
3838 4 : w = _src_wnd->w;
3839 4 : h = _src_wnd->h;
3840 4 : ox = _src_wnd->x;
3841 4 : oy = _src_wnd->y;
3842 : }
3843 : else {
3844 0 : w = vs_src->width;
3845 0 : h = vs_src->height;
3846 : ox = oy = 0;
3847 : }
3848 :
3849 4 : switch (vs_src->pixel_format) {
3850 1 : case GF_PIXEL_UYVY:
3851 1 : pU = vs_src->video_buffer + vs_src->pitch_y* oy + ox;
3852 1 : pY = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 1;
3853 1 : pV = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 3;
3854 : break;
3855 1 : case GF_PIXEL_YUYV:
3856 1 : pY = vs_src->video_buffer + vs_src->pitch_y * oy + ox;
3857 1 : pU = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 1;
3858 1 : pV = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 3;
3859 : break;
3860 1 : case GF_PIXEL_YVYU:
3861 1 : pY = vs_src->video_buffer + vs_src->pitch_y * oy + ox;
3862 1 : pV = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 1;
3863 1 : pU = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 3;
3864 : break;
3865 1 : case GF_PIXEL_VYUY:
3866 1 : pV = vs_src->video_buffer + vs_src->pitch_y* oy + ox;
3867 1 : pY = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 1;
3868 1 : pU = vs_src->video_buffer + vs_src->pitch_y * oy + ox + 3;
3869 : break;
3870 : default:
3871 : return GF_NOT_SUPPORTED;
3872 : }
3873 :
3874 4 : if (is_planar_yuv(vs_dst->pixel_format)) {
3875 : u8 *dst_y, *dst_u, *dst_v;
3876 :
3877 4 : dst_y = (u8*)vs_dst->video_buffer;
3878 4 : if (vs_dst->pixel_format == GF_PIXEL_YUV) {
3879 4 : dst_v = (u8*)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height;
3880 4 : dst_u = (u8*)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4;
3881 : }
3882 : else {
3883 0 : dst_u = (u8*)vs_dst->video_buffer + vs_dst->pitch_y * vs_dst->height;
3884 0 : dst_v = (u8*)vs_dst->video_buffer + 5 * vs_dst->pitch_y * vs_dst->height / 4;
3885 : }
3886 512 : for (i = 0; i<h; i++) {
3887 32768 : for (j = 0; j<w; j += 2) {
3888 32768 : *dst_y = *pY;
3889 32768 : *(dst_y + 1) = *(pY + 2);
3890 32768 : dst_y += 2;
3891 32768 : pY += 4;
3892 32768 : if (i % 2) continue;
3893 :
3894 16384 : *dst_u = (*pU + *(pU + vs_src->pitch_y)) / 2;
3895 16384 : *dst_v = (*pV + *(pV + vs_src->pitch_y)) / 2;
3896 16384 : dst_u++;
3897 16384 : dst_v++;
3898 16384 : pU += 4;
3899 16384 : pV += 4;
3900 : }
3901 512 : if (i % 2) {
3902 256 : pU += vs_src->pitch_y;
3903 256 : pV += vs_src->pitch_y;
3904 : }
3905 : }
3906 : return GF_OK;
3907 : }
3908 :
3909 0 : if (vs_src->pixel_format == vs_dst->pixel_format) {
3910 0 : for (i = 0; i<h; i++) {
3911 0 : char *dst = vs_dst->video_buffer + i*vs_dst->pitch_y;
3912 0 : pY = vs_src->video_buffer + vs_src->pitch_y * (i + oy) + ox;
3913 0 : memcpy(dst, pY, sizeof(char) * 2 * w);
3914 : }
3915 : return GF_OK;
3916 : }
3917 :
3918 0 : for (i = 0; i<h; i++) {
3919 0 : u8 *dst = vs_dst->video_buffer + i*vs_dst->pitch_y;
3920 0 : u8 *y = pY + vs_src->pitch_y * i;
3921 0 : u8 *u = pU + vs_src->pitch_y * i;
3922 0 : u8 *v = pV + vs_src->pitch_y * i;
3923 0 : switch (vs_dst->pixel_format) {
3924 : case GF_PIXEL_UYVY:
3925 0 : for (j = 0; j<w; j += 2) {
3926 0 : dst[0] = *u;
3927 0 : dst[1] = *y;
3928 0 : dst[2] = *v;
3929 0 : dst[3] = *(y + 2);
3930 0 : dst += 4;
3931 0 : y += 4;
3932 0 : u += 4;
3933 0 : v += 4;
3934 : }
3935 : break;
3936 : case GF_PIXEL_YVYU:
3937 0 : for (j = 0; j<w; j += 2) {
3938 0 : dst[0] = *y;
3939 0 : dst[1] = *v;
3940 0 : dst[2] = *(y + 2);
3941 0 : dst[3] = *u;
3942 0 : dst += 4;
3943 0 : y += 4;
3944 0 : u += 4;
3945 0 : v += 4;
3946 : }
3947 : break;
3948 : case GF_PIXEL_YUYV:
3949 0 : for (j = 0; j<w; j += 2) {
3950 0 : dst[0] = *y;
3951 0 : dst[1] = *u;
3952 0 : dst[2] = *(y + 2);
3953 0 : dst[3] = *v;
3954 0 : dst += 4;
3955 0 : y += 4;
3956 0 : u += 4;
3957 0 : v += 4;
3958 : }
3959 : break;
3960 : case GF_PIXEL_VYUY:
3961 0 : for (j = 0; j<w; j += 2) {
3962 0 : dst[0] = *v;
3963 0 : dst[1] = *y;
3964 0 : dst[2] = *u;
3965 0 : dst[3] = *(y + 2);
3966 0 : dst += 4;
3967 0 : y += 4;
3968 0 : u += 4;
3969 0 : v += 4;
3970 : }
3971 : break;
3972 : default:
3973 : return GF_NOT_SUPPORTED;
3974 : }
3975 : }
3976 : return GF_OK;
3977 : }
3978 :
3979 :
3980 10 : u32 get_bpp(u32 pf)
3981 : {
3982 10 : switch (pf) {
3983 : case GF_PIXEL_RGB_555:
3984 : case GF_PIXEL_RGB_565:
3985 : return 2;
3986 6 : case GF_PIXEL_RGB:
3987 : case GF_PIXEL_RGBS:
3988 : case GF_PIXEL_BGR:
3989 6 : return 3;
3990 0 : case GF_PIXEL_RGBX:
3991 : case GF_PIXEL_BGRX:
3992 : case GF_PIXEL_XRGB:
3993 : case GF_PIXEL_XBGR:
3994 : case GF_PIXEL_ARGB:
3995 : case GF_PIXEL_RGBAS:
3996 : case GF_PIXEL_RGBD:
3997 : case GF_PIXEL_RGBDS:
3998 0 : return 4;
3999 : }
4000 4 : return 0;
4001 : }
4002 :
4003 69 : static GF_Err color_write_rgb_to_24(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd)
4004 : {
4005 : u32 i;
4006 : u32 w, h, ox, oy;
4007 : u8 *src;
4008 : u32 BPP;
4009 :
4010 69 : if (vs_src->pixel_format != vs_dst->pixel_format) return GF_NOT_SUPPORTED;
4011 2 : BPP = get_bpp(vs_src->pixel_format);
4012 2 : if (!BPP) return GF_NOT_SUPPORTED;
4013 :
4014 2 : if (_src_wnd) {
4015 2 : w = _src_wnd->w;
4016 2 : h = _src_wnd->h;
4017 2 : ox = _src_wnd->x;
4018 2 : oy = _src_wnd->y;
4019 : } else {
4020 0 : w = vs_src->width;
4021 0 : h = vs_src->height;
4022 : ox = oy = 0;
4023 : }
4024 :
4025 : /*go to start of src*/
4026 2 : src = vs_src->video_buffer + vs_src->pitch_x * oy + BPP * ox;
4027 :
4028 258 : for (i = 0; i<h; i++) {
4029 256 : memcpy(vs_dst->video_buffer + i*vs_dst->pitch_y, src, sizeof(u8) * BPP * w);
4030 256 : src += vs_src->pitch_y;
4031 : }
4032 : return GF_OK;
4033 : }
4034 :
4035 :
4036 8 : static GF_Err color_write_rgb_to_32(GF_VideoSurface *vs_dst, GF_VideoSurface *vs_src, GF_Window *_src_wnd)
4037 : {
4038 : u32 i, j, w, h, ox, oy;
4039 : u8 *src;
4040 : Bool isBGR;
4041 : u8 *dst, *cur;
4042 8 : u32 BPP = get_bpp(vs_src->pixel_format);
4043 8 : if (!BPP) return GF_NOT_SUPPORTED;
4044 :
4045 4 : if (_src_wnd) {
4046 4 : w = _src_wnd->w;
4047 4 : h = _src_wnd->h;
4048 4 : ox = _src_wnd->x;
4049 4 : oy = _src_wnd->y;
4050 : }
4051 : else {
4052 0 : w = vs_src->width;
4053 0 : h = vs_src->height;
4054 : ox = oy = 0;
4055 : }
4056 :
4057 : /*go to start of src*/
4058 4 : src = vs_src->video_buffer + vs_src->pitch_y * oy + BPP * ox;
4059 :
4060 4 : if (vs_src->pixel_format == vs_dst->pixel_format) {
4061 0 : for (i = 0; i<h; i++) {
4062 0 : memcpy(vs_dst->video_buffer + i*vs_dst->pitch_y, src, sizeof(u8) * BPP * w);
4063 : }
4064 : return GF_OK;
4065 : }
4066 : /*get all pixels*/
4067 : isBGR = (vs_dst->pixel_format == GF_PIXEL_BGRX) ? GF_TRUE : GF_FALSE;
4068 4 : if (isBGR) {
4069 1 : switch (vs_src->pixel_format) {
4070 : case GF_PIXEL_RGB:
4071 : case GF_PIXEL_RGBS:
4072 128 : for (i = 0; i<h; i++) {
4073 128 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
4074 128 : cur = src + i*vs_src->pitch_y;
4075 16512 : for (j = 0; j<w; j++) {
4076 16384 : dst[0] = *cur++;
4077 16384 : dst[1] = *cur++;
4078 16384 : dst[2] = *cur++;
4079 16384 : dst += 4;
4080 : }
4081 : }
4082 : break;
4083 : case GF_PIXEL_RGBDS:
4084 : case GF_PIXEL_RGBD:
4085 0 : for (i = 0; i<h; i++) {
4086 0 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
4087 0 : cur = src + i*vs_src->pitch_y;
4088 0 : for (j = 0; j<w; j++) {
4089 0 : dst[0] = *cur++;
4090 0 : dst[1] = *cur++;
4091 0 : dst[2] = *cur++;
4092 0 : cur++;
4093 0 : dst += 4;
4094 : }
4095 : }
4096 : break;
4097 : case GF_PIXEL_BGR:
4098 0 : for (i = 0; i<h; i++) {
4099 0 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
4100 0 : cur = src + i*vs_src->pitch_y;
4101 0 : for (j = 0; j<w; j++) {
4102 0 : dst[2] = *cur++;
4103 0 : dst[1] = *cur++;
4104 0 : dst[0] = *cur++;
4105 0 : dst += 4;
4106 : }
4107 : }
4108 : break;
4109 : default:
4110 : return GF_NOT_SUPPORTED;
4111 : }
4112 : }
4113 : else {
4114 3 : switch (vs_src->pixel_format) {
4115 : case GF_PIXEL_RGB:
4116 : case GF_PIXEL_RGBS:
4117 384 : for (i = 0; i<h; i++) {
4118 384 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
4119 384 : cur = src + i*vs_src->pitch_y;
4120 49536 : for (j = 0; j<w; j++) {
4121 49152 : dst[2] = *cur++;
4122 49152 : dst[1] = *cur++;
4123 49152 : dst[0] = *cur++;
4124 49152 : dst += 4;
4125 : }
4126 : }
4127 : break;
4128 : case GF_PIXEL_RGBD:
4129 : case GF_PIXEL_RGBDS:
4130 0 : for (i = 0; i<h; i++) {
4131 0 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
4132 0 : cur = src + i*vs_src->pitch_y;
4133 0 : for (j = 0; j<w; j++) {
4134 0 : dst[2] = *cur++;
4135 0 : dst[1] = *cur++;
4136 0 : dst[0] = *cur++;
4137 0 : cur++;
4138 0 : dst += 4;
4139 : }
4140 : }
4141 : break;
4142 : case GF_PIXEL_BGR:
4143 0 : for (i = 0; i<h; i++) {
4144 0 : dst = (u8*)vs_dst->video_buffer + i*vs_dst->pitch_y;
4145 0 : cur = src + i*vs_src->pitch_y;
4146 0 : for (j = 0; j<w; j++) {
4147 0 : dst[0] = *cur++;
4148 0 : dst[1] = *cur++;
4149 0 : dst[2] = *cur++;
4150 0 : dst += 4;
4151 : }
4152 : }
4153 : break;
4154 : default:
4155 : return GF_NOT_SUPPORTED;
4156 : }
4157 : }
4158 : return GF_OK;
4159 : }
4160 :
4161 : #endif
4162 :
4163 :
4164 : /* Basic SVG datatype parsing functions */
4165 : static const struct predef_col {
4166 : const char *name;
4167 : u8 r;
4168 : u8 g;
4169 : u8 b;
4170 : } predefined_colors[] =
4171 : {
4172 : {"aliceblue",240, 248, 255},
4173 : {"antiquewhite",250, 235, 215},
4174 : {"aquamarine",127, 255, 212},
4175 : {"azure",240, 255, 255},
4176 : {"beige",245, 245, 220},
4177 : {"bisque",255, 228, 196},
4178 : {"black", 0, 0, 0},
4179 : {"blanchedalmond",255, 235, 205},
4180 : {"blue", 0, 0, 255},
4181 : {"blueviolet",138, 43, 226},
4182 : {"brown",165, 42, 42},
4183 : {"burlywood",222, 184, 135},
4184 : {"cadetblue", 95, 158, 160},
4185 : {"chartreuse",127, 255, 0},
4186 : {"chocolate",210, 105, 30},
4187 : {"coral",255, 127, 80},
4188 : {"lightpink",255, 182, 193},
4189 : {"lightsalmon",255, 160, 122},
4190 : {"lightseagreen", 32, 178, 170},
4191 : {"lightskyblue",135, 206, 250},
4192 : {"lightslategray",119, 136, 153},
4193 : {"lightslategrey",119, 136, 153},
4194 : {"lightsteelblue",176, 196, 222},
4195 : {"lightyellow",255, 255, 224},
4196 : {"lime", 0, 255, 0},
4197 : {"limegreen", 50, 205, 50},
4198 : {"linen",250, 240, 230},
4199 : {"magenta",255, 0, 255},
4200 : {"maroon",128, 0, 0},
4201 : {"mediumaquamarine",102, 205, 170},
4202 : {"mediumblue", 0, 0, 205},
4203 : {"mediumorchid",186, 85, 211},
4204 : {"cornflowerblue",100, 149, 237},
4205 : {"cornsilk",255, 248, 220},
4206 : {"crimson",220, 20, 60},
4207 : {"cyan", 0, 255, 255},
4208 : {"darkblue", 0, 0, 139},
4209 : {"darkcyan", 0, 139, 139},
4210 : {"darkgoldenrod",184, 134, 11},
4211 : {"darkgray",169, 169, 169},
4212 : {"darkgreen", 0, 100, 0},
4213 : {"darkgrey",169, 169, 169},
4214 : {"darkkhaki",189, 183, 107},
4215 : {"darkmagenta",139, 0, 139},
4216 : {"darkolivegreen", 85, 107, 47},
4217 : {"darkorange",255, 140, 0},
4218 : {"darkorchid",153, 50, 204},
4219 : {"darkred",139, 0, 0},
4220 : {"darksalmon",233, 150, 122},
4221 : {"darkseagreen",143, 188, 143},
4222 : {"darkslateblue", 72, 61, 139},
4223 : {"darkslategray", 47, 79, 79},
4224 : {"darkslategrey", 47, 79, 79},
4225 : {"darkturquoise", 0, 206, 209},
4226 : {"darkviolet",148, 0, 211},
4227 : {"deeppink",255, 20, 147},
4228 : {"deepskyblue", 0, 191, 255},
4229 : {"dimgray",105, 105, 105},
4230 : {"dimgrey",105, 105, 105},
4231 : {"dodgerblue", 30, 144, 255},
4232 : {"firebrick",178, 34, 34},
4233 : {"floralwhite",255, 250, 240},
4234 : {"forestgreen", 34, 139, 34},
4235 : {"fuchsia",255, 0, 255},
4236 : {"gainsboro",220, 220, 220},
4237 : {"ghostwhite",248, 248, 255},
4238 : {"gold",255, 215, 0},
4239 : {"goldenrod",218, 165, 32},
4240 : {"gray",128, 128, 128},
4241 : {"grey",128, 128, 128},
4242 : {"green", 0, 128, 0},
4243 : {"greenyellow",173, 255, 47},
4244 : {"honeydew",240, 255, 240},
4245 : {"hotpink",255, 105, 180},
4246 : {"indianred",205, 92, 92},
4247 : {"indigo", 75, 0, 130},
4248 : {"ivory",255, 255, 240},
4249 : {"khaki",240, 230, 140},
4250 : {"lavender",230, 230, 25},
4251 : {"lavenderblush",255, 240, 245},
4252 : {"mediumpurple",147, 112, 219},
4253 : {"mediumseagreen", 60, 179, 113},
4254 : {"mediumslateblue",123, 104, 238},
4255 : {"mediumspringgreen", 0, 250, 154},
4256 : {"mediumturquoise", 72, 209, 204},
4257 : {"mediumvioletred",199, 21, 133},
4258 : {"midnightblue", 25, 25, 112},
4259 : {"mintcream",245, 255, 250},
4260 : {"mistyrose",255, 228, 225},
4261 : {"moccasin",255, 228, 181},
4262 : {"navajowhite",255, 222, 173},
4263 : {"navy", 0, 0, 128},
4264 : {"oldlace",253, 245, 230},
4265 : {"olive",128, 128, 0},
4266 : {"olivedrab",107, 142, 35},
4267 : {"orange",255, 165, 0},
4268 : {"orangered",255, 69, 0},
4269 : {"orchid",218, 112, 214},
4270 : {"palegoldenrod",238, 232, 170},
4271 : {"palegreen",152, 251, 152},
4272 : {"paleturquoise",175, 238, 238},
4273 : {"palevioletred",219, 112, 147},
4274 : {"papayawhip",255, 239, 213},
4275 : {"peachpuff",255, 218, 185},
4276 : {"peru",205, 133, 63},
4277 : {"pink",255, 192, 203},
4278 : {"plum",221, 160, 221},
4279 : {"powderblue",176, 224, 230},
4280 : {"purple",128, 0, 128},
4281 : {"red",255, 0, 0},
4282 : {"rosybrown",188, 143, 143},
4283 : {"royalblue", 65, 105, 225},
4284 : {"saddlebrown",139, 69, 19},
4285 : {"salmon",250, 128, 114},
4286 : {"sandybrown",244, 164, 96},
4287 : {"seagreen", 46, 139, 87},
4288 : {"seashell",255, 245, 238},
4289 : {"sienna",160, 82, 45},
4290 : {"silver",192, 192, 192},
4291 : {"skyblue",135, 206, 235},
4292 : {"slateblue",106, 90, 205},
4293 : {"slategray",112, 128, 144},
4294 : {"slategrey",112, 128, 144},
4295 : {"snow",255, 250, 250},
4296 : {"springgreen", 0, 255, 127},
4297 : {"steelblue", 70, 130, 180},
4298 : {"tan",210, 180, 140},
4299 : {"teal", 0, 128, 128},
4300 : {"lawngreen",124, 252, 0},
4301 : {"lemonchiffon",255, 250, 205},
4302 : {"lightblue",173, 216, 230},
4303 : {"lightcoral",240, 128, 128},
4304 : {"lightcyan",224, 255, 255},
4305 : {"lightgoldenrodyellow",250, 250, 210},
4306 : {"lightgray",211, 211, 211},
4307 : {"lightgreen",144, 238, 144},
4308 : {"lightgrey",211, 211, 211},
4309 : {"thistle",216, 191, 216},
4310 : {"tomato",255, 99, 71},
4311 : {"turquoise", 64, 224, 208},
4312 : {"violet",238, 130, 238},
4313 : {"wheat",245, 222, 179},
4314 : {"white",255, 255, 255},
4315 : {"whitesmoke",245, 245, 245},
4316 : {"yellow",255, 255, 0},
4317 : {"yellowgreen",154, 205, 50},
4318 : {"aqua", 0, 255, 255},
4319 :
4320 : };
4321 :
4322 :
4323 : GF_EXPORT
4324 1211 : GF_Color gf_color_parse(const char *name)
4325 : {
4326 : u32 i, count;
4327 : u32 res;
4328 1211 : if ((name[0]=='$') || (name[0]=='#')) {
4329 13 : sscanf(name+1, "%x", &res);
4330 13 : return res | 0xFF000000;
4331 : }
4332 1198 : if (!strnicmp(name, "0x", 2) ) {
4333 0 : sscanf(name+2, "%x", &res);
4334 0 : return res | 0xFF000000;
4335 : }
4336 :
4337 : count = sizeof(predefined_colors) / sizeof(struct predef_col);
4338 75253 : for (i=0; i<count; i++) {
4339 76451 : if (!strcmp(name, predefined_colors[i].name)) {
4340 1198 : res = GF_COL_ARGB(0xFF, predefined_colors[i].r, predefined_colors[i].g, predefined_colors[i].b);
4341 1198 : return res;
4342 : }
4343 : }
4344 :
4345 : return 0;
4346 :
4347 : }
4348 :
4349 : GF_EXPORT
4350 114 : const char *gf_color_get_name(GF_Color col)
4351 : {
4352 : u32 i, count;
4353 : u8 r, g, b;
4354 :
4355 114 : r = GF_COL_R(col);
4356 114 : g = GF_COL_G(col);
4357 114 : b = GF_COL_B(col);
4358 :
4359 : count = sizeof(predefined_colors) / sizeof(struct predef_col);
4360 9784 : for (i=0; i<count; i++) {
4361 9758 : if (predefined_colors[i].r != r) continue;
4362 1304 : if (predefined_colors[i].g != g) continue;
4363 208 : if (predefined_colors[i].b != b) continue;
4364 88 : return predefined_colors[i].name;
4365 : }
4366 : return NULL;
4367 : }
4368 :
4369 :
4370 : GF_EXPORT
4371 148 : Bool gf_color_enum(u32 *idx, GF_Color *col, const char **color_name)
4372 : {
4373 : u32 count = sizeof(predefined_colors) / sizeof(struct predef_col);
4374 148 : if (*idx>=count) return GF_FALSE;
4375 147 : if (col) *col = GF_COL_ARGB(0xFF, predefined_colors[*idx].r, predefined_colors[*idx].g, predefined_colors[*idx].b);
4376 147 : if (color_name) *color_name = predefined_colors[*idx].name;
4377 147 : (*idx)++;
4378 147 : return GF_TRUE;
4379 : }
|