\section{Introduction}
\mylabel{sec:cpp}

This chapter describes the C++ API for the VIPS image processing library.
The C++ API is as efficient as the C interface to VIPS, but is
far easier to use: almost all creation, destruction and error handling issues
are handled for you automatically.

The Python interface is a very simple wrapping of this C++ API generated
automatically with SWIG. It adds a few utility methods noted below, but
otherwise the two interfaces are identical other than language
syntax.

\subsection{If you've used the C API}

To show how much easier the VIPS C++ API is to use, compare \fref{fg:negative}
to \fref{fg:invert-c++}. \fref{fg:invert-py} is the same thing in Python.

A typical build line for the C++ program might be:

\begin{verbatim}
g++ invert.cc \
  `pkg-config vipsCC-7.18 \
    --cflags --libs` 
\end{verbatim}

The key points are:

\begin{itemize}

\item
You just include \verb+<vips/vips>+ --- this then gets all of the
other includes you need. Everything is in the \verb+vips+ namespace.

\item
The C++ API replaces all of the VIPS C types --- \verb+IMAGE+ becomes
\verb+VImage+ and so on. The C++ API also includes \verb+VDisplay+,
\verb+VMask+ and \verb+VError+.

\item
Image processing operations are member functions of the \verb+VImage+ class
--- here, \verb+VImage( argv[1] )+ creates a new \verb+VImage+ object using
the first argument to initialise it (the input filename). It then calls the
member function \verb+invert()+, which inverts the \verb+VImage+ and returns a
new \verb+VImage+.  Finally it calls the member function \verb+write()+, which
writes the result image to the named file.

\item
The VIPS C++ API uses exceptions --- the \verb+VError+ class is covered
later. If you run this program with a bad input file, for example, you get the
following output:

\begin{verbatim}
$ invert jim fred
invert: VIPS error: format_for_file: 
  file "jim" not found
\end{verbatim}

\end{itemize}

\begin{fig2}
\begin{verbatim}
#include <iostream>
#include <vips/vips>

int
main (int argc, char **argv)
{
  if (argc != 3)
    {
      std::cerr << "usage: " << argv[0] << " infile outfile\n";
      return (1);
    }

  try
  {
    vips::VImage fred (argv[1]);

    fred.invert ().write (argv[2]);
  }
  catch (vips::VError e)
  {
    e.perror (argv[0]);
  }

  return (0);
}
\end{verbatim}
\caption{\texttt{invert} program in C++}
\label{fg:invert-c++}
\end{fig2}

\begin{fig2}
\begin{verbatim}
#!/usr/bin/python

import sys
from vipsCC import *

try:
  a = VImage.VImage (sys.argv[1])
  a.invert ().write (sys.argv[2])
except VError.VError, e:
  e.perror (sys.argv[0])
\end{verbatim}
\caption{\texttt{invert} program in Python}
\label{fg:invert-py}
\end{fig2}
