Commit ba940deb9f for ffmpeg
commit ba940deb9f710ac5fd2fc2a3f3bd769c534057b6
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Tue Oct 27 01:37:34 2026 +0100
avfilter/wavelet97: add a decimated transform
Lowpass coefficients are stored at even and highpass ones at odd
positions of the line, so a level works in place on the lattice of the
previous level's lowpass coefficients. Reconstruction from a single
polyphase set needs no averaging, hence no factor 0.5.
Assisted-by: Claude
diff --git a/libavfilter/wavelet97.c b/libavfilter/wavelet97.c
index c639b8d596..65a9b8ebc0 100644
--- a/libavfilter/wavelet97.c
+++ b/libavfilter/wavelet97.c
@@ -90,6 +90,33 @@ static inline void compose(float *dst, const float *src_l, const float *src_h,
}
}
+static inline void decompose_decimated(float *dst, const float *src,
+ const double coeff[2][5], int stride, int n)
+{
+ int x, i;
+ for (x = 0; x < n; x++) {
+ const double *c = coeff[x & 1];
+ double sum = src[x * stride] * c[0];
+ for (i = 1; i <= 4; i++)
+ sum += c[i] * (src[avpriv_mirror(x - i, n - 1) * stride]
+ + src[avpriv_mirror(x + i, n - 1) * stride]);
+ dst[x * stride] = sum;
+ }
+}
+
+static inline void compose_decimated(float *dst, const float *src,
+ int stride, int n)
+{
+ int x, i;
+ for (x = 0; x < n; x++) {
+ double sum = src[x * stride] * icoeff[x & 1][0];
+ for (i = 1; i <= 4; i++)
+ sum += icoeff[(x + i) & 1][i] * (src[avpriv_mirror(x - i, n - 1) * stride]
+ + src[avpriv_mirror(x + i, n - 1) * stride]);
+ dst[x * stride] = sum;
+ }
+}
+
void ff_wavelet97_decompose_lines(float *dst_l, float *dst_h, const float *src,
const double coeff[2][5],
int xlinesize, int ylinesize,
@@ -117,6 +144,23 @@ void ff_wavelet97_compose_lines(float *dst, const float *src_l, const float *src
step * xlinesize, (w - x + step - 1) / step);
}
+void ff_wavelet97_decompose_decimated_lines(float *dst, const float *src,
+ const double coeff[2][5],
+ int xstride, int ystride,
+ int len, int line0, int line1)
+{
+ for (int y = line0; y < line1; y++)
+ decompose_decimated(dst + ystride*y, src + ystride*y, coeff, xstride, len);
+}
+
+void ff_wavelet97_compose_decimated_lines(float *dst, const float *src,
+ int xstride, int ystride,
+ int len, int line0, int line1)
+{
+ for (int y = line0; y < line1; y++)
+ compose_decimated(dst + ystride*y, src + ystride*y, xstride, len);
+}
+
void ff_wavelet97_decompose(float *dst[4], const float *src, float *temp[2],
const double coeff[2][5],
int linesize, int step, int w, int h)
diff --git a/libavfilter/wavelet97.h b/libavfilter/wavelet97.h
index a8ed9f2034..d886ab8f97 100644
--- a/libavfilter/wavelet97.h
+++ b/libavfilter/wavelet97.h
@@ -52,6 +52,25 @@ void ff_wavelet97_compose_lines(float *dst, const float *src_l, const float *src
int xlinesize, int ylinesize,
int step, int w, int line0, int line1);
+/**
+ * Decimated analysis of lines line0..line1-1 along one direction.
+ * Line y, sample x is at src[y * ystride + x * xstride], x < len, len >= 2.
+ * Lowpass coefficients are written to even, highpass ones to odd x of dst.
+ *
+ * @param coeff lowpass and highpass filters, normally ff_wavelet97_coeff
+ */
+void ff_wavelet97_decompose_decimated_lines(float *dst, const float *src,
+ const double coeff[2][5],
+ int xstride, int ystride,
+ int len, int line0, int line1);
+
+/**
+ * Inverse of ff_wavelet97_decompose_decimated_lines() with ff_wavelet97_coeff.
+ */
+void ff_wavelet97_compose_decimated_lines(float *dst, const float *src,
+ int xstride, int ystride,
+ int len, int line0, int line1);
+
/**
* One level of undecimated 2D analysis, filters are mirrored at the plane borders.
*