summaryrefslogtreecommitdiff
path: root/libavfilter/vf_ciescope.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2022-04-19 19:50:49 +0200
committerPaul B Mahol <onemda@gmail.com>2022-04-19 20:32:23 +0200
commitda4b7c2be4af70f39da0e356517069aaecf9402d (patch)
treec06f6e04e1d83c040a410de5e794c3c981cede6e /libavfilter/vf_ciescope.c
parent8b717a40441659d852517a2326646ad4dbd96f7d (diff)
downloadffmpeg-da4b7c2be4af70f39da0e356517069aaecf9402d.tar.gz
avfilter/vf_ciescope: little optimizations
Diffstat (limited to 'libavfilter/vf_ciescope.c')
-rw-r--r--libavfilter/vf_ciescope.c304
1 files changed, 167 insertions, 137 deletions
diff --git a/libavfilter/vf_ciescope.c b/libavfilter/vf_ciescope.c
index fcb28d2b5e..31e7953edc 100644
--- a/libavfilter/vf_ciescope.c
+++ b/libavfilter/vf_ciescope.c
@@ -62,12 +62,14 @@ typedef struct CiescopeContext {
float contrast;
int background;
- double log2lin[65536];
- double igamma;
- double i[3][3];
- double m[3][3];
+ float log2lin[65536];
+ float igamma;
+ float i[3][3];
+ float m[3][3];
AVFrame *f;
- void (*filter)(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y);
+ void (*filter)(AVFilterContext *ctx, const uint8_t *ptr,
+ ptrdiff_t linesize,
+ float *cx, float *cy, int x, int y);
} CiescopeContext;
#define OFFSET(x) offsetof(CiescopeContext, x)
@@ -163,11 +165,11 @@ static int config_output(AVFilterLink *outlink)
point. */
struct ColorSystem {
- double xRed, yRed, /* Red primary illuminant */
- xGreen, yGreen, /* Green primary illuminant */
- xBlue, yBlue, /* Blue primary illuminant */
- xWhite, yWhite, /* White point */
- gamma; /* gamma of nonlinear correction */
+ float xRed, yRed, /* Red primary illuminant */
+ xGreen, yGreen, /* Green primary illuminant */
+ xBlue, yBlue, /* Blue primary illuminant */
+ xWhite, yWhite, /* White point */
+ gamma; /* gamma of nonlinear correction */
};
static float const spectral_chromaticity[][3] = {
@@ -712,23 +714,23 @@ static struct ColorSystem CustomSystem = {
*/
static void
-uv_to_xy(double const u,
- double const v,
- double * const xc,
- double * const yc)
+uv_to_xy(float const u,
+ float const v,
+ float *const xc,
+ float *const yc)
{
/*
Given 1970 coordinates u, v, determine 1931 chromaticities x, y
*/
- *xc = 3*u / (2*u - 8*v + 4);
- *yc = 2*v / (2*u - 8*v + 4);
+ *xc = 3.f*u / (2.f*u - 8.f*v + 4.f);
+ *yc = 2.f*v / (2.f*u - 8.f*v + 4.f);
}
static void
-upvp_to_xy(double const up,
- double const vp,
- double * const xc,
- double * const yc)
+upvp_to_xy(float const up,
+ float const vp,
+ float * const xc,
+ float * const yc)
{
/*
Given 1976 coordinates u', v', determine 1931 chromaticities x, y
@@ -738,48 +740,50 @@ upvp_to_xy(double const up,
}
static void
-xy_to_upvp(double xc,
- double yc,
- double * const up,
- double * const vp)
+xy_to_upvp(float xc,
+ float yc,
+ float * const up,
+ float * const vp)
{
/*
Given 1931 chromaticities x, y, determine 1976 coordinates u', v'
*/
- *up = 4*xc / (- 2*xc + 12*yc + 3);
- *vp = 9*yc / (- 2*xc + 12*yc + 3);
+ const float scale = 1.f / (-2.f*xc + 12.f*yc + 3.f);
+ *up = 4.f*xc * scale;
+ *vp = 9.f*yc * scale;
}
static void
-xy_to_uv(double xc,
- double yc,
- double * const u,
- double * const v)
+xy_to_uv(float xc,
+ float yc,
+ float * const u,
+ float * const v)
{
/*
Given 1931 chromaticities x, y, determine 1960 coordinates u, v
*/
- *u = 4*xc / (- 2*xc + 12*yc + 3);
- *v = 6*yc / (- 2*xc + 12*yc + 3);
+ const float scale = 1.f / (-2.f*xc + 12.f*yc + 3.f);
+ *u = 4.f*xc * scale;
+ *v = 6.f*yc * scale;
}
static void
-xyz_to_rgb(const double m[3][3],
- double xc, double yc, double zc,
- double * const r, double * const g, double * const b)
+xyz_to_rgb(const float m[3][3],
+ float xc, float yc, float zc,
+ float * const r, float * const g, float * const b)
{
*r = m[0][0]*xc + m[0][1]*yc + m[0][2]*zc;
*g = m[1][0]*xc + m[1][1]*yc + m[1][2]*zc;
*b = m[2][0]*xc + m[2][1]*yc + m[2][2]*zc;
}
-static void invert_matrix3x3(double in[3][3], double out[3][3])
+static void invert_matrix3x3(float in[3][3], float out[3][3])
{
- double m00 = in[0][0], m01 = in[0][1], m02 = in[0][2],
+ float m00 = in[0][0], m01 = in[0][1], m02 = in[0][2],
m10 = in[1][0], m11 = in[1][1], m12 = in[1][2],
m20 = in[2][0], m21 = in[2][1], m22 = in[2][2];
int i, j;
- double det;
+ float det;
out[0][0] = (m11 * m22 - m21 * m12);
out[0][1] = -(m01 * m22 - m21 * m02);
@@ -800,9 +804,9 @@ static void invert_matrix3x3(double in[3][3], double out[3][3])
}
}
-static void get_rgb2xyz_matrix(struct ColorSystem system, double m[3][3])
+static void get_rgb2xyz_matrix(struct ColorSystem system, float m[3][3])
{
- double S[3], X[4], Z[4];
+ float S[3], X[4], Z[4];
int i;
X[0] = system.xRed / system.yRed;
@@ -834,31 +838,32 @@ static void get_rgb2xyz_matrix(struct ColorSystem system, double m[3][3])
}
static void
-rgb_to_xy(double rc,
- double gc,
- double bc,
- double * const x,
- double * const y,
- double * const z,
- const double m[3][3])
+rgb_to_xy(float rc,
+ float gc,
+ float bc,
+ float * const x,
+ float * const y,
+ float * const z,
+ const float m[3][3])
{
- double sum;
+ float scale;
*x = m[0][0] * rc + m[0][1] * gc + m[0][2] * bc;
*y = m[1][0] * rc + m[1][1] * gc + m[1][2] * bc;
*z = m[2][0] * rc + m[2][1] * gc + m[2][2] * bc;
- sum = *x + *y + *z;
- if (sum == 0)
- sum = 1;
- *x = *x / sum;
- *y = *y / sum;
+ scale = *x + *y + *z;
+ if (scale == 0.f)
+ scale = 1.f;
+ scale = 1.f / scale;
+ *x = *x * scale;
+ *y = *y * scale;
}
static int
-constrain_rgb(double * const r,
- double * const g,
- double * const b)
+constrain_rgb(float * const r,
+ float * const g,
+ float * const b)
{
/*----------------------------------------------------------------------------
If the requested RGB shade contains a negative weight for one of
@@ -866,7 +871,7 @@ constrain_rgb(double * const r,
the given triple of primaries. Desaturate it by adding white,
equal quantities of R, G, and B, enough to make RGB all positive.
-----------------------------------------------------------------------------*/
- double w;
+ float w;
/* Amount of white needed is w = - min(0, *r, *g, *b) */
w = (0 < *r) ? 0 : *r;
@@ -886,7 +891,7 @@ constrain_rgb(double * const r,
static void
gamma_correct(const struct ColorSystem * const cs,
- double * const c)
+ float * const c)
{
/*----------------------------------------------------------------------------
Transform linear RGB values to nonlinear RGB values.
@@ -899,8 +904,8 @@ gamma_correct(const struct ColorSystem * const cs,
http://www.inforamp.net/~poynton/ColorFAQ.html
http://www.inforamp.net/~poynton/GammaFAQ.html
-----------------------------------------------------------------------------*/
- double gamma;
- double cc;
+ float gamma;
+ float cc;
gamma = cs->gamma;
@@ -922,9 +927,9 @@ gamma_correct(const struct ColorSystem * const cs,
static void
gamma_correct_rgb(const struct ColorSystem * const cs,
- double * const r,
- double * const g,
- double * const b)
+ float * const r,
+ float * const g,
+ float * const b)
{
gamma_correct(cs, r);
gamma_correct(cs, g);
@@ -938,24 +943,24 @@ gamma_correct_rgb(const struct ColorSystem * const cs,
#define Sz(x) (((x) * (int)FFMIN(w, h)) / 512)
static void
-monochrome_color_location(double waveLength, int w, int h,
+monochrome_color_location(float waveLength, int w, int h,
int cie, int *xP, int *yP)
{
const int ix = waveLength - 360;
- const double pX = spectral_chromaticity[ix][0];
- const double pY = spectral_chromaticity[ix][1];
- const double pZ = spectral_chromaticity[ix][2];
- const double px = pX / (pX + pY + pZ);
- const double py = pY / (pX + pY + pZ);
+ const float pX = spectral_chromaticity[ix][0];
+ const float pY = spectral_chromaticity[ix][1];
+ const float pZ = spectral_chromaticity[ix][2];
+ const float px = pX / (pX + pY + pZ);
+ const float py = pY / (pX + pY + pZ);
if (cie == LUV) {
- double up, vp;
+ float up, vp;
xy_to_upvp(px, py, &up, &vp);
*xP = up * (w - 1);
*yP = (h - 1) - vp * (h - 1);
} else if (cie == UCS) {
- double u, v;
+ float u, v;
xy_to_uv(px, py, &u, &v);
*xP = u * (w - 1);
@@ -1099,7 +1104,7 @@ fill_in_tongue(uint16_t* const pixels,
int const h,
uint16_t const maxval,
const struct ColorSystem * const cs,
- double const m[3][3],
+ float const m[3][3],
int const cie,
int const correct_gamma,
float const contrast)
@@ -1122,24 +1127,24 @@ fill_in_tongue(uint16_t* const pixels,
int x;
for (x = leftEdge; x <= rightEdge; ++x) {
- double cx, cy, cz, jr, jg, jb, jmax;
+ float cx, cy, cz, jr, jg, jb, jmax;
int r, g, b, mx = maxval;
if (cie == LUV) {
- double up, vp;
- up = ((double) x) / (w - 1);
- vp = 1.0 - ((double) y) / (h - 1);
+ float up, vp;
+ up = ((float) x) / (w - 1);
+ vp = 1.0 - ((float) y) / (h - 1);
upvp_to_xy(up, vp, &cx, &cy);
cz = 1.0 - (cx + cy);
} else if (cie == UCS) {
- double u, v;
- u = ((double) x) / (w - 1);
- v = 1.0 - ((double) y) / (h - 1);
+ float u, v;
+ u = ((float) x) / (w - 1);
+ v = 1.0 - ((float) y) / (h - 1);
uv_to_xy(u, v, &cx, &cy);
cz = 1.0 - (cx + cy);
} else if (cie == XYY) {
- cx = ((double) x) / (w - 1);
- cy = 1.0 - ((double) y) / (h - 1);
+ cx = ((float) x) / (w - 1);
+ cy = 1.0 - ((float) y) / (h - 1);
cz = 1.0 - (cx + cy);
} else {
av_assert0(0);
@@ -1189,12 +1194,12 @@ plot_white_point(uint16_t* pixels,
int wx, wy;
if (cie == LUV) {
- double wup, wvp;
+ float wup, wvp;
xy_to_upvp(cs->xWhite, cs->yWhite, &wup, &wvp);
wx = (w - 1) * wup;
wy = (h - 1) - ((int) ((h - 1) * wvp));
} else if (cie == UCS) {
- double wu, wv;
+ float wu, wv;
xy_to_uv(cs->xWhite, cs->yWhite, &wu, &wv);
wx = (w - 1) * wu;
wy = (h - 1) - ((int) ((h - 1) * wv));
@@ -1234,68 +1239,82 @@ static int draw_background(AVFilterContext *ctx)
tongue_outline(pixels, s->f->linesize[0] / 2, w, h, 65535, s->cie);
- fill_in_tongue(pixels, s->f->linesize[0] / 2, w, h, 65535, cs, (const double (*)[3])s->i, s->cie,
+ fill_in_tongue(pixels, s->f->linesize[0] / 2, w, h, 65535, cs, (const float (*)[3])s->i, s->cie,
s->correct_gamma, s->contrast);
return 0;
}
-static void filter_rgb48(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y)
+static void filter_rgb48(AVFilterContext *ctx, const uint8_t *ptr,
+ ptrdiff_t linesize,
+ float *cx, float *cy, int x, int y)
{
CiescopeContext *s = ctx->priv;
- const uint16_t* src = (const uint16_t*)(in->data[0] + in->linesize[0] * y + x * 6);
- double r = src[0] / 65535.;
- double g = src[1] / 65535.;
- double b = src[2] / 65535.;
- double cz;
-
- rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m);
+ const float scale = 1. / 65535.;
+ const uint16_t *src = (const uint16_t*)(ptr + linesize * y + x * 6);
+ float r = src[0] * scale;
+ float g = src[1] * scale;
+ float b = src[2] * scale;
+ float cz;
+
+ rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m);
}
-static void filter_rgba64(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y)
+static void filter_rgba64(AVFilterContext *ctx, const uint8_t *ptr,
+ ptrdiff_t linesize,
+ float *cx, float *cy, int x, int y)
{
CiescopeContext *s = ctx->priv;
- const uint16_t* src = (const uint16_t*)(in->data[0] + in->linesize[0] * y + x * 8);
- double r = src[0] / 65535.;
- double g = src[1] / 65535.;
- double b = src[2] / 65535.;
- double cz;
-
- rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m);
+ const float scale = 1. / 65535.;
+ const uint16_t *src = (const uint16_t*)(ptr + linesize * y + x * 8);
+ float r = src[0] * scale;
+ float g = src[1] * scale;
+ float b = src[2] * scale;
+ float cz;
+
+ rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m);
}
-static void filter_rgb24(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y)
+static void filter_rgb24(AVFilterContext *ctx, const uint8_t *ptr,
+ ptrdiff_t linesize,
+ float *cx, float *cy, int x, int y)
{
CiescopeContext *s = ctx->priv;
- const uint8_t* src = in->data[0] + in->linesize[0] * y + x * 3;
- double r = src[0] / 255.;
- double g = src[1] / 255.;
- double b = src[2] / 255.;
- double cz;
-
- rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m);
+ const float scale = 1. / 255.;
+ const uint8_t *src = ptr + linesize * y + x * 3;
+ float r = src[0] * scale;
+ float g = src[1] * scale;
+ float b = src[2] * scale;
+ float cz;
+
+ rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m);
}
-static void filter_rgba(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y)
+static void filter_rgba(AVFilterContext *ctx, const uint8_t *ptr,
+ ptrdiff_t linesize,
+ float *cx, float *cy, int x, int y)
{
CiescopeContext *s = ctx->priv;
- const uint8_t* src = in->data[0] + in->linesize[0] * y + x * 4;
- double r = src[0] / 255.;
- double g = src[1] / 255.;
- double b = src[2] / 255.;
- double cz;
-
- rgb_to_xy(r, g, b, cx, cy, &cz, (const double (*)[3])s->m);
+ const float scale = 1. / 255.;
+ const uint8_t *src = ptr + linesize * y + x * 4;
+ float r = src[0] * scale;
+ float g = src[1] * scale;
+ float b = src[2] * scale;
+ float cz;
+
+ rgb_to_xy(r, g, b, cx, cy, &cz, (const float (*)[3])s->m);
}
-static void filter_xyz(AVFilterContext *ctx, AVFrame *in, double *cx, double *cy, int x, int y)
+static void filter_xyz(AVFilterContext *ctx, const uint8_t *ptr,
+ ptrdiff_t linesize,
+ float *cx, float *cy, int x, int y)
{
CiescopeContext *s = ctx->priv;
- const uint16_t* src = (uint16_t *)(in->data[0] + in->linesize[0] * y + x * 6);
- double lx = s->log2lin[src[0]];
- double ly = s->log2lin[src[1]];
- double lz = s->log2lin[src[2]];
- double sum = lx + ly + lz;
+ const uint16_t* src = (uint16_t *)(ptr + linesize * y + x * 6);
+ float lx = s->log2lin[src[0]];
+ float ly = s->log2lin[src[1]];
+ float lz = s->log2lin[src[2]];
+ float sum = lx + ly + lz;
if (sum == 0)
sum = 1;
@@ -1315,7 +1334,7 @@ static void plot_gamuts(uint16_t *pixels, int linesize, int w, int h,
if (!((1 << i) & gamuts))
continue;
if (cie == LUV) {
- double wup, wvp;
+ float wup, wvp;
xy_to_upvp(cs->xRed, cs->yRed, &wup, &wvp);
rx = (w - 1) * wup;
ry = (h - 1) - ((int) ((h - 1) * wvp));
@@ -1326,7 +1345,7 @@ static void plot_gamuts(uint16_t *pixels, int linesize, int w, int h,
bx = (w - 1) * wup;
by = (h - 1) - ((int) ((h - 1) * wvp));
} else if (cie == UCS) {
- double wu, wv;
+ float wu, wv;
xy_to_uv(cs->xRed, cs->yRed, &wu, &wv);
rx = (w - 1) * wu;
ry = (h - 1) - ((int) ((h - 1) * wv));
@@ -1384,37 +1403,48 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
}
for (y = 0; y < in->height; y++) {
+ const uint8_t *src = in->data[0];
+ const ptrdiff_t src_linesize = in->linesize[0];
+ uint16_t *dst = (uint16_t *)out->data[0];
+ const ptrdiff_t linesize = out->linesize[0] / 2;
+ const int w_1 = w - 1;
+ const int h_1 = h - 1;
+
for (x = 0; x < in->width; x++) {
- double cx, cy;
- uint16_t *dst;
- int wx, wy;
+ float cx, cy;
+ int wx, wy, pos;
+ int r, g, b;
- s->filter(ctx, in, &cx, &cy, x, y);
+ s->filter(ctx, src, src_linesize, &cx, &cy, x, y);
if (s->cie == LUV) {
- double up, vp;
+ float up, vp;
xy_to_upvp(cx, cy, &up, &vp);
cx = up;
cy = vp;
} else if (s->cie == UCS) {
- double u, v;
+ float u, v;
xy_to_uv(cx, cy, &u, &v);
cx = u;
cy = v;
}
- wx = (w - 1) * cx;
- wy = (h - 1) - ((h - 1) * cy);
+ wx = w_1 * cx;
+ wy = h_1 - h_1 * cy;
if (wx < 0 || wx >= w ||
wy < 0 || wy >= h)
continue;
- dst = (uint16_t *)(out->data[0] + wy * out->linesize[0] + wx * 8 + 0);
- dst[0] = FFMIN(dst[0] + i, 65535);
- dst[1] = FFMIN(dst[1] + i, 65535);
- dst[2] = FFMIN(dst[2] + i, 65535);
- dst[3] = 65535;
+ pos = wy * linesize + wx * 4;
+ r = dst[pos + 0] + i;
+ g = dst[pos + 1] + i;
+ b = dst[pos + 2] + i;
+
+ dst[pos + 0] = FFMIN(r, 65535);
+ dst[pos + 1] = FFMIN(g, 65535);
+ dst[pos + 2] = FFMIN(b, 65535);
+ dst[pos + 3] = 65535;
}
}