Merge branch 'dzsave-metadata' of github.com:jcupitt/libvips into dzsave-metadata
Conflicts: ChangeLog configure.ac
This commit is contained in:
commit
fc14733b2b
13
ChangeLog
13
ChangeLog
@ -1,5 +1,18 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
26/6/14 started 7.40.2
|
26/6/14 started 7.40.2
|
||||||
- fixes to help freebsd
|
- fixes to help freebsd
|
||||||
|
=======
|
||||||
|
30/6/14 started 7.40.3
|
||||||
|
- fix interlaced thumbnails in vipsthumbnail, thanks lovell
|
||||||
|
- add --properties argument to dzsave, thanks bgilbert
|
||||||
|
|
||||||
|
25/6/14 started 7.40.2
|
||||||
|
- dzsave write to zip stops at 4gb, thanks bgilbert
|
||||||
|
- improve short option name handling, thanks bgilbert
|
||||||
|
- added --enable-docs configure option to help freebsd
|
||||||
|
- removed a bash-ism from configure to help freebsd
|
||||||
|
- don't assume GType fits in an int to help freebsd
|
||||||
|
>>>>>>> c5fbe6daa642b522c54b6912b22649f59c8d237f
|
||||||
|
|
||||||
24/6/14 started 7.40.1
|
24/6/14 started 7.40.1
|
||||||
- revise man.1 pages
|
- revise man.1 pages
|
||||||
|
16
Makefile.am
16
Makefile.am
@ -19,6 +19,14 @@ P_COMPILE_DIR =
|
|||||||
P_DIST_DIR = swig
|
P_DIST_DIR = swig
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if ENABLE_DOCS
|
||||||
|
D_DIST_DIR =
|
||||||
|
D_BUILD_DIR = doc
|
||||||
|
else
|
||||||
|
D_DIST_DIR = doc
|
||||||
|
D_BUILD_DIR =
|
||||||
|
endif
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
libvips \
|
libvips \
|
||||||
tools \
|
tools \
|
||||||
@ -26,7 +34,8 @@ SUBDIRS = \
|
|||||||
man \
|
man \
|
||||||
doc \
|
doc \
|
||||||
$(C_COMPILE_DIR) \
|
$(C_COMPILE_DIR) \
|
||||||
$(P_COMPILE_DIR)
|
$(P_COMPILE_DIR) \
|
||||||
|
$(D_BUILD_DIR)
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
m4 \
|
m4 \
|
||||||
@ -38,15 +47,18 @@ EXTRA_DIST = \
|
|||||||
acinclude.m4 \
|
acinclude.m4 \
|
||||||
depcomp \
|
depcomp \
|
||||||
$(C_DIST_DIR) \
|
$(C_DIST_DIR) \
|
||||||
$(P_DIST_DIR)
|
$(P_DIST_DIR) \
|
||||||
|
$(D_DIST_DIR)
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = vips.pc $(C_PKGCONFIG)
|
pkgconfig_DATA = vips.pc $(C_PKGCONFIG)
|
||||||
|
|
||||||
|
if ENABLE_DOCS
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
-rm -rf ${DESTDIR}$(datadir)/doc/vips
|
-rm -rf ${DESTDIR}$(datadir)/doc/vips
|
||||||
$(mkinstalldirs) ${DESTDIR}$(datadir)/doc/vips
|
$(mkinstalldirs) ${DESTDIR}$(datadir)/doc/vips
|
||||||
-cp -r ${top_srcdir}/doc/html ${top_srcdir}/doc/pdf ${DESTDIR}$(datadir)/doc/vips
|
-cp -r ${top_srcdir}/doc/html ${top_srcdir}/doc/pdf ${DESTDIR}$(datadir)/doc/vips
|
||||||
|
endif
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
# make sure we don't get any .svn dirs from EXTRA_DIST
|
# make sure we don't get any .svn dirs from EXTRA_DIST
|
||||||
|
@ -109,8 +109,9 @@ Static analysis with:
|
|||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
libvips has to have gettext, glib-2.x and libxml-2.0. The build system needs
|
libvips has to have gettext, glib-2.x and libxml-2.0. The build system
|
||||||
sh, pkg-config, swig, gtk-doc-tools, automake, gobject-introspection and gnu make.
|
needs sh, pkg-config, swig, gtk-doc-tools, automake, gobject-introspection
|
||||||
|
and gnu make.
|
||||||
|
|
||||||
# Optional dependencies
|
# Optional dependencies
|
||||||
|
|
||||||
@ -155,10 +156,6 @@ If available, libvips adds support for creating image pyramids with dzsave.
|
|||||||
The TIFF library. It needs to be built with support for JPEG and
|
The TIFF library. It needs to be built with support for JPEG and
|
||||||
ZIP compression. 3.4b037 and later are known to be OK.
|
ZIP compression. 3.4b037 and later are known to be OK.
|
||||||
|
|
||||||
## libz
|
|
||||||
|
|
||||||
If your TIFF library includes ZIP compression, you'll need this too.
|
|
||||||
|
|
||||||
## fftw3
|
## fftw3
|
||||||
|
|
||||||
If libvips finds this library, it uses it for fourier transforms. It
|
If libvips finds this library, it uses it for fourier transforms. It
|
||||||
|
4
TODO
4
TODO
@ -14,6 +14,8 @@
|
|||||||
gtk-doc now used markdown, phew, use this to expand some sections
|
gtk-doc now used markdown, phew, use this to expand some sections
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +38,9 @@
|
|||||||
|
|
||||||
- vips_getpoint() needs an optional imag return
|
- vips_getpoint() needs an optional imag return
|
||||||
|
|
||||||
|
- add porter-duff compositing, see
|
||||||
|
|
||||||
|
https://github.com/jcupitt/ruby-vips/issues/28
|
||||||
|
|
||||||
- now vips_linear() has uchar output, can we do something with orc?
|
- now vips_linear() has uchar output, can we do something with orc?
|
||||||
|
|
||||||
|
44
configure.ac
44
configure.ac
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# also update the version number in the m4 macros below
|
# also update the version number in the m4 macros below
|
||||||
|
|
||||||
AC_INIT([vips], [7.40.2], [vipsip@jiscmail.ac.uk])
|
AC_INIT([vips], [7.40.3], [vipsip@jiscmail.ac.uk])
|
||||||
# required for gobject-introspection
|
# required for gobject-introspection
|
||||||
AC_PREREQ(2.62)
|
AC_PREREQ(2.62)
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
|||||||
# user-visible library versioning
|
# user-visible library versioning
|
||||||
m4_define([vips_major_version], [7])
|
m4_define([vips_major_version], [7])
|
||||||
m4_define([vips_minor_version], [40])
|
m4_define([vips_minor_version], [40])
|
||||||
m4_define([vips_micro_version], [2])
|
m4_define([vips_micro_version], [3])
|
||||||
m4_define([vips_version],
|
m4_define([vips_version],
|
||||||
[vips_major_version.vips_minor_version.vips_micro_version])
|
[vips_major_version.vips_minor_version.vips_micro_version])
|
||||||
|
|
||||||
@ -37,8 +37,8 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date`
|
|||||||
# binary interface changes backwards compatible?: increment age
|
# binary interface changes backwards compatible?: increment age
|
||||||
# binary interface changes not backwards compatible?: reset age to 0
|
# binary interface changes not backwards compatible?: reset age to 0
|
||||||
|
|
||||||
LIBRARY_CURRENT=37
|
LIBRARY_CURRENT=38
|
||||||
LIBRARY_REVISION=5
|
LIBRARY_REVISION=1
|
||||||
LIBRARY_AGE=0
|
LIBRARY_AGE=0
|
||||||
|
|
||||||
# patched into include/vips/version.h
|
# patched into include/vips/version.h
|
||||||
@ -124,6 +124,23 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# we are a C library with some optional C++ components inside it
|
||||||
|
# on most platforms, we just include -lstdc++ in the link line for programs
|
||||||
|
# using vips, but not all
|
||||||
|
|
||||||
|
# we ought to write a proper configure test for this :(
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for needs -lstdc++])
|
||||||
|
case "$host_os" in
|
||||||
|
freebsd*)
|
||||||
|
vips_needs_stdcpp=no
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
vips_needs_stdcpp=yes
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
AC_MSG_RESULT([$vips_needs_stdcpp])
|
||||||
|
|
||||||
AC_MSG_CHECKING([for native Win32])
|
AC_MSG_CHECKING([for native Win32])
|
||||||
case "$host" in
|
case "$host" in
|
||||||
*-*-mingw*)
|
*-*-mingw*)
|
||||||
@ -190,6 +207,20 @@ else
|
|||||||
fi
|
fi
|
||||||
AC_DEFINE_UNQUOTED(VIPS_ICC_DIR,"$profile_dir",[default directory for ICC profiles])
|
AC_DEFINE_UNQUOTED(VIPS_ICC_DIR,"$profile_dir",[default directory for ICC profiles])
|
||||||
|
|
||||||
|
# option to stop docs installing ... eg. freebsd likes this
|
||||||
|
AC_ARG_ENABLE(docs,
|
||||||
|
AS_HELP_STRING([--enable-docs], [install docs (default: yes)]))
|
||||||
|
|
||||||
|
if test x"$enable_docs" != x"no"; then
|
||||||
|
AM_CONDITIONAL(ENABLE_DOCS, true)
|
||||||
|
enable_docs=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$enable_docs" != x"yes"; then
|
||||||
|
AM_CONDITIONAL(ENABLE_DOCS, false)
|
||||||
|
enable_docs=no
|
||||||
|
fi
|
||||||
|
|
||||||
# we want largefile support, if possible
|
# we want largefile support, if possible
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
@ -233,7 +264,9 @@ if test x"$enable_cxx" != x"no"; then
|
|||||||
# need -lstdc++ for (eg.) the C++ format loaders
|
# need -lstdc++ for (eg.) the C++ format loaders
|
||||||
# this gets added to vips.pc to help mingw and friends link programs
|
# this gets added to vips.pc to help mingw and friends link programs
|
||||||
# using libvips
|
# using libvips
|
||||||
|
if test x"$vips_needs_stdcpp" != x"no"; then
|
||||||
VIPS_CXX_LIBS="-lstdc++"
|
VIPS_CXX_LIBS="-lstdc++"
|
||||||
|
fi
|
||||||
enable_cxx=yes
|
enable_cxx=yes
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -350,7 +383,7 @@ PKG_CHECK_MODULES(THREADS, glib-2.0 >= 2.32,[
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# after 2.36 the type system inits itself
|
# with 2.36 and after the type system inits itself
|
||||||
PKG_CHECK_MODULES(TYPE_INIT, glib-2.0 < 2.36,[
|
PKG_CHECK_MODULES(TYPE_INIT, glib-2.0 < 2.36,[
|
||||||
AC_DEFINE(NEED_TYPE_INIT,1,[define if your glib needs g_type_init().])
|
AC_DEFINE(NEED_TYPE_INIT,1,[define if your glib needs g_type_init().])
|
||||||
],[
|
],[
|
||||||
@ -775,6 +808,7 @@ open files in binary mode: $vips_binary_open
|
|||||||
enable debug: $enable_debug
|
enable debug: $enable_debug
|
||||||
build C++ components: $enable_cxx
|
build C++ components: $enable_cxx
|
||||||
build docs with gtkdoc: $enable_gtk_doc
|
build docs with gtkdoc: $enable_gtk_doc
|
||||||
|
install docs: $enable_docs
|
||||||
gobject introspection: $found_introspection
|
gobject introspection: $found_introspection
|
||||||
|
|
||||||
* optional packages and modules
|
* optional packages and modules
|
||||||
|
@ -123,6 +123,9 @@ vips_compass_build( VipsObject *object )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
/* Silence compiler wrning.
|
||||||
|
*/
|
||||||
|
x = NULL;
|
||||||
g_assert( 0 );
|
g_assert( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@
|
|||||||
* - set Type on strips so we can convert for save correctly, thanks
|
* - set Type on strips so we can convert for save correctly, thanks
|
||||||
* philipgiuliani
|
* philipgiuliani
|
||||||
* 25/6/14
|
* 25/6/14
|
||||||
* - save openslide metadata to .dzi, see
|
* - stop on zip write >4gb, thanks bgilbert
|
||||||
|
* - save metadata to .dzi, see
|
||||||
* https://github.com/jcupitt/libvips/issues/137
|
* https://github.com/jcupitt/libvips/issues/137
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -166,6 +167,7 @@ typedef struct _VipsGsfDirectory {
|
|||||||
* this on cleanup.
|
* this on cleanup.
|
||||||
*/
|
*/
|
||||||
GsfOutput *container;
|
GsfOutput *container;
|
||||||
|
|
||||||
} VipsGsfDirectory;
|
} VipsGsfDirectory;
|
||||||
|
|
||||||
/* Close all dirs, non-NULL on error.
|
/* Close all dirs, non-NULL on error.
|
||||||
@ -389,6 +391,7 @@ struct _VipsForeignSaveDz {
|
|||||||
VipsArrayDouble *background;
|
VipsArrayDouble *background;
|
||||||
VipsForeignDzDepth depth;
|
VipsForeignDzDepth depth;
|
||||||
gboolean centre;
|
gboolean centre;
|
||||||
|
gboolean properties;
|
||||||
VipsAngle angle;
|
VipsAngle angle;
|
||||||
VipsForeignDzContainer container;
|
VipsForeignDzContainer container;
|
||||||
|
|
||||||
@ -420,6 +423,11 @@ struct _VipsForeignSaveDz {
|
|||||||
* becomes ".jpg".
|
* becomes ".jpg".
|
||||||
*/
|
*/
|
||||||
char *file_suffix;
|
char *file_suffix;
|
||||||
|
|
||||||
|
/* libgsf can't write zip files larger than 4gb. Track bytes written
|
||||||
|
* here and try to guess when we'll go over.
|
||||||
|
*/
|
||||||
|
size_t bytes_written;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef VipsForeignSaveClass VipsForeignSaveDzClass;
|
typedef VipsForeignSaveClass VipsForeignSaveDzClass;
|
||||||
@ -706,8 +714,10 @@ write_vips_property( VipsImage *image,
|
|||||||
char *str_value;
|
char *str_value;
|
||||||
|
|
||||||
str_value = g_strdup_value_contents( value );
|
str_value = g_strdup_value_contents( value );
|
||||||
|
gsf_output_printf( out, " <property>\n" );
|
||||||
gsf_output_printf( out, " <name>%s</name>\n", field );
|
gsf_output_printf( out, " <name>%s</name>\n", field );
|
||||||
gsf_output_printf( out, " <value>%s</value>\n", str_value );
|
gsf_output_printf( out, " <value>%s</value>\n", str_value );
|
||||||
|
gsf_output_printf( out, " </property>\n" );
|
||||||
g_free( str_value );
|
g_free( str_value );
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -718,14 +728,26 @@ write_vips_properties( VipsForeignSaveDz *dz )
|
|||||||
{
|
{
|
||||||
VipsForeignSave *save = (VipsForeignSave *) dz;
|
VipsForeignSave *save = (VipsForeignSave *) dz;
|
||||||
|
|
||||||
|
time_t now;
|
||||||
|
char time_string[50];
|
||||||
GsfOutput *out;
|
GsfOutput *out;
|
||||||
|
|
||||||
|
time( &now );
|
||||||
|
strftime( time_string, sizeof( time_string ),
|
||||||
|
"%FT%TZ", gmtime( &now ) );
|
||||||
|
|
||||||
out = vips_gsf_path( dz->tree,
|
out = vips_gsf_path( dz->tree,
|
||||||
"vips-properties.xml", dz->root_name, NULL );
|
"vips-properties.xml", dz->root_name, NULL );
|
||||||
|
|
||||||
gsf_output_printf( out,
|
gsf_output_printf( out,
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
|
||||||
gsf_output_printf( out, "<image>\n" );
|
gsf_output_printf( out, "<image\n" );
|
||||||
|
gsf_output_printf( out, " version=\"%s\"\n", VIPS_VERSION );
|
||||||
|
gsf_output_printf( out, " date=\"%s\"\n", time_string );
|
||||||
|
gsf_output_printf( out, " "
|
||||||
|
"xmlns=\"http://www.vips.ecs.soton.ac.uk/vips/%s\"\n",
|
||||||
|
VIPS_VERSION );
|
||||||
|
gsf_output_printf( out, " >\n" );
|
||||||
gsf_output_printf( out, " <properties>\n" );
|
gsf_output_printf( out, " <properties>\n" );
|
||||||
(void) vips_image_map( save->ready, write_vips_property, out );
|
(void) vips_image_map( save->ready, write_vips_property, out );
|
||||||
gsf_output_printf( out, " </properties>\n" );
|
gsf_output_printf( out, " </properties>\n" );
|
||||||
@ -1039,12 +1061,14 @@ strip_work( VipsThreadState *state, void *a )
|
|||||||
Strip *strip = (Strip *) a;
|
Strip *strip = (Strip *) a;
|
||||||
Layer *layer = strip->layer;
|
Layer *layer = strip->layer;
|
||||||
VipsForeignSaveDz *dz = layer->dz;
|
VipsForeignSaveDz *dz = layer->dz;
|
||||||
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( dz );
|
||||||
|
|
||||||
VipsImage *x;
|
VipsImage *x;
|
||||||
VipsImage *t;
|
VipsImage *t;
|
||||||
void *buf;
|
void *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
GsfOutput *out;
|
GsfOutput *out;
|
||||||
|
gboolean status;
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "strip_work\n" );
|
printf( "strip_work\n" );
|
||||||
@ -1115,13 +1139,36 @@ strip_work( VipsThreadState *state, void *a )
|
|||||||
out = tile_name( layer,
|
out = tile_name( layer,
|
||||||
state->x / dz->tile_size, state->y / dz->tile_size );
|
state->x / dz->tile_size, state->y / dz->tile_size );
|
||||||
|
|
||||||
gsf_output_write( out, len, buf );
|
status = gsf_output_write( out, len, buf );
|
||||||
|
dz->bytes_written += len;
|
||||||
|
|
||||||
gsf_output_close( out );
|
gsf_output_close( out );
|
||||||
g_object_unref( out );
|
g_object_unref( out );
|
||||||
|
|
||||||
|
g_free( buf );
|
||||||
|
|
||||||
|
if( !status ) {
|
||||||
g_mutex_unlock( vips__global_lock );
|
g_mutex_unlock( vips__global_lock );
|
||||||
|
|
||||||
g_free( buf );
|
vips_error( class->nickname,
|
||||||
|
"%s", gsf_output_error( out )->message );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow a 100,000 byte margin. This probably isn't enough: we don't
|
||||||
|
* include the space zip needs for the index nor anything we are
|
||||||
|
* outputting apart from the gsf_output_write() above.
|
||||||
|
*/
|
||||||
|
if( dz->container == VIPS_FOREIGN_DZ_CONTAINER_ZIP &&
|
||||||
|
dz->bytes_written > (size_t) UINT_MAX - 100000 ) {
|
||||||
|
g_mutex_unlock( vips__global_lock );
|
||||||
|
|
||||||
|
vips_error( class->nickname,
|
||||||
|
"%s", _( "output file too large" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock( vips__global_lock );
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "strip_work: success\n" );
|
printf( "strip_work: success\n" );
|
||||||
@ -1666,7 +1713,8 @@ vips_foreign_save_dz_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( write_vips_properties( dz ) )
|
if( dz->properties &&
|
||||||
|
write_vips_properties( dz ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_gsf_tree_close( dz->tree ) )
|
if( vips_gsf_tree_close( dz->tree ) )
|
||||||
@ -1821,6 +1869,13 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class )
|
|||||||
VIPS_TYPE_FOREIGN_DZ_CONTAINER,
|
VIPS_TYPE_FOREIGN_DZ_CONTAINER,
|
||||||
VIPS_FOREIGN_DZ_CONTAINER_FS );
|
VIPS_FOREIGN_DZ_CONTAINER_FS );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( class, "properties", 16,
|
||||||
|
_( "Properties" ),
|
||||||
|
_( "Write a properties file to the output directory" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignSaveDz, properties ),
|
||||||
|
FALSE );
|
||||||
|
|
||||||
/* How annoying. We stupidly had these in earlier versions.
|
/* How annoying. We stupidly had these in earlier versions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1886,16 +1941,17 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
|
|||||||
* @centre: centre the tiles
|
* @centre: centre the tiles
|
||||||
* @angle: rotate the image by this much
|
* @angle: rotate the image by this much
|
||||||
* @container: set container type
|
* @container: set container type
|
||||||
|
* @properties: write a properties file
|
||||||
*
|
*
|
||||||
* Save an image as a set of tiles at various resolutions. By default dzsave
|
* Save an image as a set of tiles at various resolutions. By default dzsave
|
||||||
* uses DeepZoom layout -- use @layout to pick other conventions.
|
* uses DeepZoom layout -- use @layout to pick other conventions.
|
||||||
*
|
*
|
||||||
* vips_dzsave() creates a directory called @name to hold the tiles. If @name
|
* vips_dzsave() creates a directory called @name to hold the tiles. If @name
|
||||||
* ends ".zip", vips_dzsave() will create a zip file called @name to hold the
|
* ends `.zip`, vips_dzsave() will create a zip file called @name to hold the
|
||||||
* tiles. You can use @container to force zip file output.
|
* tiles. You can use @container to force zip file output.
|
||||||
*
|
*
|
||||||
* You can set @suffix to something like ".jpg[Q=85]" to control the tile write
|
* You can set @suffix to something like `".jpg[Q=85]"` to control the tile
|
||||||
* options.
|
* write options.
|
||||||
*
|
*
|
||||||
* In Google layout mode, edge tiles are expanded to @tile_size by @tile_size
|
* In Google layout mode, edge tiles are expanded to @tile_size by @tile_size
|
||||||
* pixels. Normally they are filled with white, but you can set another colour
|
* pixels. Normally they are filled with white, but you can set another colour
|
||||||
@ -1908,6 +1964,12 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
|
|||||||
* Use @depth to control how low the pyramid goes. This defaults to the
|
* Use @depth to control how low the pyramid goes. This defaults to the
|
||||||
* correct setting for the @layout you select.
|
* correct setting for the @layout you select.
|
||||||
*
|
*
|
||||||
|
* If @properties is %TRUE, vips_dzsave() will write a file called
|
||||||
|
* `vips-properties.xml` to the output directory. This file lists all of the
|
||||||
|
* metadata attached to @in in an obvious manner. It can be useful for viewing
|
||||||
|
* programs which wish to use fields from source files loaded via
|
||||||
|
* vips_openslideload().
|
||||||
|
*
|
||||||
* See also: vips_tiffsave().
|
* See also: vips_tiffsave().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error.
|
* Returns: 0 on success, -1 on error.
|
||||||
|
@ -645,6 +645,7 @@ write_ppm( Write *write, int ascii )
|
|||||||
char *magic;
|
char *magic;
|
||||||
time_t timebuf;
|
time_t timebuf;
|
||||||
|
|
||||||
|
magic = "unset";
|
||||||
if( in->BandFmt == VIPS_FORMAT_FLOAT && in->Bands == 3 )
|
if( in->BandFmt == VIPS_FORMAT_FLOAT && in->Bands == 3 )
|
||||||
magic = "PF";
|
magic = "PF";
|
||||||
else if( in->BandFmt == VIPS_FORMAT_FLOAT && in->Bands == 1 )
|
else if( in->BandFmt == VIPS_FORMAT_FLOAT && in->Bands == 1 )
|
||||||
|
@ -2541,25 +2541,36 @@ vips_class_find( const char *basename, const char *nickname )
|
|||||||
return( class );
|
return( class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* What we store for each nickname. We can't just store the type with
|
||||||
|
* GINT_TO_POINTER() since GType is 64 bits on some platforms.
|
||||||
|
*/
|
||||||
|
typedef struct _NicknameGType {
|
||||||
|
const char *nickname;
|
||||||
|
GType type;
|
||||||
|
gboolean duplicate;
|
||||||
|
} NicknameGType;
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
vips_class_add_hash( VipsObjectClass *class, GHashTable *table )
|
vips_class_add_hash( VipsObjectClass *class, GHashTable *table )
|
||||||
{
|
{
|
||||||
GType type = G_OBJECT_CLASS_TYPE( class );
|
GType type = G_OBJECT_CLASS_TYPE( class );
|
||||||
|
NicknameGType *hit;
|
||||||
|
|
||||||
/* If this is not a unique name, store -1 for the GType. In this case
|
hit = (NicknameGType *)
|
||||||
|
g_hash_table_lookup( table, (void *) class->nickname );
|
||||||
|
|
||||||
|
/* If this is not a unique name, mark as a duplicate. In this case
|
||||||
* we'll need to fall back to a search.
|
* we'll need to fall back to a search.
|
||||||
*/
|
*/
|
||||||
if( g_hash_table_lookup( table, (void *) class->nickname ) ) {
|
if( hit )
|
||||||
g_hash_table_insert( table,
|
hit->duplicate = TRUE;
|
||||||
(void *) class->nickname, GINT_TO_POINTER( -1 ) );
|
else {
|
||||||
#ifdef DEBUG
|
hit = g_new( NicknameGType, 1 );
|
||||||
printf( "vips_class_add_hash: duplicate nickname %s\n",
|
hit->nickname = class->nickname;
|
||||||
class->nickname );
|
hit->type = type;
|
||||||
#endif /*DEBUG*/
|
hit->duplicate = FALSE;
|
||||||
|
g_hash_table_insert( table, (void *) hit->nickname, hit );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
g_hash_table_insert( table,
|
|
||||||
(void *) class->nickname, GINT_TO_POINTER( type ) );
|
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
@ -2587,27 +2598,32 @@ vips_type_find( const char *basename, const char *nickname )
|
|||||||
|
|
||||||
const char *classname = basename ? basename : "VipsObject";
|
const char *classname = basename ? basename : "VipsObject";
|
||||||
|
|
||||||
|
NicknameGType *hit;
|
||||||
GType base;
|
GType base;
|
||||||
GType type;
|
GType type;
|
||||||
|
|
||||||
vips__object_nickname_table = (GHashTable *) g_once( &once,
|
vips__object_nickname_table = (GHashTable *) g_once( &once,
|
||||||
(GThreadFunc) vips_class_build_hash, NULL );
|
(GThreadFunc) vips_class_build_hash, NULL );
|
||||||
|
|
||||||
type = GPOINTER_TO_INT( g_hash_table_lookup(
|
hit = (NicknameGType *)
|
||||||
vips__object_nickname_table, (void *) nickname ) );
|
g_hash_table_lookup( vips__object_nickname_table,
|
||||||
|
(void *) nickname );
|
||||||
|
|
||||||
/* We must only search below basename ... check that the cache hit is
|
/* We must only search below basename ... check that the cache hit is
|
||||||
* in the right part of the tree.
|
* in the right part of the tree.
|
||||||
*/
|
*/
|
||||||
if( !(base = g_type_from_name( classname )) )
|
if( !(base = g_type_from_name( classname )) )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
if( !type ||
|
if( hit &&
|
||||||
type == -1 ||
|
!hit->duplicate &&
|
||||||
!g_type_is_a( type, base ) ) {
|
g_type_is_a( hit->type, base ) )
|
||||||
|
type = hit->type;
|
||||||
|
else {
|
||||||
VipsObjectClass *class;
|
VipsObjectClass *class;
|
||||||
|
|
||||||
if( !(class = vips_class_find( basename, nickname )) )
|
if( !(class = vips_class_find( basename, nickname )) )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
|
||||||
type = G_OBJECT_CLASS_TYPE( class );
|
type = G_OBJECT_CLASS_TYPE( class );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,9 +953,15 @@ vips_call_options_add( VipsObject *object,
|
|||||||
GOptionEntry entry[2];
|
GOptionEntry entry[2];
|
||||||
|
|
||||||
entry[0].long_name = name;
|
entry[0].long_name = name;
|
||||||
entry[0].short_name = name[0];
|
|
||||||
entry[0].description = g_param_spec_get_blurb( pspec );
|
entry[0].description = g_param_spec_get_blurb( pspec );
|
||||||
|
|
||||||
|
/* Don't set short names for deprecated args.
|
||||||
|
*/
|
||||||
|
if( argument_class->flags & VIPS_ARGUMENT_DEPRECATED )
|
||||||
|
entry[0].short_name = '\0';
|
||||||
|
else
|
||||||
|
entry[0].short_name = name[0];
|
||||||
|
|
||||||
entry[0].flags = 0;
|
entry[0].flags = 0;
|
||||||
if( !needs_string )
|
if( !needs_string )
|
||||||
entry[0].flags |= G_OPTION_FLAG_NO_ARG;
|
entry[0].flags |= G_OPTION_FLAG_NO_ARG;
|
||||||
|
@ -128,6 +128,15 @@ vips_mosaic_build( VipsObject *object )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
/* Silence compiler warnings.
|
||||||
|
*/
|
||||||
|
dx0 = 0;
|
||||||
|
dy0 = 0;
|
||||||
|
scale1 = 0.0;
|
||||||
|
angle1 = 0.0;
|
||||||
|
dx1 = 0.0;
|
||||||
|
dy1 = 0.0;
|
||||||
|
|
||||||
g_assert( 0 );
|
g_assert( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@
|
|||||||
* 7/3/14
|
* 7/3/14
|
||||||
* - remove the embedded thumbnail reader, embedded thumbnails are too
|
* - remove the embedded thumbnail reader, embedded thumbnails are too
|
||||||
* unlike the main image wrt. rotation / colour / etc.
|
* unlike the main image wrt. rotation / colour / etc.
|
||||||
|
* 30/6/14
|
||||||
|
* - fix interlaced thumbnail output, thanks lovell
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -585,8 +587,10 @@ thumbnail_rotate( VipsObject *process, VipsImage *im )
|
|||||||
* (eg.) "/poop/tn_somefile.jpg".
|
* (eg.) "/poop/tn_somefile.jpg".
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
thumbnail_write( VipsImage *im, const char *filename )
|
thumbnail_write( VipsObject *process, VipsImage *im, const char *filename )
|
||||||
{
|
{
|
||||||
|
VipsImage **t = (VipsImage **) vips_object_local_array( process, 1 );
|
||||||
|
|
||||||
char *file;
|
char *file;
|
||||||
char *p;
|
char *p;
|
||||||
char buf[FILENAME_MAX];
|
char buf[FILENAME_MAX];
|
||||||
@ -618,7 +622,16 @@ thumbnail_write( VipsImage *im, const char *filename )
|
|||||||
|
|
||||||
g_free( file );
|
g_free( file );
|
||||||
|
|
||||||
if( vips_image_write_to_file( im, output_name, NULL ) ) {
|
/* We need to cache the whole of the thumbnail before we write it
|
||||||
|
* in case we are writing an interlaced image. Interlaced png (for
|
||||||
|
* example) will make 7 passes over the image during write.
|
||||||
|
*/
|
||||||
|
if( vips_tilecache( im, &t[0],
|
||||||
|
"threaded", TRUE,
|
||||||
|
"persistent", TRUE,
|
||||||
|
"max_tiles", -1,
|
||||||
|
NULL ) ||
|
||||||
|
vips_image_write_to_file( t[0], output_name, NULL ) ) {
|
||||||
g_free( output_name );
|
g_free( output_name );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@ -644,7 +657,7 @@ thumbnail_process( VipsObject *process, const char *filename )
|
|||||||
thumbnail_shrink( process, in, interp, sharpen )) ||
|
thumbnail_shrink( process, in, interp, sharpen )) ||
|
||||||
!(crop = thumbnail_crop( process, thumbnail )) ||
|
!(crop = thumbnail_crop( process, thumbnail )) ||
|
||||||
!(rotate = thumbnail_rotate( process, crop )) ||
|
!(rotate = thumbnail_rotate( process, crop )) ||
|
||||||
thumbnail_write( rotate, filename ) )
|
thumbnail_write( process, rotate, filename ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
Loading…
Reference in New Issue
Block a user