#include <math.h>
#include "common/macros.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327
#endif
#pragma once
#ifndef ADM_TOOLS_H_
#define ADM_TOOLS_H_
#define ADM_CM_THRESH_S_0_0(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
sum += flt_ptr[src_px_stride + 1]; \
sum += flt_ptr[src_px_stride]; \
sum += flt_ptr[src_px_stride + 1]; \
sum += flt_ptr[1]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[0]); \
sum += flt_ptr[1]; \
sum += flt_ptr[src_px_stride + 1]; \
sum += flt_ptr[src_px_stride]; \
sum += flt_ptr[src_px_stride + 1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_0_W_M_1(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
sum += flt_ptr[src_px_stride + w - 2]; \
sum += flt_ptr[src_px_stride + w - 1]; \
sum += flt_ptr[src_px_stride + w - 1]; \
sum += flt_ptr[w - 2]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[w - 1]); \
sum += flt_ptr[w - 1]; \
sum += flt_ptr[src_px_stride + w - 2]; \
sum += flt_ptr[src_px_stride + w - 1]; \
sum += flt_ptr[src_px_stride + w - 1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_0_J(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
sum += flt_ptr[src_px_stride + j - 1]; \
sum += flt_ptr[src_px_stride + j]; \
sum += flt_ptr[src_px_stride + j + 1]; \
sum += flt_ptr[j - 1]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[j]); \
sum += flt_ptr[j + 1]; \
sum += flt_ptr[src_px_stride + j - 1]; \
sum += flt_ptr[src_px_stride + j]; \
sum += flt_ptr[src_px_stride + j + 1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_H_M_1_0(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
src_ptr += (src_px_stride * (h - 2)); \
flt_ptr += (src_px_stride * (h - 2)); \
sum += flt_ptr[1]; \
sum += flt_ptr[0]; \
sum += flt_ptr[1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[1]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[0]); \
sum += flt_ptr[1]; \
sum += flt_ptr[1]; \
sum += flt_ptr[0]; \
sum += flt_ptr[1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_H_M_1_W_M_1(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
src_ptr += (src_px_stride * (h - 2)); \
flt_ptr += (src_px_stride * (h - 2)); \
sum += flt_ptr[w - 2]; \
sum += flt_ptr[w - 1]; \
sum += flt_ptr[w - 1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[w - 2]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[w - 1]); \
sum += flt_ptr[w - 1]; \
sum += flt_ptr[w - 2]; \
sum += flt_ptr[w - 1]; \
sum += flt_ptr[w - 1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_H_M_1_J(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
src_ptr += (src_px_stride * (h - 2)); \
flt_ptr += (src_px_stride * (h - 2)); \
sum += flt_ptr[j - 1];\
sum += flt_ptr[j]; \
sum += flt_ptr[j + 1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[j - 1]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[j]); \
sum += flt_ptr[j + 1]; \
sum += flt_ptr[j - 1]; \
sum += flt_ptr[j]; \
sum += flt_ptr[j + 1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_I_J(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
src_ptr += (src_px_stride * (i - 1)); \
flt_ptr += (src_px_stride * (i - 1)); \
sum += flt_ptr[j - 1]; \
sum += flt_ptr[j]; \
sum += flt_ptr[j + 1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[j - 1]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[j]); \
sum += flt_ptr[j + 1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[j - 1]; \
sum += flt_ptr[j]; \
sum += flt_ptr[j + 1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_I_0(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
src_ptr += (src_px_stride * (i - 1)); \
flt_ptr += (src_px_stride * (i - 1)); \
sum += flt_ptr[1]; \
sum += flt_ptr[0]; \
sum += flt_ptr[1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[1]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[0]); \
sum += flt_ptr[1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[1]; \
sum += flt_ptr[0]; \
sum += flt_ptr[1]; \
*accum += sum; \
} \
}
#define ADM_CM_THRESH_S_I_W_M_1(angles,flt_angles,src_px_stride,accum,w,h,i,j) \
{ \
*accum = 0; \
for (int theta = 0; theta < 3; ++theta) { \
const float *src_ptr = angles[theta]; \
const float *flt_ptr = flt_angles[theta]; \
float sum = 0; \
src_ptr += (src_px_stride * (i-1)); \
flt_ptr += (src_px_stride * (i - 1)); \
sum += flt_ptr[w - 2]; \
sum += flt_ptr[w - 1]; \
sum += flt_ptr[w - 1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[w - 2]; \
sum += FLOAT_ONE_BY_15 * fabsf(src_ptr[w - 1]); \
sum += flt_ptr[w - 1]; \
src_ptr += src_px_stride; \
flt_ptr += src_px_stride; \
sum += flt_ptr[w - 2]; \
sum += flt_ptr[w - 1]; \
sum += flt_ptr[w - 1]; \
*accum += sum; \
} \
}
typedef struct adm_dwt_band_t_s {
float *band_a;
float *band_v;
float *band_h;
float *band_d;
} adm_dwt_band_t_s;
typedef struct adm_dwt_band_t_d {
double *band_a;
double *band_v;
double *band_h;
double *band_d;
} adm_dwt_band_t_d;
float adm_sum_cube_s(const float *x, int w, int h, int stride, double border_factor);
void adm_decouple_s(const adm_dwt_band_t_s *ref, const adm_dwt_band_t_s *dis, const adm_dwt_band_t_s *r, const adm_dwt_band_t_s *a, int w, int h, int ref_stride, int dis_stride, int r_stride, int a_stride, double border_factor, double adm_enhn_gain_limit);
void adm_csf_s(const adm_dwt_band_t_s *src, const adm_dwt_band_t_s *dst, const adm_dwt_band_t_s *flt, int orig_h, int scale, int w, int h, int src_stride, int dst_stride, double border_factor, double adm_norm_view_dist, int adm_ref_display_height, int adm_csf_mode);
void adm_cm_thresh_s(const adm_dwt_band_t_s *src, float *dst, int w, int h, int src_stride, int dst_stride);
float adm_csf_den_scale_s(const adm_dwt_band_t_s *src, int orig_h, int scale, int w, int h, int src_stride, double border_factor, double adm_norm_view_dist, int adm_ref_display_height, int adm_csf_mode);
float adm_cm_s(const adm_dwt_band_t_s *src, const adm_dwt_band_t_s *dst, const adm_dwt_band_t_s *csf_a, int w, int h, int src_stride, int dst_stride, int csf_a_stride, double border_factor, int scale, double adm_norm_view_dist, int adm_ref_display_height, int adm_csf_mode);
void dwt2_src_indices_filt_s(int **src_ind_y, int **src_ind_x, int w, int h);
void adm_dwt2_s(const float *src, const adm_dwt_band_t_s *dst, int **ind_y, int **ind_x, int w, int h, int src_stride, int dst_stride);
void adm_dwt2_d(const double *src, const adm_dwt_band_t_d *dst, int **ind_y, int **ind_x, int w, int h, int src_stride, int dst_stride);
struct dwt_model_params {
float a;
float k;
float f0;
float g[4];
};
static const struct dwt_model_params dwt_7_9_YCbCr_threshold[3] = {
{ .a = 0.495, .k = 0.466, .f0 = 0.401, .g = { 1.501, 1.0, 0.534, 1.0} },
{ .a = 1.633, .k = 0.353, .f0 = 0.209, .g = { 1.520, 1.0, 0.502, 1.0} },
{ .a = 0.944, .k = 0.521, .f0 = 0.404, .g = { 1.868, 1.0, 0.516, 1.0} }
};
static const float dwt_7_9_basis_function_amplitudes[6][4] = {
{ 0.62171, 0.67234, 0.72709, 0.67234 },
{ 0.34537, 0.41317, 0.49428, 0.41317 },
{ 0.18004, 0.22727, 0.28688, 0.22727 },
{ 0.091401, 0.11792, 0.15214, 0.11792 },
{ 0.045943, 0.059758, 0.077727, 0.059758 },
{ 0.023013, 0.030018, 0.039156, 0.030018 }
};
static FORCE_INLINE inline float dwt_quant_step(const struct dwt_model_params *params,
int lambda, int theta, double adm_norm_view_dist, int adm_ref_display_height)
{
float r = adm_norm_view_dist * adm_ref_display_height * M_PI / 180.0;
float temp = log10(pow(2.0,lambda+1)*params->f0*params->g[theta]/r);
float Q = 2.0*params->a*pow(10.0,params->k*temp*temp)/dwt_7_9_basis_function_amplitudes[lambda][theta];
return Q;
}
#endif