There are a bunch of fractal programs with their own file formats for storing iteration data:
- MandelMachine has MMIT
- Kalles Fraktaler has KFB
etc
It would be cool to have a standard file format that fractal programs can use for interoperability.
I propose using
OpenEXR 2.0 https://www.openexr.com/ as it is licensed permissively, and is widely used / tested already. It is flexible (supports any number of float32 and uint32 channels), with multi-image files, and deep images with variable number of samples per pixel. The main thing is to standardize on the channel names (which are strings). I propose these to start with (all channels are optional):
uint32 N integer iteration count
0xFFFFFFFF is non-escaped before header metadata field
int Iterations (or
string Iterations, it can exceed the range of int, sigh...)
0x00000000 is uncalculated/glitch/no-data-available. If actual iteration values can be zero or negative, add a bias constant to each count and store it in the header metadata field
int IterationsBias (or
string IterationsBias, it can exceed the range of int). the bias could be negative, this might allow you to store high iteration counts without necessarily needing two channels if the actual min/max range is small enough)
for images with biased iteration counts above 0xFFFFFFFE, split into two channels:
uint32 N0 least significant 32 bits
uint32 N1 most significant 32 bits; 0xFFFFFFFF is interpreted as non-escaped, regardless of the value of N0 (but it should also be set to 0xFFFFFFFF)
for future supercomputers, this can be extended with N2 etc...
genType NF fractional iteration count, expected to be in [0.0 .. 1.0) for float32 and half (float16), and the full range normalized by dividing by 0x100000000 for uint32. The continuous iteration count (when escaped) is N+NF-IterationsBias. This is stored separately to avoid losing precision at high iteration counts
floatType DE signed distance estimate, normalized such that distance to a neighbouring boundary pixel is approximately 1.0 for exterior distance estimate and -1.0 for interior distance estimate. If there are exterior de and no interior de available (or vice versa) the missing data can be written as 0.0, but readers should also handle NaN in this case.
floatType DEX,
floatType DEY directional distance estimate in cartesian form, normalized such that distance to a neighbouring boundary pixel sqrt(DEX^2 + DEY^2) is approximately 1.0. If some pixels have no direcitonal DE the missing data can be written as (0.0, 0.0), but readers should also handle NaNs in this case. The vector should point away from the fractal boundary.
floatType ZX,
floatType ZY coordinates at the first escaped iteration. Image should have a header attribute
floatType EscapeRadius.
Orbit traps can be handled as layers with TRAP somewhere in the path:
uint32 TRAP.N iteration number at which trap was hit, see above for large iteration counts
floatType TRAP.TD distance to trap (eg an x-axis trap would have |y-coordinate|) (normalized however you like, as deep images may have tiny values (perhaps?), but should be monotonic, it could eg be negative if you take logs for more range than float32)
floatType TRAP.ZX,
floatType TRAP.ZY coordinates at the trap iteration, should be normalized so that the magnitude at the edge of the trap is 1.0 (can't use just X and Y because Y is already claimed in EXR for colour luminance).
Deep images could be used to accumulate all the orbit traps hit over the lifetime of the pixel's iteration. More research needed on this.
Feedback very welcome! There's not much point to this exercise if the only software implementing it is KF (it doesn't do it yet, but I will work on it soon).
EDITED 2019-09-09 to add notes about string attributes for Iterations and IterationsBias, as well as allowing negative bias; added DEX/DEY spec
Linkback: https://fractalforums.org/programming/11/towards-a-common-file-format-for-2d-escape-time-iteration-data/3017/