Merge remote-tracking branch 'origin/format-hacking' into format-hacking

Conflicts:
	TODO
	libvips/file/jpegload.c
	libvips/foreign/foreign.c
	libvips/foreign/jpeg2vips.c
	libvips/foreign/jpegsave.c
	libvips/include/vips/file.h
This commit is contained in:
John Cupitt 2011-11-29 16:36:23 +00:00
commit 9208afb8b2
22 changed files with 702 additions and 571 deletions

138
TODO
View File

@ -1,41 +1,127 @@
- how do we set up the inheritance?
we have
- argh this is horrible
operation
file (filename, priority, suffs)
save (in, ready, saveable, format_table)
jpeg (Q, profile)
how about adding a property 'fileloader' ... define this and your object
will be tested by vips_foreign_find_load()
of that system we need the same args, except without suffs and filename ...
we do want priority
or! put is_a etc. in VipsForeign but only set them for classes which support
it and leave NULL otherwise
perhaps reorganse as
consider just properties ... at the moment we have:
operation
format (priority)
save (in, ready, saveable, format_table)
jpeg (Q, profile)
file (filename, suffs)
VipsForeign (filename)
VipsForeignLoad (disc, flags)
VipsForeignLoadJpeg (shrink, fail)
VipsForeignLoadVips
VipsForeignSave (in)
VipsForeignSaveJpeg (Q, profile)
VipsForeignSaveVips
operation
format (priority)
save (in, ready, saveable, format_table)
jpeg (Q, profile)
buffer (buff)
how about:
operation
format (priority)
save (in, ready, saveable, format_table)
tiff (Q, profile, filename, suffs)
VipsForeign
VipsForeignLoad (disc, flags)
VipsForeignLoadJpeg (shrink, fail)
VipsForeignLoadJpegBuffer (buffer)
VipsForeignLoadJpegFile (filename)
VipsForeignLoadVips (source-filename)
VipsForeignLoadTiff (source-filename, page)
VipsForeignSave (in)
VipsForeignSaveJpeg (Q, profile)
VipsForeignSaveJpegFile (filename)
VipsForeignSaveJpegBuffer (buffer)
VipsForeignSaveVips (dest-filename)
VipsForeignSaveTiff (dest-filename, pyramid, comp, etc.)
means when we search for a format to save with, not all subclasses of format
will have a suffs field, we'd need to test
so all we do is nmove the filename prop of the load/save subclasses, not too
bad
- we can make the interfaces we need much simpler if we use properties for all
data members ... eg. fetch "flags" property if we can
put 'priority' in VipsForeignClass
interfaces become
interface load (header, load)
interface load-from-file (is_a)
interface load-from-buffer (buffer)
interface save (ready, saveable, format_table)
interface save-to-file (filename, suffs)
interface save-to-buffer (buffer)
classes are
VipsForeign (priority)
VipsForeignLoad (disc, flags, out, real, get_flags, header, load)
VipsForeignLoadJpeg (shrink, fail)
VipsForeignLoadJpegFile (filename, is_a)
VipsForeignLoadJpegBuffer (buffer)
VipsForeignSave (in, ready, saveable, format_table)
VipsForeignSaveJpeg (Q, profile)
VipsForeignSaveJpegFile (filename, suffs)
VipsForeignSaveJpegBuffer (buffer)
- at the moment we have:
- add classes to read and write jpeg buffers
VipsFile (filename)
VipsFileLoad (disc, flags)
VipsFileLoadJpeg (shrink, fail)
VipsFileSave (in)
VipsFileSaveJpeg (Q, profile)
we want jpeg*_buffer to have everything jpeg* has, except filename and
suffs
reorganise as
VipsForeign (priority)
VipsForeignLoad (disc, flags, out, real, get_flags, header, load)
VipsForeignLoadJpeg (shrink, fail)
VipsForeignLoadJpegFile (filename, is_a)
VipsForeignLoadJpegBuffer (buffer)
VipsForeignSave (in, ready, saveable, format_table)
VipsForeignSaveJpeg (Q, profile)
VipsForeignSaveJpegFile (filename, suffs)
VipsForeignSaveJpegBuffer (buffer)
how do we do 'pick a loader by filename'? we need to find all subclasses of
VipsForeign which implement suffs?
we're going to need to register loaders and savers on a separate list
somewhere :-(
or have load-from-file as an interface?
interface load (priority, disc, flags, out, get_flags, header, load)
interface load-from-file (filename, is_a)
interface load-from-buffer (buffer)
interface save (priority, in, ready, saveable, format_table)
interface save-to-file (filename, suffs)
interface save-to-buffer (buffer)
then walk VipsForeign and test whether each class implements load-from-file
can interfaces have data members?
read up on gobject interfaces
- test vips_foreign_load_vips_get_flags(), sense inverted?
we have various printf()s left in the byteswap codepath
test this, if we can .. perhaps add a swap-magic flag to edvips?
- add classes for read and write jpeg buffers
make compat wrappers for old im_jpeg2vips() and im_vips2jpeg()

View File

@ -635,7 +635,7 @@ AC_OUTPUT([
libvips/convolution/Makefile
libvips/deprecated/Makefile
libvips/format/Makefile
libvips/file/Makefile
libvips/foreign/Makefile
libvips/freq_filt/Makefile
libvips/histograms_lut/Makefile
libvips/inplace/Makefile

View File

@ -10,7 +10,7 @@ C_LIB =
endif
SUBDIRS = \
file \
foreign \
include \
arithmetic \
resample \
@ -53,7 +53,7 @@ libvips_la_LIBADD = \
deprecated/libdeprecated.la \
$(C_LIB) \
format/libformat.la \
file/libfile.la \
foreign/libforeign.la \
freq_filt/libfreq_filt.la \
histograms_lut/libhistograms_lut.la \
inplace/libinplace.la \

View File

@ -1,6 +1,6 @@
noinst_LTLIBRARIES = libfile.la
noinst_LTLIBRARIES = libforeign.la
libfile_la_SOURCES = \
libforeign_la_SOURCES = \
vips2jpeg.c \
jpeg2vips.c \
jpeg.h \
@ -8,6 +8,6 @@ libfile_la_SOURCES = \
jpegsave.c \
vipssave.c \
vipsload.c \
file.c
foreign.c
INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@

View File

@ -56,48 +56,48 @@
*
* If you define a new file, support for
* it automatically appears in all VIPS user-interfaces. It will also be
* transparently supported by vips_image_new_from_file() and friends.
* transparently supported by vips_image_new_from_foreign() and friends.
*
* VIPS comes with VipsFile for TIFF, JPEG, PNG, Analyze, PPM, OpenEXR, CSV,
* VIPS comes with VipsForeign for TIFF, JPEG, PNG, Analyze, PPM, OpenEXR, CSV,
* Matlab, Radiance, RAW, VIPS and one that wraps libMagick.
*/
/**
* VipsFileFlags:
* @VIPS_FILE_NONE: no flags set
* @VIPS_FILE_PARTIAL: the image may be read lazilly
* @VIPS_FILE_BIGENDIAN: image pixels are most-significant byte first
* VipsForeignFlags:
* @VIPS_FOREIGN_NONE: no flags set
* @VIPS_FOREIGN_PARTIAL: the image may be read lazilly
* @VIPS_FOREIGN_BIGENDIAN: image pixels are most-significant byte first
*
* Some hints about the image loader.
*
* @VIPS_FILE_PARTIAL means that the image can be read directly from the
* @VIPS_FOREIGN_PARTIAL means that the image can be read directly from the
* file without needing to be unpacked to a temporary image first.
*
* @VIPS_FILE_BIGENDIAN means that image pixels are most-significant byte
* @VIPS_FOREIGN_BIGENDIAN means that image pixels are most-significant byte
* first. Depending on the native byte order of the host machine, you may
* need to swap bytes. See copy_swap().
*/
/**
* VipsFile:
* VipsForeign:
*
* #VipsFile has these virtual methods:
* #VipsForeign has these virtual methods:
*
* |[
* typedef struct _VipsFileClass {
* typedef struct _VipsForeignClass {
* VipsObjectClass parent_class;
*
* gboolean (*is_a)( const char *filename );
* int (*header)( const char *filename, VipsImage *out );
* int (*load)( const char *filename, VipsImage *out );
* int (*save)( VipsImage *in, const char *filename );
* VipsFileFlags (*get_flags)( const char *filename );
* VipsForeignFlags (*get_flags)( const char *filename );
* int priority;
* const char **suffs;
* } VipsFileClass;
* } VipsForeignClass;
* ]|
*
* Add a new file to VIPS by subclassing VipsFile. Subclasses need to
* Add a new file to VIPS by subclassing VipsForeign. Subclasses need to
* implement at least load() or save().
*
* These members are:
@ -179,7 +179,7 @@
* At the command-line, use:
*
* |[
* vips --list classes | grep File
* vips --list classes | grep Foreign
* ]|
*
* To see a list of all the supported files.
@ -187,14 +187,14 @@
* For example, the TIFF file is defined like this:
*
|[
typedef VipsFile VipsFileTiff;
typedef VipsFileClass VipsFileTiffClass;
typedef VipsForeign VipsForeignTiff;
typedef VipsForeignClass VipsForeignTiffClass;
static void
vips_file_tiff_class_init( VipsFileTiffClass *class )
vips_foreign_tiff_class_init( VipsForeignTiffClass *class )
{
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFileClass *file_class = (VipsFileClass *) class;
VipsForeignClass *file_class = (VipsForeignClass *) class;
object_class->nickname = "tiff";
object_class->description = _( "TIFF" );
@ -208,14 +208,14 @@ vips_file_tiff_class_init( VipsFileTiffClass *class )
}
static void
vips_file_tiff_init( VipsFileTiff *object )
vips_foreign_tiff_init( VipsForeignTiff *object )
{
}
G_DEFINE_TYPE( VipsFileTiff, vips_file_tiff, VIPS_TYPE_FILE );
G_DEFINE_TYPE( VipsForeignTiff, vips_foreign_tiff, VIPS_TYPE_FOREIGN );
]|
*
* Then call vips_file_tiff_get_type() somewhere in your init code to link
* Then call vips_foreign_tiff_get_type() somewhere in your init code to link
* the file into VIPS (though of course the tiff file is linked in for you
* already).
*
@ -224,15 +224,15 @@ G_DEFINE_TYPE( VipsFileTiff, vips_file_tiff, VIPS_TYPE_FILE );
/* Abstract base class for image files.
*/
G_DEFINE_ABSTRACT_TYPE( VipsFile, vips_file, VIPS_TYPE_OPERATION );
G_DEFINE_ABSTRACT_TYPE( VipsForeign, vips_foreign, VIPS_TYPE_OPERATION );
static void
vips_file_print_class( VipsObjectClass *object_class, VipsBuf *buf )
vips_foreign_print_class( VipsObjectClass *object_class, VipsBuf *buf )
{
VipsFileClass *class = VIPS_FILE_CLASS( object_class );
VipsForeignClass *class = VIPS_FOREIGN_CLASS( object_class );
const char **p;
VIPS_OBJECT_CLASS( vips_file_parent_class )->
VIPS_OBJECT_CLASS( vips_foreign_parent_class )->
print_class( object_class, buf );
vips_buf_appends( buf, " " );
@ -251,7 +251,7 @@ vips_file_print_class( VipsObjectClass *object_class, VipsBuf *buf )
}
static void
vips_file_class_init( VipsFileClass *class )
vips_foreign_class_init( VipsForeignClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
@ -261,27 +261,27 @@ vips_file_class_init( VipsFileClass *class )
object_class->nickname = "file";
object_class->description = _( "load and save image files" );
object_class->print_class = vips_file_print_class;
object_class->print_class = vips_foreign_print_class;
VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ),
_( "File filename" ),
_( "Foreign filename" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsFile, filename ),
G_STRUCT_OFFSET( VipsForeign, filename ),
NULL );
}
static void
vips_file_init( VipsFile *object )
vips_foreign_init( VipsForeign *object )
{
}
/* To iterate over supported files we build a temp list of subclasses of
* VipsFile, sort by priority, iterate, and free.
* VipsForeign, sort by priority, iterate, and free.
*/
static void *
file_add_class( VipsFileClass *file, GSList **files )
file_add_class( VipsForeignClass *file, GSList **files )
{
/* Append so we don't reverse the list of files.
*/
@ -291,19 +291,19 @@ file_add_class( VipsFileClass *file, GSList **files )
}
static gint
file_compare( VipsFileClass *a, VipsFileClass *b )
file_compare( VipsForeignClass *a, VipsForeignClass *b )
{
return( b->priority - a->priority );
}
/**
* vips_file_map:
* @base: base class to search below (eg. "VipsFileLoad")
* @fn: function to apply to each #VipsFileClass
* vips_foreign_map:
* @base: base class to search below (eg. "VipsForeignLoad")
* @fn: function to apply to each #VipsForeignClass
* @a: user data
* @b: user data
*
* Apply a function to every #VipsFileClass that VIPS knows about. Files
* Apply a function to every #VipsForeignClass that VIPS knows about. Foreigns
* are presented to the function in priority order.
*
* Like all VIPS map functions, if @fn returns %NULL, iteration continues. If
@ -315,7 +315,7 @@ file_compare( VipsFileClass *a, VipsFileClass *b )
* Returns: the result of iteration
*/
void *
vips_file_map( const char *base, VipsSListMap2Fn fn, void *a, void *b )
vips_foreign_map( const char *base, VipsSListMap2Fn fn, void *a, void *b )
{
GSList *files;
void *result;
@ -334,24 +334,24 @@ vips_file_map( const char *base, VipsSListMap2Fn fn, void *a, void *b )
/* Abstract base class for image load.
*/
G_DEFINE_ABSTRACT_TYPE( VipsFileLoad, vips_file_load, VIPS_TYPE_FILE );
G_DEFINE_ABSTRACT_TYPE( VipsForeignLoad, vips_foreign_load, VIPS_TYPE_FOREIGN );
static void
vips_file_load_dispose( GObject *gobject )
vips_foreign_load_dispose( GObject *gobject )
{
VipsFileLoad *load = VIPS_FILE_LOAD( gobject );
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( gobject );
VIPS_UNREF( load->real );
G_OBJECT_CLASS( vips_file_load_parent_class )->dispose( gobject );
G_OBJECT_CLASS( vips_foreign_load_parent_class )->dispose( gobject );
}
static void
vips_file_load_print_class( VipsObjectClass *object_class, VipsBuf *buf )
vips_foreign_load_print_class( VipsObjectClass *object_class, VipsBuf *buf )
{
VipsFileLoadClass *class = VIPS_FILE_LOAD_CLASS( object_class );
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_CLASS( object_class );
VIPS_OBJECT_CLASS( vips_file_load_parent_class )->
VIPS_OBJECT_CLASS( vips_foreign_load_parent_class )->
print_class( object_class, buf );
if( class->is_a )
@ -364,13 +364,13 @@ vips_file_load_print_class( VipsObjectClass *object_class, VipsBuf *buf )
vips_buf_appends( buf, ", load" );
}
/* Can this VipsFile open this file?
/* Can this VipsForeign open this file?
*/
static void *
vips_file_load_new_from_file_sub( VipsFileLoadClass *load_class,
vips_foreign_load_new_from_foreign_sub( VipsForeignLoadClass *load_class,
const char *filename )
{
VipsFileClass *class = VIPS_FILE_CLASS( load_class );
VipsForeignClass *class = VIPS_FOREIGN_CLASS( load_class );
if( load_class->is_a ) {
if( load_class->is_a( filename ) )
@ -383,31 +383,31 @@ vips_file_load_new_from_file_sub( VipsFileLoadClass *load_class,
}
/**
* vips_file_find_load:
* vips_foreign_find_load:
* @filename: file to find a file for
*
* Searches for an operation you could use to load a file.
*
* See also: vips_file_read().
* See also: vips_foreign_read().
*
* Returns: the nmae of an operation on success, %NULL on error
*/
const char *
vips_file_find_load( const char *filename )
vips_foreign_find_load( const char *filename )
{
VipsFileLoadClass *load_class;
VipsForeignLoadClass *load_class;
if( !vips_existsf( "%s", filename ) ) {
vips_error( "VipsFileLoad",
vips_error( "VipsForeignLoad",
_( "file \"%s\" not found" ), filename );
return( NULL );
}
if( !(load_class = (VipsFileLoadClass *) vips_file_map(
"VipsFileLoad",
(VipsSListMap2Fn) vips_file_load_new_from_file_sub,
if( !(load_class = (VipsForeignLoadClass *) vips_foreign_map(
"VipsForeignLoad",
(VipsSListMap2Fn) vips_foreign_load_new_from_foreign_sub,
(void *) filename, NULL )) ) {
vips_error( "VipsFileLoad",
vips_error( "VipsForeignLoad",
_( "file \"%s\" not a known file" ), filename );
return( NULL );
}
@ -416,18 +416,18 @@ vips_file_find_load( const char *filename )
}
static VipsObject *
vips_file_load_new_from_string( const char *string )
vips_foreign_load_new_from_string( const char *string )
{
const char *file_op;
GType type;
VipsFileLoad *load;
VipsForeignLoad *load;
if( !(file_op = vips_file_find_load( string )) )
if( !(file_op = vips_foreign_find_load( string )) )
return( NULL );
type = g_type_from_name( file_op );
g_assert( type );
load = VIPS_FILE_LOAD( g_object_new( type, NULL ) );
load = VIPS_FOREIGN_LOAD( g_object_new( type, NULL ) );
g_object_set( load,
"filename", string,
NULL );
@ -467,10 +467,10 @@ vips_get_disc_threshold( void )
* on the new image.
*/
static void *
vips_file_load_start_cb( VipsImage *out, void *a, void *dummy )
vips_foreign_load_start_cb( VipsImage *out, void *a, void *dummy )
{
VipsFileLoad *load = VIPS_FILE_LOAD( a );
VipsFileLoadClass *class = VIPS_FILE_LOAD_GET_CLASS( a );
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( a );
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( a );
if( !load->real ) {
const size_t disc_threshold = vips_get_disc_threshold();
@ -485,7 +485,7 @@ vips_file_load_start_cb( VipsImage *out, void *a, void *dummy )
*/
if( load->disc &&
disc_threshold &&
(load->flags & VIPS_FILE_PARTIAL) &&
(load->flags & VIPS_FOREIGN_PARTIAL) &&
image_size > disc_threshold )
if( !(load->real = vips_image_new_disc_temp( "%s.v" )) )
return( NULL );
@ -511,7 +511,7 @@ vips_file_load_start_cb( VipsImage *out, void *a, void *dummy )
/* Just pointer-copy.
*/
static int
vips_file_load_generate_cb( VipsRegion *or,
vips_foreign_load_generate_cb( VipsRegion *or,
void *seq, void *a, void *b, gboolean *stop )
{
VipsRegion *ir = (VipsRegion *) seq;
@ -532,10 +532,10 @@ vips_file_load_generate_cb( VipsRegion *or,
}
static int
vips_file_load_build( VipsObject *object )
vips_foreign_load_build( VipsObject *object )
{
VipsFileLoad *load = VIPS_FILE_LOAD( object );
VipsFileLoadClass *class = VIPS_FILE_LOAD_GET_CLASS( object );
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( object );
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( object );
g_object_set( object, "out", vips_image_new(), NULL );
@ -543,7 +543,7 @@ vips_file_load_build( VipsObject *object )
class->get_flags( load ) )
return( -1 );
if( VIPS_OBJECT_CLASS( vips_file_load_parent_class )->
if( VIPS_OBJECT_CLASS( vips_foreign_load_parent_class )->
build( object ) )
return( -1 );
@ -569,8 +569,8 @@ vips_file_load_build( VipsObject *object )
* pixels for @out from @real on demand.
*/
if( vips_image_generate( load->out,
vips_file_load_start_cb,
vips_file_load_generate_cb,
vips_foreign_load_start_cb,
vips_foreign_load_generate_cb,
vips_stop_one,
load, NULL ) )
return( -1 );
@ -580,18 +580,18 @@ vips_file_load_build( VipsObject *object )
}
static void
vips_file_load_class_init( VipsFileLoadClass *class )
vips_foreign_load_class_init( VipsForeignLoadClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
gobject_class->dispose = vips_file_load_dispose;
gobject_class->dispose = vips_foreign_load_dispose;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->build = vips_file_load_build;
object_class->print_class = vips_file_load_print_class;
object_class->new_from_string = vips_file_load_new_from_string;
object_class->build = vips_foreign_load_build;
object_class->print_class = vips_foreign_load_print_class;
object_class->new_from_string = vips_foreign_load_new_from_string;
object_class->nickname = "fileload";
object_class->description = _( "file loaders" );
@ -599,26 +599,26 @@ vips_file_load_class_init( VipsFileLoadClass *class )
_( "Output" ),
_( "Output image" ),
VIPS_ARGUMENT_REQUIRED_OUTPUT,
G_STRUCT_OFFSET( VipsFileLoad, out ) );
G_STRUCT_OFFSET( VipsForeignLoad, out ) );
VIPS_ARG_ENUM( class, "flags", 6,
_( "Flags" ),
_( "Flags for this file" ),
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
G_STRUCT_OFFSET( VipsFileLoad, flags ),
VIPS_TYPE_FILE_FLAGS, VIPS_FILE_NONE );
G_STRUCT_OFFSET( VipsForeignLoad, flags ),
VIPS_TYPE_FOREIGN_FLAGS, VIPS_FOREIGN_NONE );
VIPS_ARG_BOOL( class, "disc", 7,
_( "Disc" ),
_( "Open to disc" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsFileLoad, disc ),
G_STRUCT_OFFSET( VipsForeignLoad, disc ),
TRUE );
}
static void
vips_file_load_init( VipsFileLoad *load )
vips_foreign_load_init( VipsForeignLoad *load )
{
load->disc = TRUE;
}
@ -626,24 +626,24 @@ vips_file_load_init( VipsFileLoad *load )
/* Abstract base class for image savers.
*/
G_DEFINE_ABSTRACT_TYPE( VipsFileSave, vips_file_save, VIPS_TYPE_FILE );
G_DEFINE_ABSTRACT_TYPE( VipsForeignSave, vips_foreign_save, VIPS_TYPE_FOREIGN );
static void
vips_file_save_dispose( GObject *gobject )
vips_foreign_save_dispose( GObject *gobject )
{
VipsFileSave *save = VIPS_FILE_SAVE( gobject );
VipsForeignSave *save = VIPS_FOREIGN_SAVE( gobject );
VIPS_UNREF( save->ready );
G_OBJECT_CLASS( vips_file_save_parent_class )->dispose( gobject );
G_OBJECT_CLASS( vips_foreign_save_parent_class )->dispose( gobject );
}
static void
vips_file_save_print_class( VipsObjectClass *object_class, VipsBuf *buf )
vips_foreign_save_print_class( VipsObjectClass *object_class, VipsBuf *buf )
{
VipsFileSaveClass *class = VIPS_FILE_SAVE_CLASS( object_class );
VipsForeignSaveClass *class = VIPS_FOREIGN_SAVE_CLASS( object_class );
VIPS_OBJECT_CLASS( vips_file_save_parent_class )->
VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )->
print_class( object_class, buf );
vips_buf_appendf( buf, ", %s",
@ -653,10 +653,10 @@ vips_file_save_print_class( VipsObjectClass *object_class, VipsBuf *buf )
/* Can we write this filename with this file?
*/
static void *
vips_file_save_new_from_filename_sub( VipsFileSaveClass *save_class,
vips_foreign_save_new_from_foreignname_sub( VipsForeignSaveClass *save_class,
const char *filename )
{
VipsFileClass *class = VIPS_FILE_CLASS( save_class );
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
if( vips_filename_suffix_match( filename, class->suffs ) )
return( save_class );
@ -665,25 +665,25 @@ vips_file_save_new_from_filename_sub( VipsFileSaveClass *save_class,
}
/**
* vips_file_find_save:
* vips_foreign_find_save:
* @filename: name to find a file for
*
* Searches for an operation you could use to save a file.
*
* See also: vips_file_write().
* See also: vips_foreign_write().
*
* Returns: the name of an operation on success, %NULL on error
*/
const char *
vips_file_find_save( const char *filename )
vips_foreign_find_save( const char *filename )
{
VipsFileSaveClass *save_class;
VipsForeignSaveClass *save_class;
if( !(save_class = (VipsFileSaveClass *) vips_file_map(
"VipsFileSave",
(VipsSListMap2Fn) vips_file_save_new_from_filename_sub,
if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
"VipsForeignSave",
(VipsSListMap2Fn) vips_foreign_save_new_from_foreignname_sub,
(void *) filename, NULL )) ) {
vips_error( "VipsFileSave",
vips_error( "VipsForeignSave",
_( "\"%s\" is not a supported image file." ),
filename );
@ -694,18 +694,18 @@ vips_file_find_save( const char *filename )
}
static VipsObject *
vips_file_save_new_from_string( const char *string )
vips_foreign_save_new_from_string( const char *string )
{
const char *file_op;
GType type;
VipsFileSave *save;
VipsForeignSave *save;
if( !(file_op = vips_file_find_save( string )) )
if( !(file_op = vips_foreign_find_save( string )) )
return( NULL );
type = g_type_from_name( file_op );
g_assert( type );
save = VIPS_FILE_SAVE( g_object_new( type, NULL ) );
save = VIPS_FOREIGN_SAVE( g_object_new( type, NULL ) );
g_object_set( save,
"filename", string,
NULL );
@ -716,9 +716,9 @@ vips_file_save_new_from_string( const char *string )
/* Generate the saveable image.
*/
static int
vips_file_convert_saveable( VipsFileSave *save )
vips_foreign_convert_saveable( VipsForeignSave *save )
{
VipsFileSaveClass *class = VIPS_FILE_SAVE_GET_CLASS( save );
VipsForeignSaveClass *class = VIPS_FOREIGN_SAVE_GET_CLASS( save );
VipsImage *in = save->in;
/* in holds a reference to the output of our chain as we build it.
@ -910,14 +910,14 @@ vips_file_convert_saveable( VipsFileSave *save )
}
static int
vips_file_save_build( VipsObject *object )
vips_foreign_save_build( VipsObject *object )
{
VipsFileSave *save = VIPS_FILE_SAVE( object );
VipsForeignSave *save = VIPS_FOREIGN_SAVE( object );
if( vips_file_convert_saveable( save ) )
if( vips_foreign_convert_saveable( save ) )
return( -1 );
if( VIPS_OBJECT_CLASS( vips_file_save_parent_class )->
if( VIPS_OBJECT_CLASS( vips_foreign_save_parent_class )->
build( object ) )
return( -1 );
@ -925,18 +925,18 @@ vips_file_save_build( VipsObject *object )
}
static void
vips_file_save_class_init( VipsFileSaveClass *class )
vips_foreign_save_class_init( VipsForeignSaveClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
gobject_class->dispose = vips_file_save_dispose;
gobject_class->dispose = vips_foreign_save_dispose;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->build = vips_file_save_build;
object_class->print_class = vips_file_save_print_class;
object_class->new_from_string = vips_file_save_new_from_string;
object_class->build = vips_foreign_save_build;
object_class->print_class = vips_foreign_save_print_class;
object_class->new_from_string = vips_foreign_save_new_from_string;
object_class->nickname = "filesave";
object_class->description = _( "file savers" );
@ -944,35 +944,35 @@ vips_file_save_class_init( VipsFileSaveClass *class )
_( "Input" ),
_( "Image to save" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsFileSave, in ) );
G_STRUCT_OFFSET( VipsForeignSave, in ) );
}
static void
vips_file_save_init( VipsFileSave *object )
vips_foreign_save_init( VipsForeignSave *object )
{
}
/**
* vips_file_read:
* vips_foreign_read:
* @filename: file to load
* @out: output image
* @...: %NULL-terminated list of optional named arguments
*
* Loads @filename into @out using the loader recommended by
* vips_file_find_load().
* vips_foreign_find_load().
*
* See also: vips_file_write().
* See also: vips_foreign_write().
*
* Returns: 0 on success, -1 on error
*/
int
vips_file_read( const char *filename, VipsImage **out, ... )
vips_foreign_read( const char *filename, VipsImage **out, ... )
{
const char *operation;
va_list ap;
int result;
if( !(operation = vips_file_find_load( filename )) )
if( !(operation = vips_foreign_find_load( filename )) )
return( -1 );
va_start( ap, out );
@ -983,25 +983,25 @@ vips_file_read( const char *filename, VipsImage **out, ... )
}
/**
* vips_file_write:
* vips_foreign_write:
* @in: image to write
* @filename: file to write to
*
* Saves @in to @filename using the saver recommended by
* vips_file_find_save().
* vips_foreign_find_save().
*
* See also: vips_file_read().
* See also: vips_foreign_read().
*
* Returns: 0 on success, -1 on error
*/
int
vips_file_write( VipsImage *in, const char *filename, ... )
vips_foreign_write( VipsImage *in, const char *filename, ... )
{
const char *operation;
va_list ap;
int result;
if( !(operation = vips_file_find_save( filename )) )
if( !(operation = vips_foreign_find_save( filename )) )
return( -1 );
va_start( ap, filename );
@ -1015,17 +1015,17 @@ vips_file_write( VipsImage *in, const char *filename, ... )
* instead?
*/
void
vips_file_operation_init( void )
vips_foreign_operation_init( void )
{
extern GType vips_file_load_jpeg_get_type( void );
extern GType vips_file_save_jpeg_get_type( void );
extern GType vips_file_load_vips_get_type( void );
extern GType vips_file_save_vips_get_type( void );
extern GType vips_foreign_load_jpeg_get_type( void );
extern GType vips_foreign_save_jpeg_get_type( void );
extern GType vips_foreign_load_vips_get_type( void );
extern GType vips_foreign_save_vips_get_type( void );
#ifdef HAVE_JPEG
vips_file_load_jpeg_get_type();
vips_file_save_jpeg_get_type();
vips_foreign_load_jpeg_get_type();
vips_foreign_save_jpeg_get_type();
#endif /*HAVE_JPEG*/
vips_file_load_vips_get_type();
vips_file_save_vips_get_type();
vips_foreign_load_vips_get_type();
vips_foreign_save_vips_get_type();
}

View File

@ -303,7 +303,7 @@ attach_exif_entry( ExifEntry *entry, VipsExif *ve )
/* Can't do anything sensible with the error return.
*/
(void) im_meta_set_string( ve->image,
(void) vips_image_set_string( ve->image,
vips_buf_all( &name ), vips_buf_all( &value ) );
}
@ -366,7 +366,7 @@ set_vips_resolution( IMAGE *im, ExifData *ed )
if( get_entry_rational( ed, EXIF_TAG_X_RESOLUTION, &xres ) ||
get_entry_rational( ed, EXIF_TAG_Y_RESOLUTION, &yres ) ||
get_entry_short( ed, EXIF_TAG_RESOLUTION_UNIT, &unit ) ) {
im_warn( "im_jpeg2vips",
vips_warn( "VipsJpeg",
"%s", _( "error reading resolution" ) );
return;
}
@ -387,7 +387,7 @@ set_vips_resolution( IMAGE *im, ExifData *ed )
break;
default:
im_warn( "im_jpeg2vips", "%s", _( "bad resolution unit" ) );
vips_warn( "VipsJpeg", "%s", _( "bad resolution unit" ) );
return;
}
@ -401,14 +401,11 @@ attach_thumbnail( IMAGE *im, ExifData *ed )
if( ed->size > 0 ) {
char *thumb_copy;
thumb_copy = im_malloc( NULL, ed->size );
thumb_copy = g_malloc( ed->size );
memcpy( thumb_copy, ed->data, ed->size );
if( im_meta_set_blob( im, "jpeg-thumbnail-data",
(im_callback_fn) im_free, thumb_copy, ed->size ) ) {
im_free( thumb_copy );
return( -1 );
}
vips_image_set_blob( im, "jpeg-thumbnail-data",
(VipsCallbackFn) g_free, thumb_copy, ed->size );
}
return( 0 );
@ -422,7 +419,7 @@ read_exif( IMAGE *im, void *data, int data_length )
/* Only use the first one.
*/
if( im_header_get_typeof( im, IM_META_EXIF_NAME ) ) {
if( vips_image_get_typeof( im, VIPS_META_EXIF_NAME ) ) {
#ifdef DEBUG
printf( "read_exif: second EXIF block, ignoring\n" );
#endif /*DEBUG*/
@ -436,14 +433,11 @@ read_exif( IMAGE *im, void *data, int data_length )
/* Always attach a copy of the unparsed exif data.
*/
if( !(data_copy = im_malloc( NULL, data_length )) )
if( !(data_copy = vips_malloc( NULL, data_length )) )
return( -1 );
memcpy( data_copy, data, data_length );
if( im_meta_set_blob( im, IM_META_EXIF_NAME,
(im_callback_fn) im_free, data_copy, data_length ) ) {
im_free( data_copy );
return( -1 );
}
vips_image_set_blob( im, VIPS_META_EXIF_NAME,
(VipsCallbackFn) vips_free, data_copy, data_length );
#ifdef HAVE_EXIF
{
@ -490,13 +484,13 @@ read_exif( IMAGE *im, void *data, int data_length )
}
static int
read_xmp( IMAGE *im, void *data, int data_length )
read_xmp( IMAGE *im, void *data, size_t data_length )
{
char *data_copy;
/* XMP sections start "http". Only use the first one.
*/
if( im_header_get_typeof( im, VIPS_META_XMP_NAME ) ) {
if( vips_image_get_typeof( im, VIPS_META_XMP_NAME ) ) {
#ifdef DEBUG
printf( "read_xmp: second XMP block, ignoring\n" );
#endif /*DEBUG*/
@ -510,14 +504,11 @@ read_xmp( IMAGE *im, void *data, int data_length )
/* Always attach a copy of the unparsed exif data.
*/
if( !(data_copy = im_malloc( NULL, data_length )) )
if( !(data_copy = vips_malloc( NULL, data_length )) )
return( -1 );
memcpy( data_copy, data, data_length );
if( im_meta_set_blob( im, VIPS_META_XMP_NAME,
(im_callback_fn) im_free, data_copy, data_length ) ) {
im_free( data_copy );
return( -1 );
}
vips_image_set_blob( im, VIPS_META_XMP_NAME,
(VipsCallbackFn) vips_free, data_copy, data_length );
return( 0 );
}
@ -535,13 +526,13 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
IMAGE *out, gboolean *invert_pels, int shrink )
{
jpeg_saved_marker_ptr p;
int type;
VipsInterpretation interpretation;
/* Capture app2 sections here for assembly.
*/
void *app2_data[MAX_APP2_SECTIONS] = { 0 };
int app2_data_length[MAX_APP2_SECTIONS] = { 0 };
int data_length;
size_t app2_data_length[MAX_APP2_SECTIONS] = { 0 };
size_t data_length;
int i;
/* Read JPEG header. libjpeg will set out_color_space sanely for us
@ -555,11 +546,11 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
*invert_pels = FALSE;
switch( cinfo->out_color_space ) {
case JCS_GRAYSCALE:
type = IM_TYPE_B_W;
interpretation = VIPS_INTERPRETATION_B_W;
break;
case JCS_CMYK:
type = IM_TYPE_CMYK;
interpretation = VIPS_INTERPRETATION_CMYK;
/* Photoshop writes CMYK JPEG inverted :-( Maybe this is a
* way to spot photoshop CMYK JPGs.
*/
@ -569,22 +560,23 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
case JCS_RGB:
default:
type = IM_TYPE_sRGB;
interpretation = VIPS_INTERPRETATION_sRGB;
break;
}
/* Set VIPS header.
*/
im_initdesc( out,
vips_image_init_fields( out,
cinfo->output_width, cinfo->output_height,
cinfo->output_components,
IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, type,
1.0, 1.0, 0, 0 );
VIPS_FORMAT_UCHAR, VIPS_CODING_NONE,
interpretation,
1.0, 1.0 );
/* Interlaced jpegs need lots of memory to read, so our caller needs
* to know.
*/
(void) im_meta_set_int( out, "jpeg-multiscan",
(void) vips_image_set_int( out, "jpeg-multiscan",
jpeg_has_multiple_scans( cinfo ) );
/* Look for EXIF and ICC profile.
@ -609,12 +601,12 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
/* Possible EXIF or XMP data.
*/
if( p->data_length > 4 &&
im_isprefix( "Exif", (char *) p->data ) &&
vips_isprefix( "Exif", (char *) p->data ) &&
read_exif( out, p->data, p->data_length ) )
return( -1 );
if( p->data_length > 4 &&
im_isprefix( "http", (char *) p->data ) &&
vips_isprefix( "http", (char *) p->data ) &&
read_xmp( out, p->data, p->data_length ) )
return( -1 );
@ -624,7 +616,7 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
/* ICC profile.
*/
if( p->data_length > 14 &&
im_isprefix( "ICC_PROFILE",
vips_isprefix( "ICC_PROFILE",
(char *) p->data ) ) {
/* cur_marker numbers from 1, according to
* spec.
@ -659,7 +651,7 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
data_length );
#endif /*DEBUG*/
if( !(data = im_malloc( NULL, data_length )) )
if( !(data = vips_malloc( NULL, data_length )) )
return( -1 );
p = 0;
@ -668,11 +660,8 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo,
p += app2_data_length[i];
}
if( im_meta_set_blob( out, IM_META_ICC_NAME,
(im_callback_fn) im_free, data, data_length ) ) {
im_free( data );
return( -1 );
}
vips_image_set_blob( out, VIPS_META_ICC_NAME,
(VipsCallbackFn) vips_free, data, data_length );
}
return( 0 );
@ -689,7 +678,7 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out,
/* Check VIPS.
*/
if( im_outcheck( out ) || im_setupout( out ) )
if( vips_image_wio_output( out ) )
return( -1 );
/* Get size of output line and make a buffer.
@ -714,7 +703,7 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out,
for( x = 0; x < sz; x++ )
row_pointer[0][x] = 255 - row_pointer[0][x];
}
if( im_writeline( y, out, row_pointer[0] ) )
if( vips_image_write_line( out, y, row_pointer[0] ) )
return( -1 );
}
@ -728,8 +717,8 @@ read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out,
/* Read a JPEG file into a VIPS image.
*/
int
vips__jpeg_read_file( const char *name, VipsImage *out, gboolean header_only,
int shrink, gboolean fail )
vips__jpeg_read_file( const char *filename, VipsImage *out,
gboolean header_only, int shrink, gboolean fail )
{
struct jpeg_decompress_struct cinfo;
ErrorManager eman;
@ -754,7 +743,7 @@ vips__jpeg_read_file( const char *name, VipsImage *out, gboolean header_only,
/* Make input.
*/
if( !(fp = im__file_open_read( name, NULL, FALSE )) )
if( !(fp = vips__file_open_read( filename, NULL, FALSE )) )
return( -1 );
eman.fp = fp;
jpeg_stdio_src( &cinfo, fp );
@ -778,13 +767,14 @@ vips__jpeg_read_file( const char *name, VipsImage *out, gboolean header_only,
if( eman.pub.num_warnings != 0 ) {
if( fail ) {
im_error( "im_jpeg2vips", "%s", im_error_buffer() );
vips_error( "VipsJpeg", "%s", vips_error_buffer() );
result = -1;
}
else {
im_warn( "im_jpeg2vips", _( "read gave %ld warnings" ),
vips_warn( "VipsJpeg",
_( "read gave %ld warnings" ),
eman.pub.num_warnings );
im_warn( "im_jpeg2vips", "%s", im_error_buffer() );
vips_warn( "VipsJpeg", "%s", vips_error_buffer() );
}
}
@ -965,8 +955,7 @@ buf_source (j_decompress_ptr cinfo, void *buf, size_t len)
int
vips__jpeg_read_buffer( void *buf, size_t len, VipsImage *out,
gboolean header_only,
int shrink, int fail )
gboolean header_only, int shrink, int fail )
{
struct jpeg_decompress_struct cinfo;
ErrorManager eman;

View File

@ -1,7 +1,46 @@
/* save to jpeg
/* load jpeg from a file
*
* 28/11/03 JC
* - better no-overshoot on tile loop
* 12/11/04
* - better demand size choice for eval
* 30/6/05 JC
* - update im_error()/im_warn()
* - now loads and saves exif data
* 30/7/05
* - now loads ICC profiles
* - now saves ICC profiles from the VIPS header
* 24/8/05
* - jpeg load sets vips xres/yres from exif, if possible
* - jpeg save sets exif xres/yres from vips, if possible
* 29/8/05
* - cut from old vips_jpeg.c
* 13/10/06
* - add </libexif/ prefix if required
* 11/2/08
* - spot CMYK jpegs and set Type
* - spot Adobe CMYK JPEG and invert ink density
* 15/2/08
* - added "shrink" parameter
* 16/6/09
* - added "fail" option ... fail on any warnings
* 12/10/09
* - also set scale_num on shrink (thanks Guido)
* 4/2/10
* - gtkdoc
* 4/12/10
* - attach the jpeg thumbnail and multiscan fields (thanks Mike)
* 21/2/10
* - only accept the first APP1 block which starts "Exif..." as exif
* data, some jpegs seem to have several APP1s, argh
* 20/4/2011
* - added im_bufjpeg2vips()
* 12/10/2011
* - read XMP data
* 3/11/11
* - attach exif tags as coded values
* 24/11/11
* - wrap a class around the jpeg reader
* - redo as a class
*/
/*
@ -75,8 +114,8 @@
#include "jpeg.h"
typedef struct _VipsFileLoadJpeg {
VipsFileLoad parent_object;
typedef struct _VipsForeignLoadJpeg {
VipsForeignLoad parent_object;
/* Shrink by this much during load.
*/
@ -86,16 +125,21 @@ typedef struct _VipsFileLoadJpeg {
*/
gboolean fail;
} VipsFileLoadJpeg;
/* For some jpeg CMYK formats we have to invert pels on read.
*/
gboolean invert_pels;
typedef VipsFileLoadClass VipsFileLoadJpegClass;
} VipsForeignLoadJpeg;
G_DEFINE_TYPE( VipsFileLoadJpeg, vips_file_load_jpeg, VIPS_TYPE_FILE_LOAD );
typedef VipsForeignLoadClass VipsForeignLoadJpegClass;
G_DEFINE_TYPE( VipsForeignLoadJpeg, vips_foreign_load_jpeg,
VIPS_TYPE_FOREIGN_LOAD );
static int
vips_file_load_jpeg_build( VipsObject *object )
vips_foreign_load_jpeg_build( VipsObject *object )
{
VipsFileLoadJpeg *jpeg = (VipsFileLoadJpeg *) object;
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) object;
if( jpeg->shrink != 1 &&
jpeg->shrink != 2 &&
@ -106,22 +150,28 @@ vips_file_load_jpeg_build( VipsObject *object )
return( -1 );
}
if( VIPS_OBJECT_CLASS( vips_file_load_jpeg_parent_class )->
if( VIPS_OBJECT_CLASS( vips_foreign_load_jpeg_parent_class )->
build( object ) )
return( -1 );
return( 0 );
}
static gboolean
vips_foreign_load_jpeg_is_a( const char *filename )
{
return( vips__isjpeg( filename ) );
}
/* Read just the image header into ->out.
*/
static int
vips_file_load_jpeg_header( VipsFileLoad *load )
vips_foreign_load_jpeg_header( VipsForeignLoad *load )
{
VipsFile *file = VIPS_FILE( load );
VipsFileLoadJpeg *jpeg = (VipsFileLoadJpeg *) load;
VipsForeign *foreign = VIPS_FOREIGN( load );
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
if( vips__jpeg_read_file( file->filename, load->out,
if( vips__jpeg_read_file( foreign->filename, load->out,
TRUE, jpeg->shrink, jpeg->fail ) )
return( -1 );
@ -129,56 +179,58 @@ vips_file_load_jpeg_header( VipsFileLoad *load )
}
static int
vips_file_load_jpeg_load( VipsFileLoad *load )
vips_foreign_load_jpeg_load( VipsForeignLoad *load )
{
VipsFile *file = VIPS_FILE( load );
VipsFileLoadJpeg *jpeg = (VipsFileLoadJpeg *) load;
VipsForeign *foreign = VIPS_FOREIGN( load );
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
if( vips__jpeg_read_file( file->filename, load->real,
if( vips__jpeg_read_file( foreign->filename, load->real,
FALSE, jpeg->shrink, jpeg->fail ) )
return( -1 );
return( 0 );
}
static const char *jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL };
static void
vips_file_load_jpeg_class_init( VipsFileLoadJpegClass *class )
vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFileClass *file_class = (VipsFileClass *) class;
VipsFileLoadClass *load_class = (VipsFileLoadClass *) class;
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "jpegload";
object_class->description = _( "load jpeg from file" );
object_class->build = vips_file_load_jpeg_build;
object_class->build = vips_foreign_load_jpeg_build;
file_class->suffs = vips__jpeg_suffs;
foreign_class->suffs = jpeg_suffs;
load_class->is_a = vips__isjpeg;
load_class->header = vips_file_load_jpeg_header;
load_class->load = vips_file_load_jpeg_load;
load_class->is_a = vips_foreign_load_jpeg_is_a;
load_class->header = vips_foreign_load_jpeg_header;
load_class->load = vips_foreign_load_jpeg_load;
VIPS_ARG_INT( class, "shrink", 10,
_( "Shrink" ),
_( "Shrink factor on load" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsFileLoadJpeg, shrink ),
G_STRUCT_OFFSET( VipsForeignLoadJpeg, shrink ),
1, 16, 1 );
VIPS_ARG_BOOL( class, "fail", 11,
_( "Fail" ),
_( "Fail on first warning" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsFileLoadJpeg, fail ),
G_STRUCT_OFFSET( VipsForeignLoadJpeg, fail ),
FALSE );
}
static void
vips_file_load_jpeg_init( VipsFileLoadJpeg *jpeg )
vips_foreign_load_jpeg_init( VipsForeignLoadJpeg *jpeg )
{
jpeg->shrink = 1;
}

View File

@ -75,8 +75,8 @@
#include "jpeg.h"
typedef struct _VipsFileSaveJpeg {
VipsFileSave parent_object;
typedef struct _VipsForeignSaveJpeg {
VipsForeignSave parent_object;
/* Quality factor.
*/
@ -86,25 +86,24 @@ typedef struct _VipsFileSaveJpeg {
*/
char *profile;
} VipsFileSaveJpeg;
} VipsForeignSaveJpeg;
typedef VipsFileSaveClass VipsFileSaveJpegClass;
typedef VipsForeignSaveClass VipsForeignSaveJpegClass;
G_DEFINE_TYPE( VipsFileSaveJpeg, vips_file_save_jpeg, VIPS_TYPE_FILE_SAVE );
G_DEFINE_TYPE( VipsForeignSaveJpeg, vips_foreign_save_jpeg, VIPS_TYPE_FOREIGN_SAVE );
static int
vips_file_save_jpeg_build( VipsObject *object )
vips_foreign_save_jpeg_build( VipsObject *object )
{
VipsFile *file = (VipsFile *) object;
VipsFileSave *save = (VipsFileSave *) object;
VipsFileSaveJpeg *jpeg = (VipsFileSaveJpeg *) object;
VipsForeign *foreign = (VipsForeign *) object;
VipsForeignSave *save = (VipsForeignSave *) object;
VipsForeignSaveJpeg *jpeg = (VipsForeignSaveJpeg *) object;
if( VIPS_OBJECT_CLASS( vips_file_save_jpeg_parent_class )->
if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_parent_class )->
build( object ) )
return( -1 );
// ->ready loses a ref suring the write??
if( vips__jpeg_write_file( save->ready, file->filename,
if( vips__jpeg_write_file( save->ready, foreign->filename,
jpeg->Q, jpeg->profile ) )
return( -1 );
@ -121,21 +120,21 @@ static int bandfmt_jpeg[10] = {
};
static void
vips_file_save_jpeg_class_init( VipsFileSaveJpegClass *class )
vips_foreign_save_jpeg_class_init( VipsForeignSaveJpegClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFileClass *file_class = (VipsFileClass *) class;
VipsFileSaveClass *save_class = (VipsFileSaveClass *) class;
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "jpegsave";
object_class->description = _( "save image to jpeg file" );
object_class->build = vips_file_save_jpeg_build;
object_class->build = vips_foreign_save_jpeg_build;
file_class->suffs = vips__jpeg_suffs;
foreign_class->suffs = vips__jpeg_suffs;
save_class->saveable = VIPS_SAVEABLE_RGB_CMYK;
save_class->format_table = bandfmt_jpeg;
@ -144,19 +143,19 @@ vips_file_save_jpeg_class_init( VipsFileSaveJpegClass *class )
_( "Q" ),
_( "Q factor" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsFileSaveJpeg, Q ),
G_STRUCT_OFFSET( VipsForeignSaveJpeg, Q ),
1, 100, 75 );
VIPS_ARG_STRING( class, "profile", 11,
_( "profile" ),
_( "ICC profile to embed" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsFileSaveJpeg, profile ),
G_STRUCT_OFFSET( VipsForeignSaveJpeg, profile ),
NULL );
}
static void
vips_file_save_jpeg_init( VipsFileSaveJpeg *jpeg )
vips_foreign_save_jpeg_init( VipsForeignSaveJpeg *jpeg )
{
jpeg->Q = 75;
}

View File

@ -851,8 +851,8 @@ typedef struct _Block {
struct _Block *next;
JOCTET *data; /* Allocated area */
int size; /* Max size */
int used; /* How much has been used */
size_t size; /* Max size */
size_t used; /* How much has been used */
} Block;
static Block *
@ -897,10 +897,10 @@ block_append( Block *block )
return( new );
}
static int
static size_t
block_length( Block *block )
{
int len;
size_t len;
len = 0;
for( block = block->first; block; block = block->next )

View File

@ -44,42 +44,42 @@
#include <vips/vips.h>
#include <vips/internal.h>
typedef VipsFileLoad VipsFileLoadVips;
typedef VipsFileLoadClass VipsFileLoadVipsClass;
typedef VipsForeignLoad VipsForeignLoadVips;
typedef VipsForeignLoadClass VipsForeignLoadVipsClass;
G_DEFINE_TYPE( VipsFileLoadVips, vips_file_load_vips, VIPS_TYPE_FILE_LOAD );
G_DEFINE_TYPE( VipsForeignLoadVips, vips_foreign_load_vips, VIPS_TYPE_FOREIGN_LOAD );
static gboolean
vips_file_load_vips_is_a( const char *filename )
vips_foreign_load_vips_is_a( const char *filename )
{
return( vips__file_magic( filename ) );
}
static int
vips_file_load_vips_get_flags( VipsFileLoad *load )
vips_foreign_load_vips_get_flags( VipsForeignLoad *load )
{
VipsFile *file = VIPS_FILE( load );
VipsForeign *foreign = VIPS_FOREIGN( load );
load->flags = VIPS_FILE_PARTIAL;
load->flags = VIPS_FOREIGN_PARTIAL;
if( vips__file_magic( file->filename ) == VIPS_MAGIC_INTEL ) {
printf( "vips_file_load_vips_get_flags: "
if( vips__file_magic( foreign->filename ) == VIPS_MAGIC_INTEL ) {
printf( "vips_foreign_load_vips_get_flags: "
"%s is intel, setting bigendian\n",
file->filename );
load->flags |= VIPS_FILE_BIGENDIAN;
foreign->filename );
load->flags |= VIPS_FOREIGN_BIGENDIAN;
}
return( 0 );
}
static int
vips_file_load_vips_header( VipsFileLoad *load )
vips_foreign_load_vips_header( VipsForeignLoad *load )
{
VipsFile *file = VIPS_FILE( load );
VipsForeign *foreign = VIPS_FOREIGN( load );
VipsImage *out;
VipsImage *out2;
if( !(out2 = vips_image_new_from_file( file->filename )) )
if( !(out2 = vips_image_new_from_file( foreign->filename )) )
return( -1 );
/* Remove the @out that's there now.
@ -96,25 +96,25 @@ vips_file_load_vips_header( VipsFileLoad *load )
static const char *vips_suffs[] = { ".v", NULL };
static void
vips_file_load_vips_class_init( VipsFileLoadVipsClass *class )
vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class )
{
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFileClass *file_class = (VipsFileClass *) class;
VipsFileLoadClass *load_class = (VipsFileLoadClass *) class;
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
object_class->nickname = "vipsload";
object_class->description = _( "load vips from file" );
file_class->suffs = vips_suffs;
foreign_class->suffs = vips_suffs;
load_class->is_a = vips_file_load_vips_is_a;
load_class->get_flags = vips_file_load_vips_get_flags;
load_class->header = vips_file_load_vips_header;
load_class->is_a = vips_foreign_load_vips_is_a;
load_class->get_flags = vips_foreign_load_vips_get_flags;
load_class->header = vips_foreign_load_vips_header;
load_class->load = NULL;
}
static void
vips_file_load_vips_init( VipsFileLoadVips *vips )
vips_foreign_load_vips_init( VipsForeignLoadVips *vips )
{
}

View File

@ -46,22 +46,23 @@
#include <vips/vips.h>
typedef VipsFileSave VipsFileSaveVips;
typedef VipsFileSaveClass VipsFileSaveVipsClass;
typedef VipsForeignSave VipsForeignSaveVips;
typedef VipsForeignSaveClass VipsForeignSaveVipsClass;
G_DEFINE_TYPE( VipsFileSaveVips, vips_file_save_vips, VIPS_TYPE_FILE_SAVE );
G_DEFINE_TYPE( VipsForeignSaveVips, vips_foreign_save_vips,
VIPS_TYPE_FOREIGN_SAVE );
static int
vips_file_save_vips_build( VipsObject *object )
vips_foreign_save_vips_build( VipsObject *object )
{
VipsFile *file = (VipsFile *) object;
VipsFileSave *save = (VipsFileSave *) object;
VipsForeign *foreign = (VipsForeign *) object;
VipsForeignSave *save = (VipsForeignSave *) object;
if( VIPS_OBJECT_CLASS( vips_file_save_vips_parent_class )->
if( VIPS_OBJECT_CLASS( vips_foreign_save_vips_parent_class )->
build( object ) )
return( -1 );
if( vips_image_write_to_file( save->ready, file->filename ) )
if( vips_image_write_to_file( save->ready, foreign->filename ) )
return( -1 );
return( 0 );
@ -91,24 +92,24 @@ static int vips_bandfmt_vips[10] = {
static const char *vips_suffs[] = { ".v", NULL };
static void
vips_file_save_vips_class_init( VipsFileSaveVipsClass *class )
vips_foreign_save_vips_class_init( VipsForeignSaveVipsClass *class )
{
VipsObjectClass *object_class = (VipsObjectClass *) class;
VipsFileClass *file_class = (VipsFileClass *) class;
VipsFileSaveClass *save_class = (VipsFileSaveClass *) class;
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
object_class->nickname = "vipssave";
object_class->description = _( "save image to vips file" );
object_class->build = vips_file_save_vips_build;
object_class->build = vips_foreign_save_vips_build;
file_class->suffs = vips_suffs;
foreign_class->suffs = vips_suffs;
save_class->saveable = VIPS_SAVEABLE_ANY;
save_class->format_table = vips_bandfmt_vips;
}
static void
vips_file_save_vips_init( VipsFileSaveVips *vips )
vips_foreign_save_vips_init( VipsForeignSaveVips *vips )
{
}

View File

@ -14,7 +14,7 @@ pkginclude_HEADERS = \
error.h \
operation.h \
format.h \
file.h \
foreign.h \
inplace.h \
generate.h \
header.h \
@ -57,7 +57,7 @@ EXTRA_DIST = version.h.in internal.h enumtemplate
# well
vips_scan_headers = \
${top_srcdir}/libvips/include/vips/memory.h \
${top_srcdir}/libvips/include/vips/file.h \
${top_srcdir}/libvips/include/vips/foreign.h \
${top_srcdir}/libvips/include/vips/arithmetic.h \
${top_srcdir}/libvips/include/vips/conversion.h \
${top_srcdir}/libvips/include/vips/util.h \

View File

@ -6,9 +6,9 @@
G_BEGIN_DECLS
/* enumerations from "../../../libvips/include/vips/file.h" */
GType vips_file_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FILE_FLAGS (vips_file_flags_get_type())
/* enumerations from "../../../libvips/include/vips/foreign.h" */
GType vips_foreign_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_FOREIGN_FLAGS (vips_foreign_flags_get_type())
GType vips_saveable_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_SAVEABLE (vips_saveable_get_type())
/* enumerations from "../../../libvips/include/vips/arithmetic.h" */

View File

@ -1,239 +0,0 @@
/* Base type for supported image files. Subclass this to add a new
* file.
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef VIPS_FILE_H
#define VIPS_FILE_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#define VIPS_TYPE_FILE (vips_file_get_type())
#define VIPS_FILE( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FILE, VipsFile ))
#define VIPS_FILE_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FILE, VipsFileClass))
#define VIPS_IS_FILE( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FILE ))
#define VIPS_IS_FILE_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FILE ))
#define VIPS_FILE_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FILE, VipsFileClass ))
typedef struct _VipsFile {
VipsOperation parent_object;
/*< public >*/
/* Filename for load or save.
*/
char *filename;
} VipsFile;
typedef struct _VipsFileClass {
VipsOperationClass parent_class;
/*< public >*/
/* Loop over files in this order, default 0. We need this because
* some files can be read by several loaders (eg. tiff can be read
* by the libMagick loader as well as by the tiff loader), and we want
* to make sure the better loader comes first.
*/
int priority;
/* Null-terminated list of recommended suffixes, eg. ".tif", ".tiff".
* This can be used by both load and save, so it's in the base class.
*/
const char **suffs;
} VipsFileClass;
GType vips_file_get_type( void );
/* Map over and find files. This uses type introspection to loop over
* subclasses of VipsFile.
*/
void *vips_file_map( const char *base, VipsSListMap2Fn fn, void *a, void *b );
#define VIPS_TYPE_FILE_LOAD (vips_file_load_get_type())
#define VIPS_FILE_LOAD( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FILE_LOAD, VipsFileLoad ))
#define VIPS_FILE_LOAD_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FILE_LOAD, VipsFileLoadClass))
#define VIPS_IS_FILE_LOAD( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FILE_LOAD ))
#define VIPS_IS_FILE_LOAD_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FILE_LOAD ))
#define VIPS_FILE_LOAD_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FILE_LOAD, VipsFileLoadClass ))
/* Image file properties.
*/
typedef enum {
VIPS_FILE_NONE = 0, /* No flags set */
VIPS_FILE_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */
VIPS_FILE_BIGENDIAN = 2 /* Most-significant byte first */
} VipsFileFlags;
typedef struct _VipsFileLoad {
VipsFile parent_object;
/*< public >*/
/* Open to disc (default is to open to memory).
*/
gboolean disc;
/* Flags read from the file.
*/
VipsFileFlags flags;
/* The image we generate.
*/
VipsImage *out;
/* The behind-the-scenes real image we decompress to. This can be a
* disc file or a memory buffer.
*/
VipsImage *real;
} VipsFileLoad;
typedef struct _VipsFileLoadClass {
VipsFileClass parent_class;
/*< public >*/
/* Is a file in this format.
*/
gboolean (*is_a)( const char * );
/* Get the flags for this file. NULL means 0, ie. no flags.
*/
int (*get_flags)( VipsFileLoad * );
/* Set the header fields in @out from @filename. If you can read the
* whole image as well with no performance cost (as with vipsload),
* leave ->load() NULL and only @header will be used.
*/
int (*header)( VipsFileLoad * );
/* Read the whole image into @real. It gets copied to @out later.
*/
int (*load)( VipsFileLoad * );
} VipsFileLoadClass;
GType vips_file_load_get_type( void );
const char *vips_file_find_load( const char *filename );
#define VIPS_TYPE_FILE_SAVE (vips_file_save_get_type())
#define VIPS_FILE_SAVE( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FILE_SAVE, VipsFileSave ))
#define VIPS_FILE_SAVE_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FILE_SAVE, VipsFileSaveClass))
#define VIPS_IS_FILE_SAVE( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FILE_SAVE ))
#define VIPS_IS_FILE_SAVE_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FILE_SAVE ))
#define VIPS_FILE_SAVE_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FILE_SAVE, VipsFileSaveClass ))
/**
* VipsSaveable:
* @VIPS_SAVEABLE_RGB: 1 or 3 bands (eg. PPM)
* @VIPS_SAVEABLE_RGBA: 1, 2, 3 or 4 bands (eg. PNG)
* @VIPS_SAVEABLE_RGB_CMYK: 1, 3 or 4 bands (eg. JPEG)
* @VIPS_SAVEABLE_ANY: any number of bands (eg. TIFF)
*
* See also: #VipsFileSave.
*/
typedef enum {
VIPS_SAVEABLE_RGB,
VIPS_SAVEABLE_RGBA,
VIPS_SAVEABLE_RGB_CMYK,
VIPS_SAVEABLE_ANY,
VIPS_SAVEABLE_LAST
} VipsSaveable;
typedef struct _VipsFileSave {
VipsFile parent_object;
/*< public >*/
/* The image we are to save.
*/
VipsImage *in;
/* The image converted to a saveable format (eg. 8-bit RGB).
*/
VipsImage *ready;
} VipsFileSave;
typedef struct _VipsFileSaveClass {
VipsFileClass parent_class;
/*< public >*/
/* How this format treats bands.
*/
VipsSaveable saveable;
/* How this format treats band formats.
*/
VipsBandFormat *format_table;
} VipsFileSaveClass;
GType vips_file_save_get_type( void );
const char *vips_file_find_save( const char *filename );
/* Read/write an image convenience functions.
*/
int vips_file_read( const char *filename, VipsImage **out, ... );
int vips_file_write( VipsImage *in, const char *filename, ... );
void vips_file_operation_init( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*VIPS_FILE_H*/

View File

@ -0,0 +1,240 @@
/* Base type for supported image foreigns. Subclass this to add a new
* foreign.
*/
/*
This foreign is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
These foreigns are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifndef VIPS_FOREIGN_H
#define VIPS_FOREIGN_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
/* Image file load properties.
*/
typedef enum {
VIPS_FOREIGN_NONE = 0, /* No flags set */
VIPS_FOREIGN_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */
VIPS_FOREIGN_BIGENDIAN = 2 /* Most-significant byte first */
} VipsForeignFlags;
#define VIPS_TYPE_FOREIGN (vips_foreign_get_type())
#define VIPS_FOREIGN( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FOREIGN, VipsForeign ))
#define VIPS_FOREIGN_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FOREIGN, VipsForeignClass))
#define VIPS_IS_FOREIGN( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FOREIGN ))
#define VIPS_IS_FOREIGN_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FOREIGN ))
#define VIPS_FOREIGN_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FOREIGN, VipsForeignClass ))
typedef struct _VipsForeign {
VipsOperation parent_object;
/*< public >*/
/* Filename for load or save.
*/
char *filename;
} VipsForeign;
typedef struct _VipsForeignClass {
VipsOperationClass parent_class;
/*< public >*/
/* Loop over formats in this order, default 0. We need this because
* some formats can be read by several loaders (eg. tiff can be read
* by the libMagick loader as well as by the tiff loader), and we want
* to make sure the better loader comes first.
*/
int priority;
/* Null-terminated list of recommended suffixes, eg. ".tif", ".tiff".
* This can be used by both load and save, so it's in the base class.
*/
const char **suffs;
} VipsForeignClass;
GType vips_foreign_get_type( void );
/* Map over and find formats. This uses type introspection to loop over
* subclasses of VipsForeign.
*/
void *vips_foreign_map( const char *base,
VipsSListMap2Fn fn, void *a, void *b );
#define VIPS_TYPE_FOREIGN_LOAD (vips_foreign_load_get_type())
#define VIPS_FOREIGN_LOAD( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoad ))
#define VIPS_FOREIGN_LOAD_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoadClass))
#define VIPS_IS_FOREIGN_LOAD( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FOREIGN_LOAD ))
#define VIPS_IS_FOREIGN_LOAD_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FOREIGN_LOAD ))
#define VIPS_FOREIGN_LOAD_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FOREIGN_LOAD, VipsForeignLoadClass ))
typedef struct _VipsForeignLoad {
VipsForeign parent_object;
/*< public >*/
/* Open to disc (default is to open to memory).
*/
gboolean disc;
/* Flags read from the foreign.
*/
VipsForeignFlags flags;
/* The image we generate.
*/
VipsImage *out;
/* The behind-the-scenes real image we decompress to. This can be a
* disc foreign or a memory buffer.
*/
VipsImage *real;
} VipsForeignLoad;
typedef struct _VipsForeignLoadClass {
VipsForeignClass parent_class;
/*< public >*/
/* Is a foreign in this format.
*/
gboolean (*is_a)( const char * );
/* Get the flags for this foreign.
*/
int (*get_flags)( VipsForeignLoad * );
/* Set the header fields in @out from @foreignname. If you can read the
* whole image as well with no performance cost (as with vipsload),
* leave ->load() NULL and only @header will be used.
*/
int (*header)( VipsForeignLoad * );
/* Read the whole image into @real. It gets copied to @out later.
*/
int (*load)( VipsForeignLoad * );
} VipsForeignLoadClass;
GType vips_foreign_load_get_type( void );
const char *vips_foreign_find_load( const char *foreignname );
#define VIPS_TYPE_FOREIGN_SAVE (vips_foreign_save_get_type())
#define VIPS_FOREIGN_SAVE( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_FOREIGN_SAVE, VipsForeignSave ))
#define VIPS_FOREIGN_SAVE_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_FOREIGN_SAVE, VipsForeignSaveClass))
#define VIPS_IS_FOREIGN_SAVE( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_FOREIGN_SAVE ))
#define VIPS_IS_FOREIGN_SAVE_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_FOREIGN_SAVE ))
#define VIPS_FOREIGN_SAVE_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_FOREIGN_SAVE, VipsForeignSaveClass ))
/**
* VipsSaveable:
* @VIPS_SAVEABLE_RGB: 1 or 3 bands (eg. PPM)
* @VIPS_SAVEABLE_RGBA: 1, 2, 3 or 4 bands (eg. PNG)
* @VIPS_SAVEABLE_RGB_CMYK: 1, 3 or 4 bands (eg. JPEG)
* @VIPS_SAVEABLE_ANY: any number of bands (eg. TIFF)
*
* See also: #VipsForeignSave.
*/
typedef enum {
VIPS_SAVEABLE_RGB,
VIPS_SAVEABLE_RGBA,
VIPS_SAVEABLE_RGB_CMYK,
VIPS_SAVEABLE_ANY,
VIPS_SAVEABLE_LAST
} VipsSaveable;
typedef struct _VipsForeignSave {
VipsForeign parent_object;
/*< public >*/
/* The image we are to save.
*/
VipsImage *in;
/* The image converted to a saveable format (eg. 8-bit RGB).
*/
VipsImage *ready;
} VipsForeignSave;
typedef struct _VipsForeignSaveClass {
VipsForeignClass parent_class;
/*< public >*/
/* How this format treats bands.
*/
VipsSaveable saveable;
/* How this format treats band formats.
*/
VipsBandFormat *format_table;
} VipsForeignSaveClass;
GType vips_foreign_save_get_type( void );
const char *vips_foreign_find_save( const char *filename );
/* Read/write an image convenience functions.
*/
int vips_foreign_read( const char *filename, VipsImage **out, ... );
int vips_foreign_write( VipsImage *in, const char *filename, ... );
void vips_foreign_operation_init( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*VIPS_FOREIGN_H*/

View File

@ -116,7 +116,7 @@ extern "C" {
#include <vips/threadpool.h>
#include <vips/header.h>
#include <vips/operation.h>
#include <vips/file.h>
#include <vips/foreign.h>
#include <vips/enumtypes.h>

View File

@ -41,7 +41,7 @@ INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
# well
vips_scan_headers = \
${top_srcdir}/libvips/include/vips/memory.h \
${top_srcdir}/libvips/include/vips/file.h \
${top_srcdir}/libvips/include/vips/foreign.h \
${top_srcdir}/libvips/include/vips/conversion.h \
${top_srcdir}/libvips/include/vips/arithmetic.h \
${top_srcdir}/libvips/include/vips/util.h \

View File

@ -4,21 +4,21 @@
/* auto-generated enums for vips introspection */
#include <vips/vips.h>
/* enumerations from "../../libvips/include/vips/file.h" */
/* enumerations from "../../libvips/include/vips/foreign.h" */
GType
vips_file_flags_get_type( void )
vips_foreign_flags_get_type( void )
{
static GType etype = 0;
if( etype == 0 ) {
static const GEnumValue values[] = {
{VIPS_FILE_NONE, "VIPS_FILE_NONE", "none"},
{VIPS_FILE_PARTIAL, "VIPS_FILE_PARTIAL", "partial"},
{VIPS_FILE_BIGENDIAN, "VIPS_FILE_BIGENDIAN", "bigendian"},
{VIPS_FOREIGN_NONE, "VIPS_FOREIGN_NONE", "none"},
{VIPS_FOREIGN_PARTIAL, "VIPS_FOREIGN_PARTIAL", "partial"},
{VIPS_FOREIGN_BIGENDIAN, "VIPS_FOREIGN_BIGENDIAN", "bigendian"},
{0, NULL, NULL}
};
etype = g_enum_register_static( "VipsFileFlags", values );
etype = g_enum_register_static( "VipsForeignFlags", values );
}
return( etype );

View File

@ -472,7 +472,7 @@ vips_image_rewind( VipsObject *object )
static void
vips_image_save_cb( VipsImage *image, int *result, char *filename )
{
if( vips_file_write( image, filename, NULL ) )
if( vips_foreign_write( image, filename, NULL ) )
*result = -1;
g_free( filename );
@ -602,6 +602,9 @@ vips_image_build( VipsObject *object )
VipsImage *t;
VipsImage *t2;
printf( "vips_image_build: "
"byteswapping vips read\n" );
/* Open the image in t, then byteswap to this
* image.
*/
@ -628,7 +631,7 @@ vips_image_build( VipsObject *object )
else {
VipsImage *t;
if( vips_file_read( filename, &t, NULL ) )
if( vips_foreign_read( filename, &t, NULL ) )
return( -1 );
image->dtype = VIPS_IMAGE_PARTIAL;
@ -645,10 +648,10 @@ vips_image_build( VipsObject *object )
{
const char *file_op;
if( !(file_op = vips_file_find_save( filename )) )
if( !(file_op = vips_foreign_find_save( filename )) )
return( -1 );
if( strcmp( file_op, "VipsFileSaveVips" ) == 0 )
if( strcmp( file_op, "VipsForeignSaveVips" ) == 0 )
image->dtype = VIPS_IMAGE_OPENOUT;
else {
image->dtype = VIPS_IMAGE_PARTIAL;

View File

@ -231,7 +231,7 @@ vips_init( const char *argv0 )
*/
vips_arithmetic_operation_init();
vips_conversion_operation_init();
vips_file_operation_init();
vips_foreign_operation_init();
/* Load up any plugins in the vips libdir. We don't error on failure,
* it's too annoying to have VIPS refuse to start because of a broken

View File

@ -1232,7 +1232,7 @@ vips_object_set_argument_from_string( VipsObject *object,
g_assert( argument_class->flags & VIPS_ARGUMENT_INPUT );
if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) &&
(oclass = g_type_class_ref( VIPS_TYPE_FILE_LOAD )) ) {
(oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_LOAD )) ) {
VipsObject *new_object;
VipsImage *out;
@ -1418,7 +1418,7 @@ vips_object_get_argument_to_string( VipsObject *object,
g_assert( argument_class->flags & VIPS_ARGUMENT_OUTPUT );
if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) &&
(oclass = g_type_class_ref( VIPS_TYPE_FILE_SAVE )) ) {
(oclass = g_type_class_ref( VIPS_TYPE_FOREIGN_SAVE )) ) {
VipsObject *new_object;
VipsImage *in;