|
FFmpeg
|
Convert packed RGB/BGR to PAL8 with a per-frame palette whose colors sit on a face-centered cubic (FCC) lattice. More...
#include <math.h>#include "libavutil/lfg.h"#include "libavutil/mem.h"#include "libavutil/opt.h"#include "libavutil/pixdesc.h"#include "avfilter.h"#include "filters.h"#include "formats.h"#include "video.h"Go to the source code of this file.
Data Structures | |
| struct | PalEntry |
| struct | LatticePalContext |
| struct | HeapEnt |
Macros | |
| #define | MAX_DENSITY 255 |
| #define | MAX_DENSITY_ALPHA 64 |
| #define | VC_SHIFT 6 |
| #define | VC_SIZE (1 << VC_SHIFT) |
| #define | VC_AREA (VC_SIZE * VC_SIZE) |
| #define | VC_MASK (VC_SIZE - 1) |
| #define | VC_SIGMA 1.5f |
| #define | VC_RADIUS 7 |
| #define | VC_KSIZE (2 * VC_RADIUS + 1) |
| #define | OFFSET(x) |
| #define | FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
| #define | CHECK_CELL3(a, b, c) |
| #define | CHECK_CELL4(a, b, c, l) |
Enumerations | |
| enum | dithering_mode { DITHERING_NONE , DITHERING_BAYER , DITHERING_BLUE_NOISE , DITHERING_FLOYD_STEINBERG , NB_DITHERING } |
| enum | refine_mode { REFINE_NONE , REFINE_FULL , REFINE_RESIDUAL , REFINE_BATCHED , NB_REFINE } |
Functions | |
| AVFILTER_DEFINE_CLASS (latticepal) | |
| static int | query_formats (const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out) |
| static void | vc_splat (float *energy, const float *kern, int pos, float sign) |
| Add (sign > 0) or remove (sign < 0) the Gaussian energy contribution of a minority pixel at position pos on the VC_SIZE x VC_SIZE torus. | |
| static int | vc_extreme (const float *energy, const uint8_t *bits, int want_set, int find_max) |
| Position of the extreme energy value among the cells whose bit equals want_set: the tightest cluster (find_max, among minority pixels) or the largest void (!find_max, among majority pixels). | |
| static void | vc_generate (uint16_t *rank, uint8_t *bits, float *energy, float *e1, const float *kern, AVLFG *lfg) |
| Generate a void-and-cluster blue noise rank matrix (Ulichney 1993): every cell gets a unique rank in [0, VC_AREA). | |
| static av_always_inline void | quant_dn (const LatticePalContext *s, const int *in, int f[4]) |
| Quantize a color to the nearest point of the scaled D3 (FCC) or D4 lattice. | |
| static av_always_inline int | color_inc (LatticePalContext *s, const int f[4]) |
| Account one pixel using the lattice color with indices f, registering the color in the cell table and the used color list on first use. | |
| static int | nearest_alive (LatticePalContext *s, const uint8_t ci[4], int self, int *out_d2) |
| Find the nearest live color of the used color list, excluding self (pass -1 to match any live color). | |
| static void | nn_search (LatticePalContext *s, int self) |
| static void | heap_push (HeapEnt *heap, int *nb, int64_t imp, int idx) |
| static HeapEnt | heap_pop (HeapEnt *heap, int *nb) |
| static int | reduce_colors (LatticePalContext *s, int target) |
| Reduce the live colors down to target by repeatedly dropping the color whose removal has the least impact: its pixel count times the squared distance to the nearest remaining color, which then absorbs the dropped pixels. | |
| static av_always_inline uint32_t | entry_color (const LatticePalContext *s, const PalEntry *e) |
| Palette color (AARRGGBB) of a used color list entry. | |
| static int | refine_full (LatticePalContext *s, AVFrame *out, const AVFrame *in) |
| Full refinement pass: rediffuse the whole frame against the final palette. | |
| static int | refine_residual (LatticePalContext *s, AVFrame *out, const AVFrame *in) |
| Residual refinement pass: rediffuse only the error of the dropped colors, using the first pass quantized color as the diffusion target. | |
| static int | batch_assign (LatticePalContext *s, const AVFrame *in) |
| Rediffuse the whole frame against the current live colors and reassign every pixel, recounting how often each live color is actually used. | |
| static int | reduce_batched (LatticePalContext *s, const AVFrame *in) |
| Batched reduction: instead of dropping all excess colors against the first pass statistics, drop half of the excess, rediffuse the frame against the survivors and recount from the actual assignments, then repeat. | |
| static int | filter_frame (AVFilterLink *inlink, AVFrame *in) |
| static int | config_input (AVFilterLink *inlink) |
| static av_cold void | uninit (AVFilterContext *ctx) |
Variables | |
| static const AVOption | latticepal_options [] |
| static const uint8_t | dither_8x8_73 [8][8] |
| static const AVFilterPad | latticepal_inputs [] |
| const FFFilter | ff_vf_latticepal |
Convert packed RGB/BGR to PAL8 with a per-frame palette whose colors sit on a face-centered cubic (FCC) lattice.
The FCC lattice is realized as the D3 checkerboard lattice: the points (i,j,k) with an even coordinate sum, scaled so that the density option is the number of lattice steps spanning one color axis (0..255). Only the lattice points actually used by a frame enter its palette; if a frame uses more than 256 of them, the used colors are reduced by iteratively dropping the color whose removal has the least impact and mapping its pixels to the nearest remaining color.
Definition in file vf_latticepal.c.
| #define MAX_DENSITY 255 |
Definition at line 45 of file vf_latticepal.c.
| #define MAX_DENSITY_ALPHA 64 |
Definition at line 46 of file vf_latticepal.c.
Referenced by config_input().
| #define VC_SHIFT 6 |
Definition at line 65 of file vf_latticepal.c.
Referenced by filter_frame(), and vc_splat().
| #define VC_SIZE (1 << VC_SHIFT) |
Definition at line 66 of file vf_latticepal.c.
Definition at line 67 of file vf_latticepal.c.
Referenced by config_input(), vc_extreme(), and vc_generate().
| #define VC_MASK (VC_SIZE - 1) |
Definition at line 68 of file vf_latticepal.c.
Referenced by filter_frame(), and vc_splat().
| #define VC_SIGMA 1.5f |
Definition at line 69 of file vf_latticepal.c.
Referenced by config_input().
| #define VC_RADIUS 7 |
Definition at line 70 of file vf_latticepal.c.
Referenced by config_input(), and vc_splat().
| #define VC_KSIZE (2 * VC_RADIUS + 1) |
Definition at line 71 of file vf_latticepal.c.
Referenced by config_input(), and vc_splat().
| #define OFFSET | ( | x | ) |
Definition at line 116 of file vf_latticepal.c.
| #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
Definition at line 117 of file vf_latticepal.c.
Referenced by nearest_alive().
Referenced by nearest_alive().
| enum dithering_mode |
| Enumerator | |
|---|---|
| DITHERING_NONE | |
| DITHERING_BAYER | |
| DITHERING_BLUE_NOISE | |
| DITHERING_FLOYD_STEINBERG | |
| NB_DITHERING | |
Definition at line 48 of file vf_latticepal.c.
| enum refine_mode |
| Enumerator | |
|---|---|
| REFINE_NONE | |
| REFINE_FULL | |
| REFINE_RESIDUAL | |
| REFINE_BATCHED | |
| NB_REFINE | |
Definition at line 56 of file vf_latticepal.c.
| AVFILTER_DEFINE_CLASS | ( | latticepal | ) |
|
static |
Definition at line 137 of file vf_latticepal.c.
Add (sign > 0) or remove (sign < 0) the Gaussian energy contribution of a minority pixel at position pos on the VC_SIZE x VC_SIZE torus.
Definition at line 175 of file vf_latticepal.c.
Referenced by vc_generate().
|
static |
Position of the extreme energy value among the cells whose bit equals want_set: the tightest cluster (find_max, among minority pixels) or the largest void (!find_max, among majority pixels).
Definition at line 194 of file vf_latticepal.c.
Referenced by vc_generate().
|
static |
Generate a void-and-cluster blue noise rank matrix (Ulichney 1993): every cell gets a unique rank in [0, VC_AREA).
On a torus the filtered field of the zero pattern is the constant kernel sum minus the field of the one pattern, so the tightest cluster of zeros coincides with the largest void of ones and the ranking above 50% fill needs no separate phase.
Definition at line 219 of file vf_latticepal.c.
Referenced by config_input().
|
static |
Quantize a color to the nearest point of the scaled D3 (FCC) or D4 lattice.
Conway & Sloane: round every coordinate to the nearest integer; if the coordinate sum is odd, re-round the coordinate with the largest rounding error in the other direction. This works for any checkerboard lattice Dn.
| in | the nc input components |
| f | receives the nc lattice indices |
Definition at line 281 of file vf_latticepal.c.
Referenced by batch_assign(), filter_frame(), refine_full(), and refine_residual().
|
static |
Account one pixel using the lattice color with indices f, registering the color in the cell table and the used color list on first use.
Definition at line 313 of file vf_latticepal.c.
Referenced by filter_frame().
|
static |
Find the nearest live color of the used color list, excluding self (pass -1 to match any live color).
While many colors are alive, search outward in Chebyshev shells of the lattice index space; the component value difference of a cell r shells away is at least r * min_gap, which bounds the search once a candidate is known. When only few colors are left the lattice around them is sparse and shells get expensive, so scan the compact live list instead. (For 3 components ci[3] is 0 everywhere, contributing nothing.)
Definition at line 360 of file vf_latticepal.c.
Referenced by batch_assign(), and nn_search().
|
static |
Definition at line 462 of file vf_latticepal.c.
Referenced by filter_frame(), and reduce_colors().
Definition at line 475 of file vf_latticepal.c.
Referenced by reduce_colors().
Definition at line 487 of file vf_latticepal.c.
Referenced by reduce_colors().
|
static |
Reduce the live colors down to target by repeatedly dropping the color whose removal has the least impact: its pixel count times the squared distance to the nearest remaining color, which then absorbs the dropped pixels.
An impact can only grow: counts grow by absorption and the nearest neighbor distance grows when the neighbor is dropped. Stale heap entries therefore underestimate their color's impact, and validating at pop time and re-pushing the corrected entry yields the exact minimum.
Definition at line 516 of file vf_latticepal.c.
Referenced by filter_frame(), and reduce_batched().
|
static |
Palette color (AARRGGBB) of a used color list entry.
Definition at line 590 of file vf_latticepal.c.
Referenced by filter_frame().
|
static |
Full refinement pass: rediffuse the whole frame against the final palette.
The first pass diffused its error against the full lattice, so the shift from dropped colors to their nearest survivor is uncompensated and shows up as flat discolored patches exactly where the reduction hit. Re-run Floyd-Steinberg error diffusion on the original pixels, quantizing to the nearest final palette color, which redistributes that error by construction (error diffusion is average correct against any codebook).
The nearest palette color is resolved at lattice cell granularity: used cells already hold their slot from the remap, cells first touched by the diffusion get a scan over the at most 256 survivors and are cached in the cell table and recorded for the per frame reset.
Definition at line 614 of file vf_latticepal.c.
Referenced by filter_frame().
|
static |
Residual refinement pass: rediffuse only the error of the dropped colors, using the first pass quantized color as the diffusion target.
The error stream then carries only the removal residuals: a pixel whose color survived and that receives no incoming residual picks its own color with zero error and is unchanged, keeping the character of the selected dither mode outside the reduced regions.
Runs before the cell table is rewritten: cells hold list indices, and cells resolved on demand are cached as -(slot + 1).
Definition at line 712 of file vf_latticepal.c.
Referenced by filter_frame().
|
static |
Rediffuse the whole frame against the current live colors and reassign every pixel, recounting how often each live color is actually used.
Cells resolving to a dead or unused state are cached as -(list index+1); stale caches from earlier rounds heal themselves through the alive check.
Definition at line 816 of file vf_latticepal.c.
Referenced by reduce_batched().
|
static |
Batched reduction: instead of dropping all excess colors against the first pass statistics, drop half of the excess, rediffuse the frame against the survivors and recount from the actual assignments, then repeat.
Colors whose pixels the rediffusion absorbed elsewhere become free to drop, while colors that dithering cannot reproduce (extremes of the used gamut) keep their pixels and with them a high removal impact, so they are protected in later rounds.
Definition at line 908 of file vf_latticepal.c.
Referenced by filter_frame().
|
static |
Definition at line 941 of file vf_latticepal.c.
|
static |
Definition at line 1197 of file vf_latticepal.c.
|
static |
Definition at line 1359 of file vf_latticepal.c.
|
static |
Definition at line 118 of file vf_latticepal.c.
|
static |
Definition at line 160 of file vf_latticepal.c.
Referenced by config_input().
|
static |
Definition at line 1375 of file vf_latticepal.c.
| const FFFilter ff_vf_latticepal |
Definition at line 1384 of file vf_latticepal.c.