split to trunk/branches
This commit is contained in:
commit
5494f610e2
|
@ -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.
|
|
@ -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!
|
||||
|
||||
|
|
@ -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.
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -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
|
|
@ -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"
|
||||
])
|
||||
|
|
@ -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.
|
|
@ -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
|
Binary file not shown.
|
@ -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
|
||||
|
|
@ -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
|
||||
])
|
|
@ -0,0 +1,4 @@
|
|||
SUBDIRS = \
|
||||
vips2dj \
|
||||
mitsub \
|
||||
vdump
|
|
@ -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@
|
|
@ -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 );
|
||||
}
|
||||
|
|
@ -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)
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
|
@ -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
|
|
@ -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}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
SUBDIRS = vips2dj
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
SUBDIRS = lab cmyk mono
|
||||
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,10 @@
|
|||
grestore end % Image Trailer grestore
|
||||
grestore % Print PostScript grestore
|
||||
pse
|
||||
endp
|
||||
showpage
|
||||
%%PageTrailer
|
||||
%%Trailer
|
||||
end
|
||||
%%EOF
|
||||
|
|
@ -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)
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
%%EndFeature
|
||||
}featurecleanup
|
||||
(Johan Lammens; document: Lab_example)setjob
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
grestore end
|
||||
grestore
|
||||
pse
|
||||
endp
|
||||
%%PageTrailer
|
||||
%%Trailer
|
||||
end
|
||||
%%EOF
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
grestore end % Image Trailer grestore
|
||||
grestore % Print PostScript grestore
|
||||
pse
|
||||
endp
|
||||
showpage
|
||||
%%PageTrailer
|
||||
%%Trailer
|
||||
end
|
||||
%%EOF
|
||||
|
|
@ -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 );
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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 );
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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}
|
|
@ -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}
|
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
|
@ -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 |
|
@ -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 |
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
|
@ -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.
|
||||
|
|
@ -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}
|
|
@ -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}
|
|
@ -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 :-(
|
|
@ -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}
|
|
@ -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 = ®->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 = ®->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,
|
||||
>otal, 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.
|
||||
|
|
@ -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}
|
|
@ -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()+.
|
|
@ -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}
|
|
@ -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.
|
|
@ -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}
|
|
@ -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.
|
|
@ -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}
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
SUBDIRS = vips
|
|
@ -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
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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 */
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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.
|
||||
*/
|
|
@ -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*/
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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 */
|
||||
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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*/
|
|
@ -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
Loading…
Reference in New Issue