Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2019
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / software 2D rasterizer module
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 :
28 : #include "rast_soft.h"
29 :
30 : //TODO: support for color spaces, support for more than 10 bits and BigEndian format ?
31 :
32 : #if 1
33 :
34 : #define mul255(_a, _b) ( (((u32)(_a) + 1) * (u32)(_b) ) >> 8)
35 :
36 : #else
37 : static s32
38 : mul255(s32 a, s32 b)
39 : {
40 : return ((a + 1) * b) >> 8;
41 : }
42 : #endif
43 :
44 : static s32
45 : mul255_zero(s32 a, s32 b)
46 : {
47 1062636 : if (!a) return 0;
48 726794 : return ((a + 1) * b) >> 8;
49 : }
50 :
51 : //RGB <-> YUV full range conversion, using integer (1024 factor)
52 : #define YUV_USE_INT
53 :
54 1498 : void gf_evg_rgb_to_yuv(GF_EVGSurface *surf, GF_Color col, u8*y, u8*cb, u8*cr)
55 : {
56 1498 : u32 r = GF_COL_R(col);
57 1498 : u32 g = GF_COL_G(col);
58 : u32 b = GF_COL_B(col);
59 :
60 : #ifndef YUV_USE_INT
61 : *y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
62 : *cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
63 : *cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
64 : #else
65 1498 : u32 _v = 306*r + 601 * g + 117 * b;
66 1498 : *y = (u8) (_v >> 10);
67 1498 : _v = (-173*(s32)r - 339*(s32)g + 511*b + 131072);
68 1498 : *cb = (u8) (_v >> 10);
69 1498 : _v = (511 * r - 428*(s32)g - 83*(s32)b + 131072);
70 1498 : *cr = (u8) (_v >> 10);
71 : #endif
72 1498 : }
73 4344554 : GF_Color gf_evg_argb_to_ayuv(GF_EVGSurface *surf, GF_Color col)
74 : {
75 : u8 a, y, cb, cr;
76 : a = GF_COL_A(col);
77 4344554 : u32 r = GF_COL_R(col);
78 4344554 : u32 g = GF_COL_G(col);
79 : u32 b = GF_COL_B(col);
80 :
81 : #ifndef YUV_USE_INT
82 : y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
83 : cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
84 : cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
85 : #else
86 4344554 : u32 _v = 306*r + 601 * g + 117 * b;
87 4344554 : y = (u8) (_v >> 10);
88 4344554 : _v = (-173*(s32)r - 339*(s32)g + 511*b + 131072);
89 4344554 : cb = (u8) (_v >> 10);
90 4344554 : _v = (511 * r - 428*(s32)g - 83*(s32)b + 131072);
91 4344554 : cr = (u8) (_v >> 10);
92 : #endif
93 4344554 : return GF_COL_ARGB(a, y, cb, cr);
94 : }
95 :
96 2 : GF_Err gf_gf_evg_rgb_to_yuv_f(GF_EVGSurface *surf, Float r, Float g, Float b, Float *y, Float *cb, Float *cr)
97 : {
98 2 : *y = (0.299f * r + 0.587f * g + 0.114f * b);
99 2 : *cb = (-0.169f * (s32)r - 0.331f * (s32)g + 0.499f * b + 128.0f);
100 2 : *cr = (0.499f * r - 0.418f * (s32)g - 0.0813f * (s32)b + 128.0f);
101 2 : return GF_OK;
102 : }
103 2 : GF_Err gf_evg_yuv_to_rgb_f(GF_EVGSurface *surf, Float y, Float cb, Float cr, Float *r, Float *g, Float *b)
104 : {
105 2 : *r = (y + 1.402f * (cr - 128.0f));
106 2 : *g = (y - 0.344136f * (cb - 128.0f) - 0.714136f * (cr-128.0f) );
107 2 : *b = (y + 1.772f * (cb - 128.0f) );
108 2 : return GF_OK;
109 : }
110 :
111 1237678 : GF_Color gf_evg_ayuv_to_argb(GF_EVGSurface *surf, GF_Color col)
112 : {
113 : u32 a;
114 : s32 y, cb, cr;
115 : s32 r, g, b;
116 : a = GF_COL_A(col);
117 1237678 : y = GF_COL_R(col);
118 1237678 : cb = GF_COL_G(col);
119 1237678 : cr = GF_COL_B(col);
120 :
121 : #ifndef YUV_USE_INT
122 : r = (s32) (y + 1.402 * (cr - 128));
123 : g = (s32) (y - 0.344136 * (cb - 128) - 0.714136*(cr-128) );
124 : b = (s32) (y + 1.772 * (cb - 128) );
125 :
126 : #define TRUNC_8BIT(_a) if (_a<0) {_a = 0;} else if (_a>255) {_a=255;}
127 : TRUNC_8BIT(r)
128 : TRUNC_8BIT(g)
129 : TRUNC_8BIT(b)
130 :
131 : #else
132 1237678 : y *= 1024;
133 1237678 : r = (s32) (y + 1436 * (cr - 128));
134 1237678 : g = (s32) (y - 352 * (cb - 128) - 731*(cr-128) );
135 1237678 : b = (s32) (y + 1814 * (cb - 128) );
136 :
137 : #define TRUNC_8BIT(_a) if (_a<0) {_a = 0;} else { u32 __a = (u32) _a; __a>>=10; if (__a>255) {__a=255;} _a = __a; }
138 1237678 : TRUNC_8BIT(r)
139 1237678 : TRUNC_8BIT(g)
140 1237678 : TRUNC_8BIT(b)
141 :
142 : #endif
143 :
144 :
145 1237678 : return GF_COL_ARGB(a, r, g, b);
146 : }
147 :
148 584425 : u64 gf_evg_argb_to_ayuv_wide(GF_EVGSurface *surf, u64 col)
149 : {
150 : u16 a, y, cb, cr;
151 : u32 r, g, b;
152 :
153 : a = (col>>48)&0xFFFF;
154 584425 : r = (col>>32)&0xFFFF;
155 584425 : g = (col>>16)&0xFFFF;
156 584425 : b = (col)&0xFFFF;
157 :
158 : #ifndef YUV_USE_INT
159 : y = (u16) (0.299*r + 0.587 * g + 0.114 * b);
160 : cb = (u16) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 32768);
161 : cr = (u16) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 32768);
162 : #else
163 584425 : u32 _v = 306*r + 601 * g + 117 * b;
164 584425 : y = (u16) (_v >> 10);
165 584425 : _v = (-173*(s32)r - 339*(s32)g + 511*b + 33554432);
166 584425 : cb = (u16) (_v >> 10);
167 584425 : _v = (511 * r - 428*(s32)g - 83*(s32)b + 33554432);
168 584425 : cr = (u16) (_v >> 10);
169 : #endif
170 :
171 :
172 584425 : return evg_make_col_wide(a, y, cb, cr);
173 : }
174 2 : u64 gf_evg_ayuv_to_argb_wide(GF_EVGSurface *surf, u64 col)
175 : {
176 : u32 a;
177 : s64 y, cb, cr;
178 : s32 r, g, b;
179 : a = (col>>48)&0xFFFF;
180 2 : y = (col>>32)&0xFFFF;
181 2 : cb = (col>>16)&0xFFFF;
182 2 : cr = (col)&0xFFFF;
183 :
184 : #ifndef YUV_USE_INT
185 : r = (s32) (y + 1.402 * (cr - 32768));
186 : g = (s32) (y - 0.344136 * (cb - 32768) - 0.714136*(cr-32768) );
187 : b = (s32) (y + 1.772 * (cb - 32768) );
188 : #define TRUNC_16BIT(_a) if (_a<0) {_a = 0;} else if (_a>32768) {_a=32768;}
189 : TRUNC_16BIT(r)
190 : TRUNC_16BIT(g)
191 : TRUNC_16BIT(b)
192 :
193 : #else
194 2 : y *= 1024;
195 2 : r = (s32) (y + 1436 * (cr - 32768));
196 2 : g = (s32) (y - 352 * (cb - 32768) - 731*(cr-32768) );
197 2 : b = (s32) (y + 1814 * (cb - 32768) );
198 :
199 : #define TRUNC_16BIT(_a) if (_a<0) {_a = 0;} else { u32 __a = (u32) _a; __a>>=10; if (__a>32768) {__a=32768;} _a = __a; }
200 2 : TRUNC_16BIT(r)
201 2 : TRUNC_16BIT(g)
202 2 : TRUNC_16BIT(b)
203 :
204 : #endif
205 :
206 2 : return evg_make_col_wide(a, r, g, b);
207 : }
208 :
209 1 : void evg_make_ayuv_color_mx(GF_ColorMatrix *cmat, GF_ColorMatrix *yuv_cmat)
210 : {
211 : GF_ColorMatrix cmx_y2r, cmx_r2y;
212 1 : gf_cmx_init(&cmx_r2y);
213 1 : gf_cmx_init(&cmx_y2r);
214 1 : cmx_r2y.identity = cmx_y2r.identity = GF_FALSE;
215 :
216 : //r = (s32) (y + 1.402 * (cr - 128));
217 1 : cmx_y2r.m[0] = FIX_ONE; //y
218 1 : cmx_y2r.m[2] = FLT2FIX(1.402); //cr
219 1 : cmx_y2r.m[4] = FLT2FIX(-1.402 * 0.504); //tr
220 :
221 : //g = (s32) (y - 0.344136 * (cb - 128) - 0.714136*(cr-128) );
222 1 : cmx_y2r.m[5] = FIX_ONE; //y
223 1 : cmx_y2r.m[6] = FLT2FIX(- 0.344136); //cb
224 1 : cmx_y2r.m[7] = FLT2FIX(- 0.714136); //cr
225 1 : cmx_y2r.m[9] = FLT2FIX(0.344136 * 0.504 + 0.714136*0.504); //tr
226 :
227 : //b = (s32) (y + 1.772 * (cb - 128) );
228 1 : cmx_y2r.m[10] = FIX_ONE; //y
229 1 : cmx_y2r.m[11] = FLT2FIX(1.772); //cb
230 1 : cmx_y2r.m[14] = FLT2FIX(-1.772 * 0.504); //tr
231 :
232 :
233 : //y = (u8) (0.299*r + 0.587 * g + 0.114 * b);
234 1 : cmx_r2y.m[0] = FLT2FIX(0.299); //r
235 1 : cmx_r2y.m[1] = FLT2FIX(0.587); //g
236 1 : cmx_r2y.m[2] = FLT2FIX(0.114); //b
237 :
238 :
239 : //cb = (u8) (-0.169*(s32)r - 0.331*(s32)g + 0.499*b + 128);
240 1 : cmx_r2y.m[5] = FLT2FIX(-0.169); //r
241 1 : cmx_r2y.m[6] = FLT2FIX(-0.331); //g
242 1 : cmx_r2y.m[7] = FLT2FIX(0.499); //b
243 1 : cmx_r2y.m[9] = FLT2FIX(0.504); //tr
244 :
245 : //cr = (u8) (0.499 * r - 0.418*(s32)g - 0.0813*(s32)b + 128);
246 1 : cmx_r2y.m[10] = FLT2FIX(0.499); //r
247 1 : cmx_r2y.m[11] = FLT2FIX(-0.418); //g
248 1 : cmx_r2y.m[12] = FLT2FIX(-0.0813); //b
249 1 : cmx_r2y.m[14] = FLT2FIX(0.504); //tr
250 :
251 1 : gf_cmx_copy(yuv_cmat, &cmx_r2y);
252 1 : gf_cmx_multiply(yuv_cmat, cmat);
253 1 : gf_cmx_multiply(yuv_cmat, &cmx_y2r);
254 1 : }
255 :
256 :
257 : /*
258 : YUV420p part
259 : */
260 :
261 : static void overmask_yuv420p(u8 col_a, u8 cy, char *dst, u32 alpha)
262 : {
263 : s32 srca = col_a;
264 : u32 srcc = cy;
265 495871 : s32 dstc = (*dst) & 0xFF;
266 :
267 487409 : srca = mul255(srca, alpha);
268 495871 : *dst = mul255(srca, srcc - dstc) + dstc;
269 : }
270 :
271 : static void overmask_yuv420p_const_run(u8 a, u8 val, u8 *ptr, u32 count, short x)
272 : {
273 1097177 : while (count) {
274 569182 : u8 dst = *(ptr);
275 569182 : *ptr = (u8) mul255(a, val - dst) + dst;
276 569182 : ptr ++;
277 569182 : count--;
278 : }
279 : }
280 31408 : void evg_yuv420p_flush_uv_const(GF_EVGSurface *surf, u8 *surf_uv_alpha, s32 cu, s32 cv, s32 y)
281 : {
282 : u32 i, a;
283 31408 : u8 *pU = surf->pixels + surf->height *surf->pitch_y;
284 : u8 *pV;
285 31408 : pU += y/2 * surf->pitch_y/2;
286 31408 : pV = pU + surf->height/2 * surf->pitch_y/2;
287 :
288 : //no need to swap u and V in const flush, they have been swaped when setting up the brush
289 :
290 : //we are at an odd line, write uv
291 16306736 : for (i=0; i<surf->width; i+=2) {
292 : u8 dst;
293 :
294 : //even line
295 16275328 : a = surf->uv_alpha[i] + surf->uv_alpha[i+1];
296 : //odd line
297 16275328 : a += surf_uv_alpha[i] + surf_uv_alpha[i+1];
298 :
299 16275328 : if (a) {
300 : char *s_ptr_u, *s_ptr_v;
301 :
302 421788 : a /= 4;
303 :
304 421788 : s_ptr_u = pU + i / 2;
305 421788 : s_ptr_v = pV + i / 2;
306 421788 : if (a==0xFF) {
307 170891 : *s_ptr_u = (u8) cu;
308 170891 : *s_ptr_v = (u8) cv;
309 : } else {
310 250897 : dst = *(s_ptr_u);
311 250897 : *s_ptr_u = (u8) mul255(a, cu - dst) + dst;
312 :
313 250897 : dst = *(s_ptr_v);
314 250897 : *s_ptr_v = (u8) mul255(a, cv - dst) + dst;
315 : }
316 : }
317 : }
318 31408 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
319 31408 : }
320 :
321 63492 : void evg_yuv420p_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
322 : {
323 63492 : char *pY = surf->pixels;
324 : u8 *surf_uv_alpha;
325 : s32 i;
326 : u8 cy, cu, cv;
327 63492 : Bool write_uv = (y%2) ? GF_TRUE : GF_FALSE;
328 :
329 63492 : if (surf->is_422) {
330 : write_uv = GF_TRUE;
331 307 : surf_uv_alpha = surf->uv_alpha;
332 : }
333 63185 : else if (write_uv) {
334 31598 : surf_uv_alpha = surf->uv_alpha + surf->width;
335 : } else {
336 31587 : surf_uv_alpha = surf->uv_alpha;
337 : }
338 :
339 63492 : pY += y * surf->pitch_y;
340 :
341 63492 : cy = GF_COL_R(surf->fill_col);
342 63492 : cu = GF_COL_G(surf->fill_col);
343 : cv = GF_COL_B(surf->fill_col);
344 :
345 680181 : for (i=0; i<count; i++) {
346 : u32 a;
347 : char *s_pY;
348 : u32 len;
349 616689 : len = spans[i].len;
350 616689 : s_pY = pY + spans[i].x;
351 :
352 616689 : a = spans[i].coverage;
353 616689 : if (a != 0xFF) {
354 521487 : overmask_yuv420p_const_run((u8)a, cy, s_pY, len, 0);
355 521487 : memset(surf_uv_alpha + spans[i].x, (u8)a, len);
356 : } else {
357 936822 : while (len--) {
358 841620 : *(s_pY) = cy;
359 841620 : s_pY ++;
360 : }
361 95202 : memset(surf_uv_alpha + spans[i].x, 0xFF, spans[i].len);
362 : }
363 : }
364 63492 : if (write_uv) {
365 31905 : surf->yuv_flush_uv(surf, surf_uv_alpha, cu, cv, y);
366 : }
367 :
368 63492 : }
369 :
370 396 : void evg_yuv420p_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
371 : {
372 : u32 a;
373 396 : char *pY = surf->pixels;
374 : u8 *surf_uv_alpha;
375 : s32 i;
376 : u8 cy, cu, cv;
377 396 : Bool write_uv = (y%2) ? GF_TRUE : GF_FALSE;
378 :
379 396 : if (surf->is_422) {
380 : write_uv = GF_TRUE;
381 56 : surf_uv_alpha = surf->uv_alpha;
382 340 : } else if (write_uv) {
383 170 : surf_uv_alpha = surf->uv_alpha + surf->width;
384 : } else {
385 170 : surf_uv_alpha = surf->uv_alpha;
386 : }
387 :
388 396 : pY += y * surf->pitch_y;
389 :
390 396 : cy = GF_COL_R(surf->fill_col);
391 396 : cu = GF_COL_G(surf->fill_col);
392 : cv = GF_COL_B(surf->fill_col);
393 396 : a = GF_COL_A(surf->fill_col);
394 :
395 396 : if (surf->get_alpha) {
396 0 : for (i=0; i<count; i++) {
397 : u32 fin, j;
398 0 : for (j=0; j<spans[i].len; j++) {
399 0 : s32 x = spans[i].x + j;
400 0 : char *s_pY = pY + x;
401 0 : u8 aa = surf->get_alpha(surf->get_alpha_udta, a, x, y);
402 0 : fin = mul255(aa, spans[i].coverage);
403 :
404 0 : overmask_yuv420p_const_run((u8)fin, cy, s_pY, 1, 0);
405 :
406 0 : memset(surf_uv_alpha + x, (u8)fin, 1);
407 : }
408 : }
409 : } else {
410 1492 : for (i=0; i<count; i++) {
411 : char *s_pY;
412 : u32 fin, len;
413 1492 : len = spans[i].len;
414 1492 : s_pY = pY + spans[i].x;
415 1492 : fin = mul255(a, spans[i].coverage);
416 :
417 1492 : overmask_yuv420p_const_run((u8)fin, cy, s_pY, len, 0);
418 :
419 1492 : memset(surf_uv_alpha + spans[i].x, (u8)fin, len);
420 : }
421 : }
422 : //we are at an odd line, write uv
423 396 : if (write_uv)
424 226 : surf->yuv_flush_uv(surf, surf_uv_alpha, cu, cv, y);
425 396 : }
426 :
427 :
428 71811 : void evg_yuv420p_flush_uv_var(GF_EVGSurface *surf, u8 *surf_uv_alpha, s32 _cu, s32 _cv, s32 y)
429 : {
430 : u32 i;
431 : u8 *pU, *pV;
432 71811 : pU = surf->pixels + surf->height *surf->pitch_y;
433 71811 : pU += y/2 * surf->pitch_y/2;
434 71811 : pV = pU + surf->height/2 * surf->pitch_y/2;
435 :
436 71811 : if (surf->swap_uv) {
437 : u8 *tmp = pU;
438 : pU = pV;
439 : pV = tmp;
440 : }
441 :
442 44114304 : for (i=0; i<surf->width; i+=2) {
443 : u32 a, a11, a12, a21, a22;
444 44114304 : u32 idx1=3*i;
445 44114304 : u32 idx2=3*i + 3;
446 : //get alpha
447 44114304 : a11 = (u32)surf->uv_alpha[idx1];
448 44114304 : a12 = (u32)surf->uv_alpha[idx2];
449 44114304 : a21 = (u32)surf_uv_alpha[idx1];
450 44114304 : a22 = (u32)surf_uv_alpha[idx2];
451 :
452 44114304 : a = a11 + a12 + a21 + a22;
453 44114304 : if (a) {
454 : u8 cdst=0;
455 : u32 chroma_u, chroma_v, c11, c12, c21, c22;
456 :
457 5283243 : a /= 4;
458 : //get cb
459 5283243 : idx1 += 1;
460 5283243 : idx2 += 1;
461 :
462 5283243 : if (a!=0xFF) {
463 207408 : cdst = *pU;
464 : }
465 5283243 : c11 = (u32)surf->uv_alpha[idx1];
466 5416836 : if (a11!=0xFF) c11 = mul255_zero(a11, c11 - cdst) + cdst;
467 5283243 : c12 = (u32)surf->uv_alpha[idx2];
468 5416649 : if (a12!=0xFF) c12 = mul255_zero(a12, c12 - cdst) + cdst;
469 5283243 : c21 = (u32)surf_uv_alpha[idx1];
470 5406840 : if (a21!=0xFF) c21 = mul255_zero(a21, c21 - cdst) + cdst;
471 5283243 : c22 = (u32)surf_uv_alpha[idx2];
472 5407391 : if (a22!=0xFF) c22 = mul255_zero(a22, c22 - cdst) + cdst;
473 :
474 5283243 : chroma_u = c11 + c12 + c21 + c22;
475 5283243 : chroma_u /= 4;
476 :
477 : //get cr
478 5283243 : idx1 += 1;
479 5283243 : idx2 += 1;
480 :
481 5283243 : if (a!=0xFF) {
482 207408 : cdst = *pV;
483 : }
484 5283243 : c11 = (u32)surf->uv_alpha[idx1];
485 5416836 : if (a11!=0xFF) c11 = mul255_zero(a11, c11 - cdst) + cdst;
486 5283243 : c12 = (u32)surf->uv_alpha[idx2];
487 5416649 : if (a12!=0xFF) c12 = mul255_zero(a12, c12 - cdst) + cdst;
488 5283243 : c21 = (u32)surf_uv_alpha[idx1];
489 5406840 : if (a21!=0xFF) c21 = mul255_zero(a21, c21 - cdst) + cdst;
490 5283243 : c22 = (u32)surf_uv_alpha[idx2];
491 5407391 : if (a22!=0xFF) c22 = mul255_zero(a22, c22 - cdst) + cdst;
492 :
493 5283243 : chroma_v = c11 + c12 + c21 + c22;
494 5283243 : chroma_v /= 4;
495 :
496 5283243 : *pU = chroma_u;
497 5283243 : *pV = chroma_v;
498 : }
499 44114304 : pU++;
500 44114304 : pV++;
501 : }
502 : //reset for next pass
503 71811 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
504 :
505 71811 : }
506 :
507 148489 : void evg_yuv420p_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
508 : {
509 : s32 i;
510 148489 : char *pY = surf->pixels;
511 : u8 *surf_uv_alpha;
512 148489 : Bool write_uv = (y%2) ? GF_TRUE : GF_FALSE;
513 :
514 148489 : if (surf->is_422) {
515 : write_uv = GF_TRUE;
516 2539 : surf_uv_alpha = surf->uv_alpha;
517 145950 : } else if (write_uv) {
518 : //second line of storage (we store alpha, cr, cb for each pixel)
519 72943 : surf_uv_alpha = surf->uv_alpha + 3*surf->width;
520 : } else {
521 : //first line of storage
522 73007 : surf_uv_alpha = surf->uv_alpha;
523 : }
524 :
525 148489 : pY += y * surf->pitch_y;
526 :
527 589701 : for (i=0; i<count; i++) {
528 : u8 spanalpha, col_a;
529 : char *s_pY;
530 : short x;
531 : u32 *p_col;
532 : u32 len;
533 441212 : len = spans[i].len;
534 441212 : spanalpha = spans[i].coverage;
535 441212 : evg_fill_run(surf->sten, surf, spans[i].x, y, len);
536 441212 : p_col = surf->stencil_pix_run;
537 :
538 441212 : s_pY = pY + spans[i].x;
539 441212 : x = spans[i].x;
540 :
541 22705452 : while (len--) {
542 21823028 : u32 col = *p_col;
543 21823028 : col_a = GF_COL_A(col);
544 21823028 : if (col_a) {
545 : u8 cy, cb, cr;
546 21576435 : u32 idx=3*x;
547 : //col is directly packed as AYCbCr
548 21576435 : cy = GF_COL_R(col);
549 21576435 : cb = GF_COL_G(col);
550 21576435 : cr = GF_COL_B(col);
551 :
552 21576435 : if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
553 466254 : overmask_yuv420p(col_a, cy, s_pY, spanalpha);
554 :
555 466254 : u8 a = mul255(col_a, spanalpha);
556 466254 : surf_uv_alpha[idx] = a;
557 : } else {
558 21110181 : *s_pY = cy;
559 21110181 : surf_uv_alpha[idx] = 0xFF;
560 : }
561 21576435 : surf_uv_alpha[idx+1] = cb;
562 21576435 : surf_uv_alpha[idx+2] = cr;
563 : }
564 21823028 : s_pY++;
565 21823028 : p_col++;
566 21823028 : x++;
567 : }
568 : }
569 : //compute final u,v for both lines
570 148489 : if (write_uv) {
571 75482 : surf->yuv_flush_uv(surf, surf_uv_alpha, 0, 0, y);
572 : }
573 148489 : }
574 :
575 26 : GF_Err evg_surface_clear_yuv420p(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
576 : {
577 : s32 i;
578 : u8 cy, cb, cr;
579 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
580 : u8 *pY, *pU, *pV;
581 :
582 26 : pY = surf->pixels + rc.y * surf->pitch_y + rc.x;
583 26 : pU = surf->pixels + surf->height * surf->pitch_y + rc.y/2 * surf->pitch_y/2 + rc.x/2;
584 26 : pV = surf->pixels + 5*surf->height * surf->pitch_y/4 + rc.y/2 * surf->pitch_y/2 + rc.x/2;
585 26 : if (surf->swap_uv) {
586 : u8 *tmp = pU;
587 : pU = pV;
588 : pV = tmp;
589 : }
590 :
591 26 : gf_evg_rgb_to_yuv(surf, col, &cy, &cb, &cr);
592 :
593 7466 : for (i = 0; i < rc.height; i++) {
594 7440 : memset(pY, cy, rc.width);
595 7440 : pY += surf->pitch_y;
596 7440 : if (i%2) {
597 3720 : memset(pU, cb, rc.width/2);
598 3720 : pU += surf->pitch_y/2;
599 3720 : memset(pV, cr, rc.width/2);
600 3720 : pV += surf->pitch_y/2;
601 : }
602 : }
603 26 : return GF_OK;
604 : }
605 :
606 :
607 : /*
608 : NV12 / NV21 part
609 : */
610 :
611 :
612 360 : void evg_nv12_flush_uv_const(GF_EVGSurface *surf, u8 *surf_uv_alpha, s32 cu, s32 cv, s32 y)
613 : {
614 : u32 i, a;
615 360 : char *pU = surf->pixels + surf->height *surf->pitch_y;
616 360 : pU += y/2 * surf->pitch_y;
617 :
618 23400 : for (i=0; i<surf->width; i+=2) {
619 : u8 dst;
620 :
621 : //even line
622 23040 : a = surf->uv_alpha[i] + surf->uv_alpha[i+1];
623 : //odd line
624 23040 : a += surf_uv_alpha[i] + surf_uv_alpha[i+1];
625 :
626 23040 : if (a) {
627 : char *s_ptr;
628 3090 : a /= 4;
629 :
630 3090 : s_ptr = pU + i;
631 3090 : if (a==0xFF) {
632 1232 : *s_ptr = cu;
633 :
634 : s_ptr++;
635 1232 : *s_ptr = cv;
636 : } else {
637 1858 : dst = *(s_ptr);
638 1858 : *s_ptr = (u8) mul255(a, cu - dst) + dst;
639 :
640 : s_ptr++;
641 1858 : dst = *(s_ptr);
642 1858 : *s_ptr = (u8) mul255(a, cv - dst) + dst;
643 : }
644 : }
645 : }
646 360 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
647 360 : }
648 :
649 1132 : void evg_nv12_flush_uv_var(GF_EVGSurface *surf, u8 *surf_uv_alpha, s32 cu, s32 cv, s32 y)
650 : {
651 : u32 i;
652 : char *pU;
653 1132 : pU = surf->pixels + surf->height *surf->pitch_y;
654 1132 : pU += y/2 * surf->pitch_y;
655 :
656 73580 : for (i=0; i<surf->width; i+=2) {
657 : u32 a, a11, a12, a21, a22;
658 :
659 72448 : u32 idx1=3*i;
660 72448 : u32 idx2=3*i + 3;
661 :
662 : //get alpha
663 72448 : a11 = (u32)surf->uv_alpha[idx1];
664 72448 : a12 = (u32)surf->uv_alpha[idx2];
665 72448 : a21 = (u32)surf_uv_alpha[idx1];
666 72448 : a22 = (u32)surf_uv_alpha[idx2];
667 72448 : a = a11+a12+a21+a22;
668 :
669 72448 : if (a) {
670 : u8 cdst=0;
671 : u32 chroma_u, chroma_v, c11, c12, c21, c22;
672 :
673 54726 : a /= 4;
674 :
675 : //get cb
676 54726 : idx1 += 1;
677 54726 : idx2 += 1;
678 54726 : if (a!=0xFF)
679 3640 : cdst = pU[surf->idx_u];
680 :
681 54726 : c11 = (u32)surf->uv_alpha[idx1];
682 57592 : if (a11!=0xFF) c11 = mul255_zero(a11, c11 - cdst) + cdst;
683 54726 : c12 = (u32)surf->uv_alpha[idx2];
684 57596 : if (a12!=0xFF) c12 = mul255_zero(a12, c12 - cdst) + cdst;
685 54726 : c21 = (u32)surf_uv_alpha[idx1];
686 57558 : if (a21!=0xFF) c21 = mul255_zero(a21, c21 - cdst) + cdst;
687 54726 : c22 = (u32)surf_uv_alpha[idx2];
688 57566 : if (a22!=0xFF) c22 = mul255_zero(a22, c22 - cdst) + cdst;
689 :
690 54726 : chroma_u = c11 + c12 + c21 + c22;
691 54726 : chroma_u /= 4;
692 :
693 : //get cr
694 54726 : idx1 += 1;
695 54726 : idx2 += 1;
696 :
697 54726 : if (a!=0xFF)
698 3640 : cdst = pU[surf->idx_v];
699 :
700 54726 : c11 = (u32)surf->uv_alpha[idx1];
701 57592 : if (a11!=0xFF) c11 = mul255_zero(a11, c11 - cdst) + cdst;
702 54726 : c12 = (u32)surf->uv_alpha[idx2];
703 57596 : if (a12!=0xFF) c12 = mul255_zero(a12, c12 - cdst) + cdst;
704 54726 : c21 = (u32)surf_uv_alpha[idx1];
705 57558 : if (a21!=0xFF) c21 = mul255_zero(a21, c21 - cdst) + cdst;
706 54726 : c22 = (u32)surf_uv_alpha[idx2];
707 57566 : if (a22!=0xFF) c22 = mul255_zero(a22, c22 - cdst) + cdst;
708 :
709 54726 : chroma_v = c11 + c12 + c21 + c22;
710 54726 : chroma_v /= 4;
711 :
712 54726 : pU[surf->idx_u] = chroma_u;
713 54726 : pU[surf->idx_v] = chroma_v;
714 : }
715 72448 : pU+=2;
716 : }
717 : //reset for next pass
718 1132 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
719 1132 : }
720 :
721 :
722 8 : GF_Err evg_surface_clear_nv12(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col, Bool swap_uv)
723 : {
724 : s32 i;
725 : u8 cy, cb, cr;
726 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
727 8 : char *pY = surf->pixels;
728 8 : char *pU = surf->pixels + surf->height *surf->pitch_y;
729 : char *pU_first;
730 :
731 8 : pY += rc.y * surf->pitch_y;
732 8 : pU += rc.y/2 * surf->pitch_y;
733 :
734 8 : pY += rc.x;
735 8 : pU += rc.x/2;
736 : pU_first = pU;
737 :
738 8 : gf_evg_rgb_to_yuv(surf, col, &cy, &cb, &cr);
739 :
740 8 : if (swap_uv) {
741 4 : u8 t = cb;
742 4 : cb = cr;
743 4 : cr = t;
744 : }
745 1024 : for (i = 0; i < rc.height; i++) {
746 1024 : memset(pY, cy, rc.width);
747 1024 : pY += surf->pitch_y;
748 1024 : if (i%2) {
749 : //first uv line, build it
750 512 : if (i==1) {
751 : s32 j;
752 512 : for (j=0; j<rc.width/2; j++) {
753 512 : *pU = cb;
754 : pU++;
755 512 : *pU = cr;
756 512 : pU++;
757 : }
758 : }
759 : //non-first uv line recopy from first
760 : else {
761 : memcpy(pU, pU_first, rc.width);
762 504 : pU += surf->pitch_y;
763 : }
764 : }
765 : }
766 8 : return GF_OK;
767 : }
768 :
769 :
770 : /*
771 : YUV422 part
772 : */
773 :
774 363 : void evg_yuv422p_flush_uv_const(GF_EVGSurface *surf, u8 *surf_uv_alpha, s32 cu, s32 cv, s32 y)
775 : {
776 : u32 i, a;
777 363 : char *pU = surf->pixels + surf->height *surf->pitch_y;
778 : char *pV;
779 363 : pU += y * surf->pitch_y/2;
780 363 : pV = pU + surf->height * surf->pitch_y/2;
781 :
782 23595 : for (i=0; i<surf->width; i+=2) {
783 : u8 dst;
784 :
785 23232 : a = surf->uv_alpha[i] + surf->uv_alpha[i+1];
786 :
787 23232 : if (a) {
788 : char *s_ptr_u, *s_ptr_v;
789 :
790 2928 : a /= 2;
791 2928 : s_ptr_u = pU + i / 2;
792 2928 : s_ptr_v = pV + i / 2;
793 2928 : if (a==0xFF) {
794 1313 : *s_ptr_u = (u8) cu;
795 1313 : *s_ptr_v = (u8) cv;
796 : } else {
797 1615 : dst = *(s_ptr_u);
798 1615 : *s_ptr_u = (u8) mul255(a, cu - dst) + dst;
799 :
800 1615 : dst = *(s_ptr_v);
801 1615 : *s_ptr_v = (u8) mul255(a, cv - dst) + dst;
802 : }
803 : }
804 : }
805 363 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
806 363 : }
807 :
808 2539 : void evg_yuv422p_flush_uv_var(GF_EVGSurface *surf, u8 *surf_uv_alpha, s32 _cu, s32 _cv, s32 y)
809 : {
810 : u32 i;
811 : char *pU, *pV;
812 2539 : pU = surf->pixels + surf->height *surf->pitch_y;
813 2539 : pU += y * surf->pitch_y/2;
814 2539 : pV = pU + surf->height * surf->pitch_y/2;
815 :
816 165035 : for (i=0; i<surf->width; i+=2) {
817 : u32 a, a1, a2;
818 162496 : u32 idx1=3*i;
819 162496 : u32 idx2=3*i + 3;
820 : //get alpha
821 162496 : a1 = (u32)surf->uv_alpha[idx1];
822 162496 : a2 = (u32)surf->uv_alpha[idx2];
823 162496 : a = a1+a2;
824 162496 : if (a) {
825 : u8 cdst=0;
826 : u32 chroma_u, chroma_v, c1, c2;
827 :
828 144569 : a /= 2;
829 :
830 : //get cb
831 144569 : if (a != 0xFF)
832 3063 : cdst = *pU;
833 :
834 144569 : c1 = (u32)surf->uv_alpha[idx1+1];
835 147149 : if (a1!=0xFF) c1 = mul255_zero(a1, c1 - cdst) + cdst;
836 144569 : c2 = (u32)surf->uv_alpha[idx2+1];
837 147155 : if (a2!=0xFF) c2 = mul255_zero(a2, c1 - cdst) + cdst;
838 144569 : chroma_u = c1 + c2;
839 144569 : chroma_u /= 2;
840 :
841 : //get cb
842 144569 : if (a != 0xFF)
843 3063 : cdst = *pV;
844 :
845 144569 : c1 = (u32)surf->uv_alpha[idx1+2];
846 147149 : if (a1!=0xFF) c1 = mul255_zero(a1, c1 - cdst) + cdst;
847 144569 : c2 = (u32)surf->uv_alpha[idx2+2];
848 147155 : if (a2!=0xFF) c2 = mul255_zero(a2, c1 - cdst) + cdst;
849 144569 : chroma_v = c1 + c2;
850 144569 : chroma_v /= 2;
851 :
852 :
853 144569 : *pU = chroma_u;
854 144569 : *pV = chroma_v;
855 : }
856 162496 : pU++;
857 162496 : pV++;
858 : }
859 : //reset for next pass
860 2539 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
861 2539 : }
862 :
863 :
864 9 : GF_Err evg_surface_clear_yuv422p(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
865 : {
866 : s32 i;
867 : u8 cy, cb, cr;
868 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
869 9 : char *pY = surf->pixels;
870 9 : char *pU = surf->pixels + surf->height *surf->pitch_y;
871 : char *pV;
872 :
873 9 : pY += rc.y * surf->pitch_y;
874 9 : pU += rc.y/2 * surf->pitch_y/2;
875 9 : pV = pU + surf->height/2 * surf->pitch_y/2;
876 :
877 9 : pY += rc.x;
878 9 : pU += rc.x/2;
879 9 : pV += rc.x/2;
880 :
881 9 : gf_evg_rgb_to_yuv(surf, col, &cy, &cb, &cr);
882 :
883 1161 : for (i = 0; i < rc.height; i++) {
884 1152 : memset(pY, cy, rc.width);
885 1152 : pY += surf->pitch_y;
886 1152 : memset(pU, cb, rc.width/2);
887 1152 : pU += surf->pitch_y/2;
888 1152 : memset(pV, cr, rc.width/2);
889 1152 : pV += surf->pitch_y/2;
890 : }
891 9 : return GF_OK;
892 : }
893 :
894 : /*
895 : YUV444 part
896 : */
897 :
898 307 : void evg_yuv444p_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
899 : {
900 : char *pY, *pU, *pV;
901 : s32 i;
902 : u8 cy, cu, cv;
903 :
904 307 : pY = surf->pixels + y * surf->pitch_y;
905 307 : pU = surf->pixels + surf->height*surf->pitch_y + y * surf->pitch_y;
906 307 : pV = surf->pixels + 2*surf->height*surf->pitch_y + y * surf->pitch_y;
907 :
908 307 : cy = GF_COL_R(surf->fill_col);
909 307 : cu = GF_COL_G(surf->fill_col);
910 : cv = GF_COL_B(surf->fill_col);
911 :
912 2032 : for (i=0; i<count; i++) {
913 : u32 a;
914 : char *s_pY, *s_pU, *s_pV;
915 : u32 len;
916 1725 : len = spans[i].len;
917 1725 : s_pY = pY + spans[i].x;
918 1725 : s_pU = pU + spans[i].x;
919 1725 : s_pV = pV + spans[i].x;
920 :
921 1725 : a = spans[i].coverage;
922 1725 : if (a != 0xFF) {
923 1428 : overmask_yuv420p_const_run((u8)a, cy, s_pY, len, 0);
924 1428 : overmask_yuv420p_const_run((u8)a, cu, s_pU, len, 0);
925 1428 : overmask_yuv420p_const_run((u8)a, cv, s_pV, len, 0);
926 : } else {
927 3226 : while (len--) {
928 2929 : *(s_pY) = cy;
929 2929 : s_pY ++;
930 2929 : *(s_pU) = cu;
931 2929 : s_pU ++;
932 2929 : *(s_pV) = cv;
933 2929 : s_pV ++;
934 : }
935 : }
936 : }
937 307 : }
938 :
939 56 : void evg_yuv444p_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
940 : {
941 : u32 a;
942 : char *pY, *pU, *pV;
943 : s32 i;
944 : u8 cy, cu, cv;
945 :
946 56 : pY = surf->pixels + y * surf->pitch_y;
947 56 : pU = surf->pixels + surf->height*surf->pitch_y + y * surf->pitch_y;
948 56 : pV = surf->pixels + 2*surf->height*surf->pitch_y + y * surf->pitch_y;
949 :
950 56 : cy = GF_COL_R(surf->fill_col);
951 56 : cu = GF_COL_G(surf->fill_col);
952 : cv = GF_COL_B(surf->fill_col);
953 56 : a = GF_COL_A(surf->fill_col);
954 :
955 56 : if (surf->get_alpha) {
956 0 : for (i=0; i<count; i++) {
957 : u32 j;
958 0 : for (j=0; j<spans[i].len; j++) {
959 : char *s_pY, *s_pU, *s_pV;
960 : u32 fin;
961 0 : s32 x = spans[i].x + j;
962 0 : s_pY = pY + x;
963 0 : s_pU = pU + x;
964 0 : s_pV = pV + x;
965 0 : u8 aa = surf->get_alpha(surf->get_alpha_udta, a, x, y);
966 0 : fin = mul255(aa, spans[i].coverage);
967 :
968 0 : overmask_yuv420p_const_run((u8)fin, cy, s_pY, 1, 0);
969 0 : overmask_yuv420p_const_run((u8)fin, cu, s_pU, 1, 0);
970 0 : overmask_yuv420p_const_run((u8)fin, cv, s_pV, 1, 0);
971 : }
972 : }
973 : } else {
974 244 : for (i=0; i<count; i++) {
975 : char *s_pY, *s_pU, *s_pV;
976 : u32 fin, len;
977 244 : len = spans[i].len;
978 244 : s_pY = pY + spans[i].x;
979 244 : s_pU = pU + spans[i].x;
980 244 : s_pV = pV + spans[i].x;
981 244 : fin = mul255(a, spans[i].coverage);
982 :
983 244 : overmask_yuv420p_const_run((u8)fin, cy, s_pY, len, 0);
984 244 : overmask_yuv420p_const_run((u8)fin, cu, s_pU, len, 0);
985 244 : overmask_yuv420p_const_run((u8)fin, cv, s_pV, len, 0);
986 : }
987 : }
988 56 : }
989 :
990 2539 : void evg_yuv444p_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
991 : {
992 : s32 i;
993 : char *pY, *pU, *pV;
994 :
995 2539 : pY = surf->pixels + y * surf->pitch_y;
996 2539 : pU = pY + surf->height*surf->pitch_y;
997 : pV = pU + surf->height*surf->pitch_y;
998 :
999 5798 : for (i=0; i<count; i++) {
1000 : u8 spanalpha, col_a;
1001 : u32 len;
1002 : u32 *p_col;
1003 : char *s_pY, *s_pU, *s_pV;
1004 3259 : len = spans[i].len;
1005 3259 : spanalpha = spans[i].coverage;
1006 3259 : evg_fill_run(surf->sten, surf, spans[i].x, y, len);
1007 3259 : p_col = surf->stencil_pix_run;
1008 :
1009 3259 : s_pY = pY + spans[i].x;
1010 3259 : s_pU = pU + spans[i].x;
1011 3259 : s_pV = pV + spans[i].x;
1012 :
1013 306421 : while (len--) {
1014 299903 : u32 col = *p_col;
1015 299903 : col_a = GF_COL_A(col);
1016 299903 : if (col_a) {
1017 : u8 cy, cb, cr;
1018 288203 : cy = GF_COL_R(col);
1019 288203 : cb = GF_COL_G(col);
1020 : cr = GF_COL_B(col);
1021 :
1022 288203 : if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
1023 4231 : overmask_yuv420p(col_a, cy, s_pY, spanalpha);
1024 : overmask_yuv420p(col_a, cb, s_pU, spanalpha);
1025 : overmask_yuv420p(col_a, cr, s_pV, spanalpha);
1026 : } else {
1027 283972 : *s_pY = cy;
1028 283972 : *s_pU = cb;
1029 283972 : *s_pV = cr;
1030 : }
1031 : }
1032 299903 : s_pY++;
1033 299903 : s_pU++;
1034 299903 : s_pV++;
1035 299903 : p_col++;
1036 : }
1037 : }
1038 2539 : }
1039 :
1040 9 : GF_Err evg_surface_clear_yuv444p(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
1041 : {
1042 : s32 i;
1043 : u8 cy, cb, cr;
1044 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
1045 9 : char *pY = surf->pixels;
1046 9 : char *pU = surf->pixels + surf->height *surf->pitch_y;
1047 : char *pV;
1048 :
1049 9 : pY += rc.y * surf->pitch_y;
1050 9 : pU += rc.y * surf->pitch_y;
1051 : pV = pU + surf->height * surf->pitch_y;
1052 :
1053 9 : pY += rc.x;
1054 9 : pU += rc.x;
1055 9 : pV += rc.x;
1056 :
1057 9 : gf_evg_rgb_to_yuv(surf, col, &cy, &cb, &cr);
1058 :
1059 1161 : for (i = 0; i < rc.height; i++) {
1060 1152 : memset(pY, cy, rc.width);
1061 1152 : pY += surf->pitch_y;
1062 1152 : memset(pU, cb, rc.width);
1063 1152 : pU += surf->pitch_y;
1064 1152 : memset(pV, cr, rc.width);
1065 1152 : pV += surf->pitch_y;
1066 : }
1067 9 : return GF_OK;
1068 : }
1069 :
1070 :
1071 : /*
1072 : YUYV part
1073 : */
1074 :
1075 : static void overmask_yuvy(char *dst, u8 c, u32 alpha)
1076 : {
1077 : s32 srca = alpha;
1078 : u32 srcc = c;
1079 47168 : s32 dstc = (*dst) & 0xFF;
1080 47168 : *dst = mul255(srca, srcc - dstc) + dstc;
1081 : }
1082 1228 : void evg_yuyv_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
1083 : {
1084 : char *pY;
1085 : s32 i;
1086 : u8 cy, cu, cv;
1087 :
1088 1228 : if (!count) return;
1089 :
1090 1212 : pY = surf->pixels + y * surf->pitch_y;
1091 1212 : cy = GF_COL_R(surf->fill_col);
1092 1212 : cu = GF_COL_G(surf->fill_col);
1093 : cv = GF_COL_B(surf->fill_col);
1094 :
1095 8112 : for (i=0; i<count; i++) {
1096 : char *s_pY;
1097 : u32 len;
1098 6900 : len = spans[i].len;
1099 : //get start of yuyv block: devide x by 2, multiply by 4 (two Y pix packed in 4 bytes)
1100 6900 : s_pY = pY + (spans[i].x/2) * 4;
1101 : //move to first Y in block
1102 6900 : s_pY += surf->idx_y1;
1103 : //if odd pixel move to next one
1104 6900 : if (spans[i].x%2) s_pY += 2;
1105 :
1106 6900 : if (spans[i].coverage != 0xFF) {
1107 5712 : memset(surf->uv_alpha + spans[i].x, spans[i].coverage, len);
1108 11576 : while (len--) {
1109 5864 : overmask_yuvy(s_pY, cy, spans[i].coverage);
1110 5864 : s_pY += 2;
1111 : }
1112 : } else {
1113 1188 : memset(surf->uv_alpha + spans[i].x, 0xFF, len);
1114 :
1115 12904 : while (len--) {
1116 11716 : *s_pY = cy;
1117 11716 : s_pY += 2;
1118 : }
1119 : }
1120 : }
1121 :
1122 77568 : for (i=0; i<(s32) surf->width; i+=2) {
1123 77568 : u32 a = (u32)surf->uv_alpha[i];
1124 77568 : a += (u32)surf->uv_alpha[i + 1];
1125 77568 : if (a) {
1126 9592 : a /=2;
1127 9592 : if (a==0xFF) {
1128 5252 : pY[surf->idx_u] = cu;
1129 5252 : pY[surf->idx_v] = cv;
1130 4340 : } else if (a) {
1131 4284 : overmask_yuvy(pY + surf->idx_u, cu, a);
1132 4284 : overmask_yuvy(pY + surf->idx_v, cv, a);
1133 : }
1134 : }
1135 77568 : pY+=4;
1136 : }
1137 1212 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1138 : }
1139 :
1140 224 : void evg_yuyv_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
1141 : {
1142 : char *pY;
1143 : s32 i;
1144 : u8 cy, cu, cv, a;
1145 :
1146 224 : pY = surf->pixels + y * surf->pitch_y;
1147 224 : cy = GF_COL_R(surf->fill_col);
1148 224 : cu = GF_COL_G(surf->fill_col);
1149 : cv = GF_COL_B(surf->fill_col);
1150 224 : a = GF_COL_A(surf->fill_col);
1151 :
1152 1200 : for (i=0; i<count; i++) {
1153 : char *s_pY;
1154 : u32 fin, len;
1155 976 : len = spans[i].len;
1156 976 : s_pY = pY + (spans[i].x/2) * 4;
1157 976 : if (spans[i].x%2) s_pY += 2;
1158 :
1159 976 : fin = mul255(a, spans[i].coverage);
1160 :
1161 976 : memset(surf->uv_alpha + spans[i].x, (u8)fin, len);
1162 5000 : while (len--) {
1163 4024 : overmask_yuvy(s_pY + surf->idx_y1, cy, fin);
1164 4024 : s_pY += 2;
1165 : }
1166 : }
1167 224 : pY = surf->pixels + y * surf->pitch_y;
1168 14560 : for (i=0; i<(s32) surf->width; i+=2) {
1169 14336 : u32 p_a = surf->uv_alpha[i];
1170 14336 : p_a += surf->uv_alpha[i + 1];
1171 14336 : p_a /=2;
1172 14336 : if (p_a==0xFF) {
1173 0 : pY[surf->idx_u] = cu;
1174 0 : pY[surf->idx_v] = cv;
1175 14336 : } else if (p_a) {
1176 2104 : overmask_yuvy(pY + surf->idx_u, cu, p_a);
1177 2104 : overmask_yuvy(pY + surf->idx_v, cv, p_a);
1178 : }
1179 14336 : pY+=4;
1180 : }
1181 224 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1182 :
1183 224 : }
1184 :
1185 4524 : void evg_yuyv_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
1186 : {
1187 : s32 i;
1188 : char *pY;
1189 :
1190 4524 : pY = surf->pixels + y * surf->pitch_y;
1191 :
1192 11928 : for (i=0; i<count; i++) {
1193 : u8 spanalpha, col_a;
1194 : u32 *p_col;
1195 : char *s_pY;
1196 : u32 len, x;
1197 7404 : len = spans[i].len;
1198 7404 : s_pY = pY + (spans[i].x/2) * 4;
1199 7404 : if (spans[i].x%2) s_pY += 2;
1200 :
1201 7404 : spanalpha = spans[i].coverage;
1202 7404 : evg_fill_run(surf->sten, surf, spans[i].x, y, len);
1203 7404 : p_col = surf->stencil_pix_run;
1204 :
1205 7404 : x = spans[i].x;
1206 :
1207 493524 : while (len--) {
1208 478716 : u32 col = *p_col;
1209 478716 : col_a = GF_COL_A(col);
1210 478716 : if (col_a) {
1211 431916 : u32 idx=3*x;
1212 : u8 cy, cb, cr;
1213 431916 : cy = GF_COL_R(col);
1214 431916 : cb = GF_COL_G(col);
1215 431916 : cr = GF_COL_B(col);
1216 :
1217 431916 : if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
1218 16924 : overmask_yuv420p(col_a, cy, s_pY + surf->idx_y1, spanalpha);
1219 :
1220 16924 : u8 a = mul255(col_a, spanalpha);
1221 16924 : surf->uv_alpha[idx] = a;
1222 : } else {
1223 414992 : s_pY[surf->idx_y1] = cy;
1224 414992 : surf->uv_alpha[idx] = 0xFF;
1225 : }
1226 431916 : surf->uv_alpha[idx+1] = cb;
1227 431916 : surf->uv_alpha[idx+2] = cr;
1228 : }
1229 478716 : s_pY+=2;
1230 478716 : p_col++;
1231 478716 : x++;
1232 : }
1233 : }
1234 4524 : pY = surf->pixels + y * surf->pitch_y;
1235 294060 : for (i=0; i<(s32)surf->width; i+=2) {
1236 : u32 a;
1237 289536 : u32 idx1=3*i;
1238 289536 : u32 idx2=3*i + 3;
1239 : //get alpha
1240 289536 : a = (u32)surf->uv_alpha[idx1] + (u32)surf->uv_alpha[idx2];
1241 289536 : if (a) {
1242 : u32 chroma;
1243 :
1244 217828 : a /= 2;
1245 :
1246 : //get cb
1247 217828 : chroma = (u32)surf->uv_alpha[idx1+1] + (u32)surf->uv_alpha[idx2+1];
1248 217828 : chroma /= 2;
1249 217828 : if (a==0xFF) {
1250 205576 : pY[surf->idx_u] = chroma;
1251 : } else {
1252 12252 : overmask_yuvy(pY + surf->idx_u, chroma, a);
1253 : }
1254 : //get cr
1255 217828 : chroma = (u32)surf->uv_alpha[idx1+2] + (u32)surf->uv_alpha[idx2+2];
1256 217828 : chroma /= 2;
1257 217828 : if (a==0xFF) {
1258 205576 : pY[surf->idx_v] = chroma;
1259 : } else {
1260 12252 : overmask_yuvy(pY + surf->idx_v, chroma, a);
1261 : }
1262 : }
1263 289536 : pY+=4;
1264 : }
1265 :
1266 4524 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1267 :
1268 4524 : }
1269 :
1270 16 : GF_Err evg_surface_clear_yuyv(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
1271 : {
1272 : u32 i;
1273 : s32 j;
1274 : u8 cy, cb, cr;
1275 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
1276 : char *o_pY;
1277 16 : char *pY = surf->pixels;
1278 16 : pY += rc.y * surf->pitch_y;
1279 16 : pY += (rc.x/2) * 4;
1280 :
1281 16 : gf_evg_rgb_to_yuv(surf, col, &cy, &cb, &cr);
1282 : o_pY = pY;
1283 2064 : for (i = 0; i <(u32)rc.height; i++) {
1284 2048 : if (!i) {
1285 : char *dst = pY;
1286 1024 : for (j = 0; j < rc.width/2; j++) {
1287 1024 : dst[surf->idx_y1] = cy;
1288 1024 : dst[surf->idx_u] = cb;
1289 1024 : dst[surf->idx_y1 + 2] = cy;
1290 1024 : dst[surf->idx_v] = cr;
1291 1024 : dst += 4;
1292 : }
1293 : } else {
1294 2032 : memcpy(pY, o_pY, rc.width*2);
1295 : }
1296 2048 : pY += surf->pitch_y;
1297 : }
1298 16 : return GF_OK;
1299 : }
1300 :
1301 :
1302 : #ifdef GPAC_BIG_ENDIAN
1303 :
1304 : #define set_u16_le(_ptr, val) { ((u8 *)_ptr)[0] = (val>>8)&0xFF; ((u8 *)_ptr)[1] = (val&0xFF); }
1305 : #define set_u16_be(_ptr, val) { *(u16 *) _ptr = (u16) val; }
1306 :
1307 : #define get_u16_le(val, _ptr) { val = ((u32) (*(u8 *) _ptr+1)<< 8) | *(u8 *) _ptr; }
1308 : #define get_u16_be(val, _ptr) { val = *(u16 *) (_ptr); }
1309 :
1310 : #else
1311 :
1312 : #define set_u16_le(_ptr, val) { (*(u16 *) _ptr) = (u16) val; }
1313 : #define set_u16_be(_ptr, val) { ((u8 *)_ptr)[0] = (val>>8)&0xFF; ((u8 *)_ptr)[1] = (val&0xFF); }
1314 :
1315 : #define get_u16_le(val, _ptr) { val = *(u16 *) (_ptr); }
1316 : #define get_u16_be(val, _ptr) { val = ((u32) (*(u8 *) _ptr)<< 8) | *(u8 *) _ptr+1; }
1317 :
1318 : #endif
1319 :
1320 :
1321 : /*
1322 : YUV420p-10 part
1323 : */
1324 : static s32
1325 : mul_10(s64 a, s64 b)
1326 : {
1327 224422 : return (s32) ( ((a + 1) * b) >> 16);
1328 : }
1329 :
1330 : static s32
1331 : mul_10_zero(s64 a, s64 b)
1332 : {
1333 131480 : if (!a) return 0;
1334 128228 : return (s32) ( ((a + 1) * b) >> 16);
1335 : }
1336 :
1337 : static void overmask_yuv420p_10(u16 col_a, u16 cy, u16 *dst, u32 alpha)
1338 : {
1339 : s32 srca = col_a;
1340 111925 : u32 srcc = cy;
1341 : s32 dstc;
1342 111925 : get_u16_le(dstc, dst);
1343 :
1344 80063 : srca = mul_10(srca, alpha);
1345 223850 : set_u16_le(dst, (mul_10(srca, srcc - dstc) + dstc) );
1346 : }
1347 :
1348 : static void overmask_yuv420p_10_const_run(u16 a, u16 val, u16 *ptr, u32 count, short x)
1349 : {
1350 29008 : while (count) {
1351 : u16 dst;
1352 17304 : get_u16_le(dst, ptr);
1353 34608 : set_u16_le(ptr, (u16) (mul_10(a, val - dst) + dst));
1354 17304 : ptr ++;
1355 17304 : count--;
1356 : }
1357 : }
1358 :
1359 180 : void evg_yuv420p_10_flush_uv_const(GF_EVGSurface *surf, u8 *_surf_uv_alpha, s32 cu, s32 cv, s32 y)
1360 : {
1361 : u32 i, a;
1362 180 : u16 *surf_uv_alpha_even = (u16 *) surf->uv_alpha;
1363 : u16 *surf_uv_alpha_odd = (u16 *) _surf_uv_alpha;
1364 180 : char *pU = surf->pixels + surf->height *surf->pitch_y;
1365 : char *pV;
1366 180 : pU += y/2 * surf->pitch_y/2;
1367 180 : pV = pU + surf->height/2 * surf->pitch_y/2;
1368 :
1369 : //we are at an odd line, write uv
1370 11700 : for (i=0; i<surf->width; i+=2) {
1371 : u16 dst;
1372 :
1373 : //even line
1374 11520 : a = surf_uv_alpha_even[i] + surf_uv_alpha_even[i+1];
1375 : //odd line
1376 11520 : a += surf_uv_alpha_odd[i] + surf_uv_alpha_odd[i+1];
1377 :
1378 11520 : if (a) {
1379 : u16 *s_ptr_u, *s_ptr_v;
1380 :
1381 1545 : a /= 4;
1382 :
1383 1545 : s_ptr_u = ((u16 *) pU) + i/2;
1384 1545 : s_ptr_v = ((u16 *) pV) + i/2;
1385 1545 : if (a==0xFFFF) {
1386 0 : set_u16_le(s_ptr_u, cu);
1387 0 : set_u16_le(s_ptr_v, cv);
1388 : } else {
1389 1545 : get_u16_le(dst, s_ptr_u);
1390 3090 : set_u16_le(s_ptr_u, (u16) (mul_10(a, cu - dst) + dst) );
1391 1545 : get_u16_le(dst, s_ptr_v);
1392 3090 : set_u16_le(s_ptr_v, (u16) (mul_10(a, cv - dst) + dst) );
1393 : }
1394 : }
1395 : }
1396 180 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1397 180 : }
1398 :
1399 1228 : void evg_yuv420p_10_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
1400 : {
1401 : u16 *pY;
1402 : u16 *surf_uv_alpha;
1403 : s32 i;
1404 : u16 cy, cu, cv;
1405 1228 : Bool write_uv = (y%2) ? GF_TRUE : GF_FALSE;
1406 :
1407 1228 : if (surf->is_422) {
1408 : write_uv = GF_TRUE;
1409 307 : surf_uv_alpha = (u16 *)surf->uv_alpha;
1410 : }
1411 921 : else if (write_uv) {
1412 456 : surf_uv_alpha = ((u16 *)surf->uv_alpha) + surf->width;
1413 : } else {
1414 465 : surf_uv_alpha = (u16 *)surf->uv_alpha;
1415 : }
1416 :
1417 1228 : pY = (u16 *) (surf->pixels + y * surf->pitch_y);
1418 :
1419 1228 : cy = (surf->fill_col_wide>>32) & 0xFFFF;
1420 1228 : cy >>=6;
1421 1228 : cu = (surf->fill_col_wide>>16) & 0xFFFF;
1422 1228 : cu >>=6;
1423 1228 : cv = (surf->fill_col_wide) & 0xFFFF;
1424 1228 : cv >>=6;
1425 :
1426 8128 : for (i=0; i<count; i++) {
1427 : u32 a;
1428 : u16 *s_pY;
1429 : u32 j, len;
1430 6900 : len = spans[i].len;
1431 6900 : s_pY = pY + spans[i].x;
1432 :
1433 6900 : a = 0xFF * spans[i].coverage;
1434 24480 : for (j=0; j<len; j++) {
1435 17580 : surf_uv_alpha[spans[i].x + j] = a;
1436 : }
1437 :
1438 6900 : if (spans[i].coverage != 0xFF) {
1439 5712 : overmask_yuv420p_10_const_run(a, cy, s_pY, len, 0);
1440 : } else {
1441 12904 : while (len--) {
1442 11716 : set_u16_le(s_pY, cy);
1443 11716 : s_pY ++;
1444 : }
1445 : }
1446 : }
1447 1228 : if (write_uv) {
1448 763 : surf->yuv_flush_uv(surf, (u8 *)surf_uv_alpha, cu, cv, y);
1449 : }
1450 :
1451 1228 : }
1452 :
1453 224 : void evg_yuv420p_10_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
1454 : {
1455 : u32 a;
1456 : u16 *pY;
1457 : u16 *surf_uv_alpha;
1458 : s32 i;
1459 : u16 cy, cu, cv;
1460 224 : Bool write_uv = (y%2) ? GF_TRUE : GF_FALSE;
1461 :
1462 224 : if (surf->is_422) {
1463 : write_uv = GF_TRUE;
1464 56 : surf_uv_alpha = (u16 *)surf->uv_alpha;
1465 168 : } else if (write_uv) {
1466 84 : surf_uv_alpha = (u16 *)surf->uv_alpha + surf->width;
1467 : } else {
1468 84 : surf_uv_alpha = (u16 *)surf->uv_alpha;
1469 : }
1470 :
1471 224 : pY = (u16 *) (surf->pixels + y * surf->pitch_y);
1472 :
1473 :
1474 224 : a = (surf->fill_col_wide>>48) & 0xFFFF;
1475 224 : cy = (surf->fill_col_wide>>32) & 0xFFFF;
1476 224 : cy >>=6;
1477 224 : cu = (surf->fill_col_wide>>16) & 0xFFFF;
1478 224 : cu >>=6;
1479 224 : cv = (surf->fill_col_wide) & 0xFFFF;
1480 224 : cv >>=6;
1481 :
1482 224 : if (surf->get_alpha) {
1483 0 : for (i=0; i<count; i++) {
1484 : u32 j;
1485 0 : for (j=0; j<spans[i].len; j++) {
1486 : u16 *s_pY;
1487 : u32 fin;
1488 0 : s32 x = spans[i].x + j;
1489 0 : s_pY = pY + x;
1490 0 : fin = surf->get_alpha(surf->get_alpha_udta, a, x, y) * spans[i].coverage;
1491 0 : fin /= 0xFF;
1492 :
1493 0 : overmask_yuv420p_10_const_run(fin, cy, s_pY, 1, 0);
1494 0 : surf_uv_alpha[x] = fin;
1495 : }
1496 : }
1497 : } else {
1498 976 : for (i=0; i<count; i++) {
1499 : u16 *s_pY;
1500 : u32 fin, len, j;
1501 976 : len = spans[i].len;
1502 976 : s_pY = pY + spans[i].x;
1503 976 : fin = a * spans[i].coverage;
1504 976 : fin /= 0xFF;
1505 :
1506 976 : overmask_yuv420p_10_const_run(fin, cy, s_pY, len, 0);
1507 :
1508 4024 : for (j=0; j<len; j++) {
1509 4024 : surf_uv_alpha[spans[i].x + j] = fin;
1510 : }
1511 : }
1512 : }
1513 : //we are at an odd line, write uv
1514 224 : if (write_uv)
1515 140 : surf->yuv_flush_uv(surf, (u8*)surf_uv_alpha, cu, cv, y);
1516 224 : }
1517 :
1518 622 : void evg_yuv420p_10_flush_uv_var(GF_EVGSurface *surf, u8 *_surf_uv_alpha, s32 _cu, s32 _cv, s32 y)
1519 : {
1520 : u32 i;
1521 622 : u16 *surf_uv_alpha_even = (u16 *) surf->uv_alpha;
1522 : u16 *surf_uv_alpha_odd = (u16 *) _surf_uv_alpha;
1523 : u16 *pU, *pV;
1524 622 : pU = (u16 *) (surf->pixels + surf->height *surf->pitch_y + y/2 * surf->pitch_y/2);
1525 622 : pV = (u16 *) (surf->pixels + 5*surf->height *surf->pitch_y/4 + y/2 * surf->pitch_y/2);
1526 :
1527 37742 : for (i=0; i<surf->width; i+=2) {
1528 : u32 a, a11, a12, a21, a22;
1529 37120 : u32 idx1=3*i;
1530 37120 : u32 idx2=3*i + 3;
1531 :
1532 : //get alpha
1533 37120 : a11 = (u32)surf_uv_alpha_even[idx1];
1534 37120 : a12 = (u32)surf_uv_alpha_even[idx2];
1535 37120 : a21 = (u32)surf_uv_alpha_odd[idx1];
1536 37120 : a22 = (u32)surf_uv_alpha_odd[idx2];
1537 :
1538 37120 : a = a11+a12+a21+a22;
1539 37120 : if (a) {
1540 : s32 cdst=0;
1541 : s32 chroma_u, chroma_v, c11, c12, c21, c22;
1542 :
1543 30177 : a /= 4;
1544 :
1545 : //get cb
1546 30177 : idx1 += 1;
1547 30177 : idx2 += 1;
1548 :
1549 30177 : if (a!=0xFFFF) {
1550 4634 : get_u16_le(cdst, pU);
1551 : }
1552 30177 : c11 = (u32)surf_uv_alpha_even[idx1];
1553 34424 : if (a11!=0xFFFF) c11 = mul_10_zero(a11, c11 - cdst) + cdst;
1554 30177 : c12 = (u32)surf_uv_alpha_even[idx2];
1555 34426 : if (a12!=0xFFFF) c12 = mul_10_zero(a12, c12 - cdst) + cdst;
1556 30177 : c21 = (u32)surf_uv_alpha_odd[idx1];
1557 34407 : if (a21!=0xFFFF) c21 = mul_10_zero(a21, c21 - cdst) + cdst;
1558 30177 : c22 = (u32)surf_uv_alpha_odd[idx2];
1559 34411 : if (a22!=0xFFFF) c22 = mul_10_zero(a22, c22 - cdst) + cdst;
1560 :
1561 30177 : chroma_u = c11 + c12 + c21 + c22;
1562 30177 : chroma_u /= 4;
1563 30177 : set_u16_le(pU, (u16) chroma_u);
1564 :
1565 : //get cr
1566 30177 : idx1 += 1;
1567 30177 : idx2 += 1;
1568 :
1569 30177 : if (a!=0xFFFF) {
1570 4634 : get_u16_le(cdst, pV);
1571 : }
1572 30177 : c11 = (u32)surf_uv_alpha_even[idx1];
1573 34424 : if (a11!=0xFFFF) c11 = mul_10_zero(a11, c11 - cdst) + cdst;
1574 30177 : c12 = (u32)surf_uv_alpha_even[idx2];
1575 34426 : if (a12!=0xFFFF) c12 = mul_10_zero(a12, c12 - cdst) + cdst;
1576 30177 : c21 = (u32)surf_uv_alpha_odd[idx1];
1577 34407 : if (a21!=0xFFFF) c21 = mul_10_zero(a21, c21 - cdst) + cdst;
1578 30177 : c22 = (u32)surf_uv_alpha_odd[idx2];
1579 34411 : if (a22!=0xFFFF) c22 = mul_10_zero(a22, c22 - cdst) + cdst;
1580 :
1581 30177 : chroma_v = c11 + c12 + c21 + c22;
1582 30177 : chroma_v /= 4;
1583 30177 : set_u16_le(pV, (u16) chroma_v);
1584 : }
1585 37120 : pU++;
1586 37120 : pV++;
1587 : }
1588 : //reset for next pass
1589 622 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1590 :
1591 622 : }
1592 :
1593 4628 : void evg_yuv420p_10_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
1594 : {
1595 : s32 i;
1596 : u16 *pY;
1597 : u16 *surf_uv_alpha;
1598 4628 : Bool write_uv = (y%2) ? GF_TRUE : GF_FALSE;
1599 :
1600 4628 : if (surf->is_422) {
1601 : write_uv = GF_TRUE;
1602 1131 : surf_uv_alpha = (u16 *) surf->uv_alpha;
1603 3497 : } else if (write_uv) {
1604 : //second line of storage (we store alpha, cr, cb for each pixel)
1605 1754 : surf_uv_alpha = ((u16 *) surf->uv_alpha) + 3*surf->width;
1606 : } else {
1607 : //first line of storage
1608 1743 : surf_uv_alpha = (u16 *) surf->uv_alpha;
1609 : }
1610 :
1611 4628 : pY = (u16 *) (surf->pixels + y * surf->pitch_y);
1612 :
1613 12440 : for (i=0; i<count; i++) {
1614 : u8 spanalpha;
1615 : u32 len;
1616 : u64 *p_col;
1617 : u16 *s_pY;
1618 : short x;
1619 7812 : len = spans[i].len;
1620 7812 : spanalpha = spans[i].coverage;
1621 7812 : evg_fill_run(surf->sten, surf, spans[i].x, y, len);
1622 7812 : p_col = surf->stencil_pix_run;
1623 :
1624 7812 : s_pY = pY + spans[i].x;
1625 7812 : x = spans[i].x;
1626 :
1627 494748 : while (len--) {
1628 479124 : u64 col = *p_col;
1629 479124 : u32 col_a = (col>>48)&0xFFFF;
1630 479124 : if (col_a) {
1631 : u16 cy, cb, cr;
1632 479124 : u32 idx=3*x;
1633 : //col is directly packed as AYCbCr
1634 479124 : cy = ((col>>32) & 0xFFFF) >> 6;
1635 479124 : cb = ((col>>16) & 0xFFFF) >> 6;
1636 479124 : cr = ((col) & 0xFFFF) >> 6;
1637 :
1638 479124 : if ((spanalpha!=0xFF) || (col_a != 0xFFFF)) {
1639 64132 : u16 spana = spanalpha;
1640 64132 : spana <<= 8;
1641 : overmask_yuv420p_10(col_a, cy, s_pY, spana);
1642 64132 : surf_uv_alpha[idx] = mul_10(col_a, spana);
1643 : } else {
1644 414992 : set_u16_le(s_pY, cy);
1645 414992 : surf_uv_alpha[idx] = 0xFFFF;
1646 : }
1647 479124 : surf_uv_alpha[idx+1] = cb;
1648 479124 : surf_uv_alpha[idx+2] = cr;
1649 : }
1650 479124 : s_pY++;
1651 479124 : p_col++;
1652 479124 : x++;
1653 : }
1654 : }
1655 : //compute final u,v for both lines
1656 4628 : if (write_uv) {
1657 2885 : surf->yuv_flush_uv(surf, (u8 *)surf_uv_alpha, 0, 0, y);
1658 : }
1659 4628 : }
1660 :
1661 4 : GF_Err evg_surface_clear_yuv420p_10(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
1662 : {
1663 : s32 i, j;
1664 : u8 _cy, _cb, _cr;
1665 : u16 cy, cb, cr;
1666 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
1667 : u16 *pY, *pU, *pV, *o_pY, *o_pU, *o_pV;
1668 :
1669 4 : pY = (u16 *) (surf->pixels + rc.y * surf->pitch_y + 2*rc.x);
1670 4 : pU = (u16 *) (surf->pixels + surf->height * surf->pitch_y + rc.y/2 * surf->pitch_y/2 + rc.x);
1671 4 : pV = (u16 *) (surf->pixels + 5*surf->height * surf->pitch_y/4 + rc.y/2 * surf->pitch_y/2 + rc.x);
1672 :
1673 4 : gf_evg_rgb_to_yuv(surf, col, &_cy, &_cb, &_cr);
1674 4 : cy = ((u16)_cy) << 2;
1675 4 : cb = ((u16)_cb) << 2;
1676 4 : cr = ((u16)_cr) << 2;
1677 : o_pY = pY;
1678 : o_pU = pU;
1679 : o_pV = pV;
1680 516 : for (i = 0; i <rc.height; i++) {
1681 512 : if (!i) {
1682 4 : if (cy) {
1683 0 : for (j=0; j<rc.width; j++)
1684 0 : set_u16_le(&pY[j] , cy);
1685 : } else {
1686 4 : memset(pY, 0, rc.width*2);
1687 : }
1688 : } else {
1689 508 : memcpy(pY, o_pY, rc.width*2);
1690 : }
1691 : //pitch is in bytes, we are in short
1692 512 : pY += surf->pitch_y/2;
1693 :
1694 512 : if (i%2) continue;
1695 :
1696 256 : if (!i) {
1697 256 : for (j=0; j<rc.width/2; j++) {
1698 256 : set_u16_le(&pU[j], cb);
1699 256 : set_u16_le(&pV[j], cr);
1700 : }
1701 : } else {
1702 252 : memcpy(pU, o_pU, rc.width);//half width at 2 bytes per short
1703 : memcpy(pV, o_pV, rc.width);
1704 : }
1705 : //pitch is in bytes, we are in short
1706 256 : pU += surf->pitch_y/4;
1707 256 : pV += surf->pitch_y/4;
1708 : }
1709 4 : return GF_OK;
1710 : }
1711 :
1712 : /*
1713 : NV12 / NV21 10 bit part
1714 : */
1715 :
1716 :
1717 360 : void evg_nv12_10_flush_uv_const(GF_EVGSurface *surf, u8 *_surf_uv_alpha, s32 cu, s32 cv, s32 y)
1718 : {
1719 : u32 i, a;
1720 360 : u16 *surf_uv_alpha_even = (u16 *) surf->uv_alpha;
1721 : u16 *surf_uv_alpha_odd = (u16 *)_surf_uv_alpha;
1722 360 : u8 *pUV = surf->pixels + surf->height * surf->pitch_y + y/2 * surf->pitch_y;
1723 360 : u8 *pU = pUV + 2*surf->idx_u;
1724 360 : u8 *pV = pUV + 2*surf->idx_v;
1725 :
1726 23400 : for (i=0; i<surf->width; i+=2) {
1727 : //even line
1728 23040 : a = surf_uv_alpha_even[i] + surf_uv_alpha_even[i+1];
1729 : //odd line
1730 23040 : a += surf_uv_alpha_odd[i] + surf_uv_alpha_odd[i+1];
1731 :
1732 23040 : if (a) {
1733 : s32 dst;
1734 3090 : a /= 4;
1735 :
1736 3090 : if (a==0xFFFF) {
1737 0 : set_u16_le(pU, cu);
1738 0 : set_u16_le(pV, cv);
1739 : } else {
1740 3090 : get_u16_le(dst, pU);
1741 6180 : set_u16_le(pU, (u16) (mul_10(a, cu - dst) + dst) );
1742 3090 : get_u16_le(dst, pV);
1743 6180 : set_u16_le(pV, (u16) (mul_10(a, cv - dst) + dst) );
1744 : }
1745 : }
1746 23040 : pU += 4;
1747 23040 : pV += 4;
1748 : }
1749 360 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1750 360 : }
1751 :
1752 :
1753 1132 : void evg_nv12_10_flush_uv_var(GF_EVGSurface *surf, u8 *_surf_uv_alpha, s32 cu, s32 cv, s32 y)
1754 : {
1755 : u32 i;
1756 1132 : u16 *surf_uv_alpha_even = (u16 *) surf->uv_alpha;
1757 : u16 *surf_uv_alpha_odd = (u16 *) _surf_uv_alpha;
1758 1132 : u8 *pUV = surf->pixels + surf->height *surf->pitch_y + y/2 * surf->pitch_y;
1759 1132 : u8 *pU = pUV + 2*surf->idx_u;
1760 1132 : u8 *pV = pUV + 2*surf->idx_v;
1761 :
1762 73580 : for (i=0; i<surf->width; i+=2) {
1763 : u32 a, a11, a12, a21, a22;
1764 72448 : u32 idx1=3*i;
1765 72448 : u32 idx2=3*i + 3;
1766 : //get alpha
1767 72448 : a11 = (u32)surf_uv_alpha_even[idx1];
1768 72448 : a12 = (u32)surf_uv_alpha_even[idx2];
1769 72448 : a21 = (u32)surf_uv_alpha_odd[idx1];
1770 72448 : a22 = (u32)surf_uv_alpha_odd[idx2];
1771 72448 : a = a11+a12+a21+a22;
1772 :
1773 72448 : if (a) {
1774 : s32 cdst=0, chroma_u, chroma_v, c11, c12, c21, c22;
1775 :
1776 60034 : a /= 4;
1777 :
1778 : //get cb
1779 60034 : idx1 += 1;
1780 60034 : idx2 += 1;
1781 60034 : if (a!=0xFFFF)
1782 8948 : get_u16_le(cdst, pU);
1783 :
1784 60034 : c11 = (u32)surf_uv_alpha_even[idx1];
1785 68208 : if (a11!=0xFFFF) c11 = mul_10_zero(a11, c11 - cdst) + cdst;
1786 60034 : c12 = (u32)surf_uv_alpha_even[idx2];
1787 68212 : if (a12!=0xFFFF) c12 = mul_10_zero(a12, c12 - cdst) + cdst;
1788 60034 : c21 = (u32)surf_uv_alpha_odd[idx1];
1789 68174 : if (a21!=0xFFFF) c21 = mul_10_zero(a21, c21 - cdst) + cdst;
1790 60034 : c22 = (u32)surf_uv_alpha_odd[idx2];
1791 68182 : if (a22!=0xFFFF) c22 = mul_10_zero(a22, c22 - cdst) + cdst;
1792 :
1793 60034 : chroma_u = c11+c12+c21+c22;
1794 60034 : chroma_u /= 4;
1795 :
1796 : //get cr
1797 60034 : idx1 += 1;
1798 60034 : idx2 += 1;
1799 60034 : if (a!=0xFFFF)
1800 8948 : get_u16_le(cdst, pV);
1801 :
1802 60034 : c11 = (u32)surf_uv_alpha_even[idx1];
1803 68208 : if (a11!=0xFFFF) c11 = mul_10_zero(a11, c11 - cdst) + cdst;
1804 60034 : c12 = (u32)surf_uv_alpha_even[idx2];
1805 68212 : if (a12!=0xFFFF) c12 = mul_10_zero(a12, c12 - cdst) + cdst;
1806 60034 : c21 = (u32)surf_uv_alpha_odd[idx1];
1807 68174 : if (a21!=0xFFFF) c21 = mul_10_zero(a21, c21 - cdst) + cdst;
1808 60034 : c22 = (u32)surf_uv_alpha_odd[idx2];
1809 68182 : if (a22!=0xFFFF) c22 = mul_10_zero(a22, c22 - cdst) + cdst;
1810 :
1811 60034 : chroma_v = c11+c12+c21+c22;
1812 60034 : chroma_v /= 4;
1813 :
1814 :
1815 60034 : set_u16_le(pU, chroma_u);
1816 60034 : set_u16_le(pV, chroma_v);
1817 : }
1818 72448 : pU += 4;
1819 72448 : pV += 4;
1820 : }
1821 : //reset for next pass
1822 1132 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1823 1132 : }
1824 :
1825 :
1826 8 : GF_Err evg_surface_clear_nv12_10(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col, Bool swap_uv)
1827 : {
1828 : s32 i, j;
1829 : u8 _cy, _cb, _cr;
1830 : u16 cy, cb, cr;
1831 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
1832 : u16 *s_pY, *s_pU;
1833 8 : char *pY = surf->pixels;
1834 8 : char *pU = surf->pixels + surf->height *surf->pitch_y;
1835 : char *pU_first, *pY_first;
1836 :
1837 8 : pY += rc.y * surf->pitch_y;
1838 8 : pU += rc.y/2 * surf->pitch_y;
1839 :
1840 8 : pY += 2*rc.x;
1841 8 : pU += 2*rc.x;
1842 : pU_first = pU;
1843 : pY_first = pY;
1844 :
1845 8 : gf_evg_rgb_to_yuv(surf, col, &_cy, &_cb, &_cr);
1846 :
1847 8 : if (swap_uv) {
1848 4 : u8 t = _cb;
1849 4 : _cb = _cr;
1850 4 : _cr = t;
1851 : }
1852 8 : cy = ((u16)_cy) << 2;
1853 8 : cb = ((u16)_cb) << 2;
1854 8 : cr = ((u16)_cr) << 2;
1855 :
1856 : s_pY = (u16 *) pY;
1857 : s_pU = (u16 *) pU;
1858 :
1859 : //init first lines
1860 8 : if (cy) {
1861 0 : for (j=0; j<rc.width;j++) {
1862 0 : set_u16_le(&s_pY[j], cy);
1863 : }
1864 : } else {
1865 8 : memset(s_pY, 0, 2*rc.width);
1866 : }
1867 8 : s_pY += surf->pitch_y/2;
1868 :
1869 520 : for (j=0; j<rc.width/2; j++) {
1870 512 : set_u16_le(&s_pU[2*j], cb);
1871 512 : set_u16_le(&s_pU[2*j + 1], cr);
1872 : }
1873 8 : s_pU += surf->pitch_y/2;
1874 :
1875 1024 : for (i = 1; i < rc.height; i++) {
1876 :
1877 1016 : memcpy(s_pY, pY_first, 2*rc.width);
1878 1016 : s_pY += surf->pitch_y/2;
1879 :
1880 1016 : if (i%2) continue;
1881 :
1882 : //non-first uv line recopy from first (half width, U and V mix, 2 bytes = width*2)
1883 : memcpy(s_pU, pU_first, 2*rc.width);
1884 504 : s_pU += surf->pitch_y/2;
1885 : }
1886 8 : return GF_OK;
1887 : }
1888 :
1889 :
1890 :
1891 : /*
1892 : YUV422 10 part
1893 : */
1894 :
1895 363 : void evg_yuv422p_10_flush_uv_const(GF_EVGSurface *surf, u8 *_surf_uv_alpha, s32 cu, s32 cv, s32 y)
1896 : {
1897 : u32 i, a;
1898 363 : char *pU = surf->pixels + surf->height *surf->pitch_y;
1899 : char *pV;
1900 363 : u16 *surf_uv_alpha = (u16 *) surf->uv_alpha;
1901 363 : pU += y * surf->pitch_y/2;
1902 363 : pV = pU + surf->height * surf->pitch_y/2;
1903 :
1904 23595 : for (i=0; i<surf->width; i+=2) {
1905 23232 : a = surf_uv_alpha[i] + surf_uv_alpha[i+1];
1906 :
1907 23232 : if (a) {
1908 : s32 dst;
1909 : u16 *s_ptr_u, *s_ptr_v;
1910 :
1911 2930 : a /= 2;
1912 :
1913 2930 : s_ptr_u = (u16*)pU + i / 2;
1914 2930 : s_ptr_v = (u16*)pV + i / 2;
1915 2930 : if (a==0xFFFF) {
1916 0 : set_u16_le(s_ptr_u, (u16) cu);
1917 0 : set_u16_le(s_ptr_v, (u16) cv);
1918 :
1919 : } else {
1920 2930 : get_u16_le(dst, s_ptr_u);
1921 5860 : set_u16_le(s_ptr_u, (u16) (mul_10(a, cu - dst) + dst) );
1922 :
1923 2930 : get_u16_le(dst, s_ptr_v);
1924 5860 : set_u16_le(s_ptr_v, (u16) (mul_10(a, cv - dst) + dst));
1925 : }
1926 : }
1927 : }
1928 363 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1929 363 : }
1930 :
1931 1131 : void evg_yuv422p_10_flush_uv_var(GF_EVGSurface *surf, u8 *_surf_uv_alpha, s32 _cu, s32 _cv, s32 y)
1932 : {
1933 : u32 i;
1934 1131 : u16 *surf_uv_alpha = (u16 *) surf->uv_alpha;
1935 1131 : u16 *pU = (u16 *) (surf->pixels + surf->height *surf->pitch_y + y * surf->pitch_y/2);
1936 1131 : u16 *pV = (u16 *) (surf->pixels + surf->height *surf->pitch_y + surf->height * surf->pitch_y/2 + y * surf->pitch_y/2);
1937 :
1938 73515 : for (i=0; i<surf->width; i+=2) {
1939 : u32 a, a11, a12;
1940 72384 : u32 idx1=3*i;
1941 72384 : u32 idx2=3*i + 3;
1942 : //get alpha
1943 72384 : a11 = surf_uv_alpha[idx1];
1944 72384 : a12 = surf_uv_alpha[idx2];
1945 72384 : a=a11+a12;
1946 :
1947 72384 : if (a) {
1948 : s32 cdst=0, chroma_u, chroma_v, c11, c12;
1949 :
1950 59944 : a /= 2;
1951 :
1952 : //get cb
1953 59944 : if (a!=0xFFFF)
1954 8550 : get_u16_le(cdst, pU);
1955 :
1956 59944 : c11 = (u32)surf_uv_alpha[idx1+1];
1957 68011 : if (a11!=0xFFFF) c11 = mul_10_zero(a11, c11 - cdst) + cdst;
1958 59944 : c12 = (u32)surf_uv_alpha[idx2+1];
1959 68017 : if (a12!=0xFFFF) c12 = mul_10_zero(a12, c12 - cdst) + cdst;
1960 :
1961 59944 : chroma_u = c11 + c12;
1962 59944 : chroma_u /= 2;
1963 59944 : set_u16_le(pU, (u16) chroma_u);
1964 :
1965 : //get cr
1966 59944 : if (a!=0xFFFF)
1967 8550 : get_u16_le(cdst, pV);
1968 :
1969 59944 : c11 = (u32)surf_uv_alpha[idx1+2];
1970 68011 : if (a11!=0xFFFF) c11 = mul_10_zero(a11, c11 - cdst) + cdst;
1971 59944 : c12 = (u32)surf_uv_alpha[idx2+2];
1972 68017 : if (a12!=0xFFFF) c12 = mul_10_zero(a12, c12 - cdst) + cdst;
1973 :
1974 59944 : chroma_v = c11 + c12;
1975 59944 : chroma_v /= 2;
1976 59944 : set_u16_le(pV, (u16) chroma_v);
1977 : }
1978 72384 : pU++;
1979 72384 : pV++;
1980 : }
1981 : //reset for next pass
1982 1131 : memset(surf->uv_alpha, 0, surf->uv_alpha_alloc);
1983 1131 : }
1984 :
1985 :
1986 4 : GF_Err evg_surface_clear_yuv422p_10(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
1987 : {
1988 : s32 i, j;
1989 : u8 _cy, _cb, _cr;
1990 : u16 cy, cb, cr;
1991 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
1992 4 : char *pY = surf->pixels;
1993 4 : char *pU = surf->pixels + surf->height *surf->pitch_y;
1994 : char *pV;
1995 : char *o_pY, *o_pU, *o_pV;
1996 :
1997 4 : pY += rc.y * surf->pitch_y;
1998 4 : pU += rc.y/2 * surf->pitch_y/2;
1999 4 : pV = pU + surf->height/2 * surf->pitch_y/2;
2000 :
2001 4 : pY += 2*rc.x;
2002 4 : pU += rc.x;
2003 4 : pV += rc.x;
2004 :
2005 : o_pY = pY;
2006 : o_pU = pU;
2007 : o_pV = pV;
2008 4 : gf_evg_rgb_to_yuv(surf, col, &_cy, &_cb, &_cr);
2009 :
2010 4 : cy = ((u16)_cy) << 2;
2011 4 : cb = ((u16)_cb) << 2;
2012 4 : cr = ((u16)_cr) << 2;
2013 :
2014 516 : for (i = 0; i < rc.height; i++) {
2015 512 : if (!i) {
2016 512 : for (j=0; j<rc.width; j++) {
2017 512 : set_u16_le(&((u16 *)pY)[j], cy);
2018 512 : if (j%2) {
2019 256 : set_u16_le(&((u16 *)pU)[j/2], cb);
2020 256 : set_u16_le(& ((u16 *)pV)[j/2], cr);
2021 : }
2022 : }
2023 : } else {
2024 508 : memcpy(pY, o_pY, 2*rc.width);
2025 508 : memcpy(pU, o_pU, rc.width);
2026 : memcpy(pV, o_pV, rc.width);
2027 : }
2028 512 : pY += surf->pitch_y;
2029 512 : pU += surf->pitch_y/2;
2030 512 : pV += surf->pitch_y/2;
2031 : }
2032 4 : return GF_OK;
2033 : }
2034 :
2035 :
2036 : /*
2037 : YUV444 10bits part
2038 : */
2039 :
2040 307 : void evg_yuv444p_10_fill_const(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
2041 : {
2042 : u16 *pY, *pU, *pV;
2043 : s32 i;
2044 : u32 cy, cu, cv;
2045 :
2046 307 : pY = (u16 *) (surf->pixels + y * surf->pitch_y);
2047 307 : pU = (u16 *) (surf->pixels + surf->height*surf->pitch_y + y * surf->pitch_y);
2048 307 : pV = (u16 *) (surf->pixels + 2*surf->height*surf->pitch_y + y * surf->pitch_y);
2049 :
2050 307 : cy = (surf->fill_col_wide>>32) & 0xFFFF;
2051 307 : cy >>=6;
2052 307 : cu = (surf->fill_col_wide>>16) & 0xFFFF;
2053 307 : cu >>=6;
2054 307 : cv = (surf->fill_col_wide) & 0xFFFF;
2055 307 : cv >>=6;
2056 :
2057 2032 : for (i=0; i<count; i++) {
2058 : u32 a;
2059 : u16 *s_pY, *s_pU, *s_pV;
2060 : u32 len;
2061 1725 : len = spans[i].len;
2062 1725 : s_pY = pY + spans[i].x;
2063 1725 : s_pU = pU + spans[i].x;
2064 1725 : s_pV = pV + spans[i].x;
2065 :
2066 1725 : if (spans[i].coverage != 0xFF) {
2067 1428 : a = 0xFF * spans[i].coverage;
2068 :
2069 1428 : overmask_yuv420p_10_const_run(a, cy, s_pY, len, 0);
2070 1428 : overmask_yuv420p_10_const_run(a, cu, s_pU, len, 0);
2071 1428 : overmask_yuv420p_10_const_run(a, cv, s_pV, len, 0);
2072 : } else {
2073 3226 : while (len--) {
2074 2929 : set_u16_le(s_pY, cy);
2075 2929 : s_pY ++;
2076 2929 : set_u16_le(s_pU, cu);
2077 2929 : s_pU ++;
2078 2929 : set_u16_le(s_pV, cv);
2079 2929 : s_pV ++;
2080 : }
2081 : }
2082 : }
2083 307 : }
2084 :
2085 56 : void evg_yuv444p_10_fill_const_a(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
2086 : {
2087 : u32 a;
2088 : u16 *pY, *pU, *pV;
2089 : s32 i;
2090 : u32 cy, cu, cv;
2091 :
2092 56 : pY = (u16 *) (surf->pixels + y * surf->pitch_y);
2093 56 : pU = (u16 *) (surf->pixels + surf->height*surf->pitch_y + y * surf->pitch_y);
2094 56 : pV = (u16 *) (surf->pixels + 2*surf->height*surf->pitch_y + y * surf->pitch_y);
2095 :
2096 56 : a = (surf->fill_col_wide>>48) & 0xFFFF;
2097 56 : cy = (surf->fill_col_wide>>32) & 0xFFFF;
2098 56 : cy >>=6;
2099 56 : cu = (surf->fill_col_wide>>16) & 0xFFFF;
2100 56 : cu >>=6;
2101 56 : cv = (surf->fill_col_wide) & 0xFFFF;
2102 56 : cv >>=6;
2103 :
2104 56 : if (surf->get_alpha) {
2105 0 : for (i=0; i<count; i++) {
2106 : u32 j;
2107 0 : for (j=0; j<spans[i].len; j++) {
2108 : u16 *s_pY, *s_pU, *s_pV;
2109 : u32 fin;
2110 0 : s32 x = spans[i].x + j;
2111 0 : s_pY = pY + x;
2112 0 : s_pU = pU + x;
2113 0 : s_pV = pV + x;
2114 :
2115 0 : fin = surf->get_alpha(surf->get_alpha_udta, a, x, y) * spans[i].coverage;
2116 0 : fin /= 0xFF;
2117 :
2118 0 : overmask_yuv420p_10_const_run(fin, cy, s_pY, 1, 0);
2119 0 : overmask_yuv420p_10_const_run(fin, cu, s_pU, 1, 0);
2120 0 : overmask_yuv420p_10_const_run(fin, cv, s_pV, 1, 0);
2121 : }
2122 : }
2123 : } else {
2124 244 : for (i=0; i<count; i++) {
2125 : u16 *s_pY, *s_pU, *s_pV;
2126 : u32 fin, len;
2127 244 : len = spans[i].len;
2128 244 : s_pY = pY + spans[i].x;
2129 244 : s_pU = pU + spans[i].x;
2130 244 : s_pV = pV + spans[i].x;
2131 :
2132 244 : fin = a * spans[i].coverage;
2133 244 : fin /= 0xFF;
2134 :
2135 244 : overmask_yuv420p_10_const_run(fin, cy, s_pY, len, 0);
2136 244 : overmask_yuv420p_10_const_run(fin, cu, s_pU, len, 0);
2137 244 : overmask_yuv420p_10_const_run(fin, cv, s_pV, len, 0);
2138 : }
2139 : }
2140 56 : }
2141 :
2142 1131 : void evg_yuv444p_10_fill_var(s32 y, s32 count, EVG_Span *spans, GF_EVGSurface *surf)
2143 : {
2144 : s32 i;
2145 : u16 *pY, *pU, *pV;
2146 :
2147 1131 : pY = (u16 *) (surf->pixels + y * surf->pitch_y);
2148 1131 : pU = (u16 *) (surf->pixels + surf->height*surf->pitch_y + y * surf->pitch_y);
2149 1131 : pV = (u16 *) (surf->pixels + 2*surf->height*surf->pitch_y + y * surf->pitch_y);
2150 :
2151 2982 : for (i=0; i<count; i++) {
2152 : u8 spanalpha;
2153 : u32 len;
2154 : u64 *p_col;
2155 : u16 *s_pY, *s_pU, *s_pV;
2156 1851 : len = spans[i].len;
2157 1851 : spanalpha = spans[i].coverage;
2158 1851 : evg_fill_run(surf->sten, surf, spans[i].x, y, len);
2159 1851 : p_col = surf->stencil_pix_run;
2160 :
2161 1851 : s_pY = pY + spans[i].x;
2162 1851 : s_pU = pU + spans[i].x;
2163 1851 : s_pV = pV + spans[i].x;
2164 :
2165 123381 : while (len--) {
2166 119679 : u64 col = *p_col;
2167 119679 : u32 col_a = (col>>48)&0xFFFF;
2168 119679 : if (col_a) {
2169 : u16 cy, cb, cr;
2170 : //col is directly packed as AYCbCr
2171 119679 : cy = ((col>>32) & 0xFFFF) >> 6;
2172 119679 : cb = ((col>>16) & 0xFFFF) >> 6;
2173 119679 : cr = ((col) & 0xFFFF) >> 6;
2174 :
2175 119679 : if ((spanalpha!=0xFF) || (col_a != 0xFFFF)) {
2176 15931 : u16 spana = spanalpha;
2177 15931 : spana <<= 8;
2178 : overmask_yuv420p_10(col_a, cy, s_pY, spana);
2179 : overmask_yuv420p_10(col_a, cb, s_pU, spana);
2180 : overmask_yuv420p_10(col_a, cr, s_pV, spana);
2181 : } else {
2182 103748 : set_u16_le(s_pY, cy);
2183 103748 : set_u16_le(s_pU, cb);
2184 103748 : set_u16_le(s_pV, cr);
2185 : }
2186 : }
2187 119679 : s_pY++;
2188 119679 : s_pU++;
2189 119679 : s_pV++;
2190 119679 : p_col++;
2191 : }
2192 : }
2193 1131 : }
2194 :
2195 4 : GF_Err evg_surface_clear_yuv444p_10(GF_EVGSurface *_surf, GF_IRect rc, GF_Color col)
2196 : {
2197 : s32 i;
2198 : u8 _cy, _cb, _cr;
2199 : u16 cy, cb, cr;
2200 : GF_EVGSurface *surf = (GF_EVGSurface *)_surf;
2201 4 : char *pY = surf->pixels;
2202 4 : char *pU = surf->pixels + surf->height *surf->pitch_y;
2203 : char *pV, *o_pY, *o_pU, *o_pV;
2204 :
2205 4 : pY += rc.y * surf->pitch_y;
2206 4 : pU += rc.y * surf->pitch_y;
2207 : pV = pU + surf->height * surf->pitch_y;
2208 :
2209 4 : pY += 2*rc.x;
2210 4 : pU += 2*rc.x;
2211 4 : pV += 2*rc.x;
2212 :
2213 4 : gf_evg_rgb_to_yuv(surf, col, &_cy, &_cb, &_cr);
2214 :
2215 4 : cy = ((u16)_cy) << 2;
2216 4 : cb = ((u16)_cb) << 2;
2217 4 : cr = ((u16)_cr) << 2;
2218 :
2219 : o_pY = pY;
2220 : o_pU = pU;
2221 : o_pV = pV;
2222 :
2223 516 : for (i = 0; i < rc.height; i++) {
2224 512 : if (!i) {
2225 : s32 j;
2226 512 : for (j=0; j<rc.width; j++) {
2227 512 : set_u16_le(& ((u16 *)pY)[j], cy);
2228 512 : set_u16_le(& ((u16 *)pU)[j], cb);
2229 512 : set_u16_le(& ((u16 *)pV)[j], cr);
2230 : }
2231 : } else {
2232 508 : memcpy(pY, o_pY, 2*rc.width);
2233 : memcpy(pU, o_pU, 2*rc.width);
2234 : memcpy(pV, o_pV, 2*rc.width);
2235 : }
2236 512 : pY += surf->pitch_y;
2237 512 : pU += surf->pitch_y;
2238 512 : pV += surf->pitch_y;
2239 : }
2240 4 : return GF_OK;
2241 : }
|