mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
followup cleanup for blur and make compilable with /clr
BUG=none TEST=none Review URL: https://webrtc-codereview.appspot.com/645007 git-svn-id: http://libyuv.googlecode.com/svn/trunk@284 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
f38aefef4b
commit
133adc4647
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 283
|
||||
Version: 284
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 283
|
||||
#define LIBYUV_VERSION 284
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
|
||||
@ -48,8 +48,8 @@ extern "C" {
|
||||
|
||||
// Low level cpuid for X86. Returns zeros on other CPUs.
|
||||
void CpuId(int cpu_info[4], int info_type) {
|
||||
#if defined(__i386__) || defined(__x86_64__) || \
|
||||
defined(_M_IX86) || defined(_M_X64)
|
||||
#if !defined(__CLR_VER) && (defined(_M_IX86) || defined(_M_X64) || \
|
||||
defined(__i386__) || defined(__x86_64__))
|
||||
__cpuid(cpu_info, info_type);
|
||||
#else
|
||||
cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
|
||||
@ -82,7 +82,7 @@ int ArmCpuCaps(const char* cpuinfo_name) {
|
||||
int cpu_info_ = 0;
|
||||
|
||||
int InitCpuFlags() {
|
||||
#if defined(CPU_X86)
|
||||
#if !defined(__CLR_VER) && defined(CPU_X86)
|
||||
int cpu_info[4];
|
||||
__cpuid(cpu_info, 1);
|
||||
cpu_info_ = ((cpu_info[3] & 0x04000000) ? kCpuHasSSE2 : 0) |
|
||||
|
||||
@ -12,7 +12,10 @@
|
||||
|
||||
// Must be included before jpeglib
|
||||
#include <assert.h>
|
||||
#ifndef __CLR_VER
|
||||
#include <setjmp.h>
|
||||
#define HAVE_SETJMP
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -25,10 +28,12 @@ extern "C" {
|
||||
|
||||
namespace libyuv {
|
||||
|
||||
#ifdef HAVE_SETJMP
|
||||
struct SetJmpErrorMgr {
|
||||
jpeg_error_mgr base; // Must be at the top
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
#endif
|
||||
|
||||
const int MJpegDecoder::kColorSpaceUnknown = JCS_UNKNOWN;
|
||||
const int MJpegDecoder::kColorSpaceGrayscale = JCS_GRAYSCALE;
|
||||
@ -46,10 +51,12 @@ MJpegDecoder::MJpegDecoder()
|
||||
databuf_strides_(NULL) {
|
||||
decompress_struct_ = new jpeg_decompress_struct;
|
||||
source_mgr_ = new jpeg_source_mgr;
|
||||
#ifdef HAVE_SETJMP
|
||||
error_mgr_ = new SetJmpErrorMgr;
|
||||
decompress_struct_->err = jpeg_std_error(&error_mgr_->base);
|
||||
// Override standard exit()-based error handler.
|
||||
error_mgr_->base.error_exit = &ErrorHandler;
|
||||
#endif
|
||||
decompress_struct_->client_data = NULL;
|
||||
source_mgr_->init_source = &init_source;
|
||||
source_mgr_->fill_input_buffer = &fill_input_buffer;
|
||||
@ -66,7 +73,9 @@ MJpegDecoder::~MJpegDecoder() {
|
||||
jpeg_destroy_decompress(decompress_struct_);
|
||||
delete decompress_struct_;
|
||||
delete source_mgr_;
|
||||
#ifdef HAVE_SETJMP
|
||||
delete error_mgr_;
|
||||
#endif
|
||||
DestroyOutputBuffers();
|
||||
}
|
||||
|
||||
@ -111,11 +120,13 @@ bool MJpegDecoder::LoadFrame(const uint8* src, size_t src_len) {
|
||||
buf_.len = static_cast<int>(src_len);
|
||||
buf_vec_.pos = 0;
|
||||
decompress_struct_->client_data = &buf_vec_;
|
||||
#ifdef HAVE_SETJMP
|
||||
if (setjmp(error_mgr_->setjmp_buffer)) {
|
||||
// We called jpeg_read_header, it experienced an error, and we called
|
||||
// longjmp() and rewound the stack to here. Return error.
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if (jpeg_read_header(decompress_struct_, TRUE) != JPEG_HEADER_OK) {
|
||||
// ERROR: Bad MJPEG header
|
||||
return false;
|
||||
@ -231,11 +242,13 @@ int MJpegDecoder::GetComponentSize(int component) {
|
||||
}
|
||||
|
||||
bool MJpegDecoder::UnloadFrame() {
|
||||
#ifdef HAVE_SETJMP
|
||||
if (setjmp(error_mgr_->setjmp_buffer)) {
|
||||
// We called jpeg_abort_decompress, it experienced an error, and we called
|
||||
// longjmp() and rewound the stack to here. Return error.
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
jpeg_abort_decompress(decompress_struct_);
|
||||
return true;
|
||||
}
|
||||
@ -257,12 +270,14 @@ bool MJpegDecoder::DecodeToBuffers(
|
||||
// ERROR: Bad dimensions
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_SETJMP
|
||||
if (setjmp(error_mgr_->setjmp_buffer)) {
|
||||
// We called into jpeglib, it experienced an error sometime during this
|
||||
// function call, and we called longjmp() and rewound the stack to here.
|
||||
// Return error.
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if (!StartDecode()) {
|
||||
return false;
|
||||
}
|
||||
@ -344,12 +359,14 @@ bool MJpegDecoder::DecodeToCallback(CallbackFunction fn, void* opaque,
|
||||
// ERROR: Bad dimensions
|
||||
return false;
|
||||
}
|
||||
#ifdef HAVE_SETJMP
|
||||
if (setjmp(error_mgr_->setjmp_buffer)) {
|
||||
// We called into jpeglib, it experienced an error sometime during this
|
||||
// function call, and we called longjmp() and rewound the stack to here.
|
||||
// Return error.
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if (!StartDecode()) {
|
||||
return false;
|
||||
}
|
||||
@ -437,6 +454,7 @@ void MJpegDecoder::term_source(j_decompress_ptr cinfo) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
#ifdef HAVE_SETJMP
|
||||
void MJpegDecoder::ErrorHandler(j_common_ptr cinfo) {
|
||||
// This is called when a jpeglib command experiences an error. Unfortunately
|
||||
// jpeglib's error handling model is not very flexible, because it expects the
|
||||
@ -453,6 +471,7 @@ void MJpegDecoder::ErrorHandler(j_common_ptr cinfo) {
|
||||
// and causes it to return (for a second time) with value 1.
|
||||
longjmp(mgr->setjmp_buffer, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MJpegDecoder::AllocOutputBuffers(int num_outbufs) {
|
||||
if (num_outbufs != num_outbufs_) {
|
||||
|
||||
@ -1685,7 +1685,7 @@ int ARGBComputeCumulativeSum(const uint8* src_argb, int src_stride_argb,
|
||||
return -1;
|
||||
}
|
||||
void (*ComputeCumulativeSumRow)(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C;
|
||||
const int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C;
|
||||
#if defined(HAS_CUMULATIVESUMTOAVERAGE_SSE2)
|
||||
if (TestCpuFlag(kCpuHasSSE2)) {
|
||||
ComputeCumulativeSumRow = ComputeCumulativeSumRow_SSE2;
|
||||
@ -1703,14 +1703,15 @@ int ARGBComputeCumulativeSum(const uint8* src_argb, int src_stride_argb,
|
||||
}
|
||||
|
||||
// Blur ARGB image.
|
||||
// Caller should allocate cumsum table of width * height * 16 bytes aligned
|
||||
// to 16 byte boundary.
|
||||
// Caller should allocate CumulativeSum table of width * height * 16 bytes
|
||||
// aligned to 16 byte boundary. height can be radius * 2 + 2 to save memory
|
||||
// as the buffer is treated as circular.
|
||||
int ARGBBlur(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int32* dst_cumsum, int dst_stride32_cumsum,
|
||||
int width, int height, int radius) {
|
||||
void (*ComputeCumulativeSumRow)(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C;
|
||||
const int32* previous_cumsum, int width) = ComputeCumulativeSumRow_C;
|
||||
void (*CumulativeSumToAverage)(const int32* topleft, const int32* botleft,
|
||||
int width, int area, uint8* dst, int count) = CumulativeSumToAverage_C;
|
||||
#if defined(HAS_CUMULATIVESUMTOAVERAGE_SSE2)
|
||||
@ -1719,6 +1720,8 @@ int ARGBBlur(const uint8* src_argb, int src_stride_argb,
|
||||
CumulativeSumToAverage = CumulativeSumToAverage_SSE2;
|
||||
}
|
||||
#endif
|
||||
// Compute enough CumulativeSum for first row to be blurred. After this
|
||||
// one row of CumulativeSum is updated at a time.
|
||||
ARGBComputeCumulativeSum(src_argb, src_stride_argb,
|
||||
dst_cumsum, dst_stride32_cumsum,
|
||||
width, radius);
|
||||
@ -1726,23 +1729,26 @@ int ARGBBlur(const uint8* src_argb, int src_stride_argb,
|
||||
src_argb = src_argb + radius * src_stride_argb;
|
||||
int32* cumsum_bot_row = &dst_cumsum[(radius - 1) * dst_stride32_cumsum];
|
||||
|
||||
int32* max_cumsum_bot_row =
|
||||
const int32* max_cumsum_bot_row =
|
||||
&dst_cumsum[(radius * 2 + 2) * dst_stride32_cumsum];
|
||||
int32* cumsum_top_row = &dst_cumsum[0];
|
||||
const int32* cumsum_top_row = &dst_cumsum[0];
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
int top_y = ((y - radius - 1) >= 0) ? (y - radius - 1) : 0;
|
||||
int bot_y = ((y + radius) < height) ? (y + radius) : (height - 1);
|
||||
int area = radius * (bot_y - top_y);
|
||||
|
||||
// Increment cumsum_top_row pointer with circular buffer wrap around.
|
||||
if (top_y) {
|
||||
cumsum_top_row += dst_stride32_cumsum;
|
||||
if (cumsum_top_row >= max_cumsum_bot_row) {
|
||||
cumsum_top_row = dst_cumsum;
|
||||
}
|
||||
}
|
||||
// Increment cumsum_bot_row pointer with circular buffer wrap around and
|
||||
// then fill in a row of CumulativeSum.
|
||||
if ((y + radius) < height) {
|
||||
int32* prev_cumsum_bot_row = cumsum_bot_row;
|
||||
const int32* prev_cumsum_bot_row = cumsum_bot_row;
|
||||
cumsum_bot_row += dst_stride32_cumsum;
|
||||
if (cumsum_bot_row >= max_cumsum_bot_row) {
|
||||
cumsum_bot_row = dst_cumsum;
|
||||
|
||||
19
source/row.h
19
source/row.h
@ -22,7 +22,8 @@ extern "C" {
|
||||
#define kMaxStride (2560 * 4)
|
||||
#define IS_ALIGNED(p, a) (!((uintptr_t)(p) & ((a) - 1)))
|
||||
|
||||
#if defined(COVERAGE_ENABLED) || defined(TARGET_IPHONE_SIMULATOR)
|
||||
#if defined(__CLR_VER) || defined(COVERAGE_ENABLED) || \
|
||||
defined(TARGET_IPHONE_SIMULATOR)
|
||||
#define YUV_DISABLE_ASM
|
||||
#endif
|
||||
// True if compiling for SSSE3 as a requirement.
|
||||
@ -101,7 +102,7 @@ extern "C" {
|
||||
#define HAS_I422TOABGRROW_NEON
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_MSC_VER) && !defined(__CLR_VER)
|
||||
#define SIMD_ALIGNED(var) __declspec(align(16)) var
|
||||
typedef __declspec(align(16)) int8 vec8[16];
|
||||
typedef __declspec(align(16)) uint8 uvec8[16];
|
||||
@ -109,7 +110,7 @@ typedef __declspec(align(16)) int16 vec16[8];
|
||||
typedef __declspec(align(16)) uint16 uvec16[8];
|
||||
typedef __declspec(align(16)) int32 vec32[4];
|
||||
typedef __declspec(align(16)) uint32 uvec32[4];
|
||||
#else // __GNUC__
|
||||
#elif defined(__GNUC__)
|
||||
#define SIMD_ALIGNED(var) var __attribute__((aligned(16)))
|
||||
typedef int8 __attribute__((vector_size(16))) vec8;
|
||||
typedef uint8 __attribute__((vector_size(16))) uvec8;
|
||||
@ -117,6 +118,14 @@ typedef int16 __attribute__((vector_size(16))) vec16;
|
||||
typedef uint16 __attribute__((vector_size(16))) uvec16;
|
||||
typedef int32 __attribute__((vector_size(16))) vec32;
|
||||
typedef uint32 __attribute__((vector_size(16))) uvec32;
|
||||
#else
|
||||
#define SIMD_ALIGNED(var) var
|
||||
typedef int8 vec8[16];
|
||||
typedef uint8 uvec8[16];
|
||||
typedef int16 vec16[8];
|
||||
typedef uint16 uvec16[8];
|
||||
typedef int32 vec32[4];
|
||||
typedef uint32 uvec32[4];
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__x86_64__)
|
||||
@ -493,12 +502,12 @@ void ARGBSepiaRow_SSSE3(uint8* dst_argb, int width);
|
||||
void CumulativeSumToAverage_SSE2(const int32* topleft, const int32* botleft,
|
||||
int width, int area, uint8* dst, int count);
|
||||
void ComputeCumulativeSumRow_SSE2(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width);
|
||||
const int32* previous_cumsum, int width);
|
||||
|
||||
void CumulativeSumToAverage_C(const int32* topleft, const int32* botleft,
|
||||
int width, int area, uint8* dst, int count);
|
||||
void ComputeCumulativeSumRow_C(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width);
|
||||
const int32* previous_cumsum, int width);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
||||
@ -951,7 +951,7 @@ void ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb, int width) {
|
||||
}
|
||||
|
||||
void ComputeCumulativeSumRow_C(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width) {
|
||||
const int32* previous_cumsum, int width) {
|
||||
int32 row_sum[4] = {0, 0, 0, 0};
|
||||
for (int x = 0; x < width; ++x) {
|
||||
row_sum[0] += row[x * 4 + 0];
|
||||
|
||||
@ -2936,7 +2936,7 @@ void ARGBSepiaRow_SSSE3(uint8* dst_argb, int width) {
|
||||
// Creates a table of cumulative sums where each value is a sum of all values
|
||||
// above and to the left of the value, inclusive of the value.
|
||||
void ComputeCumulativeSumRow_SSE2(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width) {
|
||||
const int32* previous_cumsum, int width) {
|
||||
asm volatile (
|
||||
"sub %1,%2 \n"
|
||||
"pxor %%xmm0,%%xmm0 \n"
|
||||
|
||||
@ -3121,7 +3121,7 @@ void CumulativeSumToAverage_SSE2(const int32* topleft, const int32* botleft,
|
||||
// Creates a table of cumulative sums where each value is a sum of all values
|
||||
// above and to the left of the value.
|
||||
void ComputeCumulativeSumRow_SSE2(const uint8* row, int32* cumsum,
|
||||
int32* previous_cumsum, int width) {
|
||||
const int32* previous_cumsum, int width) {
|
||||
__asm {
|
||||
mov eax, row
|
||||
mov edx, cumsum
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user