# FractInt
# 1 GIF Metadata
GIF images exported from FractInt have embedded metadata. You can load GIFs back into FractInt (or xFractInt on Linux) and continue exploring from the same location.
The original FractInt.exe
(which works on Linux with Wine and DOSBox)
has a command line option for converting GIF to PAR
(PAR is FractInt’s parameter format based on ASCII text):
wine fractint.exe foo.gif makepar=bar.par/foo
The bar.par
file can contain many parameters,
they will be appended each time.
# 2 PAR to KFR conversion
KFR is the parameter file format of Kalle’s Fraktaler 2.
It is rather simple, consisting of Key: Value
pairs,
each on their own line in a text file with DOS line endings.
The tools dos2unix
and unix2dos
are useful for converting.
PAR format has a few awkward aspects, so the conversion is done in 3 parts.
# 2.1 Split PAR to PPAR
MightyMandel (an abandoned fractal program of mine) has a script that splits a PAR collection into multiple files with a slightly simpler format. Line continuations (lines ending in backslash) are merged. Key/value pairs are separated by newlines instead of commas.
The script split2ppar.sh
is reproduced here:
#!/bin/bash
tmp="$(mktemp -d --tmpdir=. split2ppar.XXXXXXXX)"
for file in "${@}"
do
name="$(basename "${file}")"
file="$(readlink -e "${file}")"
pushd "${tmp}"
awk "/{/{n++}{print > \"${name}_\"n\".par\" }" "${file}"
popd
done
pushd "${tmp}"
for file in *.par
do
ident="$(head -n 1 "${file}" | sed 's/ .*$//')"
mv "${file}" "${ident}.par" # rename input
cat < "${ident}.par" | # read input
sed 's/;.*$//' | # delete ; comments
tr '\n' ' ' | # join on one line with spaces
sed 's/\\ *//g' | # merge lines ended with '\'
tr -s ' ' | # compress multiple ' ' to single ' '
sed 's/^.*{\([^}]*\)}.*$/\1/' | # extract the part between { }
tr ' ' '\n' | # split into separate lines
cat > "${ident}.ppar" # write output
done
popd
ls "${tmp}/"*
# 2.2 Palette Conversion
FractInt palettes have 256 colours (of which the first is reserved for interior).
They are stored as 6bit RGB, encoded in ASCII.
Gradients of slowly changing colours are compressed as two endpoints and a count.
Check FractInt documentation Topic=Color Specification
for details.
My decoder ppar2kfp.c
is reproduced here (implemented in C):
#include <assert.h>
#include <stdio.h>
int main(int argc, char **argv)
{
unsigned char palette[256][3];
// decompress palette spec
int lastindex = 0;
int index = 0;
int channel = 0;
int count = 0;
char input;
while (EOF != (input = fgetc(stdin)))
{
if (input == ' ' || input == '\r' || input == '\n' || input == '\\')
{
continue;
}
if (input == '<')
{
assert(index > 0);
assert(channel == 0);
lastindex = index - 1;
count = 0;
while ('>' != (input = fgetc(stdin)))
{
assert(EOF != input);
assert('0' <= input);
assert(input <= '9');
count *= 10;
count += input - '0';
}
index += count;
assert(index < 256);
}
else
{
int sixbit = 0;
if ('0' <= input && input <= '9') sixbit = input - '0';
else if ('A' <= input && input <= 'Z') sixbit = input - 'A' + 10;
else if ('_' == input) sixbit = 36;
else if ('`' == input) sixbit = 37;
else if ('a' <= input && input <= 'z') sixbit = input - 'a' + 38;
else
{
assert(! "expected encoded channel value character");
}
int eightbit = (sixbit << 2) | (sixbit >> 4); // scale so that 0 -> 0, 63 -> 255
palette[index][channel] = eightbit;
channel++;
if (channel == 3)
{
channel = 0;
if (count > 0)
{
assert(count == index - (lastindex + 1));
for (int fillindex = lastindex + 1; fillindex < index; ++fillindex)
{
for (int fillchannel = 0; fillchannel < 3; ++fillchannel)
{
// linear interpolation
palette[fillindex][fillchannel] = (int) palette[lastindex][fillchannel] +
( ((int) palette[index][fillchannel] - (int) palette[lastindex][fillchannel])
* (fillindex - lastindex)
+ (index - lastindex) / 2 // for rounding instead of truncation
) / (index - lastindex);
}
}
}
count = 0;
index++;
if (index == 256)
{
break;
}
}
}
}
assert(index == 256);
printf("InteriorColor: %d,%d,%d,\n", palette[0][2], palette[0][1], palette[0][0]);
printf("Colors: ");
for (index = 1; index < 256; ++index)
{
printf("%d,%d,%d,", palette[index][2], palette[index][1], palette[index][0]);
}
printf("\n");
return 0;
}
It expects the value of the colors=
key on standard input
and outputs a converted palette on standard output
# 2.3 Export KFR
This script ppar2kfr.sh
extracts the coordinates,
using ghc
as a calculator to multiply the zoom factor by 2 to match KF convention.
The script assumes the parameter is for Mandelbrot set without checking.
It uses the above C program (which must be compiled and put next to this script) to extract the palette colours.
It also sets various values so that the colours match better (though they weren’t 100% exact matches in my tests).
Some PAR files have other colour mappings that make the output from KF look completely different from the original output from FractInt, please check before starting a big render.
#!/bin/bash
(
cat $1 |
grep ^center-mag= |
sed "s|^center-mag=||g" |
tr "/" " " |
(
read Re Im Zoom XMag RotateAngle Skew
echo "Re: $Re"
echo "Im: $Im"
Zoom="$(ghc -e "2 * $Zoom")"
echo "Zoom: $Zoom"
cat $1 |
grep ^maxiter= |
sed "s|^maxiter=\(.*\)$|Iterations: \1|g"
if [ ! "${XMag}" ]
then
XMag=1
fi
if [ "${XMag}" != "1" ]
then
echo "unsupported XMag $XMag" >&2
fi
if [ ! "${RotateAngle}" ]
then
RotateAngle=0
fi
echo "RotateAngle: $RotateAngle"
if [ ! "${Skew}" ]
then
Skew=0
fi
if [ Skew != "0" ]
then
echo "unsupported Skew $Skew" >&2
fi
)
) |
sed 's|: +|: |g'
cat $1 |
grep ^colors= |
sed "s|^colors=||g" |
"$(dirname "$(readlink -e "$0")")"/ppar2kfp
cat <<EOF
ColorOffset: 1020
IterDiv: 0.2490234375
JitterSeed: 1
ImagPointsUp: 1
SmoothMethod: 1
SmoothingMethod: 1
Smooth: 0
Flat: 1
BailoutRadiusPreset: 1
BailoutRadiusCustom: 2
BailoutNormPreset: 1
BailoutNormCustom: 2
ColorMethod: 0
Differences: 0
ColorPhaseStrength: 0
MultiColor: 0
BlendMC: 0
MultiColors:
Power: 2
FractalType: 0
Slopes: 0
SlopePower: 50
SlopeRatio: 20
SlopeAngle: 45
real: 1
imag: 1
SeedR: 0
SeedI: 0
FactorAR: 1
FactorAI: 0
Period: 0
TextureEnabled: 0
TextureMerge: 1
TexturePower: 200
TextureRatio: 100
TextureFile:
StretchAngle: 0
StretchAmount: 0
Version: 2150100
ImageWidth: 1024
ImageHeight: 768
EOF
Use it like ppar2kfr.sh foo.ppar > foo.kfr
.
The output has UNIX line endings,
convert it to something compatible with KF using unix2dos
.