Blob Blame History Raw
/**
@mainpage Lensfun: A library for rectifying and simulating photographic lens distortions

@section intro Introduction

The goal of the Lensfun library is to provide a open source database
of photographic lenses and their characteristics. In the past there
was a effort in this direction (see http://www.epaperpress.com/ptlens/),
but then author decided to take the commercial route and the database
froze at the last public stage. This database was used as the basement
on which Lensfun database grew, thanks to PTLens author which gave his
permission for this, while the code was totally rewritten from scratch
(and the database was converted to a totally new, XML-based format).

The Lensfun library not only provides a way to read the database and
search for specific things in it, but also provides a set of algorithms
for correcting images based on detailed knowledge of lens properties and
calibration data. Right now Lensfun is designed to correct distortion,
transversal (also known as lateral) chromatic aberrations, and
vignetting.  Furthermore, it can convert between different types of
lenses, for example from fisheye into rectilinear.

@section contents Contents

<ul>
<li>@ref license
<li>@ref credits
<li>Command line programs
    <ul>
    <li>@ref lensfun-update-data
    <li>@ref lensfun-add-adapter
    </ul>
<li>@ref database
    <ul>
    <li>@ref dbformat
    <li>@ref dbsearch
    <li>@ref filldb
    </ul>
<li>@ref corrections
<li>@ref programming
    <ul>
    <li>@ref basearch
    <li>@ref samplecode
    </ul>
</ul>


@page license Software license

The libraries which are part of this package are licensed under the terms of the
<b>GNU Lesser General Public License, version 3</b>. Libraries are located under
the subdirectory libs/ of the source package. A copy of the license is available
in the file lgpl-3.0.txt which can be found in the source archive. You can read
it here: @ref lgpl or <a href="http://www.gnu.org/licenses/lgpl-3.0.html">on the GNU site</a>.

Applications which are part of this package are licensed under the terms of the
<b>GNU General Public License, version 3</b>. Applications are located under
the apps/ subdirectory of the source package. A copy of the license can be found
in the file gpl-3.0.txt which can be found in the source archive. You can read it
here: @ref gpl or <a href="http://www.gnu.org/licenses/gpl-3.0.html">on the GNU site</a>.

Test programs and tools are put into public domain, unless explicitly specified
otherwise in the header of the source files. Test programs are located under the
tests/ subdirectory, and tools are located in tools/.

The lens database is licensed under the Creative Commons Attribution-Share Alike 3.0
license. The database is located under the data/ subdirectory of the source package.
You can read it here: @ref cc-by-ca or
<a href="http://creativecommons.org/licenses/by-sa/">on the Creative Commons Web site</a>.


@page credits Credits

This project was contrived by <b>Andrew Zabolotny</b>, who developed all
features present in Lensfun.  Later, when Andrew had no time anymore for
regular releases, <b>Sebastian Kraft</b> took over maintenance.  The following
people contributed code:

<ul>
<li><b>Niels Kristian Bech Jensen</b>
<li><b>Pascal de Bruijn</b>
<li><b>Thomas Modes</b>
<li><b>Torsten Bronger</b>
</ul>

The following people directly or indirectly contributed to the birth and growth
of this library:

<ul>
<li><b>Thomas Niemann</b> for the original open-source PTLens software and database.
<li><b>Pablo d'Angelo</b> for the idea of a open-source lens database.
<li><b>The whole PanoTools team:</b> for all math and knowledge I have borrowed
    from PanoTools.
    <ul>
    <li><b>Helmut Dersch</b> – The father of most (all?) open-source panorama creation tools.
    <li><b>Daniel M. German</b>
    <li><b>Kevin Kratzke</b>
    <li><b>Rik Littlefield</b>
    <li><b>Fulvio Senore</b>
    <li><b>Jim Watters</b>
    <li><b>Thomas Rauscher</b>
    <li><b>Pablo d'Angelo</b> (thanks once more :)
    <li><b>Bret McKee</b>
    <li><b>Robert Platt</b>
    </ul>
</ul>

Also I would like to thank all the people sending profiles for the database. 


@page lensfun-update-data Updating Lensfun's database: lensfun‑update-data

New lenses and cameras arrive at Lensfun every week.  So, it is desirable to
update your copy of Lensfun's database to stay up-to-date.  In particular, if
you have sent calibration pictures to Torsten's calibration service, you must
update your local Lensfun database after the calibration in order to be able to
use the new calibrations.

For this purpose, there exists a simple command-line tool called
“update‑lensfun‑data”.  If you call it (it doesn't need parameters), just wait
for a second and the database is updated.  It will report whether an update was
necessary.

If you want the updates to be installed system-wide, the program needs root
privileges.  So call the program with “sudo lensfun‑update‑data” and enter your
root password.  There exists a second version of the programm called
“g‑lensfun‑update‑data”.  It will let you enter the root password – if new data
is available – in a neat window.  This version is especially useful for GUI
programs, which can call it in the background.

If it is sufficient that the updates are available to only your user account,
call “lensfun‑update‑data” without root priviledges.  The updates are then
written to ~/.local/share/lensfun/updates”.

In case there is more than one version of Lensfun on your system (e.g. you
installed a new version, but the original version of your Linux distribution is
still there and used by some programs), “lensfun‑update‑data” tries to detect
this and updates the other database versions, too.

@page lensfun-add-adapter Adding mount adapters: lensfun‑add‑adapter

Lensfun contains information about lens mounts of cameras and available mounts
for lens models.  This way, the calling application can offer the user a list
with lenses that fit on their camera in order to pick one.  Otherwise, you
would see *all* lenses every time.  This can be pretty overwhelming.

But if you bought an adapter for another mount system, you would want to see
lenses of that mount system listed for your camera.  So, you must tell Lensfun
somehow that you own the adapter.  You can do so by calling
lensfun‑add‑adapter.

The easiest way to use it is to call it with no parameters.
lensfun‑add‑adapter will then enter an interactive mode.  First you have to
enter your camera model.  lensfun‑add‑adapter will use that to determine the
destination mount.  In particular, the extended lens lists will show up for
every camera with that mount, not just the one you entered.  Then, you have to
select the mount of the lenses you can now put on your camera, using the
adapter.  That's it.

You can also use lensfun‑add‑adapter to reset your adapter configuration.  Call
it with the ‑‑help paremeter to see all functions.


@page database Lens database

Lensfun uses an XML-based format for its database.
A single XML file can contain entries for mounts, cameras and lenses.
The whole file content is enclosed in a @<lensdatabase@> element.

The database is made of multiple XML files, conventionally split by
manufacturer and camera type. Compact, SLR, and mirrorless cameras/lenses are
split apart for easier maintainance.

The database contains three kinds of objects: @b mounts, @b cameras and @b lenses.

Every @b camera has a mount type assigned (and only one). Similarily, @b lenses
also have a list of mounts assigned, because lenses often come in several variants
with different mounts. Finally, every @b mount has assigned a list of compatible mounts,
so if your camera has mount B which is compatible with mount A, you can list all the
lenses that come either with mounts A or B. However, there are various custom adapters
that can be used to connect lenses to bodies with “incompatible” mounts, so the
application in any case may provide a mean to choose from the whole list in
addition to filtering lenses by mount.

The cameras may be autodetected by using EXIF information from
the source image. However, the Lensfun library is not tied in any way
to EXIF tags, it is in the application's responsibility to read those
tags in any way they like. In fact, you may detect the camera which
was used to take the image in some other way (for example, if you
want to use Lensfun for processing images taken from videocams, which
usually do not use EXIF, or scanned images from film cameras),
you may even ask the user directly to choose the camera from a list.

Same about lenses: you may either autodetect them (which is tricky
even if you have EXIF information, since unlike camera/model the
lens model is highly manufacturer-dependent and is usually hidden
in the Exif.MakerNote tag which is a big binary blob; luckily
the exiv2 library can parse many vendor-specific MakerNote's),
or you may provide some mean for the user to enter the
lens model manually. The Lensfun library will help you a little
here, since it provides a means to match a set of lenses from
the database given a human-entered lens description (e.g.
fuzzy lens search).

<ul>
<li>@ref dbformat
<li>@ref dbsearch
</ul>


@page dbformat Database file format

Here goes a simple lens database file, I hope I don't have to explain
much what is what, as the format is pretty much self-documenting.

@verbatim
<lensdatabase version="1">

    <mount>
        <name>Pentax K</name>
        <compat>M42</compat>
    </mount>

    <lens>
        <maker>Pentax</maker>
        <model>SMC Pentax M 50mm f/1.4</model>
        <mount>Pentax K</mount>
        <cropfactor>1.0</cropfactor>
        <focal value="50" />
        <aperture min="1.4" max="22" />
        <type>rectilinear</type>
        <calibration>
            <!-- WARNING: this calibration data is completely bogus :) -->
            <distortion model="ptlens" focal="50" a="0.012" b="-0.036" c="0" />
        </calibration>
    </lens>

    <camera>
        <maker>Pentax</maker>
        <model>Pentax K10D</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.531</cropfactor>
    </camera>

</lensdatabase>
@endverbatim

The “version” attribute at the @<lensdatabase@> element denotes the format
version of this database file.  It is an integer number and defaults to “0”.
Because it was introduced in Lensfun 0.3, “0” is the format version of all
Lensfun releases before that.  Database format changes mostly are
backwards-compatible, so that a certain Lensfun version supports database
versions up to a certain number.  The most recent lens database is offered for
download in all versions, and the @ref lensfun-update-data
"lensfun-update-data" program fetches the appropriate for you.  See @ref
db_versions for the version history.

Since lenses and cameras may be known with different names in
different languages/countries, the library provides a built-in
mechanism for name translations. You can provide such multi-language
strings for every language you want, and when the library client will
ask for string value, it will get the one in the current locale.

This mechanism is also useful sometimes when you want to use a
name for camera which is different from the value put in EXIF
data. For example:

@verbatim
<maker>Konica Minolta Camera, Inc.</maker>
<maker lang="en">Konica Minolta</maker>
<maker lang="ru">Коника Минольта</maker>
@endverbatim

The value without a “lang” attribute is always used for identification,
but GUI may use the translated string for display. If no language matches,
and an "en" translation is present, it is used. And only if there's no
native translation and there's no "en" translation, the no-language
version is used.

Here is a complete list of elements recognized by the library and the
format of the data within elements.

<ul>
<li>@ref el_mount
<li>@ref el_camera
<li>@ref el_lens
</ul>


@page db_versions Database format versions

<table>
  <tr><th>database<br/>version</th><th>Lensfun<br/>release</th><th>changes</th><th>incompatibilities with<br/>previous versions</th></tr>
  <tr><td>0</td><td>≤ 0.2.8</td><td>—</td><td>—</td></tr>
  <tr><td>1</td><td>0.3</td><td><ul>
        <li>new: @<aspect-ratio@> tag</li>
        <li>new: @<real-focal-length@> tag</li>
        <li>removed: @<field_of_view@> tag </li>
        <li>APS-C crop factors are given with a higher accuracy</li>
    </ul></td><td>—</td></tr>
</table>


@page el_mount Describing camera mounts: \<mount\>

Add \<mount\> element only for mounts for interchangeable lenses.  If the lens
is fixed (mostly a compact camera), a \<mount\> element for it may be declared
locally by the user (see \ref lensfun-add-adapter), but it should not be in the
core database.

Possible embedded elements:
<dl>
<dt>\<name\>string\</name\>
<dd>This gives the name of the mount.  Mount names for fixed-lens cameras – and
only they – must start with a lower case letter.
<dt>\<compat\>string\</compat\>
<dd>Declares that this mount is compatible with another one. Usually this means that
either they are directly compatible (e.g. the Pentax KAF2 mount is compatible with
Pentax K so you can insert K lenses into a KAF2 camera) or there exists mount adapters
which permit to install lenses with such mounts into this mount. Note that the
compatibility is unidirectional, e.g. in the above example it doesn't say that you
can insert Pentax KAF2 lenses into a Pentax K camera; if you need a two-way
compatibility, declare it both ways. Also the “compatibility” is restricted
in the sense that if mount A is compatible with mount B (e.g. you can put B lenses
on an A camera), and mount B is compatible with mount C, this does not neccessarily
mean that mount A is compatible with mount C. Recursion doesn't work here, this is
a design decision. If you need to make mount A compatible with mount C, declare it
so explicitely.

Things are slightly complicated with mirrorless systems because they are
adaptable to virtually any non-mirrorless system.  In order to avoid too many
useless entries in the lens selection lists for mirrorless mounts, only
important (e.g. because only few native lenses yet exist) compatibilities
should be included into Lensfun's official database (e.g. Canon EF on Canon M).
The user can override this easily in their local database files, adding
compatibilities for all mounts they have adaptors for, see @ref
lensfun-add-adapter.</dl>

@page el_camera Declaring cameras: \<camera\>

Possible embedded elements:
<dl>
<dt>\<maker\>string\</maker\>
<dd>Camera maker. This must be specified \b exactly as it is specified in
    camera EXIF data to allow for automatic recognition of the camera.
    Upper and lower case doesn't matter, though.
<dt>\<model\>string\</model\>
<dd>Camera model. This must be specified \b exactly as it is specified in
    camera EXIF data to allow for automatic recognition of the camera.
    Upper and lower case doesn't matter, though.
<dt>\<variant\>string\</variant\>
<dd>Camera variant. Sometimes makers create several cameras without changing
    EXIF information. Unfortunately, camera variant cannot be
    automatically detected so this is a manual choice item.  This field
    can also be used to deal with cameras with more than one aspect
    ratio.  For every available aspect ratio, make a copy of the
    \<camera\> entry, entering the aspect ratio into the \<variant\>
    field (e.g. \<variant\>16:9\</variant\>).  Of course, the crop
    factor may have to be adapted as well.
<dt>\<mount\>string\</mount\>
<dd>Camera mount. There can be only one such element in camera declaration.
    If you want to specify that it is possible to use lenses with a different mount
    on this camera, use the \<compat\> element in mount declaration.
<dt>\<cropfactor\>number\</cropfactor\>
<dd>Camera crop factor. This is the ratio between the standard film frame diagonal
(36x24mm) and camera sensor diagonal.  Be accurate here.  For example, no APS-C
camera really has crop factor 1.5.
</dl>

@page el_lens Declaring lenses: \<lens\>

Possible embedded elements:
<dl>
<dt>\<maker\>string\</maker\>
<dd>Lens maker.
<dt>\<model\>string\</model\>
<dd>Lens model. This must be specified exactly as it is returned by EXIF
    reading libraries to allow for automatic recognition of the lens. However,
    upper and lower case doesn't matter, neither does the ordering of the
    “words” in the lens model name.  A “word” in Lensfun interpretation is a
    sequence of characters of the same type (Lensfun senses three character
    types: digits, punctuation characters and all others). Words made of single
    punctuation characters are ignored. Also, as a special exception, the word
    consisting of a single “f” is ignored too. So, “[IF]” is really split into
    three words – “[”, “IF”, “]”, and then first and last words are discarded.
    Accordingly, “smc PENTAX-DA 12-24mm F4 ED AL [IF]” is split into “smc”,
    “pentax”, “da”, “12”, “24”, “mm”, “4”, “ED”, “AL”, “IF”.   Have a look at
    other lenses of the same manufacturer for the naming conventions.  See
    below for further information about the parsing of the model name field.
<dt>\<type\>string\</type\>
<dd>Lens type. This is one of: “rectilinear", “fisheye”, “panoramic”, 
    “equirectangular”, “orthographic”, “stereographic”, “equisolid”,
    “fisheye_thoby”.  If this field is not given, Lensfun assumes rectilinear.
<dt>\<focal min="number" max="number" value="number" /\>
<dd>Lens focal length in mm. This can be either a single value for a fixed-focal length
    lens, or a minimum and maximum value in the case of a zoom lens.
<dt>\<aperture min="number" max="number" value="number" /\>
<dd>Lens aperture as the f-number. This can be either a single value for a fixed-aperture
    lens (very rare), or the minimal and maximal possible f-stop number for
    this lens (over the whole zoom range for a zoom lens).
<dt>\<mount\>string\</mount\>
<dd>Lens mount. There can be multiple \<mount\> entries if the same lens is manufactured
    with several mounts, or it has a variable mount (e.g. Tamron Adaptall).
<dt>\<cropfactor\>number\</cropfactor\>
<dd>This is the crop factor of the camera with which all shots for computing distortion
    models were made. The library will compute correction factors if you used this lens
    on another camera with a different crop factor. Generally it is advised to use
    a camera with maximal crop factor for this lens, because the models may become
    imprecise for crop factors smaller than the one used for models.
<dt>\<aspect-ratio\>number\</aspect-ratio\>
<dd>This is the aspect ratio of the camera with which all shots for computing
    distortion models were made. It is the ratio of the longer edge to the
    shorter edge. Lensfun needs the aspect ratio internally for correct
    application of the distortion parameters. You may give it is as a real number
    or as a ratio with a colon like “4:3”. It defaults to 1.5 or 3:2.
<dt>\<center x="number" y="number" /\>
<dd>The decentering of the lens, i.e. the offset of its optical axis
    from the center of the viewframe. “x” denotes the offset in
    horizontal direction, “y” in vertical direction. The scale is so
    that the smaller dimension (for very most cameras the height) has
    the value 2. Both offsets default to 0.  It may be particularly helpful for
    shift lenses.
<dt>\<calibration\>calibration data\</calibration\>
<dd>@ref elem_calibration
</dl>

Library recognizes several ways to specify lens parameters directly
in lens model name. The first way to specify lens focal length and
aperture range is “[min focal]-[max focal]mm f/[min aperture]-[max aperture]”
where the “mm” and “f/” are totally optional. For primes the 'max'
values may be omited. Examples:

<ul>
<li>70-210mm f/4-5.6
<li>18-55 3.5-5.6
<li>50 f2
</ul>

Another pattern for lens parameters is
“[min aperture]-[max aperture]/[min focal]-[max focal]”. Examples:

<ul>
<li>2.8-3.5/25-45
<li>4.5/300
</ul>

(Note that “max aperture” refers here to the minimal f-stop number at the
maximal focal length of a zoom lens.  Its value is ignored by Lensfun.  As
explained above, Lensfun only stores the minimal and maximal possible f-stop
number of the lens, not matter at which focal length, e.g. 3.5–32.)

If the focal length in the lens model name is wrong because a converter is
used, one of the words “converter” or “extender” must appear somewhere in the
lens model name.

Moreover, the library finds missing min/max values for focal length and
aperture by looking at the range of these parameters in the @<calibration@>
section.


@page elem_calibration Lens calibration data format

Possible embedded elements:
<dl>
<dt>\<distortion focal="number" model="name" k1="number" k2="number" k3="number" a="number" b="number" c="number" /\>
<dd>Declares the image distortion model for this lens. Distortion is specific for every
    focal length (in mm), so you can declare multiple distortion entries with different focal
    values; the library will interpolate the parameters for intermediate focal
    lengths.  The model name may be "none", "poly3", "poly5", or "ptlens".
    @see lfDistortionModel
<dt>\<tca focal="number" model="name" kr="number" kb="number" /\>
<dd>Declares the Transversal Chromatic Aberrations model for this lens,
    depending on focal length.  The library will interpolate the parameters for
    intermediate focal lengths.  The model name may be "none", "linear",
    or "poly3".
    @see lfTCAModel
<dt>\<vignetting focal="number" aperture="number" distance="number" model="name" k1="number" k2="number" k3="number" /\>
<dd>Declares the vignetting model for this lens at given focal length (in mm), given aperture (as f-number),
    and given distance to subject in focus (in meters). This kind of calibration requires relatively many
    sample points since it depends on three variables.  The library will
    interpolate the parameters for between the sample points if necessary.  The
    model name may be "none" or "pa".
    @see lfVignettingModel
<dt>\<crop focal="number" mode="name" left="number" right="number" top="number" bottom="number" /\>
<dd>Declares the image crop for this lens. Crop can be specific for every
    focal length (in mm), so you can declare multiple crop entries with different focal
    values; the library will interpolate the parameters for intermediate focal
    lengths.  The mode name may be "no_crop", "crop_rectangle", or "crop_circle".
    @see lfCropMode
<dt>\<real-focal-length focal="number" real-focal="number" /\>
<dd>Declares the *real* focal length of the lens in the <a
    href="http://en.wikipedia.org/wiki/Paraxial_approximation">paraxial
    approximation</a>, in contrast to the *nominal* focal length used in all
    "focal" attributes.  Especially for fisheye lenses, both values can differ
    significantly.  Lensfun itself needs the real focal length for lens type
    transformations.  It uses the nominal focal length as a fallback.

    The real focal length can be determined reliably only with a 360° panorama,
    e.g. with Hugin.  However, Hugin's results <a
    href="https://bugs.launchpad.net/hugin/+bug/1307457">need to be
    rectified</a>.  The real focal length must correspond to the distortion
    coefficients.  Typically, they are the result of the very same parameter
    optimisation.
</dl>

@page dbsearch How database files are found and loaded

In a typical application, all XML files are loaded automatically at startup.
If the same object is defined in multiple files, later definitions override
earlier definitions, e.g. user can override system-wide definitions by placing
appropriately formatted XML files in its home directory.

A typical application will initialize the lens database by calling the method
lfDatabase::Load() with no parameters. This method searches for all available
XML files and loads them, ignoring files with errors.

The main place where Lensfun looks for database files usually is
<b>/usr/share/lensfun/version_<i>x</i></b>, where <i>x</i> is the database
format version (@ref db_versions).  However, this is configurable at
compilation time, and for locally compiled Lensfun, it is mostly
<b>/usr/local/share/lensfun/version_<i>x</i></b>.  A special directory is
<b>/var/lib/lensfun-updates/version_<i>x</i></b>: If it exists and contains a
newer database, it is loaded instead of the main place.  On Windows, this is
something like <b>C:\\Documents and
Settings\\\%User\%\\something\\version_<i>x</i></b> but I'm not sure exactly
:-).

“Newer database” means that the file timestamp.txt, which is amongst the XML
files, contains a larger value.  This value is the database timestamp in UNIX
time.

After having read the global database, the user's home directory is
searched. Usually, this is
<b>~/.local/share/lensfun</b>.  The exact path can be found in the variable
lfDatabase::HomeDataDir.  The subdirectory <b>updates/version_<i>x</i></b> may
contain a user-specific DB update.  This represents an alternative to
/var/lib/lensfun-updates/version_<i>x</i> for which no root priviledges are
needed.

<b>~/.local/share/lensfun/version_<i>x</i></b> is also scanned with higher
priority than the one without the version_<i>x</i>, so that the user can set
entries specific for a database version.  This is useful only if you need to
maintain two or more different Lensfun versions on your system.

So sum it up for Linux and other Unix-like platforms, the load order is:
<ol>
  <li>the directory Lensfun's database was installed into (usually
  /usr/share/{local/}lensfun/version_<i>x</i>), @em or
  /var/lib/lensfun-updates/version_<i>x</i>, @em or
  ~/.local/share/lensfun/updates/version_<i>x</i>, whatever is newest</li>
  <li>~/.local/share/lensfun</li>
  <li>~/.local/share/lensfun/version_<i>x</i></li>
</ol>

Another way to load database file is to load them one by one. For this you call
lfDatabase::Load(const char *) for every XML file that must be loaded.


@page corrections How the corrections work

For both the people working on Lensfun and the people working with
Lensfun, it is very important to understand how corrections are applied
to the images.

@section ordering Order of the image operations

The image operations are not commutative.  Thus, it is important to
apply them in the right order.  This is:

<ol>
<li>devignetting
<li>anti-TCA
<li>undistortion
<li>change of projection
<li>scaling
</ol>

@subsection imagecorrections Image corrections

The first three image operations that are applied are the image
corrections.

Their order relative to each other is closely connected with the way the
lens errors are \a measured.  Vignetting is measured on the pristine
image, consequently, it must be corrected before any pixel-warping
operations are applied.  The same is true for TCA measurements.
Distortion is also measured on the pristine image, however, undistortion
is not affected by a previous devigneting or anti-TCA.  This results in
the above enumerated order: First devignetting, then anti-TCA, then
undistortion.

Well, the order of devignetting and anti-TCA is still not clearly
defined by this actually.  But imagine very very hefty TCA.  It distorts
the red and the blue channel relatively to the green one.  This would
affect the vignetting measurement considerably.  However, the other way
round would be much less invasive: A massive vignetting would not change
the TCA measurements much.  Therefore, vignetting must be eliminated
before TCA is eliminated.  Otherwise, devignetting would work on the
wrong image.

By the way, correcting TCA and distortion one directly after the other
makes it possible to do this very efficiently: The pixel coordinates are
transformed by both image operators, and after that, only \a one
interpolation and \a one pixel value lookup are necessary.

@subsection changeofprojection Change of projection

Lensfun can also re-map a fisheye to a rectilinear image.
Mathematically speaking, a perfect lens follows a well-defined
projection (in other places also called “lens type” or “geometry”),
like:

@f[\begin{aligned}
r &= 2f\sin(\theta/2) &\text{equisolid} \\
r &= f\theta &\text{equidistant} \\
r &= 2f\tan(\theta/2) &\text{stereographic} \\
r &= f\sin(\theta) &\text{orthographic} \\
r &= f\tan(\theta) &\text{rectilinear}
\end{aligned}
@f]

Here, @f$\theta@f$ is the angle between the incoming ray of light and
the optical axis, @f$f@f$ is the focal length, and @f$r@f$ is the
distance of the resulting dot on the sensor from the sensor center.

You see, the rectilinear projection is just one of many.  And all of
them have their advantages and disadvantages.  The first four
projections are considered fisheye.

Lensfun can change the projection of the image.  But converting
e.g. from fisheye to rectilinear is not a correction.  A fisheye image
is as perfect as a rectilinear image if it follows the respective
projection formula.  And the image follows the projection formula after
a successful distortion correction.

Therefore, the change of projection is perfomed \a after the image
corrections.

@subsection scaling Scaling

Often it is desirable to scale the resulting image, e.g. to eliminate
black areas at the borders caused by one of the previous image
operations.  This scaling affect the resulting image, therefore, it
comes last in the processing.


@section actualorder How it is really done

The actual order perfomed in the Lensfun-calling program will differ
from the above list.

Why is this?  Understanding this is very important for hacking on
Lensfun as well as for using it in your own programs.

When it comes to pixel coordinate transformations, it is very sensful to
start with the perfect, rectified image (still empty) and distort its
pixel coordinates to the distorted image.  This distorted image is the
source image (the RAW file), and you can do a simple pixel lookup there,
possibly with interpolation.  This way, you find all pixel values for
your rectified image efficiently and accurately.

However, if you perform pixel lookup this way, things happen the other way
round compared to the section before, because you follow the path through the
image manipulations the reverse way:

<ol>
<li>scaling
<li>change of projection
<li>undistortion
<li>anti-TCA
<li>devignetting
</ol>

This reverse order is the reason why the formulae for distortion models in
::lfDistortionModel map the \a undistorted coordinate to the \a distorted
coordinate.  This seems to be wrong at first because we want to undistort after
all.  But given how undistortion is actually done, it makes sense.  The same is
true for ::lfTCAModel.

Note that in the sequence \a scaling → <em>change of projection</em> → \a
undistortion → <em>anti-TCA</em>, the resulting coordinates of the previous
step are the input coordinates for the respective next step.

In reality, devignetting is performed first nevertheless, because it can be
separated from all other operations, by calling
lfModifier::ApplyColorModification.  Then, you do the coordinate-transforming
operations from scaling to anti-TCA.  Lensfun can do this in one function call
with lfModifier::ApplySubpixelGeometryDistortion.  Finally, you do a lookup on
the vignetting-corrected RAW data, using the transformed coordinates.


@page programming Using this library in your programs

One of main goals while developing this library was easiness of use.
Libraries with complex API are usually slow to be accepted by the community,
and often libraries that can do less but have a cleaner API are preferred
over more sophisticated libraries that have a user-unfriendly API.

The library is accessinble both from plain C and C++ programs.
Since the library itself is written in C++ (without use of bloated and bloating
libraries like libstdc++ or boost), the C interface is a (very) thin wrapper
around the C++ classes. The overhead imposed by the wrappers is negligible.

<ul>
<li>@ref basearch
<li>@ref samplecode
</ul>


@page basearch Library architecture

The library provides five basic types of objects to work with:
@b mounts (lfMount), @b cameras (lfCamera), @b lenses (lfLens),
@b databases (lfDatabase) and @b modificators (lfModifier).

The lfMount structure provides the information about a mount. For now the only
information about a mount is its name and the list of compatible mounts.

The lfCamera structure provides information about a particular camera. Camera maker,
model name, mount type and other things are included here.

The lfLens structure provides information about a lens. This structure contains a
lot of information, since it's the heart of the library. Besides other things, this
contains a list of lens calibration data. This information tells the library how to
correct images distorted by a certain lens.

The lfDatabase class provides a interface to the XML database. It allows to load,
save XML files and to search the database for lenses, cameras and mounts.

Finally, the lfModifier class will allow you to modify images. Not only correct
for distortion introduced by lenses but also apply special effects on a image such
as emulating certain lens (e.g. apply a reverse transform), modify the geometry
of a image (e.g. convert a fisheye image to a rectilinear etc).

A typical application will first load the database by creating a lfDatabase object
and invoking the respective lfDatabase::Load() method. After that it can look for a
Lens object using the bits of information from the user or from the source file.
For example, the EXIF data contains the camera maker and camera model. Using this
you can search for the respective camera in the database. In camera record you look
at the mount field, and then do a lens search based on at least mount name. Additionaly,
you may provide the lens manufacturer and/or model name from the EXIF data (which is
not always possible). You get a list of possible lenses. If it's just one lens, you
can assume that it's exactly the lens that was used to take the shot (this is true
for compact cameras which have a fixed mount).

Now if you found more than one matching lens you must provide the user a choice.
User chooses the exact lens that was used to make a shot. After that you can
create a lfModifier object using lens data. Using this object the image
may be modified according to user preferences.

Lensfun transformations -- at least those involving TCA and vignetting
correction -- must be applied to linear RGB data in the sensor's original
colour space. Linear RGB can only be retrieved from RAW files, as JPEG files from 
most cameras already have colour transfromations applied. This is very important. If you do e.g. 
TCA correction on sRGB data, the colour fringes are still visible.  And if you do 
vignetting correction after a gamma has been applied, the corners probably will look too
bright.  So make sure that Lensfun comes early enough in your processing chain.


@page filldb Filling the database

Earlier or later (usually earlier) you'll find out that your camera/lens is not
in the database. Well, that's easy to fix, just add it to the database yourself! ;)

As stated in the section @ref dbsearch, the library will look for xml database files
in various subdirectories. The best place to put your own definitions into is
~/.local/share/lensfun/. This directory is guaranteed to not be overwriten by
library or even OS upgrades, so it's safe to keep them there.

So now you just create a new file under ~/.local/share/lensfun/ -- with any name,
but with the '.xml' extension:

@verbatim
<lensdatabase version="1">
    ... put your definitions here ...
</lensdatabase>
@endverbatim

and it will be automatically found and loaded at library initialization time,

Of course, if you create new camera/lens definitions, I will be grateful if you
send them to me so that I can include them in future releases of the database.

<ul>
<li>@ref addcamera
<li>@ref addlens
</ul>


@page addcamera Adding new cameras to the database

Adding new cameras is very easy. You just have to know its crop factor, and the
EXIF identification strings for this camera; that's all.

If you don't know the crop factor, you can search in google for e.g.
“Nikon D300 sensor size”. Let's suppose you found out that your sensor size
is 23.6 × 15.8mm. Now compute the length of the diagonal using Pythagora's theorem:

@f[
    d = \sqrt{23.6^2 + 15.8^2}\,\mathrm{mm} = 28.4\,\mathrm{mm}
@f]

Now you just divide the magic number 43.27 (the diagonal of a usual 35mm film frame)
by the number you got:

@f[
    \mathrm{cropfactor} = \frac{43.27}{28.4} = 1.523
@f]

Now you must find out the identification string for your camera from EXIF data.
For this you can use the exiv2 script:

@verbatim
    $ exiv2 blah.nef
    ....
    Camera make     : NIKON CORPORATION
    Camera model    : NIKON D300
    ....
@endverbatim

Now you can create a XML entry for your camera:

@verbatim
    <camera>
        <maker>Nikon Corporation</maker>
        <maker lang="en">Nikon</maker>
        <model>Nikon D300</model>
        <model lang="en">D300</model>
        <mount>Nikon F AF</mount>
        <cropfactor>1.523</cropfactor>
    </camera>
@endverbatim

Now add this definition to a XML database file along Lensfun database
search path and your camera will be detected and Lensfun will work properly
with images produced by it.

<ul>
<li>@ref el_camera
</ul>


@page addlens Adding new lenses to the database

There are several levels of detalization you can use when adding a new lens
into the database. First, you could just add the basic identification information
to the database, just to let the database know that such a lens exist. Then,
you might try to find out the mathematical model for the distortion of the lens.
Finally, you might try to find out the vignetting and transversal chromatic
aberration parameters of the lens and get a complete lens description in database.

A simple lens database entry would look something like:

@verbatim
    <lens>
        <maker>Pentax</maker>
        <model>smc Pentax-DA 12-24mm f/4 ED AL IF</model>
        <mount>Pentax KAF2</mount>
    </lens>
@endverbatim

The above code just tells Lensfun that there exist a lens called
“smc Pentax-DA 12-24mm f/4 ED AL IF” manufactured by Pentax and it uses the
Pentax KAF2 mount. This is not very useful except to make user happy that
there's at least one other person in the world owning his lens.

A better lens database entry would contain at least some data about how to
correct lens distortion. This data can be calculated from test shots.
Some special program should be used for this, or you could try to manually
adjust the coefficients until you get decent results.

Computing math model coefficients for distortion, tca, vignetting is a separate
very complex matter. It is out of the scope of this manual to give even a
short brief about this. There's a tutorial on Lensfun site that will teach you
how to create a complete lens entry using just Hugin.

<ul>
<li>@ref el_lens
</ul>


@page samplecode Sample code

Here goes some coding examples, from simple to complex.

<ul><li>\ref example.c</ul>

This is a example written in pure C and it shows how to load the whole
database, then prints it to stdout and finally saves the whole database
to a new XML file.

<ul><li>\ref tfun.cpp</ul>

This is a more complex sample in C++ which shows how to do database lookups.
The results found are saved to a new XML file.

<ul><li>\ref lenstool.cpp</ul>

This is a more or less complex command-line application which can access
most library functionality. It has been used as the main library testbed.

*/

/**
\example example.c
Sample program demonstrating basic usage of C API.
*/

/**
\example tfun.cpp
This example shows how to do basic database lookups.
*/

/**
\example lenstool.cpp
Library testbed. This program can access most library functionality.
*/

/**
\page gpl GNU General Public License, version 3
\verbinclude gpl-3.0.txt
*/

/**
\page lgpl GNU Lesser General Public License, version 3
\verbinclude lgpl-3.0.txt
*/

/**
\page cc-by-ca Creative Commons Attribution-Share Alike 3.0 Unported
\verbinclude cc-by-sa-3.0.txt
*/