-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
4,094 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* | ||
* Copyright 2024 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef ULTRAHDR_DSP_ARM_MEM_NEON_H | ||
#define ULTRAHDR_DSP_ARM_MEM_NEON_H | ||
|
||
#include <arm_neon.h> | ||
|
||
#include "ultrahdr/ultrahdrcommon.h" | ||
|
||
namespace ultrahdr { | ||
|
||
// The multi-vector load/store intrinsics are well-supported on AArch64 but | ||
// only supported from GCC 14.1 (and not at all on Clang) for 32-bit platforms. | ||
#if __aarch64__ || (!__clang__ && __GNUC__ >= 14) | ||
#define COMPILER_SUPPORTS_LDST_MULTIPLE 1 | ||
#endif | ||
|
||
static FORCE_INLINE uint8x16x2_t load_u8x16_x2(const uint8_t *src) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
return vld1q_u8_x2(src); | ||
#else | ||
uint8x16x2_t res = {{vld1q_u8(src + 0), vld1q_u8(src + 16)}}; | ||
return res; | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE uint8x16x4_t load_u8x16_x4(const uint8_t *src) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
return vld1q_u8_x4(src); | ||
#else | ||
uint8x16x4_t res = { | ||
{vld1q_u8(src + 0), vld1q_u8(src + 16), vld1q_u8(src + 32), vld1q_u8(src + 48)}}; | ||
return res; | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE uint16x8x2_t load_u16x8_x2(const uint16_t *src) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
return vld1q_u16_x2(src); | ||
#else | ||
uint16x8x2_t res = {{vld1q_u16(src + 0), vld1q_u16(src + 8)}}; | ||
return res; | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE uint16x8x4_t load_u16x8_x4(const uint16_t *src) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
return vld1q_u16_x4(src); | ||
#else | ||
uint16x8x4_t res = { | ||
{vld1q_u16(src + 0), vld1q_u16(src + 8), vld1q_u16(src + 16), vld1q_u16(src + 24)}}; | ||
return res; | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE uint32x4x2_t load_u32x4_x2(const uint32_t *src) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
return vld1q_u32_x2(src); | ||
#else | ||
uint32x4x2_t res = {{vld1q_u32(src + 0), vld1q_u32(src + 4)}}; | ||
return res; | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE uint32x4x4_t load_u32x4_x4(const uint32_t *src) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
return vld1q_u32_x4(src); | ||
#else | ||
uint32x4x4_t res = { | ||
{vld1q_u32(src + 0), vld1q_u32(src + 4), vld1q_u32(src + 8), vld1q_u32(src + 12)}}; | ||
return res; | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE void store_u8x16_x2(uint8_t *dst, uint8x16x2_t a) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
vst1q_u8_x2(dst, a); | ||
#else | ||
vst1q_u8(dst + 0, a.val[0]); | ||
vst1q_u8(dst + 16, a.val[1]); | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE void store_u8x16_x4(uint8_t *dst, uint8x16x4_t a) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
vst1q_u8_x4(dst, a); | ||
#else | ||
vst1q_u8(dst + 0, a.val[0]); | ||
vst1q_u8(dst + 16, a.val[1]); | ||
vst1q_u8(dst + 32, a.val[2]); | ||
vst1q_u8(dst + 48, a.val[3]); | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE void store_u16x8_x2(uint16_t *dst, uint16x8x2_t a) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
vst1q_u16_x2(dst, a); | ||
#else | ||
vst1q_u16(dst + 0, a.val[0]); | ||
vst1q_u16(dst + 8, a.val[1]); | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE void store_u16x8_x4(uint16_t *dst, uint16x8x4_t a) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
vst1q_u16_x4(dst, a); | ||
#else | ||
vst1q_u16(dst + 0, a.val[0]); | ||
vst1q_u16(dst + 8, a.val[1]); | ||
vst1q_u16(dst + 16, a.val[2]); | ||
vst1q_u16(dst + 24, a.val[3]); | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE void store_u32x4_x2(uint32_t *dst, uint32x4x2_t a) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
vst1q_u32_x2(dst, a); | ||
#else | ||
vst1q_u32(dst + 0, a.val[0]); | ||
vst1q_u32(dst + 4, a.val[1]); | ||
#endif | ||
} | ||
|
||
static FORCE_INLINE void store_u32x4_x4(uint32_t *dst, uint32x4x4_t a) { | ||
#ifdef COMPILER_SUPPORTS_LDST_MULTIPLE | ||
vst1q_u32_x4(dst, a); | ||
#else | ||
vst1q_u32(dst + 0, a.val[0]); | ||
vst1q_u32(dst + 4, a.val[1]); | ||
vst1q_u32(dst + 8, a.val[2]); | ||
vst1q_u32(dst + 12, a.val[3]); | ||
#endif | ||
} | ||
|
||
} // namespace ultrahdr | ||
|
||
#endif // ULTRAHDR_DSP_ARM_MEM_NEON_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
/* | ||
* Copyright 2024 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#ifndef ULTRAHDR_EDITORHELPER_H | ||
#define ULTRAHDR_EDITORHELPER_H | ||
|
||
#include "ultrahdr_api.h" | ||
#include "ultrahdr/ultrahdrcommon.h" | ||
|
||
namespace ultrahdr { | ||
|
||
/*!\brief uhdr image effect descriptor */ | ||
typedef struct uhdr_effect_desc { | ||
virtual std::string to_string() = 0; | ||
|
||
virtual ~uhdr_effect_desc() = default; | ||
} uhdr_effect_desc_t; /**< alias for struct uhdr_effect_desc */ | ||
|
||
/*!\brief mirror effect descriptor */ | ||
typedef struct uhdr_mirror_effect : uhdr_effect_desc { | ||
uhdr_mirror_effect(uhdr_mirror_direction_t direction); | ||
|
||
std::string to_string() { | ||
return "effect : mirror, metadata : direction - " + ((m_direction == UHDR_MIRROR_HORIZONTAL) | ||
? std::string{"horizontal"} | ||
: std::string{"vertical"}); | ||
} | ||
|
||
uhdr_mirror_direction_t m_direction; | ||
|
||
void (*m_mirror_uint8_t)(uint8_t*, uint8_t*, int, int, int, int, uhdr_mirror_direction_t); | ||
void (*m_mirror_uint16_t)(uint16_t*, uint16_t*, int, int, int, int, uhdr_mirror_direction_t); | ||
void (*m_mirror_uint32_t)(uint32_t*, uint32_t*, int, int, int, int, uhdr_mirror_direction_t); | ||
void (*m_mirror_uint64_t)(uint64_t*, uint64_t*, int, int, int, int, uhdr_mirror_direction_t); | ||
} uhdr_mirror_effect_t; /**< alias for struct uhdr_mirror_effect */ | ||
|
||
/*!\brief rotate effect descriptor */ | ||
typedef struct uhdr_rotate_effect : uhdr_effect_desc { | ||
uhdr_rotate_effect(int degree); | ||
|
||
std::string to_string() { | ||
return "effect : rotate, metadata : degree - " + std::to_string(m_degree); | ||
} | ||
|
||
int m_degree; | ||
|
||
void (*m_rotate_uint8_t)(uint8_t*, uint8_t*, int, int, int, int, int); | ||
void (*m_rotate_uint16_t)(uint16_t*, uint16_t*, int, int, int, int, int); | ||
void (*m_rotate_uint32_t)(uint32_t*, uint32_t*, int, int, int, int, int); | ||
void (*m_rotate_uint64_t)(uint64_t*, uint64_t*, int, int, int, int, int); | ||
} uhdr_rotate_effect_t; /**< alias for struct uhdr_rotate_effect */ | ||
|
||
/*!\brief crop effect descriptor */ | ||
typedef struct uhdr_crop_effect : uhdr_effect_desc { | ||
uhdr_crop_effect(int left, int right, int top, int bottom) | ||
: m_left{left}, m_right{right}, m_top{top}, m_bottom{bottom} {} | ||
|
||
std::string to_string() { | ||
return "effect : crop, metadata : left, right, top, bottom - " + std::to_string(m_left) + " ," + | ||
std::to_string(m_right) + " ," + std::to_string(m_top) + " ," + std::to_string(m_bottom); | ||
} | ||
|
||
int m_left; | ||
int m_right; | ||
int m_top; | ||
int m_bottom; | ||
} uhdr_crop_effect_t; /**< alias for struct uhdr_crop_effect */ | ||
|
||
/*!\brief resize effect descriptor */ | ||
typedef struct uhdr_resize_effect : uhdr_effect_desc { | ||
uhdr_resize_effect(int width, int height); | ||
|
||
std::string to_string() { | ||
return "effect : resize, metadata : dimensions w, h" + std::to_string(m_width) + " ," + | ||
std::to_string(m_height); | ||
} | ||
|
||
int m_width; | ||
int m_height; | ||
|
||
void (*m_resize_uint8_t)(uint8_t*, uint8_t*, int, int, int, int, int, int); | ||
void (*m_resize_uint16_t)(uint16_t*, uint16_t*, int, int, int, int, int, int); | ||
void (*m_resize_uint32_t)(uint32_t*, uint32_t*, int, int, int, int, int, int); | ||
void (*m_resize_uint64_t)(uint64_t*, uint64_t*, int, int, int, int, int, int); | ||
} uhdr_resize_effect_t; /**< alias for struct uhdr_resize_effect */ | ||
|
||
template <typename T> | ||
extern void rotate_buffer_clockwise(T* src_buffer, T* dst_buffer, int src_w, int src_h, | ||
int src_stride, int dst_stride, int degree); | ||
|
||
template <typename T> | ||
extern void mirror_buffer(T* src_buffer, T* dst_buffer, int src_w, int src_h, int src_stride, | ||
int dst_stride, uhdr_mirror_direction_t direction); | ||
|
||
template <typename T> | ||
extern void resize_buffer(T* src_buffer, T* dst_buffer, int src_w, int src_h, int dst_w, int dst_h, | ||
int src_stride, int dst_stride); | ||
|
||
#if (defined(UHDR_ENABLE_INTRINSICS) && (defined(__ARM_NEON__) || defined(__ARM_NEON))) | ||
template <typename T> | ||
extern void mirror_buffer_neon(T* src_buffer, T* dst_buffer, int src_w, int src_h, int src_stride, | ||
int dst_stride, uhdr_mirror_direction_t direction); | ||
|
||
template <typename T> | ||
extern void rotate_buffer_clockwise_neon(T* src_buffer, T* dst_buffer, int src_w, int src_h, | ||
int src_stride, int dst_stride, int degrees); | ||
#endif | ||
|
||
#ifdef UHDR_ENABLE_GLES | ||
|
||
std::unique_ptr<uhdr_raw_image_ext_t> apply_resize_gles(uhdr_raw_image_t* src, int dst_w, int dst_h, | ||
uhdr_opengl_ctxt* gl_ctxt, | ||
GLuint* srcTexture); | ||
|
||
std::unique_ptr<uhdr_raw_image_ext_t> apply_mirror_gles(ultrahdr::uhdr_mirror_effect_t* desc, | ||
uhdr_raw_image_t* src, | ||
uhdr_opengl_ctxt* gl_ctxt, | ||
GLuint* srcTexture); | ||
|
||
std::unique_ptr<uhdr_raw_image_ext_t> apply_rotate_gles(ultrahdr::uhdr_rotate_effect_t* desc, | ||
uhdr_raw_image_t* src, | ||
uhdr_opengl_ctxt* gl_ctxt, | ||
GLuint* srcTexture); | ||
|
||
void apply_crop_gles(uhdr_raw_image_t* src, int left, int top, int wd, int ht, | ||
uhdr_opengl_ctxt* gl_ctxt, GLuint* srcTexture); | ||
#endif | ||
|
||
std::unique_ptr<uhdr_raw_image_ext_t> apply_rotate(ultrahdr::uhdr_rotate_effect_t* desc, | ||
uhdr_raw_image_t* src, void* gl_ctxt = nullptr, | ||
void* texture = nullptr); | ||
|
||
std::unique_ptr<uhdr_raw_image_ext_t> apply_mirror(ultrahdr::uhdr_mirror_effect_t* desc, | ||
uhdr_raw_image_t* src, void* gl_ctxt = nullptr, | ||
void* texture = nullptr); | ||
|
||
std::unique_ptr<uhdr_raw_image_ext_t> apply_resize(ultrahdr::uhdr_resize_effect_t* desc, | ||
uhdr_raw_image* src, int dst_w, int dst_h, | ||
void* gl_ctxt = nullptr, | ||
void* texture = nullptr); | ||
|
||
void apply_crop(uhdr_raw_image_t* src, int left, int top, int wd, int ht, void* gl_ctxt = nullptr, | ||
void* texture = nullptr); | ||
|
||
} // namespace ultrahdr | ||
|
||
#endif // ULTRAHDR_EDITORHELPER_H |
Oops, something went wrong.