LCOV - code coverage report
Current view: top level - media/libyuv/libyuv/source - convert_from.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 383 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright 2012 The LibYuv Project Authors. All rights reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS. All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "libyuv/convert_from.h"
      12             : 
      13             : #include "libyuv/basic_types.h"
      14             : #include "libyuv/convert.h"  // For I420Copy
      15             : #include "libyuv/cpu_id.h"
      16             : #include "libyuv/planar_functions.h"
      17             : #include "libyuv/rotate.h"
      18             : #include "libyuv/scale.h"  // For ScalePlane()
      19             : #include "libyuv/video_common.h"
      20             : #include "libyuv/row.h"
      21             : 
      22             : #ifdef __cplusplus
      23             : namespace libyuv {
      24             : extern "C" {
      25             : #endif
      26             : 
      27             : #define SUBSAMPLE(v, a, s) (v < 0) ? (-((-v + a) >> s)) : ((v + a) >> s)
      28           0 : static __inline int Abs(int v) {
      29           0 :   return v >= 0 ? v : -v;
      30             : }
      31             : 
      32             : // I420 To any I4xx YUV format with mirroring.
      33           0 : static int I420ToI4xx(const uint8* src_y,
      34             :                       int src_stride_y,
      35             :                       const uint8* src_u,
      36             :                       int src_stride_u,
      37             :                       const uint8* src_v,
      38             :                       int src_stride_v,
      39             :                       uint8* dst_y,
      40             :                       int dst_stride_y,
      41             :                       uint8* dst_u,
      42             :                       int dst_stride_u,
      43             :                       uint8* dst_v,
      44             :                       int dst_stride_v,
      45             :                       int src_y_width,
      46             :                       int src_y_height,
      47             :                       int dst_uv_width,
      48             :                       int dst_uv_height) {
      49           0 :   const int dst_y_width = Abs(src_y_width);
      50           0 :   const int dst_y_height = Abs(src_y_height);
      51           0 :   const int src_uv_width = SUBSAMPLE(src_y_width, 1, 1);
      52           0 :   const int src_uv_height = SUBSAMPLE(src_y_height, 1, 1);
      53           0 :   if (src_y_width == 0 || src_y_height == 0 || dst_uv_width <= 0 ||
      54             :       dst_uv_height <= 0) {
      55           0 :     return -1;
      56             :   }
      57           0 :   if (dst_y) {
      58             :     ScalePlane(src_y, src_stride_y, src_y_width, src_y_height, dst_y,
      59           0 :                dst_stride_y, dst_y_width, dst_y_height, kFilterBilinear);
      60             :   }
      61             :   ScalePlane(src_u, src_stride_u, src_uv_width, src_uv_height, dst_u,
      62           0 :              dst_stride_u, dst_uv_width, dst_uv_height, kFilterBilinear);
      63             :   ScalePlane(src_v, src_stride_v, src_uv_width, src_uv_height, dst_v,
      64           0 :              dst_stride_v, dst_uv_width, dst_uv_height, kFilterBilinear);
      65           0 :   return 0;
      66             : }
      67             : 
      68             : // 420 chroma is 1/2 width, 1/2 height
      69             : // 422 chroma is 1/2 width, 1x height
      70             : LIBYUV_API
      71           0 : int I420ToI422(const uint8* src_y,
      72             :                int src_stride_y,
      73             :                const uint8* src_u,
      74             :                int src_stride_u,
      75             :                const uint8* src_v,
      76             :                int src_stride_v,
      77             :                uint8* dst_y,
      78             :                int dst_stride_y,
      79             :                uint8* dst_u,
      80             :                int dst_stride_u,
      81             :                uint8* dst_v,
      82             :                int dst_stride_v,
      83             :                int width,
      84             :                int height) {
      85           0 :   const int dst_uv_width = (Abs(width) + 1) >> 1;
      86           0 :   const int dst_uv_height = Abs(height);
      87             :   return I420ToI4xx(src_y, src_stride_y, src_u, src_stride_u, src_v,
      88             :                     src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
      89             :                     dst_v, dst_stride_v, width, height, dst_uv_width,
      90           0 :                     dst_uv_height);
      91             : }
      92             : 
      93             : // 420 chroma is 1/2 width, 1/2 height
      94             : // 444 chroma is 1x width, 1x height
      95             : LIBYUV_API
      96           0 : int I420ToI444(const uint8* src_y,
      97             :                int src_stride_y,
      98             :                const uint8* src_u,
      99             :                int src_stride_u,
     100             :                const uint8* src_v,
     101             :                int src_stride_v,
     102             :                uint8* dst_y,
     103             :                int dst_stride_y,
     104             :                uint8* dst_u,
     105             :                int dst_stride_u,
     106             :                uint8* dst_v,
     107             :                int dst_stride_v,
     108             :                int width,
     109             :                int height) {
     110           0 :   const int dst_uv_width = Abs(width);
     111           0 :   const int dst_uv_height = Abs(height);
     112             :   return I420ToI4xx(src_y, src_stride_y, src_u, src_stride_u, src_v,
     113             :                     src_stride_v, dst_y, dst_stride_y, dst_u, dst_stride_u,
     114             :                     dst_v, dst_stride_v, width, height, dst_uv_width,
     115           0 :                     dst_uv_height);
     116             : }
     117             : 
     118             : // Copy to I400. Source can be I420,422,444,400,NV12,NV21
     119             : LIBYUV_API
     120           0 : int I400Copy(const uint8* src_y,
     121             :              int src_stride_y,
     122             :              uint8* dst_y,
     123             :              int dst_stride_y,
     124             :              int width,
     125             :              int height) {
     126           0 :   if (!src_y || !dst_y || width <= 0 || height == 0) {
     127           0 :     return -1;
     128             :   }
     129             :   // Negative height means invert the image.
     130           0 :   if (height < 0) {
     131           0 :     height = -height;
     132           0 :     src_y = src_y + (height - 1) * src_stride_y;
     133           0 :     src_stride_y = -src_stride_y;
     134             :   }
     135           0 :   CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
     136           0 :   return 0;
     137             : }
     138             : 
     139             : LIBYUV_API
     140           0 : int I422ToYUY2(const uint8* src_y,
     141             :                int src_stride_y,
     142             :                const uint8* src_u,
     143             :                int src_stride_u,
     144             :                const uint8* src_v,
     145             :                int src_stride_v,
     146             :                uint8* dst_yuy2,
     147             :                int dst_stride_yuy2,
     148             :                int width,
     149             :                int height) {
     150             :   int y;
     151             :   void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u,
     152             :                         const uint8* src_v, uint8* dst_yuy2, int width) =
     153           0 :       I422ToYUY2Row_C;
     154           0 :   if (!src_y || !src_u || !src_v || !dst_yuy2 || width <= 0 || height == 0) {
     155           0 :     return -1;
     156             :   }
     157             :   // Negative height means invert the image.
     158           0 :   if (height < 0) {
     159           0 :     height = -height;
     160           0 :     dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2;
     161           0 :     dst_stride_yuy2 = -dst_stride_yuy2;
     162             :   }
     163             :   // Coalesce rows.
     164           0 :   if (src_stride_y == width && src_stride_u * 2 == width &&
     165           0 :       src_stride_v * 2 == width && dst_stride_yuy2 == width * 2) {
     166           0 :     width *= height;
     167           0 :     height = 1;
     168           0 :     src_stride_y = src_stride_u = src_stride_v = dst_stride_yuy2 = 0;
     169             :   }
     170             : #if defined(HAS_I422TOYUY2ROW_SSE2)
     171           0 :   if (TestCpuFlag(kCpuHasSSE2)) {
     172           0 :     I422ToYUY2Row = I422ToYUY2Row_Any_SSE2;
     173           0 :     if (IS_ALIGNED(width, 16)) {
     174           0 :       I422ToYUY2Row = I422ToYUY2Row_SSE2;
     175             :     }
     176             :   }
     177             : #endif
     178             : #if defined(HAS_I422TOYUY2ROW_NEON)
     179             :   if (TestCpuFlag(kCpuHasNEON)) {
     180             :     I422ToYUY2Row = I422ToYUY2Row_Any_NEON;
     181             :     if (IS_ALIGNED(width, 16)) {
     182             :       I422ToYUY2Row = I422ToYUY2Row_NEON;
     183             :     }
     184             :   }
     185             : #endif
     186             : 
     187           0 :   for (y = 0; y < height; ++y) {
     188           0 :     I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width);
     189           0 :     src_y += src_stride_y;
     190           0 :     src_u += src_stride_u;
     191           0 :     src_v += src_stride_v;
     192           0 :     dst_yuy2 += dst_stride_yuy2;
     193             :   }
     194           0 :   return 0;
     195             : }
     196             : 
     197             : LIBYUV_API
     198           0 : int I420ToYUY2(const uint8* src_y,
     199             :                int src_stride_y,
     200             :                const uint8* src_u,
     201             :                int src_stride_u,
     202             :                const uint8* src_v,
     203             :                int src_stride_v,
     204             :                uint8* dst_yuy2,
     205             :                int dst_stride_yuy2,
     206             :                int width,
     207             :                int height) {
     208             :   int y;
     209             :   void (*I422ToYUY2Row)(const uint8* src_y, const uint8* src_u,
     210             :                         const uint8* src_v, uint8* dst_yuy2, int width) =
     211           0 :       I422ToYUY2Row_C;
     212           0 :   if (!src_y || !src_u || !src_v || !dst_yuy2 || width <= 0 || height == 0) {
     213           0 :     return -1;
     214             :   }
     215             :   // Negative height means invert the image.
     216           0 :   if (height < 0) {
     217           0 :     height = -height;
     218           0 :     dst_yuy2 = dst_yuy2 + (height - 1) * dst_stride_yuy2;
     219           0 :     dst_stride_yuy2 = -dst_stride_yuy2;
     220             :   }
     221             : #if defined(HAS_I422TOYUY2ROW_SSE2)
     222           0 :   if (TestCpuFlag(kCpuHasSSE2)) {
     223           0 :     I422ToYUY2Row = I422ToYUY2Row_Any_SSE2;
     224           0 :     if (IS_ALIGNED(width, 16)) {
     225           0 :       I422ToYUY2Row = I422ToYUY2Row_SSE2;
     226             :     }
     227             :   }
     228             : #endif
     229             : #if defined(HAS_I422TOYUY2ROW_NEON)
     230             :   if (TestCpuFlag(kCpuHasNEON)) {
     231             :     I422ToYUY2Row = I422ToYUY2Row_Any_NEON;
     232             :     if (IS_ALIGNED(width, 16)) {
     233             :       I422ToYUY2Row = I422ToYUY2Row_NEON;
     234             :     }
     235             :   }
     236             : #endif
     237             : #if defined(HAS_I422TOYUY2ROW_MSA)
     238             :   if (TestCpuFlag(kCpuHasMSA)) {
     239             :     I422ToYUY2Row = I422ToYUY2Row_Any_MSA;
     240             :     if (IS_ALIGNED(width, 32)) {
     241             :       I422ToYUY2Row = I422ToYUY2Row_MSA;
     242             :     }
     243             :   }
     244             : #endif
     245             : 
     246           0 :   for (y = 0; y < height - 1; y += 2) {
     247           0 :     I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width);
     248           0 :     I422ToYUY2Row(src_y + src_stride_y, src_u, src_v,
     249           0 :                   dst_yuy2 + dst_stride_yuy2, width);
     250           0 :     src_y += src_stride_y * 2;
     251           0 :     src_u += src_stride_u;
     252           0 :     src_v += src_stride_v;
     253           0 :     dst_yuy2 += dst_stride_yuy2 * 2;
     254             :   }
     255           0 :   if (height & 1) {
     256           0 :     I422ToYUY2Row(src_y, src_u, src_v, dst_yuy2, width);
     257             :   }
     258           0 :   return 0;
     259             : }
     260             : 
     261             : LIBYUV_API
     262           0 : int I422ToUYVY(const uint8* src_y,
     263             :                int src_stride_y,
     264             :                const uint8* src_u,
     265             :                int src_stride_u,
     266             :                const uint8* src_v,
     267             :                int src_stride_v,
     268             :                uint8* dst_uyvy,
     269             :                int dst_stride_uyvy,
     270             :                int width,
     271             :                int height) {
     272             :   int y;
     273             :   void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u,
     274             :                         const uint8* src_v, uint8* dst_uyvy, int width) =
     275           0 :       I422ToUYVYRow_C;
     276           0 :   if (!src_y || !src_u || !src_v || !dst_uyvy || width <= 0 || height == 0) {
     277           0 :     return -1;
     278             :   }
     279             :   // Negative height means invert the image.
     280           0 :   if (height < 0) {
     281           0 :     height = -height;
     282           0 :     dst_uyvy = dst_uyvy + (height - 1) * dst_stride_uyvy;
     283           0 :     dst_stride_uyvy = -dst_stride_uyvy;
     284             :   }
     285             :   // Coalesce rows.
     286           0 :   if (src_stride_y == width && src_stride_u * 2 == width &&
     287           0 :       src_stride_v * 2 == width && dst_stride_uyvy == width * 2) {
     288           0 :     width *= height;
     289           0 :     height = 1;
     290           0 :     src_stride_y = src_stride_u = src_stride_v = dst_stride_uyvy = 0;
     291             :   }
     292             : #if defined(HAS_I422TOUYVYROW_SSE2)
     293           0 :   if (TestCpuFlag(kCpuHasSSE2)) {
     294           0 :     I422ToUYVYRow = I422ToUYVYRow_Any_SSE2;
     295           0 :     if (IS_ALIGNED(width, 16)) {
     296           0 :       I422ToUYVYRow = I422ToUYVYRow_SSE2;
     297             :     }
     298             :   }
     299             : #endif
     300             : #if defined(HAS_I422TOUYVYROW_NEON)
     301             :   if (TestCpuFlag(kCpuHasNEON)) {
     302             :     I422ToUYVYRow = I422ToUYVYRow_Any_NEON;
     303             :     if (IS_ALIGNED(width, 16)) {
     304             :       I422ToUYVYRow = I422ToUYVYRow_NEON;
     305             :     }
     306             :   }
     307             : #endif
     308             : #if defined(HAS_I422TOUYVYROW_MSA)
     309             :   if (TestCpuFlag(kCpuHasMSA)) {
     310             :     I422ToUYVYRow = I422ToUYVYRow_Any_MSA;
     311             :     if (IS_ALIGNED(width, 32)) {
     312             :       I422ToUYVYRow = I422ToUYVYRow_MSA;
     313             :     }
     314             :   }
     315             : #endif
     316             : 
     317           0 :   for (y = 0; y < height; ++y) {
     318           0 :     I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width);
     319           0 :     src_y += src_stride_y;
     320           0 :     src_u += src_stride_u;
     321           0 :     src_v += src_stride_v;
     322           0 :     dst_uyvy += dst_stride_uyvy;
     323             :   }
     324           0 :   return 0;
     325             : }
     326             : 
     327             : LIBYUV_API
     328           0 : int I420ToUYVY(const uint8* src_y,
     329             :                int src_stride_y,
     330             :                const uint8* src_u,
     331             :                int src_stride_u,
     332             :                const uint8* src_v,
     333             :                int src_stride_v,
     334             :                uint8* dst_uyvy,
     335             :                int dst_stride_uyvy,
     336             :                int width,
     337             :                int height) {
     338             :   int y;
     339             :   void (*I422ToUYVYRow)(const uint8* src_y, const uint8* src_u,
     340             :                         const uint8* src_v, uint8* dst_uyvy, int width) =
     341           0 :       I422ToUYVYRow_C;
     342           0 :   if (!src_y || !src_u || !src_v || !dst_uyvy || width <= 0 || height == 0) {
     343           0 :     return -1;
     344             :   }
     345             :   // Negative height means invert the image.
     346           0 :   if (height < 0) {
     347           0 :     height = -height;
     348           0 :     dst_uyvy = dst_uyvy + (height - 1) * dst_stride_uyvy;
     349           0 :     dst_stride_uyvy = -dst_stride_uyvy;
     350             :   }
     351             : #if defined(HAS_I422TOUYVYROW_SSE2)
     352           0 :   if (TestCpuFlag(kCpuHasSSE2)) {
     353           0 :     I422ToUYVYRow = I422ToUYVYRow_Any_SSE2;
     354           0 :     if (IS_ALIGNED(width, 16)) {
     355           0 :       I422ToUYVYRow = I422ToUYVYRow_SSE2;
     356             :     }
     357             :   }
     358             : #endif
     359             : #if defined(HAS_I422TOUYVYROW_NEON)
     360             :   if (TestCpuFlag(kCpuHasNEON)) {
     361             :     I422ToUYVYRow = I422ToUYVYRow_Any_NEON;
     362             :     if (IS_ALIGNED(width, 16)) {
     363             :       I422ToUYVYRow = I422ToUYVYRow_NEON;
     364             :     }
     365             :   }
     366             : #endif
     367             : #if defined(HAS_I422TOUYVYROW_MSA)
     368             :   if (TestCpuFlag(kCpuHasMSA)) {
     369             :     I422ToUYVYRow = I422ToUYVYRow_Any_MSA;
     370             :     if (IS_ALIGNED(width, 32)) {
     371             :       I422ToUYVYRow = I422ToUYVYRow_MSA;
     372             :     }
     373             :   }
     374             : #endif
     375             : 
     376           0 :   for (y = 0; y < height - 1; y += 2) {
     377           0 :     I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width);
     378           0 :     I422ToUYVYRow(src_y + src_stride_y, src_u, src_v,
     379           0 :                   dst_uyvy + dst_stride_uyvy, width);
     380           0 :     src_y += src_stride_y * 2;
     381           0 :     src_u += src_stride_u;
     382           0 :     src_v += src_stride_v;
     383           0 :     dst_uyvy += dst_stride_uyvy * 2;
     384             :   }
     385           0 :   if (height & 1) {
     386           0 :     I422ToUYVYRow(src_y, src_u, src_v, dst_uyvy, width);
     387             :   }
     388           0 :   return 0;
     389             : }
     390             : 
     391             : // TODO(fbarchard): test negative height for invert.
     392             : LIBYUV_API
     393           0 : int I420ToNV12(const uint8* src_y,
     394             :                int src_stride_y,
     395             :                const uint8* src_u,
     396             :                int src_stride_u,
     397             :                const uint8* src_v,
     398             :                int src_stride_v,
     399             :                uint8* dst_y,
     400             :                int dst_stride_y,
     401             :                uint8* dst_uv,
     402             :                int dst_stride_uv,
     403             :                int width,
     404             :                int height) {
     405           0 :   if (!src_y || !src_u || !src_v || !dst_y || !dst_uv || width <= 0 ||
     406             :       height == 0) {
     407           0 :     return -1;
     408             :   }
     409           0 :   int halfwidth = (width + 1) / 2;
     410           0 :   int halfheight = height > 0 ? (height + 1) / 2 : (height - 1) / 2;
     411           0 :   if (dst_y) {
     412           0 :     CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);
     413             :   }
     414             :   MergeUVPlane(src_u, src_stride_u, src_v, src_stride_v, dst_uv, dst_stride_uv,
     415           0 :                halfwidth, halfheight);
     416           0 :   return 0;
     417             : }
     418             : 
     419             : LIBYUV_API
     420           0 : int I420ToNV21(const uint8* src_y,
     421             :                int src_stride_y,
     422             :                const uint8* src_u,
     423             :                int src_stride_u,
     424             :                const uint8* src_v,
     425             :                int src_stride_v,
     426             :                uint8* dst_y,
     427             :                int dst_stride_y,
     428             :                uint8* dst_vu,
     429             :                int dst_stride_vu,
     430             :                int width,
     431             :                int height) {
     432             :   return I420ToNV12(src_y, src_stride_y, src_v, src_stride_v, src_u,
     433             :                     src_stride_u, dst_y, dst_stride_y, dst_vu, dst_stride_vu,
     434           0 :                     width, height);
     435             : }
     436             : 
     437             : // Convert I422 to RGBA with matrix
     438           0 : static int I420ToRGBAMatrix(const uint8* src_y,
     439             :                             int src_stride_y,
     440             :                             const uint8* src_u,
     441             :                             int src_stride_u,
     442             :                             const uint8* src_v,
     443             :                             int src_stride_v,
     444             :                             uint8* dst_rgba,
     445             :                             int dst_stride_rgba,
     446             :                             const struct YuvConstants* yuvconstants,
     447             :                             int width,
     448             :                             int height) {
     449             :   int y;
     450             :   void (*I422ToRGBARow)(const uint8* y_buf, const uint8* u_buf,
     451             :                         const uint8* v_buf, uint8* rgb_buf,
     452             :                         const struct YuvConstants* yuvconstants, int width) =
     453           0 :       I422ToRGBARow_C;
     454           0 :   if (!src_y || !src_u || !src_v || !dst_rgba || width <= 0 || height == 0) {
     455           0 :     return -1;
     456             :   }
     457             :   // Negative height means invert the image.
     458           0 :   if (height < 0) {
     459           0 :     height = -height;
     460           0 :     dst_rgba = dst_rgba + (height - 1) * dst_stride_rgba;
     461           0 :     dst_stride_rgba = -dst_stride_rgba;
     462             :   }
     463             : #if defined(HAS_I422TORGBAROW_SSSE3)
     464           0 :   if (TestCpuFlag(kCpuHasSSSE3)) {
     465           0 :     I422ToRGBARow = I422ToRGBARow_Any_SSSE3;
     466           0 :     if (IS_ALIGNED(width, 8)) {
     467           0 :       I422ToRGBARow = I422ToRGBARow_SSSE3;
     468             :     }
     469             :   }
     470             : #endif
     471             : #if defined(HAS_I422TORGBAROW_AVX2)
     472           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     473           0 :     I422ToRGBARow = I422ToRGBARow_Any_AVX2;
     474           0 :     if (IS_ALIGNED(width, 16)) {
     475           0 :       I422ToRGBARow = I422ToRGBARow_AVX2;
     476             :     }
     477             :   }
     478             : #endif
     479             : #if defined(HAS_I422TORGBAROW_NEON)
     480             :   if (TestCpuFlag(kCpuHasNEON)) {
     481             :     I422ToRGBARow = I422ToRGBARow_Any_NEON;
     482             :     if (IS_ALIGNED(width, 8)) {
     483             :       I422ToRGBARow = I422ToRGBARow_NEON;
     484             :     }
     485             :   }
     486             : #endif
     487             : #if defined(HAS_I422TORGBAROW_DSPR2)
     488             :   if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
     489             :       IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
     490             :       IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
     491             :       IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
     492             :       IS_ALIGNED(dst_rgba, 4) && IS_ALIGNED(dst_stride_rgba, 4)) {
     493             :     I422ToRGBARow = I422ToRGBARow_DSPR2;
     494             :   }
     495             : #endif
     496             : #if defined(HAS_I422TORGBAROW_MSA)
     497             :   if (TestCpuFlag(kCpuHasMSA)) {
     498             :     I422ToRGBARow = I422ToRGBARow_Any_MSA;
     499             :     if (IS_ALIGNED(width, 8)) {
     500             :       I422ToRGBARow = I422ToRGBARow_MSA;
     501             :     }
     502             :   }
     503             : #endif
     504             : 
     505           0 :   for (y = 0; y < height; ++y) {
     506           0 :     I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width);
     507           0 :     dst_rgba += dst_stride_rgba;
     508           0 :     src_y += src_stride_y;
     509           0 :     if (y & 1) {
     510           0 :       src_u += src_stride_u;
     511           0 :       src_v += src_stride_v;
     512             :     }
     513             :   }
     514           0 :   return 0;
     515             : }
     516             : 
     517             : // Convert I420 to RGBA.
     518             : LIBYUV_API
     519           0 : int I420ToRGBA(const uint8* src_y,
     520             :                int src_stride_y,
     521             :                const uint8* src_u,
     522             :                int src_stride_u,
     523             :                const uint8* src_v,
     524             :                int src_stride_v,
     525             :                uint8* dst_rgba,
     526             :                int dst_stride_rgba,
     527             :                int width,
     528             :                int height) {
     529             :   return I420ToRGBAMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
     530             :                           src_stride_v, dst_rgba, dst_stride_rgba,
     531           0 :                           &kYuvI601Constants, width, height);
     532             : }
     533             : 
     534             : // Convert I420 to BGRA.
     535             : LIBYUV_API
     536           0 : int I420ToBGRA(const uint8* src_y,
     537             :                int src_stride_y,
     538             :                const uint8* src_u,
     539             :                int src_stride_u,
     540             :                const uint8* src_v,
     541             :                int src_stride_v,
     542             :                uint8* dst_bgra,
     543             :                int dst_stride_bgra,
     544             :                int width,
     545             :                int height) {
     546             :   return I420ToRGBAMatrix(src_y, src_stride_y, src_v,
     547             :                           src_stride_v,  // Swap U and V
     548             :                           src_u, src_stride_u, dst_bgra, dst_stride_bgra,
     549             :                           &kYvuI601Constants,  // Use Yvu matrix
     550           0 :                           width, height);
     551             : }
     552             : 
     553             : // Convert I420 to RGB24 with matrix
     554           0 : static int I420ToRGB24Matrix(const uint8* src_y,
     555             :                              int src_stride_y,
     556             :                              const uint8* src_u,
     557             :                              int src_stride_u,
     558             :                              const uint8* src_v,
     559             :                              int src_stride_v,
     560             :                              uint8* dst_rgb24,
     561             :                              int dst_stride_rgb24,
     562             :                              const struct YuvConstants* yuvconstants,
     563             :                              int width,
     564             :                              int height) {
     565             :   int y;
     566             :   void (*I422ToRGB24Row)(const uint8* y_buf, const uint8* u_buf,
     567             :                          const uint8* v_buf, uint8* rgb_buf,
     568             :                          const struct YuvConstants* yuvconstants, int width) =
     569           0 :       I422ToRGB24Row_C;
     570           0 :   if (!src_y || !src_u || !src_v || !dst_rgb24 || width <= 0 || height == 0) {
     571           0 :     return -1;
     572             :   }
     573             :   // Negative height means invert the image.
     574           0 :   if (height < 0) {
     575           0 :     height = -height;
     576           0 :     dst_rgb24 = dst_rgb24 + (height - 1) * dst_stride_rgb24;
     577           0 :     dst_stride_rgb24 = -dst_stride_rgb24;
     578             :   }
     579             : #if defined(HAS_I422TORGB24ROW_SSSE3)
     580           0 :   if (TestCpuFlag(kCpuHasSSSE3)) {
     581           0 :     I422ToRGB24Row = I422ToRGB24Row_Any_SSSE3;
     582           0 :     if (IS_ALIGNED(width, 8)) {
     583           0 :       I422ToRGB24Row = I422ToRGB24Row_SSSE3;
     584             :     }
     585             :   }
     586             : #endif
     587             : #if defined(HAS_I422TORGB24ROW_AVX2)
     588           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     589           0 :     I422ToRGB24Row = I422ToRGB24Row_Any_AVX2;
     590           0 :     if (IS_ALIGNED(width, 16)) {
     591           0 :       I422ToRGB24Row = I422ToRGB24Row_AVX2;
     592             :     }
     593             :   }
     594             : #endif
     595             : #if defined(HAS_I422TORGB24ROW_NEON)
     596             :   if (TestCpuFlag(kCpuHasNEON)) {
     597             :     I422ToRGB24Row = I422ToRGB24Row_Any_NEON;
     598             :     if (IS_ALIGNED(width, 8)) {
     599             :       I422ToRGB24Row = I422ToRGB24Row_NEON;
     600             :     }
     601             :   }
     602             : #endif
     603             : #if defined(HAS_I422TORGB24ROW_MSA)
     604             :   if (TestCpuFlag(kCpuHasMSA)) {
     605             :     I422ToRGB24Row = I422ToRGB24Row_Any_MSA;
     606             :     if (IS_ALIGNED(width, 16)) {
     607             :       I422ToRGB24Row = I422ToRGB24Row_MSA;
     608             :     }
     609             :   }
     610             : #endif
     611             : 
     612           0 :   for (y = 0; y < height; ++y) {
     613           0 :     I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width);
     614           0 :     dst_rgb24 += dst_stride_rgb24;
     615           0 :     src_y += src_stride_y;
     616           0 :     if (y & 1) {
     617           0 :       src_u += src_stride_u;
     618           0 :       src_v += src_stride_v;
     619             :     }
     620             :   }
     621           0 :   return 0;
     622             : }
     623             : 
     624             : // Convert I420 to RGB24.
     625             : LIBYUV_API
     626           0 : int I420ToRGB24(const uint8* src_y,
     627             :                 int src_stride_y,
     628             :                 const uint8* src_u,
     629             :                 int src_stride_u,
     630             :                 const uint8* src_v,
     631             :                 int src_stride_v,
     632             :                 uint8* dst_rgb24,
     633             :                 int dst_stride_rgb24,
     634             :                 int width,
     635             :                 int height) {
     636             :   return I420ToRGB24Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
     637             :                            src_stride_v, dst_rgb24, dst_stride_rgb24,
     638           0 :                            &kYuvI601Constants, width, height);
     639             : }
     640             : 
     641             : // Convert I420 to RAW.
     642             : LIBYUV_API
     643           0 : int I420ToRAW(const uint8* src_y,
     644             :               int src_stride_y,
     645             :               const uint8* src_u,
     646             :               int src_stride_u,
     647             :               const uint8* src_v,
     648             :               int src_stride_v,
     649             :               uint8* dst_raw,
     650             :               int dst_stride_raw,
     651             :               int width,
     652             :               int height) {
     653             :   return I420ToRGB24Matrix(src_y, src_stride_y, src_v,
     654             :                            src_stride_v,  // Swap U and V
     655             :                            src_u, src_stride_u, dst_raw, dst_stride_raw,
     656             :                            &kYvuI601Constants,  // Use Yvu matrix
     657           0 :                            width, height);
     658             : }
     659             : 
     660             : // Convert I420 to ARGB1555.
     661             : LIBYUV_API
     662           0 : int I420ToARGB1555(const uint8* src_y,
     663             :                    int src_stride_y,
     664             :                    const uint8* src_u,
     665             :                    int src_stride_u,
     666             :                    const uint8* src_v,
     667             :                    int src_stride_v,
     668             :                    uint8* dst_argb1555,
     669             :                    int dst_stride_argb1555,
     670             :                    int width,
     671             :                    int height) {
     672             :   int y;
     673             :   void (*I422ToARGB1555Row)(const uint8* y_buf, const uint8* u_buf,
     674             :                             const uint8* v_buf, uint8* rgb_buf,
     675             :                             const struct YuvConstants* yuvconstants,
     676           0 :                             int width) = I422ToARGB1555Row_C;
     677           0 :   if (!src_y || !src_u || !src_v || !dst_argb1555 || width <= 0 ||
     678             :       height == 0) {
     679           0 :     return -1;
     680             :   }
     681             :   // Negative height means invert the image.
     682           0 :   if (height < 0) {
     683           0 :     height = -height;
     684           0 :     dst_argb1555 = dst_argb1555 + (height - 1) * dst_stride_argb1555;
     685           0 :     dst_stride_argb1555 = -dst_stride_argb1555;
     686             :   }
     687             : #if defined(HAS_I422TOARGB1555ROW_SSSE3)
     688           0 :   if (TestCpuFlag(kCpuHasSSSE3)) {
     689           0 :     I422ToARGB1555Row = I422ToARGB1555Row_Any_SSSE3;
     690           0 :     if (IS_ALIGNED(width, 8)) {
     691           0 :       I422ToARGB1555Row = I422ToARGB1555Row_SSSE3;
     692             :     }
     693             :   }
     694             : #endif
     695             : #if defined(HAS_I422TOARGB1555ROW_AVX2)
     696           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     697           0 :     I422ToARGB1555Row = I422ToARGB1555Row_Any_AVX2;
     698           0 :     if (IS_ALIGNED(width, 16)) {
     699           0 :       I422ToARGB1555Row = I422ToARGB1555Row_AVX2;
     700             :     }
     701             :   }
     702             : #endif
     703             : #if defined(HAS_I422TOARGB1555ROW_NEON)
     704             :   if (TestCpuFlag(kCpuHasNEON)) {
     705             :     I422ToARGB1555Row = I422ToARGB1555Row_Any_NEON;
     706             :     if (IS_ALIGNED(width, 8)) {
     707             :       I422ToARGB1555Row = I422ToARGB1555Row_NEON;
     708             :     }
     709             :   }
     710             : #endif
     711             : #if defined(HAS_I422TOARGB1555ROW_DSPR2)
     712             :   if (TestCpuFlag(kCpuHasDSPR2)) {
     713             :     I422ToARGB1555Row = I422ToARGB1555Row_Any_DSPR2;
     714             :     if (IS_ALIGNED(width, 4)) {
     715             :       I422ToARGB1555Row = I422ToARGB1555Row_DSPR2;
     716             :     }
     717             :   }
     718             : #endif
     719             : #if defined(HAS_I422TOARGB1555ROW_MSA)
     720             :   if (TestCpuFlag(kCpuHasMSA)) {
     721             :     I422ToARGB1555Row = I422ToARGB1555Row_Any_MSA;
     722             :     if (IS_ALIGNED(width, 8)) {
     723             :       I422ToARGB1555Row = I422ToARGB1555Row_MSA;
     724             :     }
     725             :   }
     726             : #endif
     727             : 
     728           0 :   for (y = 0; y < height; ++y) {
     729             :     I422ToARGB1555Row(src_y, src_u, src_v, dst_argb1555, &kYuvI601Constants,
     730           0 :                       width);
     731           0 :     dst_argb1555 += dst_stride_argb1555;
     732           0 :     src_y += src_stride_y;
     733           0 :     if (y & 1) {
     734           0 :       src_u += src_stride_u;
     735           0 :       src_v += src_stride_v;
     736             :     }
     737             :   }
     738           0 :   return 0;
     739             : }
     740             : 
     741             : // Convert I420 to ARGB4444.
     742             : LIBYUV_API
     743           0 : int I420ToARGB4444(const uint8* src_y,
     744             :                    int src_stride_y,
     745             :                    const uint8* src_u,
     746             :                    int src_stride_u,
     747             :                    const uint8* src_v,
     748             :                    int src_stride_v,
     749             :                    uint8* dst_argb4444,
     750             :                    int dst_stride_argb4444,
     751             :                    int width,
     752             :                    int height) {
     753             :   int y;
     754             :   void (*I422ToARGB4444Row)(const uint8* y_buf, const uint8* u_buf,
     755             :                             const uint8* v_buf, uint8* rgb_buf,
     756             :                             const struct YuvConstants* yuvconstants,
     757           0 :                             int width) = I422ToARGB4444Row_C;
     758           0 :   if (!src_y || !src_u || !src_v || !dst_argb4444 || width <= 0 ||
     759             :       height == 0) {
     760           0 :     return -1;
     761             :   }
     762             :   // Negative height means invert the image.
     763           0 :   if (height < 0) {
     764           0 :     height = -height;
     765           0 :     dst_argb4444 = dst_argb4444 + (height - 1) * dst_stride_argb4444;
     766           0 :     dst_stride_argb4444 = -dst_stride_argb4444;
     767             :   }
     768             : #if defined(HAS_I422TOARGB4444ROW_SSSE3)
     769           0 :   if (TestCpuFlag(kCpuHasSSSE3)) {
     770           0 :     I422ToARGB4444Row = I422ToARGB4444Row_Any_SSSE3;
     771           0 :     if (IS_ALIGNED(width, 8)) {
     772           0 :       I422ToARGB4444Row = I422ToARGB4444Row_SSSE3;
     773             :     }
     774             :   }
     775             : #endif
     776             : #if defined(HAS_I422TOARGB4444ROW_AVX2)
     777           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     778           0 :     I422ToARGB4444Row = I422ToARGB4444Row_Any_AVX2;
     779           0 :     if (IS_ALIGNED(width, 16)) {
     780           0 :       I422ToARGB4444Row = I422ToARGB4444Row_AVX2;
     781             :     }
     782             :   }
     783             : #endif
     784             : #if defined(HAS_I422TOARGB4444ROW_NEON)
     785             :   if (TestCpuFlag(kCpuHasNEON)) {
     786             :     I422ToARGB4444Row = I422ToARGB4444Row_Any_NEON;
     787             :     if (IS_ALIGNED(width, 8)) {
     788             :       I422ToARGB4444Row = I422ToARGB4444Row_NEON;
     789             :     }
     790             :   }
     791             : #endif
     792             : #if defined(HAS_I422TOARGB4444ROW_DSPR2)
     793             :   if (TestCpuFlag(kCpuHasDSPR2)) {
     794             :     I422ToARGB4444Row = I422ToARGB4444Row_Any_DSPR2;
     795             :     if (IS_ALIGNED(width, 4)) {
     796             :       I422ToARGB4444Row = I422ToARGB4444Row_DSPR2;
     797             :     }
     798             :   }
     799             : #endif
     800             : #if defined(HAS_I422TOARGB4444ROW_MSA)
     801             :   if (TestCpuFlag(kCpuHasMSA)) {
     802             :     I422ToARGB4444Row = I422ToARGB4444Row_Any_MSA;
     803             :     if (IS_ALIGNED(width, 8)) {
     804             :       I422ToARGB4444Row = I422ToARGB4444Row_MSA;
     805             :     }
     806             :   }
     807             : #endif
     808             : 
     809           0 :   for (y = 0; y < height; ++y) {
     810             :     I422ToARGB4444Row(src_y, src_u, src_v, dst_argb4444, &kYuvI601Constants,
     811           0 :                       width);
     812           0 :     dst_argb4444 += dst_stride_argb4444;
     813           0 :     src_y += src_stride_y;
     814           0 :     if (y & 1) {
     815           0 :       src_u += src_stride_u;
     816           0 :       src_v += src_stride_v;
     817             :     }
     818             :   }
     819           0 :   return 0;
     820             : }
     821             : 
     822             : // Convert I420 to RGB565.
     823             : LIBYUV_API
     824           0 : int I420ToRGB565(const uint8* src_y,
     825             :                  int src_stride_y,
     826             :                  const uint8* src_u,
     827             :                  int src_stride_u,
     828             :                  const uint8* src_v,
     829             :                  int src_stride_v,
     830             :                  uint8* dst_rgb565,
     831             :                  int dst_stride_rgb565,
     832             :                  int width,
     833             :                  int height) {
     834             :   int y;
     835             :   void (*I422ToRGB565Row)(const uint8* y_buf, const uint8* u_buf,
     836             :                           const uint8* v_buf, uint8* rgb_buf,
     837             :                           const struct YuvConstants* yuvconstants, int width) =
     838           0 :       I422ToRGB565Row_C;
     839           0 :   if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) {
     840           0 :     return -1;
     841             :   }
     842             :   // Negative height means invert the image.
     843           0 :   if (height < 0) {
     844           0 :     height = -height;
     845           0 :     dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565;
     846           0 :     dst_stride_rgb565 = -dst_stride_rgb565;
     847             :   }
     848             : #if defined(HAS_I422TORGB565ROW_SSSE3)
     849           0 :   if (TestCpuFlag(kCpuHasSSSE3)) {
     850           0 :     I422ToRGB565Row = I422ToRGB565Row_Any_SSSE3;
     851           0 :     if (IS_ALIGNED(width, 8)) {
     852           0 :       I422ToRGB565Row = I422ToRGB565Row_SSSE3;
     853             :     }
     854             :   }
     855             : #endif
     856             : #if defined(HAS_I422TORGB565ROW_AVX2)
     857           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     858           0 :     I422ToRGB565Row = I422ToRGB565Row_Any_AVX2;
     859           0 :     if (IS_ALIGNED(width, 16)) {
     860           0 :       I422ToRGB565Row = I422ToRGB565Row_AVX2;
     861             :     }
     862             :   }
     863             : #endif
     864             : #if defined(HAS_I422TORGB565ROW_NEON)
     865             :   if (TestCpuFlag(kCpuHasNEON)) {
     866             :     I422ToRGB565Row = I422ToRGB565Row_Any_NEON;
     867             :     if (IS_ALIGNED(width, 8)) {
     868             :       I422ToRGB565Row = I422ToRGB565Row_NEON;
     869             :     }
     870             :   }
     871             : #endif
     872             : #if defined(HAS_I422TORGB565ROW_MSA)
     873             :   if (TestCpuFlag(kCpuHasMSA)) {
     874             :     I422ToRGB565Row = I422ToRGB565Row_Any_MSA;
     875             :     if (IS_ALIGNED(width, 8)) {
     876             :       I422ToRGB565Row = I422ToRGB565Row_MSA;
     877             :     }
     878             :   }
     879             : #endif
     880             : 
     881           0 :   for (y = 0; y < height; ++y) {
     882           0 :     I422ToRGB565Row(src_y, src_u, src_v, dst_rgb565, &kYuvI601Constants, width);
     883           0 :     dst_rgb565 += dst_stride_rgb565;
     884           0 :     src_y += src_stride_y;
     885           0 :     if (y & 1) {
     886           0 :       src_u += src_stride_u;
     887           0 :       src_v += src_stride_v;
     888             :     }
     889             :   }
     890           0 :   return 0;
     891             : }
     892             : 
     893             : // Ordered 8x8 dither for 888 to 565.  Values from 0 to 7.
     894             : static const uint8 kDither565_4x4[16] = {
     895             :     0, 4, 1, 5, 6, 2, 7, 3, 1, 5, 0, 4, 7, 3, 6, 2,
     896             : };
     897             : 
     898             : // Convert I420 to RGB565 with dithering.
     899             : LIBYUV_API
     900           0 : int I420ToRGB565Dither(const uint8* src_y,
     901             :                        int src_stride_y,
     902             :                        const uint8* src_u,
     903             :                        int src_stride_u,
     904             :                        const uint8* src_v,
     905             :                        int src_stride_v,
     906             :                        uint8* dst_rgb565,
     907             :                        int dst_stride_rgb565,
     908             :                        const uint8* dither4x4,
     909             :                        int width,
     910             :                        int height) {
     911             :   int y;
     912             :   void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf,
     913             :                         const uint8* v_buf, uint8* rgb_buf,
     914             :                         const struct YuvConstants* yuvconstants, int width) =
     915           0 :       I422ToARGBRow_C;
     916             :   void (*ARGBToRGB565DitherRow)(const uint8* src_argb, uint8* dst_rgb,
     917             :                                 const uint32 dither4, int width) =
     918           0 :       ARGBToRGB565DitherRow_C;
     919           0 :   if (!src_y || !src_u || !src_v || !dst_rgb565 || width <= 0 || height == 0) {
     920           0 :     return -1;
     921             :   }
     922             :   // Negative height means invert the image.
     923           0 :   if (height < 0) {
     924           0 :     height = -height;
     925           0 :     dst_rgb565 = dst_rgb565 + (height - 1) * dst_stride_rgb565;
     926           0 :     dst_stride_rgb565 = -dst_stride_rgb565;
     927             :   }
     928           0 :   if (!dither4x4) {
     929           0 :     dither4x4 = kDither565_4x4;
     930             :   }
     931             : #if defined(HAS_I422TOARGBROW_SSSE3)
     932           0 :   if (TestCpuFlag(kCpuHasSSSE3)) {
     933           0 :     I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
     934           0 :     if (IS_ALIGNED(width, 8)) {
     935           0 :       I422ToARGBRow = I422ToARGBRow_SSSE3;
     936             :     }
     937             :   }
     938             : #endif
     939             : #if defined(HAS_I422TOARGBROW_AVX2)
     940           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     941           0 :     I422ToARGBRow = I422ToARGBRow_Any_AVX2;
     942           0 :     if (IS_ALIGNED(width, 16)) {
     943           0 :       I422ToARGBRow = I422ToARGBRow_AVX2;
     944             :     }
     945             :   }
     946             : #endif
     947             : #if defined(HAS_I422TOARGBROW_NEON)
     948             :   if (TestCpuFlag(kCpuHasNEON)) {
     949             :     I422ToARGBRow = I422ToARGBRow_Any_NEON;
     950             :     if (IS_ALIGNED(width, 8)) {
     951             :       I422ToARGBRow = I422ToARGBRow_NEON;
     952             :     }
     953             :   }
     954             : #endif
     955             : #if defined(HAS_I422TOARGBROW_DSPR2)
     956             :   if (TestCpuFlag(kCpuHasDSPR2) && IS_ALIGNED(width, 4) &&
     957             :       IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
     958             :       IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
     959             :       IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2)) {
     960             :     I422ToARGBRow = I422ToARGBRow_DSPR2;
     961             :   }
     962             : #endif
     963             : #if defined(HAS_I422TOARGBROW_MSA)
     964             :   if (TestCpuFlag(kCpuHasMSA)) {
     965             :     I422ToARGBRow = I422ToARGBRow_Any_MSA;
     966             :     if (IS_ALIGNED(width, 8)) {
     967             :       I422ToARGBRow = I422ToARGBRow_MSA;
     968             :     }
     969             :   }
     970             : #endif
     971             : #if defined(HAS_ARGBTORGB565DITHERROW_SSE2)
     972           0 :   if (TestCpuFlag(kCpuHasSSE2)) {
     973           0 :     ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2;
     974           0 :     if (IS_ALIGNED(width, 4)) {
     975           0 :       ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_SSE2;
     976             :     }
     977             :   }
     978             : #endif
     979             : #if defined(HAS_ARGBTORGB565DITHERROW_AVX2)
     980           0 :   if (TestCpuFlag(kCpuHasAVX2)) {
     981           0 :     ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_AVX2;
     982           0 :     if (IS_ALIGNED(width, 8)) {
     983           0 :       ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_AVX2;
     984             :     }
     985             :   }
     986             : #endif
     987             : #if defined(HAS_ARGBTORGB565DITHERROW_NEON)
     988             :   if (TestCpuFlag(kCpuHasNEON)) {
     989             :     ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_NEON;
     990             :     if (IS_ALIGNED(width, 8)) {
     991             :       ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_NEON;
     992             :     }
     993             :   }
     994             : #endif
     995             : #if defined(HAS_ARGBTORGB565DITHERROW_MSA)
     996             :   if (TestCpuFlag(kCpuHasMSA)) {
     997             :     ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_MSA;
     998             :     if (IS_ALIGNED(width, 8)) {
     999             :       ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_MSA;
    1000             :     }
    1001             :   }
    1002             : #endif
    1003             :   {
    1004             :     // Allocate a row of argb.
    1005           0 :     align_buffer_64(row_argb, width * 4);
    1006           0 :     for (y = 0; y < height; ++y) {
    1007           0 :       I422ToARGBRow(src_y, src_u, src_v, row_argb, &kYuvI601Constants, width);
    1008           0 :       ARGBToRGB565DitherRow(row_argb, dst_rgb565,
    1009           0 :                             *(uint32*)(dither4x4 + ((y & 3) << 2)),
    1010           0 :                             width);  // NOLINT
    1011           0 :       dst_rgb565 += dst_stride_rgb565;
    1012           0 :       src_y += src_stride_y;
    1013           0 :       if (y & 1) {
    1014           0 :         src_u += src_stride_u;
    1015           0 :         src_v += src_stride_v;
    1016             :       }
    1017             :     }
    1018           0 :     free_aligned_buffer_64(row_argb);
    1019             :   }
    1020           0 :   return 0;
    1021             : }
    1022             : 
    1023             : // Convert I420 to specified format
    1024             : LIBYUV_API
    1025           0 : int ConvertFromI420(const uint8* y,
    1026             :                     int y_stride,
    1027             :                     const uint8* u,
    1028             :                     int u_stride,
    1029             :                     const uint8* v,
    1030             :                     int v_stride,
    1031             :                     uint8* dst_sample,
    1032             :                     int dst_sample_stride,
    1033             :                     int width,
    1034             :                     int height,
    1035             :                     uint32 fourcc) {
    1036           0 :   uint32 format = CanonicalFourCC(fourcc);
    1037           0 :   int r = 0;
    1038           0 :   if (!y || !u || !v || !dst_sample || width <= 0 || height == 0) {
    1039           0 :     return -1;
    1040             :   }
    1041           0 :   switch (format) {
    1042             :     // Single plane formats
    1043             :     case FOURCC_YUY2:
    1044           0 :       r = I420ToYUY2(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1045             :                      dst_sample_stride ? dst_sample_stride : width * 2, width,
    1046           0 :                      height);
    1047           0 :       break;
    1048             :     case FOURCC_UYVY:
    1049           0 :       r = I420ToUYVY(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1050             :                      dst_sample_stride ? dst_sample_stride : width * 2, width,
    1051           0 :                      height);
    1052           0 :       break;
    1053             :     case FOURCC_RGBP:
    1054           0 :       r = I420ToRGB565(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1055             :                        dst_sample_stride ? dst_sample_stride : width * 2, width,
    1056           0 :                        height);
    1057           0 :       break;
    1058             :     case FOURCC_RGBO:
    1059           0 :       r = I420ToARGB1555(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1060             :                          dst_sample_stride ? dst_sample_stride : width * 2,
    1061           0 :                          width, height);
    1062           0 :       break;
    1063             :     case FOURCC_R444:
    1064           0 :       r = I420ToARGB4444(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1065             :                          dst_sample_stride ? dst_sample_stride : width * 2,
    1066           0 :                          width, height);
    1067           0 :       break;
    1068             :     case FOURCC_24BG:
    1069           0 :       r = I420ToRGB24(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1070             :                       dst_sample_stride ? dst_sample_stride : width * 3, width,
    1071           0 :                       height);
    1072           0 :       break;
    1073             :     case FOURCC_RAW:
    1074           0 :       r = I420ToRAW(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1075             :                     dst_sample_stride ? dst_sample_stride : width * 3, width,
    1076           0 :                     height);
    1077           0 :       break;
    1078             :     case FOURCC_ARGB:
    1079           0 :       r = I420ToARGB(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1080             :                      dst_sample_stride ? dst_sample_stride : width * 4, width,
    1081           0 :                      height);
    1082           0 :       break;
    1083             :     case FOURCC_BGRA:
    1084           0 :       r = I420ToBGRA(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1085             :                      dst_sample_stride ? dst_sample_stride : width * 4, width,
    1086           0 :                      height);
    1087           0 :       break;
    1088             :     case FOURCC_ABGR:
    1089           0 :       r = I420ToABGR(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1090             :                      dst_sample_stride ? dst_sample_stride : width * 4, width,
    1091           0 :                      height);
    1092           0 :       break;
    1093             :     case FOURCC_RGBA:
    1094           0 :       r = I420ToRGBA(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1095             :                      dst_sample_stride ? dst_sample_stride : width * 4, width,
    1096           0 :                      height);
    1097           0 :       break;
    1098             :     case FOURCC_I400:
    1099           0 :       r = I400Copy(y, y_stride, dst_sample,
    1100             :                    dst_sample_stride ? dst_sample_stride : width, width,
    1101           0 :                    height);
    1102           0 :       break;
    1103             :     case FOURCC_NV12: {
    1104           0 :       uint8* dst_uv = dst_sample + width * height;
    1105           0 :       r = I420ToNV12(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1106             :                      dst_sample_stride ? dst_sample_stride : width, dst_uv,
    1107             :                      dst_sample_stride ? dst_sample_stride : width, width,
    1108           0 :                      height);
    1109           0 :       break;
    1110             :     }
    1111             :     case FOURCC_NV21: {
    1112           0 :       uint8* dst_vu = dst_sample + width * height;
    1113           0 :       r = I420ToNV21(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1114             :                      dst_sample_stride ? dst_sample_stride : width, dst_vu,
    1115             :                      dst_sample_stride ? dst_sample_stride : width, width,
    1116           0 :                      height);
    1117           0 :       break;
    1118             :     }
    1119             :     // TODO(fbarchard): Add M420.
    1120             :     // Triplanar formats
    1121             :     case FOURCC_I420:
    1122             :     case FOURCC_YV12: {
    1123           0 :       dst_sample_stride = dst_sample_stride ? dst_sample_stride : width;
    1124           0 :       int halfstride = (dst_sample_stride + 1) / 2;
    1125           0 :       int halfheight = (height + 1) / 2;
    1126             :       uint8* dst_u;
    1127             :       uint8* dst_v;
    1128           0 :       if (format == FOURCC_YV12) {
    1129           0 :         dst_v = dst_sample + dst_sample_stride * height;
    1130           0 :         dst_u = dst_v + halfstride * halfheight;
    1131             :       } else {
    1132           0 :         dst_u = dst_sample + dst_sample_stride * height;
    1133           0 :         dst_v = dst_u + halfstride * halfheight;
    1134             :       }
    1135             :       r = I420Copy(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1136             :                    dst_sample_stride, dst_u, halfstride, dst_v, halfstride,
    1137           0 :                    width, height);
    1138           0 :       break;
    1139             :     }
    1140             :     case FOURCC_I422:
    1141             :     case FOURCC_YV16: {
    1142           0 :       dst_sample_stride = dst_sample_stride ? dst_sample_stride : width;
    1143           0 :       int halfstride = (dst_sample_stride + 1) / 2;
    1144             :       uint8* dst_u;
    1145             :       uint8* dst_v;
    1146           0 :       if (format == FOURCC_YV16) {
    1147           0 :         dst_v = dst_sample + dst_sample_stride * height;
    1148           0 :         dst_u = dst_v + halfstride * height;
    1149             :       } else {
    1150           0 :         dst_u = dst_sample + dst_sample_stride * height;
    1151           0 :         dst_v = dst_u + halfstride * height;
    1152             :       }
    1153             :       r = I420ToI422(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1154             :                      dst_sample_stride, dst_u, halfstride, dst_v, halfstride,
    1155           0 :                      width, height);
    1156           0 :       break;
    1157             :     }
    1158             :     case FOURCC_I444:
    1159             :     case FOURCC_YV24: {
    1160           0 :       dst_sample_stride = dst_sample_stride ? dst_sample_stride : width;
    1161             :       uint8* dst_u;
    1162             :       uint8* dst_v;
    1163           0 :       if (format == FOURCC_YV24) {
    1164           0 :         dst_v = dst_sample + dst_sample_stride * height;
    1165           0 :         dst_u = dst_v + dst_sample_stride * height;
    1166             :       } else {
    1167           0 :         dst_u = dst_sample + dst_sample_stride * height;
    1168           0 :         dst_v = dst_u + dst_sample_stride * height;
    1169             :       }
    1170             :       r = I420ToI444(y, y_stride, u, u_stride, v, v_stride, dst_sample,
    1171             :                      dst_sample_stride, dst_u, dst_sample_stride, dst_v,
    1172           0 :                      dst_sample_stride, width, height);
    1173           0 :       break;
    1174             :     }
    1175             :     // Formats not supported - MJPG, biplanar, some rgb formats.
    1176             :     default:
    1177           0 :       return -1;  // unknown fourcc - return failure code.
    1178             :   }
    1179           0 :   return r;
    1180             : }
    1181             : 
    1182             : #ifdef __cplusplus
    1183             : }  // extern "C"
    1184             : }  // namespace libyuv
    1185             : #endif

Generated by: LCOV version 1.13