Commit 133adc46 authored by fbarchard@google.com's avatar fbarchard@google.com

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