Merge branch 'master' into loadpdf-range
This commit is contained in:
commit
ffc5279d2f
@ -2,6 +2,8 @@
|
|||||||
- many more wepsave options [Felix Bünemann]
|
- many more wepsave options [Felix Bünemann]
|
||||||
- added quant_table option to wepsave [Felix Bünemann]
|
- added quant_table option to wepsave [Felix Bünemann]
|
||||||
- added @n option to pdfload
|
- 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
|
15/4/16 started 8.3.1
|
||||||
- rename vips wrapper script, it was still vips-8.2, thanks Benjamin
|
- rename vips wrapper script, it was still vips-8.2, thanks Benjamin
|
||||||
|
4
TODO
4
TODO
@ -3,10 +3,10 @@
|
|||||||
$ vips copy k2.jpg x.dz[suffix=.jpg[Q=90]]
|
$ vips copy k2.jpg x.dz[suffix=.jpg[Q=90]]
|
||||||
dzsave: not , or ) after parameter
|
dzsave: not , or ) after parameter
|
||||||
|
|
||||||
- add n_pages to pdfload
|
|
||||||
|
|
||||||
- add more webp tests to py suite
|
- 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
|
- the gif tests in the suite sometimes fail with giflib5 because of an
|
||||||
uninitialized struct in giflib, see
|
uninitialized struct in giflib, see
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
* - allow zip > 4gb if we have a recent libgsf
|
* - allow zip > 4gb if we have a recent libgsf
|
||||||
* 9/9/15
|
* 9/9/15
|
||||||
* - better overlap handling, thanks robclouth
|
* - better overlap handling, thanks robclouth
|
||||||
|
* 24/11/15
|
||||||
|
* - don't write almost blank tiles in google mode
|
||||||
* 25/11/15
|
* 25/11/15
|
||||||
* - always strip tile metadata
|
* - always strip tile metadata
|
||||||
* 16/12/15
|
* 16/12/15
|
||||||
@ -596,6 +598,12 @@ struct _VipsForeignSaveDz {
|
|||||||
* Track bytes written here and try to guess when we'll go over.
|
* Track bytes written here and try to guess when we'll go over.
|
||||||
*/
|
*/
|
||||||
size_t bytes_written;
|
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;
|
typedef VipsForeignSaveClass VipsForeignSaveDzClass;
|
||||||
@ -1096,6 +1104,53 @@ tile_name( Layer *layer, int x, int y )
|
|||||||
return( out );
|
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
|
static int
|
||||||
strip_work( VipsThreadState *state, void *a )
|
strip_work( VipsThreadState *state, void *a )
|
||||||
{
|
{
|
||||||
@ -1116,7 +1171,7 @@ strip_work( VipsThreadState *state, void *a )
|
|||||||
printf( "strip_work\n" );
|
printf( "strip_work\n" );
|
||||||
#endif /*DEBUG_VERBOSE*/
|
#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.
|
* this case, and the viewer will display blank.png for us.
|
||||||
*/
|
*/
|
||||||
if( dz->centre ) {
|
if( dz->centre ) {
|
||||||
@ -1149,6 +1204,22 @@ strip_work( VipsThreadState *state, void *a )
|
|||||||
state->pos.width, state->pos.height, NULL ) )
|
state->pos.width, state->pos.height, NULL ) )
|
||||||
return( -1 );
|
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.
|
/* Google tiles need to be padded up to tilesize.
|
||||||
*/
|
*/
|
||||||
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
|
if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_GOOGLE ) {
|
||||||
@ -1596,6 +1667,16 @@ vips_foreign_save_dz_build( VipsObject *object )
|
|||||||
save->ready = z;
|
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
|
/* The real pixels we have from our input. This is about to get
|
||||||
* expanded with background.
|
* expanded with background.
|
||||||
*/
|
*/
|
||||||
|
@ -433,10 +433,10 @@ vips_image_guess_format( const VipsImage *image )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_INTERPRETATION_CMYK:
|
case VIPS_INTERPRETATION_CMYK:
|
||||||
if( image->BandFmt != VIPS_FORMAT_USHORT )
|
if( image->BandFmt == VIPS_FORMAT_USHORT )
|
||||||
format = VIPS_FORMAT_UCHAR;
|
format = VIPS_FORMAT_USHORT;
|
||||||
else
|
else
|
||||||
format = image->BandFmt;
|
format = VIPS_FORMAT_UCHAR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_INTERPRETATION_LABQ:
|
case VIPS_INTERPRETATION_LABQ:
|
||||||
@ -453,14 +453,15 @@ vips_image_guess_format( const VipsImage *image )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_INTERPRETATION_MATRIX:
|
case VIPS_INTERPRETATION_MATRIX:
|
||||||
if( image->BandFmt != VIPS_FORMAT_DOUBLE )
|
if( image->BandFmt == VIPS_FORMAT_DOUBLE )
|
||||||
format = VIPS_FORMAT_FLOAT;
|
format = VIPS_FORMAT_DOUBLE;
|
||||||
else
|
else
|
||||||
format = image->BandFmt;
|
format = VIPS_FORMAT_FLOAT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
format = VIPS_FORMAT_NOTSET;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return( format );
|
return( format );
|
||||||
|
Loading…
Reference in New Issue
Block a user