LensSerious 0.1
Lens-correction mathematics as data, not as a library of callbacks
Loading...
Searching...
No Matches
lensserious_vendor.c File Reference

The per-vendor decoders behind ls_vendor_resolve(), and the OpcodeList3 parser. More...

#include "lensserious_vendor.h"
#include <math.h>
#include <string.h>
+ Include dependency graph for lensserious_vendor.c:

Go to the source code of this file.

Macros

#define DNG_OPCODE_ID_WARP_RECTILINEAR   1u
 
#define DNG_OPCODE_ID_VIGNETTE_RADIAL   3u
 
#define DNG_WARP_PLANES_MIN   1u
 
#define DNG_WARP_PLANES_MAX   3u
 
#define DNG_WARP_HEADER_SIZE   4u /* the plane count */
 
#define DNG_WARP_PLANE_SIZE   (6u * 8u) /* six doubles per plane */
 
#define DNG_WARP_CENTER_SIZE   (2u * 8u) /* cx, cy */
 
#define DNG_VIGNETTE_COEFFS_SIZE   (5u * 8u)
 
#define DNG_VIGNETTE_CENTER_SIZE   (2u * 8u)
 

Functions

static float _linear_spline (const float *xi, const float *yi, const int ni, const float x)
 
static int _sony_has_data (const ls_vendor_data_t *d)
 
static int _sony_axes (const ls_vendor_data_t *d)
 
static int _sony_populate (const ls_vendor_data_t *d, const ls_vendor_finetune_t *ft, ls_knots_t *knots)
 
static int _fuji_has_data (const ls_vendor_data_t *d)
 
static int _fuji_axes (const ls_vendor_data_t *d)
 
static int _fuji_populate (const ls_vendor_data_t *d, const ls_vendor_finetune_t *ft, ls_knots_t *knots)
 
static int _dng_axes (const ls_vendor_data_t *d)
 
static double _dng_warp_radial (const double coeffs[6], const double r2)
 
static int _dng_populate (const ls_vendor_data_t *d, const ls_vendor_finetune_t *ft, ls_knots_t *knots)
 
static int _olympus_axes (const ls_vendor_data_t *d)
 
static int _olympus_populate (const ls_vendor_data_t *d, const ls_vendor_finetune_t *ft, ls_knots_t *knots)
 
int ls_vendor_axes (const ls_vendor_data_t *d)
 Which correction axes this data carries.
 
int ls_vendor_resolve (const ls_vendor_data_t *d, const ls_vendor_finetune_t *ft, int w, int h, ls_knots_t *knots, float *autoscale)
 The conversion: vendor tables in, generic knots out.
 
static double _get_be_double (const uint8_t *p)
 
static uint32_t _get_be_long (const uint8_t *p)
 
static void _parse_warp_rectilinear (const uint8_t *param, uint32_t param_size, ls_vendor_dng_t *out)
 
static void _parse_vignette_radial (const uint8_t *param, uint32_t param_size, ls_vendor_dng_t *out)
 
int ls_vendor_parse_dng_opcodelist3 (const uint8_t *blob, size_t len, ls_vendor_dng_t *out)
 Parse a DNG OpcodeList3 payload: WarpRectilinear (1) and VignetteRadial (3).
 

Variables

static const ls_vendor_finetune_t _ft_identity = { 1.f, 1.f, 1.f, 1.f }
 

Detailed Description

The per-vendor decoders behind ls_vendor_resolve(), and the OpcodeList3 parser.

Every decoder ends in the same place: radii and per-channel scale factors in ls_knots_t layout, half-diagonal normalized. What differs per vendor is the road there — Sony's fixed-point tables at implicit radii, Fujifilm's percentage tables at explicit radii needing a resample, a DNG's closed-form polynomials sampled onto knots, Olympus's likewise. The maths is a faithful port of the darktable/Ansel implementation; a pixel rendered through these knots must not move because the code changed repositories.

Definition in file lensserious_vendor.c.

Macro Definition Documentation

◆ DNG_OPCODE_ID_VIGNETTE_RADIAL

#define DNG_OPCODE_ID_VIGNETTE_RADIAL   3u

Definition at line 443 of file lensserious_vendor.c.

Referenced by ls_vendor_parse_dng_opcodelist3().

◆ DNG_OPCODE_ID_WARP_RECTILINEAR

#define DNG_OPCODE_ID_WARP_RECTILINEAR   1u

Definition at line 442 of file lensserious_vendor.c.

Referenced by ls_vendor_parse_dng_opcodelist3().

◆ DNG_VIGNETTE_CENTER_SIZE

#define DNG_VIGNETTE_CENTER_SIZE   (2u * 8u)

Definition at line 451 of file lensserious_vendor.c.

Referenced by _parse_vignette_radial().

◆ DNG_VIGNETTE_COEFFS_SIZE

#define DNG_VIGNETTE_COEFFS_SIZE   (5u * 8u)

Definition at line 450 of file lensserious_vendor.c.

Referenced by _parse_vignette_radial().

◆ DNG_WARP_CENTER_SIZE

#define DNG_WARP_CENTER_SIZE   (2u * 8u) /* cx, cy */

Definition at line 449 of file lensserious_vendor.c.

Referenced by _parse_warp_rectilinear().

◆ DNG_WARP_HEADER_SIZE

#define DNG_WARP_HEADER_SIZE   4u /* the plane count */

Definition at line 447 of file lensserious_vendor.c.

Referenced by _parse_warp_rectilinear().

◆ DNG_WARP_PLANE_SIZE

#define DNG_WARP_PLANE_SIZE   (6u * 8u) /* six doubles per plane */

Definition at line 448 of file lensserious_vendor.c.

Referenced by _parse_warp_rectilinear().

◆ DNG_WARP_PLANES_MAX

#define DNG_WARP_PLANES_MAX   3u

Definition at line 446 of file lensserious_vendor.c.

Referenced by _parse_warp_rectilinear().

◆ DNG_WARP_PLANES_MIN

#define DNG_WARP_PLANES_MIN   1u

Definition at line 445 of file lensserious_vendor.c.

Function Documentation

◆ _dng_axes()

◆ _dng_populate()

◆ _dng_warp_radial()

static double _dng_warp_radial ( const double coeffs[6],
const double r2 )
static

WarpRectilinear's radial part: kr0..kr3 evaluated at r^2, by Horner.

Definition at line 217 of file lensserious_vendor.c.

Referenced by _dng_populate().

◆ _fuji_axes()

◆ _fuji_has_data()

static int _fuji_has_data ( const ls_vendor_data_t * d)
static

Definition at line 114 of file lensserious_vendor.c.

References ls_vendor_data_t::fuji, ls_vendor_fuji_t::nc, and ls_vendor_data_t::u.

Referenced by _fuji_axes().

◆ _fuji_populate()

◆ _get_be_double()

static double _get_be_double ( const uint8_t * p)
static

Definition at line 453 of file lensserious_vendor.c.

Referenced by _parse_vignette_radial(), and _parse_warp_rectilinear().

◆ _get_be_long()

static uint32_t _get_be_long ( const uint8_t * p)
static

◆ _linear_spline()

static float _linear_spline ( const float * xi,
const float * yi,
const int ni,
const float x )
static

Piecewise-linear interpolation over (xi, yi), clamped at both ends. The resampler the Fujifilm decoder and the autoscale sweep share.

Definition at line 34 of file lensserious_vendor.c.

Referenced by _fuji_populate(), and ls_vendor_resolve().

◆ _olympus_axes()

◆ _olympus_populate()

◆ _parse_vignette_radial()

static void _parse_vignette_radial ( const uint8_t * param,
uint32_t param_size,
ls_vendor_dng_t * out )
static

◆ _parse_warp_rectilinear()

◆ _sony_axes()

◆ _sony_has_data()

static int _sony_has_data ( const ls_vendor_data_t * d)
static

◆ _sony_populate()

◆ ls_vendor_axes()

int ls_vendor_axes ( const ls_vendor_data_t * d)

Which correction axes this data carries.

Returns
A mask of LS_ENABLE_DISTORTION, LS_ENABLE_TCA and LS_ENABLE_VIGNETTING; 0 when the data carries nothing usable (including d NULL or type NONE).

Cheap — table scans, no knots work — so a GUI may ask per repaint. The same mask vocabulary as ls_modifier_init() returns, one axis language across the library. An all-zero table is reported as ABSENT, not as a present-but-identity correction: several bodies write zero-filled tables for lenses they choose not to correct.

Definition at line 353 of file lensserious_vendor.c.

References _dng_axes(), _fuji_axes(), _olympus_axes(), _sony_axes(), LS_VENDOR_DNG, LS_VENDOR_FUJI, LS_VENDOR_NONE, LS_VENDOR_OLYMPUS, LS_VENDOR_SONY, and ls_vendor_data_t::type.

Referenced by ls_vendor_parse_dng_opcodelist3(), and ls_vendor_resolve().

◆ ls_vendor_parse_dng_opcodelist3()

int ls_vendor_parse_dng_opcodelist3 ( const uint8_t * blob,
size_t len,
ls_vendor_dng_t * out )

Parse a DNG OpcodeList3 payload: WarpRectilinear (1) and VignetteRadial (3).

Parameters
blobthe tag's raw bytes, exactly as the file carries them (big-endian, per the DNG 1.3 specification). Not written to.
lenthe payload size in bytes.
outfilled with whatever was recognised; zeroed first, so a partial parse leaves the untouched corrections cleanly absent.
Returns
The axes mask the parsed opcodes provide; 0 when the list holds none of the recognised opcodes (other opcode ids are skipped, as the specification intends); LS_VENDOR_EBADDATA when the list structure itself is broken before anything was recognised. A list that breaks AFTER yielding a usable opcode returns what it yielded: partial data is data.

Every read is bounds-checked against len; a truncated or hostile blob cannot read past the buffer.

Definition at line 505 of file lensserious_vendor.c.

References _get_be_long(), _parse_vignette_radial(), _parse_warp_rectilinear(), DNG_OPCODE_ID_VIGNETTE_RADIAL, DNG_OPCODE_ID_WARP_RECTILINEAR, ls_vendor_axes(), LS_VENDOR_DNG, and LS_VENDOR_EBADDATA.

◆ ls_vendor_resolve()

int ls_vendor_resolve ( const ls_vendor_data_t * d,
const ls_vendor_finetune_t * ft,
int w,
int h,
ls_knots_t * knots,
float * autoscale )

The conversion: vendor tables in, generic knots out.

Parameters
dthe extracted data. See what the consumer extracts.
ftper-axis strength, or NULL for "as the maker measured" (all 1.0).
wimage width in pixels — the PROCESSED dimensions the radii are measured against (after the sensor's fixed border trim, before any user crop). Ansel passes dt_image_t.p_width/p_height.
himage height in pixels.
knotsout: the normalized table, ready for ls_modifier_init_knots(). Fully written on success (n and vn included); zeroed on failure.
autoscaleout, may be NULL: the zoom that just clears the borders the correction leaves, measured over the region between the inscribed circle and the corner. Pass it (times any user scale) as ls_modifier_init_knots()'s scale argument. 1.0 on failure.
Returns
The resolved axes mask (same bits as ls_vendor_axes()); 0 when the data carries nothing — a zero-filled table with a valid type included, see ls_vendor_axes(); LS_VENDOR_EBADDATA when a claimed correction fails to convert.

Pure and thread-safe: no allocation, no globals, callable from a pipeline thread per commit. Not per pixel — resolve once, keep the knots.

Definition at line 368 of file lensserious_vendor.c.

References _dng_populate(), _ft_identity, _fuji_populate(), _linear_spline(), _olympus_populate(), _sony_populate(), ls_knots_t::cor_rgb, LS_ENABLE_VIGNETTING, ls_vendor_axes(), LS_VENDOR_DNG, LS_VENDOR_EBADDATA, LS_VENDOR_FUJI, LS_VENDOR_OLYMPUS, LS_VENDOR_SONY, ls_knots_t::n, ls_knots_t::radius, ls_vendor_data_t::type, and ls_knots_t::vn.

Variable Documentation

◆ _ft_identity

const ls_vendor_finetune_t _ft_identity = { 1.f, 1.f, 1.f, 1.f }
static

Definition at line 53 of file lensserious_vendor.c.

Referenced by ls_vendor_resolve().