split to trunk/branches

This commit is contained in:
John Cupitt 2007-08-29 16:23:50 +00:00
commit 5494f610e2
1109 changed files with 143498 additions and 0 deletions

19
AUTHORS Normal file
View File

@ -0,0 +1,19 @@
Authors of VIPS
See also the files THANKS and ChangeLog
Nicos Dessipris and Kirk Martinez started VIPS in 1990.
John Cupitt started ip in late 1990, and took over maintenance of the VIPS
library in 1995.
Ruven Pillay, Steve Perry, Lars Raffelt, David Saunders, Jean-Philippe
Laurant, Ahmed Abood, Helene Chahine, Joe Padfield, Andrey Kiselev, Lev
Serebryakov, Simon Goodall, Konrad Lang, Markus Wollgarten, Jesper Friis
and others contributed patches for the library and ip.
Hans Breuer contributed many win32 compatibility fixes and a win32 build
system. Dennis Lubert cleaned up the C++ API.
Jose Manuel Menendez Garcia, Javier Alejandre Arenas, and Juan Torres Arjona
contributed the tmake VIPS.DLL build system and the MSVC project files.

504
COPYING Normal file
View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

1511
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

182
INSTALL Normal file
View File

@ -0,0 +1,182 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

56
Makefile.am Normal file
View File

@ -0,0 +1,56 @@
# only build in the python dir if we can
if HAVE_PYTHON
P_COMPILE_DIR = python
P_DIST_DIR =
else
P_COMPILE_DIR =
P_DIST_DIR = python
endif
SUBDIRS = \
libsrc \
src \
include \
libsrcCC \
contrib \
po \
$(P_COMPILE_DIR)
EXTRA_DIST = \
doc \
benchmark \
bootstrap.sh \
win32 \
vipsCC-7.12.pc.in \
vips-7.12.pc.in \
vips-7.12.spec.in \
acinclude.m4 \
depcomp \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
$(P_DIST_DIR)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = vips-7.12.pc vipsCC-7.12.pc
install-exec-hook:
-rm -rf ${DESTDIR}$(datadir)/doc/vips
$(mkinstalldirs) ${DESTDIR}$(datadir)/doc/vips
-cp -r ${top_srcdir}/doc/html ${top_srcdir}/doc/pdf ${DESTDIR}$(datadir)/doc/vips
dist-hook:
# make sure we don't get any .svn dirs from EXTRA_DIST
-find $(distdir) -name .svn -exec rm -rf {} \;
uninstall-hook:
# make sure we have write permission for 'rm'
-chmod -R u+w ${DESTDIR}$(datadir)/doc/vips
-rm -rf ${DESTDIR}$(datadir)/doc/vips
distclean-local:
# need to remove expanded intltool files in build area to pass distcheck
-rm ${top_builddir}/intltool-extract \
${top_builddir}/intltool-merge \
${top_builddir}/intltool-update

232
NEWS Normal file
View File

@ -0,0 +1,232 @@
VIPS changed from 7.10 to 7.12 (not exhaustive, see ChangeLog for details)
Non-backwards compatible changes
================================
- IMAGE->Hist is deprecated, use im_history_get() instead
- im_append_Hist() removed
- IMAGE->Bbits is deprecated (now ignored)
- im_region_local() replaced by im_region_buffer()
VIPS enhancements
=================
- new backwards and forwards compatible VIPS file format: it has a new
metadata system that efficiently shares and propogates ICC profiles,
EXIF data, etc. & whatever
- speed ups: new pixel buffer cache saves and reuses computations, uses liboil
where possible for a small speedup
- SMP scaling: simplified lock system improves SMP scaling, double-buffered
image writes overlap computation
- lower mem use: new mmap window cache shares file mappings, history buffers
share and reuse image history metadata
- built-in support for new image formats: OpenEXR, Analyze7, CSV
- RGB16 and GREY16 image hints
- uses GOption for much better command-line argument handling
- better C++ binding: namespaces, VError derives from std::exception, image
and number vector constants
- python binding
- gcc sentinel attributes added
- added GValue as an arg type
- added im_benchmark() and friends for testing
- new functions:
im_analyze2vips(), im_benchmark*(), im_buildlut(),
im_concurrency_get/set(), im_contrast_surface(),
im_contrast_surface_raw(), im_copy_from(), im_copy_morph(),
im_cp_desc_array(), im_cp_descv(), im_extract_areabands(),
im_flood_blob_copy(), im_get_option_group(), im_grid(),
im_header_exists(), im_header_map(), im_history_get(),
im_invalidate(), im_isscalar(), im_lineset(), im_linreg(),
im_meta*(), im_msb(), im_norm_dmask(), im_project(),
im_raw2vips(), IM_REGION_ADDR_TOPLEFT(), im_tile_cache(),
im_video_test()
VIPS changed from 7.8 to 7.10 (not exhaustive, see ChangeLog for details)
Non-backwards compatible changes
================================
- no longer generates vips-config script, instead it makes .pc files for
pkg-config ... replace any "vips-config" with "pkg-config vips-7.10"
- origin hint semantics changed ... it now records the position in the output
image of the origin of the input image
- all float to int casts on pixel values are now floor() rather than rint(),
for consistency with C casting semantics
VIPS enhancements
=================
- nip reworked for gtk+-2.4, now called nip2
- now based on glib, so VIPS no longer has it's own thread, plugin and data
structure libraries
- i18n support, although not quite complete yet
- new error message API to make i18n possible (compatibility macros mean the
old API still works)
- new 'start up VIPS' call, im_init_world(), sets up i18n and threads
(optional to call it, but i18n won't fully work unless you do)
- C programs now just need "#include <vips/vips.h>", no other includes
required
- wraps the Pango font rendering library, see im_text()
- new function flag: NOCACHE ... means the result of the call should not be
cached, useful for video grab functions and paintbox functions
- im_embed() now supports a wider range of embedding styles, including a fast
edge stretch
- all area operations use the new embed style to expand their input rather
than their output, so there are no more black borders on filtered images
- other new functions: im_render(), im_cache(), im_extract_bands(),
im_copy_swap(), im_rint(), im_make_xy(), im_init_world(), im_error(),
im_warn(), im_diag(), im_rank_image(), im_replicate()
- many fixes and improvements to old funcs
- configure and portability improvements
Bug fixes
=========
- all serious bug fixes got back-ported to 7.8, I think
VIPS changes from 7.6 to 7.8 (again, not exhaustive, see ChangeLog for details)
Non-backwards compatible changes
================================
- output format options specified in filenames: new prototypes for load and
save tiff and jpeg
- C++ API name changes ... error => VError
- include path change
- C includes <vips/vips.h>
- C++ includes <vips/vipscpp.h>
- im_extract*() numbers bands from zero, not from 1 ... also other funcs which
refer to bands (eg. im_lrmosaic() etc.)
- mosaic funcs have extra max blend width parameter
VIPS enhancements
=================
- rewritten and much fancier ip (see separate docs), now called nip ... old ip
(slightly fixed) still there
- mmap windows remove 2GB image size limit
- images have an origin hint field
- icc transforms supported via wrapping of Little CMS
- much, much faster Fourier transforms via wrapping of libfwfft
- ppm/pgm/pbm read/write
- C++ API enhancements: new constructors, more operator equivalences
- new colourspace: Yxy
- support for D50 colour temperature images
- new functions: im_image(), im_system(), im_version*(), im_blend(),
im_copy_set(), im_flood_blob(), im_icc_*(), im_open_local_array(),
im_header_*(), im_sign(), im_ceil(), im_floor(), im_remainderconst*(),
im_print(), im_guess_prefix(), im_remosaic(), im_invertlut(), Yxy funcs,
color temperature funcs, im_clip2fmt(), im_blend(), im_lab_morph(),
im_histnorm(), im_histcum(), im_video_v4l(), im_LabS2Lab(), im_Lab2LabS()
- new type: IMAGEVEC
- header is much faster
- ip/nip split to separate packages
- better vips2dj
- better cygwin support, mingw support too
- Mac OS X and Windows build support
- new set of sensible #define names, old names can be turned off with
-DIM_NO_VIPS7_COMPAT
- many configure improvements
Bug fixes
=========
- speed ups
- fixes to implicit image format conversions
- im_zoom() spots integer overflow
- im_LabS2LabQ() rounding on a/b slightly broken for a/b == 0
- fixes to refcounting in C++ API
- mask casts in C++ were broken
VIPS Changes for 7.4 to 7.6
Non-backwards compatible changes
================================
- im_histplot() has new (and better) rules
- im_andconst(), im_orconst() and im_eorconst() now take a
double, not an unsigned char, as their constant argument type
- im_global_balance_float() renamed as im_global_balancef() to be
more consistent with other functions
- im_global_balance_search() removed ... you can do this efficiently
with an ip macro now
- new parameter "gamma" to im_global_balance() and
im_global_balancef() ... sets the gamma for the input device with
which the images were captured, set to 1.0 for old behaviour
- im_malloc() now returns void *, not char *
Bug fixes
=========
- tiny memory leak in im_list_remove() fixed
- oops, the value for sRGB in the header was wrong, now 22
- missing function descriptor for im_rank_raw()
- im_dECMC_fromLab() was broken
- im_erode() and im_dilate() output incorrect error messages
if mask elements were not one of 0, 128, 255
- im_rotate_*mask*() functions were not preserving scale and offset
values
Package enhancements
====================
The whole thing is now GPL, with GNU configure
ip changes
==========
- better display control bar
- matrix operations now appear in the workspace
- new UI elements: input options and toggles
- better LUT optimisation --- arithmetic operations on UCHAR images should be
much faster
- new macro language --- same as old one, but faster and much more powerful
- all standard menus rewritten in new macro language, much nicer!
- batch operations with Group/Ungroup
- now uses GDK for drawing in image windows, much better colour handling on
8/16-bit graphics cards
- image repaint is now threaded for an about-linear speedup as you add
more CPUs
- many interface improvements and polishes
VIPS enhancements
=================
- VIPS now uses POSIX threads (7.4 used Solaris threads) and has been rejigged
to provide a nice threading API to functions which call the library
- im_open() now knows about LSB- and MSB- first VIPS images, and
silently converts them to native order ... it also now ignores case when
deciding what format to write
- new parameter type IM_INPUT_REALVEC, a vector of doubles
- new set of functions with vector constants: im_lintra_vec(),
im_powtra_vec(), im_expntra_vec(), all relational
(im_equal_vec(), im_notequal_vec(), etc.), all boolean
(im_and_vec() etc.)
- new flag for function descriptors: "IM_FN_PTOP" set for point-to-point
functions ... makes ip use LUTs for operation
- im_tiff2vips() now reads and writes 16-bit images, and knows about zip
(deflate) compression
- convenience functions im_extract_band() extracts a band from an image;
im_extract_area() extracts an area
- im_list_member() tests for list contains object
- new functions im_write_*mask_name(), im_create_*maskv()
_ new functions im_remainder() and im_profile()
- fourier filtering, forward transform, reverse transform, make power spectrum
all free memory more quickly, making them suitable for very large images
- new functions im_isMSBfirst() and im_amiMSBfirst() test images
and this processor for MSB first byte order
- im_malloc() now prints low-on-memory warnings to stderr with
im_warning() for easier bug catching
- D65_X0 updated for latest recommedations, D60, D93,
D55, D50, A, B, C added
- minor fixes to the C++ interface to bring it in line with the newer ANSI
standards
- more and more comprehensive prototypes in "proto.h" to aid C++ (use of
"const" etc.)
- im_and*(), im_or*() and im_eor*() can now work on any
integer image

143
README Normal file
View File

@ -0,0 +1,143 @@
VIPS 7.12
=========
VIPS is an image processing library. It's good for large images and for
colour. There's a GUI as well, see the VIPS website:
http://www.vips.ecs.soton.ac.uk
Getting VIPS from SVN
=====================
Enter:
svn co https://vips.svn.sourceforge.net/svnroot/vips/vips7
Building VIPS from source
=========================
In the VIPS directory, you should just be able to do:
user% ./configure
user% make
then as root:
root% make install
By default this will install files to /usr/local/bin, /usr/local/share/vips,
/usr/local/include, /usr/local/lib and /usr/local/man.
If you have problems, read on.
Building VIPS on win32
----------------------
Probably the easiest route is to use mingw/msys. This provides a GNU-style
build environment for win32.
http://www.vips.ecs.soton.ac.uk/index.php?title=Build_on_windows
Alternatively, vips-7.x/win32 contains sample build systems using the
Microsoft toolchain. See the README in there for details.
Building VIPS on OS X
---------------------
I used macports to install all the dependencies. Fink also works.
http://www.macports.org
You need to tell configure to use the msgfmt from macports. Something like:
GMSGFMT="/opt/local/bin/msgfmt" ./configure --prefix=/Users/john/vips
Dependencies
============
VIPS has to have glib-2.x and libxml-2.0. The build system needs perl,
pkg-config and gnu make.
Optional dependencies
---------------------
Optional support libraries ... also try ./configure --help to see flags for
controlling these libs. By default, if suitable versions are found, VIPS will
build support for them automatically.
VIPS looks for stuff in /usr. If you have installed you own versions of these
libraries to /usr/local, vips will not see them. Use switches to VIPS
configure like:
./configure --prefix=/home/john/vips \
--with-tiff-includes=/home/john/vips/include \
--with-tiff-libraries=/home/john/vips/lib
to get VIPS to see your builds.
libjpeg
The IJG JPEG library. We use 6b, but 6a works too.
libexif
if available, VIPS adds support for EXIF metadata in JPEG files
libtiff
The TIFF library. It needs to be built with support for JPEG and
ZIP compression. 3.4b037 and later are known to be OK.
You'll need libz for this too. We use 1.1.3, others should work.
libz
If your TIFF library includes ZIP compression, you'll need this too.
videodev.h
If VIPS finds linux/videodev.h, you get support for Linux video
grabbing.
fftw3
If VIPS finds this library, it uses it for fourier transforms. It can
also use fftw2, but 3 is faster and more accurate.
If the library is not found, VIPS falls back to it's own internal FFT
routines which are slower and less accurate.
lcms
If present, im_icc_import(), _export() and _transform() are available
for transforming images with ICC profiles.
large files
VIPS uses the standard autoconf tests to work out how to support large
files (>2GB) on your system. Any reasonably recent *nix should be OK.
libpng
if present, VIPS can load and save png files. Version 1.2+ preferred.
libMagick
if available, VIPS adds support for loading all libMagick supported
image file types (about 80 different formats). No saving though.
pango
freetype2
fontconfig
if available, VIPS adds support for text rendering. You need the
package pangoft2 in "pkg-config --list-all"
liboil
if available, you get some inner loops replcaed by calls to liboil's
library of optimised inner loops
OpenEXR
if available, VIPS will directly read (but not write, sadly) OpenEXR
images
swig
python
python-dev
if available, we build the python binding too
Disclaimer
----------
Disclaimer: No guarantees of performance accompany this software, nor is any
responsibility assumed on the part of the authors. Please read the licence
agreement.

25
THANKS Normal file
View File

@ -0,0 +1,25 @@
VIPS THANKS file
VIPS was originally written by Nicos Dessipris, Kirk Martinez and John Cupitt.
Many people have contributed to VIPS by reporting problems, suggesting
improvements, or offering code.
Matthew Hanson
Joe Padfield
Haida Liang
Ian Clarke
Steve Perry
Stephen Chang
David Saunders
Mike Westmacott
Chris Hurst
Jim Coddington
Lou
Rachel Billinge
Colin White
ENST
Thomson-CSF
We've also had very helpful funding from the European Commission and
Hewlett-Packard.

147
TODO Normal file
View File

@ -0,0 +1,147 @@
- when we fork for 7.13 do this stuff ... don't do now, we'll break the other
packages
http://www.freshports.org/graphics/vips
freebsd packaging now does:
In both:
- use explict --mandir=${PREFIX}/man to avoid man-pages getting
into ${PREFIX}/shared/man incorrectly
- deal with the NOPORTDOCS situation by simply not-extracting
the extra documentation from the distribution tarball
- parallelize the build to scale with the number of CPUs
In vips:
- move the (giant) list of man-pages into a separate Makefile.man
- turn the pages, which contain only `.so other-page', into
MANLINKS (specified in Makefile.man)
- provide a "maintainance target" to regenerate the Makefile.man
during the next upgrade
- do not install the HTML-ized versions of man-pages
- create OPTIONS for use of devel/liboil and graphics/ImageMagick
(OPTION to use PYTHON awaits portmgr's decision/action)
In nip2:
- do install the HTML pages regardless of NOPORTDOCS -- these
are accessible to the user through the application GUI
- arrange for update-mime-database and update-desktop-database
to be run upon install (@exec) and uninstall (@unexec)
- LIB_DEPEND on math/gsl, which nip2 can use for extra functionality
Python binding
==============
- python startup fails with plugins in vipslib:
Fatal Python error: can't initialise module vips
plugin: unable to open plugin "/home/john/vips/lib/resample.plg"
plugin: /home/john/vips/lib/resample.plg: undefined symbol: im_start_one
do we need to build plugins with -rpath etc. and more libs?
or do we need to make sure our python modules export all their im_ symbols?
WONTFIX
=======
- TIFF load/save should use meta system for unknown tags
- balance should use new meta stuff
- magick2vips should spot ICC profiles and attach them as meta
- magick should set some header field for n_frames and frame_height? see also
analyze
- see TODO notes in openexr read (though they all need more openexr C API)
consider openexr write
- matrix invert is a copypaste of NR :-( fix this
- add GREYCstoration filter
http://www.haypocalc.com/wiki/Gimp_Plugin_GREYCstoration
actually, it has to be a plugin, since their code is GPL
and very memory-hungry for large images :-( needs 20x size of image to be
processed
could we rewrite with VIPS? how much more stuff would we need to add?
try again using the current version of the filter from the suthors rather
than the gimp plugin
- im_csv2vips() could use "-" for filename to mean stdin
but then we'd have to read to a malloced buffer of some sort rather than an
image, since we might need to grow it during the read, since we couldn't
then seek
- add erode/dilate 3x3 special case using a 512-bit LUT
... nope, actually slower :-( we end up doing an inner loop like
for( i = 0; i < 9; i++ )
bits |= (p[o[i]] != 0) << i;
which is horrible. Maybe if we had a one band true 1 bit image it'd be
quicker since we could get bits out in parallel and wouldn't have to worry
about converting non-zero to 1
could have a Coding type for bitpack? eg. relational produces a bitpack
image by default, boolean & morph can work on bitpack etc
maybe something for vips8 ... we could have a flag on operations for the
coding types they can accept, and if they are passed other type, they are
automatically converted
- non-linear sharpen: replace each pixel by the lightest or darkest neighbour
depending on which is closer in value
- can wrap other inplace funcs which use ink now we have vector_to_ink() in
inplace_dispatch.c
see also comments in nip2 TODO ... we could auto-wrap in vips_call.c
cleaner!
- on win32, should not write matrix files in binary mode, we want CR/LF chars
so we can load into excel etc easily
how odd, we're doing
if( !(fp = fopen( name, "w" )) ) {
shouldn't be binary ... hmm
Build
=====
- xmlFree() is still broken :-(
maybe we are not importing it correctly? im_readhist.c references
_imp__xmlFree
how is this made? look at gcc -E output ... maybe there's an extra define we
need to make it generate the right link code?
see what libxml2.dll.a is exporting that looks anything like xmlFree
- can we make a fftw3.dll? also, magick.dll?
maybe just build with no-undefined? can we then link the DLL against the
static lib?
- update gtk/glib/etc. on the PC to the latest versions, apparently much
quicker (esp. pango)
This TODO list is now held on the VIPS Wiki
http://wiki.vips.ecs.soton.ac.uk/bin/view/Vips/TodoVips7

584
acinclude.m4 Normal file
View File

@ -0,0 +1,584 @@
dnl From FIND_MOTIF and ACX_PTHREAD, without much understanding
dnl
dnl FIND_ZIP[ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]
dnl ------------------------------------------------
dnl
dnl Find ZIP libraries and headers
dnl
dnl Put includes stuff in ZIP_INCLUDES
dnl Put link stuff in ZIP_LIBS
dnl
dnl Default ACTION-IF-FOUND defines HAVE_ZIP
dnl
AC_DEFUN([FIND_ZIP], [
AC_REQUIRE([AC_PATH_XTRA])
ZIP_INCLUDES=""
ZIP_LIBS=""
AC_ARG_WITH(zip,
[ --without-zip do not use libz])
# Treat --without-zip like --without-zip-includes --without-zip-libraries.
if test "$with_zip" = "no"; then
ZIP_INCLUDES=no
ZIP_LIBS=no
fi
AC_ARG_WITH(zip-includes,
[ --with-zip-includes=DIR ZIP include files are in DIR],
ZIP_INCLUDES="-I$withval")
AC_ARG_WITH(zip-libraries,
[ --with-zip-libraries=DIR ZIP libraries are in DIR],
ZIP_LIBS="-L$withval -lz")
AC_MSG_CHECKING(for ZIP)
# Look for zlib.h
if test "$ZIP_INCLUDES" = ""; then
zip_save_LIBS="$LIBS"
LIBS="-lz $LIBS"
# Check the standard search path
AC_TRY_COMPILE([#include <zlib.h>],[int a;],[
ZIP_INCLUDES=""
], [
# zlib.h is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/include /usr/*/include \
/usr/local/*/include \
"${prefix}"/include/* \
/usr/include/* /usr/local/include/* /*/include; do
if test -f "$dir/zlib.h"; then
ZIP_INCLUDES="-I$dir"
break
fi
done
if test "$ZIP_INCLUDES" = ""; then
ZIP_INCLUDES=no
fi
])
LIBS="$zip_save_LIBS"
fi
# Now for the libraries
if test "$ZIP_LIBS" = ""; then
zip_save_LIBS="$LIBS"
zip_save_INCLUDES="$INCLUDES"
LIBS="-lz $LIBS"
INCLUDES="$ZIP_INCLUDES $INCLUDES"
# Try the standard search path first
AC_TRY_LINK([#include <zlib.h>],[zlibVersion()], [
ZIP_LIBS="-lz"
], [
# libz is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/lib /usr/*/lib /usr/local/*/lib \
"${prefix}"/lib/* /usr/lib/* \
/usr/local/lib/* /*/lib; do
if test -d "$dir" && test "`ls $dir/libz.* 2> /dev/null`" != ""; then
ZIP_LIBS="-L$dir -lz"
break
fi
done
if test "$ZIP_LIBS" = ""; then
ZIP_LIBS=no
fi
])
LIBS="$zip_save_LIBS"
INCLUDES="$zip_save_INCLUDES"
fi
AC_SUBST(ZIP_LIBS)
AC_SUBST(ZIP_INCLUDES)
# Print a helpful message
zip_libraries_result="$ZIP_LIBS"
zip_includes_result="$ZIP_INCLUDES"
if test x"$zip_libraries_result" = x""; then
zip_libraries_result="in default path"
fi
if test x"$zip_includes_result" = x""; then
zip_includes_result="in default path"
fi
if test "$zip_libraries_result" = "no"; then
zip_libraries_result="(none)"
fi
if test "$zip_includes_result" = "no"; then
zip_includes_result="(none)"
fi
AC_MSG_RESULT(
[libraries $zip_libraries_result, headers $zip_includes_result])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "$ZIP_INCLUDES" != "no" && test "$ZIP_LIBS" != "no"; then
ifelse([$1],,AC_DEFINE(HAVE_ZIP,1,[Define if you have libz libraries and header files.]),[$1])
:
else
ZIP_LIBS=""
ZIP_INCLUDES=""
$2
fi
])dnl
dnl From FIND_MOTIF and ACX_PTHREAD, without much understanding
dnl
dnl FIND_TIFF[ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]
dnl ------------------------------------------------
dnl
dnl Find TIFF libraries and headers
dnl
dnl Put compile stuff in TIFF_INCLUDES
dnl Put link stuff in TIFF_LIBS
dnl
dnl Default ACTION-IF-FOUND defines HAVE_TIFF
dnl
AC_DEFUN([FIND_TIFF], [
AC_REQUIRE([AC_PATH_XTRA])
TIFF_INCLUDES=""
TIFF_LIBS=""
AC_ARG_WITH(tiff,
[ --without-tiff do not use libtiff])
# Treat --without-tiff like --without-tiff-includes --without-tiff-libraries.
if test "$with_tiff" = "no"; then
TIFF_INCLUDES=no
TIFF_LIBS=no
fi
AC_ARG_WITH(tiff-includes,
[ --with-tiff-includes=DIR TIFF include files are in DIR],
TIFF_INCLUDES="-I$withval")
AC_ARG_WITH(tiff-libraries,
[ --with-tiff-libraries=DIR TIFF libraries are in DIR],
TIFF_LIBS="-L$withval -ltiff")
AC_MSG_CHECKING(for TIFF)
# Look for tiff.h
if test "$TIFF_INCLUDES" = ""; then
# Check the standard search path
AC_TRY_COMPILE([#include <tiff.h>],[int a;],[
TIFF_INCLUDES=""
], [
# tiff.h is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/include /usr/*/include \
/usr/local/*/include "${prefix}"/include/* \
/usr/include/* /usr/local/include/* \
/opt/include /opt/*/include /*/include; do
if test -f "$dir/tiff.h"; then
TIFF_INCLUDES="-I$dir"
break
fi
done
if test "$TIFF_INCLUDES" = ""; then
TIFF_INCLUDES=no
fi
])
fi
# Now for the libraries
if test "$TIFF_LIBS" = ""; then
tiff_save_LIBS="$LIBS"
tiff_save_INCLUDES="$INCLUDES"
LIBS="-ltiff -lm $LIBS"
INCLUDES="$TIFF_INCLUDES $INCLUDES"
# Try the standard search path first
AC_TRY_LINK([#include <tiff.h>],[TIFFGetVersion();], [
TIFF_LIBS="-ltiff"
], [
# libtiff is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/lib /usr/*/lib /usr/local/*/lib \
"${prefix}"/lib/* /usr/lib/* \
/usr/local/lib/* \
/opt/lib /opt/*/lib /*/lib; do
if test -d "$dir" && test "`ls $dir/libtiff.* 2> /dev/null`" != ""; then
TIFF_LIBS="-L$dir -ltiff"
break
fi
done
if test "$TIFF_LIBS" = ""; then
TIFF_LIBS=no
fi
])
LIBS="$tiff_save_LIBS"
INCLUDES="$tiff_save_INCLUDES"
fi
AC_SUBST(TIFF_LIBS)
AC_SUBST(TIFF_INCLUDES)
# Print a helpful message
tiff_libraries_result="$TIFF_LIBS"
tiff_includes_result="$TIFF_INCLUDES"
if test x"$tiff_libraries_result" = x""; then
tiff_libraries_result="in default path"
fi
if test x"$tiff_includes_result" = x""; then
tiff_includes_result="in default path"
fi
if test "$tiff_libraries_result" = "no"; then
tiff_libraries_result="(none)"
fi
if test "$tiff_includes_result" = "no"; then
tiff_includes_result="(none)"
fi
AC_MSG_RESULT(
[libraries $tiff_libraries_result, headers $tiff_includes_result])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "$TIFF_INCLUDES" != "no" && test "$TIFF_LIBS" != "no"; then
ifelse([$1],,AC_DEFINE(HAVE_TIFF,1,[Define if you have tiff libraries and header files.]),[$1])
:
else
TIFF_INCLUDES=""
TIFF_LIBS=""
$2
fi
])dnl
dnl From FIND_MOTIF and ACX_PTHREAD, without much understanding
dnl
dnl FIND_JPEG[ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]
dnl ------------------------------------------------
dnl
dnl Find JPEG libraries and headers
dnl
dnl Put compile stuff in JPEG_INCLUDES
dnl Put link stuff in JPEG_LIBS
dnl
dnl Default ACTION-IF-FOUND defines HAVE_JPEG
dnl
AC_DEFUN([FIND_JPEG], [
AC_REQUIRE([AC_PATH_XTRA])
JPEG_INCLUDES=""
JPEG_LIBS=""
AC_ARG_WITH(jpeg,
[ --without-jpeg do not use libjpeg])
# Treat --without-jpeg like --without-jpeg-includes --without-jpeg-libraries.
if test "$with_jpeg" = "no"; then
JPEG_INCLUDES=no
JPEG_LIBS=no
fi
AC_ARG_WITH(jpeg-includes,
[ --with-jpeg-includes=DIR JPEG include files are in DIR],
JPEG_INCLUDES="-I$withval")
AC_ARG_WITH(jpeg-libraries,
[ --with-jpeg-libraries=DIR JPEG libraries are in DIR],
JPEG_LIBS="-L$withval -ljpeg")
AC_MSG_CHECKING(for JPEG)
# Look for jpeg.h
if test "$JPEG_INCLUDES" = ""; then
jpeg_save_LIBS="$LIBS"
LIBS="-ljpeg $LIBS"
# Check the standard search path
AC_TRY_COMPILE([
#include <stdio.h>
#include <jpeglib.h>],[int a],[
JPEG_INCLUDES=""
], [
# jpeg.h is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/include \
/usr/local/include \
/usr/*/include \
/usr/local/*/include /usr/*/include \
"${prefix}"/include/* \
/usr/include/* /usr/local/include/* \
/opt/include /opt/*/include /*/include; do
if test -f "$dir/jpeglib.h"; then
JPEG_INCLUDES="-I$dir"
break
fi
done
if test "$JPEG_INCLUDES" = ""; then
JPEG_INCLUDES=no
fi
])
LIBS="$jpeg_save_LIBS"
fi
# Now for the libraries
if test "$JPEG_LIBS" = ""; then
jpeg_save_LIBS="$LIBS"
jpeg_save_INCLUDES="$INCLUDES"
LIBS="-ljpeg $LIBS"
INCLUDES="$JPEG_INCLUDES $INCLUDES"
# Try the standard search path first
AC_TRY_LINK([
#include <stdio.h>
#include <jpeglib.h>],[jpeg_abort((void*)0)], [
JPEG_LIBS="-ljpeg"
], [
# libjpeg is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/lib \
/usr/local/lib \
/usr/*/lib \
"${prefix}"/lib/* /usr/lib/* \
/usr/local/lib/* \
/opt/lib /opt/*/lib /*/lib; do
if test -d "$dir" && test "`ls $dir/libjpeg.* 2> /dev/null`" != ""; then
JPEG_LIBS="-L$dir -ljpeg"
break
fi
done
if test "$JPEG_LIBS" = ""; then
JPEG_LIBS=no
fi
])
LIBS="$jpeg_save_LIBS"
INCLUDES="$jpeg_save_INCLUDES"
fi
AC_SUBST(JPEG_LIBS)
AC_SUBST(JPEG_INCLUDES)
# Print a helpful message
jpeg_libraries_result="$JPEG_LIBS"
jpeg_includes_result="$JPEG_INCLUDES"
if test x"$jpeg_libraries_result" = x""; then
jpeg_libraries_result="in default path"
fi
if test x"$jpeg_includes_result" = x""; then
jpeg_includes_result="in default path"
fi
if test "$jpeg_libraries_result" = "no"; then
jpeg_libraries_result="(none)"
fi
if test "$jpeg_includes_result" = "no"; then
jpeg_includes_result="(none)"
fi
AC_MSG_RESULT(
[libraries $jpeg_libraries_result, headers $jpeg_includes_result])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "$JPEG_INCLUDES" != "no" && test "$JPEG_LIBS" != "no"; then
ifelse([$1],,AC_DEFINE(HAVE_JPEG,1,[Define if you have jpeg libraries and header files.]),[$1])
:
else
JPEG_INCLUDES=""
JPEG_LIBS=""
$2
fi
])dnl
dnl From FIND_MOTIF and ACX_PTHREAD, without much understanding
dnl
dnl FIND_PNG[ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]
dnl ------------------------------------------------
dnl
dnl Find PNG libraries and headers
dnl
dnl Put compile stuff in PNG_INCLUDES
dnl Put link stuff in PNG_LIBS
dnl
dnl Default ACTION-IF-FOUND defines HAVE_PNG
dnl
AC_DEFUN([FIND_PNG], [
AC_REQUIRE([AC_PATH_XTRA])
PNG_INCLUDES=""
PNG_LIBS=""
AC_ARG_WITH(png,
[ --without-png do not use libpng])
# Treat --without-png like --without-png-includes --without-png-libraries.
if test "$with_png" = "no"; then
PNG_INCLUDES=no
PNG_LIBS=no
fi
AC_ARG_WITH(png-includes,
[ --with-png-includes=DIR PNG include files are in DIR],
PNG_INCLUDES="-I$withval")
AC_ARG_WITH(png-libraries,
[ --with-png-libraries=DIR PNG libraries are in DIR],
PNG_LIBS="-L$withval -lpng")
AC_MSG_CHECKING(for PNG)
# Look for png.h
if test "$PNG_INCLUDES" = ""; then
png_save_LIBS="$LIBS"
LIBS="-lpng $LIBS"
# Check the standard search path
AC_TRY_COMPILE([
#include <png.h>],[int a],[
PNG_INCLUDES=""
], [
# png.h is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/include \
/usr/local/include \
/usr/*/include \
/usr/local/*/include /usr/*/include \
"${prefix}"/include/* \
/usr/include/* /usr/local/include/* /*/include; do
if test -f "$dir/png.h"; then
PNG_INCLUDES="-I$dir"
break
fi
done
if test "$PNG_INCLUDES" = ""; then
PNG_INCLUDES=no
fi
])
LIBS="$png_save_LIBS"
fi
# Now for the libraries
if test "$PNG_LIBS" = ""; then
png_save_LIBS="$LIBS"
png_save_INCLUDES="$INCLUDES"
LIBS="-lpng $LIBS"
INCLUDES="$PNG_INCLUDES $INCLUDES"
# Try the standard search path first
AC_TRY_LINK([
#include <png.h>],[png_access_version_number()], [
PNG_LIBS="-lpng"
], [
# libpng is not in the standard search path.
# A whole bunch of guesses
for dir in \
"${prefix}"/*/lib \
/usr/local/lib \
/usr/*/lib \
"${prefix}"/lib/* /usr/lib/* \
/usr/local/lib/* /*/lib; do
if test -d "$dir" && test "`ls $dir/libpng.* 2> /dev/null`" != ""; then
PNG_LIBS="-L$dir -lpng"
break
fi
done
if test "$PNG_LIBS" = ""; then
PNG_LIBS=no
fi
])
LIBS="$png_save_LIBS"
INCLUDES="$png_save_INCLUDES"
fi
AC_SUBST(PNG_LIBS)
AC_SUBST(PNG_INCLUDES)
# Print a helpful message
png_libraries_result="$PNG_LIBS"
png_includes_result="$PNG_INCLUDES"
if test x"$png_libraries_result" = x""; then
png_libraries_result="in default path"
fi
if test x"$png_includes_result" = x""; then
png_includes_result="in default path"
fi
if test "$png_libraries_result" = "no"; then
png_libraries_result="(none)"
fi
if test "$png_includes_result" = "no"; then
png_includes_result="(none)"
fi
AC_MSG_RESULT(
[libraries $png_libraries_result, headers $png_includes_result])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "$PNG_INCLUDES" != "no" && test "$PNG_LIBS" != "no"; then
ifelse([$1],,AC_DEFINE(HAVE_PNG,1,[Define if you have png libraries and header files.]),[$1])
:
else
PNG_INCLUDES=""
PNG_LIBS=""
$2
fi
])dnl
dnl a macro to check for ability to create python extensions
dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
dnl function also defines PYTHON_INCLUDES
AC_DEFUN([AM_CHECK_PYTHON_HEADERS],
[AC_REQUIRE([AM_PATH_PYTHON])
AC_MSG_CHECKING(for headers required to compile python extensions)
dnl deduce PYTHON_INCLUDES
py_prefix=`$PYTHON -c "import sys; print sys.prefix"`
py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"`
PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}"
if test "$py_prefix" != "$py_exec_prefix"; then
PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}"
fi
AC_SUBST(PYTHON_INCLUDES)
dnl check if the headers exist:
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES"
AC_TRY_CPP([#include <Python.h>],dnl
[AC_MSG_RESULT(found)
$1],dnl
[AC_MSG_RESULT(not found)
$2])
CPPFLAGS="$save_CPPFLAGS"
])

19
benchmark/README Normal file
View File

@ -0,0 +1,19 @@
VIPS SMP benchmark
------------------
This is adapted from the system used to generate images for POD:
http://cima.ng-london.org.uk/~john/POD
Images from a 10k by 10k studio digital camera are colour processed, resized,
cropped and sharpened.
This thing was originally processing images off a remote server over a 100mbit
network. No attempt was made to make it quick (there was no point): you
could make it a lot faster very easily.
See
http://www.vips.ecs.soton.ac.uk/index.php?title=Benchmarks
for results.

47
benchmark/benchmarkn.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/sh
uname -a
gcc --version
vips --version
# how large an image do you want to process?
# sample2.v is 290x442 pixels ... replicate this many times horizontally and
# vertically to get a highres image for the benchmark
tile=13
# how complex an operation do you want to run?
# this sets the number of copies of the benchmark we chain together:
# higher values run more slowly and are more likely to be CPU-bound
chain=1
echo building test image ...
echo "tile=$tile"
vips im_replicate sample2.v temp.v $tile $tile
if [ $? != 0 ]; then
echo "build of test image failed -- out of disc space?"
exit 1
fi
echo -n "test image is" `header -f Xsize temp.v`
echo " by" `header -f Ysize temp.v` "pixels"
echo "starting benchmark ..."
echo "chain=$chain"
for cpus in 1 2 3 ; do
export IM_CONCURRENCY=$cpus
echo IM_CONCURRENCY=$IM_CONCURRENCY
echo time -p vips im_benchmarkn temp.v temp2.v $chain
time -p vips im_benchmarkn temp.v temp2.v $chain
time -p vips im_benchmarkn temp.v temp2.v $chain
if [ $? != 0 ]; then
echo "benchmark failed -- install problem?"
exit 1
fi
# find pixel average ... should be the same for all IM_CONCURRENCY settings
# or we have some kind of terrible bug
echo vips im_avg temp2.v
vips im_avg temp2.v
done

BIN
benchmark/sample2.v Normal file

Binary file not shown.

34
bootstrap.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
# set -x
# a bunch of cleaning up ... make certain everything will be regenerated
rm -f Makefile Makefile.in aclocal.m4
rm -rf autom4te.cache
rm -f config.* configure depcomp
rm -f install-sh intltool-* libtool ltmain.sh missing mkinstalldirs
rm -f stamp-* vipsCC-7.12.pc vips-7.12.spec vips-7.12.pc
rm -f python/vipsCC/*.cxx
rm -f python/vipsCC/VImage.h
rm -f python/vipsCC/VImage.py python/vipsCC/VError.py python/vipsCC/VMask.py python/vipsCC/Display.py
rm -f benchmark/temp*
# some systems need libtoolize, some glibtoolize ... how annoying
echo testing for glibtoolize ...
if glibtoolize --version >/dev/null 2>&1; then
LIBTOOLIZE=glibtoolize
echo using glibtoolize
else
LIBTOOLIZE=libtoolize
echo using libtoolize
fi
aclocal
glib-gettextize --force --copy
test -r aclocal.m4 && chmod u+w aclocal.m4
intltoolize --copy --force --automake
autoconf
autoheader
$LIBTOOLIZE --copy --force --automake
automake --add-missing --copy

382
configure.in Normal file
View File

@ -0,0 +1,382 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(include/vips/colour.h)
AM_CONFIG_HEADER(config.h)
# user-visible library versioning
IM_MAJOR_VERSION=7
IM_MINOR_VERSION=12
IM_MICRO_VERSION=5
IM_VERSION=$IM_MAJOR_VERSION.$IM_MINOR_VERSION.$IM_MICRO_VERSION
IM_VERSION_STRING=$IM_VERSION-`date`
VERSION=$IM_VERSION
PACKAGE=vips
# libtool library versioning ... not user-visible (except as part of the
# library file name) and does not correspond to major/minor/micro above
# rules:
# sources changed: increment revision
# interface changed: increment current, reset revision to 0
# interface changes backwards compatible?: increment age
# interface changes not backwards compatible?: reset age to 0
LIBRARY_CURRENT=14
LIBRARY_REVISION=2
LIBRARY_AGE=2
AM_INIT_AUTOMAKE($PACKAGE,$VERSION)
# patched into include/vips/version.h
AC_SUBST(IM_VERSION)
AC_SUBST(IM_VERSION_STRING)
AC_SUBST(IM_MAJOR_VERSION)
AC_SUBST(IM_MINOR_VERSION)
AC_SUBST(IM_MICRO_VERSION)
# put into library name by libsrc/Makefile.am and libsrcCC/Makefile.am
AC_SUBST(LIBRARY_CURRENT)
AC_SUBST(LIBRARY_REVISION)
AC_SUBST(LIBRARY_AGE)
AC_CANONICAL_HOST
AC_MSG_CHECKING([for native Win32])
case "$host" in
*-*-mingw*)
vips_os_win32=yes
;;
*)
vips_os_win32=no
;;
esac
AC_MSG_RESULT([$vips_os_win32])
if test x"$vips_os_win32" = "xyes"; then
AC_DEFINE(OS_WIN32,1,[native win32])
# makes gcc use win native alignment
VIPS_CFLAGS="-mms-bitfields $VIPS_CFLAGS"
fi
# Cygwin/mingw need binary open to avoid CR/LF madness
# ... should be a better way to test for this
AC_MSG_CHECKING([for binary open needed])
case "$host_os" in
cygwin* | mingw*)
vips_binary_open=yes
;;
*)
vips_binary_open=no
;;
esac
AC_MSG_RESULT([$vips_binary_open])
if test x"$vips_binary_open" = "xyes"; then
AC_DEFINE(BINARY_OPEN,1,[define to open non-text files in binary mode])
fi
# we want largefile support, if possible
AC_SYS_LARGEFILE
# Checks for programs.
AC_PROG_AWK
AC_PROG_CC
AC_PROG_CC_STDC
AC_C_CONST
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_CXX
AM_WITH_DMALLOC
# vips.c/im_guess_prefix.c need to know the exe suffix and (as a fallback)
# the install prefix
AC_DEFINE_UNQUOTED(IM_EXEEXT,"$EXEEXT",[extension for executable files])
AC_DEFINE_UNQUOTED(IM_PREFIX,"$prefix",[configure-time install prefix])
# i18n
GETTEXT_PACKAGE=vips7
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
[The prefix for our gettext translation domains.])
ALL_LINGUAS="en_GB malkovich"
AC_PROG_INTLTOOL
AM_GLIB_GNU_GETTEXT
# Checks for libraries.
# build list of pkg-config packages we used here
PACKAGES_USED=""
# Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS([errno.h math.h fcntl.h limits.h stdlib.h string.h sys/file.h sys/ioctl.h sys/param.h sys/time.h sys/mman.h sys/types.h sys/stat.h unistd.h io.h direct.h windows.h])
# uncomment to change which libs we build
# AC_DISABLE_SHARED
# AC_DISABLE_STATIC
# couldn't get this working :-( maybe try again with the next libtool
AC_LIBTOOL_WIN32_DLL
AC_CHECK_TOOL(DLLWRAP, dllwrap)
AC_CHECK_TOOL(DLLTOOL, dlltool)
AC_CHECK_TOOL(OBJDUMP, objdump)
AC_CHECK_TOOL(RANLIB, ranlib)
AC_CHECK_TOOL(STRIP, strip)
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(AS, as)
AC_CHECK_TOOL(LD, ld)
AC_PROVIDE(AC_LIBTOOL_WIN32_DLL)
AC_PROG_LIBTOOL
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MEMCMP
AC_FUNC_MMAP
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([getcwd gettimeofday getwd memset munmap putenv realpath strcasecmp strchr strcspn strdup strerror strrchr strspn vsnprintf realpath mkstemp mktemp random rand])
AC_CHECK_LIB(m,cbrt,[AC_DEFINE(HAVE_CBRT,1,[have cbrt() in libm.])])
# have to have these
PKG_CHECK_MODULES(REQUIRED, glib-2.0 >= 2.6 gmodule-2.0 >= 2.4 libxml-2.0 gobject-2.0)
PACKAGES_USED="$PACKAGES_USED glib-2.0 gmodule-2.0 libxml-2.0 gobject-2.0"
# option to eval without threads
AC_ARG_ENABLE(threads, AS_HELP_STRING([--enable-threads], [evaluate with threads (default: yes)]))
if test "x$enable_threads" != "xno"; then
AC_DEFINE(HAVE_THREADS,1,[threaded evaluation])
PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
PACKAGES_USED="$PACKAGES_USED gthread-2.0"
fi
# optional supporting libraries
# we can wrap fftw3 and fftw2 ... but just look for fftw3, since we can do
# that with pkg-config
AC_ARG_WITH([fftw3], AS_HELP_STRING([--without-fftw3], [build without fftw3 (default: test)]))
if test "x$with_fftw3" != "xno"; then
PKG_CHECK_MODULES(FFTW3, fftw3,
[AC_DEFINE(HAVE_FFTW3,1,[define if you have fftw3 installed.])
PACKAGES_USED="$PACKAGES_USED fftw3"],
[AC_MSG_WARN([fftw3 not found; disabling fftw support])])
fi
# ImageMagic ... detect attribute iteration too
AC_ARG_WITH([magick], AS_HELP_STRING([--without-magick], [build without libMagic (default: test)]))
if test "x$with_magick" != "xno"; then
PKG_CHECK_MODULES(MAGICK, ImageMagick,
[AC_DEFINE(HAVE_MAGICK,1,[define if you have libMagick installed.])
PACKAGES_USED="$PACKAGES_USED ImageMagick"],
[AC_MSG_WARN([libMagick not found; disabling Magick support])])
fi
if test "x$with_magick" != "xno"; then
# we need ResetImageAttributeIterator() / GetNextImageAttribute() to get
# attrs, but that's 6.2+ I think ... test for them
save_LIBS=$LIBS
LIBS="$LIBS $MAGICK_LIBS"
AC_CHECK_FUNCS(GetNextImageAttribute,
AC_DEFINE(HAVE_MAGICK_ATTR,1,[define if your imagemagick has attribute support.]))
LIBS=$save_LIBS
fi
# liboil
AC_ARG_WITH([liboil], AS_HELP_STRING([--without-liboil], [build without liboil
(default: test)]))
if test "x$with_liboil" != "xno"; then
PKG_CHECK_MODULES(LIBOIL, liboil-0.3,
[AC_DEFINE(HAVE_LIBOIL,1,[define if you have liboil-0.3 installed.])
PACKAGES_USED="$PACKAGES_USED liboil-0.3"],
[AC_MSG_WARN([liboil not found; disabling liboil support])])
fi
# lcms
AC_ARG_WITH([lcms], AS_HELP_STRING([--without-lcms], [build without lcms (default: test)]))
if test "x$with_lcms" != "xno"; then
PKG_CHECK_MODULES(LCMS, lcms,
[AC_DEFINE(HAVE_LCMS,1,[define if you have lcms installed.])
PACKAGES_USED="$PACKAGES_USED lcms"],
[AC_MSG_WARN([lcms not found; disabling lcms support])])
fi
# OpenEXR
AC_ARG_WITH([OpenEXR], AS_HELP_STRING([--without-OpenEXR], [build without OpenEXR (default: test)]))
# require 1.2.2 since 1.2.1 has a broken ImfCloseTiledInputFile()
if test "x$with_OpenEXR" != "xno"; then
PKG_CHECK_MODULES(OPENEXR, OpenEXR >= 1.2.2,
[AC_DEFINE(HAVE_OPENEXR,1,[define if you have OpenEXR >=1.2.2 installed.])
PACKAGES_USED="$PACKAGES_USED OpenEXR"],
[AC_MSG_WARN([OpenEXR not found; disabling OpenEXR support])])
fi
# pangoft2
AC_ARG_WITH([pangoft2], AS_HELP_STRING([--without-pangoft2], [build without pangoft2 (default: test)]))
if test "x$with_pangoft2" != "xno"; then
PKG_CHECK_MODULES(PANGOFT2, pangoft2,
[AC_DEFINE(HAVE_PANGOFT2,1,[define if you have pangoft2 installed.])
PACKAGES_USED="$PACKAGES_USED pangoft2"],
[AC_MSG_WARN([pangoft2 not found; disabling pangoft2 support])])
fi
# hmm, these don't have .pc files on ubuntu 5.10, how odd
FIND_TIFF(,[AC_MSG_WARN([libtiff not found; disabling TIFF support])])
FIND_ZIP(,[AC_MSG_WARN([libz not found; disabling ZIP support])])
FIND_JPEG(,[AC_MSG_WARN([libjpeg not found; disabling JPEG support])])
# look for PNG with pkg-config ... fall back to our tester
PKG_CHECK_MODULES(PNG, libpng,
[AC_DEFINE(HAVE_PNG,1,[define if you have libpng installed.])
PACKAGES_USED="$PACKAGES_USED libpng"],
[FIND_PNG(,[AC_MSG_WARN([libpng not found; disabling PNG support])])])
# libexif
AC_ARG_WITH([libexif], AS_HELP_STRING([--without-libexif], [build without libexif (default: test)]))
if test "x$with_libexif" != "xno"; then
PKG_CHECK_MODULES(EXIF, libexif >= 0.6,
[AC_DEFINE(HAVE_EXIF,1,[define if you have libexif >= 0.6 installed.])
PACKAGES_USED="$PACKAGES_USED libexif"],
[AC_MSG_WARN([libexif >= 0.6 not found; disabling exif support])
with_libexif=no])
fi
# some libexif packages need include <libexif/poop.h>, some just <poop.h>
# how annoying
if test "x$with_libexif" != "xno"; then
# cppflags not cflags because we want the preproc to see the -I as well
save_CPPFLAGS=$CPPFLAGS
CPPFLAGS="$EXIF_CFLAGS $CPPFLAGS"
AC_CHECK_HEADER(exif-data.h,
AC_DEFINE(UNTAGGED_EXIF,1,[libexif includes don't need libexif prefix]))
CPPFLAGS=$save_CPPFLAGS
fi
# Look for linux video
AC_CHECK_HEADER(linux/videodev.h,
AC_DEFINE(HAVE_VIDEODEV,1,[have video4linux 1]),[
AC_MSG_WARN([linux/videodev.h not found; disabling Linux video support])
])
# make python binding?
AC_ARG_WITH([python], AS_HELP_STRING([--without-python], [build without Python bindings (default: test)]))
if test "x$with_python" != "xno"; then
AM_PATH_PYTHON(2.2,,
[with_python=no
AC_MSG_WARN([Python not found; disabling Python binding])])
fi
if test "x$with_python" != "xno"; then
AM_CHECK_PYTHON_HEADERS(,
[with_python=no
AC_MSG_WARN([Python headers not found])])
fi
# need SWIG too
if test "x$with_python" != "xno"; then
AC_CHECK_PROG(HAVE_SWIG, swig, [yes])
if test "x$HAVE_SWIG" != "xyes"; then
with_python=no
AC_MSG_WARN([SWIG not found; disabling Python binding])
else
with_python=yes
fi
fi
if test "x$with_python" = "xyes"; then
AM_CONDITIONAL(HAVE_PYTHON, true)
else
AM_CONDITIONAL(HAVE_PYTHON, false)
fi
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES and VIPS_LIBS
VIPS_CFLAGS="$VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $FFTW3_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $OPENEXR_CFLAGS $LIBOIL_CFLAGS"
VIPS_INCLUDES="$PNG_INCLUDES $TIFF_INCLUDES $ZIP_INCLUDES $JPEG_INCLUDES $FFTW_INCLUDES $LCMS_INCLUDES"
VIPS_LIBS="$MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $ZIP_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $FFTW3_LIBS $FFTW_LIBS $LCMS_LIBS $LIBOIL_LIBS $OPENEXR_LIBS $EXIF_LIBS -lm"
AC_SUBST(VIPS_CFLAGS)
AC_SUBST(VIPS_INCLUDES)
AC_SUBST(VIPS_LIBS)
AC_SUBST(PACKAGES_USED)
AC_OUTPUT([
vips-7.12.pc
vipsCC-7.12.pc
vips-7.12.spec
Makefile
include/vips/version.h
include/Makefile
include/vips/Makefile
libsrc/Makefile
libsrc/acquire/Makefile
libsrc/arithmetic/Makefile
libsrc/boolean/Makefile
libsrc/colour/Makefile
libsrc/conversion/Makefile
libsrc/convolution/Makefile
libsrc/freq_filt/Makefile
libsrc/histograms_lut/Makefile
libsrc/inplace/Makefile
libsrc/iofuncs/Makefile
libsrc/matrix/Makefile
libsrc/morphology/Makefile
libsrc/mosaicing/Makefile
libsrc/other/Makefile
libsrc/relational/Makefile
libsrc/video/Makefile
libsrc/acquire/man3/Makefile
libsrc/arithmetic/man3/Makefile
libsrc/boolean/man3/Makefile
libsrc/colour/man3/Makefile
libsrc/conversion/man3/Makefile
libsrc/convolution/man3/Makefile
libsrc/freq_filt/man3/Makefile
libsrc/histograms_lut/man3/Makefile
libsrc/inplace/man3/Makefile
libsrc/iofuncs/man3/Makefile
libsrc/matrix/man3/Makefile
libsrc/morphology/man3/Makefile
libsrc/mosaicing/man3/Makefile
libsrc/other/man3/Makefile
libsrc/relational/man3/Makefile
libsrc/video/man3/Makefile
libsrcCC/Makefile
src/Makefile
src/iofuncs/Makefile
src/mosaicing/Makefile
src/other/Makefile
src/scripts/Makefile
src/scripts/batch_crop
src/scripts/batch_image_convert
src/scripts/batch_rubber_sheet
src/scripts/light_correct
src/scripts/shrink_width
src/iofuncs/man1/Makefile
src/other/man1/Makefile
src/scripts/man1/Makefile
contrib/Makefile
contrib/vips2dj/Makefile
contrib/vips2dj/share/Makefile
contrib/vips2dj/share/vips2dj/Makefile
contrib/vips2dj/share/vips2dj/lab/Makefile
contrib/vips2dj/share/vips2dj/cmyk/Makefile
contrib/vips2dj/share/vips2dj/mono/Makefile
contrib/vdump/Makefile
contrib/mitsub/Makefile
python/Makefile
python/vipsCC/Makefile
po/Makefile.in
])

4
contrib/Makefile.am Normal file
View File

@ -0,0 +1,4 @@
SUBDIRS = \
vips2dj \
mitsub \
vdump

View File

@ -0,0 +1,7 @@
bin_PROGRAMS = mitsub
mitsub_SOURCES = mitsub.c
INCLUDES = -I${top_srcdir}/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
AM_LDFLAGS = @LDFLAGS@
LDADD = @VIPS_CFLAGS@ ${top_builddir}/libsrc/libvips.la @VIPS_LIBS@

491
contrib/mitsub/mitsub.c Normal file
View File

@ -0,0 +1,491 @@
/*
* Version which sents raw data to the printer, which enlarges and centers.
* Works for monochrome and four band IM_TYPE_CMYK images. Uses putc instead of
* fprintf. Sents data straight to the printer. If enlargement, it is full and
* x and y ratios are the same (aspect ratio is not changed)
*
* Helene Chahine, July 95
*
* JC 4/8/95
* - small tidies and bug fixes
* - now does 1, 3 and 4 band
* - resets printer after use
* JC 1/9/95
* - colour reverse mode added
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <string.h>
#include <vips/vips.h>
#include <vips/util.h>
#define NBPRINT 1 /* Maximun 15 copies */
#define VMAX 2904 /* Number of horizontal pixels */
#define HMAX 2368 /* Number of vertical pixels */
int
main( int argc, char *argv[] )
{
int enlar = 0;
int center = 0;
int rev = 0;
IMAGE *vips;
FILE *out;
int n1, n2;
int x, y;
int xsize, ysize;
int c;
PEL *p;
if( im_init_world( argv[0] ) )
error_exit( "unable to start VIPS" );
while( --argc > 0 && (*++argv)[0] == '-' )
while( (c = *++argv[0]) )
switch( c ) {
case 'e':
enlar = 1;
break;
case 'c':
center = 1;
break;
case 'r':
rev = 1;
break;
default:
error_exit( "mitsub: illegal option %c", c );
}
if( argc != 2 )
error_exit( "usage: mitsub [-ecr] vipsfile mitfile\n"
"where:\n"
"\tvipsfile may be 1, 3 or 4 bands for mono, IM_TYPE_RGB or "
"IM_TYPE_CMYK printing\n"
"\tmitfile may be '-', meaning send to stdout\n"
"\t-e means enlarge to fill page\n"
"\t-c means centre within page\n"
"\t-r means reverse black/white\n"
"\tNOTE: data is sent raw, with 0 == no ink - all correction is up to "
"you\n"
"example:\n"
"\t%% mitsub -ec fred.v - > /dev/bpp0" );
if( !(vips = im_open( argv[0], "r" )) )
error_exit( "mitsub: unable to open \"%s\" for input",
argv[0] );
if( strcmp( argv[1], "-" ) == 0 )
out = stdout;
else if( !(out = fopen( argv[1], "w" )) )
error_exit( "mitsub: unable to open \"%s\" for output",
argv[1] );
if( vips->Coding != IM_CODING_NONE || vips->BandFmt != IM_BANDFMT_UCHAR )
error_exit( "mitsub: uncoded uchar only" );
if( vips->Bands != 1 && vips->Bands != 3 && vips->Bands != 4 )
error_exit( "mitsub: 1,3 and 4 band images only" );
/* Set xsize and ysize.
*/
if( vips->Xsize <= vips->Ysize ) {
xsize = vips->Xsize;
ysize = vips->Ysize;
}
else {
im_diagnostics( "mitsub: rotating ..." );
xsize = vips->Ysize;
ysize = vips->Xsize;
}
/* Shrink if image is too big.
*/
if( xsize > HMAX || ysize > VMAX ) {
double x_factor = HMAX/xsize;
double y_factor = VMAX/ysize;
double factor = IM_MAX( x_factor, y_factor );
IMAGE *sh = im_open( "shrink", "t" );
im_diagnostics( "mitsub: shrinking by %g ...", factor );
if( !sh || im_shrink( vips, sh, factor, factor ) )
error_exit( "mitsub: shrink failed" );
vips = sh;
enlar = 0;
}
/* On line command and buffer clear.
*/
putc( 0x11, out );
putc( 0x1b, out );
putc( 'Z', out );
/* Memory clear.
*/
putc( 0x1b, out );
putc( 'Z', out );
/* Media size. (Size A4)
*/
putc( 0x1b, out );
putc( '#', out );
putc( 'P', out );
putc( '0', out );
/* Enlargement.
*/
if( enlar ) {
double rh, rv;
int n, m;
/* Enlarge method: ('0'=simple enlargement,
* '1'=linear enlargement)
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'O', out );
putc( '1', out );
rh = HMAX/(double) xsize;
rv = VMAX/(double) ysize;
if( rh > 8 || rv > 8 ) {
n = 8;
m = 1;
}
else if( rh > rv ) {
double fact = VMAX/255;
n = 255;
m = (int) ysize/fact + 1;
}
else {
double fact = HMAX/255;
n = 255;
m = (int) xsize/fact + 1;
}
im_diagnostics( "mitsub: enlarging by %g ...", (double) n/m );
/* Horizontal enlarge.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'P', out );
putc( n, out );
putc( m, out );
/* Vertical enlarge.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'Q', out );
putc( n, out );
putc( m, out );
}
else {
/* No enlargement.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'O', out );
putc( '1', out );
putc( 0x1b, out );
putc( '&', out );
putc( 'P', out );
putc( 1, out );
putc( 1, out );
putc( 0x1b, out );
putc( '&', out );
putc( 'Q', out );
putc( 1, out );
putc( 1, out );
}
if( rev ) {
/* Colour reversing.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'W', out );
putc( '2', out );
}
else {
/* No reverse.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'W', out );
putc( '0', out );
}
/* Number of copies.
*/
putc( 0x1b, out );
putc( '#', out );
putc( 'C', out );
putc( NBPRINT, out );
/* Left margin.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'S', out );
putc( 0, out );
/* Top margin.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'T', out );
putc( 0, out );
/* Centering. ('1' = centering available, '0'= no centering).
*/
if( center ) {
im_diagnostics( "mitsub: centering ..." );
putc( 0x1b, out );
putc( '&', out );
putc( 'C', out );
putc( '1', out );
}
else {
/* No centering.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'C', out );
putc( '0', out );
}
/* Transfer format = pixel order method for colour, = frame order
* method for monochrome.
*/
switch( vips->Bands ) {
case 3:
case 4:
putc( 0x1b, out );
putc( '&', out );
putc( 'A', out );
putc( '2', out );
break;
case 1:
putc( 0x1b, out );
putc( '&', out );
putc( 'A', out );
putc( '0', out );
break;
default:
error_exit( "internal error" );
/*NOTREACHED*/
}
/* Colour specification.
*/
switch( vips->Bands ) {
case 4:
case 1:
/* IM_TYPE_CMYK. For mono, send just K.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'I', out );
putc( '2', out );
break;
case 3:
/* IM_TYPE_RGB.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'I', out );
putc( '0', out );
break;
default:
error_exit( "internal error" );
/*NOTREACHED*/
}
/* Gray scale level.
*/
putc( 0x1b, out );
putc( '#', out );
putc( 'L', out );
putc( 8, out );
/* Rotation.
*/
if( vips->Xsize <= vips->Ysize ) {
putc( 0x1b, out );
putc( '#', out );
putc( 'R', out );
putc( '0', out );
}
else {
putc( 0x1b, out );
putc( '#', out );
putc( 'R', out );
putc( '1', out );
}
/* Horizontal shift.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'J', out );
putc( 0, out );
putc( 0, out );
/* Vertical shift.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'K', out );
putc( 0, out );
putc( 0, out );
/* Number of horizontal pixels.
*/
n1 = vips->Xsize >> 8;
n2 = vips->Xsize & 0xff;
putc( 0x1b, out );
putc( '&', out );
putc( 'H', out );
putc( n1, out );
putc( n2, out );
/* Number of vertical pixels.
*/
n1 = vips->Ysize >> 8;
n2 = vips->Ysize & 0xff;
putc( 0x1b, out );
putc( '&', out );
putc( 'V', out );
putc( n1, out );
putc( n2, out );
/* Transfer colour (for monochrome image only).
*/
if( vips->Bands == 1 ) {
putc( 0x1b, out );
putc( 'C', out );
putc( '4', out );
}
/* Image data transfer. Image must be sent as YMCK.
*/
putc( 0x1b, out );
putc( 'O', out );
if( im_incheck( vips ) )
error_exit( "mitsub: unable to read image data" );
p = (PEL *) vips->data;
switch( vips->Bands ) {
case 4:
im_diagnostics( "mitsub: sending IM_TYPE_CMYK ..." );
for( y = 0; y < vips->Ysize; y++ )
for( x = 0; x < vips->Xsize; x++ ) {
putc( p[2], out );
putc( p[1], out );
putc( p[0], out );
putc( p[3], out );
p += 4;
}
break;
case 3:
im_diagnostics( "mitsub: sending IM_TYPE_RGB ..." );
for( y = 0; y < vips->Ysize; y++ )
for( x = 0; x < vips->Xsize; x++ ) {
putc( p[0], out );
putc( p[1], out );
putc( p[2], out );
p += 3;
}
break;
case 1:
im_diagnostics( "mitsub: sending K ..." );
for( y = 0; y < vips->Ysize; y++ )
for( x = 0; x < vips->Xsize; x++ )
putc( *p++, out );
break;
}
/* Form feed. Page end.
*/
putc( 0x0c, out );
/* Now try to reset printer to default settings.
*
* No enlargement.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'O', out );
putc( '1', out );
putc( 0x1b, out );
putc( '&', out );
putc( 'P', out );
putc( 1, out );
putc( 1, out );
putc( 0x1b, out );
putc( '&', out );
putc( 'Q', out );
putc( 1, out );
putc( 1, out );
/* No centering.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'C', out );
putc( '0', out );
/* No colour reverse.
*/
putc( 0x1b, out );
putc( '&', out );
putc( 'W', out );
putc( '0', out );
return( 0 );
}

15
contrib/vdump/Makefile.am Normal file
View File

@ -0,0 +1,15 @@
bin_PROGRAMS = vdump
vdump_SOURCES = vdump.c
man_MANS = \
vdump.1
pkgdata_DATA = \
vdump.pro
INCLUDES = -I${top_srcdir}/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
AM_LDFLAGS = @LDFLAGS@
LDADD = @VIPS_CFLAGS@ ${top_builddir}/libsrc/libvips.la @VIPS_LIBS@
EXTRA_DIST = $(pkgdata_DATA) $(man_MANS)

69
contrib/vdump/vdump.1 Normal file
View File

@ -0,0 +1,69 @@
.TH VDUMP 1 "July 1990"
.SH NAME
vdump \- convert VIPS image files to Postscript
.SH SYNOPSIS
.B vdump
[
.B \-slpDa
]
.IR filename
.SH DESCRIPTION
.B vdump
turns the vasari format file in its argument to encapsulated PostScript on its
stadard output. The result can be
either sent directly to a printer or included in any document processor which
supports encapsulated PostScript diagrams - eg. WordPerfect, Tex etc. For
example:
.IP
.B
example% vdump campin.v | lpr -Plaser
.LP
or
.IP
.B
example% vdump -l -s4 -D campin.v > campin.PS
.LP
.br
.B vdump
normally outputs portrait, you can force output to portrait or landscape with the
.BR \-p
or
.BR \-l
flags.
.br
The
.BR \-a
flag makes vdump select
either portrait or landscape orientation so as to get
the largest possible image onto an A4 sheet.
.br
.B vdump
will dump one or three band unsigned char images only.
.SH OPTIONS
.TP
.B \-p
Force portrait output.
.TP
.B \-l
Force landscape output.
.TP
.B \-a
Automatically select portrait/landscape.
.TP
.B \-s<factor>
Set a sub-sampling factor (default 1).
.BR \-s1
will not sub-sample at all,
.BR \-s4
will reduce by a factor of 4.
.TP
.B \-D
Produce output suitable for including in documents. This option
simply supresses the generation of a showpage command.
.SH SEE\ ALSO
ip(1), vips2dj(1)
.SH COPYRIGHT
.br
1990: J. Cupitt, National Gallery

399
contrib/vdump/vdump.c Normal file
View File

@ -0,0 +1,399 @@
/* This is incredibly primitive and annoying.
*
* Turn a VASARI format file into PostScript. Do simple subsampling of
* images to get the size down .. no point in sending anything much larger
* than 100x100 to the laserwriter if it's going in a document. The output
* conforms to PS-Adobe-2.0 EPSF-2.0, I think.
*
* Options:
* -s<n> Average an nxn area in the image for each pixel in the output.
* This reduces the size of the files significantly (obviously).
* Default 1.
* -l Force landscape output
* -p Force portrait output (default)
* -a Automatic choice of portrait/landscape
* Nasty: as we have to include a %%BoundingBox: line, we can't
* size the image to fit comfortably in whatever size paper this
* PostScript printer takes.
* -D Supress generation of showpage. Sometimes necessary if you
* want to include the PS file in a document.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <vips/vips.h>
#include <vips/util.h>
#define USAGE "usage: [-s<scale> -alpD] vasari_format_file"
#define PROLOGUE "vdump.pro"
#define PAPER_WIDTH (8.25*72.0) /* Paper size .. A4 */
#define PAPER_HEIGHT (11.75*72.0)
#define PAPER_MARGIN (1.0*72.0) /* Margin we leave around the edge */
#define PRINT_WIDTH (PAPER_WIDTH - 2.0*PAPER_MARGIN)
#define PRINT_HEIGHT (PAPER_HEIGHT - 2.0*PAPER_MARGIN)
#define PRINT_RATIO (PRINT_WIDTH / PRINT_HEIGHT)
/* Useful: a pixel. We mmap the file, then cast the pointer to the image to
* a pointer to one of these things.
*/
struct pixel {
unsigned char p_red;
unsigned char p_green;
unsigned char p_blue;
};
/* A monochrome pixel.
*/
struct mpixel {
unsigned char p_val;
};
enum output_format {
LANDSCAPE, /* Rotated by 90 degrees */
PORTRAIT, /* Vertical */
AUTOMATIC /* Whichever fits best */
};
static const char *our_name; /* Name of this prog */
static char *file_name; /* Name of file we dump */
static int print_on = 1; /* Generate showpage */
/* Copy between two fds
*/
static void
copy_file( from, to )
FILE *from, *to;
{ int ch;
while( (ch = getc( from )) != EOF )
putc( ch, to );
}
/* Send a file to stdout. Used to transmit the prelude.
*/
static int
transmit_file( name )
char *name;
{ const char *prefix;
char buf[PATH_MAX];
FILE *fp;
if( !(prefix = im_guess_prefix( our_name, "VIPSHOME" )) )
error_exit( "VIPSHOME not defined" );
im_snprintf( buf, PATH_MAX, "%s/share/%s/%s", prefix, PACKAGE, name );
/* Send it!
*/
if( !(fp = fopen( buf, "r" )) )
error_exit( "can't find %s", name );
copy_file( fp, stdout );
fclose( fp );
return( -1 );
}
/* Encode a colour VASARI file as mono hex bytes. Scale down by a factor of
* s. We scale by averaging regions of sxs pixels .. is this the best way?
* works ok for our laserwriter anyway. We lose incomplete regions down the RH
* side and across the bottom.
*/
static void
encode_colour( im, s, data )
IMAGE *im;
int s;
struct pixel *data;
{ int p = 35;
int x, y;
int i, j;
/* Scan across and down. Make sure we chop off those incomplete
* regions on the RH side and across the bottom.
*/
for( y = 0; y <= im->Ysize - s; y += s )
for( x = 0; x <= im->Xsize - s; x += s ) {
int col = 0;
struct pixel *rs = &data[y * im->Xsize + x];
/* Now average the region. We monochromise each pixel
* and add it to the running total.
*/
for( i = 0; i < s; i++ ) {
struct pixel *d = &rs[i * im->Xsize];
for( j = 0; j < s; j++ ) {
col += (int) (d->p_red + d->p_green +
d->p_blue) / 3;
d++;
}
}
col /= s*s;
/* Output the averaged pixel.
*/
printf( "%02x", col );
if( !p-- ) {
printf( "\n" );
p = 35;
}
}
printf( "\n" );
}
/* Encode a mono VASARI file as hex bytes. Scale down by a factor of
* s. We scale by averaging regions of sxs pixels .. is this the best way?
* works ok for our laserwriter anyway. We lose incomplete regions down the RH
* side and across the bottom.
*/
static void
encode_mono( im, s, data )
IMAGE *im;
int s;
struct mpixel *data;
{ int p = 35;
int x, y;
int i, j;
/* Scan across and down. Make sure we chop off those incomplete
* regions on the RH side and across the bottom.
*/
for( y = 0; y <= im->Ysize - s; y += s )
for( x = 0; x <= im->Xsize - s; x += s ) {
int col = 0;
struct mpixel *rs = &data[y * im->Xsize + x];
/* Now average the region.
*/
for( i = 0; i < s; i++ ) {
struct mpixel *d = &rs[i * im->Xsize];
for( j = 0; j < s; j++ )
col += d++->p_val;
}
col /= s*s;
/* Output the averaged pixel.
*/
printf( "%02x", col );
if( !p-- ) { printf( "\n" ); p = 35; }
}
printf( "\n" );
}
/* Print the image. Work out the orientation, print the prologue, then call
* one of the dumps above to do the image.
*/
static void
dump( im, format, scale )
IMAGE *im;
enum output_format format;
int scale;
{ float r, width, height, xstart, ystart;
/* Fix orientation, then set our origin and output size. Four cases ..
* can any of these be combined? Perhaps not.
*/
r = (float) im->Xsize / im->Ysize;
if( format == AUTOMATIC ) {
if( im->Xsize > im->Ysize )
format = LANDSCAPE;
else
format = PORTRAIT;
}
if( format == PORTRAIT ) {
/* Is it going to be smaller than the paper vertically or
* horizontally?
*/
if( r > PRINT_RATIO ) {
/* It's too wide. We make it as large as possible
* horizontally, then center it vertically.
*/
width = PRINT_WIDTH;
height = PRINT_WIDTH / r;
xstart = PAPER_MARGIN;
ystart = (PRINT_HEIGHT - height) / 2.0 + PAPER_MARGIN;
}
else {
/* Too high. Make as large as possible vertically,
* then center it horizontally.
*/
height = PRINT_HEIGHT;
width = PRINT_HEIGHT * r;
ystart = PAPER_MARGIN;
xstart = (PRINT_WIDTH - width) / 2.0 + PAPER_MARGIN;
}
}
else {
/* Do a landscape picture. Will we run out of space
* horizontally or vertically?
*/
if( 1.0 / r < PRINT_RATIO ) {
/* Very wide indeed! Fit it horizontally, then center
* it vertically.
*/
height = PRINT_HEIGHT;
width = PRINT_HEIGHT / r;
ystart = PAPER_MARGIN;
xstart = (PRINT_WIDTH - width) / 2.0 + PAPER_MARGIN;
}
else {
/* Too tall. Make as large as possible vertically,
* then center it horizontally.
*/
width = PRINT_WIDTH;
height = PRINT_WIDTH * r;
xstart = PAPER_MARGIN;
ystart = (PRINT_HEIGHT - height) / 2.0 + PAPER_MARGIN;
}
}
/* Print header.
*/
printf( "%%!PS-Adobe-2.0 EPSF-2.0\n" );
printf( "%%%%BoundingBox: %d %d %d %d\n", (int) xstart, (int) ystart,
(int) (width + xstart), (int) (height + ystart) );
printf( "%%%%Title: %s\n", file_name );
printf( "%%%%Creator: %s\n", our_name );
/* Print prologue.
*/
transmit_file( PROLOGUE );
/* Print position, scale and rotation. Print size in pixels and call
* doimage.
*/
if( format == LANDSCAPE )
printf( "%d %d translate\n",
(int) (xstart + width), (int) ystart );
else
printf( "%d %d translate\n", (int) xstart, (int) ystart );
printf( "%d %d scale\n", (int) width, (int) height );
if( format == LANDSCAPE )
printf( "90 rotate\n" );
printf( "%d %d 8 doimage\n",
(int) (im->Xsize / scale), (int) (im->Ysize / scale) );
/* Print body of file.
*/
if( im->Bands == 3 )
encode_colour( im, scale, (struct pixel *) im->data );
else
encode_mono( im, scale, (struct mpixel *) im->data );
/* Print trailer.
*/
if( print_on )
printf( "showpage\n" );
printf( "%%%%EndDocument\n" );
}
/* Start here!
*/
int
main( argc, argv )
int argc;
char **argv;
{ int scale = 1;
enum output_format format = PORTRAIT;
IMAGE *im = NULL;
if( im_init_world( argv[0] ) )
error_exit( "unable to start VIPS" );
our_name = *argv;
/* Decode args .. just look for file names and our three options.
*/
while( --argc )
if( *argv[argc] == '-' )
switch( argv[argc][1] ) {
case 's':
if( sscanf( argv[argc] + 2,
"%d", &scale ) != 1 )
error_exit( USAGE );
break;
case 'l':
format = LANDSCAPE;
break;
case 'p':
format = PORTRAIT;
break;
case 'a':
format = AUTOMATIC;
break;
case 'D':
print_on = 0;
break;
default:
error_exit( USAGE );
break;
}
else {
/* Try to open the file. If we have previously opened,
* then flag an error.
*/
if( im != NULL )
error_exit( USAGE );
file_name = argv[argc];
if( !(im = im_open( file_name, "r" )) )
error_exit( "unable to open %s", file_name );
}
if( im == NULL ) error_exit( USAGE );
/* Check it for suitability. We can print colour
* or monochrome pictures.
*/
if( im->Coding != IM_CODING_NONE )
error_exit( "cannot print compressed pictures" );
if( !(
(im->Bands == 3 && im->Bbits == 8 &&
im->BandFmt == IM_BANDFMT_UCHAR) ||
(im->Bands == 1 && im->Bbits == 8 &&
im->BandFmt == IM_BANDFMT_UCHAR)
) )
error_exit( "can only print mono or colour images" );
if( im_incheck( im ) )
error_exit( "unable to get pixels" );
dump( im, format, scale);
return( 0 );
}

25
contrib/vdump/vdump.pro Normal file
View File

@ -0,0 +1,25 @@
%%Pages: 1
%%Creator: vdump
%%EndComments
%%BeginDocument: vdump
/doimage {
/b exch def /m exch def /n exch def
/pix n string def
n m b [n 0 0 m neg 0 m]
{ currentfile pix readhexstring pop }
image
} def
/spotsize {
/perinch exch def
currentscreen 3 -1 roll
pop perinch
3 1 roll setscreen
} def
/invert {
/curtran currenttransfer cvlit def
/newtran curtran length 3 add array def
newtran 0 {1 exch sub} putinterval
newtran 3 curtran putinterval
newtran cvx settransfer
} def
80 spotsize

View File

@ -0,0 +1,17 @@
SUBDIRS = share
bin_PROGRAMS = \
vips2dj
vips2dj_DEPENDENCIES = vips2dj.h
vips2dj_SOURCES = \
vips2ah.c \
vips2dj.c
INCLUDES = -I${top_srcdir}/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
AM_LDFLAGS = @LDFLAGS@
LDADD = @VIPS_CFLAGS@ ${top_builddir}/libsrc/libvips.la @VIPS_LIBS@
EXTRA_DIST = ${vips2dj_DEPENDENCIES}

View File

@ -0,0 +1,2 @@
SUBDIRS = vips2dj

View File

@ -0,0 +1,2 @@
SUBDIRS = lab cmyk mono

View File

@ -0,0 +1,14 @@
vips2djcmykpsbitsdir = $(datadir)/vips/vips2dj/cmyk
vips2djcmykpsbits_DATA = \
head1 \
head2 \
head3 \
head4 \
head5 \
head6
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(vips2djcmykpsbitsdir)
EXTRA_DIST = $(vips2djcmykpsbits_DATA)

View File

@ -0,0 +1,686 @@
%!PS-Adobe-3.0
%%Title: (micro_65_macbeth.tif)
%%Creator: (Adobe\250 Photoshop\250 6.0: AdobePS 8.7.0)
%%CreationDate: (2:17 pm Monday, April 29, 2002)
%%For: (FOTOG4)
%%Routing: (mailto:Colin.White@ng-london.org.uk)
%%Pages: 1
%%DocumentFonts:
%%DocumentNeededResources:
%%DocumentSuppliedResources:
%%DocumentData: Clean7Bit
%%PageOrder: Ascend
%%Orientation: Portrait
%%DocumentMedia: (Default) 612 792 0 () ()
%RBINumCopies: 1
%RBINupNess: 1 1
%ADO_ImageableArea: 30 33 582 761
%RBIDocumentSuppliedFonts:
[{
%%BeginPluginPS: SetTime
/HPDict /ProcSet findresource /SetTime get (20020429140835) exch exec
%%EndPluginPS
}stopped cleartomark
[{
%%BeginPluginPS: HPJobname
/HPDict /ProcSet findresource /SetJobName get (micro_65_macbeth_tif) exch exec
%%EndPluginPS
}stopped cleartomark
%%EndComments
%%BeginDefaults
%%ViewingOrientation: 1 0 0 1
%%EndDefaults
userdict/dscInfo 5 dict dup begin
/Title(micro_65_macbeth.tif)def
/Creator(Adobe\250 Photoshop\250 6.0: AdobePS 8.7.0)def
/CreationDate(2:17 pm Monday, April 29, 2002)def
/For(FOTOG4)def
/Pages 1 def
end put
%%BeginProlog
/md 178 dict def md begin/currentpacking where {pop /sc_oldpacking currentpacking def true setpacking}if
%%BeginFile: lw8_feature-1.01
%%Copyright: Copyright 1990-1999 Adobe Systems Incorporated and Apple Computer Incorporated. All Rights Reserved.
/bd{bind def}bind def
/ld{load def}bd
/xs{exch store}bd
/Z{0 def}bd
/T true def
/F false def
/level2
/languagelevel where
{
pop languagelevel 2 ge
}{
F
}ifelse
def
/odictstk Z
/oopstk Z
/fcl
{
count oopstk sub dup 0 gt
{
{pop}repeat
}{
pop
}ifelse
countdictstack odictstk sub dup 0 gt
{
{end}repeat
}{
pop
}ifelse
}bd
/sfcl2
{
/odictstk countdictstack store
count/oopstk xs
}bd
/efcl2
{
stopped{$error/newerror F put}if
fcl
}bd
/noload Z
/startnoload
{
{/noload save store}if
}bd
/endnoload
{
{noload restore}if
}bd
/setcopies{
level2
{
1 dict begin/NumCopies exch def currentdict end setpagedevice
}{
userdict/#copies 3 -1 roll put
}ifelse
}def
level2 startnoload
/ststpgdev{}def
/dopgdev{}def
/stpgdev{}def
/buf Z
/didstop T def
/sfcl
{
/didstop T store
/odictstk countdictstack store
count/oopstk xs
currentfile cvx stopped
{
$error/newerror F put
didstop
{
save/didstop xs
/buf vmstatus exch sub exch pop dup 0 lt{pop 0}if
dup 64000 gt{pop 64000}if string store
{
currentfile buf readline
{
(}efcl)eq{exit}if
}{
/UnexpectedEOF errordict/rangecheck get exec
}ifelse
}loop
didstop restore
}if
}if
fcl
}bd
/efcl
{
/didstop F store
exec
stop
}bd
level2 endnoload level2 not startnoload
/setpagedevice where{pop/realstpgdev/setpagedevice ld}if
/SC_topddict Z
/SC_spdict Z
/$spusrdict F def
/dopgdev
{
userdict/setpagedevice undef
$spusrdict
{
userdict/setpagedevice/realstpgdev load put
/$spusrdict F store
}if
SC_topddict realstpgdev
}bd
/stpgdev
{
SC_topddict dup 3 -1 roll
{
SC_spdict 2 index known
{
SC_spdict 2 index get
dup 3 -1 roll
{
put dup
}forall
pop put dup
}{
put dup
}ifelse
}forall
pop pop
}bd
/ststpgdev
{
/setpagedevice where
{
userdict eq
{
/$spusrdict T store
}if
}if
userdict/setpagedevice/stpgdev load put
/SC_topddict 0 dict store
/SC_spdict 3 dict begin
/InputAttributes 0 dict def
/Policies 0 dict def
/OutputAttributes 0 dict def
currentdict
end
store
}def
/sfcl/sfcl2 ld
/efcl/efcl2 ld
level2 not endnoload
%%EndFile
%%BeginFile: lw8_basic-4.0
/xdf{exch def}bd
/:L/lineto
/lw/setlinewidth
/:M/moveto
/rl/rlineto
/rm/rmoveto
/:C/curveto
/:T/translate
/:K/closepath
/:mf/makefont
/gS/gsave
/gR/grestore
/np/newpath
12{ld}repeat
/framewidth -1 def
/QDframwid -1 def
/numframes Z
/mTS matrix def
/$m matrix def
/av 87 def
/por T def
/normland F def
/psb-nosave{}def
/pse-nosave{}def
/us Z
/psb{/us save store}bd
/pse{us restore}bd
/level3
/languagelevel where
{
pop languagelevel 3 ge
}{
F
}ifelse
def
level2 startnoload
/setjob
{
statusdict/jobname 3 -1 roll put
}bd
/devg/DeviceGray def
/devr/DeviceRGB def
/devc/DeviceCMYK def
level2 endnoload level2 not startnoload
/setjob
{
1 dict begin/JobName xdf currentdict end setuserparams
}bd
/devg[/DeviceGray]def
/devr[/DeviceRGB]def
/devc[/DeviceCMYK]def
level2 not endnoload
/pm Z
/mT Z
/sD Z
/mTSsetup{
mT $m currentmatrix mTS concatmatrix pop
}bd
/pmSVsetup{
/pm save store
}bd
/initializepage
{
mT concat
}bd
/endp
{
pm restore
}bd
/adjRect
{
dup 2 mul 6 2 roll
4 index sub exch 5 -1 roll sub exch
4 2 roll
4 index add exch 5 -1 roll add exch
4 2 roll
}bd
/frame1up
{
gS
mTS setmatrix
QDframwid lw
/setstrokeadjust where{pop T setstrokeadjust}if
clippath pathbbox
2 index sub exch
3 index sub exch
currentlinewidth framewidth mul
adjRect
numframes dup 0 lt{pop 0}if
{
4 copy
rS
currentlinewidth framewidth
mul 4 mul
adjRect
}repeat
pop pop pop pop
gR
}bd
/$c devr def
/rectclip where
{
pop/rC/rectclip ld
}{
/rC
{
np 4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
:K
clip np
}bd
}ifelse
/rectfill where
{
pop/rF/rectfill ld
}{
/rF
{
gS
np
4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
fill
gR
}bd
}ifelse
/rectstroke where
{
pop/rS/rectstroke ld
}{
/rS
{
gS
np
4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
:K
stroke
gR
}bd
}ifelse
%%EndFile
%%BeginFile: lw8_level1_colorspace-2.0
/G/setgray ld
/:F1/setgray ld
/:F/setrgbcolor ld
/:F4/setcmykcolor where
{
pop
/setcmykcolor ld
}{
{
3
{
dup
3 -1 roll add
dup 1 gt{pop 1}if
1 exch sub
4 1 roll
}repeat
pop
setrgbcolor
}bd
}ifelse
/:Fx
{
counttomark
{0{G}0{:F}{:F4}}
exch get
exec
pop
}bd
/$cs Z
/:rg{devr :ss}bd
/:sc{$cs :ss}bd
/:dc
{
dup type/arraytype eq{0 get}if
dup/DeviceCMYK eq
{
pop devc
}{
/DeviceGray eq
{
devg
}{
devr
}ifelse
}ifelse
/$cs xdf
}bd
/:sgl{}def
/:dr{}bd
/:fCRD{pop}bd
/:ckcs{}bd
/:ss{/$c xdf}bd
%%EndFile
%%BeginFile: lw8_uniform_graphics-2.0
/@a
{
np :M 0 rl :L 0 exch rl 0 rl :L fill
}bd
/@b
{
np :M 0 rl 0 exch rl :L 0 rl 0 exch rl fill
}bd
/@c
{
moveto 0 rlineto stroke
}bd
/@w
{
moveto 0 exch rlineto stroke
}bd
/arct where
{
pop
}{
/arct
{
arcto pop pop pop pop
}bd
}ifelse
/x1 Z
/x2 Z
/y1 Z
/y2 Z
/rad Z
/@q
{
/rad xs
/y2 xs
/x2 xs
/y1 xs
/x1 xs
np
x2 x1 add 2 div y1 :M
x2 y1 x2 y2 rad arct
x2 y2 x1 y2 rad arct
x1 y2 x1 y1 rad arct
x1 y1 x2 y1 rad arct
fill
}bd
/@s
{
/rad xs
/y2 xs
/x2 xs
/y1 xs
/x1 xs
np
x2 x1 add 2 div y1 :M
x2 y1 x2 y2 rad arct
x2 y2 x1 y2 rad arct
x1 y2 x1 y1 rad arct
x1 y1 x2 y1 rad arct
:K
stroke
}bd
/@i
{
np 0 360 arc fill
}bd
/@j
{
gS
np
:T
scale
0 0 .5 0 360 arc
fill
gR
}bd
/@e
{
np
0 360 arc
:K
stroke
}bd
/@f
{
np
$m currentmatrix
pop
:T
scale
0 0 .5 0 360 arc
:K
$m setmatrix
stroke
}bd
/@k
{
gS
np
:T
0 0 :M
0 0 5 2 roll
arc fill
gR
}bd
/@l
{
gS
np
:T
0 0 :M
scale
0 0 .5 5 -2 roll arc
fill
gR
}bd
/@m
{
np
arc
stroke
}bd
/@n
{
np
$m currentmatrix
pop
:T
scale
0 0 .5 5 -2 roll arc
$m setmatrix
stroke
}bd
%%EndFile
%%BeginFile: lw8_bubn-2.1
/$t Z
/$p Z
/$s Z
/$o 1. def
/2state? F def
/ps Z
level2 startnoload
/pushcolor/currentrgbcolor ld
/popcolor/setrgbcolor ld
/setcmykcolor where
{
pop/currentcmykcolor where
{
pop/pushcolor/currentcmykcolor ld
/popcolor/setcmykcolor ld
}if
}if
level2 endnoload level2 not startnoload
/pushcolor
{
currentcolorspace $c eq
{
currentcolor currentcolorspace T
}{
currentcmykcolor F
}ifelse
}bd
/popcolor
{
{
setcolorspace setcolor
}{
setcmykcolor
}ifelse
}bd
level2 not endnoload
/pushstatic
{
2state?
$o
$t
$p
$s
$cs
ps
}bd
/popstatic
{
/ps xs
/$cs xs
/$s xs
/$p xs
/$t xs
/$o xs
/2state? xs
}bd
/pushgstate
{
currentpoint
pushcolor
currentlinewidth
currentlinecap
currentlinejoin
currentdash exch aload length
np clippath pathbbox
$m currentmatrix aload pop
}bd
/popgstate
{
$m astore setmatrix
2 index sub exch
3 index sub exch
rC
array astore exch setdash
setlinejoin
setlinecap
lw
popcolor
np :M
}bd
/bu
{
errordict/nocurrentpoint{pop 0 0}put
2state?
{
pushgstate
gR
}if
pushgstate
gR
pushgstate
pushstatic
pm restore
mTS setmatrix
}bd
/bn
{
/pm save store
popstatic
popgstate
gS
popgstate
2state?
{
gS
popgstate
}if
}bd
/cpat{pop 64 div setgray 8{pop}repeat}bd
%%EndFile
/currentpacking where {pop sc_oldpacking setpacking}if end
%%EndProlog
%%BeginSetup
md begin
%RBIIncludeNonPPDFeature: NumCopies 1
%RBIBeginNonPPDFeature: WaitTimeout 600
600/languagelevel where{pop languagelevel 2 ge}{false}ifelse{1 dict dup/WaitTimeout 4 -1 roll put setuserparams}{statusdict/waittimeout 3 -1 roll put}ifelse
%RBIEndNonPPDFeature
sfcl{
%%BeginFeature: *HPColorAsGray No
<< /ProcessColorModel /DeviceCMYK >> setpagedevice
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPIntent Colorimetric
userdict /UserRenderIntent (RelativeColorimetric) put
<<>> setpagedevice
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPAutoScaling Off
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *PageSize Letter
/HPDict /ProcSet findresource /SetMargins get [ 0 0 0 0 ] exch exec

View File

@ -0,0 +1,160 @@
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *OutputMode Best
<< /PostRenderingEnhance true
/PostRenderingEnhanceDetails
<< /PrintQuality 3
/Type 36 >>
>> systemdict /setpagedevice get exec
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPMaxDetail False
<< /PostRenderingEnhance true
/PostRenderingEnhanceDetails
<< /MaxQualityResolution false
/Type 36 >>
>> systemdict /setpagedevice get exec
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *MirrorPrint False
<</MirrorPrint false>>setpagedevice
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPTransverse False
userdict /HPCustTrans known
{
(<<) cvx exec
/Orientation
userdict /HPCustTrans get
(>>) cvx exec setpagedevice
}
{
<</Orientation 0>> setpagedevice
} ifelse
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPPantone False
/SpotColorMatching where {
pop
false SpotColorMatching
} if
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPColorMan NoEmulation
/CMYKColorManagement where {
pop
/None CMYKColorManagement
/None RGBColorManagement
} if
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPCMYKEmulation None
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPRGBEmulation None
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPCyanBrightness leveleven
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPMagentaBrightness leveleven
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPYellowBrightness leveleven
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPBlackBrightness leveleven
%%EndFeature
}efcl
(FOTOG4)setjob

View File

@ -0,0 +1,12 @@
%RBIIncludeStartNup
/sD 16 dict def
{/Courier findfont[10 0 0 -10 0 0]:mf setfont}stopped{$error/newerror F put}if
%%EndSetup
%%Page: 1 1
%%BeginPageSetup
%RBIIncludePageSlotInvocation
mTSsetup
pmSVsetup
initializepage
(FOTOG4; page: 1 of 1)setjob
%%EndPageSetup

View File

@ -0,0 +1,76 @@
11 -30000 -29999.5 @c
-29990 -30000 :M
psb
gsave %% Print PostScript gsave
/hascolor
/deviceinfo where
{pop deviceinfo /Colors known
{deviceinfo /Colors get exec 1 gt}
{false} ifelse}
{/statusdict where
{pop statusdict /processcolors known
{statusdict /processcolors get exec 1 gt}
{false} ifelse}
{false} ifelse}
ifelse
def
40 dict begin
/_image systemdict /image get def
/_setgray systemdict /setgray get def
/_currentgray systemdict /currentgray get def
/_settransfer systemdict /settransfer get def
/_currenttransfer systemdict /currenttransfer get def
/blank 0 _currenttransfer exec
1 _currenttransfer exec eq def
/negative blank
{0 _currenttransfer exec 0.5 lt}
{0 _currenttransfer exec 1 _currenttransfer exec gt}
ifelse def
/inverted? negative def
/level2 systemdict /languagelevel known
{languagelevel 2 ge} {false} ifelse def
/level3 systemdict /languagelevel known
{languagelevel 3 ge} {false} ifelse def
/foureq {4 index eq 8 1 roll
4 index eq 8 1 roll
4 index eq 8 1 roll
4 index eq 8 1 roll
pop pop pop pop and and and} def
hascolor {/band 0 def} {/band 5 def} ifelse
/setcmykcolor where {pop
1 0 0 0 setcmykcolor _currentgray 1 exch sub
0 1 0 0 setcmykcolor _currentgray 1 exch sub
0 0 1 0 setcmykcolor _currentgray 1 exch sub
0 0 0 1 setcmykcolor _currentgray 1 exch sub
4 {4 copy} repeat
1 0 0 0 foureq {/band 1 store} if
0 1 0 0 foureq {/band 2 store} if
0 0 1 0 foureq {/band 3 store} if
0 0 0 1 foureq {/band 4 store} if
0 0 0 0 foureq {/band 6 store} if} if
blank {/band 6 store} if
blank not {
{} bind
{} bind
{} bind
{} bind
/__settransfer {{dummy1 exec dummy2 exec}
dup 0 4 -1 roll put dup 2 _currenttransfer put
_settransfer} def
band 0 eq {
systemdict /currentcolortransfer get exec
{dummy1 exec dummy2 exec}
dup 0 11 -1 roll put dup 2 7 -1 roll put
{dummy1 exec dummy2 exec}
dup 0 10 -1 roll put dup 2 7 -1 roll put
{dummy1 exec dummy2 exec}
dup 0 9 -1 roll put dup 2 7 -1 roll put
{dummy1 exec dummy2 exec}
dup 0 8 -1 roll put dup 2 7 -1 roll put
systemdict /setcolortransfer get exec} if
band 1 eq {pop pop pop __settransfer} if
band 2 eq {pop pop __settransfer pop} if
band 3 eq {pop __settransfer pop pop} if
band 4 ge {__settransfer pop pop pop} if
} if
gsave % Image Header gsave

View File

@ -0,0 +1,101 @@
level2 {
band 0 eq {
/DeviceCMYK
} {/DeviceGray} ifelse
setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if
/picstr1 cols string def
/picstr2 cols string def
/picstr3 cols string def
/picstr4 cols string def
/picstr5 cols string def
/_rowpadstr cols string def
/rawreaddata {currentfile exch readhexstring pop} def
/padreaddata { _topPad 0 gt { /_topPad _topPad 1 sub def pop _rowpadstr }
{ _subImageRows 0 gt { /_subImageRows _subImageRows 1 sub def
dup _leftPad _picsubstr rawreaddata putinterval }
{ pop _rowpadstr } ifelse } ifelse } def
/image2 level2 {/image load def} {{begin
Width Height BitsPerComponent ImageMatrix
Decode length 2 eq
{/DataSource load image} if
Decode length 6 eq
{DataSource 0 get DataSource 1 get DataSource 2 get
true 3 colorimage} if
Decode length 8 eq
{DataSource 0 get DataSource 1 get
DataSource 2 get DataSource 3 get
true 4 colorimage} if
end} def} ifelse
/_image2 level2 {/_image load def} {{begin
Width Height BitsPerComponent ImageMatrix
/DataSource load _image end} def} ifelse
/beginimage {
band 0 eq band 5 eq or
{image2} if
band 1 ge band 4 le and
{{1 exch sub dummy exec} dup 3 _currenttransfer put
_settransfer _image2} if
band 6 eq
{negative {{pop 0}} {{pop 1}} ifelse
_settransfer _image2} if
} def
/readdata /rawreaddata load bind def
12 dict begin
/ImageType 1 def
/Width cols def
/Height rows def
/ImageMatrix [cols 0 0 rows 0 0] def
/BitsPerComponent 8 def
band 0 eq
{/Decode [0 1 0 1 0 1 0 1] def}
{/Decode [0 1] def} ifelse
band 0 eq {
/MultipleDataSources true def
/DataSource [
{picstr1 readdata}
{picstr2 readdata}
{picstr3 readdata}
{picstr4 readdata picstr5 readdata pop}
] def} if
band 1 eq {
/DataSource {
picstr1 readdata
picstr2 readdata pop
picstr3 readdata pop
picstr4 readdata pop
picstr5 readdata pop
} def} if
band 2 eq {
/DataSource {
picstr1 readdata pop
picstr2 readdata
picstr3 readdata pop
picstr4 readdata pop
picstr5 readdata pop
} def} if
band 3 eq {
/DataSource {
picstr1 readdata pop
picstr2 readdata pop
picstr3 readdata
picstr4 readdata pop
picstr5 readdata pop
} def} if
band 4 eq {
/DataSource {
picstr1 readdata pop
picstr2 readdata pop
picstr3 readdata pop
picstr4 readdata
picstr5 readdata pop
} def} if
band 5 ge {
/DataSource {
picstr1 readdata pop
picstr2 readdata pop
picstr3 readdata pop
picstr4 readdata pop
picstr5 readdata
} def} if
currentdict end
beginimage

View File

@ -0,0 +1,10 @@
grestore end % Image Trailer grestore
grestore % Print PostScript grestore
pse
endp
showpage
%%PageTrailer
%%Trailer
end
%%EOF

View File

@ -0,0 +1,14 @@
vips2djlabpsbitsdir = $(datadir)/vips/vips2dj/lab
vips2djlabpsbits_DATA = \
head1 \
head2 \
head3 \
head4 \
head5 \
head6
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(vips2djlabpsbitsdir)
EXTRA_DIST = $(vips2djlabpsbits_DATA)

View File

@ -0,0 +1,600 @@
%!PS-Adobe-3.0
%%Title: (Lab_example)
%%Creator: (Adobe Photoshop\250 4.0: PSPrinter 8.3.1)
%%CreationDate: (12:54 martes, 5 agosto 1997)
%%For: (Johan Lammens)
%%Pages: 1
%%DocumentFonts:
%%DocumentNeededFonts:
%%DocumentSuppliedFonts:
%%DocumentData: Clean7Bit
%%PageOrder: Ascend
%%Orientation: Portrait
%%DocumentMedia: Default 612 792 0 () ()
%ADO_ImageableArea: 51 77 561 715
%%EndComments
%%BeginDefaults
%%ViewingOrientation: 1 0 0 1
%%EndDefaults
userdict begin/dscInfo 5 dict dup begin
/Title(Lab_example)def
/Creator(Adobe Photoshop\250 4.0: PSPrinter 8.3.1)def
/CreationDate(12:54 martes, 5 agosto 1997)def
/For(Johan Lammens)def
/Pages 1 def
end def end
/md 163 dict def md begin/currentpacking where {pop /sc_oldpacking currentpacking def true setpacking}if
%%BeginFile: adobe_psp_basic
%%Copyright: Copyright 1990-1996 Adobe Systems Incorporated. All Rights Reserved.
/bd{bind def}bind def
/xdf{exch def}bd
/xs{exch store}bd
/ld{load def}bd
/Z{0 def}bd
/T/true
/F/false
/:L/lineto
/lw/setlinewidth
/:M/moveto
/rl/rlineto
/rm/rmoveto
/:C/curveto
/:T/translate
/:K/closepath
/:mf/makefont
/gS/gsave
/gR/grestore
/np/newpath
14{ld}repeat
/$m matrix def
/av 83 def
/por true def
/normland false def
/psb-nosave{}bd
/pse-nosave{}bd
/us Z
/psb{/us save store}bd
/pse{us restore}bd
/level2
/languagelevel where
{
pop languagelevel 2 ge
}{
false
}ifelse
def
/featurecleanup
{
stopped
cleartomark
countdictstack exch sub dup 0 gt
{
{end}repeat
}{
pop
}ifelse
}bd
/noload Z
/startnoload
{
{/noload save store}if
}bd
/endnoload
{
{noload restore}if
}bd
level2 startnoload
/setjob
{
statusdict/jobname 3 -1 roll put
}bd
/setcopies
{
userdict/#copies 3 -1 roll put
}bd
level2 endnoload level2 not startnoload
/setjob
{
1 dict begin/JobName xdf currentdict end setuserparams
}bd
/setcopies
{
1 dict begin/NumCopies xdf currentdict end setpagedevice
}bd
level2 not endnoload
/pm Z
/mT Z
/sD Z
/realshowpage Z
/initializepage
{
/pm save store mT concat
}bd
/endp
{
pm restore showpage
}def
/endp1
{
pm restore
}def
/endp2
{
showpage
}def
/$c/DeviceRGB def
/rectclip where
{
pop/rC/rectclip ld
}{
/rC
{
np 4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
:K
clip np
}bd
}ifelse
/rectfill where
{
pop/rF/rectfill ld
}{
/rF
{
gS
np
4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
fill
gR
}bd
}ifelse
/rectstroke where
{
pop/rS/rectstroke ld
}{
/rS
{
gS
np
4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
:K
stroke
gR
}bd
}ifelse
%%EndFile
%%BeginFile: adobe_psp_colorspace_level1
%%Copyright: Copyright 1991-1996 Adobe Systems Incorporated. All Rights Reserved.
/G/setgray ld
/:F1/setgray ld
/:F/setrgbcolor ld
/:F4/setcmykcolor where
{
pop
/setcmykcolor ld
}{
{
3
{
dup
3 -1 roll add
dup 1 gt{pop 1}if
1 exch sub
4 1 roll
}repeat
pop
setrgbcolor
}bd
}ifelse
/:Fx
{
counttomark
{0{G}0{:F}{:F4}}
exch get
exec
pop
}bd
/:rg{/DeviceRGB :ss}bd
/:sc{$cs :ss}bd
/:dc{/$cs xdf}bd
/:sgl{}def
/:dr{}bd
/:nmCRD{pop}bd
/:fCRD{pop}bd
/:ckcs{}bd
/:ss{/$c xdf}bd
/$cs Z
%%EndFile
%%BeginFile: adobe_psp_uniform_graphics
%%Copyright: Copyright 1990-1996 Adobe Systems Incorporated. All Rights Reserved.
/@a
{
np :M 0 rl :L 0 exch rl 0 rl :L fill
}bd
/@b
{
np :M 0 rl 0 exch rl :L 0 rl 0 exch rl fill
}bd
/@c
{
moveto lineto stroke
}bd
/arct where
{
pop
}{
/arct
{
arcto pop pop pop pop
}bd
}ifelse
/x1 Z
/x2 Z
/y1 Z
/y2 Z
/rad Z
/@q
{
/rad xs
/y2 xs
/x2 xs
/y1 xs
/x1 xs
np
x2 x1 add 2 div y1 :M
x2 y1 x2 y2 rad arct
x2 y2 x1 y2 rad arct
x1 y2 x1 y1 rad arct
x1 y1 x2 y1 rad arct
fill
}bd
/@s
{
/rad xs
/y2 xs
/x2 xs
/y1 xs
/x1 xs
np
x2 x1 add 2 div y1 :M
x2 y1 x2 y2 rad arct
x2 y2 x1 y2 rad arct
x1 y2 x1 y1 rad arct
x1 y1 x2 y1 rad arct
:K
stroke
}bd
/@i
{
np 0 360 arc fill
}bd
/@j
{
gS
np
:T
scale
0 0 .5 0 360 arc
fill
gR
}bd
/@e
{
np
0 360 arc
:K
stroke
}bd
/@f
{
np
$m currentmatrix
pop
:T
scale
0 0 .5 0 360 arc
:K
$m setmatrix
stroke
}bd
/@k
{
gS
np
:T
0 0 :M
0 0 5 2 roll
arc fill
gR
}bd
/@l
{
gS
np
:T
0 0 :M
scale
0 0 .5 5 -2 roll arc
fill
gR
}bd
/@m
{
np
arc
stroke
}bd
/@n
{
np
$m currentmatrix
pop
:T
scale
0 0 .5 5 -2 roll arc
$m setmatrix
stroke
}bd
%%EndFile
%%BeginFile: adobe_psp_customps
%%Copyright: Copyright 1990-1996 Adobe Systems Incorporated. All Rights Reserved.
/$t Z
/$p Z
/$s Z
/$o 1. def
/2state? false def
/ps Z
level2 startnoload
/pushcolor/currentrgbcolor ld
/popcolor/setrgbcolor ld
/setcmykcolor where
{
pop/currentcmykcolor where
{
pop/pushcolor/currentcmykcolor ld
/popcolor/setcmykcolor ld
}if
}if
level2 endnoload level2 not startnoload
/pushcolor
{
currentcolorspace $c eq
{
currentcolor currentcolorspace true
}{
currentcmykcolor false
}ifelse
}bd
/popcolor
{
{
setcolorspace setcolor
}{
setcmykcolor
}ifelse
}bd
level2 not endnoload
/pushstatic
{
ps
2state?
$o
$t
$p
$s
$cs
}bd
/popstatic
{
/$cs xs
/$s xs
/$p xs
/$t xs
/$o xs
/2state? xs
/ps xs
}bd
/pushgstate
{
save errordict/nocurrentpoint{pop 0 0}put
currentpoint
3 -1 roll restore
pushcolor
currentlinewidth
currentlinecap
currentlinejoin
currentdash exch aload length
np clippath pathbbox
$m currentmatrix aload pop
}bd
/popgstate
{
$m astore setmatrix
2 index sub exch
3 index sub exch
rC
array astore exch setdash
setlinejoin
setlinecap
lw
popcolor
np :M
}bd
/bu
{
pushgstate
gR
pushgstate
2state?
{
gR
pushgstate
}if
pushstatic
pm restore
mT concat
}bd
/bn
{
/pm save store
popstatic
popgstate
gS
popgstate
2state?
{
gS
popgstate
}if
}bd
/cpat{pop 64 div setgray 8{pop}repeat}bd
%%EndFile
%%BeginFile: adobe_psp_basic_text
%%Copyright: Copyright 1990-1996 Adobe Systems Incorporated. All Rights Reserved.
/S/show ld
/A{
0.0 exch ashow
}bd
/R{
0.0 exch 32 exch widthshow
}bd
/W{
0.0 3 1 roll widthshow
}bd
/J{
0.0 32 4 2 roll 0.0 exch awidthshow
}bd
/V{
0.0 4 1 roll 0.0 exch awidthshow
}bd
/fcflg true def
/fc{
fcflg{
vmstatus exch sub 50000 lt{
(%%[ Warning: Running out of memory ]%%\r)print flush/fcflg false store
}if pop
}if
}bd
/$f[1 0 0 -1 0 0]def
/:ff{$f :mf}bd
/MacEncoding StandardEncoding 256 array copy def
MacEncoding 39/quotesingle put
MacEncoding 96/grave put
/Adieresis/Aring/Ccedilla/Eacute/Ntilde/Odieresis/Udieresis/aacute
/agrave/acircumflex/adieresis/atilde/aring/ccedilla/eacute/egrave
/ecircumflex/edieresis/iacute/igrave/icircumflex/idieresis/ntilde/oacute
/ograve/ocircumflex/odieresis/otilde/uacute/ugrave/ucircumflex/udieresis
/dagger/degree/cent/sterling/section/bullet/paragraph/germandbls
/registered/copyright/trademark/acute/dieresis/notequal/AE/Oslash
/infinity/plusminus/lessequal/greaterequal/yen/mu/partialdiff/summation
/product/pi/integral/ordfeminine/ordmasculine/Omega/ae/oslash
/questiondown/exclamdown/logicalnot/radical/florin/approxequal/Delta/guillemotleft
/guillemotright/ellipsis/space/Agrave/Atilde/Otilde/OE/oe
/endash/emdash/quotedblleft/quotedblright/quoteleft/quoteright/divide/lozenge
/ydieresis/Ydieresis/fraction/currency/guilsinglleft/guilsinglright/fi/fl
/daggerdbl/periodcentered/quotesinglbase/quotedblbase/perthousand
/Acircumflex/Ecircumflex/Aacute/Edieresis/Egrave/Iacute/Icircumflex/Idieresis/Igrave
/Oacute/Ocircumflex/apple/Ograve/Uacute/Ucircumflex/Ugrave/dotlessi/circumflex/tilde
/macron/breve/dotaccent/ring/cedilla/hungarumlaut/ogonek/caron
MacEncoding 128 128 getinterval astore pop
level2 startnoload
/copyfontdict
{
findfont dup length dict
begin
{
1 index/FID ne{def}{pop pop}ifelse
}forall
}bd
level2 endnoload level2 not startnoload
/copyfontdict
{
findfont dup length dict
copy
begin
}bd
level2 not endnoload
md/fontname known not{
/fontname/customfont def
}if
/Encoding Z
/:mre
{
copyfontdict
/Encoding MacEncoding def
fontname currentdict
end
definefont :ff def
}bd
/:bsr
{
copyfontdict
/Encoding Encoding 256 array copy def
Encoding dup
}bd
/pd{put dup}bd
/:esr
{
pop pop
fontname currentdict
end
definefont :ff def
}bd
/scf
{
scalefont def
}bd
/scf-non
{
$m scale :mf setfont
}bd
/ps Z
/fz{/ps xs}bd
/sf/setfont ld
/cF/currentfont ld
/mbf
{
/makeblendedfont where
{
pop
makeblendedfont
/ABlend exch definefont
}{
pop
}ifelse
def
}def
%%EndFile
/currentpacking where {pop sc_oldpacking setpacking}if end
%%EndProlog
%%BeginSetup
md begin
countdictstack[{
%%BeginFeature: *InputSlot OnlyOne
%%EndFeature
}featurecleanup
countdictstack[{
%%BeginFeature: *InstalledMemory standard
%%EndFeature
}featurecleanup
countdictstack[{
%%BeginFeature: *HPIntent Colorimetric
userdict /UserRenderIntent (Colorimetric) put
<<>> setpagedevice
%%EndFeature
}featurecleanup
countdictstack[{
%%BeginFeature: *PageRegion Letter

View File

@ -0,0 +1,3 @@
%%EndFeature
}featurecleanup
(Johan Lammens; document: Lab_example)setjob

View File

@ -0,0 +1,9 @@
/sD 16 dict def
300 level2{1 dict dup/WaitTimeout 4 -1 roll put setuserparams}{statusdict/waittimeout 3 -1 roll put}ifelse
/Courier findfont[10 0 0 -10 0 0]:mf setfont
%%EndSetup
%%Page: 1 1
%%BeginPageSetup
initializepage
(Johan Lammens; document: Lab_example; page: 1 of 1)setjob
%%EndPageSetup

View File

@ -0,0 +1,71 @@
-30000 -29999 -1 1 -29989 -30000 1 -30000 -30000 @a
-30000 -30000 :M
psb
gsave
/hascolor
/deviceinfo where
{pop deviceinfo /Colors known
{deviceinfo /Colors get exec 1 gt}
{false} ifelse}
{/statusdict where
{pop statusdict /processcolors known
{statusdict /processcolors get exec 1 gt}
{false} ifelse}
{false} ifelse}
ifelse
def
40 dict begin
/_image systemdict /image get def
/_setgray systemdict /setgray get def
/_currentgray systemdict /currentgray get def
/_settransfer systemdict /settransfer get def
/_currenttransfer systemdict /currenttransfer get def
/blank 0 _currenttransfer exec
1 _currenttransfer exec eq def
/negative blank
{0 _currenttransfer exec 0.5 lt}
{0 _currenttransfer exec 1 _currenttransfer exec gt}
ifelse def
/inverted? negative def
/level2 systemdict /languagelevel known
{languagelevel 2 ge} {false} ifelse def
/foureq {4 index eq 8 1 roll
4 index eq 8 1 roll
4 index eq 8 1 roll
4 index eq 8 1 roll
pop pop pop pop and and and} def
hascolor {/band 0 def} {/band 5 def} ifelse
/setcmykcolor where {pop
1 0 0 0 setcmykcolor _currentgray 1 exch sub
0 1 0 0 setcmykcolor _currentgray 1 exch sub
0 0 1 0 setcmykcolor _currentgray 1 exch sub
0 0 0 1 setcmykcolor _currentgray 1 exch sub
4 {4 copy} repeat
1 0 0 0 foureq {/band 1 store} if
0 1 0 0 foureq {/band 2 store} if
0 0 1 0 foureq {/band 3 store} if
0 0 0 1 foureq {/band 4 store} if
0 0 0 0 foureq {/band 6 store} if} if
blank {/band 6 store} if
blank not {
{} bind
{} bind
{} bind
{} bind
/__settransfer {{dummy1 exec dummy2 exec}
dup 0 4 -1 roll put dup 2 _currenttransfer put
_settransfer} def
band 0 eq {
systemdict /currentcolortransfer get exec
{dummy1 exec dummy2 exec}
dup 0 11 -1 roll put dup 2 7 -1 roll put
{dummy1 exec dummy2 exec}
dup 0 10 -1 roll put dup 2 7 -1 roll put
{dummy1 exec dummy2 exec}
dup 0 9 -1 roll put dup 2 7 -1 roll put
{dummy1 exec dummy2 exec}
dup 0 8 -1 roll put dup 2 7 -1 roll put
systemdict /setcolortransfer get exec} if
band 0 ne {__settransfer pop pop pop} if
} if
gsave

View File

@ -0,0 +1,70 @@
level2 {
band 0 eq {
[/CIEBasedABC 5 dict begin
/RangeABC [0 100 -128 127 -128 127] def
/DecodeABC [{16 add 116 div} bind
{500 div} bind {200 div} bind] def
/MatrixABC [1 1 1 1 0 0 0 0 -1] def
/DecodeLMN [
{dup 6 29 div ge {dup dup mul mul}
{4 29 div sub 108 841 div mul}
ifelse 0.9505 mul} bind
{dup 6 29 div ge {dup dup mul mul}
{4 29 div sub 108 841 div mul}
ifelse} bind
{dup 6 29 div ge {dup dup mul mul}
{4 29 div sub 108 841 div mul}
ifelse 1.0890 mul} bind
] def
/WhitePoint [0.9505 1 1.0890] def
currentdict end]
} {/DeviceGray} ifelse
setcolorspace} if
/picstr1 cols string def
/picstr2 cols string def
/picstr3 cols string def
/readdata {currentfile exch readhexstring pop} def
/image2 level2 {/image load def} {{begin
Width Height BitsPerComponent ImageMatrix
Decode length 2 eq
{/DataSource load image} if
Decode length 6 eq
{DataSource 0 get DataSource 1 get DataSource 2 get
true 3 colorimage} if
Decode length 8 eq
{DataSource 0 get DataSource 1 get
DataSource 2 get DataSource 3 get
true 4 colorimage} if
end} def} ifelse
/_image2 level2 {/_image load def} {{begin
Width Height BitsPerComponent ImageMatrix
/DataSource load _image end} def} ifelse
/beginimage {
band 0 eq band 4 eq or band 5 eq or
{image2}
{negative {{pop 0}} {{pop 1}} ifelse
_settransfer _image2} ifelse
} def
12 dict begin
/ImageType 1 def
/Width cols def
/Height rows def
/ImageMatrix [cols 0 0 rows 0 0] def
/BitsPerComponent 8 def
band 0 eq level2 and
{/Decode [0 100 -128 127 -128 127] def
/MultipleDataSources true def
/DataSource [
{picstr1 readdata}
{picstr2 readdata}
{picstr3 readdata}
] def}
{/Decode [0 1] def
/DataSource {
picstr1 readdata
picstr2 readdata pop
picstr3 readdata pop
} def}
ifelse
currentdict end
beginimage

View File

@ -0,0 +1,9 @@
grestore end
grestore
pse
endp
%%PageTrailer
%%Trailer
end
%%EOF

View File

@ -0,0 +1,14 @@
vips2djmonopsbitsdir = $(datadir)/vips/vips2dj/mono
vips2djmonopsbits_DATA = \
head1 \
head2 \
head3 \
head4 \
head5 \
head6
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(vips2djmonopsbitsdir)
EXTRA_DIST = $(vips2djmonopsbits_DATA)

View File

@ -0,0 +1,686 @@
%!PS-Adobe-3.0
%%Title: (Untitled-1)
%%Creator: (Adobe\250 Photoshop\250 6.0: AdobePS 8.7.0)
%%CreationDate: (3:00 pm Tuesday, April 30, 2002)
%%For: (FOTOG4)
%%Routing: (mailto:Colin.White@ng-london.org.uk)
%%Pages: 1
%%DocumentFonts:
%%DocumentNeededResources:
%%DocumentSuppliedResources:
%%DocumentData: Clean7Bit
%%PageOrder: Ascend
%%Orientation: Portrait
%%DocumentMedia: (Default) 612 792 0 () ()
%RBINumCopies: 1
%RBINupNess: 1 1
%ADO_ImageableArea: 30 33 582 761
%RBIDocumentSuppliedFonts:
[{
%%BeginPluginPS: SetTime
/HPDict /ProcSet findresource /SetTime get (20020430145733) exch exec
%%EndPluginPS
}stopped cleartomark
[{
%%BeginPluginPS: HPJobname
/HPDict /ProcSet findresource /SetJobName get (Untitled_1) exch exec
%%EndPluginPS
}stopped cleartomark
%%EndComments
%%BeginDefaults
%%ViewingOrientation: 1 0 0 1
%%EndDefaults
userdict/dscInfo 5 dict dup begin
/Title(Untitled-1)def
/Creator(Adobe\250 Photoshop\250 6.0: AdobePS 8.7.0)def
/CreationDate(3:00 pm Tuesday, April 30, 2002)def
/For(FOTOG4)def
/Pages 1 def
end put
%%BeginProlog
/md 178 dict def md begin/currentpacking where {pop /sc_oldpacking currentpacking def true setpacking}if
%%BeginFile: lw8_feature-1.01
%%Copyright: Copyright 1990-1999 Adobe Systems Incorporated and Apple Computer Incorporated. All Rights Reserved.
/bd{bind def}bind def
/ld{load def}bd
/xs{exch store}bd
/Z{0 def}bd
/T true def
/F false def
/level2
/languagelevel where
{
pop languagelevel 2 ge
}{
F
}ifelse
def
/odictstk Z
/oopstk Z
/fcl
{
count oopstk sub dup 0 gt
{
{pop}repeat
}{
pop
}ifelse
countdictstack odictstk sub dup 0 gt
{
{end}repeat
}{
pop
}ifelse
}bd
/sfcl2
{
/odictstk countdictstack store
count/oopstk xs
}bd
/efcl2
{
stopped{$error/newerror F put}if
fcl
}bd
/noload Z
/startnoload
{
{/noload save store}if
}bd
/endnoload
{
{noload restore}if
}bd
/setcopies{
level2
{
1 dict begin/NumCopies exch def currentdict end setpagedevice
}{
userdict/#copies 3 -1 roll put
}ifelse
}def
level2 startnoload
/ststpgdev{}def
/dopgdev{}def
/stpgdev{}def
/buf Z
/didstop T def
/sfcl
{
/didstop T store
/odictstk countdictstack store
count/oopstk xs
currentfile cvx stopped
{
$error/newerror F put
didstop
{
save/didstop xs
/buf vmstatus exch sub exch pop dup 0 lt{pop 0}if
dup 64000 gt{pop 64000}if string store
{
currentfile buf readline
{
(}efcl)eq{exit}if
}{
/UnexpectedEOF errordict/rangecheck get exec
}ifelse
}loop
didstop restore
}if
}if
fcl
}bd
/efcl
{
/didstop F store
exec
stop
}bd
level2 endnoload level2 not startnoload
/setpagedevice where{pop/realstpgdev/setpagedevice ld}if
/SC_topddict Z
/SC_spdict Z
/$spusrdict F def
/dopgdev
{
userdict/setpagedevice undef
$spusrdict
{
userdict/setpagedevice/realstpgdev load put
/$spusrdict F store
}if
SC_topddict realstpgdev
}bd
/stpgdev
{
SC_topddict dup 3 -1 roll
{
SC_spdict 2 index known
{
SC_spdict 2 index get
dup 3 -1 roll
{
put dup
}forall
pop put dup
}{
put dup
}ifelse
}forall
pop pop
}bd
/ststpgdev
{
/setpagedevice where
{
userdict eq
{
/$spusrdict T store
}if
}if
userdict/setpagedevice/stpgdev load put
/SC_topddict 0 dict store
/SC_spdict 3 dict begin
/InputAttributes 0 dict def
/Policies 0 dict def
/OutputAttributes 0 dict def
currentdict
end
store
}def
/sfcl/sfcl2 ld
/efcl/efcl2 ld
level2 not endnoload
%%EndFile
%%BeginFile: lw8_basic-4.0
/xdf{exch def}bd
/:L/lineto
/lw/setlinewidth
/:M/moveto
/rl/rlineto
/rm/rmoveto
/:C/curveto
/:T/translate
/:K/closepath
/:mf/makefont
/gS/gsave
/gR/grestore
/np/newpath
12{ld}repeat
/framewidth -1 def
/QDframwid -1 def
/numframes Z
/mTS matrix def
/$m matrix def
/av 87 def
/por T def
/normland F def
/psb-nosave{}def
/pse-nosave{}def
/us Z
/psb{/us save store}bd
/pse{us restore}bd
/level3
/languagelevel where
{
pop languagelevel 3 ge
}{
F
}ifelse
def
level2 startnoload
/setjob
{
statusdict/jobname 3 -1 roll put
}bd
/devg/DeviceGray def
/devr/DeviceRGB def
/devc/DeviceCMYK def
level2 endnoload level2 not startnoload
/setjob
{
1 dict begin/JobName xdf currentdict end setuserparams
}bd
/devg[/DeviceGray]def
/devr[/DeviceRGB]def
/devc[/DeviceCMYK]def
level2 not endnoload
/pm Z
/mT Z
/sD Z
/mTSsetup{
mT $m currentmatrix mTS concatmatrix pop
}bd
/pmSVsetup{
/pm save store
}bd
/initializepage
{
mT concat
}bd
/endp
{
pm restore
}bd
/adjRect
{
dup 2 mul 6 2 roll
4 index sub exch 5 -1 roll sub exch
4 2 roll
4 index add exch 5 -1 roll add exch
4 2 roll
}bd
/frame1up
{
gS
mTS setmatrix
QDframwid lw
/setstrokeadjust where{pop T setstrokeadjust}if
clippath pathbbox
2 index sub exch
3 index sub exch
currentlinewidth framewidth mul
adjRect
numframes dup 0 lt{pop 0}if
{
4 copy
rS
currentlinewidth framewidth
mul 4 mul
adjRect
}repeat
pop pop pop pop
gR
}bd
/$c devr def
/rectclip where
{
pop/rC/rectclip ld
}{
/rC
{
np 4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
:K
clip np
}bd
}ifelse
/rectfill where
{
pop/rF/rectfill ld
}{
/rF
{
gS
np
4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
fill
gR
}bd
}ifelse
/rectstroke where
{
pop/rS/rectstroke ld
}{
/rS
{
gS
np
4 2 roll
:M
1 index 0 rl
0 exch rl
neg 0 rl
:K
stroke
gR
}bd
}ifelse
%%EndFile
%%BeginFile: lw8_level1_colorspace-2.0
/G/setgray ld
/:F1/setgray ld
/:F/setrgbcolor ld
/:F4/setcmykcolor where
{
pop
/setcmykcolor ld
}{
{
3
{
dup
3 -1 roll add
dup 1 gt{pop 1}if
1 exch sub
4 1 roll
}repeat
pop
setrgbcolor
}bd
}ifelse
/:Fx
{
counttomark
{0{G}0{:F}{:F4}}
exch get
exec
pop
}bd
/$cs Z
/:rg{devr :ss}bd
/:sc{$cs :ss}bd
/:dc
{
dup type/arraytype eq{0 get}if
dup/DeviceCMYK eq
{
pop devc
}{
/DeviceGray eq
{
devg
}{
devr
}ifelse
}ifelse
/$cs xdf
}bd
/:sgl{}def
/:dr{}bd
/:fCRD{pop}bd
/:ckcs{}bd
/:ss{/$c xdf}bd
%%EndFile
%%BeginFile: lw8_uniform_graphics-2.0
/@a
{
np :M 0 rl :L 0 exch rl 0 rl :L fill
}bd
/@b
{
np :M 0 rl 0 exch rl :L 0 rl 0 exch rl fill
}bd
/@c
{
moveto 0 rlineto stroke
}bd
/@w
{
moveto 0 exch rlineto stroke
}bd
/arct where
{
pop
}{
/arct
{
arcto pop pop pop pop
}bd
}ifelse
/x1 Z
/x2 Z
/y1 Z
/y2 Z
/rad Z
/@q
{
/rad xs
/y2 xs
/x2 xs
/y1 xs
/x1 xs
np
x2 x1 add 2 div y1 :M
x2 y1 x2 y2 rad arct
x2 y2 x1 y2 rad arct
x1 y2 x1 y1 rad arct
x1 y1 x2 y1 rad arct
fill
}bd
/@s
{
/rad xs
/y2 xs
/x2 xs
/y1 xs
/x1 xs
np
x2 x1 add 2 div y1 :M
x2 y1 x2 y2 rad arct
x2 y2 x1 y2 rad arct
x1 y2 x1 y1 rad arct
x1 y1 x2 y1 rad arct
:K
stroke
}bd
/@i
{
np 0 360 arc fill
}bd
/@j
{
gS
np
:T
scale
0 0 .5 0 360 arc
fill
gR
}bd
/@e
{
np
0 360 arc
:K
stroke
}bd
/@f
{
np
$m currentmatrix
pop
:T
scale
0 0 .5 0 360 arc
:K
$m setmatrix
stroke
}bd
/@k
{
gS
np
:T
0 0 :M
0 0 5 2 roll
arc fill
gR
}bd
/@l
{
gS
np
:T
0 0 :M
scale
0 0 .5 5 -2 roll arc
fill
gR
}bd
/@m
{
np
arc
stroke
}bd
/@n
{
np
$m currentmatrix
pop
:T
scale
0 0 .5 5 -2 roll arc
$m setmatrix
stroke
}bd
%%EndFile
%%BeginFile: lw8_bubn-2.1
/$t Z
/$p Z
/$s Z
/$o 1. def
/2state? F def
/ps Z
level2 startnoload
/pushcolor/currentrgbcolor ld
/popcolor/setrgbcolor ld
/setcmykcolor where
{
pop/currentcmykcolor where
{
pop/pushcolor/currentcmykcolor ld
/popcolor/setcmykcolor ld
}if
}if
level2 endnoload level2 not startnoload
/pushcolor
{
currentcolorspace $c eq
{
currentcolor currentcolorspace T
}{
currentcmykcolor F
}ifelse
}bd
/popcolor
{
{
setcolorspace setcolor
}{
setcmykcolor
}ifelse
}bd
level2 not endnoload
/pushstatic
{
2state?
$o
$t
$p
$s
$cs
ps
}bd
/popstatic
{
/ps xs
/$cs xs
/$s xs
/$p xs
/$t xs
/$o xs
/2state? xs
}bd
/pushgstate
{
currentpoint
pushcolor
currentlinewidth
currentlinecap
currentlinejoin
currentdash exch aload length
np clippath pathbbox
$m currentmatrix aload pop
}bd
/popgstate
{
$m astore setmatrix
2 index sub exch
3 index sub exch
rC
array astore exch setdash
setlinejoin
setlinecap
lw
popcolor
np :M
}bd
/bu
{
errordict/nocurrentpoint{pop 0 0}put
2state?
{
pushgstate
gR
}if
pushgstate
gR
pushgstate
pushstatic
pm restore
mTS setmatrix
}bd
/bn
{
/pm save store
popstatic
popgstate
gS
popgstate
2state?
{
gS
popgstate
}if
}bd
/cpat{pop 64 div setgray 8{pop}repeat}bd
%%EndFile
/currentpacking where {pop sc_oldpacking setpacking}if end
%%EndProlog
%%BeginSetup
md begin
%RBIIncludeNonPPDFeature: NumCopies 1
%RBIBeginNonPPDFeature: WaitTimeout 600
600/languagelevel where{pop languagelevel 2 ge}{false}ifelse{1 dict dup/WaitTimeout 4 -1 roll put setuserparams}{statusdict/waittimeout 3 -1 roll put}ifelse
%RBIEndNonPPDFeature
sfcl{
%%BeginFeature: *HPColorAsGray No
<< /ProcessColorModel /DeviceCMYK >> setpagedevice
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPIntent Colorimetric
userdict /UserRenderIntent (RelativeColorimetric) put
<<>> setpagedevice
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPAutoScaling Off
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *PageSize Letter
/HPDict /ProcSet findresource /SetMargins get [ 0 0 0 0 ] exch exec

View File

@ -0,0 +1,160 @@
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *OutputMode Best
<< /PostRenderingEnhance true
/PostRenderingEnhanceDetails
<< /PrintQuality 3
/Type 36 >>
>> systemdict /setpagedevice get exec
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPMaxDetail False
<< /PostRenderingEnhance true
/PostRenderingEnhanceDetails
<< /MaxQualityResolution false
/Type 36 >>
>> systemdict /setpagedevice get exec
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *MirrorPrint False
<</MirrorPrint false>>setpagedevice
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPTransverse False
userdict /HPCustTrans known
{
(<<) cvx exec
/Orientation
userdict /HPCustTrans get
(>>) cvx exec setpagedevice
}
{
<</Orientation 0>> setpagedevice
} ifelse
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPPantone False
/SpotColorMatching where {
pop
false SpotColorMatching
} if
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPColorMan Native
/CMYKColorManagement where {
pop
/Native CMYKColorManagement
/sRGB RGBColorManagement
} if
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPCMYKEmulation None
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPRGBEmulation None
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPCyanBrightness leveleven
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPMagentaBrightness leveleven
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPYellowBrightness leveleven
%%EndFeature
}efcl
sfcl{
%%BeginFeature: *HPBlackBrightness leveleven
%%EndFeature
}efcl
(FOTOG4)setjob

View File

@ -0,0 +1,12 @@
%RBIIncludeStartNup
/sD 16 dict def
{/Courier findfont[10 0 0 -10 0 0]:mf setfont}stopped{$error/newerror F put}if
%%EndSetup
%%Page: 1 1
%%BeginPageSetup
%RBIIncludePageSlotInvocation
mTSsetup
pmSVsetup
initializepage
(FOTOG4; page: 1 of 1)setjob
%%EndPageSetup

View File

@ -0,0 +1,29 @@
11 -30000 -29999.5 @c
-29990 -30000 :M
psb
gsave %% Print PostScript gsave
40 dict begin
/_image systemdict /image get def
/_setgray systemdict /setgray get def
/_currentgray systemdict /currentgray get def
/_settransfer systemdict /settransfer get def
/_currenttransfer systemdict /currenttransfer get def
/blank 0 _currenttransfer exec
1 _currenttransfer exec eq def
/negative blank
{0 _currenttransfer exec 0.5 lt}
{0 _currenttransfer exec 1 _currenttransfer exec gt}
ifelse def
/inverted? negative def
/level2 systemdict /languagelevel known
{languagelevel 2 ge} {false} ifelse def
/level3 systemdict /languagelevel known
{languagelevel 3 ge} {false} ifelse def
blank not {
{} bind
/__settransfer {{dummy1 exec dummy2 exec}
dup 0 4 -1 roll put dup 2 _currenttransfer put
_settransfer} def
__settransfer
} if
gsave % Image Header gsave

View File

@ -0,0 +1,27 @@
level2 {
/DeviceGray
setcolorspace currentdict /PhotoshopDuotoneColorSpace undef currentdict /PhotoshopDuotoneAltColorSpace undef } if
/picstr1 cols string def
/_rowpadstr cols string def
/rawreaddata {currentfile exch readhexstring pop} def
/padreaddata { _topPad 0 gt { /_topPad _topPad 1 sub def pop _rowpadstr }
{ _subImageRows 0 gt { /_subImageRows _subImageRows 1 sub def
dup _leftPad _picsubstr rawreaddata putinterval }
{ pop _rowpadstr } ifelse } ifelse } def
/image2 level2 {/image load def} {{begin
Width Height BitsPerComponent ImageMatrix
/DataSource load image end} def} ifelse
/beginimage {
image2
} def
/readdata /rawreaddata load bind def
12 dict begin
/ImageType 1 def
/Width cols def
/Height rows def
/ImageMatrix [cols 0 0 rows 0 0] def
/BitsPerComponent 8 def
/Decode [0 1] def
/DataSource {picstr1 readdata} def
currentdict end
beginimage

View File

@ -0,0 +1,11 @@
grestore end % Image Trailer grestore
grestore % Print PostScript grestore
pse
endp
showpage
%%PageTrailer
%%Trailer
end
%%EOF

170
contrib/vips2dj/vips2ah.c Normal file
View File

@ -0,0 +1,170 @@
/* Output IM_CODING_LABQ as band-separated ASCIIHEX for PostScript
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <vips/vips.h>
#include <vips/region.h>
static int
writeimage( REGION *ir, FILE *out )
{
IMAGE *im = ir->im;
int x, y, z;
int l = 0;
PEL *p;
Rect area;
/* Set up input area.
*/
area.left = 0;
area.top = 0;
area.width = im->Xsize;
area.height = 1;
/* Write a byte.
*/
#define PUT( C ) {\
int c1 = (C);\
\
if( putc( c1, out ) == EOF ) {\
im_errormsg( "vips2hp2500cp: write error - disc full?" );\
return( -1 );\
}\
}
/* Write a hex character.
*/
#define writehexc( C ) {\
int c = (C);\
\
if( c < 10 ) {\
PUT( c + '0' );\
}\
else\
PUT( (c - 10) + 'A' );\
}
/* Write a hex byte.
*/
#define writehexb( B ) { \
int b = (B);\
\
writehexc( (b >> 4 ) & 0xf );\
writehexc( b & 0xf );\
}
/* Output a hex byte, linefeed on eol.
*/
#define writewrap( B ) { \
writehexb( B ); \
if( l++ > 30 ) { \
PUT( '\n' ); \
l = 0; \
} \
}
/* Loop for each scan-line.
*/
for( y = 0; y < im->Ysize; y++ ) {
/* Ask for this scan-line.
*/
area.top = y;
if( im_prepare( ir, &area ) )
return( -1 );
p = (PEL *) IM_REGION_ADDR( ir, 0, y );
if( im->Coding == IM_CODING_LABQ ) {
/* Do L* ... easy.
*/
for( x = 0; x < im->Xsize; x++ )
writewrap( p[x*4] );
/* a* and b* ... more difficult. Photoshop uses
* bizzare coding for a/b.
*/
for( z = 1; z < 3; z++ ) {
for( x = 0; x < im->Xsize; x++ ) {
int i = (signed char) p[x*4 + z];
writewrap( i + 128 );
}
}
}
else if( im->Bands == 4 ) {
for( z = 0; z < 4; z++ )
for( x = 0; x < im->Xsize; x++ ) {
int v = p[x*4 + z];
writewrap( v );
}
/* Extra channel?? Just send zeros.
*/
for( x = 0; x < im->Xsize; x++ )
writewrap( 0xff );
}
else if( im->Bands == 1 ) {
for( x = 0; x < im->Xsize; x++ ) {
int v = p[x];
writewrap( v );
}
}
}
PUT( '\n' );
return( 0 );
}
/* Start here!
*/
int
vips2asciihex( IMAGE *in, FILE *out )
{
REGION *ir;
if( im_pincheck( in ) )
return( -1 );
if( !(ir = im_region_create( in )) )
return( -1 );
if( writeimage( ir, out ) ) {
im_region_free( ir );
return( -1 );
}
im_region_free( ir );
return( 0 );
}

377
contrib/vips2dj/vips2dj.c Normal file
View File

@ -0,0 +1,377 @@
/* Convert lab, cmyk and mono images to postscript.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <vips/vips.h>
#include <vips/util.h>
#include "vips2dj.h"
static const char *argv0 = NULL;
/* Geometries for the printers we know about.
*/
PrinterGeometry printer_data[] = {
/* name, paper width, print width, print length, left, top */
{ "2500cp", 2592, 2502, 3728, 51, 82 },
{ "3500cp", 3888, 3786, 5212, 51, 82 },
{ "5000ps", 4320, 4280, 5212, 20, 99 },
{ "4600dn", 594, 570, 817, 11, 15 }
};
/* Print a geo entry.
*/
static void
print_printers( void )
{
int i;
printf( "%12s %12s %12s %12s %12s %12s\n", "printer name",
"paper width", "print width", "print length",
"left margin", "top margin" );
for( i = 0; i < IM_NUMBER( printer_data ); i++ )
printf( "%12s %12d %12d %12d %12d %12d\n",
printer_data[i].name,
printer_data[i].pwidth,
printer_data[i].width,
printer_data[i].length,
printer_data[i].left,
printer_data[i].top );
}
/* Turn a name to a printer geometry.
*/
static PrinterGeometry *
find_printer( char *name )
{
int i;
for( i = 0; i < IM_NUMBER( printer_data ); i++ )
if( strcmp( name, printer_data[i].name ) == 0 )
return( &printer_data[i] );
im_errormsg( "vips2dj: unknown printer \"%s\"", name );
return( NULL );
}
/* Copy between two fds
*/
static int
copy_bytes( FILE *in, FILE *out )
{
int ch;
while( (ch = getc( in )) != EOF )
if( putc( ch, out ) == EOF ) {
im_errormsg( "vips2dj: write error -- disc full?" );
return( -1 );
}
return( 0 );
}
/* Send a file to out. Used to transmit the preludes.
*/
static int
transmit_file( char *mode, char *name, FILE *out )
{
const char *prefix;
char buf[PATH_MAX];
FILE *in;
if( !(prefix = im_guess_prefix( argv0, "VIPSHOME" )) )
return( -1 );
/* Send it!
*/
im_snprintf( buf, PATH_MAX, "%s/share/vips/vips2dj/%s/%s",
prefix, mode, name );
if( !(in = fopen( buf, "r" )) ) {
im_errormsg( "vips2dj: can't find \"%s\"", name );
return( -1 );
}
if( copy_bytes( in, out ) ) {
fclose( in );
return( -1 );
}
fclose( in );
return( 0 );
}
/* Send the file to fp. width and height are the size to print at in points.
*/
static int
send_file( PrinterGeometry *geo, IMAGE *im, char *mode,
FILE *out, int width, int height )
{
/* Send all the start stuff.
*/
if( transmit_file( mode, "head1", out ) )
return( -1 );
/* Set page size.
*/
fprintf( out, "<</PageSize[%d %d]/ImagingBBox null>>setpagedevice\n",
geo->pwidth, height + 2*geo->top );
if( transmit_file( mode, "head2", out ) )
return( -1 );
/* Set mT (margin transform? don't know)
*/
fprintf( out, "/mT[1 0 0 -1 %d %d]def\n",
geo->left, height + geo->top );
if( transmit_file( mode, "head3", out ) )
return( -1 );
/* Set rC ... printable area.
*/
fprintf( out, "gS 0 0 %d %d rC\n", width, height );
if( transmit_file( mode, "head4", out ) )
return( -1 );
/* Set image params.
*/
fprintf( out, "/rows %d def\n", im->Ysize );
fprintf( out, "/cols %d def\n", im->Xsize );
fprintf( out, "%d %d scale\n", width, height );
if( transmit_file( mode, "head5", out ) )
return( -1 );
/* Send the body of the image.
*/
if( vips2asciihex( im, out ) )
return( -1 );
if( transmit_file( mode, "head6", out ) )
return( -1 );
return( 0 );
}
/* Start here!
*/
int
main( int argc, char **argv )
{
IMAGE *im = NULL;
FILE *out = stdout;
int width = -1;
int height = -1;
int dpi = -1;
int max = 0;
int one2one = 0;
PrinterGeometry *geo = find_printer( "2500cp" );
char *mode;
int i;
if( im_init_world( argv[0] ) )
error_exit( "unable to start VIPS" );
argv0 = argv[0];
if( argc <= 1 ) {
printf(
"usage:\n"
"\t%s [options] <image file>\n"
"convert LAB, CMYK and mono image files to postscript\n"
"\tLAB printed with printer colour management\n"
"\tCMYK sent directly as dot percent\n"
"\tmono prints as K only\n"
"options include:\n"
"\t-printer <name>\tformat for printer <name>\n"
"\t-3500cp\t\tfor HP 3500CP printer (default 2500cp)\n"
"\t-max\t\tprint as large as possible\n"
"\t-1:1\t\tsize the image to print at 1:1 ... resolution in\n"
"\t\t\timage header must be set for this\n"
"\t-width <n>\tforce specified width, in points\n"
"\t-height <n>\tforce specified height, in points\n"
"\t-dpi <n>\tforce specified resolution (default 150dpi)\n"
"\t-a5, -a4, -a3, -a2, -a1, -a0\n"
"\t\t\tforce specified height (width ignored)\n"
"\t-o <file>\toutput to file (default stdout)\n",
argv0 );
printf( "supported printers:\n" );
print_printers();
return( 1 );
}
/* Decode args .. just look for file names and our three options.
*/
for( i = 1; i < argc; i++ )
if( *argv[i] == '-' ) {
if( strcmp( argv[i]+1, "width" ) == 0 ) {
if( !argv[i+1] || sscanf( argv[i+1],
"%d", &width ) != 1 || width <= 10 )
error_exit( "bad width" );
i++;
}
else if( strcmp( argv[i]+1, "height" ) == 0 ) {
if( !argv[i+1] || sscanf( argv[i+1],
"%d", &height ) != 1 || height <= 10 )
error_exit( "bad height" );
i++;
}
else if( strcmp( argv[i]+1, "3500cp" ) == 0 ) {
geo = find_printer( "3500cp" );
}
else if( strcmp( argv[i]+1, "printer" ) == 0 ) {
if( !argv[i+1] ||
!(geo = find_printer( argv[i+1] )) )
error_exit( "bad printer model" );
i++;
}
else if( strcmp( argv[i]+1, "dpi" ) == 0 ) {
if( !argv[i+1] || sscanf( argv[i+1],
"%d", &dpi ) != 1 || dpi <= 1 ||
dpi >= 600 )
error_exit( "bad dpi" );
i++;
}
else if( strcmp( argv[i]+1, "o" ) == 0 ) {
if( !argv[i+1] || !(out = fopen(
argv[i+1], "w" )) )
error_exit( "bad output name" );
i++;
}
else if( strcmp( argv[i]+1, "1:1" ) == 0 )
one2one = 1;
else if( strcmp( argv[i]+1, "a5" ) == 0 )
height = 595;
else if( strcmp( argv[i]+1, "a4" ) == 0 )
height = 839;
else if( strcmp( argv[i]+1, "a3" ) == 0 )
height = 1187;
else if( strcmp( argv[i]+1, "a2" ) == 0 )
height = 1678;
else if( strcmp( argv[i]+1, "a1" ) == 0 )
height = 2373;
else if( strcmp( argv[i]+1, "a0" ) == 0 )
height = 3356;
else if( strcmp( argv[i]+1, "max" ) == 0 )
max = 1;
else
error_exit( "bad flag" );
}
else {
/* Try to open the file.
*/
if( im != NULL || !(im = im_open( argv[i], "r" )) )
error_exit( "bad input image" );
}
if( im == NULL )
error_exit( "no input image" );
/* Stop used-before-set complaints on mode.
*/
mode = "lab";
/* Pick a PS mode.
*/
if( im->Coding == IM_CODING_LABQ )
mode = "lab";
else if( im->Coding == IM_CODING_NONE &&
im->Bands == 4 && im->BandFmt == IM_BANDFMT_UCHAR )
mode = "cmyk";
else if( im->Coding == IM_CODING_NONE &&
im->Bands == 1 && im->BandFmt == IM_BANDFMT_UCHAR )
mode = "mono";
else
error_exit( "unsupported image type "
"(IM_CODING_LABQ, mono, IM_TYPE_CMYK only)" );
/* Make sure width and height are both set.
*/
if( one2one ) {
/* Set width/height from res.
*/
if( im->Xres <= 0 || im->Xres >= 100 ||
im->Yres <= 0 || im->Yres >= 100 )
error_exit( "uanble to print 1:1 - resolution not "
"set in image" );
height = (((im->Ysize / im->Yres) / 10.0) / 2.54) * 72.0;
width = (((im->Xsize / im->Xres) / 10.0) / 2.54) * 72.0;
}
else if( max ) {
float iaspect = (float) im->Xsize / im->Ysize;
float paspect = (float) geo->width / geo->length;
if( iaspect > paspect )
/* Image aspect ratio > paper ... fit width.
*/
width = geo->width;
else
height = geo->length;
}
else if( dpi > 0 ) {
/* Given res ... set width/height.
*/
height = (im->Ysize / (float) dpi) * 72.0;
width = (im->Xsize / (float) dpi) * 72.0;
}
if( width >= 0 || height >= 0 ) {
/* Given width or height or both --- set other one.
*/
if( height < 0 ) {
float fdpi = im->Xsize / (width / 72.0);
height = (im->Ysize / fdpi) * 72.0;
}
else {
float fdpi = im->Ysize / (height / 72.0);
width = (im->Xsize / fdpi) * 72.0;
}
}
else {
/* Nothing set ... default to 150 dpi.
*/
height = (im->Ysize / 150.0) * 72.0;
width = (im->Xsize / 150.0) * 72.0;
}
if( send_file( geo, im, mode, out, width, height ) )
error_exit( "error sending file" );
return( 0 );
}

45
contrib/vips2dj/vips2dj.h Normal file
View File

@ -0,0 +1,45 @@
/* Header for vips2dj.
*/
/*
Copyright (C) 1991-2003 The National Gallery
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
/* Geometry for a printer model.
*/
typedef struct {
char *name; /* Printer name (eg. "2500cp") */
int pwidth; /* Paper width (36/54 inches) */
int width; /* Printable width, points */
int length; /* Printable length, points */
int left; /* Left margin, points */
int top; /* Top margin, points */
} PrinterGeometry;
/* All the models.
*/
extern PrinterGeometry printer_data[];
extern int vips2asciihex( IMAGE *in, FILE *out );

13
doc/Makefile Normal file
View File

@ -0,0 +1,13 @@
#
prefix = /home/john/vips
install all:
cd src; $(MAKE) -f Makefile install
echo "Making html man pages"
./Makehtmlman $(prefix)/share/man/man1
./Makehtmlman $(prefix)/share/man/man3
.PHONEY: clean
clean:
cd src; $(MAKE) -f Makefile clean

93
doc/Makehtmlman Executable file
View File

@ -0,0 +1,93 @@
#!/bin/bash
# Make html in html/man from the man pages in the named
# directories
# Config stuff
out_dir=`pwd`/html/man
# print usage and exit
usage() {
echo usage: $0 dir1 dir2 ...
echo make html in $out_dir from the man pages in the
echo named directories
exit 1
}
# If a dir does not exist, make it
makedir() {
if test ! -d "$1"; then
mkdir "$1"
status=$?
if test $status -ne 0 && test ! -d "$1"; then
exit $status
fi
fi
}
makedir `pwd`/html
makedir `pwd`/html/man
makedir $out_dir
# echo the filename given a path
filename() {
echo ${1/#*\//}
}
# echo the dirname given a path... make sure there's a trailing slash
dirname() {
# break off the filename, then junk that many chars off the end of
# $1 to make the dirname
local file=`filename $1`
local dir=${1:0:$((${#1}-${#file}))}
# is dir "/"? return immediately
if test "$dir" == "/"; then
echo "/"
return
fi
# remove trailing slash, provided we're not removing everything
dir=${dir/%\//}
# if there's no dir, we must be in the current dir
if test "$dir" == ""; then
dir="."
fi
# finally add a trailing "/" back again
echo $dir/
}
# Need VIPSHOME
export VIPSHOME=`vips im_guess_prefix im_version VIPSHOME`
: ${VIPSHOME:?}
if test $# -le 0; then
usage
fi
# Loop over args, adding source man pages
for dir in $*; do
if test -d "$dir"; then
files="$files $dir/*.[0-9]"
else
echo "$0: directory $dir does not exist"
exit 1
fi
done
# Make output!
let j=0
for i in $files; do
file=`filename $i`
dir=`dirname $i`
( cd $dir/.. ;
rman -f html -r '%s.%s.html' $dir$file > $out_dir/$file.html )
let j+=1
done
echo "$0: made $j pages of html"

15
doc/README Normal file
View File

@ -0,0 +1,15 @@
VIPS documentation
edit Makefile and change "prefix" to be your install prefix (eg.
"/usr/local/vips-7.8") ... the HTML man page maker will pull manual pages from
this area
type 'make' to rebuild postscript and html. You will need gnu make, latex
and latex2html. It will also scan the VIPS man pages and build a set of
HTML versions using the Makehtmlman script.
src/intro/ has some MS word documents written by Joe Padfield while at the
Hamilton-Karr.
once everything has built, copy the html and ps directories to
$prefix/share/doc/vips

65
doc/src/Makefile Normal file
View File

@ -0,0 +1,65 @@
#
PDF = vipsmanual.pdf
SRC = \
applintro.tex \
cppintro.tex \
fileformat.tex \
func.tex \
iosys.tex \
ipio.tex \
mydefs.tex \
operintro.tex \
packages.tex \
pio.tex \
refintro.tex \
vdisplay.tex \
verror.tex \
vimage.tex \
vipsmanual.tex \
vmask.tex \
wio.tex
mkinstalldirs = $(SHELL) ../../mkinstalldirs
destdir = ../
all: $(PDF) html
install: all $(PDF) html
-rm -rf ${destdir}/pdf/*.pdf
-rm -rf ${destdir}/html/vips*
-rm -rf ${destdir}/html/figs
$(mkinstalldirs) ${destdir}/pdf
$(mkinstalldirs) ${destdir}/html
-cp $(PDF) ${destdir}/pdf
-cp -r vipsmanual/* ${destdir}/html
$(PDF): $(SRC)
pdflatex vipsmanual.tex
pdflatex vipsmanual.tex
.PHONEY: html
html:
-rm -rf vipsmanual
mkdir vipsmanual
htlatex vipsmanual.tex html.cfg,3 "" -dvipsmanual/
cp -r figs vipsmanual
.PHONEY: clean
clean:
-rm -f *.4ct
-rm -f *.4tc
-rm -f *.log
-rm -f *.xref
-rm -f *.tmp
-rm -f *.html
-rm -f *.css
-rm -f *.lg
-rm -f *.idv
-rm -f *.aux
-rm -f *.dvi
-rm -f *.lof
-rm -f *.lot
-rm -f *.toc
-rm -f *.pdf
-rm -rf vipsmanual

51
doc/src/applintro.tex Normal file
View File

@ -0,0 +1,51 @@
\section{Introduction}
\mylabel{sec:appl}
This chapter explains how to call VIPS functions from C programs. It does not
explain how to write new image processing operations (See \pref{sec:oper}),
only how to call the ones that VIPS provides. If you want to call VIPS
functions from C++ programs, you can either use the interface described here
or you can try out the much nicer C++ interface described in \pref{sec:cpp}.
See \pref{sec:ref} for an introduction to the image processing operations
available in the library. \fref{fg:architecture} tries to show
an overview of this structure.
\begin{fig2}
\figw{5in}{arch.png}
\caption{VIPS software architecture}
\label{fg:architecture}
\end{fig2}
VIPS includes a set of UNIX manual pages. Enter (for example):
\begin{verbatim}
example% man im_extract
\end{verbatim}
\noindent
to get an explanation of the \verb+im_extract()+ function.
All the comand-line vips operations will print help text too. For example:
\begin{verbatim}
example% vips im_extract
usage: vips im_extract input output
left top width height band
where:
input is of type "image"
output is of type "image"
left is of type "integer"
top is of type "integer"
width is of type "integer"
height is of type "integer"
band is of type "integer"
extract area/band, from package
"conversion"
flags: (PIO function)
(coordinate transformer)
(area operation)
(result can be cached)
vips: error calling function
im_run_command: too few arguments
\end{verbatim}

105
doc/src/cppintro.tex Normal file
View File

@ -0,0 +1,105 @@
\section{Introduction}
\mylabel{sec:cpp}
This chapter describes the C++ API for the VIPS image processing library,
version 7.12. 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. The two interfaces are identical, except for 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.12 \
--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}
example% invert jim fred
invert: VIPS error: im_open:
"jim" is not a supported
format
\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";
exit( 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}

BIN
doc/src/figs/arch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

385
doc/src/figs/arch.svg Normal file
View File

@ -0,0 +1,385 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
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"
width="744.09448819"
height="1052.3622047"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.44"
sodipodi:docbase="/home/john/CVS_DEVEL/vips-7.11/doc/src/figs"
sodipodi:docname="arch.svg"
inkscape:export-filename="/home/john/CVS_DEVEL/vips-7.11/doc/src/figs/arch.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<linearGradient
id="linearGradient3766">
<stop
style="stop-color:blue;stop-opacity:1;"
offset="0"
id="stop3768" />
<stop
style="stop-color:blue;stop-opacity:0;"
offset="1"
id="stop3770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient3776"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,-15.86361,-14.13077)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4785"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,1.338534,0.3584,272.4737)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4830"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.849266,0,0,1.338534,561.8794,272.4737)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4854"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.599266,0,0,0.598685,36.9083,203.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4867"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,162.8669,201.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4869"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,162.8669,201.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4889"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,1.13158,138.5445,237.5269)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4908"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,162.8669,201.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4939"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,162.8669,201.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4953"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,162.8669,201.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4955"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,162.8669,201.2571)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient4960"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.84935,0,0,0.598685,-29.41424,440.032)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient5163"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,1.338534,0.3584,272.4737)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient5172"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.849266,0,0,1.338534,561.8794,272.4737)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.6541113"
inkscape:cx="439.18963"
inkscape:cy="678.19429"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="1670"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="6"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
id="layer1"
inkscape:groupmode="layer">
<path
sodipodi:nodetypes="cccccccccccccc"
id="path4813"
d="M 465.26905,347.4375 C 474.21535,347.4375 481.4253,354.6162 481.4253,363.5625 L 481.4253,424.125 L 481.4253,440.8125 C 481.4253,449.7588 474.21535,456.9375 465.26905,456.9375 L 373.2378,456.9375 L 308.96873,456.9375 C 300.02243,456.9375 292.81247,449.75882 292.81248,440.8125 L 292.81248,424.125 C 292.81248,415.1787 300.02245,407.96875 308.96873,407.96875 L 357.08155,407.96875 L 357.08155,363.5625 C 357.08155,354.6162 364.2915,347.4375 373.2378,347.4375 L 465.26905,347.4375 z "
style="fill:url(#linearGradient5172);fill-opacity:1;stroke:black;stroke-width:2.30000257;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:url(#linearGradient5163);fill-opacity:1;stroke:black;stroke-width:2.30000257;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 96.96875,347.4375 C 88.022452,347.4375 80.8125,354.6162 80.8125,363.5625 L 80.8125,424.125 L 80.8125,440.8125 C 80.8125,449.7588 88.022452,456.9375 96.96875,456.9375 L 189,456.9375 L 253.26907,456.9375 C 262.21537,456.9375 269.42533,449.75882 269.42532,440.8125 L 269.42532,424.125 C 269.42532,415.1787 262.21535,407.96875 253.26907,407.96875 L 205.15625,407.96875 L 205.15625,363.5625 C 205.15625,354.6162 197.9463,347.4375 189,347.4375 L 96.96875,347.4375 z "
id="rect4755"
sodipodi:nodetypes="cccccccccccccc" />
<path
style="fill:url(#linearGradient4889);fill-opacity:1;stroke:black;stroke-width:2.3000021;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 160.8539,280.5 C 151.9076,280.5 144.7289,287.70995 144.7289,296.65625 L 144.7289,313.34375 C 144.7289,322.29005 151.90761,329.46873 160.8539,329.46875 L 219,329.46875 L 219,377.34375 C 219,386.29005 226.20996,393.46876 235.15625,393.46875 L 327.1875,393.46875 C 336.1338,393.46875 343.34374,386.29006 343.34375,377.34375 L 343.34375,329.46875 L 400.95157,329.46875 C 409.89787,329.46875 417.07659,322.29004 417.07657,313.34375 L 417.07657,296.65625 C 417.07657,287.70995 409.89786,280.5 400.95157,280.5 L 160.8539,280.5 z "
id="rect4693"
sodipodi:nodetypes="ccccccccccccccc" />
<g
id="g4943"
transform="translate(4.079103,0)">
<g
transform="translate(-102.3224,-83.2251)"
id="g4667">
<rect
rx="16.148552"
ry="16.14856"
y="234.78189"
x="243.32465"
height="48.983932"
width="124.34397"
id="rect3778"
style="opacity:1;fill:url(#linearGradient4953);fill-opacity:1;stroke:black;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text1972"
y="262.58441"
x="305.4527"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;opacity:1;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="262.58441"
x="305.4527"
sodipodi:role="line"
id="tspan1974"
style="fill:white;fill-opacity:1;stroke:none">Python binding</tspan></text>
</g>
<g
transform="translate(-102.3224,-19.75669)"
id="g4686">
<rect
style="opacity:1;fill:url(#linearGradient4955);fill-opacity:1;stroke:black;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4674"
width="124.34397"
height="48.983932"
x="243.32465"
y="234.78189"
ry="16.14856"
rx="16.148552" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;opacity:1;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="305.4527"
y="262.58441"
id="text4676"><tspan
style="fill:white;fill-opacity:1;stroke:none"
id="tspan4678"
sodipodi:role="line"
x="305.4527"
y="262.58441">C++ binding</tspan></text>
</g>
</g>
<text
id="text4788"
y="370.34372"
x="144.39862"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="370.34372"
x="144.39862"
sodipodi:role="line"
id="tspan4790"
style="fill:white;fill-opacity:1;stroke:none">VIPS image</tspan><tspan
y="385.34372"
x="144.39862"
sodipodi:role="line"
style="fill:white;fill-opacity:1;stroke:none"
id="tspan4792">processing</tspan><tspan
y="400.34372"
x="144.39862"
sodipodi:role="line"
style="fill:white;fill-opacity:1;stroke:none"
id="tspan4794">operations</tspan></text>
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="418.38409"
y="370.34372"
id="text4815"><tspan
style="fill:white;fill-opacity:1;stroke:none"
id="tspan4817"
sodipodi:role="line"
x="418.38409"
y="370.34372">User image</tspan><tspan
id="tspan4819"
style="fill:white;fill-opacity:1;stroke:none"
sodipodi:role="line"
x="418.38409"
y="385.34372">processing</tspan><tspan
id="tspan4821"
style="fill:white;fill-opacity:1;stroke:none"
sodipodi:role="line"
x="418.38409"
y="400.34372">operations</tspan></text>
<rect
style="fill:url(#linearGradient4960);fill-opacity:1;stroke:black;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4836"
width="270.76959"
height="48.983932"
x="145.78938"
y="473.55679"
ry="16.14856"
rx="16.148552" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="281.13031"
y="501.35931"
id="text4838"><tspan
style="fill:white;fill-opacity:1;stroke:none"
id="tspan4840"
sodipodi:role="line"
x="281.13031"
y="501.35931">VIPS IO system</tspan></text>
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="281.13031"
y="308.29611"
id="text4875"><tspan
style="fill:white;fill-opacity:1;stroke:none"
id="tspan4877"
sodipodi:role="line"
x="281.13031"
y="308.29611">Function dispatch</tspan></text>
<g
transform="translate(49.48783,-19.7567)"
id="g4900">
<g
id="g4924">
<rect
rx="16.148552"
ry="16.14856"
y="234.78189"
x="243.32465"
height="48.983932"
width="124.34397"
id="rect4902"
style="opacity:1;fill:url(#linearGradient4939);fill-opacity:1;stroke:black;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text4904"
y="256.2475"
x="305.4527"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;opacity:1;fill:white;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="256.2475"
x="305.4527"
sodipodi:role="line"
id="tspan4906"
style="fill:white;fill-opacity:1;stroke:none">Command-line</tspan><tspan
id="tspan4922"
y="271.2475"
x="305.4527"
sodipodi:role="line"
style="fill:white;fill-opacity:1;stroke:none">interface</tspan></text>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,505 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg1431"
sodipodi:version="0.32"
inkscape:version="0.43"
sodipodi:docbase="/home/john/CVS_DEVEL/vips-7.11/doc/src/figs"
sodipodi:docname="interconvert.svg"
inkscape:export-filename="/home/john/CVS_DEVEL/vips-7.11/doc/src/figs/interconvert.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs1433">
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;">
<path
id="path2732"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.4) rotate(180)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mstart"
style="overflow:visible">
<path
id="path2735"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.4)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;">
<path
id="path2738"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.8) rotate(180)" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path2741"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.8)" />
</marker>
<linearGradient
id="linearGradient3766">
<stop
style="stop-color:blue;stop-opacity:1;"
offset="0"
id="stop3768" />
<stop
style="stop-color:blue;stop-opacity:0;"
offset="1"
id="stop3770" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1473"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1533"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1553"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1599"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1601"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1619"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient1635"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,247.81,161.7982)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3766"
id="linearGradient2757"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.849266,0,0,0.598685,16.7937,60.4338)"
x1="158.72054"
y1="0.55397713"
x2="158.86745"
y2="185.72389" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.3548828"
inkscape:cx="276.197"
inkscape:cy="811.45446"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="917"
inkscape:window-height="766"
inkscape:window-x="721"
inkscape:window-y="190" />
<metadata
id="metadata1436">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g1468"
transform="translate(-145.6376,-17.86691)">
<rect
rx="21.578072"
ry="20.801611"
y="195.32306"
x="328.2677"
height="41.603222"
width="43.156143"
id="rect4674"
style="fill:url(#linearGradient1473);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text4676"
y="220.5983"
x="349.58502"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="220.5983"
x="349.58502"
sodipodi:role="line"
id="tspan4678"
style="fill:#ffffff;fill-opacity:1;stroke:none">Lab</tspan></text>
</g>
<g
transform="translate(-61.37789,49.49029)"
id="g1475">
<rect
style="fill:url(#linearGradient1599);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1477"
width="43.156143"
height="41.603222"
x="328.2677"
y="195.32306"
ry="20.801611"
rx="21.578072" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="349.58502"
y="220.5983"
id="text1479"><tspan
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan1481"
sodipodi:role="line"
x="349.58502"
y="220.5983">XYZ</tspan></text>
</g>
<g
id="g1505"
transform="translate(-61.37789,-85.22411)">
<rect
rx="21.578072"
ry="20.801611"
y="195.32306"
x="328.2677"
height="41.603222"
width="43.156143"
id="rect1507"
style="fill:url(#linearGradient1601);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text1509"
y="220.5983"
x="349.58502"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="220.5983"
x="349.58502"
sodipodi:role="line"
id="tspan1511"
style="fill:#ffffff;fill-opacity:1;stroke:none">LCh</tspan></text>
</g>
<g
transform="translate(22.88186,5.077526)"
id="g1525">
<rect
style="fill:url(#linearGradient1533);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1527"
width="43.156143"
height="41.603222"
x="328.2677"
y="195.32306"
ry="20.801611"
rx="21.578072" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="349.58502"
y="220.5983"
id="text1529"><tspan
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan1531"
sodipodi:role="line"
x="349.58502"
y="220.5983">disp</tspan></text>
</g>
<g
id="g1535"
transform="translate(22.88186,95.37916)">
<rect
rx="21.578072"
ry="20.801611"
y="195.32306"
x="328.2677"
height="41.603222"
width="43.156143"
id="rect1537"
style="fill:url(#linearGradient1543);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text1539"
y="220.5983"
x="349.58502"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="220.5983"
x="349.58502"
sodipodi:role="line"
id="tspan1541"
style="fill:#ffffff;fill-opacity:1;stroke:none">Yxy</tspan></text>
</g>
<g
transform="translate(22.88186,-85.22411)"
id="g1545">
<rect
style="fill:url(#linearGradient1553);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1547"
width="43.156143"
height="41.603222"
x="328.2677"
y="195.32306"
ry="20.801611"
rx="21.578072" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="349.58502"
y="220.5983"
id="text1549"><tspan
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan1551"
sodipodi:role="line"
x="349.58502"
y="220.5983">UCS</tspan></text>
</g>
<g
id="g2759">
<rect
rx="21.578072"
ry="20.801611"
y="93.958656"
x="97.251404"
height="41.603222"
width="43.156143"
id="rect1487"
style="fill:url(#linearGradient2757);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text1489"
y="119.23389"
x="118.56873"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="119.23389"
x="118.56873"
sodipodi:role="line"
id="tspan1491"
style="fill:#ffffff;fill-opacity:1;stroke:none">LabQ</tspan></text>
</g>
<g
transform="translate(-231.0163,-17.86691)"
id="g1495">
<rect
style="fill:url(#linearGradient1619);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1497"
width="43.156143"
height="41.603222"
x="328.2677"
y="195.32306"
ry="20.801611"
rx="21.578072" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="349.58502"
y="220.5983"
id="text1499"><tspan
style="fill:#ffffff;fill-opacity:1;stroke:none"
id="tspan1501"
sodipodi:role="line"
x="349.58502"
y="220.5983">LabS</tspan></text>
</g>
<g
id="g1555"
transform="translate(-231.0163,65.63058)">
<rect
rx="21.578072"
ry="20.801611"
y="195.32306"
x="328.2677"
height="41.603222"
width="43.156143"
id="rect1557"
style="fill:url(#linearGradient1635);fill-opacity:1;stroke:#000000;stroke-width:2.30000234;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text1559"
y="220.5983"
x="349.58502"
style="font-size:12px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="220.5983"
x="349.58502"
sodipodi:role="line"
id="tspan1561"
style="fill:#ffffff;fill-opacity:1;stroke:none">ICC</tspan></text>
</g>
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 141.55754,198.25776 L 181.4801,198.25776"
id="path1639"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1495"
inkscape:connection-end="#g1468" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 181.76199,220.20937 L 141.27566,259.80364"
id="path1645"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1468"
inkscape:connection-end="#g1555" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 181.76199,176.30615 L 141.27566,136.71188"
id="path1647"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1468" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 226.93624,216.42658 L 265.73981,247.44614"
id="path1685"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1468"
inkscape:connection-end="#g1475" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 226.93624,180.08894 L 265.73981,149.06938"
id="path1687"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1468"
inkscape:connection-end="#g1505" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-mid:none;marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 311.19595,130.90056 L 349.99956,130.90056"
id="path1689"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1505"
inkscape:connection-end="#g1545" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);stroke-miterlimit:4;stroke-dasharray:none"
d="M 311.19595,253.63514 L 349.99956,233.18201"
id="path1691"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1475"
inkscape:connection-end="#g1525" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend);marker-mid:none;stroke-miterlimit:4;stroke-dasharray:none"
d="M 311.19595,277.99294 L 349.99956,299.12585"
id="path1693"
inkscape:connector-type="polyline"
inkscape:connection-start="#g1475"
inkscape:connection-end="#g1535" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="408.81937"
y="224.40727"
id="text2764"><tspan
sodipodi:role="line"
id="tspan2766"
x="408.81937"
y="224.40727">Any VIPS RGB space</tspan></text>
<text
id="text2768"
y="326.40729"
x="94.858322"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
sodipodi:linespacing="125%"><tspan
y="326.40729"
x="94.858322"
id="tspan2770"
sodipodi:role="line">Any device with</tspan><tspan
y="341.40729"
x="94.858322"
sodipodi:role="line"
id="tspan2772">an ICC profile</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

160
doc/src/fileformat.tex Normal file
View File

@ -0,0 +1,160 @@
\section{The VIPS file format}
VIPS has its own very simple file format. It is used inside VIPS to hold
images during computation. You can save images in VIPS format if you want,
but the VIPS format is not widely used and you may have problems reading
your images into other packages.
If you intend to keep an image, it's much better to save it as TIFF,
JPEG, PNG or PBM/PGM/PPM. VIPS can transparently read and write all these
formats.
\subsection{VIPS file header}
\label{sec:header}
All VIPS image files start with a 64-byte header giving basic information
about the image dimensions, see \tref{fg:header}. This is followed by the
image data. This is usually just the pixel values in native format (ie. the
byte order used by the machine that wrote the file) laid out left-to-right and
top-to-bottom. After the image data comes a block of optional XML which holds
extra image metadata, such as ICC profiles and image history.
You can use the command-line program \verb+header+ to extract the XML from an
image and \verb+edvips+ to replace it, see the man pages.
The \ct{Type} field, the \ct{Xres}/\ct{Yres} fields, and the
\ct{Xoffset}/\ct{Yoffset} fields are advisory. VIPS maintains their value
(if you convert an image to \cielab{} colour space with \ct{im\_XYZ2Lab()},
for example, VIPS will set \ct{Type} to be \ct{IM\_TYPE\_LAB}), but never
uses these values itself in determining the action of an image processing
function. These fields are to help the user, and to help application
programs built on VIPS which are trying to present image data to the user
in a meaningful way.
The \ct{BandFmt}, \ct{Coding} and \ct{Type} fields can take the values
shown in tables~\ref{fg:bandfmt}, \ref{fg:coding} and \ref{fg:type}. The C++
and Python names for these values are slightly different, for historical
reasons.
\begin{tab2}
\begin{center}
\begin{tabular}{|l|l|l|}
\hline
Bytes & Represent & VIPS name \\
\hline
0--3 & VIPS magic number (in hex, 08 f2 f6 b6) & \\
4--7 & Number of pels per horizontal line (integer) & \ct{Xsize} \\
8--11 & Number of horizontal lines (integer) & \ct{Ysize} \\
12--15 & Number of bands (integer) & \ct{Bands} \\
16--19 & Unused (legacy) & \ct{Bbits} \\
20--23 & Band format (eg. \ct{IM\_BANDFMT\_USHORT}) & \ct{BandFmt} \\
24--27 & Coding type (eg. \ct{IM\_CODING\_NONE}) & \ct{Coding} \\
28--31 & Type (eg. \ct{IM\_TYPE\_LAB}) & \ct{Type} \\
32--35 & Horizontal resolution (float, pixels mm$^{-1}$) & \ct{Xres} \\
36--39 & Vertical resolution (float, pixels mm$^{-1}$) & \ct{Yres} \\
40--43 & Unused (legacy) & \ct{Length} \\
44--45 & Unused (legacy) & \ct{Compression} \\
46--47 & Unused (legacy) & \ct{Level} \\
48--51 & Horizontal offset of origin & \ct{Xoffset} \\
52--55 & Vertical offset of origin & \ct{Yoffset} \\
56--63 & For future expansion (all zeros for now) & \\
\hline
\end{tabular}
\end{center}
\caption{VIPS header\label{fg:header}}
\end{tab2}
\begin{tab2}
\begin{center}
\begin{tabular}{|l|l|l|l|}
\hline
\ct{BandFmt} & C++ and Python name & Value & Meaning \\
\hline
\ct{IM\_BANDFMT\_NOTSET} & \ct{FMTNOTSET} & -1 & \\
\ct{IM\_BANDFMT\_UCHAR} & \ct{FMTUCHAR} & 0 & Unsigned 8-bit int \\
\ct{IM\_BANDFMT\_CHAR} & \ct{FMTCHAR} & 1 & Signed 8-bit int \\
\ct{IM\_BANDFMT\_USHORT} & \ct{FMTUSHORT} & 2 & Unsigned 16-bit int \\
\ct{IM\_BANDFMT\_SHORT} & \ct{FMTSHORT} & 3 & Signed 16-bit int \\
\ct{IM\_BANDFMT\_UINT} & \ct{FMTUINT} & 4 & Unsigned 32-bit int \\
\ct{IM\_BANDFMT\_INT} & \ct{FMTINT} & 5 & Signed 32-bit int \\
\ct{IM\_BANDFMT\_FLOAT} & \ct{FMTFLOAT} & 6 & 32-bit IEEE float \\
\ct{IM\_BANDFMT\_COMPLEX} & \ct{FMTCOMPLEX} & 7 & Complex (2 floats) \\
\ct{IM\_BANDFMT\_DOUBLE} & \ct{FMTDOUBLE} & 8 & 64-bit IEEE double \\
\ct{IM\_BANDFMT\_DPCOMPLEX} & \ct{FMTDPCOMPLEX} & 9 & Complex (2 doubles) \\
\hline
\end{tabular}
\end{center}
\caption{Possible values for \ct{BandFmt}\label{fg:bandfmt}}
\end{tab2}
\begin{tab2}
\begin{center}
\begin{tabular}{|l|l|l|l|}
\hline
\ct{Coding} & C++ and Python name & Value & Meaning \\
\hline
\ct{IM\_CODING\_NONE} & \ct{NOCODING} & 0 & VIPS computation format \\
\ct{IM\_CODING\_LABQ} & \ct{LABQ} & 2 & LABQ storage format \\
\hline
\end{tabular}
\end{center}
\caption{Possible values for \texttt{Coding}\label{fg:coding}}
\end{tab2}
\begin{tab2}
\begin{center}
\begin{tabular}{|l|l|l|l|}
\hline
\ct{Type} & C++ and Python name & Value & Meaning \\
\hline
\ct{IM\_TYPE\_MULTIBAND} & \ct{MULTIBAND} & 0 & Some multiband image \\
\ct{IM\_TYPE\_B\_W} & \ct{B\_W} & 1 & Some single band image \\
\ct{IM\_TYPE\_HISTOGRAM} & \ct{HISTOGRAM} & 10 & Histogram or LUT \\
\ct{IM\_TYPE\_FOURIER} & \ct{FOURIER} & 24 & Image in Fourier space \\
\ct{IM\_TYPE\_XYZ} & \ct{XYZ} & 12 & \ciexyz{} colour space \\
\ct{IM\_TYPE\_LAB} & \ct{LAB} & 13 & \cielab{} colour space \\
\ct{IM\_TYPE\_CMYK} & \ct{CMYK} & 15 & \ct{im\_icc\_export()} \\
\ct{IM\_TYPE\_LABQ} & \ct{LABQ} & 16 & 32-bit \cielab{} \\
\ct{IM\_TYPE\_RGB} & \ct{RGB} & 17 & Some RGB \\
\ct{IM\_TYPE\_UCS} & \ct{UCS} & 18 & \cieucs{} colour space \\
\ct{IM\_TYPE\_LCH} & \ct{LCH} & 19 & \cielch{} colour space \\
\ct{IM\_TYPE\_LABS} & \ct{LABS} & 21 & 48-bit \cielab{} \\
\ct{IM\_TYPE\_sRGB} & \ct{sRGB} & 22 & sRGB colour space \\
\ct{IM\_TYPE\_YXY} & \ct{YXY} & 23 & \cieyxy{} colour space \\
\ct{IM\_TYPE\_RGB16} & \ct{RGB16} & 25 & 16-bit RGB \\
\ct{IM\_TYPE\_GREY16} & \ct{GREY16} & 26 & 16-bit monochrome \\
\hline
\end{tabular}
\end{center}
\caption{Possible values for \texttt{Type}\label{fg:type}}
\end{tab2}
\subsection{Computation formats}
This type of image has \ct{Coding} set to \ct{IM\_CODING\_NONE}. The
header is then followed by a large array of pixels, laid out left-to-right,
top-to-bottom. Each pixel contains the specified number of bands. Each band
has the specified band format, which may be an 8-, 16- or 32-bit integer
(either signed or unsigned), a single or double precision IEEE floating
point number, or a pair of single or double precision floats forming a
complex number.
All values are stored in the host-machine's native number representation (that
is, either most-significant first, as in SPARC and 680x0 machines, or
least-significant first, for Intel and DEC machines). The VIPS library will
automatically byte-swap for you if necessary, but this can be slow.
\subsection{Storage formats}
All storage formats have other values for the \ct{Coding} field. This
release supports only \ct{IM\_CODING\_LABQ} format.
\ct{IM\_CODING\_LABQ} stores $L^{*}$, $a^{*}$ and $b^{*}$ for each pixel,
with 10 bits for $L^{*}$ and 11 bits for each of $a^{*}$ and $b^{*}$. These
32 bits are packed into 4 bytes, with the most significant 8 bits of each
value in the first 3 bytes, and the left-over bits packed into the final
byte as 2:3:3.
This format is a little awkward to process. Some VIPS functions can work
directly on \ct{IM\_CODING\_LABQ} images (\ct{im\_extract()}, for example),
but most will require you to unpack the image to one of the computation
formats (for example with \ct{im\_LabQ2Lab()}) first.

676
doc/src/func.tex Normal file
View File

@ -0,0 +1,676 @@
\section{Function dispatch and plug-ins}
As image processing libraries increase in size it becomes progressively more
difficult to build applications which present the operations the libbrary
offers to the user. Every time a new operation is added, every user interface
needs to be adapted --- a job which can rapidly become unmanageable.
To address this problem VIPS includes a simple database which stores an
abstract description of every image processing operation. User interfaces,
rather than having special code wired into them for each operation, can
simply interrogate the database and present what they find to the user.
The operation database is extensible. You can define new operations, and even
new types, and add them to VIPS. These new operations will then automatically
appear in all VIPS user interfaces with no extra programming effort. Plugins
can extend the database at runtime: when VIPS starts, it loads all the plugin
in the VIPS library area.
\subsection{Simple plugin example}
As an example, consider this function:
\begin{verbatim}
#include <stdio.h>
#include <vips/vips.h>
/* The function we define. Call this
* from other parts of your C
* application.
*/
int
double_integer( int in )
{
return( in * 2 );
}
\end{verbatim}
\noindent
The source for all the example code in this section is in the vips-examples
package.
The first step is to make a layer over this function which will make it
look like a standard VIPS function. VIPS insists on the following pattern:
\begin{itemize}
\item
The function should be int-valued, and return 0 for success and non-zero
for error. It should set \verb+im_error()+.
\item
The function should take a single argument: a pointer to a
\verb+NULL+-terminated array of \verb+im_objects+.
\item
Each \verb+im_object+ represents one argument to the function (either output
or input) in the form specified by the corresponding entry in the function's
argument descriptor.
\end{itemize}
The argument descriptor is an array of structures, each describing one
argument. For this example, it is:
\begin{verbatim}
/* Describe the type of our function.
* One input int, and one output int.
*/
static im_arg_desc arg_types[] = {
IM_INPUT_INT( "in" ),
IM_OUTPUT_INT( "out" )
};
\end{verbatim}
\verb+IM_INPUT_INT()+ and \verb+IM_OUTPUT_INT()+ are macros defined in
\verb+<vips/dispatch.h>+ which make argument types easy to define. Other
macros available are listed in table~\ref{tab:type}.
\begin{tab2}
\begin{center}
\begin{tabular}{|l|l|l|}
\hline
Macro & Meaning &
\texttt{im\_object} has type \\
\hline
\texttt{IM\_INPUT\_IMAGEVEC} & Vector of input images &
\texttt{IMAGE **} \\
\texttt{IM\_INPUT\_IMAGE} & Input image &
\texttt{IMAGE *} \\
\texttt{IM\_OUTPUT\_IMAGE} & Output image &
\texttt{IMAGE *} \\
\texttt{IM\_RW\_IMAGE} & Read-write image &
\texttt{IMAGE *} \\
\texttt{IM\_INPUT\_DOUBLE} & Input double &
\texttt{double *} \\
\texttt{IM\_INPUT\_DOUBLEVEC} & Input vector of double &
\texttt{im\_realvec\_object *} \\
\texttt{IM\_INPUT\_INTVEC} & Input vector of int &
\texttt{im\_intvec\_object *} \\
\texttt{IM\_OUTPUT\_DOUBLE} & Output double &
\texttt{double *} \\
\texttt{IM\_INPUT\_INT} & Input int &
\texttt{int *} \\
\texttt{IM\_OUTPUT\_INT} & Output int &
\texttt{int *} \\
\texttt{IM\_INPUT\_STRING} & Input string &
\texttt{char *} \\
\texttt{IM\_OUTPUT\_STRING} & Output string &
\texttt{char *} \\
\texttt{IM\_INPUT\_DISPLAY} & Input display &
\texttt{im\_col\_display *} \\
\texttt{IM\_OUTPUT\_DISPLAY} & Output display &
\texttt{im\_col\_display *} \\
\texttt{IM\_OUTPUT\_COMPLEX} & Output complex &
\texttt{double *} \\
\texttt{IM\_INPUT\_DMASK} & Input double array &
\texttt{im\_mask\_object *} \\
\texttt{IM\_OUTPUT\_DMASK} & Output double array to file &
\texttt{im\_mask\_object *} \\
\texttt{IM\_OUTPUT\_DMASK\_STATS}& Output double array to screen &
\\
\texttt{IM\_INPUT\_IMASK} & Input int array &
\texttt{im\_mask\_object *} \\
\texttt{IM\_OUTPUT\_IMASK} & Output int array to file &
\texttt{im\_mask\_object *} \\
\texttt{IM\_INPUT\_GVALUE} & Input GValue &
\texttt{GValue *} \\
\texttt{IM\_OUTPUT\_GVALUE} & Output GValue &
\texttt{GValue *} \\
\hline
\end{tabular}
\end{center}
\caption{Argument type macros\label{tab:type}}
\end{tab2}
The argument to the type macro is the name of the argument. These names
are used by user-interface programs to provide feedback, and sometimes as
variable names. The order in which you list the arguments is the order in
which user-interfaces will present them to the user. You should use the
following conventions when selecting names and an order for your arguments:
\begin{itemize}
\item
Names should be entirely in lower-case and contain no special characters,
apart from the digits 0-9 and the underscore character `\_'.
\item
Names should indicate the function of the argument. For example,
\verb+im_add()+ has the following argument names:
\begin{verbatim}
example% vips -help im_add
vips: args: in1 in2 out
where:
in1 is of type "image"
in2 is of type "image"
out is of type "image"
add two images, from package
"arithmetic"
flags:
(PIO function)
(no coordinate transformation)
(point-to-point operation)
\end{verbatim}
\item
You should order arguments with large input objects first, then output
objects, then any extra arguments or options. For example, \verb+im_extract()+
has the following sequence of arguments:
\begin{verbatim}
example% vips -help im_extract
vips: args: input output left top
width height channel
where:
input is of type "image"
output is of type "image"
left is of type "integer"
top is of type "integer"
width is of type "integer"
height is of type "integer"
channel is of type "integer"
extract area/band, from package
"conversion"
flags:
(PIO function)
(no coordinate transformation)
(point-to-point operation)
\end{verbatim}
\end{itemize}
This function sits over \verb+double_integer()+, providing VIPS with an
interface which it can call:
\begin{verbatim}
/* Call our function via a VIPS
* im_object vector.
*/
static int
double_vec( im_object *argv )
{
int *in = (int *) argv[0];
int *out = (int *) argv[1];
*out = double_integer( *in );
/* Always succeed.
*/
return( 0 );
}
\end{verbatim}
Finally, these two pieces of information (the argument description and
the VIPS-style function wrapper) can be gathered together into a function
description.
\begin{verbatim}
/* Description of double_integer.
*/
static im_function double_desc = {
"double_integer",
"double an integer",
0,
double_vec,
IM_NUMBER( arg_types ),
arg_types
};
\end{verbatim}
\label{sec:number}
\verb+IM_NUMBER()+ is a macro which returns the number of elements in a
static array. The \verb+flags+ field contains hints which user-interfaces
can use for various optimisations. At present, the possible values are:
\begin{description}
\item[\texttt{IM\_FN\_PIO}]
This function uses the VIPS PIO system (see \pref{sec:pio}).
\item[\texttt{IM\_FN\_TRANSFORM}]
This the function transforms coordinates.
\item[\texttt{IM\_FN\_PTOP}]
This is a point-to-point operation, that is, it can be replaced with a
look-up table.
\item[\texttt{IM\_FN\_NOCACHE}]
This operation has side effects and should not be cached. Useful for video
grabbers, for example.
\end{description}
This function description now needs to be added to the VIPS function database.
VIPS groups sets of related functions together in packages. There is only
a single function in this example, so we can just write:
\begin{verbatim}
/* Group up all the functions in this
* file.
*/
static im_function
*function_list[] = {
&double_desc
};
/* Define the package_table symbol.
* This is what VIPS looks for when
* loading the plugin.
*/
im_package package_table = {
"example",
IM_NUMBER( function_list ),
function_list
};
\end{verbatim}
The package has to be named \verb+package_table+, and has to be exported
from the file (that is, not a static). VIPS looks for a symbol of this name
when it opens your object file.
This file needs to be made into a dynamically loadable object. On my machine,
I can do this with:
\begin{verbatim}
example% gcc -fPIC -DPIC -c
`pkg-config vips-7.12 --cflags`
plug.c -o plug.o
example% gcc -shared plug.o
-o double.plg
\end{verbatim}
You can now use \verb+double.plg+ with any of the VIPS applications which
support function dispatch. For example:
\begin{verbatim}
example% vips -plugin double.plg \
double_integer 12
24
example%
\end{verbatim}
If you copy \verb+double.plg+ into your VIPS library area (the directory where
libvips is installed, or \verb+$VIPSHOME/lib+) it will be automatically
loaded by all VIPS programs as they start up.
\subsection{A more complicated example}
This section lists the source for \verb+im_extract()+'s function
description. Almost all functions in the VIPS library have descriptors ---
if you are not sure how to write a description, it's usually easiest to
copy one from a similar function in the library.
\begin{verbatim}
/* Args to im_extract.
*/
static im_arg_desc
extract_args[] = {
IM_INPUT_IMAGE( "input" ),
IM_OUTPUT_IMAGE( "output" ),
IM_INPUT_INT( "left" ),
IM_INPUT_INT( "top" ),
IM_INPUT_INT( "width" ),
IM_INPUT_INT( "height" ),
IM_INPUT_INT( "channel" )
};
/* Call im_extract via arg vector.
*/
static int
extract_vec( im_object *argv )
{
IMAGE_BOX box;
box.xstart = *((int *) argv[2]);
box.ystart = *((int *) argv[3]);
box.xsize = *((int *) argv[4]);
box.ysize = *((int *) argv[5]);
box.chsel = *((int *) argv[6]);
return( im_extract(
argv[0], argv[1], &box ) );
}
/* Description of im_extract.
*/
static im_function
extract_desc = {
"im_extract",
"extract area/band",
IM_FN_PIO | IM_FN_TRANSFORM,
extract_vec,
NUMBER( extract_args ),
extract_args
};
\end{verbatim}
\subsection{Adding new types}
The VIPS type mechanism is extensible. User plug-ins can add new types
and user-interfaces can (to a certain extent) provide interfaces to these
user-defined types.
Here is the definition of \verb+im_arg_desc+:
\begin{verbatim}
/* Describe a VIPS command argument.
*/
typedef struct {
char *name;
im_type_desc *desc;
im_print_obj_fn print;
} im_arg_desc;
\end{verbatim}
The \verb+name+ field is the argument name above. The \verb+desc+ field
points to a structure defining the argument type, and the \verb+print+ field
is an (optionally \verb+NULL+) pointer to a function which VIPS will call
for output arguments after your function successfully completes and before
the object is destroyed. It can be used to print results to the terminal,
or to copy results into a user-interface layer.
\begin{verbatim}
/* Success on an argument. This is
* called if the image processing
* function succeeds and should be
* used to (for example) print
* output.
*/
typedef int (*im_print_obj_fn)
( im_object obj );
\end{verbatim}
\verb+im_type_desc+ is defined as:
\begin{verbatim}
/* Describe a VIPS type.
*/
typedef struct {
im_arg_type type;
int size;
im_type_flags flags;
im_init_obj_fn init;
im_dest_obj_fn dest;
} im_type_desc;
\end{verbatim}
Where \verb+im_arg_type+ is defined as
\begin{verbatim}
/* Type names. You may define your
* own, but if you use one of these,
* then you should use the built-in
* VIPS type converters.
*/
#define IM_TYPE_IMAGEVEC "imagevec"
#define IM_TYPE_DOUBLEVEC "doublevec"
#define IM_TYPE_INTVEC "intvec"
#define IM_TYPE_DOUBLE "double"
#define IM_TYPE_INT "integer"
#define IM_TYPE_COMPLEX "complex"
#define IM_TYPE_STRING "string"
#define IM_TYPE_IMASK "intmask"
#define IM_TYPE_DMASK "doublemask"
#define IM_TYPE_IMAGE "image"
#define IM_TYPE_DISPLAY "display"
#define IM_TYPE_GVALUE "gvalue"
typedef char *im_arg_type;
\end{verbatim}
In other words, it's just a string. When you add a new type, you just need
to choose a new unique string to name it. Be aware that the string is printed
to the user by various parts of VIPS, and so needs to be ``human-readable''.
The flags are:
\begin{verbatim}
/* These bits are ored together to
* make the flags in a type
* descriptor.
*
* IM_TYPE_OUTPUT: set to indicate
* output, otherwise input.
*
* IM_TYPE_ARG: Two ways of making
* an im_object --- with and without
* a command-line string to help you
* along. Arguments with a string
* are thing like IMAGE descriptors,
* which require a filename to
* initialise. Arguments without are
* things like output numbers, where
* making the object simply involves
* allocating storage.
*/
typedef enum {
IM_TYPE_OUTPUT = 0x1,
IM_TYPE_ARG = 0x2
} im_type_flags;
\end{verbatim}
And the \verb+init+ and \verb+destroy+ functions are:
\begin{verbatim}
/* Initialise and destroy objects.
* The "str" argument to the init
* function will not be supplied
* if this is not an ARG type.
*/
typedef int (*im_init_obj_fn)
( im_object *obj, char *str );
typedef int (*im_dest_obj_fn)
( im_object obj );
\end{verbatim}
As an example, here is the definition for a new type of unsigned
integers. First, we need to define the \verb+init+ and \verb+print+
functions. These transform objects of the type to and from string
representation.
\begin{verbatim}
/* Init function for unsigned int
* input.
*/
static int
uint_init( im_object *obj, char *str )
{
unsigned int *i = (int *) *obj;
if( sscanf( str, "%d", i ) != 1 ||
*i < 0 ) {
im_error( "uint_init",
"bad format" );
return( -1 );
}
return( 0 );
}
/* Print function for unsigned int
* output.
*/
static int
uint_print( im_object obj )
{
unsigned int *i =
(unsigned int *) obj;
printf( "%d\n", (int) *i );
return( 0 );
}
\end{verbatim}
Now we can define the type itself. We make two of these --- one for unsigned
int used as input, and one for output.
\begin{verbatim}
/* Name our type.
*/
#define TYPE_UINT "uint"
/* Input unsigned int type.
*/
static im_type_desc input_uint = {
TYPE_UINT, /* Its an int */
sizeof( unsigned int ),/* Memory */
IM_TYPE_ARG, /* Needs arg */
uint_init, /* Init */
NULL /* Destroy */
};
/* Output unsigned int type.
*/
static im_type_desc output_uint = {
TYPE_UINT, /* It's an int */
sizeof( unsigned int ),/* Memory */
IM_TYPE_OUTPUT, /* It's output */
NULL, /* Init */
NULL /* Destroy */
};
\end{verbatim}
Finally, we can define two macros to make structures of type
\verb+im_arg_desc+ for us.
\begin{verbatim}
#define INPUT_UINT( S ) \
{ S, &input_uint, NULL }
#define OUTPUT_UINT( S ) \
{ S, &output_uint, uint_print }
\end{verbatim}
For more examples, see the definitions for the built-in VIPS types.
\subsection{Using function dispatch in your application}
VIPS provides a set of functions for adding new image processing functions
to the VIPS function database, finding functions by name, and calling
functions. See the manual pages for full details.
\subsubsection{Adding and removing functions}
\begin{verbatim}
im_package *im_load_plugin(
const char *name );
\end{verbatim}
This function opens the named file, searches it for a symbol named
\verb+package_table+, and adds any functions it finds to the VIPS function
database. When you search for a function, any plug-ins are searched first,
so you can override standard VIPS function with your own code.
The function returns a pointer to the package it added, or \verb+NULL+
on error.
\begin{verbatim}
int im_close_plugins( void )
\end{verbatim}
This function closes all plug-ins, removing then from the VIPS function
database. It returns non-zero on error.
\subsubsection{Searching the function database}
\begin{verbatim}
void *im_map_packages(
im_list_map_fn fn, void *a )
\end{verbatim}
This function applies the argument function \verb+fn+ to every package
in the database, starting with the most recently added package. As with
\verb+im_list_map()+, the argument function should return \verb+NULL+
to continue searching, or non-\verb+NULL+ to terminate the search
early. \verb+im_map_packages()+ returns \verb+NULL+ if \verb+fn+ returned
\verb+NULL+ for all arguments. The extra argument \verb+a+ is carried around
by VIPS for your use.
For example, this fragment of code prints the names of all loaded packages
to \verb+fd+:
\begin{verbatim}
static void *
print_package_name( im_package *pack,
FILE *fp )
{
(void) fprintf( fp,
"package: \"%s\"\n",
pack->name );
/* Continue search.
*/
return( NULL );
}
static void
print_packages( FILE *fp )
{
(void) im_map_packages(
(im_list_map_fn)
print_package_name, fp );
}
\end{verbatim}
VIPS defines three convenience functions based on \verb+im_map_packages()+
which simplify searching for specific functions:
\begin{verbatim}
im_function *
im_find_function( char *name )
im_package *
im_find_package( char *name )
im_package *
im_package_of_function( char *name )
\end{verbatim}
\subsubsection{Building argument structures and running commands}
\begin{verbatim}
int im_free_vargv( im_function *fn,
im_object *vargv )
int im_allocate_vargv(
im_function *fn,
im_object *vargv )
\end{verbatim}
These two functions allocate space for and free VIPS argument lists. The
allocate function simply calls \verb+im_malloc()+ to allocate any store
that the types require (and also initializes it to zero). The free function
just calls \verb+im_free()+ for any storage that was allocated.
Note that neither of these functions calls the \verb+init+, \verb+dest+
or \verb+print+ functions for the types --- that's up to you.
\begin{verbatim}
int im_run_command( char *name,
int argc, char **argv )
\end{verbatim}
This function does everything. In effect,
\begin{verbatim}
im_run_command( "im_invert", 2,
{ "fred.v", "fred2.v", NULL } )
\end{verbatim}
is exactly equivalent to
\begin{verbatim}
system( "vips im_invert fred.v "
"fred2.v" )
\end{verbatim}
but no process is forked.

17
doc/src/html.cfg Normal file
View File

@ -0,0 +1,17 @@
% configuration file for output of nipguide as html
\Preamble{html}
\begin{document}
% stop the mono font shrinkage we do for paper output
\renewenvironment{ctd}{\begin{quote}\tt}{\end{quote}}
% make a label
% in html, write an extra label which we can link to nip's help system
\renewcommand{\mylabel}[1]{
\label{#1}
\HCode{<a name="nip_label_#1"></a>}
}
% supress " on page xx" if we're making HTML
\renewcommand{\onpage}[1]{}
\EndPreamble

845
doc/src/iosys.tex Normal file
View File

@ -0,0 +1,845 @@
\section{Core C API}
VIPS is
built on top of several other libraries, two of which, glib and gobject, are
exposed at various points in the C API.
You can read up on glib at the GTK+ website:
\begin{verbatim}
http://www.gtk.org/api
\end{verbatim}
There's also an excellent book by Matthias Warkus, \emph{The Official
GNOME 2 Developer's Guide}, which covers the same material in a tutorial
manner.
\subsection{Startup}
Before calling any VIPS function, you need to start VIPS up:
\begin{verbatim}
int im_init_world( const char *argv0 );
\end{verbatim}
The \verb+argv0+ argument is the value of \verb+argv[0]+ your program was passed
by the host operating system. VIPS uses this with \verb+im_guess_prefix()+
to try to find various VIPS data files.
If you don't call this function, VIPS will call it for you the first time you
use a VIPS function. But it won't be able to get the \verb+argv0+ value for
you, so it may not be able to find it's data files.
VIPS also offers the optional:
\begin{verbatim}
GOptionGroup *im_get_option_group( void );
\end{verbatim}
You can use this with GOption to parse your program's command-line arguments.
It adds several useful VIPS flags, including \verb+--vips-concurrency+.
\fref{fg:hello} shows both these functions in use. Again, the GOption stuff is
optional and just lets VIPS add some flags to your program. You do need the
\verb+im_init_world()+ though.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <vips/vips.h>
static gboolean print_stuff;
static GOptionEntry options[] = {
{ "print", 'p', 0, G_OPTION_ARG_NONE, &print_stuff,
"print \"hello world!\"", NULL },
{ NULL }
};
int
main( int argc, char **argv )
{
GOptionContext *context;
GError *error = NULL;
if( im_init_world( argv[0] ) )
error_exit( "unable to start VIPS" );
context = g_option_context_new( "- my program" );
g_option_context_add_main_entries( context,
options, "main" );
g_option_context_add_group( context, im_get_option_group() );
if( !g_option_context_parse( context, &argc, &argv, &error ) ) {
if( error ) {
fprintf( stderr, "%s\n", error->message );
g_error_free( error );
}
error_exit( "try \"%s --help\"", g_get_prgname() );
}
g_option_context_free( context );
if( print_stuff )
printf( "hello, world!\n" );
return( 0 );
}
\end{verbatim}
\caption{Hello World for VIPS}
\label{fg:hello}
\end{fig2}
\subsection{Image descriptors}
The base level of the VIPS I/O system provides \verb+IMAGE+ descriptors.
An image represented by a descriptor may be an image file on disc, an area
of memory that has been allocated for the image, an output file, a delayed
computation, and so on. Programs need (usually) only know that they have
a descriptor, they do not see many of the details. \fref{fg:image}
shows the definition of the \verb+IMAGE+ descriptor.
\begin{fig2}
\begin{verbatim}
typedef struct {
/* Fields from image header.
*/
int Xsize; /* Pels per line */
int Ysize; /* Lines */
int Bands; /* Number of bands */
int Bbits; /* Bits per band */
int BandFmt; /* Band format */
int Coding; /* Coding type */
int Type; /* Type of file */
float XRes; /* Horizontal res in pels/mm */
float YRes; /* Vertical res in pels/mm */
int Length; /* Obsolete (unused) */
short Compression; /* Obsolete (unused) */
short Level; /* Obsolete (unused) */
int Xoffset; /* Position of origin */
int Yoffset;
/* Derived fields that may be read by the user.
*/
char *filename; /* File name */
struct time_info *time;/* Timing for eval callback */
int kill; /* Set to non-zero to block eval */
... and lots of other private fields used by VIPS for
... housekeeping.
} IMAGE;
\end{verbatim}
\caption{The \texttt{IMAGE} descriptor}
\label{fg:image}
\end{fig2}
The first set of fields simply come from the image file header:
see \pref{sec:header} for a full description of all the fields. The next
set are maintained for you by the VIPS I/O system. \verb+filename+ is the
name of the file that this image came from. If you have attached an eval
callback to this image, \verb+time+ points to a set of timing statistics
which can be used by user-interfaces built on VIPS to provide feedback
about the progress of evaluation --- see \pref{sec:eval}. Finally, if you
set \verb+kill+ to non-zero, VIPS will block any pipelines which use this
descriptor as an intermediate. See \pref{sec:block}.
The remaining fields are private and are used by VIPS for housekeeping.
\subsection{Header fields}
\label{sec:fields}
You can access header fields either directly (as \verb+im->Xsize+, for
example) or programmatically with \verb+im_header_int()+ and friends. For
example:
\begin{verbatim}
int i;
im_header_int( im, "Xsize", &i );
\end{verbatim}
There's also \verb+im_header_map()+ to loop over header fields, and
\verb+im_header_get_type+ to test the type of fields. These functions work for
image meta fields as well, see \pref{sec:meta}.
\subsection{Opening and closing}
Descriptors are created with \verb+im_open()+. This takes a file name
and a string representing the mode with which the descriptor is to be opened:
\begin{verbatim}
IMAGE *im_open( const char *filename,
const char *mode )
\end{verbatim}
The possible values for mode are:
\begin{description}
\item[\texttt{"r"}]
The file is opened read-only.
If you open a non-VIPS image, or a VIPS image written on a machine with a
different byte ordering, \verb+im_open()+ will automatically convert it to
native VIPS format. If the underlying file does not support random access
(JPEG, for example), the entire file will be converted in memory.
VIPS can read images in TIFF, JPEG, PPM/\-PGM/\-PBM, PNG and VIPS
format, all in both big- and little-endian varieties. You can control the
details of the conversion with extra characters embedded in the filename. For
example:
\begin{verbatim}
fred = im_open( "fred.tif:2",
"r" );
\end{verbatim}
\noindent
will read page 2 of a multi-page TIFF. See the man pages for details.
If VIPS has been built with libMagick, it can also read any of the 80 or so
libMagick-supported image file formats.
\item[\texttt{"w"}]
An \verb+IMAGE+ descriptor is created which, when written to, will write
pixels to disc in the specified file.
VIPS looks at the filename suffix to determine the save format. If there
is no suffix, or the filename ends in \verb+".v"+, the image is written
in VIPS native format.
If the filename ends in \verb+".tif"+ or \verb+".tiff"+, the image
is written with \verb+im_vips2tiff()+. If the filename ends in
\verb+".jpg"+, \verb+".jpeg"+ or \verb+".jpe"+, the image is written with
\verb+im_vips2jpg()+. If the filename ends with \verb+".pbm"+, \verb+".pgm"+
or \verb+".ppm"+, the image is written using \verb+im_vips2ppm()+.
If the filename ends with \verb+".png"+, the image is written using
\verb+im_vips2png()+. Case is not considered when testing the suffix.
If you want to control the details of the conversion to the disc format (such
as setting the Q factor for a JPEG, for example), you embed extra control
characters in the filename. For example:
\begin{verbatim}
fred = im_open( "fred.jpg:95",
"w" );
\end{verbatim}
\noindent
writes to \verb+fred+ will write a JPEG with Q 95. Again, see the man pages
for the conversion functions for details.
\item[\texttt{"t"}]
As the \verb+"w"+ mode, but pels written to the descriptor will be saved
in a temporary memory buffer.
\item[\texttt{"p"}]
This creates a special partial image. Partial images are used to join VIPS
operations together, see \pref{sec:joinup}.
\item[\texttt{"rw"}]
As the \verb+"r"+ mode, but the image is mapped into the caller's address
space read-write. This mode is only provided for the use of paintbox-style
applications which need to directly modify an image. Most programs should
use the \verb+"w"+ mode for image output.
\end{description}
If an error occurs opening the image, \verb+im_open()+ calls
\verb+im_error()+ with a string describing the cause of the error and
returns \verb+NULL+. \verb+im_error()+ has type
\begin{verbatim}
void im_error( const char *domain,
const char *format, ... )
\end{verbatim}
\noindent
The first argument is a string giving the name of the thing that raised
the error (just \verb+"im_open"+, for example). The format and subsequent
arguments work exactly as \verb+printf()+. It formats the message and
appends the string formed to the error log. You can get a pointer to the
error text with \verb+im_error_buffer()+.
\begin{verbatim}
const char *im_error_buffer()
\end{verbatim}
\noindent
Applications may display this string to give users feedback about the
cause of the error. The VIPS exit function, \verb+error_exit()+, prints
\verb+im_error_buffer()+ to \verb+stderr+ and terminates the program with an
error code of 1.
\begin{verbatim}
void error_exit( const char *format,
... )
\end{verbatim}
\noindent
There are other functions for handling errors: see the man page for
\verb+im_error()+.
If the file name given to \verb+im_open()+ ends with \verb+".v"+, VIPS
looks in the same directory as the image for a file with the same name
but with the extension \verb+".desc"+. If present, this file is read in
and a pointer to the data put in the \verb+Hist+ field of the descriptor. See
the notes on \verb+im_updatehist()+ in \pref{sec:examples}.
Descriptors are closed with \verb+im_close()+. It has type:
\begin{verbatim}
int im_close( IMAGE *im )
\end{verbatim}
\verb+im_close()+ returns 0 on success and non-zero on error.
If the descriptor represents a disc file which
has been written to and whose name ends in \verb+".v"+, VIPS writes the
\verb+Hist+ field of the image descriptor to a file in the same directory
whose name ends in \verb+".desc"+.
\subsection{Examples}
\label{sec:examples}
As an example, \fref{fg:widthheight} will print the width and height
of an image stored on disc.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <vips/vips.h>
int
main( int argc, char **argv )
{
IMAGE *im;
/* Check arguments.
*/
if( im_init_world( argv[0] ) )
error_exit( "unable to start VIPS" );
if( argc != 2 )
error_exit( "usage: %s filename", argv[0] );
/* Open file.
*/
if( !(im = im_open( argv[1], "r" )) )
error_exit( "unable to open %s for input", argv[1] );
/* Process.
*/
printf( "width = %d, height = %d\n", im->Xsize, im->Ysize );
/* Close.
*/
if( im_close( im ) )
error_exit( "unable to close %s", argv[1] );
return( 0 );
}
\end{verbatim}
\label{fg:widthheight}
\caption{Print width and height of an image}
\end{fig2}
To compile this example, use:
\begin{verbatim}
cc `pkg-config vips-7.12 \
--cflags --libs` myfunc.c
\end{verbatim}
As a slightly more complicated example, \fref{fg:negative}
will calculate the photographic negative of an image.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <vips/vips.h>
int
main( int argc, char **argv )
{
IMAGE *in, *out;
/* Check arguments.
*/
if( im_init_world( argv[0] ) )
error_exit( "unable to start VIPS" );
if( argc != 3 )
error_exit( "usage: %s infile outfile", argv[0] );
/* Open images for read and write, invert, update the history with our
* args, and close.
*/
if( !(in = im_open( argv[1], "r" )) ||
!(out = im_open( argv[2], "w" )) ||
im_invert( in, out ) ||
im_updatehist( out, argc, argv ) ||
im_close( in ) ||
im_close( out ) )
error_exit( argv[0] );
return( 0 );
}
\end{verbatim}
\label{fg:negative}
\caption{Find photographic negative}
\end{fig2}
\subsection{Metadata}
\label{sec:meta}
VIPS lets you attach arbitrary metadata to an IMAGE. For example, ICC
profiles, EXIF tags, whatever you like. VIPS will efficiently propogate
metadata as images are processed (usually just by copying pointers) and will
automatically save and load metadata from VIPS files (see
\pref{sec:header}).
A piece of metadata is a value and an identifying name. A set of
convenience functions let you set and get int, double, string and blob. For
example:
\begin{verbatim}
int im_meta_set_int( IMAGE *,
const char *field, int );
int im_meta_get_int( IMAGE *,
const char *field, int * );
\end{verbatim}
So you can do:
\begin{verbatim}
if( im_meta_set_int( im, "poop", 42 ) )
return( -1 );
\end{verbatim}
\noindent
to create an int called \verb+"poop"+, then at some later point (possibly much,
much later), in an image distantly derived from \verb+im+, you can use:
\begin{verbatim}
int i;
if( im_meta_get_int( im, "poop", &i ) )
return( -1 );
\end{verbatim}
\noindent
And get the value 42 back.
You can use \verb+im_meta_set()+ and \verb+im_meta_get()+ to attach arbitrary
\verb+GValue+ to images.
See the man page for \verb+im_meta_set()+ for full
details.
You can test for a field being present with \verb+im_meta_get_type()+ (you'll
get \verb+G_TYPE_INT+ back for \verb+"poop"+, for example, or 0 if it is not
defined for this image).
\subsection{History}
\label{sec:history}
VIPS tracks the history of an image, that is, the sequence of operations which
have led to the creation of an image. You can view a VIPS image's history with
the \verb+header+ command, or with \nip{}'s \ct{View Header} menu. Whenever an
application performs an action, it should append a line of shell script to the
history which would perform the same action.
The call to \verb+im_updatehist()+ in \fref{fg:negative} adds a line to the
image history noting the invocation of this program, its arguments, and the
time and date at which it was run. You may also find \verb+im_histlin()+
helpful. It has type:
\begin{verbatim}
void im_histlin( IMAGE *im,
const char *fmt, ... )
\end{verbatim}
\noindent
It formats its arguments as \verb+printf()+ and appends the string formed
to the image history.
You read an image's history with \verb+im_history_get()+. It returns the
entire history of an image, one action per line. No need to free the result.
\begin{verbatim}
const char *
im_history_get( IMAGE *im );
\end{verbatim}
\subsection{Eval callbacks}
\label{sec:eval}
VIPS lets you attach callbacks to image descriptors. These are functions
you provide which VIPS will call when certain events occur. See
\pref{sec:callback} for a full list.
Eval callbacks are called repeatedly during evaluation and can be used by
user-interface programs to give feedback about the progress of evaluation.
\subsection{Detailed rules for descriptors}
These rules are intended to answer awkward questions.
\begin{enumerate}
\item
You can output to a descriptor only once.
\item
You can use a descriptor as an input many times.
\item
You can only output to a descriptor that was opened with modes \verb+"w"+,
\verb+"t"+ and \verb+"p"+.
\item
You can only use a descriptor as input if it was opened with modes \verb+"r"+
or \verb+"rw"+.
\item
If you have output to a descriptor, you may subsequently use it as an
input. \verb+"w"+ descriptors are automatically changed to \verb+"r"+
descriptors.
If the function you are passing the descriptor to uses WIO (see
\pref{sec:limit}), then \verb+"p"+ descriptors become \verb+"t"+.
If the function you are passing the descriptor to uses PIO, then \verb+"p"+
descriptors are unchanged.
\end{enumerate}
\subsection{Automatic resource deallocation}
VIPS lets you allocate resources local to an image descriptor, that is,
when the descriptor is closed, all resources which were allocated local to
that descriptor are automatically released for you.
\subsubsection{Local image descriptors}
VIPS provides a function which will open a new image local to
an existing image. \verb+im_open_local()+ has type:
\begin{verbatim}
IMAGE *im_open_local( IMAGE *im,
const char *filename,
const char *mode )
\end{verbatim}
It behaves exactly as \verb+im_open()+, except that you do not need to close
the descriptor it returns. It will be closed automatically when its parent
descriptor \verb+im+ is closed.
\begin{fig2}
\begin{verbatim}
/* Add another image to the accumulated total.
*/
static int
sum1( IMAGE *acc, IMAGE **in, int nin, IMAGE *out )
{
IMAGE *t;
if( nin == 0 )
/* All done ... copy to out.
*/
return( im_copy( acc, out ) );
/* Make a new intermediate, and add to it..
*/
return( !(t = im_open_local( out, "sum1:1", "p" )) ||
im_add( acc, in[0], t ) ||
sum1( t, in + 1, nin - 1, out ) );
}
/* Sum the array of images in[]. nin is the number of images in
* in[], out is the descriptor we write the final image to.
*/
int
total( IMAGE **in, int nin, IMAGE *out )
{
/* Check that we have at least one image.
*/
if( nin <= 0 ) {
im_error( "total", "nin should be > 0" );
return( -1 );
}
/* More than 1, sum recursively.
*/
return( sum1( in[0], in + 1, nin - 1, out ) );
}
\end{verbatim}
\caption{Sum an array of images}
\label{fg:addemup}
\end{fig2}
\fref{fg:addemup} is a function which will sum an array of images.
We need never close any of the (unknown) number of intermediate images which
we open. They will all be closed for us by our caller, when our caller
finally closes \verb+out+. VIPS lets local images themselves have local
images and automatically makes sure that all are closed in the correct order.
It is very important that these intermediate images are made local to
\verb+out+ rather than \verb+in+, for reasons which should become apparent
in the section on combining operations below.
There's also \verb+im_open_local_array()+ for when you need a lot of local
descriptors, see the man page.
\subsubsection{Local memory allocation}
\label{sec:malloc}
VIPS includes a set of functions for memory allocation local to an image
descriptor. The base memory allocation function is \verb+im_malloc()+. It
has type:
\begin{verbatim}
void *im_malloc( IMAGE *im,
size_t size )
\end{verbatim}
It operates exactly as the standard \verb+malloc()+ C library function,
except that the area of memory it allocates is local to image descriptor
\verb+im+. If \verb+im_malloc()+ is unable to allocate memory, it returns
\verb+NULL+. If you pass \verb+NULL+ instead of a valid image descriptor,
then \verb+im_malloc()+ allocates memory globally and you must free it
yourself at some stage.
To free memory explicitly, use \verb+im_free()+:
\begin{verbatim}
int im_free( void *mem )
\end{verbatim}
\noindent
\verb+im_free()+ always returns 0, so you can use it as an argument to a
callback.
Three macros make memory allocation even easier. \verb+IM_NEW()+ allocates
a new object. You give it a descriptor and a type, and it returns a pointer
to enough space to hold an object of that type. It has type:
\begin{verbatim}
type-name *IM_NEW( IMAGE *im, type-name )
\end{verbatim}
The second macro, \verb+IM_ARRAY()+, is very similar, but allocates
space for an array of objects. Note that, unlike the usual \verb+calloc()+
C library function, it does not initialise the array to zero. It has type:
\begin{verbatim}
type-name *IM_ARRAY( IMAGE *im,
int n, type-name )
\end{verbatim}
Finally, \verb+IM_NUMBER()+ returns the number of elements in an array of
defined size. See the man pages for a series of examples, or
see \pref{sec:number}.
\subsubsection{Other local operations}
The above facilities are implemented with the VIPS core function
\verb+im_add_close_callback()+. You can use this facility to make your own
local resource allocators for other types of object --- see the manual page
for more help.
\subsection{Error handling}
All VIPS operations return 0 on success and non-zero on error, setting
\verb+im_error()+. As a consequence, when a VIPS function fails, you do not
need to generate an error message --- you can simply propogate the error back
up to your caller. If however you detect some error yourself (for example,
the bad parameter in the example above), you must call \verb+im_error()+
to let your caller know what the problem was.
VIPS provides two more functions for error message handling: \verb+im_warn()+
and \verb+im_diag()+. These are intended to be used for less serious
messages, as their names suggest. Currently, they simply format and print
their arguments to \verb+stderr+, optionally supressed by the setting of an
environment variable. Future releases of VIPS may allow more sophisticated
trapping of these functions to allow their text to be easily presented to
the user by VIPS applications. See the manual pages.
\subsection{Joining operations together}
\label{sec:joinup}
VIPS lets you join image processing operations together so that they
behave as a single unit. \fref{fg:join} shows the definition of the
function \verb+im_Lab2disp()+ from the VIPS library. This function converts
an image in \cielab{} colour space to an RGB image for a monitor. The
monitor characteristics (gamma, phosphor type, etc.) are described by the
\verb+im_col_display+ structure, see the man page for \verb+im_col_XYZ2rgb()+.
\begin{fig2}
\begin{verbatim}
int
im_Lab2disp( IMAGE *in, IMAGE *out, struct im_col_display *disp )
{
IMAGE *t1;
if( !(t1 = im_open_local( out, "im_Lab2disp:1", "p" )) ||
im_Lab2XYZ( in, t1 ) ||
im_XYZ2disp( t1, out, disp ) )
return( -1 );
return( 0 );
}
\end{verbatim}
\caption{Two image-processing operations joined together}
\label{fg:join}
\end{fig2}
The special \verb+"p"+ mode (for partial) used to open the image descriptor
used as the intermediate image in this function `glues' the two operations
together. When you use \verb+im_Lab2disp()+, the two operations inside it
will execute together and no extra storage is necessary for the intermediate
image (\verb+t1+ in this example). This is important if you want to process
images larger than the amount of RAM you have on your machine.
As an added bonus, if you have more than one CPU in your computer, the work
will be automatically spread across the processors for you. You can control
this parallelisation with the \verb+IM_CONCURRENCY+ environment variable and
with \verb+im_concurrency_set()+. See the man page for \verb+im_generate()+.
\subsubsection{How it works}
When a VIPS function is asked to output to a \verb+"p"+ image descriptor,
all the fields in the descriptor are set (the output image size and type
are set, for example), but no image data is actually generated. Instead,
the function attaches callbacks to the image descriptor which VIPS can use
later to generate any piece of the output image that might be needed.
When a VIPS function is asked to output to a \verb+"w"+ or a \verb+"t"+
descriptor (a real disc file or a real memory buffer), it evaluates
immediately and its evaluation in turn forces the evaluation of any earlier
\verb+"p"+ images.
In the example in \fref{fg:join}, whether or not any pixels are really
processed when \verb+im_Lab2disp()+ is called depends upon the mode in
which \verb+out+ was opened. If \verb+out+ is also a partial image, then
no pixels will be calculated --- instead, a pipeline of VIPS operations
will be constructed behind the scenes and attached to \verb+out+.
Conversely, if \verb+out+ is a real image (that is, either \verb+"w"+
or \verb+"t"+), then the final VIPS operation in the function
(\verb+im_XYZ2disp()+) will output the entire image to \verb+out+, causing
the earlier parts of \verb+im_Lab2disp()+ (and indeed possibly some earlier
pieces of program, if \verb+in+ was also a \verb+"p"+ image) to run.
When a VIPS pipeline does finally evaluate, all of the functions in the
pipeline execute together, sucking image data through the system in small
pieces. As a consequence, no intermediate images are generated, large
amounts of RAM are not needed, and no slow disc I/O needs to be performed.
Since VIPS partial I/O is demand-driven rather than data-driven this works
even if some of the operations perform coordinate transformations. We could,
for example, include a call to \verb+im_affine()+, which performs
arbitrary rotation and scaling, and everything would still work correctly.
\subsubsection{Pitfalls with partials}
To go with all of the benefits that partial image I/O brings, there are
also some problems. The most serious is that you are often not quite certain
when computation will happen. This can cause problems if you close an input
file, thinking that it is finished with, when in fact that file has not
been processed yet. Doing this results in dangling pointers and an almost
certain core-dump.
You can prevent this from happening with careful use of
\verb+im_open_local()+. If you always open local to your output image,
you can be sure that the input will not be closed before the output has been
generated to a file or memory buffer. You do not need to be so careful with
non-image arguments. VIPS functions which take extra non-image arguments
(a matrix, perhaps) are careful to make their own copy of the object before
returning.
\subsubsection{Non-image output}
Some VIPS functions consume images, but make no image
output. \verb+im_stats()+ for example, scans an image calculating various
statistical values. When you use \verb+im_stats()+, it behaves as a data
sink, sucking image data through any earlier pipeline stages.
\subsubsection{Calculating twice}
In some circumstances, the same image data can be generated twice.
\fref{fg:thrmean} is a function which finds the mean value of an
image, and writes a new image in which pixels less than the mean are set to
0 and images greater than the mean are set to 255.
\begin{fig2}
\begin{verbatim}
int
threshold_at_mean( IMAGE *in, IMAGE *out )
{
double mean;
if( im_avg( in, &mean ) ||
im_moreconst( in, out, mean ) )
return( -1 );
return( 0 );
}
\end{verbatim}
\caption{Threshold an image at the mean value}
\label{fg:thrmean}
\end{fig2}
This seems straightforward --- but consider if image \verb+in+ were a
\verb+"p"+, and represented the output of a large pipeline of operations. The
call to \verb+im_avg()+ would force the evaluation of the entire pipeline,
and throw it all away, keeping only the average value. The subsequent call to
\verb+im_moreconst()+ will cause the pipeline to be evaluated a second time.
When designing a program, it is sensible to pay attention to these
issues. It might be faster, in some cases, to output to a file before
calling \verb+im_avg()+, find the average of the disc file, and then run
\verb+im_moreconst()+ from that.
\subsubsection{Blocking computation}
\label{sec:block}
\verb+IMAGE+ descriptors have a flag called \verb+kill+ which can be used
to block computation. If \verb+im->kill+ is set to a non-zero value,
then any VIPS pipelines which use \verb+im+ as an intermediate will fail
with an error message. This is useful for user-interface writers ---
suppose your interface is forced to close an image which many other images
are using as a source of data. You can just set the \verb+kill+ flag in all
of the deleted image's immediate children and prevent any dangling pointers
from being followed.
\subsubsection{Limitations}
\label{sec:limit}
Not all VIPS operations are partial-aware. These non-partial operations
use a pre-VIPS7.0 I/O scheme in which the whole of the input image has to
be present at the same time. In some cases, this is because partial I/O
simply makes no sense --- for example, a Fourier Transform can produce no
output until it has seen all of the input. \verb+im_fwfft()+ is therefore
not a partial operation. In other cases, we have simply not got around to
rewriting the old non-partial operation in the newer partial style.
You can mix partial and non-partial VIPS operations freely, without worrying
about which type they are. The only effect will be on the time your pipeline
takes to execute, and the memory requirements of the intermediate images. VIPS
uses the following rules when you mix the two styles of operation:
\begin{enumerate}
\item
When a non-partial operation is asked to output to a partial image descriptor,
the \verb+"p"+ descriptor is magically transformed into a \verb+"t"+
descriptor.
\item
When a non-partial operation is asked to read from a \verb+"p"+ descriptor,
the \verb+"p"+ descriptor is turned into a \verb+"t"+ type, and any earlier
stages in the pipeline forced to evaluate into that memory buffer.
The non-partial operation then processes from the memory buffer.
\end{enumerate}
These rules have the consequence that you may only process very large images
if you only use partial operations. If you use any non-partial operations,
then parts of your pipelines will fall back to old whole-image I/O and you
will need to think carefully about where your intermediates should be stored.

56
doc/src/ipio.tex Normal file
View File

@ -0,0 +1,56 @@
\section{Programming in-place functions}
VIPS includes a little support for in-place functions --- functions
which operate directly on an image, both reading and writing from the same
descriptor via the data pointer. This is an extremely dangerous way to
handle IO, since any bugs in your program will trash your input image.
Operations of this type should call \verb+im_rwcheck()+ instead of
\verb+im_incheck()+. \verb+im_rwcheck()+ tries to get a descriptor ready
for in-place writing. For example, a function which cleared an image to
black might be written as:
\begin{verbatim}
#include <stdio.h>
#include <memory.h>
#include <vips/vips.h>
int
black_inplace( IMAGE *im )
{
/* Check that we can RW to im.
*/
if( im_rwcheck( im ) )
return( -1 );
/* Zap the image!
*/
memset( im->data, 0,
IM_IMAGE_SIZEOF_LINE( im ) *
im->Ysize );
return( 0 );
}
\end{verbatim}
This function might be called from an application as:
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
void
zap( char *name )
{
IMAGE *im;
if( !(im = im_open( name, "rw" )) ||
black_inplace( im ) ||
im_updatehist( im, "zap image" ) ||
im_close( im ) )
error_exit( "failure!" );
}
\end{verbatim}

113
doc/src/mydefs.tex Normal file
View File

@ -0,0 +1,113 @@
% My defs
% Computer Text, Computer text=>, Computer Text Display
\newcommand{\ct}[1]{\texttt{#1}}
\newcommand{\ctr}[1]{\ct{#1} / }
\newenvironment{ctd}{\begin{quote}\footnotesize\tt}{\end{quote}}
\pagecolor{white}
% abbreviations
\newcommand{\vips}{\ct{vips}}
\newcommand{\nip}{\ct{nip2}}
\newcommand{\bs}{$\backslash$}
\newcommand{\rtp}{\^{ }}
\newcommand{\cielab}{\emph{CIE~}$L^{*}a^{*}b^{*}$}
\newcommand{\ciexyz}{\emph{CIE XYZ}}
\newcommand{\cieyxy}{\emph{CIE Yxy}}
\newcommand{\cielch}{\emph{CIE LCh}}
\newcommand{\cieucs}{\emph{UCS(1:1)}}
\newcommand{\cross}{$\times{}$}
% make a label ... override this for HTML output
\newcommand{\mylabel}[1]{\label{#1}}
% generate " on page xx" if a label is referring to something on another page
% override this for HTML output
\newcounter{boink}
\newcommand{\onpage}[1]{%
\addtocounter{boink}{1}%
\label{atref\theboink{}}%
\ifthenelse{\pageref{atref\theboink{}}=\pageref{#1}}%
{}%
{ on page~\pageref{#1}}}
% format a reference to a section .. "$3.11 on page 37"
\newcommand{\pref}[1]{\S\ref{#1}\onpage{#1}}
\newcommand{\tref}[1]{Table~\ref{#1}\onpage{#1}}
\newcommand{\fref}[1]{Figure~\ref{#1}\onpage{#1}}
\newcommand{\cref}[1]{Chapter~\ref{#1}\onpage{#1}}
\newcommand{\aref}[1]{Appendix~\ref{#1}\onpage{#1}}
% Insert a file ... height and name.
\newcommand{\fig}[2]{
\begin{center}
\includegraphics[height=#1]{figs/#2}
\end{center}
}
% Insert a file ... width and name.
\newcommand{\figw}[2]{
\begin{center}
\includegraphics[width=#1]{figs/#2}
\end{center}
}
% make a 2-column figure ... define our own so we can easily override in html
% output
\newenvironment{fig2}{\begin{figure*}}{\end{figure*}}
% same for 2-col tables
\newenvironment{tab2}{\begin{table*}}{\end{table*}}
% environment for setting ip defs
\newenvironment{ipdef}{
\par
\samepage
\begin{ctd}
\begin{tabular}{@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}lllllllllllllllllllllllllllll}
~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & \\[-1.3em]
}{
\end{tabular}
\end{ctd}
\par
}
% causes problems for htlatex :-(
% make this a noop for now
% \newcommand{\dtxt}[1]{\multicolumn{25}{@{\hspace{0.2em}}l}{#1}}
\newcommand{\dtxt}[1]{#1}
% Insert a blank page
\newcommand{\blankpage}{%
\newpage
~~~~
\pagestyle{plain}
\newpage
% Another one necessary in twocolumn mode
~~~~
\newpage
\pagestyle{fancy}
}
%\addtolength{\headheight}{3pt}
% Make text a bit wider, since we are two column.
\addtolength{\textwidth}{0.5in}
\addtolength{\oddsidemargin}{-0.25in}
\addtolength{\evensidemargin}{-0.25in}
% twocolumn seems to remove the binding offset ... add it back
%\addtolength{\oddsidemargin}{-0.2in}
%\addtolength{\evensidemargin}{0.2in}
% More space between headers and footers and the body
\addtolength{\topmargin}{-0.5em}
\addtolength{\headsep}{0.5em}
\addtolength{\footskip}{0.5em}
% Swap left and right binding offsets
\newlength{\fred}
\setlength{\fred}{\oddsidemargin}
\setlength{\oddsidemargin}{\evensidemargin}
\setlength{\evensidemargin}{\fred}

109
doc/src/operintro.tex Normal file
View File

@ -0,0 +1,109 @@
\section{Introduction}
\mylabel{sec:oper}
This chapter explains how to write image processing operations using the
VIPS image I/O (input-output) system. For background, you should probably
take a look at \pref{sec:appl}. This is supposed to be a tutorial, if you
need detailed information on any particular function, use the on-line UNIX
manual pages.
\subsection{Why use VIPS?}
If you use the VIPS image I/O system, you get a number of benefits:
\begin{description}
\item[Threading]
If your computer has more than one CPU, the VIPS I/O system will automatically
split your image processing operation into separate threads (provided you
use PIO, see below). You should get an approximately linear speed-up as
you add more CPUs.
\item[Pipelining]
Provided you use PIO (again, see below), VIPS can automatically join
operations together. A sequence of image processing operations will all
execute together, with image data flowing through the processing pipeline
in small pieces. This makes it possible to perform complex processing on
very large images with no need to worry about storage management.
\item[Composition]
Because VIPS can efficiently compose image processing operations, you can
implement your new operation in small, reusable, easy-to-understand
pieces. VIPS already has a lot of these: many new operations can be
implemented by simply composing existing operations.
\item[Large files]
Provided you use PIO and as long as the underlying OS supports large files
(that is, files larger than 2GB), VIPS operations can work on files larger
than can be addressed with 32 bits on a plain 32-bit machine. VIPS operations
only see 32 bit addresses; the VIPS I/O system transparently maps these to
64 bit operations for I/O. Large file support is included on most unixes after
about 1998.
\item[Abstraction]
VIPS operations see only arrays of numbers in native format. Details of
representation (big/little endian, VIPS/TIFF/JPEG file format, etc.) are
hidden from you.
\item[Interfaces]
Once you have your image processing operation implemented, it automatically
appears in all of the VIPS interfaces. VIPS comes with a GUI (\nip{}), a
UNIX command-line interface (\vips{}) and a C++ and Python API.
\item[Portability]
VIPS operations can be compiled on most unixes, Mac OS X and Windows NT, 2000
and XP without modification. Mostly.
\end{description}
\subsection{I/O styles}
The I/O system supports three styles of input-output.
\begin{description}
\item[Whole-image I/O (WIO)]
This style is a largely a left-over from VIPS 6.x. WIO image-processing
operations have all of the input image given to them in a large memory
array. They can read any of the input pels at will with simple pointer
arithmetic.
\item[Partial-image I/O (PIO)]
In this style operations only have a small part of the input image available
to them at any time. When PIO operations are joined together into a pipeline,
images flow through them in small pieces, with all the operations in a
pipeline executing at the same time.
\item[In-place]
The third style allows pels to be read and written anywhere in
the image at any time, and is used by the VIPS in-place operations, such
as \verb+im_fastline()+. You should only use it for operations which would
just be impossibly inefficient to write with either of the other two styles.
\end{description}
WIO operations are easy to program, but slow and inflexible when images
become large. PIO operations are harder to program, but scale well as images
become larger, and are automatically parallelized by the VIPS I/O system.
If you can face it, and if your algorithm can be expressed in this way, you
should write your operations using PIO. Whichever you choose, applications
which call your operation will see no difference, except in execution speed.
If your image processing operation performs no coordinate transformations,
that is, if your output image is the same size as your input image or images,
and if each output pixel depends only upon the pixel at the corresponding
position in the input images, then you can use the \verb+im_wrapone()+
and \verb+im_wrapmany()+ operations. These take a simple buffer-processing
operation supplied by you and wrap it up as a full-blown PIO operation.
See~\pref{sec:wrapone}.
\subsection{What's new in this version}
The VIPS API is mostly unaltered since 7.3, so there are not many major
changes. I've just reworked the text, reformatted, fixed a few typos,
and changed the dates.
VIPS has acquired some crud over the years. We are planning to clean all
this stuff up at some stage (and break backwards-compatibility). Maybe for
VIPS 8 :-(

822
doc/src/packages.tex Normal file
View File

@ -0,0 +1,822 @@
\section{VIPS packages}
\mylabel{sec:packages}
\subsection{Arithmetic}
See \fref{fg:arithmetic}.
Arithmetic functions work on images as if each band element were a separate
number. All operations are point-to-point --- each output element depends
exactly upon the corresponding input element. All (except in a few cases
noted in the manual pages) will work with images of any type (or any mixture
of types), of any size and of any number of bands.
Arithmetic operations try to preserve precision by increasing the number of
bits in the output image when necessary. Generally, this follows the ANSI C
conventions for type promotion --- so multiplying two \verb+IM_BANDFMT_UCHAR+
images together, for example, produces a \verb+IM_BANDFMT_USHORT+ image, and
taking the \verb+im_costra()+ of a \verb+IM_BANDFMT_USHORT+ image produces
a \verb+IM_BANDFMT_FLOAT+ image. The details of the type conversions are
in the manual pages.
\begin{fig2}
\begin{verbatim}
john% vips --list arithmetic
im_abs - absolute value
im_acostra - acos of image (result in degrees)
im_add - add two images
im_asintra - asin of image (result in degrees)
im_atantra - atan of image (result in degrees)
im_avg - average value of image
im_point_bilinear - interpolate value at single point, linearly
im_ceil - round to smallest integal value not less than
im_cmulnorm - multiply two complex images, normalising output
im_costra - cos of image (angles in degrees)
im_deviate - standard deviation of image
im_divide - divide two images
im_exp10tra - 10^pel of image
im_expntra - x^pel of image
im_expntra_vec - [x,y,z]^pel of image
im_exptra - e^pel of image
im_fav4 - average of 4 images
im_floor - round to largest integal value not greater than
im_gadd - calculate a*in1 + b*in2 + c = outfile
im_invert - photographic negative
im_lintra - calculate a*in + b = outfile
im_linreg - pixelwise linear regression
im_lintra_vec - calculate a*in + b -> out, a and b vectors
im_litecor - calculate max(white)*factor*(in/white), if clip == 1
im_log10tra - log10 of image
im_logtra - ln of image
im_max - maximum value of image
im_maxpos - position of maximum in image
im_maxpos_avg - position of maximum, averaging in case of draw
im_measure - measure averages of a grid of patches
im_min - minimum value of image
im_minpos - position of minimum value of image
im_multiply - multiply two images
im_powtra - pel^x ofbuildimage
im_powtra_vec - pel^[x,y,z] of image
im_remainder - remainder after integer division
im_remainderconst - remainder after integer division by a constant
im_remainderconst_vec - remainder after integer division by a vector
im_rint - round to nearest integal value
im_sign - unit vector in direction of value
im_sintra - sin of image (angles in degrees)
im_stats - many image statistics in one pass
im_subtract - subtract two images
im_tantra - tan of image (angles in degrees)
\end{verbatim}
\caption{Arithmetic functions}
\label{fg:arithmetic}
\end{fig2}
\subsection{Relational}
See \fref{fg:relational}.
Relational functions compare images to other images or to constants. They
accept any image or pair of images (provided they are the same size and
have the same number of bands --- their types may differ) and produce a
\verb+IM_BANDFMT_UCHAR+ image with the same number of bands as the input
image, with 255 in every band element for which the condition is true and
0 elsewhere.
They may be combined with the boolean functions to form complex relational
conditions. Use \verb+im_max()+ (or \verb+im_min()+) to find out if a
condition is true (or false) for a whole image.
\begin{fig2}
\begin{verbatim}
john% vips --list relational
im_blend - use cond image to blend between images in1 and in2
im_equal - two images equal in value
im_equal_vec - image equals doublevec
im_equalconst - image equals const
im_ifthenelse - use cond image to choose pels from image in1 or in2
im_less - in1 less than in2 in value
im_less_vec - in less than doublevec
im_lessconst - in less than const
im_lesseq - in1 less than or equal to in2 in value
im_lesseq_vec - in less than or equal to doublevec
im_lesseqconst - in less than or equal to const
im_more - in1 more than in2 in value
im_more_vec - in more than doublevec
im_moreconst - in more than const
im_moreeq - in1 more than or equal to in2 in value
im_moreeq_vec - in more than or equal to doublevec
im_moreeqconst - in more than or equal to const
im_notequal - two images not equal in value
im_notequal_vec - image does not equal doublevec
im_notequalconst - image does not equal const
\end{verbatim}
\caption{Relational functions}
\label{fg:relational}
\end{fig2}
\subsection{Boolean}
See \fref{fg:boolean}.
The boolean functions perform boolean arithmetic on pairs of
\verb+IM_BANDFMT_UCHAR+ images. They are useful for combining the results of
the relational and morphological functions. You can use
\verb+im_eorconst()+ with 255 as \verb+im_not()+.
\begin{fig2}
\begin{verbatim}
john% vips --list boolean
im_andimage - bitwise and of two images
im_andimageconst - bitwise and of an image with a constant
im_andimage_vec - bitwise and of an image with a vector constant
im_orimage - bitwise or of two images
im_orimageconst - bitwise or of an image with a constant
im_orimage_vec - bitwise or of an image with a vector constant
im_eorimage - bitwise eor of two images
im_eorimageconst - bitwise eor of an image with a constant
im_eorimage_vec - bitwise eor of an image with a vector constant
im_shiftleft - shift integer image n bits to left
im_shiftright - shift integer image n bits to right
\end{verbatim}
\caption{Boolean functions}
\label{fg:boolean}
\end{fig2}
\subsection{Colour}
\label{sec:colour}
See \fref{fg:colour}.
The colour functions can be divided into two main types. First, functions to
transform images between the different colour spaces supported by VIPS:
\verb+RGB+ (also referred to as \verb+disp+), \verb+sRGB+, \verb+XYZ+,
\verb+Yxy+, \verb+Lab+, \verb+LabQ+, \verb+LabS+, \verb+LCh+ and
\verb+UCS+), and second, functions for calculating colour difference
metrics. Figure~\ref{fg:convert} shows how the VIPS colour spaces
interconvert.
\begin{fig2}
\figw{5in}{interconvert.png}
\caption{VIPS colour space conversion}
\label{fg:convert}
\end{fig2}
The colour spaces supported by VIPS are:
\begin{description}
\item[\texttt{LabQ}]
This is the principal VIPS colorimetric storage format. See the
man page for \verb+im_LabQ2Lab()+ for an explanation. You cannot perform
calculations on \verb+LabQ+ images. They are for storage only. Also refered
to as \verb+LABPACK+.
\item[\texttt{LabS}]
This format represents coordinates in \cielab{} space as a three-
band \verb+IM_BANDFMT_SHORT+ image, scaled to fit the full range of bits. It is
the best format for computation, being relatively compact, quick, and
accurate. Colour values expressed in this way are hard to visualise.
\item[\texttt{Lab}]
\verb+Lab+ colourspace represents \cielab{} colour values with a three-band
\verb+IM_BANDFMT_FLOAT+ image. This is the simplest format for general work: adding the
constant 50 to the L channel, for example, has the expected result.
\item[\texttt{XYZ}]
\ciexyz{} colour space represented as a three-band \verb+IM_BANDFMT_FLOAT+
image.
\item[\texttt{XYZ}]
\cieyxy{} colour space represented as a three-band \verb+IM_BANDFMT_FLOAT+
image.
\item[\texttt{RGB}]
(also refered to as \verb+disp+) This format is similar to the RGB colour
systems used in other packages. If you want to export your image to a PC,
for example, convert your colorimetric image to \verb+RGB+, then turn it
to TIFF with \verb+im_vips2tiff()+. You need to supply a structure which
characterises your display. See the manual page for \verb+im_col_XYZ2rgb()+
for hints on these guys.
VIPS also supports \verb+sRGB+. This is a version of RGB with a carefully
defined and standard conversion from XYZ. See:
\begin{verbatim}
http://www.color.org/
\end{verbatim}
\item[\texttt{LCh}]
Like \verb+Lab+, but rectangular $ab$ coordinates are replaced with polar $Ch$
(Chroma and hue) coordinates. Hue angles are expressed in degrees.
\item[\texttt{UCS}]
A colour space based on the CMC(1:1) colour difference measurement. This
is a highly uniform colour space, much better than \cielab{} for expressing
small differences. Conversions to and from \verb+UCS+ are extremely slow.
\end{description}
All VIPS colourspaces assume a D65 illuminant.
The colour-difference functions calculate either $\Delta{}E$ \cielab{} (1976
or 2000) or $\Delta{}E$ CMC(1:1) on two images in \verb+Lab+, \verb+XYZ+
or \verb+disp+ colour space.
\begin{fig2}
\begin{verbatim}
example% vips --list colour
im_LCh2Lab - convert LCh to Lab
im_LCh2UCS - convert LCh to UCS
im_Lab2LCh - convert Lab to LCh
im_Lab2LabQ - convert Lab to LabQ
im_Lab2LabS - convert Lab to LabS
im_Lab2UCS - convert Lab to UCS
im_Lab2XYZ - convert D65 Lab to XYZ
im_Lab2XYZ_temp - convert Lab to XYZ, with a specified colour temperature
im_Lab2disp - convert Lab to displayable
im_LabQ2LabS - convert LabQ to LabS
im_LabQ2Lab - convert LabQ to Lab
im_LabQ2XYZ - convert LabQ to XYZ
im_LabQ2disp - convert LabQ to displayable
im_LabS2LabQ - convert LabS to LabQ
im_LabS2Lab - convert LabS to Lab
im_UCS2LCh - convert UCS to LCh
im_UCS2Lab - convert UCS to Lab
im_UCS2XYZ - convert UCS to XYZ
im_XYZ2Lab - convert D65 XYZ to Lab
im_XYZ2Lab_temp - convert XYZ to Lab, with a specified colour temperature
im_XYZ2UCS - convert XYZ to UCS
im_XYZ2Yxy - convert XYZ to Yxy
im_XYZ2disp - convert XYZ to displayble
im_XYZ2sRGB - convert XYZ to sRGB
im_Yxy2XYZ - convert Yxy to XYZ
im_dE00_fromLab - calculate delta-E CIE2000 for two Lab images
im_dECMC_fromLab - calculate delta-E CMC(1:1) for two Lab images
im_dECMC_fromdisp - calculate delta-E CMC(1:1) for two displayable images
im_dE_fromLab - calculate delta-E for two Lab images
im_dE_fromXYZ - calculate delta-E for two XYZ images
im_dE_fromdisp - calculate delta-E for two displayable images
im_disp2Lab - convert displayable to Lab
im_disp2XYZ - convert displayable to XYZ
im_icc_ac2rc - convert LAB from AC to RC using a profile
im_icc_export - convert LAB to 8-bit device with a profile
im_icc_export_depth - convert LAB to device with a profile
im_icc_import - convert device to LAB with a profile
im_icc_import_embedded - convert device to LAB using the embedded profile
im_icc_present - test for presence of ICC library
im_icc_transform - convert between two device images with a pair of profiles
im_lab_morph - morph colourspace of a LAB image
im_sRGB2XYZ - convert sRGB to XYZ
\end{verbatim}
\caption{Colour functions}
\label{fg:colour}
\end{fig2}
\subsection{Conversion}
See \fref{fg:conversion}.
These functions may be split into three broad groups: functions which convert
between the VIPS numeric formats (\verb+im_clip2fmt()+, for example, converts
an image of any type to the specified \verb+IM_BANDFMT+), functions
supporting complex arithmetic (\verb+im_c2amph()+, for example, converts
a complex image from rectangular to polar co ordinates) and functions
which perform some simple geometric conversion (\verb+im_extract()+ forms
a sub-image).
\verb+gbandjoin+ and the C function \verb+im_gbandjoin()+ will do a bandwise
join of many images at the same time. See the manual pages.
\begin{fig2}
\begin{verbatim}
example% vips --list conversion
im_bandjoin - bandwise join of two images
im_bernd - extract from pyramid as jpeg
im_black - generate black image
im_c2amph - convert real and imaginary to phase and amplitude
im_c2imag - extract imaginary part of complex image
im_c2ps - find power spectrum of complex image
im_c2real - extract real part of complex image
im_c2rect - convert phase and amplitude to real and imaginary
im_clip2c - convert to signed 8-bit integer
im_clip2cm - convert to complex
im_clip2d - convert to double-precision float
im_clip2dcm - convert to double complex
im_clip2f - convert to single-precision float
im_clip2fmt - convert image format to ofmt
im_clip2i - convert to signed 32-bit integer
im_clip2s - convert to signed 16-bit integer
im_clip2ui - convert to unsigned 32-bit integer
im_clip2us - convert to unsigned 16-bit integer
im_clip - convert to unsigned 8-bit integer
im_copy - copy image
im_copy_morph - copy image, setting pixel layout
im_copy_swap - copy image, swapping byte order
im_copy_set - copy image, setting informational fields
im_copy_set_meta - copy image, setting a meta field
im_csv2vips - read a file in csv format
im_extract_area - extract area
im_extract_areabands - extract area and bands
im_extract_band - extract band
im_extract_bands - extract several bands
im_extract - extract area/band
im_falsecolour - turn luminance changes into chrominance changes
im_fliphor - flip image left-right
im_flipver - flip image top-bottom
im_gbandjoin - bandwise join of many images
im_grid - chop a tall thin image into a grid of images
im_insert - insert sub-image into main image at position
im_insert_noexpand - insert sub-image into main image at position, no expansion
im_jpeg2vips - convert from jpeg
im_lrjoin - join two images left-right
im_magick2vips - load file with libMagick
im_mask2vips - convert DOUBLEMASK to VIPS image
im_msb - convert to uchar by discarding bits
im_msb_band - convert to single band uchar by discarding bits
im_png2vips - convert PNG file to VIPS image
im_exr2vips - convert an OpenEXR file to VIPS
im_ppm2vips - read a file in pbm/pgm/ppm format
im_analyze2vips - read a file in analyze format
im_print - print string to stdout
im_recomb - linear recombination with mask
im_replicate - replicate an image horizontally and vertically
im_ri2c - join two non-complex images to form complex
im_rot180 - rotate image 180 degrees
im_rot270 - rotate image 270 degrees clockwise
im_rot90 - rotate image 90 degrees clockwise
im_scale - scale image linearly to fit range 0-255
im_scaleps - logarithmic scale of image to fit range 0-255
im_rightshift_size - decrease size by a power-of-two factor
im_slice - slice an image using two thresholds
\end{verbatim}
\caption{Conversion functions}
\label{fg:conversion}
\end{fig2}
\begin{fig2}
\begin{verbatim}
im_subsample - subsample image by integer factors
im_system - run command on image
im_tbjoin - join two images top-bottom
im_text - generate text image
im_thresh - slice an image at a threshold
im_tiff2vips - convert TIFF file to VIPS image
im_vips2csv - write an image in csv format
im_vips2jpeg - convert to jpeg
im_vips2mask - convert VIPS image to DOUBLEMASK
im_vips2mimejpeg - convert to jpeg as mime type on stdout
im_vips2png - convert VIPS image to PNG file
im_vips2ppm - write a file in pbm/pgm/ppm format
im_vips2tiff - convert VIPS image to TIFF file
im_zoom - simple zoom of an image by integer factors
\end{verbatim}
\caption{Conversion functions (cont.)}
\end{fig2}
\subsection{Matricies}
See \fref{fg:matricies}.
VIPS uses matricies for morphological operations, for convolutions, and
for some colour-space conversions. There are two types of matrix: integer
(\verb+INTMASK+) and double precision floating point (\verb+DOUBLEMASK+).
For convenience, both types are stored in files as ASCII. The first
line of the file should start with the matrix dimensions, width first,
then on the same line an optional scale and offset. The two size fields
should be integers; the scale and offset may be floats. Subsequent lines
should contain the matrix elements, one row per line. The scale and
offset are the conventional ones used to represent non-integer values in
convolution masks --- in other words:
\[
result = {value \over scale} + offset
\]
If the scale and offset are missing, they default to 1.0 and 0.0. See the
sections on convolution for more on the use of these fields. So as an example,
a 4 by 4 identity matrix would be stored as:
\begin{verbatim}
4 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
\end{verbatim}
And a 3 by 3 mask for block averaging with convolution might be stored as:
\begin{verbatim}
3 3 9 0
1 1 1
1 1 1
1 1 1
\end{verbatim}
\noindent
(in other words, sum all the pels in every 3 by 3 area, and divide by 9).
This matrix contains only integer elements and so could be used as an
argument to functions expecting both \verb+INTMASK+ and \verb+DOUBLEMASK+
matricies. However, masks containing floating-point values (such as the
output of \verb+im_matinv()+) can only be used as arguments to functions
expecting \verb+DOUBLEMASK+s.
A set of functions for mask input and output are also available for
C-programmers --- see the manual pages for \verb+im_read_dmask()+. For
other matrix functions, see also the convolution sections and the arithmetic
sections.
\begin{fig2}
\begin{verbatim}
example% vips --list matrix
im_matcat - append matrix in2 to the end of matrix in1
im_matinv - invert matrix
im_matmul - multiply matrix in1 by matrix in2
im_mattrn - transpose matrix
\end{verbatim}
\caption{Matrix functions}
\label{fg:matricies}
\end{fig2}
\subsection{Convolution}
See \fref{fg:convolution}.
The functions available in the convolution package can be split into five
main groups.
First, are the convolution functions. The most useful function is
\verb+im_conv()+ which will convolve any non-complex type with an
\verb+INTMASK+ matrix. The output image will have the same size, type, and
number of bands as the input image. Of the other \verb+im_conv()+ functions,
functions whose name ends in \verb+_raw+ do not add a black border around the
output image, functions ending in \verb+f+ use a \verb+DOUBLEMASK+ matrix
and write float (or double) output, and functions containing \verb+sep+
are for seperable convolutions. \verb+im_compass()+, \verb+im_lindetect()+
and \verb+im_gradient()+ convolve with rotating masks. \verb+im_embed()+
is used by the convolution functions to add the border to the output.
Next, are the build functions. \verb+im_gauss_*mask()+ and its ilk
generate gaussian masks, \verb+im_log_*mask()+ generate logs of Laplacians.
\verb+im_addgnoise()+ and \verb+im_gaussnoise()+ create or add gaussian
noise to an image.
Two functions do correlation: \verb+im_fastcor()+ does a quick and dirty
correlation, \verb+im_spcor()+ calculates true spatial correlation, and is
rather slow.
Some functions are provided for analysing images: \verb+im_zerox()+ counts
zero-crossing points in an image, \verb+im_mpercent()+ finds a threshold
that will isolate a percentage of points in an image.
Finally, \verb+im_resize_linear()+ and \verb+im_shrink()+ do as you would
expect.
\begin{fig2}
\begin{verbatim}
example% vips --list convolution
im_addgnoise - add gaussian noise with mean 0 and std. dev. sigma
im_compass - convolve with 8-way rotating integer mask
im_contrast_surface - find high-contrast points in an image
im_contrast_surface_raw - find high-contrast points in an image
im_conv - convolve
im_conv_raw - convolve, no border
im_convf - convolve, with DOUBLEMASK
im_convf_raw - convolve, with DOUBLEMASK, no border
im_convsep - seperable convolution
im_convsep_raw - seperable convolution, no border
im_convsepf - seperable convolution, with DOUBLEMASK
im_convsepf_raw - seperable convolution, with DOUBLEMASK, no border
im_convsub - convolve uchar to uchar, sub-sampling by xskip, yskip
im_embed - embed in within a set of borders
im_fastcor - fast correlate in2 within in1
im_fastcor_raw - fast correlate in2 within in1, no border
im_gauss_dmask - generate gaussian DOUBLEMASK
im_gauss_imask - generate gaussian INTMASK
im_gaussnoise - generate image of gaussian noise with specified statistics
im_gradient - convolve with 2-way rotating mask
im_rank_image - point-wise pixel rank
im_lindetect - convolve with 4-way rotating mask
im_log_dmask - generate laplacian of gaussian DOUBLEMASK
im_log_imask - generate laplacian of gaussian INTMASK
im_maxvalue - point-wise maximum value
im_mpercent - find threshold above which there are percent values
im_rank - rank filter nth element of xsize/ysize window
im_rank_raw - rank filter nth element of xsize/ysize window, no border
im_read_dmask - read matrix of double from file
im_resize_linear - resize to X by Y pixels with linear interpolation
im_rotate_dmask45 - rotate DOUBLEMASK clockwise by 45 degrees
im_rotate_dmask90 - rotate DOUBLEMASK clockwise by 90 degrees
im_rotate_imask45 - rotate INTMASK clockwise by 45 degrees
im_rotate_imask90 - rotate INTMASK clockwise by 90 degrees
im_sharpen - sharpen high frequencies of L channel of LabQ
im_shrink - shrink image by xfac, yfac times
im_spcor - normalised correlation of in2 within in1
im_spcor_raw - normalised correlation of in2 within in1, no black padding
im_spcor2 - normalised correlation of in2 within in1
im_spcor2_raw - normalised correlation of in2 within in1, no black padding
im_stretch3 - stretch 3%, sub-pixel displace by xdisp/ydisp
im_zerox - find +ve or -ve zero crossings in IM_BANDFMT_INT image
\end{verbatim}
\caption{Convolution functions}
\label{fg:convolution}
\end{fig2}
\subsection{In-place operations}
\label{sec:inplace}
See \fref{fg:inplace}.
A few of the in-place operations are available from the command-line. Most are
not. More will be added.
\begin{fig2}
\begin{verbatim}
example% vips --list inplace
im_circle - plot circle on image
im_flood_blob_copy - flood while pixel == start pixel
im_insertplace - draw image sub inside image main at position (x,y)
im_line - draw line between points (x1,y1) and (x2,y2)
im_lineset - draw line between points (x1,y1) and (x2,y2)
\end{verbatim}
\caption{In-place operations}
\label{fg:inplace}
\end{fig2}
\subsection{Frequency filtering}
See \fref{fg:freq}.
The basic Fourier functions are \verb+im_fwfft()+ and
\verb+im_invfft()+, which calculate the fast-fourier transform and inverse
transform of an image. Also \verb+im_invfftr()+, which just returns the real
part of the inverse transform.
The Fourier image has its origin at pel (0,0) ---
for viewing, use \verb+im_rotquad()+ to move the origin to the centre of
the image.
Once an image is in the frequency domain, it can be filtered by multiplying
it with a mask image. The VIPS mask generator is \verb+im_create_fmask()+
see the manual page for details of the arguments, but it will create low
pass, high pass, ring pass and band pass filters, which may each be ideal,
Gaussian or Butterworth. There is also a fractal mask option.
The other functions in the package build on these base
facilities. \verb+im_freqflt()+ transforms an input image to
Fourier space, multiplies it by a mask image, and transforms it back
again. \verb+im_flt_image_freq()+ will create a mask image of the correct
size for you, and call \verb+im_freqflt()+. \verb+im_disp_ps()+ will call
the right combinations of functions to make a displayable power spectrum
for an image.
\begin{fig2}
\begin{verbatim}
example% vips --list freq_filt
im_create_fmask - create frequency domain filter mask
im_disp_ps - make displayable power spectrum
im_flt_image_freq - frequency domain filter image
im_fractsurf - generate a fractal surface of given dimension
im_freqflt - frequency-domain filter of in with mask
im_fwfft - forward fast-fourier transform
im_rotquad - rotate image quadrants to move origin to centre
im_invfft - inverse fast-fourier transform
im_invfftr - real part of inverse fast-fourier transform
\end{verbatim}
\caption{Fourier functions}
\label{fg:freq}
\end{fig2}
\subsection{Histograms and LUTs}
See \fref{fg:hist}.
VIPS represents histograms and look-up tables in the same way --- as images.
They should have either \verb+Xsize+ or \verb+Ysize+ set to 1, and the
other dimension set to the number of elements in the table. The table can be
of any size, have any band format, and have any number of bands.
Use \verb+im_histgr()+ to find the histogram of an image. Use
\verb+im_histnD()+ to find the n-dimensional histogram of an n-band
image. Perform operations on histograms with \verb+im_histcum()+,
\verb+im_histnorm()+, \verb+im_histspec()+, \verb+im_invertlut()+. Visualise
histograms with \verb+im_histplot()+. Use a histogram (or LUT) to transform
an image with \verb+im_maplut()+. Build a histogram from scratch with
\verb+im_identity()+ or \verb+im_identity_ushort()+.
Use \verb+im_lhist*()+ for local histogram equalisation, and
\verb+im_stdif*()+ for statisticaol differencing. The \verb+im_tone_*()+
functions are for operations on the L channel of a LAB image. Other
functions are useful combinations of these basic operations.
\begin{fig2}
\begin{verbatim}
example% vips --list histograms_lut
im_gammacorrect - gamma-correct image
im_heq - histogram-equalise image
im_hist - find and graph histogram of image
im_histcum - turn histogram to cumulative histogram
im_histeq - form histogram equalistion LUT
im_histgr - find histogram of image
im_histnD - find 1D, 2D or 3D histogram of image
im_histnorm - form normalised histogram
im_histplot - plot graph of histogram
im_histspec - find histogram which will make pdf of in match ref
im_hsp - match stats of in to stats of ref
im_identity - generate identity histogram
im_identity_ushort - generate ushort identity histogram
im_ismonotonic - test LUT for monotonicity
im_lhisteq - local histogram equalisation
im_lhisteq_raw - local histogram equalisation, no border
im_invertlut - generate correction table from set of measures
im_buildlut - generate LUT table from set of x/y positions
im_maplut - map image through LUT
im_project - find horizontal and vertical projections of an image
im_stdif - statistical differencing
im_stdif_raw - statistical differencing, no border
im_tone_analyse - analyse in and create LUT for tone adjustment
im_tone_build - create LUT for tone adjustment of LabS images
im_tone_build_range - create LUT for tone adjustment
im_tone_map - map L channel of LabS or LabQ image through LUT
\end{verbatim}
\caption{Histogram/LUT functions}
\label{fg:hist}
\end{fig2}
\subsection{Morphology}
See \fref{fg:morph}.
The morphological functions are used on one-band \verb+IM_BANDFMT_UCHAR+ binary
images (images containing only zero and not-zero). They search images
for particular patterns of pixels (specified with the mask argument),
either adding or removing pixels when they find a match. They are useful
for cleaning up images --- for example, you might threshold an image, and
then use one of the morphological functions to remove all single isolated
pixels from the result.
If you combine the morphological operators with the mask rotators
(\verb+im_rotate_imask45()+, for example) and apply them repeatedly, you
can achieve very complicated effects: you can thin, prune, fill, open edges,
close gaps, and many others. For example, see `Fundamentals of Digital
Image Processing' by A. Jain, pp 384-388, Prentice-Hall, 1989 for more ideas.
Beware that VIPS reverses the usual image processing convention, by assuming
white objects on a black background.
The mask you give to the morphological functions should contain only the
values 0 (for background), 128 (for don't care) and 255 (for object). The
mask must have odd length sides --- the origin of the mask is taken to be
the centre value. For example, the mask:
\begin{verbatim}
3 3
128 255 128
255 0 255
128 255 128
\end{verbatim}
\noindent
applied to an image with \verb+im_erode()+, will find all black pixels
4-way connected with white pixels. Essentially, \verb+im_dilate()+
sets pixels in the output if any part of the mask matches, whereas
\verb+im_erode()+ sets pixels only if all of the mask matches.
The \verb+_raw()+ version of the functions do not add a black border to the
output. \verb+im_cntlines()+ and \verb+im_profile+ are occasionally useful for
analysing results.
See the boolean operations \verb+im_and()+, \verb+im_or()+ and
\verb+im_eor()+ for analogues of the usual set difference and set
union operations.
\begin{fig2}
\begin{verbatim}
example% vips --list morphology
im_cntlines - count horizontal or vertical lines
im_dilate - dilate image with mask, adding a black border
im_dilate_raw - dilate image with mask
im_erode - erode image with mask, adding a black border
im_erode_raw - erode image with mask
im_profile - find first horizontal/vertical edge
\end{verbatim}
\caption{Morphological functions}
\label{fg:morph}
\end{fig2}
\subsection{Mosaicing}
See \fref{fg:mosaicing}.
These functions are useful for joining many small images together to make one
large image. They can cope with unstable contrast, and arbitary sub-image
layout, but will not do any geometric correction. The mosaicing functions
can be grouped into layers:
The lowest level functions are \verb+im_correl()+. and \verb+im_affine()+.
\verb+im_correl()+ searches a large image for a small sub-image, returning
the position of the best sub-image match. \verb+im_affine()+ performs
a general affine transform on an image: that is, any transform in which
parallel lines remain parallel.
Next, \verb+im_lrmerge()+ and \verb+im_tbmerge()+ blend two images together
left-right or up-down.
Next up are \verb+im_lrmosaic()+ and \verb+im_tbmosaic()+. These use the
two low-level merge operations to join two images given just an approximate
overlap as a start point. Optional extra parameters let you do 'balancing'
too: if your images have come from a source where there is no precise
control over the exposure (for example, images from a tube camera, or a
set of images scanned from photographic sources), \verb+im_lrmosaic()+
and \verb+im_tbmosaic()+ will adjust the contrast of the left image to
match the right, the right to the left, or both to some middle value.
The functions \verb+im_lrmosaic1()+ and \verb+im_tbmosaic1()+ are first-order
analogues of the basic mosaic functions: they take two tie-points and use
them to rotate and scale the right-hand or bottom image before starting to join.
Finally, \verb+im_global_balance()+ can be used to re-balance a mosaic
which has been assembled with these functions. It will generally do a
better job than the low-level balancer built into \verb+im_lrmosaic()+
and \verb+im_tbmosaic()+. See the man page. \verb+im_remosaic()+ uses the same
techniques, but will reassemble the image from a different set of source
images.
\begin{fig2}
\begin{verbatim}
example% vips --list mosaicing
im_affine - affine transform
im_correl - search area around sec for match for area around ref
im__find_lroverlap - search for left-right overlap of ref and sec
im__find_tboverlap - search for top-bottom overlap of ref and sec
im_global_balance - automatically rebuild mosaic with balancing
im_global_balancef - automatically rebuild mosaic with balancing, float output
im_lrmerge - left-right merge of in1 and in2
im_lrmerge1 - first-order left-right merge of ref and sec
im_lrmosaic - left-right mosaic of ref and sec
im_lrmosaic1 - first-order left-right mosaic of ref and sec
im_match_linear - resample ref so that tie-points match
im_match_linear_search - search sec, then resample so that tie-points match
im_remosaic - automatically rebuild mosaic with new files
im_similarity_area - output area xywh of similarity transformation
im_similarity - similarity transformation
im_tbmerge - top-bottom merge of in1 and in2
im_tbmerge1 - first-order top-bottom merge of in1 and in2
im_tbmosaic - top-bottom mosaic of in1 and in2
im_tbmosaic1 - first-order top-bottom mosaic of ref and sec
\end{verbatim}
\caption{Mosaic functions}
\label{fg:mosaicing}
\end{fig2}
\subsection{Other}
See \fref{fg:other}.
These functions generate various test images. You can combine them with
the arithmetic and rotate functions to build more complicated images.
The \verb+im_benchmark*()+ operations are for testing the VIPS SMP system.
\begin{fig2}
\begin{verbatim}
example% vips --list other
im_benchmark - do something complicated for testing
im_benchmark2 - do something complicated for testing
im_benchmarkn - do something complicated for testing
im_eye - generate IM_BANDFMT_UCHAR [0,255] frequency/amplitude image
im_grey - generate IM_BANDFMT_UCHAR [0,255] grey scale image
im_feye - generate IM_BANDFMT_FLOAT [-1,1] frequency/amplitude image
im_fgrey - generate IM_BANDFMT_FLOAT [0,1] grey scale image
im_fzone - generate IM_BANDFMT_FLOAT [-1,1] zone plate image
im_make_xy - generate image with pixel value equal to coordinate
im_zone - generate IM_BANDFMT_UCHAR [0,255] zone plate image
\end{verbatim}
\caption{Other functions}
\label{fg:other}
\end{fig2}
\subsection{IO functions}
See \fref{fg:other}.
These functions are related to the image IO system.
\begin{fig2}
\begin{verbatim}
example% vips --list iofuncs
im_binfile - open a headerless binary file
im_cache - cache results of an operation
im_guess_prefix - guess install area
im_header_get_type - return field type
im_header_int - extract int fields from header
im_header_double - extract double fields from header
im_header_string - extract string fields from header
im_version - VIPS version number
im_version_string - VIPS version string
\end{verbatim}
\caption{IO functions}
\label{fg:io}
\end{fig2}

868
doc/src/pio.tex Normal file
View File

@ -0,0 +1,868 @@
\section{Programming PIO functions}
\label{sec:pio}
The VIPS PIO system has a number of advantages over WIO, as summarised in
the introduction. On the other hand, they are a bit more complicated.
\subsection{Easy PIO with \texttt{im\_wrapone()} and \texttt{im\_wrapmany()}}
\label{sec:wrapone}
PIO is a very general image IO system, and because of this flexibility,
can be complicated to program. As a convenience, VIPS offers an easy-to-use
layer over PIO with the funtions \verb+im_wrapone()+ and \verb+im_wrapmany()+.
If your image processing function is uninterested in coordinates, that is,
if your input and output images are the same size, and each output pixel
depends only upon the value of the corresponding pixel in the input image
or images, then these functions are for you.
Consider the \verb+invert()+ function of figure~\ref{fg:invert}. First,
we have to write the core of this as a buffer-processing function:
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
/* p points to a buffer of pixels which
* need inverting, q points to the buffer
* we should write the result to, and n
* is the number of pels present.
*/
static void
invert_buffer( unsigned char *p,
unsigned char *q, int n )
{
int i;
for( i = 0; i < n; i++ )
q[i] = 255 - p[i];
}
\end{verbatim}
Now we have to wrap up this very primitive expression of the invert operation
as a PIO function. We use \verb+im_wrapone()+ to do this. It has type:
\begin{verbatim}
int
im_wrapone( IMAGE *in, IMAGE *out,
im_wrapone_fn fn, void *a, void *b )
\end{verbatim}
\noindent
where:
\begin{verbatim}
void
(*im_wrapone_fn)(void *in, void *out,
int n, void *a, void *b )
\end{verbatim}
\noindent
almost the same type as our buffer-processing function above. The values
\verb+a+ and \verb+b+ are carried around by VIPS for whatever use you
fancy. \verb+invert()+ can now be written as:
\begin{verbatim}
int
invert( IMAGE *in, IMAGE *out )
{
/* Check parameters.
*/
if( in->BandFmt != IM_BANDFMT_UCHAR ||
in->Bands != 1 ||
in->Coding != IM_CODING_NONE ) {
im_error( "invert", "bad image" );
return( -1 );
}
/* Set fields in output image.
*/
if( im_cp_desc( out, in ) )
return( -1 );
/* Process! We don't use either of the
* user parameters in this function,
* so leave them as NULL.
*/
if( im_wrapone( in, out,
(im_wrapone_fn) invert_buffer,
NULL, NULL ) )
return( -1 );
return( 0 );
}
\end{verbatim}
And that's all there is to it. This function will have all of the desirable
properties of PIO functions, while being as easy to program as the WIO
\verb+invert()+ earlier in this chapter.
This version of \verb+invert()+ is not very general: it will only accept
one-band unsigned char images. It is easy to modify for n-band images:
\begin{verbatim}
/* As before, but use one of the user
* parameters to pass in the number of
* bands in the image.
*/
static void
invert_buffer( unsigned char *p,
unsigned char *q, int n,
IMAGE *in )
{
int i;
int sz = n * in->Bands;
for( i = 0; i < sz; i++ )
q[i] = 255 - p[i];
}
\end{verbatim}
We must also modify \verb+invert()+:
\begin{verbatim}
int
invert( IMAGE *in, IMAGE *out )
{
/* Check parameters.
*/
if( in->BandFmt != IM_BANDFMT_UCHAR ||
in->Coding != IM_CODING_NONE ) {
im_error( "invert", "bad image" );
return( -1 );
}
/* Set fields in output image.
*/
if( im_cp_desc( out, in ) )
return( -1 );
/* Process! The first user-parameter
* is the number of bands involved.
*/
if( im_wrapone( in, out,
(im_wrapone_fn)invert_buffer,
in, NULL ) )
return( -1 );
return( 0 );
}
\end{verbatim}
There are two significant hidden traps here. First, inside the buffer
processing functions, you may only read the contents of the user parameters
\verb+a+ and \verb+b+, you may not write to them. This is because on a
multi-CPU machine, several copies of your buffer-processing functions will
be run in parallel --- if they all write to the same place, there will be
complete confusion. If you need writeable parameters (for example, to count
and report overflows), you can't use \verb+im_wrapone()+, you'll have to
use the PIO system in all its gory detail, see below.
Secondly, your buffer processing function may not be called immediately. VIPS
may decide to delay evaluation of your operation until long after the call
to \verb+invert()+ has returned. As a result, care is needed to ensure
that you never read anything in your buffer-processing function that may
have been freed. The best way to ensure this is to use the local resource
allocators, such as \verb+im_open_local()+ and \verb+im_malloc()+. This issue
is discussed at length in the sections below, and in \pref{sec:appl}.
\verb+im_wrapone()+ is for operations which take exactly one input image. VIPS
provides a second function, \verb+im_wrapmany()+, which works for any number
of input images. The type of \verb+im_wrapmany()+ is slightly different:
\begin{verbatim}
int
im_wrapmany( IMAGE **in, IMAGE *out,
im_wrapmany_fn fn, void *a, void *b )
\end{verbatim}
\noindent
\begin{verbatim}
void
(*im_wrapmany_fn)( void **in, void *out,
int n, void *a, void *b )
\end{verbatim}
\noindent
\verb+im_wrapmany()+ takes a \verb+NULL+-terminated array of input images,
and creates a \verb+NULL+-terminated array of buffers for the use of your
buffer processing function. A function to add two \verb+IM_BANDFMT_UCHAR+
images to make a \verb+IM_BANDFMT_UCHAR+ image might be written as:
\begin{verbatim}
static void
add_buffer( unsigned char **in,
unsigned short *out, int n,
IMAGE *in )
{
int i;
int sz = n * in->Bands;
unsigned char *p1 = in[0];
unsigned char *p2 = in[1];
for( i = 0; i < sz; i++ )
out[i] = p1[i] + p2[i];
}
\end{verbatim}
This can be made into a PIO function with:
\begin{verbatim}
int
add_uchar( IMAGE *i1, IMAGE *i2,
IMAGE *out )
{
IMAGE *invec[3];
/* Check parameters. We don't need to
* check that i1 and i2 are the same
* size, im_wrapmany() does that for
* us.
*/
if( i1->BandFmt != IM_BANDFMT_UCHAR ||
i1->Coding != IM_CODING_NONE ||
i2->BandFmt != IM_BANDFMT_UCHAR ||
i2->Coding != IM_CODING_NONE ||
i1->Bands != i2->Bands ) {
im_error( "add_uchar", "bad in" );
return( -1 );
}
/* Set fields in output image. As
* input image, but we want a USHORT.
*/
if( im_cp_desc( out, i1 ) )
return( -1 );
out->BandFmt = IM_BANDFMT_USHORT;
out->Bbits = IM_BBITS_SHORT;
/* Process! The first user-parameter
* is the number of bands involved.
* invec is a NULL-terminated array of
* input images.
*/
invec[0] = i1; invec[1] = i2;
invec[2] = NULL;
if( im_wrapmany( invec, out,
(im_wrapone_fn)add_buffer,
i1, NULL ) )
return( -1 );
return( 0 );
}
\end{verbatim}
\subsection{Region descriptors}
Regions are the next layer of abstraction above image descriptors. A region
is a small part of an image, held in memory ready for processing. A region
is defined as:
\begin{verbatim}
typedef struct {
Rect valid;
IMAGE *im;
... and some other private fields,
... used by VIPS for housekeeping
} REGION;
\end{verbatim}
\noindent
where \verb+valid+ holds the sub-area of image \verb+im+ that this region
represents, and \verb+Rect+ is defined as:
\begin{verbatim}
typedef struct {
int left, top;
int width, height;
} Rect;
\end{verbatim}
\noindent
two macros are available for \verb+Rect+ calculations:
\begin{verbatim}
int IM_RECT_RIGHT( Rect *r )
int IM_RECT_BOTTOM( Rect *r )
\end{verbatim}
\noindent
where \verb+IM_RECT_RIGHT()+ returns \verb+left+ + \verb+width+, and
\verb+IM_RECT_BOTTOM()+ returns \verb+top+ + \verb+height+. A small library
of C functions are also available for \verb+Rect+ algebra, see the manual
pages for \verb+im_rect_intersectrect()+.
Regions are created with \verb+im_region_create()+. This has type:
\begin{verbatim}
REGION *im_region_create( IMAGE *im )
\end{verbatim}
\noindent
\verb+im_region_create()+ returns a pointer to a new region structure,
or \verb+NULL+ on error. Regions returned by \verb+im_region_create()+
are blank --- they contain no image data and cannot be read from or written
to. See the next couple of sections for calls to fill regions with data.
Regions are destroyed with \verb+im_region_free()+. It has type:
\begin{verbatim}
int im_region_free( REGION *reg )
\end{verbatim}
\noindent
And, as usual, returns 0 on success and non-zero on error, setting
\verb+im_error()+. You must free all regions you create. If you close
an image without freeing all the regions defined on that image, the image is
just marked for future closure --- it is not actually closed until the final
region is freed. This behaviour helps to prevent dangling pointers, and it
is not difficult to make sure you free all regions --- see the examples below.
\subsection{Image input with regions}
Before you can read from a region, you need to call \verb+im_prepare()+
to fill the region with image data. It has type:
\begin{verbatim}
int im_prepare( REGION *reg, Rect *r )
\end{verbatim}
Area \verb+r+ of the image on which \verb+reg+ has been created is prepared
and attached to the region.
Exactly what this preparation involves depends upon the image --- it can
vary from simply adjusting some pointers, to triggering the evaluation of a
series of other functions. If it returns successfully, \verb+im_prepare()+
guarantees that all pixels within \verb+reg->valid+ may be accessed. Note
that this may be smaller or larger than \verb+r+, since \verb+im_prepare()+
clips \verb+r+ against the size of the image.
Programs can access image data in the region by calling the macro
\verb+IM_REGION_ADDR()+. It has type
\begin{verbatim}
char *IM_REGION_ADDR( REGION *reg,
int x, int y )
\end{verbatim}
Provided that point (x,y) lies inside \verb+reg->valid+,
\verb+IM_REGION_ADDR()+ returns a pointer to pel $(x,y)$. Adding to the result
of \verb+IM_REGION_ADDR()+ moves to the right along the line of pels, provided
you stay strictly within \verb+reg->valid+. Add \verb+IM_REGION_LSKIP()+
to move down a line, see below. \verb+IM_REGION_ADDR()+ has some other
useful features --- see the manual page.
Other macros are available to ease address calculation:
\begin{verbatim}
int IM_REGION_LSKIP( REGION *reg )
int IM_REGION_N_ELEMENTS( REGION *reg )
int IM_REGION_SIZEOF_LINE( REGION *reg )
\end{verbatim}
\noindent
These find the number of bytes to add to the result of \verb+IM_REGION_ADDR()+
to move down a line, the number of band elements across the region and the
number of bytes across the region.
\fref{fg:paverage} is a version of \verb+average()+ which uses
regions rather than WIO input. Two things: first, we should really be
using \verb+im_iterate()+, see \pref{sec:sequence}, to do the rectangle
algebra for us. Secondly, note that we call \verb+im_pincheck()+ rather
than \verb+im_incheck()+. \verb+im_pincheck()+ signals to the IO system
that you are a PIO-aware function, giving \verb+im_prepare()+ much more
flexibility in the sorts of preparation it can do. Also see the manual
pages for \verb+im_poutcheck()+ and \verb+im_piocheck()+.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/region.h>
int
average( IMAGE *im, double *out )
{
int total, i, y;
REGION *reg;
Rect area, *r;
/* Check im.
*/
if( im_pincheck( im ) )
return( -1 );
if( im->BandFmt != IM_BANDFMT_UCHAR || im->Coding != IM_CODING_NONE ) {
im_error( "average", "uncoded uchar images only" );
return( -1 );
}
/* Make a region on im which we can use for reading.
*/
if( !(reg = im_region_create( im )) )
return( -1 );
\end{verbatim}
\caption{First PIO average of image}
\label{fg:paverage}
\end{fig2}
\begin{fig2}
\begin{verbatim}
/* Move area over the image in 100x100 pel chunks.
* im_prepare() will clip against the edges of the image
* for us.
*/
total = 0;
r = &reg->valid;
area.width = 100; area.height = 100;
for( area.top = 0; area.top < im->Ysize; area.top += 100 )
for( area.left = 0; area.left < im->Xsize;
area.left += 100 ) {
/* Fill reg with pels.
*/
if( im_prepare( reg, &area ) ) {
/* We must free the region!
*/
im_region_free( reg );
return( -1 );
}
/* Loop over reg, adding to our total.
*/
for( y = r->top; y < IM_RECT_BOTTOM( r ); y++ ) {
unsigned char *p = IM_REGION_ADDR( reg, r->left, y );
for( i = 0; i < IM_REGION_N_ELEMENTS( reg ); i++ )
total += p[i];
}
}
/* Make sure we free the region.
*/
im_region_free( reg );
/* Find average.
*/
*out = (double) total / (IM_IMAGE_N_ELEMENTS( im ) * im->Ysize);
return( 0 );
}
\end{verbatim}
\caption{First PIO average of image (cont.)}
\end{fig2}
This version of \verb+average()+ can be called in exactly the same way as
the previous one, but this version has the great advantage of not needing
to have the whole of the input image available at once.
We can do one better than this --- if the image is being split into small
pieces, we can assign each piece to a separate thread of execution and get
parallelism. To support this splitting of tasks, VIPS has the notion of
a sequence.
\subsection{Splitting into sequences}
\label{sec:sequence}
A sequence comes in three parts: a start function, a processing function,
and a stop function. When VIPS starts up a new sequence, it runs the
start function. Start functions return sequence values: a void pointer
representing data local to this sequence. VIPS then repeatedly calls the
processing function, passing in the sequence value and a new piece of image
data for processing. Finally, when processing is complete, VIPS cleans up by
calling the stop function, passing in the sequence value as an argument. The
types look like this:
\begin{verbatim}
void *
(*start_fn)( IMAGE *out,
void *a, void *b )
int
(*process_fn)( REGION *reg,
void *seq, void *a, void *b )
int
(*stop_fn)( void *seq, void *a, void *b )
\end{verbatim}
\noindent
The values \verb+a+ and \verb+b+ are carried around by VIPS for your use.
For functions like \verb+average()+ which consume images but produce no image
output, VIPS provides \verb+im_iterate()+. This has type:
\begin{verbatim}
int im_iterate( IMAGE *in,
void *(*start_fn)(),
int (*process_fn)(),
int (*stop_fn)(),
void *a, void *b )
\end{verbatim}
VIPS starts one or more sequences, runs one or more processing functions
over image \verb+in+ until all of \verb+in+ has been consumed, and then closes
all of the sequences down and returns. VIPS guarantees that the regions
the \verb+process_fn()+ is given will be complete and disjoint, that is,
every pixel in the image will be passed through exactly one sequence. To
make it possible for the sequences to each contribute to the result of the
function in an orderly manner, VIPS also guarantees that all start and stop
functions are mutually exclusive.
A note on types: \verb+<vips/region.h>+ declares prototypes for
\verb+im_iterate()+ and \verb+im_generate()+ (see \pref{sec:generate}),
but does not give prototypes for the function arguments. This loses a
little type-safety, but gains some convenience.
An example should make this clearer. This version of \verb+average()+
is very similar to the average function in the VIPS library --- it is only
missing polymorphism.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/region.h>
/* Start function for average(). We allocate a small piece of
* storage which this sequence will accumulate its total in. Our
* sequence value is just a pointer to this storage area.
*
* The first of the two pointers VIPS carries around for us is a
* pointer to the space where we store the grand total.
*/
static int *
average_start( IMAGE *out )
{
int *seq = IM_NEW( out, int );
if( !seq )
return( NULL );
*seq = 0;
return( seq );
}
/* Stop function for average(). Add the total which has
* accumulated in our sequence value to the grand total for
* the program.
*/
static int
average_stop( int *seq, int *gtotal )
{
/* Stop functions are mutually exclusive, so we can write
* to gtotal without clashing with any other stop functions.
*/
*gtotal += *seq;
return( 0 );
}
\end{verbatim}
\caption{Final PIO average of image}
\label{fg:p2average}
\end{fig2}
\begin{fig2}
\begin{verbatim}
/* Process function for average(). Total this region, and
* add that total to the sequence value.
*/
static int
average_process( REGION *reg, int *seq )
{
int total, i, y;
Rect *r = &reg->valid;
/* Get the appropriate part of the input image ready.
*/
if( im_prepare( reg, r ) )
return( -1 );
/* Loop over the region.
*/
total = 0;
for( y = r->top; y < IM_RECT_BOTTOM( r ); y++ ) {
unsigned char *p = IM_REGION_ADDR( reg, r->left, y );
for( i = 0; i < IM_REGION_N_ELEMENTS( reg ); i++ )
total += p[i];
}
/* Add to the total for this sequence.
*/
*seq += total;
return( 0 );
}
\end{verbatim}
\caption{Final PIO average of image (cont.)}
\end{fig2}
\begin{fig2}
\begin{verbatim}
/* Find average of image.
*/
int
average( IMAGE *im, double *out )
{
/* Accumulate grand total here.
*/
int gtotal = 0;
/* Prepare im for PIO reading.
*/
if( im_pincheck( im ) )
return( -1 );
/* Check it is the sort of thing we can process.
*/
if( im->BandFmt != IM_BANDFMT_UCHAR ||
im->Coding != IM_CODING_NONE ) {
im_error( "average", "uncoded uchar images only" );
return( -1 );
}
/* Loop over the image in pieces, and possibly in parallel.
*/
if( im_iterate( im,
average_start, average_process, average_stop,
&gtotal, NULL ) )
return( -1 );
/* Calculate average.
*/
*out = (double) gtotal / (IM_IMAGE_N_ELEMENTS( im ) * im->Ysize);
return( 0 );
}
\end{verbatim}
\caption{Final PIO average of image (cont.)}
\end{fig2}
There are a couple of variations on \verb+im_prepare()+: you can use
\verb+im_prepare_to()+ to force writing to a particular place, and
\verb+im_prepare_thread()+ to use threaded evaluation. See the man pages.
\subsection{Output to regions}
\label{sec:generate}
Regions are written to in just the same way they are read from --- by
writing to a pointer found with the \verb+IM_REGION_ADDR()+ macro.
\verb+im_iterate()+ does input --- \verb+im_generate()+ does output. It
has the same type as \verb+im_iterate()+:
\begin{verbatim}
int
im_generate( IMAGE *out,
void *(*start_fn)(),
int (*process_fn)(),
int (*stop_fn)(),
void *a, void *b )
\end{verbatim}
The region given to the process function is ready for output. Each time
the process function is called, it should fill in the pels in the region
it was given. Note that, unlike \verb+im_iterate()+, the areas the process
function is asked to produce are not guaranteed to be either disjoint or
complete. Again, VIPS may start up many process functions if it sees fit.
Here is \verb+invert()+, rewritten to use PIO. This piece of code makes use
of a pair of standard start and stop functions provided by the VIPS library:
\verb+im_start_one()+ and \verb+im_stop_one()+. They assume that the first
of the two user arguments to \verb+im_generate()+ is the input image. They are
defined as:
\begin{verbatim}
REGION *
im_start_one( IMAGE *out, IMAGE *in )
{
return( im_region_create( in ) );
}
\end{verbatim}
\noindent
and:
\begin{verbatim}
int
im_stop_one( REGION *seq )
{
return( im_region_free( seq ) );
}
\end{verbatim}
They are useful for simple functions which expect only one input
image. See the manual page for \verb+im_start_many()+ for many-input
functions.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/region.h>
/* Process function for invert(). Build the pixels in or
* from the appropriate pixels in ir.
*/
static int
invert_process( REGION *or, REGION *ir )
{
Rect *r = &or->valid;
int i, y;
/* Ask for the part of ir we need to make or. In this
* case, the two areas will be the same.
*/
if( im_prepare( ir, r ) )
return( -1 );
/* Loop over or writing pels calculated from ir.
*/
for( y = r->top; y < IM_RECT_BOTTOM( r ); y++ ) {
unsigned char *p = IM_REGION_ADDR( ir, r->left, y );
unsigned char *q = IM_REGION_ADDR( or, r->left, y );
for( i = 0; i < IM_REGION_N_ELEMENTS( or ); i++ )
q[i] = 255 - p[i];
}
/* Success!
*/
return( 0 );
}
\end{verbatim}
\caption{PIO invert}
\label{fg:p2invert}
\end{fig2}
\begin{fig2}
\begin{verbatim}
/* Invert an image.
*/
int
invert( IMAGE *in, IMAGE *out )
{
/* Check descriptors for PIO compatibility.
*/
if( im_piocheck( in, out ) )
return( -1 );
/* Check input image for compatibility with us.
*/
if( in->BandFmt != IM_BANDFMT_UCHAR || in->Coding != IM_CODING_NONE ) {
im_error( "invert", "uncoded uchar images only" );
return( -1 );
}
/* out inherits from in, as before.
*/
if( im_cp_desc( out, in ) )
return( -1 );
/* Set demand hints for out.
*/
if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
return( -1 );
/* Build out in pieces, and possibly in parallel!
*/
if( im_generate( out,
im_start_one, invert_process, im_stop_one,
in, NULL ) )
return( -1 );
return( 0 );
}
\end{verbatim}
\caption{PIO invert (cont.)}
\end{fig2}
Functions have some choice about the way they write their output. Usually, they
should just write to the region they were given by \verb+im_generate()+. They
can, if they wish, set up the region for output to some other place. See
the manual page for \verb+im_region_region()+. See also the source for
\verb+im_copy()+ and \verb+im_extract()+ for examples of these tricks.
Note also the call to \verb+im_demand_hint()+. This function hints to the IO
system, suggesting the sorts of shapes of region this function is happiest
with. VIPS supports four basic shapes --- choosing the correct shape can
have a dramatic effect on the speed of your function. See the man page for
full details.
\subsection{Callbacks}
\label{sec:callback}
VIPS lets you attach callbacks to image descriptors. These are functions
you provide that VIPS will call when certain events occur. This release
of VIPS supports three callbacks:
\subsubsection{Close callbacks}
These callbacks are invoked just before an image is closed. They are useful
for freeing objects which are associated with the image. All callbacks are
triggered in the reverse order to the order in which they were attached. This
is sometimes important when freeing objects which contain pointers to
other objects.
Use \verb+im_add_close_callback()+ to add a close callback:
\begin{verbatim}
int
im_add_close_callback( IMAGE *im,
int (*callback)(),
void *a, void *b )
\end{verbatim}
\noindent
where \verb+callback()+ is a function supplied by you which has type:
\begin{verbatim}
int callback( void *a, void *b )
\end{verbatim}
\noindent
and which returns 0 on success, and -1 on error, setting
\verb+im_error()+. As with \verb+im_generate()+, the values \verb+a+
and \verb+b+ are carried around for you by VIPS, and may be used as your
function sees fit.
\subsubsection{Eval callbacks}
These are callbacks which are invoked by VIPS during evaluation. They
are called each time a region is filled with data (for PIO functions), or
each time \verb+im_writeline()+ is called (for WIO functions). The callback
has access to a large struct containing information about the progress of
evaluation, useful for user-interfaces built on top of VIPS. See the manual
page for \verb+im_add_eval_callback()+ for full details.
\subsubsection{Evalend callbacks}
These are triggered after completion of evaluation of an image, just after all
stop functions have been called. Evalend callbacks are useful for summarising
the results of a computation, see the example in the section below.
\subsection{Memory allocation revisited}
When you are using PIO, memory allocation becomes rather more complicated than
it was before. There are essentially two types of memory which your function
might want to use for working space: memory which is associated with each
instance of your function (remember that two copies of you function may be
joined together in a pipeline and be running at the same time --- you can't
just use global variables), and memory which is local to each sequence
which VIPS starts on your argument image.
The first type, memory local to this function instance, typically holds
copies of any parameters passed to your image processing function, and links
to any read-only tables used by sequences which you run over the image. This
should be allocated in your main function.
The second type of memory, memory local to a sequence, should be allocated
in a start function. Because this space is private to a sequence, it may be
written to. Start and stop functions are guaranteed
to be single-threaded, so you may write to the function-local memory within
them.

105
doc/src/refintro.tex Normal file
View File

@ -0,0 +1,105 @@
\section{Introduction}
\mylabel{sec:ref}
This document introduces the functions available in the VIPS image
processing library. For detailed information on particular functions,
refer to the UNIX on-line manual pages. Enter (for example):
\begin{verbatim}
example% man im_abs
\end{verbatim}
for information on the function \verb+im_abs()+.
All the comand-line vips operations will print help text too. For example:
\begin{verbatim}
example% vips im_extract
usage: vips im_extract input output
left top width height band
where:
input is of type "image"
output is of type "image"
left is of type "integer"
top is of type "integer"
width is of type "integer"
height is of type "integer"
band is of type "integer"
extract area/band, from package
"conversion"
flags: (PIO function)
(coordinate transformer)
(area operation)
(result can be cached)
vips: error calling function
im_run_command: too few arguments
\end{verbatim}
Once you have found a function you need to use, you can call it from a C
program (see \pref{sec:appl}), you can call
it from C++ or Python (see \pref{sec:cpp}), you can call
it from the \nip{} ((see the \emph{nip Manual}), or SIAM graphical
user-interfaces, or you can run it from the UNIX command line with the
\vips{} program. For example:
\begin{verbatim}
john% vips im_vips2tiff cam.v t1.tif none
john% vips im_tiff2vips t1.tif t2.v.v 0
john% vips im_equal cam.v t2.v t3.v
john% vips im_min t3.v
255
\end{verbatim}
VIPS may have been set up at your site with a set of links which call the
vips program for you. You may also be able to type:
\begin{verbatim}
john% im_vips2tiff cam.v t1.tif none
john% im_tiff2vips t1.tif t2.v.v 0
john% im_equal cam.v t2.v t3.v
john% im_min t3.v
\end{verbatim}
There are a few VIPS programs which you cannot run with \vips{}, either
because their arguments are a very strange, or because they are complete
mini-applications (like \verb+vips2dj+). These programs are listed in
table~\ref{tb:nondb}, see the man pages for full details.
\begin{tab2}
\centerline{
\begin{tabular}{|l|l|}
\hline
Name & Description \\
\hline
\texttt{binfile} & Read RAW image \\
\texttt{debugim} & Print an image pixel by pixel \\
\texttt{edvips} & Change fields in a VIPS header \\
\texttt{header} & Print fields from a VIPS header \\
\texttt{printlines} & Print an image a line at a time \\
\texttt{vips} & VIPS universal main program \\
\texttt{vips-7.12} & VIPS wrapper script \\
\texttt{find\_mosaic} & Analyse a set of images for overlaps \\
\texttt{mergeup} & Join a set of images together \\
\texttt{cooc\_features} & Calculate features of a co-occurence matrix \\
\texttt{cooc} & Calculate a co-occurence matrix \\
\texttt{glds\_features} & Calculate features of a grey-level
distribution matrix \\
\texttt{glds} & Calculate a grey-level distribution matrix \\
\texttt{simcontr} & Demonstrate simultaneous contrast \\
\texttt{sines} & Generate a sinusoidal test pattern \\
\texttt{spatres} & Generate a spatial resolution test pattern \\
\texttt{squares} & Generate some squares \\
\texttt{batch\_crop} & Crop a lot of images \\
\texttt{batch\_image\_convert} & File format convert a lot of images \\
\texttt{batch\_rubber\_sheet} & Warp a lot of images \\
\texttt{light\_correct} & Correct a set of images for shading errors \\
\texttt{mitsub} & Format a VIPS image for output to a Mitsubishi 3600 \\
\texttt{shrink\_width} & Shrink to a specific width \\
\texttt{vdump} & VIPS to mono Postscript \\
\texttt{vips2dj} & VIPS to high-quality colour Postscript \\
\hline
\end{tabular}
}
\caption{Miscellaneous programs}
\label{tb:nondb}
\end{tab2}

75
doc/src/vdisplay.tex Normal file
View File

@ -0,0 +1,75 @@
\section{The \texttt{VDisplay} class}
The \verb+VDisplay+ class is an abstraction over the VIPS \verb+im_col_display+
type which gives convenient and safe representation of VIPS display profiles.
VIPS display profiles are now obsolete. You're better off using the
ICC colour management \verb+VImage+ member functions \verb+ICC_export()+ and
\verb+ICC_import()+.
\subsection{Constructors}
There are two constructors for \verb+VDisplay+:
\begin{verbatim}
VDisplay( const char *name );
VDisplay();
\end{verbatim}
The first form initialises the display from one of the standard VIPS display
types. For example:
\begin{verbatim}
VDisplay fred( "sRGB" );
VDisplay jim( "ultra2-20/2/98" );
\end{verbatim}
Makes \verb+fred+ a profile for making images in sRGB format, and \verb+jim+ a
profile representing my workstation display, as of 20/2/98. The second form
of constructor makes an uninitialised display.
\subsection{Projection functions}
A set of member functions of \verb+VDisplay+ provide read and write access to
the fields in the display.
\begin{verbatim}
char *name();
VDisplayType &type();
matrix &mat();
float &YCW();
float &xCW();
float &yCW();
float &YCR();
float &YCG();
float &YCB();
int &Vrwr();
int &Vrwg();
int &Vrwb();
float &Y0R();
float &Y0G();
float &Y0B();
float &gammaR();
float &gammaG();
float &gammaB();
float &B();
float &P();
\end{verbatim}
Where \verb+VDisplayType+ is defined as:
\begin{verbatim}
enum VDisplayType {
BARCO,
DUMB
};
\end{verbatim}
And \verb+matrix+ is defined as:
\begin{verbatim}
typedef float matrix[3][3];
\end{verbatim}
For a description of all the fields in a VIPS display profile, see the manual
page for \verb+im_XYZ2RGB()+.

76
doc/src/verror.tex Normal file
View File

@ -0,0 +1,76 @@
\section{The \texttt{VError} class}
The \verb+VError+ class is the class thrown by the VIPS C++ API when an
error is detected. It is derived from \verb+std::exception+ in the usual way.
\subsection{Constructors}
There are two constructors for \verb+VError+:
\begin{verbatim}
VError( std::string str );
VError();
\end{verbatim}
The first form creates an error object initialised with the specified
string, the last form creates an empty error object.
\subsection{Projection functions}
A function gives access to the string held by \verb+VError+:
\begin{verbatim}
const char *what();
\end{verbatim}
You can also send to an \verb+ostream+.
\begin{verbatim}
std::ostream& operator<<(
std::ostream&, const error& );
\end{verbatim}
\subsection{Computing with \texttt{VError}}
Two member functions let you append elements to an error:
\begin{verbatim}
VError &app( std::string txt );
VError &app( const int i );
\end{verbatim}
For example:
\begin{verbatim}
VError wombat;
int n = 12;
wombat.app( "possum: no more than " ).
app( n ).app( " elements\n" );
throw( wombat );
\end{verbatim}
\noindent
will throw a \verb+VError+ with a diagnostic of:
\begin{verbatim}
possum: no more than 12 elements
\end{verbatim}
The member function \verb+perror()+ prints the error message to \verb+stdout+
and exits with a code of 1.
\begin{verbatim}
void perror( const char * );
void perror();
\end{verbatim}
\subsection{Convenience function}
The convenience function \verb+verror+ creates an \verb+VError+ with the
specified error string, and throws it. If you pass \verb+""+ for the string,
verror uses the contents of the VIPS error buffer instead.
\begin{verbatim}
extern void verror( std::string str = "" );
\end{verbatim}

279
doc/src/vimage.tex Normal file
View File

@ -0,0 +1,279 @@
\section{The \texttt{VImage} class}
The \verb+VImage+ class is a layer over the VIPS \verb+IMAGE+ type. It
automates almost all of the image creation and destruction issues that
complicate the C API, it automates error handling, and it provides a
convenient system for composing operations.
\subsection{Constructors}
There are two principal constructors for \verb+VImage+:
\begin{verbatim}
VImage::VImage( const char *name,
const char *mode = "r" );
VImage::VImage();
\end{verbatim}
The first form creates a new \verb+VImage+, linking it to the named file.
\verb+mode+ sets the mode for the file: it can take the following values:
\begin{description}
\item[\texttt{"r"}]
The named image file is opened read-only. This is the default mode.
\item[\texttt{"w"}]
A \verb+VImage+ is created which, when written to, will write pixels to disc
in the specified file.
\item[\texttt{"t"}]
As the \verb'"w"' mode, but pixels written to the \verb+VImage+ will be saved
in a temporary memory buffer.
\item[\texttt{"p"}]
This creates a special `partial' image. Partial images represent
intermediate results, and are used to join VIPS operations together,
see~\pref{sec:compute}.
\item[\texttt{"rw"}]
As the \verb'"r"' mode, but the image is mapped into your address space
read-write. This mode is only provided for the use of paintbox-style
applications, which need to directly modify an image. See \pref{sec:inplace}.
\end{description}
The second form of constructor is shorthand for:
\begin{verbatim}
VImage( "VImage:1", "p" )
\end{verbatim}
\noindent
It is used for representing intermediate results of computations.
Two further constructors are handy for wrapping \verb+VImage+ around existing
images.
\begin{verbatim}
VImage( void *buffer,
int width, int height, int bands,
TBandFmt format );
VImage( void *image );
\end{verbatim}
\noindent
The first constructor makes a \verb+VImage+ from an area of memory (perhaps
from another image processing system), and the second makes a \verb+VImage+
from an \verb+IMAGE+.
In both these two cases, the VIPS C++ API does not assume responsibility
for the resouces: it's up to you to make sure the buffer is freed.
\subsection{File conversion}
VIPS can read and write a number of different file formats. Information about
file format conversion is taken from the filename. For example:
\begin{verbatim}
VImage jim( "fred.jpg" );
\end{verbatim}
\noindent
This will decompress the file \verb+fred.jpg+ to a memory buffer, wrap a VIPS
image around the buffer and build a reference to it called \verb+jim+.
Options are passed to the file format converters embedded in the filename. For
example:
\begin{verbatim}
VImage out( "jen.tif:deflate", "w" );
\end{verbatim}
\noindent
\noindent
Writing to the descriptor \verb+out+ will cause a TIFF image to be written to
disc with deflate compression.
See the manual page for \verb+im_open(3)+ for details of all the file formats
and conversions available.
\subsection{Projection functions}
A set of member functions of \verb+VImage+ provide access to the fields in
the header:
\begin{verbatim}
int Xsize();
int Ysize();
int Bands();
TBandFmt BandFmt();
TCoding Coding();
TType Type();
float Xres();
float Yres();
int Length();
TCompression Compression();
short Level();
int Xoffset();
int Yoffset();
\end{verbatim}
\noindent
Where \verb+TBandFmt+, \verb+TCoding+, \verb+TType+ and \verb+TCompression+
are \verb+enum+s for the types in the VIPS file header. See section~\pref{sec:header} for an explanation of all of these fields.
The \verb+image()+ member function provides access to the \verb+IMAGE+
descriptor underlying the C++ API. See the \pref{sec:appl} for details.
\begin{verbatim}
void *image();
\end{verbatim}
The \verb+data()+ member function returns a pointer to an array of pixel data
for the image.
\begin{verbatim}
void *data() const;
\end{verbatim}
\noindent
This can be very slow and use huge amounts of RAM.
Finally, two projection functions give access to the filename and history
fields maintained by the VIPS IO system.
\begin{verbatim}
char *filename();
char *Hist();
\end{verbatim}
\subsection{Assignment}
\verb+VImage+ defines copy and assignment, with reference-counted
pointer-style semantics. For example, if you write:
\begin{verbatim}
VImage fred( "fred.v" );
VImage jim( "jim.v" );
fred = jim;
\end{verbatim}
This will automatically close the file \verb+fred.v+, and make the variable
\verb+fred+ point to the image \verb+jim.v+ instead. Both \verb+jim+ and
\verb+fred+ now point to the same underlying image object.
Internally, a \verb+VImage+ object is just a pointer to a reference-counting
block, which in turn holds a pointer to the underlying VIPS \verb+IMAGE+ type.
You can therefore efficiently pass \verb+VImage+ objects to functions by
value, and return \verb+VImage+ objects as function results.
\subsection{Computing with \texttt{VImage}s}
\label{sec:compute}
All VIPS image processing operations are member functions of the \verb+VImage+
class. For example:
\begin{verbatim}
VImage fred( "fred.v" );
VImage jim( "jim.v" );
VImage result = fred.cos() + jim;
\end{verbatim}
Will apply \verb+im_costra()+ to \verb+fred.v+, making an image where each
pixel is the cosine of the corresponding pixel in \verb+fred.v+; then add that
image to \verb+jim.v+. Finally, the result will be held in \verb+result+.
VIPS is a demand-driven image processing system: when it computes expressions
like this, no actual pixels are calculated (although you can use the
projection functions on images --- \verb+result.BandFmt()+ for example). When
you finally write the result to a file (or use some operation that needs pixel
values, such as \verb+min()+, find minimum value), VIPS evaluates all of the
operations you have called to that point in parallel. If you have more than one
CPU in your machine, the load is spread over the available processors. This
means that there is no limit to the size of the images you can process.
\pref{sec:packages} lists all of the VIPS packages. These general
rules apply:
\begin{itemize}
\item
VIPS operation names become C++ member function names by dropping the
\verb+im_+ prefix, and if present, the \verb+tra+ postfix, the \verb+const+
postfix and the \verb+_vec+ postfix. For example, the
VIPS operation \verb+im_extract()+ becomes \verb+extract()+, and
\verb+im_costra()+ becomes \verb+cos()+.
\item
The \verb+VImage+ object to which you apply the member function is the first
input image, the member function returns the first output. If there is no
image input, the member is declared \verb+static+.
\item
\verb+INTMASK+ and \verb+DOUBLEMASK+ types become \verb+VMask+ objects,
\verb+im_col_display+ types become \verb+VDisplay+ objects.
\item
Several C API functions can map to the same C++ API member. For example,
\verb+im_andimage+, \verb+im_andimage_vec+ and \verb+im_andimageconst+ all map
to the member \verb+andimage+. The API relies on overloading to
discriminate between these functions.
\end{itemize}
This part of the C++ API is generated automatically from the VIPS function
database, so it should all be up-to-date.
There are a set of arithmetic operators defined for your convenience. You can
generally write any arithmetic expression and include \verb+VImage+ in there.
\begin{verbatim}
VImage fred( "fred.v" );
VImage jim( "jim.v" );
Vimage v = int((fred + jim) / 2);
\end{verbatim}
\subsection{Writing results}
Once you have computed some result, you can write it to a file with the member
\verb+write()+. It takes the following forms:
\begin{verbatim}
VImage write( const char *name );
VImage write( VImage out );
VImage write();
\end{verbatim}
The first form simply writes the image to the named file. The second form
writes the image to the specified \verb+VImage+ object, for example:
\begin{verbatim}
VImage fred( "fred.v" );
VImage jim( "jim buffer", "t" );
Vimage v = (fred + 42).write( jim );
\end{verbatim}
\noindent
This creates a temporary memory buffer called \verb+jim+, and fills it with
the result of adding 42 to every pixel in \verb+fred.v+.
The final form of \verb+write()+ writes the image to a memory buffer, and
returns that.
\subsection{Type conversions}
Two type conversions are defined: you can cast \verb+VImage+ to a
\verb+VDMask+ and to a \verb+VIMask+.
\begin{verbatim}
operator VDMask();
operator VIMask();
\end{verbatim}
These operations are slow and need a lot of memory! Emergencies only.

88
doc/src/vipsmanual.tex Normal file
View File

@ -0,0 +1,88 @@
\documentclass[a4paper,twocolumn,dvips]{book}
\usepackage[dvips=false,pdftex=false,vtex=false]{geometry}
\usepackage{ifpdf}
\ifpdf
\usepackage[pdftex]{graphicx,color}
\else
\usepackage{graphicx,color}
\fi
\usepackage{times}
\usepackage{fancyhdr}
\usepackage{ifthen}
\input{mydefs}
\fancyhead{} % clear all fields
\fancyhead[LE,RO]{\leftmark} % left-even, right-odd
\fancyhead[RE,LO]{VIPS Manual} % right-even, left-odd
\fancyfoot[LE,RO]{\thepage} % left-even, right-odd
\fancyfoot[RE,LO]{January 2007}
\begin{document}
\pagenumbering{roman}
\begin{titlepage}
\thispagestyle{empty}
\begin{center}
\huge
VIPS Manual\\
\large Version 7.12\\
\vspace{0.5in}
\large
John Cupitt,
Kirk Martinez\\
\end{center}
% hmm ... must be a better way to get the quote at the bottom of the page
\vspace{6in}
This manual formatted \today
\setcounter{page}{1}
\end{titlepage}
% \blankpage
\tableofcontents
\thispagestyle{plain}
% \blankpage
\listoffigures
\thispagestyle{plain}
% \blankpage
\listoftables
\thispagestyle{plain}
% \blankpage
\pagenumbering{arabic}
\thispagestyle{plain}
\cfoot{}
\chapter{VIPS from C++ and Python}
\input{cppintro}
\input{fileformat}
\input{vimage}
\input{vmask}
\input{vdisplay}
\input{verror}
\chapter{VIPS for C programmers}
\input{applintro}
\input{iosys}
\input{func}
\chapter{Writing VIPS operations}
\input{operintro}
\input{wio}
\input{pio}
\input{ipio}
\chapter{VIPS reference}
\input{refintro}
\input{packages}
\end{document}

151
doc/src/vmask.tex Normal file
View File

@ -0,0 +1,151 @@
\section{The \texttt{VMask} class}
The \verb+VMask+ class is an abstraction over the VIPS \verb+DOUBLEMASK+ and
\verb+INTMASK+ types which gives convenient and safe representation of
matricies.
\verb+VMask+ has two sub-classes, \verb+VIMask+ and \verb+VDMask+. These
represent matricies of integers and doubles respectively.
\subsection{Constructors}
There are three constructors for \verb+VIMask+ and \verb+VDMask+:
\begin{verbatim}
VIMask( int xsize, int ysize );
VIMask( int xsize, int ysize,
int scale, int offset, ... );
VIMask( const char *name );
VIMask();
VDMask( int xsize, int ysize );
VDMask( int xsize, int ysize,
double scale, double offset, ... );
VDMask( const char *name );
VDMask();
\end{verbatim}
The first form creates an empty matrix, with the specified dimensions;
the second form initialises a matrix from a varargs list; the third form
reads the matrix from the named file. The final form makes a mask object
with no contents yet.
\subsection{Projection functions}
A set of member functions of \verb+VIMask+ provide access to the fields in
the matrix:
\begin{verbatim}
int xsize() const;
int ysize() const;
int scale() const;
int offset() const;
const char *filename() const;
\end{verbatim}
\verb+VDMask+ is the same, except that the \verb+scale()+ and \verb+offset()+
members return \verb+double+. \verb+VMask+ allows all operations that are
common to \verb+VIMask+ and \verb+VDMask+.
\subsection{Assignment}
\verb+VMask+ defines copy and assignment with pointer-style
semantics. You can write stuff like:
\begin{verbatim}
VIMask fred( "mask" );
VMask jim;
jim = fred;
\end{verbatim}
This reads the file \verb+mask+, noting a pointer to the mask in \verb+fred+.
It then makes \verb+jim+ also point to it, so \verb+jim+ and \verb+fred+ are
sharing the same underlying matrix values.
Internally, a \verb+VMask+ object is just a pointer to a reference-counting
block, which in turn holds a pointer to the underlying VIPS \verb+MASK+ type.
You can therefore efficiently pass \verb+VMask+ objects to functions by
value, and return \verb+VMask+ objects as function results.
\subsection{Computing with \texttt{VMask}}
You can use \verb+[]+ to get at matrix elements, numbered left-to-right,
top-to-bottom. Alternatively, use \verb+()+ to address elements by $x,y$
position. For example:
\begin{verbatim}
VIMask fred( "mask" );
for( int i = 0; i < fred.xsize(); i++ )
fred[i] = 12;
\end{verbatim}
\noindent
will set the first line of the matrix to 12, and:
\begin{verbatim}
VDMask fred( "mask" );
for( int x = 0; x < fred.xsize(); x++ )
fred(x, x) = 12.0;
\end{verbatim}
\noindent
will set the leading diagonal to 12.
See the member functions below for other operations on \verb+VMask+.
\subsection{\texttt{VIMask} operations}
The following operations are defined for \verb+VIMask+:
\begin{verbatim}
// Cast to VDMask and VImage
operator VDMask();
operator VImage();
// Build gaussian and log masks
static VIMask gauss( double, double );
static VIMask log( double, double );
// Rotate
VIMask rotate45();
VIMask rotate90();
// Transpose, invert, join and multiply
VDMask trn() ;
VDMask inv();
VDMask cat( VDMask );
VDMask mul( VDMask );
\end{verbatim}
\subsection{\texttt{VDMask} operations}
The following operations are defined for \verb+VDMask+:
\begin{verbatim}
// Cast to VIMask and VImage
operator VIMask();
operator VImage();
// Build gauss and log masks
static VDMask gauss( double, double );
static VDMask log( double, double );
// Rotate
VDMask rotate45();
VDMask rotate90();
// Scale to intmask
VIMask scalei();
// Transpose, invert, join and multiply
VDMask trn();
VDMask inv();
VDMask cat( VDMask );
VDMask mul( VDMask );
\end{verbatim}
\subsection{Output of masks}
You can output masks with the usual \verb+<<+ operator.

363
doc/src/wio.tex Normal file
View File

@ -0,0 +1,363 @@
\section{Programming WIO operations}
WIO is the style for you if you want ease of programming, or if your
algorithm must have the whole of the input image available at the same
time. For example, a Fourier transform operation is unable to produce any
output until it has seen the whole of the input image.
\subsection{Input from an image}
In WIO input, the whole of the image data is made available to the program
via the \verb+data+ field of the descriptor. To make an image ready for reading
in this style, programs should call \verb+im_incheck()+:
\begin{verbatim}
int im_incheck( IMAGE *im )
\end{verbatim}
\noindent
If it succeeds, it returns 0, if it fails, it returns non-zero and
sets \verb+im_error()+. On success, VIPS guarantees that all of the
user-accessible fields in the descriptor contain valid data, and that all
of the image data may be read by simply reading from the \verb+data+ field
(see below for an example). This will only work for images less than about
2GB in size.
VIPS has some simple macros to help address calculations on images:
\begin{verbatim}
int IM_IMAGE_SIZEOF_ELEMENT( IMAGE * )
int IM_IMAGE_SIZEOF_PEL( IMAGE * )
int IM_IMAGE_SIZEOF_LINE( IMAGE * )
int IM_IMAGE_N_ELEMENTS( IMAGE * )
char *IM_IMAGE_ADDR( IMAGE *,
int x, int y )
\end{verbatim}
\noindent
These macros calculate \verb+sizeof()+ a band element, a pel and a horizontal
line of pels. \verb+IM_IMAGE_N_ELEMENTS+ returns the number of band elements
across an image. \verb+IM_IMAGE_ADDR+ calculates the address of a pixel in an
image. If \verb+DEBUG+ is defined, it does bounds checking too.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
int
average( IMAGE *im, double *out )
{
int x, y;
long total;
/* Prepare for reading.
*/
if( im_incheck( im ) )
return( -1 );
/* Check that this is the kind of image we can process.
*/
if( im->BandFmt != IM_BANDFMT_UCHAR ||
im->Coding != IM_CODING_NONE ) {
im_error( "average", "uncoded uchar images only" );
return( -1 );
}
/* Loop over the image, summing pixels.
*/
total = 0;
for( y = 0; y < im->Ysize; y++ ) {
unsigned char *p = (unsigned char *) IM_IMAGE_ADDR( im, 0, y );
for( x = 0; x < IM_IMAGE_N_ELEMENTS( im ); x++ )
total += p[x];
}
/* Calculate average.
*/
*out = (double) total /
(IM_IMAGE_N_ELEMENTS( im ) * im->Ysize));
/* Success!
*/
return( 0 );
}
\end{verbatim}
\caption{Find average of image}
\label{fg:average}
\end{fig2}
\fref{fg:average} is a simple WIO operation which calculates the
average of an unsigned char image. It will work for any size image, with any
number of bands. See~\pref{sec:poly} for techniques for making operations
which will work for any image type. This operation might be called from an
application with:
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
void
find_average( char *name )
{
IMAGE *im;
double avg;
if( !(im = im_open( name, "r" )) ||
average( im, &avg ) ||
im_close( im ) )
error_exit( "failure!" );
printf( "Average of \"%s\" is %G\n",
name, avg );
}
\end{verbatim}
\noindent
When you write an image processing operation, you can test it by writing
a VIPS function descriptor and calling it from the \vips{} universal
main program, or from the \nip{} interface. See \pref{sec:appl}.
\subsection{Output to an image}
Before attempting WIO output, programs should call \verb+im_outcheck()+. It
has type:
\begin{verbatim}
int im_outcheck( IMAGE *im )
\end{verbatim}
\noindent
If \verb+im_outcheck()+ succeeds, VIPS guarantees that WIO output is sensible.
Programs should then set fields in the output descriptor to describe
the sort of image they wish to write (size, type, and so on) and call
\verb+im_setupout()+. It has type:
\begin{verbatim}
int im_setupout( IMAGE *im )
\end{verbatim}
\noindent
\verb+im_setupout()+ creates the output file or memory buffer, using the
size and type fields that were filled in by the program between the calls to
\verb+im_outcheck()+ and \verb+im_setupout()+, and gets it ready for writing.
Pels are written with \verb+im_writeline()+. This takes a y position (pel
(0,0) is in the top-left-hand corner of the image), a descriptor and a
pointer to a line of pels. It has type:
\begin{verbatim}
int im_writeline( int y,
IMAGE *im, unsigned char *pels )
\end{verbatim}
Two convenience functions are available to make this process slightly
easier. \verb+im_iocheck()+ is useful for programs which take one input
image and produce one image output. It simply calls \verb+im_incheck()+
and \verb+im_outcheck()+. It has type:
\begin{verbatim}
int im_iocheck( IMAGE *in, IMAGE *out )
\end{verbatim}
The second convenience function copies the fields describing size, type,
metadata and history from one image descriptor to another. It is useful when
the output
image will be similar in size and type to the input image. It has type:
\begin{verbatim}
int im_cp_desc( IMAGE *out, IMAGE *in )
\end{verbatim}
\noindent
There's also \verb+im_cp_descv()+, see the man page.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/util.h>
int
invert( IMAGE *in, IMAGE *out )
{
int x, y;
unsigned char *buffer;
/* Check images.
*/
if( im_iocheck( in, out ) )
return( -1 );
if( in->BandFmt != IM_BANDFMT_UCHAR || in->Coding != IM_CODING_NONE ) {
im_error( "invert", "uncoded uchar images only" );
return( -1 );
}
/* Make output image.
*/
if( im_cp_desc( out, in ) )
return( -1 );
if( im_setupout( out ) )
return( -1 );
/* Allocate a line buffer and make sure it will be freed correctly.
*/
if( !(buffer = IM_ARRAY( out,
IM_IMAGE_SIZEOF_LINE( in ), unsigned char )) )
return( -1 );
/* Loop over the image!
*/
for( y = 0; y < in->Ysize; y++ ) {
unsigned char *p = (unsigned char *) IM_IMAGE_ADDR( in, 0, y );
for( x = 0; x < IM_IMAGE_N_ELEMENTS( in ); x++ )
buffer[x] = 255 - p[x];
if( im_writeline( y, out, buffer ) )
return( -1 );
}
return( 0 );
}
\end{verbatim}
\caption{Invert an image}
\label{fg:invert}
\end{fig2}
\fref{fg:invert} is a WIO VIPS operation which finds the photographic
negative of an unsigned char image. See \pref{sec:malloc} for an explanation
of \verb+IM_ARRAY+. This operation might be called from an
application with:
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <vips/vips.h>
void
find_negative( char *inn, char *outn )
{
IMAGE *in, *out;
if( !(in = im_open( inn, "r" )) ||
!(out = im_open( outn, "w" )) ||
invert( in, out ) ||
im_updatehist( out, "invert" ) ||
im_close( in ) ||
im_close( out ) )
error_exit( "failure!" );
}
\end{verbatim}
See \pref{sec:history} for an explanation of the call to \verb+im_updatehist()+.
\subsection{Polymorphism}
\label{sec:poly}
Most image processing operations in the VIPS library can operate on
images of any type (\verb+IM_BANDFMT_UCHAR+, as in our examples above,
also \verb+IM_BANDFMT_UINT+ etc.). This is usually implemented with code
replication: the operation contains loops for processing every kind of image,
and when called, invokes the appropriate loop for the image it is given.
As an example, figure~\ref{fg:exp} calculates \verb+exp()+ for every pel
in an image. If the input image is \verb+double+, we write \verb+double+
output. If it is any other non-complex type, we write \verb+float+. If it
is complex, we flag an error (\verb+exp()+ of a complex number is fiddly).
The example uses an image type predicate, \verb+im_iscomplex()+. There are
a number of these predicate functions, see the manual page.
\begin{fig2}
\begin{verbatim}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <vips/vips.h>
#include <vips/util.h>
/* Exponential transform.
*/
int
exptra( IMAGE *in, IMAGE *out )
{
int x, y;
unsigned char *buffer;
/* Check descriptors.
*/
if( im_iocheck( in, out ) )
return( -1 );
if( in->Coding != IM_CODING_NONE || im_iscomplex( in ) ) {
im_error( "exptra", "uncoded non-complex only" );
return( -1 );
}
/* Make output image.
*/
if( im_cp_desc( out, in ) )
return( -1 );
if( in->BandFmt != IM_BANDFMT_DOUBLE )
out->BandFmt = IM_BANDFMT_FLOAT;
if( im_setupout( out ) )
return( -1 );
\end{verbatim}
\caption{Calculate \texttt{exp()} for an image}
\label{fg:exp}
\end{fig2}
\begin{fig2}
\begin{verbatim}
/* Allocate a line buffer.
*/
if( !(buffer = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( in ), unsigned char )) )
return( -1 );
/* Our inner loop, parameterised for both the input and output
* types. Note the use of `\', since macros have to be all on
* one line.
*/
#define loop(IN, OUT) { \
for( y = 0; y < in->Ysize; y++ ) { \
IN *p = (IN *) IM_IMAGE_ADDR( in, 0, y ); \
OUT *q = (OUT *) buffer; \
\
for( x = 0; x < IM_IMAGE_N_ELEMENTS( in ); x++ ) \
q[x] = exp( p[x] ); \
if( im_writeline( y, out, buffer ) ) \
return( -1 ); \
} \
}
/* Switch for all the types we can handle.
*/
switch( in->BandFmt ) {
case IM_BANDFMT_UCHAR: loop( unsigned char, float ); break;
case IM_BANDFMT_CHAR: loop( char, float ); break;
case IM_BANDFMT_USHORT:loop( unsigned short, float ); break;
case IM_BANDFMT_SHORT: loop( short, float ); break;
case IM_BANDFMT_UINT: loop( unsigned int, float ); break;
case IM_BANDFMT_INT: loop( int, float ); break;
case IM_BANDFMT_FLOAT: loop( float, float ); break;
case IM_BANDFMT_DOUBLE:loop( double, double ); break;
default:
im_error( "exptra", "internal error" );
return( -1 );
}
/* Success.
*/
return( 0 );
}
\end{verbatim}
\caption{Calculate \texttt{exp()} for an image (cont)}
\end{fig2}

2
include/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
SUBDIRS = vips

34
include/vips/Makefile.am Normal file
View File

@ -0,0 +1,34 @@
pkginclude_HEADERS = \
VDisplay.h \
VError.h \
VImage.h \
VMask.h \
vipscpp.h \
colour.h \
debug.h \
dispatch.h \
fmask.h \
history.h \
mosaic.h \
proto.h \
rect.h \
region.h \
r_access.h \
struct.h \
semaphore.h \
threadgroup.h \
thread.h \
time.h \
util.h \
meta.h \
version.h \
vips.h \
vips \
intl.h \
vbuf.h \
vipsc++.h
vipsc++.h:
vips --cpph all > vipsc++.h
EXTRA_DIST = version.h.in internal.h

113
include/vips/VDisplay.h Normal file
View File

@ -0,0 +1,113 @@
/* VIPS display class.
*
* Hide details of im_col_display API.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_VDISPLAY_H
#define IM_VDISPLAY_H
/* SWIG includes this file directly rather than going through vipscpp.h ... so
* we have to define these macros here as well.
*/
#ifdef SWIG
#define VIPS_NAMESPACE_START namespace vips {
#define VIPS_NAMESPACE_END }
#endif /*SWIG*/
/* Wrap pointers to these, but we don't want to import all the old C API. Just
* declare them.
*/
extern "C" {
struct im_col_display;
struct im_col_tab_disp;
}
VIPS_NAMESPACE_START
// Wrapper over im_col_display with ref counting
class VDisplay {
struct refblock {
im_col_display *disp; // im_col_display struct
im_col_tab_disp *luts; // luts built from this display
int priv; // disp is ours, or system
int nrefs; // Refs to us
// Invalidate lut
void cleanlut();
// Break attached stuff
void cleanref();
// Get ready to write
void wready() throw( VError );
// Check that luts are up-to-date
void cluts() throw( VError );
refblock() : disp(0), luts(0), priv(0), nrefs(1) {}
~refblock() { cleanref(); }
};
refblock *ref;
public:
enum VDisplayType {
BARCO, // Does many corrections for us
DUMB // Needs many corrections
};
// Get named display
VDisplay( const char *name ) throw( VError );
// Get default display
VDisplay();
// Copy constructor
VDisplay( const VDisplay &a ) { ref = a.ref; ref->nrefs++; }
// Assignment
VDisplay &operator=( const VDisplay &a );
// Destructor
virtual ~VDisplay();
// The matrix type we use
typedef float matrix[3][3];
// Extract display pointer
void *disp() const { return( ref->disp ); }
// Extract luts pointer, rebuilding luts if necessary
im_col_tab_disp *luts() const throw( VError )
{ ref->cluts(); return( ref->luts ); }
};
VIPS_NAMESPACE_END
#endif /*IM_VDISPLAY_H*/

82
include/vips/VError.h Normal file
View File

@ -0,0 +1,82 @@
// Header for error type
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_VERROR_H
#define IM_VERROR_H
/* SWIG includes this file directly rather than going through vipscpp.h ... so
* we have to define these macros here as well.
*/
#ifdef SWIG
#define VIPS_NAMESPACE_START namespace vips {
#define VIPS_NAMESPACE_END }
#endif /*SWIG*/
/* Don't include these when parsing for SWIG.
*/
#ifndef SWIG
# include <string>
# include <iosfwd>
# include <exception>
#endif /*!SWIG*/
VIPS_NAMESPACE_START
// Error type
class VError : public std::exception {
std::string _what;
public:
VError( std::string what ) : _what( what ) {}
VError() {}
virtual ~VError() throw() {}
// Print message and exit
void perror( const char * );
void perror();
// Append some more text to the message
VError &app( std::string txt );
VError &app( const int i );
// Extract string
virtual const char *what() const throw() { return _what.c_str(); }
void ostream_print( std::ostream & ) const;
};
inline std::ostream &operator<<( std::ostream &file, const VError &err )
{
err.ostream_print( file );
return( file );
}
void verror( std::string str = "" ) throw( VError );
VIPS_NAMESPACE_END
#endif /*IM_VERROR_H*/

401
include/vips/VImage.h Normal file
View File

@ -0,0 +1,401 @@
// VIPS image wrapper
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_VIMAGE_H
#define IM_VIMAGE_H
/* SWIG includes this file directly rather than going through vipscpp.h ... so
* we have to define these macros here as well.
*/
#ifdef SWIG
# define VIPS_NAMESPACE_START namespace vips {
# define VIPS_NAMESPACE_END }
#endif /*SWIG*/
/* Don't include these when parsing for SWIG.
*/
#ifndef SWIG
# include <list>
# include <complex>
# include <vector>
#endif /*!SWIG*/
/* Wrap pointers to these, but we don't want to import all the old C API. Just
* declare them.
*/
extern "C" {
struct im__IMAGE;
/* Needed by Vargv, see below.
*/
struct im__function;
typedef void *im__object;
}
VIPS_NAMESPACE_START
/* VIPS image class.
*
* Slightly tricky: we have two sorts of sharing. Several VImage can share one
* refblock (while results are being returned from functions, for example),
* and several other refblocks can have IMAGEs which depend upon this IMAGE
* for their result.
*/
class VImage {
/* We'd like this to be protected so that user subclasses can define
* their own member wrappers. But sadly C++ doesn't work like that:
* subclasses of VImage can only refer to protected members via
* this->, which isn't what we need. Just make it public and hope no
* one touches it.
*/
public:
/* Doesn't need to be wrapped.
*/
#ifndef SWIG
// Count ref etc. in one of these. One for each open VIPS image.
struct refblock {
im__IMAGE *im; // IMAGE pointer
int close_on_delete; // Set if we must im_close()
int nrefs; // Number of refs to us
std::list<refblock*> orefs; // Refs im makes
// Construct/destruct
refblock();
virtual ~refblock() throw( VError );
// Add a ref - this (output image) depends upon IMAGE in
void addref( refblock *in ) throw( VError );
// Remove a ref
void removeref() throw( VError );
// Debugging
void debug_print();
// Linked list needs "==" -- use address equivalence
friend int operator==( const refblock &left,
const refblock &right ) { return( &left == &right ); }
};
refblock *_ref;
#endif /*!SWIG*/
public:
#ifdef DEBUG
/* All the refblocks in the world.
*/
static std::list<refblock*> all_refblock;
#endif /*DEBUG*/
/* Print all refblocks ... debugging. Compile with DEBUG to enable
* this.
*/
static void print_all();
/* Typedefs and enums we need.
*/
// Type type
enum TType {
MULTIBAND = 0,
B_W = 1,
LUMINACE = 2,
XRAY = 3,
IR = 4,
YUV = 5,
RED_ONLY = 6,
GREEN_ONLY = 7,
BLUE_ONLY = 8,
POWER_SPECTRUM = 9,
HISTOGRAM = 10,
LUT = 11,
XYZ = 12,
LAB = 13,
CMC = 14,
CMYK = 15,
LABQ = 16,
RGB = 17,
UCS = 18,
LCH = 19,
LABS = 21,
sRGB = 22,
YXY = 23,
FOURIER = 24,
RGB16 = 25,
GREY16 = 26
};
// Format type
enum TBandFmt {
FMTNOTSET = -1,
FMTUCHAR = 0,
FMTCHAR = 1,
FMTUSHORT = 2,
FMTSHORT = 3,
FMTUINT = 4,
FMTINT = 5,
FMTFLOAT = 6,
FMTCOMPLEX = 7,
FMTDOUBLE = 8,
FMTDPCOMPLEX = 9
};
// Coding type
enum TCoding {
NOCODING = 0,
COLQUANT = 1,
LABPACK = 2,
LABPACK_COMPRESSED = 3,
RGB_COMPRESSED = 4,
LUM_COMPRESSED = 5
};
// Compression type
enum TCompression {
NO_COMPRESSION = 0,
TCSF_COMPRESSION = 1,
JPEG_COMPRESSION = 2
};
/* Start of wrappers for iofuncs.
*/
// Plain constructors
VImage( const char *name, const char *mode = "r" ) throw( VError );
VImage( void *data, int width, int height,
int bands, TBandFmt format ) throw( VError );
VImage( im__IMAGE *image );
VImage() throw( VError );
// Copy constructor
VImage( const VImage &a );
// Assignment - delete old ref
VImage &operator=( const VImage &a ) throw( VError );
// Destructor
virtual ~VImage() throw( VError ) { _ref->removeref(); }
// Extract underlying IMAGE* pointer
im__IMAGE *image() const { return( _ref->im ); }
// Extract underlying data pointer
void *data() const throw( VError );
// Write this to another VImage, to a file, or to a mem buffer
VImage write( VImage out ) throw( VError );
VImage write( const char *name ) throw( VError );
VImage write() throw( VError );
// Debugging ... print header fields
void debug_print();
// Projection functions to get header fields
int Xsize();
int Ysize();
int Bands();
TBandFmt BandFmt();
TCoding Coding();
TType Type();
float Xres();
float Yres();
int Length();
TCompression Compression();
short Level();
int Xoffset();
int Yoffset();
// Derived fields
const char *filename();
const char *Hist();
// Set header fields
void initdesc( int, int, int, TBandFmt, TCoding, TType,
float = 1.0, float = 1.0, int = 0, int = 0 ) throw( VError );
/* Insert automatically generated headers.
*/
#include "vipsc++.h"
/* No point getting SWIG to wrap these ... we do this by hand later so we can
* handle things like "a + 12" correctly.
*/
#ifndef SWIG
// And some in-line operator equivalences done by hand
friend VImage operator+( VImage a, VImage b ) throw( VError )
{ return( a.add( b ) ); }
friend VImage operator+( double a, VImage b ) throw( VError )
{ return( b.lin( 1.0, a ) ); }
friend VImage operator+( VImage a, double b ) throw( VError )
{ return( a.lin( 1.0, b ) ); }
friend VImage operator-( VImage a, VImage b ) throw( VError )
{ return( a.subtract( b ) ); }
friend VImage operator-( double a, VImage b ) throw( VError )
{ return( b.lin( -1.0, a ) ); }
friend VImage operator-( VImage a, double b ) throw( VError )
{ return( a.lin( 1.0, -b ) ); }
friend VImage operator*( VImage a, VImage b ) throw( VError )
{ return( a.multiply( b ) ); }
friend VImage operator*( double a, VImage b ) throw( VError )
{ return( b.lin( a, 0.0 ) ); }
friend VImage operator*( VImage a, double b ) throw( VError )
{ return( a.lin( b, 0.0 ) ); }
friend VImage operator/( VImage a, VImage b ) throw( VError )
{ return( a.divide( b ) ); }
friend VImage operator/( double a, VImage b ) throw( VError )
{ return( b.pow( -1.0 ).lin( a, 0.0 ) ); }
friend VImage operator/( VImage a, double b ) throw( VError )
{ return( a.lin( 1.0/b, 0.0 ) ); }
friend VImage operator%( VImage a, VImage b ) throw( VError )
{ return( a.remainder( b ) ); }
friend VImage operator%( VImage a, double b ) throw( VError )
{ return( a.remainder( b ) ); }
friend VImage operator<( VImage a, VImage b ) throw( VError )
{ return( a.less( b ) ); }
friend VImage operator<( double a, VImage b ) throw( VError )
{ return( b.more( a ) ); }
friend VImage operator<( VImage a, double b ) throw( VError )
{ return( a.less( b ) ); }
friend VImage operator<=( VImage a, VImage b ) throw( VError )
{ return( a.lesseq( b ) ); }
friend VImage operator<=( double a, VImage b ) throw( VError )
{ return( b.moreeq( a ) ); }
friend VImage operator<=( VImage a, double b ) throw( VError )
{ return( a.lesseq( b ) ); }
friend VImage operator>( VImage a, VImage b ) throw( VError )
{ return( a.more( b ) ); }
friend VImage operator>( double a, VImage b ) throw( VError )
{ return( b.less( a ) ); }
friend VImage operator>( VImage a, double b ) throw( VError )
{ return( a.more( b ) ); }
friend VImage operator>=( VImage a, VImage b ) throw( VError )
{ return( a.moreeq( b ) ); }
friend VImage operator>=( double a, VImage b ) throw( VError )
{ return( b.lesseq( a ) ); }
friend VImage operator>=( VImage a, double b ) throw( VError )
{ return( a.moreeq( b ) ); }
friend VImage operator==( VImage a, VImage b ) throw( VError )
{ return( a.equal( b ) ); }
friend VImage operator==( double a, VImage b ) throw( VError )
{ return( b.equal( a ) ); }
friend VImage operator==( VImage a, double b ) throw( VError )
{ return( a.equal( b ) ); }
friend VImage operator!=( VImage a, VImage b ) throw( VError )
{ return( a.notequal( b ) ); }
friend VImage operator!=( double a, VImage b ) throw( VError )
{ return( b.notequal( a ) ); }
friend VImage operator!=( VImage a, double b ) throw( VError )
{ return( a.notequal( b ) ); }
friend VImage operator&( VImage a, VImage b ) throw( VError )
{ return( a.andimage( b ) ); }
friend VImage operator&( int a, VImage b ) throw( VError )
{ return( b.andimage( a ) ); }
friend VImage operator&( VImage a, int b ) throw( VError )
{ return( a.andimage( b ) ); }
friend VImage operator|( VImage a, VImage b ) throw( VError )
{ return( a.orimage( b ) ); }
friend VImage operator|( int a, VImage b ) throw( VError )
{ return( b.orimage( a ) ); }
friend VImage operator|( VImage a, int b ) throw( VError )
{ return( a.orimage( b ) ); }
friend VImage operator^( VImage a, VImage b ) throw( VError )
{ return( a.eorimage( b ) ); }
friend VImage operator^( int a, VImage b ) throw( VError )
{ return( b.eorimage( a ) ); }
friend VImage operator^( VImage a, int b ) throw( VError )
{ return( a.eorimage( b ) ); }
friend VImage operator<<( VImage a, int b ) throw( VError )
{ return( a.shiftleft( b ) ); }
friend VImage operator>>( VImage a, int b ) throw( VError )
{ return( a.shiftright( b ) ); }
friend VImage operator-( VImage a ) throw( VError )
{ return( a * -1 ); }
// Type conversion: VImage to VDMask and VIMask
operator VDMask() throw( VError )
{ return( this->vips2mask() ); }
operator VIMask() throw( VError )
{ return( VIMask( VDMask( *this ) ) ); }
#endif /*!SWIG*/
};
/* Don't include these when parsing for SWIG.
*/
#ifndef SWIG
/* Class wrapping up a vargv. Member function wrappers need this. It needs to
* be part of the public API in case people subclass VImage and add their own
* members.
*/
class Vargv {
// Function we are args to
im__function *fn;
// Base of object vector
im__object *base;
public:
Vargv( const char *name );
~Vargv();
// Reference to element of base
im__object &data( int i = 0 ) { return( base[i] ); };
// Invoke function
void call();
};
#endif /*!SWIG*/
VIPS_NAMESPACE_END
// Other VIPS protos
extern "C" {
extern int im_init_world( const char *argv0 );
extern void im__print_all();
extern void im_col_Lab2XYZ(
float, float, float,
float *, float *, float * );
}
#endif /*IM_VIMAGE_H*/

375
include/vips/VMask.h Normal file
View File

@ -0,0 +1,375 @@
/* VIPS mask class.
*
* Just like VImage, but we don't need dependency stuff. Instead, have a base
* wrapper over *MASK, derive VMaskD and VMaskI from that, and then put
* refcounting over all of them.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_VMASK_H
#define IM_VMASK_H
/* SWIG includes this file directly rather than going through vipscpp.h ... so
* we have to define these macros here as well.
*/
#ifdef SWIG
# define VIPS_NAMESPACE_START namespace vips {
# define VIPS_NAMESPACE_END }
#endif /*SWIG*/
/* Don't include these when parsing for SWIG.
*/
#ifndef SWIG
# include <cstdarg>
# include <iosfwd>
#endif /*!SWIG*/
/* Wrap pointers to these, but we don't want to import all the old C API. Just
* declare them.
*/
extern "C" {
struct im__INTMASK;
struct im__DOUBLEMASK;
}
VIPS_NAMESPACE_START
/* This first section is private. Only expose the non-P versions of these
* classes later on. Don't need to wrap then in SWIG either.
*/
#ifndef SWIG
namespace _private_detail {
union MASKUNION {
im__INTMASK *iptr;
im__DOUBLEMASK *dptr;
};
// Private wrapper over *MASK - user does not see this
class VPMask {
friend class VMask;
public:
// Track type of mask with this
enum VMaskType {
UNASSIGNED, // Not yet set
INT, // mask points to INTMASK
DOUBLE // mask points to DOUBLEMASK
};
MASKUNION data; // Mask pointer - INT or DOUBLE
VMaskType type; // Track type too, for safety
virtual ~VPMask() {};
// Duplicate
virtual VPMask *dup() const = 0;
// Projection functions to get MASK fields
virtual int xsize() const = 0;
virtual int ysize() const = 0;
virtual const char *filename() const = 0;
// Output
virtual void ostream_print( std::ostream & ) const = 0;
};
// Specialise for INTMASK
class VPIMask : public VPMask {
public:
VPIMask( int xsize, int ysize ) throw( VError );
VPIMask( int xsize, int ysize, int scale, int offset, va_list ap )
throw( VError );
VPIMask( const char * )
throw( VError );
VPIMask( im__INTMASK * );
VPIMask();
virtual ~VPIMask();
VPMask *dup() const throw( VError );
void embed( im__INTMASK * ) throw( VError );
int xsize() const throw( VError );
int ysize() const throw( VError );
int scale() const throw( VError );
int offset() const throw( VError );
const char *filename() const throw( VError );
// Output
virtual void ostream_print( std::ostream & ) const throw( VError );
// Extract start of array of ints
int *array() const;
};
// Specialise for DOUBLEMASK
class VPDMask : public VPMask {
public:
VPDMask( int xsize, int ysize ) throw( VError );
VPDMask( int xsize, int ysize,
double scale, double offset, va_list ap ) throw( VError );
VPDMask( const char * ) throw( VError );
VPDMask( im__DOUBLEMASK * );
VPDMask();
virtual ~VPDMask();
VPMask *dup() const throw( VError );
void embed( im__DOUBLEMASK * ) throw( VError );
int xsize() const throw( VError );
int ysize() const throw( VError );
double scale() const throw( VError );
double offset() const throw( VError );
const char *filename() const throw( VError );
// Output
virtual void ostream_print( std::ostream & ) const throw( VError );
// Extract start of array of doubles
double *array() const;
};
} // end of namespace _private_detail
inline std::ostream &operator<<( std::ostream &file,
const _private_detail::VPMask &msk )
{
msk.ostream_print( file );
return( file );
}
#endif /*!SWIG*/
// Wrapper over VP?Mask with ref counting
class VMask {
protected:
struct refblock {
_private_detail::VPMask *pmask; // Mask: double or int
int nrefs; // Refs to us
refblock() : pmask(0), nrefs(1) {}
virtual ~refblock() { delete pmask; }
};
refblock *ref;
// Make sure this is a private copy of pmask --- dup if nrefs != 1
void make_private();
public:
// Constructor leaves msk uninitialised
VMask() { ref = new refblock; }
// Copy constructor
VMask( const VMask &a ) { ref = a.ref; ref->nrefs++; }
// Assignment
VMask &operator=( const VMask &a );
// Destructor
virtual ~VMask();
int xsize() const throw( VError )
{ return( ref->pmask->xsize() ); }
int ysize() const throw( VError )
{ return( ref->pmask->ysize() ); }
int size() const throw( VError )
{ return( xsize() * ysize() ); }
const char *filename() const throw( VError )
{ return( ref->pmask->filename() ); }
// Extract underlying type
_private_detail::VPMask::VMaskType type() const
{ return( ref->pmask->type ); }
// Extract underlying VIPS pointer
_private_detail::MASKUNION mask() const { return( ref->pmask->data ); }
void ostream_print( std::ostream & ) const;
};
inline std::ostream &operator<<( std::ostream &file, const VMask &msk )
{
msk.ostream_print( file );
return( file );
}
// Need to forward ref these
class VDMask;
class VImage;
// Wrapper over _private_detail::VPIMask with ref counting
class VIMask : public VMask {
public:
VIMask( int xsize, int ysize )
{
ref->pmask = new _private_detail::VPIMask( xsize, ysize );
}
VIMask( int xsize, int ysize, int scale, int offset, ... )
{
va_list ap;
va_start( ap, offset );
ref->pmask = new _private_detail::VPIMask( xsize, ysize,
scale, offset, ap );
va_end( ap );
}
VIMask( const char *name )
{
ref->pmask = new _private_detail::VPIMask( name );
}
// No mask there yet
VIMask() {}
int scale()
{
return( ((_private_detail::VPIMask *)ref->pmask)->scale() );
}
int offset()
{
return( ((_private_detail::VPIMask *)ref->pmask)->offset() );
}
// Embed INTMASK in VIMask
void embed( im__INTMASK * ) throw( VError );
// Overload [] to get linear array subscript.
int &operator[]( int ) throw( VError );
// Overload () to get matrix subscript.
int &operator()( int x, int y ) throw( VError )
{ return( (*this)[x + y*xsize()] ); }
// and as a function call that SWIG can wrap
int get( int i ) throw( VError )
{ return( (*this)[i] ); }
// Type conversion: INTMASK->DOUBLEMASK
operator VDMask();
// Type conversion: INTMASK->image
operator VImage();
// VIMask build functions
static VIMask gauss( double, double ) throw( VError );
static VIMask log( double, double ) throw( VError );
// VIMask manipulation
VIMask rotate45() throw( VError );
VIMask rotate90() throw( VError );
// Arithmetic ... cast to double, and use VDMask funcs. For some
// reason, the compiler won't let us do casts to VDImage yet, so no
// inlines.
VDMask trn() throw( VError );
VDMask inv() throw( VError );
VDMask cat( VDMask ) throw( VError );
VDMask mul( VDMask ) throw( VError );
};
// Wrapper over _private_detail::VPDMask with ref counting
class VDMask : public VMask {
public:
VDMask( int xsize, int ysize )
{
ref->pmask = new _private_detail::VPDMask( xsize, ysize );
}
VDMask( int xsize, int ysize, double scale, double offset, ... )
{
va_list ap;
va_start( ap, offset );
ref->pmask = new _private_detail::VPDMask( xsize, ysize,
scale, offset, ap );
va_end( ap );
}
VDMask( const char *name )
{
ref->pmask = new _private_detail::VPDMask( name );
}
// No mask yet
VDMask() { }
// Embed DOUBLEMASK in VDMask
void embed( im__DOUBLEMASK * ) throw( VError );
double scale() throw( VError )
{
return( ((_private_detail::VPDMask *)ref->pmask)->scale() );
}
double offset() throw( VError )
{
return( ((_private_detail::VPDMask *)ref->pmask)->offset() );
}
// Overload [] to get linear array subscript.
double &operator[]( int ) throw( VError );
// Overload () to get matrix subscript.
double &operator()( int x, int y ) throw( VError )
{ return( (*this)[x + y*xsize()] ); }
// and as a function call that SWIG can wrap
double get( int i ) throw( VError )
{ return( (*this)[i] ); }
// Type conversion: double->int
operator VIMask();
// Type conversion: DOUBLEMASK->image
operator VImage() throw( VError );
// VDMask build functions
static VDMask gauss( double, double ) throw( VError );
static VDMask log( double, double ) throw( VError );
// VDMask manipulation
VDMask rotate45() throw( VError );
VDMask rotate90() throw( VError );
// Scale to intmask
VIMask scalei() throw( VError );
// Simple arithmetic
VDMask trn() throw( VError );
VDMask inv() throw( VError );
VDMask cat( VDMask ) throw( VError );
VDMask mul( VDMask ) throw( VError );
};
VIPS_NAMESPACE_END
#endif /*IM_VMASK_H*/

234
include/vips/colour.h Normal file
View File

@ -0,0 +1,234 @@
/* Definitions for VIPS colour package.
*
* J.Cupitt, 8/4/93
* 15/7/96 JC
* - C++ stuff added
* 20/2/98 JC
* - new display calibration added
* 26/9/05
* - added IM_ prefix to colour temps
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_COLOUR_H
#define IM_COLOUR_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#include <vips/util.h>
/* Convert degrees->rads and vice-versa.
*/
#define IM_RAD( r ) (((r) / 360.0) * 2.0 * IM_PI)
#define IM_DEG( a ) (((a) / (2.0 * IM_PI)) * 360.0)
/* Areas under curves for Dxx. 2 degree observer.
*/
#define IM_D93_X0 (89.7400)
#define IM_D93_Y0 (100.0)
#define IM_D93_Z0 (130.7700)
#define IM_D75_X0 (94.9682)
#define IM_D75_Y0 (100.0)
#define IM_D75_Z0 (122.5710)
/* D65 temp 6504.
*/
#define IM_D65_X0 (95.0470)
#define IM_D65_Y0 (100.0)
#define IM_D65_Z0 (108.8827)
#define IM_D55_X0 (95.6831)
#define IM_D55_Y0 (100.0)
#define IM_D55_Z0 (92.0871)
#define IM_D50_X0 (96.4250)
#define IM_D50_Y0 (100.0)
#define IM_D50_Z0 (82.4680)
/* A temp 2856k.
*/
#define IM_A_X0 (109.8503)
#define IM_A_Y0 (100.0)
#define IM_A_Z0 (35.5849)
/* B temp 4874k.
*/
#define IM_B_X0 (99.0720)
#define IM_B_Y0 (100.0)
#define IM_B_Z0 (85.2230)
/* C temp 6774k.
*/
#define IM_C_X0 (98.0700)
#define IM_C_Y0 (100.0)
#define IM_C_Z0 (118.2300)
#define IM_E_X0 (100.0)
#define IM_E_Y0 (100.0)
#define IM_E_Z0 (100.0)
#define IM_D3250_X0 (105.6590)
#define IM_D3250_Y0 (100.0)
#define IM_D3250_Z0 (45.8501)
/* Two kinds of display. A DISP_BARCO does gamma correction etc etc for us and
* needs only a colour space transform, a DISP_DUMB is an ordinary display and
* needs a full range of corrections.
*/
enum im_col_disp_type {
DISP_BARCO = 0,
DISP_DUMB
};
/* Structure for holding information about a display device. See the BARCO
* papers for details on the fields.
*/
struct im_col_display {
char *d_name; /* Display name */
enum im_col_disp_type d_type; /* Display type */
float d_mat[3][3]; /* XYZ -> luminance matrix */
float d_YCW; /* Luminosity of reference white */
float d_xCW; /* x, y for reference white */
float d_yCW;
float d_YCR; /* Light o/p for reference white */
float d_YCG;
float d_YCB;
int d_Vrwr; /* Pixel values for ref. white */
int d_Vrwg;
int d_Vrwb;
float d_Y0R; /* Residual light for black pixel */
float d_Y0G;
float d_Y0B;
float d_gammaR; /* Gamma values for the three guns */
float d_gammaG;
float d_gammaB;
float d_B; /* 'Background' (like brightness) */
float d_P; /* 'Picture' (like contrast) */
};
/* Structure for holding the lookup tables for XYZ<=>rgb conversion.
* Also holds the luminance to XYZ matrix and the inverse one.
*/
struct im_col_tab_disp {
float t_Yr2r[1501]; /* Conversion of Yr to r */
float t_Yg2g[1501]; /* Conversion of Yg to g */
float t_Yb2b[1501]; /* Conversion of Yb to b */
float t_r2Yr[1501]; /* Conversion of r to Yr */
float t_g2Yg[1501]; /* Conversion of g to Yg */
float t_b2Yb[1501]; /* Conversion of b to Yb */
float mat_XYZ2lum[3][3]; /* XYZ to Yr, Yg, Yb matrix */
float mat_lum2XYZ[3][3]; /* Yr, Yg, Yb to XYZ matrix */
float rstep, gstep, bstep;
float ristep, gistep, bistep;
};
/* Colour loading and conversion functions.
*/
void im_col_ab2Ch( float a, float b, float *C, float *h );
void im_col_LCh2ab( float L, float C, float h, float *a, float *b );
void im_col_XYZ2Lab( float X, float Y, float Z, float *L, float *a, float *b );
void im_col_Lab2XYZ( float L, float a, float b, float *X, float *Y, float *Z );
float im_col_pythagoras( float L1, float a1, float b1,
float L2, float a2, float b2 );
struct im_col_tab_disp *im_col_make_tables_RGB(
IMAGE *im,
struct im_col_display *d );
int im_col_rgb2XYZ( struct im_col_display *d,
struct im_col_tab_disp *table,
int r, int g, int b,
float *X, float *Y, float *Z );
int im_col_XYZ2rgb(
struct im_col_display *d, struct im_col_tab_disp *table,
float X, float Y, float Z,
int *r_ret, int *g_ret, int *b_ret,
int *or_ret );
float im_col_L2Lucs( float L );
float im_col_Lucs2L( float Lucs );
float im_col_C2Cucs( float C );
float im_col_Cucs2C( float Cucs );
float im_col_Ch2hucs( float C, float h );
float im_col_Chucs2h( float C, float hucs );
double im_col_ab2h( double a, double b );
int im_ICC2display( char *filename, struct im_col_display *dpy );
int im_XYZ2disp( IMAGE *, IMAGE *, struct im_col_display * );
int im_Lab2disp( IMAGE *, IMAGE *, struct im_col_display * );
int im_LabQ2disp( IMAGE *, IMAGE *, struct im_col_display * );
int im_disp2XYZ( IMAGE *, IMAGE *, struct im_col_display * );
int im_disp2Lab( IMAGE *, IMAGE *, struct im_col_display * );
void *im_LabQ2disp_build_table( IMAGE *out, struct im_col_display *d );
int im_LabQ2disp_table( IMAGE *in, IMAGE *out, void *table );
int im_dE_fromdisp( IMAGE *, IMAGE *, IMAGE *, struct im_col_display * );
int im_dECMC_fromdisp( IMAGE *, IMAGE *, IMAGE *, struct im_col_display * );
int im_dE00_fromLab( IMAGE *, IMAGE *, IMAGE * );
/* Colour display values and arrays
&im_col_screen_white, index 0
&im_col_SPARC_white, index 1
&im_col_D65_white, index 2
&im_col_barco_white, index 3
&im_col_mitsubishi, index 4
&im_col_relative, index 5
&ultra2, index 6
&srgb_profile, index 7
*/
struct im_col_display *im_col_displays( int );
struct im_col_display *im_col_display_name( const char * );
/* Render intents for icc wrappers.
*/
#define IM_INTENT_PERCEPTUAL (0)
#define IM_INTENT_RELATIVE_COLORIMETRIC (1)
#define IM_INTENT_SATURATION (2)
#define IM_INTENT_ABSOLUTE_COLORIMETRIC (3)
int im_icc_present( void );
int im_icc_transform( IMAGE *in, IMAGE *out,
const char *input_profile_filename,
const char *output_profile_filename,
int intent );
int im_icc_import( IMAGE *in, IMAGE *out,
const char *input_profile_filename, int intent );
int im_icc_import_embedded( IMAGE *in, IMAGE *out, int intent );
int im_icc_export( IMAGE *in, IMAGE *out,
const char *output_profile_filename, int intent );
int im_icc_export_depth( IMAGE *in, IMAGE *out, int depth,
const char *output_profile_filename, int intent );
int im_icc_ac2rc( IMAGE *in, IMAGE *out, const char *profile_filename );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_COLOUR_H*/

50
include/vips/debug.h Normal file
View File

@ -0,0 +1,50 @@
/* Support for debug.c in iofuncs.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_DEBUG_H
#define IM_DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* All open image descriptors ... see im_init() and im_close().
*/
extern GSList *im__open_images;
/* Print one line for each descriptor, complete dump for one descriptor.
*/
void im__print_one( int n );
void im__print_all( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /* IM_DEBUG_H */

269
include/vips/dispatch.h Normal file
View File

@ -0,0 +1,269 @@
/* VIPS function dispatch.
*
* J. Cupitt, 8/4/93.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_DISPATCH_H
#define IM_DISPATCH_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#include <vips/vips.h>
#include <vips/util.h>
/* Type names. You may define your own, but if you use one of these, then
* you should use the built-in VIPS type converters.
*/
#define IM_TYPE_IMAGEVEC "imagevec" /* im_object is ptr to IMAGE[] */
#define IM_TYPE_DOUBLEVEC "doublevec" /* im_object is ptr to double[] */
#define IM_TYPE_INTVEC "intvec" /* im_object is ptr to int[] */
#define IM_TYPE_DOUBLE "double" /* im_object is ptr to double */
#define IM_TYPE_INT "integer" /* 32-bit integer */
#define IM_TYPE_COMPLEX "complex" /* Pair of doubles */
#define IM_TYPE_STRING "string" /* Zero-terminated char array */
#define IM_TYPE_IMASK "intmask" /* Integer mask type */
#define IM_TYPE_DMASK "doublemask" /* Double mask type */
#define IM_TYPE_IMAGE "image" /* IMAGE descriptor */
#define IM_TYPE_DISPLAY "display" /* Display descriptor */
#define IM_TYPE_GVALUE "gvalue" /* GValue wrapper */
typedef char *im_arg_type; /* Type of argument id */
/* Internal representation of an argument to an image processing function.
*/
typedef void *im_object;
/* These bits are ored together to make the flags in a type descriptor.
*
* IM_TYPE_OUTPUT: set to indicate output, otherwise input.
*
* IM_TYPE_ARG: Two ways of making an im_object --- with and without a
* command-line string to help you along. Arguments with a string are thing
* like IMAGE descriptors, which require a filename to initialise.
* Arguments without are things like output numbers, where making the object
* simply involves allocating storage.
*/
typedef enum {
IM_TYPE_NONE = 0, /* No flags */
IM_TYPE_OUTPUT = 0x1, /* Output/input object */
IM_TYPE_ARG = 0x2 /* Uses a str arg in construction */
} im_type_flags;
/* Initialise and destroy objects. The "str" argument to the init function
* will not be supplied if this is not an ARG type.
*/
typedef int (*im_init_obj_fn)( im_object *obj, char *str );
typedef int (*im_dest_obj_fn)( im_object obj );
/* Describe a VIPS type.
*/
typedef struct {
im_arg_type type; /* Type of argument */
int size; /* sizeof( im_object repres. ) */
im_type_flags flags; /* Flags */
im_init_obj_fn init; /* Operation functions */
im_dest_obj_fn dest;
} im_type_desc;
/* Success on an argument. This is called if the image processing function
* succeeds and should be used to (for example) print output.
*/
typedef int (*im_print_obj_fn)( im_object obj );
/* Describe a VIPS command argument.
*/
typedef struct {
char *name; /* eg. "width" */
im_type_desc *desc; /* Type description */
im_print_obj_fn print; /* Print some output objects */
} im_arg_desc;
/* Type of VIPS dispatch funtion.
*/
typedef int (*im_dispatch_fn)( im_object *argv );
/* Maximum size of arg table.
*/
#define IM_MAX_ARGS (1000)
/* Flags for functions. These are for information only, and more may be
* added.
*/
typedef enum {
IM_FN_NONE = 0, /* No flags set */
IM_FN_PIO = 0x1, /* Is a partial function */
IM_FN_TRANSFORM = 0x2, /* Performs coordinate transformations */
IM_FN_PTOP = 0x4, /* Point-to-point ... can be done with a LUT */
IM_FN_NOCACHE = 0x8 /* Result should not be cached */
} im_fn_flags;
/* Describe a VIPS function.
*/
typedef struct {
char *name; /* eg "im_invert" */
char *desc; /* Description - eg "photographic negative" */
im_fn_flags flags; /* Flags for this function */
im_dispatch_fn disp; /* Dispatch */
int argc; /* Number of args */
im_arg_desc *argv; /* Arg table */
} im_function;
/* A set of VIPS functions forming a package.
*/
typedef struct {
char *name; /* Package name (eg "arithmetic") */
int nfuncs; /* Number of functions in package */
im_function **table; /* Array of function descriptors */
} im_package;
/* Externs for dispatch.
*/
/* Struct for mask IO to a file.
*/
typedef struct {
char *name; /* Command-line name in */
void *mask; /* Mask --- DOUBLE or INT */
} im_mask_object;
/* Struct for doublevec IO
*/
typedef struct {
int n; /* Vector length */
double *vec; /* Vector */
} im_doublevec_object;
/* Struct for intvec IO
*/
typedef struct {
int n; /* Vector length */
int *vec; /* Vector */
} im_intvec_object;
/* Struct for imagevec IO
*/
typedef struct {
int n; /* Vector length */
IMAGE **vec; /* Vector */
} im_imagevec_object;
/* Built-in VIPS types.
*/
extern im_type_desc im__input_imagevec;
extern im_type_desc im__input_image;
extern im_type_desc im__output_image;
extern im_type_desc im__rw_image;
extern im_type_desc im__input_doublevec;
extern im_type_desc im__input_intvec;
extern im_type_desc im__input_double;
extern im_type_desc im__output_double;
extern im_type_desc im__input_int;
extern im_type_desc im__output_int;
extern im_type_desc im__input_string;
extern im_type_desc im__output_string;
extern im_type_desc im__output_complex;
extern im_type_desc im__input_dmask;
extern im_type_desc im__output_dmask;
extern im_type_desc im__output_dmask_screen;
extern im_type_desc im__input_display;
extern im_type_desc im__output_display;
extern im_type_desc im__input_imask;
extern im_type_desc im__output_imask;
extern im_type_desc im__input_gvalue;
/* VIPS print functions.
*/
int im__iprint( im_object obj ); /* int */
int im__dprint( im_object obj ); /* double */
int im__cprint( im_object obj ); /* complex */
int im__sprint( im_object obj ); /* string */
int im__displayprint( im_object obj ); /* im_col_display */
int im__dmsprint( im_object obj ); /* DOUBLEMASK as stats */
int im__gprint( im_object obj ); /* GValue */
/* Macros for convenient creation.
*/
#define IM_INPUT_IMAGEVEC( S ) { S, &im__input_imagevec, NULL }
#define IM_INPUT_IMAGE( S ) { S, &im__input_image, NULL }
#define IM_OUTPUT_IMAGE( S ) { S, &im__output_image, NULL }
#define IM_RW_IMAGE( S ) { S, &im__rw_image, NULL }
#define IM_INPUT_DOUBLE( S ) { S, &im__input_double, NULL }
#define IM_INPUT_DOUBLEVEC( S ) { S, &im__input_doublevec, NULL }
#define IM_INPUT_INTVEC( S ) { S, &im__input_intvec, NULL }
#define IM_OUTPUT_DOUBLE( S ) { S, &im__output_double, im__dprint }
#define IM_INPUT_INT( S ) { S, &im__input_int, NULL }
#define IM_OUTPUT_INT( S ) { S, &im__output_int, im__iprint }
#define IM_INPUT_STRING( S ) { S, &im__input_string, NULL }
#define IM_OUTPUT_STRING( S ) { S, &im__output_string, im__sprint }
#define IM_INPUT_DISPLAY( S ) { S, &im__input_display, NULL }
#define IM_OUTPUT_DISPLAY( S ) { S, &im__output_display, im__displayprint }
#define IM_OUTPUT_COMPLEX( S ) { S, &im__output_complex, im__cprint }
#define IM_INPUT_DMASK( S ) { S, &im__input_dmask, NULL }
#define IM_OUTPUT_DMASK( S ) { S, &im__output_dmask, NULL }
#define IM_OUTPUT_DMASK_STATS( S ) { S, &im__output_dmask_screen, im__dmsprint }
#define IM_INPUT_IMASK( S ) { S, &im__input_imask, NULL }
#define IM_OUTPUT_IMASK( S ) { S, &im__output_imask, NULL }
#define IM_INPUT_GVALUE( S ) { S, &im__input_gvalue, NULL }
#define IM_OUTPUT_GVALUE( S ) { S, &im__output_gvalue, im__gprint }
/* Add a plug-in package.
*/
im_package *im_load_plugin( const char *name );
int im_load_plugins( const char *fmt, ... )
__attribute__((format(printf, 1, 2)));
/* Close all plug-ins.
*/
int im_close_plugins( void );
/* Loop over all loaded packages.
*/
void *im_map_packages( VSListMap2Fn fn, void *a );
/* Convenience functions for finding packages, functions, etc.
*/
im_function *im_find_function( const char *name );
im_package *im_find_package( const char *name );
im_package *im_package_of_function( const char *name );
/* Allocate space for, and free im_object argument lists.
*/
int im_free_vargv( im_function *fn, im_object *vargv );
int im_allocate_vargv( im_function *fn, im_object *vargv );
/* Run a VIPS command by name.
*/
int im_run_command( char *name, int argc, char **argv );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_DISPATCH_H*/

86
include/vips/fmask.h Normal file
View File

@ -0,0 +1,86 @@
/* @(#) Typical filter function
* va_list is filter parameters
* lowpass highpass filters
* flag = 0 -> idealhpf, parameters: frequency cutoff
* flag = 1 -> ideallpf, parameters: frequency cutoff
* flag = 2 -> buthpf, parameters: order, frequency cutoff, amplitude cutoff
* flag = 3 -> butlpf, parameters: order, frequency cutoff, amplitude cutoff
* flag = 4 -> gaussianlpf, parameters: frequency cutoff, amplitude cutoff
* flag = 5 -> gaussianhpf, parameters: frequency cutoff, amplitude cutoff
* ring pass ring reject filters
* flag = 6 -> idealrpf, parameters: frequency cutoff, width
* flag = 7 -> idealrrf, parameters: frequency cutoff, width
* flag = 8 -> butrpf, parameters: order, freq cutoff, width, ampl cutoff
* flag = 9 -> butrrf, parameters: order, freq cutoff, width, ampl cutoff
* flag = 10 -> gaussianrpf, parameters: frequency cutoff, width, ampl cutoff
* flag = 11 -> gaussianrrf, parameters: frequency cutoff, width, ampl cutoff
* bandpass bandreject filters
* flag = 12 -> idealbpf, parameters: center frequency, 2*radius
* flag = 13 -> idealbrf, parameters: centre frequency, 2*radius
* flag = 14 -> butbpf, parameters: order, frequency, 2*radius, ampl cutoff
* flag = 15 -> butbrf, parameters: order, frequency, 2*radius, ampl cutoff
* flag = 16 -> gaussianbpf, parameters: frequency cutoff, width, ampl cutoff
* flag = 17 -> gaussianbrf, parameters: frequency cutoff, width, ampl cutoff
* fractal filters (for filtering gaussian noises only)
* flag = 18 -> fractal, parameters: fractal dimension
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_FMASK_H
#define IM_FMASK_H
typedef enum mask_type {
MASK_IDEAL_HIGHPASS = 0,
MASK_IDEAL_LOWPASS = 1,
MASK_BUTTERWORTH_HIGHPASS = 2,
MASK_BUTTERWORTH_LOWPASS = 3,
MASK_GAUSS_HIGHPASS = 4,
MASK_GAUSS_LOWPASS = 5,
MASK_IDEAL_RINGPASS = 6,
MASK_IDEAL_RINGREJECT = 7,
MASK_BUTTERWORTH_RINGPASS = 8,
MASK_BUTTERWORTH_RINGREJECT = 9,
MASK_GAUSS_RINGPASS = 10,
MASK_GAUSS_RINGREJECT = 11,
MASK_IDEAL_BANDPASS = 12,
MASK_IDEAL_BANDREJECT = 13,
MASK_BUTTERWORTH_BANDPASS = 14,
MASK_BUTTERWORTH_BANDREJECT = 15,
MASK_GAUSS_BANDPASS = 16,
MASK_GAUSS_BANDREJECT = 17,
MASK_FRACTAL_FLT = 18
} MaskType;
int im_flt_image_freq( IMAGE *in, IMAGE *out, MaskType flag, ... );
int im_create_fmask( IMAGE *out, int xsize, int ysize, MaskType flag, ... );
int im__fmaskcir( IMAGE *out, MaskType flag, va_list ap );
#endif /*IM_FMASK_H*/

59
include/vips/history.h Normal file
View File

@ -0,0 +1,59 @@
/* @(#) Useful macros for appending one line in the History field of the
* @(#) output image descriptor when a function is called
* @(#) The main program should use im_updatehist()
* @(#) The added line corresponds to the command relevant to the function
* @(#) for instance
* @(#) for the function: im_add(in1, in2, out) the following lines of code can
* @(#) be used to add a line of history in the Hist member
* @(#) of the out image descriptor
* @(#) ....
* @(#) IMAGE *in1, *in2, *out;
* @(#) ....
* @(#) if ( im_add(in1, in2, out) == -1 ) return(-1);
* @(#) if ( IM_ADD(in1, in2, out) == -1 ) return(-1);
* @(#) ....
* @(#)
* @(#) The first function will add the two images in1 and in2,
* @(#) whereas the second call will append
* @(#) at the history descriptor of out the line:
* @(#) add infile outfile # date
* @(#) where infile is in.filename and outfile is out.filename
* @(#) The history line has been prepared in such a way that the first
* @(#) argument is the UNIX command which corresponds to the function
* @(#) As a general rule, all functions in im_funcs directory which
* @(#) have a correponding command in src directory are listed here
* @(#)
* @(#) Since the macros presented in this file correspond to the function
* @(#) im_histlin() the returned value is 0 on success and -1 on error.
* @(#)
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
/* Made obsolete by the function database stuff ... just here in case anyone
* still includes it.
*/

121
include/vips/internal.h Normal file
View File

@ -0,0 +1,121 @@
/* Prototypes for internal VIPS functions.
*
* 11/9/06
* - cut from proto.h
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_INTERNAL_H
#define IM_INTERNAL_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
typedef int (*im__fftproc_fn)( IMAGE *, IMAGE *, IMAGE * );
/* iofuncs
*/
void im__read_4byte( int msb_first, unsigned char *to, unsigned char **from );
void im__read_2byte( int msb_first, unsigned char *to, unsigned char **from );
void im__write_4byte( unsigned char **to, unsigned char *from );
void im__write_2byte( unsigned char **to, unsigned char *from );
int im__read_header_bytes( IMAGE *im, unsigned char *from );
int im__write_header_bytes( IMAGE *im, unsigned char *to );
int im__has_extension_block( IMAGE *im );
void *im__read_extension_block( IMAGE *im, int *size );
int im__readhist( IMAGE *image );
int im__write_extension_block( IMAGE *im, void *buf, int size );
int im__writehist( IMAGE *image );
extern int im__read_test;
extern int im__mmap_limit;
extern GMutex *im__global_lock;
IMAGE *im__convert_saveable( IMAGE *in, gboolean allow_alpha );
void im__link_make( IMAGE *parent, IMAGE *child );
void im__link_break_all( IMAGE *im );
void *im__link_map( IMAGE *im, VSListMap2Fn fn, void *a, void *b );
GValue *im__gvalue_ref_string_new( const char *text );
void im__gslist_gvalue_free( GSList *list );
GSList *im__gslist_gvalue_copy( const GSList *list );
GSList *im__gslist_gvalue_merge( GSList *a, const GSList *b );
char *im__gslist_gvalue_get( const GSList *list );
void im__buffer_init( void );
int im__cast_and_call();
int im__read_header( IMAGE *image );
int im__test_kill( IMAGE *im );
void *im__mmap( int fd, int writeable, size_t length, gint64 offset );
int im__munmap( void *start, size_t length );
int im__write( int, const void *, size_t );
int im__open_image_file( const char *filename );
gint64 im__image_pixel_length( IMAGE *im );
void im__change_suffix( const char *name, char *out, int mx,
const char *new_suff, const char **olds, int nolds );
void im__print_all( void );
void im__print_one( int );
int im__trigger_callbacks( GSList *cblist );
int im__close( IMAGE * );
int im__handle_eval( IMAGE *im, int w, int h );
int im__create_int_luts( int *, int, int **, int **, int * );
int im__create_double_luts( double *, int, double **, double **, int * );
int im__fft_sp( float *rvec, float *ivec, int logrows, int logcols );
int im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn );
int im__mean_std_double_buffer( double *buffer, int size,
double *pmean, double *pstd );
int im__mean_std_int_buffer( int *buffer, int size,
double *pmean, double *pstd );
int im__find_lroverlap( IMAGE *ref_in, IMAGE *sec_in, IMAGE *out,
int bandno_in,
int xref, int yref, int xsec, int ysec,
int halfcorrelation, int halfarea,
int *dx0, int *dy0,
double *scale1, double *angle1, double *dx1, double *dy1 );
int im__find_tboverlap( IMAGE *ref_in, IMAGE *sec_in, IMAGE *out,
int bandno_in,
int xref, int yref, int xsec, int ysec,
int halfcorrelation, int halfarea,
int *dx0, int *dy0,
double *scale1, double *angle1, double *dx1, double *dy1 );
int im__find_best_contrast( IMAGE *image,
int xpos, int ypos, int xsize, int ysize,
int xarray[], int yarray[], int cont[],
int nbest, int hcorsize );
int im__balance( IMAGE *ref, IMAGE *sec, IMAGE *out,
IMAGE **ref_out, IMAGE **sec_out, int dx, int dy, int balancetype );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_INTERNAL_H*/

44
include/vips/intl.h Normal file
View File

@ -0,0 +1,44 @@
/* i18n stuff for vips.
*/
#ifndef IM_VIPS_INTL_H
#define IM_VIPS_INTL_H
const char *im__gettext( const char *msgid );
const char *im__ngettext( const char *msgid,
const char *plural, unsigned long int n );
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) im__gettext(String)
/* ngettext may be defined as a macro if we're optimised.
*/
#ifdef ngettext
#undef ngettext
#endif /*ngettext*/
#define ngettext(String,Plural,number) im__ngettext(String,Plural,number)
#ifdef gettext_noop
#define N_(String) gettext_noop(String)
#else
#define N_(String) (String)
#endif
#else /*!ENABLE_NLS*/
#define _(String) (String)
#define N_(String) (String)
#define textdomain(String) (String)
#define gettext(String) (String)
#define dgettext(Domain,String) (String)
#define dcgettext(Domain,String,Type) (String)
#define bindtextdomain(Domain,Directory) (Domain)
#define bind_textdomain_codeset(Domain,Codeset) (Codeset)
#define ngettext(S, P, N) ((N) == 1 ? (S) : (P))
#define dngettext(D, S, P, N) ngettext(S, P, N)
#endif /* ENABLE_NLS */
#endif /* IM_VIPS_INTL_H */

107
include/vips/meta.h Normal file
View File

@ -0,0 +1,107 @@
/* Metadata API.
*/
/*
Copyright (C) 1991-2005 The National Gallery
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_META_H
#define IM_META_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* Reserved header names.
*/
#define IM_META_EXIF_NAME "exif-data"
#define IM_META_ICC_NAME "icc-profile-data"
#define IM_META_XML "xml-header"
/* Types we add for meta fields.
*/
#define IM_TYPE_SAVE_STRING (im_save_string_get_type())
GType im_save_string_get_type( void );
const char *im_save_string_get( const GValue *value );
void im_save_string_set( GValue *value, const char *str );
void im_save_string_setf( GValue *value, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
#define IM_TYPE_AREA (im_area_get_type())
GType im_area_get_type( void );
#define IM_TYPE_REF_STRING (im_ref_string_get_type())
GType im_ref_string_get_type( void );
int im_ref_string_set( GValue *value, const char *str );
const char *im_ref_string_get( const GValue *value );
size_t im_ref_string_get_length( const GValue *value );
#define IM_TYPE_BLOB (im_blob_get_type())
GType im_blob_get_type( void );
void *im_blob_get( const GValue *value, size_t *data_length );
int im_blob_set( GValue *value, im_callback_fn free_fn,
void *data, size_t length );
/* What we store in the Meta hash table. We can't just use GHashTable's
* key/value pairs, since we need to iterate over meta in Meta_traverse order.
*
* We don't refcount at this level ... large meta values are refcounted by
* their GValue implementation, see eg. MetaArea below.
*/
typedef struct _Meta {
IMAGE *im;
char *field; /* strdup() of field name */
GValue value; /* copy of value */
} Meta;
int im_meta_set( IMAGE *, const char *field, GValue * );
int im_meta_get( IMAGE *, const char *field, GValue * );
GType im_meta_get_type( IMAGE *im, const char *field );
int im_meta_set_int( IMAGE *, const char *field, int i );
int im_meta_get_int( IMAGE *, const char *field, int *i );
int im_meta_set_double( IMAGE *, const char *field, double d );
int im_meta_get_double( IMAGE *, const char *field, double *d );
int im_meta_set_area( IMAGE *, const char *field, im_callback_fn, void * );
int im_meta_get_area( IMAGE *, const char *field, void **data );
int im_meta_set_string( IMAGE *, const char *field, const char *str );
int im_meta_get_string( IMAGE *, const char *field, char **str );
int im_meta_set_blob( IMAGE *im, const char *field,
im_callback_fn free_fn, void *blob, size_t blob_length );
int im_meta_get_blob( IMAGE *im, const char *field,
void **blob, size_t *blob_length );
/* Internal.
*/
void im__meta_init_types( void );
void im__meta_destroy( IMAGE *im );
int im__meta_cp( IMAGE *, const IMAGE * );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*!IM_META_H*/

86
include/vips/mosaic.h Normal file
View File

@ -0,0 +1,86 @@
/* @(#) Local definitions used by the mosaicing program
* @(#) If MAXPOINTS change please ensure that it is still a multiple of
* @(#) AREAS or else AREAS must change as well. Initial setup is for
* @(#) MAXPOINTS = 60, AREAS = 3.
* @(#)
* Copyright: 1990, 1991 N. Dessipris
* Author: Nicos Dessipris
* Written on: 07/11/1989
* Modified on : 29/11/1989
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_MOSAIC_H
#define IM_MOSAIC_H
#define MAXPOINTS 60 /* MAXPOINTS % AREAS (in im_calcon) must be zero */
typedef struct {
char *reference; /* filename of reference */
char *secondary; /* filename of secondary */
int deltax; /* initial estimate of displacement */
int deltay; /* initial estimate of displacement */
int nopoints; /* must be multiple of AREAS and <= MAXPOINTS */
int halfcorsize; /* recommended 5 */
int halfareasize; /* recommended 8 */
/* x, y_reference and contrast found by im_calcon()
*/
int x_reference[MAXPOINTS], y_reference[MAXPOINTS];
int contrast[MAXPOINTS];
/* x, y_secondary and correlation set by im_chkpair()
*/
int x_secondary[MAXPOINTS], y_secondary[MAXPOINTS];
/* returns the corrected best correlation
* as detected in 2*halfareasize+1
* centered at point (x2, y2) and using
* correlation area 2*halfareasize+1
*/
double correlation[MAXPOINTS];
/* Coefficients calculated by im_clinear()
*/
double l_scale, l_angle, l_deltax, l_deltay;
/* used by im_clinear()
*/
double dx[MAXPOINTS], dy[MAXPOINTS];
double deviation[MAXPOINTS];
} TIE_POINTS;
int im_clinear( TIE_POINTS *points );
int im__chkpair( IMAGE *, IMAGE *, TIE_POINTS *point );
int im__initialize( TIE_POINTS *points );
int im__improve( TIE_POINTS *inpoints, TIE_POINTS *outpoints );
int im__avgdxdy( TIE_POINTS *points, int *dx, int *dy );
int im__lrcalcon( IMAGE *ref, TIE_POINTS *points );
int im__tbcalcon( IMAGE *ref, TIE_POINTS *points );
#endif /*IM_MOSAIC_H*/

749
include/vips/proto.h Normal file
View File

@ -0,0 +1,749 @@
/* @(#) Header file for Birkbeck/VIPS Image Processing Library
* Authors: N. Dessipris, K. Martinez, Birkbeck College, London.
* and J. Cupitt The National Gallery, London.
*
* Sept 94
*
* 15/7/96 JC
* - now does C++ extern stuff
* - many more protos
* 15/4/97 JC
* - protos split out here, more of them
* - still not complete tho' ...
* 8/4/99 JC
* - lots of consts added to please C++
* - and more protos added
* 11/9/06
* - internal protos cut out to help SWIG
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_PROTO_H
#define IM_PROTO_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* Need these for some protos.
*/
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <glib-object.h>
/* If we're being parsed by SWIG, remove gcc attributes.
*/
#ifdef SWIG
# ifndef __attribute__
# define __attribute__(x) /*NOTHING*/
# endif
#endif /*SWIG*/
typedef int (*im_callback_fn)( void *, void * );
typedef void *(*im_construct_fn)( void *, void *, void * );
typedef void *(*im_header_map_fn)( IMAGE *, const char *, GValue *, void * );
/* iofuncs
*/
int im_init_world( const char *argv0 );
GOptionGroup *im_get_option_group( void );
const char *im_error_buffer( void );
int im_debugim( IMAGE * );
int im_printlines( IMAGE * );
int im_header_int( IMAGE *im, const char *field, int *out );
int im_header_double( IMAGE *im, const char *field, double *out );
int im_header_string( IMAGE *im, const char *field, char **out );
GType im_header_get_type( IMAGE *im, const char *field );
int im_header_get( IMAGE *im, const char *field, GValue *value_copy );
void *im_header_map( IMAGE *im, im_header_map_fn fn, void *a );
const char *im_version_string( void );
int im_version( int flag );
const char *im_guess_prefix( const char *, const char * );
IMAGE *im_init( const char * );
IMAGE *im_openout( const char * );
int im_openin( IMAGE *image );
int im_openinrw( IMAGE *image );
IMAGE *im_setbuf( const char * );
IMAGE *im_partial( const char * );
IMAGE *im_binfile( const char *, int, int, int, int );
IMAGE *im_image( void *, int, int, int, int );
int im_mapfile( IMAGE * );
int im_mapfilerw( IMAGE * );
int im_remapfilerw( IMAGE *image );
IMAGE *im_open( const char *, const char * );
IMAGE *im_open_header( const char * );
int im_image_sanity( IMAGE * );
void *im_malloc( IMAGE *im, size_t sz );
int im_free( void * );
int im_close( IMAGE * );
int im_rwcheck( IMAGE * );
int im_iocheck( IMAGE *, IMAGE * );
int im_incheck( IMAGE * );
int im_outcheck( IMAGE * );
int im_piocheck( IMAGE *, IMAGE * );
int im_pincheck( IMAGE * );
int im_poutcheck( IMAGE * );
int im_cp_desc( IMAGE *, IMAGE * );
int im_cp_descv( IMAGE *out, IMAGE *in1, ... )
__attribute__((sentinel));
int im_cp_desc_array( IMAGE *out, IMAGE *in[] );
int im_setupout( IMAGE * );
int im_writeline( int, IMAGE *, PEL * );
int im_isuint( IMAGE * );
int im_isint( IMAGE * );
int im_isfloat( IMAGE * );
int im_isscalar( IMAGE * );
int im_iscomplex( IMAGE * );
int im_isfile( IMAGE * );
int im_ispartial( IMAGE * );
int im_isMSBfirst( IMAGE * );
int im_amiMSBfirst( void );
int im_ispoweroftwo( int );
int im_existsf( const char *name, ... )
__attribute__((format(printf, 1, 2)));
int im_istiff( const char * );
int im_istifftiled( const char * );
int im_istiffpyramid( const char * );
int im_isjpeg( const char * );
int im_isvips( const char * );
int im_isexr( const char * );
int im_isppm( const char * );
int im_ispng( const char * );
int im_ismagick( const char * );
int im_isanalyze( const char *filename );
int im_add_close_callback( IMAGE *, im_callback_fn, void *, void * );
int im_add_eval_callback( IMAGE *, im_callback_fn, void *, void * );
int im_add_evalend_callback( IMAGE *, im_callback_fn, void *, void * );
void error_exit( const char *, ... )
__attribute__((noreturn, format(printf, 1, 2)));
void im_error_clear( void );
void im_verror( const char *domain, const char *fmt, va_list ap );
void im_error( const char *domain, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
void im_error_system( int err, const char *domain, const char *fmt, ... )
__attribute__((format(printf, 3, 4)));
void im_warn( const char *domain, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
void im_diag( const char *domain, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
int im_bits_of_fmt( int );
const char *im_Type2char( int );
const char *im_BandFmt2char( int );
const char *im_Coding2char( int );
const char *im_Compression2char( int );
const char *im_dhint2char( im_demand_type );
const char *im_dtype2char( im_desc_type );
int im_char2Type( const char * );
int im_char2BandFmt( const char * );
int im_char2Coding( const char * );
int im_char2Compression( const char * );
int im_unmapfile( IMAGE * );
void im_printdesc( IMAGE * );
void im_initdesc( IMAGE *,
int, int, int, int, int, int, int, float, float,
int, int );
int im_histlin( IMAGE *image, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
int im_updatehist( IMAGE *out, const char *name, int argc, char *argv[] );
const char *im_history_get( IMAGE *im );
int im_render( IMAGE *in, IMAGE *out, IMAGE *mask,
int width, int height, int max,
void (*notify)( IMAGE *, Rect *, void * ), void *client );
int im_render_fade( IMAGE *in, IMAGE *out, IMAGE *mask,
int width, int height, int max,
int fps, int steps,
int priority,
void (*notify)( IMAGE *, Rect *, void * ), void *client );
int im_cache( IMAGE *in, IMAGE *out, int width, int height, int max );
/* morphology
*/
int im_dilate( IMAGE *in, IMAGE *out, INTMASK *m );
int im_dilate_raw( IMAGE *in, IMAGE *out, INTMASK *m );
int im_erode( IMAGE *in, IMAGE *out, INTMASK *m );
int im_erode_raw( IMAGE *in, IMAGE *out, INTMASK *m );
int im_cntlines( IMAGE *im, double *nolines, int flag );
int im_profile( IMAGE *in, IMAGE *out, int dir );
/* convolution
*/
void im_copy_dmask_matrix( DOUBLEMASK *mask, double **matrix );
void im_copy_matrix_dmask( double **matrix, DOUBLEMASK *mask );
INTMASK *im_create_imask( const char *, int, int );
INTMASK *im_create_imaskv( const char *, int, int, ... );
DOUBLEMASK *im_create_dmask( const char *, int, int );
DOUBLEMASK *im_create_dmaskv( const char *, int, int, ... );
INTMASK *im_dup_imask( INTMASK *, const char * );
DOUBLEMASK *im_dup_dmask( DOUBLEMASK *, const char * );
int im_free_imask( INTMASK * );
int im_free_dmask( DOUBLEMASK * );
INTMASK *im_read_imask( const char * );
DOUBLEMASK *im_read_dmask( const char * );
void im_print_imask( INTMASK * );
void im_print_dmask( DOUBLEMASK * );
int im_write_imask( INTMASK * );
int im_write_dmask( DOUBLEMASK * );
int im_write_imask_name( INTMASK *, const char * );
int im_write_dmask_name( DOUBLEMASK *, const char * );
INTMASK *im_scale_dmask( DOUBLEMASK *, const char * );
void im_norm_dmask( DOUBLEMASK *mask );
int *im_offsets45( int );
int *im_offsets90( int );
INTMASK *im_rotate_imask90( INTMASK *, const char * );
INTMASK *im_rotate_imask45( INTMASK *, const char * );
DOUBLEMASK *im_rotate_dmask90( DOUBLEMASK *, const char * );
DOUBLEMASK *im_rotate_dmask45( DOUBLEMASK *, const char * );
INTMASK *im_log_imask( const char *, double, double );
DOUBLEMASK *im_log_dmask( const char *, double, double );
INTMASK *im_gauss_imask( const char *, double, double );
DOUBLEMASK *im_gauss_dmask( const char *, double, double );
int im_rank( IMAGE *, IMAGE *, int, int, int );
int im_sharpen( IMAGE *, IMAGE *, int, double, double, double, double, double );
int im_addgnoise( IMAGE *, IMAGE *, double );
int im_gaussnoise( IMAGE *, int, int, double, double );
int im_zerox( IMAGE *, IMAGE *, int );
int im_maxvalue( IMAGE **in, IMAGE *out, int n );
int im_rank_image( IMAGE **in, IMAGE *out, int n, int index );
int im_compass( IMAGE *, IMAGE *, INTMASK * );
int im_gradient( IMAGE *, IMAGE *, INTMASK * );
int im_lindetect( IMAGE *, IMAGE *, INTMASK * );
int im_conv( IMAGE *, IMAGE *, INTMASK * );
int im_conv_raw( IMAGE *, IMAGE *, INTMASK * );
int im_convf( IMAGE *, IMAGE *, DOUBLEMASK * );
int im_convf_raw( IMAGE *, IMAGE *, DOUBLEMASK * );
int im_convsep( IMAGE *, IMAGE *, INTMASK * );
int im_convsep_raw( IMAGE *, IMAGE *, INTMASK * );
int im_convsepf( IMAGE *, IMAGE *, DOUBLEMASK * );
int im_convsepf_raw( IMAGE *, IMAGE *, DOUBLEMASK * );
int im_convsub( IMAGE *, IMAGE *, INTMASK *, int, int );
int im_grad_x( IMAGE *in, IMAGE *out );
int im_grad_y( IMAGE *in, IMAGE *out );
int im_fastcor( IMAGE *, IMAGE *, IMAGE * );
int im_fastcor_raw( IMAGE *, IMAGE *, IMAGE * );
int im_spcor( IMAGE *, IMAGE *, IMAGE * );
int im_spcor_raw( IMAGE *, IMAGE *, IMAGE * );
int im_spcor2( IMAGE *, IMAGE *, IMAGE * );
int im_spcor2_raw( IMAGE *, IMAGE *, IMAGE * );
int im_gradcor( IMAGE *, IMAGE *, IMAGE * );
int im_gradcor_raw( IMAGE *, IMAGE *, IMAGE * );
int im_contrast_surface( IMAGE *, IMAGE *, int, int );
int im_contrast_surface_raw( IMAGE *, IMAGE *, int, int );
int im_resize_linear( IMAGE *, IMAGE *, int, int );
int im_mpercent( IMAGE *, double, int * );
int im_shrink( IMAGE *, IMAGE *, double, double );
int im_embed( IMAGE *, IMAGE *, int, int, int, int, int );
int im_stretch3( IMAGE *in, IMAGE *out, double dx, double dy );
int im_rank_raw( IMAGE *in, IMAGE *out, int xsize, int ysize, int n );
/* freq_filt
*/
int im_fractsurf( IMAGE *out, int size, double frd );
int im_freqflt( IMAGE *, IMAGE *, IMAGE * );
int im_disp_ps( IMAGE *, IMAGE * );
int im_rotquad( IMAGE *, IMAGE * );
int im_fwfft( IMAGE *, IMAGE * );
int im_invfft( IMAGE *, IMAGE * );
int im_invfftr( IMAGE *, IMAGE * );
/* arithmetic
*/
DOUBLEMASK *im_measure( IMAGE *, IMAGE_BOX *,
int, int, int *, int, const char * );
DOUBLEMASK *im_stats( IMAGE * );
int im_abs( IMAGE *in, IMAGE *out );
int im_max( IMAGE *in, double *out );
int im_min( IMAGE *in, double *out );
int im_avg( IMAGE *in, double *out );
int im_deviate( IMAGE *in, double *out );
int im_maxpos( IMAGE *in, int *xpos, int *ypos, double *out );
int im_minpos( IMAGE *in, int *xpos, int *ypos, double *out );
int im_maxpos_avg( IMAGE *im, double *xpos, double *ypos, double *out );
int im_maxpos_vec( IMAGE *im, int *xpos, int *ypos, double *maxima, int n );
int im_minpos_vec( IMAGE *im, int *xpos, int *ypos, double *minima, int n );
int im_add( IMAGE *, IMAGE *, IMAGE * );
int im_subtract( IMAGE *, IMAGE *, IMAGE * );
int im_invert( IMAGE *, IMAGE * );
int im_linreg( IMAGE **ins, IMAGE *out, double *xs );
int im_lintra( double, IMAGE *, double, IMAGE * );
int im_lintra_vec( int n, double *a, IMAGE *in, double *b, IMAGE *out );
int im_multiply( IMAGE *, IMAGE *, IMAGE * );
int im_divide( IMAGE *, IMAGE *, IMAGE * );
int im_point_bilinear( IMAGE *im, double x, double y, int band, double *val );
int im_powtra( IMAGE *, IMAGE *, double );
int im_powtra_vec( IMAGE *in, IMAGE *out, int n, double *e );
int im_exptra( IMAGE *, IMAGE * );
int im_exp10tra( IMAGE *, IMAGE * );
int im_expntra( IMAGE *, IMAGE *, double );
int im_expntra_vec( IMAGE *in, IMAGE *out, int n, double *e );
int im_logtra( IMAGE *, IMAGE * );
int im_log10tra( IMAGE *, IMAGE * );
int im_remainder( IMAGE *, IMAGE *, IMAGE * );
int im_remainderconst( IMAGE *, IMAGE *, double );
int im_remainderconst_vec( IMAGE *, IMAGE *, int, double * );
int im_floor( IMAGE *, IMAGE * );
int im_rint( IMAGE *, IMAGE * );
int im_ceil( IMAGE *, IMAGE * );
int im_sintra( IMAGE *, IMAGE * );
int im_sign( IMAGE *in, IMAGE *out );
int im_costra( IMAGE *, IMAGE * );
int im_tantra( IMAGE *, IMAGE * );
int im_asintra( IMAGE *, IMAGE * );
int im_acostra( IMAGE *, IMAGE * );
int im_atantra( IMAGE *, IMAGE * );
int im_cmulnorm( IMAGE *, IMAGE *, IMAGE * );
int im_fav4( IMAGE **, IMAGE * );
int im_gadd( double, IMAGE *, double, IMAGE *, double, IMAGE *);
int im_litecor( IMAGE *, IMAGE *, IMAGE *, int, double );
int im_bandmean( IMAGE *in, IMAGE *out );
/* boolean
*/
int im_andimage( IMAGE *, IMAGE *, IMAGE * );
int im_andconst( IMAGE *, IMAGE *, double );
int im_and_vec( IMAGE *, IMAGE *, int, double * );
int im_orimage( IMAGE *, IMAGE *, IMAGE * );
int im_orconst( IMAGE *, IMAGE *, double );
int im_or_vec( IMAGE *, IMAGE *, int, double * );
int im_eorimage( IMAGE *, IMAGE *, IMAGE * );
int im_eorconst( IMAGE *, IMAGE *, double );
int im_eor_vec( IMAGE *, IMAGE *, int, double * );
int im_shiftleft( IMAGE *, IMAGE *, int );
int im_shiftright( IMAGE *, IMAGE *, int );
/* histogram
*/
int im_maplut( IMAGE *, IMAGE *, IMAGE * );
int im_gammacorrect( IMAGE *, IMAGE *, double );
int im_heq( IMAGE *in, IMAGE *out, int bandno );
int im_hist( IMAGE *in, IMAGE *out, int bandno );
int im_histeq( IMAGE *in, IMAGE *out );
int im_histnorm( IMAGE *in, IMAGE *out );
int im_histcum( IMAGE *in, IMAGE *out );
int im_histgr( IMAGE *in, IMAGE *out, int bandno );
int im_histnD( IMAGE *in, IMAGE *out, int bins );
int im_histplot( IMAGE *hist, IMAGE *histplot );
int im_histspec( IMAGE *hin, IMAGE *href, IMAGE *lut );
int im_hsp( IMAGE *in, IMAGE *ref, IMAGE *out );
int im_identity( IMAGE *lut, int bands );
int im_identity_ushort( IMAGE *lut, int bands, int sz );
int im_lhisteq( IMAGE *in, IMAGE *out, int xwin, int ywin );
int im_lhisteq_raw( IMAGE *in, IMAGE *out, int xwin, int ywin );
int im_invertlut( DOUBLEMASK *input, IMAGE *output, int lut_size );
int im_buildlut( DOUBLEMASK *input, IMAGE *output );
int im_stdif( IMAGE *in, IMAGE *out,
double a, double m0, double b, double s0, int xwin, int ywin );
int im_stdif_raw( IMAGE *in, IMAGE *out,
double a, double m0, double b, double s0, int xwin, int ywin );
int im_tone_build_range( IMAGE *out,
int in_max, int out_max,
double Lb, double Lw, double Ps, double Pm, double Ph,
double S, double M, double H );
int im_tone_build( IMAGE *out,
double Lb, double Lw, double Ps, double Pm, double Ph,
double S, double M, double H );
int im_tone_analyse( IMAGE *in, IMAGE *lut,
double Ps, double Pm, double Ph, double S, double M, double H );
int im_ismonotonic( IMAGE *lut, int *out );
int im_tone_map( IMAGE *in, IMAGE *out, IMAGE *lut );
int im_project( IMAGE *in, IMAGE *hout, IMAGE *vout );
/* conversion
*/
/* Copy and swap types.
*/
typedef enum {
IM_ARCH_NATIVE,
IM_ARCH_BYTE_SWAPPED,
IM_ARCH_LSB_FIRST,
IM_ARCH_MSB_FIRST
} im_arch_type;
DOUBLEMASK *im_vips2mask( IMAGE *, const char * );
int im_mask2vips( DOUBLEMASK *, IMAGE * );
int im_copy_set( IMAGE *, IMAGE *, int, float, float, int, int );
int im_copy_set_meta( IMAGE *in, IMAGE *out, const char *field, GValue *meta );
int im_copy_morph( IMAGE *, IMAGE *, int, int, int );
int im_copy( IMAGE *, IMAGE * );
int im_copy_swap( IMAGE *in, IMAGE *out );
int im_copy_from( IMAGE *in, IMAGE *out, im_arch_type architecture );
int im_extract( IMAGE *, IMAGE *, IMAGE_BOX * );
int im_extract_band( IMAGE *in, IMAGE *out, int band );
int im_extract_bands( IMAGE *in, IMAGE *out, int band, int nbands );
int im_extract_area( IMAGE *in, IMAGE *out, int x, int y, int w, int h );
int im_extract_areabands( IMAGE *in, IMAGE *out,
int left, int top, int width, int height, int band, int nbands );
int im_subsample( IMAGE *, IMAGE *, int, int );
int im_zoom( IMAGE *, IMAGE *, int, int );
int im_bandjoin( IMAGE *, IMAGE *, IMAGE * );
int im_gbandjoin( IMAGE **, IMAGE *, int );
int im_black( IMAGE *, int, int, int );
int im_text( IMAGE *out, const char *text, const char *font,
int width, int alignment, int dpi );
int im_c2amph( IMAGE *, IMAGE * );
int im_c2rect( IMAGE *, IMAGE * );
int im_clip2fmt( IMAGE *in, IMAGE *out, int ofmt );
int im_clip2dcm( IMAGE *, IMAGE * );
int im_clip2cm( IMAGE *, IMAGE * );
int im_clip2us( IMAGE *, IMAGE * );
int im_clip2ui( IMAGE *, IMAGE * );
int im_clip2s( IMAGE *, IMAGE * );
int im_clip2i( IMAGE *, IMAGE * );
int im_clip2d( IMAGE *, IMAGE * );
int im_clip2f( IMAGE *, IMAGE * );
int im_clip2c( IMAGE *, IMAGE * );
int im_clip( IMAGE *, IMAGE * );
int im_ri2c( IMAGE *, IMAGE *, IMAGE * );
int im_c2imag( IMAGE *, IMAGE * );
int im_c2real( IMAGE *, IMAGE * );
int im_c2ps( IMAGE *, IMAGE * );
int im_fliphor( IMAGE *, IMAGE * );
int im_flipver( IMAGE *, IMAGE * );
int im_falsecolour( IMAGE *, IMAGE * );
int im_recomb( IMAGE *, IMAGE *, DOUBLEMASK * );
int im_insert( IMAGE *, IMAGE *, IMAGE *, int, int );
int im_insert_noexpand( IMAGE *, IMAGE *, IMAGE *, int, int );
int im_rot90( IMAGE *, IMAGE * );
int im_rot180( IMAGE *, IMAGE * );
int im_rot270( IMAGE *, IMAGE * );
int im_lrjoin( IMAGE *, IMAGE *, IMAGE * );
int im_tbjoin( IMAGE *, IMAGE *, IMAGE * );
int im_scale( IMAGE *, IMAGE * );
int im_scaleps( IMAGE *, IMAGE * );
int im_slice( IMAGE *, IMAGE *, double, double );
int im_system( IMAGE *im, const char *cmd, char **out );
int im_print( const char *message );
int im_thresh( IMAGE *, IMAGE *, double );
int im_jpeg2vips( const char *, IMAGE * );
int im_jpeg2vips_header( const char *, IMAGE * );
int im_vips2jpeg( IMAGE *, const char * );
int im_vips2mimejpeg( IMAGE *, int );
int im_vips2bufjpeg( IMAGE *, IMAGE *, int, char **, int * );
int im_vips2tiff( IMAGE *, const char * );
int im_bernd( const char *, int, int, int, int );
int im_tiff2vips( const char *, IMAGE * );
int im_tiff2vips_header( const char *, IMAGE * );
int im_tile_cache( IMAGE *, IMAGE *, int, int, int );
int im_magick2vips( const char *, IMAGE * );
int im_magick2vips_header( const char *, IMAGE * );
int im_png2vips( const char *, IMAGE * );
int im_png2vips_header( const char *, IMAGE * );
int im_exr2vips( const char *, IMAGE * );
int im_exr2vips_header( const char *, IMAGE * );
int im_ppm2vips( const char *, IMAGE * );
int im_ppm2vips_header( const char *, IMAGE * );
int im_vips2ppm( IMAGE *, const char * );
int im_analyze2vips( const char *filename, IMAGE *out );
int im_analyze2vips_header( const char *filename, IMAGE *out );
int im_vips2csv( IMAGE *in, const char *filename );
int im_csv2vips( const char *filename, IMAGE *out );
int im_csv2vips_header( const char *filename, IMAGE *out );
int im_vips2png( IMAGE *, const char * );
int im_raw2vips( const char *filename, IMAGE *out,
int width, int height, int bpp, int offset );
int im_replicate( IMAGE *in, IMAGE *out, int across, int down );
int im_grid( IMAGE *in, IMAGE *out, int tile_height, int across, int down );
int im_msb ( IMAGE * in, IMAGE * out );
int im_msb_band ( IMAGE * in, IMAGE * out, int band );
/* colour
*/
int im_Lab2LCh( IMAGE *, IMAGE * );
int im_LCh2Lab( IMAGE *, IMAGE * );
int im_LabQ2XYZ( IMAGE *, IMAGE * );
int im_LCh2UCS( IMAGE *, IMAGE * );
int im_Lab2LCh( IMAGE *, IMAGE * );
int im_Lab2LabQ( IMAGE *, IMAGE * );
int im_Lab2LabS( IMAGE *, IMAGE * );
int im_Lab2XYZ( IMAGE *, IMAGE * );
int im_Lab2XYZ_temp( IMAGE *, IMAGE *, double X0, double Y0, double Z0 );
int im_Lab2UCS( IMAGE *, IMAGE * );
int im_LabQ2Lab( IMAGE *, IMAGE * );
int im_LabQ2LabS( IMAGE *, IMAGE * );
int im_LabS2LabQ( IMAGE *, IMAGE * );
int im_LabS2Lab( IMAGE *, IMAGE * );
int im_UCS2XYZ( IMAGE *, IMAGE * );
int im_UCS2LCh( IMAGE *, IMAGE * );
int im_UCS2Lab( IMAGE *, IMAGE * );
int im_XYZ2Lab( IMAGE *, IMAGE * );
int im_XYZ2Lab_temp( IMAGE *, IMAGE *, double X0, double Y0, double Z0 );
int im_XYZ2UCS( IMAGE *, IMAGE * );
int im_sRGB2XYZ( IMAGE *, IMAGE * );
int im_XYZ2sRGB( IMAGE *, IMAGE * );
int im_Yxy2XYZ( IMAGE *, IMAGE * );
int im_XYZ2Yxy( IMAGE *, IMAGE * );
int im_dECMC_fromLab( IMAGE *, IMAGE *, IMAGE * );
int im_dE_fromXYZ( IMAGE *, IMAGE *, IMAGE * );
int im_dE_fromLab( IMAGE *, IMAGE *, IMAGE * );
void imb_Lab2LCh( float *, float *, int );
void imb_LCh2Lab( float *, float *, int );
void imb_XYZ2Lab_tables( void );
void imb_XYZ2Lab( float *, float *, int, im_colour_temperature * );
void imb_Lab2XYZ( float *, float *, int, im_colour_temperature * );
void imb_LabQ2Lab( PEL *, float *, int );
void imb_Lab2LabQ( float *, PEL *, int );
void imb_LabS2Lab( signed short *, float *, int );
void imb_Lab2LabS( float *, signed short *, int n );
void im_col_make_tables_UCS( void );
float im_col_dECMC( float, float, float, float, float, float );
float im_col_dE00( float, float, float, float, float, float );
int im_lab_morph( IMAGE *in, IMAGE *out,
DOUBLEMASK *mask,
double L_offset, double L_scale,
double a_scale, double b_scale );
/* other
*/
int im_feye( IMAGE *image,
const int xsize, const int ysize, const double factor );
int im_eye( IMAGE *image,
const int xsize, const int ysize, const double factor );
int im_zone( IMAGE *im, int size );
int im_fzone( IMAGE *im, int size );
int im_grey( IMAGE *im, const int xsize, const int ysize );
int im_fgrey( IMAGE *im, const int xsize, const int ysize );
int im_make_xy( IMAGE *out, const int xsize, const int ysize );
int im_benchmarkn( IMAGE *in, IMAGE *out, int n );
int im_benchmark2( IMAGE *in, double *out );
int im_cooc_matrix( IMAGE *im, IMAGE *m,
int xp, int yp, int xs, int ys, int dx, int dy, int flag );
int im_cooc_asm( IMAGE *m, double *asmoment );
int im_cooc_contrast( IMAGE *m, double *contrast );
int im_cooc_correlation( IMAGE *m, double *correlation );
int im_cooc_entropy( IMAGE *m, double *entropy );
int im_glds_matrix( IMAGE *im, IMAGE *m,
int xpos, int ypos, int xsize, int ysize, int dx, int dy );
int im_glds_asm( IMAGE *m, double *asmoment );
int im_glds_contrast( IMAGE *m, double *contrast );
int im_glds_entropy( IMAGE *m, double *entropy );
int im_glds_mean( IMAGE *m, double *mean );
int im_simcontr( IMAGE *image, int xs, int ys );
int im_sines( IMAGE *image,
int xsize, int ysize, double horfreq, double verfreq );
int im_spatres( IMAGE *in, IMAGE *out, int step );
int im_rightshift_size( IMAGE *in, IMAGE *out, int xshift, int yshift, int band_fmt );
/* mosaicing
*/
int im_lrmerge( IMAGE *ref, IMAGE *sec, IMAGE *out,
int dx, int dy, int mwidth );
int im_tbmerge( IMAGE *ref, IMAGE *sec, IMAGE *out,
int dx, int dy, int mwidth );
int im_lrmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2,
int mwidth );
int im_tbmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2,
int mwidth );
int im_lrmosaic( IMAGE *ref, IMAGE *sec, IMAGE *out,
int bandno,
int xref, int yref, int xsec, int ysec,
int halfcorrelation, int halfarea,
int balancetype,
int mwidth );
int im_tbmosaic( IMAGE *ref, IMAGE *sec, IMAGE *out,
int bandno,
int xref, int yref, int xsec, int ysec,
int halfcorrelation, int halfarea,
int balancetype,
int mwidth );
int im_lrmosaic1( IMAGE *ref, IMAGE *sec, IMAGE *out,
int bandno,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2,
int halfcorrelation, int halfarea,
int balancetype,
int mwidth );
int im_tbmosaic1( IMAGE *ref, IMAGE *sec, IMAGE *out,
int bandno,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2,
int halfcorrelation, int halfarea,
int balancetype,
int mwidth );
int im_global_balance( IMAGE *in, IMAGE *out, double gamma );
int im_global_balancef( IMAGE *in, IMAGE *out, double gamma );
int im_match_linear( IMAGE *ref, IMAGE *sec, IMAGE *out,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2 );
int im_match_linear_search( IMAGE *ref, IMAGE *sec, IMAGE *out,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2,
int hwindowsize, int hsearchsize );
int im_affine( IMAGE *in, IMAGE *out,
double a, double b, double c, double d, double dx, double dy,
int ox, int oy, int ow, int oh );
int im_similarity( IMAGE *in, IMAGE *out,
double a, double b, double dx, double dy );
int im_similarity_area( IMAGE *in, IMAGE *out,
double a, double b, double dx, double dy,
int ox, int oy, int ow, int oh );
int im_correl( IMAGE *ref, IMAGE *sec,
int xref, int yref, int xsec, int ysec,
int hwindowsize, int hsearchsize,
double *correlation, int *x, int *y );
int im_remosaic( IMAGE *in, IMAGE *out,
const char *old_str, const char *new_str );
/* inplace
*/
int im_plotmask( IMAGE *, int, int, PEL *, PEL *, Rect * );
int im_smear( IMAGE *, int, int, Rect * );
int im_smudge( IMAGE *, int, int, Rect * );
int im_paintrect( IMAGE *, Rect *, PEL * );
int im_circle( IMAGE *, int, int, int, int );
int im_insertplace( IMAGE *, IMAGE *, int, int );
int im_line( IMAGE *, int, int, int, int, int );
int im_fastlineuser();
int im_readpoint( IMAGE *, int, int, PEL * );
int im_flood( IMAGE *, int, int, PEL *, Rect * );
int im_flood_blob( IMAGE *, int, int, PEL *, Rect * );
int im_flood_blob_copy( IMAGE *in, IMAGE *out, int x, int y, PEL *ink );
int im_lineset( IMAGE *in, IMAGE *out, IMAGE *mask, IMAGE *ink,
int n, int *x1v, int *y1v, int *x2v, int *y2v );
/* relational
*/
int im_equal( IMAGE *, IMAGE *, IMAGE * );
int im_equalconst( IMAGE *, IMAGE *, double );
int im_equal_vec( IMAGE *, IMAGE *, int, double * );
int im_notequal( IMAGE *, IMAGE *, IMAGE * );
int im_notequalconst( IMAGE *, IMAGE *, double );
int im_notequal_vec( IMAGE *, IMAGE *, int, double * );
int im_more( IMAGE *, IMAGE *, IMAGE * );
int im_moreconst( IMAGE *, IMAGE *, double );
int im_more_vec( IMAGE *, IMAGE *, int, double * );
int im_less( IMAGE *, IMAGE *, IMAGE * );
int im_lessconst( IMAGE *, IMAGE *, double );
int im_less_vec( IMAGE *, IMAGE *, int, double * );
int im_moreeq( IMAGE *, IMAGE *, IMAGE * );
int im_moreeqconst( IMAGE *, IMAGE *, double );
int im_moreeq_vec( IMAGE *, IMAGE *, int, double * );
int im_lesseq( IMAGE *, IMAGE *, IMAGE * );
int im_lesseqconst( IMAGE *, IMAGE *, double );
int im_lesseq_vec( IMAGE *, IMAGE *, int, double * );
int im_ifthenelse( IMAGE *, IMAGE *, IMAGE *, IMAGE * );
int im_blend( IMAGE *, IMAGE *, IMAGE *, IMAGE * );
/* matrix
*/
DOUBLEMASK *im_mattrn( DOUBLEMASK *, const char * );
DOUBLEMASK *im_matcat( DOUBLEMASK *, DOUBLEMASK *, const char * );
DOUBLEMASK *im_matmul( DOUBLEMASK *, DOUBLEMASK *, const char * );
DOUBLEMASK *im_lu_decomp( const DOUBLEMASK *mat, const char *name );
int im_lu_solve( const DOUBLEMASK *lu, double *vec );
DOUBLEMASK *im_matinv( const DOUBLEMASK *mat, const char *name );
int im_matinv_inplace( DOUBLEMASK *mat );
int *im_ivector();
float *im_fvector();
double *im_dvector();
void im_free_ivector();
void im_free_fvector();
void im_free_dvector();
int **im_imat_alloc();
float **im_fmat_alloc();
double **im_dmat_alloc();
void im_free_imat();
void im_free_fmat();
void im_free_dmat();
int im_invmat( double **, int );
/* video
*/
int im_video_v4l1( IMAGE *im, const char *device,
int channel, int brightness, int colour, int contrast, int hue,
int ngrabs );
int im_video_test( IMAGE *im, int brightness, int error );
/* Backwards compatibility macros.
*/
#define im_clear_error_string() im_error_clear()
#define im_errorstring() im_error_buffer()
/* Deprecated API.
*/
void im_errormsg( const char *fmt, ... )
__attribute__((format(printf, 1, 2)));
void im_verrormsg( const char *fmt, va_list ap );
void im_errormsg_system( int err, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
void im_diagnostics( const char *fmt, ... )
__attribute__((format(printf, 1, 2)));
void im_warning( const char *fmt, ... )
__attribute__((format(printf, 1, 2)));
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_PROTO_H*/

85
include/vips/r_access.h Normal file
View File

@ -0,0 +1,85 @@
/* r_access.h
*
* 2006-09-21 tcv
* random access to images and regions
*/
#ifndef IM_R_ACCESS_H
#define IM_R_ACCESS_H
#include <vips/vips.h>
/** ARRAY MEMBER MACROS **/
/* these are local */
#define IM__TYPE_FROM_ARRAY(type,vptr,i) ( ((type*) (vptr))[i] )
#define IM__CHAR_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( gint8, (vptr), (i) )
#define IM__UCHAR_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( guint8, (vptr), (i) )
#define IM__SHORT_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( gint16, (vptr), (i) )
#define IM__USHORT_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( guint16, (vptr), (i) )
#define IM__INT_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( gint32, (vptr), (i) )
#define IM__UINT_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( guint32, (vptr), (i) )
#define IM__FLOAT_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( float, (vptr), (i) )
#define IM__DOUBLE_FROM_ARRAY(vptr,i) IM__TYPE_FROM_ARRAY( double, (vptr), (i) )
#define IM__VALUE_FROM_ARRAY(band_fmt,vptr,i) ( \
( IM_BANDFMT_DOUBLE == (band_fmt) ) ? IM__DOUBLE_FROM_ARRAY( (vptr), (i) ) \
: ( IM_BANDFMT_FLOAT == (band_fmt) ) ? IM__FLOAT_FROM_ARRAY( (vptr), (i) ) \
: ( IM_BANDFMT_INT == (band_fmt) ) ? IM__INT_FROM_ARRAY( (vptr), (i) ) \
: ( IM_BANDFMT_UINT == (band_fmt) ) ? IM__UINT_FROM_ARRAY( (vptr), (i) ) \
: ( IM_BANDFMT_SHORT == (band_fmt) ) ? IM__SHORT_FROM_ARRAY( (vptr), (i) ) \
: ( IM_BANDFMT_USHORT == (band_fmt) ) ? IM__USHORT_FROM_ARRAY( (vptr), (i) ) \
: ( IM_BANDFMT_CHAR == (band_fmt) ) ? IM__CHAR_FROM_ARRAY( (vptr), (i) ) \
: IM__UCHAR_FROM_ARRAY( (vptr), (i) ) )
#define IM__ARRAY_ASSIGNMENT(band_fmt,vptr,i,val) ( \
( IM_BANDFMT_DOUBLE == (band_fmt) ) ? ( IM__DOUBLE_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM_BANDFMT_FLOAT == (band_fmt) ) ? ( IM__FLOAT_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM_BANDFMT_INT == (band_fmt) ) ? ( IM__INT_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM_BANDFMT_UINT == (band_fmt) ) ? ( IM__UINT_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM_BANDFMT_SHORT == (band_fmt) ) ? ( IM__SHORT_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM_BANDFMT_USHORT == (band_fmt) ) ? ( IM__USHORT_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM_BANDFMT_CHAR == (band_fmt) ) ? ( IM__CHAR_FROM_ARRAY( (vptr), (i) )= (val) ) \
: ( IM__UCHAR_FROM_ARRAY( (vptr), (i) )= (val) ) )
#define IM__ARRAY_INCREMENT(band_fmt,vptr,i,val) ( \
( IM_BANDFMT_DOUBLE == (band_fmt) ) ? ( IM__DOUBLE_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM_BANDFMT_FLOAT == (band_fmt) ) ? ( IM__FLOAT_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM_BANDFMT_INT == (band_fmt) ) ? ( IM__INT_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM_BANDFMT_UINT == (band_fmt) ) ? ( IM__UINT_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM_BANDFMT_SHORT == (band_fmt) ) ? ( IM__SHORT_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM_BANDFMT_USHORT == (band_fmt) ) ? ( IM__USHORT_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM_BANDFMT_CHAR == (band_fmt) ) ? ( IM__CHAR_FROM_ARRAY( (vptr), (i) )+= (val) ) \
: ( IM__UCHAR_FROM_ARRAY( (vptr), (i) )+= (val) ) )
/** IMAGE MEMBER MACROS **/
/* export these */
#define IM_IMAGE_VALUE(im,x,y,band) IM__VALUE_FROM_ARRAY( (im)-> BandFmt, \
IM_IMAGE_ADDR( (im), (x), (y) ), (band) )
#define IM_IMAGE_ASSIGNMENT(im,x,y,band,val) IM__ARRAY_ASSIGNMENT( (im)-> BandFmt, \
IM_IMAGE_ADDR( (im), (x), (y) ), (band), (val) )
#define IM_IMAGE_INCREMENT(im,x,y,band,val) IM__ARRAY_INCREMENT( (im)-> BandFmt, \
IM_IMAGE_ADDR( (im), (x), (y) ), (band), (val) )
/** REGION MEMBER MACROS **/
/* export these */
#define IM_REGION_VALUE(reg,x,y,band) IM__VALUE_FROM_ARRAY( (reg)-> im-> BandFmt, \
IM_REGION_ADDR( (reg), (x), (y) ), (band) )
#define IM_REGION_ASSIGNMENT(reg,x,y,band,val) IM__ARRAY_ASSIGNMENT( (reg)-> im-> BandFmt, \
IM_REGION_ADDR( (reg), (x), (y) ), (band), (val) )
#define IM_REGION_INCREMENT(reg,x,y,band,val) IM__ARRAY_INCREMENT( (reg)-> im-> BandFmt, \
IM_REGION_ADDR( (reg), (x), (y) ), (band), (val) )
#endif /* IM_R_ACCESS_H */

75
include/vips/rect.h Normal file
View File

@ -0,0 +1,75 @@
/* Simple rectangle algebra.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_RECT_H
#define IM_RECT_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* A rectangle.
*/
typedef struct im_rect_struct {
int left, top, width, height;
} Rect;
/* Only define old, broken names if asked.
*/
#ifdef IM_ENABLE_DEPRECATED
/* Useful macros. Compatibility ... see below for new names.
*/
#define right(R) ((R)->left + (R)->width)
#define bottom(R) ((R)->top + (R)->height)
#endif /*IM_ENABLE_DEPRECATED*/
#define IM_RECT_RIGHT(R) ((R)->left + (R)->width)
#define IM_RECT_BOTTOM(R) ((R)->top + (R)->height)
#define IM_RECT_HCENTRE(R) ((R)->left + (R)->width / 2)
#define IM_RECT_VCENTRE(R) ((R)->top + (R)->height / 2)
/* Rectangle algebra functions.
*/
void im_rect_marginadjust( Rect *r, int n );
int im_rect_includespoint( Rect *r, int x, int y );
int im_rect_includesrect( Rect *r1, Rect *r2 );
void im_rect_intersectrect( Rect *r1, Rect *r2, Rect *r3 );
int im_rect_isempty( Rect *r );
void im_rect_unionrect( Rect *r1, Rect *r2, Rect *r3 );
int im_rect_equalsrect( Rect *r1, Rect *r2 );
Rect *im_rect_dup( Rect *r );
void im_rect_normalise( Rect *r );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_RECT_H*/

293
include/vips/region.h Normal file
View File

@ -0,0 +1,293 @@
/* Definitions for partial image regions.
*
* J.Cupitt, 8/4/93
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_REGION_H
#define IM_REGION_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#ifdef TIME_THREAD
#include <sys/time.h>
#endif /*TIME_THREAD*/
#include "rect.h"
/* Per-thread buffer cache. Held in a GPrivate.
*/
typedef struct im__buffer_cache_t {
GHashTable *hash; /* Hash to im_buffer_cache_list_t* */
GThread *thread; /* Just for sanity checking */
} im_buffer_cache_t;
/* Per-image buffer cache. Hash to this from im_buffer_cache_t.
* We can't store the GSList directly in the hash table, as GHashTable lacks an
* update operation and we'd need to _remove() and _insert() on every list
* operation.
*/
typedef struct im__buffer_cache_list_t {
GSList *buffers; /* GSList of im_buffer_t* */
GThread *thread; /* Just for sanity checking */
IMAGE *im;
im_buffer_cache_t *cache;
} im_buffer_cache_list_t;
/* What we track for each pixel buffer.
*/
typedef struct {
int ref_count; /* # of regions referencing us */
IMAGE *im; /* IMAGE we are attached to */
Rect area; /* Area this pixel buffer covers */
gboolean done; /* Calculated and in cache */
im_buffer_cache_t *cache;
gboolean invalid; /* Needs to be recalculated */
char *buf; /* Private malloc() area */
size_t bsize; /* Size of private malloc() */
} im_buffer_t;
/* Region types.
*/
typedef enum region_type {
IM_REGION_NONE,
IM_REGION_BUFFER, /* a pixel buffer */
IM_REGION_OTHER_REGION, /* memory on another region */
IM_REGION_OTHER_IMAGE, /* memory on another image */
IM_REGION_WINDOW /* mmap() buffer on fd on another image */
} RegionType;
/* Sub-area of image.
*/
typedef struct region_struct {
/* Users may read these two fields.
*/
IMAGE *im; /* Link back to parent image */
Rect valid; /* Area of parent we can see */
/* The rest of REGION is private.
*/
RegionType type; /* What kind of attachment */
char *data; /* Off here to get data */
int bpl; /* Bytes-per-line for data */
void *seq; /* Sequence we are using to fill region */
/* The thread that made this region. Used to assert() test that
* regions are not being shared between threads.
*/
GThread *thread;
/* Ref to the window we use for this region, if any.
*/
im_window_t *window;
/* Ref to the buffer we use for this region, if any.
*/
im_buffer_t *buffer;
} REGION;
/* Private to iofuncs: the size of the `tiles' requested by im_generate()
* when acting as a data sink.
*/
#define IM__TILE_WIDTH (64)
#define IM__TILE_HEIGHT (64)
/* The height of the strips for the other two request styles.
*/
#define IM__THINSTRIP_HEIGHT (1)
#define IM__FATSTRIP_HEIGHT (16)
/* Functions on regions.
*/
void im__region_take_ownership( REGION *reg );
void im__region_check_ownership( REGION *reg );
void im__region_no_ownership( REGION *reg );
REGION *im_region_create( IMAGE *im );
void im_region_free( REGION *reg );
int im_region_buffer( REGION *reg, Rect *r );
int im_region_image( REGION *reg, Rect *r );
int im_region_region( REGION *reg, REGION *to, Rect *r, int x, int y );
int im_region_equalsregion( REGION *reg1, REGION *reg2 );
int im_region_position( REGION *reg1, int x, int y );
typedef int (*im_region_fill_fn)( REGION *, void * );
int im_region_fill( REGION *reg, Rect *r, im_region_fill_fn fn, void *a );
/* IMAGE functions which use regions. We do not strictly type the function
* arguments to avoid hassle.
*/
int im_prepare( REGION *reg, Rect *r );
int im_prepare_many( REGION **reg, Rect *r );
int im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y );
int im_generate( IMAGE *im,
void *(*start_fn)(), int (*gen_fn)(), int (*stop_fn)(),
void *a, void *b
);
int im_iterate( IMAGE *im,
void *(*start_fn)(), int (*scan_fn)(), int (*stop_fn)(),
void *a, void *b
);
void im__copy_region( REGION *reg, REGION *dest, Rect *r, int x, int y );
/* Convenience functions for im_generate()/im_iterate().
*/
void *im_start_one( IMAGE *out, IMAGE *in, void *dummy );
int im_stop_one( REGION *reg, void *dummy1, void *dummy2 );
void *im_start_many( IMAGE *out, IMAGE **in, void *dummy );
int im_stop_many( REGION **out, void *dummy1, void *dummy2 );
IMAGE **im_allocate_input_array( IMAGE *out, ... );
int im_demand_hint( IMAGE *im, im_demand_type hint, ... )
__attribute__((sentinel));
int im_demand_hint_array( IMAGE *im, im_demand_type hint, IMAGE **in );
void im_free_region_array( REGION **regs );
REGION **im_allocate_region_array( IMAGE *im, int count );
void im__find_demand_size( IMAGE *im, int *pw, int *ph );
/* Buffer processing.
*/
typedef void (*im_wrapmany_fn)( void **in, void *out, int width,
void *a, void *b );
int im_wrapmany( IMAGE **in, IMAGE *out,
im_wrapmany_fn fn, void *a, void *b );
typedef void (*im_wrapone_fn)( void *in, void *out, int width,
void *a, void *b );
int im_wrapone( IMAGE *in, IMAGE *out,
im_wrapone_fn fn, void *a, void *b );
/* Internal VIPS functions shared by partials.
*/
int im__call_start( REGION *reg );
void im__call_stop( REGION *reg );
/* window manager.
*/
im_window_t *im_window_ref( IMAGE *im, int top, int height );
int im_window_unref( im_window_t *window );
void im_window_print( im_window_t *window );
/* buffer manager.
*/
void im_buffer_done( im_buffer_t *buffer );
void im_buffer_undone( im_buffer_t *buffer );
void im_buffer_unref( im_buffer_t *buffer );
im_buffer_t *im_buffer_ref( IMAGE *im, Rect *area );
im_buffer_t *im_buffer_unref_ref( im_buffer_t *buffer, IMAGE *im, Rect *area );
void im_buffer_print( im_buffer_t *buffer );
void im_invalidate( IMAGE *im );
/* Only define if IM_ENABLE_DEPRECATED is set.
*/
#ifdef IM_ENABLE_DEPRECATED
/* Compatibilty macros ... delete soon. See below for the new names.
*/
/* Macros on REGIONs.
* lskip() add to move down line
* nele() number of elements across region
* rsize() sizeof width of region
* addr() address of pixel in region
*/
#define lskip(B) ((B)->bpl)
#define nele(B) ((B)->valid.width*(B)->im->Bands)
#define rsize(B) ((B)->valid.width*psize((B)->im))
/* addr() is special: if DEBUG is defined, make an addr() with bounds checking.
*/
#ifdef DEBUG
#define addr(B,X,Y) \
( (im_rect_includespoint( &(B)->valid, (X), (Y) ))? \
((B)->data + ((Y) - (B)->valid.top)*lskip(B) + \
((X) - (B)->valid.left)*psize((B)->im)): \
(fprintf( stderr, \
"addr: point out of bounds, file \"%s\", line %d\n" \
"(point x=%d, y=%d\n" \
" should have been within Rect left=%d, top=%d, " \
"width=%d, height=%d)\n", \
__FILE__, __LINE__, \
(X), (Y), \
(B)->valid.left, \
(B)->valid.top, \
(B)->valid.width, \
(B)->valid.height ), abort(), (char *) NULL) \
)
#else /*DEBUG*/
#define addr(B,X,Y) ((B)->data + ((Y)-(B)->valid.top)*lskip(B) + \
((X)-(B)->valid.left)*psize((B)->im))
#endif /*DEBUG*/
#endif /*IM_ENABLE_DEPRECATED*/
/* Macros on REGIONs.
* IM_REGION_LSKIP() add to move down line
* IM_REGION_N_ELEMENTS() number of elements across region
* IM_REGION_SIZEOF_LINE() sizeof width of region
* IM_REGION_ADDR() address of pixel in region
*/
#define IM_REGION_LSKIP(R) ((R)->bpl)
#define IM_REGION_N_ELEMENTS(R) ((R)->valid.width*(R)->im->Bands)
#define IM_REGION_SIZEOF_LINE(R) \
((R)->valid.width * IM_IMAGE_SIZEOF_PEL((R)->im))
/* If DEBUG is defined, add bounds checking.
*/
#ifdef DEBUG
#define IM_REGION_ADDR(B,X,Y) \
( (im_rect_includespoint( &(B)->valid, (X), (Y) ))? \
((B)->data + ((Y) - (B)->valid.top)*IM_REGION_LSKIP(B) + \
((X) - (B)->valid.left)*IM_IMAGE_SIZEOF_PEL((B)->im)): \
(fprintf( stderr, \
"IM_REGION_ADDR: point out of bounds, " \
"file \"%s\", line %d\n" \
"(point x=%d, y=%d\n" \
" should have been within Rect left=%d, top=%d, " \
"width=%d, height=%d)\n", \
__FILE__, __LINE__, \
(X), (Y), \
(B)->valid.left, \
(B)->valid.top, \
(B)->valid.width, \
(B)->valid.height ), abort(), (char *) NULL) \
)
#else /*DEBUG*/
#define IM_REGION_ADDR(B,X,Y) \
((B)->data + \
((Y)-(B)->valid.top) * IM_REGION_LSKIP(B) + \
((X)-(B)->valid.left) * IM_IMAGE_SIZEOF_PEL((B)->im))
#endif /*DEBUG*/
#define IM_REGION_ADDR_TOPLEFT(B) ( (B)->data )
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_REGION_H*/

64
include/vips/semaphore.h Normal file
View File

@ -0,0 +1,64 @@
/* Definitions for thread support.
*
* JC, 9/5/94
* 30/7/99 RP, JC
* - reworked for posix/solaris threads
* 28/9/99 JC
* - restructured, made part of public API
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_SEMAPHORE_H
#define IM_SEMAPHORE_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* Implement our own semaphores.
*/
typedef struct {
char *name;
int v;
GMutex *mutex;
GCond *cond;
} im_semaphore_t;
int im_semaphore_up( im_semaphore_t *s );
int im_semaphore_down( im_semaphore_t *s );
int im_semaphore_upn( im_semaphore_t *s, int n );
int im_semaphore_downn( im_semaphore_t *s, int n );
void im_semaphore_destroy( im_semaphore_t *s );
void im_semaphore_init( im_semaphore_t *s, int v, char *name );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_SEMAPHORE_H*/

44
include/vips/struct.h Normal file
View File

@ -0,0 +1,44 @@
/* Header file for structures using the mosaicing programs */
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_STRUCT_H
#define IM_STRUCT_H
typedef struct {
char *reference, *secondary;
int nopoints;
float *xref, *yref, *xsec, *ysec;
} CNTRL_POINTS;
typedef struct {
char *reference, *secondary;
float scale, angle, deltax, deltay;
float Xcoef[6], Ycoef[6];
} MERGE_PARAM;
#endif /*IM_STRUCT_H*/

77
include/vips/thread.h Normal file
View File

@ -0,0 +1,77 @@
/* Private include file ... if we've been configured without gthread, we need
* to point the g_thread_*() and g_mutex_*() functions at our own stubs.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_THREAD_H
#define IM_THREAD_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#ifndef HAVE_THREADS
#undef g_thread_supported
#define g_thread_supported() (0)
#define g_thread_init im__g_thread_init
#define g_thread_join im__g_thread_join
#define g_thread_self im__g_thread_self
#define g_thread_create_full im__g_thread_create_full
/* We don't need a shadow imlementation of g_thread_create(), even though we
* use it, because it's just a macro over g_thread_create_full().
*/
void im__g_thread_init( GThreadFunctions *vtable );
gpointer im__g_thread_join( GThread * );
gpointer im__g_thread_self( void );
GThread *im__g_thread_create_full( GThreadFunc,
gpointer, gulong, gboolean, gboolean, GThreadPriority, GError ** );
#undef g_mutex_new
#undef g_mutex_free
#undef g_mutex_lock
#undef g_mutex_unlock
#define g_mutex_new im__g_mutex_new
#define g_mutex_free im__g_mutex_free
#define g_mutex_lock im__g_mutex_lock
#define g_mutex_unlock im__g_mutex_unlock
GMutex *im__g_mutex_new( void );
void im__g_mutex_free( GMutex * );
void im__g_mutex_lock( GMutex * );
void im__g_mutex_unlock( GMutex * );
#endif /*!HAVE_THREADS*/
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_THREAD_H*/

134
include/vips/threadgroup.h Normal file
View File

@ -0,0 +1,134 @@
/* Thread eval for VIPS.
*
* 29/9/99 JC
* - from thread.h
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_THREADGROUP_H
#define IM_THREADGROUP_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#include <vips/semaphore.h>
/* Stack size for each thread. Need to set this explicitly because some
* systems have a very low default.
FIXME ... should have an environment variable for this?
*/
#define IM__DEFAULT_STACK_SIZE (2 * 1024 * 1024)
/* Default tile geometry.
*/
extern int im__tile_width;
extern int im__tile_height;
extern int im__fatstrip_height;
extern int im__thinstrip_height;
/* Default n threads.
*/
extern int im__concurrency;
/* A work function.
*/
typedef int (*im__work_fn)( REGION *, void *, void *, void * );
/* What we track for each thread.
*/
typedef struct {
REGION *reg; /* Region this thread operates on */
struct im__threadgroup_t *tg; /* Thread group we are part of */
GThread *thread; /* Thread for this region */
im_semaphore_t go; /* Thread waits here to start work */
int kill; /* Set this to make thread exit */
int error; /* Set by thread if work fn fails */
REGION *oreg; /* If part of an inplace threadgroup, */
Rect pos; /* where this thread should write */
int x, y; /* it's result */
void *a, *b, *c; /* User arguments to work fns */
#ifdef TIME_THREAD
hrtime_t *btime, *etime;
int tpos;
#endif /*TIME_THREAD*/
} im_thread_t;
/* What we track for a group of threads working together.
*/
typedef struct im__threadgroup_t {
int zombie; /* Set if has been freed */
IMAGE *im; /* Image we are calculating */
int pw, ph; /* Tile size */
int nlines; /* Scanlines-at-once we prefer for iteration */
im__work_fn work; /* Work fn for this threadgroup */
int inplace; /* Regions should be contiguous */
int nthr; /* Number of threads in group */
im_thread_t **thr; /* Threads */
im_semaphore_t idle_sem;/* The number of idle threads */
GSList *idle; /* All the idle threads */
GMutex *idle_lock;
#ifdef DEBUG_HIGHWATER
int nidle; /* Number of idles */
int min_idle; /* How short idle got */
#endif /*DEBUG_HIGHWATER*/
int kill; /* Set this to stop threadgroup early */
} im_threadgroup_t;
void im_concurrency_set( int concurrency );
int im_concurrency_get( void );
/* Thread group functions.
*/
im_threadgroup_t *im_threadgroup_create( IMAGE *im );
int im_threadgroup_free( im_threadgroup_t *tg );
im_thread_t *im_threadgroup_get( im_threadgroup_t *tg );
void im_threadgroup_wait( im_threadgroup_t *tg );
int im_threadgroup_iserror( im_threadgroup_t *tg );
void im_threadgroup_trigger( im_thread_t *thr );
/* Threaded im_prepare()
*/
int im_prepare_thread( im_threadgroup_t *tg, REGION *oreg, Rect *r );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_THREADGROUP_H*/

63
include/vips/time.h Normal file
View File

@ -0,0 +1,63 @@
/* Definitions for time struct.
*
* J.Cupitt, 8/4/93
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_TIME_H
#define IM_TIME_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#include <sys/types.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /*HAVE_SYS_TIME_H*/
/* Struct we keep a record of execution time in. Passed to eval callback, so
* it can assess progress.
*/
struct time_info {
IMAGE *im; /* Image we are part of */
time_t start; /* Start time, in seconds */
int run; /* Time we have been running */
int eta; /* Estimated seconds of computation left */
gint64 tpels; /* Number of pels we expect to calculate */
gint64 npels; /* Number of pels calculated so far */
int percent; /* Percent complete */
};
extern int im__handle_eval( IMAGE *im, int w, int h );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_TIME_H*/

324
include/vips/util.h Normal file
View File

@ -0,0 +1,324 @@
/* Various useful definitions.
*
* J.Cupitt, 8/4/93
* 15/7/96 JC
* - C++ stuff added
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef IM_UTIL_H
#define IM_UTIL_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* Some platforms don't have M_PI in math.h :-(
*/
#define IM_PI (3.14159265358979323846)
/* Only define if IM_ENABLE_DEPRECATED is set.
*/
#ifdef IM_ENABLE_DEPRECATED
#ifndef MAX
#define MAX(A,B) ((A)>(B)?(A):(B))
#define MIN(A,B) ((A)<(B)?(A):(B))
#endif /*MAX*/
#define CLIP(A,V,B) MAX( (A), MIN( (B), (V) ) )
#define NEW(IM,A) ((A *)im_malloc((IM),sizeof(A)))
#define NUMBER(R) (sizeof(R)/sizeof(R[0]))
#define ARRAY(IM,N,T) ((T *)im_malloc((IM),(N) * sizeof(T)))
/* Duff's device. Do OPERation N times in a 16-way unrolled loop.
*/
#define UNROLL( N, OPER ) { \
if( (N) ) { \
int duff_count = ((N) + 15) / 16; \
\
switch( (N) % 16 ) { \
case 0: do { OPER; \
case 15: OPER; \
case 14: OPER; \
case 13: OPER; \
case 12: OPER; \
case 11: OPER; \
case 10: OPER; \
case 9: OPER; \
case 8: OPER; \
case 7: OPER; \
case 6: OPER; \
case 5: OPER; \
case 4: OPER; \
case 3: OPER; \
case 2: OPER; \
case 1: OPER; \
} while( --duff_count > 0 ); \
} \
} \
}
/* Round a float to the nearest integer. This should give an identical result
* to the math.h rint() function (and the old SunOS nint() function), but be
* much faster. Beware: it evaluates its argument more than once, so don't use
* ++!
*/
#define RINT( R ) ((int)((R)>0?((R)+0.5):((R)-0.5)))
/* Various integer range clips. Record over/under flows.
*/
#define CLIP_UCHAR( V, SEQ ) { \
if( (V) & (UCHAR_MAX ^ -1) ) { \
if( (V) < 0 ) { \
(SEQ)->underflow++; \
(V) = 0; \
} \
if( (V) > UCHAR_MAX ) { \
(SEQ)->overflow++; \
(V) = UCHAR_MAX; \
} \
} \
}
#define CLIP_USHORT( V, SEQ ) { \
if( (V) & (USHRT_MAX ^ -1) ) { \
if( (V) < 0 ) { \
(SEQ)->underflow++; \
(V) = 0; \
} \
if( (V) > USHRT_MAX ) { \
(SEQ)->overflow++; \
(V) = USHRT_MAX; \
} \
} \
}
#define CLIP_CHAR( V, SEQ ) { \
if( (V) < SCHAR_MIN ) { \
(SEQ)->underflow++; \
(V) = SCHAR_MIN; \
} \
if( (V) > SCHAR_MAX ) { \
(SEQ)->overflow++; \
(V) = SCHAR_MAX; \
} \
}
#define CLIP_SHORT( V, SEQ ) { \
if( (V) < SHRT_MIN ) { \
(SEQ)->underflow++; \
(V) = SHRT_MIN; \
} \
if( (V) > SHRT_MAX ) { \
(SEQ)->overflow++; \
(V) = SHRT_MAX; \
} \
}
#define CLIP_NONE( V, SEQ ) {}
#endif /*IM_ENABLE_DEPRECATED*/
#define IM_MAX(A,B) ((A)>(B)?(A):(B))
#define IM_MIN(A,B) ((A)<(B)?(A):(B))
#define IM_ABS(x) (((x) >= 0) ? (x) : -(x))
#define IM_CLIP(A,V,B) IM_MAX( (A), IM_MIN( (B), (V) ) )
#define IM_NEW(IM,A) ((A *)im_malloc((IM),sizeof(A)))
#define IM_NUMBER(R) ((int)(sizeof(R)/sizeof(R[0])))
#define IM_ARRAY(IM,N,T) ((T *)im_malloc((IM),(N) * sizeof(T)))
#define IM_FREEF( F, S ) do { \
if( S ) { \
(void) F( (S) ); \
(S) = 0; \
} \
} while( 0 )
#define IM_FREE( A ) IM_FREEF( im_free, A )
#define IM_SETSTR( S, V ) do { \
if( (S) != (V) ) { \
if( !(S) || !(V) || strcmp( (S), (V) ) != 0 ) { \
const char *sst = (V); \
\
IM_FREE( S ); \
if( sst ) \
(S) = im_strdup( NULL, sst ); \
} \
} \
} while( 0 )
/* Duff's device. Do OPERation N times in a 16-way unrolled loop.
*/
#define IM_UNROLL( N, OPER ) { \
if( (N) ) { \
int duff_count = ((N) + 15) / 16; \
\
switch( (N) % 16 ) { \
case 0: do { OPER; \
case 15: OPER; \
case 14: OPER; \
case 13: OPER; \
case 12: OPER; \
case 11: OPER; \
case 10: OPER; \
case 9: OPER; \
case 8: OPER; \
case 7: OPER; \
case 6: OPER; \
case 5: OPER; \
case 4: OPER; \
case 3: OPER; \
case 2: OPER; \
case 1: OPER; \
} while( --duff_count > 0 ); \
} \
} \
}
/* Round a float to the nearest integer. This should give an identical result
* to the math.h rint() function (and the old SunOS nint() function), but be
* much faster. Beware: it evaluates its argument more than once, so don't use
* ++!
*/
#define IM_RINT( R ) ((int)((R)>0?((R)+0.5):((R)-0.5)))
/* Various integer range clips. Record over/under flows.
*/
#define IM_CLIP_UCHAR( V, SEQ ) { \
if( (V) < 0 ) { \
(SEQ)->underflow++; \
(V) = 0; \
} \
else if( (V) > UCHAR_MAX ) { \
(SEQ)->overflow++; \
(V) = UCHAR_MAX; \
} \
}
#define IM_CLIP_USHORT( V, SEQ ) { \
if( (V) < 0 ) { \
(SEQ)->underflow++; \
(V) = 0; \
} \
else if( (V) > USHRT_MAX ) { \
(SEQ)->overflow++; \
(V) = USHRT_MAX; \
} \
}
#define IM_CLIP_CHAR( V, SEQ ) { \
if( (V) < SCHAR_MIN ) { \
(SEQ)->underflow++; \
(V) = SCHAR_MIN; \
} \
else if( (V) > SCHAR_MAX ) { \
(SEQ)->overflow++; \
(V) = SCHAR_MAX; \
} \
}
#define IM_CLIP_SHORT( V, SEQ ) { \
if( (V) < SHRT_MIN ) { \
(SEQ)->underflow++; \
(V) = SHRT_MIN; \
} \
else if( (V) > SHRT_MAX ) { \
(SEQ)->overflow++; \
(V) = SHRT_MAX; \
} \
}
#define IM_CLIP_NONE( V, SEQ ) {}
/* Now implemented as macros.
*/
#define im_open_local( IM, NAME, MODE ) \
((IMAGE *) im_local( (IM), \
(im_construct_fn) im_open, (im_callback_fn) im_close, \
(void *) (NAME), (void *) (MODE), NULL ))
/* Strange double cast stops bogus warnings from gcc 4.1
*/
#define im_open_local_array( IM, OUT, N, NAME, MODE ) \
(im_local_array( (IM), (void **)((void*)(OUT)), (N),\
(im_construct_fn) im_open, (im_callback_fn) im_close, \
(void *) (NAME), (void *) (MODE), NULL ))
/* strtok replacement.
*/
char *im__break_token( char *str, char *brk );
/* Like GFunc, but return a value.
*/
typedef void *(*VSListMap2Fn)( void *, void *, void * );
typedef void *(*VSListMap4Fn)( void *, void *, void *, void *, void * );
typedef void *(*VSListFold2Fn)( void *, void *, void *, void * );
gboolean im_slist_equal( GSList *l1, GSList *l2 );
void *im_slist_map2( GSList *list, VSListMap2Fn fn, void *a, void *b );
void *im_slist_map2_rev( GSList *list, VSListMap2Fn fn, void *a, void *b );
void *im_slist_map4( GSList *list,
VSListMap4Fn fn, void *a, void *b, void *c, void *d );
void *im_slist_fold2( GSList *list, void *start,
VSListFold2Fn fn, void *a, void *b );
GSList *im_slist_filter( GSList *list, VSListMap2Fn fn, void *a, void *b );
void im_slist_free_all( GSList *list );
void *im_map_equal( void *a, void *b );
char *im_strncpy( char *dest, const char *src, int n );
char *im_strrstr( const char *haystack, const char *needle );
char *im_strdup( IMAGE *im, const char *str );
gboolean im_ispostfix( const char *a, const char *b );
gboolean im_isprefix( const char *a, const char *b );
int im_vsnprintf( char *str, size_t size, const char *format, va_list ap );
int im_snprintf( char *str, size_t size, const char *format, ... )
__attribute__((format(printf, 3, 4)));
char *im_break_token( char *str, const char *brk );
const char *im_skip_dir( const char *filename );
void im_filename_split( const char *path, char *name, char *mode );
void im_filename_suffix( const char *path, char *suffix );
int im_filename_suffix_match( const char *path, const char *suffixes[] );
char *im_getnextoption( char **in );
char *im_getsuboption( const char *buf );
void *im_local( IMAGE *im,
im_construct_fn cons, im_callback_fn dest, void *a, void *b, void *c );
int im_local_array( IMAGE *im, void **out, int n,
im_construct_fn cons, im_callback_fn dest, void *a, void *b, void *c );
gint64 im_file_length( int fd );
char *im__file_read( FILE *fp, const char *name, unsigned int *length_out );
char *im__file_read_name( const char *name, unsigned int *length_out );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*IM_UTIL_H*/

Some files were not shown because too many files have changed in this diff Show More