add iiif layout to dzsave
This commit is contained in:
parent
4cf8246312
commit
f499cefb0e
@ -17,6 +17,7 @@
|
|||||||
- nifti load/save uses double for all floating point metadata
|
- nifti load/save uses double for all floating point metadata
|
||||||
- add vips_error_buffer_copy()
|
- add vips_error_buffer_copy()
|
||||||
- add @no_strip option to dzsave [kalozka1]
|
- add @no_strip option to dzsave [kalozka1]
|
||||||
|
- add iiif layout to dzsave
|
||||||
|
|
||||||
31/8/19 started 8.8.3
|
31/8/19 started 8.8.3
|
||||||
- revert sharpen restoring the input colourspace
|
- revert sharpen restoring the input colourspace
|
||||||
|
@ -83,6 +83,8 @@
|
|||||||
* - add @skip_blanks
|
* - add @skip_blanks
|
||||||
* 21/10/19
|
* 21/10/19
|
||||||
* - add @no_strip
|
* - add @no_strip
|
||||||
|
* 9/11/19
|
||||||
|
* - add IIIF layout
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -937,6 +939,86 @@ write_blank( VipsForeignSaveDz *dz )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write IIIF JSON metadata.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
write_json( VipsForeignSaveDz *dz )
|
||||||
|
{
|
||||||
|
GsfOutput *out;
|
||||||
|
char buf[VIPS_PATH_MAX];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
out = vips_gsf_path( dz->tree, "info.json", NULL );
|
||||||
|
|
||||||
|
gsf_output_printf( out,
|
||||||
|
"{\n"
|
||||||
|
" \"@context\": \"http://iiif.io/api/image/2/context.json\",\n"
|
||||||
|
" \"@id\": \"https://example.com/iiif/apple\",\n"
|
||||||
|
" \"profile\": [\n"
|
||||||
|
" \"http://iiif.io/api/image/2/level0.json\",\n"
|
||||||
|
" {\n"
|
||||||
|
" \"formats\": [\n"
|
||||||
|
" \"jpg\"\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"qualities\": [\n"
|
||||||
|
" \"default\"\n"
|
||||||
|
" ]\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n"
|
||||||
|
" \"protocol\": \"http://iiif.io/api/image\",\n"
|
||||||
|
" \"sizes\": [\n" );
|
||||||
|
|
||||||
|
for( i = 0; i < dz->layer->n + 5; i++ ) {
|
||||||
|
gsf_output_printf( out,
|
||||||
|
" {\n"
|
||||||
|
" \"width\": %d,\n"
|
||||||
|
" \"height\": \"full\"\n"
|
||||||
|
" }",
|
||||||
|
1 << (i + 4) );
|
||||||
|
if( i != dz->layer->n - 4 )
|
||||||
|
gsf_output_printf( out, "," );
|
||||||
|
gsf_output_printf( out, "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
gsf_output_printf( out,
|
||||||
|
" ],\n" );
|
||||||
|
|
||||||
|
gsf_output_printf( out,
|
||||||
|
" \"tiles\": [\n"
|
||||||
|
" {\n"
|
||||||
|
" \"scalefactors\": [\n" );
|
||||||
|
|
||||||
|
for( i = 0; i < dz->layer->n; i++ ) {
|
||||||
|
gsf_output_printf( out,
|
||||||
|
" %d",
|
||||||
|
1 << i );
|
||||||
|
if( i != dz->layer->n - 1 )
|
||||||
|
gsf_output_printf( out, "," );
|
||||||
|
gsf_output_printf( out, "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
gsf_output_printf( out,
|
||||||
|
" ],\n"
|
||||||
|
" \"width\": %d\n"
|
||||||
|
" }\n"
|
||||||
|
" ],\n", dz->tile_size );
|
||||||
|
|
||||||
|
gsf_output_printf( out,
|
||||||
|
" \"width\": %d,\n"
|
||||||
|
" \"height\": %d\n",
|
||||||
|
dz->layer->image->Xsize,
|
||||||
|
dz->layer->image->Ysize );
|
||||||
|
|
||||||
|
gsf_output_printf( out,
|
||||||
|
"}\n" );
|
||||||
|
|
||||||
|
(void) gsf_output_close( out );
|
||||||
|
g_object_unref( out );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
write_vips_meta( VipsForeignSaveDz *dz )
|
write_vips_meta( VipsForeignSaveDz *dz )
|
||||||
{
|
{
|
||||||
@ -1306,6 +1388,40 @@ tile_name( Layer *layer, int x, int y )
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIPS_FOREIGN_DZ_LAYOUT_IIIF:
|
||||||
|
{
|
||||||
|
/* Tiles are addressed in full resolution coordinates, so
|
||||||
|
* scale up by layer->sub and dz->tile_size
|
||||||
|
*/
|
||||||
|
int left = x * dz->tile_size * layer->sub;
|
||||||
|
int top = y * dz->tile_size * layer->sub;
|
||||||
|
int width = VIPS_MIN( dz->tile_size * layer->sub,
|
||||||
|
layer->width * layer->sub - left );
|
||||||
|
int height = VIPS_MIN( dz->tile_size * layer->sub,
|
||||||
|
layer->height * layer->sub - top );
|
||||||
|
|
||||||
|
/* IIIF "size" is just real tile width, I think.
|
||||||
|
*
|
||||||
|
* TODO .. .is this right? shouldn't it be the smaller of
|
||||||
|
* width and height?
|
||||||
|
*/
|
||||||
|
int size = VIPS_MIN( dz->tile_size,
|
||||||
|
layer->width - x * dz->tile_size );
|
||||||
|
|
||||||
|
vips_snprintf( dirname, VIPS_PATH_MAX, "%d,%d,%d,%d",
|
||||||
|
left, top, width, height );
|
||||||
|
vips_snprintf( dirname2, VIPS_PATH_MAX, "%d,", size );
|
||||||
|
vips_snprintf( name, VIPS_PATH_MAX, "default%s",
|
||||||
|
dz->file_suffix );
|
||||||
|
|
||||||
|
/* "0" is rotation and is always 0.
|
||||||
|
*/
|
||||||
|
out = vips_gsf_path( dz->tree,
|
||||||
|
name, dirname, dirname2, "0", NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
||||||
@ -1814,10 +1930,11 @@ vips_foreign_save_dz_build( VipsObject *object )
|
|||||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( dz );
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( dz );
|
||||||
VipsRect real_pixels;
|
VipsRect real_pixels;
|
||||||
|
|
||||||
/* Google and zoomify default to zero overlap, ".jpg".
|
/* Google, zoomify and iiif default to zero overlap, ".jpg".
|
||||||
*/
|
*/
|
||||||
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY ||
|
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY ||
|
||||||
dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
|
dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ||
|
||||||
|
dz->layout == VIPS_FOREIGN_DZ_LAYOUT_IIIF ) {
|
||||||
if( !vips_object_argument_isset( object, "overlap" ) )
|
if( !vips_object_argument_isset( object, "overlap" ) )
|
||||||
dz->overlap = 0;
|
dz->overlap = 0;
|
||||||
if( !vips_object_argument_isset( object, "suffix" ) )
|
if( !vips_object_argument_isset( object, "suffix" ) )
|
||||||
@ -1832,6 +1949,13 @@ vips_foreign_save_dz_build( VipsObject *object )
|
|||||||
dz->tile_size = 256;
|
dz->tile_size = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some iif writers default to 256, some to 512. We pick 512.
|
||||||
|
*/
|
||||||
|
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_IIIF ) {
|
||||||
|
if( !vips_object_argument_isset( object, "tile_size" ) )
|
||||||
|
dz->tile_size = 512;
|
||||||
|
}
|
||||||
|
|
||||||
/* skip_blanks defaults to 5 in google mode.
|
/* skip_blanks defaults to 5 in google mode.
|
||||||
*/
|
*/
|
||||||
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE &&
|
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE &&
|
||||||
@ -2136,6 +2260,11 @@ vips_foreign_save_dz_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIPS_FOREIGN_DZ_LAYOUT_IIIF:
|
||||||
|
if( write_json( dz ) )
|
||||||
|
return( -1 );
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
@ -588,6 +588,7 @@ int vips_niftisave( VipsImage *in, const char *filename, ... )
|
|||||||
* @VIPS_FOREIGN_DZ_LAYOUT_DZ: use DeepZoom directory layout
|
* @VIPS_FOREIGN_DZ_LAYOUT_DZ: use DeepZoom directory layout
|
||||||
* @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
|
||||||
|
* @VIPS_FOREIGN_DZ_LAYOUT_IIIF: use IIIF directory layout
|
||||||
*
|
*
|
||||||
* What directory layout and metadata standard to use.
|
* What directory layout and metadata standard to use.
|
||||||
*/
|
*/
|
||||||
@ -595,6 +596,7 @@ typedef enum {
|
|||||||
VIPS_FOREIGN_DZ_LAYOUT_DZ,
|
VIPS_FOREIGN_DZ_LAYOUT_DZ,
|
||||||
VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY,
|
VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY,
|
||||||
VIPS_FOREIGN_DZ_LAYOUT_GOOGLE,
|
VIPS_FOREIGN_DZ_LAYOUT_GOOGLE,
|
||||||
|
VIPS_FOREIGN_DZ_LAYOUT_IIIF,
|
||||||
VIPS_FOREIGN_DZ_LAYOUT_LAST
|
VIPS_FOREIGN_DZ_LAYOUT_LAST
|
||||||
} VipsForeignDzLayout;
|
} VipsForeignDzLayout;
|
||||||
|
|
||||||
|
@ -612,6 +612,7 @@ vips_foreign_dz_layout_get_type( void )
|
|||||||
{VIPS_FOREIGN_DZ_LAYOUT_DZ, "VIPS_FOREIGN_DZ_LAYOUT_DZ", "dz"},
|
{VIPS_FOREIGN_DZ_LAYOUT_DZ, "VIPS_FOREIGN_DZ_LAYOUT_DZ", "dz"},
|
||||||
{VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY, "VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY", "zoomify"},
|
{VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY, "VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY", "zoomify"},
|
||||||
{VIPS_FOREIGN_DZ_LAYOUT_GOOGLE, "VIPS_FOREIGN_DZ_LAYOUT_GOOGLE", "google"},
|
{VIPS_FOREIGN_DZ_LAYOUT_GOOGLE, "VIPS_FOREIGN_DZ_LAYOUT_GOOGLE", "google"},
|
||||||
|
{VIPS_FOREIGN_DZ_LAYOUT_IIIF, "VIPS_FOREIGN_DZ_LAYOUT_IIIF", "iiif"},
|
||||||
{VIPS_FOREIGN_DZ_LAYOUT_LAST, "VIPS_FOREIGN_DZ_LAYOUT_LAST", "last"},
|
{VIPS_FOREIGN_DZ_LAYOUT_LAST, "VIPS_FOREIGN_DZ_LAYOUT_LAST", "last"},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user