1 /* foreign file formats base class
2  *
3  * 7/2/12
4  * 	- add support for sequential reads
5  * 18/6/12
6  * 	- flatten alpha with vips_flatten()
7  * 28/5/13
8  * 	- auto rshift down to 8 bits during save
9  * 19/1/14
10  * 	- pack and unpack rad to scrgb
11  * 18/8/14
12  * 	- fix conversion to 16-bit RGB, thanks John
13  * 18/6/15
14  * 	- forward progress signals from load
15  * 23/5/16
16  * 	- remove max-alpha stuff, this is now automatic
17  * 12/6/17
18  * 	- transform cmyk->rgb if there's an embedded profile
19  * 16/6/17
20  * 	- add page_height
21  * 1/1/18
22  * 	- META_SEQ support moved here
23  * 5/3/18
24  * 	- block _start if one start fails, see #893
25  * 1/4/18
26  * 	- drop incompatible ICC profiles before save
27  * 24/7/21
28  * 	- add fail-on
29  */
30 
31 /*
32 
33     This file is part of VIPS.
34 
35     VIPS is free software; you can redistribute it and/or modify
36     it under the terms of the GNU Lesser General Public License as published by
37     the Free Software Foundation; either version 2 of the License, or
38     (at your option) any later version.
39 
40     This program is distributed in the hope that it will be useful,
41     but WITHOUT ANY WARRANTY; without even the implied warranty of
42     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
43     GNU Lesser General Public License for more details.
44 
45     You should have received a copy of the GNU Lesser General Public License
46     along with this program; if not, write to the Free Software
47     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
48     02110-1301  USA
49 
50  */
51 
52 /*
53 
54     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
55 
56  */
57 
58 /*
59 #define DEBUG
60  */
61 
62 #ifdef HAVE_CONFIG_H
63 #include <config.h>
64 #endif /*HAVE_CONFIG_H*/
65 #include <vips/intl.h>
66 
67 #include <stdio.h>
68 #include <stdlib.h>
69 
70 #include <vips/vips.h>
71 #include <vips/internal.h>
72 #include <vips/debug.h>
73 
74 #include "pforeign.h"
75 
76 /**
77  * SECTION: foreign
78  * @short_description: load and save images in a variety of formats
79  * @stability: Stable
80  * @see_also: <link linkend="libvips-image">image</link>
81  * @include: vips/vips.h
82  * @title: VipsForeign
83  *
84  * This set of operations load and save images in a variety of formats.
85  *
86  * The operations share a base class that offers a simple way to search for a
87  * subclass of #VipsForeign which can load a certain file (see
88  * vips_foreign_find_load()) or buffer (see vips_foreign_find_load_buffer()),
89  * or which could be used to save an image to a
90  * certain file type (see vips_foreign_find_save() and
91  * vips_foreign_find_save_buffer()). You can then run these
92  * operations using vips_call() and friends to perform the load or save.
93  *
94  * vips_image_write_to_file() and vips_image_new_from_file() and friends use
95  * these functions to automate file load and save.
96  *
97  * You can also invoke the operations directly, for example:
98  *
99  * |[
100  * vips_tiffsave (my_image, "frank.anything",
101  *     "compression", VIPS_FOREIGN_TIFF_COMPRESSION_JPEG,
102  *     NULL);
103  * ]|
104  *
105  * To add support for a new file format to vips, simply define a new subclass
106  * of #VipsForeignLoad or #VipsForeignSave.
107  *
108  * If you define a new operation which is a subclass of #VipsForeign, support
109  * for it automatically appears in all VIPS user-interfaces. It will also be
110  * transparently supported by vips_image_new_from_file() and friends.
111  *
112  * VIPS comes with VipsForeign for TIFF, JPEG, PNG, Analyze, PPM, OpenEXR, CSV,
113  * Matlab, Radiance, RAW, FITS, WebP, SVG, PDF, GIF and VIPS. It also includes
114  * import filters which can load with libMagick and with OpenSlide.
115  *
116  * ## Writing a new loader
117  *
118  * Add a new loader to VIPS by subclassing #VipsForeignLoad. Subclasses need to
119  * implement at least @header().
120  *
121  * @header() must set at least the header fields of @out. @load(), if defined,
122  * must load the pixels to @real.
123  *
124  * The suffix list is used to select a format to save a file in, and to pick a
125  * loader if you don't define is_a().
126  *
127  * You should also define @nickname and @description in #VipsObject.
128  *
129  * As a complete example, here's code for a PNG loader, minus the actual
130  * calls to libpng.
131  *
132  * |[
133  * typedef struct _VipsForeignLoadPng {
134  *   VipsForeignLoad parent_object;
135  *
136  *   char *filename;
137  * } VipsForeignLoadPng;
138  *
139  * typedef VipsForeignLoadClass VipsForeignLoadPngClass;
140  *
141  * G_DEFINE_TYPE( VipsForeignLoadPng, vips_foreign_load_png,
142  *   VIPS_TYPE_FOREIGN_LOAD );
143  *
144  * static VipsForeignFlags
145  * vips_foreign_load_png_get_flags_filename( const char *filename )
146  * {
147  *   VipsForeignFlags flags;
148  *
149  *   flags = 0;
150  *   if( vips__png_isinterlaced( filename ) )
151  *   	flags = VIPS_FOREIGN_PARTIAL;
152  *   else
153  *   	flags = VIPS_FOREIGN_SEQUENTIAL;
154  *
155  *   return( flags );
156  * }
157  *
158  * static VipsForeignFlags
159  * vips_foreign_load_png_get_flags( VipsForeignLoad *load )
160  * {
161  *   VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
162  *
163  *   return( vips_foreign_load_png_get_flags_filename( png->filename ) );
164  * }
165  *
166  * static int
167  * vips_foreign_load_png_header( VipsForeignLoad *load )
168  * {
169  *   VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
170  *
171  *   if( vips__png_header( png->filename, load->out ) )
172  *   	return( -1 );
173  *
174  *   return( 0 );
175  * }
176  *
177  * static int
178  * vips_foreign_load_png_load( VipsForeignLoad *load )
179  * {
180  *   VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
181  *
182  *   if( vips__png_read( png->filename, load->real ) )
183  *   	return( -1 );
184  *
185  *   return( 0 );
186  * }
187  *
188  * static void
189  * vips_foreign_load_png_class_init( VipsForeignLoadPngClass *class )
190  * {
191  *   GObjectClass *gobject_class = G_OBJECT_CLASS( class );
192  *   VipsObjectClass *object_class = (VipsObjectClass *) class;
193  *   VipsForeignClass *foreign_class = (VipsForeignClass *) class;
194  *   VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
195  *
196  *   gobject_class->set_property = vips_object_set_property;
197  *   gobject_class->get_property = vips_object_get_property;
198  *
199  *   object_class->nickname = "pngload";
200  *   object_class->description = _( "load png from file" );
201  *
202  *   foreign_class->suffs = vips__png_suffs;
203  *
204  *   load_class->is_a = vips__png_ispng;
205  *   load_class->get_flags_filename =
206  *   	vips_foreign_load_png_get_flags_filename;
207  *   load_class->get_flags = vips_foreign_load_png_get_flags;
208  *   load_class->header = vips_foreign_load_png_header;
209  *   load_class->load = vips_foreign_load_png_load;
210  *
211  *   VIPS_ARG_STRING( class, "filename", 1,
212  *   	_( "Filename" ),
213  *   	_( "Filename to load from" ),
214  *   	VIPS_ARGUMENT_REQUIRED_INPUT,
215  *   	G_STRUCT_OFFSET( VipsForeignLoadPng, filename ),
216  *   	NULL );
217  * }
218  *
219  * static void
220  * vips_foreign_load_png_init( VipsForeignLoadPng *png )
221  * {
222  * }
223  * ]|
224  *
225  * ## Writing a new saver
226  *
227  * Call your saver in the class' @build() method after chaining up. The
228  * prepared image should be ready for you to save in @ready.
229  *
230  * As a complete example, here's the code for the CSV saver, minus the calls
231  * to the actual save routines.
232  *
233  * |[
234  * typedef struct _VipsForeignSaveCsv {
235  *   VipsForeignSave parent_object;
236  *
237  *   char *filename;
238  *   const char *separator;
239  * } VipsForeignSaveCsv;
240  *
241  * typedef VipsForeignSaveClass VipsForeignSaveCsvClass;
242  *
243  * G_DEFINE_TYPE( VipsForeignSaveCsv, vips_foreign_save_csv,
244  *   VIPS_TYPE_FOREIGN_SAVE );
245  *
246  * static int
247  * vips_foreign_save_csv_build( VipsObject *object )
248  * {
249  *   VipsForeignSave *save = (VipsForeignSave *) object;
250  *   VipsForeignSaveCsv *csv = (VipsForeignSaveCsv *) object;
251  *
252  *   if( VIPS_OBJECT_CLASS( vips_foreign_save_csv_parent_class )->
253  *   	build( object ) )
254  *   	return( -1 );
255  *
256  *   if( vips__csv_write( save->ready, csv->filename, csv->separator ) )
257  *   	return( -1 );
258  *
259  *   return( 0 );
260  * }
261  *
262  * static void
263  * vips_foreign_save_csv_class_init( VipsForeignSaveCsvClass *class )
264  * {
265  *   GObjectClass *gobject_class = G_OBJECT_CLASS( class );
266  *   VipsObjectClass *object_class = (VipsObjectClass *) class;
267  *   VipsForeignClass *foreign_class = (VipsForeignClass *) class;
268  *   VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
269  *
270  *   gobject_class->set_property = vips_object_set_property;
271  *   gobject_class->get_property = vips_object_get_property;
272  *
273  *   object_class->nickname = "csvsave";
274  *   object_class->description = _( "save image to csv file" );
275  *   object_class->build = vips_foreign_save_csv_build;
276  *
277  *   foreign_class->suffs = vips__foreign_csv_suffs;
278  *
279  *   save_class->saveable = VIPS_SAVEABLE_MONO;
280  *   // no need to define ->format_table, we don't want the input
281  *   // cast for us
282  *
283  *   VIPS_ARG_STRING( class, "filename", 1,
284  *   	_( "Filename" ),
285  *   	_( "Filename to save to" ),
286  *   	VIPS_ARGUMENT_REQUIRED_INPUT,
287  *   	G_STRUCT_OFFSET( VipsForeignSaveCsv, filename ),
288  *   	NULL );
289  *
290  *   VIPS_ARG_STRING( class, "separator", 13,
291  *   	_( "Separator" ),
292  *   	_( "Separator characters" ),
293  *   	VIPS_ARGUMENT_OPTIONAL_INPUT,
294  *   	G_STRUCT_OFFSET( VipsForeignSaveCsv, separator ),
295  *   	"\t" );
296  * }
297  *
298  * static void
299  * vips_foreign_save_csv_init( VipsForeignSaveCsv *csv )
300  * {
301  *   csv->separator = g_strdup( "\t" );
302  * }
303  * ]|
304  */
305 
306 /* Use this to link images to the load operation that made them.
307  */
308 static GQuark vips__foreign_load_operation = 0;
309 
310 /**
311  * VipsForeignFlags:
312  * @VIPS_FOREIGN_NONE: no flags set
313  * @VIPS_FOREIGN_PARTIAL: the image may be read lazilly
314  * @VIPS_FOREIGN_BIGENDIAN: image pixels are most-significant byte first
315  * @VIPS_FOREIGN_SEQUENTIAL: top-to-bottom lazy reading
316  *
317  * Some hints about the image loader.
318  *
319  * #VIPS_FOREIGN_PARTIAL means that the image can be read directly from the
320  * file without needing to be unpacked to a temporary image first.
321  *
322  * #VIPS_FOREIGN_SEQUENTIAL means that the loader supports lazy reading, but
323  * only top-to-bottom (sequential) access. Formats like PNG can read sets of
324  * scanlines, for example, but only in order.
325  *
326  * If neither PARTIAL or SEQUENTIAL is set, the loader only supports whole
327  * image read. Setting both PARTIAL and SEQUENTIAL is an error.
328  *
329  * #VIPS_FOREIGN_BIGENDIAN means that image pixels are most-significant byte
330  * first. Depending on the native byte order of the host machine, you may
331  * need to swap bytes. See vips_copy().
332  */
333 
334 G_DEFINE_ABSTRACT_TYPE( VipsForeign, vips_foreign, VIPS_TYPE_OPERATION );
335 
336 static void
vips_foreign_summary_class(VipsObjectClass * object_class,VipsBuf * buf)337 vips_foreign_summary_class( VipsObjectClass *object_class, VipsBuf *buf )
338 {
339 	VipsForeignClass *class = VIPS_FOREIGN_CLASS( object_class );
340 
341 	VIPS_OBJECT_CLASS( vips_foreign_parent_class )->
342 		summary_class( object_class, buf );
343 
344 	if( class->suffs ) {
345 		const char **p;
346 
347 		vips_buf_appends( buf, " (" );
348 		for( p = class->suffs; *p; p++ ) {
349 			vips_buf_appendf( buf, "%s", *p );
350 			if( p[1] )
351 				vips_buf_appends( buf, ", " );
352 		}
353 		vips_buf_appends( buf, ")" );
354 	}
355 
356 	vips_buf_appendf( buf, ", priority=%d", class->priority );
357 
358 }
359 
360 static void
vips_foreign_class_init(VipsForeignClass * class)361 vips_foreign_class_init( VipsForeignClass *class )
362 {
363 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
364 	VipsObjectClass *object_class = (VipsObjectClass *) class;
365 
366 	gobject_class->set_property = vips_object_set_property;
367 	gobject_class->get_property = vips_object_get_property;
368 
369 	object_class->nickname = "foreign";
370 	object_class->description = _( "load and save image files" );
371 	object_class->summary_class = vips_foreign_summary_class;
372 }
373 
374 static void
vips_foreign_init(VipsForeign * object)375 vips_foreign_init( VipsForeign *object )
376 {
377 }
378 
379 /* To iterate over supported files we build a temp list of subclasses of
380  * VipsForeign, sort by priority, iterate, and free.
381  */
382 
383 static void *
file_add_class(VipsForeignClass * class,GSList ** files)384 file_add_class( VipsForeignClass *class, GSList **files )
385 {
386 	/* We exclude "rawload" as it has a different API.
387 	 */
388 	if( !vips_isprefix( "rawload", VIPS_OBJECT_CLASS( class )->nickname ) )
389 		/* Append so we don't reverse the list of files. Sort will
390 		 * not reorder items of equal priority.
391 		 */
392 		*files = g_slist_append( *files, class );
393 
394 	return( NULL );
395 }
396 
397 static gint
file_compare(VipsForeignClass * a,VipsForeignClass * b,void * user_data)398 file_compare( VipsForeignClass *a, VipsForeignClass *b, void *user_data )
399 {
400         return( b->priority - a->priority );
401 }
402 
403 /**
404  * vips_foreign_map:
405  * @base: base class to search below (eg. "VipsForeignLoad")
406  * @fn: (scope call): function to apply to each #VipsForeignClass
407  * @a: user data
408  * @b: user data
409  *
410  * Apply a function to every #VipsForeignClass that VIPS knows about. Foreigns
411  * are presented to the function in priority order.
412  *
413  * Like all VIPS map functions, if @fn returns %NULL, iteration continues. If
414  * it returns non-%NULL, iteration terminates and that value is returned. The
415  * map function returns %NULL if all calls return %NULL.
416  *
417  * See also: vips_slist_map().
418  *
419  * Returns: (transfer none): the result of iteration
420  */
421 void *
vips_foreign_map(const char * base,VipsSListMap2Fn fn,void * a,void * b)422 vips_foreign_map( const char *base, VipsSListMap2Fn fn, void *a, void *b )
423 {
424 	GSList *files;
425 	void *result;
426 
427 	files = NULL;
428 	(void) vips_class_map_all( g_type_from_name( base ),
429 		(VipsClassMapFn) file_add_class, (void *) &files );
430 
431 	files = g_slist_sort( files, (GCompareFunc) file_compare );
432 #ifdef DEBUG
433 {
434 	GSList *p;
435 
436 	printf( "vips_foreign_map: search order\n" );
437 	for( p = files; p; p = p->next ) {
438 		VipsForeignClass *class = (VipsForeignClass *) p->data;
439 
440 		printf( "\t%s\n", VIPS_OBJECT_CLASS( class )->nickname );
441 	}
442 }
443 #endif /*DEBUG*/
444 	result = vips_slist_map2( files, fn, a, b );
445 
446 	g_slist_free( files );
447 
448 	return( result );
449 }
450 
451 /* Abstract base class for image load.
452  */
453 
454 G_DEFINE_ABSTRACT_TYPE( VipsForeignLoad, vips_foreign_load, VIPS_TYPE_FOREIGN );
455 
456 static void
vips_foreign_load_dispose(GObject * gobject)457 vips_foreign_load_dispose( GObject *gobject )
458 {
459 	VipsForeignLoad *load = VIPS_FOREIGN_LOAD( gobject );
460 
461 	VIPS_UNREF( load->real );
462 
463 	G_OBJECT_CLASS( vips_foreign_load_parent_class )->dispose( gobject );
464 }
465 
466 static void
vips_foreign_load_summary_class(VipsObjectClass * object_class,VipsBuf * buf)467 vips_foreign_load_summary_class( VipsObjectClass *object_class, VipsBuf *buf )
468 {
469 	VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_CLASS( object_class );
470 
471 	VIPS_OBJECT_CLASS( vips_foreign_load_parent_class )->
472 		summary_class( object_class, buf );
473 
474 	if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) ) {
475 		if( class->is_a )
476 			vips_buf_appends( buf, ", is_a" );
477 		if( class->is_a_buffer )
478 			vips_buf_appends( buf, ", is_a_buffer" );
479 		if( class->is_a_source )
480 			vips_buf_appends( buf, ", is_a_source" );
481 		if( class->get_flags )
482 			vips_buf_appends( buf, ", get_flags" );
483 		if( class->get_flags_filename )
484 			vips_buf_appends( buf, ", get_flags_filename" );
485 		if( class->header )
486 			vips_buf_appends( buf, ", header" );
487 		if( class->load )
488 			vips_buf_appends( buf, ", load" );
489 
490 		/* You can omit ->load(), you must not omit ->header().
491 		 */
492 		g_assert( class->header );
493 	}
494 }
495 
496 /* Can this VipsForeign open this file?
497  */
498 static void *
vips_foreign_find_load_sub(VipsForeignLoadClass * load_class,const char * filename,void * b)499 vips_foreign_find_load_sub( VipsForeignLoadClass *load_class,
500 	const char *filename, void *b )
501 {
502 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( load_class );
503 	VipsForeignClass *class = VIPS_FOREIGN_CLASS( load_class );
504 
505 	/* Ignore the buffer and source loaders.
506 	 */
507 	if( vips_ispostfix( object_class->nickname, "_buffer" ) ||
508 		vips_ispostfix( object_class->nickname, "_source" ) )
509 		return( NULL );
510 
511 #ifdef DEBUG
512 	printf( "vips_foreign_find_load_sub: %s\n",
513 		VIPS_OBJECT_CLASS( class )->nickname );
514 #endif /*DEBUG*/
515 
516 	/* Try to sniff the filetype from the first few bytes, if we can,
517 	 * otherwise fall back to checking the filename suffix.
518 	 */
519 	if( load_class->is_a ) {
520 		if( load_class->is_a( filename ) )
521 			return( load_class );
522 
523 #ifdef DEBUG
524 		printf( "vips_foreign_find_load_sub: is_a failed\n" );
525 #endif /*DEBUG*/
526 	}
527 	else if( class->suffs ) {
528 		if( vips_filename_suffix_match( filename, class->suffs ) )
529 			return( load_class );
530 	}
531 	else
532 		g_warning( "loader %s has no is_a method and no suffix list",
533 			object_class->nickname );
534 
535 	return( NULL );
536 }
537 
538 /**
539  * vips_foreign_find_load:
540  * @filename: file to find a loader for
541  *
542  * Searches for an operation you could use to load @filename. Any trailing
543  * options on @filename are stripped and ignored.
544  *
545  * See also: vips_foreign_find_load_buffer(), vips_image_new_from_file().
546  *
547  * Returns: the name of an operation on success, %NULL on error
548  */
549 const char *
vips_foreign_find_load(const char * name)550 vips_foreign_find_load( const char *name )
551 {
552 	char filename[VIPS_PATH_MAX];
553 	char option_string[VIPS_PATH_MAX];
554 	VipsForeignLoadClass *load_class;
555 
556 	vips__filename_split8( name, filename, option_string );
557 
558 	/* Very common, so make a better error message for this case.
559 	 */
560 	if( !vips_existsf( "%s", filename ) ) {
561 		vips_error( "VipsForeignLoad",
562 			_( "file \"%s\" does not exist" ), name );
563 		return( NULL );
564 	}
565 	if( vips_isdirf( "%s", filename ) ) {
566 		vips_error( "VipsForeignLoad",
567 			_( "\"%s\" is a directory" ), name );
568 		return( NULL );
569 	}
570 
571 	if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
572 		"VipsForeignLoad",
573 		(VipsSListMap2Fn) vips_foreign_find_load_sub,
574 		(void *) filename, NULL )) ) {
575 		vips_error( "VipsForeignLoad",
576 			_( "\"%s\" is not a known file format" ), name );
577 		return( NULL );
578 	}
579 
580 #ifdef DEBUG
581 	printf( "vips_foreign_find_load: selected %s\n",
582 		VIPS_OBJECT_CLASS( load_class )->nickname );
583 #endif /*DEBUG*/
584 
585 	return( G_OBJECT_CLASS_NAME( load_class ) );
586 }
587 
588 /* Kept for compat with earlier version of the vip8 API. Use
589  * vips_image_new_from_file() now.
590  */
591 
592 int
vips_foreign_load(const char * name,VipsImage ** out,...)593 vips_foreign_load( const char *name, VipsImage **out, ... )
594 {
595 	char filename[VIPS_PATH_MAX];
596 	char option_string[VIPS_PATH_MAX];
597 	const char *operation_name;
598 	va_list ap;
599 	int result;
600 
601 	vips__filename_split8( name, filename, option_string );
602 	if( !(operation_name = vips_foreign_find_load( filename )) )
603 		return( -1 );
604 
605 	va_start( ap, out );
606 	result = vips_call_split_option_string( operation_name, option_string,
607 		ap, filename, out );
608 	va_end( ap );
609 
610 	return( result );
611 }
612 
613 /* Can this VipsForeign open this buffer?
614  */
615 static void *
vips_foreign_find_load_buffer_sub(VipsForeignLoadClass * load_class,const void ** buf,size_t * len)616 vips_foreign_find_load_buffer_sub( VipsForeignLoadClass *load_class,
617 	const void **buf, size_t *len )
618 {
619 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( load_class );
620 
621 	/* Skip non-buffer loaders.
622 	 */
623 	if( !vips_ispostfix( object_class->nickname, "_buffer" ) )
624 		return( NULL );
625 
626 	if( load_class->is_a_buffer ) {
627 		if( load_class->is_a_buffer( *buf, *len ) )
628 			return( load_class );
629 	}
630 	else
631 		g_warning( "loader %s has no is_a_buffer method",
632 			object_class->nickname );
633 
634 	return( NULL );
635 }
636 
637 /**
638  * vips_foreign_find_load_buffer:
639  * @data: (array length=size) (element-type guint8) (transfer none): start of
640  * memory buffer
641  * @size: (type gsize): number of bytes in @data
642  *
643  * Searches for an operation you could use to load a memory buffer. To see the
644  * range of buffer loaders supported by your vips, try something like:
645  *
646  * 	vips -l | grep load_buffer
647  *
648  * See also: vips_image_new_from_buffer().
649  *
650  * Returns: (transfer none): the name of an operation on success, %NULL on
651  * error.
652  */
653 const char *
vips_foreign_find_load_buffer(const void * data,size_t size)654 vips_foreign_find_load_buffer( const void *data, size_t size )
655 {
656 	VipsForeignLoadClass *load_class;
657 
658 	if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
659 		"VipsForeignLoad",
660 		(VipsSListMap2Fn) vips_foreign_find_load_buffer_sub,
661 		&data, &size )) ) {
662 		vips_error( "VipsForeignLoad",
663 			"%s", _( "buffer is not in a known format" ) );
664 		return( NULL );
665 	}
666 
667 	return( G_OBJECT_CLASS_NAME( load_class ) );
668 }
669 
670 /* Can this VipsForeign open this source?
671  */
672 static void *
vips_foreign_find_load_source_sub(void * item,void * a,void * b)673 vips_foreign_find_load_source_sub( void *item, void *a, void *b )
674 {
675 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( item );
676 	VipsForeignLoadClass *load_class = VIPS_FOREIGN_LOAD_CLASS( item );
677 	VipsSource *source = VIPS_SOURCE( a );
678 
679 	/* Skip non-source loaders.
680 	 */
681 	if( !vips_ispostfix( object_class->nickname, "_source" ) )
682 		return( NULL );
683 
684 	if( load_class->is_a_source ) {
685 		/* We may have done a _read() rather than a _sniff() in one of
686 		 * the is_a testers. Always rewind.
687 		 */
688 		(void) vips_source_rewind( source );
689 
690 		if( load_class->is_a_source( source ) )
691 			return( load_class );
692 	}
693 	else
694 		g_warning( "loader %s has no is_a_source method",
695 			object_class->nickname );
696 
697 	return( NULL );
698 }
699 
700 /**
701  * vips_foreign_find_load_source:
702  * @source: source to load from
703  *
704  * Searches for an operation you could use to load a source. To see the
705  * range of source loaders supported by your vips, try something like:
706  *
707  * 	vips -l | grep load_source
708  *
709  * See also: vips_image_new_from_source().
710  *
711  * Returns: (transfer none): the name of an operation on success, %NULL on
712  * error.
713  */
714 const char *
vips_foreign_find_load_source(VipsSource * source)715 vips_foreign_find_load_source( VipsSource *source )
716 {
717 	VipsForeignLoadClass *load_class;
718 
719 	if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
720 		"VipsForeignLoad",
721 		vips_foreign_find_load_source_sub,
722 		source, NULL )) ) {
723 		vips_error( "VipsForeignLoad",
724 			"%s", _( "source is not in a known format" ) );
725 		return( NULL );
726 	}
727 
728 	/* All source loaders should be NOCACHE.
729 	 */
730 	g_assert( VIPS_OPERATION_CLASS( load_class )->flags &
731 		VIPS_OPERATION_NOCACHE );
732 
733 	return( G_OBJECT_CLASS_NAME( load_class ) );
734 }
735 
736 /**
737  * vips_foreign_is_a:
738  * @loader: name of loader to use for test
739  * @filename: file to test
740  *
741  * Return %TRUE if @filename can be loaded by @loader. @loader is something
742  * like "tiffload" or "VipsForeignLoadTiff".
743  *
744  * Returns: %TRUE if @filename can be loaded by @loader.
745  */
746 gboolean
vips_foreign_is_a(const char * loader,const char * filename)747 vips_foreign_is_a( const char *loader, const char *filename )
748 {
749 	const VipsObjectClass *class;
750 	VipsForeignLoadClass *load_class;
751 
752 	if( !(class = vips_class_find( "VipsForeignLoad", loader )) )
753 		return( FALSE );
754 	load_class = VIPS_FOREIGN_LOAD_CLASS( class );
755 	if( load_class->is_a &&
756 		load_class->is_a( filename ) )
757 		return( TRUE );
758 
759 	return( FALSE );
760 }
761 
762 /**
763  * vips_foreign_is_a_buffer:
764  * @loader: name of loader to use for test
765  * @data: (array length=size) (element-type guint8): pointer to the buffer to test
766  * @size: (type gsize): size of the buffer to test
767  *
768  * Return %TRUE if @data can be loaded by @loader. @loader is something
769  * like "tiffload_buffer" or "VipsForeignLoadTiffBuffer".
770  *
771  * Returns: %TRUE if @data can be loaded by @loader.
772  */
773 gboolean
vips_foreign_is_a_buffer(const char * loader,const void * data,size_t size)774 vips_foreign_is_a_buffer( const char *loader, const void *data, size_t size )
775 {
776 	const VipsObjectClass *class;
777 	VipsForeignLoadClass *load_class;
778 
779 	if( !(class = vips_class_find( "VipsForeignLoad", loader )) )
780 		return( FALSE );
781 	load_class = VIPS_FOREIGN_LOAD_CLASS( class );
782 	if( load_class->is_a_buffer &&
783 		load_class->is_a_buffer( data, size ) )
784 		return( TRUE );
785 
786 	return( FALSE );
787 }
788 
789 /**
790  * vips_foreign_is_a_source:
791  * @loader: name of loader to use for test
792  * @source: source to test
793  *
794  * Return %TRUE if @source can be loaded by @loader. @loader is something
795  * like "tiffload_source" or "VipsForeignLoadTiffSource".
796  *
797  * Returns: %TRUE if @data can be loaded by @source.
798  */
799 gboolean
vips_foreign_is_a_source(const char * loader,VipsSource * source)800 vips_foreign_is_a_source( const char *loader, VipsSource *source )
801 {
802 	const VipsObjectClass *class;
803 	VipsForeignLoadClass *load_class;
804 
805 	if( !(class = vips_class_find( "VipsForeignLoad", loader )) )
806 		return( FALSE );
807 	load_class = VIPS_FOREIGN_LOAD_CLASS( class );
808 	if( load_class->is_a_source &&
809 		load_class->is_a_source( source ) )
810 		return( TRUE );
811 
812 	return( FALSE );
813 }
814 
815 /**
816  * vips_foreign_flags:
817  * @loader: name of loader to use for test
818  * @filename: file to test
819  *
820  * Return the flags for @filename using @loader.
821  * @loader is something like "tiffload" or "VipsForeignLoadTiff".
822  *
823  * Returns: the flags for @filename.
824  */
825 VipsForeignFlags
vips_foreign_flags(const char * loader,const char * filename)826 vips_foreign_flags( const char *loader, const char *filename )
827 {
828 	const VipsObjectClass *class;
829 
830 	if( (class = vips_class_find( "VipsForeignLoad", loader )) ) {
831 		VipsForeignLoadClass *load_class =
832 			VIPS_FOREIGN_LOAD_CLASS( class );
833 
834 		if( load_class->get_flags_filename )
835 			return( load_class->get_flags_filename( filename ) );
836 	}
837 
838 	return( 0 );
839 }
840 
841 static VipsObject *
vips_foreign_load_new_from_string(const char * string)842 vips_foreign_load_new_from_string( const char *string )
843 {
844 	const char *file_op;
845 	GType type;
846 	VipsForeignLoad *load;
847 
848 	if( !(file_op = vips_foreign_find_load( string )) )
849 		return( NULL );
850 	type = g_type_from_name( file_op );
851 	g_assert( type );
852 
853 	load = VIPS_FOREIGN_LOAD( g_object_new( type, NULL ) );
854 	g_object_set( load,
855 		"filename", string,
856 		NULL );
857 
858 	return( VIPS_OBJECT( load ) );
859 }
860 
861 static VipsImage *
vips_foreign_load_temp(VipsForeignLoad * load)862 vips_foreign_load_temp( VipsForeignLoad *load )
863 {
864 	const guint64 disc_threshold = vips_get_disc_threshold();
865 	const guint64 image_size = VIPS_IMAGE_SIZEOF_IMAGE( load->out );
866 
867 	/* ->memory used to be called ->disc and default TRUE. If it's been
868 	 * forced FALSE, set memory TRUE.
869 	 */
870 	if( !load->disc )
871 		load->memory = TRUE;
872 
873 	if( load->memory ) {
874 #ifdef DEBUG
875 		printf( "vips_foreign_load_temp: forced memory temp\n" );
876 #endif /*DEBUG*/
877 
878 		return( vips_image_new_memory() );
879 	}
880 
881 	/* If this is a partial operation, we can open directly.
882 	 */
883 	if( load->flags & VIPS_FOREIGN_PARTIAL ) {
884 #ifdef DEBUG
885 		printf( "vips_foreign_load_temp: partial temp\n" );
886 #endif /*DEBUG*/
887 
888 		return( vips_image_new() );
889 	}
890 
891 	/* If it can do sequential access and it's been requested, we can open
892 	 * directly.
893 	 */
894 	if( (load->flags & VIPS_FOREIGN_SEQUENTIAL) &&
895 		load->access != VIPS_ACCESS_RANDOM ) {
896 #ifdef DEBUG
897 		printf( "vips_foreign_load_temp: partial sequential temp\n" );
898 #endif /*DEBUG*/
899 
900 		return( vips_image_new() );
901 	}
902 
903 	/* We open via disc if the uncompressed image will be larger than
904 	 * vips_get_disc_threshold()
905 	 */
906 	if( image_size > disc_threshold ) {
907 #ifdef DEBUG
908 		printf( "vips_foreign_load_temp: disc temp\n" );
909 #endif /*DEBUG*/
910 
911 		return( vips_image_new_temp_file( "%s.v" ) );
912 	}
913 
914 #ifdef DEBUG
915 	printf( "vips_foreign_load_temp: fallback memory temp\n" );
916 #endif /*DEBUG*/
917 
918 	/* Otherwise, fall back to a memory buffer.
919 	 */
920 	return( vips_image_new_memory() );
921 
922 }
923 
924 /* Check two images for compatibility: their geometries need to match.
925  */
926 static gboolean
vips_foreign_load_iscompat(VipsImage * a,VipsImage * b)927 vips_foreign_load_iscompat( VipsImage *a, VipsImage *b )
928 {
929 	if( a->Xsize != b->Xsize ||
930 		a->Ysize != b->Ysize ||
931 		a->Bands != b->Bands ||
932 		a->Coding != b->Coding ||
933 		a->BandFmt != b->BandFmt ) {
934 		vips_error( "VipsForeignLoad",
935 			"%s", _( "images do not match" ) );
936 		return( FALSE );
937 	}
938 
939 	return( TRUE );
940 }
941 
942 /* Our start function ... do the lazy open, if necessary, and return a region
943  * on the new image.
944  */
945 static void *
vips_foreign_load_start(VipsImage * out,void * a,void * b)946 vips_foreign_load_start( VipsImage *out, void *a, void *b )
947 {
948 	VipsForeignLoad *load = VIPS_FOREIGN_LOAD( b );
949 	VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( load );
950 
951 	/* If this start has failed before in another thread, we can fail now.
952 	 */
953 	if( load->error )
954 		return( NULL );
955 
956 	if( !load->real ) {
957 		if( !(load->real = vips_foreign_load_temp( load )) )
958 			return( NULL );
959 
960 #ifdef DEBUG
961 		printf( "vips_foreign_load_start: triggering ->load()\n" );
962 #endif /*DEBUG*/
963 
964 		/* Read the image in. This may involve a long computation and
965 		 * will finish with load->real holding the decompressed image.
966 		 *
967 		 * We want our caller to be able to see this computation on
968 		 * @out, so eval signals on ->real need to appear on ->out.
969 		 */
970 		load->real->progress_signal = load->out;
971 
972 		/* Note the load object on the image. Loaders can use
973 		 * this to signal invalidate if they hit a load error. See
974 		 * vips_foreign_load_invalidate() below.
975 		 */
976 		g_object_set_qdata( G_OBJECT( load->real ),
977 			vips__foreign_load_operation, load );
978 
979 		/* Load the image and check the result.
980 		 *
981 		 * ->header() read the header into @out, load will read the
982 		 * image into @real. They must match exactly in size, bands,
983 		 * format and coding for the copy to work.
984 		 *
985 		 * Some versions of ImageMagick give different results between
986 		 * Ping and Load for some formats, for example.
987 		 *
988 		 * If the load fails, we need to stop
989 		 */
990 		if( class->load( load ) ||
991 			vips_image_pio_input( load->real ) ||
992 			!vips_foreign_load_iscompat( load->real, out ) ) {
993 			vips_operation_invalidate( VIPS_OPERATION( load ) );
994 			load->error = TRUE;
995 
996 			return( NULL );
997 		}
998 
999 		/* We have to tell vips that out depends on real. We've set
1000 		 * the demand hint below, but not given an input there.
1001 		 */
1002 		if( vips_image_pipelinev( load->out, load->out->dhint,
1003 			load->real, NULL ) )
1004 			return( NULL );
1005 	}
1006 
1007 	return( vips_region_new( load->real ) );
1008 }
1009 
1010 /* Just pointer-copy.
1011  */
1012 static int
vips_foreign_load_generate(VipsRegion * or,void * seq,void * a,void * b,gboolean * stop)1013 vips_foreign_load_generate( VipsRegion *or,
1014 	void *seq, void *a, void *b, gboolean *stop )
1015 {
1016 	VipsRegion *ir = (VipsRegion *) seq;
1017 
1018         VipsRect *r = &or->valid;
1019 
1020         /* Ask for input we need.
1021          */
1022         if( vips_region_prepare( ir, r ) )
1023                 return( -1 );
1024 
1025         /* Attach output region to that.
1026          */
1027         if( vips_region_region( or, ir, r, r->left, r->top ) )
1028                 return( -1 );
1029 
1030         return( 0 );
1031 }
1032 
1033 static int
vips_foreign_load_build(VipsObject * object)1034 vips_foreign_load_build( VipsObject *object )
1035 {
1036 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
1037 	VipsForeignLoad *load = VIPS_FOREIGN_LOAD( object );
1038 	VipsForeignLoadClass *fclass = VIPS_FOREIGN_LOAD_GET_CLASS( object );
1039 
1040 	VipsForeignFlags flags;
1041 	gboolean sequential;
1042 
1043 #ifdef DEBUG
1044 	printf( "vips_foreign_load_build:\n" );
1045 #endif /*DEBUG*/
1046 
1047 	flags = 0;
1048 	if( fclass->get_flags )
1049 		flags |= fclass->get_flags( load );
1050 
1051 	if( (flags & VIPS_FOREIGN_PARTIAL) &&
1052 		(flags & VIPS_FOREIGN_SEQUENTIAL) ) {
1053 		g_warning( "%s",
1054 			_( "VIPS_FOREIGN_PARTIAL and VIPS_FOREIGN_SEQUENTIAL "
1055 				"both set -- using SEQUENTIAL" ) );
1056 		flags ^= VIPS_FOREIGN_PARTIAL;
1057 	}
1058 
1059 	g_object_set( load, "flags", flags, NULL );
1060 
1061 	/* Seq access has been requested and the loader supports seq.
1062 	 */
1063 	sequential = (load->flags & VIPS_FOREIGN_SEQUENTIAL) &&
1064 		load->access != VIPS_ACCESS_RANDOM;
1065 
1066 	/* We must block caching of seq loads.
1067 	 */
1068 	if( sequential )
1069 		load->nocache = TRUE;
1070 
1071 	/* The deprecated "fail" field sets fail_on warning.
1072 	 */
1073 	if( vips_object_argument_isset( object, "fail" ) &&
1074 		!vips_object_argument_isset( object, "fail_on" ) )
1075 		load->fail_on = load->fail ?
1076 			VIPS_FAIL_ON_WARNING : VIPS_FAIL_ON_NONE;
1077 
1078 	if( VIPS_OBJECT_CLASS( vips_foreign_load_parent_class )->
1079 		build( object ) )
1080 		return( -1 );
1081 
1082 	if( load->sequential )
1083 		g_warning( "%s",
1084 			_( "ignoring deprecated \"sequential\" mode -- "
1085 				"please use \"access\" instead" ) );
1086 
1087 	g_object_set( object, "out", vips_image_new(), NULL );
1088 
1089 	vips_image_set_string( load->out,
1090 		VIPS_META_LOADER, class->nickname );
1091 
1092 #ifdef DEBUG
1093 	printf( "vips_foreign_load_build: triggering ->header()\n" );
1094 #endif /*DEBUG*/
1095 
1096 	/* Read the header into @out.
1097 	 */
1098 	if( fclass->header &&
1099 		fclass->header( load ) )
1100 		return( -1 );
1101 
1102 	/* If there's no ->load() method then the header read has done
1103 	 * everything. Otherwise, it's just set fields and we must also
1104 	 * load pixels.
1105 	 *
1106 	 * Delay the load until the first pixel is requested by doing the work
1107 	 * in the start function of the copy.
1108 	 */
1109 	if( fclass->load ) {
1110 #ifdef DEBUG
1111 		printf( "vips_foreign_load_build: delaying read ...\n" );
1112 #endif /*DEBUG*/
1113 
1114 		/* ->header() should set the dhint. It'll default to the safe
1115 		 * SMALLTILE if header() did not set it.
1116 		 */
1117 		if( vips_image_pipelinev( load->out, load->out->dhint, NULL ) )
1118 			return( -1 );
1119 
1120 		/* Then 'start' creates the real image and 'gen' fetches
1121 		 * pixels for @out from @real on demand.
1122 		 */
1123 		if( vips_image_generate( load->out,
1124 			vips_foreign_load_start,
1125 			vips_foreign_load_generate,
1126 			vips_stop_one,
1127 			NULL, load ) )
1128 			return( -1 );
1129 	}
1130 
1131 	/* Tell downstream if we are reading sequentially.
1132 	 */
1133 	if( sequential )
1134 		vips_image_set_area( load->out,
1135 			VIPS_META_SEQUENTIAL, NULL, NULL );
1136 
1137 	return( 0 );
1138 }
1139 
1140 static VipsOperationFlags
vips_foreign_load_operation_get_flags(VipsOperation * operation)1141 vips_foreign_load_operation_get_flags( VipsOperation *operation )
1142 {
1143 	VipsForeignLoad *load = VIPS_FOREIGN_LOAD( operation );
1144 
1145 	VipsOperationFlags flags;
1146 
1147 	flags = VIPS_OPERATION_CLASS( vips_foreign_load_parent_class )->
1148 		get_flags( operation );
1149 	if( load->nocache )
1150 		flags |= VIPS_OPERATION_NOCACHE;
1151 
1152 	return( flags );
1153 }
1154 
1155 static void
vips_foreign_load_class_init(VipsForeignLoadClass * class)1156 vips_foreign_load_class_init( VipsForeignLoadClass *class )
1157 {
1158 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
1159 	VipsObjectClass *object_class = (VipsObjectClass *) class;
1160 	VipsOperationClass *operation_class = (VipsOperationClass *) class;
1161 
1162 	gobject_class->dispose = vips_foreign_load_dispose;
1163 	gobject_class->set_property = vips_object_set_property;
1164 	gobject_class->get_property = vips_object_get_property;
1165 
1166 	object_class->build = vips_foreign_load_build;
1167 	object_class->summary_class = vips_foreign_load_summary_class;
1168 	object_class->new_from_string = vips_foreign_load_new_from_string;
1169 	object_class->nickname = "fileload";
1170 	object_class->description = _( "file loaders" );
1171 
1172 	operation_class->get_flags = vips_foreign_load_operation_get_flags;
1173 
1174 	VIPS_ARG_IMAGE( class, "out", 2,
1175 		_( "Output" ),
1176 		_( "Output image" ),
1177 		VIPS_ARGUMENT_REQUIRED_OUTPUT,
1178 		G_STRUCT_OFFSET( VipsForeignLoad, out ) );
1179 
1180 	VIPS_ARG_FLAGS( class, "flags", 106,
1181 		_( "Flags" ),
1182 		_( "Flags for this file" ),
1183 		VIPS_ARGUMENT_OPTIONAL_OUTPUT,
1184 		G_STRUCT_OFFSET( VipsForeignLoad, flags ),
1185 		VIPS_TYPE_FOREIGN_FLAGS, VIPS_FOREIGN_NONE );
1186 
1187 	VIPS_ARG_BOOL( class, "memory", 107,
1188 		_( "Memory" ),
1189 		_( "Force open via memory" ),
1190 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1191 		G_STRUCT_OFFSET( VipsForeignLoad, memory ),
1192 		FALSE );
1193 
1194 	VIPS_ARG_ENUM( class, "access", 108,
1195 		_( "Access" ),
1196 		_( "Required access pattern for this file" ),
1197 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1198 		G_STRUCT_OFFSET( VipsForeignLoad, access ),
1199 		VIPS_TYPE_ACCESS, VIPS_ACCESS_RANDOM );
1200 
1201 	VIPS_ARG_ENUM( class, "fail-on", 109,
1202 		_( "Fail on" ),
1203 		_( "Error level to fail on" ),
1204 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1205 		G_STRUCT_OFFSET( VipsForeignLoad, fail_on ),
1206 		VIPS_TYPE_FAIL_ON, VIPS_FAIL_ON_NONE );
1207 
1208 	VIPS_ARG_BOOL( class, "sequential", 110,
1209 		_( "Sequential" ),
1210 		_( "Sequential read only" ),
1211 		VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
1212 		G_STRUCT_OFFSET( VipsForeignLoad, sequential ),
1213 		FALSE );
1214 
1215 	VIPS_ARG_BOOL( class, "fail", 111,
1216 		_( "Fail" ),
1217 		_( "Fail on first warning" ),
1218 		VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
1219 		G_STRUCT_OFFSET( VipsForeignLoad, fail ),
1220 		FALSE );
1221 
1222 	VIPS_ARG_BOOL( class, "disc", 112,
1223 		_( "Disc" ),
1224 		_( "Open to disc" ),
1225 		VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED,
1226 		G_STRUCT_OFFSET( VipsForeignLoad, disc ),
1227 		TRUE );
1228 
1229 }
1230 
1231 static void
vips_foreign_load_init(VipsForeignLoad * load)1232 vips_foreign_load_init( VipsForeignLoad *load )
1233 {
1234 	load->disc = TRUE;
1235 	load->access = VIPS_ACCESS_RANDOM;
1236 	load->fail_on = VIPS_FAIL_ON_NONE;
1237 }
1238 
1239 /*
1240  * Loaders can call this
1241  */
1242 
1243 /**
1244  * vips_foreign_load_invalidate: (method)
1245  * @image: image to invalidate
1246  *
1247  * Loaders can call this on the image they are making if they see a read error
1248  * from the load library. It signals "invalidate" on the load operation and
1249  * will cause it to be dropped from cache.
1250  *
1251  * If we know a file will cause a read error, we don't want to cache the
1252  * failing operation, we want to make sure the image will really be opened
1253  * again if our caller tries again. For example, a broken file might be
1254  * replaced by a working one.
1255  */
1256 void
vips_foreign_load_invalidate(VipsImage * image)1257 vips_foreign_load_invalidate( VipsImage *image )
1258 {
1259 	VipsOperation *operation;
1260 
1261 #ifdef DEBUG
1262 	printf( "vips_foreign_load_invalidate: %p\n", image );
1263 #endif /*DEBUG*/
1264 
1265 	if( (operation = g_object_get_qdata( G_OBJECT( image ),
1266 		vips__foreign_load_operation )) ) {
1267 		vips_operation_invalidate( operation );
1268 	}
1269 }
1270 
1271 /* Abstract base class for image savers.
1272  */
1273 
1274 G_DEFINE_ABSTRACT_TYPE( VipsForeignSave, vips_foreign_save, VIPS_TYPE_FOREIGN );
1275 
1276 static void
vips_foreign_save_dispose(GObject * gobject)1277 vips_foreign_save_dispose( GObject *gobject )
1278 {
1279 	VipsForeignSave *save = VIPS_FOREIGN_SAVE( gobject );
1280 
1281 	VIPS_UNREF( save->ready );
1282 
1283 	G_OBJECT_CLASS( vips_foreign_save_parent_class )->dispose( gobject );
1284 }
1285 
1286 static void
vips_foreign_save_summary_class(VipsObjectClass * object_class,VipsBuf * buf)1287 vips_foreign_save_summary_class( VipsObjectClass *object_class, VipsBuf *buf )
1288 {
1289 	VipsForeignSaveClass *class = VIPS_FOREIGN_SAVE_CLASS( object_class );
1290 
1291 	VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )->
1292 		summary_class( object_class, buf );
1293 
1294 	vips_buf_appendf( buf, ", %s",
1295 		vips_enum_nick( VIPS_TYPE_SAVEABLE, class->saveable ) );
1296 }
1297 
1298 static VipsObject *
vips_foreign_save_new_from_string(const char * string)1299 vips_foreign_save_new_from_string( const char *string )
1300 {
1301 	const char *file_op;
1302 	GType type;
1303 	VipsForeignSave *save;
1304 
1305 	if( !(file_op = vips_foreign_find_save( string )) )
1306 		return( NULL );
1307 	type = g_type_from_name( file_op );
1308 	g_assert( type );
1309 
1310 	save = VIPS_FOREIGN_SAVE( g_object_new( type, NULL ) );
1311 	g_object_set( save,
1312 		"filename", string,
1313 		NULL );
1314 
1315 	return( VIPS_OBJECT( save ) );
1316 }
1317 
1318 /* Convert an image for saving.
1319  */
1320 int
vips__foreign_convert_saveable(VipsImage * in,VipsImage ** ready,VipsSaveable saveable,VipsBandFormat * format,VipsCoding * coding,VipsArrayDouble * background)1321 vips__foreign_convert_saveable( VipsImage *in, VipsImage **ready,
1322 	VipsSaveable saveable, VipsBandFormat *format, VipsCoding *coding,
1323 	VipsArrayDouble *background )
1324 {
1325 	/* in holds a reference to the output of our chain as we build it.
1326 	 */
1327 	g_object_ref( in );
1328 
1329 	/* For coded images, can this class save the coding we are in now?
1330 	 * Nothing to do.
1331 	 */
1332 	if( in->Coding != VIPS_CODING_NONE &&
1333 		coding[in->Coding] ) {
1334 		*ready = in;
1335 		return( 0 );
1336 	}
1337 
1338 	/* For uncoded images, if this saver supports ANY bands and this
1339 	 * format we have nothing to do.
1340 	 */
1341 	if( in->Coding == VIPS_CODING_NONE &&
1342 	        saveable == VIPS_SAVEABLE_ANY &&
1343 		format[in->BandFmt] == in->BandFmt ) {
1344 		*ready = in;
1345 		return( 0 );
1346 	}
1347 
1348 	/* Otherwise ... we need to decode and then (possibly) recode at the
1349 	 * end.
1350 	 */
1351 
1352 	/* If this is an VIPS_CODING_LABQ, we can go straight to RGB.
1353 	 */
1354 	if( in->Coding == VIPS_CODING_LABQ ) {
1355 		VipsImage *out;
1356 
1357 		if( vips_LabQ2sRGB( in, &out, NULL ) ) {
1358 			g_object_unref( in );
1359 			return( -1 );
1360 		}
1361 		g_object_unref( in );
1362 
1363 		in = out;
1364 	}
1365 
1366 	/* If this is an VIPS_CODING_RAD, we unpack to float. This could be
1367 	 * scRGB or XYZ.
1368 	 */
1369 	if( in->Coding == VIPS_CODING_RAD ) {
1370 		VipsImage *out;
1371 
1372 		if( vips_rad2float( in, &out, NULL ) ) {
1373 			g_object_unref( in );
1374 			return( -1 );
1375 		}
1376 		g_object_unref( in );
1377 
1378 		in = out;
1379 	}
1380 
1381 	/* If the saver supports RAD, we need to go to scRGB or XYZ.
1382 	 */
1383 	if( coding[VIPS_CODING_RAD] ) {
1384 		if( in->Type != VIPS_INTERPRETATION_scRGB &&
1385 			in->Type != VIPS_INTERPRETATION_XYZ ) {
1386 			VipsImage *out;
1387 
1388 			if( vips_colourspace( in, &out,
1389 				VIPS_INTERPRETATION_scRGB, NULL ) ) {
1390 				g_object_unref( in );
1391 				return( -1 );
1392 			}
1393 			g_object_unref( in );
1394 
1395 			in = out;
1396 		}
1397 	}
1398 
1399 	/* If this image is CMYK and the saver is RGB-only, use lcms to try to
1400 	 * import to XYZ.
1401 	 */
1402 	if( in->Type == VIPS_INTERPRETATION_CMYK &&
1403 		in->Bands >= 4 &&
1404 		(saveable == VIPS_SAVEABLE_RGB ||
1405 		 saveable == VIPS_SAVEABLE_RGBA ||
1406 		 saveable == VIPS_SAVEABLE_RGBA_ONLY) ) {
1407 		VipsImage *out;
1408 
1409 		if( vips_icc_import( in, &out,
1410 			"pcs", VIPS_PCS_XYZ,
1411 			"embedded", TRUE,
1412 			"input_profile", "cmyk",
1413 			NULL ) ) {
1414 			g_object_unref( in );
1415 			return( -1 );
1416 		}
1417 		g_object_unref( in );
1418 
1419 		in = out;
1420 	}
1421 
1422 	/* If this is something other than CMYK or RAD, and it's not already
1423 	 * an RGB image, eg. maybe a LAB image, we need to transform
1424 	 * to RGB.
1425 	 */
1426 	if( !coding[VIPS_CODING_RAD] &&
1427 		in->Bands >= 3 &&
1428 		in->Type != VIPS_INTERPRETATION_CMYK &&
1429 		in->Type != VIPS_INTERPRETATION_sRGB &&
1430 		in->Type != VIPS_INTERPRETATION_RGB16 &&
1431 		in->Type != VIPS_INTERPRETATION_scRGB &&
1432 		vips_colourspace_issupported( in ) &&
1433 		(saveable == VIPS_SAVEABLE_RGB ||
1434 		 saveable == VIPS_SAVEABLE_RGBA ||
1435 		 saveable == VIPS_SAVEABLE_RGBA_ONLY ||
1436 		 saveable == VIPS_SAVEABLE_RGB_CMYK) ) {
1437 		VipsImage *out;
1438 		VipsInterpretation interpretation;
1439 
1440 		/* Do we make RGB or RGB16? We don't want to squash a 16-bit
1441 		 * RGB down to 8 bits if the saver supports 16.
1442 		 */
1443 		if( vips_band_format_is8bit( format[in->BandFmt] ) )
1444 			interpretation = VIPS_INTERPRETATION_sRGB;
1445 		else
1446 			interpretation = VIPS_INTERPRETATION_RGB16;
1447 
1448 		if( vips_colourspace( in, &out, interpretation, NULL ) ) {
1449 			g_object_unref( in );
1450 			return( -1 );
1451 		}
1452 		g_object_unref( in );
1453 
1454 		in = out;
1455 	}
1456 
1457 	/* VIPS_SAVEABLE_RGBA_ONLY does not support mono types ... convert
1458 	 * to sRGB.
1459 	 */
1460 	if( !coding[VIPS_CODING_RAD] &&
1461 		in->Bands < 3 &&
1462 		vips_colourspace_issupported( in ) &&
1463 		saveable == VIPS_SAVEABLE_RGBA_ONLY ) {
1464 		VipsImage *out;
1465 		VipsInterpretation interpretation;
1466 
1467 		/* Do we make RGB or RGB16? We don't want to squash a 16-bit
1468 		 * RGB down to 8 bits if the saver supports 16.
1469 		 */
1470 		if( vips_band_format_is8bit( format[in->BandFmt] ) )
1471 			interpretation = VIPS_INTERPRETATION_sRGB;
1472 		else
1473 			interpretation = VIPS_INTERPRETATION_RGB16;
1474 
1475 		if( vips_colourspace( in, &out, interpretation, NULL ) ) {
1476 			g_object_unref( in );
1477 			return( -1 );
1478 		}
1479 		g_object_unref( in );
1480 
1481 		in = out;
1482 	}
1483 
1484 	/* Get the bands right. We must do this after all colourspace
1485 	 * transforms, since they can change the number of bands.
1486 	 */
1487 	if( in->Coding == VIPS_CODING_NONE ) {
1488 		/* Do we need to flatten out an alpha channel? There needs to
1489 		 * be an alpha there now, and this writer needs to not support
1490 		 * alpha.
1491 		 */
1492 		if( (in->Bands == 2 ||
1493 			(in->Bands == 4 &&
1494 			 in->Type != VIPS_INTERPRETATION_CMYK)) &&
1495 			(saveable == VIPS_SAVEABLE_MONO ||
1496 			 saveable == VIPS_SAVEABLE_RGB ||
1497 			 saveable == VIPS_SAVEABLE_RGB_CMYK) ) {
1498 			VipsImage *out;
1499 
1500 			if( vips_flatten( in, &out,
1501 				"background", background,
1502 				NULL ) ) {
1503 				g_object_unref( in );
1504 				return( -1 );
1505 			}
1506 			g_object_unref( in );
1507 
1508 			in = out;
1509 		}
1510 
1511 		/* Other alpha removal strategies ... just drop the extra
1512 		 * bands.
1513 		 */
1514 
1515 		else if( in->Bands > 3 &&
1516 			(saveable == VIPS_SAVEABLE_RGB ||
1517 			 (saveable == VIPS_SAVEABLE_RGB_CMYK &&
1518 			  in->Type != VIPS_INTERPRETATION_CMYK)) ) {
1519 			VipsImage *out;
1520 
1521 			/* Don't let 4 bands though unless the image really is
1522 			 * a CMYK.
1523 			 *
1524 			 * Consider a RGBA png being saved as JPG. We can
1525 			 * write CMYK jpg, but we mustn't do that for RGBA
1526 			 * images.
1527 			 */
1528 			if( vips_extract_band( in, &out, 0,
1529 				"n", 3,
1530 				NULL ) ) {
1531 				g_object_unref( in );
1532 				return( -1 );
1533 			}
1534 			g_object_unref( in );
1535 
1536 			in = out;
1537 		}
1538 		else if( in->Bands > 4 &&
1539 			((saveable == VIPS_SAVEABLE_RGB_CMYK &&
1540 			  in->Type == VIPS_INTERPRETATION_CMYK) ||
1541 			 saveable == VIPS_SAVEABLE_RGBA ||
1542 			 saveable == VIPS_SAVEABLE_RGBA_ONLY) ) {
1543 			VipsImage *out;
1544 
1545 			if( vips_extract_band( in, &out, 0,
1546 				"n", 4,
1547 				NULL ) ) {
1548 				g_object_unref( in );
1549 				return( -1 );
1550 			}
1551 			g_object_unref( in );
1552 
1553 			in = out;
1554 		}
1555 		else if( in->Bands > 1 &&
1556 			saveable == VIPS_SAVEABLE_MONO ) {
1557 			VipsImage *out;
1558 
1559 			if( vips_extract_band( in, &out, 0, NULL ) ) {
1560 				g_object_unref( in );
1561 				return( -1 );
1562 			}
1563 			g_object_unref( in );
1564 
1565 			in = out;
1566 		}
1567 
1568 		/* Else we have VIPS_SAVEABLE_ANY and we don't chop bands down.
1569 		 */
1570 	}
1571 
1572 	/* Handle the ushort interpretations.
1573 	 *
1574 	 * RGB16 and GREY16 use 0-65535 for black-white. If we have an image
1575 	 * tagged like this, and it has more than 8 bits (we leave crazy uchar
1576 	 * images tagged as RGB16 alone), we'll need to get it ready for the
1577 	 * saver.
1578 	 */
1579 	if( (in->Type == VIPS_INTERPRETATION_RGB16 ||
1580 		 in->Type == VIPS_INTERPRETATION_GREY16) &&
1581 		!vips_band_format_is8bit( in->BandFmt ) ) {
1582 		/* If the saver supports ushort, cast to ushort. It may be
1583 		 * float at the moment, for example.
1584 		 *
1585 		 * If the saver does not support ushort, automatically shift
1586 		 * it down. This is the behaviour we want for saving an RGB16
1587 		 * image as JPG, for example.
1588 		 */
1589 		if( format[VIPS_FORMAT_USHORT] == VIPS_FORMAT_USHORT ) {
1590 			VipsImage *out;
1591 
1592 			if( vips_cast( in, &out, VIPS_FORMAT_USHORT, NULL ) ) {
1593 				g_object_unref( in );
1594 				return( -1 );
1595 			}
1596 			g_object_unref( in );
1597 
1598 			in = out;
1599 		}
1600 		else {
1601 			VipsImage *out;
1602 
1603 			if( vips_rshift_const1( in, &out, 8, NULL ) ) {
1604 				g_object_unref( in );
1605 				return( -1 );
1606 			}
1607 			g_object_unref( in );
1608 
1609 			in = out;
1610 
1611 			/* That could have produced an int image ... make sure
1612 			 * we are now uchar.
1613 			 */
1614 			if( vips_cast( in, &out, VIPS_FORMAT_UCHAR, NULL ) ) {
1615 				g_object_unref( in );
1616 				return( -1 );
1617 			}
1618 			g_object_unref( in );
1619 
1620 			in = out;
1621 		}
1622 	}
1623 
1624 	/* Cast to the output format.
1625 	 */
1626 	{
1627 		VipsImage *out;
1628 
1629 		if( vips_cast( in, &out, format[in->BandFmt], NULL ) ) {
1630 			g_object_unref( in );
1631 			return( -1 );
1632 		}
1633 		g_object_unref( in );
1634 
1635 		in = out;
1636 	}
1637 
1638 	/* Does this class want a coded image? Search the coding table for the
1639 	 * first one.
1640 	 */
1641 	if( coding[VIPS_CODING_NONE] ) {
1642 		/* Already NONE, nothing to do.
1643 		 */
1644 	}
1645 	else if( coding[VIPS_CODING_LABQ] ) {
1646 		VipsImage *out;
1647 
1648 		if( vips_Lab2LabQ( in, &out, NULL ) ) {
1649 			g_object_unref( in );
1650 			return( -1 );
1651 		}
1652 		g_object_unref( in );
1653 
1654 		in = out;
1655 	}
1656 	else if( coding[VIPS_CODING_RAD] ) {
1657 		VipsImage *out;
1658 
1659 		if( vips_float2rad( in, &out, NULL ) ) {
1660 			g_object_unref( in );
1661 			return( -1 );
1662 		}
1663 		g_object_unref( in );
1664 
1665 		in = out;
1666 	}
1667 
1668 	/* Some format libraries, like libpng, will throw a hard error if the
1669 	 * profile is inappropriate for this image type. With profiles inherited
1670 	 * from a source image, this can happen all the time, so we
1671 	 * want to silently drop the profile in this case.
1672 	 */
1673 	if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
1674 		const void *data;
1675 		size_t length;
1676 
1677 		if( !vips_image_get_blob( in, VIPS_META_ICC_NAME,
1678 			&data, &length ) &&
1679 			!vips_icc_is_compatible_profile( in, data, length ) ) {
1680 			VipsImage *out;
1681 
1682 			if( vips_copy( in, &out, NULL ) ) {
1683 				g_object_unref( in );
1684 				return( -1 );
1685 			}
1686 			g_object_unref( in );
1687 
1688 			in = out;
1689 
1690 			vips_image_remove( in, VIPS_META_ICC_NAME );
1691 		}
1692 	}
1693 
1694 	*ready = in;
1695 
1696 	return( 0 );
1697 }
1698 
1699 static int
vips_foreign_save_build(VipsObject * object)1700 vips_foreign_save_build( VipsObject *object )
1701 {
1702 	VipsForeignSave *save = VIPS_FOREIGN_SAVE( object );
1703 
1704 	if( save->in ) {
1705 		VipsForeignSaveClass *class =
1706 			VIPS_FOREIGN_SAVE_GET_CLASS( save );
1707 		VipsImage *ready;
1708 
1709 		if( vips__foreign_convert_saveable( save->in, &ready,
1710 			class->saveable, class->format_table, class->coding,
1711 			save->background ) )
1712 			return( -1 );
1713 
1714 		if( save->page_height ) {
1715 			VipsImage *x;
1716 
1717 			if( vips_copy( ready, &x, NULL ) ) {
1718 				VIPS_UNREF( ready );
1719 				return( -1 );
1720 			}
1721 			VIPS_UNREF( ready );
1722 			ready = x;
1723 
1724 			vips_image_set_int( ready,
1725 				VIPS_META_PAGE_HEIGHT, save->page_height );
1726 		}
1727 
1728 		VIPS_UNREF( save->ready );
1729 		save->ready = ready;
1730 	}
1731 
1732 	if( VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )->
1733 		build( object ) )
1734 		return( -1 );
1735 
1736 	return( 0 );
1737 }
1738 
1739 #define UC VIPS_FORMAT_UCHAR
1740 #define C VIPS_FORMAT_CHAR
1741 #define US VIPS_FORMAT_USHORT
1742 #define S VIPS_FORMAT_SHORT
1743 #define UI VIPS_FORMAT_UINT
1744 #define I VIPS_FORMAT_INT
1745 #define F VIPS_FORMAT_FLOAT
1746 #define X VIPS_FORMAT_COMPLEX
1747 #define D VIPS_FORMAT_DOUBLE
1748 #define DX VIPS_FORMAT_DPCOMPLEX
1749 
1750 static int vips_foreign_save_format_table[10] = {
1751 // UC  C   US  S   UI  I  F  X  D  DX
1752    UC, C,  US, S,  UI, I, F, X, D, DX
1753 };
1754 
1755 static void
vips_foreign_save_class_init(VipsForeignSaveClass * class)1756 vips_foreign_save_class_init( VipsForeignSaveClass *class )
1757 {
1758 	GObjectClass *gobject_class = G_OBJECT_CLASS( class );
1759 	VipsObjectClass *object_class = (VipsObjectClass *) class;
1760 	VipsOperationClass *operation_class = (VipsOperationClass *) class;
1761 
1762 	int i;
1763 
1764 	gobject_class->dispose = vips_foreign_save_dispose;
1765 	gobject_class->set_property = vips_object_set_property;
1766 	gobject_class->get_property = vips_object_get_property;
1767 
1768 	object_class->build = vips_foreign_save_build;
1769 	object_class->summary_class = vips_foreign_save_summary_class;
1770 	object_class->new_from_string = vips_foreign_save_new_from_string;
1771 	object_class->nickname = "filesave";
1772 	object_class->description = _( "file savers" );
1773 
1774 	/* All savers are sequential by definition. Things like tiled tiff
1775 	 * write and interlaced png write, which are not, add extra caches
1776 	 * on their input.
1777 	 */
1778 	operation_class->flags |= VIPS_OPERATION_SEQUENTIAL;
1779 
1780 	/* Must not cache savers.
1781 	 */
1782 	operation_class->flags |= VIPS_OPERATION_NOCACHE;
1783 
1784 	/* Default to no coding allowed.
1785 	 */
1786 	for( i = 0; i < VIPS_CODING_LAST; i++ )
1787 		class->coding[i] = FALSE;
1788 	class->coding[VIPS_CODING_NONE] = TRUE;
1789 
1790 	/* Default to no cast on save.
1791 	 */
1792 	class->format_table = vips_foreign_save_format_table;
1793 
1794 	VIPS_ARG_IMAGE( class, "in", 0,
1795 		_( "Input" ),
1796 		_( "Image to save" ),
1797 		VIPS_ARGUMENT_REQUIRED_INPUT,
1798 		G_STRUCT_OFFSET( VipsForeignSave, in ) );
1799 
1800 	VIPS_ARG_BOOL( class, "strip", 100,
1801 		_( "Strip" ),
1802 		_( "Strip all metadata from image" ),
1803 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1804 		G_STRUCT_OFFSET( VipsForeignSave, strip ),
1805 		FALSE );
1806 
1807 	VIPS_ARG_BOXED( class, "background", 101,
1808 		_( "Background" ),
1809 		_( "Background value" ),
1810 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1811 		G_STRUCT_OFFSET( VipsForeignSave, background ),
1812 		VIPS_TYPE_ARRAY_DOUBLE );
1813 
1814 	VIPS_ARG_INT( class, "page_height", 102,
1815 		_( "Page height" ),
1816 		_( "Set page height for multipage save" ),
1817 		VIPS_ARGUMENT_OPTIONAL_INPUT,
1818 		G_STRUCT_OFFSET( VipsForeignSave, page_height ),
1819 		0, VIPS_MAX_COORD, 0 );
1820 
1821 }
1822 
1823 static void
vips_foreign_save_init(VipsForeignSave * save)1824 vips_foreign_save_init( VipsForeignSave *save )
1825 {
1826 	save->background = vips_array_double_newv( 1, 0.0 );
1827 }
1828 
1829 /* Can we write this filename with this class?
1830  */
1831 static void *
vips_foreign_find_save_sub(VipsForeignSaveClass * save_class,const char * filename,void * b)1832 vips_foreign_find_save_sub( VipsForeignSaveClass *save_class,
1833 	const char *filename, void *b )
1834 {
1835 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class );
1836 	VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
1837 
1838 	const char **p;
1839 
1840 	/* All savers needs suffs defined since we use the suff to pick the
1841 	 * saver.
1842 	 */
1843 	if( !class->suffs )
1844 		g_warning( "no suffix defined for %s", object_class->nickname );
1845 
1846 	/* Skip non-file savers.
1847 	 */
1848 	if( vips_ispostfix( object_class->nickname, "_buffer" ) ||
1849 		vips_ispostfix( object_class->nickname, "_target" ) )
1850 		return( NULL );
1851 
1852 	/* vips_foreign_find_save() has already removed any options from the
1853 	 * end of the filename, so we can test directly against the suffix.
1854 	 */
1855 	for( p = class->suffs; *p; p++ )
1856 		if( vips_iscasepostfix( filename, *p ) )
1857 			return( save_class );
1858 
1859 	return( NULL );
1860 }
1861 
1862 /**
1863  * vips_foreign_find_save:
1864  * @filename: name to find a saver for
1865  *
1866  * Searches for an operation you could use to write to @filename.
1867  * Any trailing options on @filename are stripped and ignored.
1868  *
1869  * See also: vips_foreign_find_save_buffer(), vips_image_write_to_file().
1870  *
1871  * Returns: the name of an operation on success, %NULL on error
1872  */
1873 const char *
vips_foreign_find_save(const char * name)1874 vips_foreign_find_save( const char *name )
1875 {
1876 	char filename[VIPS_PATH_MAX];
1877 	char option_string[VIPS_PATH_MAX];
1878 	VipsForeignSaveClass *save_class;
1879 
1880 	vips__filename_split8( name, filename, option_string );
1881 
1882 	if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
1883 		"VipsForeignSave",
1884 		(VipsSListMap2Fn) vips_foreign_find_save_sub,
1885 		(void *) filename, NULL )) ) {
1886 		vips_error( "VipsForeignSave",
1887 			_( "\"%s\" is not a known file format" ), name );
1888 
1889 		return( NULL );
1890 	}
1891 
1892 	return( G_OBJECT_CLASS_NAME( save_class ) );
1893 }
1894 
1895 static void *
vips_foreign_get_suffixes_count_cb(VipsForeignSaveClass * save_class,void * a,void * b)1896 vips_foreign_get_suffixes_count_cb( VipsForeignSaveClass *save_class,
1897 	void *a, void *b )
1898 {
1899 	VipsForeignClass *foreign_class = VIPS_FOREIGN_CLASS( save_class );
1900 	int *n_fields = (int *) a;
1901 
1902 	int i;
1903 
1904 	if( foreign_class->suffs )
1905 		for( i = 0; foreign_class->suffs[i]; i++ )
1906 			*n_fields += 1;
1907 
1908 	return( NULL );
1909 }
1910 
1911 static void *
vips_foreign_get_suffixes_add_cb(VipsForeignSaveClass * save_class,void * a,void * b)1912 vips_foreign_get_suffixes_add_cb( VipsForeignSaveClass *save_class,
1913 	void *a, void *b )
1914 {
1915 	VipsForeignClass *foreign_class = VIPS_FOREIGN_CLASS( save_class );
1916 	gchar ***p = (gchar ***) a;
1917 
1918 	int i;
1919 
1920 	if( foreign_class->suffs )
1921 		for( i = 0; foreign_class->suffs[i]; i++ ) {
1922 			**p = g_strdup( foreign_class->suffs[i] );
1923 			*p += 1;
1924 		}
1925 
1926 	return( NULL );
1927 }
1928 
1929 /**
1930  * vips_foreign_get_suffixes: (method)
1931  *
1932  * Get a %NULL-terminated array listing all the supported suffixes.
1933  *
1934  * This is not the same as all the supported file types, since libvips
1935  * detects image format for load by testing the first few bytes.
1936  *
1937  * Use vips_foreign_find_load() to detect type for a specific file.
1938  *
1939  * Free the return result with g_strfreev().
1940  *
1941  * Returns: (transfer full): all supported file extensions, as a
1942  * %NULL-terminated array.
1943  */
1944 gchar **
vips_foreign_get_suffixes(void)1945 vips_foreign_get_suffixes( void )
1946 {
1947 	int n_suffs;
1948 	gchar **suffs;
1949 	gchar **p;
1950 
1951 	n_suffs = 0;
1952 	(void) vips_foreign_map(
1953 		"VipsForeignSave",
1954 		(VipsSListMap2Fn) vips_foreign_get_suffixes_count_cb,
1955 		&n_suffs, NULL );
1956 
1957 	suffs = g_new0( gchar *, n_suffs + 1 );
1958 	p = suffs;
1959 	(void) vips_foreign_map(
1960 		"VipsForeignSave",
1961 		(VipsSListMap2Fn) vips_foreign_get_suffixes_add_cb,
1962 		&p, NULL );
1963 
1964 	return( suffs );
1965 }
1966 
1967 /* Kept for early vips8 API compat.
1968  */
1969 
1970 int
vips_foreign_save(VipsImage * in,const char * name,...)1971 vips_foreign_save( VipsImage *in, const char *name, ... )
1972 {
1973 	char filename[VIPS_PATH_MAX];
1974 	char option_string[VIPS_PATH_MAX];
1975 	const char *operation_name;
1976 	va_list ap;
1977 	int result;
1978 
1979 	vips__filename_split8( name, filename, option_string );
1980 
1981 	if( !(operation_name = vips_foreign_find_save( filename )) )
1982 		return( -1 );
1983 
1984 	va_start( ap, name );
1985 	result = vips_call_split_option_string( operation_name, option_string,
1986 		ap, in, filename );
1987 	va_end( ap );
1988 
1989 	return( result );
1990 }
1991 
1992 /* Can this class write this filetype to a target?
1993  */
1994 static void *
vips_foreign_find_save_target_sub(VipsForeignSaveClass * save_class,const char * suffix,void * b)1995 vips_foreign_find_save_target_sub( VipsForeignSaveClass *save_class,
1996 	const char *suffix, void *b )
1997 {
1998 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class );
1999 	VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
2000 
2001 	/* All concrete savers needs suffs, since we use the suff to pick the
2002 	 * saver.
2003 	 */
2004 	if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) &&
2005 		!class->suffs )
2006 		g_warning( "no suffix defined for %s", object_class->nickname );
2007 
2008 	if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) &&
2009 		class->suffs &&
2010 		vips_ispostfix( object_class->nickname, "_target" ) &&
2011 		vips_filename_suffix_match( suffix, class->suffs ) )
2012 		return( save_class );
2013 
2014 	return( NULL );
2015 }
2016 
2017 /**
2018  * vips_foreign_find_save_target:
2019  * @suffix: format to find a saver for
2020  *
2021  * Searches for an operation you could use to write to a target in @suffix
2022  * format.
2023  *
2024  * See also: vips_image_write_to_buffer().
2025  *
2026  * Returns: the name of an operation on success, %NULL on error
2027  */
2028 const char *
vips_foreign_find_save_target(const char * name)2029 vips_foreign_find_save_target( const char *name )
2030 {
2031 	char suffix[VIPS_PATH_MAX];
2032 	char option_string[VIPS_PATH_MAX];
2033 	VipsForeignSaveClass *save_class;
2034 
2035 	vips__filename_split8( name, suffix, option_string );
2036 
2037 	if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
2038 		"VipsForeignSave",
2039 		(VipsSListMap2Fn) vips_foreign_find_save_target_sub,
2040 		(void *) suffix, NULL )) ) {
2041 		vips_error( "VipsForeignSave",
2042 			_( "\"%s\" is not a known target format" ), name );
2043 
2044 		return( NULL );
2045 	}
2046 
2047 	return( G_OBJECT_CLASS_NAME( save_class ) );
2048 }
2049 
2050 /* Can we write this buffer with this file type?
2051  */
2052 static void *
vips_foreign_find_save_buffer_sub(VipsForeignSaveClass * save_class,const char * suffix,void * b)2053 vips_foreign_find_save_buffer_sub( VipsForeignSaveClass *save_class,
2054 	const char *suffix, void *b )
2055 {
2056 	VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class );
2057 	VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
2058 
2059 	/* All concrete savers needs suffs, since we use the suff to pick the
2060 	 * saver.
2061 	 */
2062 	if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) &&
2063 		!class->suffs )
2064 		g_warning( "no suffix defined for %s", object_class->nickname );
2065 
2066 	if( !G_TYPE_IS_ABSTRACT( G_TYPE_FROM_CLASS( class ) ) &&
2067 		class->suffs &&
2068 		vips_ispostfix( object_class->nickname, "_buffer" ) &&
2069 		vips_filename_suffix_match( suffix, class->suffs ) )
2070 		return( save_class );
2071 
2072 	return( NULL );
2073 }
2074 
2075 /**
2076  * vips_foreign_find_save_buffer:
2077  * @suffix: name to find a saver for
2078  *
2079  * Searches for an operation you could use to write to a buffer in @suffix
2080  * format.
2081  *
2082  * See also: vips_image_write_to_buffer().
2083  *
2084  * Returns: the name of an operation on success, %NULL on error
2085  */
2086 const char *
vips_foreign_find_save_buffer(const char * name)2087 vips_foreign_find_save_buffer( const char *name )
2088 {
2089 	char suffix[VIPS_PATH_MAX];
2090 	char option_string[VIPS_PATH_MAX];
2091 	VipsForeignSaveClass *save_class;
2092 
2093 	vips__filename_split8( name, suffix, option_string );
2094 
2095 	if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
2096 		"VipsForeignSave",
2097 		(VipsSListMap2Fn) vips_foreign_find_save_buffer_sub,
2098 		(void *) suffix, NULL )) ) {
2099 		vips_error( "VipsForeignSave",
2100 			_( "\"%s\" is not a known buffer format" ), name );
2101 
2102 		return( NULL );
2103 	}
2104 
2105 	return( G_OBJECT_CLASS_NAME( save_class ) );
2106 }
2107 
2108 /* C API wrappers for loadable modules go here.
2109  */
2110 
2111 /**
2112  * vips_heifload:
2113  * @filename: file to load
2114  * @out: (out): decompressed image
2115  * @...: %NULL-terminated list of optional named arguments
2116  *
2117  * Optional arguments:
2118  *
2119  * * @page: %gint, page (top-level image number) to read
2120  * * @n: %gint, load this many pages
2121  * * @thumbnail: %gboolean, fetch thumbnail instead of image
2122  *
2123  * Read a HEIF image file into a VIPS image.
2124  *
2125  * Use @page to select a page to render, numbering from zero. If neither @n
2126  * nor @page are set, @page defaults to the primary page, otherwise to 0.
2127  *
2128  * Use @n to select the number of pages to render. The default is 1. Pages are
2129  * rendered in a vertical column. Set to -1 to mean "until the end of the
2130  * document". Use vips_grid() to reorganise pages.
2131  *
2132  * HEIF images have a primary image. The metadata item `heif-primary` gives
2133  * the page number of the primary.
2134  *
2135  * If @thumbnail is %TRUE, then fetch a stored thumbnail rather than the
2136  * image.
2137  *
2138  * See also: vips_image_new_from_file().
2139  *
2140  * Returns: 0 on success, -1 on error.
2141  */
2142 int
vips_heifload(const char * filename,VipsImage ** out,...)2143 vips_heifload( const char *filename, VipsImage **out, ... )
2144 {
2145 	va_list ap;
2146 	int result;
2147 
2148 	va_start( ap, out );
2149 	result = vips_call_split( "heifload", ap, filename, out );
2150 	va_end( ap );
2151 
2152 	return( result );
2153 }
2154 
2155 /**
2156  * vips_heifload_buffer:
2157  * @buf: (array length=len) (element-type guint8): memory area to load
2158  * @len: (type gsize): size of memory area
2159  * @out: (out): image to write
2160  * @...: %NULL-terminated list of optional named arguments
2161  *
2162  * Optional arguments:
2163  *
2164  * * @page: %gint, page (top-level image number) to read
2165  * * @n: %gint, load this many pages
2166  * * @thumbnail: %gboolean, fetch thumbnail instead of image
2167  *
2168  * Read a HEIF image file into a VIPS image.
2169  * Exactly as vips_heifload(), but read from a memory buffer.
2170  *
2171  * You must not free the buffer while @out is active. The
2172  * #VipsObject::postclose signal on @out is a good place to free.
2173  *
2174  * See also: vips_heifload().
2175  *
2176  * Returns: 0 on success, -1 on error.
2177  */
2178 int
vips_heifload_buffer(void * buf,size_t len,VipsImage ** out,...)2179 vips_heifload_buffer( void *buf, size_t len, VipsImage **out, ... )
2180 {
2181 	va_list ap;
2182 	VipsBlob *blob;
2183 	int result;
2184 
2185 	/* We don't take a copy of the data or free it.
2186 	 */
2187 	blob = vips_blob_new( NULL, buf, len );
2188 
2189 	va_start( ap, out );
2190 	result = vips_call_split( "heifload_buffer", ap, blob, out );
2191 	va_end( ap );
2192 
2193 	vips_area_unref( VIPS_AREA( blob ) );
2194 
2195 	return( result );
2196 }
2197 
2198 /**
2199  * vips_heifload_source:
2200  * @source: source to load from
2201  * @out: (out): image to write
2202  * @...: %NULL-terminated list of optional named arguments
2203  *
2204  * Optional arguments:
2205  *
2206  * * @page: %gint, page (top-level image number) to read
2207  * * @n: %gint, load this many pages
2208  * * @thumbnail: %gboolean, fetch thumbnail instead of image
2209  *
2210  * Exactly as vips_heifload(), but read from a source.
2211  *
2212  * See also: vips_heifload().
2213  *
2214  * Returns: 0 on success, -1 on error.
2215  */
2216 int
vips_heifload_source(VipsSource * source,VipsImage ** out,...)2217 vips_heifload_source( VipsSource *source, VipsImage **out, ... )
2218 {
2219 	va_list ap;
2220 	int result;
2221 
2222 	va_start( ap, out );
2223 	result = vips_call_split( "heifload_source", ap, source, out );
2224 	va_end( ap );
2225 
2226 	return( result );
2227 }
2228 
2229 /**
2230  * vips_heifsave: (method)
2231  * @in: image to save
2232  * @filename: file to write to
2233  * @...: %NULL-terminated list of optional named arguments
2234  *
2235  * Optional arguments:
2236  *
2237  * * @Q: %gint, quality factor
2238  * * @lossless: %gboolean, enable lossless encoding
2239  * * @compression: #VipsForeignHeifCompression, write with this compression
2240  * * @effort: %gint, encoding effort
2241  * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
2242  *
2243  * Write a VIPS image to a file in HEIF format.
2244  *
2245  * Use @Q to set the compression factor. Default 50, which seems to be roughly
2246  * what the iphone uses. Q 30 gives about the same quality as JPEG Q 75.
2247  *
2248  * Set @lossless %TRUE to switch to lossless compression.
2249  *
2250  * Use @compression to set the encoder e.g. HEVC, AVC, AV1. It defaults to AV1
2251  * if the target filename ends with ".avif", otherwise HEVC.
2252  *
2253  * Use @effort to control the CPU effort spent improving compression.
2254  * This is currently only applicable to AV1 encoders. Defaults to 4, 0 is
2255  * fastest, 9 is slowest.
2256  *
2257  * Chroma subsampling is normally automatically disabled for Q >= 90. You can
2258  * force the subsampling mode with @subsample_mode.
2259  *
2260  * See also: vips_image_write_to_file(), vips_heifload().
2261  *
2262  * Returns: 0 on success, -1 on error.
2263  */
2264 int
vips_heifsave(VipsImage * in,const char * filename,...)2265 vips_heifsave( VipsImage *in, const char *filename, ... )
2266 {
2267 	va_list ap;
2268 	int result;
2269 
2270 	va_start( ap, filename );
2271 	result = vips_call_split( "heifsave", ap, in, filename );
2272 	va_end( ap );
2273 
2274 	return( result );
2275 }
2276 
2277 /**
2278  * vips_heifsave_buffer: (method)
2279  * @in: image to save
2280  * @buf: (array length=len) (element-type guint8): return output buffer here
2281  * @len: (type gsize): return output length here
2282  * @...: %NULL-terminated list of optional named arguments
2283  *
2284  * Optional arguments:
2285  *
2286  * * @Q: %gint, quality factor
2287  * * @lossless: %gboolean, enable lossless encoding
2288  * * @compression: #VipsForeignHeifCompression, write with this compression
2289  * * @effort: %gint, encoding effort
2290  * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
2291  *
2292  * As vips_heifsave(), but save to a memory buffer.
2293  *
2294  * The address of the buffer is returned in @obuf, the length of the buffer in
2295  * @olen. You are responsible for freeing the buffer with g_free() when you
2296  * are done with it.
2297  *
2298  * See also: vips_heifsave(), vips_image_write_to_file().
2299  *
2300  * Returns: 0 on success, -1 on error.
2301  */
2302 int
vips_heifsave_buffer(VipsImage * in,void ** buf,size_t * len,...)2303 vips_heifsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
2304 {
2305 	va_list ap;
2306 	VipsArea *area;
2307 	int result;
2308 
2309 	area = NULL;
2310 
2311 	va_start( ap, len );
2312 	result = vips_call_split( "heifsave_buffer", ap, in, &area );
2313 	va_end( ap );
2314 
2315 	if( !result &&
2316 		area ) {
2317 		if( buf ) {
2318 			*buf = area->data;
2319 			area->free_fn = NULL;
2320 		}
2321 		if( len )
2322 			*len = area->length;
2323 
2324 		vips_area_unref( area );
2325 	}
2326 
2327 	return( result );
2328 }
2329 
2330 /**
2331  * vips_heifsave_target: (method)
2332  * @in: image to save
2333  * @target: save image to this target
2334  * @...: %NULL-terminated list of optional named arguments
2335  *
2336  * Optional arguments:
2337  *
2338  * * @Q: %gint, quality factor
2339  * * @lossless: %gboolean, enable lossless encoding
2340  * * @compression: #VipsForeignHeifCompression, write with this compression
2341  * * @effort: %gint, encoding effort
2342  * * @subsample_mode: #VipsForeignSubsample, chroma subsampling mode
2343  *
2344  * As vips_heifsave(), but save to a target.
2345  *
2346  * See also: vips_heifsave(), vips_image_write_to_target().
2347  *
2348  * Returns: 0 on success, -1 on error.
2349  */
2350 int
vips_heifsave_target(VipsImage * in,VipsTarget * target,...)2351 vips_heifsave_target( VipsImage *in, VipsTarget *target, ... )
2352 {
2353 	va_list ap;
2354 	int result;
2355 
2356 	va_start( ap, target );
2357 	result = vips_call_split( "heifsave_target", ap, in, target );
2358 	va_end( ap );
2359 
2360 	return( result );
2361 }
2362 
2363 /**
2364  * vips_jxlload:
2365  * @filename: file to load
2366  * @out: (out): decompressed image
2367  * @...: %NULL-terminated list of optional named arguments
2368  *
2369  * Read a JPEG-XL image.
2370  *
2371  * The JPEG-XL loader and saver are experimental features and may change
2372  * in future libvips versions.
2373  *
2374  * See also: vips_image_new_from_file().
2375  *
2376  * Returns: 0 on success, -1 on error.
2377  */
2378 int
vips_jxlload(const char * filename,VipsImage ** out,...)2379 vips_jxlload( const char *filename, VipsImage **out, ... )
2380 {
2381 	va_list ap;
2382 	int result;
2383 
2384 	va_start( ap, out );
2385 	result = vips_call_split( "jxlload", ap, filename, out );
2386 	va_end( ap );
2387 
2388 	return( result );
2389 }
2390 
2391 /**
2392  * vips_jxlload_buffer:
2393  * @buf: (array length=len) (element-type guint8): memory area to load
2394  * @len: (type gsize): size of memory area
2395  * @out: (out): image to write
2396  * @...: %NULL-terminated list of optional named arguments
2397  *
2398  * Exactly as vips_jxlload(), but read from a buffer.
2399  *
2400  * Returns: 0 on success, -1 on error.
2401  */
2402 int
vips_jxlload_buffer(void * buf,size_t len,VipsImage ** out,...)2403 vips_jxlload_buffer( void *buf, size_t len, VipsImage **out, ... )
2404 {
2405 	va_list ap;
2406 	VipsBlob *blob;
2407 	int result;
2408 
2409 	/* We don't take a copy of the data or free it.
2410 	 */
2411 	blob = vips_blob_new( NULL, buf, len );
2412 
2413 	va_start( ap, out );
2414 	result = vips_call_split( "jxlload_buffer", ap, blob, out );
2415 	va_end( ap );
2416 
2417 	vips_area_unref( VIPS_AREA( blob ) );
2418 
2419 	return( result );
2420 }
2421 
2422 /**
2423  * vips_jxlload_source:
2424  * @source: source to load from
2425  * @out: (out): decompressed image
2426  * @...: %NULL-terminated list of optional named arguments
2427  *
2428  * Exactly as vips_jxlload(), but read from a source.
2429  *
2430  * Returns: 0 on success, -1 on error.
2431  */
2432 int
vips_jxlload_source(VipsSource * source,VipsImage ** out,...)2433 vips_jxlload_source( VipsSource *source, VipsImage **out, ... )
2434 {
2435 	va_list ap;
2436 	int result;
2437 
2438 	va_start( ap, out );
2439 	result = vips_call_split( "jxlload_source", ap, source, out );
2440 	va_end( ap );
2441 
2442 	return( result );
2443 }
2444 
2445 /**
2446  * vips_jxlsave: (method)
2447  * @in: image to save
2448  * @filename: file to write to
2449  * @...: %NULL-terminated list of optional named arguments
2450  *
2451  * Optional arguments:
2452  *
2453  * * @tier: %gint, decode speed tier
2454  * * @distance: %gdouble, maximum encoding error
2455  * * @effort: %gint, encoding effort
2456  * * @lossless: %gboolean, enables lossless compression
2457  * * @Q: %gint, quality setting
2458  *
2459  * Write a VIPS image to a file in JPEG-XL format.
2460  *
2461  * The JPEG-XL loader and saver are experimental features and may change
2462  * in future libvips versions.
2463  *
2464  * @tier sets the overall decode speed the encoder will target. Minimum is 0
2465  * (highest quality), and maximum is 4 (lowest quality). Default is 0.
2466  *
2467  * @distance sets the target maximum encoding error. Minimum is 0
2468  * (highest quality), and maximum is 15 (lowest quality). Default is 1.0
2469  * (visually lossless).
2470  *
2471  * As a convenience, you can also use @Q to set @distance. @Q uses
2472  * approximately the same scale as regular JPEG.
2473  *
2474  * Set @lossless to enable lossless compresion.
2475  *
2476  * Returns: 0 on success, -1 on error.
2477  */
2478 int
vips_jxlsave(VipsImage * in,const char * filename,...)2479 vips_jxlsave( VipsImage *in, const char *filename, ... )
2480 {
2481 	va_list ap;
2482 	int result;
2483 
2484 	va_start( ap, filename );
2485 	result = vips_call_split( "jxlsave", ap, in, filename );
2486 	va_end( ap );
2487 
2488 	return( result );
2489 }
2490 
2491 /**
2492  * vips_jxlsave_buffer: (method)
2493  * @in: image to save
2494  * @buf: (array length=len) (element-type guint8): return output buffer here
2495  * @len: (type gsize): return output length here
2496  * @...: %NULL-terminated list of optional named arguments
2497  *
2498  * Optional arguments:
2499  *
2500  * * @tier: %gint, decode speed tier
2501  * * @distance: %gdouble, maximum encoding error
2502  * * @effort: %gint, encoding effort
2503  * * @lossless: %gboolean, enables lossless compression
2504  * * @Q: %gint, quality setting
2505  *
2506  * As vips_jxlsave(), but save to a memory buffer.
2507  *
2508  * See also: vips_jxlsave(), vips_image_write_to_target().
2509  *
2510  * Returns: 0 on success, -1 on error.
2511  */
2512 int
vips_jxlsave_buffer(VipsImage * in,void ** buf,size_t * len,...)2513 vips_jxlsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
2514 {
2515 	va_list ap;
2516 	VipsArea *area;
2517 	int result;
2518 
2519 	area = NULL;
2520 
2521 	va_start( ap, len );
2522 	result = vips_call_split( "jxlsave_buffer", ap, in, &area );
2523 	va_end( ap );
2524 
2525 	if( !result &&
2526 		area ) {
2527 		if( buf ) {
2528 			*buf = area->data;
2529 			area->free_fn = NULL;
2530 		}
2531 		if( len )
2532 			*len = area->length;
2533 
2534 		vips_area_unref( area );
2535 	}
2536 
2537 	return( result );
2538 }
2539 
2540 /**
2541  * vips_jxlsave_target: (method)
2542  * @in: image to save
2543  * @target: save image to this target
2544  * @...: %NULL-terminated list of optional named arguments
2545  *
2546  * Optional arguments:
2547  *
2548  * * @tier: %gint, decode speed tier
2549  * * @distance: %gdouble, maximum encoding error
2550  * * @effort: %gint, encoding effort
2551  * * @lossless: %gboolean, enables lossless compression
2552  * * @Q: %gint, quality setting
2553  *
2554  * As vips_jxlsave(), but save to a target.
2555  *
2556  * See also: vips_jxlsave(), vips_image_write_to_target().
2557  *
2558  * Returns: 0 on success, -1 on error.
2559  */
2560 int
vips_jxlsave_target(VipsImage * in,VipsTarget * target,...)2561 vips_jxlsave_target( VipsImage *in, VipsTarget *target, ... )
2562 {
2563 	va_list ap;
2564 	int result;
2565 
2566 	va_start( ap, target );
2567 	result = vips_call_split( "jxlsave_target", ap, in, target );
2568 	va_end( ap );
2569 
2570 	return( result );
2571 }
2572 
2573 /**
2574  * vips_pdfload:
2575  * @filename: file to load
2576  * @out: (out): output image
2577  * @...: %NULL-terminated list of optional named arguments
2578  *
2579  * Optional arguments:
2580  *
2581  * * @page: %gint, load this page, numbered from zero
2582  * * @n: %gint, load this many pages
2583  * * @dpi: %gdouble, render at this DPI
2584  * * @scale: %gdouble, scale render by this factor
2585  * * @background: #VipsArrayDouble background colour
2586  *
2587  * Render a PDF file into a VIPS image.
2588  *
2589  * The output image is always RGBA --- CMYK PDFs will be
2590  * converted. If you need CMYK bitmaps, you should use vips_magickload()
2591  * instead.
2592  *
2593  * Use @page to select a page to render, numbering from zero.
2594  *
2595  * Use @n to select the number of pages to render. The default is 1. Pages are
2596  * rendered in a vertical column, with each individual page aligned to the
2597  * left. Set to -1 to mean "until the end of the document". Use vips_grid()
2598  * to change page layout.
2599  *
2600  * Use @dpi to set the rendering resolution. The default is 72. Additionally,
2601  * you can scale by setting @scale. If you set both, they combine.
2602  *
2603  * Use @background to set the background RGBA colour. The default is 255
2604  * (solid white), use eg. 0 for a transparent background.
2605  *
2606  * The operation fills a number of header fields with metadata, for example
2607  * "pdf-author". They may be useful.
2608  *
2609  * This function only reads the image header and does not render any pixel
2610  * data. Rendering occurs when pixels are accessed.
2611  *
2612  * See also: vips_image_new_from_file(), vips_magickload().
2613  *
2614  * Returns: 0 on success, -1 on error.
2615  */
2616 int
vips_pdfload(const char * filename,VipsImage ** out,...)2617 vips_pdfload( const char *filename, VipsImage **out, ... )
2618 {
2619 	va_list ap;
2620 	int result;
2621 
2622 	va_start( ap, out );
2623 	result = vips_call_split( "pdfload", ap, filename, out );
2624 	va_end( ap );
2625 
2626 	return( result );
2627 }
2628 
2629 /**
2630  * vips_pdfload_buffer:
2631  * @buf: (array length=len) (element-type guint8): memory area to load
2632  * @len: (type gsize): size of memory area
2633  * @out: (out): image to write
2634  * @...: %NULL-terminated list of optional named arguments
2635  *
2636  * Optional arguments:
2637  *
2638  * * @page: %gint, load this page, numbered from zero
2639  * * @n: %gint, load this many pages
2640  * * @dpi: %gdouble, render at this DPI
2641  * * @scale: %gdouble, scale render by this factor
2642  * * @background: #VipsArrayDouble background colour
2643  *
2644  * Read a PDF-formatted memory buffer into a VIPS image. Exactly as
2645  * vips_pdfload(), but read from memory.
2646  *
2647  * You must not free the buffer while @out is active. The
2648  * #VipsObject::postclose signal on @out is a good place to free.
2649  *
2650  * See also: vips_pdfload().
2651  *
2652  * Returns: 0 on success, -1 on error.
2653  */
2654 int
vips_pdfload_buffer(void * buf,size_t len,VipsImage ** out,...)2655 vips_pdfload_buffer( void *buf, size_t len, VipsImage **out, ... )
2656 {
2657 	va_list ap;
2658 	VipsBlob *blob;
2659 	int result;
2660 
2661 	/* We don't take a copy of the data or free it.
2662 	 */
2663 	blob = vips_blob_new( NULL, buf, len );
2664 
2665 	va_start( ap, out );
2666 	result = vips_call_split( "pdfload_buffer", ap, blob, out );
2667 	va_end( ap );
2668 
2669 	vips_area_unref( VIPS_AREA( blob ) );
2670 
2671 	return( result );
2672 }
2673 
2674 /**
2675  * vips_pdfload_source:
2676  * @source: source to load from
2677  * @out: (out): image to write
2678  * @...: %NULL-terminated list of optional named arguments
2679  *
2680  * Optional arguments:
2681  *
2682  * * @page: %gint, load this page, numbered from zero
2683  * * @n: %gint, load this many pages
2684  * * @dpi: %gdouble, render at this DPI
2685  * * @scale: %gdouble, scale render by this factor
2686  * * @background: #VipsArrayDouble background colour
2687  *
2688  * Exactly as vips_pdfload(), but read from a source.
2689  *
2690  * See also: vips_pdfload()
2691  *
2692  * Returns: 0 on success, -1 on error.
2693  */
2694 int
vips_pdfload_source(VipsSource * source,VipsImage ** out,...)2695 vips_pdfload_source( VipsSource *source, VipsImage **out, ... )
2696 {
2697 	va_list ap;
2698 	int result;
2699 
2700 	va_start( ap, out );
2701 	result = vips_call_split( "pdfload_source", ap, source, out );
2702 	va_end( ap );
2703 
2704 	return( result );
2705 }
2706 
2707 /**
2708  * vips_openslideload:
2709  * @filename: file to load
2710  * @out: (out): decompressed image
2711  * @...: %NULL-terminated list of optional named arguments
2712  *
2713  * Optional arguments:
2714  *
2715  * * @level: %gint, load this level
2716  * * @associated: %gchararray, load this associated image
2717  * * @attach_associated: %gboolean, attach all associated images as metadata
2718  * * @autocrop: %gboolean, crop to image bounds
2719  *
2720  * Read a virtual slide supported by the OpenSlide library into a VIPS image.
2721  * OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle,
2722  * and Ventana formats.
2723  *
2724  * To facilitate zooming, virtual slide formats include multiple scaled-down
2725  * versions of the high-resolution image.  These are typically called
2726  * "levels".  By default, vips_openslideload() reads the highest-resolution
2727  * level (level 0).  Set @level to the level number you want.
2728  *
2729  * In addition to the slide image itself, virtual slide formats sometimes
2730  * include additional images, such as a scan of the slide's barcode.
2731  * OpenSlide calls these "associated images".  To read an associated image,
2732  * set @associated to the image's name.
2733  * A slide's associated images are listed in the
2734  * "slide-associated-images" metadata item.
2735  *
2736  * If you set @attach_associated, then all associated images are attached as
2737  * metadata items. Use vips_image_get_image() on @out to retrieve them. Images
2738  * are attached as "openslide-associated-XXXXX", where XXXXX is the name of the
2739  * associated image.
2740  *
2741  * The output of this operator is always RGBA.
2742  *
2743  * See also: vips_image_new_from_file().
2744  *
2745  * Returns: 0 on success, -1 on error.
2746  */
2747 int
vips_openslideload(const char * filename,VipsImage ** out,...)2748 vips_openslideload( const char *filename, VipsImage **out, ... )
2749 {
2750 	va_list ap;
2751 	int result;
2752 
2753 	va_start( ap, out );
2754 	result = vips_call_split( "openslideload", ap, filename, out );
2755 	va_end( ap );
2756 
2757 	return( result );
2758 }
2759 
2760 /**
2761  * vips_openslideload_source:
2762  * @source: source to load from
2763  * @out: (out): decompressed image
2764  * @...: %NULL-terminated list of optional named arguments
2765  *
2766  * Optional arguments:
2767  *
2768  * * @level: %gint, load this level
2769  * * @associated: %gchararray, load this associated image
2770  * * @attach_associated: %gboolean, attach all associated images as metadata
2771  * * @autocrop: %gboolean, crop to image bounds
2772  *
2773  * Exactly as vips_openslideload(), but read from a source.
2774  *
2775  * Returns: 0 on success, -1 on error.
2776  */
2777 int
vips_openslideload_source(VipsSource * source,VipsImage ** out,...)2778 vips_openslideload_source( VipsSource *source, VipsImage **out, ... )
2779 {
2780 	va_list ap;
2781 	int result;
2782 
2783 	va_start( ap, out );
2784 	result = vips_call_split( "openslideload_source", ap, source, out );
2785 	va_end( ap );
2786 
2787 	return( result );
2788 }
2789 
2790 /* Called from iofuncs to init all operations in this dir. Use a plugin system
2791  * instead?
2792  */
2793 void
vips_foreign_operation_init(void)2794 vips_foreign_operation_init( void )
2795 {
2796 	extern GType vips_foreign_load_rad_file_get_type( void );
2797 	extern GType vips_foreign_load_rad_buffer_get_type( void );
2798 	extern GType vips_foreign_load_rad_source_get_type( void );
2799 	extern GType vips_foreign_save_rad_file_get_type( void );
2800 	extern GType vips_foreign_save_rad_buffer_get_type( void );
2801 	extern GType vips_foreign_save_rad_target_get_type( void );
2802 
2803 	extern GType vips_foreign_load_mat_get_type( void );
2804 
2805 	extern GType vips_foreign_load_ppm_file_get_type( void );
2806 	extern GType vips_foreign_load_ppm_source_get_type( void );
2807 	extern GType vips_foreign_save_ppm_file_get_type( void );
2808 	extern GType vips_foreign_save_pbm_target_get_type( void );
2809 	extern GType vips_foreign_save_pgm_target_get_type( void );
2810 	extern GType vips_foreign_save_ppm_target_get_type( void );
2811 	extern GType vips_foreign_save_pfm_target_get_type( void );
2812 
2813 	extern GType vips_foreign_load_png_file_get_type( void );
2814 	extern GType vips_foreign_load_png_buffer_get_type( void );
2815 	extern GType vips_foreign_load_png_source_get_type( void );
2816 	extern GType vips_foreign_save_png_file_get_type( void );
2817 	extern GType vips_foreign_save_png_buffer_get_type( void );
2818 	extern GType vips_foreign_save_png_target_get_type( void );
2819 
2820 	extern GType vips_foreign_load_csv_file_get_type( void );
2821 	extern GType vips_foreign_load_csv_source_get_type( void );
2822 	extern GType vips_foreign_save_csv_file_get_type( void );
2823 	extern GType vips_foreign_save_csv_target_get_type( void );
2824 
2825 	extern GType vips_foreign_load_matrix_file_get_type( void );
2826 	extern GType vips_foreign_load_matrix_source_get_type( void );
2827 	extern GType vips_foreign_save_matrix_file_get_type( void );
2828 	extern GType vips_foreign_save_matrix_target_get_type( void );
2829 	extern GType vips_foreign_print_matrix_get_type( void );
2830 
2831 	extern GType vips_foreign_load_fits_file_get_type( void );
2832 	extern GType vips_foreign_load_fits_source_get_type( void );
2833 	extern GType vips_foreign_save_fits_get_type( void );
2834 
2835 	extern GType vips_foreign_load_analyze_get_type( void );
2836 
2837 	extern GType vips_foreign_load_openexr_get_type( void );
2838 
2839 	extern GType vips_foreign_load_openslide_file_get_type( void );
2840 	extern GType vips_foreign_load_openslide_source_get_type( void );
2841 
2842 	extern GType vips_foreign_load_vips_file_get_type( void );
2843 	extern GType vips_foreign_load_vips_source_get_type( void );
2844 	extern GType vips_foreign_save_vips_file_get_type( void );
2845 	extern GType vips_foreign_save_vips_target_get_type( void );
2846 
2847 	extern GType vips_foreign_load_jpeg_file_get_type( void );
2848 	extern GType vips_foreign_load_jpeg_buffer_get_type( void );
2849 	extern GType vips_foreign_load_jpeg_source_get_type( void );
2850 	extern GType vips_foreign_save_jpeg_file_get_type( void );
2851 	extern GType vips_foreign_save_jpeg_buffer_get_type( void );
2852 	extern GType vips_foreign_save_jpeg_target_get_type( void );
2853 	extern GType vips_foreign_save_jpeg_mime_get_type( void );
2854 
2855 	extern GType vips_foreign_load_tiff_file_get_type( void );
2856 	extern GType vips_foreign_load_tiff_buffer_get_type( void );
2857 	extern GType vips_foreign_load_tiff_source_get_type( void );
2858 	extern GType vips_foreign_save_tiff_file_get_type( void );
2859 	extern GType vips_foreign_save_tiff_buffer_get_type( void );
2860 
2861 	extern GType vips_foreign_load_raw_get_type( void );
2862 	extern GType vips_foreign_save_raw_get_type( void );
2863 	extern GType vips_foreign_save_raw_fd_get_type( void );
2864 
2865 	extern GType vips_foreign_load_magick_file_get_type( void );
2866 	extern GType vips_foreign_load_magick_buffer_get_type( void );
2867 	extern GType vips_foreign_load_magick7_file_get_type( void );
2868 	extern GType vips_foreign_load_magick7_buffer_get_type( void );
2869 	extern GType vips_foreign_save_magick_file_get_type( void );
2870 	extern GType vips_foreign_save_magick_bmp_file_get_type( void );
2871 	extern GType vips_foreign_save_magick_buffer_get_type( void );
2872 	extern GType vips_foreign_save_magick_bmp_buffer_get_type( void );
2873 
2874 	extern GType vips_foreign_save_dz_file_get_type( void );
2875 	extern GType vips_foreign_save_dz_buffer_get_type( void );
2876 
2877 	extern GType vips_foreign_load_webp_file_get_type( void );
2878 	extern GType vips_foreign_load_webp_buffer_get_type( void );
2879 	extern GType vips_foreign_load_webp_source_get_type( void );
2880 	extern GType vips_foreign_save_webp_file_get_type( void );
2881 	extern GType vips_foreign_save_webp_buffer_get_type( void );
2882 	extern GType vips_foreign_save_webp_target_get_type( void );
2883 
2884 	extern GType vips_foreign_load_pdf_file_get_type( void );
2885 	extern GType vips_foreign_load_pdf_buffer_get_type( void );
2886 	extern GType vips_foreign_load_pdf_source_get_type( void );
2887 
2888 	extern GType vips_foreign_load_svg_file_get_type( void );
2889 	extern GType vips_foreign_load_svg_buffer_get_type( void );
2890 	extern GType vips_foreign_load_svg_source_get_type( void );
2891 
2892 	extern GType vips_foreign_load_jp2k_file_get_type( void );
2893 	extern GType vips_foreign_load_jp2k_buffer_get_type( void );
2894 	extern GType vips_foreign_load_jp2k_source_get_type( void );
2895 	extern GType vips_foreign_save_jp2k_file_get_type( void );
2896 	extern GType vips_foreign_save_jp2k_buffer_get_type( void );
2897 	extern GType vips_foreign_save_jp2k_target_get_type( void );
2898 
2899 	extern GType vips_foreign_load_jxl_file_get_type( void );
2900 	extern GType vips_foreign_load_jxl_buffer_get_type( void );
2901 	extern GType vips_foreign_load_jxl_source_get_type( void );
2902 	extern GType vips_foreign_save_jxl_file_get_type( void );
2903 	extern GType vips_foreign_save_jxl_buffer_get_type( void );
2904 	extern GType vips_foreign_save_jxl_target_get_type( void );
2905 
2906 	extern GType vips_foreign_load_heif_file_get_type( void );
2907 	extern GType vips_foreign_load_heif_buffer_get_type( void );
2908 	extern GType vips_foreign_load_heif_source_get_type( void );
2909 	extern GType vips_foreign_save_heif_file_get_type( void );
2910 	extern GType vips_foreign_save_heif_buffer_get_type( void );
2911 	extern GType vips_foreign_save_heif_target_get_type( void );
2912 	extern GType vips_foreign_save_avif_target_get_type( void );
2913 
2914 	extern GType vips_foreign_load_nifti_file_get_type( void );
2915 	extern GType vips_foreign_load_nifti_source_get_type( void );
2916 	extern GType vips_foreign_save_nifti_get_type( void );
2917 
2918 	extern GType vips_foreign_load_nsgif_file_get_type( void );
2919 	extern GType vips_foreign_load_nsgif_buffer_get_type( void );
2920 	extern GType vips_foreign_load_nsgif_source_get_type( void );
2921 
2922 	extern GType vips_foreign_save_cgif_file_get_type( void );
2923 	extern GType vips_foreign_save_cgif_buffer_get_type( void );
2924 	extern GType vips_foreign_save_cgif_target_get_type( void );
2925 
2926 	vips_foreign_load_csv_file_get_type();
2927 	vips_foreign_load_csv_source_get_type();
2928 	vips_foreign_save_csv_file_get_type();
2929 	vips_foreign_save_csv_target_get_type();
2930 
2931 	vips_foreign_load_matrix_file_get_type();
2932 	vips_foreign_load_matrix_source_get_type();
2933 	vips_foreign_save_matrix_file_get_type();
2934 	vips_foreign_save_matrix_target_get_type();
2935 	vips_foreign_print_matrix_get_type();
2936 
2937 	vips_foreign_load_raw_get_type();
2938 	vips_foreign_save_raw_get_type();
2939 	vips_foreign_save_raw_fd_get_type();
2940 
2941 	vips_foreign_load_vips_file_get_type();
2942 	vips_foreign_load_vips_source_get_type();
2943 	vips_foreign_save_vips_file_get_type();
2944 	vips_foreign_save_vips_target_get_type();
2945 
2946 #ifdef HAVE_ANALYZE
2947 	vips_foreign_load_analyze_get_type();
2948 #endif /*HAVE_ANALYZE*/
2949 
2950 #ifdef HAVE_PPM
2951 	vips_foreign_load_ppm_file_get_type();
2952 	vips_foreign_load_ppm_source_get_type();
2953 	vips_foreign_save_ppm_file_get_type();
2954 	vips_foreign_save_pbm_target_get_type();
2955 	vips_foreign_save_pgm_target_get_type();
2956 	vips_foreign_save_ppm_target_get_type();
2957 	vips_foreign_save_pfm_target_get_type();
2958 #endif /*HAVE_PPM*/
2959 
2960 #ifdef HAVE_RADIANCE
2961 	vips_foreign_load_rad_file_get_type();
2962 	vips_foreign_load_rad_buffer_get_type();
2963 	vips_foreign_load_rad_source_get_type();
2964 	vips_foreign_save_rad_file_get_type();
2965 	vips_foreign_save_rad_buffer_get_type();
2966 	vips_foreign_save_rad_target_get_type();
2967 #endif /*HAVE_RADIANCE*/
2968 
2969 #if defined(HAVE_POPPLER) && !defined(POPPLER_MODULE)
2970 	vips_foreign_load_pdf_file_get_type();
2971 	vips_foreign_load_pdf_buffer_get_type();
2972 	vips_foreign_load_pdf_source_get_type();
2973 #endif /*defined(HAVE_POPPLER) && !defined(POPPLER_MODULE)*/
2974 
2975 #ifdef HAVE_PDFIUM
2976 	vips_foreign_load_pdf_file_get_type();
2977 	vips_foreign_load_pdf_buffer_get_type();
2978 	vips_foreign_load_pdf_source_get_type();
2979 #endif /*HAVE_PDFIUM*/
2980 
2981 #ifdef HAVE_RSVG
2982 	vips_foreign_load_svg_file_get_type();
2983 	vips_foreign_load_svg_buffer_get_type();
2984 	vips_foreign_load_svg_source_get_type();
2985 #endif /*HAVE_RSVG*/
2986 
2987 #if defined(HAVE_LIBJXL) && !defined(LIBJXL_MODULE)
2988 	vips_foreign_load_jxl_file_get_type();
2989 	vips_foreign_load_jxl_buffer_get_type();
2990 	vips_foreign_load_jxl_source_get_type();
2991 	vips_foreign_save_jxl_file_get_type();
2992 	vips_foreign_save_jxl_buffer_get_type();
2993 	vips_foreign_save_jxl_target_get_type();
2994 #endif /*defined(HAVE_LIBJXL) && !defined(LIBJXL_MODULE)*/
2995 
2996 #ifdef HAVE_LIBOPENJP2
2997 	vips_foreign_load_jp2k_file_get_type();
2998 	vips_foreign_load_jp2k_buffer_get_type();
2999 	vips_foreign_load_jp2k_source_get_type();
3000 	vips_foreign_save_jp2k_file_get_type();
3001 	vips_foreign_save_jp2k_buffer_get_type();
3002 	vips_foreign_save_jp2k_target_get_type();
3003 #endif /*HAVE_LIBOPENJP2*/
3004 
3005 #ifdef HAVE_NSGIF
3006 	vips_foreign_load_nsgif_file_get_type();
3007 	vips_foreign_load_nsgif_buffer_get_type();
3008 	vips_foreign_load_nsgif_source_get_type();
3009 #endif /*HAVE_NSGIF*/
3010 
3011 #ifdef HAVE_CGIF
3012 	vips_foreign_save_cgif_file_get_type();
3013 	vips_foreign_save_cgif_buffer_get_type();
3014 	vips_foreign_save_cgif_target_get_type();
3015 #endif /*HAVE_CGIF*/
3016 
3017 #ifdef HAVE_GSF
3018 	vips_foreign_save_dz_file_get_type();
3019 	vips_foreign_save_dz_buffer_get_type();
3020 #endif /*HAVE_GSF*/
3021 
3022 #ifdef HAVE_PNG
3023 	vips_foreign_load_png_file_get_type();
3024 	vips_foreign_load_png_buffer_get_type();
3025 	vips_foreign_load_png_source_get_type();
3026 	vips_foreign_save_png_file_get_type();
3027 	vips_foreign_save_png_buffer_get_type();
3028 	vips_foreign_save_png_target_get_type();
3029 #endif /*HAVE_PNG*/
3030 
3031 #ifdef HAVE_SPNG
3032 	vips_foreign_load_png_file_get_type();
3033 	vips_foreign_load_png_buffer_get_type();
3034 	vips_foreign_load_png_source_get_type();
3035 #endif /*HAVE_SPNG*/
3036 
3037 #ifdef HAVE_MATIO
3038 	vips_foreign_load_mat_get_type();
3039 #endif /*HAVE_MATIO*/
3040 
3041 #ifdef HAVE_JPEG
3042 	vips_foreign_load_jpeg_file_get_type();
3043 	vips_foreign_load_jpeg_buffer_get_type();
3044 	vips_foreign_load_jpeg_source_get_type();
3045 	vips_foreign_save_jpeg_file_get_type();
3046 	vips_foreign_save_jpeg_buffer_get_type();
3047 	vips_foreign_save_jpeg_target_get_type();
3048 	vips_foreign_save_jpeg_mime_get_type();
3049 #endif /*HAVE_JPEG*/
3050 
3051 #ifdef HAVE_LIBWEBP
3052 	vips_foreign_load_webp_file_get_type();
3053 	vips_foreign_load_webp_buffer_get_type();
3054 	vips_foreign_load_webp_source_get_type();
3055 	vips_foreign_save_webp_file_get_type();
3056 	vips_foreign_save_webp_buffer_get_type();
3057 	vips_foreign_save_webp_target_get_type();
3058 #endif /*HAVE_LIBWEBP*/
3059 
3060 #ifdef HAVE_TIFF
3061 	vips_foreign_load_tiff_file_get_type();
3062 	vips_foreign_load_tiff_buffer_get_type();
3063 	vips_foreign_load_tiff_source_get_type();
3064 	vips_foreign_save_tiff_file_get_type();
3065 	vips_foreign_save_tiff_buffer_get_type();
3066 #endif /*HAVE_TIFF*/
3067 
3068 #if defined(HAVE_OPENSLIDE) && !defined(OPENSLIDE_MODULE)
3069 	vips_foreign_load_openslide_file_get_type();
3070 	vips_foreign_load_openslide_source_get_type();
3071 #endif /*defined(HAVE_OPENSLIDE) && !defined(OPENSLIDE_MODULE)*/
3072 
3073 #if defined(ENABLE_MAGICKLOAD) && !defined(MAGICK_MODULE)
3074 #ifdef HAVE_MAGICK6
3075 	vips_foreign_load_magick_file_get_type();
3076 	vips_foreign_load_magick_buffer_get_type();
3077 #endif /*HAVE_MAGICK6*/
3078 
3079 #ifdef HAVE_MAGICK7
3080 	vips_foreign_load_magick7_file_get_type();
3081 	vips_foreign_load_magick7_buffer_get_type();
3082 #endif /*HAVE_MAGICK7*/
3083 #endif /*defined(ENABLE_MAGICKLOAD) && !defined(MAGICK_MODULE)*/
3084 
3085 #if defined(ENABLE_MAGICKSAVE) && !defined(MAGICK_MODULE)
3086 	vips_foreign_save_magick_file_get_type();
3087 	vips_foreign_save_magick_bmp_file_get_type();
3088 	vips_foreign_save_magick_buffer_get_type();
3089 	vips_foreign_save_magick_bmp_buffer_get_type();
3090 #endif /*defined(ENABLE_MAGICKSAVE) && !defined(MAGICK_MODULE)*/
3091 
3092 #ifdef HAVE_CFITSIO
3093 	vips_foreign_load_fits_file_get_type();
3094 	vips_foreign_load_fits_source_get_type();
3095 	vips_foreign_save_fits_get_type();
3096 #endif /*HAVE_CFITSIO*/
3097 
3098 #ifdef HAVE_OPENEXR
3099 	vips_foreign_load_openexr_get_type();
3100 #endif /*HAVE_OPENEXR*/
3101 
3102 #ifdef HAVE_NIFTI
3103 	vips_foreign_load_nifti_file_get_type();
3104 	vips_foreign_load_nifti_source_get_type();
3105 	vips_foreign_save_nifti_get_type();
3106 #endif /*HAVE_NIFTI*/
3107 
3108 #if defined(HAVE_HEIF_DECODER) && !defined(HEIF_MODULE)
3109 	vips_foreign_load_heif_file_get_type();
3110 	vips_foreign_load_heif_buffer_get_type();
3111 	vips_foreign_load_heif_source_get_type();
3112 #endif /*defined(HAVE_HEIF_DECODER) && !defined(HEIF_MODULE)*/
3113 
3114 #if defined(HAVE_HEIF_ENCODER) && !defined(HEIF_MODULE)
3115 	vips_foreign_save_heif_file_get_type();
3116 	vips_foreign_save_heif_buffer_get_type();
3117 	vips_foreign_save_heif_target_get_type();
3118 	vips_foreign_save_avif_target_get_type();
3119 #endif /*defined(HAVE_HEIF_ENCODER) && !defined(HEIF_MODULE)*/
3120 
3121 	vips__foreign_load_operation =
3122 		g_quark_from_static_string( "vips-foreign-load-operation" );
3123 }
3124