58constexpr const char *
MOD_NAME =
"[gamma cap. f.] ";
62using std::numeric_limits;
72 for (
int i = 0; i <= numeric_limits<uint8_t>::max(); ++i) {
73 lut8.push_back(pow(
static_cast<double>(i)
74 / numeric_limits<uint8_t>::max(), gamma)
75 * numeric_limits<uint8_t>::max());
77 for (
int i = 0; i <= numeric_limits<uint16_t>::max(); ++i) {
78 lut16.push_back(pow(
static_cast<double>(i)
79 / numeric_limits<uint16_t>::max(), gamma)
80 * numeric_limits<uint16_t>::max());
82 for (
int i = 0; i <= numeric_limits<uint8_t>::max(); ++i) {
83 lut8_16.push_back(pow(
static_cast<double>(i)
84 / numeric_limits<uint8_t>::max(), gamma)
85 * numeric_limits<uint16_t>::max());
87 for (
int i = 0; i <= numeric_limits<uint16_t>::max(); ++i) {
88 lut16_8.push_back(pow(
static_cast<double>(i)
89 / numeric_limits<uint16_t>::max(), gamma)
90 * numeric_limits<uint8_t>::max());
94 void apply_gamma(
int in_depth,
int out_depth,
size_t in_len,
void const * __restrict in,
void * __restrict out) {
95 if (in_depth == CHAR_BIT &&
out_depth == CHAR_BIT) {
97 }
else if (in_depth == 2 * CHAR_BIT &&
out_depth == 2 * CHAR_BIT) {
99 }
else if (in_depth == CHAR_BIT &&
out_depth == 2 * CHAR_BIT) {
101 }
else if (in_depth == 2 * CHAR_BIT &&
out_depth == CHAR_BIT) {
109 template<
typename inT,
typename outT>
117 template<
typename inT,
typename outT>
120 for (
size_t i = 0; i < d->len; ++i) {
121 d->out[i] = d->lut[d->in[i]];
126 template<
typename inT,
typename outT>
void apply_lut(
size_t in_len,
const vector<outT> &lut,
void const *in,
void *out)
128 auto *in_data =
static_cast<const inT*
>(in);
129 auto *out_data =
static_cast<outT*
>(out);
130 unsigned int cpus = thread::hardware_concurrency();
131 in_len /=
sizeof(inT);
132 vector<data<inT, outT>> d;
133 vector<task_result_handle_t> handles(cpus);
134 for (
unsigned int i = 0; i < cpus; i++) {
135 d.push_back({in_len / cpus, lut, in_data + i * (in_len / cpus), out_data + i * (in_len / cpus)});
137 for (
unsigned int i = 0; i < cpus; i++) {
140 for (
unsigned int i = 0; i < cpus; i++) {
155 if (strlen(cfg) == 0 || strcmp(cfg,
"help") == 0) {
156 col() <<
"Performs gamma transformation.\n\n"
158 col() <<
"\t" <<
SBOLD(
"-F gamma:value[:8|:16]") <<
"\n";
161 <<
" - force output to 8 (16) bits regardless the input\n";
164 char *endptr =
nullptr;
166 double gamma = strtod(cfg, &endptr);
168 if (gamma <= 0.0 || errno != 0 || (*endptr !=
'\0' && *endptr !=
':')) {
173 if (*endptr !=
'\0') {
176 bits = strtol(endptr, &endptr, 0);
177 if ((bits != 8 && bits != 16) || *endptr !=
'\0') {
196 if (in->color_spec !=
RGB && in->color_spec !=
RG48) {
204 if (s->out_depth != 0) {
208 if (s->vo_pp_out_buffer !=
nullptr) {
209 out->
tiles[0].
data = (
char *) s->vo_pp_out_buffer;
232 s->vo_pp_out_buffer = buffer;
void vf_free(struct video_frame *buf)
Frees video_frame structure.
struct video_desc video_desc_from_frame(const struct video_frame *frame)
Returns struct video_desc from video frame.
void vf_data_deleter(struct video_frame *buf)
struct video_frame * vf_alloc_desc(struct video_desc desc)
Allocates video frame accordig given desc.
const char * get_codec_name(codec_t codec)
#define CAPTURE_FILTER_ABI_VERSION
#define ADD_VO_PP_CAPTURE_FILTER_WRAPPER(name, init, filter, done, set_out_buf, get_prop_callb)
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
static auto filter(void *state, struct video_frame *in) -> video_frame *
static void vo_pp_set_out_buffer(void *state, char *buffer)
static const struct capture_filter_info capture_filter_gamma
constexpr const char * MOD_NAME
static void done(void *state)
static auto init(struct module *parent, const char *cfg, void **state)
@ LIBRARY_CLASS_CAPTURE_FILTER
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
const vector< outT > & lut
void apply_gamma(int in_depth, int out_depth, size_t in_len, void const *__restrict in, void *__restrict out)
static void * compute(void *arg)
state_capture_filter_gamma(double gamma, int out_depth)
int out_depth
0, 8 or 16 (0 menas keep)
void * vo_pp_out_buffer
buffer to write to if we use vo_pp wrapper (otherwise unused)
vector< uint8_t > lut16_8
vector< uint16_t > lut8_16
void apply_lut(size_t in_len, const vector< outT > &lut, void const *in, void *out)
char * data
Raw tile data. Pointer must be at least 4B aligned.
unsigned int data_len
length of the data
void(* data_deleter)(struct video_frame *)
void(* dispose)(struct video_frame *)
Struct video_frame represents a video frame and contains video description.
struct tile tiles[FLEXIBLE_ARRAY_MEMBER]
struct video_frame_callbacks callbacks
@ RGB
RGB 8-bit (packed into 24-bit word)
@ RG48
16-bit RGB little-endian (RlRhGl...)
This is an umbrella header for video functions.
int get_bits_per_component(codec_t codec)
#define VIDEO_FRAME_DISPOSE(frame)
void * wait_task(task_result_handle_t handle)
task_result_handle_t task_run_async(runnable_t task, void *data)
Runs task asynchronously.