media/libyuv/source/convert_argb.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright 2011 The LibYuv Project Authors. All rights reserved.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license
michael@0 5 * that can be found in the LICENSE file in the root of the source
michael@0 6 * tree. An additional intellectual property rights grant can be found
michael@0 7 * in the file PATENTS. All contributing project authors may
michael@0 8 * be found in the AUTHORS file in the root of the source tree.
michael@0 9 */
michael@0 10
michael@0 11 #include "libyuv/convert_argb.h"
michael@0 12
michael@0 13 #include "libyuv/cpu_id.h"
michael@0 14 #include "libyuv/format_conversion.h"
michael@0 15 #ifdef HAVE_JPEG
michael@0 16 #include "libyuv/mjpeg_decoder.h"
michael@0 17 #endif
michael@0 18 #include "libyuv/rotate_argb.h"
michael@0 19 #include "libyuv/row.h"
michael@0 20 #include "libyuv/video_common.h"
michael@0 21
michael@0 22 #ifdef __cplusplus
michael@0 23 namespace libyuv {
michael@0 24 extern "C" {
michael@0 25 #endif
michael@0 26
michael@0 27 // Copy ARGB with optional flipping
michael@0 28 LIBYUV_API
michael@0 29 int ARGBCopy(const uint8* src_argb, int src_stride_argb,
michael@0 30 uint8* dst_argb, int dst_stride_argb,
michael@0 31 int width, int height) {
michael@0 32 if (!src_argb || !dst_argb ||
michael@0 33 width <= 0 || height == 0) {
michael@0 34 return -1;
michael@0 35 }
michael@0 36 // Negative height means invert the image.
michael@0 37 if (height < 0) {
michael@0 38 height = -height;
michael@0 39 src_argb = src_argb + (height - 1) * src_stride_argb;
michael@0 40 src_stride_argb = -src_stride_argb;
michael@0 41 }
michael@0 42
michael@0 43 CopyPlane(src_argb, src_stride_argb, dst_argb, dst_stride_argb,
michael@0 44 width * 4, height);
michael@0 45 return 0;
michael@0 46 }
michael@0 47
michael@0 48 // Convert I444 to ARGB.
michael@0 49 LIBYUV_API
michael@0 50 int I444ToARGB(const uint8* src_y, int src_stride_y,
michael@0 51 const uint8* src_u, int src_stride_u,
michael@0 52 const uint8* src_v, int src_stride_v,
michael@0 53 uint8* dst_argb, int dst_stride_argb,
michael@0 54 int width, int height) {
michael@0 55 if (!src_y || !src_u || !src_v ||
michael@0 56 !dst_argb ||
michael@0 57 width <= 0 || height == 0) {
michael@0 58 return -1;
michael@0 59 }
michael@0 60 // Negative height means invert the image.
michael@0 61 if (height < 0) {
michael@0 62 height = -height;
michael@0 63 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 64 dst_stride_argb = -dst_stride_argb;
michael@0 65 }
michael@0 66 // Coalesce rows.
michael@0 67 if (src_stride_y == width &&
michael@0 68 src_stride_u == width &&
michael@0 69 src_stride_v == width &&
michael@0 70 dst_stride_argb == width * 4) {
michael@0 71 width *= height;
michael@0 72 height = 1;
michael@0 73 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
michael@0 74 }
michael@0 75 void (*I444ToARGBRow)(const uint8* y_buf,
michael@0 76 const uint8* u_buf,
michael@0 77 const uint8* v_buf,
michael@0 78 uint8* rgb_buf,
michael@0 79 int width) = I444ToARGBRow_C;
michael@0 80 #if defined(HAS_I444TOARGBROW_SSSE3)
michael@0 81 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 82 I444ToARGBRow = I444ToARGBRow_Any_SSSE3;
michael@0 83 if (IS_ALIGNED(width, 8)) {
michael@0 84 I444ToARGBRow = I444ToARGBRow_Unaligned_SSSE3;
michael@0 85 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 86 I444ToARGBRow = I444ToARGBRow_SSSE3;
michael@0 87 }
michael@0 88 }
michael@0 89 }
michael@0 90 #elif defined(HAS_I444TOARGBROW_NEON)
michael@0 91 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 92 I444ToARGBRow = I444ToARGBRow_Any_NEON;
michael@0 93 if (IS_ALIGNED(width, 8)) {
michael@0 94 I444ToARGBRow = I444ToARGBRow_NEON;
michael@0 95 }
michael@0 96 }
michael@0 97 #endif
michael@0 98
michael@0 99 for (int y = 0; y < height; ++y) {
michael@0 100 I444ToARGBRow(src_y, src_u, src_v, dst_argb, width);
michael@0 101 dst_argb += dst_stride_argb;
michael@0 102 src_y += src_stride_y;
michael@0 103 src_u += src_stride_u;
michael@0 104 src_v += src_stride_v;
michael@0 105 }
michael@0 106 return 0;
michael@0 107 }
michael@0 108
michael@0 109 // Convert I422 to ARGB.
michael@0 110 LIBYUV_API
michael@0 111 int I422ToARGB(const uint8* src_y, int src_stride_y,
michael@0 112 const uint8* src_u, int src_stride_u,
michael@0 113 const uint8* src_v, int src_stride_v,
michael@0 114 uint8* dst_argb, int dst_stride_argb,
michael@0 115 int width, int height) {
michael@0 116 if (!src_y || !src_u || !src_v ||
michael@0 117 !dst_argb ||
michael@0 118 width <= 0 || height == 0) {
michael@0 119 return -1;
michael@0 120 }
michael@0 121 // Negative height means invert the image.
michael@0 122 if (height < 0) {
michael@0 123 height = -height;
michael@0 124 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 125 dst_stride_argb = -dst_stride_argb;
michael@0 126 }
michael@0 127 // Coalesce rows.
michael@0 128 if (src_stride_y == width &&
michael@0 129 src_stride_u * 2 == width &&
michael@0 130 src_stride_v * 2 == width &&
michael@0 131 dst_stride_argb == width * 4) {
michael@0 132 width *= height;
michael@0 133 height = 1;
michael@0 134 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
michael@0 135 }
michael@0 136 void (*I422ToARGBRow)(const uint8* y_buf,
michael@0 137 const uint8* u_buf,
michael@0 138 const uint8* v_buf,
michael@0 139 uint8* rgb_buf,
michael@0 140 int width) = I422ToARGBRow_C;
michael@0 141 #if defined(HAS_I422TOARGBROW_SSSE3)
michael@0 142 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 143 I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
michael@0 144 if (IS_ALIGNED(width, 8)) {
michael@0 145 I422ToARGBRow = I422ToARGBRow_Unaligned_SSSE3;
michael@0 146 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 147 I422ToARGBRow = I422ToARGBRow_SSSE3;
michael@0 148 }
michael@0 149 }
michael@0 150 }
michael@0 151 #endif
michael@0 152 #if defined(HAS_I422TOARGBROW_AVX2)
michael@0 153 if (TestCpuFlag(kCpuHasAVX2) && width >= 16) {
michael@0 154 I422ToARGBRow = I422ToARGBRow_Any_AVX2;
michael@0 155 if (IS_ALIGNED(width, 16)) {
michael@0 156 I422ToARGBRow = I422ToARGBRow_AVX2;
michael@0 157 }
michael@0 158 }
michael@0 159 #endif
michael@0 160 #if defined(HAS_I422TOARGBROW_NEON)
michael@0 161 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 162 I422ToARGBRow = I422ToARGBRow_Any_NEON;
michael@0 163 if (IS_ALIGNED(width, 8)) {
michael@0 164 I422ToARGBRow = I422ToARGBRow_NEON;
michael@0 165 }
michael@0 166 }
michael@0 167 #endif
michael@0 168 #if defined(HAS_I422TOARGBROW_MIPS_DSPR2)
michael@0 169 if (TestCpuFlag(kCpuHasMIPS_DSPR2) && IS_ALIGNED(width, 4) &&
michael@0 170 IS_ALIGNED(src_y, 4) && IS_ALIGNED(src_stride_y, 4) &&
michael@0 171 IS_ALIGNED(src_u, 2) && IS_ALIGNED(src_stride_u, 2) &&
michael@0 172 IS_ALIGNED(src_v, 2) && IS_ALIGNED(src_stride_v, 2) &&
michael@0 173 IS_ALIGNED(dst_argb, 4) && IS_ALIGNED(dst_stride_argb, 4)) {
michael@0 174 I422ToARGBRow = I422ToARGBRow_MIPS_DSPR2;
michael@0 175 }
michael@0 176 #endif
michael@0 177
michael@0 178 for (int y = 0; y < height; ++y) {
michael@0 179 I422ToARGBRow(src_y, src_u, src_v, dst_argb, width);
michael@0 180 dst_argb += dst_stride_argb;
michael@0 181 src_y += src_stride_y;
michael@0 182 src_u += src_stride_u;
michael@0 183 src_v += src_stride_v;
michael@0 184 }
michael@0 185 return 0;
michael@0 186 }
michael@0 187
michael@0 188 // Convert I411 to ARGB.
michael@0 189 LIBYUV_API
michael@0 190 int I411ToARGB(const uint8* src_y, int src_stride_y,
michael@0 191 const uint8* src_u, int src_stride_u,
michael@0 192 const uint8* src_v, int src_stride_v,
michael@0 193 uint8* dst_argb, int dst_stride_argb,
michael@0 194 int width, int height) {
michael@0 195 if (!src_y || !src_u || !src_v ||
michael@0 196 !dst_argb ||
michael@0 197 width <= 0 || height == 0) {
michael@0 198 return -1;
michael@0 199 }
michael@0 200 // Negative height means invert the image.
michael@0 201 if (height < 0) {
michael@0 202 height = -height;
michael@0 203 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 204 dst_stride_argb = -dst_stride_argb;
michael@0 205 }
michael@0 206 // Coalesce rows.
michael@0 207 if (src_stride_y == width &&
michael@0 208 src_stride_u * 4 == width &&
michael@0 209 src_stride_v * 4 == width &&
michael@0 210 dst_stride_argb == width * 4) {
michael@0 211 width *= height;
michael@0 212 height = 1;
michael@0 213 src_stride_y = src_stride_u = src_stride_v = dst_stride_argb = 0;
michael@0 214 }
michael@0 215 void (*I411ToARGBRow)(const uint8* y_buf,
michael@0 216 const uint8* u_buf,
michael@0 217 const uint8* v_buf,
michael@0 218 uint8* rgb_buf,
michael@0 219 int width) = I411ToARGBRow_C;
michael@0 220 #if defined(HAS_I411TOARGBROW_SSSE3)
michael@0 221 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 222 I411ToARGBRow = I411ToARGBRow_Any_SSSE3;
michael@0 223 if (IS_ALIGNED(width, 8)) {
michael@0 224 I411ToARGBRow = I411ToARGBRow_Unaligned_SSSE3;
michael@0 225 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 226 I411ToARGBRow = I411ToARGBRow_SSSE3;
michael@0 227 }
michael@0 228 }
michael@0 229 }
michael@0 230 #elif defined(HAS_I411TOARGBROW_NEON)
michael@0 231 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 232 I411ToARGBRow = I411ToARGBRow_Any_NEON;
michael@0 233 if (IS_ALIGNED(width, 8)) {
michael@0 234 I411ToARGBRow = I411ToARGBRow_NEON;
michael@0 235 }
michael@0 236 }
michael@0 237 #endif
michael@0 238
michael@0 239 for (int y = 0; y < height; ++y) {
michael@0 240 I411ToARGBRow(src_y, src_u, src_v, dst_argb, width);
michael@0 241 dst_argb += dst_stride_argb;
michael@0 242 src_y += src_stride_y;
michael@0 243 src_u += src_stride_u;
michael@0 244 src_v += src_stride_v;
michael@0 245 }
michael@0 246 return 0;
michael@0 247 }
michael@0 248
michael@0 249 // Convert I400 to ARGB.
michael@0 250 LIBYUV_API
michael@0 251 int I400ToARGB_Reference(const uint8* src_y, int src_stride_y,
michael@0 252 uint8* dst_argb, int dst_stride_argb,
michael@0 253 int width, int height) {
michael@0 254 if (!src_y || !dst_argb ||
michael@0 255 width <= 0 || height == 0) {
michael@0 256 return -1;
michael@0 257 }
michael@0 258 // Negative height means invert the image.
michael@0 259 if (height < 0) {
michael@0 260 height = -height;
michael@0 261 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 262 dst_stride_argb = -dst_stride_argb;
michael@0 263 }
michael@0 264 // Coalesce rows.
michael@0 265 if (src_stride_y == width &&
michael@0 266 dst_stride_argb == width * 4) {
michael@0 267 width *= height;
michael@0 268 height = 1;
michael@0 269 src_stride_y = dst_stride_argb = 0;
michael@0 270 }
michael@0 271 void (*YToARGBRow)(const uint8* y_buf,
michael@0 272 uint8* rgb_buf,
michael@0 273 int width) = YToARGBRow_C;
michael@0 274 #if defined(HAS_YTOARGBROW_SSE2)
michael@0 275 if (TestCpuFlag(kCpuHasSSE2) && width >= 8 &&
michael@0 276 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 277 YToARGBRow = YToARGBRow_Any_SSE2;
michael@0 278 if (IS_ALIGNED(width, 8)) {
michael@0 279 YToARGBRow = YToARGBRow_SSE2;
michael@0 280 }
michael@0 281 }
michael@0 282 #elif defined(HAS_YTOARGBROW_NEON)
michael@0 283 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 284 YToARGBRow = YToARGBRow_Any_NEON;
michael@0 285 if (IS_ALIGNED(width, 8)) {
michael@0 286 YToARGBRow = YToARGBRow_NEON;
michael@0 287 }
michael@0 288 }
michael@0 289 #endif
michael@0 290
michael@0 291 for (int y = 0; y < height; ++y) {
michael@0 292 YToARGBRow(src_y, dst_argb, width);
michael@0 293 dst_argb += dst_stride_argb;
michael@0 294 src_y += src_stride_y;
michael@0 295 }
michael@0 296 return 0;
michael@0 297 }
michael@0 298
michael@0 299 // Convert I400 to ARGB.
michael@0 300 LIBYUV_API
michael@0 301 int I400ToARGB(const uint8* src_y, int src_stride_y,
michael@0 302 uint8* dst_argb, int dst_stride_argb,
michael@0 303 int width, int height) {
michael@0 304 if (!src_y || !dst_argb ||
michael@0 305 width <= 0 || height == 0) {
michael@0 306 return -1;
michael@0 307 }
michael@0 308 // Negative height means invert the image.
michael@0 309 if (height < 0) {
michael@0 310 height = -height;
michael@0 311 src_y = src_y + (height - 1) * src_stride_y;
michael@0 312 src_stride_y = -src_stride_y;
michael@0 313 }
michael@0 314 // Coalesce rows.
michael@0 315 if (src_stride_y == width &&
michael@0 316 dst_stride_argb == width * 4) {
michael@0 317 width *= height;
michael@0 318 height = 1;
michael@0 319 src_stride_y = dst_stride_argb = 0;
michael@0 320 }
michael@0 321 void (*I400ToARGBRow)(const uint8* src_y, uint8* dst_argb, int pix) =
michael@0 322 I400ToARGBRow_C;
michael@0 323 #if defined(HAS_I400TOARGBROW_SSE2)
michael@0 324 if (TestCpuFlag(kCpuHasSSE2) && width >= 8) {
michael@0 325 I400ToARGBRow = I400ToARGBRow_Any_SSE2;
michael@0 326 if (IS_ALIGNED(width, 8)) {
michael@0 327 I400ToARGBRow = I400ToARGBRow_Unaligned_SSE2;
michael@0 328 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 329 I400ToARGBRow = I400ToARGBRow_SSE2;
michael@0 330 }
michael@0 331 }
michael@0 332 }
michael@0 333 #elif defined(HAS_I400TOARGBROW_NEON)
michael@0 334 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 335 I400ToARGBRow = I400ToARGBRow_Any_NEON;
michael@0 336 if (IS_ALIGNED(width, 8)) {
michael@0 337 I400ToARGBRow = I400ToARGBRow_NEON;
michael@0 338 }
michael@0 339 }
michael@0 340 #endif
michael@0 341 for (int y = 0; y < height; ++y) {
michael@0 342 I400ToARGBRow(src_y, dst_argb, width);
michael@0 343 src_y += src_stride_y;
michael@0 344 dst_argb += dst_stride_argb;
michael@0 345 }
michael@0 346 return 0;
michael@0 347 }
michael@0 348
michael@0 349 // Shuffle table for converting BGRA to ARGB.
michael@0 350 static uvec8 kShuffleMaskBGRAToARGB = {
michael@0 351 3u, 2u, 1u, 0u, 7u, 6u, 5u, 4u, 11u, 10u, 9u, 8u, 15u, 14u, 13u, 12u
michael@0 352 };
michael@0 353
michael@0 354 // Shuffle table for converting ABGR to ARGB.
michael@0 355 static uvec8 kShuffleMaskABGRToARGB = {
michael@0 356 2u, 1u, 0u, 3u, 6u, 5u, 4u, 7u, 10u, 9u, 8u, 11u, 14u, 13u, 12u, 15u
michael@0 357 };
michael@0 358
michael@0 359 // Shuffle table for converting RGBA to ARGB.
michael@0 360 static uvec8 kShuffleMaskRGBAToARGB = {
michael@0 361 1u, 2u, 3u, 0u, 5u, 6u, 7u, 4u, 9u, 10u, 11u, 8u, 13u, 14u, 15u, 12u
michael@0 362 };
michael@0 363
michael@0 364 // Convert BGRA to ARGB.
michael@0 365 LIBYUV_API
michael@0 366 int BGRAToARGB(const uint8* src_bgra, int src_stride_bgra,
michael@0 367 uint8* dst_argb, int dst_stride_argb,
michael@0 368 int width, int height) {
michael@0 369 return ARGBShuffle(src_bgra, src_stride_bgra,
michael@0 370 dst_argb, dst_stride_argb,
michael@0 371 (const uint8*)(&kShuffleMaskBGRAToARGB),
michael@0 372 width, height);
michael@0 373 }
michael@0 374
michael@0 375 // Convert ABGR to ARGB.
michael@0 376 LIBYUV_API
michael@0 377 int ABGRToARGB(const uint8* src_abgr, int src_stride_abgr,
michael@0 378 uint8* dst_argb, int dst_stride_argb,
michael@0 379 int width, int height) {
michael@0 380 return ARGBShuffle(src_abgr, src_stride_abgr,
michael@0 381 dst_argb, dst_stride_argb,
michael@0 382 (const uint8*)(&kShuffleMaskABGRToARGB),
michael@0 383 width, height);
michael@0 384 }
michael@0 385
michael@0 386 // Convert RGBA to ARGB.
michael@0 387 LIBYUV_API
michael@0 388 int RGBAToARGB(const uint8* src_rgba, int src_stride_rgba,
michael@0 389 uint8* dst_argb, int dst_stride_argb,
michael@0 390 int width, int height) {
michael@0 391 return ARGBShuffle(src_rgba, src_stride_rgba,
michael@0 392 dst_argb, dst_stride_argb,
michael@0 393 (const uint8*)(&kShuffleMaskRGBAToARGB),
michael@0 394 width, height);
michael@0 395 }
michael@0 396
michael@0 397 // Convert RGB24 to ARGB.
michael@0 398 LIBYUV_API
michael@0 399 int RGB24ToARGB(const uint8* src_rgb24, int src_stride_rgb24,
michael@0 400 uint8* dst_argb, int dst_stride_argb,
michael@0 401 int width, int height) {
michael@0 402 if (!src_rgb24 || !dst_argb ||
michael@0 403 width <= 0 || height == 0) {
michael@0 404 return -1;
michael@0 405 }
michael@0 406 // Negative height means invert the image.
michael@0 407 if (height < 0) {
michael@0 408 height = -height;
michael@0 409 src_rgb24 = src_rgb24 + (height - 1) * src_stride_rgb24;
michael@0 410 src_stride_rgb24 = -src_stride_rgb24;
michael@0 411 }
michael@0 412 // Coalesce rows.
michael@0 413 if (src_stride_rgb24 == width * 3 &&
michael@0 414 dst_stride_argb == width * 4) {
michael@0 415 width *= height;
michael@0 416 height = 1;
michael@0 417 src_stride_rgb24 = dst_stride_argb = 0;
michael@0 418 }
michael@0 419 void (*RGB24ToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) =
michael@0 420 RGB24ToARGBRow_C;
michael@0 421 #if defined(HAS_RGB24TOARGBROW_SSSE3)
michael@0 422 if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 &&
michael@0 423 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 424 RGB24ToARGBRow = RGB24ToARGBRow_Any_SSSE3;
michael@0 425 if (IS_ALIGNED(width, 16)) {
michael@0 426 RGB24ToARGBRow = RGB24ToARGBRow_SSSE3;
michael@0 427 }
michael@0 428 }
michael@0 429 #elif defined(HAS_RGB24TOARGBROW_NEON)
michael@0 430 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 431 RGB24ToARGBRow = RGB24ToARGBRow_Any_NEON;
michael@0 432 if (IS_ALIGNED(width, 8)) {
michael@0 433 RGB24ToARGBRow = RGB24ToARGBRow_NEON;
michael@0 434 }
michael@0 435 }
michael@0 436 #endif
michael@0 437
michael@0 438 for (int y = 0; y < height; ++y) {
michael@0 439 RGB24ToARGBRow(src_rgb24, dst_argb, width);
michael@0 440 src_rgb24 += src_stride_rgb24;
michael@0 441 dst_argb += dst_stride_argb;
michael@0 442 }
michael@0 443 return 0;
michael@0 444 }
michael@0 445
michael@0 446 // Convert RAW to ARGB.
michael@0 447 LIBYUV_API
michael@0 448 int RAWToARGB(const uint8* src_raw, int src_stride_raw,
michael@0 449 uint8* dst_argb, int dst_stride_argb,
michael@0 450 int width, int height) {
michael@0 451 if (!src_raw || !dst_argb ||
michael@0 452 width <= 0 || height == 0) {
michael@0 453 return -1;
michael@0 454 }
michael@0 455 // Negative height means invert the image.
michael@0 456 if (height < 0) {
michael@0 457 height = -height;
michael@0 458 src_raw = src_raw + (height - 1) * src_stride_raw;
michael@0 459 src_stride_raw = -src_stride_raw;
michael@0 460 }
michael@0 461 // Coalesce rows.
michael@0 462 if (src_stride_raw == width * 3 &&
michael@0 463 dst_stride_argb == width * 4) {
michael@0 464 width *= height;
michael@0 465 height = 1;
michael@0 466 src_stride_raw = dst_stride_argb = 0;
michael@0 467 }
michael@0 468 void (*RAWToARGBRow)(const uint8* src_rgb, uint8* dst_argb, int pix) =
michael@0 469 RAWToARGBRow_C;
michael@0 470 #if defined(HAS_RAWTOARGBROW_SSSE3)
michael@0 471 if (TestCpuFlag(kCpuHasSSSE3) && width >= 16 &&
michael@0 472 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 473 RAWToARGBRow = RAWToARGBRow_Any_SSSE3;
michael@0 474 if (IS_ALIGNED(width, 16)) {
michael@0 475 RAWToARGBRow = RAWToARGBRow_SSSE3;
michael@0 476 }
michael@0 477 }
michael@0 478 #elif defined(HAS_RAWTOARGBROW_NEON)
michael@0 479 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 480 RAWToARGBRow = RAWToARGBRow_Any_NEON;
michael@0 481 if (IS_ALIGNED(width, 8)) {
michael@0 482 RAWToARGBRow = RAWToARGBRow_NEON;
michael@0 483 }
michael@0 484 }
michael@0 485 #endif
michael@0 486
michael@0 487 for (int y = 0; y < height; ++y) {
michael@0 488 RAWToARGBRow(src_raw, dst_argb, width);
michael@0 489 src_raw += src_stride_raw;
michael@0 490 dst_argb += dst_stride_argb;
michael@0 491 }
michael@0 492 return 0;
michael@0 493 }
michael@0 494
michael@0 495 // Convert RGB565 to ARGB.
michael@0 496 LIBYUV_API
michael@0 497 int RGB565ToARGB(const uint8* src_rgb565, int src_stride_rgb565,
michael@0 498 uint8* dst_argb, int dst_stride_argb,
michael@0 499 int width, int height) {
michael@0 500 if (!src_rgb565 || !dst_argb ||
michael@0 501 width <= 0 || height == 0) {
michael@0 502 return -1;
michael@0 503 }
michael@0 504 // Negative height means invert the image.
michael@0 505 if (height < 0) {
michael@0 506 height = -height;
michael@0 507 src_rgb565 = src_rgb565 + (height - 1) * src_stride_rgb565;
michael@0 508 src_stride_rgb565 = -src_stride_rgb565;
michael@0 509 }
michael@0 510 // Coalesce rows.
michael@0 511 if (src_stride_rgb565 == width * 2 &&
michael@0 512 dst_stride_argb == width * 4) {
michael@0 513 width *= height;
michael@0 514 height = 1;
michael@0 515 src_stride_rgb565 = dst_stride_argb = 0;
michael@0 516 }
michael@0 517 void (*RGB565ToARGBRow)(const uint8* src_rgb565, uint8* dst_argb, int pix) =
michael@0 518 RGB565ToARGBRow_C;
michael@0 519 #if defined(HAS_RGB565TOARGBROW_SSE2)
michael@0 520 if (TestCpuFlag(kCpuHasSSE2) && width >= 8 &&
michael@0 521 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 522 RGB565ToARGBRow = RGB565ToARGBRow_Any_SSE2;
michael@0 523 if (IS_ALIGNED(width, 8)) {
michael@0 524 RGB565ToARGBRow = RGB565ToARGBRow_SSE2;
michael@0 525 }
michael@0 526 }
michael@0 527 #elif defined(HAS_RGB565TOARGBROW_NEON)
michael@0 528 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 529 RGB565ToARGBRow = RGB565ToARGBRow_Any_NEON;
michael@0 530 if (IS_ALIGNED(width, 8)) {
michael@0 531 RGB565ToARGBRow = RGB565ToARGBRow_NEON;
michael@0 532 }
michael@0 533 }
michael@0 534 #endif
michael@0 535
michael@0 536 for (int y = 0; y < height; ++y) {
michael@0 537 RGB565ToARGBRow(src_rgb565, dst_argb, width);
michael@0 538 src_rgb565 += src_stride_rgb565;
michael@0 539 dst_argb += dst_stride_argb;
michael@0 540 }
michael@0 541 return 0;
michael@0 542 }
michael@0 543
michael@0 544 // Convert ARGB1555 to ARGB.
michael@0 545 LIBYUV_API
michael@0 546 int ARGB1555ToARGB(const uint8* src_argb1555, int src_stride_argb1555,
michael@0 547 uint8* dst_argb, int dst_stride_argb,
michael@0 548 int width, int height) {
michael@0 549 if (!src_argb1555 || !dst_argb ||
michael@0 550 width <= 0 || height == 0) {
michael@0 551 return -1;
michael@0 552 }
michael@0 553 // Negative height means invert the image.
michael@0 554 if (height < 0) {
michael@0 555 height = -height;
michael@0 556 src_argb1555 = src_argb1555 + (height - 1) * src_stride_argb1555;
michael@0 557 src_stride_argb1555 = -src_stride_argb1555;
michael@0 558 }
michael@0 559 // Coalesce rows.
michael@0 560 if (src_stride_argb1555 == width * 2 &&
michael@0 561 dst_stride_argb == width * 4) {
michael@0 562 width *= height;
michael@0 563 height = 1;
michael@0 564 src_stride_argb1555 = dst_stride_argb = 0;
michael@0 565 }
michael@0 566 void (*ARGB1555ToARGBRow)(const uint8* src_argb1555, uint8* dst_argb,
michael@0 567 int pix) = ARGB1555ToARGBRow_C;
michael@0 568 #if defined(HAS_ARGB1555TOARGBROW_SSE2)
michael@0 569 if (TestCpuFlag(kCpuHasSSE2) && width >= 8 &&
michael@0 570 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 571 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_SSE2;
michael@0 572 if (IS_ALIGNED(width, 8)) {
michael@0 573 ARGB1555ToARGBRow = ARGB1555ToARGBRow_SSE2;
michael@0 574 }
michael@0 575 }
michael@0 576 #elif defined(HAS_ARGB1555TOARGBROW_NEON)
michael@0 577 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 578 ARGB1555ToARGBRow = ARGB1555ToARGBRow_Any_NEON;
michael@0 579 if (IS_ALIGNED(width, 8)) {
michael@0 580 ARGB1555ToARGBRow = ARGB1555ToARGBRow_NEON;
michael@0 581 }
michael@0 582 }
michael@0 583 #endif
michael@0 584
michael@0 585 for (int y = 0; y < height; ++y) {
michael@0 586 ARGB1555ToARGBRow(src_argb1555, dst_argb, width);
michael@0 587 src_argb1555 += src_stride_argb1555;
michael@0 588 dst_argb += dst_stride_argb;
michael@0 589 }
michael@0 590 return 0;
michael@0 591 }
michael@0 592
michael@0 593 // Convert ARGB4444 to ARGB.
michael@0 594 LIBYUV_API
michael@0 595 int ARGB4444ToARGB(const uint8* src_argb4444, int src_stride_argb4444,
michael@0 596 uint8* dst_argb, int dst_stride_argb,
michael@0 597 int width, int height) {
michael@0 598 if (!src_argb4444 || !dst_argb ||
michael@0 599 width <= 0 || height == 0) {
michael@0 600 return -1;
michael@0 601 }
michael@0 602 // Negative height means invert the image.
michael@0 603 if (height < 0) {
michael@0 604 height = -height;
michael@0 605 src_argb4444 = src_argb4444 + (height - 1) * src_stride_argb4444;
michael@0 606 src_stride_argb4444 = -src_stride_argb4444;
michael@0 607 }
michael@0 608 // Coalesce rows.
michael@0 609 if (src_stride_argb4444 == width * 2 &&
michael@0 610 dst_stride_argb == width * 4) {
michael@0 611 width *= height;
michael@0 612 height = 1;
michael@0 613 src_stride_argb4444 = dst_stride_argb = 0;
michael@0 614 }
michael@0 615 void (*ARGB4444ToARGBRow)(const uint8* src_argb4444, uint8* dst_argb,
michael@0 616 int pix) = ARGB4444ToARGBRow_C;
michael@0 617 #if defined(HAS_ARGB4444TOARGBROW_SSE2)
michael@0 618 if (TestCpuFlag(kCpuHasSSE2) && width >= 8 &&
michael@0 619 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 620 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_SSE2;
michael@0 621 if (IS_ALIGNED(width, 8)) {
michael@0 622 ARGB4444ToARGBRow = ARGB4444ToARGBRow_SSE2;
michael@0 623 }
michael@0 624 }
michael@0 625 #elif defined(HAS_ARGB4444TOARGBROW_NEON)
michael@0 626 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 627 ARGB4444ToARGBRow = ARGB4444ToARGBRow_Any_NEON;
michael@0 628 if (IS_ALIGNED(width, 8)) {
michael@0 629 ARGB4444ToARGBRow = ARGB4444ToARGBRow_NEON;
michael@0 630 }
michael@0 631 }
michael@0 632 #endif
michael@0 633
michael@0 634 for (int y = 0; y < height; ++y) {
michael@0 635 ARGB4444ToARGBRow(src_argb4444, dst_argb, width);
michael@0 636 src_argb4444 += src_stride_argb4444;
michael@0 637 dst_argb += dst_stride_argb;
michael@0 638 }
michael@0 639 return 0;
michael@0 640 }
michael@0 641
michael@0 642 // Convert NV12 to ARGB.
michael@0 643 LIBYUV_API
michael@0 644 int NV12ToARGB(const uint8* src_y, int src_stride_y,
michael@0 645 const uint8* src_uv, int src_stride_uv,
michael@0 646 uint8* dst_argb, int dst_stride_argb,
michael@0 647 int width, int height) {
michael@0 648 if (!src_y || !src_uv || !dst_argb ||
michael@0 649 width <= 0 || height == 0) {
michael@0 650 return -1;
michael@0 651 }
michael@0 652 // Negative height means invert the image.
michael@0 653 if (height < 0) {
michael@0 654 height = -height;
michael@0 655 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 656 dst_stride_argb = -dst_stride_argb;
michael@0 657 }
michael@0 658 void (*NV12ToARGBRow)(const uint8* y_buf,
michael@0 659 const uint8* uv_buf,
michael@0 660 uint8* rgb_buf,
michael@0 661 int width) = NV12ToARGBRow_C;
michael@0 662 #if defined(HAS_NV12TOARGBROW_SSSE3)
michael@0 663 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 664 NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3;
michael@0 665 if (IS_ALIGNED(width, 8)) {
michael@0 666 NV12ToARGBRow = NV12ToARGBRow_Unaligned_SSSE3;
michael@0 667 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 668 NV12ToARGBRow = NV12ToARGBRow_SSSE3;
michael@0 669 }
michael@0 670 }
michael@0 671 }
michael@0 672 #elif defined(HAS_NV12TOARGBROW_NEON)
michael@0 673 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 674 NV12ToARGBRow = NV12ToARGBRow_Any_NEON;
michael@0 675 if (IS_ALIGNED(width, 8)) {
michael@0 676 NV12ToARGBRow = NV12ToARGBRow_NEON;
michael@0 677 }
michael@0 678 }
michael@0 679 #endif
michael@0 680
michael@0 681 for (int y = 0; y < height; ++y) {
michael@0 682 NV12ToARGBRow(src_y, src_uv, dst_argb, width);
michael@0 683 dst_argb += dst_stride_argb;
michael@0 684 src_y += src_stride_y;
michael@0 685 if (y & 1) {
michael@0 686 src_uv += src_stride_uv;
michael@0 687 }
michael@0 688 }
michael@0 689 return 0;
michael@0 690 }
michael@0 691
michael@0 692 // Convert NV21 to ARGB.
michael@0 693 LIBYUV_API
michael@0 694 int NV21ToARGB(const uint8* src_y, int src_stride_y,
michael@0 695 const uint8* src_uv, int src_stride_uv,
michael@0 696 uint8* dst_argb, int dst_stride_argb,
michael@0 697 int width, int height) {
michael@0 698 if (!src_y || !src_uv || !dst_argb ||
michael@0 699 width <= 0 || height == 0) {
michael@0 700 return -1;
michael@0 701 }
michael@0 702 // Negative height means invert the image.
michael@0 703 if (height < 0) {
michael@0 704 height = -height;
michael@0 705 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 706 dst_stride_argb = -dst_stride_argb;
michael@0 707 }
michael@0 708 void (*NV21ToARGBRow)(const uint8* y_buf,
michael@0 709 const uint8* uv_buf,
michael@0 710 uint8* rgb_buf,
michael@0 711 int width) = NV21ToARGBRow_C;
michael@0 712 #if defined(HAS_NV21TOARGBROW_SSSE3)
michael@0 713 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 714 NV21ToARGBRow = NV21ToARGBRow_Any_SSSE3;
michael@0 715 if (IS_ALIGNED(width, 8)) {
michael@0 716 NV21ToARGBRow = NV21ToARGBRow_Unaligned_SSSE3;
michael@0 717 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 718 NV21ToARGBRow = NV21ToARGBRow_SSSE3;
michael@0 719 }
michael@0 720 }
michael@0 721 }
michael@0 722 #endif
michael@0 723 #if defined(HAS_NV21TOARGBROW_NEON)
michael@0 724 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 725 NV21ToARGBRow = NV21ToARGBRow_Any_NEON;
michael@0 726 if (IS_ALIGNED(width, 8)) {
michael@0 727 NV21ToARGBRow = NV21ToARGBRow_NEON;
michael@0 728 }
michael@0 729 }
michael@0 730 #endif
michael@0 731
michael@0 732 for (int y = 0; y < height; ++y) {
michael@0 733 NV21ToARGBRow(src_y, src_uv, dst_argb, width);
michael@0 734 dst_argb += dst_stride_argb;
michael@0 735 src_y += src_stride_y;
michael@0 736 if (y & 1) {
michael@0 737 src_uv += src_stride_uv;
michael@0 738 }
michael@0 739 }
michael@0 740 return 0;
michael@0 741 }
michael@0 742
michael@0 743 // Convert M420 to ARGB.
michael@0 744 LIBYUV_API
michael@0 745 int M420ToARGB(const uint8* src_m420, int src_stride_m420,
michael@0 746 uint8* dst_argb, int dst_stride_argb,
michael@0 747 int width, int height) {
michael@0 748 if (!src_m420 || !dst_argb ||
michael@0 749 width <= 0 || height == 0) {
michael@0 750 return -1;
michael@0 751 }
michael@0 752 // Negative height means invert the image.
michael@0 753 if (height < 0) {
michael@0 754 height = -height;
michael@0 755 dst_argb = dst_argb + (height - 1) * dst_stride_argb;
michael@0 756 dst_stride_argb = -dst_stride_argb;
michael@0 757 }
michael@0 758 void (*NV12ToARGBRow)(const uint8* y_buf,
michael@0 759 const uint8* uv_buf,
michael@0 760 uint8* rgb_buf,
michael@0 761 int width) = NV12ToARGBRow_C;
michael@0 762 #if defined(HAS_NV12TOARGBROW_SSSE3)
michael@0 763 if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
michael@0 764 NV12ToARGBRow = NV12ToARGBRow_Any_SSSE3;
michael@0 765 if (IS_ALIGNED(width, 8)) {
michael@0 766 NV12ToARGBRow = NV12ToARGBRow_Unaligned_SSSE3;
michael@0 767 if (IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 768 NV12ToARGBRow = NV12ToARGBRow_SSSE3;
michael@0 769 }
michael@0 770 }
michael@0 771 }
michael@0 772 #elif defined(HAS_NV12TOARGBROW_NEON)
michael@0 773 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 774 NV12ToARGBRow = NV12ToARGBRow_Any_NEON;
michael@0 775 if (IS_ALIGNED(width, 8)) {
michael@0 776 NV12ToARGBRow = NV12ToARGBRow_NEON;
michael@0 777 }
michael@0 778 }
michael@0 779 #endif
michael@0 780
michael@0 781 for (int y = 0; y < height - 1; y += 2) {
michael@0 782 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width);
michael@0 783 NV12ToARGBRow(src_m420 + src_stride_m420, src_m420 + src_stride_m420 * 2,
michael@0 784 dst_argb + dst_stride_argb, width);
michael@0 785 dst_argb += dst_stride_argb * 2;
michael@0 786 src_m420 += src_stride_m420 * 3;
michael@0 787 }
michael@0 788 if (height & 1) {
michael@0 789 NV12ToARGBRow(src_m420, src_m420 + src_stride_m420 * 2, dst_argb, width);
michael@0 790 }
michael@0 791 return 0;
michael@0 792 }
michael@0 793
michael@0 794 // Convert YUY2 to ARGB.
michael@0 795 LIBYUV_API
michael@0 796 int YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2,
michael@0 797 uint8* dst_argb, int dst_stride_argb,
michael@0 798 int width, int height) {
michael@0 799 if (!src_yuy2 || !dst_argb ||
michael@0 800 width <= 0 || height == 0) {
michael@0 801 return -1;
michael@0 802 }
michael@0 803 // Negative height means invert the image.
michael@0 804 if (height < 0) {
michael@0 805 height = -height;
michael@0 806 src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
michael@0 807 src_stride_yuy2 = -src_stride_yuy2;
michael@0 808 }
michael@0 809 // Coalesce rows.
michael@0 810 if (src_stride_yuy2 == width * 2 &&
michael@0 811 dst_stride_argb == width * 4) {
michael@0 812 width *= height;
michael@0 813 height = 1;
michael@0 814 src_stride_yuy2 = dst_stride_argb = 0;
michael@0 815 }
michael@0 816 void (*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb, int pix) =
michael@0 817 YUY2ToARGBRow_C;
michael@0 818 #if defined(HAS_YUY2TOARGBROW_SSSE3)
michael@0 819 // Posix is 16, Windows is 8.
michael@0 820 if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) {
michael@0 821 YUY2ToARGBRow = YUY2ToARGBRow_Any_SSSE3;
michael@0 822 if (IS_ALIGNED(width, 16)) {
michael@0 823 YUY2ToARGBRow = YUY2ToARGBRow_Unaligned_SSSE3;
michael@0 824 if (IS_ALIGNED(src_yuy2, 16) && IS_ALIGNED(src_stride_yuy2, 16) &&
michael@0 825 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 826 YUY2ToARGBRow = YUY2ToARGBRow_SSSE3;
michael@0 827 }
michael@0 828 }
michael@0 829 }
michael@0 830 #elif defined(HAS_YUY2TOARGBROW_NEON)
michael@0 831 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 832 YUY2ToARGBRow = YUY2ToARGBRow_Any_NEON;
michael@0 833 if (IS_ALIGNED(width, 8)) {
michael@0 834 YUY2ToARGBRow = YUY2ToARGBRow_NEON;
michael@0 835 }
michael@0 836 }
michael@0 837 #endif
michael@0 838 for (int y = 0; y < height; ++y) {
michael@0 839 YUY2ToARGBRow(src_yuy2, dst_argb, width);
michael@0 840 src_yuy2 += src_stride_yuy2;
michael@0 841 dst_argb += dst_stride_argb;
michael@0 842 }
michael@0 843 return 0;
michael@0 844 }
michael@0 845
michael@0 846 // Convert UYVY to ARGB.
michael@0 847 LIBYUV_API
michael@0 848 int UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy,
michael@0 849 uint8* dst_argb, int dst_stride_argb,
michael@0 850 int width, int height) {
michael@0 851 if (!src_uyvy || !dst_argb ||
michael@0 852 width <= 0 || height == 0) {
michael@0 853 return -1;
michael@0 854 }
michael@0 855 // Negative height means invert the image.
michael@0 856 if (height < 0) {
michael@0 857 height = -height;
michael@0 858 src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
michael@0 859 src_stride_uyvy = -src_stride_uyvy;
michael@0 860 }
michael@0 861 // Coalesce rows.
michael@0 862 if (src_stride_uyvy == width * 2 &&
michael@0 863 dst_stride_argb == width * 4) {
michael@0 864 width *= height;
michael@0 865 height = 1;
michael@0 866 src_stride_uyvy = dst_stride_argb = 0;
michael@0 867 }
michael@0 868 void (*UYVYToARGBRow)(const uint8* src_uyvy, uint8* dst_argb, int pix) =
michael@0 869 UYVYToARGBRow_C;
michael@0 870 #if defined(HAS_UYVYTOARGBROW_SSSE3)
michael@0 871 // Posix is 16, Windows is 8.
michael@0 872 if (TestCpuFlag(kCpuHasSSSE3) && width >= 16) {
michael@0 873 UYVYToARGBRow = UYVYToARGBRow_Any_SSSE3;
michael@0 874 if (IS_ALIGNED(width, 16)) {
michael@0 875 UYVYToARGBRow = UYVYToARGBRow_Unaligned_SSSE3;
michael@0 876 if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16) &&
michael@0 877 IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
michael@0 878 UYVYToARGBRow = UYVYToARGBRow_SSSE3;
michael@0 879 }
michael@0 880 }
michael@0 881 }
michael@0 882 #elif defined(HAS_UYVYTOARGBROW_NEON)
michael@0 883 if (TestCpuFlag(kCpuHasNEON) && width >= 8) {
michael@0 884 UYVYToARGBRow = UYVYToARGBRow_Any_NEON;
michael@0 885 if (IS_ALIGNED(width, 8)) {
michael@0 886 UYVYToARGBRow = UYVYToARGBRow_NEON;
michael@0 887 }
michael@0 888 }
michael@0 889 #endif
michael@0 890 for (int y = 0; y < height; ++y) {
michael@0 891 UYVYToARGBRow(src_uyvy, dst_argb, width);
michael@0 892 src_uyvy += src_stride_uyvy;
michael@0 893 dst_argb += dst_stride_argb;
michael@0 894 }
michael@0 895 return 0;
michael@0 896 }
michael@0 897
michael@0 898 #ifdef __cplusplus
michael@0 899 } // extern "C"
michael@0 900 } // namespace libyuv
michael@0 901 #endif

mercurial