Merge branch 'affine-bug'
Conflicts: libvips/resample/transform.c
This commit is contained in:
commit
ecd771cde7
@ -4,6 +4,9 @@
|
|||||||
25/7/14 started 7.40.5
|
25/7/14 started 7.40.5
|
||||||
- fix a race in im_maxpos_avg()
|
- fix a race in im_maxpos_avg()
|
||||||
- limit n_thr on tiny images
|
- limit n_thr on tiny images
|
||||||
|
- don't exit() on memleak detected, just warn
|
||||||
|
- add "autocrop" option to openslide load
|
||||||
|
- argh fix affine, again
|
||||||
|
|
||||||
4/7/14 started 7.40.4
|
4/7/14 started 7.40.4
|
||||||
- fix vips_rawsave_fd(), thanks aferrero2707
|
- fix vips_rawsave_fd(), thanks aferrero2707
|
||||||
|
12
TODO
12
TODO
@ -1,3 +1,15 @@
|
|||||||
|
- affine makes black lines with interp window_offset > 1, see nohalo
|
||||||
|
|
||||||
|
- experiment with size down to two sizes above in vipsthumbnail
|
||||||
|
|
||||||
|
how does this affect speed and sharpness?
|
||||||
|
|
||||||
|
- vipsthumbnail -t plus large -s seems to fail?
|
||||||
|
|
||||||
|
- bicubic adds noise to 255/255/255, why? try babe.jpg background
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- vips_object_unref_outputs() needs docs ... bindings will need it
|
- vips_object_unref_outputs() needs docs ... bindings will need it
|
||||||
|
|
||||||
- rewrite im_conv() etc. as vips_conv()
|
- rewrite im_conv() etc. as vips_conv()
|
||||||
|
@ -2,549 +2,23 @@
|
|||||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||||
]>
|
]>
|
||||||
<refentry id="glib-building">
|
<refentry id="binding">
|
||||||
<refmeta>
|
<refmeta>
|
||||||
<refentrytitle>Compiling the GLib package</refentrytitle>
|
<refentrytitle>Writing bindings for libvips</refentrytitle>
|
||||||
<manvolnum>3</manvolnum>
|
<manvolnum>3</manvolnum>
|
||||||
<refmiscinfo>GLib Library</refmiscinfo>
|
<refmiscinfo>VIPS Library</refmiscinfo>
|
||||||
</refmeta>
|
</refmeta>
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>Compiling the GLib Package</refname>
|
<refname>Binding</refname>
|
||||||
<refpurpose>How to compile GLib itself</refpurpose>
|
<refpurpose>How to write bindings for libvips</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsect1 id="building">
|
<refsect1 id="binding-goi">
|
||||||
<title>Building the Library on UNIX</title>
|
<title>Binding and gobject-introspection</title>
|
||||||
<para>
|
<para>
|
||||||
On UNIX, GLib uses the standard GNU build system,
|
Stuff about goi.
|
||||||
using <application>autoconf</application> for package
|
|
||||||
configuration and resolving portability issues,
|
|
||||||
<application>automake</application> for building makefiles
|
|
||||||
that comply with the GNU Coding Standards, and
|
|
||||||
<application>libtool</application> for building shared
|
|
||||||
libraries on multiple platforms. The normal sequence for
|
|
||||||
compiling and installing the GLib library is thus:
|
|
||||||
|
|
||||||
<literallayout>
|
|
||||||
<userinput>./configure</userinput>
|
|
||||||
<userinput>make</userinput>
|
|
||||||
<userinput>make install</userinput>
|
|
||||||
</literallayout>
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
The standard options provided by <application>GNU
|
|
||||||
autoconf</application> may be passed to the
|
|
||||||
<command>configure</command> script. Please see the
|
|
||||||
<application>autoconf</application> documentation or run
|
|
||||||
<command>./configure --help</command> for information about
|
|
||||||
the standard options.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The GTK+ documentation contains
|
|
||||||
<ulink url="../gtk/gtk-building.html">further details</ulink>
|
|
||||||
about the build process and ways to influence it.
|
|
||||||
</para>
|
|
||||||
</refsect1>
|
|
||||||
<refsect1 id="dependencies">
|
|
||||||
<title>Dependencies</title>
|
|
||||||
<para>
|
|
||||||
Before you can compile the GLib library, you need to have
|
|
||||||
various other tools and libraries installed on your system.
|
|
||||||
Beyond a C compiler (which must implement C90, but does not need
|
|
||||||
to implement C99), the two tools needed during the build process
|
|
||||||
(as differentiated from the tools used in when creating GLib
|
|
||||||
mentioned above such as <application>autoconf</application>) are
|
|
||||||
<command>pkg-config</command> and GNU make.
|
|
||||||
</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<ulink url="http://www.freedesktop.org/software/pkgconfig/">pkg-config</ulink>
|
|
||||||
is a tool for tracking the compilation flags needed for
|
|
||||||
libraries that are used by the GLib library. (For each
|
|
||||||
library, a small <literal>.pc</literal> text file is
|
|
||||||
installed in a standard location that contains the compilation
|
|
||||||
flags needed for that library along with version number
|
|
||||||
information.) The version of <command>pkg-config</command>
|
|
||||||
needed to build GLib is mirrored in the
|
|
||||||
<filename>dependencies</filename> directory
|
|
||||||
on the <ulink url="ftp://ftp.gtk.org/pub/gtk/v2.2/">GTK+ FTP
|
|
||||||
site.</ulink>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The GLib Makefiles make use of several features specific to
|
|
||||||
<ulink url="http://www.gnu.org/software/make">GNU
|
|
||||||
make</ulink>, and will not build correctly with other
|
|
||||||
versions of <command>make</command>. You will need to
|
|
||||||
install it if you don't already have it on your system. (It
|
|
||||||
may be called <command>gmake</command> rather than
|
|
||||||
<command>make</command>.)
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
<para>
|
|
||||||
A UNIX build of GLib requires that the system implements at
|
|
||||||
least the original 1990 version of POSIX. Beyond this, it
|
|
||||||
depends on a number of other libraries.
|
|
||||||
</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The <ulink url="http://www.gnu.org/software/libiconv/">GNU
|
|
||||||
libiconv library</ulink> is needed to build GLib if your
|
|
||||||
system doesn't have the <function>iconv()</function>
|
|
||||||
function for doing conversion between character
|
|
||||||
encodings. Most modern systems should have
|
|
||||||
<function>iconv()</function>, however many older systems lack
|
|
||||||
an <function>iconv()</function> implementation. On such systems,
|
|
||||||
you must install the libiconv library. This can be found at:
|
|
||||||
<ulink url="http://www.gnu.org/software/libiconv">http://www.gnu.org/software/libiconv</ulink>.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If your system has an <function>iconv()</function> implementation but
|
|
||||||
you want to use libiconv instead, you can pass the
|
|
||||||
--with-libiconv option to configure. This forces
|
|
||||||
libiconv to be used.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Note that if you have libiconv installed in your default include
|
|
||||||
search path (for instance, in <filename>/usr/local/</filename>), but
|
|
||||||
don't enable it, you will get an error while compiling GLib because
|
|
||||||
the <filename>iconv.h</filename> that libiconv installs hides the
|
|
||||||
system iconv.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you are using the native iconv implementation on Solaris
|
|
||||||
instead of libiconv, you'll need to make sure that you have
|
|
||||||
the converters between locale encodings and UTF-8 installed.
|
|
||||||
At a minimum you'll need the SUNWuiu8 package. You probably
|
|
||||||
should also install the SUNWciu8, SUNWhiu8, SUNWjiu8, and
|
|
||||||
SUNWkiu8 packages.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The native iconv on Compaq Tru64 doesn't contain support for
|
|
||||||
UTF-8, so you'll need to use GNU libiconv instead. (When
|
|
||||||
using GNU libiconv for GLib, you'll need to use GNU libiconv
|
|
||||||
for GNU gettext as well.) This probably applies to related
|
|
||||||
operating systems as well.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The libintl library from the <ulink
|
|
||||||
url="http://www.gnu.org/software/gettext">GNU gettext
|
|
||||||
package</ulink> is needed if your system doesn't have the
|
|
||||||
<function>gettext()</function> functionality for handling
|
|
||||||
message translation databases.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A thread implementation is needed. The thread support in GLib
|
|
||||||
can be based upon POSIX threads or win32 threads.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
GRegex uses the <ulink url="http://www.pcre.org/">PCRE library</ulink>
|
|
||||||
for regular expression matching. The default is to use the internal
|
|
||||||
version of PCRE that is patched to use GLib for memory management
|
|
||||||
and Unicode handling. If you prefer to use the system-supplied PCRE
|
|
||||||
library you can pass the <option>--with-pcre=system</option> option
|
|
||||||
to, but it is not recommended.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional extended attribute support in GIO requires the
|
|
||||||
getxattr() family of functions that may be provided by glibc or
|
|
||||||
by the standalone libattr library. To build GLib without extended
|
|
||||||
attribute support, use the <option>--disable-xattr</option>
|
|
||||||
option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional SELinux support in GIO requires libselinux.
|
|
||||||
To build GLib without SELinux support, use the
|
|
||||||
<option>--disable-selinux</option> option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional support for DTrace requires the
|
|
||||||
<filename>sys/sdt.h</filename> header, which is provided
|
|
||||||
by SystemTap on Linux. To build GLib without DTrace, use
|
|
||||||
the <option>--disable-dtrace</option> configure option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional support for
|
|
||||||
<ulink url="http://sourceware.org/systemtap/">SystemTap</ulink>
|
|
||||||
can be disabled with the <option>--disable-systemtap</option>
|
|
||||||
configure option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
|
|
||||||
</refsect1>
|
|
||||||
<refsect1 id="extra-configuration-options">
|
|
||||||
<title>Extra Configuration Options</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In addition to the normal options, the
|
|
||||||
<command>configure</command> script in the GLib
|
|
||||||
library supports these additional arguments:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--enable-debug</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Turns on various amounts of debugging support. Setting this to 'no'
|
|
||||||
disables g_assert(), g_return_if_fail(), g_return_val_if_fail() and
|
|
||||||
all cast checks between different object types. Setting it to 'minimum' disables only cast checks. Setting it to 'yes' enables
|
|
||||||
<link linkend="G-DEBUG:CAPS">runtime debugging</link>.
|
|
||||||
The default is 'minimum'.
|
|
||||||
Note that 'no' is fast, but dangerous as it tends to destabilize
|
|
||||||
even mostly bug-free software by changing the effect of many bugs
|
|
||||||
from simple warnings into fatal crashes. Thus
|
|
||||||
<option>--enable-debug=no</option> should <emphasis>not</emphasis>
|
|
||||||
be used for stable releases of GLib.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-gc-friendly</systemitem> and
|
|
||||||
<systemitem>--enable-gc-friendly</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default, and with <systemitem>--disable-gc-friendly</systemitem>
|
|
||||||
as well, Glib does not clear the memory for certain objects before
|
|
||||||
they are freed. For example, Glib may decide to recycle GList nodes
|
|
||||||
by putting them in a free list. However, memory profiling and debugging
|
|
||||||
tools like <ulink url="http://www.valgrind.org">Valgrind</ulink> work
|
|
||||||
better if an application does not keep dangling pointers to freed
|
|
||||||
memory (even though these pointers are no longer dereferenced), or
|
|
||||||
invalid pointers inside uninitialized memory.
|
|
||||||
The <systemitem>--enable-gc-friendly</systemitem> option makes Glib
|
|
||||||
clear memory in these situations:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When shrinking a GArray, Glib will clear the memory no longer
|
|
||||||
available in the array: shrink an array from 10 bytes to 7, and
|
|
||||||
the last 3 bytes will be cleared. This includes removals of single
|
|
||||||
and multiple elements.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When growing a GArray, Glib will clear the new chunk of memory.
|
|
||||||
Grow an array from 7 bytes to 10 bytes, and the last 3 bytes will
|
|
||||||
be cleared.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The above applies to GPtrArray as well.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When freeing a node from a GHashTable, Glib will first clear
|
|
||||||
the node, which used to have pointers to the key and the value
|
|
||||||
stored at that node.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When destroying or removing a GTree node, Glib will clear the node,
|
|
||||||
which used to have pointers to the node's value, and the left and
|
|
||||||
right subnodes.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Since clearing the memory has a cost,
|
|
||||||
<systemitem>--disable-gc-friendly</systemitem> is the default.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-mem-pools</systemitem> and
|
|
||||||
<systemitem>--enable-mem-pools</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Many small chunks of memory are often allocated via collective pools
|
|
||||||
in GLib and are cached after release to speed up reallocations.
|
|
||||||
For sparse memory systems this behaviour is often inferior, so
|
|
||||||
memory pools can be disabled to avoid excessive caching and force
|
|
||||||
atomic maintenance of chunks through the <function>g_malloc()</function>
|
|
||||||
and <function>g_free()</function> functions. Code currently affected by
|
|
||||||
this:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<structname>GMemChunk</structname>s become basically non-effective
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<structname>GSignal</structname> disables all caching
|
|
||||||
(potentially very slow)
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<structname>GType</structname> doesn't honour the
|
|
||||||
<structname>GTypeInfo</structname>
|
|
||||||
<structfield>n_preallocs</structfield> field anymore
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
the <structname>GBSearchArray</structname> flag
|
|
||||||
<literal>G_BSEARCH_ALIGN_POWER2</literal> becomes non-functional
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-threads</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Specify a thread implementation to use. Available options are
|
|
||||||
'posix' or 'win32'. Normally, <command>configure</command>
|
|
||||||
should be able to work out the system threads API on its own.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-regex</systemitem> and
|
|
||||||
<systemitem>--enable-regex</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Do not compile GLib with regular expression support.
|
|
||||||
GLib will be smaller because it will not need the
|
|
||||||
PCRE library. This is however not recommended, as
|
|
||||||
programs may need GRegex.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-pcre</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Specify whether to use the internal or the system-supplied
|
|
||||||
PCRE library.
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
'internal' means that GRegex will be compiled to use
|
|
||||||
the internal PCRE library.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
'system' means that GRegex will be compiled to use
|
|
||||||
the system-supplied PCRE library.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
Using the internal PCRE is the preferred solution:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
System-supplied PCRE has a separated copy of the big tables
|
|
||||||
used for Unicode handling.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Some systems have PCRE libraries compiled without some needed
|
|
||||||
features, such as UTF-8 and Unicode support.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
PCRE uses some global variables for memory management and
|
|
||||||
other features. In the rare case of a program using both
|
|
||||||
GRegex and PCRE (maybe indirectly through a library),
|
|
||||||
this variables could lead to problems when they are modified.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-included-printf</systemitem> and
|
|
||||||
<systemitem>--enable-included-printf</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether the C library provides a suitable set
|
|
||||||
of printf() functions. In detail, <command>configure</command>
|
|
||||||
checks that the semantics of snprintf() are as specified by C99
|
|
||||||
and that positional parameters as specified in the Single Unix
|
|
||||||
Specification are supported. If this not the case, GLib will
|
|
||||||
include an implementation of the printf() family.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
These options can be used to explicitly control whether
|
|
||||||
an implementation of the printf() family should be included or not.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-Bsymbolic</systemitem> and
|
|
||||||
<systemitem>--enable-Bsymbolic</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default, GLib uses the -Bsymbolic-functions linker
|
|
||||||
flag to avoid intra-library PLT jumps. A side-effect
|
|
||||||
of this is that it is no longer possible to override
|
|
||||||
internal uses of GLib functions with
|
|
||||||
<envar>LD_PRELOAD</envar>. Therefore, it may make
|
|
||||||
sense to turn this feature off in some situations.
|
|
||||||
The <option>--disable-Bsymbolic</option> option allows
|
|
||||||
to do that.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-gtk-doc</systemitem> and
|
|
||||||
<systemitem>--enable-gtk-doc</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether the
|
|
||||||
<application>gtk-doc</application> package is installed.
|
|
||||||
If it is, then it will use it to extract and build the
|
|
||||||
documentation for the GLib library. These options
|
|
||||||
can be used to explicitly control whether
|
|
||||||
<application>gtk-doc</application> should be
|
|
||||||
used or not. If it is not used, the distributed,
|
|
||||||
pre-generated HTML files will be installed instead of
|
|
||||||
building them on your machine.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-man</systemitem> and
|
|
||||||
<systemitem>--enable-man</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether <application>xsltproc</application>
|
|
||||||
and the necessary Docbook stylesheets are installed.
|
|
||||||
If they are, then it will use them to rebuild the included
|
|
||||||
man pages from the XML sources. These options can be used
|
|
||||||
to explicitly control whether man pages should be rebuilt
|
|
||||||
used or not. The distribution includes pre-generated man
|
|
||||||
pages.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-xattr</systemitem> and
|
|
||||||
<systemitem>--enable-xattr</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether the getxattr() family of functions
|
|
||||||
is available. If it is, then extended attribute support
|
|
||||||
will be included in GIO. These options can be used to
|
|
||||||
explicitly control whether extended attribute support
|
|
||||||
should be included or not. getxattr() and friends can
|
|
||||||
be provided by glibc or by the standalone libattr library.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-selinux</systemitem> and
|
|
||||||
<systemitem>--enable-selinux</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will
|
|
||||||
auto-detect if libselinux is available and include
|
|
||||||
SELinux support in GIO if it is. These options can be
|
|
||||||
used to explicitly control whether SELinux support should
|
|
||||||
be included.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-dtrace</systemitem> and
|
|
||||||
<systemitem>--enable-dtrace</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will
|
|
||||||
detect if DTrace support is available, and use it.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-systemtap</systemitem> and
|
|
||||||
<systemitem>--enable-systemtap</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This option requires DTrace support. If it is available, then
|
|
||||||
the <command>configure</command> script will also check for
|
|
||||||
the presence of SystemTap.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--enable-gcov</systemitem> and
|
|
||||||
<systemitem>--disable-gcov</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Enable the generation of coverage reports for the GLib tests.
|
|
||||||
This requires the lcov frontend to gcov from the
|
|
||||||
<ulink url="http://ltp.sourceforge.net">Linux Test Project</ulink>.
|
|
||||||
To generate a coverage report, use the lcov make target. The
|
|
||||||
report is placed in the <filename>glib-lcov</filename> directory.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-runtime-libdir=RELPATH</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Allows specifying a relative path to where to install the runtime
|
|
||||||
libraries (meaning library files used for running, not developing,
|
|
||||||
GLib applications). This can be used in operating system setups where
|
|
||||||
programs using GLib needs to run before e.g. <filename>/usr</filename>
|
|
||||||
is mounted.
|
|
||||||
For example, if LIBDIR is <filename>/usr/lib</filename> and
|
|
||||||
<filename>../../lib</filename> is passed to
|
|
||||||
<systemitem>--with-runtime-libdir</systemitem> then the
|
|
||||||
runtime libraries are installed into <filename>/lib</filename> rather
|
|
||||||
than <filename>/usr/lib</filename>.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-python</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Allows specifying the Python interpreter to use, either as an absolute path,
|
|
||||||
or as a program name. GLib can be built with Python 2 (at least version 2.5)
|
|
||||||
or Python 3.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
</refentry>
|
</refentry>
|
||||||
|
@ -2,549 +2,23 @@
|
|||||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||||
]>
|
]>
|
||||||
<refentry id="glib-building">
|
<refentry id="extending">
|
||||||
<refmeta>
|
<refmeta>
|
||||||
<refentrytitle>Compiling the GLib package</refentrytitle>
|
<refentrytitle>Extending VIPS</refentrytitle>
|
||||||
<manvolnum>3</manvolnum>
|
<manvolnum>3</manvolnum>
|
||||||
<refmiscinfo>GLib Library</refmiscinfo>
|
<refmiscinfo>VIPS Library</refmiscinfo>
|
||||||
</refmeta>
|
</refmeta>
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>Compiling the GLib Package</refname>
|
<refname>Extending</refname>
|
||||||
<refpurpose>How to compile GLib itself</refpurpose>
|
<refpurpose>How to add operations to VIPS</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsect1 id="building">
|
<refsect1 id="extending-subclassing">
|
||||||
<title>Building the Library on UNIX</title>
|
<title>Adding operations to VIPS</title>
|
||||||
<para>
|
<para>
|
||||||
On UNIX, GLib uses the standard GNU build system,
|
all about subclassing.
|
||||||
using <application>autoconf</application> for package
|
|
||||||
configuration and resolving portability issues,
|
|
||||||
<application>automake</application> for building makefiles
|
|
||||||
that comply with the GNU Coding Standards, and
|
|
||||||
<application>libtool</application> for building shared
|
|
||||||
libraries on multiple platforms. The normal sequence for
|
|
||||||
compiling and installing the GLib library is thus:
|
|
||||||
|
|
||||||
<literallayout>
|
|
||||||
<userinput>./configure</userinput>
|
|
||||||
<userinput>make</userinput>
|
|
||||||
<userinput>make install</userinput>
|
|
||||||
</literallayout>
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
The standard options provided by <application>GNU
|
|
||||||
autoconf</application> may be passed to the
|
|
||||||
<command>configure</command> script. Please see the
|
|
||||||
<application>autoconf</application> documentation or run
|
|
||||||
<command>./configure --help</command> for information about
|
|
||||||
the standard options.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The GTK+ documentation contains
|
|
||||||
<ulink url="../gtk/gtk-building.html">further details</ulink>
|
|
||||||
about the build process and ways to influence it.
|
|
||||||
</para>
|
|
||||||
</refsect1>
|
|
||||||
<refsect1 id="dependencies">
|
|
||||||
<title>Dependencies</title>
|
|
||||||
<para>
|
|
||||||
Before you can compile the GLib library, you need to have
|
|
||||||
various other tools and libraries installed on your system.
|
|
||||||
Beyond a C compiler (which must implement C90, but does not need
|
|
||||||
to implement C99), the two tools needed during the build process
|
|
||||||
(as differentiated from the tools used in when creating GLib
|
|
||||||
mentioned above such as <application>autoconf</application>) are
|
|
||||||
<command>pkg-config</command> and GNU make.
|
|
||||||
</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<ulink url="http://www.freedesktop.org/software/pkgconfig/">pkg-config</ulink>
|
|
||||||
is a tool for tracking the compilation flags needed for
|
|
||||||
libraries that are used by the GLib library. (For each
|
|
||||||
library, a small <literal>.pc</literal> text file is
|
|
||||||
installed in a standard location that contains the compilation
|
|
||||||
flags needed for that library along with version number
|
|
||||||
information.) The version of <command>pkg-config</command>
|
|
||||||
needed to build GLib is mirrored in the
|
|
||||||
<filename>dependencies</filename> directory
|
|
||||||
on the <ulink url="ftp://ftp.gtk.org/pub/gtk/v2.2/">GTK+ FTP
|
|
||||||
site.</ulink>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The GLib Makefiles make use of several features specific to
|
|
||||||
<ulink url="http://www.gnu.org/software/make">GNU
|
|
||||||
make</ulink>, and will not build correctly with other
|
|
||||||
versions of <command>make</command>. You will need to
|
|
||||||
install it if you don't already have it on your system. (It
|
|
||||||
may be called <command>gmake</command> rather than
|
|
||||||
<command>make</command>.)
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
<para>
|
|
||||||
A UNIX build of GLib requires that the system implements at
|
|
||||||
least the original 1990 version of POSIX. Beyond this, it
|
|
||||||
depends on a number of other libraries.
|
|
||||||
</para>
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The <ulink url="http://www.gnu.org/software/libiconv/">GNU
|
|
||||||
libiconv library</ulink> is needed to build GLib if your
|
|
||||||
system doesn't have the <function>iconv()</function>
|
|
||||||
function for doing conversion between character
|
|
||||||
encodings. Most modern systems should have
|
|
||||||
<function>iconv()</function>, however many older systems lack
|
|
||||||
an <function>iconv()</function> implementation. On such systems,
|
|
||||||
you must install the libiconv library. This can be found at:
|
|
||||||
<ulink url="http://www.gnu.org/software/libiconv">http://www.gnu.org/software/libiconv</ulink>.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If your system has an <function>iconv()</function> implementation but
|
|
||||||
you want to use libiconv instead, you can pass the
|
|
||||||
--with-libiconv option to configure. This forces
|
|
||||||
libiconv to be used.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
Note that if you have libiconv installed in your default include
|
|
||||||
search path (for instance, in <filename>/usr/local/</filename>), but
|
|
||||||
don't enable it, you will get an error while compiling GLib because
|
|
||||||
the <filename>iconv.h</filename> that libiconv installs hides the
|
|
||||||
system iconv.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you are using the native iconv implementation on Solaris
|
|
||||||
instead of libiconv, you'll need to make sure that you have
|
|
||||||
the converters between locale encodings and UTF-8 installed.
|
|
||||||
At a minimum you'll need the SUNWuiu8 package. You probably
|
|
||||||
should also install the SUNWciu8, SUNWhiu8, SUNWjiu8, and
|
|
||||||
SUNWkiu8 packages.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
The native iconv on Compaq Tru64 doesn't contain support for
|
|
||||||
UTF-8, so you'll need to use GNU libiconv instead. (When
|
|
||||||
using GNU libiconv for GLib, you'll need to use GNU libiconv
|
|
||||||
for GNU gettext as well.) This probably applies to related
|
|
||||||
operating systems as well.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The libintl library from the <ulink
|
|
||||||
url="http://www.gnu.org/software/gettext">GNU gettext
|
|
||||||
package</ulink> is needed if your system doesn't have the
|
|
||||||
<function>gettext()</function> functionality for handling
|
|
||||||
message translation databases.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
A thread implementation is needed. The thread support in GLib
|
|
||||||
can be based upon POSIX threads or win32 threads.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
GRegex uses the <ulink url="http://www.pcre.org/">PCRE library</ulink>
|
|
||||||
for regular expression matching. The default is to use the internal
|
|
||||||
version of PCRE that is patched to use GLib for memory management
|
|
||||||
and Unicode handling. If you prefer to use the system-supplied PCRE
|
|
||||||
library you can pass the <option>--with-pcre=system</option> option
|
|
||||||
to, but it is not recommended.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional extended attribute support in GIO requires the
|
|
||||||
getxattr() family of functions that may be provided by glibc or
|
|
||||||
by the standalone libattr library. To build GLib without extended
|
|
||||||
attribute support, use the <option>--disable-xattr</option>
|
|
||||||
option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional SELinux support in GIO requires libselinux.
|
|
||||||
To build GLib without SELinux support, use the
|
|
||||||
<option>--disable-selinux</option> option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional support for DTrace requires the
|
|
||||||
<filename>sys/sdt.h</filename> header, which is provided
|
|
||||||
by SystemTap on Linux. To build GLib without DTrace, use
|
|
||||||
the <option>--disable-dtrace</option> configure option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The optional support for
|
|
||||||
<ulink url="http://sourceware.org/systemtap/">SystemTap</ulink>
|
|
||||||
can be disabled with the <option>--disable-systemtap</option>
|
|
||||||
configure option.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
|
|
||||||
</refsect1>
|
|
||||||
<refsect1 id="extra-configuration-options">
|
|
||||||
<title>Extra Configuration Options</title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
In addition to the normal options, the
|
|
||||||
<command>configure</command> script in the GLib
|
|
||||||
library supports these additional arguments:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--enable-debug</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Turns on various amounts of debugging support. Setting this to 'no'
|
|
||||||
disables g_assert(), g_return_if_fail(), g_return_val_if_fail() and
|
|
||||||
all cast checks between different object types. Setting it to 'minimum' disables only cast checks. Setting it to 'yes' enables
|
|
||||||
<link linkend="G-DEBUG:CAPS">runtime debugging</link>.
|
|
||||||
The default is 'minimum'.
|
|
||||||
Note that 'no' is fast, but dangerous as it tends to destabilize
|
|
||||||
even mostly bug-free software by changing the effect of many bugs
|
|
||||||
from simple warnings into fatal crashes. Thus
|
|
||||||
<option>--enable-debug=no</option> should <emphasis>not</emphasis>
|
|
||||||
be used for stable releases of GLib.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-gc-friendly</systemitem> and
|
|
||||||
<systemitem>--enable-gc-friendly</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default, and with <systemitem>--disable-gc-friendly</systemitem>
|
|
||||||
as well, Glib does not clear the memory for certain objects before
|
|
||||||
they are freed. For example, Glib may decide to recycle GList nodes
|
|
||||||
by putting them in a free list. However, memory profiling and debugging
|
|
||||||
tools like <ulink url="http://www.valgrind.org">Valgrind</ulink> work
|
|
||||||
better if an application does not keep dangling pointers to freed
|
|
||||||
memory (even though these pointers are no longer dereferenced), or
|
|
||||||
invalid pointers inside uninitialized memory.
|
|
||||||
The <systemitem>--enable-gc-friendly</systemitem> option makes Glib
|
|
||||||
clear memory in these situations:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When shrinking a GArray, Glib will clear the memory no longer
|
|
||||||
available in the array: shrink an array from 10 bytes to 7, and
|
|
||||||
the last 3 bytes will be cleared. This includes removals of single
|
|
||||||
and multiple elements.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When growing a GArray, Glib will clear the new chunk of memory.
|
|
||||||
Grow an array from 7 bytes to 10 bytes, and the last 3 bytes will
|
|
||||||
be cleared.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
The above applies to GPtrArray as well.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When freeing a node from a GHashTable, Glib will first clear
|
|
||||||
the node, which used to have pointers to the key and the value
|
|
||||||
stored at that node.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
When destroying or removing a GTree node, Glib will clear the node,
|
|
||||||
which used to have pointers to the node's value, and the left and
|
|
||||||
right subnodes.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Since clearing the memory has a cost,
|
|
||||||
<systemitem>--disable-gc-friendly</systemitem> is the default.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-mem-pools</systemitem> and
|
|
||||||
<systemitem>--enable-mem-pools</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Many small chunks of memory are often allocated via collective pools
|
|
||||||
in GLib and are cached after release to speed up reallocations.
|
|
||||||
For sparse memory systems this behaviour is often inferior, so
|
|
||||||
memory pools can be disabled to avoid excessive caching and force
|
|
||||||
atomic maintenance of chunks through the <function>g_malloc()</function>
|
|
||||||
and <function>g_free()</function> functions. Code currently affected by
|
|
||||||
this:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<structname>GMemChunk</structname>s become basically non-effective
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<structname>GSignal</structname> disables all caching
|
|
||||||
(potentially very slow)
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
<structname>GType</structname> doesn't honour the
|
|
||||||
<structname>GTypeInfo</structname>
|
|
||||||
<structfield>n_preallocs</structfield> field anymore
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
the <structname>GBSearchArray</structname> flag
|
|
||||||
<literal>G_BSEARCH_ALIGN_POWER2</literal> becomes non-functional
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-threads</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Specify a thread implementation to use. Available options are
|
|
||||||
'posix' or 'win32'. Normally, <command>configure</command>
|
|
||||||
should be able to work out the system threads API on its own.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-regex</systemitem> and
|
|
||||||
<systemitem>--enable-regex</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Do not compile GLib with regular expression support.
|
|
||||||
GLib will be smaller because it will not need the
|
|
||||||
PCRE library. This is however not recommended, as
|
|
||||||
programs may need GRegex.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-pcre</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Specify whether to use the internal or the system-supplied
|
|
||||||
PCRE library.
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
'internal' means that GRegex will be compiled to use
|
|
||||||
the internal PCRE library.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
'system' means that GRegex will be compiled to use
|
|
||||||
the system-supplied PCRE library.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
Using the internal PCRE is the preferred solution:
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
System-supplied PCRE has a separated copy of the big tables
|
|
||||||
used for Unicode handling.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Some systems have PCRE libraries compiled without some needed
|
|
||||||
features, such as UTF-8 and Unicode support.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
PCRE uses some global variables for memory management and
|
|
||||||
other features. In the rare case of a program using both
|
|
||||||
GRegex and PCRE (maybe indirectly through a library),
|
|
||||||
this variables could lead to problems when they are modified.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-included-printf</systemitem> and
|
|
||||||
<systemitem>--enable-included-printf</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether the C library provides a suitable set
|
|
||||||
of printf() functions. In detail, <command>configure</command>
|
|
||||||
checks that the semantics of snprintf() are as specified by C99
|
|
||||||
and that positional parameters as specified in the Single Unix
|
|
||||||
Specification are supported. If this not the case, GLib will
|
|
||||||
include an implementation of the printf() family.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
These options can be used to explicitly control whether
|
|
||||||
an implementation of the printf() family should be included or not.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-Bsymbolic</systemitem> and
|
|
||||||
<systemitem>--enable-Bsymbolic</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default, GLib uses the -Bsymbolic-functions linker
|
|
||||||
flag to avoid intra-library PLT jumps. A side-effect
|
|
||||||
of this is that it is no longer possible to override
|
|
||||||
internal uses of GLib functions with
|
|
||||||
<envar>LD_PRELOAD</envar>. Therefore, it may make
|
|
||||||
sense to turn this feature off in some situations.
|
|
||||||
The <option>--disable-Bsymbolic</option> option allows
|
|
||||||
to do that.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-gtk-doc</systemitem> and
|
|
||||||
<systemitem>--enable-gtk-doc</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether the
|
|
||||||
<application>gtk-doc</application> package is installed.
|
|
||||||
If it is, then it will use it to extract and build the
|
|
||||||
documentation for the GLib library. These options
|
|
||||||
can be used to explicitly control whether
|
|
||||||
<application>gtk-doc</application> should be
|
|
||||||
used or not. If it is not used, the distributed,
|
|
||||||
pre-generated HTML files will be installed instead of
|
|
||||||
building them on your machine.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-man</systemitem> and
|
|
||||||
<systemitem>--enable-man</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether <application>xsltproc</application>
|
|
||||||
and the necessary Docbook stylesheets are installed.
|
|
||||||
If they are, then it will use them to rebuild the included
|
|
||||||
man pages from the XML sources. These options can be used
|
|
||||||
to explicitly control whether man pages should be rebuilt
|
|
||||||
used or not. The distribution includes pre-generated man
|
|
||||||
pages.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-xattr</systemitem> and
|
|
||||||
<systemitem>--enable-xattr</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will try
|
|
||||||
to auto-detect whether the getxattr() family of functions
|
|
||||||
is available. If it is, then extended attribute support
|
|
||||||
will be included in GIO. These options can be used to
|
|
||||||
explicitly control whether extended attribute support
|
|
||||||
should be included or not. getxattr() and friends can
|
|
||||||
be provided by glibc or by the standalone libattr library.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-selinux</systemitem> and
|
|
||||||
<systemitem>--enable-selinux</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will
|
|
||||||
auto-detect if libselinux is available and include
|
|
||||||
SELinux support in GIO if it is. These options can be
|
|
||||||
used to explicitly control whether SELinux support should
|
|
||||||
be included.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-dtrace</systemitem> and
|
|
||||||
<systemitem>--enable-dtrace</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
By default the <command>configure</command> script will
|
|
||||||
detect if DTrace support is available, and use it.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--disable-systemtap</systemitem> and
|
|
||||||
<systemitem>--enable-systemtap</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
This option requires DTrace support. If it is available, then
|
|
||||||
the <command>configure</command> script will also check for
|
|
||||||
the presence of SystemTap.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--enable-gcov</systemitem> and
|
|
||||||
<systemitem>--disable-gcov</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Enable the generation of coverage reports for the GLib tests.
|
|
||||||
This requires the lcov frontend to gcov from the
|
|
||||||
<ulink url="http://ltp.sourceforge.net">Linux Test Project</ulink>.
|
|
||||||
To generate a coverage report, use the lcov make target. The
|
|
||||||
report is placed in the <filename>glib-lcov</filename> directory.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-runtime-libdir=RELPATH</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Allows specifying a relative path to where to install the runtime
|
|
||||||
libraries (meaning library files used for running, not developing,
|
|
||||||
GLib applications). This can be used in operating system setups where
|
|
||||||
programs using GLib needs to run before e.g. <filename>/usr</filename>
|
|
||||||
is mounted.
|
|
||||||
For example, if LIBDIR is <filename>/usr/lib</filename> and
|
|
||||||
<filename>../../lib</filename> is passed to
|
|
||||||
<systemitem>--with-runtime-libdir</systemitem> then the
|
|
||||||
runtime libraries are installed into <filename>/lib</filename> rather
|
|
||||||
than <filename>/usr/lib</filename>.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
|
|
||||||
<formalpara>
|
|
||||||
<title><systemitem>--with-python</systemitem></title>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
Allows specifying the Python interpreter to use, either as an absolute path,
|
|
||||||
or as a program name. GLib can be built with Python 2 (at least version 2.5)
|
|
||||||
or Python 3.
|
|
||||||
</para>
|
|
||||||
</formalpara>
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
</refentry>
|
</refentry>
|
||||||
|
@ -21,27 +21,41 @@
|
|||||||
docs for full details, but this section will try to give a brief
|
docs for full details, but this section will try to give a brief
|
||||||
overview. The <command>vips</command> program is handy for getting a
|
overview. The <command>vips</command> program is handy for getting a
|
||||||
summary of an operation's parameters.
|
summary of an operation's parameters.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
When your program starts, use <function>vips_init()</function> to set up
|
When your program starts, use <function>vips_init()</function> to set up
|
||||||
the VIPS library. You should pass it the name of your program, usually
|
the VIPS library. You should pass it the name of your program, usually
|
||||||
<literal>argv[0]</literal>. Use <function>vips_shutdown()</function>
|
<literal>argv[0]</literal>. Use <function>vips_shutdown()</function>
|
||||||
when you exit.
|
when you exit.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
You can add the VIPS flags to your GObject command-line processing
|
You can add the VIPS flags to your GObject command-line processing
|
||||||
with vips_get_option_group(), see below.
|
with vips_get_option_group(), see below.
|
||||||
|
</para>
|
||||||
|
|
||||||
The basic data object is #VipsImage. You can create an image from a
|
<para>
|
||||||
file on disc or from an area of memory, either as a C-style array,
|
The basic data object is the #VipsImage, see <link
|
||||||
or as a formatted object, like JPEG. See vips_image_new_from_file() and
|
linkend="VipsImage">VIPS Image</link> for details on the
|
||||||
friends.
|
image class. You can create an image from a file on disc or from an
|
||||||
Loading an image is fast. VIPS read just enough of the image to be able
|
area of memory, either as a C-style array, or as a formatted object,
|
||||||
to get the various properties, such as width in pixels. It delays
|
like JPEG. See vips_image_new_from_file() and friends. Loading an
|
||||||
reading any pixels until they are really needed.
|
image is fast. VIPS read just enough of the image to be able to get
|
||||||
|
the various properties, such as width in pixels. It delays reading
|
||||||
|
any pixels until they are really needed.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
Once you have an image, you can get properties from it in the usual way.
|
Once you have an image, you can get properties from it in the usual way.
|
||||||
You can use projection functions like vips_image_get_width(), or
|
You can use projection functions, like vips_image_get_width() or
|
||||||
g_object_get() to get GObject properties.
|
g_object_get(), to get GObject properties. All VIPS objects are
|
||||||
|
immutable, meaning you can only get properties, you can't set them.
|
||||||
|
See <link linkend="libvips-header">VIPS Header</link> to read about
|
||||||
|
image properties.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
VIPS is based on the GObject library and is therefore refcounted.
|
VIPS is based on the GObject library and is therefore refcounted.
|
||||||
vips_image_new_from_file() returns an object with a count of 1.
|
vips_image_new_from_file() returns an object with a count of 1.
|
||||||
When you are done with an image, use g_object_unref() to dispose of it.
|
When you are done with an image, use g_object_unref() to dispose of it.
|
||||||
@ -49,25 +63,89 @@
|
|||||||
copy of the image, it will ref it. So you can unref an image as soon as
|
copy of the image, it will ref it. So you can unref an image as soon as
|
||||||
you no longer need it, you don't need to hang on to it in case anyone
|
you no longer need it, you don't need to hang on to it in case anyone
|
||||||
else is still using it.
|
else is still using it.
|
||||||
|
|
||||||
VIPS images are three-dimensional arrays, the dimensions being width,
|
|
||||||
height and bands. Each dimension can be up to 2 ** 31 pixels (or band
|
|
||||||
elements). An image has a format, meaning the machine number type used
|
|
||||||
to represent each value. VIPS supports 10 formats, from 8-bit unsigned
|
|
||||||
integer up to 128-bit double complex, see #VipsBandFormat.
|
|
||||||
|
|
||||||
In VIPS, images are uninterpreted arrays, meaning that from the point of
|
|
||||||
view of most operations, they are just large collections of numbers.
|
|
||||||
There's no difference between an RGBA (RGB with alpha) image and a CMYK
|
|
||||||
image, for example, they are both just four-band images. It's up to the
|
|
||||||
user of the library to pass the right sort of image to each operation.
|
|
||||||
|
|
||||||
To take an example, VIPS has vips_Lab2XYZ(), an operation to transform
|
|
||||||
an image from CIE LAB colour space to CIE XYZ space. It assumes the
|
|
||||||
first three bands represent pixels in LAB colour space and returns an
|
|
||||||
image where the first three bands
|
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Use things like vips_invert() to manipulate your images. See <link
|
||||||
|
linkend="VipsOperation">VIPS Operations</link> for information on
|
||||||
|
running operations on images. When you are done, you can write
|
||||||
|
the final image to a disc file, to a formatted memory buffer, or to
|
||||||
|
C-style memory array. See vips_image_write_to_file() and friends.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
VIPS keeps a log of error message, see <link
|
||||||
|
linkend="libvips-error">VIPS Error</link> to find out how to get and
|
||||||
|
set the error log.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>VIPS from C example</title>
|
||||||
|
<programlisting language="C">
|
||||||
|
/* compile with:
|
||||||
|
*
|
||||||
|
* gcc -g -Wall try211.c `pkg-config vips --cflags --libs`
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <vips/vips.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
GOptionContext *context;
|
||||||
|
GOptionGroup *main_group;
|
||||||
|
GError *error = NULL;
|
||||||
|
VipsImage *in;
|
||||||
|
double mean;
|
||||||
|
VipsImage *out;
|
||||||
|
|
||||||
|
if( vips_init( argv[0] ) )
|
||||||
|
vips_error_exit( NULL );
|
||||||
|
|
||||||
|
context = g_option_context_new( "hello infile outfile - VIPS demo" );
|
||||||
|
|
||||||
|
main_group = g_option_group_new( NULL, NULL, NULL, NULL, NULL );
|
||||||
|
g_option_context_set_main_group( context, main_group );
|
||||||
|
g_option_context_add_group( context, vips_get_option_group() );
|
||||||
|
|
||||||
|
if( !g_option_context_parse( context, &argc, &argv, &error ) ) {
|
||||||
|
if( error ) {
|
||||||
|
fprintf( stderr, "%s\n", error->message );
|
||||||
|
g_error_free( error );
|
||||||
|
}
|
||||||
|
|
||||||
|
vips_error_exit( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( argc != 3 )
|
||||||
|
vips_error_exit( "usage: %s infile outfile", argv[0] );
|
||||||
|
|
||||||
|
if( !(in = vips_image_new_from_file( argv[1], NULL )) )
|
||||||
|
vips_error_exit( NULL );
|
||||||
|
|
||||||
|
printf( "image width = %d\n", vips_image_get_width( in ) );
|
||||||
|
|
||||||
|
if( vips_avg( in, &mean, NULL ) )
|
||||||
|
vips_error_exit( NULL );
|
||||||
|
|
||||||
|
printf( "mean pixel value = %g\n", mean );
|
||||||
|
|
||||||
|
if( vips_invert( in, &out, NULL ) )
|
||||||
|
vips_error_exit( NULL );
|
||||||
|
|
||||||
|
g_object_unref( in );
|
||||||
|
|
||||||
|
if( vips_image_write_to_file( out, argv[2], NULL ) )
|
||||||
|
vips_error_exit( NULL );
|
||||||
|
|
||||||
|
g_object_unref( out );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
</refentry>
|
</refentry>
|
||||||
|
@ -76,7 +76,7 @@ typedef struct _VipsBuildlut {
|
|||||||
int xlow; /* Index 0 in output is this x */
|
int xlow; /* Index 0 in output is this x */
|
||||||
int lut_size; /* Number of output elements to generate */
|
int lut_size; /* Number of output elements to generate */
|
||||||
double **data; /* Matrix row pointers */
|
double **data; /* Matrix row pointers */
|
||||||
double *buf; /* Ouput buffer */
|
double *buf; /* Output buffer */
|
||||||
} VipsBuildlut;
|
} VipsBuildlut;
|
||||||
|
|
||||||
typedef VipsCreateClass VipsBuildlutClass;
|
typedef VipsCreateClass VipsBuildlutClass;
|
||||||
|
@ -2307,6 +2307,7 @@ vips_openexrload( const char *filename, VipsImage **out, ... )
|
|||||||
*
|
*
|
||||||
* @level: load this level
|
* @level: load this level
|
||||||
* @associated: load this associated image
|
* @associated: load this associated image
|
||||||
|
* @autocrop: crop to image bounds
|
||||||
*
|
*
|
||||||
* Read a virtual slide supported by the OpenSlide library into a VIPS image.
|
* Read a virtual slide supported by the OpenSlide library into a VIPS image.
|
||||||
* OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle,
|
* OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle,
|
||||||
@ -2324,8 +2325,7 @@ vips_openexrload( const char *filename, VipsImage **out, ... )
|
|||||||
* A slide's associated images are listed in the
|
* A slide's associated images are listed in the
|
||||||
* "slide-associated-images" metadata item.
|
* "slide-associated-images" metadata item.
|
||||||
*
|
*
|
||||||
* The output of this operator is in pre-multipled ARGB format. Use
|
* The output of this operator is always RGBA.
|
||||||
* im_argb2rgba() to decode to png-style RGBA.
|
|
||||||
*
|
*
|
||||||
* See also: vips_image_new_from_file().
|
* See also: vips_image_new_from_file().
|
||||||
*
|
*
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
* - always output solid (not transparent) pixels
|
* - always output solid (not transparent) pixels
|
||||||
* 25/1/14
|
* 25/1/14
|
||||||
* - use openslide_detect_vendor() on >= 3.4.0
|
* - use openslide_detect_vendor() on >= 3.4.0
|
||||||
|
* 30/7/14
|
||||||
|
* - add autocrop toggle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -92,6 +94,11 @@ typedef struct {
|
|||||||
|
|
||||||
char *associated;
|
char *associated;
|
||||||
|
|
||||||
|
/* Crop to image bounds if @autocrop is set.
|
||||||
|
*/
|
||||||
|
gboolean autocrop;
|
||||||
|
VipsRect bounds;
|
||||||
|
|
||||||
/* Only valid if associated == NULL.
|
/* Only valid if associated == NULL.
|
||||||
*/
|
*/
|
||||||
int32_t level;
|
int32_t level;
|
||||||
@ -178,9 +185,39 @@ check_associated_image( openslide_t *osr, const char *name )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_bounds( openslide_t *osr, VipsRect *rect )
|
||||||
|
{
|
||||||
|
static const char *openslide_names[] = {
|
||||||
|
"openslide.bounds-x",
|
||||||
|
"openslide.bounds-y",
|
||||||
|
"openslide.bounds-width",
|
||||||
|
"openslide.bounds-height"
|
||||||
|
};
|
||||||
|
static int vips_offsets[] = {
|
||||||
|
G_STRUCT_OFFSET( VipsRect, left ),
|
||||||
|
G_STRUCT_OFFSET( VipsRect, top ),
|
||||||
|
G_STRUCT_OFFSET( VipsRect, width ),
|
||||||
|
G_STRUCT_OFFSET( VipsRect, height )
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *value;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i = 0; i < 4; i++ ) {
|
||||||
|
if( !(value = openslide_get_property_value( osr,
|
||||||
|
openslide_names[i] )) )
|
||||||
|
return( FALSE );
|
||||||
|
G_STRUCT_MEMBER( int, rect, vips_offsets[i] ) =
|
||||||
|
atoi( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
static ReadSlide *
|
static ReadSlide *
|
||||||
readslide_new( const char *filename, VipsImage *out,
|
readslide_new( const char *filename, VipsImage *out,
|
||||||
int level, const char *associated )
|
int level, gboolean autocrop, const char *associated )
|
||||||
{
|
{
|
||||||
ReadSlide *rslide;
|
ReadSlide *rslide;
|
||||||
int64_t w, h;
|
int64_t w, h;
|
||||||
@ -188,7 +225,8 @@ readslide_new( const char *filename, VipsImage *out,
|
|||||||
const char *background;
|
const char *background;
|
||||||
const char * const *properties;
|
const char * const *properties;
|
||||||
|
|
||||||
if( level && associated ) {
|
if( level &&
|
||||||
|
associated ) {
|
||||||
vips_error( "openslide2vips",
|
vips_error( "openslide2vips",
|
||||||
"%s", _( "specify only one of level or associated "
|
"%s", _( "specify only one of level or associated "
|
||||||
"image" ) );
|
"image" ) );
|
||||||
@ -201,6 +239,7 @@ readslide_new( const char *filename, VipsImage *out,
|
|||||||
rslide );
|
rslide );
|
||||||
|
|
||||||
rslide->level = level;
|
rslide->level = level;
|
||||||
|
rslide->autocrop = autocrop;
|
||||||
rslide->associated = g_strdup( associated );
|
rslide->associated = g_strdup( associated );
|
||||||
|
|
||||||
/* Non-crazy defaults, override below if we can.
|
/* Non-crazy defaults, override below if we can.
|
||||||
@ -264,6 +303,39 @@ readslide_new( const char *filename, VipsImage *out,
|
|||||||
rslide->tile_height = atoi( value );
|
rslide->tile_height = atoi( value );
|
||||||
if( value )
|
if( value )
|
||||||
VIPS_DEBUG_MSG( "readslide_new: found tile-size\n" );
|
VIPS_DEBUG_MSG( "readslide_new: found tile-size\n" );
|
||||||
|
|
||||||
|
/* Some images have a bounds in the header. Crop to
|
||||||
|
* that if autocrop is set.
|
||||||
|
*/
|
||||||
|
if( rslide->autocrop )
|
||||||
|
if( !get_bounds( rslide->osr, &rslide->bounds ) )
|
||||||
|
rslide->autocrop = FALSE;
|
||||||
|
if( rslide->autocrop ) {
|
||||||
|
VipsRect image;
|
||||||
|
|
||||||
|
rslide->bounds.left /= rslide->downsample;
|
||||||
|
rslide->bounds.top /= rslide->downsample;
|
||||||
|
rslide->bounds.width /= rslide->downsample;
|
||||||
|
rslide->bounds.height /= rslide->downsample;
|
||||||
|
|
||||||
|
/* Clip against image size.
|
||||||
|
*/
|
||||||
|
image.left = 0;
|
||||||
|
image.top = 0;
|
||||||
|
image.width = w;
|
||||||
|
image.height = h;
|
||||||
|
vips_rect_intersectrect( &rslide->bounds, &image,
|
||||||
|
&rslide->bounds );
|
||||||
|
|
||||||
|
/* If we've clipped to nothing, ignore bounds.
|
||||||
|
*/
|
||||||
|
if( vips_rect_isempty( &rslide->bounds ) )
|
||||||
|
rslide->autocrop = FALSE;
|
||||||
|
}
|
||||||
|
if( rslide->autocrop ) {
|
||||||
|
w = rslide->bounds.width;
|
||||||
|
h = rslide->bounds.height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rslide->bg = 0xffffff;
|
rslide->bg = 0xffffff;
|
||||||
@ -271,7 +343,9 @@ readslide_new( const char *filename, VipsImage *out,
|
|||||||
OPENSLIDE_PROPERTY_NAME_BACKGROUND_COLOR )) )
|
OPENSLIDE_PROPERTY_NAME_BACKGROUND_COLOR )) )
|
||||||
rslide->bg = strtoul( background, NULL, 16 );
|
rslide->bg = strtoul( background, NULL, 16 );
|
||||||
|
|
||||||
if( w < 0 || h < 0 || rslide->downsample < 0 ) {
|
if( w <= 0 ||
|
||||||
|
h <= 0 ||
|
||||||
|
rslide->downsample < 0 ) {
|
||||||
vips_error( "openslide2vips", _( "getting dimensions: %s" ),
|
vips_error( "openslide2vips", _( "getting dimensions: %s" ),
|
||||||
openslide_get_error( rslide->osr ) );
|
openslide_get_error( rslide->osr ) );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -283,6 +357,13 @@ readslide_new( const char *filename, VipsImage *out,
|
|||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !rslide->autocrop ) {
|
||||||
|
rslide->bounds.left = 0;
|
||||||
|
rslide->bounds.top = 0;
|
||||||
|
rslide->bounds.width = w;
|
||||||
|
rslide->bounds.height = h;
|
||||||
|
}
|
||||||
|
|
||||||
vips_image_init_fields( out, w, h, 4, VIPS_FORMAT_UCHAR,
|
vips_image_init_fields( out, w, h, 4, VIPS_FORMAT_UCHAR,
|
||||||
VIPS_CODING_NONE, VIPS_INTERPRETATION_RGB, 1.0, 1.0 );
|
VIPS_CODING_NONE, VIPS_INTERPRETATION_RGB, 1.0, 1.0 );
|
||||||
|
|
||||||
@ -301,9 +382,9 @@ readslide_new( const char *filename, VipsImage *out,
|
|||||||
|
|
||||||
int
|
int
|
||||||
vips__openslide_read_header( const char *filename, VipsImage *out,
|
vips__openslide_read_header( const char *filename, VipsImage *out,
|
||||||
int level, char *associated )
|
int level, gboolean autocrop, char *associated )
|
||||||
{
|
{
|
||||||
if( !readslide_new( filename, out, level, associated ) )
|
if( !readslide_new( filename, out, level, autocrop, associated ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -340,8 +421,8 @@ vips__openslide_generate( VipsRegion *out,
|
|||||||
|
|
||||||
openslide_read_region( rslide->osr,
|
openslide_read_region( rslide->osr,
|
||||||
buf,
|
buf,
|
||||||
r->left * rslide->downsample,
|
(r->left + rslide->bounds.left) * rslide->downsample,
|
||||||
r->top * rslide->downsample,
|
(r->top + rslide->bounds.top) * rslide->downsample,
|
||||||
rslide->level,
|
rslide->level,
|
||||||
r->width, r->height );
|
r->width, r->height );
|
||||||
|
|
||||||
@ -391,7 +472,8 @@ vips__openslide_generate( VipsRegion *out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips__openslide_read( const char *filename, VipsImage *out, int level )
|
vips__openslide_read( const char *filename, VipsImage *out,
|
||||||
|
int level, gboolean autocrop )
|
||||||
{
|
{
|
||||||
ReadSlide *rslide;
|
ReadSlide *rslide;
|
||||||
VipsImage *raw;
|
VipsImage *raw;
|
||||||
@ -403,7 +485,8 @@ vips__openslide_read( const char *filename, VipsImage *out, int level )
|
|||||||
raw = vips_image_new();
|
raw = vips_image_new();
|
||||||
vips_object_local( out, raw );
|
vips_object_local( out, raw );
|
||||||
|
|
||||||
if( !(rslide = readslide_new( filename, raw, level, NULL )) )
|
if( !(rslide = readslide_new( filename, raw,
|
||||||
|
level, autocrop, NULL )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_generate( raw,
|
if( vips_image_generate( raw,
|
||||||
@ -446,7 +529,7 @@ vips__openslide_read_associated( const char *filename, VipsImage *out,
|
|||||||
raw = vips_image_new_memory();
|
raw = vips_image_new_memory();
|
||||||
vips_object_local( out, raw );
|
vips_object_local( out, raw );
|
||||||
|
|
||||||
if( !(rslide = readslide_new( filename, raw, 0, associated )) ||
|
if( !(rslide = readslide_new( filename, raw, 0, FALSE, associated )) ||
|
||||||
vips_image_write_prepare( raw ) )
|
vips_image_write_prepare( raw ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
openslide_read_associated_image( rslide->osr, rslide->associated,
|
openslide_read_associated_image( rslide->osr, rslide->associated,
|
||||||
|
@ -37,9 +37,9 @@ extern "C" {
|
|||||||
|
|
||||||
int vips__openslide_isslide( const char *filename );
|
int vips__openslide_isslide( const char *filename );
|
||||||
int vips__openslide_read_header( const char *filename, VipsImage *out,
|
int vips__openslide_read_header( const char *filename, VipsImage *out,
|
||||||
int level, char *associated );
|
int level, gboolean autocrop, char *associated );
|
||||||
int vips__openslide_read( const char *filename, VipsImage *out,
|
int vips__openslide_read( const char *filename, VipsImage *out,
|
||||||
int level );
|
int level, gboolean autocrop );
|
||||||
int vips__openslide_read_associated( const char *filename, VipsImage *out,
|
int vips__openslide_read_associated( const char *filename, VipsImage *out,
|
||||||
const char *associated );
|
const char *associated );
|
||||||
|
|
||||||
|
@ -70,6 +70,10 @@ typedef struct _VipsForeignLoadOpenslide {
|
|||||||
*/
|
*/
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
|
/* Crop to image bounds.
|
||||||
|
*/
|
||||||
|
gboolean autocrop;
|
||||||
|
|
||||||
/* Load this associated image.
|
/* Load this associated image.
|
||||||
*/
|
*/
|
||||||
char *associated;
|
char *associated;
|
||||||
@ -109,7 +113,8 @@ vips_foreign_load_openslide_header( VipsForeignLoad *load )
|
|||||||
VipsForeignLoadOpenslide *openslide = (VipsForeignLoadOpenslide *) load;
|
VipsForeignLoadOpenslide *openslide = (VipsForeignLoadOpenslide *) load;
|
||||||
|
|
||||||
if( vips__openslide_read_header( openslide->filename, load->out,
|
if( vips__openslide_read_header( openslide->filename, load->out,
|
||||||
openslide->level, openslide->associated ) )
|
openslide->level, openslide->autocrop,
|
||||||
|
openslide->associated ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
VIPS_SETSTR( load->out->filename, openslide->filename );
|
VIPS_SETSTR( load->out->filename, openslide->filename );
|
||||||
@ -124,7 +129,7 @@ vips_foreign_load_openslide_load( VipsForeignLoad *load )
|
|||||||
|
|
||||||
if( !openslide->associated ) {
|
if( !openslide->associated ) {
|
||||||
if( vips__openslide_read( openslide->filename, load->real,
|
if( vips__openslide_read( openslide->filename, load->real,
|
||||||
openslide->level ) )
|
openslide->level, openslide->autocrop ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -190,7 +195,14 @@ vips_foreign_load_openslide_class_init( VipsForeignLoadOpenslideClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsForeignLoadOpenslide, level ),
|
G_STRUCT_OFFSET( VipsForeignLoadOpenslide, level ),
|
||||||
0, 100000, 0 );
|
0, 100000, 0 );
|
||||||
|
|
||||||
VIPS_ARG_STRING( class, "associated", 11,
|
VIPS_ARG_BOOL( class, "autocrop", 11,
|
||||||
|
_( "Autocrop" ),
|
||||||
|
_( "Crop to image bounds" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadOpenslide, autocrop ),
|
||||||
|
FALSE );
|
||||||
|
|
||||||
|
VIPS_ARG_STRING( class, "associated", 12,
|
||||||
_( "Associated" ),
|
_( "Associated" ),
|
||||||
_( "Load this associated image" ),
|
_( "Load this associated image" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
@ -254,7 +254,7 @@ vips_invfft_class_init( VipsInvfftClass *class )
|
|||||||
|
|
||||||
VIPS_ARG_BOOL( class, "real", 4,
|
VIPS_ARG_BOOL( class, "real", 4,
|
||||||
_( "Real" ),
|
_( "Real" ),
|
||||||
_( "Ouput only the real part of the transform" ),
|
_( "Output only the real part of the transform" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsInvfft, real ),
|
G_STRUCT_OFFSET( VipsInvfft, real ),
|
||||||
FALSE );
|
FALSE );
|
||||||
|
@ -582,7 +582,10 @@ vips_buffer_print( VipsBuffer *buffer )
|
|||||||
static void
|
static void
|
||||||
vips__buffer_init_cb( VipsBufferThread *buffer_thread )
|
vips__buffer_init_cb( VipsBufferThread *buffer_thread )
|
||||||
{
|
{
|
||||||
vips_error_exit( "vips_thread_shutdown() not called for thread %p",
|
/* This is a mem leak, not catastrophic.
|
||||||
|
*/
|
||||||
|
vips_warn( "VipsBuffer",
|
||||||
|
_( "vips_thread_shutdown() not called for thread %p" ),
|
||||||
g_thread_self() );
|
g_thread_self() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,9 @@ vips_thread_profile_save( VipsThreadProfile *profile )
|
|||||||
vips__file_open_write( "vips-profile.txt", TRUE );
|
vips__file_open_write( "vips-profile.txt", TRUE );
|
||||||
if( !vips__thread_fp ) {
|
if( !vips__thread_fp ) {
|
||||||
g_mutex_unlock( vips__global_lock );
|
g_mutex_unlock( vips__global_lock );
|
||||||
vips_error_exit( "unable to create profile log" );
|
vips_warn( "VipsGate",
|
||||||
|
"%s", "unable to create profile log" );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf( "recording profile in vips-profile.txt\n" );
|
printf( "recording profile in vips-profile.txt\n" );
|
||||||
@ -192,7 +194,8 @@ vips__thread_profile_init_cb( VipsThreadProfile *profile )
|
|||||||
* We can't do the freeing in this callback since GPrivate has already
|
* We can't do the freeing in this callback since GPrivate has already
|
||||||
* stopped working.
|
* stopped working.
|
||||||
*/
|
*/
|
||||||
vips_error_exit( "vips_thread_shutdown() not called for thread %p",
|
vips_warn( "VipsBuffer",
|
||||||
|
_( "vips_thread_shutdown() not called for thread %p" ),
|
||||||
g_thread_self() );
|
g_thread_self() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,45 @@
|
|||||||
*
|
*
|
||||||
* The image class and associated types and macros.
|
* The image class and associated types and macros.
|
||||||
*
|
*
|
||||||
* Images can be created from files on disc (with vips_image_new_from_file()),
|
* Images can be created from formatted files on disc, from C-style arrays on
|
||||||
* from formatted buffers held in memory (with vips_image_new_from_buffer()),
|
* disc, from formatted areas of memory, or from C-style arrays in memory. See
|
||||||
* and from C-style arrays held in memory (with vips_image_new_from_memory()).
|
* vips_image_new_from_file() and friends.
|
||||||
|
* Creating an image is fast. VIPS reads just enough of
|
||||||
|
* the image to be able to get the various properties, such as width in
|
||||||
|
* pixels. It delays reading any pixels until they are really needed.
|
||||||
|
*
|
||||||
|
* Once you have an image, you can get properties from it in the usual way.
|
||||||
|
* You can use projection functions, like vips_image_get_width() or
|
||||||
|
* g_object_get(), to get %GObject properties.
|
||||||
|
*
|
||||||
|
* VIPS images are three-dimensional arrays, the dimensions being width,
|
||||||
|
* height and bands. Each dimension can be up to 2 ** 31 pixels (or band
|
||||||
|
* elements). An image has a format, meaning the machine number type used
|
||||||
|
* to represent each value. VIPS supports 10 formats, from 8-bit unsigned
|
||||||
|
* integer up to 128-bit double complex, see vips_image_get_format()..
|
||||||
|
*
|
||||||
|
* In VIPS, images are uninterpreted arrays, meaning that from the point of
|
||||||
|
* view of most operations, they are just large collections of numbers.
|
||||||
|
* There's no difference between an RGBA (RGB with alpha) image and a CMYK
|
||||||
|
* image, for example, they are both just four-band images. It's up to the
|
||||||
|
* user of the library to pass the right sort of image to each operation.
|
||||||
|
*
|
||||||
|
* To take an example, VIPS has vips_Lab2XYZ(), an operation to transform
|
||||||
|
* an image from CIE LAB colour space to CIE XYZ space. It assumes the
|
||||||
|
* first three bands represent pixels in LAB colour space and returns an
|
||||||
|
* image where the first three bands are transformed to XYZ and any
|
||||||
|
* remaining bands are just copied. Pass it a RGB image by mistake and
|
||||||
|
* you'll just get nonsense.
|
||||||
|
*
|
||||||
|
* VIPS has a feature to help (a little) with this: it sets a
|
||||||
|
* #VipsInterpretation hint for each image (see
|
||||||
|
* vips_image_get_interpretation()); a hint which says how pixels should
|
||||||
|
* probably be interpreted. For example, vips_Lab2XYZ() will set the
|
||||||
|
* interpretation of the output image to #VIPS_INTERPRETATION_XYZ. A
|
||||||
|
* few utility operations will also use interpretation as a guide. For
|
||||||
|
* example, you can give vips_colourspace() an input image and a desired
|
||||||
|
* colourspace and it will use the input's interpretation hint to apply
|
||||||
|
* the best sequence of colourspace transforms to get to the desired space.
|
||||||
*
|
*
|
||||||
* Use things like vips_invert() to manipulate your images. When you are done,
|
* Use things like vips_invert() to manipulate your images. When you are done,
|
||||||
* you can write images to disc files (with vips_image_write_to_file()),
|
* you can write images to disc files (with vips_image_write_to_file()),
|
||||||
@ -77,7 +113,6 @@
|
|||||||
* linkend="libvips-header">header</link> for getting and setting image
|
* linkend="libvips-header">header</link> for getting and setting image
|
||||||
* metadata. See <link linkend="VipsObject">object</link> for a discussion of
|
* metadata. See <link linkend="VipsObject">object</link> for a discussion of
|
||||||
* the lower levels.
|
* the lower levels.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -674,10 +709,6 @@ vips_image_rewind( VipsObject *object )
|
|||||||
/* Delayed save.
|
/* Delayed save.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* If we write to (eg.) TIFF, actually do the write
|
|
||||||
* to a "p" and on "written" do im_vips2tiff() or whatever.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* From "written" callback: save to image->filename using VipsForeign.
|
/* From "written" callback: save to image->filename using VipsForeign.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -1067,10 +1098,10 @@ vips_image_class_init( VipsImageClass *class )
|
|||||||
* can't :-(
|
* can't :-(
|
||||||
*
|
*
|
||||||
* For example, a "p" image might be made with vips_image_new() and
|
* For example, a "p" image might be made with vips_image_new() and
|
||||||
* constructed, then passed to im_copy() of whatever to be written to.
|
* constructed, then passed to vips_copy() of whatever to be written to.
|
||||||
* That operation will then need to set width/height etc.
|
* That operation will then need to set width/height etc.
|
||||||
*
|
*
|
||||||
* We can't set_once either, since im_copy_set() etc. need to update
|
* We can't set_once either, since vips_copy() etc. need to update
|
||||||
* xoffset and friends on the way through.
|
* xoffset and friends on the way through.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2286,10 +2317,10 @@ vips_image_write_to_memory( VipsImage *in, void **buf_out, size_t *len_out )
|
|||||||
|
|
||||||
len = VIPS_IMAGE_SIZEOF_IMAGE( in );
|
len = VIPS_IMAGE_SIZEOF_IMAGE( in );
|
||||||
if( !(buf = g_try_malloc( len )) ) {
|
if( !(buf = g_try_malloc( len )) ) {
|
||||||
vips_error( "vips_image_write_to_buffer",
|
vips_error( "vips_image_write_to_memory",
|
||||||
_( "out of memory --- size == %dMB" ),
|
_( "out of memory --- size == %dMB" ),
|
||||||
(int) (len / (1024.0 * 1024.0)) );
|
(int) (len / (1024.0 * 1024.0)) );
|
||||||
vips_warn( "vips_image_write_to_buffer",
|
vips_warn( "vips_image_write_to_memory",
|
||||||
_( "out of memory --- size == %dMB" ),
|
_( "out of memory --- size == %dMB" ),
|
||||||
(int) (len / (1024.0*1024.0)) );
|
(int) (len / (1024.0*1024.0)) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -2990,7 +3021,7 @@ vips_image_pio_output( VipsImage *image )
|
|||||||
|
|
||||||
case VIPS_IMAGE_PARTIAL:
|
case VIPS_IMAGE_PARTIAL:
|
||||||
if( image->generate_fn ) {
|
if( image->generate_fn ) {
|
||||||
vips_error( "im_poutcheck",
|
vips_error( "vips_image_pio_output",
|
||||||
"%s", _( "image already written" ) );
|
"%s", _( "image already written" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -419,6 +419,9 @@ vips_vsnprintf( char *str, size_t size, const char *format, va_list ap )
|
|||||||
int n;
|
int n;
|
||||||
static char buf[MAX_BUF];
|
static char buf[MAX_BUF];
|
||||||
|
|
||||||
|
/* We can't return an error code, we may already have trashed the
|
||||||
|
* stack. We must stop immediately.
|
||||||
|
*/
|
||||||
if( size > MAX_BUF )
|
if( size > MAX_BUF )
|
||||||
vips_error_exit( "panic: buffer overflow "
|
vips_error_exit( "panic: buffer overflow "
|
||||||
"(request to write %d bytes to buffer of %d bytes)",
|
"(request to write %d bytes to buffer of %d bytes)",
|
||||||
|
@ -81,6 +81,9 @@
|
|||||||
* - added input space translation
|
* - added input space translation
|
||||||
* 22/1/14
|
* 22/1/14
|
||||||
* - auto RAD decode
|
* - auto RAD decode
|
||||||
|
* 1/8/14
|
||||||
|
* - revise transform ... again
|
||||||
|
* - see new stress test in nip2/test/extras
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -111,6 +114,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
#define DEBUG_VERBOSE
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -177,11 +181,12 @@ G_DEFINE_TYPE( VipsAffine, vips_affine, VIPS_TYPE_RESAMPLE );
|
|||||||
/* We have five (!!) coordinate systems. Working forward through them, these
|
/* We have five (!!) coordinate systems. Working forward through them, these
|
||||||
* are:
|
* are:
|
||||||
*
|
*
|
||||||
* 1. The original input image
|
* 1. The original input image. iarea is defined on this image.
|
||||||
*
|
*
|
||||||
* 2. This is embedded in a larger image to provide borders for the
|
* 2. This is embedded in a larger image to provide borders for the
|
||||||
* interpolator. iarea->left/top give the offset. These are the coordinates we
|
* interpolator. window_offset and window_size control the embedding.
|
||||||
* pass to VIPS_REGION_ADDR()/vips_region_prepare() for the input image.
|
* These are the coordinates we pass to VIPS_REGION_ADDR()/
|
||||||
|
* vips_region_prepare() and the interpolator.
|
||||||
*
|
*
|
||||||
* The borders are sized by the interpolator's window_size property and offset
|
* The borders are sized by the interpolator's window_size property and offset
|
||||||
* by the interpolator's window_offset property. For example,
|
* by the interpolator's window_offset property. For example,
|
||||||
@ -194,7 +199,7 @@ G_DEFINE_TYPE( VipsAffine, vips_affine, VIPS_TYPE_RESAMPLE );
|
|||||||
* 3. We need point (0, 0) in (1) to be at (0, 0) for the transformation. So
|
* 3. We need point (0, 0) in (1) to be at (0, 0) for the transformation. So
|
||||||
* shift everything up and left to make the displaced input image. This is the
|
* shift everything up and left to make the displaced input image. This is the
|
||||||
* space that the transformation maps from, and can have negative pixels
|
* space that the transformation maps from, and can have negative pixels
|
||||||
* (up and left of the image, for interpolation).
|
* (up and left of the image, for interpolation). iarea works here too.
|
||||||
*
|
*
|
||||||
* 4. Output transform space. This is the where the transform maps to. Pixels
|
* 4. Output transform space. This is the where the transform maps to. Pixels
|
||||||
* can be negative, since a rotated image can go up and left of the origin.
|
* can be negative, since a rotated image can go up and left of the origin.
|
||||||
@ -233,21 +238,23 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
|||||||
|
|
||||||
VipsRect image, want, need, clipped;
|
VipsRect image, want, need, clipped;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "affine: generating left=%d, top=%d, width=%d, height=%d\n",
|
printf( "vips_affine_gen: "
|
||||||
|
"generating left=%d, top=%d, width=%d, height=%d\n",
|
||||||
r->left,
|
r->left,
|
||||||
r->top,
|
r->top,
|
||||||
r->width,
|
r->width,
|
||||||
r->height );
|
r->height );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
/* We are generating this chunk of the transformed image.
|
/* We are generating this chunk of the transformed image. This takes
|
||||||
|
* us to space 4.
|
||||||
*/
|
*/
|
||||||
want = *r;
|
want = *r;
|
||||||
want.left += oarea->left;
|
want.left += oarea->left;
|
||||||
want.top += oarea->top;
|
want.top += oarea->top;
|
||||||
|
|
||||||
/* Find the area of the input image we need.
|
/* Find the area of the input image we need. This takes us to space 3.
|
||||||
*/
|
*/
|
||||||
vips__transform_invert_rect( &affine->trn, &want, &need );
|
vips__transform_invert_rect( &affine->trn, &want, &need );
|
||||||
|
|
||||||
@ -260,17 +267,18 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
|||||||
*/
|
*/
|
||||||
vips_rect_marginadjust( &need, 1 );
|
vips_rect_marginadjust( &need, 1 );
|
||||||
|
|
||||||
/* Now go to space (2) above.
|
/* We need to fetch a larger area for the interpolator.
|
||||||
*/
|
|
||||||
need.left += iarea->left;
|
|
||||||
need.top += iarea->top;
|
|
||||||
|
|
||||||
/* Add a border for interpolation.
|
|
||||||
*/
|
*/
|
||||||
|
need.left -= window_offset;
|
||||||
|
need.top -= window_offset;
|
||||||
need.width += window_size - 1;
|
need.width += window_size - 1;
|
||||||
need.height += window_size - 1;
|
need.height += window_size - 1;
|
||||||
need.left -= window_offset;
|
|
||||||
need.top -= window_offset;
|
/* Now go to space 2, the expanded input image. This is the one we
|
||||||
|
* read pixels from.
|
||||||
|
*/
|
||||||
|
need.left += window_offset;
|
||||||
|
need.top += window_offset;
|
||||||
|
|
||||||
/* Clip against the size of (2).
|
/* Clip against the size of (2).
|
||||||
*/
|
*/
|
||||||
@ -280,38 +288,34 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
|||||||
image.height = in->Ysize;
|
image.height = in->Ysize;
|
||||||
vips_rect_intersectrect( &need, &image, &clipped );
|
vips_rect_intersectrect( &need, &image, &clipped );
|
||||||
|
|
||||||
/* Outside input image? All black.
|
#ifdef DEBUG_VERBOSE
|
||||||
*/
|
printf( "vips_affine_gen: "
|
||||||
if( vips_rect_isempty( &clipped ) ) {
|
"preparing left=%d, top=%d, width=%d, height=%d\n",
|
||||||
vips_region_black( or );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We do need some pixels from the input image to make our output -
|
|
||||||
* ask for them.
|
|
||||||
*/
|
|
||||||
if( vips_region_prepare( ir, &clipped ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "affine: preparing left=%d, top=%d, width=%d, height=%d\n",
|
|
||||||
clipped.left,
|
clipped.left,
|
||||||
clipped.top,
|
clipped.top,
|
||||||
clipped.width,
|
clipped.width,
|
||||||
clipped.height );
|
clipped.height );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
|
if( vips_rect_isempty( &clipped ) ) {
|
||||||
|
vips_region_black( or );
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
if( vips_region_prepare( ir, &clipped ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
VIPS_GATE_START( "vips_affine_gen: work" );
|
VIPS_GATE_START( "vips_affine_gen: work" );
|
||||||
|
|
||||||
/* Resample! x/y loop over pixels in the output image (5).
|
/* Resample! x/y loop over pixels in the output image (5).
|
||||||
*/
|
*/
|
||||||
for( y = to; y < bo; y++ ) {
|
for( y = to; y < bo; y++ ) {
|
||||||
/* Input clipping rectangle.
|
/* Input clipping rectangle. We offset this so we can clip in
|
||||||
|
* space 2.
|
||||||
*/
|
*/
|
||||||
const int ile = iarea->left;
|
const int ile = iarea->left + window_offset;
|
||||||
const int ito = iarea->top;
|
const int ito = iarea->top + window_offset;
|
||||||
const int iri = iarea->left + iarea->width;
|
const int iri = ile + iarea->width;
|
||||||
const int ibo = iarea->top + iarea->height;
|
const int ibo = ito + iarea->height;
|
||||||
|
|
||||||
/* Derivative of matrix.
|
/* Derivative of matrix.
|
||||||
*/
|
*/
|
||||||
@ -334,16 +338,16 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
|||||||
ix = affine->trn.ia * ox + affine->trn.ib * oy;
|
ix = affine->trn.ia * ox + affine->trn.ib * oy;
|
||||||
iy = affine->trn.ic * ox + affine->trn.id * oy;
|
iy = affine->trn.ic * ox + affine->trn.id * oy;
|
||||||
|
|
||||||
/* Now move to (2).
|
/* And the input offset in (3).
|
||||||
*/
|
|
||||||
ix += iarea->left;
|
|
||||||
iy += iarea->top;
|
|
||||||
|
|
||||||
/* And the input offset.
|
|
||||||
*/
|
*/
|
||||||
ix -= affine->trn.idx;
|
ix -= affine->trn.idx;
|
||||||
iy -= affine->trn.idy;
|
iy -= affine->trn.idy;
|
||||||
|
|
||||||
|
/* Finally to 2.
|
||||||
|
*/
|
||||||
|
ix += window_offset;
|
||||||
|
iy += window_offset;
|
||||||
|
|
||||||
q = VIPS_REGION_ADDR( or, le, y );
|
q = VIPS_REGION_ADDR( or, le, y );
|
||||||
|
|
||||||
for( x = le; x < ri; x++ ) {
|
for( x = le; x < ri; x++ ) {
|
||||||
@ -352,19 +356,31 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
|||||||
fx = FAST_PSEUDO_FLOOR( ix );
|
fx = FAST_PSEUDO_FLOOR( ix );
|
||||||
fy = FAST_PSEUDO_FLOOR( iy );
|
fy = FAST_PSEUDO_FLOOR( iy );
|
||||||
|
|
||||||
/* Clipping!
|
/* Clip against iarea.
|
||||||
*/
|
*/
|
||||||
if( fx < ile ||
|
if( fx >= ile &&
|
||||||
fx > iri ||
|
fx < iri &&
|
||||||
fy < ito ||
|
fy >= ito &&
|
||||||
fy > ibo ) {
|
fy < ibo ) {
|
||||||
for( z = 0; z < ps; z++ )
|
/* Verify that we can read the whole stencil.
|
||||||
q[z] = 0;
|
* With DEBUG on this will range-check.
|
||||||
}
|
*/
|
||||||
else {
|
g_assert( VIPS_REGION_ADDR( ir,
|
||||||
|
(int) ix - window_offset,
|
||||||
|
(int) iy - window_offset ) );
|
||||||
|
g_assert( VIPS_REGION_ADDR( ir,
|
||||||
|
(int) ix - window_offset +
|
||||||
|
window_size - 1,
|
||||||
|
(int) iy - window_offset +
|
||||||
|
window_size - 1 ) );
|
||||||
|
|
||||||
interpolate( affine->interpolate,
|
interpolate( affine->interpolate,
|
||||||
q, ir, ix, iy );
|
q, ir, ix, iy );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
for( z = 0; z < ps; z++ )
|
||||||
|
q[z] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ix += ddx;
|
ix += ddx;
|
||||||
iy += ddy;
|
iy += ddy;
|
||||||
@ -416,8 +432,8 @@ vips_affine_build( VipsObject *object )
|
|||||||
window_offset =
|
window_offset =
|
||||||
vips_interpolate_get_window_offset( affine->interpolate );
|
vips_interpolate_get_window_offset( affine->interpolate );
|
||||||
|
|
||||||
affine->trn.iarea.left = window_offset;
|
affine->trn.iarea.left = 0;
|
||||||
affine->trn.iarea.top = window_offset;
|
affine->trn.iarea.top = 0;
|
||||||
affine->trn.iarea.width = in->Xsize;
|
affine->trn.iarea.width = in->Xsize;
|
||||||
affine->trn.iarea.height = in->Ysize;
|
affine->trn.iarea.height = in->Ysize;
|
||||||
affine->trn.a = ((double *) affine->matrix->data)[0];
|
affine->trn.a = ((double *) affine->matrix->data)[0];
|
||||||
@ -429,7 +445,13 @@ vips_affine_build( VipsObject *object )
|
|||||||
affine->trn.odx = 0;
|
affine->trn.odx = 0;
|
||||||
affine->trn.ody = 0;
|
affine->trn.ody = 0;
|
||||||
|
|
||||||
|
if( vips__transform_calc_inverse( &affine->trn ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
/* Set the default value for oarea.
|
||||||
|
*/
|
||||||
vips__transform_set_area( &affine->trn );
|
vips__transform_set_area( &affine->trn );
|
||||||
|
|
||||||
if( vips_object_argument_isset( object, "oarea" ) ) {
|
if( vips_object_argument_isset( object, "oarea" ) ) {
|
||||||
affine->trn.oarea.left = ((int *) affine->oarea->data)[0];
|
affine->trn.oarea.left = ((int *) affine->oarea->data)[0];
|
||||||
affine->trn.oarea.top = ((int *) affine->oarea->data)[1];
|
affine->trn.oarea.top = ((int *) affine->oarea->data)[1];
|
||||||
@ -447,15 +469,16 @@ vips_affine_build( VipsObject *object )
|
|||||||
if( vips_object_argument_isset( object, "idy" ) )
|
if( vips_object_argument_isset( object, "idy" ) )
|
||||||
affine->trn.idy = affine->idy;
|
affine->trn.idy = affine->idy;
|
||||||
|
|
||||||
if( vips__transform_calc_inverse( &affine->trn ) )
|
#ifdef DEBUG
|
||||||
return( -1 );
|
printf( "vips_affine_build: copy on identity transform disabled\n" );
|
||||||
|
#else /*!DEBUG*/
|
||||||
if( vips__transform_isidentity( &affine->trn ) &&
|
if( vips__transform_isidentity( &affine->trn ) &&
|
||||||
affine->trn.oarea.left == 0 &&
|
affine->trn.oarea.left == 0 &&
|
||||||
affine->trn.oarea.top == 0 &&
|
affine->trn.oarea.top == 0 &&
|
||||||
affine->trn.oarea.width == in->Xsize &&
|
affine->trn.oarea.width == in->Xsize &&
|
||||||
affine->trn.oarea.height == in->Ysize )
|
affine->trn.oarea.height == in->Ysize )
|
||||||
return( vips_image_write( in, resample->out ) );
|
return( vips_image_write( in, resample->out ) );
|
||||||
|
#endif /*!DEBUG*/
|
||||||
|
|
||||||
/* Check for coordinate overflow ... we want to be able to hold the
|
/* Check for coordinate overflow ... we want to be able to hold the
|
||||||
* output space inside INT_MAX / TRANSFORM_SCALE.
|
* output space inside INT_MAX / TRANSFORM_SCALE.
|
||||||
@ -478,13 +501,14 @@ vips_affine_build( VipsObject *object )
|
|||||||
*/
|
*/
|
||||||
if( vips_embed( in, &t[2],
|
if( vips_embed( in, &t[2],
|
||||||
window_offset, window_offset,
|
window_offset, window_offset,
|
||||||
in->Xsize + window_size, in->Ysize + window_size,
|
in->Xsize + window_size - 1, in->Ysize + window_size - 1,
|
||||||
"extend", VIPS_EXTEND_COPY,
|
"extend", VIPS_EXTEND_COPY,
|
||||||
NULL ) )
|
NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
in = t[2];
|
in = t[2];
|
||||||
|
|
||||||
/* Normally SMALLTILE ... except if this is a size up/down affine.
|
/* Normally SMALLTILE ... except if this is strictly a size
|
||||||
|
* up/down affine.
|
||||||
*/
|
*/
|
||||||
if( affine->trn.b == 0.0 &&
|
if( affine->trn.b == 0.0 &&
|
||||||
affine->trn.c == 0.0 )
|
affine->trn.c == 0.0 )
|
||||||
@ -499,12 +523,14 @@ vips_affine_build( VipsObject *object )
|
|||||||
resample->out->Ysize = affine->trn.oarea.height;
|
resample->out->Ysize = affine->trn.oarea.height;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips_affine_build: transform: "
|
printf( "vips_affine_build: transform: " );
|
||||||
"a = %g, b = %g, c = %g, d = %g\n",
|
vips__transform_print( &affine->trn );
|
||||||
affine->trn.a,
|
printf( " window_offset = %d, window_size = %d\n",
|
||||||
affine->trn.b,
|
window_offset, window_size );
|
||||||
affine->trn.c,
|
printf( " input image width = %d, height = %d\n",
|
||||||
affine->trn.d );
|
in->Xsize, in->Ysize );
|
||||||
|
printf( " output image width = %d, height = %d\n",
|
||||||
|
resample->out->Xsize, resample->out->Ysize );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
/* Generate!
|
/* Generate!
|
||||||
|
@ -156,8 +156,8 @@ vips__transform_print( const VipsTransformation *trn )
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vips__transform_forward_point( const VipsTransformation *trn,
|
vips__transform_forward_point( const VipsTransformation *trn,
|
||||||
double x, double y, /* In input space */
|
double x, double y, /* In input space */
|
||||||
double *ox, double *oy ) /* In output space */
|
double *ox, double *oy )/* In output space */
|
||||||
{
|
{
|
||||||
x += trn->idx;
|
x += trn->idx;
|
||||||
y += trn->idy;
|
y += trn->idy;
|
||||||
@ -170,11 +170,11 @@ vips__transform_forward_point( const VipsTransformation *trn,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vips__transform_invert_point( const VipsTransformation *trn,
|
vips__transform_invert_point( const VipsTransformation *trn,
|
||||||
double x, double y, /* In output space */
|
double x, double y, /* In output space */
|
||||||
double *ox, double *oy ) /* In input space */
|
double *ox, double *oy )/* In input space */
|
||||||
{
|
{
|
||||||
x -= trn->odx;
|
x -= trn->odx;
|
||||||
y -= trn->ody;
|
y -= trn->ody;
|
||||||
|
|
||||||
*ox = trn->ia * x + trn->ib * y - trn->idx;
|
*ox = trn->ia * x + trn->ib * y - trn->idx;
|
||||||
*oy = trn->ic * x + trn->id * y - trn->idy;
|
*oy = trn->ic * x + trn->id * y - trn->idy;
|
||||||
@ -187,7 +187,7 @@ typedef void (*transform_fn)( const VipsTransformation *,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
transform_rect( const VipsTransformation *trn, transform_fn transform,
|
transform_rect( const VipsTransformation *trn, transform_fn transform,
|
||||||
const VipsRect *in, /* In input space */
|
const VipsRect *in, /* In input space */
|
||||||
VipsRect *out ) /* In output space */
|
VipsRect *out ) /* In output space */
|
||||||
{
|
{
|
||||||
double x1, y1; /* Map corners */
|
double x1, y1; /* Map corners */
|
||||||
@ -198,9 +198,12 @@ transform_rect( const VipsTransformation *trn, transform_fn transform,
|
|||||||
|
|
||||||
/* Map input VipsRect.
|
/* Map input VipsRect.
|
||||||
*/
|
*/
|
||||||
transform( trn, in->left, in->top, &x1, &y1 );
|
transform( trn, in->left, in->top,
|
||||||
transform( trn, in->left, VIPS_RECT_BOTTOM( in ), &x3, &y3 );
|
&x1, &y1 );
|
||||||
transform( trn, VIPS_RECT_RIGHT( in ), in->top, &x2, &y2 );
|
transform( trn, in->left, VIPS_RECT_BOTTOM( in ),
|
||||||
|
&x3, &y3 );
|
||||||
|
transform( trn, VIPS_RECT_RIGHT( in ), in->top,
|
||||||
|
&x2, &y2 );
|
||||||
transform( trn, VIPS_RECT_RIGHT( in ), VIPS_RECT_BOTTOM( in ),
|
transform( trn, VIPS_RECT_RIGHT( in ), VIPS_RECT_BOTTOM( in ),
|
||||||
&x4, &y4 );
|
&x4, &y4 );
|
||||||
|
|
||||||
@ -234,7 +237,7 @@ vips__transform_forward_rect( const VipsTransformation *trn,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vips__transform_invert_rect( const VipsTransformation *trn,
|
vips__transform_invert_rect( const VipsTransformation *trn,
|
||||||
const VipsRect *in, /* In output space */
|
const VipsRect *in, /* In output space */
|
||||||
VipsRect *out ) /* In input space */
|
VipsRect *out ) /* In input space */
|
||||||
{
|
{
|
||||||
transform_rect( trn, vips__transform_invert_point, in, out );
|
transform_rect( trn, vips__transform_invert_point, in, out );
|
||||||
|
Loading…
Reference in New Issue
Block a user