Merge branch 'master' into add-webp-metadata

This commit is contained in:
John Cupitt 2017-01-04 16:13:39 +00:00
commit 5d61bd4982
77 changed files with 2268 additions and 1408 deletions

View File

@ -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

View File

@ -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

View File

@ -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
])

View File

@ -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;
}

View File

@ -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>

View File

@ -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)

View File

@ -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,

View File

@ -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 &&

View File

@ -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 );
}

View File

@ -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,

View File

@ -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" );

View File

@ -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 );

View File

@ -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 );

View File

@ -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,

View File

@ -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 );

View File

@ -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" ) );

View File

@ -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

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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 )

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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

View File

@ -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.
*/

View File

@ -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 );
}

View File

@ -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 );

View File

@ -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[];

View File

@ -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;
}

View File

@ -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

View File

@ -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
*

View File

@ -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

View File

@ -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

View File

@ -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 ) ) {

View File

@ -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.

View File

@ -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

View File

@ -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*/

View File

@ -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)));

View File

@ -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;

View File

@ -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)));

View File

@ -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*/

View File

@ -0,0 +1,2 @@
/* This file is autogenerated, do not edit. */
#define VIPS_SONAME "libvips.so.42"

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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 ))

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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.
*/

View File

@ -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

View File

@ -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;

View File

@ -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 ) );
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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;

View File

@ -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 );

View File

@ -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.

View File

@ -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*/
}

View File

@ -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();
}

View File

@ -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 );
}

View File

@ -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" ) );

View File

@ -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.
*/

View File

@ -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(),

View File

@ -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 ) )

View File

@ -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 )) ||

Binary file not shown.

View File

@ -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():

View File

@ -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];

View File

@ -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*/