2
0
mirror of https://github.com/boostorg/gil.git synced 2026-01-19 04:12:11 +00:00

Update documentation.

This commit is contained in:
Stefan Seefeld
2018-04-02 13:25:32 -04:00
parent 2987d32037
commit 22c82514dc
41 changed files with 6602 additions and 203 deletions

55
.ci/upload_docs.sh Executable file
View File

@@ -0,0 +1,55 @@
#!/bin/bash
set -e # Exit with nonzero exit code if anything fails
SOURCE_BRANCH="master"
TARGET_BRANCH="gh-pages"
# Pull requests and commits to other branches shouldn't try to deploy, just build to verify
if [ "$TRAVIS_PULL_REQUEST" != "false" ] || \
[ "$TRAVIS_BRANCH" != master -a \
"$TRAVIS_BRANCH" != develop -a \
"$TRAVIS_BRANCH" != doc -a \
"$TRAVIS_BRANCH" != ci ]; then
echo "No docs to upload."
exit 0
fi
if [ -z "$GH_TOKEN" ]; then
echo "Error: GH_TOKEN is undefined"
exit 1
fi
# Save some useful information
REPO=`git config remote.origin.url`
SHA=`git rev-parse --verify HEAD`
# doc happens to contain the "html" tree that we want to push
# into the gh-pages branch. So we step into that directory, create a new repo,
# set the remote appropriately, then commit and push.
cd doc
git init
git config user.name "Travis CI"
git config user.email "travis-ci"
# Make sure 'GH_TOKEN' is set (as 'secure' variable) in .travis.yml
git remote add upstream "https://$GH_TOKEN@github.com/boostorg/gil.git"
git fetch upstream
git reset upstream/gh-pages
# Prepare version.
if [ "$TRAVIS_BRANCH" = develop -o "$TRAVIS_BRANCH" = doc ]; then
mkdir -p develop/doc/
cp ../index.html develop/
cp ../doc/index.html develop/doc/
cp -a html develop/doc/
git add -A develop
else
cp ../index.html .
cp ../doc/index.html doc/
git add -A .
fi
# Commit the new version.
git commit -m "Deploy to GitHub Pages: ${SHA}"
# Now that we're all set up, we can push.
git push -q upstream HEAD:gh-pages

View File

@@ -20,3 +20,10 @@ indent_size = 2
indent_style = space
trim_trailing_whitespace = true
insert_final_newline = true
[*.rst]
indent_size = 4
indent_style = space
max_line_length = 80
trim_trailing_whitespace = true
insert_final_newline = true

View File

@@ -13,9 +13,13 @@ branches:
only:
- master
- develop
- doc
- ci
env:
global:
- secure: "UHit2f6Hq2pkHvx8rfrQvFacYiQKVO3vrCbNuDi/VSAIzQjRnqCqE06y4vpXLMsXf62TvBeCBStIuI8g+HP8B+f39oGb/9Om+yIgN/yes47R4sLFKFbRiOS6sfCIefJp7Kx7GSFf81xWxStpIU4QaSsk8Dlt5xyurTWXFSde+lQ="
matrix:
- BOGUS_JOB=true
@@ -103,6 +107,13 @@ matrix:
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 VARIANT=release
- env: DOC=1
addons:
apt:
packages:
- python-sphinx
- doxygen
install:
- cd ..
- git clone -b master --depth 1 https://github.com/boostorg/boost.git boost-root
@@ -111,17 +122,35 @@ install:
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/gil
- cp -r $TRAVIS_BUILD_DIR/.ci libs/gil
- python tools/boostdep/depinst/depinst.py gil
- ./bootstrap.sh
- ./b2 headers
script:
- |-
if [ "$DOC" ]; then
echo "using doxygen ;" > ~/user-config.jam
./b2 libs/gil/doc
else
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
- ./b2 libs/gil/test toolset=$TOOLSET variant=$VARIANT
- ./b2 libs/gil/toolbox/test toolset=$TOOLSET variant=$VARIANT
- ./b2 libs/gil/numeric/test toolset=$TOOLSET variant=$VARIANT
- ./b2 libs/gil/io/test//simple toolset=$TOOLSET variant=$VARIANT
./b2 libs/gil/test toolset=$TOOLSET variant=$VARIANT
./b2 libs/gil/toolbox/test toolset=$TOOLSET variant=$VARIANT
./b2 libs/gil/numeric/test toolset=$TOOLSET variant=$VARIANT
./b2 libs/gil/io/test//simple toolset=$TOOLSET variant=$VARIANT
fi
after_success:
# Upload docs only when building upstream.
- |
if [ "$DOC" -a \
"$TRAVIS_REPO_SLUG" = "boostorg/gil" -a \
"$TRAVIS_PULL_REQUEST" = "false" ]; then
export GH_TOKEN
cd libs/gil
.ci/upload_docs.sh
fi
notifications:
email:

64
doc/Jamfile Normal file
View File

@@ -0,0 +1,64 @@
# Copyright (c) 2018 Stefan Seefeld
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import doxygen ;
import os ;
import path ;
.doxygen = [ doxygen.name ] ;
.doxygen ?= doxygen ;
#doxygen/gil_standalone/gil_boost.doxygen
make reference : doxyfile
: @make_doxygen
: <location>html
<dependency>$(headers)
;
rule make_doxygen ( targets * : sources * : properties * )
{
LIB_DIR on $(targets) =
[ path.native [ path.parent [ path.root
[ on $(sources[1]) return $(SEARCH) ] [ path.pwd ] ] ] ] ;
}
if [ os.name ] = NT
{
actions make_doxygen
{
SET LIB_DIR=$(LIB_DIR)
chdir "$(>:D)" && "$(.doxygen)" $(>:D=)
}
}
else
{
actions make_doxygen
{
export LIB_DIR=$(LIB_DIR)
cd $(>:D) && "$(.doxygen)" $(>:D=)
}
}
make html
: index.rst
: @sphinx-build
: <location>.
<dependency>reference
;
if [ os.name ] = NT
{
actions sphinx-build { chdir "$(>:D)" && make clean && make html}
}
else
{
actions sphinx-build { make -C "$(>:D)" clean html}
}
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : html ;
explicit boostrelease ;

133
doc/Makefile Normal file
View File

@@ -0,0 +1,133 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
HTMLDIR = html
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
all: html
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(HTMLDIR)
@echo
@echo "Build finished. The HTML pages are in $(HTMLDIR)."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/BoostNumPy.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/BoostNumPy.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/BoostNumPy"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/BoostNumPy"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
make -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

BIN
doc/_static/boost-gil.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

191
doc/_static/boost-gil.svg vendored Normal file
View File

@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
style="overflow:visible"
version="1.1"
id="Layer_1"
width="820"
height="180"
viewBox="0 0 820 180"
overflow="visible"
enable-background="new 0 0 517 500"
xml:space="preserve"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="gil-font-denmark.svg"
inkscape:export-filename="D:\dev\boost\boost\libs\gil\doc\_static\boost-gil-font-denmark.png"
inkscape:export-xdpi="44.681793"
inkscape:export-ydpi="44.681793"><metadata
id="metadata3335"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs3333"><linearGradient
gradientTransform="matrix(1.9133544,0,0,1.9133544,-21.124757,-365.67174)"
id="XMLID_8_"
gradientUnits="userSpaceOnUse"
x1="39.3022"
y1="222.79201"
x2="78.625504"
y2="222.79201"><stop
offset="0.0056"
style="stop-color:#B1D2EC"
id="stop6390" /><stop
offset="1"
style="stop-color:#C8E6F6"
id="stop6392" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#XMLID_5_"
id="radialGradient5450"
gradientUnits="userSpaceOnUse"
cx="63.75"
cy="246.375"
r="58.375" /><linearGradient
y2="222.79201"
x2="78.625504"
y1="222.79201"
x1="39.3022"
gradientUnits="userSpaceOnUse"
id="XMLID_8_-1"
gradientTransform="matrix(1.9133544,0,0,1.9133544,-21.124757,-365.67174)"><stop
id="stop3323"
style="stop-color:#B1D2EC"
offset="0.0056" /><stop
id="stop3325"
style="stop-color:#C8E6F6"
offset="1" /></linearGradient><linearGradient
y2="242.22659"
x2="110.314"
y1="242.22659"
x1="66.6689"
gradientUnits="userSpaceOnUse"
id="XMLID_7_"><stop
id="stop3313"
style="stop-color:#B1D2EC"
offset="0.0056" /><stop
id="stop3315"
style="stop-color:#C8E6F6"
offset="1" /></linearGradient><linearGradient
y2="262.375"
x2="72.826698"
y1="262.375"
x1="28.6553"
gradientUnits="userSpaceOnUse"
id="XMLID_6_"><stop
id="stop3303"
style="stop-color:#8AACD6"
offset="0" /><stop
id="stop3305"
style="stop-color:#A7C7E6"
offset="1" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1027"
id="namedview3331"
showgrid="true"
inkscape:zoom="1.2162237"
inkscape:cx="366.31882"
inkscape:cy="213.48907"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="true"><inkscape:grid
type="xygrid"
id="grid335" /></sodipodi:namedview><g
id="shadow"
transform="matrix(1.5826403,0,0,1.5826403,-12.506692,-304.30966)"><radialGradient
id="XMLID_5_"
cx="63.75"
cy="246.375"
r="58.375"
gradientUnits="userSpaceOnUse"><stop
offset="0"
style="stop-color:#000000"
id="stop3283" /><stop
offset="0.0641"
style="stop-color:#191919"
id="stop3285" /><stop
offset="0.2539"
style="stop-color:#5E5E5E"
id="stop3287" /><stop
offset="0.4336"
style="stop-color:#979797"
id="stop3289" /><stop
offset="0.5979"
style="stop-color:#C4C4C4"
id="stop3291" /><stop
offset="0.7439"
style="stop-color:#E4E4E4"
id="stop3293" /><stop
offset="0.866"
style="stop-color:#F8F8F8"
id="stop3295" /><stop
offset="0.9494"
style="stop-color:#FFFFFF"
id="stop3297" /></radialGradient><circle
cx="63.75"
cy="246.375"
r="58.375"
id="circle3299"
style="opacity:0.3;fill:url(#radialGradient5450)" /></g><path
style="opacity:0.6;fill:#ff4b4b;fill-opacity:1;stroke-width:1.9133544"
inkscape:connector-curvature="0"
id="path3327"
d="m 70.946681,23.667177 -20.872783,36.439834 13.225105,23.805956 31.476593,0.08993 c 0,0 21.245884,-36.024636 22.302064,-37.813623 1.46562,0 8.23507,0 8.23507,0 L 112.4856,23.667177 Z" /><path
style="fill:#ffffff;stroke-width:1.9133544"
inkscape:connector-curvature="0"
id="path3329"
d="m 113.59918,21.753822 h -2.22523 -39.319437 -2.217578 l -1.102092,1.924835 -19.784084,34.541787 -1.073392,1.873174 1.048518,1.886567 12.15554,21.881121 1.088699,1.963102 2.244365,0.0057 29.259015,0.08419 2.192704,0.0057 1.115482,-1.88848 21.1904,-35.928969 h 3.84967 6.58386 l -3.25845,-5.72093 -10.64781,-18.695386 z M 52.270428,60.122318 72.054513,25.580531 h 39.319437 l 10.64781,18.695386 v 0 0 h -6.03663 l -22.300146,37.81171 -29.259015,-0.08419 z" /><polygon
style="opacity:0.6;fill:#008000"
id="polygon3307"
points="39.724,243.375 28.655,262.286 39.721,281.375 61.665,281.375 72.827,262.465 61.668,243.375 "
transform="matrix(1.9024077,0,0,1.9024077,-21.299337,-394.60399)" /><path
style="fill:#ffffff;stroke-width:1.90240765"
inkscape:connector-curvature="0"
id="path3309"
d="M 97.11032,66.492078 H 94.926359 55.361986 53.179924 l -1.101494,1.883384 -19.946744,34.079758 -1.120518,1.91192 1.112908,1.91763 19.946745,34.40694 1.099591,1.8967 h 2.191574 39.564373 2.172551 l 1.1034,-1.87006 20.11225,-34.07783 1.13574,-1.92524 -1.12623,-1.92904 L 98.21182,68.377364 Z M 35.415241,104.37665 55.361986,70.296894 h 39.564373 l 20.112251,34.408876 v 0 0 L 94.926359,138.7836 H 55.361986 Z" /><polygon
style="opacity:0.6;fill:#3c8fd0;fill-opacity:1"
id="polygon3317"
points="77.164,223.15 66.669,241.262 78.307,261.304 99.112,261.21 110.314,242.047 99.106,223.15 "
transform="matrix(1.9115339,0,0,1.9115339,-49.169778,-377.37337)" /><path
style="fill:#ffffff;stroke-width:1.91153395"
inkscape:connector-curvature="0"
id="path3319"
d="m 141.36236,47.273888 h -2.17723 -39.75417 -2.204 l -1.10487,1.905799 -18.950946,32.710168 -1.110602,1.91918 1.112513,1.917269 21.133915,36.393726 1.11252,1.91344 2.21164,-0.01 37.5712,-0.16821 2.18297,-0.01 1.10105,-1.88477 20.29475,-34.717308 1.13545,-1.942119 -1.14883,-1.936384 -20.29476,-34.218368 z M 80.480009,83.807124 99.43096,51.096956 h 39.75417 l 20.29475,34.218368 v 0 0 l -20.29475,34.717306 -37.5712,0.16822 z" /><text
x="193.24495"
y="108.73149"
transform="skewX(-9.9973689)"
id="text3467-9-13"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:117.33333333px;line-height:0%;font-family:Denmark;-inkscape-font-specification:'Denmark, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr;text-anchor:start;fill:#00507f;fill-opacity:1;stroke-width:1.25;"><tspan
sodipodi:role="line"
id="tspan57"
x="193.24495"
y="108.73149">Boost.GIL </tspan></text>
<text
x="203.43552"
y="148.13144"
transform="skewX(-9.9973689)"
id="text3467-9-13-3"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:0%;font-family:Denmark;-inkscape-font-specification:'Denmark, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;overflow:visible;fill:#00507f;fill-opacity:1;stroke-width:1.25"><tspan
sodipodi:role="line"
id="tspan77"
x="203.43552"
y="148.13144">Generic Image Library</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 8.5 KiB

716
doc/_static/boost.css vendored Normal file
View File

@@ -0,0 +1,716 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
http://spirit.sourceforge.net/
Copyright 2013 Niall Douglas additions for colors and alignment.
Copyright 2013 Paul A. Bristow additions for more colors and alignments.
Distributed under the Boost Software License, Version 1.0. (See accompany-
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
/*=============================================================================
Body defaults
=============================================================================*/
body
{
margin: 1em;
font-family: sans-serif;
}
/*=============================================================================
Paragraphs
=============================================================================*/
p
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Program listings
=============================================================================*/
/* Code on paragraphs */
p tt.computeroutput
{
font-size: 9pt;
}
pre.synopsis
{
font-size: 9pt;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.programlisting,
.screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Program listings in tables don't get borders */
td .programlisting,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}
/*=============================================================================
Headings
=============================================================================*/
h1, h2, h3, h4, h5, h6
{
text-align: left;
margin: 1em 0em 0.5em 0em;
font-weight: bold;
}
h1 { font-size: 140%; }
h2 { font-weight: bold; font-size: 140%; }
h3 { font-weight: bold; font-size: 130%; }
h4 { font-weight: bold; font-size: 120%; }
h5 { font-weight: normal; font-style: italic; font-size: 110%; }
h6 { font-weight: normal; font-style: italic; font-size: 100%; }
/* Top page titles */
title,
h1.title,
h2.title
h3.title,
h4.title,
h5.title,
h6.title,
.refentrytitle
{
font-weight: bold;
margin-bottom: 1pc;
}
h1.title { font-size: 140% }
h2.title { font-size: 140% }
h3.title { font-size: 130% }
h4.title { font-size: 120% }
h5.title { font-size: 110% }
h6.title { font-size: 100% }
.section h1
{
margin: 0em 0em 0.5em 0em;
font-size: 140%;
}
.section h2 { font-size: 140% }
.section h3 { font-size: 130% }
.section h4 { font-size: 120% }
.section h5 { font-size: 110% }
.section h6 { font-size: 100% }
/* Code on titles */
h1 tt.computeroutput { font-size: 140% }
h2 tt.computeroutput { font-size: 140% }
h3 tt.computeroutput { font-size: 130% }
h4 tt.computeroutput { font-size: 130% }
h5 tt.computeroutput { font-size: 130% }
h6 tt.computeroutput { font-size: 130% }
/*=============================================================================
Author
=============================================================================*/
h3.author
{
font-size: 100%
}
/*=============================================================================
Lists
=============================================================================*/
li
{
font-size: 10pt;
line-height: 1.3;
}
/* Unordered lists */
ul
{
text-align: left;
}
/* Ordered lists */
ol
{
text-align: left;
}
/*=============================================================================
Links
=============================================================================*/
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/*=============================================================================
Spirit style navigation
=============================================================================*/
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/*=============================================================================
Copyright footer
=============================================================================*/
.copyright-footer
{
text-align: right;
font-size: 70%;
}
.copyright-footer p
{
text-align: right;
font-size: 80%;
}
/*=============================================================================
Table of contents
=============================================================================*/
div.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 80%;
line-height: 1.15;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/* Code on toc */
.toc .computeroutput { font-size: 120% }
/* No margin on nested menus */
.toc dl dl { margin: 0; }
/*=============================================================================
Tables
=============================================================================*/
.table-title,
div.table p.title
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
}
.informaltable table,
.table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table,
div.table table
{
padding: 4px;
}
/* Table Cells */
div.informaltable table tr td,
div.table table tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
}
div.informaltable table tr th,
div.table table tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
}
table.simplelist
{
width: auto !important;
margin: 0em !important;
padding: 0em !important;
border: none !important;
}
table.simplelist td
{
margin: 0em !important;
padding: 0em !important;
text-align: left !important;
font-size: 9pt !important;
border: none !important;
}
/*=============================================================================
Suppress margins in tables
=============================================================================*/
table th > *:first-child,
table td > *:first-child
{
margin-top: 0;
}
table th > *:last-child,
table td > *:last-child
{
margin-bottom: 0;
}
/*=============================================================================
Blurbs
=============================================================================*/
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
font-size: 9pt; /* A little bit smaller than the main text */
line-height: 1.2;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
p.blurb img
{
padding: 1pt;
}
/*=============================================================================
Variable Lists
=============================================================================*/
div.variablelist
{
margin: 1em 0;
}
/* Make the terms in definition lists bold */
div.variablelist dl dt,
span.term
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist table tbody tr td
{
text-align: left;
vertical-align: top;
padding: 0em 2em 0em 0em;
font-size: 10pt;
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
div.variablelist dl dt
{
margin-bottom: 0.2em;
}
div.variablelist dl dd
{
margin: 0em 0em 0.5em 2em;
font-size: 10pt;
}
div.variablelist table tbody tr td p,
div.variablelist dl dd p
{
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
/*=============================================================================
Misc
=============================================================================*/
/* Title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
span.underline
{
text-decoration: underline;
}
span.strikethrough
{
text-decoration: line-through;
}
/* Copyright, Legal Notice */
div div.legalnotice p
{
text-align: left
}
/*=============================================================================
Colors
=============================================================================*/
@media screen
{
body {
background-color: #FFFFFF;
color: #000000;
}
/* Syntax Highlighting */
.keyword { color: #0000AA; }
.identifier { color: #000000; }
.special { color: #707070; }
.preprocessor { color: #402080; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.white_bkd { background-color: #FFFFFF; }
.dk_grey_bkd { background-color: #999999; }
/* Links */
a, a .keyword, a .identifier, a .special, a .preprocessor
a .char, a .comment, a .string, a .number
{
color: #005a9c;
}
a:visited, a:visited .keyword, a:visited .identifier,
a:visited .special, a:visited .preprocessor a:visited .char,
a:visited .comment, a:visited .string, a:visited .number
{
color: #9c5a9c;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
{
text-decoration: none; /* no underline */
color: #000000;
}
/* Copyright, Legal Notice */
.copyright
{
color: #666666;
font-size: small;
}
div div.legalnotice p
{
color: #666666;
}
/* Program listing */
pre.synopsis
{
border: 1px solid #DCDCDC;
}
.programlisting,
.screen
{
border: 1px solid #DCDCDC;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Blurbs */
div.note,
div.tip,
div.important,
div.caution,
div.warning,
p.blurb
{
border: 1px solid #DCDCDC;
}
/* Table of contents */
div.toc
{
border: 1px solid #DCDCDC;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
}
div.informaltable table tr th,
div.table table tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
.copyright-footer
{
color: #8F8F8F;
}
/* Misc */
span.highlight
{
color: #00A000;
}
}
@media print
{
/* Links */
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Program listing */
pre.synopsis
{
border: 1px solid gray;
}
.programlisting,
.screen
{
border: 1px solid gray;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Table of contents */
div.toc
{
border: 1px solid gray;
}
.informaltable table,
.table table
{
border: 1px solid gray;
border-collapse: collapse;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid gray;
}
div.informaltable table tr th,
div.table table tr th
{
border: 1px solid gray;
}
table.simplelist tr td
{
border: none !important;
}
/* Misc */
span.highlight
{
font-weight: bold;
}
}
/*=============================================================================
Images
=============================================================================*/
span.inlinemediaobject img
{
vertical-align: middle;
}
/*==============================================================================
Super and Subscript: style so that line spacing isn't effected, see
http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341
==============================================================================*/
sup,
sub {
height: 0;
line-height: 1;
vertical-align: baseline;
position: relative;
}
/* For internet explorer: */
* html sup,
* html sub {
vertical-align: bottom;
}
sup {
bottom: 1ex;
}
sub {
top: .5ex;
}
/*==============================================================================
Indexes: pretty much the same as the TOC.
==============================================================================*/
.index
{
font-size: 80%;
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
}
.index ul
{
padding-left: 3em;
}
.index p
{
padding: 2px;
margin: 2px;
}
.index-entry-level-0
{
font-weight: bold;
}
.index em
{
font-weight: bold;
}
/*==============================================================================
Alignment and coloring use 'role' feature, available from Quickbook 1.6 up.
Added from Niall Douglas for role color and alignment.
http://article.gmane.org/gmane.comp.lib.boost.devel/243318
*/
/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */
span.aligncenter
{
display: inline-block; width: 100%; text-align: center;
}
span.alignright
{
display: inline-block; width: 100%; text-align: right;
}
/* alignleft is the default. */
span.alignleft
{
display: inline-block; width: 100%; text-align: left;
}
/* alignjustify stretches the word spacing so that each line has equal width
within a chosen fraction of page width (here arbitrarily 20%).
*Not* useful inside table items as the column width remains the total string width.
Nor very useful, except to temporarily restrict the width.
*/
span.alignjustify
{
display: inline-block; width: 20%; text-align: justify;
}
/* Text colors.
Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords.
Quickbook Usage: [role red Some red text]
*/
span.red { inline-block; color: red; }
span.green { color: green; }
span.lime { color: #00FF00; }
span.blue { color: blue; }
span.navy { color: navy; }
span.yellow { color: yellow; }
span.magenta { color: magenta; }
span.indigo { color: #4B0082; }
span.cyan { color: cyan; }
span.purple { color: purple; }
span.gold { color: gold; }
span.silver { color: silver; } /* lighter gray */
span.gray { color: #808080; } /* light gray */

BIN
doc/_static/boost.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

5
doc/_static/doxygen.css vendored Normal file
View File

@@ -0,0 +1,5 @@
.headertitle
{
color: #00507f;
font-size: 200%;
}

BIN
doc/_static/gil.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

186
doc/_static/gil.svg vendored Normal file
View File

@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
style="overflow:visible"
version="1.1"
id="Layer_1"
width="775.63513"
height="184.77325"
viewBox="0 0 775.63516 184.77325"
overflow="visible"
enable-background="new 0 0 517 500"
xml:space="preserve"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="logo.svg"><metadata
id="metadata3335"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs3333"><linearGradient
gradientTransform="matrix(1.9133544,0,0,1.9133544,-21.124757,-365.67174)"
id="XMLID_8_"
gradientUnits="userSpaceOnUse"
x1="39.3022"
y1="222.79201"
x2="78.625504"
y2="222.79201"><stop
offset="0.0056"
style="stop-color:#B1D2EC"
id="stop6390" /><stop
offset="1"
style="stop-color:#C8E6F6"
id="stop6392" /></linearGradient><radialGradient
inkscape:collect="always"
xlink:href="#XMLID_5_"
id="radialGradient5450"
gradientUnits="userSpaceOnUse"
cx="63.75"
cy="246.375"
r="58.375" /><linearGradient
y2="222.79201"
x2="78.625504"
y1="222.79201"
x1="39.3022"
gradientUnits="userSpaceOnUse"
id="XMLID_8_-1"
gradientTransform="matrix(1.9133544,0,0,1.9133544,-21.124757,-365.67174)"><stop
id="stop3323"
style="stop-color:#B1D2EC"
offset="0.0056" /><stop
id="stop3325"
style="stop-color:#C8E6F6"
offset="1" /></linearGradient><linearGradient
y2="242.22659"
x2="110.314"
y1="242.22659"
x1="66.6689"
gradientUnits="userSpaceOnUse"
id="XMLID_7_"><stop
id="stop3313"
style="stop-color:#B1D2EC"
offset="0.0056" /><stop
id="stop3315"
style="stop-color:#C8E6F6"
offset="1" /></linearGradient><linearGradient
y2="262.375"
x2="72.826698"
y1="262.375"
x1="28.6553"
gradientUnits="userSpaceOnUse"
id="XMLID_6_"><stop
id="stop3303"
style="stop-color:#8AACD6"
offset="0" /><stop
id="stop3305"
style="stop-color:#A7C7E6"
offset="1" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1588"
inkscape:window-height="1157"
id="namedview3331"
showgrid="false"
inkscape:zoom="2.4324473"
inkscape:cx="124.58112"
inkscape:cy="46.589017"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" /><g
id="shadow"
transform="matrix(1.5826403,0,0,1.5826403,-8.5066916,-297.53638)"><radialGradient
id="XMLID_5_"
cx="63.75"
cy="246.375"
r="58.375"
gradientUnits="userSpaceOnUse"><stop
offset="0"
style="stop-color:#000000"
id="stop3283" /><stop
offset="0.0641"
style="stop-color:#191919"
id="stop3285" /><stop
offset="0.2539"
style="stop-color:#5E5E5E"
id="stop3287" /><stop
offset="0.4336"
style="stop-color:#979797"
id="stop3289" /><stop
offset="0.5979"
style="stop-color:#C4C4C4"
id="stop3291" /><stop
offset="0.7439"
style="stop-color:#E4E4E4"
id="stop3293" /><stop
offset="0.866"
style="stop-color:#F8F8F8"
id="stop3295" /><stop
offset="0.9494"
style="stop-color:#FFFFFF"
id="stop3297" /></radialGradient><circle
cx="63.75"
cy="246.375"
r="58.375"
id="circle3299"
style="opacity:0.3;fill:url(#radialGradient5450)" /></g><path
style="fill:#ff4b4b;stroke-width:1.9133544;opacity:0.6;fill-opacity:1"
inkscape:connector-curvature="0"
id="path3327"
d="m 74.946681,30.440455 -20.872783,36.439834 13.225105,23.805956 31.476593,0.08993 c 0,0 21.245884,-36.024636 22.302064,-37.813623 1.46562,0 8.23507,0 8.23507,0 L 116.4856,30.440455 Z" /><path
style="fill:#ffffff;stroke-width:1.9133544"
inkscape:connector-curvature="0"
id="path3329"
d="m 117.59918,28.5271 h -2.22523 -39.319437 -2.217578 l -1.102092,1.924835 -19.784084,34.541787 -1.073392,1.873174 1.048518,1.886567 12.15554,21.881121 1.088699,1.963102 2.244365,0.0057 29.259015,0.08419 2.192704,0.0057 1.115482,-1.88848 21.1904,-35.928969 h 3.84967 6.58386 l -3.25845,-5.72093 -10.64781,-18.695386 z M 56.270428,66.895596 76.054513,32.353809 h 39.319437 l 10.64781,18.695386 v 0 0 h -6.03663 l -22.300146,37.81171 -29.259015,-0.08419 z" /><text
xml:space="preserve"
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.02042961px;line-height:0%;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L, Bold Italic';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#00507f;fill-opacity:1;stroke:none;stroke-width:0.91836917px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="197.86095"
y="125.53873"
id="text5174"><tspan
sodipodi:role="line"
id="tspan5176"
x="197.86095"
y="125.53873"
style="font-size:121.07550049px;line-height:1;stroke-width:0.91836917px">Boost.GIL</tspan></text>
<text
xml:space="preserve"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:25px;font-family:'Nimbus Sans L';-inkscape-font-specification:'Nimbus Sans L, Italic';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#00507f;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="290.19308"
y="168.3289"
id="text879"><tspan
sodipodi:role="line"
id="tspan877"
x="290.19308"
y="168.3289">Generic Image Library</tspan></text>
<polygon
style="fill:#008000;opacity:0.6"
id="polygon3307"
points="61.665,281.375 72.827,262.465 61.668,243.375 39.724,243.375 28.655,262.286 39.721,281.375 "
transform="matrix(1.9024077,0,0,1.9024077,-17.299337,-387.83071)" /><path
style="fill:#ffffff;stroke-width:1.90240765"
inkscape:connector-curvature="0"
id="path3309"
d="M 101.11032,73.265356 H 98.926359 59.361986 57.179924 l -1.101494,1.883384 -19.946744,34.07973 -1.120518,1.91192 1.112908,1.91763 19.946745,34.40694 1.099591,1.8967 h 2.191574 39.564373 2.172551 l 1.1034,-1.87006 20.11225,-34.07783 1.13574,-1.92524 -1.12623,-1.92904 -20.11225,-34.408848 z M 39.415241,111.1499 59.361986,77.070172 h 39.564373 l 20.112251,34.408848 v 0 0 L 98.926359,145.55685 H 59.361986 Z" /><polygon
style="fill:#3c8fd0;opacity:0.6;fill-opacity:1"
id="polygon3317"
points="99.112,261.21 110.314,242.047 99.106,223.15 77.164,223.15 66.669,241.262 78.307,261.304 "
transform="matrix(1.9115339,0,0,1.9115339,-45.169778,-370.60009)" /><path
style="fill:#ffffff;stroke-width:1.91153395"
inkscape:connector-curvature="0"
id="path3319"
d="m 145.36236,54.047166 h -2.17723 -39.75417 -2.204 l -1.10487,1.905799 -18.950946,32.710168 -1.110602,1.91918 1.112513,1.917269 21.133915,36.393698 1.11252,1.91344 2.21164,-0.01 37.5712,-0.16821 2.18297,-0.01 1.10105,-1.88477 20.29475,-34.71728 1.13545,-1.942119 -1.14883,-1.936384 -20.29476,-34.218368 z M 84.480009,90.580402 103.43096,57.870234 h 39.75417 l 20.29475,34.218368 v 0 0 l -20.29475,34.717278 -37.5712,0.16822 z" /></svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
doc/_static/home.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

BIN
doc/_static/logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
doc/_static/next.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

BIN
doc/_static/prev.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

40
doc/_static/style.css vendored Normal file
View File

@@ -0,0 +1,40 @@
@import url(boost.css);
.header h1 a
{
color: #00507f;
font-size: 200%;
font-style: italic;
}
.header h3 { margin: 1px;}
#contents
{
/* border-bottom: solid thin black;*/
}
.highlight
{
border: 1px solid #dcdcdc;
background-color: inherit;
padding: 0 1em;
margin: 0 5em;
}
#searchbox
{
float: right;
width: auto;
margin: 0 2em;
}
.admonition-title { font-weight: bold;}
.toctree-wrapper,
.contents
{
display: inline-block;
border: 1px solid #dcdcdc;
padding: 1em;
margin: 0 2em;
}
.toctree-wrapper .caption,
.toctree-wrapper .topic-title { font-weight: bold;}

BIN
doc/_static/up.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

119
doc/_templates/layout.html vendored Normal file
View File

@@ -0,0 +1,119 @@
{%- macro navbar() %}
<div class="navbar" style="text-align:right;">
{#%- if parents|count > 0 %#}
{#{ parents[1].title }#}
{%- if prev %}
<a class="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"><img src="{{ pathto('_static/prev.png', 1) }}" alt="prev"/></a>
{%- endif %}
{%- if parents %}
<a class="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"><img src="{{ pathto('_static/up.png', 1) }}" alt="up"/></a>
{%- endif %}
{%- if next %}
<a class="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"><img src="{{ pathto('_static/next.png', 1) }}" alt="next"/></a>
{%- endif %}
{#%- endif %#}
</div>
{%- endmacro %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{{ metatags }}
{%- if builder != 'htmlhelp' %}
{%- set titlesuffix = docstitle|e %}
{%- set titlesuffix = " - " + titlesuffix %}
{%- endif %}
<title>{{ title|striptags }}{{ titlesuffix }}</title>
{%- if builder == 'web' %}
<link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
{%- for link, type, title in page_links %}
<link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
{%- endfor %}
{%- else %}
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/style.css', 1) }}" type="text/css" />
{%- endif %}
{%- if builder != 'htmlhelp' %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ pathto("", 1) }}',
VERSION: '{{ release|e }}',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '{{ file_suffix }}'
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
{%- if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
<body>
<div class="header">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="{{ pathto('index') }}"><img
alt="C++ Boost" src="{{ pathto('_static/' + logo, 1) }}" border="0"></a></h3>
</td>
<td >
<h1 align="center"><a href="{{ pathto('index') }}"></a></h1>
</td>
<td>
{%- if pagename != "search" %}
<div id="searchbox" style="display: none">
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="{{ _('Search') }}" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}
</td>
</tr>
</table>
</div>
<hr/>
<div class="content">
{%- block top_navbar %}{{ navbar() }}{% endblock %}
{% block body %} {% endblock %}
{%- block bottom_navbar %}{{ navbar() }}{% endblock %}
</div>
</body>
</html>

218
doc/conf.py Normal file
View File

@@ -0,0 +1,218 @@
# -*- coding: utf-8 -*-
#
# Boost.GIL documentation build configuration file.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Boost.GIL'
copyright = u'2018, Stefan Seefeld'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'default'
highlight_language = 'c++'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = '_static/gil.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'BoostGILdoc'
html_add_permalinks = False
# -- Options for LaTeX output --------------------------------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'BoostGIL.tex', u'Boost.GIL Documentation',
u'Stefan Seefeld', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'boostgil', u'Boost.GIL Documentation',
[u'Stefan Seefeld'], 1)
]

2938
doc/design_guide.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,9 @@
#---------------------------------------------------------------------------
PROJECT_NAME = "Generic Image Library "
PROJECT_NUMBER =
OUTPUT_DIRECTORY = ../../
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = YES
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class " \
@@ -30,7 +29,6 @@ STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = YES
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = YES
SEPARATE_MEMBER_PAGES = NO
@@ -66,7 +64,6 @@ GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
@@ -81,36 +78,11 @@ WARN_LOGFILE = warnings.txt
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ./ \
../ \
../../../../../boost/gil \
../../../../../boost/gil/extension/io \
../../../../../boost/gil/extension/dynamic_image
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
INPUT = . \
../include/boost/gil \
../include/boost/gil/extension/io \
../include/boost/gil/extension/dynamic_image
FILE_PATTERNS = *.hpp \
*.dox
RECURSIVE = NO
EXCLUDE =
@@ -119,10 +91,11 @@ EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH = ../images
#IMAGE_PATH = ../images
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
MARKDOWN_SUPPORT = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
@@ -143,19 +116,18 @@ IGNORE_PREFIX =
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_OUTPUT = html/reference
HTML_FILE_EXTENSION = .html
HTML_HEADER = header_html.txt
HTML_FOOTER =
HTML_STYLESHEET = ../../adobe_source.css
HTML_ALIGN_MEMBERS = YES
HTML_HEADER = header.html
HTML_FOOTER = footer.html
HTML_EXTRA_STYLESHEET = doxygen-boost.css
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = YES
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
@@ -195,8 +167,6 @@ MAN_LINKS = NO
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
@@ -248,8 +218,6 @@ DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO

3
doc/doxygen-boost.css Normal file
View File

@@ -0,0 +1,3 @@
@import url('../_static/style.css');
address.footer { text-align: center; }

View File

@@ -1,36 +0,0 @@
<!-- Copyright 2008 Lubomir Bourdev and Hailin Jin
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!--
Copyright 2005-2007 Adobe Systems Incorporated
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
or a copy at http://stlab.adobe.com/licenses.html)
Some files are held under additional license.
Please see "http://stlab.adobe.com/licenses.html" for more information.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<TITLE>$title</TITLE>
<META HTTP-EQUIV="content-type" CONTENT="text/html;charset=ISO-8859-1"/>
<LINK TYPE="text/css" REL="stylesheet" HREF="adobe_source.css"/>
</head>
<body>
<table border="0" cellspacing="0" cellpadding="0" style='width: 100%; margin: 0; padding: 0'><tr>
<td width="100%" valign="top" style='padding-left: 10px; padding-right: 10px; padding-bottom: 10px'>
<div class="qindex"><a class="qindex" href="index.html">Modules</a>
| <a class="qindex" href="classes.html">Alphabetical List</a>
| <a class="qindex" href="annotated.html">Class List</a>
| <a class="qindex" href="dirs.html">Directories</a>
| <a class="qindex" href="files.html">File List</a>
| <a class="qindex" href="../index.html">GIL Home Page</a>
</div>
<!-- End Header -->

22
doc/footer.html Normal file
View File

@@ -0,0 +1,22 @@
<!-- HTML footer for doxygen 1.8.13-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion
</li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/>
<address class="footer">
<small>
$generatedby &#160;<a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion
</small>
</address>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

34
doc/header.html Normal file
View File

@@ -0,0 +1,34 @@
<!-- HTML header for doxygen 1.8.13-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<div class="boost-header">
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary="header">
<tr>
<td valign="top" width="300">
<h3><a href="../index.html"><img alt="Boost GIL" src="../_static/gil.png" border="0"></a></h3>
</td>
<td ><h1 align="center"><a href="../index.html"></a></h1></td>
<td>$searchbox</td>
</tr>
</table>
</div>
<hr/>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->

BIN
doc/images/gil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,97 +1,9 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><!--
Copyright 2005-2007 Adobe Systems Incorporated
Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
or a copy at http://opensource.adobe.com/licenses.html)
Some files are held under additional license.
Please see "http://opensource.adobe.com/licenses.html" for more information.
-->
<title>Adobe Generic Image Library: Main Page</title>
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
<link type="text/css" rel="stylesheet" href="adobe_source.css">
<table style="margin: 0pt; padding: 0pt; width: 100%;" border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td style="background-color: rgb(238, 238, 238);" nowrap="1" valign="top">
<div style="padding: 5px;" align="center">
<a title="www.boost.org home page" href="http://www.boost.org/" tabindex="2" style="border: medium none ;">
<img src="boost.png" alt="Boost Libraries" style="padding: 3px;">
</a>
</div>
<div style="margin: 5px;">
<h3 class="navbar">Information</h3>
<ul>
<li><a href="http://opensource.adobe.com/gil/index.html">GIL ASL Home</a></li>
<li><a href="http://opensource.adobe.com/gil/contribute.html">GIL Extensions</a></li>
<li><a href="http://sourceforge.net/forum/forum.php?forum_id=648138">GIL Discussion Forum</a></li>
<li><a href="http://opensource.adobe.com/gil/contributors.html">Acknowledgements</a></li>
</ul>
<h3 class="navbar">Other Resources</h3>
<ul>
<li><a href="http://opensource.adobe.com/">Adobe Open Source</a></li>
<li><a href="http://www.sgi.com/tech/stl">SGI STL</a></li>
</ul>
</div>
<h3 class="navbar">GIL Sponsor</h3>
<div style="padding: 5px;" align="center">
<a title="www.adobe.com home page" href="http://www.adobe.com/" tabindex="2" style="border: medium none ;">
<img src="adobe_logo.gif" alt="Adobe Systems, Inc." style="padding: 3px;">
</a>
</div>
</td>
<td style="padding-left: 10px; padding-right: 10px; padding-bottom: 10px;" valign="top" width="100%">
<!-- End Header -->
<br>
<p>
</p><h1>Generic Image Library Documentation</h1>
<p>
<ul>
<li><strong><a href="https://stlab.adobe.com/gil/presentation/index.htm">Video Tutorial</a> </strong>
<p>
Watch a 55 minute video presentation of GIL. It roughly follows the tutorial, though in some places covers a bit more material. It is slightly outdated.</li>
<p>
<li><strong><a href="html/giltutorial.html">Tutorial</a> </strong>
<p>
The tutorial gives you a jump start in using the library. It starts with a simple non-generic algorithm that
is gradually evolved to be more generic, faster and more flexible. The tutorial covers most of what you need to know to make effective use of GIL, but does not systematically
cover all aspects of the library.</li>
<p>
<li><strong><a href="html/gildesignguide.html">Design Guide</a></strong>
<p>
The design guide provides a more formal and complete description of the library, including the concepts and the
design rationale.
<p>
<li><strong><a href="html/index.html">Doxygen Documentation</a></strong>
<p>
Interactive cross-linked documentation
<p>
<li>Sample files:
<ul>
<li><a href="../example/x_gradient.cpp">x_gradient.cpp</a> Writing an algorithm that operates on generic images</li>
<li><a href="../example/dynamic_image.cpp">dynamic_image.cpp</a> Using images whose properties (color space, channel type) are specified at run time</li>
<li><a href="../example/histogram.cpp">histogram.cpp</a> Creating a histogram</li>
<li><a href="../example/interleaved_ptr.cpp">interleaved_ptr.cpp</a>,
<a href="../example/interleaved_ptr.hpp">interleaved_ptr.hpp</a>,
<a href="../example/interleaved_ref.hpp">interleaved_ref.hpp</a> Creating your own pixel reference and pixel iterator</li>
<li><a href="../example/mandelbrot.cpp">mandelbrot.cpp</a> Creating a synthetic image defined by a function</li>
<li><a href="../example/packed_pixel.cpp">packed_pixel.cpp</a> Defining bitmasks and images whose channels or pixels are not byte-aligned</li>
<li><a href="../example/resize.cpp">resize.cpp</a> Rescaling an image using bilinear sampling (requires the optional Numeric extension)</li>
<li><a href="../example/affine.cpp">affine.cpp</a> Applying an affine transformation to an image (requires the optional Numeric extension)</li>
<li><a href="../example/convolution.cpp">convolution.cpp</a> Blurring images (requires the optional Numeric extension)</li>
</ul>
</ul>
</body></html>
<html>
<head>
<meta http-equiv="refresh" content="0; URL=html/index.html"/>
</head>
<body>
Automatic redirection failed, please go to
<a href="html/index.html">html/index.html</a>
</body>
</html>

40
doc/index.rst Normal file
View File

@@ -0,0 +1,40 @@
Boost Generic Image Library
===========================
The Generic Image Library (GIL) is a C++ library that abstracts image
representations from algorithms and allows writing code that can work on
a variety of images with performance similar to hand-writing for a specific
image type.
.. toctree::
:maxdepth: 2
tutorial
io
toolbox
numeric
design_guide
API Reference <./reference/index.html#://>
Sample files
------------
* :download:`x_gradient.cpp <../example/x_gradient.cpp>`:
Writing an algorithm that operates on generic images
* :download:`dynamic_image.cpp <../example/dynamic_image.cpp>`:
Using images whose properties (color space, channel type) are specified at run time
* :download:`histogram.cpp <../example/histogram.cpp>`: Creating a histogram
* :download:`interleaved_ptr.cpp <../example/interleaved_ptr.cpp>`,
:download:`interleaved_ptr.hpp <../example/interleaved_ptr.hpp>`,
:download:`interleaved_ref.hpp <../example/interleaved_ref.hpp>`:
Creating your own pixel reference and pixel iterator
* :download:`mandelbrot.cpp <../example/mandelbrot.cpp>`:
Creating a synthetic image defined by a function
* :download:`packed_pixel.cpp <../example/packed_pixel.cpp>`:
Defining bitmasks and images whose channels or pixels are not byte-aligned
* :download:`resize.cpp <../example/resize.cpp>`:
Rescaling an image using bilinear sampling (requires the optional Numeric extension)
* :download:`affine.cpp <../example/affine.cpp>`:
Applying an affine transformation to an image (requires the optional Numeric extension)
* :download:`convolution.cpp <../example/convolution.cpp>`:
Blurring images (requires the optional Numeric extension)

601
doc/io.rst Normal file
View File

@@ -0,0 +1,601 @@
IO extensions
=============
.. _BMP_Wiki: http://en.wikipedia.org/wiki/BMP_file_format
.. _JPEG_Wiki: http://en.wikipedia.org/wiki/JPEG
.. _JPEG_lib: http://www.ijg.org/
.. _PNG_Wiki: http://en.wikipedia.org/wiki/Portable_Network_Graphics
.. _PNG_Lib: http://libpng.org/pub/png/libpng.html
.. _PNM_Wiki: http://en.wikipedia.org/wiki/Portable_anymap
.. _RAW_Wiki: http://en.wikipedia.org/wiki/Raw_image_format
.. _TARGA_Wiki: http://en.wikipedia.org/wiki/Truevision_TGA
.. _RAW_lib: http://www.libraw.org/
.. _RAW_Wiki: http://en.wikipedia.org/wiki/Raw_image_format
.. _TIFF_Wiki: http://en.wikipedia.org/wiki/Tagged_Image_File_Format
.. _TIFF_Lib: http://www.remotesensing.org/libtiff/
.. _TIFF_Base_Tags: http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
.. _TIFF_Extension_Tags: http://www.awaresystems.be/imaging/tiff/tifftags/extension.html
.. _BMP_TEST_FILES: http://entropymine.com/jason/bmpsuite/
.. _PNG_TEST_FILES: http://www.schaik.com/pngsuite/pngsuite.html
.. _TARGA_TEST_FILES: http://www.fileformat.info/format/tga/sample/index.htm
.. _TIFF_LIB_TIFF_TEST_FILES: http://www.remotesensing.org/libtiff/images.html
.. _TIFF_GRAPHICSMAGICK_TEST_FILES: ftp://ftp.graphicsmagick.org/pub/tiff-samples/tiff-sample-images-be.tar.gz
Overview
--------
This extension to boost::gil provides an easy to use interface for reading and writing
various image formats. It also includes a framework for adding new formats.
Please see section 3.3 for all supported image formats. A basic tutorial is provided
in section [link gil.io.tutorial Tutorial]. Also, this extension requires Boost version 1.42 and up. Furthermore the gil
extension Toolbox is used.
For adding new image formats please refer to section [link gil.io.using_io.extending_gil__io_with_new_formats Extending GIL::IO with new Formats].
[h2 Supported Platforms]
All platforms supported by boost which have a decent C++ compiler. Depending on the
image format one or more of the following image libraries might be needed:
* libtiff
* libjpeg
* libpng
* libraw
* zlib
The library is designed to support as many formats as required by the user.
For instance, if the user only needs bmp support none of the above mentioned
dependencies are required.
There are more details available in this documentation on the image format dependencies.
Please see section [link gil.io.using_io.supported_image_formats Supported Image Formats].
[endsect]
Tutorial
--------
Thanks to modern C++ programming techniques the interface for this library
is rather small and easy to use. In this tutorial I'll give you a short walk-around
on how to use this boost::gil extension. For more details please refer to section 3.
Since this is an extension to boost::gil I expect the user to have some very basic
understanding of the gil ( generic image library ). Please see here for the help.
[h2 Header Files]
The header files to be included all have the same format. For instance, tiff_all.hpp will
allow to read and write. Whereas, tiff_read.hpp only allows for reading. If the user only
wants to write jpeg's include jpeg_write.hpp. All formats provide these three types of header files:
* xxx_all.hpp
* xxx_read.hpp
* xxx_write.hpp
xxx stands for image format.
Reading An Image
~~~~~~~~~~~~~~~~
Probably the most common case to read a tiff image can be done as follows::
std::string filename( "image.tif" );
rgb8_image_t img;
read_image( filename, img, tiff_tag() );
The code would be same for all other image formats. The only thing that needs to
change is the tag type ( tiff_tag ) in the read_image call.
The read_image() expects the supplied image type to be compatible with the
image stored in the file. If the user doesn't know what format an image has he/she
can use read_and_convert_image().
Another important fact is that read_image() will allocate the appropriate
memory needed for the read operation. There are read_view or read_and_convert_view
counterparts, if the memory is already allocated.
Sometimes the user only wants to read a sub-part of an image, then the above call
would look as follows::
read_image( filename
, img
, image_read_settings< tiff_tag >( point_t( 0, 0 ), point_t( 50, 50 ) )
);
The image_read_settings class will provide the user with image format independent
reading setting but can also serves as a pointer for format dependent settings. Please
see the specific image format sections [link gil.io.using_io.supported_image_formats Supported Image Formats] for more details.
Writing An Image
~~~~~~~~~~~~~~~~
Besides reading the information also writing is the second part of this boost::gil extension.
Writing is a lot simpler than reading since an existing image view contains all the information.
For instance writing an image can be done as follows::
std::string filename( "image.tif" );
rgb8_image_t img( 640, 480 );
// write data into image
write_view( filename
, view( img )
, tiff_tag()
);
The interface is similar to reading an image. To add image format specific parameter the user can use
image_write_info class. For instance, a user can specify the jpeg quality when writing like this::
std::string filename( "image.jpg" );
rgb8_image_t img( 640, 480 );
// write data into image
write_view( filename
, view( img )
, image_write_info< jpeg_tag >( 95 )
);
The above example will write an image where the jpeg quality is set to 95 percent.
Reading And Writing In-Memory Buffers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reading and writing in-memory buffers are supported as well. See as follows::
// 1. Read an image.
ifstream in( "test.tif", ios::binary );
rgb8_image_t img;
read_image( in, img, tiff_tag() );
// 2. Write image to in-memory buffer.
stringstream out_buffer( ios_base::out | ios_base::binary );
rgb8_image_t src;
write_view( out_buffer, view( src ), tiff_tag() );
// 3. Copy in-memory buffer to another.
stringstream in_buffer( ios_base::in | ios_base::binary );
in_buffer << out_buffer.rdbuf();
// 4. Read in-memory buffer to gil image
rgb8_image_t dst;
read_image( in_buffer, dst, tag_t() );
// 5. Write out image.
string filename( "out.tif" );
ofstream out( filename.c_str(), ios_base::binary );
write_view( out, view( dst ), tiff_tag() );
In case the user is using his own stream classes he has to make sure it has the common interface read,
write, seek, close, etc. Interface.
Using IO
--------
General Overview
~~~~~~~~~~~~~~~~
The tutorial pointed out some use cases for reading and writing images in various image formats. This section will provide a more thorough overview.
The next sections will introduce the Read and Write interface. But it might be worth poiting out that by using some advanced metaprogramming techniques
the interface is rather small and hopefully easy to understand.
Besides the general interface the user also has the ability to interface directly with the underlying image format. For that each reader or writer
provides access to the so-called backend. For instance::
typedef get_reader_backend< const std::string
, tag_t
>::type backend_t;
backend_t backend = read_image_info( bmp_filename
, tag_t()
);
BOOST_CHECK_EQUAL( backend._info._width , 127 );
BOOST_CHECK_EQUAL( backend._info._height, 64 );
Of course, the typedef can be removed when using c++11's auto feature.
Read Interface
~~~~~~~~~~~~~~
As the Tutorial demonstrated there are a few ways to read images. Here is an enumeration of
all read functions with a short description:
* read_image - read into a gil image with no conversion. Memory is allocated.
* read_view - read into a gil view with no conversion.
* read_and_convert_image - read and convert into a gil image. Memory is allocated.
* read_and_convert_view - read and convert into a gil view.
* read_image_info - read the image header.
Conversion in this context is necessary if the source ( file ) has an incompatible color space
with the destination ( gil image type ). If that's the case the user has to use the xxx_and_convert_xxx
variants.
All functions take the filename or a device as the first parameter. The filename can be anything from
a c string, std::string, std::wstring, and a boost::filesystem path. When using the path object the
user needs to define the ADD_FS_PATH_SUPPORT compiler symbol to include the boost::filesystem
dependency. Devices could be a FILE*, std::ifstream, and a TIFF* for TIFF images.
The second parameter is either an image or view type depending on the read_xxx function.
The third and last parameter is either an instance of the image_read_settings<FormatTag> or just the
FormatTag. The settings can be various depending on the format which is being read. But the all
share settings for reading a partial image area. The first point describes the top left image
coordinate whereas the second are the dimensions in x and y directions. Here an example of
setting up partial read::
read_image( filename
, img
, image_read_settings< tiff_tag >( point_t( 0, 0 ), point_t( 50, 50 ) )
);
Each format supports reading just the header information, using read_image_info(). Please
refer to the format specific sections under 3.3. A basic example follows::
image_read_info< tiff_t > info = read_image_info( filename
, tiff_t()
);
GIL also comes with a dynamic image extension. In the context of GIL.IO a user can define an any_image type based
on several image types. The IO extension would then pick the matching image type to the current image file.
The following example shows this feature::
typedef mpl::vector< gray8_image_t
, gray16_image_t
, rgb8_image_t
, rgba_image_t
> my_img_types;
any_image< my_img_types > runtime_image;
read_image( filename
, runtime_image
, tiff_tag()
);
During the review it became clear that there is a need to read big images scanline by scanline. To support such use case
a scanline_reader is implemented for all supported image formats. The scanline_read_iterators will then allow to traverse
through the image. The following code sample shows the usage::
typedef tiff_tag tag_t;
typedef scanline_reader< typename get_read_device< const char*
, tag_t
>::type
, tag_t
> reader_t;
reader_t reader = make_scanline_reader( "C:/boost/libs/gil/io/test_images/tiff/test.tif", tag_t() );
typedef rgba8_image_t image_t;
image_t dst( reader._info._width, reader._info._height );
fill_pixels( view(dst), image_t::value_type() );
typedef reader_t::iterator_t iterator_t;
iterator_t it = reader.begin();
iterator_t end = reader.end();
for( int row = 0; it != end; ++it, ++row )
{
copy_pixels( interleaved_view( reader._info._width
, 1
, ( image_t::view_t::x_iterator ) *it
, reader._scanline_length
)
, subimage_view( view( dst )
, 0
, row
, reader._info._width
, 1
)
);
}
There are many ways to travese an image but for as of now only by scanline is supported.
Write Interface
~~~~~~~~~~~~~~~
There is only one function for writing out images, write_view. Similar to reading the first parameter is either
a filename or a device. The filename can be anything from a c string, std::string, std::wstring, and a
boost::filesystem path. When using the path object the user needs to define the ADD_FS_PATH_SUPPORT compiler symbol
to include the boost::filesystem dependency. Devices could be a FILE*, std::ifstream, and a TIFF* for TIFF images.
The second parameter is an view object to image being written. The third and last parameter is either a tag or
an image_write_info< FormatTag > object containing more settings. One example for instance is the jpeg quality.
Refer to the format specific sections under 3.3. to have a list of all the possible settings.
Writing an any_image<...> is supported. See the following example::
typedef mpl::vector< gray8_image_t
, gray16_image_t
, rgb8_image_t
, rgba_image_t
> my_img_types;
any_image< my_img_types > runtime_image;
// fill any_image
write_view( filename
, view( runtime_image )
, tiff_tag()
);
Compiler Symbols
~~~~~~~~~~~~~~~~
The following table gives an overview of all supported compiler symbols that can be set by the user:
.. comment [table Compiler Symbols
======================================================== ========================================================
Symbol Description
======================================================== ========================================================
BOOST_GIL_IO_ENABLE_GRAY_ALPHA Enable the color space "gray_alpha".
BOOST_GIL_IO_ADD_FS_PATH_SUPPORT Enable boost::filesystem 3.0 library.
BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED Use libpng in floating point mode. This symbol is incompatible with BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED.
BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED Use libpng in integer mode. This symbol is incompatible with BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED.
BOOST_GIL_IO_PNG_DITHERING_SUPPORTED Look up "dithering" in libpng manual for explanation.
BOOST_GIL_IO_PNG_1_4_OR_LOWER Allow compiling with libpng 1.4 or lower.
BOOST_GIL_EXTENSION_IO_JPEG_C_LIB_COMPILED_AS_CPLUSPLUS libjpeg is compiled as c++ lib.
BOOST_GIL_EXTENSION_IO_PNG_C_LIB_COMPILED_AS_CPLUSPLUS libpng is compiled as c++ lib.
BOOST_GIL_EXTENSION_IO_RAW_C_LIB_COMPILED_AS_CPLUSPLUS libraw is compiled as c++ lib.
BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS libtiff is compiled as c++ lib.
BOOST_GIL_EXTENSION_IO_ZLIB_C_LIB_COMPILED_AS_CPLUSPLUS zlib is compiled as c++ lib.
BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES Allow basic test images to be read from local hard drive. The paths can be set in paths.hpp
BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES Allow images to be written to the local hard drive. The paths can be set in paths.hpp
BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES Run tests using the bmp test images suite. See _BMP_TEST_FILES
BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES Run tests using the png test images suite. See _PNG_TEST_FILES
BOOST_GIL_IO_USE_PNM_TEST_SUITE_IMAGES Run tests using the pnm test images suite. Send me an email for accessing the files.
BOOST_GIL_IO_USE_TARGA_FILEFORMAT_TEST_SUITE_IMAGES Run tests using the targa file format test images suite. See _TARGA_TEST_FILES
BOOST_GIL_IO_USE_TIFF_LIBTIFF_TEST_SUITE_IMAGES Run tests using the targa file format test images suite. See _TIFF_LIB_TIFF_TEST_FILES
BOOST_GIL_IO_USE_TIFF_GRAPHICSMAGICK_TEST_SUITE_IMAGES Run tests using the targa file format test images suite. See _TIFF_GRAPHICSMAGICK_TEST_FILES
======================================================== ========================================================
Supported Image Formats
~~~~~~~~~~~~~~~~~~~~~~~
BMP
+++
For a general overview of the BMP image file format go to the following BMP_Wiki_.
Please note, the code has not been tested on X Windows System variations
of the BMP format which are usually referred to XBM and XPM formats.
Here, only the MS Windows and OS/2 format is relevant.
Currently the code is able to read and write the following image types:
:Read: ``gray1_image_t``, ``gray4_image_t``, ``gray8_image_t``, ``rgb8_image_t`` and, ``rgba8_image_t``
:Write: ``rgb8_image_t`` and, ``rgba8_image_t``
The lack of having an indexed image type in gil restricts the current interface to only
write out non-indexed images. This is subject to change soon.
JPEG
++++
For a general overview of the JPEG image file format go to the following JPEG_Wiki_.
This jpeg extension is based on the libjpeg library which can be found here, JPEG_Lib_.
All versions starting from 8x are supported.
The user has to make sure this library is properly installed. I strongly recommend the user
to build the library yourself. It could potentially save you a lot of trouble.
Currently the code is able to read and write the following image types:
:Read: ``gray8_image_t``, ``rgb8_image_t``, ``cmyk8_image_t``
:Write: ``gray8_image_t``, ``rgb8_image_t``, ``cmyk8_image_t``
Reading YCbCr or YCCK images is possible but might result in inaccuracies since both color spaces
aren't available yet for gil. For now these color space are read as rgb images.
This is subject to change soon.
PNG
+++
For a general overview of the PNG image file format go to the following PNG_Wiki_.
This png extension is based on the libpng, which can be found here, PNG_Lib_.
All versions starting from 1.5.x are supported.
The user has to make sure this library is properly installed. I strongly recommend the user
to build the library yourself. It could potentially save you a lot of trouble.
Currently the code is able to read and write the following image types:
:Read: gray1, gray2, gray4, gray8, gray16, gray_alpha_8, gray_alpha_16, rgb8, rgb16, rgba8, rgba16
:Write: gray1, gray2, gray4, gray8, gray16, gray_alpha_8, gray_alpha_16, rgb8, rgb16, rgba8, rgba16
For reading gray_alpha images the user has to enable the ENABLE_GRAY_ALPHA compiler switch. This color
space is defined in the toolbox by using gray_alpha.hpp.
PNM
+++
For a general overview of the PNM image file format go to the following PNM_Wiki_.
No external library is needed for the pnm format. Both ascii and binary formats are supported.
Currently the code is able to read and write the following image types:
:Read: gray1, gray8, rgb8
:Write: gray1, gray8, rgb8
When reading a mono text image the data is read as a gray8 image.
RAW
+++
For a general overview see RAW_Wiki_.
Currently the extension is only able to read rgb8 images.
TARGA
+++++
For a general overview of the BMP image file format go to the following TARGA_Wiki_.
Currently the code is able to read and write the following image types:
:Read: rgb8_image_t and rgba8_image_t
:Write: rgb8_image_t and rgba8_image_t
The lack of having an indexed image type in gil restricts the current interface to only
write out non-indexed images. This is subject to change soon.
TIFF
++++
For a general overview of the TIFF image file format go to the following TIFF_Wiki_.
This tiff extension is based on the libtiff, which can be found, TIFF_Lib_.
All versions starting from 3.9.x are supported.
The user has to make sure this library is properly installed. I strongly recommend the user
to build the library yourself. It could potentially save you a lot of trouble.
TIFF images can virtually encode all kinds of channel sizes representing various color spaces. Even
planar images are possible. For instance, rbg323 or gray7. The channels also can have specific formats, like
integer values or floating point values. For a complete set of options please consult the following websites:
* TIFF_Base_Tags_
* TIFF_Extension_Tags_
The author of this extension is not claiming all tiff formats are supported. This extension is
likely to be a moving target adding new features with each new milestone. Here is an incomplete lists:
* Multi-page tiffs - read only
* Strip tiffs - read and write support
* Tiled tiffs - read and write support with user defined tiled sizes
* bit images tiffs - fully supported, like gray1_image_t ( minisblack )
* planar tiffs - fully supported
* floating point tiffs - fully supported
* palette tiffs - supported but no indexed image type is available as of now
This gil extension uses two different test image suites to test read and write capabilities. See test_image folder.
It's advisable to use ImageMagick's test viewer to display images.
Extending GIL::IO with new Formats
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extending the gil::io with new formats is meant to be simple and straightforward. Before adding I would
recommend to have a look at existing implementations and then trying to follow a couple of guidelines:
* Create the following files for your new xxx format
* xxx_read.hpp // Only includes read code
* xxx_write.hpp // Only includes write code
* xxx_all.hpp // includes xxx_read.hpp and xxx_write.hpp
* Add the code to the boost::gil::detail namespace
* Create a tag type for the new format. Like this::
struct xxx_tag : format_tag {};
* Create the image_read_info for the new format. It contains all the information that are
necessary to read an image. It should be filled and returned by the get_info() member of
the reader class. See below::
template<> struct image_read_info< xxx_tag > {};
* Create the image_write_info for the new format. It contains all the information that are
necessary to write an image::
template<> struct image_write_info< xxx_tag > {};
* Use the following reader skeleton as a start::
template< typename Device
, typename ConversionPolicy
>
class reader< Device
, xxx_tag
, ConversionPolicy
>
: public reader_base< xxx_tag
, ConversionPolicy
>
{
private:
typedef typename ConversionPolicy::color_converter_type cc_t;
public:
reader( Device& device )
: _io_dev( device )
{}
reader( Device& device
, const cc_t& cc
)
: _io_dev( device )
, reader_base< xxx_tag
, ConversionPolicy
>( cc )
{}
image_read_info< xxx_tag > get_info()
{
// your implementation here
}
template< typename View >
void apply( const View& dst_view )
{
// your implementation here
}
};
* The writer skeleton::
template< typename Device >
class writer< Device
, xxx_tag
>
{
public:
writer( Device & file )
: out(file)
{}
template<typename View>
void apply( const View& view )
{
// your implementation here
}
template<typename View>
void apply( const View& view
, const image_write_info< xxx_tag >& info )
{
// your implementation here
}
};
Running gil::io tests
---------------------
gil::io comes with a large suite of test cases which reads and writes various file formats. It uses some test image suites which can be found online or which can be demanded from me by sending me an email.
There are some test images created by me in the test folder. To enable unit tests which make use of them set the following compiler options BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES and BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES.
The following list provides all links to the image suites the compiler symbol to enable the tests:
:BMP: BMP_TEST_FILES_ -- BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES
:PNG: PNG_TEST_FILES_ -- BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES
:PNM: request files from me -- BOOST_GIL_IO_USE_PNM_TEST_SUITE_IMAGES
:TARGA: TARGA_TEST_FILES_ -- BOOST_GIL_IO_USE_TARGA_FILEFORMAT_TEST_SUITE_IMAGES
:TIFF: TIFF_LIB_TIFF_TEST_FILES_ -- BOOST_GIL_IO_USE_TIFF_LIBTIFF_TEST_SUITE_IMAGES
:TIFF: TIFF_GRAPHICSMAGICK_TEST_FILES_ -- BOOST_GIL_IO_USE_TIFF_GRAPHICSMAGICK_TEST_SUITE_IMAGES

7
doc/numeric.rst Normal file
View File

@@ -0,0 +1,7 @@
Numeric extension
=================
Overview
--------
todo

View File

@@ -217,12 +217,7 @@ Since pixels model the ColorBaseConcept, all color-base related algorithms also
/// \brief Support for reading and writing PNG image files
/*!
\mainpage Generic Image Library
\section Documentation
- A Quick, Hands-on \ref GILTutorial "Tutorial".
- A Detailed \ref GILDesignGuide "Design Guide".
\mainpage API Reference
\section Modules

149
doc/rst.css Normal file
View File

@@ -0,0 +1,149 @@
@import url("doc/src/boostbook.css");
@import url("doc/src/docutils.css");
/* Copyright David Abrahams 2006. Distributed under the Boost
Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
dl.docutils dt {
font-weight: bold }
img.boost-logo {
border: none;
vertical-align: middle
}
pre.literal-block span.concept {
font-style: italic;
}
.nav {
display: inline;
list-style-type: none;
}
.prevpage {
padding-top: -5px;
text-align: left;
float: left;
}
.nextpage {
padding-top: -20px;
text-align: right;
float: right;
}
div.small {
font-size: smaller }
h2 a {
font-size: 90%;
}
h3 a {
font-size: 80%;
}
h4 a {
font-size: 70%;
}
h5 a {
font-size: 60%;
}
dl,table
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Tables
=============================================================================*/
/* The only clue docutils gives us that tables are logically tables,
and not, e.g., footnotes, is that they have border="1". Therefore
we're keying off of that. We used to manually patch docutils to
add a "table" class to all logical tables, but that proved much too
fragile.
*/
table[border="1"]
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
table[border="1"]
{
padding: 4px;
}
/* Table Cells */
table[border="1"] tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
}
table[border="1"] tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
}
@media screen
{
/* Tables */
table[border="1"] tr td
{
border: 1px solid #DCDCDC;
}
table[border="1"] tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
pre,
.screen
{
border: 1px solid #DCDCDC;
}
td pre
td .screen
{
border: 0px
}
.sidebar pre
{
border: 0px
}
}
pre,
.screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Program listings in tables don't get borders */
td pre,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}

60
doc/toolbox.rst Normal file
View File

@@ -0,0 +1,60 @@
ToolBox extension
=================
.. _Reference: reference.html
Overview
--------
ToolBox provides collection of Boost.GIL extensions which are too
small to be maintained as standalone extensions.
Content:
* Color converters: Gray to RGBA
* Color spaces: CMYKA, Gray with Alpha, HSL, HSV, Lab, XYZ
* Metafunctions:
* ``channel_type``
* ``channel_type_to_index``
* ``get_num_bits``
* ``get_pixel_type``
* ``is_bit_aligned``
* ``is_homogeneous``
* ``is_similar``
* ``pixel_bit_size``
* Image types:
* ``indexed_image``
This extension will hopefully be added on by the community.
Since the extension is header-only, user just needs to include
its main header ``#include <boost/gil/extension/toolbox.hpp>``.
All definitions of the toolbox belong to the ``boost::gil`` namespace.
Folder Structure
----------------
The toolbox structured in the following sub-directories:
* color_converters
* color_spaces
* metafunctions
* image_types
Acknowledgements
----------------
Thanks to all the people who have reviewed this library and
made suggestions for improvements.
Reference
---------
The Reference_ section.

950
doc/tutorial.rst Normal file
View File

@@ -0,0 +1,950 @@
Tutorial
========
.. contents::
:local:
Installation
------------
The latest version of GIL can be downloaded from http://boostorg.github.com/gilGIL's web page, at http://stlab.adobe.com/gil.
GIL is approved for integration into Boost and in the future will be installed simply by installing Boost from http://www.boost.org.
GIL consists of header files only and does not require any libraries to link against. It does not require Boost to be built.
Including ``boost/gil/gil_all.hpp`` will be sufficient for most projects.
Example - Computing the Image Gradient
--------------------------------------
This tutorial will walk through an example of using GIL to compute the
image gradients. We will start with some very simple and non-generic
code and make it more generic as we go along. Let us start with a
horizontal gradient and use the simplest possible approximation to a
gradient - central difference. The gradient at pixel x can be
approximated with the half-difference of its two neighboring pixels:
D[x] = (I[x-1] - I[x+1]) / 2
For simplicity, we will also ignore the boundary cases - the pixels
along the edges of the image for which one of the neighbors is not
defined. The focus of this document is how to use GIL, not how to
create a good gradient generation algorithm.
Interface and Glue Code
~~~~~~~~~~~~~~~~~~~~~~~
Let us first start with 8-bit unsigned grayscale image as the input and 8-bit
signed grayscale image as the output.
Here is how the interface to our algorithm looks like::
#include <boost/gil/gil_all.hpp>
using namespace boost::gil;
void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
assert(src.dimensions() == dst.dimensions());
... // compute the gradient
}
``gray8c_view_t`` is the type of the source image view - an 8-bit
grayscale view, whose pixels are read-only (denoted by the "c"). The
output is a grayscale view with a 8-bit signed (denoted by the "s")
integer channel type. See Appendix 1 for the complete convention GIL
uses to name concrete types.
GIL makes a distinction between an image and an image view. A GIL
**image view**, is a shallow, lightweight view of a rectangular grid
of pixels. It provides access to the pixels but does not own the
pixels. Copy-constructing a view does not deep-copy the pixels. Image
views do not propagate their constness to the pixels and should always
be taken by a const reference. Whether a view is mutable or read-only
(immutable) is a property of the view type.
A GIL `image`, on the other hand, is a view with associated
ownership. It is a container of pixels; its constructor/destructor
allocates/deallocates the pixels, its copy-constructor performs
deep-copy of the pixels and its operator== performs deep-compare of
the pixels. Images also propagate their constness to their pixels - a
constant reference to an image will not allow for modifying its
pixels.
Most GIL algorithms operate on image views; images are rarely
needed. GIL's design is very similar to that of the STL. The STL
equivalent of GIL's image is a container, like ``std::vector``,
whereas GIL's image view corresponds to STL range, which is often
represented with a pair of iterators. STL algorithms operate on
ranges, just like GIL algorithms operate on image views.
GIL's image views can be constructed from raw data - the dimensions,
the number of bytes per row and the pixels, which for chunky views are
represented with one pointer. Here is how to provide the glue between
your code and GIL::
void ComputeXGradientGray8(const unsigned char* src_pixels, ptrdiff_t src_row_bytes, int w, int h,
signed char* dst_pixels, ptrdiff_t dst_row_bytes)
{
gray8c_view_t src = interleaved_view(w, h, (const gray8_pixel_t*)src_pixels,src_row_bytes);
gray8s_view_t dst = interleaved_view(w, h, ( gray8s_pixel_t*)dst_pixels,dst_row_bytes);
x_gradient(src,dst);
}
This glue code is very fast and views are lightweight - in the above
example the views have a size of 16 bytes. They consist of a pointer
to the top left pixel and three integers - the width, height, and
number of bytes per row.
First Implementation
~~~~~~~~~~~~~~~~~~~~
Focusing on simplicity at the expense of speed, we can compute the horizontal gradient like this::
void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
for (int y=0; y<src.height(); ++y)
for (int x=1; x<src.width()-1; ++x)
dst(x,y) = (src(x-1,y) - src(x+1,y)) / 2;
}
We use image view's ``operator(x,y)`` to get a reference to the pixel
at a given location and we set it to the half-difference of its left
and right neighbors. ``operator()`` returns a reference to a
grayscale pixel. A grayscale pixel is convertible to its channel type
(``unsigned char`` for ``src``) and it can be copy-constructed from a
channel. (This is only true for grayscale pixels). While the above
code is easy to read, it is not very fast, because the binary
``operator()`` computes the location of the pixel in a 2D grid, which
involves addition and multiplication. Here is a faster version of the
above::
void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
for (int y=0; y<src.height(); ++y)
{
gray8c_view_t::x_iterator src_it = src.row_begin(y);
gray8s_view_t::x_iterator dst_it = dst.row_begin(y);
for (int x=1; x<src.width()-1; ++x)
dst_it[x] = (src_it[x-1] - src_it[x+1]) / 2;
}
}
We use pixel iterators initialized at the beginning of each row. GIL's
iterators are Random Access Traversal iterators. If you are not
familiar with random access iterators, think of them as if they were
pointers. In fact, in the above example the two iterator types are raw
C pointers and their ``operator[]`` is a fast pointer indexing
operator.
The code to compute gradient in the vertical direction is very
similar::
void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
for (int x=0; x<src.width(); ++x)
{
gray8c_view_t::y_iterator src_it = src.col_begin(x);
gray8s_view_t::y_iterator dst_it = dst.col_begin(x);
for (int y=1; y<src.height()-1; ++y)
dst_it[y] = (src_it[y-1] - src_it[y+1])/2;
}
}
Instead of looping over the rows, we loop over each column and create
a \p y_iterator, an iterator moving vertically. In this case a simple
pointer cannot be used because the distance between two adjacent
pixels equals the number of bytes in each row of the image. GIL uses
here a special step iterator class whose size is 8 bytes - it contains
a raw C pointer and a step. Its ``operator[]`` multiplies the index
by its step.
The above version of ``y_gradient``, however, is much slower (easily
an order of magnitude slower) than ``x_gradient`` because of the
memory access pattern; traversing an image vertically results in lots
of cache misses. A much more efficient and cache-friendly version will
iterate over the columns in the inner loop::
void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
for (int y=1; y<src.height()-1; ++y)
{
gray8c_view_t::x_iterator src1_it = src.row_begin(y-1);
gray8c_view_t::x_iterator src2_it = src.row_begin(y+1);
gray8s_view_t::x_iterator dst_it = dst.row_begin(y);
for (int x=0; x<src.width(); ++x) {
*dst_it = ((*src1_it) - (*src2_it))/2;
++dst_it;
++src1_it;
++src2_it;
}
}
}
This sample code also shows an alternative way of using pixel
iterators - instead of ``operator[]`` one could use increments and
dereferences.
Using Locators
~~~~~~~~~~~~~~
Unfortunately this cache-friendly version requires the extra hassle of
maintaining two separate iterators in the source view. For every
pixel, we want to access its neighbors above and below it. Such
relative access can be done with GIL locators::
void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
gray8c_view_t::xy_locator src_loc = src.xy_at(0,1);
for (int y=1; y<src.height()-1; ++y)
{
gray8s_view_t::x_iterator dst_it = dst.row_begin(y);
for (int x=0; x<src.width(); ++x)
{
(*dst_it) = (src_loc(0,-1) - src_loc(0,1)) / 2;
++dst_it;
++src_loc.x(); // each dimension can be advanced separately
}
src_loc+=point2<std::ptrdiff_t>(-src.width(),1); // carriage return
}
}
The first line creates a locator pointing to the first pixel of the
second row of the source view. A GIL pixel locator is very similar to
an iterator, except that it can move both horizontally and
vertically. ``src_loc.x()`` and ``src_loc.y()`` return references to a
horizontal and a vertical iterator respectively, which can be used to
move the locator along the desired dimension, as shown
above. Additionally, the locator can be advanced in both dimensions
simultaneously using its ``operator+=`` and ``operator-=``. Similar to
image views, locators provide binary ``operator()`` which returns a
reference to a pixel with a relative offset to the current locator
position. For example, ``src_loc(0,1)`` returns a reference to the
neighbor below the current pixel. Locators are very lightweight
objects - in the above example the locator has a size of 8 bytes - it
consists of a raw pointer to the current pixel and an int indicating
the number of bytes from one row to the next (which is the step when
moving vertically). The call to ``++src_loc.x()`` corresponds to a
single C pointer increment. However, the example above performs more
computations than necessary. The code ``src_loc(0,1)`` has to compute
the offset of the pixel in two dimensions, which is slow. Notice
though that the offset of the two neighbors is the same, regardless of
the pixel location. To improve the performance, GIL can cache and
reuse this offset::
void y_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
gray8c_view_t::xy_locator src_loc = src.xy_at(0,1);
gray8c_view_t::xy_locator::cached_location_t above = src_loc.cache_location(0,-1);
gray8c_view_t::xy_locator::cached_location_t below = src_loc.cache_location(0, 1);
for (int y=1; y<src.height()-1; ++y)
{
gray8s_view_t::x_iterator dst_it = dst.row_begin(y);
for (int x=0; x<src.width(); ++x)
{
(*dst_it) = (src_loc[above] - src_loc[below])/2;
++dst_it;
++src_loc.x();
}
src_loc+=point2<std::ptrdiff_t>(-src.width(),1);
}
}
In this example ``src_loc[above]`` corresponds to a fast pointer
indexing operation and the code is efficient.
Creating a Generic Version of GIL Algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let us make our ``x_gradient`` more generic. It should work with any
image views, as long as they have the same number of channels. The
gradient operation is to be computed for each channel
independently. Here is how the new interface looks like::
template <typename SrcView, typename DstView>
void x_gradient(const SrcView& src, const DstView& dst)
{
gil_function_requires<ImageViewConcept<SrcView> >();
gil_function_requires<MutableImageViewConcept<DstView> >();
gil_function_requires<ColorSpacesCompatibleConcept<
typename color_space_type<SrcView>::type,
typename color_space_type<DstView>::type> >();
... // compute the gradient
}
The new algorithm now takes the types of the input and output image
views as template parameters. That allows using both built-in GIL
image views, as well as any user-defined image view classes. The
first three lines are optional; they use ``boost::concept_check`` to
ensure that the two arguments are valid GIL image views, that the
second one is mutable and that their color spaces are compatible
(i.e. have the same set of channels).
GIL does not require using its own built-in constructs. You are free
to use your own channels, color spaces, iterators, locators, views and
images. However, to work with the rest of GIL they have to satisfy a
set of requirements; in other words, they have to \e model the
corresponding GIL _concept_. GIL's concepts are defined in the user
guide.
One of the biggest drawbacks of using templates and generic
programming in C++ is that compile errors can be very difficult to
comprehend. This is a side-effect of the lack of early type
checking - a generic argument may not satisfy the requirements of a
function, but the incompatibility may be triggered deep into a nested
call, in code unfamiliar and hardly related to the problem. GIL uses
``boost::concept_check`` to mitigate this problem. The above three
lines of code check whether the template parameters are valid models
of their corresponding concepts. If a model is incorrect, the compile
error will be inside ``gil_function_requires``, which is much closer
to the problem and easier to track. Furthermore, such checks get
compiled out and have zero performance overhead. The disadvantage of
using concept checks is the sometimes severe impact they have on
compile time. This is why GIL performs concept checks only in debug
mode, and only if ``BOOST_GIL_USE_CONCEPT_CHECK`` is defined (off by
default).
The body of the generic function is very similar to that of the
concrete one. The biggest difference is that we need to loop over the
channels of the pixel and compute the gradient for each channel::
template <typename SrcView, typename DstView>
void x_gradient(const SrcView& src, const DstView& dst)
{
for (int y=0; y<src.height(); ++y)
{
typename SrcView::x_iterator src_it = src.row_begin(y);
typename DstView::x_iterator dst_it = dst.row_begin(y);
for (int x=1; x<src.width()-1; ++x)
for (int c=0; c<num_channels<SrcView>::value; ++c)
dst_it[x][c] = (src_it[x-1][c]- src_it[x+1][c])/2;
}
}
Having an explicit loop for each channel could be a performance
problem. GIL allows us to abstract out such per-channel operations::
template <typename Out>
struct halfdiff_cast_channels
{
template <typename T> Out operator()(const T& in1, const T& in2) const
{
return Out((in1-in2)/2);
}
};
template <typename SrcView, typename DstView>
void x_gradient(const SrcView& src, const DstView& dst)
{
typedef typename channel_type<DstView>::type dst_channel_t;
for (int y=0; y<src.height(); ++y)
{
typename SrcView::x_iterator src_it = src.row_begin(y);
typename DstView::x_iterator dst_it = dst.row_begin(y);
for (int x=1; x<src.width()-1; ++x)
static_transform(src_it[x-1], src_it[x+1], dst_it[x],
halfdiff_cast_channels<dst_channel_t>());
}
}
``static_transform`` is an example of a channel-level GIL
algorithm. Other such algorithms are ``static_generate``,
``static_fill`` and ``static_for_each``. They are the channel-level
equivalents of STL ``generate``, ``transform``, ``fill`` and
``for_each`` respectively. GIL channel algorithms use static recursion
to unroll the loops; they never loop over the channels explicitly.
Note that sometimes modern compilers (at least Visual Studio 8)
already unroll channel-level loops, such as the one above. However,
another advantage of using GIL's channel-level algorithms is that they
pair the channels semantically, not based on their order in
memory. For example, the above example will properly match an RGB
source with a BGR destination.
Here is how we can use our generic version with images of different
types::
// Calling with 16-bit grayscale data
void XGradientGray16_Gray32(const unsigned short* src_pixels, ptrdiff_t src_row_bytes, int w, int h,
signed int* dst_pixels, ptrdiff_t dst_row_bytes)
{
gray16c_view_t src=interleaved_view(w,h,(const gray16_pixel_t*)src_pixels,src_row_bytes);
gray32s_view_t dst=interleaved_view(w,h,( gray32s_pixel_t*)dst_pixels,dst_row_bytes);
x_gradient(src,dst);
}
// Calling with 8-bit RGB data into 16-bit BGR
void XGradientRGB8_BGR16(const unsigned char* src_pixels, ptrdiff_t src_row_bytes, int w, int h,
signed short* dst_pixels, ptrdiff_t dst_row_bytes)
{
rgb8c_view_t src = interleaved_view(w,h,(const rgb8_pixel_t*)src_pixels,src_row_bytes);
rgb16s_view_t dst = interleaved_view(w,h,( rgb16s_pixel_t*)dst_pixels,dst_row_bytes);
x_gradient(src,dst);
}
// Either or both the source and the destination could be planar - the gradient code does not change
void XGradientPlanarRGB8_RGB32(
const unsigned short* src_r, const unsigned short* src_g, const unsigned short* src_b,
ptrdiff_t src_row_bytes, int w, int h,
signed int* dst_pixels, ptrdiff_t dst_row_bytes)
{
rgb16c_planar_view_t src=planar_rgb_view (w,h, src_r,src_g,src_b, src_row_bytes);
rgb32s_view_t dst=interleaved_view(w,h,(rgb32s_pixel_t*)dst_pixels,dst_row_bytes);
x_gradient(src,dst);
}
As these examples illustrate, both the source and the destination can
be interleaved or planar, of any channel depth (assuming the
destination channel is assignable to the source), and of any
compatible color spaces.
GIL 2.1 can also natively represent images whose channels are not
byte-aligned, such as 6-bit RGB222 image or a 1-bit Gray1 image. GIL
algorithms apply to these images natively. See the design guide or
sample files for more on using such images.
Image View Transformations
~~~~~~~~~~~~~~~~~~~~~~~~~~
One way to compute the y-gradient is to rotate the image by 90
degrees, compute the x-gradient and rotate the result back. Here is
how to do this in GIL::
template <typename SrcView, typename DstView>
void y_gradient(const SrcView& src, const DstView& dst)
{
x_gradient(rotated90ccw_view(src), rotated90ccw_view(dst));
}
``rotated90ccw_view`` takes an image view and returns an image view
representing 90-degrees counter-clockwise rotation of its input. It is
an example of a GIL view transformation function. GIL provides a
variety of transformation functions that can perform any axis-aligned
rotation, transpose the view, flip it vertically or horizontally,
extract a rectangular subimage, perform color conversion, subsample
view, etc. The view transformation functions are fast and shallow -
they don't copy the pixels, they just change the "coordinate system"
of accessing the pixels. ``rotated90cw_view``, for example, returns a
view whose horizontal iterators are the vertical iterators of the
original view. The above code to compute ``y_gradient`` is slow
because of the memory access pattern; using ``rotated90cw_view`` does
not make it any slower.
Another example: suppose we want to compute the gradient of the N-th
channel of a color image. Here is how to do that::
template <typename SrcView, typename DstView>
void nth_channel_x_gradient(const SrcView& src, int n, const DstView& dst)
{
x_gradient(nth_channel_view(src, n), dst);
}
``nth_channel_view`` is a view transformation function that takes any
view and returns a single-channel (grayscale) view of its N-th
channel. For interleaved RGB view, for example, the returned view is
a step view - a view whose horizontal iterator skips over two channels
when incremented. If applied on a planar RGB view, the returned type
is a simple grayscale view whose horizontal iterator is a C pointer.
Image view transformation functions can be piped together. For
example, to compute the y gradient of the second channel of the even
pixels in the view, use::
y_gradient(subsampled_view(nth_channel_view(src, 1), 2,2), dst);
GIL can sometimes simplify piped views. For example, two nested
subsampled views (views that skip over pixels in X and in Y) can be
represented as a single subsampled view whose step is the product of
the steps of the two views.
1D pixel iterators
~~~~~~~~~~~~~~~~~~
Let's go back to ``x_gradient`` one more time. Many image view
algorithms apply the same operation for each pixel and GIL provides an
abstraction to handle them. However, our algorithm has an unusual
access pattern, as it skips the first and the last column. It would be
nice and instructional to see how we can rewrite it in canonical
form. The way to do that in GIL is to write a version that works for
every pixel, but apply it only on the subimage that excludes the first
and last column::
void x_gradient_unguarded(const gray8c_view_t& src, const gray8s_view_t& dst)
{
for (int y=0; y<src.height(); ++y)
{
gray8c_view_t::x_iterator src_it = src.row_begin(y);
gray8s_view_t::x_iterator dst_it = dst.row_begin(y);
for (int x=0; x<src.width(); ++x)
dst_it[x] = (src_it[x-1] - src_it[x+1]) / 2;
}
}
void x_gradient(const gray8c_view_t& src, const gray8s_view_t& dst)
{
assert(src.width()>=2);
x_gradient_unguarded(subimage_view(src, 1, 0, src.width()-2, src.height()),
subimage_view(dst, 1, 0, src.width()-2, src.height()));
}
``subimage_view`` is another example of a GIL view transformation
function. It takes a source view and a rectangular region (in this
case, defined as x_min,y_min,width,height) and returns a view
operating on that region of the source view. The above implementation
has no measurable performance degradation from the version that
operates on the original views.
Now that ``x_gradient_unguarded`` operates on every pixel, we can
rewrite it more compactly::
void x_gradient_unguarded(const gray8c_view_t& src, const gray8s_view_t& dst)
{
gray8c_view_t::iterator src_it = src.begin();
for (gray8s_view_t::iterator dst_it = dst.begin(); dst_it!=dst.end(); ++dst_it, ++src_it)
*dst_it = (src_it.x()[-1] - src_it.x()[1]) / 2;
}
GIL image views provide ``begin()`` and ``end()`` methods that return
one dimensional pixel iterators which iterate over each pixel in the
view, left to right and top to bottom. They do a proper "carriage
return" - they skip any unused bytes at the end of a row. As such,
they are slightly suboptimal, because they need to keep track of their
current position with respect to the end of the row. Their increment
operator performs one extra check (are we at the end of the row?), a
check that is avoided if two nested loops are used instead. These
iterators have a method ``x()`` which returns the more lightweight
horizontal iterator that we used previously. Horizontal iterators have
no notion of the end of rows. In this case, the horizontal iterators
are raw C pointers. In our example, we must use the horizontal
iterators to access the two neighbors properly, since they could
reside outside the image view.
STL Equivalent Algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~
GIL provides STL equivalents of many algorithms. For example,
``std::transform`` is an STL algorithm that sets each element in a
destination range the result of a generic function taking the
corresponding element of the source range. In our example, we want to
assign to each destination pixel the value of the half-difference of
the horizontal neighbors of the corresponding source pixel. If we
abstract that operation in a function object, we can use GIL's
``transform_pixel_positions`` to do that::
struct half_x_difference
{
int operator()(const gray8c_loc_t& src_loc) const
{
return (src_loc.x()[-1] - src_loc.x()[1]) / 2;
}
};
void x_gradient_unguarded(const gray8c_view_t& src, const gray8s_view_t& dst)
{
transform_pixel_positions(src, dst, half_x_difference());
}
GIL provides the algorithms ``for_each_pixel`` and
``transform_pixels`` which are image view equivalents of STL
``std::for_each`` and ``std::transform``. It also provides
``for_each_pixel_position`` and ``transform_pixel_positions``, which
instead of references to pixels, pass to the generic function pixel
locators. This allows for more powerful functions that can use the
pixel neighbors through the passed locators. GIL algorithms iterate
through the pixels using the more efficient two nested loops (as
opposed to the single loop using 1-D iterators)
Color Conversion
~~~~~~~~~~~~~~~~
Instead of computing the gradient of each color plane of an image, we
often want to compute the gradient of the luminosity. In other words,
we want to convert the color image to grayscale and compute the
gradient of the result. Here how to compute the luminosity gradient of
a 32-bit float RGB image::
void x_gradient_rgb_luminosity(const rgb32fc_view_t& src, const gray8s_view_t& dst)
{
x_gradient(color_converted_view<gray8_pixel_t>(src), dst);
}
``color_converted_view`` is a GIL view transformation function that
takes any image view and returns a view in a target color space and
channel depth (specified as template parameters). In our example, it
constructs an 8-bit integer grayscale view over 32-bit float RGB
pixels. Like all other view transformation functions,
``color_converted_view`` is very fast and shallow. It doesn't copy the
data or perform any color conversion. Instead it returns a view that
performs color conversion every time its pixels are accessed.
In the generic version of this algorithm we might like to convert the
color space to grayscale, but keep the channel depth the same. We do
that by constructing the type of a GIL grayscale pixel with the same
channel as the source, and color convert to that pixel type::
template <typename SrcView, typename DstView>
void x_luminosity_gradient(const SrcView& src, const DstView& dst)
{
typedef pixel<typename channel_type<SrcView>::type, gray_layout_t> gray_pixel_t;
x_gradient(color_converted_view<gray_pixel_t>(src), dst);
}
When the destination color space and channel type happens to be the
same as the source one, color conversion is unnecessary. GIL detects
this case and avoids calling the color conversion code at all -
i.e. ``color_converted_view`` returns back the source view unchanged.
Image
~~~~~
The above example has a performance problem - ``x_gradient``
dereferences most source pixels twice, which will cause the above code
to perform color conversion twice. Sometimes it may be more efficient
to copy the color converted image into a temporary buffer and use it
to compute the gradient - that way color conversion is invoked once
per pixel. Using our non-generic version we can do it like this::
void x_luminosity_gradient(const rgb32fc_view_t& src, const gray8s_view_t& dst)
{
gray8_image_t ccv_image(src.dimensions());
copy_pixels(color_converted_view<gray8_pixel_t>(src), view(ccv_image));
x_gradient(const_view(ccv_image), dst);
}
First we construct an 8-bit grayscale image with the same dimensions
as our source. Then we copy a color-converted view of the source into
the temporary image. Finally we use a read-only view of the temporary
image in our ``x_gradient algorithm``. As the example shows, GIL
provides global functions ``view`` and ``const_view`` that take an
image and return a mutable or an immutable view of its pixels.
Creating a generic version of the above is a bit trickier::
template <typename SrcView, typename DstView>
void x_luminosity_gradient(const SrcView& src, const DstView& dst)
{
typedef typename channel_type<DstView>::type d_channel_t;
typedef typename channel_convert_to_unsigned<d_channel_t>::type channel_t;
typedef pixel<channel_t, gray_layout_t> gray_pixel_t;
typedef image<gray_pixel_t, false> gray_image_t;
gray_image_t ccv_image(src.dimensions());
copy_pixels(color_converted_view<gray_pixel_t>(src), view(ccv_image));
x_gradient(const_view(ccv_image), dst);
}
First we use the ``channel_type`` metafunction to get the channel type
of the destination view. A metafunction is a function operating on
types. In GIL metafunctions are class templates (declared with
``struct`` type specifier) which take their parameters as template
parameters and return their result in a nested typedef called
``type``. In this case, ``channel_type`` is a unary metafunction which
in this example is called with the type of an image view and returns
the type of the channel associated with that image view.
GIL constructs that have an associated pixel type, such as pixels,
pixel iterators, locators, views and images, all model
``PixelBasedConcept``, which means that they provide a set of
metafunctions to query the pixel properties, such as ``channel_type``,
``color_space_type``, ``channel_mapping_type``, and ``num_channels``.
After we get the channel type of the destination view, we use another
metafunction to remove its sign (if it is a signed integral type) and
then use it to generate the type of a grayscale pixel. From the pixel
type we create the image type. GIL's image class is specialized over
the pixel type and a boolean indicating whether the image should be
planar or interleaved. Single-channel (grayscale) images in GIL must
always be interleaved. There are multiple ways of constructing types
in GIL. Instead of instantiating the classes directly we could have
used type factory metafunctions. The following code is equivalent::
template <typename SrcView, typename DstView>
void x_luminosity_gradient(const SrcView& src, const DstView& dst)
{
typedef typename channel_type<DstView>::type d_channel_t;
typedef typename channel_convert_to_unsigned<d_channel_t>::type channel_t;
typedef typename image_type<channel_t, gray_layout_t>::type gray_image_t;
typedef typename gray_image_t::value_type gray_pixel_t;
gray_image_t ccv_image(src.dimensions());
copy_and_convert_pixels(src, view(ccv_image));
x_gradient(const_view(ccv_image), dst);
}
GIL provides a set of metafunctions that generate GIL types -
``image_type`` is one such meta-function that constructs the type of
an image from a given channel type, color layout, and
planar/interleaved option (the default is interleaved). There are also
similar meta-functions to construct the types of pixel references,
iterators, locators and image views. GIL also has metafunctions
``derived_pixel_reference_type``, ``derived_iterator_type``,
``derived_view_type`` and ``derived_image_type`` that construct the
type of a GIL construct from a given source one by changing one or
more properties of the type and keeping the rest.
From the image type we can use the nested typedef ``value_type`` to
obtain the type of a pixel. GIL images, image views and locators have
nested typedefs ``value_type`` and ``reference`` to obtain the type of
the pixel and a reference to the pixel. If you have a pixel iterator,
you can get these types from its ``iterator_traits``. Note also the
algorithm ``copy_and_convert_pixels``, which is an abbreviated version
of ``copy_pixels`` with a color converted source view.
Virtual Image Views
~~~~~~~~~~~~~~~~~~~
So far we have been dealing with images that have pixels stored in
memory. GIL allows you to create an image view of an arbitrary image,
including a synthetic function. To demonstrate this, let us create a
view of the Mandelbrot set. First, we need to create a function
object that computes the value of the Mandelbrot set at a given
location (x,y) in the image::
// models PixelDereferenceAdaptorConcept
struct mandelbrot_fn
{
typedef point2<ptrdiff_t> point_t;
typedef mandelbrot_fn const_t;
typedef gray8_pixel_t value_type;
typedef value_type reference;
typedef value_type const_reference;
typedef point_t argument_type;
typedef reference result_type;
BOOST_STATIC_CONSTANT(bool, is_mutable=false);
mandelbrot_fn() {}
mandelbrot_fn(const point_t& sz) : _img_size(sz) {}
result_type operator()(const point_t& p) const
{
// normalize the coords to (-2..1, -1.5..1.5)
double t=get_num_iter(point2<double>(p.x/(double)_img_size.x*3-2, p.y/(double)_img_size.y*3-1.5f));
return value_type((bits8)(pow(t,0.2)*255)); // raise to power suitable for viewing
}
private:
point_t _img_size;
double get_num_iter(const point2<double>& p) const
{
point2<double> Z(0,0);
for (int i=0; i<100; ++i) // 100 iterations
{
Z = point2<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y);
if (Z.x*Z.x + Z.y*Z.y > 4)
return i/(double)100;
}
return 0;
}
};
We can now use GIL's ``virtual_2d_locator`` with this function object
to construct a Mandelbrot view of size 200x200 pixels::
typedef mandelbrot_fn::point_t point_t;
typedef virtual_2d_locator<mandelbrot_fn,false> locator_t;
typedef image_view<locator_t> my_virt_view_t;
point_t dims(200,200);
// Construct a Mandelbrot view with a locator, taking top-left corner (0,0) and step (1,1)
my_virt_view_t mandel(dims, locator_t(point_t(0,0), point_t(1,1), mandelbrot_fn(dims)));
We can treat the synthetic view just like a real one. For example,
let's invoke our ``x_gradient`` algorithm to compute the gradient of
the 90-degree rotated view of the Mandelbrot set and save the original
and the result::
gray8s_image_t img(dims);
x_gradient(rotated90cw_view(mandel), view(img));
// Save the Mandelbrot set and its 90-degree rotated gradient (jpeg cannot save signed char; must convert to unsigned char)
jpeg_write_view("mandel.jpg",mandel);
jpeg_write_view("mandel_grad.jpg",color_converted_view<gray8_pixel_t>(const_view(img)));
Here is what the two files look like:
.. image:: images/mandel.jpg
Run-Time Specified Images and Image Views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So far we have created a generic function that computes the image
gradient of an image view template specialization. Sometimes,
however, the properties of an image view, such as its color space and
channel depth, may not be available at compile time. GIL's
``dynamic_image`` extension allows for working with GIL constructs
that are specified at run time, also called _variants_. GIL provides
models of a run-time instantiated image, ``any_image``, and a run-time
instantiated image view, ``any_image_view``. The mechanisms are in
place to create other variants, such as ``any_pixel``,
``any_pixel_iterator``, etc. Most of GIL's algorithms and all of the
view transformation functions also work with run-time instantiated
image views and binary algorithms, such as ``copy_pixels`` can have
either or both arguments be variants.
Lets make our ``x_luminosity_gradient`` algorithm take a variant image
view. For simplicity, let's assume that only the source view can be a
variant. (As an example of using multiple variants, see GIL's image
view algorithm overloads taking multiple variants.)
First, we need to make a function object that contains the templated
destination view and has an application operator taking a templated
source view::
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
template <typename DstView>
struct x_gradient_obj
{
typedef void result_type; // required typedef
const DstView& _dst;
x_gradient_obj(const DstView& dst) : _dst(dst) {}
template <typename SrcView>
void operator()(const SrcView& src) const { x_luminosity_gradient(src, _dst); }
};
The second step is to provide an overload of ``x_luminosity_gradient``
that takes image view variant and calls GIL's ``apply_operation``
passing it the function object::
template <typename SrcViews, typename DstView>
void x_luminosity_gradient(const any_image_view<SrcViews>& src, const DstView& dst)
{
apply_operation(src, x_gradient_obj<DstView>(dst));
}
``any_image_view<SrcViews>`` is the image view variant. It is
templated over ``SrcViews``, an enumeration of all possible view types
the variant can take. ``src`` contains inside an index of the
currently instantiated type, as well as a block of memory containing
the instance. ``apply_operation`` goes through a switch statement
over the index, each case of which casts the memory to the correct
view type and invokes the function object with it. Invoking an
algorithm on a variant has the overhead of one switch
statement. Algorithms that perform an operation for each pixel in an
image view have practically no performance degradation when used with
a variant.
Here is how we can construct a variant and invoke the algorithm::
#include <boost/mpl/vector.hpp>
#include <boost/gil/extension/io/jpeg_dynamic_io.hpp>
typedef mpl::vector<gray8_image_t, gray16_image_t, rgb8_image_t, rgb16_image_t> my_img_types;
any_image<my_img_types> runtime_image;
jpeg_read_image("input.jpg", runtime_image);
gray8s_image_t gradient(runtime_image.dimensions());
x_luminosity_gradient(const_view(runtime_image), view(gradient));
jpeg_write_view("x_gradient.jpg", color_converted_view<gray8_pixel_t>(const_view(gradient)));
In this example, we create an image variant that could be 8-bit or
16-bit RGB or grayscale image. We then use GIL's I/O extension to load
the image from file in its native color space and channel depth. If
none of the allowed image types matches the image on disk, an
exception will be thrown. We then construct a 8 bit signed
(i.e. ``char``) image to store the gradient and invoke ``x_gradient``
on it. Finally we save the result into another file. We save the view
converted to 8-bit unsigned, because JPEG I/O does not support signed
char.
Note how free functions and methods such as ``jpeg_read_image``,
``dimensions``, ``view`` and ``const_view`` work on both templated and
variant types. For templated images ``view(img)`` returns a templated
view, whereas for image variants it returns a view variant. For
example, the return type of ``view(runtime_image)`` is
``any_image_view<Views>`` where ``Views`` enumerates four views
corresponding to the four image types. ``const_view(runtime_image)``
returns a ``any_image_view`` of the four read-only view types, etc.
A warning about using variants: instantiating an algorithm with a
variant effectively instantiates it with every possible type the
variant can take. For binary algorithms, the algorithm is
instantiated with every possible combination of the two input types!
This can take a toll on both the compile time and the executable size.
Conclusion
~~~~~~~~~~
This tutorial provides a glimpse at the challenges associated with
writing generic and efficient image processing algorithms in GIL. We
have taken a simple algorithm and shown how to make it work with image
representations that vary in bit depth, color space, ordering of the
channels, and planar/interleaved structure. We have demonstrated that
the algorithm can work with fully abstracted virtual images, and even
images whose type is specified at run time. The associated video
presentation also demonstrates that even for complex scenarios the
generated assembly is comparable to that of a C version of the
algorithm, hand-written for the specific image types.
Yet, even for such a simple algorithm, we are far from making a fully
generic and optimized code. In particular, the presented algorithms
work on homogeneous images, i.e. images whose pixels have channels
that are all of the same type. There are examples of images, such as a
packed 565 RGB format, which contain channels of different
types. While GIL provides concepts and algorithms operating on
heterogeneous pixels, we leave the task of extending x_gradient as an
exercise for the reader. Second, after computing the value of the
gradient we are simply casting it to the destination channel
type. This may not always be the desired operation. For example, if
the source channel is a float with range [0..1] and the destination is
unsigned char, casting the half-difference to unsigned char will
result in either 0 or 1. Instead, what we might want to do is scale
the result into the range of the destination channel. GIL's
channel-level algorithms might be useful in such cases. For example,
\p channel_convert converts between channels by linearly scaling the
source channel value into the range of the destination channel.
There is a lot to be done in improving the performance as
well. Channel-level operations, such as the half-difference, could be
abstracted out into atomic channel-level algorithms and performance
overloads could be provided for concrete channel
types. Processor-specific operations could be used, for example, to
perform the operation over an entire row of pixels simultaneously, or
the data could be pre-fetched. All of these optimizations can be
realized as performance specializations of the generic
algorithm. Finally, compilers, while getting better over time, are
still failing to fully optimize generic code in some cases, such as
failing to inline some functions or put some variables into
registers. If performance is an issue, it might be worth trying your
code with different compilers.
Appendix
--------
Naming convention for GIL concrete types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Concrete (non-generic) GIL types follow this naming convention:
_ColorSpace_ + _BitDepth_ + [``f`` | ``s``]+ [``c``] + [``_planar``] +
[``_step``] + _ClassType_ + ``_t``
Where _ColorSpace_ also indicates the ordering of components. Examples
are ``rgb``, ``bgr``, ``cmyk``, ``rgba``. _BitDepth_ indicates the
bit depth of the color channel. Examples are ``8``,``16``,``32``. By
default the type of channel is unsigned integral; using ``s``
indicates signed integral and ``f`` - a floating point type, which is
always signed. ``c`` indicates object operating over immutable
pixels. ``_planar`` indicates planar organization (as opposed to
interleaved). ``_step`` indicates special image views, locators and
iterators which traverse the data in non-trivial way (for example,
backwards or every other pixel). _ClassType_ is ``_image`` (image),
``_view`` (image view), ``_loc`` (pixel 2D locator) ``_ptr`` (pixel
iterator), ``_ref`` (pixel reference), ``_pixel`` (pixel value).
examples::
bgr8_image_t a; // 8-bit interleaved BGR image
cmyk16_pixel_t b; // 16-bit CMYK pixel value;
cmyk16c_planar_ref_t c(b); // const reference to a 16-bit planar CMYK pixel.
rgb32f_planar_step_ptr_t d; // step pointer to a 32-bit planar RGB pixel.

View File

@@ -1,16 +1,9 @@
<!--
Copyright 2009 Daniel James.
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/index.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/index.html">doc/index.html</a>
</body>
<head>
<meta http-equiv="refresh" content="0; URL=doc/index.html"/>
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/index.html">doc/index.html</a>
</body>
</html>