add @depth option to dzsave

so you can ask for a 1 layer pyramid
This commit is contained in:
John Cupitt 2012-11-01 18:11:46 +00:00
parent 035cf44fe6
commit 09789ebdfd
6 changed files with 88 additions and 15 deletions

View File

@ -14,6 +14,7 @@
- openslide2vips gets underlying tile size from openslide - openslide2vips gets underlying tile size from openslide
- embed has 'background' option - embed has 'background' option
- dzsave --layout google has a @background option - dzsave --layout google has a @background option
- dzsave has a --depth option
- update for new glib threading API - update for new glib threading API
- remove no threads option - remove no threads option

3
TODO
View File

@ -1,5 +1,4 @@
- add something to dzsave to control pyramid depth ... can then use it for - test dzsave depth option
straight tiling
- boolean.c has - boolean.c has

View File

@ -26,6 +26,8 @@
* - add zoomify and google maps output * - add zoomify and google maps output
* 10/10/12 * 10/10/12
* - add @background option * - add @background option
* 1/11/12
* - add @depth option
*/ */
/* /*
@ -134,6 +136,7 @@ struct _VipsForeignSaveDz {
int tile_size; int tile_size;
VipsForeignDzLayout layout; VipsForeignDzLayout layout;
VipsArea *background; VipsArea *background;
VipsForeignDzDepth depth;
Layer *layer; /* x2 shrink pyr layer */ Layer *layer; /* x2 shrink pyr layer */
@ -238,13 +241,24 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, int width, int height )
return( NULL ); return( NULL );
} }
/* DeepZoom stops at 1x1 pixels, others when the image fits within a switch( dz->depth ) {
* tile. case VIPS_FOREIGN_DZ_DEPTH_1PIXEL:
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_DZ )
limit = 1; limit = 1;
else break;
case VIPS_FOREIGN_DZ_DEPTH_1TILE:
limit = dz->tile_size; limit = dz->tile_size;
break;
case VIPS_FOREIGN_DZ_DEPTH_1:
limit = VIPS_MAX( width, height );
break;
default:
g_assert( 0 );
limit = dz->tile_size;
break;
}
if( width > limit || if( width > limit ||
height > limit ) { height > limit ) {
@ -982,8 +996,7 @@ pyramid_strip( VipsRegion *region, VipsRect *area, void *a )
layer->write_y += target.height; layer->write_y += target.height;
/* If we've filled the strip of the layer below, let it know. /* We can either fill the region, if it's somewhere half-way
* We can either fill the region, if it's somewhere half-way
* down the image, or, if it's at the bottom, get to the last * down the image, or, if it's at the bottom, get to the last
* writeable line. * writeable line.
*/ */
@ -1013,10 +1026,6 @@ vips_foreign_save_dz_build( VipsObject *object )
VIPS_SETSTR( dz->suffix, ".jpg" ); VIPS_SETSTR( dz->suffix, ".jpg" );
} }
if( VIPS_OBJECT_CLASS( vips_foreign_save_dz_parent_class )->
build( object ) )
return( -1 );
if( dz->overlap >= dz->tile_size || if( dz->overlap >= dz->tile_size ||
dz->overlap >= dz->tile_size ) { dz->overlap >= dz->tile_size ) {
vips_error( "dzsave", vips_error( "dzsave",
@ -1025,6 +1034,21 @@ vips_foreign_save_dz_build( VipsObject *object )
return( -1 ); return( -1 );
} }
/* DeepZoom stops at 1x1 pixels, others when the image fits within a
* tile.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_DZ ) {
if( !vips_object_get_argument_assigned( object, "depth" ) )
dz->depth = VIPS_FOREIGN_DZ_DEPTH_1PIXEL;
}
else
if( !vips_object_get_argument_assigned( object, "depth" ) )
dz->depth = VIPS_FOREIGN_DZ_DEPTH_1TILE;
if( VIPS_OBJECT_CLASS( vips_foreign_save_dz_parent_class )->
build( object ) )
return( -1 );
/* Build the skeleton of the image pyramid. /* Build the skeleton of the image pyramid.
*/ */
if( !(dz->layer = pyramid_build( dz, if( !(dz->layer = pyramid_build( dz,
@ -1145,6 +1169,14 @@ vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class )
G_STRUCT_OFFSET( VipsForeignSaveDz, background ), G_STRUCT_OFFSET( VipsForeignSaveDz, background ),
VIPS_TYPE_ARRAY_DOUBLE ); VIPS_TYPE_ARRAY_DOUBLE );
VIPS_ARG_ENUM( class, "depth", 13,
_( "Depth" ),
_( "Pyramid depth" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignSaveDz, depth ),
VIPS_TYPE_FOREIGN_DZ_DEPTH,
VIPS_FOREIGN_DZ_DEPTH_1PIXEL );
/* How annoying. We stupidly had these in earlier versions. /* How annoying. We stupidly had these in earlier versions.
*/ */
@ -1182,6 +1214,7 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
dz->background = dz->background =
vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 ); vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 );
((double *) (dz->background->data))[0] = 255; ((double *) (dz->background->data))[0] = 255;
dz->depth = VIPS_FOREIGN_DZ_DEPTH_1PIXEL;
} }
/** /**
@ -1197,6 +1230,7 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
* @overlap; set tile overlap * @overlap; set tile overlap
* @tile_size; set tile size * @tile_size; set tile size
* @background: background colour * @background: background colour
* @depth: how deep to make the pyramid
* *
* 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.
@ -1208,7 +1242,7 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
* In Zoomify and Google layout, a directory called @basename is created to * In Zoomify and Google layout, a directory called @basename is created to
* hold the tile structure. * hold the tile structure.
* *
* You can set @suffix to something like ".jpg[Q=85]" to set the tile write * You can set @suffix to something like ".jpg[Q=85]" to control the tile write
* options. * 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
@ -1218,6 +1252,9 @@ vips_foreign_save_dz_init( VipsForeignSaveDz *dz )
* You can set the size and overlap of tiles with @tile_size and @overlap. * You can set the size and overlap of tiles with @tile_size and @overlap.
* They default to the correct settings for the selected @layout. * They default to the correct settings for the selected @layout.
* *
* Use @depth to control how low the pyramid goes. This defaults to the
* correct setting for the @layout you select.
*
* See also: vips_tiffsave(). * See also: vips_tiffsave().
* *
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.

View File

@ -19,6 +19,8 @@ GType vips_foreign_tiff_resunit_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_TIFF_RESUNIT (vips_foreign_tiff_resunit_get_type()) #define VIPS_TYPE_FOREIGN_TIFF_RESUNIT (vips_foreign_tiff_resunit_get_type())
GType vips_foreign_dz_layout_get_type (void) G_GNUC_CONST; GType vips_foreign_dz_layout_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_DZ_LAYOUT (vips_foreign_dz_layout_get_type()) #define VIPS_TYPE_FOREIGN_DZ_LAYOUT (vips_foreign_dz_layout_get_type())
GType vips_foreign_dz_depth_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_DZ_DEPTH (vips_foreign_dz_depth_get_type())
/* enumerations from "../../../libvips/include/vips/arithmetic.h" */ /* enumerations from "../../../libvips/include/vips/arithmetic.h" */
GType vips_operation_math_get_type (void) G_GNUC_CONST; GType vips_operation_math_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_MATH (vips_operation_math_get_type()) #define VIPS_TYPE_OPERATION_MATH (vips_operation_math_get_type())

View File

@ -430,7 +430,7 @@ int vips_radsave( VipsImage *in, const char *filename, ... )
* @VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY: use Zoomify directory layout * @VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY: use Zoomify directory layout
* @VIPS_FOREIGN_DZ_LAYOUT_GOOGLE: use Google maps directory layout * @VIPS_FOREIGN_DZ_LAYOUT_GOOGLE: use Google maps directory layout
* *
* Use inches or centimeters as the resolution unit for a tiff file. * What directory layout and metadata standard to use.
*/ */
typedef enum { typedef enum {
VIPS_FOREIGN_DZ_LAYOUT_DZ, VIPS_FOREIGN_DZ_LAYOUT_DZ,
@ -439,6 +439,21 @@ typedef enum {
VIPS_FOREIGN_DZ_LAYOUT_LAST VIPS_FOREIGN_DZ_LAYOUT_LAST
} VipsForeignDzLayout; } VipsForeignDzLayout;
/**
* VipsForeignDzDepth:
* @VIPS_FOREIGN_DZ_DEPTH_1PIXEL: create layers down to 1x1 pixel
* @VIPS_FOREIGN_DZ_DEPTH_1TILE: create layers down to 1x1 tile
* @VIPS_FOREIGN_DZ_DEPTH_1: only create a single layer
*
* How many pyramid layers to create.
*/
typedef enum {
VIPS_FOREIGN_DZ_DEPTH_1PIXEL,
VIPS_FOREIGN_DZ_DEPTH_1TILE,
VIPS_FOREIGN_DZ_DEPTH_1,
VIPS_FOREIGN_DZ_DEPTH_LAST
} VipsForeignDzDepth;
int vips_dzsave( VipsImage *in, const char *basename, ... ) int vips_dzsave( VipsImage *in, const char *basename, ... )
__attribute__((sentinel)); __attribute__((sentinel));

View File

@ -124,6 +124,25 @@ vips_foreign_dz_layout_get_type( void )
return( etype ); return( etype );
} }
GType
vips_foreign_dz_depth_get_type( void )
{
static GType etype = 0;
if( etype == 0 ) {
static const GEnumValue values[] = {
{VIPS_FOREIGN_DZ_DEPTH_1PIXEL, "VIPS_FOREIGN_DZ_DEPTH_1PIXEL", "1pixel"},
{VIPS_FOREIGN_DZ_DEPTH_1TILE, "VIPS_FOREIGN_DZ_DEPTH_1TILE", "1tile"},
{VIPS_FOREIGN_DZ_DEPTH_1, "VIPS_FOREIGN_DZ_DEPTH_1", "1"},
{VIPS_FOREIGN_DZ_DEPTH_LAST, "VIPS_FOREIGN_DZ_DEPTH_LAST", "last"},
{0, NULL, NULL}
};
etype = g_enum_register_static( "VipsForeignDzDepth", values );
}
return( etype );
}
/* enumerations from "../../libvips/include/vips/conversion.h" */ /* enumerations from "../../libvips/include/vips/conversion.h" */
GType GType
vips_extend_get_type( void ) vips_extend_get_type( void )