LCOV - code coverage report
Current view: top level - utils - color.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1667 2321 71.8 %
Date: 2021-04-29 23:48:07 Functions: 81 86 94.2 %

          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             : }

Generated by: LCOV version 1.13