Overview
This documentation covers two parts that convert legacy Fractal Image Format files (.fif) from the 1990s into modern PNG images: the command-line tool FIFlegacy and the library libFIFlegacy.
FIFlegacy is a command-line tool for everyone who simply wants to convert files. It is built on libFIFlegacy and converts a .fif file to PNG with a single command, choosing the output name automatically when none is given. With --info it prints the technical details of a file instead. Clear error messages and defined exit codes make it suitable for scripts as well. Chapter 1 describes the tool.
libFIFlegacy is a single-file C library for developers. It exports one function, ConvertLegacyFIFtoPNG(), which decodes all still-image variants of the Iterated Systems FTC/FIF1 format family and either writes a PNG file, returns the PNG in memory, or returns a detailed text description of the file. It needs nothing but the C standard library, compiles as C99 or C++ on any platform, and uses an enhanced reconstruction that reduces the block artifacts of the original format. Chapter 2 describes the library.
| Component | File | Version | Purpose |
|---|---|---|---|
| FIFlegacy | fiflegacy.c |
1.0 | Command-line converter; includes libfiflegacy.c |
| libFIFlegacy | libfiflegacy.c |
1.2 | Single-file C/C++ library with one function: decode a FIF file to PNG (file or memory) or describe it |
Supported formats
| Profile | File signature | Example files | Status |
|---|---|---|---|
| Fixed FTC 1.1 still image (24-bit YUV) | FTC\0 01 01 02 01 |
DOLPHIN.FIF, SUNSET.FIF | Converted |
| Region FTC 3.1 / 3.2 / 3.3, bit/RLE coding (gray, YUV, EUV) | FTC\0 gg 03 |
PICT001.FIF, s058p1.fif | Converted |
| Region FTC 3.1 / 3.2, arithmetic coding | FTC\0 gg 03 |
windows.fif | Converted |
| Progressive FIF1 (color and gray) | FIF\x01 75 00 |
River.fif, m8156.fif | Converted |
| P.OEM Video 2.0 and FJF video | FTC\0 01 01 0x 02 / FTC\0 02 02 02 02 |
CREW256C.FIF | Recognised, described, not converted |
Output is always an 8-bit truecolor RGB PNG; grayscale images are written with R = G = B.
FIF History
Fractal image compression grew out of research by Michael Barnsley's group at the Georgia Institute of Technology in the 1980s. In 1987 Barnsley and Alan Sloan founded Iterated Systems, Inc., and Barnsley's doctoral student Arnaud Jacquin developed the block-based method behind every FIF file: each small block of a picture is described by a transformed, larger block of the same picture. The best-known customer was Microsoft, which used FIF for the photographs of its Encarta encyclopedia.
FIF never became a standard: encoding was slow, JPEG offered a free alternative from 1992, and the format was closed and patented. In 2001 Iterated Systems became MediaBin, and FIF turned into an orphaned format, which is why FIFlegacy exists.
Since 2026 there is an open successor: FIF2, created by Rezar Behzad, with a public specification and a reference implementation in source code. Read more in FIF2: A free Reboot of FIF.
How a FIF picture is built
A FIF1 file stores its picture in five levels of detail, and each level refines the one before: the first level holds one average value per 16 × 16 block, every further level halves the block size or replaces blocks by fractal transforms. The pictures below show River.fif after each level, decoded with libFIFlegacy. Select a level to see how the picture is built up.
Chapter 1The FIFlegacy command-line tool
FIFlegacy converts a FIF file to PNG with one command, or prints its information. It is one source file, fiflegacy.c, which includes libfiflegacy.c; keep both files in the same directory when building.
1.1 Usage
fiflegacy <input.fif> [output.png] convert a FIF file to PNG
fiflegacy <input.fif> --info show information about a FIF file
fiflegacy --help show the help
fiflegacy --version show the version numbers
| Argument / option | Meaning |
|---|---|
input.fif |
The file to convert. The name must end in .fif (any upper/lower case). |
output.png |
Optional. Without it, the input name is used with the extension .png, in the same directory. If it ends with / or \, it is treated as a directory and the PNG gets the input's base name. |
--info, -i |
Print the file information instead of converting (may also come before the file name). |
--help, -h, /? |
Print the usage. |
--version, -v |
Print the versions of the tool and the library. |
Output names at a glance:
| Command | PNG written to |
|---|---|
fiflegacy pictures/DOLPHIN.FIF |
pictures/DOLPHIN.png |
fiflegacy pictures/DOLPHIN.FIF dolphin.png |
dolphin.png |
fiflegacy pictures/DOLPHIN.FIF converted/ |
converted/DOLPHIN.png |
Every call starts with the copyright line, which always shows the current version numbers of both parts:
1.2 Examples
Convert a file
> fiflegacy SUNSET.FIF
Converting "SUNSET.FIF" -> "SUNSET.png" ...
Success: PNG file written.
Image size: 640 x 400 pixels
FIF file size: 15,043 bytes (14.7 KB)
PNG file size: 393,348 bytes (384.1 KB)
If the PNG already exists it is replaced, and the success line says (existing file replaced).
Show the file information
> fiflegacy River.fif --info
Library: libfiflegacy 1.2
File: River.fif
File size: 22238 bytes
Format: FIF1 progressive fractal image (Part III)
...
Decodable: yes
Output image: 320 x 240 pixels, 8-bit RGB (PNG color type 2)
Reconstruction: enhanced (centred chroma interpolation)
Status: OK
The complete text is shown in section 2.8. --info also works for files that cannot be converted, such as videos.
A file that cannot be converted
> fiflegacy CREW256C.FIF
Converting "CREW256C.FIF" -> "CREW256C.png" ...
Error -5: "CREW256C.FIF" is a fractal VIDEO file (P.OEM or FJF video).
Videos cannot be converted to PNG.
Tip: "fiflegacy CREW256C.FIF --info" shows details of the video.
Show the versions
> fiflegacy --version
fiflegacy 1.0
libfiflegacy 1.2
1.3 Error messages
Errors are printed to standard error, starting with Error and the code, followed by a hint what to do.
| Situation | Message (shortened) |
|---|---|
| No input file, too many arguments, unknown option, empty name | Error: no input file given., too many arguments, unknown option or empty file name, each followed by the usage |
--info together with an output file |
Error: --info does not take an output file |
| Output would overwrite the input | Error: input and output are the same file |
| Wrong extension | Error -2: The input file "..." does not have the extension .fif. |
| File missing or not readable | Error -3: The input file "..." cannot be opened. |
| Not a fractal image | Error -4: "..." is not a Fractal Image Format file |
| Video file | Error -5: "..." is a fractal VIDEO file |
| Unsupported variant | Error -6: "..." uses a variant ... that is not supported |
| Damaged file | Error -7: "..." is damaged, incomplete or inconsistent |
| Template missing | Error -8: "..." needs an external template file (*.ftt) |
| Output not writable | Error -11: The output file "..." cannot be written. |
1.4 Exit codes
The exit code lets scripts check the result. For library errors it is the absolute value of the library error code.
| Exit code | Meaning |
|---|---|
| 0 | Success (with --info: the file is convertible) |
| 2 | Wrong extension (FIF_ERR_EXTENSION) |
| 3 | Input cannot be opened (FIF_ERR_OPEN) |
| 4 | Not a fractal image (FIF_ERR_UNKNOWN_FORMAT) |
| 5 | Video file (FIF_ERR_VIDEO) |
| 6 | Unsupported variant (FIF_ERR_UNSUPPORTED) |
| 7 | Damaged file (FIF_ERR_MALFORMED) |
| 8 | FTT template missing (FIF_ERR_FTT_MISSING) |
| 9 | Out of memory (FIF_ERR_MEMORY) |
| 10 | File or image too large (FIF_ERR_TOO_LARGE) |
| 11 | Output cannot be written (FIF_ERR_WRITE) |
| 64 | Wrong command-line usage |
Chapter 2The libFIFlegacy library
libFIFlegacy is one C source file that exports exactly one function, ConvertLegacyFIFtoPNG(). It decodes a FIF file and either writes a PNG to disk, returns the PNG in memory, or returns a text description of the file.
2.1 Features
- Decodes all still-image profiles of the FTC/FIF1 format family (see the Overview table).
- Writes standard PNG files with its own built-in deflate encoder; zlib and libpng are not needed.
- Three modes: PNG file, PNG in memory, or a detailed information text.
- Enhanced reconstruction by default (sharper, fewer block artifacts); the exact reference procedure of the specification is available as a compile option.
- Portable: byte-wise file parsing, no endianness or alignment assumptions, plain C99 that also compiles as C++.
- Reentrant and thread-safe: no global mutable state.
- Robust: every header field, offset and bit stream is validated; tested with AddressSanitizer, UndefinedBehaviorSanitizer and more than 1,000 deliberately damaged files.
- Safe writing: a PNG is first written to
<name>.tmpand then renamed, so a failed conversion never leaves a half-written file.
2.2 Integration
The library is a single file. Use it in one of two ways:
- Include it in exactly one source file of your project:
#include "libfiflegacy.c"
- Compile it separately as its own object file and link it. Other source files then include only the declarations:
#define LIBFIFLEGACY_DECLARATION_ONLY
#include "libfiflegacy.c"
Compile options:
| Macro | Effect |
|---|---|
LIBFIFLEGACY_DECLARATION_ONLY |
Include only types, constants and the prototype, no implementation |
LIBFIFLEGACY_STRICT_SPEC |
Use the exact reference reconstruction of the specification instead of the enhanced one (output identical to version 1.1) |
Build examples:
cc -std=c99 -O2 -c libfiflegacy.c Linux, macOS, BSD (gcc or clang)
clang -O2 -c libfiflegacy.c Windows (LLVM-MinGW)
cl /O2 /c libfiflegacy.c Windows (MSVC)
Requirements: a C99 compiler or a C++98 compiler. The code compiles without warnings with -Wall -Wextra -Wpedantic in C99, C11, C17 and C++98 to C++20.
2.3 The function
FIF_RESULT *ConvertLegacyFIFtoPNG(const char *fifPath, const char *pngPath, int modus);
| Parameter | Description |
|---|---|
fifPath |
Path and name of the input file. The name must end in .fif (any upper/lower case), otherwise the result is FIF_ERR_EXTENSION. |
pngPath |
Path and name of the PNG to write. Used only in modus 1; may be NULL in modus 2 and 3. The directory must exist; an existing file is replaced. |
modus |
FIF_MODE_FILE (1), FIF_MODE_MEMORY (2) or FIF_MODE_INFO (3), see 2.4. |
The function always returns a pointer to a FIF_RESULT. It is one single memory block that holds the structure and its data; release it with one call of free(), in every mode and also on errors. NULL is returned only if not even the small result structure could be allocated.
2.4 Modes
| Modus | Constant | What happens | Result data |
|---|---|---|---|
| 1 | FIF_MODE_FILE |
Decodes the image and writes a PNG file to pngPath |
width, height |
| 2 | FIF_MODE_MEMORY |
Decodes the image and returns the complete PNG file in memory; nothing is written to disk | data = PNG bytes, size = byte count |
| 3 | FIF_MODE_INFO |
Returns a text block with information about the file, one item per line as Key: value |
text = NUL-terminated text, size = length |
Modus 3 always delivers text when memory permits, also for files that cannot be converted (videos, damaged files, wrong extension). The lines Decodable: and Status: then state the reason, and error holds the same code modus 1 or 2 would return.
2.5 The result structure
typedef struct FIF_RESULT {
int error; /* FIF_OK or FIF_ERR_... */
int modus; /* requested modus */
int width; /* decoded image width, 0 if not decoded */
int height; /* decoded image height, 0 if not decoded */
unsigned char *data; /* modus 2: PNG bytes; modus 3: text; modus 1: NULL */
size_t size; /* modus 2: PNG byte count; modus 3: text length */
char *text; /* modus 3: NUL-terminated text, otherwise NULL */
} FIF_RESULT;
data and text point into the same memory block as the structure. Do not free them separately, and do not use them after free(result).
2.6 Error codes
| Code | Constant | Meaning |
|---|---|---|
| 0 | FIF_OK |
Success |
| −1 | FIF_ERR_ARGUMENT |
fifPath is NULL or empty, or pngPath is missing in modus 1 |
| −2 | FIF_ERR_EXTENSION |
fifPath does not end in .fif |
| −3 | FIF_ERR_OPEN |
The input file cannot be opened or read |
| −4 | FIF_ERR_UNKNOWN_FORMAT |
No FTC/FIF1 signature: not a fractal image file |
| −5 | FIF_ERR_VIDEO |
Fractal video file (P.OEM or FJF): recognised, not converted |
| −6 | FIF_ERR_UNSUPPORTED |
Recognised, but an unsupported variant (e.g. arithmetic FTC 3.3) |
| −7 | FIF_ERR_MALFORMED |
Damaged, truncated or inconsistent file |
| −8 | FIF_ERR_FTT_MISSING |
A required external .ftt template was not found or does not match |
| −9 | FIF_ERR_MEMORY |
Out of memory |
| −10 | FIF_ERR_TOO_LARGE |
Input file larger than 1 GiB, or image larger than 134,217,728 pixels (2^27) |
| −11 | FIF_ERR_WRITE |
Modus 1: the PNG file cannot be created, written or renamed |
| −12 | FIF_ERR_MODE |
modus is not 1, 2 or 3 |
Version constants for your own checks: LIBFIFLEGACY_VERSION ("1.2"), LIBFIFLEGACY_VERSION_MAJOR (1) and LIBFIFLEGACY_VERSION_MINOR (2).
2.7 Examples
Convert to a PNG file (modus 1)
#include <stdio.h>
#include <stdlib.h>
#include "libfiflegacy.c"
int main(void) {
FIF_RESULT *r = ConvertLegacyFIFtoPNG("images/DOLPHIN.FIF", "out/dolphin.png", FIF_MODE_FILE);
if (!r) { puts("out of memory"); return 1; }
if (r->error == FIF_OK)
printf("written: %d x %d pixels\n", r->width, r->height);
else
printf("conversion failed, error %d\n", r->error);
free(r);
return 0;
}
Get the PNG in memory (modus 2), for example to send it over a network, store it in a database or hand it to a GUI toolkit:
FIF_RESULT *r = ConvertLegacyFIFtoPNG("images/River.fif", NULL, FIF_MODE_MEMORY);
if (r && r->error == FIF_OK) {
/* r->data points to a complete PNG file of r->size bytes */
FILE *f = fopen("copy.png", "wb");
fwrite(r->data, 1, r->size, f);
fclose(f);
}
free(r);
Read the file information (modus 3)
FIF_RESULT *r = ConvertLegacyFIFtoPNG("images/River.fif", NULL, FIF_MODE_INFO);
if (r) {
fputs(r->text, stdout); /* one "Key: value" item per line */
if (r->error != FIF_OK)
printf("not convertible (error %d)\n", r->error);
}
free(r);
Turn error codes into messages
static const char *fif_message(int code) {
switch (code) {
case FIF_OK: return "OK";
case FIF_ERR_EXTENSION: return "the file name must end in .fif";
case FIF_ERR_OPEN: return "the file cannot be opened";
case FIF_ERR_UNKNOWN_FORMAT: return "not a fractal image file";
case FIF_ERR_VIDEO: return "fractal video, cannot be converted";
case FIF_ERR_FTT_MISSING: return "the required .ftt template is missing";
case FIF_ERR_MALFORMED: return "the file is damaged";
default: return "conversion failed";
}
}
Check the library version at compile time
#if LIBFIFLEGACY_VERSION_MAJOR < 1 || (LIBFIFLEGACY_VERSION_MAJOR == 1 && LIBFIFLEGACY_VERSION_MINOR < 2)
#error "libfiflegacy 1.2 or newer required"
#endif
2.8 The information text (modus 3)
Each line holds one item as Key: value, so the text is easy to read and easy to parse. The details depend on the format: header fields, regions, quantizers, palettes, tiles, chunks, encoder stamps or attached sound, and for videos title, frame rate, frame count and duration. The last lines report whether the file is decodable, which reconstruction was used and the status. Example for River.fif:
Library: libfiflegacy 1.2
File: River.fif
File size: 22238 bytes
Format: FIF1 progressive fractal image (Part III)
Signature: FIF\x01
Container marker: 75 00
Width: 320
Height: 240
Header size: 143 bytes
Declared file size: 22238 bytes
Source components: EUV (color: luminance + 2 chroma planes at half resolution)
Output representation: BGR
Scale: 1
Coded canvas: 320 x 256
Luminance domain step: 2
Chroma domain step: 4
Initial range exponent: 4 (ranges of 16 x 16 pixels)
Progressive levels: 5
Tile size: 160 x 256
Tile grid: 2 x 1 (2 tiles)
Primary transform limit: 5038
Aggregate transform limit: 15255
Progressive codec: 0x10
Chunk count: 3
Encoder quality: 90 %
Chunk C0 (vendor extension): value 4
Chunk FF (FTU output size): 320 x 240
Chunk 03 (offset directory): 60 bytes
Decodable: yes
Output image: 320 x 240 pixels, 8-bit RGB (PNG color type 2)
Reconstruction: enhanced (centred chroma interpolation)
Status: OK
2.9 Image quality
Since version 1.2 the FTC formats are reconstructed with three improvements over the fast reference procedure of the specification:
- Full-resolution refinement. The specification iterates only at half resolution and stops at changes of up to 4 gray levels. The library continues at full resolution in fixed-point arithmetic until the image has converged.
- Adaptive deblocking. The 4 × 4 block boundaries are smoothed in flat areas, while real edges are detected and left untouched. The strength follows the quantizer of the file; chroma is filtered only for coarse quantizers.
- Centred chroma interpolation. The half-resolution color planes are interpolated with centred sample positions (also for FIF1), which reduces color offset and color blockiness.
Measured on four test images, each encoded with the FTC transform model at two quantizer resolutions, the enhanced reconstruction improved the fidelity in all eight cases by 0.31 to 0.69 dB PSNR. FIF1 files already converge with the specified passes, so only the chroma interpolation changes there. Compile with LIBFIFLEGACY_STRICT_SPEC to get the exact reference output instead.
The quality is limited mainly by the files themselves: these are 1990s images at very high compression (DOLPHIN.FIF stores 640 × 400 pixels in 15 KB, about 0.47 bits per pixel). Details lost during encoding cannot be recovered; the decoder reduces the visible artifacts.
2.10 External templates (FTT)
Some region FTC files take part of their image content from an external Fractal Transform Template (.ftt). The FIF file stores only the template's original file name, size and identity value. The library looks for the template in the directory of the .fif file, under its base name as stored, in lower case and in upper case, and checks size and identity. If no matching template is found, the result is FIF_ERR_FTT_MISSING; modus 3 shows the name of the required file.
This code path follows the specification but has not yet been verified with real FTT files.
2.11 Limitations
| Topic | Behaviour |
|---|---|
| Video files (P.OEM Video 2.0, FJF) | Recognised and described in modus 3; conversion returns FIF_ERR_VIDEO |
| Arithmetic FTC 3.3 and arithmetic dictionary classes | FIF_ERR_UNSUPPORTED (no sample files to verify the format) |
| File name | Must end in .fif; files with other extensions are rejected even if their content is valid |
| Size | Input files up to 1 GiB, images up to 134,217,728 pixels |
| Output | 8-bit RGB PNG at the original size; palettes stored in files are validated but not applied |