Merge branch 'master' into loadpdf-range

This commit is contained in:
John Cupitt 2016-05-15 10:01:27 +01:00
commit ffc5279d2f
4 changed files with 94 additions and 10 deletions

View File

@ -2,6 +2,8 @@
- many more wepsave options [Felix Bünemann]
- added quant_table option to wepsave [Felix Bünemann]
- added @n option to pdfload
- dzsave won't write empty tiles in google mode, thanks bverem, perog,
felixbuenemann
15/4/16 started 8.3.1
- rename vips wrapper script, it was still vips-8.2, thanks Benjamin

4
TODO
View File

@ -3,10 +3,10 @@
$ vips copy k2.jpg x.dz[suffix=.jpg[Q=90]]
dzsave: not , or ) after parameter
- add n_pages to pdfload
- add more webp tests to py suite
- try moving some more of the CLI tests to py
- the gif tests in the suite sometimes fail with giflib5 because of an
uninitialized struct in giflib, see

View File

@ -55,6 +55,8 @@
* - allow zip > 4gb if we have a recent libgsf
* 9/9/15
* - better overlap handling, thanks robclouth
* 24/11/15
* - don't write almost blank tiles in google mode
* 25/11/15
* - always strip tile metadata
* 16/12/15
@ -596,6 +598,12 @@ struct _VipsForeignSaveDz {
* Track bytes written here and try to guess when we'll go over.
*/
size_t bytes_written;
/* save->background turned into a pixel that matches the image we are
* saving .. used to test for blank tiles.
*/
VipsPel *ink;
};
typedef VipsForeignSaveClass VipsForeignSaveDzClass;
@ -1096,6 +1104,53 @@ tile_name( Layer *layer, int x, int y )
return( out );
}
/* Test for tile equal to background colour. In google maps mode, we skip
* blank background tiles.
*
* Don't use exactly equality, since compression artefacts or noise can upset
* this.
*/
static gboolean
tile_equal( VipsImage *image, VipsPel * restrict ink )
{
const int bytes = VIPS_IMAGE_SIZEOF_PEL( image );
VipsRect rect;
VipsRegion *region;
int x, y, b;
region = vips_region_new( image );
/* We know @image is part of a memory buffer, so this will be quick.
*/
rect.left = 0;
rect.top = 0;
rect.width = image->Xsize;
rect.height = image->Ysize;
if( vips_region_prepare( region, &rect ) ) {
g_object_unref( region );
return( FALSE );
}
for( y = 0; y < image->Ysize; y++ ) {
VipsPel * restrict p = VIPS_REGION_ADDR( region, 0, y );
for( x = 0; x < image->Xsize; x++ ) {
for( b = 0; b < bytes; b++ )
if( VIPS_ABS( p[b] - ink[b] ) > 5 ) {
g_object_unref( region );
return( FALSE );
}
p += bytes;
}
}
g_object_unref( region );
return( TRUE );
}
static int
strip_work( VipsThreadState *state, void *a )
{
@ -1116,7 +1171,7 @@ strip_work( VipsThreadState *state, void *a )
printf( "strip_work\n" );
#endif /*DEBUG_VERBOSE*/
/* If we are centring we may be outside the real pixels. Skip in
/* If we are centering we may be outside the real pixels. Skip in
* this case, and the viewer will display blank.png for us.
*/
if( dz->centre ) {
@ -1149,6 +1204,22 @@ strip_work( VipsThreadState *state, void *a )
state->pos.width, state->pos.height, NULL ) )
return( -1 );
/* If we are writing a google map pyramid and the tile is equal to the
* background, don't save. The viewer will display blank.png for us.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE &&
tile_equal( x, dz->ink ) ) {
g_object_unref( x );
#ifdef DEBUG_VERBOSE
printf( "strip_work: skipping blank tile %d x %d\n",
state->x / dz->tile_size,
state->y / dz->tile_size );
#endif /*DEBUG_VERBOSE*/
return( 0 );
}
/* Google tiles need to be padded up to tilesize.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
@ -1596,6 +1667,16 @@ vips_foreign_save_dz_build( VipsObject *object )
save->ready = z;
}
/* We use ink in google mode to check for blank tiles.
*/
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
if( !(dz->ink = vips__vector_to_ink(
class->nickname, save->ready,
VIPS_AREA( save->background )->data, NULL,
VIPS_AREA( save->background )->n )) )
return( -1 );
}
/* The real pixels we have from our input. This is about to get
* expanded with background.
*/

View File

@ -433,10 +433,10 @@ vips_image_guess_format( const VipsImage *image )
break;
case VIPS_INTERPRETATION_CMYK:
if( image->BandFmt != VIPS_FORMAT_USHORT )
format = VIPS_FORMAT_UCHAR;
if( image->BandFmt == VIPS_FORMAT_USHORT )
format = VIPS_FORMAT_USHORT;
else
format = image->BandFmt;
format = VIPS_FORMAT_UCHAR;
break;
case VIPS_INTERPRETATION_LABQ:
@ -453,14 +453,15 @@ vips_image_guess_format( const VipsImage *image )
break;
case VIPS_INTERPRETATION_MATRIX:
if( image->BandFmt != VIPS_FORMAT_DOUBLE )
format = VIPS_FORMAT_FLOAT;
if( image->BandFmt == VIPS_FORMAT_DOUBLE )
format = VIPS_FORMAT_DOUBLE;
else
format = image->BandFmt;
format = VIPS_FORMAT_FLOAT;
break;
default:
g_assert_not_reached();
format = VIPS_FORMAT_NOTSET;
break;
}
return( format );