Merge branch 'master' into add-webp-metadata
This commit is contained in:
commit
5d61bd4982
18
ChangeLog
18
ChangeLog
@ -7,6 +7,24 @@
|
||||
- added vips_image_hasalpha()
|
||||
- added vips_thumbnail() / vips_thumbnail_buffer()
|
||||
- webpload/webpsave read and write icc, xmp, exif metadata
|
||||
- better >4gb detect for zip dzsave output [Felix Bünemann]
|
||||
- all loaders have a @fail option, meaning fail on first warning, though it
|
||||
only does anything for jpg and csv
|
||||
- add vips_image_get_fields() to help bindings
|
||||
- add tiff multi-page read/write
|
||||
- add VIPS_META_PAGE_HEIGHT metadata
|
||||
- IM6/IM7 magickload supports page/n/page-height, all_frames deprecated
|
||||
- gifload supports n/page-height
|
||||
- added #defines for VIPS_SONAME, VIPS_LIBRARY_CURRENT, VIPS_LIBRARY_REVISION,
|
||||
VIPS_LIBRARY_AGE
|
||||
- better support for bscale / bzero in fits images
|
||||
- deprecate vips_warn() / vips_info(); use g_warning() / g_info() instead
|
||||
|
||||
8/12/16 started 8.4.5
|
||||
- allow libgsf-1.14.26 to help centos, thanks tdiprima
|
||||
|
||||
11/11/16 started 8.4.4
|
||||
- fix crash in vips.exe arg parsing on Windows, thanks Yury
|
||||
|
||||
18/10/16 started 8.4.3
|
||||
- fix error detection in gif_close, thanks aaron42net
|
||||
|
@ -96,6 +96,10 @@ Leak check:
|
||||
--leak-check=yes \
|
||||
vips ... > vips-vg.log 2>&1
|
||||
|
||||
Memory error debug:
|
||||
|
||||
$ valgrind --vgdb=yes --vgdb-error=0 vips ...
|
||||
|
||||
valgrind threading check:
|
||||
|
||||
$ valgrind --tool=helgrind vips ... > vips-vg.log 2>&1
|
||||
|
@ -404,9 +404,12 @@ GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
|
||||
AC_ARG_WITH([gsf],
|
||||
AS_HELP_STRING([--without-gsf], [build without libgsf-1 (default: test)]))
|
||||
|
||||
# libgsf-1 1.14.21 crashes, .27 is known-good, not sure about 22-26
|
||||
# libgsf-1 1.14.21 crashes
|
||||
# .27 is known to work well
|
||||
# .26 seems OK but has not been tested much
|
||||
# not sure about 22-25
|
||||
if test x"$with_gsf" != "xno"; then
|
||||
PKG_CHECK_MODULES(GSF, libgsf-1 >= 1.14.27,
|
||||
PKG_CHECK_MODULES(GSF, libgsf-1 >= 1.14.26,
|
||||
[AC_DEFINE(HAVE_GSF,1,[define if you have libgsf-1 installed.])
|
||||
with_gsf=yes
|
||||
PACKAGES_USED="$PACKAGES_USED libgsf-1"
|
||||
@ -1114,7 +1117,7 @@ file import/export with libtiff: $with_tiff
|
||||
file import/export with giflib: $with_giflib
|
||||
file import/export with libjpeg: $with_jpeg
|
||||
image pyramid export: $with_gsf
|
||||
(requires libgsf-1 1.14.27 or later)
|
||||
(requires libgsf-1 1.14.26 or later)
|
||||
use libexif to load/save JPEG metadata: $with_libexif
|
||||
])
|
||||
|
||||
|
@ -350,7 +350,7 @@ set_property( VipsObject *object, const char *name, const GValue *value )
|
||||
|
||||
if( vips_object_get_argument( object, name,
|
||||
&pspec, &argument_class, &argument_instance ) ) {
|
||||
vips_warn( NULL, "%s", vips_error_buffer() );
|
||||
g_warning( "%s", vips_error_buffer() );
|
||||
vips_error_clear();
|
||||
return;
|
||||
}
|
||||
@ -364,7 +364,7 @@ set_property( VipsObject *object, const char *name, const GValue *value )
|
||||
|
||||
if( (enum_value = vips_enum_from_nick( object_class->nickname,
|
||||
pspec_type, g_value_get_string( value ) )) < 0 ) {
|
||||
vips_warn( NULL, "%s", vips_error_buffer() );
|
||||
g_warning( "%s", vips_error_buffer() );
|
||||
vips_error_clear();
|
||||
return;
|
||||
}
|
||||
|
@ -208,6 +208,14 @@ rm t1.v
|
||||
leak-test on exit, and also display an estimate of peak memory use.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Set <code>G_MESSAGES_DEBUG=VIPS</code> and GLib will display
|
||||
informational and debug messages from libvips.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
|
@ -64,6 +64,14 @@ EXTRA_DIST = \
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
all-local:
|
||||
echo '/* This file is autogenerated, do not edit. */' > soname.h && \
|
||||
source libvips.la && \
|
||||
echo "#define VIPS_SONAME \"$$dlname\"" >> soname.h && \
|
||||
( cmp -s soname.h include/vips/soname.h || \
|
||||
cp soname.h include/vips ) && \
|
||||
rm soname.h
|
||||
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
INTROSPECTION_GIRS =
|
||||
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
|
||||
|
@ -165,9 +165,11 @@ vips_measure_build( VipsObject *object )
|
||||
*/
|
||||
if( dev * 5 > VIPS_FABS( avg ) &&
|
||||
VIPS_FABS( avg ) > 3 )
|
||||
vips_warn( class->nickname,
|
||||
_( "patch %d x %d, band %d: "
|
||||
"avg = %g, sdev = %g" ),
|
||||
g_warning( _( "%s: "
|
||||
"patch %d x %d, "
|
||||
"band %d: "
|
||||
"avg = %g, sdev = %g" ),
|
||||
class->nickname,
|
||||
i, j, b, avg, dev );
|
||||
|
||||
*VIPS_MATRIX( measure->out,
|
||||
|
@ -193,9 +193,9 @@ static int
|
||||
icc_error( int code, const char *text )
|
||||
{
|
||||
if( code == LCMS_ERRC_WARNING )
|
||||
vips_warn( "VipsIcc", "%s", text );
|
||||
g_warning( "%s", text );
|
||||
else
|
||||
vips_error( "VipsIcc", "%s", text );
|
||||
vips_error( "VipsIcc", text );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -452,9 +452,9 @@ vips_check_intent( const char *domain,
|
||||
{
|
||||
if( profile &&
|
||||
!cmsIsIntentSupported( profile, intent, direction ) )
|
||||
vips_warn( domain,
|
||||
_( "intent %d (%s) not supported by "
|
||||
g_warning( _( "%s: intent %d (%s) not supported by "
|
||||
"%s profile; falling back to default intent" ),
|
||||
domain,
|
||||
intent, vips_enum_nick( VIPS_TYPE_INTENT, intent ),
|
||||
direction == LCMS_USED_AS_INPUT ?
|
||||
_( "input" ) : _( "output" ) );
|
||||
@ -542,7 +542,7 @@ vips_image_expected_bands( VipsImage *image )
|
||||
}
|
||||
|
||||
static cmsHPROFILE
|
||||
vips_icc_load_profile_image( const char *domain, VipsImage *image )
|
||||
vips_icc_load_profile_image( VipsImage *image )
|
||||
{
|
||||
void *data;
|
||||
size_t data_length;
|
||||
@ -554,15 +554,15 @@ vips_icc_load_profile_image( const char *domain, VipsImage *image )
|
||||
if( vips_image_get_blob( image, VIPS_META_ICC_NAME,
|
||||
&data, &data_length ) ||
|
||||
!(profile = cmsOpenProfileFromMem( data, data_length )) ) {
|
||||
vips_warn( domain, "%s", _( "corrupt embedded profile" ) );
|
||||
g_warning( "%s", _( "corrupt embedded profile" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
if( vips_image_expected_bands( image ) !=
|
||||
vips_icc_profile_needs_bands( profile ) ) {
|
||||
VIPS_FREEF( cmsCloseProfile, profile );
|
||||
vips_warn( domain,
|
||||
"%s", _( "embedded profile incompatible with image" ) );
|
||||
g_warning( "%s",
|
||||
_( "embedded profile incompatible with image" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
@ -584,8 +584,7 @@ vips_icc_load_profile_file( const char *domain,
|
||||
if( vips_image_expected_bands( image ) !=
|
||||
vips_icc_profile_needs_bands( profile ) ) {
|
||||
VIPS_FREEF( cmsCloseProfile, profile );
|
||||
vips_warn( domain,
|
||||
_( "profile \"%s\" incompatible with image" ),
|
||||
g_warning( _( "profile \"%s\" incompatible with image" ),
|
||||
filename );
|
||||
return( NULL );
|
||||
}
|
||||
@ -615,8 +614,7 @@ vips_icc_import_build( VipsObject *object )
|
||||
if( code->in &&
|
||||
(import->embedded ||
|
||||
!import->input_profile_filename) )
|
||||
icc->in_profile = vips_icc_load_profile_image( class->nickname,
|
||||
code->in );
|
||||
icc->in_profile = vips_icc_load_profile_image( code->in );
|
||||
|
||||
if( !icc->in_profile &&
|
||||
code->in &&
|
||||
@ -1027,8 +1025,7 @@ vips_icc_transform_build( VipsObject *object )
|
||||
if( code->in &&
|
||||
(transform->embedded ||
|
||||
!transform->input_profile_filename) )
|
||||
icc->in_profile = vips_icc_load_profile_image( class->nickname,
|
||||
code->in );
|
||||
icc->in_profile = vips_icc_load_profile_image( code->in );
|
||||
|
||||
if( !icc->in_profile &&
|
||||
code->in &&
|
||||
|
@ -126,11 +126,9 @@ vips_cast_preeval( VipsImage *image, VipsProgress *progress, VipsCast *cast )
|
||||
static void
|
||||
vips_cast_posteval( VipsImage *image, VipsProgress *progress, VipsCast *cast )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( cast );
|
||||
|
||||
if( cast->overflow || cast->underflow )
|
||||
vips_warn( class->nickname,
|
||||
_( "%d underflows and %d overflows detected" ),
|
||||
if( cast->overflow ||
|
||||
cast->underflow )
|
||||
g_warning( _( "%d underflows and %d overflows detected" ),
|
||||
cast->underflow, cast->overflow );
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ vips_copy_build( VipsObject *object )
|
||||
return( -1 );
|
||||
|
||||
if( copy->swap )
|
||||
vips_warn( class->nickname, "%s",
|
||||
g_warning( "%s",
|
||||
_( "copy swap is deprecated, use byteswap instead" ) );
|
||||
|
||||
if( vips_image_pipelinev( conversion->out,
|
||||
|
@ -124,7 +124,6 @@ vips_sequential_generate( VipsRegion *or,
|
||||
void *seq, void *a, void *b, gboolean *stop )
|
||||
{
|
||||
VipsSequential *sequential = (VipsSequential *) b;
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( sequential );
|
||||
VipsRect *r = &or->valid;
|
||||
VipsRegion *ir = (VipsRegion *) seq;
|
||||
|
||||
@ -132,8 +131,7 @@ vips_sequential_generate( VipsRegion *or,
|
||||
g_thread_self(), r->top, r->height );
|
||||
|
||||
if( sequential->trace )
|
||||
vips_info( class->nickname,
|
||||
"request for line %d, height %d",
|
||||
g_info( "request for line %d, height %d",
|
||||
r->top, r->height );
|
||||
|
||||
VIPS_GATE_START( "vips_sequential_generate: wait" );
|
||||
|
@ -605,7 +605,6 @@ vips_tile_cache_gen( VipsRegion *or,
|
||||
{
|
||||
VipsRegion *in = (VipsRegion *) seq;
|
||||
VipsBlockCache *cache = (VipsBlockCache *) b;
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( cache );
|
||||
VipsRect *r = &or->valid;
|
||||
|
||||
VipsTile *tile;
|
||||
@ -702,8 +701,7 @@ vips_tile_cache_gen( VipsRegion *or,
|
||||
"vips_tile_cache_gen: "
|
||||
"error on tile %p\n", tile );
|
||||
|
||||
vips_warn( class->nickname,
|
||||
_( "error in tile %d x %d" ),
|
||||
g_warning( _( "error in tile %d x %d" ),
|
||||
tile->pos.left, tile->pos.top );
|
||||
|
||||
vips_region_black( tile->region );
|
||||
|
@ -860,7 +860,7 @@ intize_to_fixed_point( VipsImage *in, int *out )
|
||||
for( i = 0; i < ne; i++ )
|
||||
if( scaled[i] >= 4.0 ||
|
||||
scaled[i] < -4 ) {
|
||||
vips_info( "intize_to_fixed_point",
|
||||
g_info( "intize_to_fixed_point: "
|
||||
"out of range for vector path" );
|
||||
return( -1 );
|
||||
}
|
||||
@ -880,7 +880,7 @@ intize_to_fixed_point( VipsImage *in, int *out )
|
||||
/* 0.1 is a 10% error.
|
||||
*/
|
||||
if( total_error > 0.1 ) {
|
||||
vips_info( "intize_to_fixed_point", "too many underflows" );
|
||||
g_info( "intize_to_fixed_point: too many underflows" );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
@ -906,7 +906,6 @@ intize_to_fixed_point( VipsImage *in, int *out )
|
||||
static int
|
||||
vips_convi_build( VipsObject *object )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||
VipsConvolution *convolution = (VipsConvolution *) object;
|
||||
VipsConvi *convi = (VipsConvi *) object;
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 );
|
||||
@ -941,7 +940,7 @@ vips_convi_build( VipsObject *object )
|
||||
!intize_to_fixed_point( M, convi->fixed ) &&
|
||||
!vips_convi_compile( convi, in ) ) {
|
||||
generate = vips_convi_gen_vector;
|
||||
vips_info( class->nickname, "using vector path" );
|
||||
g_info( "using vector path" );
|
||||
}
|
||||
else
|
||||
vips_convi_compile_free( convi );
|
||||
@ -980,7 +979,7 @@ vips_convi_build( VipsObject *object )
|
||||
}
|
||||
|
||||
generate = vips_convi_gen;
|
||||
vips_info( class->nickname, "using C path" );
|
||||
g_info( "using C path" );
|
||||
}
|
||||
|
||||
g_object_set( convi, "out", vips_image_new(), NULL );
|
||||
|
@ -67,7 +67,6 @@ G_DEFINE_TYPE( VipsGaussblur, vips_gaussblur, VIPS_TYPE_OPERATION );
|
||||
static int
|
||||
vips_gaussblur_build( VipsObject *object )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||
VipsGaussblur *gaussblur = (VipsGaussblur *) object;
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );
|
||||
|
||||
@ -85,7 +84,7 @@ vips_gaussblur_build( VipsObject *object )
|
||||
vips_matrixprint( t[0], NULL );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
vips_info( class->nickname, "gaussblur mask width %d", t[0]->Xsize );
|
||||
g_info( "gaussblur mask width %d", t[0]->Xsize );
|
||||
|
||||
if( vips_convsep( gaussblur->in, &t[1], t[0],
|
||||
"precision", gaussblur->precision,
|
||||
|
@ -76,7 +76,7 @@ im_csv2vips( const char *filename, IMAGE *out )
|
||||
}
|
||||
|
||||
if( vips__csv_read( name, out,
|
||||
start_skip, lines, whitespace, separator ) )
|
||||
start_skip, lines, whitespace, separator, FALSE ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
|
@ -50,7 +50,7 @@ im_magick2vips( const char *filename, IMAGE *out )
|
||||
#ifdef HAVE_MAGICK
|
||||
/* Old behaviour was always to read all frames.
|
||||
*/
|
||||
return( vips__magick_read( filename, out, TRUE, NULL, 0 ) );
|
||||
return( vips__magick_read( filename, out, NULL, 0, -1 ) );
|
||||
#else
|
||||
vips_error( "im_magick2vips",
|
||||
"%s", _( "no libMagick support in your libvips" ) );
|
||||
|
@ -94,11 +94,11 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
}
|
||||
|
||||
if( header_only ) {
|
||||
if( vips__tiff_read_header( filename, out, page, FALSE ) )
|
||||
if( vips__tiff_read_header( filename, out, page, 1, FALSE ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__tiff_read( filename, out, page, FALSE, TRUE ) )
|
||||
if( vips__tiff_read( filename, out, page, 1, FALSE, TRUE ) )
|
||||
return( -1 );
|
||||
}
|
||||
#else
|
||||
|
@ -724,3 +724,79 @@ vips_check_bands_3ormore( const char *domain, VipsImage *im )
|
||||
{
|
||||
return( vips_check_bands_atleast( domain, im, 3 ) );
|
||||
}
|
||||
|
||||
/* The old vips_info() stuff, now replaced by g_warning() / g_info().
|
||||
*/
|
||||
|
||||
int vips__info = 0;
|
||||
|
||||
void
|
||||
vips_info_set( gboolean info )
|
||||
{
|
||||
vips__info = info;
|
||||
|
||||
if( info ) {
|
||||
const char *old;
|
||||
char *new;
|
||||
|
||||
old = g_getenv( "G_MESSAGES_DEBUG" );
|
||||
if( !old )
|
||||
old = "";
|
||||
new = g_strdup_printf( "%s VIPS", old );
|
||||
g_setenv( "G_MESSAGES_DEBUG", new, TRUE );
|
||||
g_free( new );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vips_vinfo( const char *domain, const char *fmt, va_list ap )
|
||||
{
|
||||
if( vips__info ) {
|
||||
g_mutex_lock( vips__global_lock );
|
||||
(void) fprintf( stderr, _( "%s: " ), _( "info" ) );
|
||||
if( domain )
|
||||
(void) fprintf( stderr, _( "%s: " ), domain );
|
||||
(void) vfprintf( stderr, fmt, ap );
|
||||
(void) fprintf( stderr, "\n" );
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vips_info( const char *domain, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vips_vinfo( domain, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
void
|
||||
vips_vwarn( const char *domain, const char *fmt, va_list ap )
|
||||
{
|
||||
if( !g_getenv( "IM_WARNING" ) &&
|
||||
!g_getenv( "VIPS_WARNING" ) ) {
|
||||
g_mutex_lock( vips__global_lock );
|
||||
(void) fprintf( stderr, _( "%s: " ), _( "vips warning" ) );
|
||||
if( domain )
|
||||
(void) fprintf( stderr, _( "%s: " ), domain );
|
||||
(void) vfprintf( stderr, fmt, ap );
|
||||
(void) fprintf( stderr, "\n" );
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
}
|
||||
|
||||
if( vips__fatal )
|
||||
vips_error_exit( "vips__fatal" );
|
||||
}
|
||||
|
||||
void
|
||||
vips_warn( const char *domain, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vips_vwarn( domain, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ skip_to_sep( FILE *fp, const char sepmap[256] )
|
||||
*/
|
||||
static int
|
||||
read_double( FILE *fp, const char whitemap[256], const char sepmap[256],
|
||||
int lineno, int colno, double *out )
|
||||
int lineno, int colno, double *out, gboolean fail )
|
||||
{
|
||||
int ch;
|
||||
|
||||
@ -195,9 +195,10 @@ read_double( FILE *fp, const char whitemap[256], const char sepmap[256],
|
||||
/* Only a warning, since (for example) exported spreadsheets
|
||||
* will often have text or date fields.
|
||||
*/
|
||||
vips_warn( "csv2vips",
|
||||
_( "error parsing number, line %d, column %d" ),
|
||||
g_warning( _( "error parsing number, line %d, column %d" ),
|
||||
lineno, colno );
|
||||
if( fail )
|
||||
return( EOF );
|
||||
|
||||
/* Step over the bad data to the next separator.
|
||||
*/
|
||||
@ -222,7 +223,8 @@ read_csv( FILE *fp, VipsImage *out,
|
||||
int skip,
|
||||
int lines,
|
||||
const char *whitespace, const char *separator,
|
||||
gboolean read_image )
|
||||
gboolean read_image,
|
||||
gboolean fail )
|
||||
{
|
||||
int i;
|
||||
char whitemap[256];
|
||||
@ -265,7 +267,7 @@ read_csv( FILE *fp, VipsImage *out,
|
||||
}
|
||||
for( columns = 0;
|
||||
(ch = read_double( fp, whitemap, sepmap,
|
||||
skip + 1, columns + 1, &d )) == 0;
|
||||
skip + 1, columns + 1, &d, fail )) == 0;
|
||||
columns++ )
|
||||
;
|
||||
(void) fsetpos( fp, &pos );
|
||||
@ -308,7 +310,7 @@ read_csv( FILE *fp, VipsImage *out,
|
||||
int colno = x + 1;
|
||||
|
||||
ch = read_double( fp, whitemap, sepmap,
|
||||
lineno, colno, &d );
|
||||
lineno, colno, &d, fail );
|
||||
if( ch == EOF ) {
|
||||
vips_error( "csv2vips",
|
||||
_( "unexpected EOF, line %d col %d" ),
|
||||
@ -342,13 +344,15 @@ read_csv( FILE *fp, VipsImage *out,
|
||||
|
||||
int
|
||||
vips__csv_read( const char *filename, VipsImage *out,
|
||||
int skip, int lines, const char *whitespace, const char *separator )
|
||||
int skip, int lines, const char *whitespace, const char *separator,
|
||||
gboolean fail )
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if( !(fp = vips__file_open_read( filename, NULL, TRUE )) )
|
||||
return( -1 );
|
||||
if( read_csv( fp, out, skip, lines, whitespace, separator, TRUE ) ) {
|
||||
if( read_csv( fp, out,
|
||||
skip, lines, whitespace, separator, TRUE, fail ) ) {
|
||||
fclose( fp );
|
||||
return( -1 );
|
||||
}
|
||||
@ -359,13 +363,15 @@ vips__csv_read( const char *filename, VipsImage *out,
|
||||
|
||||
int
|
||||
vips__csv_read_header( const char *filename, VipsImage *out,
|
||||
int skip, int lines, const char *whitespace, const char *separator )
|
||||
int skip, int lines, const char *whitespace, const char *separator,
|
||||
gboolean fail )
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if( !(fp = vips__file_open_read( filename, NULL, TRUE )) )
|
||||
return( -1 );
|
||||
if( read_csv( fp, out, skip, lines, whitespace, separator, FALSE ) ) {
|
||||
if( read_csv( fp, out,
|
||||
skip, lines, whitespace, separator, FALSE, fail ) ) {
|
||||
fclose( fp );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ vips_foreign_load_csv_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadCsv *csv = (VipsForeignLoadCsv *) load;
|
||||
|
||||
if( vips__csv_read_header( csv->filename, load->out,
|
||||
csv->skip, csv->lines, csv->whitespace, csv->separator ) )
|
||||
csv->skip, csv->lines, csv->whitespace, csv->separator,
|
||||
load->fail ) )
|
||||
return( -1 );
|
||||
|
||||
VIPS_SETSTR( load->out->filename, csv->filename );
|
||||
@ -103,7 +104,8 @@ vips_foreign_load_csv_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadCsv *csv = (VipsForeignLoadCsv *) load;
|
||||
|
||||
if( vips__csv_read( csv->filename, load->real,
|
||||
csv->skip, csv->lines, csv->whitespace, csv->separator ) )
|
||||
csv->skip, csv->lines, csv->whitespace, csv->separator,
|
||||
load->fail ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -191,6 +193,7 @@ vips_foreign_load_csv_init( VipsForeignLoadCsv *csv )
|
||||
* * @lines: read this many lines from file
|
||||
* * @whitespace: set of whitespace characters
|
||||
* * @separator: set of separator characters
|
||||
* * @fail: %gboolean, fail on warnings
|
||||
*
|
||||
* Load a CSV (comma-separated values) file. The output image is always 1
|
||||
* band (monochrome), #VIPS_FORMAT_DOUBLE. Use vips_bandfold() to turn
|
||||
@ -218,6 +221,8 @@ vips_foreign_load_csv_init( VipsForeignLoadCsv *csv )
|
||||
* @separator sets the characters that separate fields.
|
||||
* Default ;,<emphasis>tab</emphasis>. Separators are never run together.
|
||||
*
|
||||
* Setting @fail to %TRUE makes the reader fail on any warnings.
|
||||
*
|
||||
* See also: vips_image_new_from_file(), vips_bandfold().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
|
@ -69,6 +69,8 @@
|
||||
* - move vips-properties out of subdir for gm and zoomify layouts
|
||||
* 15/10/16
|
||||
* - add dzsave_buffer
|
||||
* 11/11/16 Felix Bünemann
|
||||
* - better >4gb detection for zip output on older libgsfs
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -322,6 +324,12 @@ typedef struct _VipsGsfDirectory {
|
||||
*/
|
||||
GsfOutput *container;
|
||||
|
||||
/* Track number of files in tree and total length of filenames. We use
|
||||
* this to estimate zip size to spot a >4gb write.
|
||||
*/
|
||||
size_t file_count;
|
||||
size_t filename_lengths;
|
||||
|
||||
/* Set deflate compression level for zip container.
|
||||
*/
|
||||
gint deflate_level;
|
||||
@ -392,6 +400,8 @@ vips_gsf_tree_new( GsfOutput *out, gint deflate_level )
|
||||
tree->children = NULL;
|
||||
tree->out = out;
|
||||
tree->container = NULL;
|
||||
tree->file_count = 0;
|
||||
tree->filename_lengths = 0;
|
||||
tree->deflate_level = deflate_level;
|
||||
|
||||
return( tree );
|
||||
@ -429,6 +439,8 @@ vips_gsf_dir_new( VipsGsfDirectory *parent, const char *name )
|
||||
dir->name = g_strdup( name );
|
||||
dir->children = NULL;
|
||||
dir->container = NULL;
|
||||
dir->file_count = 0;
|
||||
dir->filename_lengths = 0;
|
||||
dir->deflate_level = parent->deflate_level;
|
||||
|
||||
if( GSF_IS_OUTFILE_ZIP( parent->out ) )
|
||||
@ -467,13 +479,23 @@ vips_gsf_path( VipsGsfDirectory *tree, const char *name, ... )
|
||||
char *dir_name;
|
||||
GsfOutput *obj;
|
||||
|
||||
/* vips_gsf_path() always makes a new file, though it may add to an
|
||||
* existing directory. Note the file, and note the length of the full
|
||||
* path we are creating.
|
||||
*/
|
||||
tree->file_count += 1;
|
||||
tree->filename_lengths += strlen( tree->out->name ) + strlen( name ) + 1;
|
||||
|
||||
dir = tree;
|
||||
va_start( ap, name );
|
||||
while( (dir_name = va_arg( ap, char * )) )
|
||||
while( (dir_name = va_arg( ap, char * )) ) {
|
||||
if( (child = vips_gsf_child_by_name( dir, dir_name )) )
|
||||
dir = child;
|
||||
else
|
||||
dir = vips_gsf_dir_new( dir, dir_name );
|
||||
|
||||
tree->filename_lengths += strlen( dir_name ) + 1;
|
||||
}
|
||||
va_end( ap );
|
||||
|
||||
if( GSF_IS_OUTFILE_ZIP( dir->out ) ) {
|
||||
@ -1220,6 +1242,29 @@ tile_equal( VipsImage *image, VipsPel * restrict ink )
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
#define VIPS_ZIP_FIXED_LH_SIZE (30 + 29)
|
||||
#define VIPS_ZIP_FIXED_CD_SIZE (46 + 9)
|
||||
#define VIPS_ZIP_EOCD_SIZE 22
|
||||
|
||||
#ifndef HAVE_GSF_ZIP64
|
||||
static size_t
|
||||
estimate_zip_size( VipsForeignSaveDz *dz )
|
||||
{
|
||||
size_t estimated_zip_size = dz->bytes_written +
|
||||
dz->tree->file_count * VIPS_ZIP_FIXED_LH_SIZE +
|
||||
dz->tree->filename_lengths +
|
||||
dz->tree->file_count * VIPS_ZIP_FIXED_CD_SIZE +
|
||||
dz->tree->filename_lengths +
|
||||
VIPS_ZIP_EOCD_SIZE;
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf( "estimate_zip_size: %zd\n", estimated_zip_size );
|
||||
#endif /*DEBUG_VERBOSE*/
|
||||
|
||||
return( estimated_zip_size );
|
||||
}
|
||||
#endif /*HAVE_GSF_ZIP64*/
|
||||
|
||||
static int
|
||||
strip_work( VipsThreadState *state, void *a )
|
||||
{
|
||||
@ -1339,17 +1384,26 @@ strip_work( VipsThreadState *state, void *a )
|
||||
}
|
||||
|
||||
#ifndef HAVE_GSF_ZIP64
|
||||
/* Allow a 100,000 byte margin. This probably isn't enough: we don't
|
||||
* include the space zip needs for the index nor anything we are
|
||||
* outputting apart from the gsf_output_write() above.
|
||||
*/
|
||||
if( dz->container == VIPS_FOREIGN_DZ_CONTAINER_ZIP &&
|
||||
dz->bytes_written > (size_t) UINT_MAX - 100000 ) {
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
if( dz->container == VIPS_FOREIGN_DZ_CONTAINER_ZIP ) {
|
||||
/* Leave 3 entry headroom for blank.png and metadata files.
|
||||
*/
|
||||
if( dz->tree->file_count + 3 >= (unsigned int) USHRT_MAX ) {
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "output file too large" ) );
|
||||
return( -1 );
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "too many files in zip" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Leave 16k headroom for blank.png and metadata files.
|
||||
*/
|
||||
if( estimate_zip_size( dz ) > (size_t) UINT_MAX - 16384) {
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "output file too large" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
#endif /*HAVE_GSF_ZIP64*/
|
||||
|
||||
@ -1943,8 +1997,7 @@ vips_foreign_save_dz_build( VipsObject *object )
|
||||
|
||||
#ifndef HAVE_GSF_DEFLATE_LEVEL
|
||||
if( dz->compression > 0 ) {
|
||||
vips_warn( class->nickname, "%s",
|
||||
_( "deflate-level not supported by libgsf, "
|
||||
g_warning( _( "deflate-level not supported by libgsf, "
|
||||
"using default compression" ) );
|
||||
dz->compression = -1;
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
* - redo as a set of fns ready for wrapping in a new-style class
|
||||
* 23/6/13
|
||||
* - fix ushort save with values >32k, thanks weaverwb
|
||||
* 4/1/17
|
||||
* - load to equivalent data type, not raw image data type ... improves
|
||||
* support for BSCALE / BZERO settings
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -119,7 +122,7 @@ typedef struct {
|
||||
VipsPel *buffer;
|
||||
} VipsFits;
|
||||
|
||||
const char *vips__fits_suffs[] = { ".fits", NULL };
|
||||
const char *vips__fits_suffs[] = { ".fits", ".fit", ".fts", NULL };
|
||||
|
||||
static void
|
||||
vips_fits_error( int status )
|
||||
@ -219,10 +222,21 @@ vips_fits_get_header( VipsFits *fits, VipsImage *out )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* cfitsio does automatic conversion from the format stored in
|
||||
* the file to the equivalent type after scale/offset. We need
|
||||
* to allocate a vips image of the equivalent type, not the original
|
||||
* type.
|
||||
*/
|
||||
if( fits_get_img_equivtype( fits->fptr, &bitpix, &status ) ) {
|
||||
vips_fits_error( status );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#ifdef VIPS_DEBUG
|
||||
VIPS_DEBUG_MSG( "naxis = %d\n", fits->naxis );
|
||||
for( i = 0; i < fits->naxis; i++ )
|
||||
VIPS_DEBUG_MSG( "%d) %lld\n", i, fits->naxes[i] );
|
||||
VIPS_DEBUG_MSG( "fits2vips: bitpix = %d\n", bitpix );
|
||||
#endif /*VIPS_DEBUG*/
|
||||
|
||||
height = 1;
|
||||
@ -266,8 +280,8 @@ vips_fits_get_header( VipsFits *fits, VipsImage *out )
|
||||
if( fits->band_select != -1 )
|
||||
bands = 1;
|
||||
|
||||
/* Get image format. We want the 'raw' format of the image, our caller
|
||||
* can convert using the meta info if they want.
|
||||
/* Get image format. This is the equivalent format, or the format
|
||||
* stored in the file.
|
||||
*/
|
||||
for( i = 0; i < VIPS_NUMBER( fits2vips_formats ); i++ )
|
||||
if( fits2vips_formats[i][0] == bitpix )
|
||||
|
@ -846,9 +846,9 @@ vips_foreign_load_build( VipsObject *object )
|
||||
|
||||
if( (flags & VIPS_FOREIGN_PARTIAL) &&
|
||||
(flags & VIPS_FOREIGN_SEQUENTIAL) ) {
|
||||
vips_warn( class->nickname, "%s",
|
||||
g_warning( "%s",
|
||||
_( "VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL "
|
||||
"both set -- using SEQUENTIAL" ) );
|
||||
"both set -- using SEQUENTIAL" ) );
|
||||
flags ^= VIPS_FOREIGN_PARTIAL;
|
||||
}
|
||||
|
||||
@ -865,12 +865,10 @@ vips_foreign_load_build( VipsObject *object )
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( load->sequential ) {
|
||||
vips_warn( class->nickname, "%s",
|
||||
_( "ignoring deprecated \"sequential\" mode" ) );
|
||||
vips_warn( class->nickname, "%s",
|
||||
_( "please use \"access\" instead" ) );
|
||||
}
|
||||
if( load->sequential )
|
||||
g_warning( "%s",
|
||||
_( "ignoring deprecated \"sequential\" mode -- "
|
||||
"please use \"access\" instead" ) );
|
||||
|
||||
g_object_set( object, "out", vips_image_new(), NULL );
|
||||
|
||||
@ -986,6 +984,13 @@ vips_foreign_load_class_init( VipsForeignLoadClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignLoad, sequential ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "fail", 11,
|
||||
_( "Fail" ),
|
||||
_( "Fail on first warning" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoad, fail ),
|
||||
FALSE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -11,6 +11,8 @@
|
||||
* - support unicode on win
|
||||
* 19/8/16
|
||||
* - better transparency detection, thanks diegocsandrim
|
||||
* 25/11/16
|
||||
* - support @n, page-height
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -82,8 +84,20 @@ typedef struct _VipsForeignLoadGif {
|
||||
*/
|
||||
int page;
|
||||
|
||||
/* Load this many pages.
|
||||
*/
|
||||
int n;
|
||||
|
||||
GifFileType *file;
|
||||
|
||||
/* The current read position, in pages.
|
||||
*/
|
||||
int current_page;
|
||||
|
||||
/* Set for EOF detected.
|
||||
*/
|
||||
gboolean eof;
|
||||
|
||||
/* As we scan the file, the index of the transparent pixel for this
|
||||
* frame.
|
||||
*/
|
||||
@ -345,7 +359,6 @@ static void
|
||||
vips_foreign_load_gif_render_line( VipsForeignLoadGif *gif,
|
||||
int width, VipsPel * restrict q, VipsPel * restrict p )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gif );
|
||||
ColorMapObject *map = gif->file->Image.ColorMap ?
|
||||
gif->file->Image.ColorMap : gif->file->SColorMap;
|
||||
|
||||
@ -355,8 +368,7 @@ vips_foreign_load_gif_render_line( VipsForeignLoadGif *gif,
|
||||
VipsPel v = p[x];
|
||||
|
||||
if( v >= map->ColorCount ) {
|
||||
vips_warn( class->nickname,
|
||||
"%s", _( "pixel value out of range" ) );
|
||||
g_warning( "%s", _( "pixel value out of range" ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -414,6 +426,13 @@ vips_foreign_load_gif_render( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
}
|
||||
}
|
||||
|
||||
/* We need a line buffer to decompress to.
|
||||
*/
|
||||
if( !gif->line )
|
||||
if( !(gif->line = VIPS_ARRAY( gif,
|
||||
gif->file->SWidth, GifPixelType )) )
|
||||
return( -1 );
|
||||
|
||||
if( file->Image.Interlace ) {
|
||||
int i;
|
||||
|
||||
@ -468,38 +487,17 @@ vips_foreign_load_gif_render( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Write the next page, if there is one, to @page. Set EOF if we hit the end of
|
||||
* the file. @page must be a memory image of the right size.
|
||||
*/
|
||||
static int
|
||||
vips_foreign_load_gif_to_memory( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
vips_foreign_load_gif_page( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gif );
|
||||
|
||||
int frame_n;
|
||||
GifRecordType record;
|
||||
int n_pages;
|
||||
|
||||
vips_image_init_fields( out,
|
||||
gif->file->SWidth, gif->file->SHeight,
|
||||
4, VIPS_FORMAT_UCHAR,
|
||||
VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, 1.0, 1.0 );
|
||||
n_pages = 0;
|
||||
|
||||
/* We will have the whole GIF frame in memory, so we can render any
|
||||
* area.
|
||||
*/
|
||||
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_ANY, NULL );
|
||||
|
||||
/* We need a line buffer to decompress to.
|
||||
*/
|
||||
gif->line = VIPS_ARRAY( gif, gif->file->SWidth, GifPixelType );
|
||||
|
||||
/* Turn out into a memory image which we then render the GIF frames
|
||||
* into.
|
||||
*/
|
||||
if( vips_image_write_prepare( out ) )
|
||||
return( -1 );
|
||||
|
||||
/* Scan the GIF until we have enough to have completely rendered the
|
||||
* frame we need.
|
||||
*/
|
||||
frame_n = 0;
|
||||
do {
|
||||
GifByteType *extension;
|
||||
int ext_code;
|
||||
@ -521,9 +519,10 @@ vips_foreign_load_gif_to_memory( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
if( vips_foreign_load_gif_render( gif, out ) )
|
||||
return( -1 );
|
||||
|
||||
frame_n += 1;
|
||||
n_pages += 1;
|
||||
|
||||
VIPS_DEBUG_MSG( "gifload: start frame %d:\n", frame_n );
|
||||
VIPS_DEBUG_MSG( "gifload: page %d:\n",
|
||||
gif->current_page + n_pages );
|
||||
|
||||
break;
|
||||
|
||||
@ -533,7 +532,7 @@ vips_foreign_load_gif_to_memory( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
gif->transparency = -1;
|
||||
|
||||
if( DGifGetExtension( gif->file,
|
||||
&ext_code, &extension) == GIF_ERROR ) {
|
||||
&ext_code, &extension ) == GIF_ERROR ) {
|
||||
vips_foreign_load_gif_error( gif );
|
||||
return( -1 );
|
||||
}
|
||||
@ -572,6 +571,7 @@ vips_foreign_load_gif_to_memory( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
|
||||
case TERMINATE_RECORD_TYPE:
|
||||
VIPS_DEBUG_MSG( "gifload: TERMINATE_RECORD_TYPE:\n" );
|
||||
gif->eof = TRUE;
|
||||
break;
|
||||
|
||||
case SCREEN_DESC_RECORD_TYPE:
|
||||
@ -585,20 +585,158 @@ vips_foreign_load_gif_to_memory( VipsForeignLoadGif *gif, VipsImage *out )
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while( frame_n <= gif->page &&
|
||||
record != TERMINATE_RECORD_TYPE );
|
||||
} while( n_pages < 1 &&
|
||||
!gif->eof );
|
||||
|
||||
if( frame_n <= gif->page ) {
|
||||
gif->current_page += n_pages;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static VipsImage *
|
||||
vips_foreign_load_gif_new_page( VipsForeignLoadGif *gif )
|
||||
{
|
||||
VipsImage *out;
|
||||
|
||||
out = vips_image_new_memory();
|
||||
|
||||
vips_image_init_fields( out,
|
||||
gif->file->SWidth, gif->file->SHeight, 4, VIPS_FORMAT_UCHAR,
|
||||
VIPS_CODING_NONE, VIPS_INTERPRETATION_sRGB, 1.0, 1.0 );
|
||||
|
||||
/* We will have the whole GIF frame in memory, so we can render any
|
||||
* area.
|
||||
*/
|
||||
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_ANY, NULL );
|
||||
|
||||
/* Turn out into a memory image which we then render the GIF frames
|
||||
* into.
|
||||
*/
|
||||
if( vips_image_write_prepare( out ) ) {
|
||||
g_object_unref( out );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
static void
|
||||
unref_array( GSList *list )
|
||||
{
|
||||
g_slist_free_full( list, (GDestroyNotify) g_object_unref );
|
||||
}
|
||||
|
||||
/* We render each frame to a separate memory image held in a linked
|
||||
* list, then assemble to out. We don't know the number of frames in advance,
|
||||
* so we can't just allocate a large area.
|
||||
*/
|
||||
static int
|
||||
vips_foreign_load_gif_pages( VipsForeignLoadGif *gif, VipsImage **out )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gif );
|
||||
|
||||
GSList *frames;
|
||||
VipsImage *frame;
|
||||
VipsImage *previous;
|
||||
VipsImage **t;
|
||||
int n_frames;
|
||||
int i;
|
||||
|
||||
frames = NULL;
|
||||
previous = NULL;
|
||||
|
||||
/* Accumulate any start stuff up to the first frame we need.
|
||||
*/
|
||||
if( !(frame = vips_foreign_load_gif_new_page( gif )) )
|
||||
return( -1 );
|
||||
do {
|
||||
if( vips_foreign_load_gif_page( gif, frame ) ) {
|
||||
g_object_unref( frame );
|
||||
return( -1 );
|
||||
}
|
||||
} while( !gif->eof &&
|
||||
gif->current_page <= gif->page );
|
||||
|
||||
if( gif->eof ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "too few frames in GIF file" ) );
|
||||
g_object_unref( frame );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
frames = g_slist_append( frames, frame );
|
||||
previous = frame;
|
||||
|
||||
while( gif->n == -1 ||
|
||||
gif->current_page < gif->page + gif->n ) {
|
||||
/* We might need a frame for this read to render to.
|
||||
*/
|
||||
if( !(frame = vips_foreign_load_gif_new_page( gif )) ) {
|
||||
unref_array( frames );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* And init with the previous frame, if any.
|
||||
*/
|
||||
if( previous )
|
||||
memcpy( VIPS_IMAGE_ADDR( frame, 0, 0 ),
|
||||
VIPS_IMAGE_ADDR( previous, 0, 0 ),
|
||||
VIPS_IMAGE_SIZEOF_IMAGE( frame ) );
|
||||
|
||||
if( vips_foreign_load_gif_page( gif, frame ) ) {
|
||||
g_object_unref( frame );
|
||||
unref_array( frames );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( gif->eof ) {
|
||||
/* Nope, didn't need the new frame.
|
||||
*/
|
||||
g_object_unref( frame );
|
||||
break;
|
||||
}
|
||||
else {
|
||||
frames = g_slist_append( frames, frame );
|
||||
previous = frame;
|
||||
}
|
||||
}
|
||||
|
||||
n_frames = g_slist_length( frames );
|
||||
|
||||
if( gif->eof &&
|
||||
gif->n != -1 &&
|
||||
n_frames < gif->n ) {
|
||||
unref_array( frames );
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "too few frames in GIF file" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* We've rendered to a memory image ... we can shut down the GIF
|
||||
/* We've rendered to a set of memory images ... we can shut down the GIF
|
||||
* reader now.
|
||||
*/
|
||||
vips_foreign_load_gif_close( gif );
|
||||
|
||||
if( !(t = VIPS_ARRAY( gif, n_frames, VipsImage * )) ) {
|
||||
unref_array( frames );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
for( i = 0; i < n_frames; i++ )
|
||||
t[i] = (VipsImage *) g_slist_nth_data( frames, i );
|
||||
|
||||
if( vips_arrayjoin( t, out, n_frames,
|
||||
"across", 1,
|
||||
NULL ) ) {
|
||||
unref_array( frames );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
unref_array( frames );
|
||||
|
||||
if( n_frames > 1 )
|
||||
vips_image_set_int( *out, VIPS_META_PAGE_HEIGHT, frame->Ysize );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -611,11 +749,9 @@ vips_foreign_load_gif_load( VipsForeignLoad *load )
|
||||
|
||||
VipsImage *im;
|
||||
|
||||
/* Render to a memory image.
|
||||
*/
|
||||
im = t[0] = vips_image_new_memory();
|
||||
if( vips_foreign_load_gif_to_memory( gif, im ) )
|
||||
if( vips_foreign_load_gif_pages( gif, &t[0] ) )
|
||||
return( -1 );
|
||||
im = t[0];
|
||||
|
||||
/* Depending on what we found, transform and write to load->real.
|
||||
*/
|
||||
@ -683,11 +819,19 @@ vips_foreign_load_gif_class_init( VipsForeignLoadGifClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignLoadGif, page ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "n", 6,
|
||||
_( "n" ),
|
||||
_( "Load this many pages" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadGif, n ),
|
||||
-1, 100000, 1 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_gif_init( VipsForeignLoadGif *gif )
|
||||
{
|
||||
gif->n = 1;
|
||||
gif->transparency = -1;
|
||||
}
|
||||
|
||||
@ -854,10 +998,16 @@ vips_foreign_load_gif_buffer_init( VipsForeignLoadGifBuffer *buffer )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, page (frame) to read
|
||||
* * @n: %gint, load this many pages
|
||||
*
|
||||
* Read a GIF file into a VIPS image. Rendering uses the giflib library.
|
||||
*
|
||||
* Use @page to set page number (frame number) to read.
|
||||
* Use @page to select a page to render, numbering from zero.
|
||||
*
|
||||
* Use @n to select the number of pages to render. The default is 1. Pages are
|
||||
* rendered in a vertical column, with each individual page aligned to the
|
||||
* left. Set to -1 to mean "until the end of the document". Use vips_grid()
|
||||
* to change page layout.
|
||||
*
|
||||
* The whole GIF is rendered into memory on header access. The output image
|
||||
* will be 1, 2, 3 or 4 bands depending on what the reader finds in the file.
|
||||
@ -889,6 +1039,7 @@ vips_gifload( const char *filename, VipsImage **out, ... )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, page (frame) to read
|
||||
* * @n: %gint, load this many pages
|
||||
*
|
||||
* Read a GIF-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_gifload(), but read from a memory buffer.
|
||||
|
@ -79,8 +79,13 @@
|
||||
* 07/09/16
|
||||
* - Don't use the exif resolution if x_resolution / y_resolution /
|
||||
* resolution_unit is missing
|
||||
<<<<<<< HEAD
|
||||
* 7/11/16
|
||||
* - exif handling moved out to exif.c
|
||||
=======
|
||||
* 4/1/17
|
||||
* - Don't warn for missing exif res, since we fall back to jfif now
|
||||
>>>>>>> master
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -180,10 +185,9 @@ readjpeg_free( ReadJpeg *jpeg )
|
||||
result = 0;
|
||||
|
||||
if( jpeg->eman.pub.num_warnings != 0 ) {
|
||||
vips_warn( "VipsJpeg",
|
||||
_( "read gave %ld warnings" ),
|
||||
g_warning( _( "read gave %ld warnings" ),
|
||||
jpeg->eman.pub.num_warnings );
|
||||
vips_warn( NULL, "%s", vips_error_buffer() );
|
||||
g_warning( "%s", vips_error_buffer() );
|
||||
|
||||
/* Make the message only appear once.
|
||||
*/
|
||||
@ -376,8 +380,7 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out )
|
||||
break;
|
||||
|
||||
default:
|
||||
vips_warn( "VipsJpeg",
|
||||
"%s", _( "unknown JFIF resolution unit" ) );
|
||||
g_warning( "%s", _( "unknown JFIF resolution unit" ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -77,10 +77,6 @@ typedef struct _VipsForeignLoadJpeg {
|
||||
*/
|
||||
int shrink;
|
||||
|
||||
/* Fail on first warning.
|
||||
*/
|
||||
gboolean fail;
|
||||
|
||||
/* Autorotate using exif orientation tag.
|
||||
*/
|
||||
gboolean autorotate;
|
||||
@ -144,13 +140,6 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignLoadJpeg, shrink ),
|
||||
1, 16, 1 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "fail", 11,
|
||||
_( "Fail" ),
|
||||
_( "Fail on first warning" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadJpeg, fail ),
|
||||
FALSE );
|
||||
|
||||
VIPS_ARG_BOOL( class, "autorotate", 12,
|
||||
_( "Autorotate" ),
|
||||
_( "Rotate image using exif orientation" ),
|
||||
@ -201,7 +190,7 @@ vips_foreign_load_jpeg_file_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||
|
||||
if( vips__jpeg_read_file( file->filename, load->out,
|
||||
TRUE, jpeg->shrink, jpeg->fail, FALSE, jpeg->autorotate ) )
|
||||
TRUE, jpeg->shrink, load->fail, FALSE, jpeg->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -214,7 +203,7 @@ vips_foreign_load_jpeg_file_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||
|
||||
if( vips__jpeg_read_file( file->filename, load->real,
|
||||
FALSE, jpeg->shrink, jpeg->fail,
|
||||
FALSE, jpeg->shrink, load->fail,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL, jpeg->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
@ -283,7 +272,7 @@ vips_foreign_load_jpeg_buffer_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||
|
||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
||||
load->out, TRUE, jpeg->shrink, jpeg->fail, FALSE,
|
||||
load->out, TRUE, jpeg->shrink, load->fail, FALSE,
|
||||
jpeg->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
@ -297,7 +286,7 @@ vips_foreign_load_jpeg_buffer_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||
|
||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
||||
load->real, FALSE, jpeg->shrink, jpeg->fail,
|
||||
load->real, FALSE, jpeg->shrink, load->fail,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL, jpeg->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -51,6 +51,8 @@
|
||||
* - add @page option, 0 by default
|
||||
* 18/4/16
|
||||
* - fix @page with graphicsmagick
|
||||
* 25/11/16
|
||||
* - remove @all_frames, add @n
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -119,8 +121,8 @@
|
||||
typedef struct _Read {
|
||||
char *filename;
|
||||
VipsImage *im;
|
||||
gboolean all_frames;
|
||||
int page;
|
||||
int n;
|
||||
|
||||
Image *image;
|
||||
ImageInfo *image_info;
|
||||
@ -166,7 +168,7 @@ read_close( VipsImage *im, Read *read )
|
||||
|
||||
static Read *
|
||||
read_new( const char *filename, VipsImage *im,
|
||||
gboolean all_frames, const char *density, int page )
|
||||
const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
static int inited = 0;
|
||||
@ -180,11 +182,17 @@ read_new( const char *filename, VipsImage *im,
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
/* IM doesn't use the -1 means end-of-file convention, change it to a
|
||||
* very large number.
|
||||
*/
|
||||
if( n == -1 )
|
||||
n = 100000;
|
||||
|
||||
if( !(read = VIPS_NEW( im, Read )) )
|
||||
return( NULL );
|
||||
read->filename = filename ? g_strdup( filename ) : NULL;
|
||||
read->all_frames = all_frames;
|
||||
read->page = page;
|
||||
read->n = n;
|
||||
read->im = im;
|
||||
read->image = NULL;
|
||||
read->image_info = CloneImageInfo( NULL );
|
||||
@ -218,24 +226,25 @@ read_new( const char *filename, VipsImage *im,
|
||||
SetImageOption( read->image_info, "dcm:display-range", "reset" );
|
||||
#endif /*HAVE_SETIMAGEOPTION*/
|
||||
|
||||
if( !all_frames ) {
|
||||
if( read->page > 0 ) {
|
||||
#ifdef HAVE_NUMBER_SCENES
|
||||
/* I can't find docs for these fields, but this seems to work.
|
||||
*/
|
||||
/* I can't find docs for these fields, but this seems to work.
|
||||
*/
|
||||
char page[256];
|
||||
|
||||
read->image_info->scene = read->page;
|
||||
read->image_info->number_scenes = 1;
|
||||
read->image_info->number_scenes = read->n;
|
||||
|
||||
/* Some IMs must have the string version set as well.
|
||||
*/
|
||||
vips_snprintf( page, 256, "%d", read->page );
|
||||
vips_snprintf( page, 256, "%d-%d",
|
||||
read->page, read->page + read->n );
|
||||
read->image_info->scenes = strdup( page );
|
||||
#else /*!HAVE_NUMBER_SCENES*/
|
||||
/* This works with GM 1.2.31 and probably others.
|
||||
*/
|
||||
read->image_info->subimage = read->page;
|
||||
read->image_info->subrange = 1;
|
||||
read->image_info->subrange = read->n;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -465,8 +474,17 @@ parse_header( Read *read )
|
||||
for( p = image; p; (p = GetNextImageInList( p )) ) {
|
||||
if( p->columns != (unsigned int) im->Xsize ||
|
||||
p->rows != (unsigned int) im->Ysize ||
|
||||
get_bands( p ) != im->Bands )
|
||||
get_bands( p ) != im->Bands ) {
|
||||
#ifdef DEBUG
|
||||
printf( "frame %d differs\n", read->n_frames );
|
||||
printf( "%zdx%zd, %d bands\n",
|
||||
p->columns, p->rows, get_bands( p ) );
|
||||
printf( "first frame is %dx%d, %d bands\n",
|
||||
im->Xsize, im->Ysize, im->Bands );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
read->n_frames += 1;
|
||||
}
|
||||
@ -479,14 +497,11 @@ parse_header( Read *read )
|
||||
printf( "image has %d frames\n", read->n_frames );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* If all_frames is off, just get the first one.
|
||||
*/
|
||||
if( !read->all_frames )
|
||||
read->n_frames = 1;
|
||||
if( read->n != -1 )
|
||||
read->n_frames = VIPS_MIN( read->n_frames, read->n );
|
||||
|
||||
/* Record frame pointers.
|
||||
*/
|
||||
im->Ysize *= read->n_frames;
|
||||
if( !(read->frames = VIPS_ARRAY( NULL, read->n_frames, Image * )) )
|
||||
return( -1 );
|
||||
p = image;
|
||||
@ -495,6 +510,11 @@ parse_header( Read *read )
|
||||
p = GetNextImageInList( p );
|
||||
}
|
||||
|
||||
if( read->n_frames > 1 ) {
|
||||
vips_image_set_int( im, VIPS_META_PAGE_HEIGHT, im->Ysize );
|
||||
im->Ysize *= read->n_frames;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -711,8 +731,8 @@ magick_fill_region( VipsRegion *out,
|
||||
}
|
||||
|
||||
int
|
||||
vips__magick_read( const char *filename, VipsImage *out,
|
||||
gboolean all_frames, const char *density, int page )
|
||||
vips__magick_read( const char *filename,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -720,7 +740,7 @@ vips__magick_read( const char *filename, VipsImage *out,
|
||||
printf( "magick2vips: vips__magick_read: %s\n", filename );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( filename, out, all_frames, density, page )) )
|
||||
if( !(read = read_new( filename, out, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -750,8 +770,8 @@ vips__magick_read( const char *filename, VipsImage *out,
|
||||
* http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=20017
|
||||
*/
|
||||
int
|
||||
vips__magick_read_header( const char *filename, VipsImage *im,
|
||||
gboolean all_frames, const char *density, int page )
|
||||
vips__magick_read_header( const char *filename,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -759,7 +779,7 @@ vips__magick_read_header( const char *filename, VipsImage *im,
|
||||
printf( "vips__magick_read_header: %s\n", filename );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( filename, im, all_frames, density, page )) )
|
||||
if( !(read = read_new( filename, out, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -778,7 +798,8 @@ vips__magick_read_header( const char *filename, VipsImage *im,
|
||||
if( parse_header( read ) )
|
||||
return( -1 );
|
||||
|
||||
if( im->Xsize <= 0 || im->Ysize <= 0 ) {
|
||||
if( out->Xsize <= 0 ||
|
||||
out->Ysize <= 0 ) {
|
||||
vips_error( "magick2vips", "%s", _( "bad image size" ) );
|
||||
return( -1 );
|
||||
}
|
||||
@ -791,8 +812,8 @@ vips__magick_read_header( const char *filename, VipsImage *im,
|
||||
}
|
||||
|
||||
int
|
||||
vips__magick_read_buffer( const void *buf, const size_t len, VipsImage *out,
|
||||
gboolean all_frames, const char *density, int page )
|
||||
vips__magick_read_buffer( const void *buf, const size_t len,
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -800,7 +821,7 @@ vips__magick_read_buffer( const void *buf, const size_t len, VipsImage *out,
|
||||
printf( "magick2vips: vips__magick_read_buffer: %p %zu\n", buf, len );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( NULL, out, all_frames, density, page )) )
|
||||
if( !(read = read_new( NULL, out, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -827,8 +848,7 @@ vips__magick_read_buffer( const void *buf, const size_t len, VipsImage *out,
|
||||
|
||||
int
|
||||
vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
VipsImage *im,
|
||||
gboolean all_frames, const char *density, int page )
|
||||
VipsImage *out, const char *density, int page, int n )
|
||||
{
|
||||
Read *read;
|
||||
|
||||
@ -836,7 +856,7 @@ vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
printf( "vips__magick_read_buffer_header: %p %zu\n", buf, len );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( !(read = read_new( NULL, im, all_frames, density, page )) )
|
||||
if( !(read = read_new( NULL, out, density, page, n )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -854,8 +874,8 @@ vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
if( parse_header( read ) )
|
||||
return( -1 );
|
||||
|
||||
if( im->Xsize <= 0 ||
|
||||
im->Ysize <= 0 ) {
|
||||
if( out->Xsize <= 0 ||
|
||||
out->Ysize <= 0 ) {
|
||||
vips_error( "magick2vips", "%s", _( "bad image size" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
*
|
||||
* 8/7/16
|
||||
* - from magickload
|
||||
* 25/11/16
|
||||
* - add @n, deprecate @all_frames (just sets n = -1)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -55,9 +57,13 @@
|
||||
typedef struct _VipsForeignLoadMagick7 {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
gboolean all_frames; /* Load all frames */
|
||||
/* Deprecated. Just sets n = -1.
|
||||
*/
|
||||
gboolean all_frames;
|
||||
|
||||
char *density; /* Load at this resolution */
|
||||
int page; /* Load this page (frame) */
|
||||
int n; /* Load this many pages */
|
||||
|
||||
Image *image;
|
||||
ImageInfo *image_info;
|
||||
@ -308,6 +314,9 @@ vips_foreign_load_magick7_build( VipsObject *object )
|
||||
if( !magick7->image_info )
|
||||
return( -1 );
|
||||
|
||||
if( magick7->all_frames )
|
||||
magick7->n = -1;
|
||||
|
||||
/* Canvas resolution for rendering vector formats like SVG.
|
||||
*/
|
||||
VIPS_SETSTR( magick7->image_info->density, magick7->density );
|
||||
@ -321,15 +330,16 @@ vips_foreign_load_magick7_build( VipsObject *object )
|
||||
*/
|
||||
SetImageOption( magick7->image_info, "dcm:display-range", "reset" );
|
||||
|
||||
if( !magick7->all_frames ) {
|
||||
if( magick7->page > 0 ) {
|
||||
/* I can't find docs for these fields, but this seems to work.
|
||||
*/
|
||||
char page[256];
|
||||
|
||||
magick7->image_info->scene = magick7->page;
|
||||
magick7->image_info->number_scenes = 1;
|
||||
magick7->image_info->number_scenes = magick7->n;
|
||||
|
||||
vips_snprintf( page, 256, "%d", magick7->page );
|
||||
vips_snprintf( page, 256, "%d-%d",
|
||||
magick7->page, magick7->page + magick7->n );
|
||||
magick7->image_info->scenes = strdup( page );
|
||||
}
|
||||
|
||||
@ -368,7 +378,7 @@ vips_foreign_load_magick7_class_init( VipsForeignLoadMagick7Class *class )
|
||||
VIPS_ARG_BOOL( class, "all_frames", 3,
|
||||
_( "all_frames" ),
|
||||
_( "Read all frames from an image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, all_frames ),
|
||||
FALSE );
|
||||
|
||||
@ -385,11 +395,20 @@ vips_foreign_load_magick7_class_init( VipsForeignLoadMagick7Class *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, page ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "n", 6,
|
||||
_( "n" ),
|
||||
_( "Load this many pages" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick7, n ),
|
||||
-1, 100000, 1 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_magick7_init( VipsForeignLoadMagick7 *magick7 )
|
||||
{
|
||||
magick7->n = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -545,14 +564,15 @@ vips_foreign_load_magick7_parse( VipsForeignLoadMagick7 *magick7,
|
||||
printf( "image has %d frames\n", magick7->n_frames );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* If all_frames is off, just get the first one.
|
||||
*/
|
||||
if( !magick7->all_frames )
|
||||
magick7->n_frames = 1;
|
||||
if( magick7->n != -1 )
|
||||
magick7->n_frames = VIPS_MIN( magick7->n_frames, magick7->n );
|
||||
|
||||
/* So we can finally set the height.
|
||||
*/
|
||||
out->Ysize *= magick7->n_frames;
|
||||
if( magick7->n_frames > 1 ) {
|
||||
vips_image_set_int( out, VIPS_META_PAGE_HEIGHT, out->Ysize );
|
||||
out->Ysize *= magick7->n_frames;
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
* - add @all_frames option, off by default
|
||||
* 14/2/16
|
||||
* - add @page option, 0 by default
|
||||
* 25/11/16
|
||||
* - add @n, deprecate @all_frames (just sets n = -1)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -61,9 +63,13 @@
|
||||
typedef struct _VipsForeignLoadMagick {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
gboolean all_frames; /* Load all frames */
|
||||
/* Deprecated. Just sets n = -1.
|
||||
*/
|
||||
gboolean all_frames;
|
||||
|
||||
char *density; /* Load at this resolution */
|
||||
int page; /* Load this page (frame) */
|
||||
int n; /* Load this many pages */
|
||||
|
||||
} VipsForeignLoadMagick;
|
||||
|
||||
@ -110,7 +116,7 @@ vips_foreign_load_magick_class_init( VipsForeignLoadMagickClass *class )
|
||||
VIPS_ARG_BOOL( class, "all_frames", 3,
|
||||
_( "all_frames" ),
|
||||
_( "Read all frames from an image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, all_frames ),
|
||||
FALSE );
|
||||
|
||||
@ -127,11 +133,19 @@ vips_foreign_load_magick_class_init( VipsForeignLoadMagickClass *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, page ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "n", 6,
|
||||
_( "n" ),
|
||||
_( "Load this many pages" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadMagick, n ),
|
||||
-1, 100000, 1 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_magick_init( VipsForeignLoadMagick *magick )
|
||||
{
|
||||
magick->n = 1;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadMagickFile {
|
||||
@ -154,7 +168,7 @@ ismagick( const char *filename )
|
||||
|
||||
t = vips_image_new();
|
||||
vips_error_freeze();
|
||||
result = vips__magick_read_header( filename, t, FALSE, NULL, 0 );
|
||||
result = vips__magick_read_header( filename, t, NULL, 0, 1 );
|
||||
g_object_unref( t );
|
||||
vips_error_thaw();
|
||||
|
||||
@ -175,8 +189,11 @@ vips_foreign_load_magick_file_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadMagickFile *magick_file =
|
||||
(VipsForeignLoadMagickFile *) load;
|
||||
|
||||
if( magick->all_frames )
|
||||
magick->n = -1;
|
||||
|
||||
if( vips__magick_read( magick_file->filename,
|
||||
load->out, magick->all_frames, magick->density, magick->page ) )
|
||||
load->out, magick->density, magick->page, magick->n ) )
|
||||
return( -1 );
|
||||
|
||||
VIPS_SETSTR( load->out->filename, magick_file->filename );
|
||||
@ -236,7 +253,7 @@ vips_foreign_load_magick_buffer_is_a_buffer( const void *buf, size_t len )
|
||||
|
||||
t = vips_image_new();
|
||||
vips_error_freeze();
|
||||
result = vips__magick_read_buffer_header( buf, len, t, FALSE, NULL, 0 );
|
||||
result = vips__magick_read_buffer_header( buf, len, t, NULL, 0, 1 );
|
||||
g_object_unref( t );
|
||||
vips_error_thaw();
|
||||
|
||||
@ -257,9 +274,12 @@ vips_foreign_load_magick_buffer_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadMagickBuffer *magick_buffer =
|
||||
(VipsForeignLoadMagickBuffer *) load;
|
||||
|
||||
if( magick->all_frames )
|
||||
magick->n = -1;
|
||||
|
||||
if( vips__magick_read_buffer(
|
||||
magick_buffer->buf->data, magick_buffer->buf->length,
|
||||
load->out, magick->all_frames, magick->density, magick->page ) )
|
||||
load->out, magick->density, magick->page, magick->n ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -307,7 +327,8 @@ vips_foreign_load_magick_buffer_init( VipsForeignLoadMagickBuffer *buffer )
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @all_frames: %gboolean, load all frames in sequence
|
||||
* * @page: %gint, load from this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @density: string, canvas resolution for rendering vector formats like SVG
|
||||
*
|
||||
* Read in an image using libMagick, the ImageMagick library. This library can
|
||||
@ -321,7 +342,8 @@ vips_foreign_load_magick_buffer_init( VipsForeignLoadMagickBuffer *buffer )
|
||||
* "--with-magickpackage" configure option.
|
||||
*
|
||||
* Normally it will only load the first image in a many-image sequence (such
|
||||
* as a GIF). Set @all_frames to true to read the whole image sequence.
|
||||
* as a GIF or a PDF). Use @page and @n to set the start page and number of
|
||||
* pages to load. Set @n to -1 to load all pages from @page onwards.
|
||||
*
|
||||
* @density is "WxH" in DPI, e.g. "600x300" or "600" (default is "72x72"). See
|
||||
* the [density
|
||||
@ -354,7 +376,8 @@ vips_magickload( const char *filename, VipsImage **out, ... )
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @all_frames: %gboolean, load all frames in sequence
|
||||
* * @page: %gint, load from this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @density: string, canvas resolution for rendering vector formats like SVG
|
||||
*
|
||||
* Read an image memory block using libMagick into a VIPS image. Exactly as
|
||||
|
@ -47,8 +47,6 @@
|
||||
* - do argb -> rgba for associated as well
|
||||
* 27/1/15
|
||||
* - unpremultiplication speedups for fully opaque/transparent pixels
|
||||
* 11/7/16
|
||||
* - just warn on tile read error
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -473,15 +471,19 @@ vips__openslide_generate( VipsRegion *out,
|
||||
rslide->level,
|
||||
r->width, r->height );
|
||||
|
||||
/* Only warn on error: we don't want to make the whole image unreadable
|
||||
* because of one broken tile.
|
||||
/* openslide errors are terminal. To support
|
||||
* @fail we'd have to close the openslide_t and reopen, perhaps
|
||||
* somehow marking this tile as unreadable.
|
||||
*
|
||||
* FIXME ... add a --fail option like jpegload
|
||||
* See
|
||||
* https://github.com/jcupitt/libvips/commit/bb0a6643f94e69294e36d2b253f9bdd60c8c40ed#commitcomment-19838911
|
||||
*/
|
||||
error = openslide_get_error( rslide->osr );
|
||||
if( error )
|
||||
vips_warn( "openslide2vips",
|
||||
if( error ) {
|
||||
vips_error( "openslide2vips",
|
||||
_( "reading region: %s" ), error );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Since we are inside a cache, we know buf must be continuous.
|
||||
*/
|
||||
|
@ -133,9 +133,8 @@ vips_foreign_load_openslide_load( VipsForeignLoad *load )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__openslide_read_associated(
|
||||
openslide->filename, load->real,
|
||||
openslide->associated ) )
|
||||
if( vips__openslide_read_associated( openslide->filename,
|
||||
load->real, openslide->associated ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
* - from openslideload.c
|
||||
* 12/5/16
|
||||
* - add @n ... number of pages to load
|
||||
* 23/11/16
|
||||
* - set page-height, if we can
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -309,6 +311,17 @@ vips_foreign_load_pdf_header( VipsForeignLoad *load )
|
||||
top += pdf->pages[i].height;
|
||||
}
|
||||
|
||||
/* If all pages are the same size, we can tag this as a toilet roll
|
||||
* image and tiffsave will be able to save it as a multipage tiff.
|
||||
*/
|
||||
for( i = 1; i < pdf->n; i++ )
|
||||
if( pdf->pages[i].width != pdf->pages[0].width ||
|
||||
pdf->pages[i].height != pdf->pages[0].height )
|
||||
break;
|
||||
if( i == pdf->n )
|
||||
vips_image_set_int( load->out,
|
||||
VIPS_META_PAGE_HEIGHT, pdf->pages[0].height );
|
||||
|
||||
vips_foreign_load_pdf_set_image( pdf, load->out );
|
||||
|
||||
return( 0 );
|
||||
|
@ -66,17 +66,17 @@ int vips__tiff_write_buf( VipsImage *in,
|
||||
gboolean properties, gboolean strip );
|
||||
|
||||
int vips__tiff_read_header( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate );
|
||||
int page, int n, gboolean autorotate );
|
||||
int vips__tiff_read( const char *filename, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind );
|
||||
int page, int n, gboolean autorotate, gboolean readbehind );
|
||||
gboolean vips__istifftiled( const char *filename );
|
||||
gboolean vips__istiff_buffer( const void *buf, size_t len );
|
||||
gboolean vips__istiff( const char *filename );
|
||||
|
||||
int vips__tiff_read_header_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
int page, gboolean autorotate );
|
||||
int page, int n, gboolean autorotate );
|
||||
int vips__tiff_read_buffer( const void *buf, size_t len, VipsImage *out,
|
||||
int page, gboolean autorotate, gboolean readbehind );
|
||||
int page, int n, gboolean autorotate, gboolean readbehind );
|
||||
|
||||
extern const char *vips__foreign_tiff_suffs[];
|
||||
|
||||
@ -87,9 +87,11 @@ int vips__analyze_read( const char *filename, VipsImage *out );
|
||||
extern const char *vips__foreign_csv_suffs[];
|
||||
|
||||
int vips__csv_read( const char *filename, VipsImage *out,
|
||||
int skip, int lines, const char *whitespace, const char *separator );
|
||||
int skip, int lines, const char *whitespace, const char *separator,
|
||||
gboolean fail );
|
||||
int vips__csv_read_header( const char *filename, VipsImage *out,
|
||||
int skip, int lines, const char *whitespace, const char *separator );
|
||||
int skip, int lines, const char *whitespace, const char *separator,
|
||||
gboolean fail );
|
||||
|
||||
int vips__csv_write( VipsImage *in, const char *filename,
|
||||
const char *separator );
|
||||
@ -118,14 +120,14 @@ int vips__fits_read( const char *filename, VipsImage *out );
|
||||
int vips__fits_write( VipsImage *in, const char *filename );
|
||||
|
||||
int vips__magick_read( const char *filename,
|
||||
VipsImage *out, gboolean all_frames, const char *density, int page );
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
int vips__magick_read_header( const char *filename,
|
||||
VipsImage *out, gboolean all_frames, const char *density, int page );
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
|
||||
int vips__magick_read_buffer( const void *buf, const size_t len,
|
||||
VipsImage *out, gboolean all_frames, const char *density, int page );
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
int vips__magick_read_buffer_header( const void *buf, const size_t len,
|
||||
VipsImage *out, gboolean all_frames, const char *density, int page );
|
||||
VipsImage *out, const char *density, int page, int n );
|
||||
|
||||
extern const char *vips__mat_suffs[];
|
||||
|
||||
|
@ -799,9 +799,8 @@ vips__ppm_save( VipsImage *in, const char *filename,
|
||||
|
||||
if( ascii &&
|
||||
in->BandFmt == VIPS_FORMAT_FLOAT ) {
|
||||
vips_warn( "vips2ppm",
|
||||
"%s", _( "float images must be binary -- "
|
||||
"disabling ascii" ) );
|
||||
g_warning( "%s",
|
||||
_( "float images must be binary -- disabling ascii" ) );
|
||||
ascii = FALSE;
|
||||
}
|
||||
|
||||
@ -810,8 +809,8 @@ vips__ppm_save( VipsImage *in, const char *filename,
|
||||
if( squash &&
|
||||
(in->Bands != 1 ||
|
||||
in->BandFmt != VIPS_FORMAT_UCHAR) ) {
|
||||
vips_warn( "vips2ppm",
|
||||
"%s", _( "can only squash 1 band uchar images -- "
|
||||
g_warning( "%s",
|
||||
_( "can only squash 1 band uchar images -- "
|
||||
"disabling squash" ) );
|
||||
squash = FALSE;
|
||||
}
|
||||
|
@ -58,8 +58,7 @@
|
||||
#include "tiff.h"
|
||||
|
||||
/* Handle TIFF errors here. Shared with vips2tiff.c. These can be called from
|
||||
* more than one thread, but vips_error and vips_warn have mutexes in, so that's
|
||||
* OK.
|
||||
* more than one thread.
|
||||
*/
|
||||
static void
|
||||
vips__thandler_error( const char *module, const char *fmt, va_list ap )
|
||||
@ -67,13 +66,13 @@ vips__thandler_error( const char *module, const char *fmt, va_list ap )
|
||||
vips_verror( module, fmt, ap );
|
||||
}
|
||||
|
||||
/* It'd be nice to be able to support the @fail option for the tiff loader, but
|
||||
* there's no easy way to do this, since libtiff has a global warning handler.
|
||||
*/
|
||||
static void
|
||||
vips__thandler_warning( const char *module, const char *fmt, va_list ap )
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
vips_vsnprintf( buf, 256, fmt, ap );
|
||||
vips_warn( module, "%s", buf );
|
||||
g_logv( G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, fmt, ap );
|
||||
}
|
||||
|
||||
/* Call this during startup. Other libraries may be using libtiff and we want
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -59,6 +59,10 @@ typedef struct _VipsForeignLoadTiff {
|
||||
*/
|
||||
int page;
|
||||
|
||||
/* Load this many pages.
|
||||
*/
|
||||
int n;
|
||||
|
||||
/* Autorotate using orientation tag.
|
||||
*/
|
||||
gboolean autorotate;
|
||||
@ -96,7 +100,14 @@ vips_foreign_load_tiff_class_init( VipsForeignLoadTiffClass *class )
|
||||
G_STRUCT_OFFSET( VipsForeignLoadTiff, page ),
|
||||
0, 100000, 0 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "autorotate", 11,
|
||||
VIPS_ARG_INT( class, "n", 11,
|
||||
_( "n" ),
|
||||
_( "Load this many pages" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadTiff, n ),
|
||||
-1, 100000, 1 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "autorotate", 12,
|
||||
_( "Autorotate" ),
|
||||
_( "Rotate image using orientation tag" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
@ -108,6 +119,7 @@ static void
|
||||
vips_foreign_load_tiff_init( VipsForeignLoadTiff *tiff )
|
||||
{
|
||||
tiff->page = 0;
|
||||
tiff->n = 1;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadTiffFile {
|
||||
@ -154,7 +166,7 @@ vips_foreign_load_tiff_file_header( VipsForeignLoad *load )
|
||||
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
||||
|
||||
if( vips__tiff_read_header( file->filename, load->out,
|
||||
tiff->page, tiff->autorotate ) )
|
||||
tiff->page, tiff->n, tiff->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
VIPS_SETSTR( load->out->filename, file->filename );
|
||||
@ -168,8 +180,9 @@ vips_foreign_load_tiff_file_load( VipsForeignLoad *load )
|
||||
VipsForeignLoadTiff *tiff = (VipsForeignLoadTiff *) load;
|
||||
VipsForeignLoadTiffFile *file = (VipsForeignLoadTiffFile *) load;
|
||||
|
||||
if( vips__tiff_read( file->filename, load->real, tiff->page,
|
||||
tiff->autorotate, load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
if( vips__tiff_read( file->filename, load->real,
|
||||
tiff->page, tiff->n, tiff->autorotate,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -239,7 +252,7 @@ vips_foreign_load_tiff_buffer_header( VipsForeignLoad *load )
|
||||
|
||||
if( vips__tiff_read_header_buffer(
|
||||
buffer->buf->data, buffer->buf->length, load->out,
|
||||
tiff->page, tiff->autorotate ) )
|
||||
tiff->page, tiff->n, tiff->autorotate ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -253,7 +266,7 @@ vips_foreign_load_tiff_buffer_load( VipsForeignLoad *load )
|
||||
|
||||
if( vips__tiff_read_buffer(
|
||||
buffer->buf->data, buffer->buf->length, load->real,
|
||||
tiff->page, tiff->autorotate,
|
||||
tiff->page, tiff->n, tiff->autorotate,
|
||||
load->access == VIPS_ACCESS_SEQUENTIAL ) )
|
||||
return( -1 );
|
||||
|
||||
@ -302,6 +315,7 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
*
|
||||
@ -310,7 +324,12 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
* pyramidal images and JPEG compression. including CMYK and YCbCr.
|
||||
*
|
||||
* @page means load this page from the file. By default the first page (page
|
||||
* 0) is read.
|
||||
* 0) is read.
|
||||
*
|
||||
* @n means load this many pages. By default a single page is read. All the
|
||||
* pages must have the same dimensions, and they are loaded as a tall, thin
|
||||
* "toilet roll" image. The #VIPS_META_PAGE_HEIGHT metadata
|
||||
* tag gives the height in pixels of each page. Use -1 to load all pages.
|
||||
*
|
||||
* Setting @autorotate to %TRUE will make the loader interpret the
|
||||
* orientation tag and automatically rotate the image appropriately during
|
||||
@ -357,6 +376,7 @@ vips_tiffload( const char *filename, VipsImage **out, ... )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page
|
||||
* * @n: %gint, load this many pages
|
||||
* * @autorotate: %gboolean, use orientation tag to rotate the image
|
||||
* during load
|
||||
*
|
||||
|
@ -475,6 +475,10 @@ vips_foreign_save_tiff_buffer_init( VipsForeignSaveTiffBuffer *buffer )
|
||||
*
|
||||
* Write a VIPS image to a file as TIFF.
|
||||
*
|
||||
* If @in has the #VIPS_META_PAGE_HEIGHT metadata item, this is assumed to be a
|
||||
* "toilet roll" image. It will be
|
||||
* written as series of pages, each #VIPS_META_PAGE_HEIGHT pixels high.
|
||||
*
|
||||
* Use @compression to set the tiff compression. Currently jpeg, packbits,
|
||||
* fax4, lzw, none and deflate are supported. The default is no compression.
|
||||
* JPEG compression is a good lossy compressor for photographs, packbits is
|
||||
|
@ -244,7 +244,7 @@ write_blob( Write *write, const char *field, int app )
|
||||
* For now, just ignore oversize objects and warn.
|
||||
*/
|
||||
if( data_length > 65530 )
|
||||
vips_warn( "VipsJpeg", _( "field \"%s\" is too large "
|
||||
g_warning( _( "field \"%s\" is too large "
|
||||
"for a single JPEG marker, ignoring" ),
|
||||
field );
|
||||
else {
|
||||
@ -486,8 +486,7 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
write->cinfo.optimize_coding = TRUE;
|
||||
}
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "trellis_quant unsupported" ) );
|
||||
g_warning( "%s", _( "trellis_quant unsupported" ) );
|
||||
}
|
||||
|
||||
/* Apply overshooting to samples with extreme values e.g. 0 & 255
|
||||
@ -499,8 +498,8 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_OVERSHOOT_DERINGING, TRUE );
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "overshoot_deringing unsupported" ) );
|
||||
g_warning( "%s",
|
||||
_( "overshoot_deringing unsupported" ) );
|
||||
}
|
||||
/* Split the spectrum of DCT coefficients into separate scans.
|
||||
* Requires progressive output. Must be set before
|
||||
@ -513,12 +512,12 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_OPTIMIZE_SCANS, TRUE );
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "Ignoring optimize_scans" ) );
|
||||
g_warning( "%s",
|
||||
_( "ignoring optimize_scans" ) );
|
||||
}
|
||||
else
|
||||
vips_warn( "vips2jpeg", "%s",
|
||||
_( "Ignoring optimize_scans for baseline" ) );
|
||||
g_warning( "%s",
|
||||
_( "ignoring optimize_scans for baseline" ) );
|
||||
}
|
||||
|
||||
/* Use predefined quantization table.
|
||||
@ -529,22 +528,21 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
jpeg_c_set_int_param( &write->cinfo,
|
||||
JINT_BASE_QUANT_TBL_IDX, quant_table );
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "Setting quant_table unsupported" ) );
|
||||
g_warning( "%s",
|
||||
_( "setting quant_table unsupported" ) );
|
||||
}
|
||||
#else
|
||||
/* Using jpeglib.h without extension parameters, warn of ignored
|
||||
* options.
|
||||
*/
|
||||
if( trellis_quant )
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring trellis_quant" ) );
|
||||
g_warning( "%s", _( "ignoring trellis_quant" ) );
|
||||
if( overshoot_deringing )
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "Ignoring overshoot_deringing" ) );
|
||||
g_warning( "%s", _( "ignoring overshoot_deringing" ) );
|
||||
if( optimize_scans )
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring optimize_scans" ) );
|
||||
g_warning( "%s", _( "ignoring optimize_scans" ) );
|
||||
if( quant_table > 0 )
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring quant_table" ) );
|
||||
g_warning( "%s", _( "ignoring quant_table" ) );
|
||||
#endif
|
||||
|
||||
/* Set compression quality. Must be called after setting params above.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -252,9 +252,9 @@ write_webp( WebPPicture *pic, VipsImage *in,
|
||||
#else
|
||||
if( lossless ||
|
||||
near_lossless )
|
||||
vips_warn( "vips2webp", "%s", _( "lossless unsupported" ) );
|
||||
g_warning( "%s", _( "lossless unsupported" ) );
|
||||
if( alpha_q != 100 )
|
||||
vips_warn( "vips2webp", "%s", _( "alpha_q unsupported" ) );
|
||||
g_warning( "%s", _( "alpha_q unsupported" ) );
|
||||
#endif
|
||||
|
||||
#if WEBP_ENCODER_ABI_VERSION >= 0x0209
|
||||
@ -264,10 +264,9 @@ write_webp( WebPPicture *pic, VipsImage *in,
|
||||
config.preprocessing |= 4;
|
||||
#else
|
||||
if( near_lossless )
|
||||
vips_warn( "vips2webp", "%s", _( "near_lossless unsupported" ) );
|
||||
g_warning( "%s", _( "near_lossless unsupported" ) );
|
||||
if( smart_subsample )
|
||||
vips_warn( "vips2webp",
|
||||
"%s", _( "smart_subsample unsupported" ) );
|
||||
g_warning( "%s", _( "smart_subsample unsupported" ) );
|
||||
#endif
|
||||
|
||||
if( !WebPValidateConfig( &config ) ) {
|
||||
|
@ -106,11 +106,8 @@ static void
|
||||
vips_maplut_posteval( VipsImage *image, VipsProgress *progress,
|
||||
VipsMaplut *maplut )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( maplut );
|
||||
|
||||
if( maplut->overflow )
|
||||
vips_warn( class->nickname,
|
||||
_( "%d overflows detected" ), maplut->overflow );
|
||||
g_warning( _( "%d overflows detected" ), maplut->overflow );
|
||||
}
|
||||
|
||||
/* Our sequence value: the region this sequence is using, and local stats.
|
||||
|
@ -37,6 +37,7 @@ pkginclude_HEADERS = \
|
||||
region.h \
|
||||
resample.h \
|
||||
semaphore.h \
|
||||
soname.h \
|
||||
threadpool.h \
|
||||
thread.h \
|
||||
transform.h \
|
||||
@ -70,6 +71,7 @@ vips_scan_headers = \
|
||||
${top_srcdir}/libvips/include/vips/morphology.h \
|
||||
${top_srcdir}/libvips/include/vips/draw.h \
|
||||
${top_srcdir}/libvips/include/vips/basic.h \
|
||||
${top_srcdir}/libvips/include/vips/version.h \
|
||||
${top_srcdir}/libvips/include/vips/object.h
|
||||
|
||||
enumtypes.h: $(vips_scan_headers) Makefile
|
||||
|
@ -284,6 +284,14 @@ int im_plotpoint( IMAGE *im, int x, int y, PEL *pel );
|
||||
int im_smudge( IMAGE *image, int ix, int iy, VipsRect *r );
|
||||
int im_smear( IMAGE *im, int ix, int iy, VipsRect *r );
|
||||
|
||||
void vips_warn( const char *domain, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void vips_vwarn( const char *domain, const char *fmt, va_list ap );
|
||||
void vips_info_set( gboolean info );
|
||||
void vips_info( const char *domain, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void vips_vinfo( const char *domain, const char *fmt, va_list ap );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -50,13 +50,6 @@ void vips_verror_system( int err, const char *domain,
|
||||
const char *fmt, va_list ap );
|
||||
void vips_error_g( GError **error );
|
||||
void vips_g_error( GError **error );
|
||||
void vips_warn( const char *domain, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void vips_vwarn( const char *domain, const char *fmt, va_list ap );
|
||||
void vips_info_set( gboolean info );
|
||||
void vips_info( const char *domain, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void vips_vinfo( const char *domain, const char *fmt, va_list ap );
|
||||
|
||||
void vips_error_exit( const char *fmt, ... )
|
||||
__attribute__((noreturn, format(printf, 1, 2)));
|
||||
|
@ -131,6 +131,10 @@ typedef struct _VipsForeignLoad {
|
||||
*/
|
||||
VipsForeignFlags flags;
|
||||
|
||||
/* Stop load on first warning.
|
||||
*/
|
||||
gboolean fail;
|
||||
|
||||
/* Deprecated and unused, just here for compat.
|
||||
*/
|
||||
gboolean sequential;
|
||||
|
@ -133,6 +133,15 @@ extern "C" {
|
||||
*/
|
||||
#define VIPS_META_ORIENTATION "orientation"
|
||||
|
||||
/**
|
||||
* VIPS_META_PAGE_HEIGHT:
|
||||
*
|
||||
* If set, the height of each page when this image was loaded. If you save an
|
||||
* image with "page-height" set to a format that supports multiple pages, such
|
||||
* as tiff, the image will be saved as a series of pages.
|
||||
*/
|
||||
#define VIPS_META_PAGE_HEIGHT "page-height"
|
||||
|
||||
guint64 vips_format_sizeof( VipsBandFormat format );
|
||||
guint64 vips_format_sizeof_unsafe( VipsBandFormat format );
|
||||
|
||||
@ -170,6 +179,7 @@ gboolean vips_image_remove( VipsImage *image, const char *name );
|
||||
typedef void *(*VipsImageMapFn)( VipsImage *image,
|
||||
const char *name, GValue *value, void *a );
|
||||
void *vips_image_map( VipsImage *image, VipsImageMapFn fn, void *a );
|
||||
gchar **vips_image_get_fields( VipsImage *image );
|
||||
|
||||
void vips_image_set_area( VipsImage *image,
|
||||
const char *name, VipsCallbackFn free_fn, void *data );
|
||||
@ -189,6 +199,7 @@ int vips_image_get_string( const VipsImage *image,
|
||||
const char *name, const char **out );
|
||||
void vips_image_set_string( VipsImage *image,
|
||||
const char *name, const char *str );
|
||||
void vips_image_print_field( const VipsImage *image, const char *field );
|
||||
|
||||
int vips_image_history_printf( VipsImage *image, const char *format, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
@ -56,11 +56,6 @@ extern "C" {
|
||||
*/
|
||||
#define VIPS_SIZEOF_HEADER (64)
|
||||
|
||||
/* Startup ABI check.
|
||||
*/
|
||||
int vips__init( const char *argv0 );
|
||||
size_t vips__get_sizeof_vipsobject( void );
|
||||
|
||||
/* What we track for each mmap window. Have a list of these on an openin
|
||||
* VipsImage.
|
||||
*/
|
||||
@ -183,6 +178,11 @@ void vips__demand_hint_array( struct _VipsImage *image,
|
||||
int vips__image_copy_fields_array( struct _VipsImage *out,
|
||||
struct _VipsImage *in[] );
|
||||
|
||||
/* Deprecated.
|
||||
*/
|
||||
int vips__init( const char *argv0 );
|
||||
size_t vips__get_sizeof_vipsobject( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
2
libvips/include/vips/soname.h
Normal file
2
libvips/include/vips/soname.h
Normal file
@ -0,0 +1,2 @@
|
||||
/* This file is autogenerated, do not edit. */
|
||||
#define VIPS_SONAME "libvips.so.42"
|
@ -135,6 +135,14 @@ G_STMT_START { \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
/* The g_info() macro was added in 2.40.
|
||||
*/
|
||||
#ifndef g_info
|
||||
/* Hopefully we have varargs macros. Maybe revisit this.
|
||||
*/
|
||||
#define g_info(...) \
|
||||
g_log( G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
/* Various integer range clips. Record over/under flows.
|
||||
*/
|
||||
|
@ -10,6 +10,21 @@
|
||||
#define VIPS_MINOR_VERSION (@VIPS_MINOR_VERSION@)
|
||||
#define VIPS_MICRO_VERSION (@VIPS_MICRO_VERSION@)
|
||||
|
||||
/* The ABI version, as used for library versioning.
|
||||
*/
|
||||
#define VIPS_LIBRARY_CURRENT (@LIBRARY_CURRENT@)
|
||||
#define VIPS_LIBRARY_REVISION (@LIBRARY_REVISION@)
|
||||
#define VIPS_LIBRARY_AGE (@LIBRARY_AGE@)
|
||||
|
||||
/**
|
||||
* VIPS_SONAME:
|
||||
*
|
||||
* The name of the shared object containing the vips library, for example
|
||||
* "libvips.so.42", or "libvips-42.dll".
|
||||
*/
|
||||
|
||||
#include "soname.h"
|
||||
|
||||
/* Not really anything to do with versions, but this is a handy place to put
|
||||
* it.
|
||||
*/
|
||||
|
@ -164,14 +164,13 @@ extern "C" {
|
||||
* not have _().
|
||||
*/
|
||||
#define VIPS_INIT( ARGV0 ) \
|
||||
(sizeof( VipsObject ) != vips__get_sizeof_vipsobject() ? ( \
|
||||
vips_info( "vips_init", "ABI mismatch" ), \
|
||||
vips_info( "vips_init", \
|
||||
"library has sizeof(VipsObject) == %zd", \
|
||||
vips__get_sizeof_vipsobject() ), \
|
||||
vips_info( "vips_init", \
|
||||
"application has sizeof(VipsObject) == %zd", \
|
||||
sizeof( VipsObject ) ), \
|
||||
(vips_version( 3 ) - vips_version( 5 ) != \
|
||||
VIPS_LIBRARY_CURRENT - VIPS_LIBRARY_AGE ? ( \
|
||||
g_warning( "ABI mismatch" ), \
|
||||
g_warning( "library has ABI version %d", \
|
||||
vips_version( 3 ) - vips_version( 5 ) ), \
|
||||
g_warning( "application needs ABI version %d", \
|
||||
VIPS_LIBRARY_CURRENT - VIPS_LIBRARY_AGE ), \
|
||||
vips_error( "vips_init", "ABI mismatch" ), \
|
||||
-1 ) : \
|
||||
vips_init( ARGV0 ))
|
||||
|
@ -68,6 +68,7 @@ vips_scan_headers = \
|
||||
${top_srcdir}/libvips/include/vips/morphology.h \
|
||||
${top_srcdir}/libvips/include/vips/draw.h \
|
||||
${top_srcdir}/libvips/include/vips/basic.h \
|
||||
${top_srcdir}/libvips/include/vips/version.h \
|
||||
${top_srcdir}/libvips/include/vips/object.h
|
||||
|
||||
enumtypes.c: $(vips_scan_headers) Makefile
|
||||
|
@ -103,12 +103,29 @@
|
||||
*
|
||||
* The domain argument most of these functions take is not localised and is
|
||||
* supposed to indicate the component which failed.
|
||||
*
|
||||
* libvips uses g_warning() and g_info() to send warning and information
|
||||
* messages to the user. You can use the usual glib mechanisms to display or
|
||||
* divert these messages. For example, info messages are hidden by default, but
|
||||
* you can see them with:
|
||||
*
|
||||
* |[
|
||||
* $ G_MESSAGES_DEBUG=VIPS vipsthumbnail k2.jpg
|
||||
* VIPS-INFO: thumbnailing k2.jpg
|
||||
* VIPS-INFO: selected loader is VipsForeignLoadJpegFile
|
||||
* VIPS-INFO: input size is 1450 x 2048
|
||||
* VIPS-INFO: loading jpeg with factor 8 pre-shrink
|
||||
* VIPS-INFO: converting to processing space srgb
|
||||
* VIPS-INFO: residual reducev by 0.5
|
||||
* VIPS-INFO: 13 point mask
|
||||
* VIPS-INFO: using vector path
|
||||
* VIPS-INFO: residual reduceh by 0.5
|
||||
* VIPS-INFO: 13 point mask
|
||||
* VIPS-INFO: thumbnailing k2.jpg as ./tn_k2.jpg
|
||||
* ]|
|
||||
*
|
||||
*/
|
||||
|
||||
/* Show info messages. Handy for debugging.
|
||||
*/
|
||||
int vips__info = 0;
|
||||
|
||||
/* Make global array to keep the error message buffer.
|
||||
*/
|
||||
#define VIPS_MAX_ERROR (10240)
|
||||
@ -371,125 +388,6 @@ vips_error_clear( void )
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_info_set:
|
||||
* @info: %TRUE to enable info messages
|
||||
*
|
||||
* If set, vips will output various informative messages to stderr as it works.
|
||||
*
|
||||
* See also: vips_info().
|
||||
*/
|
||||
void
|
||||
vips_info_set( gboolean info )
|
||||
{
|
||||
vips__info = info;
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_vinfo:
|
||||
* @domain: the source of the message
|
||||
* @fmt: printf()-style format string for the message
|
||||
* @ap: arguments to the format string
|
||||
*
|
||||
* Sends a formatted informational message to stderr if the --vips-info flag
|
||||
* has been given to the program, or the environment variable VIPS_INFO has been
|
||||
* defined, or if vips_info_set() has been called.
|
||||
*
|
||||
* Informational messages are used to report details about the operation of
|
||||
* functions.
|
||||
*
|
||||
* See also: vips_info(), vips_info_set(), vips_warn().
|
||||
*/
|
||||
void
|
||||
vips_vinfo( const char *domain, const char *fmt, va_list ap )
|
||||
{
|
||||
if( vips__info ) {
|
||||
g_mutex_lock( vips__global_lock );
|
||||
(void) fprintf( stderr, _( "%s: " ), _( "info" ) );
|
||||
if( domain )
|
||||
(void) fprintf( stderr, _( "%s: " ), domain );
|
||||
(void) vfprintf( stderr, fmt, ap );
|
||||
(void) fprintf( stderr, "\n" );
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_info:
|
||||
* @domain: the source of the diagnostic message
|
||||
* @fmt: printf()-style format string for the message
|
||||
* @...: arguments to the format string
|
||||
*
|
||||
* Sends a formatted informational message to stderr if the --vips-info flag
|
||||
* has been given to the program or the environment variable VIPS_INFO has been
|
||||
* defined, or if vips_info_set() has been called.
|
||||
*
|
||||
* Informational messages are used to report details about the operation of
|
||||
* functions.
|
||||
*
|
||||
* See also: vips_info_set(), vips_vinfo(), vips_warn().
|
||||
*/
|
||||
void
|
||||
vips_info( const char *domain, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vips_vinfo( domain, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_vwarn:
|
||||
* @domain: the source of the warning message
|
||||
* @fmt: printf()-style format string for the message
|
||||
* @ap: arguments to the format string
|
||||
*
|
||||
* Exactly as vips_warn(), but takes a va_list argument.
|
||||
*
|
||||
* See also: vips_warn().
|
||||
*/
|
||||
void
|
||||
vips_vwarn( const char *domain, const char *fmt, va_list ap )
|
||||
{
|
||||
if( !g_getenv( "IM_WARNING" ) &&
|
||||
!g_getenv( "VIPS_WARNING" ) ) {
|
||||
g_mutex_lock( vips__global_lock );
|
||||
(void) fprintf( stderr, _( "%s: " ), _( "vips warning" ) );
|
||||
if( domain )
|
||||
(void) fprintf( stderr, _( "%s: " ), domain );
|
||||
(void) vfprintf( stderr, fmt, ap );
|
||||
(void) fprintf( stderr, "\n" );
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
}
|
||||
|
||||
if( vips__fatal )
|
||||
vips_error_exit( "vips__fatal" );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_warn:
|
||||
* @domain: the source of the warning message
|
||||
* @fmt: printf()-style format string for the message
|
||||
* @...: arguments to the format string
|
||||
*
|
||||
* Sends a formatted warning message to stderr. If you define the
|
||||
* environment variable VIPS_WARNING, these message are supressed.
|
||||
*
|
||||
* Warning messages are used to report things like overflow counts.
|
||||
*
|
||||
* See also: vips_info(), vips_vwarn().
|
||||
*/
|
||||
void
|
||||
vips_warn( const char *domain, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start( ap, fmt );
|
||||
vips_vwarn( domain, fmt, ap );
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_error_exit:
|
||||
* @fmt: printf()-style format string for the message
|
||||
|
@ -143,8 +143,7 @@ vips_thread_profile_save( VipsThreadProfile *profile )
|
||||
vips__file_open_write( "vips-profile.txt", TRUE );
|
||||
if( !vips__thread_fp ) {
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
vips_warn( "VipsGate",
|
||||
"%s", "unable to create profile log" );
|
||||
g_warning( "unable to create profile log" );
|
||||
return;
|
||||
}
|
||||
|
||||
@ -204,8 +203,7 @@ vips__thread_profile_init_cb( VipsThreadProfile *profile )
|
||||
* been called.
|
||||
*/
|
||||
if( vips__thread_profile )
|
||||
vips_warn( "VipsGate",
|
||||
"discarding unsaved state for thread %p --- "
|
||||
g_warning( "discarding unsaved state for thread %p --- "
|
||||
"call vips_thread_shutdown() for this thread",
|
||||
profile->thread );
|
||||
|
||||
|
@ -411,7 +411,7 @@ vips_image_pipelinev( VipsImage *image, VipsDemandStyle hint, ... )
|
||||
;
|
||||
va_end( ap );
|
||||
if( i == MAX_IMAGES ) {
|
||||
vips_warn( "vips_image_pipeline", "%s", _( "too many images" ) );
|
||||
g_warning( "%s", _( "too many images" ) );
|
||||
|
||||
/* Make sure we have a sentinel there.
|
||||
*/
|
||||
|
@ -893,8 +893,11 @@ vips__image_copy_fields_array( VipsImage *out, VipsImage *in[] )
|
||||
|
||||
/* Need to copy last-to-first so that in0 meta will override any
|
||||
* earlier meta.
|
||||
*
|
||||
* Don't destroy the meta on out. Things like foreign.c like setting
|
||||
* image properties before calling a subclass loader, and those
|
||||
* subclass loaders will sometimes write to an image.
|
||||
*/
|
||||
vips__meta_destroy( out );
|
||||
for( i = ni - 1; i >= 0; i-- )
|
||||
if( meta_cp( out, in[i] ) )
|
||||
return( -1 );
|
||||
@ -1176,6 +1179,55 @@ vips_image_map( VipsImage *image, VipsImageMapFn fn, void *a )
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
static void *
|
||||
count_fields( VipsImage *image, const char *field, GValue *value, void *a )
|
||||
{
|
||||
int *n_fields = (int *) a;
|
||||
|
||||
n_fields += 1;
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
static void *
|
||||
add_fields( VipsImage *image, const char *field, GValue *value, void *a )
|
||||
{
|
||||
gchar ***p = (gchar ***) a;
|
||||
|
||||
**p = g_strdup( field );
|
||||
*p += 1;
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_image_get_fields:
|
||||
* @image: image to get fields from
|
||||
*
|
||||
* Get a %NULL-terminated array listing all the metadata field names on @image.
|
||||
* Free the return result with g_strfreev().
|
||||
*
|
||||
* This is handy for language bindings. From C, it's usually more convenient to
|
||||
* use vips_image_map().
|
||||
*
|
||||
* Returns: (transfer full): metadata fields in image, as a %NULL-terminated
|
||||
* array.
|
||||
*/
|
||||
gchar **
|
||||
vips_image_get_fields( VipsImage *image )
|
||||
{
|
||||
int n_fields;
|
||||
gchar **fields;
|
||||
gchar **p;
|
||||
|
||||
(void) vips_image_map( image, count_fields, &n_fields );
|
||||
fields = g_new0( gchar *, n_fields + 1 );
|
||||
p = fields;
|
||||
(void) vips_image_map( image, add_fields, &p );
|
||||
|
||||
return( fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_image_set_area:
|
||||
* @image: image to attach the metadata to
|
||||
@ -1524,6 +1576,28 @@ vips_image_get_as_string( const VipsImage *image,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_image_print_field:
|
||||
* @image: image to get the header field from
|
||||
* @field: field name
|
||||
*
|
||||
* Prints a field to stdout as ASCII. Handy for debugging.
|
||||
*/
|
||||
void
|
||||
vips_image_print_field( const VipsImage *image, const char *field )
|
||||
{
|
||||
char *str;
|
||||
|
||||
if( vips_image_get_as_string( image, field, &str ) ) {
|
||||
printf( "vips_image_print_field: unable to read field\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
printf( ".%s: %s\n", field, str );
|
||||
|
||||
g_free( str );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_image_history_printf:
|
||||
* @image: add history line to this image
|
||||
|
@ -1006,8 +1006,7 @@ vips_image_build( VipsObject *object )
|
||||
* still be able to process it without coredumps.
|
||||
*/
|
||||
if( image->file_length > sizeof_image )
|
||||
vips_warn( "VipsImage",
|
||||
_( "%s is longer than expected" ),
|
||||
g_warning( _( "%s is longer than expected" ),
|
||||
image->filename );
|
||||
break;
|
||||
|
||||
@ -2590,9 +2589,8 @@ vips_image_write_to_memory( VipsImage *in, size_t *size_out )
|
||||
vips_error( "vips_image_write_to_memory",
|
||||
_( "out of memory --- size == %dMB" ),
|
||||
(int) (size / (1024.0 * 1024.0)) );
|
||||
vips_warn( "vips_image_write_to_memory",
|
||||
_( "out of memory --- size == %dMB" ),
|
||||
(int) (size / (1024.0*1024.0)) );
|
||||
g_warning( _( "out of memory --- size == %dMB" ),
|
||||
(int) (size / (1024.0 * 1024.0)) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
@ -3143,8 +3141,7 @@ vips_image_wio_input( VipsImage *image )
|
||||
* generate from this image.
|
||||
*/
|
||||
if( image->regions )
|
||||
vips_warn( "vips_image_wio_input", "%s",
|
||||
"rewinding image with active regions" );
|
||||
g_warning( "rewinding image with active regions" );
|
||||
|
||||
break;
|
||||
|
||||
|
@ -226,10 +226,8 @@ vips_load_plugins( const char *fmt, ... )
|
||||
|
||||
module = g_module_open( path, G_MODULE_BIND_LAZY );
|
||||
if( !module ) {
|
||||
vips_warn( "vips_init",
|
||||
_( "unable to load \"%s\" -- %s" ),
|
||||
path,
|
||||
g_module_error() );
|
||||
g_warning( _( "unable to load \"%s\" -- %s" ),
|
||||
path, g_module_error() );
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
@ -343,11 +341,14 @@ vips_init( const char *argv0 )
|
||||
bindtextdomain( GETTEXT_PACKAGE, name );
|
||||
bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
|
||||
|
||||
/* Default various settings from env.
|
||||
/* Deprecated, this is just for compat.
|
||||
*/
|
||||
if( g_getenv( "VIPS_INFO" ) ||
|
||||
g_getenv( "IM_INFO" ) )
|
||||
vips_info_set( TRUE );
|
||||
|
||||
/* Default various settings from env.
|
||||
*/
|
||||
if( g_getenv( "VIPS_TRACE" ) )
|
||||
vips_cache_set_trace( TRUE );
|
||||
|
||||
@ -391,7 +392,7 @@ vips_init( const char *argv0 )
|
||||
*/
|
||||
if( im_load_plugins( "%s/vips-%d.%d",
|
||||
libdir, VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION ) ) {
|
||||
vips_warn( "vips_init", "%s", vips_error_buffer() );
|
||||
g_warning( "%s", vips_error_buffer() );
|
||||
vips_error_clear();
|
||||
}
|
||||
|
||||
@ -399,7 +400,7 @@ vips_init( const char *argv0 )
|
||||
* :-( kept for back compat convenience.
|
||||
*/
|
||||
if( im_load_plugins( "%s", libdir ) ) {
|
||||
vips_warn( "vips_init", "%s", vips_error_buffer() );
|
||||
g_warning( "%s", vips_error_buffer() );
|
||||
vips_error_clear();
|
||||
}
|
||||
|
||||
@ -432,20 +433,6 @@ vips_init( const char *argv0 )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Return the sizeof() various important data structures. These are checked
|
||||
* against the headers used to build our caller by vips_init().
|
||||
*
|
||||
* We allow direct access to members of VipsImage and VipsRegion (mostly for
|
||||
* reasons of history), so any change to a superclass of either of these
|
||||
* objects will break our ABI.
|
||||
*/
|
||||
|
||||
size_t
|
||||
vips__get_sizeof_vipsobject( void )
|
||||
{
|
||||
return( sizeof( VipsObject ) );
|
||||
}
|
||||
|
||||
/* Call this before vips stuff that uses stuff we need to have inited.
|
||||
*/
|
||||
void
|
||||
@ -592,12 +579,12 @@ vips__ngettext( const char *msgid, const char *plural, unsigned long int n )
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips_lib_version_cb( const gchar *option_name, const gchar *value,
|
||||
vips_lib_info_cb( const gchar *option_name, const gchar *value,
|
||||
gpointer data, GError **error )
|
||||
{
|
||||
printf( "libvips %s\n", VIPS_VERSION_STRING );
|
||||
vips_shutdown();
|
||||
exit( 0 );
|
||||
vips_info_set( TRUE );
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -618,9 +605,18 @@ vips_set_fatal_cb( const gchar *option_name, const gchar *value,
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips_lib_version_cb( const gchar *option_name, const gchar *value,
|
||||
gpointer data, GError **error )
|
||||
{
|
||||
printf( "libvips %s\n", VIPS_VERSION_STRING );
|
||||
vips_shutdown();
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
static GOptionEntry option_entries[] = {
|
||||
{ "vips-info", 0, G_OPTION_FLAG_HIDDEN,
|
||||
G_OPTION_ARG_NONE, &vips__info,
|
||||
{ "vips-info", 0, G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_CALLBACK, (gpointer) &vips_lib_info_cb,
|
||||
N_( "show informative messages" ), NULL },
|
||||
{ "vips-fatal", 0, G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_CALLBACK, (gpointer) &vips_set_fatal_cb,
|
||||
@ -1029,6 +1025,9 @@ vips_version_string( void )
|
||||
* Get the major, minor or micro library version, with @flag values 0, 1 and
|
||||
* 2.
|
||||
*
|
||||
* Get the ABI current, revision and age (as used by libtool) with @flag
|
||||
* values 3, 4, 5.
|
||||
*
|
||||
* Returns: library version number
|
||||
*/
|
||||
int
|
||||
@ -1037,15 +1036,24 @@ vips_version( int flag )
|
||||
switch( flag ) {
|
||||
case 0:
|
||||
return( VIPS_MAJOR_VERSION );
|
||||
|
||||
|
||||
case 1:
|
||||
return( VIPS_MINOR_VERSION );
|
||||
|
||||
|
||||
case 2:
|
||||
return( VIPS_MICRO_VERSION );
|
||||
|
||||
case 3:
|
||||
return( VIPS_LIBRARY_CURRENT );
|
||||
|
||||
case 4:
|
||||
return( VIPS_LIBRARY_REVISION );
|
||||
|
||||
case 5:
|
||||
return( VIPS_LIBRARY_AGE );
|
||||
|
||||
default:
|
||||
vips_error( "vips_version", "%s", _( "flag not 0, 1, 2" ) );
|
||||
vips_error( "vips_version", "%s", _( "flag not in [0, 5]" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
@ -1064,3 +1072,12 @@ vips_leak_set( gboolean leak )
|
||||
{
|
||||
vips__leak = leak;
|
||||
}
|
||||
|
||||
/* Deprecated.
|
||||
*/
|
||||
size_t
|
||||
vips__get_sizeof_vipsobject( void )
|
||||
{
|
||||
return( sizeof( VipsObject ) );
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ vips__mmap( int fd, int writeable, size_t length, gint64 offset )
|
||||
if( baseaddr == MAP_FAILED ) {
|
||||
vips_error_system( errno, "vips_mapfile",
|
||||
"%s", _( "unable to mmap" ) );
|
||||
vips_warn( "vips_mapfile", _( "map failed (%s), "
|
||||
g_warning( _( "map failed (%s), "
|
||||
"running very low on system resources, "
|
||||
"expect a crash soon" ), strerror( errno ) );
|
||||
return( NULL );
|
||||
|
@ -248,11 +248,9 @@ vips_tracked_free( void *s )
|
||||
g_mutex_lock( vips_tracked_mutex );
|
||||
|
||||
if( vips_tracked_allocs <= 0 )
|
||||
vips_warn( "vips_tracked",
|
||||
"%s", _( "vips_free: too many frees" ) );
|
||||
g_warning( "%s", _( "vips_free: too many frees" ) );
|
||||
if( vips_tracked_mem < size )
|
||||
vips_warn( "vips_tracked",
|
||||
"%s", _( "vips_free: too much free" ) );
|
||||
g_warning( "%s", _( "vips_free: too much free" ) );
|
||||
|
||||
vips_tracked_mem -= size;
|
||||
vips_tracked_allocs -= 1;
|
||||
@ -310,8 +308,7 @@ vips_tracked_malloc( size_t size )
|
||||
vips_error( "vips_tracked",
|
||||
_( "out of memory --- size == %dMB" ),
|
||||
(int) (size / (1024.0 * 1024.0)) );
|
||||
vips_warn( "vips_tracked",
|
||||
_( "out of memory --- size == %dMB" ),
|
||||
g_warning( _( "out of memory --- size == %dMB" ),
|
||||
(int) (size / (1024.0 * 1024.0)) );
|
||||
|
||||
return( NULL );
|
||||
|
@ -221,12 +221,8 @@ vips_operation_finalize( GObject *gobject )
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_operation_finalize: %p\n", gobject );
|
||||
|
||||
if( operation->pixels ) {
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gobject );
|
||||
|
||||
vips_info( class->nickname,
|
||||
_( "%d pixels calculated" ), operation->pixels );
|
||||
}
|
||||
if( operation->pixels )
|
||||
g_info( _( "%d pixels calculated" ), operation->pixels );
|
||||
|
||||
G_OBJECT_CLASS( vips_operation_parent_class )->finalize( gobject );
|
||||
}
|
||||
|
@ -269,8 +269,7 @@ vips__region_stop( VipsRegion *region )
|
||||
* can really do with it, sadly.
|
||||
*/
|
||||
if( result )
|
||||
vips_warn( "VipsRegion",
|
||||
"stop callback failed for image %s",
|
||||
g_warning( "stop callback failed for image %s",
|
||||
image->filename );
|
||||
|
||||
region->seq = NULL;
|
||||
|
@ -231,8 +231,7 @@ vips_system_build( VipsObject *object )
|
||||
if( std_error ) {
|
||||
vips__chomp( std_error );
|
||||
if( strcmp( std_error, "" ) != 0 )
|
||||
vips_warn( class->nickname,
|
||||
_( "stderr output: %s" ), std_error );
|
||||
g_warning( _( "stderr output: %s" ), std_error );
|
||||
}
|
||||
if( std_output ) {
|
||||
vips__chomp( std_output );
|
||||
|
@ -407,8 +407,7 @@ vips_concurrency_get( void )
|
||||
if( nthr < 1 || nthr > MAX_THREADS ) {
|
||||
nthr = VIPS_CLIP( 1, nthr, MAX_THREADS );
|
||||
|
||||
vips_warn( "vips_concurrency_get",
|
||||
_( "threads clipped to %d" ), nthr );
|
||||
g_warning( _( "threads clipped to %d" ), nthr );
|
||||
}
|
||||
|
||||
/* Save for next time around.
|
||||
|
@ -73,7 +73,7 @@ vips_vector_error( VipsVector *vector )
|
||||
{
|
||||
#ifdef HAVE_ORC_PROGRAM_GET_ERROR
|
||||
if( vector->program )
|
||||
vips_warn( "VipsVector", "orc error: %s",
|
||||
g_warning( "orc error: %s",
|
||||
orc_program_get_error( vector->program ) );
|
||||
#endif /*HAVE_ORC_PROGRAM_GET_ERROR*/
|
||||
}
|
||||
|
@ -915,8 +915,7 @@ vips_image_open_input( VipsImage *image )
|
||||
return( -1 );
|
||||
image->file_length = rsize;
|
||||
if( psize > rsize )
|
||||
vips_warn( "VipsImage",
|
||||
_( "unable to read data for \"%s\", %s" ),
|
||||
g_warning( _( "unable to read data for \"%s\", %s" ),
|
||||
image->filename, _( "file has been truncated" ) );
|
||||
|
||||
/* Set demand style. This suits a disc file we read sequentially.
|
||||
@ -928,8 +927,7 @@ vips_image_open_input( VipsImage *image )
|
||||
* harmless.
|
||||
*/
|
||||
if( readhist( image ) ) {
|
||||
vips_warn( "VipsImage", _( "error reading XML: %s" ),
|
||||
vips_error_buffer() );
|
||||
g_warning( _( "error reading XML: %s" ), vips_error_buffer() );
|
||||
vips_error_clear();
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
* - gtk-doc
|
||||
* 17/1/14
|
||||
* - redone as a class
|
||||
* 12/11/16
|
||||
* - oop, allow index == 0, thanks Rob
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -430,7 +432,7 @@ vips_rank_class_init( VipsRankClass *class )
|
||||
_( "Select pixel at index" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsRank, index ),
|
||||
1, 100000000, 50 );
|
||||
0, 100000000, 50 );
|
||||
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ vips_reduceh_build( VipsObject *object )
|
||||
*/
|
||||
reduceh->n_point =
|
||||
vips_reduce_get_points( reduceh->kernel, reduceh->hshrink );
|
||||
vips_info( object_class->nickname, "%d point mask", reduceh->n_point );
|
||||
g_info( "%d point mask", reduceh->n_point );
|
||||
if( reduceh->n_point > MAX_POINT ) {
|
||||
vips_error( object_class->nickname,
|
||||
"%s", _( "reduce factor too large" ) );
|
||||
|
@ -779,7 +779,7 @@ vips_reducev_raw( VipsReducev *reducev, VipsImage *in )
|
||||
if( in->BandFmt == VIPS_FORMAT_UCHAR &&
|
||||
vips_vector_isenabled() &&
|
||||
!vips_reducev_compile( reducev ) ) {
|
||||
vips_info( object_class->nickname, "using vector path" );
|
||||
g_info( "using vector path" );
|
||||
generate = vips_reducev_vector_gen;
|
||||
}
|
||||
|
||||
@ -848,7 +848,7 @@ vips_reducev_build( VipsObject *object )
|
||||
"%s", _( "reduce factor too large" ) );
|
||||
return( -1 );
|
||||
}
|
||||
vips_info( object_class->nickname, "%d point mask", reducev->n_point );
|
||||
g_info( "%d point mask", reducev->n_point );
|
||||
|
||||
/* Unpack for processing.
|
||||
*/
|
||||
|
@ -64,7 +64,15 @@
|
||||
* sort of 2D transform which preserves straight lines; so any combination of
|
||||
* stretch, sheer, rotate and translate. You supply an interpolator for it to
|
||||
* use to generate pixels, see vips_interpolate_new(). It will not produce
|
||||
* good results for very large shrinks.
|
||||
* good results for very large shrinks: you'll see aliasing.
|
||||
*
|
||||
* vips_reduce() is like vips_affine(), but it can only shrink images, it can't
|
||||
* enlarge, rotate, or skew. It's very fast and uses an adaptive kernel for
|
||||
* interpolation. Again, it will give poor results for large size reductions.
|
||||
*
|
||||
* vips_shrink() is a fast block shrinker. It can quickly reduce images by
|
||||
* large integer factors. It will give poor results for small size reductions:
|
||||
* again, you'll see aliasing.
|
||||
*
|
||||
* Next, vips_resize() specialises in the common task of image reduce and
|
||||
* enlarge. It strings together combinations of vips_shrink(), vips_reduce(),
|
||||
|
@ -155,7 +155,6 @@ vips_resize_interpolate( VipsKernel kernel )
|
||||
static int
|
||||
vips_resize_build( VipsObject *object )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||
VipsResample *resample = VIPS_RESAMPLE( object );
|
||||
VipsResize *resize = (VipsResize *) object;
|
||||
|
||||
@ -186,7 +185,7 @@ vips_resize_build( VipsObject *object )
|
||||
int_vshrink = vips_resize_int_shrink( resize, vscale );
|
||||
|
||||
if( int_vshrink > 1 ) {
|
||||
vips_info( class->nickname, "shrinkv by %d", int_vshrink );
|
||||
g_info( "shrinkv by %d", int_vshrink );
|
||||
if( vips_shrinkv( in, &t[0], int_vshrink, NULL ) )
|
||||
return( -1 );
|
||||
in = t[0];
|
||||
@ -195,7 +194,7 @@ vips_resize_build( VipsObject *object )
|
||||
}
|
||||
|
||||
if( int_hshrink > 1 ) {
|
||||
vips_info( class->nickname, "shrinkh by %d", int_hshrink );
|
||||
g_info( "shrinkh by %d", int_hshrink );
|
||||
if( vips_shrinkh( in, &t[1], int_hshrink, NULL ) )
|
||||
return( -1 );
|
||||
in = t[1];
|
||||
@ -251,8 +250,7 @@ vips_resize_build( VipsObject *object )
|
||||
/* Any residual downsizing.
|
||||
*/
|
||||
if( vscale < 1.0 ) {
|
||||
vips_info( class->nickname, "residual reducev by %g",
|
||||
vscale );
|
||||
g_info( "residual reducev by %g", vscale );
|
||||
if( vips_reducev( in, &t[2], 1.0 / vscale,
|
||||
"kernel", resize->kernel,
|
||||
"centre", resize->centre,
|
||||
@ -262,7 +260,7 @@ vips_resize_build( VipsObject *object )
|
||||
}
|
||||
|
||||
if( hscale < 1.0 ) {
|
||||
vips_info( class->nickname, "residual reduceh by %g",
|
||||
g_info( "residual reduceh by %g",
|
||||
hscale );
|
||||
if( vips_reduceh( in, &t[3], 1.0 / hscale,
|
||||
"kernel", resize->kernel,
|
||||
@ -285,8 +283,7 @@ vips_resize_build( VipsObject *object )
|
||||
|
||||
if( hscale > 1.0 &&
|
||||
vscale > 1.0 ) {
|
||||
vips_info( class->nickname,
|
||||
"residual scale %g x %g", hscale, vscale );
|
||||
g_info( "residual scale %g x %g", hscale, vscale );
|
||||
if( vips_affine( in, &t[4],
|
||||
hscale, 0.0, 0.0, vscale,
|
||||
"interpolate", interpolate,
|
||||
@ -295,8 +292,7 @@ vips_resize_build( VipsObject *object )
|
||||
in = t[4];
|
||||
}
|
||||
else if( hscale > 1.0 ) {
|
||||
vips_info( class->nickname,
|
||||
"residual scale %g", hscale );
|
||||
g_info( "residual scale %g", hscale );
|
||||
if( vips_affine( in, &t[4], hscale, 0.0, 0.0, 1.0,
|
||||
"interpolate", interpolate,
|
||||
NULL ) )
|
||||
@ -304,8 +300,7 @@ vips_resize_build( VipsObject *object )
|
||||
in = t[4];
|
||||
}
|
||||
else {
|
||||
vips_info( class->nickname,
|
||||
"residual scale %g", vscale );
|
||||
g_info( "residual scale %g", vscale );
|
||||
if( vips_affine( in, &t[4], 1.0, 0.0, 0.0, vscale,
|
||||
"interpolate", interpolate,
|
||||
NULL ) )
|
||||
|
@ -195,9 +195,8 @@ vips_thumbnail_open( VipsThumbnail *thumbnail )
|
||||
|
||||
if( class->get_info( thumbnail ) )
|
||||
return( NULL );
|
||||
vips_info( "thumbnail", "selected loader is %s",
|
||||
thumbnail->loader );
|
||||
vips_info( "thumbnail", "input size is %d x %d",
|
||||
g_info( "selected loader is %s", thumbnail->loader );
|
||||
g_info( "input size is %d x %d",
|
||||
thumbnail->input_width, thumbnail->input_height );
|
||||
|
||||
shrink = 1;
|
||||
@ -206,21 +205,18 @@ vips_thumbnail_open( VipsThumbnail *thumbnail )
|
||||
if( vips_isprefix( "VipsForeignLoadJpeg", thumbnail->loader ) ) {
|
||||
shrink = vips_thumbnail_find_jpegshrink( thumbnail,
|
||||
thumbnail->input_width, thumbnail->input_height );
|
||||
vips_info( "thumbnail",
|
||||
"loading jpeg with factor %d pre-shrink", shrink );
|
||||
g_info( "loading jpeg with factor %d pre-shrink", shrink );
|
||||
}
|
||||
else if( vips_isprefix( "VipsForeignLoadPdf", thumbnail->loader ) ||
|
||||
vips_isprefix( "VipsForeignLoadSvg", thumbnail->loader ) ) {
|
||||
scale = 1.0 / vips_thumbnail_calculate_shrink( thumbnail,
|
||||
thumbnail->input_width, thumbnail->input_height );
|
||||
vips_info( "thumbnail",
|
||||
"loading PDF/SVG with factor %g pre-scale", scale );
|
||||
g_info( "loading PDF/SVG with factor %g pre-scale", scale );
|
||||
}
|
||||
else if( vips_isprefix( "VipsForeignLoadWebp", thumbnail->loader ) ) {
|
||||
shrink = vips_thumbnail_calculate_shrink( thumbnail,
|
||||
thumbnail->input_width, thumbnail->input_height );
|
||||
vips_info( "thumbnail",
|
||||
"loading webp with factor %d pre-shrink", shrink );
|
||||
g_info( "loading webp with factor %d pre-shrink", shrink );
|
||||
}
|
||||
|
||||
if( !(im = class->open( thumbnail, shrink, scale )) )
|
||||
@ -269,7 +265,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
/* RAD needs special unpacking.
|
||||
*/
|
||||
if( in->Coding == VIPS_CODING_RAD ) {
|
||||
vips_info( "thumbnail", "unpacking Rad to float" );
|
||||
g_info( "unpacking Rad to float" );
|
||||
|
||||
/* rad is scrgb.
|
||||
*/
|
||||
@ -296,11 +292,9 @@ vips_thumbnail_build( VipsObject *object )
|
||||
(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ||
|
||||
thumbnail->import_profile) ) {
|
||||
if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) )
|
||||
vips_info( "thumbnail",
|
||||
"importing with embedded profile" );
|
||||
g_info( "importing with embedded profile" );
|
||||
else
|
||||
vips_info( "thumbnail",
|
||||
"importing with profile %s",
|
||||
g_info( "importing with profile %s",
|
||||
thumbnail->import_profile );
|
||||
|
||||
if( vips_icc_import( in, &t[1],
|
||||
@ -317,7 +311,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
|
||||
/* To the processing colourspace. This will unpack LABQ as well.
|
||||
*/
|
||||
vips_info( "thumbnail", "converting to processing space %s",
|
||||
g_info( "converting to processing space %s",
|
||||
vips_enum_nick( VIPS_TYPE_INTERPRETATION, interpretation ) );
|
||||
if( vips_colourspace( in, &t[2], interpretation, NULL ) )
|
||||
return( -1 );
|
||||
@ -328,7 +322,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
*/
|
||||
have_premultiplied = FALSE;
|
||||
if( vips_image_hasalpha( in ) ) {
|
||||
vips_info( "thumbnail", "premultiplying alpha" );
|
||||
g_info( "premultiplying alpha" );
|
||||
if( vips_premultiply( in, &t[3], NULL ) )
|
||||
return( -1 );
|
||||
have_premultiplied = TRUE;
|
||||
@ -353,7 +347,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
in = t[4];
|
||||
|
||||
if( have_premultiplied ) {
|
||||
vips_info( "thumbnail", "unpremultiplying alpha" );
|
||||
g_info( "unpremultiplying alpha" );
|
||||
if( vips_unpremultiply( in, &t[5], NULL ) ||
|
||||
vips_cast( t[5], &t[6], unpremultiplied_format, NULL ) )
|
||||
return( -1 );
|
||||
@ -369,8 +363,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
if( have_imported ) {
|
||||
if( thumbnail->export_profile ||
|
||||
vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
|
||||
vips_info( "thumbnail",
|
||||
"exporting to device space with a profile" );
|
||||
g_info( "exporting to device space with a profile" );
|
||||
if( vips_icc_export( in, &t[7],
|
||||
"output_profile", thumbnail->export_profile,
|
||||
NULL ) )
|
||||
@ -378,7 +371,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
in = t[7];
|
||||
}
|
||||
else {
|
||||
vips_info( "thumbnail", "converting to sRGB" );
|
||||
g_info( "converting to sRGB" );
|
||||
if( vips_colourspace( in, &t[7],
|
||||
VIPS_INTERPRETATION_sRGB, NULL ) )
|
||||
return( -1 );
|
||||
@ -390,23 +383,20 @@ vips_thumbnail_build( VipsObject *object )
|
||||
thumbnail->import_profile) ) {
|
||||
VipsImage *out;
|
||||
|
||||
vips_info( "thumbnail",
|
||||
"exporting with profile %s", thumbnail->export_profile );
|
||||
g_info( "exporting with profile %s", thumbnail->export_profile );
|
||||
|
||||
/* We first try with the embedded profile, if any, then if
|
||||
* that fails try again with the supplied fallback profile.
|
||||
*/
|
||||
out = NULL;
|
||||
if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
|
||||
vips_info( "thumbnail",
|
||||
"importing with embedded profile" );
|
||||
g_info( "importing with embedded profile" );
|
||||
|
||||
if( vips_icc_transform( in, &t[7],
|
||||
thumbnail->export_profile,
|
||||
"embedded", TRUE,
|
||||
NULL ) ) {
|
||||
vips_warn( "thumbnail",
|
||||
_( "unable to import with "
|
||||
g_warning( _( "unable to import with "
|
||||
"embedded profile: %s" ),
|
||||
vips_error_buffer() );
|
||||
|
||||
@ -418,8 +408,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
|
||||
if( !out &&
|
||||
thumbnail->import_profile ) {
|
||||
vips_info( "thumbnail",
|
||||
"importing with fallback profile" );
|
||||
g_info( "importing with fallback profile" );
|
||||
|
||||
if( vips_icc_transform( in, &t[7],
|
||||
thumbnail->export_profile,
|
||||
@ -442,7 +431,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
int left = (in->Xsize - thumbnail->width) / 2;
|
||||
int top = (in->Ysize - thumbnail->height) / 2;
|
||||
|
||||
vips_info( "thumbnail", "cropping to %dx%d",
|
||||
g_info( "cropping to %dx%d",
|
||||
thumbnail->width, thumbnail->height );
|
||||
if( vips_extract_area( in, &t[8], left, top,
|
||||
thumbnail->width, thumbnail->height, NULL ) )
|
||||
@ -454,7 +443,7 @@ vips_thumbnail_build( VipsObject *object )
|
||||
thumbnail->angle != VIPS_ANGLE_D0 ) {
|
||||
VipsAngle angle = vips_autorot_get_angle( in );
|
||||
|
||||
vips_info( "thumbnail", "rotating by %s",
|
||||
g_info( "rotating by %s",
|
||||
vips_enum_nick( VIPS_TYPE_ANGLE, angle ) );
|
||||
|
||||
/* Need to copy to memory, we have to stay seq.
|
||||
@ -573,7 +562,7 @@ vips_thumbnail_file_get_info( VipsThumbnail *thumbnail )
|
||||
|
||||
VipsImage *image;
|
||||
|
||||
vips_info( "thumbnail", "thumbnailing %s", file->filename );
|
||||
g_info( "thumbnailing %s", file->filename );
|
||||
|
||||
if( !(thumbnail->loader = vips_foreign_find_load( file->filename )) ||
|
||||
!(image = vips_image_new_from_file( file->filename, NULL )) )
|
||||
@ -726,8 +715,7 @@ vips_thumbnail_buffer_get_info( VipsThumbnail *thumbnail )
|
||||
|
||||
VipsImage *image;
|
||||
|
||||
vips_info( "thumbnail", "thumbnailing %zd bytes of data",
|
||||
buffer->buf->length );
|
||||
g_info( "thumbnailing %zd bytes of data", buffer->buf->length );
|
||||
|
||||
if( !(thumbnail->loader = vips_foreign_find_load_buffer(
|
||||
buffer->buf->data, buffer->buf->length )) ||
|
||||
|
BIN
test/images/multi-channel-z-series.ome.tif
Normal file
BIN
test/images/multi-channel-z-series.ome.tif
Normal file
Binary file not shown.
@ -43,6 +43,7 @@ class TestForeign(unittest.TestCase):
|
||||
self.jpeg_file = "images/йцук.jpg"
|
||||
self.png_file = "images/sample.png"
|
||||
self.tiff_file = "images/sample.tif"
|
||||
self.ome_file = "images/multi-channel-z-series.ome.tif"
|
||||
self.profile_file = "images/sRGB.icm"
|
||||
self.analyze_file = "images/t00740_tr1_segm.hdr"
|
||||
self.gif_file = "images/cramps.gif"
|
||||
@ -309,6 +310,39 @@ class TestForeign(unittest.TestCase):
|
||||
self.assertEqual(x1.height, x2.width)
|
||||
os.unlink("test-14.tif")
|
||||
|
||||
x = Vips.Image.new_from_file(self.ome_file)
|
||||
self.assertEqual(x.width, 439)
|
||||
self.assertEqual(x.height, 167)
|
||||
page_height = x.height
|
||||
|
||||
x = Vips.Image.new_from_file(self.ome_file, n = -1)
|
||||
self.assertEqual(x.width, 439)
|
||||
self.assertEqual(x.height, page_height * 15)
|
||||
|
||||
x = Vips.Image.new_from_file(self.ome_file, page = 1, n = -1)
|
||||
self.assertEqual(x.width, 439)
|
||||
self.assertEqual(x.height, page_height * 14)
|
||||
|
||||
x = Vips.Image.new_from_file(self.ome_file, page = 1, n = 2)
|
||||
self.assertEqual(x.width, 439)
|
||||
self.assertEqual(x.height, page_height * 2)
|
||||
|
||||
x = Vips.Image.new_from_file(self.ome_file, n = -1)
|
||||
self.assertEqual(x(0,166)[0], 96)
|
||||
self.assertEqual(x(0,167)[0], 0)
|
||||
self.assertEqual(x(0,168)[0], 1)
|
||||
|
||||
x.write_to_file("test-15.tif")
|
||||
|
||||
x = Vips.Image.new_from_file("test-15.tif", n = -1)
|
||||
self.assertEqual(x.width, 439)
|
||||
self.assertEqual(x.height, page_height * 15)
|
||||
self.assertEqual(x(0,166)[0], 96)
|
||||
self.assertEqual(x(0,167)[0], 0)
|
||||
self.assertEqual(x(0,168)[0], 1)
|
||||
|
||||
os.unlink("test-15.tif")
|
||||
|
||||
def test_magickload(self):
|
||||
x = Vips.type_find("VipsForeign", "magickload")
|
||||
if not x.is_instantiatable():
|
||||
@ -343,6 +377,7 @@ class TestForeign(unittest.TestCase):
|
||||
#self.assertEqual(im.height, height * 2)
|
||||
|
||||
# all-frames should load every frame of the animation
|
||||
# (though all-frames is deprecated)
|
||||
im = Vips.Image.magickload(self.gif_anim_file)
|
||||
width = im.width
|
||||
height = im.height
|
||||
@ -350,6 +385,16 @@ class TestForeign(unittest.TestCase):
|
||||
self.assertEqual(im.width, width)
|
||||
self.assertEqual(im.height, height * 5)
|
||||
|
||||
# page/n let you pick a range of pages
|
||||
im = Vips.Image.magickload(self.gif_anim_file)
|
||||
width = im.width
|
||||
height = im.height
|
||||
im = Vips.Image.magickload(self.gif_anim_file, page = 1, n = 2)
|
||||
self.assertEqual(im.width, width)
|
||||
self.assertEqual(im.height, height * 2)
|
||||
page_height = im.get_value("page-height")
|
||||
self.assertEqual(page_height, height)
|
||||
|
||||
# should work for dicom
|
||||
im = Vips.Image.magickload(self.dicom_file)
|
||||
self.assertEqual(im.width, 128)
|
||||
@ -530,6 +575,18 @@ class TestForeign(unittest.TestCase):
|
||||
self.file_loader("gifload", self.gif_file, gif_valid)
|
||||
self.buffer_loader("gifload_buffer", self.gif_file, gif_valid)
|
||||
|
||||
x1 = Vips.Image.new_from_file(self.gif_anim_file )
|
||||
x2 = Vips.Image.new_from_file(self.gif_anim_file, n = 2 )
|
||||
self.assertEqual(x2.height, 2 * x1.height)
|
||||
page_height = x2.get_value("page-height")
|
||||
self.assertEqual(page_height, x1.height)
|
||||
|
||||
x2 = Vips.Image.new_from_file(self.gif_anim_file, n = -1 )
|
||||
self.assertEqual(x2.height, 5 * x1.height)
|
||||
|
||||
x2 = Vips.Image.new_from_file(self.gif_anim_file, page = 1, n = -1 )
|
||||
self.assertEqual(x2.height, 4 * x1.height)
|
||||
|
||||
def test_svgload(self):
|
||||
x = Vips.type_find("VipsForeign", "svgload")
|
||||
if not x.is_instantiatable():
|
||||
|
@ -1041,12 +1041,18 @@ parse_options( GOptionContext *context, int *argc, char **argv )
|
||||
vips_error_exit( NULL );
|
||||
}
|
||||
|
||||
/* On Windows, argc will not have been updated by
|
||||
* g_option_context_parse_strv().
|
||||
*/
|
||||
for( *argc = 0; argv[*argc]; (*argc)++ )
|
||||
;
|
||||
|
||||
/* Remove any "--" argument. If one of our arguments is a negative
|
||||
* number, the user will need to have added the "--" flag to stop
|
||||
* GOption parsing. But "--" is still passed down to us and we need to
|
||||
* ignore it.
|
||||
*/
|
||||
for( i = 1; i < *argc - 1; i++ )
|
||||
for( i = 1; i < *argc; i++ )
|
||||
if( strcmp( argv[i], "--" ) == 0 ) {
|
||||
for( j = i; j < *argc; j++ )
|
||||
argv[j] = argv[j + 1];
|
||||
|
@ -213,8 +213,7 @@ thumbnail_write( VipsObject *process, VipsImage *im, const char *filename )
|
||||
g_free( dir );
|
||||
}
|
||||
|
||||
vips_info( "vipsthumbnail",
|
||||
"thumbnailing %s as %s", filename, output_name );
|
||||
g_info( "thumbnailing %s as %s", filename, output_name );
|
||||
|
||||
g_free( file );
|
||||
|
||||
@ -308,7 +307,7 @@ main( int argc, char **argv )
|
||||
|
||||
if( rotate_image ) {
|
||||
#ifndef HAVE_EXIF
|
||||
vips_warn( "vipsthumbnail", "%s",
|
||||
g_warning( "%s",
|
||||
_( "auto-rotate disabled: "
|
||||
"libvips built without exif support" ) );
|
||||
#endif /*!HAVE_EXIF*/
|
||||
|
Loading…
Reference in New Issue
Block a user