3587 lines · 102.7 KB · C++
RawDownload
/* *  Copyright 2011 The LibYuv Project Authors. All rights reserved. * *  Use of this source code is governed by a BSD-style license *  that can be found in the LICENSE file in the root of the source *  tree. An additional intellectual property rights grant can be found *  in the file PATENTS. All contributing project authors may *  be found in the AUTHORS file in the root of the source tree. */ #include "libyuv/planar_functions.h" #include <string.h>  // for memset() #include "libyuv/cpu_id.h"#ifdef HAVE_JPEG#include "libyuv/mjpeg_decoder.h"#endif#include "libyuv/row.h"#include "libyuv/scale_row.h"  // for ScaleRowDown2 #ifdef __cplusplusnamespace libyuv {extern "C" {#endif // Copy a plane of dataLIBYUV_APIvoid CopyPlane(const uint8_t* src_y,               int src_stride_y,               uint8_t* dst_y,               int dst_stride_y,               int width,               int height) {  int y;  void (*CopyRow)(const uint8_t* src, uint8_t* dst, int width) = CopyRow_C;  // Negative height means invert the image.  if (height < 0) {    height = -height;    dst_y = dst_y + (height - 1) * dst_stride_y;    dst_stride_y = -dst_stride_y;  }  // Coalesce rows.  if (src_stride_y == width && dst_stride_y == width) {    width *= height;    height = 1;    src_stride_y = dst_stride_y = 0;  }  // Nothing to do.  if (src_y == dst_y && src_stride_y == dst_stride_y) {    return;  } #if defined(HAS_COPYROW_SSE2)  if (TestCpuFlag(kCpuHasSSE2)) {    CopyRow = IS_ALIGNED(width, 32) ? CopyRow_SSE2 : CopyRow_Any_SSE2;  }#endif#if defined(HAS_COPYROW_AVX)  if (TestCpuFlag(kCpuHasAVX)) {    CopyRow = IS_ALIGNED(width, 64) ? CopyRow_AVX : CopyRow_Any_AVX;  }#endif#if defined(HAS_COPYROW_ERMS)  if (TestCpuFlag(kCpuHasERMS)) {    CopyRow = CopyRow_ERMS;  }#endif#if defined(HAS_COPYROW_NEON)  if (TestCpuFlag(kCpuHasNEON)) {    CopyRow = IS_ALIGNED(width, 32) ? CopyRow_NEON : CopyRow_Any_NEON;  }#endif   // Copy plane  for (y = 0; y < height; ++y) {    CopyRow(src_y, dst_y, width);    src_y += src_stride_y;    dst_y += dst_stride_y;  }} // TODO(fbarchard): Consider support for negative height.// TODO(fbarchard): Consider stride measured in bytes.LIBYUV_APIvoid CopyPlane_16(const uint16_t* src_y,                  int src_stride_y,                  uint16_t* dst_y,                  int dst_stride_y,                  int width,                  int height) {  int y;  void (*CopyRow)(const uint16_t* src, uint16_t* dst, int width) = CopyRow_16_C;  // Coalesce rows.  if (src_stride_y == width && dst_stride_y == width) {    width *= height;    height = 1;    src_stride_y = dst_stride_y = 0;  }#if defined(HAS_COPYROW_16_SSE2)  if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 32)) {    CopyRow = CopyRow_16_SSE2;  }#endif#if defined(HAS_COPYROW_16_ERMS)  if (TestCpuFlag(kCpuHasERMS)) {    CopyRow = CopyRow_16_ERMS;  }#endif#if defined(HAS_COPYROW_16_NEON)  if (TestCpuFlag(kCpuHasNEON) && IS_ALIGNED(width, 32)) {    CopyRow = CopyRow_16_NEON;  }#endif   // Copy plane  for (y = 0; y < height; ++y) {    CopyRow(src_y, dst_y, width);    src_y += src_stride_y;    dst_y += dst_stride_y;  }} // Convert a plane of 16 bit data to 8 bitLIBYUV_APIvoid Convert16To8Plane(const uint16_t* src_y,                       int src_stride_y,                       uint8_t* dst_y,                       int dst_stride_y,                       int scale,  // 16384 for 10 bits                       int width,                       int height) {  int y;  void (*Convert16To8Row)(const uint16_t* src_y, uint8_t* dst_y, int scale,                          int width) = Convert16To8Row_C;   // Negative height means invert the image.  if (height < 0) {    height = -height;    dst_y = dst_y + (height - 1) * dst_stride_y;    dst_stride_y = -dst_stride_y;  }  // Coalesce rows.  if (src_stride_y == width && dst_stride_y == width) {    width *= height;    height = 1;    src_stride_y = dst_stride_y = 0;  }#if defined(HAS_CONVERT16TO8ROW_SSSE3)  if (TestCpuFlag(kCpuHasSSSE3)) {    Convert16To8Row = Convert16To8Row_Any_SSSE3;    if (IS_ALIGNED(width, 16)) {      Convert16To8Row = Convert16To8Row_SSSE3;    }  }#endif#if defined(HAS_CONVERT16TO8ROW_AVX2)  if (TestCpuFlag(kCpuHasAVX2)) {    Convert16To8Row = Convert16To8Row_Any_AVX2;    if (IS_ALIGNED(width, 32)) {      Convert16To8Row = Convert16To8Row_AVX2;    }  }#endif   // Convert plane  for (y = 0; y < height; ++y) {    Convert16To8Row(src_y, dst_y, scale, width);    src_y += src_stride_y;    dst_y += dst_stride_y;  }} // Convert a plane of 8 bit data to 16 bitLIBYUV_APIvoid Convert8To16Plane(const uint8_t* src_y,                       int src_stride_y,                       uint16_t* dst_y,                       int dst_stride_y,                       int scale,  // 16384 for 10 bits                       int width,                       int height) {  int y;  void (*Convert8To16Row)(const uint8_t* src_y, uint16_t* dst_y, int scale,                          int width) = Convert8To16Row_C;   // Negative height means invert the image.  if (height < 0) {    height = -height;    dst_y = dst_y + (height - 1) * dst_stride_y;    dst_stride_y = -dst_stride_y;  }  // Coalesce rows.  if (src_stride_y == width && dst_stride_y == width) {    width *= height;    height = 1;    src_stride_y = dst_stride_y = 0;  }#if defined(HAS_CONVERT8TO16ROW_SSE2)  if (TestCpuFlag(kCpuHasSSE2)) {    Convert8To16Row = Convert8To16Row_Any_SSE2;    if (IS_ALIGNED(width, 16)) {      Convert8To16Row = Convert8To16Row_SSE2;    }  }#endif#if defined(HAS_CONVERT8TO16ROW_AVX2)  if (TestCpuFlag(kCpuHasAVX2)) {    Convert8To16Row = Convert8To16Row_Any_AVX2;    if (IS_ALIGNED(width, 32)) {      Convert8To16Row = Convert8To16Row_AVX2;    }  }#endif   // Convert plane  for (y = 0; y < height; ++y) {    Convert8To16Row(src_y, dst_y, scale, width);    src_y += src_stride_y;    dst_y += dst_stride_y;  }} // Copy I422.LIBYUV_APIint I422Copy(const uint8_t* src_y,             int src_stride_y,             const uint8_t* src_u,             int src_stride_u,             const uint8_t* src_v,             int src_stride_v,             uint8_t* dst_y,             int dst_stride_y,             uint8_t* dst_u,             int dst_stride_u,             uint8_t* dst_v,             int dst_stride_v,             int width,             int height) {  int halfwidth = (width + 1) >> 1;  if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) {    return -1;  }  // Negative height means invert the image.  if (height < 0) {    height = -height;    src_y = src_y + (height - 1) * src_stride_y;    src_u = src_u + (height - 1) * src_stride_u;    src_v = src_v + (height - 1) * src_stride_v;    src_stride_y = -src_stride_y;    src_stride_u = -src_stride_u;    src_stride_v = -src_stride_v;  }   if (dst_y) {    CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);  }  CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, halfwidth, height);  CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, halfwidth, height);  return 0;} // Copy I444.LIBYUV_APIint I444Copy(const uint8_t* src_y,             int src_stride_y,             const uint8_t* src_u,             int src_stride_u,             const uint8_t* src_v,             int src_stride_v,             uint8_t* dst_y,             int dst_stride_y,             uint8_t* dst_u,             int dst_stride_u,             uint8_t* dst_v,             int dst_stride_v,             int width,             int height) {  if (!src_u || !src_v || !dst_u || !dst_v || width <= 0 || height == 0) {    return -1;  }  // Negative height means invert the image.  if (height < 0) {    height = -height;    src_y = src_y + (height - 1) * src_stride_y;    src_u = src_u + (height - 1) * src_stride_u;    src_v = src_v + (height - 1) * src_stride_v;    src_stride_y = -src_stride_y;    src_stride_u = -src_stride_u;    src_stride_v = -src_stride_v;  }   if (dst_y) {    CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);  }  CopyPlane(src_u, src_stride_u, dst_u, dst_stride_u, width, height);  CopyPlane(src_v, src_stride_v, dst_v, dst_stride_v, width, height);  return 0;} // Copy I400.LIBYUV_APIint I400ToI400(const uint8_t* src_y,               int src_stride_y,               uint8_t* dst_y,               int dst_stride_y,               int width,               int height) {  if (!src_y || !dst_y || width <= 0 || height == 0) {    return -1;  }  // Negative height means invert the image.  if (height < 0) {    height = -height;    src_y = src_y + (height - 1) * src_stride_y;    src_stride_y = -src_stride_y;  }  CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);  return 0;} // Convert I420 to I400.LIBYUV_APIint I420ToI400(const uint8_t* src_y,               int src_stride_y,               const uint8_t* src_u,               int src_stride_u,               const uint8_t* src_v,               int src_stride_v,               uint8_t* dst_y,               int dst_stride_y,               int width,               int height) {  (void)src_u;  (void)src_stride_u;  (void)src_v;  (void)src_stride_v;  if (!src_y || !dst_y || width <= 0 || height == 0) {    return -1;  }  // Negative height means invert the image.  if (height < 0) {    height = -height;    src_y = src_y + (height - 1) * src_stride_y;    src_stride_y = -src_stride_y;  }   CopyPlane(src_y, src_stride_y, dst_y, dst_stride_y, width, height);  return 0;} // Support function for NV12 etc UV channels.// Width and height are plane sizes (typically half pixel width).LIBYUV_APIvoid SplitUVPlane(const uint8_t* src_uv,                  int src_stride_uv,                  uint8_t* dst_u,                  int dst_stride_u,                  uint8_t* dst_v,                  int dst_stride_v,                  int width,                  int height) {  int y;  void (*SplitUVRow)(const uint8_t* src_uv, uint8_t* dst_u, uint8_t* dst_v,                     int width) = SplitUVRow_C;  // Negative height means invert the image.  if (height < 0) {    height = -height;    dst_u = dst_u + (height - 1) * dst_stride_u;    dst_v = dst_v + (height - 1) * dst_stride_v;    dst_stride_u = -dst_stride_u;    dst_stride_v = -dst_stride_v;  }  // Coalesce rows.  if (src_stride_uv == width * 2 && dst_stride_u == width &&      dst_stride_v == width) {    width *= height;    height = 1;    src_stride_uv = dst_stride_u = dst_stride_v = 0;  }#if defined(HAS_SPLITUVROW_SSE2)  if (TestCpuFlag(kCpuHasSSE2)) {    SplitUVRow = SplitUVRow_Any_SSE2;    if (IS_ALIGNED(width, 16)) {      SplitUVRow = SplitUVRow_SSE2;    }  }#endif#if defined(HAS_SPLITUVROW_AVX2)  if (TestCpuFlag(kCpuHasAVX2)) {    SplitUVRow = SplitUVRow_Any_AVX2;    if (IS_ALIGNED(width, 32)) {      SplitUVRow = SplitUVRow_AVX2;    }  }#endif#if defined(HAS_SPLITUVROW_NEON)  if (TestCpuFlag(kCpuHasNEON)) {    SplitUVRow = SplitUVRow_Any_NEON;    if (IS_ALIGNED(width, 16)) {      SplitUVRow = SplitUVRow_NEON;    }  }#endif#if defined(HAS_SPLITUVROW_MSA)  if (TestCpuFlag(kCpuHasMSA)) {    SplitUVRow = SplitUVRow_Any_MSA;    if (IS_ALIGNED(width, 32)) {      SplitUVRow = SplitUVRow_MSA;    }  }#endif   for (y = 0; y < height; ++y) {    // Copy a row of UV.    SplitUVRow(src_uv, dst_u, dst_v, width);    dst_u += dst_stride_u;    dst_v += dst_stride_v;    src_uv += src_stride_uv;  }} LIBYUV_APIvoid MergeUVPlane(const uint8_t* src_u,                  int src_stride_u,                  const uint8_t* src_v,                  int src_stride_v,                  uint8_t* dst_uv,                  int dst_stride_uv,                  int width,                  int height) {  int y;  void (*MergeUVRow)(const uint8_t* src_u, const uint8_t* src_v,                     uint8_t* dst_uv, int width) = MergeUVRow_C;  // Coalesce rows.  // Negative height means invert the image.  if (height < 0) {    height = -height;    dst_uv = dst_uv + (height - 1) * dst_stride_uv;    dst_stride_uv = -dst_stride_uv;  }  // Coalesce rows.  if (src_stride_u == width && src_stride_v == width &&      dst_stride_uv == width * 2) {    width *= height;    height = 1;    src_stride_u = src_stride_v = dst_stride_uv = 0;  }#if defined(HAS_MERGEUVROW_SSE2)  if (TestCpuFlag(kCpuHasSSE2)) {    MergeUVRow = MergeUVRow_Any_SSE2;    if (IS_ALIGNED(width, 16)) {      MergeUVRow = MergeUVRow_SSE2;    }  }#endif#if defined(HAS_MERGEUVROW_AVX2)  if (TestCpuFlag(kCpuHasAVX2)) {    MergeUVRow = MergeUVRow_Any_AVX2;    if (IS_ALIGNED(width, 32)) {      MergeUVRow = MergeUVRow_AVX2;    }  }#endif#if defined(HAS_MERGEUVROW_NEON)  if (TestCpuFlag(kCpuHasNEON)) {    MergeUVRow = MergeUVRow_Any_NEON;    if (IS_ALIGNED(width, 16)) {      MergeUVRow = MergeUVRow_NEON;    }  }#endif#if defined(HAS_MERGEUVROW_MSA)  if (TestCpuFlag(kCpuHasMSA)) {    MergeUVRow = MergeUVRow_Any_MSA;    if (IS_ALIGNED(width, 16)) {      MergeUVRow = MergeUVRow_MSA;    }  }#endif   for (y = 0; y < height; ++y) {    // Merge a row of U and V into a row of UV.    MergeUVRow(src_u, src_v, dst_uv, width);    src_u += src_stride_u;    src_v += src_stride_v;    dst_uv += dst_stride_uv;  }} // Support function for NV12 etc RGB channels.// Width and height are plane sizes (typically half pixel width).LIBYUV_APIvoid SplitRGBPlane(const uint8_t* src_rgb,                   int src_stride_rgb,                   uint8_t* dst_r,                   int dst_stride_r,                   uint8_t* dst_g,                   int dst_stride_g,                   uint8_t* dst_b,

Lines 1–500 of 3587.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t