Using the fif tool

The command-line tool fif converts pictures to FIF2 and back and inspects FIF2 files. This page first shows common tasks and how to find the best quality for the size, then lists every command and option and explains the error messages.

Every command follows the same pattern: first the command, then the input and output files, then the options.

fif <command> <input> [<output>] [options]

fif help lists the commands with examples; fif help decode (or fif decode --help) lists all options of one command, grouped by what they are for.

Options must come after the file names. fif encode in.png out.fif -q 80 works; fif encode -q 80 in.png out.fif does not.

Common tasks

Compress a photograph

fif encode holiday.jpg holiday.fif -q 70

The tool prints the size of the result and the bits per pixel. Quality 70 gives a good picture for most photographs; lower values give smaller files.

Make a small file for the web

fif encode holiday.jpg web.fif --max-dim 1600 -q 50 --thumbnail 200

--max-dim 1600 reduces the picture so that its longer edge is at most 1600 pixels before it is encoded. --thumbnail 200 adds a JPEG preview of 200 pixels, which a viewer can show before it has decoded the picture. The original file name, the original size and the reduction factor are recorded in the file.

Add author and copyright

fif encode holiday.jpg holiday.fif --meta author="Ada Lovelace" --text copyright="(c) 2026 Ada Lovelace"

The camera's own data comes along by itself: from the EXIF block of a JPEG or PNG the tool takes the camera, lens, date taken, exposure, author, copyright and description, and it turns the picture upright if the camera stored it sideways. The GPS position is never taken over. A --meta or --text value with the same name replaces the camera's; --no-exif ignores the EXIF data altogether.

Each --meta and --text option stores one named value. You can use them as often as you like. The values may contain any characters, including accents and non-Latin scripts.

Decode at a larger size

fif decode holiday.fif poster.png --scale 3

The decoder carries out the fractal reconstruction at three times the coded resolution. This gives sharper edges than enlarging the normal decode in an image editor. Factors of 2 to 3 give the best results; up to 16 is possible.

Decode to an exact size

fif decode holiday.fif wallpaper.png --size 2560x1440

The picture fills the box completely. If its shape differs from the box, the excess is cut off equally on both sides; the picture is never stretched. To keep the whole picture, give only one dimension:

fif decode holiday.fif wide.png --width 2560

Decode only part of a picture

fif info holiday.fif --tiles                              # the tile map
fif decode holiday.fif detail.png --region 400x300+600+200
fif decode holiday.fif detail.png --region 400x300+600+200 --scale 4
fif decode holiday.fif some.png --tiles 0,5-6

A FIF2 picture is made of tiles that decode independently, so a part of it costs only the tiles it touches. --region takes the rectangle in the usual geometry notation: widthxheight+left+top, in the pixels of the picture as fif info reports them. The result is exactly the same as cutting the rectangle out of a full decode, only much faster: on a 3840 × 2160 picture, a 512 × 512 region decoded four times larger took 0.09 s instead of 0.62 s for the whole picture. --region combines with --scale, --width, --height and --size, which then refer to the region.

--tiles picks tiles by number, with ranges as in a print dialog. The picture keeps its full size; tiles that are not listed stay grey. fif info … --tiles shows where each tile is and which bytes of the file it needs.

Get a quick preview

fif thumbnail holiday.fif preview.jpg        # the largest stored preview, if there is one
fif thumbnail holiday.fif small.jpg 0        # preview number 0
fif decode holiday.fif preview.png --scale 1/4    # fast reduced decode

A reduced decode with 1/2, 1/4 or 1/8 is much faster than a full decode, because the reconstruction itself runs at the smaller size. The result is an approximation: 1/2 is almost indistinguishable from a properly reduced picture, 1/8 is good enough for a preview only.

Look inside a file

fif info holiday.fif

Example output:

file        holiday.fif
format      FIF2 v3.0
dimensions  1000 x 560, 3 channel(s)
size        102.3 KiB  (1.4965 bpp)
source      holiday.jpg, 1749 x 980, reduced by 1.749 before encoding
blocks      4..32, tile 256
chroma      4:2:0, shared
base layer  first 52.9 KiB of 102.3 KiB (51.7%) decodes at DC resolution
tiles       12 (4 x 3), independently decodable
sections    chunks 488 B, thumbnail 16.6 KiB, fic 85.2 KiB, raw 0 B
checksums   fic ok, chunks ok, thumbnail ok
thumbnails  1
  [0] 333 x 186 JPEG, 16.6 KiB
chunks      10
  ENCO  encoder        "libfif v3.2"
  ENCO  source_name    "holiday.jpg"
  ENCO  credits        "libfif v3.2 - (c) 2026 Oskar Behzadpour
                        FIF2 format v3.0 by Rezar Behzad
                        More info: www.FractalImageCompression.com"
  COLR  transfer       "sRGB"
  COLR  primaries      "sRGB"
  META  author         "Ada Lovelace"
  TEXT  copyright      "(c) 2026 Ada Lovelace"
  ENCO  quality        70
  ENCO  effort         5
  DECO  deblock        60

The line base layer states how much of the file is needed for a complete, coarse picture. The line checksums shows whether the file is intact.

Compare two pictures

fif compare original.png decoded.png

Prints three common quality measures: PSNR in decibels, SSIM and MS-SSIM. For all three, higher means closer to the original.

Finding the best quality for the size

No single setting is best for every picture, but five steps find the best one for yours in a few minutes. The numbers below come from a landscape photograph reduced to 1920×1080. Other pictures give other numbers, but the curve has the same shape.

1. Work at the size the picture will be shown

fif encode photo.jpg photo.fif --max-dim 1920

The number of pixels matters more than any quality setting. Half the width and height means a quarter of the pixels and roughly a third of the file size. Use the same --max-dim in all the following steps, so that what you measure is what you will encode.

2. Measure the quality curve

fif bench encodes and decodes in one step, writes no file and reports the size and the quality. Run it for several quality values:

for q in 20 35 50 65 75 85 95; do
  echo "q=$q"; fif bench photo.jpg --max-dim 1920 -q $q -e 2 --no-progress | grep -E 'size|psnr|ms-ssim'
done
-qSizeBits per pixelPSNRMS-SSIM
2037.8 KiB0.1526.81 dB0.871
35102.3 KiB0.4029.28 dB0.940
50177.8 KiB0.7030.76 dB0.967
65304.6 KiB1.2031.57 dB0.981
75379.3 KiB1.5031.76 dB0.984
85469.9 KiB1.8631.86 dB0.986
95551.7 KiB2.1831.91 dB0.987

Look for the knee: the point after which more bytes buy hardly any quality. From 35 to 50, 75 KiB more bring 1.5 dB. From 75 to 95, 172 KiB more bring only 0.15 dB. A useful rule: go higher only while 10% more size still brings at least 0.1 dB. Here the knee lies between 50 and 65.

The quality of a fractal code levels off at the top, so above about 75 you mainly buy bytes. The numbers are a guide; look at the two candidates at the knee before you decide. MS-SSIM follows the eye better than PSNR, and values above 0.98 are hard to tell from the original at normal viewing size.

fif encode photo.jpg a.fif --max-dim 1920 -q 50 && fif decode a.fif a.png
fif encode photo.jpg b.fif --max-dim 1920 -q 65 && fif decode b.fif b.png

3. Choose the effort

The effort changes the time much more than the size. At quality 65:

-eEncode timeSizePSNR
00.04 s304.7 KiB30.88 dB
20.12 s304.6 KiB31.57 dB
5 (default)0.56 s304.6 KiB31.57 dB
70.95 s311.9 KiB31.72 dB
94.35 s319.4 KiB31.81 dB

For photographs -e 2 is almost always right: the same result as the default, five times faster. Higher effort pays off for textures, patterns and aerial pictures; compare -e 2 and -e 7 with fif bench to find out.

4. Choose the colour resolution

--subsamplingSize at quality 65Use for
420 (default)304.6 KiBPhotographs. The eye sees colour less sharply than brightness.
444368.4 KiB (+21%)Screenshots, diagrams, coloured text, sharp colour edges.
400186.2 KiB (−39%)Greyscale pictures, or when colour does not matter.

5. Apply it to one picture or to many

A target tries seven qualities, so use -e 2 to keep it fast. The tool tells you which quality it chose, and warns you if the target cannot be reached:

$ fif encode photo.jpg photo.fif --max-dim 1920 --target-psnr 31 -e 2
photo.fif: 1920x1080 -> 198.6 KiB (0.7847 bpp) in 0.933 s
target      31 dB -> quality 54, 31.00 dB

$ fif encode photo.jpg photo.fif --max-dim 1920 --target-psnr 34 -e 2
photo.fif: 1920x1080 -> 583.6 KiB (2.3055 bpp) in 1.121 s
target      34 dB -> quality 100, 31.92 dB
fif: warning: 34 dB is not reachable for this image; the best result has 31.92 dB

The warning is useful in itself: this picture levels off just below 32 dB, and anything above about 31 dB costs a lot of bytes for little gain.

In short: reduce to the display size with --max-dim; measure with fif bench and pick the knee, usually between 50 and 70; use -e 2 for photographs; use --subsampling 444 for graphics and 400 for greyscale; fix -q for batches, or use --target-bpp for a fixed budget.

Command reference

CommandPurpose
fif encode <in> [<out.fif>]Compress a PNG, JPEG or PNM picture. Without an output name it writes <in> with the extension .fif.
fif decode <in.fif> <out>Reconstruct a picture. The extension of out selects the format: .png, .jpg, .jpeg, .ppm, .pgm, .pnm.
fif info <in.fif> [--tiles]Show header, metadata, preview and attached files; with --tiles also the tile map.
fif thumbnail <in.fif> <out> [N]Write stored preview N, or the largest one without N. To .jpg a JPEG preview is copied unchanged; other formats are converted.
fif compare <a> <b>Measure the difference between two pictures of the same size.
fif bench <in>Encode, decode and report quality and speed in one step. Takes the encode options.
fif versionShow the version.

Encode options

OptionDefaultEffect
-q, --quality N75Quality, 0 to 100.
-e, --effort N5Search effort, 0 to 9. 0–1: fastest. 2: good balance. 3–7: wider search. 8–9: exhaustive.
--target-bpp X–Choose the quality that gives X bits per pixel.
--target-psnr X–Choose the quality that gives X dB.
--subsampling S420Colour resolution. 444: full. 420: half in each direction, as in JPEG. 400: greyscale only.
--chroma MsharedHow colour is coded. shared: follows the brightness structure. from-luma: predicted from brightness, faster decode.
--downscale F–Reduce the input by factor F before encoding.
--width N, --height N–Reduce the input to this width or height, keeping its shape.
--max-dim N–Reduce the input so its longer edge is at most N. Smaller pictures are not changed.
--thumbnail N0 (none)Add a JPEG preview with a longer edge of N pixels, at most a third of the picture's longer edge.
--thumbnail-quality Q85JPEG quality of the preview, 1 to 100.
--meta KEY=VALUE–Store a metadata entry. Repeatable.
--text KEY=VALUE–Store a text entry, e.g. a copyright notice. Repeatable.
--misc KEY=VALUE–Store an entry of type MISC, for anything that is neither metadata nor text. Repeatable.
--chunk TYPE:KEY=VALUE–Store an entry of a type of your own, 1 to 4 characters, e.g. --chunk ACME:render=soft. Other programs skip types they do not know.
--compress-chunksoffStore all entries zlib-compressed. Worth it for long texts.
--remarks ABCD–Set the four-character REMARKS field in the header, free for any use, e.g. to mark processed files.
--no-creditsoffLeave out the credits entry naming the authors and the website (about 140 bytes). Worth it only for very small files.
--no-exifoffIgnore the EXIF data of the input: no camera metadata, and no rotation by its orientation tag.
-t, --threads N0Number of threads. 0 uses half of the processor cores.
--statsoffPrint statistics about the encoded blocks.
--progress, --no-progressautoShow or hide the progress bar.

Further options for experts adjust the block sizes (--min-block, --max-block, powers of two from 2 to 256, --tile), the search (--local-radius, --kd-candidates, --domain-shift) and the planar mode (--planar). fif help encode lists them. The defaults are chosen from measurements; changing them rarely helps.

Decode options

OptionDefaultEffect
--scale S1N (2 to 16): decode N times larger. 1/2, 1/4, 1/8: fast reduced decode. Other 1/N: full decode, then reduced.
--width W, --height H–Output width or height; the other side follows the shape of the picture.
--size WxH–Output box. The picture fills it and is trimmed at the centre if necessary, never stretched.
--deblock Nfrom fileStrength of the filter that smooths block edges, 0 to 100. 0 turns it off, -1 uses the file's recommendation.
--no-smooth-dconPaint flat blocks as single values instead of soft surfaces.
--chroma-upsampling Medge4:2:0 colour: edge follows the brightness edges, bilinear is the reference interpolation.
--ditheroffBreak up banding in smooth gradients when rounding to 8 bits.
--iterations Nfrom file, else 16Maximum number of reconstruction rounds. Overrides a recommendation in the file.
--eps Xfrom file, else 0.5Stop when no pixel changes by more than X between rounds.
--region WxH+X+Y–Decode only this rectangle, e.g. 400x300+600+200. Only the tiles it touches are decoded; the pixels equal those of a full decode.
--tiles LIST–Decode only these tiles, e.g. 0,5-6; the others stay grey.
--max-pixels N268435456Refuse pictures larger than this. A safety limit against damaged or hostile files.
-t, --threads N0Number of threads. 0 uses half of the processor cores.

When something goes wrong

Every message has the same form: one line that says what went wrong, and indented hints that say what to do about it.

fif: error: cannot open 'holiday.png': no such file
  hint: the file is looked for in the current directory; give the full path if it is elsewhere

fif: warning: means the command ran, but perhaps not as you expected. fif: error: means it stopped. All messages go to the error output, so the normal output stays clean for scripts.

Message (shortened)What to do
unknown command 'ecnode'The tool suggests the command you probably meant.
unknown command 'photo.png'The command is missing: fif encode photo.png out.fif.
options must come after the file namesWrite the files first, then the options.
unknown option '--qualty'The tool suggests the closest option, or names the command the option belongs to.
-q 150 is out of range; allowed is 0..100Every value is checked before anything is read; the hint explains the option.
the output … is the input fileChoose another output name. The tool never overwrites the picture it reads.
.bmp is not an image format fif writesUse one of the listed extensions. This is checked before decoding.
the directory 'x' does not existCreate it first. This is checked before encoding, so no work is lost.
'a.png' is named .png but contains a JPEG imageRename the file; the tool picks the reader by the extension.
'a.webp' is a WebP image, which fif cannot readConvert it to PNG first.
this fif cannot read PNGThe tool was built without libpng (or libjpeg). Install it and build again.
is a PNG image, not a FIF2 fileUse fif encode for pictures, fif decode for FIF2 files.
is not a FIF2 fileThe tool shows the first bytes. An interrupted download or a renamed file looks like this.
uses container version 2.0An old development file. Encode the picture again from the original.
is cut off / the header checksum does not matchThe file is incomplete or damaged. Copy or download it again.
the image data does not decodeCheck with fif info; the embedded preview may still be usable.
would have N pixels; the limit is MThe hint gives the exact --max-pixels value, or decode smaller.
--region … reaches past the pictureThe hint gives the largest region that fits.
there is no tile 40The message says how many tiles the file has; fif info … --tiles lists them.
warning: … is not reachable for this imageA --target-bpp or --target-psnr cannot be met. The file is the closest result.

Exit codes

CodeMeaning
0Success. There may be warnings.
1The command failed: a file is missing, cannot be read or written, is not a valid FIF2 file or is damaged.
2The command line is wrong: unknown command or option, missing or invalid value, options before the file names, an unusable output name. Nothing was read or written.

Things to know