diff --git a/configure.in b/configure.in index 6f757c23..4d256d65 100644 --- a/configure.in +++ b/configure.in @@ -305,6 +305,7 @@ AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_MEMCMP AC_FUNC_MMAP +AC_FUNC_MKDIR AC_FUNC_VPRINTF AC_CHECK_FUNCS([getcwd gettimeofday getwd memset munmap putenv realpath strcasecmp strchr strcspn strdup strerror strrchr strspn vsnprintf realpath mkstemp mktemp random rand sysconf atexit]) AC_CHECK_LIB(m,cbrt,[AC_DEFINE(HAVE_CBRT,1,[have cbrt() in libm.])]) diff --git a/libvips/foreign/Makefile.am b/libvips/foreign/Makefile.am index addf7951..7f9e7483 100644 --- a/libvips/foreign/Makefile.am +++ b/libvips/foreign/Makefile.am @@ -13,6 +13,7 @@ libforeign_la_SOURCES = \ csv.c \ csvload.c \ csvsave.c \ + dzsave.c \ rawload.c \ rawsave.c \ vipsload.c \ diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index ea5aead2..f6feaf87 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1574,6 +1574,7 @@ vips_foreign_operation_init( void ) extern GType vips_foreign_save_raw_get_type( void ); extern GType vips_foreign_save_raw_fd_get_type( void ); extern GType vips_foreign_load_magick_get_type( void ); + extern GType vips_foreign_save_dz_get_type( void ); vips_foreign_load_rad_get_type(); vips_foreign_save_rad_get_type(); @@ -1587,6 +1588,7 @@ vips_foreign_operation_init( void ) vips_foreign_save_raw_fd_get_type(); vips_foreign_load_vips_get_type(); vips_foreign_save_vips_get_type(); + vips_foreign_save_dz_get_type(); #ifdef HAVE_PNG vips_foreign_load_png_get_type(); @@ -2299,3 +2301,45 @@ vips_matload( const char *filename, VipsImage **out, ... ) return( result ); } +/** + * vips_dzsave: + * @in: image to save + * @dirname: directory to save to + * @...: %NULL-terminated list of optional named arguments + * + * Optional arguments: + * + * @suffix: suffix for tile tiles (default ".jpg") + * @overlap; set tile overlap + * @tile_width; set tile size + * @tile_height; set tile size + * + * Save an image to a deep zoom - style directory tree. + * + * The image is shrunk in a series of x2 reductions until it fits within a + * tile. Each layer is written out to a separate subdirectory of @dirname, + * with directory "0" holding the smallest, single tile image. + * + * Each tile is written as a separate file named as "@x_@y@suffix", where @x + * and @y are the tile coordinates, with (0, 0) as the top-left tile. + * + * You can set @suffix to something like ".jpg[Q=85]" to set the tile write + * options. + * + * See also: vips_tiffsave(). + * + * Returns: 0 on success, -1 on error. + */ +int +vips_dzsave( VIpsImage *in, const char *dirname, ... ) +{ + va_list ap; + int result; + + va_start( ap, dirname ); + result = vips_call_split( "dzsave", ap, in, dirname ); + va_end( ap ); + + return( result ); +} + diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 059d2bd5..81920ade 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -126,6 +126,8 @@ * 2/12/11 * - make into a simple function call ready to be wrapped as a new-style * VipsForeign class + * 21/3/12 + * - bump max layer buffer up */ /* @@ -182,7 +184,7 @@ /* Max no of tiles we buffer in a layer. Enough to buffer a line of 64x64 * tiles on a 100k pixel across image. */ -#define MAX_LAYER_BUFFER (1000) +#define MAX_LAYER_BUFFER (10000) /* Bits we OR together for quadrants in a tile. */ diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 4d235fd0..ff29ff43 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -205,6 +205,8 @@ int vips__seek( int fd, gint64 pos ); int vips__ftruncate( int fd, gint64 pos ); int vips_existsf( const char *name, ... ) __attribute__((format(printf, 1, 2))); +int vips_mkdirf( const char *name, ... ) + __attribute__((format(printf, 1, 2))); FILE *vips_popenf( const char *fmt, const char *mode, ... ) __attribute__((format(printf, 1, 3))); diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 882530e9..6d83b531 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1168,6 +1168,47 @@ vips_popenf( const char *fmt, const char *mode, ... ) return( fp ); } +/* Handle broken mkdirs() + */ +#if HAVE_MKDIR +# if MKDIR_TAKES_ONE_ARG + /* Mingw32 */ +# define mkdir(a,b) mkdir(a) +# endif +#else +# ifdef HAVE__MKDIR + /* plain Win32 */ +# include +# define mkdir(a,b) _mkdir(a) +# else +# error "Don't know how to create a directory on this system." +# endif +#endif + +/* Make a directory. + */ +int +vips_mkdirf( const char *name, ... ) +{ + va_list ap; + char buf1[PATH_MAX]; + + va_start( ap, name ); + (void) vips_vsnprintf( buf1, PATH_MAX - 1, name, ap ); + va_end( ap ); + + /* Try that. + */ + if( !mkdir( buf1, 0755 ) ) { + vips_error( "mkdirf", + _( "unable to create directory \"%s\", %s" ), + buf1, strerror( errno ) ); + return( -1 ); + } + + return( 0 ); +} + /* Break a command-line argument into tokens separated by whitespace. * * Strings can't be adjacent, so "hello world" (without quotes) is a single