tell buffer and target savers the file format (#2499)
tell buffer and target savers the file format Currently, buffer and target savers are not told the format they should write. This is usually OK (the JPEG saver already knows it should write JPEG), but some savers can write several formats, and these currently need an extra parameter. For example: ```ruby buf = x.write_to_buffer ".bmp", format: "bmp" ``` The first ".bmp" gets libvips to pick magicksave, the second `format:` param is necessary to tell magicksave to write BMP. This patch adds stub subclasses so that the savers know the exact format. It also improves PPM save.
This commit is contained in:
parent
1f321d366b
commit
47383b5bfc
@ -14,6 +14,8 @@
|
||||
- added restart_interval option to jpegsave [manthey]
|
||||
- add IIIF3 support to dzsaave [martimpassos]
|
||||
- add atan2 [indus]
|
||||
- improve buffer and target save file format selection
|
||||
- added VipsForeignPpmFormat, @format arg to ppm savers
|
||||
|
||||
16/8/21 started 8.11.4
|
||||
- fix off-by-one error in new rank fast path
|
||||
|
@ -1795,6 +1795,7 @@ vips_foreign_save_class_init( VipsForeignSaveClass *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSave, page_height ),
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2782,7 +2783,10 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_load_ppm_file_get_type( void );
|
||||
extern GType vips_foreign_load_ppm_source_get_type( void );
|
||||
extern GType vips_foreign_save_ppm_file_get_type( void );
|
||||
extern GType vips_foreign_save_pbm_target_get_type( void );
|
||||
extern GType vips_foreign_save_pgm_target_get_type( void );
|
||||
extern GType vips_foreign_save_ppm_target_get_type( void );
|
||||
extern GType vips_foreign_save_pfm_target_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_png_file_get_type( void );
|
||||
extern GType vips_foreign_load_png_buffer_get_type( void );
|
||||
@ -2841,7 +2845,9 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_load_magick7_file_get_type( void );
|
||||
extern GType vips_foreign_load_magick7_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_magick_file_get_type( void );
|
||||
extern GType vips_foreign_save_magick_bmp_file_get_type( void );
|
||||
extern GType vips_foreign_save_magick_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_magick_bmp_buffer_get_type( void );
|
||||
|
||||
extern GType vips_foreign_save_dz_file_get_type( void );
|
||||
extern GType vips_foreign_save_dz_buffer_get_type( void );
|
||||
@ -2881,6 +2887,7 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_save_heif_file_get_type( void );
|
||||
extern GType vips_foreign_save_heif_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_heif_target_get_type( void );
|
||||
extern GType vips_foreign_save_avif_target_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_nifti_file_get_type( void );
|
||||
extern GType vips_foreign_load_nifti_source_get_type( void );
|
||||
@ -2922,7 +2929,10 @@ vips_foreign_operation_init( void )
|
||||
vips_foreign_load_ppm_file_get_type();
|
||||
vips_foreign_load_ppm_source_get_type();
|
||||
vips_foreign_save_ppm_file_get_type();
|
||||
vips_foreign_save_pbm_target_get_type();
|
||||
vips_foreign_save_pgm_target_get_type();
|
||||
vips_foreign_save_ppm_target_get_type();
|
||||
vips_foreign_save_pfm_target_get_type();
|
||||
#endif /*HAVE_PPM*/
|
||||
|
||||
#ifdef HAVE_RADIANCE
|
||||
@ -3052,7 +3062,9 @@ vips_foreign_operation_init( void )
|
||||
|
||||
#if defined(ENABLE_MAGICKSAVE) && !defined(MAGICK_MODULE)
|
||||
vips_foreign_save_magick_file_get_type();
|
||||
vips_foreign_save_magick_bmp_file_get_type();
|
||||
vips_foreign_save_magick_buffer_get_type();
|
||||
vips_foreign_save_magick_bmp_buffer_get_type();
|
||||
#endif /*defined(ENABLE_MAGICKSAVE) && !defined(MAGICK_MODULE)*/
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
@ -3081,6 +3093,7 @@ vips_foreign_operation_init( void )
|
||||
vips_foreign_save_heif_file_get_type();
|
||||
vips_foreign_save_heif_buffer_get_type();
|
||||
vips_foreign_save_heif_target_get_type();
|
||||
vips_foreign_save_avif_target_get_type();
|
||||
#endif /*defined(HAVE_HEIF_ENCODER) && !defined(HEIF_MODULE)*/
|
||||
|
||||
vips__foreign_load_operation =
|
||||
|
@ -76,6 +76,17 @@
|
||||
|
||||
#include "pforeign.h"
|
||||
|
||||
const char *vips__heic_suffs[] = {
|
||||
".heic",
|
||||
".heif",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *vips__avif_suffs[] = {
|
||||
".avif",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *vips__heif_suffs[] = {
|
||||
".heic",
|
||||
".heif",
|
||||
|
@ -335,7 +335,6 @@ vips_foreign_save_heif_build( VipsObject *object )
|
||||
VipsForeignSave *save = (VipsForeignSave *) object;
|
||||
VipsForeignSaveHeif *heif = (VipsForeignSaveHeif *) object;
|
||||
|
||||
const char *filename;
|
||||
struct heif_error error;
|
||||
struct heif_writer writer;
|
||||
char *chroma;
|
||||
@ -357,15 +356,6 @@ vips_foreign_save_heif_build( VipsObject *object )
|
||||
if( vips_copy( save->ready, &heif->image, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* Compression defaults to VIPS_FOREIGN_HEIF_COMPRESSION_AV1 for .avif
|
||||
* suffix.
|
||||
*/
|
||||
filename = vips_connection_filename( VIPS_CONNECTION( heif->target ) );
|
||||
if( !vips_object_argument_isset( object, "compression" ) &&
|
||||
filename &&
|
||||
vips_iscasepostfix( filename, ".avif" ) )
|
||||
heif->compression = VIPS_FOREIGN_HEIF_COMPRESSION_AV1;
|
||||
|
||||
error = heif_context_get_encoder_for_format( heif->ctx,
|
||||
(enum heif_compression_format) heif->compression,
|
||||
&heif->encoder );
|
||||
@ -489,7 +479,6 @@ vips_foreign_save_heif_class_init( VipsForeignSaveHeifClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_foreign_save_heif_dispose;
|
||||
@ -500,8 +489,6 @@ vips_foreign_save_heif_class_init( VipsForeignSaveHeifClass *class )
|
||||
object_class->description = _( "save image in HEIF format" );
|
||||
object_class->build = vips_foreign_save_heif_build;
|
||||
|
||||
foreign_class->suffs = vips__heif_suffs;
|
||||
|
||||
save_class->saveable = VIPS_SAVEABLE_RGBA_ONLY;
|
||||
save_class->format_table = vips_heif_bandfmt;
|
||||
|
||||
@ -588,6 +575,9 @@ vips_foreign_save_heif_file_build( VipsObject *object )
|
||||
if( !(heif->target = vips_target_new_to_file( file->filename )) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_iscasepostfix( file->filename, ".avif" ) )
|
||||
heif->compression = VIPS_FOREIGN_HEIF_COMPRESSION_AV1;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_save_heif_file_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
@ -600,6 +590,7 @@ vips_foreign_save_heif_file_class_init( VipsForeignSaveHeifFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
@ -607,6 +598,8 @@ vips_foreign_save_heif_file_class_init( VipsForeignSaveHeifFileClass *class )
|
||||
object_class->nickname = "heifsave";
|
||||
object_class->build = vips_foreign_save_heif_file_build;
|
||||
|
||||
foreign_class->suffs = vips__heif_suffs;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to save to" ),
|
||||
@ -664,6 +657,7 @@ vips_foreign_save_heif_buffer_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
@ -671,6 +665,8 @@ vips_foreign_save_heif_buffer_class_init(
|
||||
object_class->nickname = "heifsave_buffer";
|
||||
object_class->build = vips_foreign_save_heif_buffer_build;
|
||||
|
||||
foreign_class->suffs = vips__heic_suffs;
|
||||
|
||||
VIPS_ARG_BOXED( class, "buffer", 1,
|
||||
_( "Buffer" ),
|
||||
_( "Buffer to save to" ),
|
||||
@ -721,6 +717,7 @@ vips_foreign_save_heif_target_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
@ -728,6 +725,8 @@ vips_foreign_save_heif_target_class_init(
|
||||
object_class->nickname = "heifsave_target";
|
||||
object_class->build = vips_foreign_save_heif_target_build;
|
||||
|
||||
foreign_class->suffs = vips__heic_suffs;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "target", 1,
|
||||
_( "Target" ),
|
||||
_( "Target to save to" ),
|
||||
@ -742,6 +741,38 @@ vips_foreign_save_heif_target_init( VipsForeignSaveHeifTarget *target )
|
||||
{
|
||||
}
|
||||
|
||||
typedef VipsForeignSaveHeifTarget VipsForeignSaveAvifTarget;
|
||||
typedef VipsForeignSaveHeifTargetClass VipsForeignSaveAvifTargetClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSaveAvifTarget, vips_foreign_save_avif_target,
|
||||
vips_foreign_save_heif_target_get_type() );
|
||||
|
||||
static void
|
||||
vips_foreign_save_avif_target_class_init(
|
||||
VipsForeignSaveAvifTargetClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
object_class->nickname = "avifsave_target";
|
||||
object_class->description = _( "save image in AVIF format" );
|
||||
|
||||
foreign_class->suffs = vips__avif_suffs;
|
||||
|
||||
/* Hide from UI.
|
||||
*/
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_avif_target_init( VipsForeignSaveAvifTarget *target )
|
||||
{
|
||||
VipsForeignSaveHeif *heif = (VipsForeignSaveHeif *) target;
|
||||
|
||||
heif->compression = VIPS_FOREIGN_HEIF_COMPRESSION_AV1;
|
||||
}
|
||||
|
||||
#endif /*HAVE_HEIF_ENCODER*/
|
||||
|
||||
/* The C API wrappers are defined in foreign.c.
|
||||
|
@ -158,6 +158,10 @@ int vips__mat_header( const char *filename, VipsImage *out );
|
||||
int vips__mat_ismat( const char *filename );
|
||||
|
||||
extern const char *vips__ppm_suffs[];
|
||||
extern const char *vips__save_pbm_suffs[];
|
||||
extern const char *vips__save_pgm_suffs[];
|
||||
extern const char *vips__save_ppm_suffs[];
|
||||
extern const char *vips__save_pfm_suffs[];
|
||||
|
||||
int vips__ppm_save_target( VipsImage *in, VipsTarget *target,
|
||||
gboolean ascii, gboolean squash );
|
||||
@ -235,6 +239,8 @@ typedef void *(*VipsNiftiMapFn)( const char *name, GValue *value, glong offset,
|
||||
void *a, void *b );
|
||||
void *vips__foreign_nifti_map( VipsNiftiMapFn fn, void *a, void *b );
|
||||
|
||||
extern const char *vips__heic_suffs[];
|
||||
extern const char *vips__avif_suffs[];
|
||||
extern const char *vips__heif_suffs[];
|
||||
|
||||
extern const char *vips__jp2k_suffs[];
|
||||
|
@ -141,7 +141,11 @@ static char *magic_names[] = {
|
||||
|
||||
/* Shared with ppmsave.
|
||||
*/
|
||||
const char *vips__ppm_suffs[] = { ".ppm", ".pgm", ".pbm", ".pfm", NULL };
|
||||
const char *vips__ppm_suffs[] = { ".pbm", ".pgm", ".ppm", ".pfm", NULL };
|
||||
const char *vips__save_pbm_suffs[] = { ".pbm", NULL };
|
||||
const char *vips__save_pgm_suffs[] = { ".pgm", NULL };
|
||||
const char *vips__save_ppm_suffs[] = { ".ppm", NULL };
|
||||
const char *vips__save_pfm_suffs[] = { ".pfm", NULL };
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_ppm_is_a_source( VipsSource *source )
|
||||
|
@ -12,6 +12,8 @@
|
||||
* - byteswap on save, if necessary [ewelot]
|
||||
* 2/12/20
|
||||
* - don't add date with @strip [ewelot]
|
||||
* 28/10/21
|
||||
* - add @format, default type by filename
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -70,6 +72,7 @@ struct _VipsForeignSavePpm {
|
||||
VipsForeignSave parent_object;
|
||||
|
||||
VipsTarget *target;
|
||||
VipsForeignPpmFormat format;
|
||||
gboolean ascii;
|
||||
int bitdepth;
|
||||
|
||||
@ -216,16 +219,70 @@ vips_foreign_save_ppm_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignSave *save = (VipsForeignSave *) object;
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) object;
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );
|
||||
|
||||
VipsImage *image;
|
||||
char *magic;
|
||||
char *date;
|
||||
VipsBandFormat target_format;
|
||||
VipsInterpretation target_interpretation;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_save_ppm_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
image = save->ready;
|
||||
target_format = image->BandFmt;
|
||||
target_interpretation = image->Type;
|
||||
|
||||
/* ppm types to set the defaults for bitdepth etc.
|
||||
*
|
||||
* pbm ... 1 band 1 bit
|
||||
* pgm ... 1 band many bit
|
||||
* ppm ... 3 band many bit
|
||||
* pfm ... 1 or 3 bands, 32 bit
|
||||
*/
|
||||
switch( ppm->format ) {
|
||||
case VIPS_FOREIGN_PPM_FORMAT_PBM:
|
||||
if( !vips_object_argument_isset( object, "bitdepth" ) )
|
||||
ppm->bitdepth = 1;
|
||||
target_interpretation = VIPS_INTERPRETATION_B_W;
|
||||
break;
|
||||
|
||||
case VIPS_FOREIGN_PPM_FORMAT_PGM:
|
||||
if( target_format == VIPS_FORMAT_USHORT )
|
||||
target_interpretation = VIPS_INTERPRETATION_GREY16;
|
||||
else
|
||||
target_interpretation = VIPS_INTERPRETATION_B_W;
|
||||
break;
|
||||
|
||||
case VIPS_FOREIGN_PPM_FORMAT_PPM:
|
||||
if( target_format == VIPS_FORMAT_USHORT )
|
||||
target_interpretation = VIPS_INTERPRETATION_RGB16;
|
||||
else
|
||||
target_interpretation = VIPS_INTERPRETATION_sRGB;
|
||||
break;
|
||||
|
||||
case VIPS_FOREIGN_PPM_FORMAT_PFM:
|
||||
target_format = VIPS_FORMAT_FLOAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Harmless.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if( vips_cast( image, &t[0], target_format, NULL ) )
|
||||
return( -1 );
|
||||
image = t[0];
|
||||
|
||||
if( image->Type != target_interpretation ) {
|
||||
if( vips_colourspace( image, &t[1],
|
||||
target_interpretation, NULL ) )
|
||||
return( -1 );
|
||||
image = t[1];
|
||||
}
|
||||
|
||||
/* Handle the deprecated squash parameter.
|
||||
*/
|
||||
@ -318,9 +375,12 @@ vips_foreign_save_ppm_build( VipsObject *object )
|
||||
double scale;
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
if( vips_image_get_double( image,
|
||||
"pfm-scale", &scale ) )
|
||||
scale = 1;
|
||||
scale = 1;
|
||||
if( vips_image_get_typeof( image, "pfm-scale" ) &&
|
||||
!vips_image_get_double( image,
|
||||
"pfm-scale", &scale ) )
|
||||
;
|
||||
|
||||
if( !vips_amiMSBfirst() )
|
||||
scale *= -1;
|
||||
/* Need to be locale independent.
|
||||
@ -391,7 +451,6 @@ vips_foreign_save_ppm_class_init( VipsForeignSavePpmClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_foreign_save_ppm_dispose;
|
||||
@ -402,11 +461,17 @@ vips_foreign_save_ppm_class_init( VipsForeignSavePpmClass *class )
|
||||
object_class->description = _( "save to ppm" );
|
||||
object_class->build = vips_foreign_save_ppm_build;
|
||||
|
||||
foreign_class->suffs = vips__ppm_suffs;
|
||||
|
||||
save_class->saveable = VIPS_SAVEABLE_RGB;
|
||||
save_class->format_table = bandfmt_ppm;
|
||||
|
||||
VIPS_ARG_ENUM( class, "format", 2,
|
||||
_( "Format" ),
|
||||
_( "Format to save in" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSavePpm, format ),
|
||||
VIPS_TYPE_FOREIGN_PPM_FORMAT,
|
||||
VIPS_FOREIGN_PPM_FORMAT_PPM );
|
||||
|
||||
VIPS_ARG_BOOL( class, "ascii", 10,
|
||||
_( "ASCII" ),
|
||||
_( "save as ascii" ),
|
||||
@ -433,6 +498,7 @@ vips_foreign_save_ppm_class_init( VipsForeignSavePpmClass *class )
|
||||
static void
|
||||
vips_foreign_save_ppm_init( VipsForeignSavePpm *ppm )
|
||||
{
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PPM;
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignSavePpmFile {
|
||||
@ -456,6 +522,13 @@ vips_foreign_save_ppm_file_build( VipsObject *object )
|
||||
!(ppm->target = vips_target_new_to_file( file->filename )) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_iscasepostfix( file->filename, ".pbm" ) )
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PBM;
|
||||
else if( vips_iscasepostfix( file->filename, ".pgm" ) )
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PGM;
|
||||
else if( vips_iscasepostfix( file->filename, ".pfm" ) )
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PFM;
|
||||
|
||||
return( VIPS_OBJECT_CLASS( vips_foreign_save_ppm_file_parent_class )->
|
||||
build( object ) );
|
||||
}
|
||||
@ -465,6 +538,7 @@ vips_foreign_save_ppm_file_class_init( VipsForeignSavePpmFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
@ -473,6 +547,8 @@ vips_foreign_save_ppm_file_class_init( VipsForeignSavePpmFileClass *class )
|
||||
object_class->description = _( "save image to ppm file" );
|
||||
object_class->build = vips_foreign_save_ppm_file_build;
|
||||
|
||||
foreign_class->suffs = vips__ppm_suffs;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to save to" ),
|
||||
@ -521,6 +597,7 @@ vips_foreign_save_ppm_target_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
@ -528,6 +605,8 @@ vips_foreign_save_ppm_target_class_init(
|
||||
object_class->nickname = "ppmsave_target";
|
||||
object_class->build = vips_foreign_save_ppm_target_build;
|
||||
|
||||
foreign_class->suffs = vips__save_ppm_suffs;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "target", 1,
|
||||
_( "Target" ),
|
||||
_( "Target to save to" ),
|
||||
@ -542,6 +621,102 @@ vips_foreign_save_ppm_target_init( VipsForeignSavePpmTarget *target )
|
||||
{
|
||||
}
|
||||
|
||||
typedef VipsForeignSavePpmTarget VipsForeignSavePbmTarget;
|
||||
typedef VipsForeignSavePpmTargetClass VipsForeignSavePbmTargetClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSavePbmTarget, vips_foreign_save_pbm_target,
|
||||
vips_foreign_save_ppm_target_get_type() );
|
||||
|
||||
static void
|
||||
vips_foreign_save_pbm_target_class_init(
|
||||
VipsForeignSavePbmTargetClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
object_class->nickname = "pbmsave_target";
|
||||
object_class->description = _( "save image in pbm format" );
|
||||
|
||||
foreign_class->suffs = vips__save_pbm_suffs;
|
||||
|
||||
/* Hide from UI.
|
||||
*/
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_pbm_target_init( VipsForeignSavePbmTarget *target )
|
||||
{
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) target;
|
||||
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PBM;
|
||||
}
|
||||
|
||||
typedef VipsForeignSavePpmTarget VipsForeignSavePgmTarget;
|
||||
typedef VipsForeignSavePpmTargetClass VipsForeignSavePgmTargetClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSavePgmTarget, vips_foreign_save_pgm_target,
|
||||
vips_foreign_save_ppm_target_get_type() );
|
||||
|
||||
static void
|
||||
vips_foreign_save_pgm_target_class_init(
|
||||
VipsForeignSavePgmTargetClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
object_class->nickname = "pgmsave_target";
|
||||
object_class->description = _( "save image in pgm format" );
|
||||
|
||||
foreign_class->suffs = vips__save_pgm_suffs;
|
||||
|
||||
/* Hide from UI.
|
||||
*/
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_pgm_target_init( VipsForeignSavePgmTarget *target )
|
||||
{
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) target;
|
||||
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PGM;
|
||||
}
|
||||
|
||||
typedef VipsForeignSavePpmTarget VipsForeignSavePfmTarget;
|
||||
typedef VipsForeignSavePpmTargetClass VipsForeignSavePfmTargetClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSavePfmTarget, vips_foreign_save_pfm_target,
|
||||
vips_foreign_save_ppm_target_get_type() );
|
||||
|
||||
static void
|
||||
vips_foreign_save_pfm_target_class_init(
|
||||
VipsForeignSavePfmTargetClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
object_class->nickname = "pfmsave_target";
|
||||
object_class->description = _( "save image in pfm format" );
|
||||
|
||||
foreign_class->suffs = vips__save_pfm_suffs;
|
||||
|
||||
/* Hide from UI.
|
||||
*/
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_pfm_target_init( VipsForeignSavePfmTarget *target )
|
||||
{
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) target;
|
||||
|
||||
ppm->format = VIPS_FOREIGN_PPM_FORMAT_PFM;
|
||||
}
|
||||
|
||||
#endif /*HAVE_PPM*/
|
||||
|
||||
/**
|
||||
@ -552,8 +727,9 @@ vips_foreign_save_ppm_target_init( VipsForeignSavePpmTarget *target )
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @ascii: save as ASCII rather than binary
|
||||
* * @squash: squash 8-bit images down to one bit
|
||||
* * @format: #VipsForeignPpmFormat, format to save in
|
||||
* * @ascii: %gboolean, save as ASCII rather than binary
|
||||
* * @bitdepth: %gint, bitdepth to save at
|
||||
*
|
||||
* Write a VIPS image to a file as PPM. It can write 1, 8, 16 or
|
||||
* 32 bit unsigned integer images, float images, colour or monochrome,
|
||||
@ -566,8 +742,9 @@ vips_foreign_save_ppm_target_init( VipsForeignSavePpmTarget *target )
|
||||
* Set @ascii to %TRUE to write as human-readable ASCII. Normally data is
|
||||
* written in binary.
|
||||
*
|
||||
* Set @squash to %TRUE to squash 8-bit images down to one bit. The saver does
|
||||
* no dithering, that's up to you.
|
||||
* Set @bitdepth to 1 to write a one-bit image.
|
||||
*
|
||||
* @format defaults to the sub-type for this filename suffix.
|
||||
*
|
||||
* See also: vips_image_write_to_file().
|
||||
*
|
||||
@ -592,6 +769,12 @@ vips_ppmsave( VipsImage *in, const char *filename, ... )
|
||||
* @target: save image to this target
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @format: #VipsForeignPpmFormat, format to save in
|
||||
* * @ascii: %gboolean, save as ASCII rather than binary
|
||||
* * @bitdepth: %gint, bitdepth to save at
|
||||
*
|
||||
* As vips_ppmsave(), but save to a target.
|
||||
*
|
||||
* See also: vips_ppmsave().
|
||||
|
@ -102,6 +102,7 @@ vips_foreign_save_magick_dispose( GObject *gobject )
|
||||
printf( "vips_foreign_save_magick_dispose: %p\n", gobject );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
VIPS_FREE( magick->filename );
|
||||
VIPS_FREE( magick->map );
|
||||
VIPS_FREEF( DestroyImageList, magick->images );
|
||||
VIPS_FREEF( DestroyImageInfo, magick->image_info );
|
||||
@ -414,7 +415,8 @@ vips_foreign_save_magick_build( VipsObject *object )
|
||||
* Instead, just list the commonly-used formats that all libMagicks support and
|
||||
* that libvips does not.
|
||||
*/
|
||||
static const char *vips__save_magick_suffs[] = { ".gif", ".bmp", NULL };
|
||||
static const char *vips__save_magick_suffs[] = { NULL };
|
||||
static const char *vips__save_magick_bmp_suffs[] = { ".bmp", NULL };
|
||||
|
||||
/* Save a bit of typing.
|
||||
*/
|
||||
@ -512,7 +514,7 @@ vips_foreign_save_magick_file_build( VipsObject *object )
|
||||
VipsForeignSaveMagick *magick = (VipsForeignSaveMagick *) object;
|
||||
VipsForeignSaveMagickFile *file = (VipsForeignSaveMagickFile *) object;
|
||||
|
||||
magick->filename = file->filename;
|
||||
magick->filename = g_strdup( file->filename );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_save_magick_file_parent_class )->
|
||||
build( object ) )
|
||||
@ -557,6 +559,38 @@ vips_foreign_save_magick_file_init( VipsForeignSaveMagickFile *file )
|
||||
{
|
||||
}
|
||||
|
||||
typedef VipsForeignSaveMagickFile VipsForeignSaveMagickBmpFile;
|
||||
typedef VipsForeignSaveMagickFileClass VipsForeignSaveMagickBmpFileClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSaveMagickBmpFile, vips_foreign_save_magick_bmp_file,
|
||||
vips_foreign_save_magick_file_get_type() );
|
||||
|
||||
static void
|
||||
vips_foreign_save_magick_bmp_file_class_init(
|
||||
VipsForeignSaveMagickBmpFileClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
object_class->nickname = "magicksave_bmp";
|
||||
object_class->description = _( "save bmp image with ImageMagick" );
|
||||
|
||||
foreign_class->suffs = vips__save_magick_bmp_suffs;
|
||||
|
||||
/* Hide from UI.
|
||||
*/
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_magick_bmp_file_init( VipsForeignSaveMagickBmpFile *file )
|
||||
{
|
||||
VipsForeignSaveMagick *magick = (VipsForeignSaveMagick *) file;
|
||||
|
||||
VIPS_SETSTR( magick->format, "bmp" );
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignSaveMagickBuffer {
|
||||
VipsForeignSaveMagick parent_object;
|
||||
|
||||
@ -630,4 +664,38 @@ vips_foreign_save_magick_buffer_init( VipsForeignSaveMagickBuffer *buffer )
|
||||
{
|
||||
}
|
||||
|
||||
typedef VipsForeignSaveMagickBuffer VipsForeignSaveMagickBmpBuffer;
|
||||
typedef VipsForeignSaveMagickBufferClass VipsForeignSaveMagickBmpBufferClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSaveMagickBmpBuffer,
|
||||
vips_foreign_save_magick_bmp_buffer,
|
||||
vips_foreign_save_magick_buffer_get_type() );
|
||||
|
||||
static void
|
||||
vips_foreign_save_magick_bmp_buffer_class_init(
|
||||
VipsForeignSaveMagickBmpBufferClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsOperationClass *operation_class = (VipsOperationClass *) class;
|
||||
|
||||
object_class->nickname = "magicksave_bmp_buffer";
|
||||
object_class->description = _( "save bmp image to magick buffer" );
|
||||
|
||||
foreign_class->suffs = vips__save_magick_bmp_suffs;
|
||||
|
||||
/* Hide from UI.
|
||||
*/
|
||||
operation_class->flags = VIPS_OPERATION_DEPRECATED;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_magick_bmp_buffer_init(
|
||||
VipsForeignSaveMagickBmpBuffer *buffer )
|
||||
{
|
||||
VipsForeignSaveMagick *magick = (VipsForeignSaveMagick *) buffer;
|
||||
|
||||
VIPS_SETSTR( magick->format, "bmp" );
|
||||
}
|
||||
|
||||
#endif /*ENABLE_MAGICKSAVE*/
|
||||
|
@ -72,6 +72,8 @@ GType vips_foreign_tiff_resunit_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_FOREIGN_TIFF_RESUNIT (vips_foreign_tiff_resunit_get_type())
|
||||
GType vips_foreign_png_filter_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_FOREIGN_PNG_FILTER (vips_foreign_png_filter_get_type())
|
||||
GType vips_foreign_ppm_format_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_FOREIGN_PPM_FORMAT (vips_foreign_ppm_format_get_type())
|
||||
GType vips_foreign_dz_layout_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_FOREIGN_DZ_LAYOUT (vips_foreign_dz_layout_get_type())
|
||||
GType vips_foreign_dz_depth_get_type (void) G_GNUC_CONST;
|
||||
|
@ -612,6 +612,31 @@ int vips_pngsave( VipsImage *in, const char *filename, ... )
|
||||
int vips_pngsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
/**
|
||||
* VipsForeignPpmFormat:
|
||||
* @VIPS_FOREIGN_PPM_PBM: portable bitmap
|
||||
* @VIPS_FOREIGN_PPM_PGM: portable greymap
|
||||
* @VIPS_FOREIGN_PPM_PPM: portable pixmap
|
||||
* @VIPS_FOREIGN_PPM_PFM: portable float map
|
||||
*
|
||||
* The netpbm file format to save as.
|
||||
*
|
||||
* #VIPS_FOREIGN_PPM_PBM images are single bit.
|
||||
*
|
||||
* #VIPS_FOREIGN_PPM_PGB images are 8, 16, or 32-bits, one band.
|
||||
*
|
||||
* #VIPS_FOREIGN_PPM_PPM images are 8, 16, or 32-bits, three bands.
|
||||
*
|
||||
* #VIPS_FOREIGN_PPM_PFM images are 32-bit float pixels.
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_FOREIGN_PPM_FORMAT_PBM,
|
||||
VIPS_FOREIGN_PPM_FORMAT_PGM,
|
||||
VIPS_FOREIGN_PPM_FORMAT_PPM,
|
||||
VIPS_FOREIGN_PPM_FORMAT_PFM,
|
||||
VIPS_FOREIGN_PPM_FORMAT_LAST
|
||||
} VipsForeignPpmFormat;
|
||||
|
||||
int vips_ppmload( const char *filename, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_ppmload_source( VipsSource *source, VipsImage **out, ... )
|
||||
|
@ -644,6 +644,26 @@ vips_foreign_png_filter_get_type( void )
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_foreign_ppm_format_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if( etype == 0 ) {
|
||||
static const GEnumValue values[] = {
|
||||
{VIPS_FOREIGN_PPM_FORMAT_PBM, "VIPS_FOREIGN_PPM_FORMAT_PBM", "pbm"},
|
||||
{VIPS_FOREIGN_PPM_FORMAT_PGM, "VIPS_FOREIGN_PPM_FORMAT_PGM", "pgm"},
|
||||
{VIPS_FOREIGN_PPM_FORMAT_PPM, "VIPS_FOREIGN_PPM_FORMAT_PPM", "ppm"},
|
||||
{VIPS_FOREIGN_PPM_FORMAT_PFM, "VIPS_FOREIGN_PPM_FORMAT_PFM", "pfm"},
|
||||
{VIPS_FOREIGN_PPM_FORMAT_LAST, "VIPS_FOREIGN_PPM_FORMAT_LAST", "last"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
etype = g_enum_register_static( "VipsForeignPpmFormat", values );
|
||||
}
|
||||
|
||||
return( etype );
|
||||
}
|
||||
GType
|
||||
vips_foreign_dz_layout_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
@ -2750,7 +2750,11 @@ vips_image_write_to_buffer( VipsImage *in,
|
||||
|
||||
vips__filename_split8( suffix, filename, option_string );
|
||||
|
||||
if( (operation_name = vips_foreign_find_save_target( filename )) ) {
|
||||
vips_error_freeze();
|
||||
operation_name = vips_foreign_find_save_target( filename );
|
||||
vips_error_thaw();
|
||||
|
||||
if( operation_name ) {
|
||||
VipsTarget *target;
|
||||
|
||||
if( !(target = vips_target_new_to_memory()) )
|
||||
|
@ -64,6 +64,7 @@ g_module_check_init( GModule *module )
|
||||
extern GType vips_foreign_save_heif_file_get_type( void );
|
||||
extern GType vips_foreign_save_heif_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_heif_target_get_type( void );
|
||||
extern GType vips_foreign_save_avif_target_get_type( void );
|
||||
|
||||
#ifdef HAVE_HEIF_DECODER
|
||||
vips_foreign_load_heif_file_get_type();
|
||||
@ -75,6 +76,7 @@ g_module_check_init( GModule *module )
|
||||
vips_foreign_save_heif_file_get_type();
|
||||
vips_foreign_save_heif_buffer_get_type();
|
||||
vips_foreign_save_heif_target_get_type();
|
||||
vips_foreign_save_avif_target_get_type();
|
||||
#endif /*HAVE_HEIF_ENCODER*/
|
||||
|
||||
return( NULL );
|
||||
|
@ -63,7 +63,9 @@ g_module_check_init( GModule *module )
|
||||
extern GType vips_foreign_load_magick7_file_get_type( void );
|
||||
extern GType vips_foreign_load_magick7_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_magick_file_get_type( void );
|
||||
extern GType vips_foreign_save_magick_bmp_file_get_type( void );
|
||||
extern GType vips_foreign_save_magick_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_magick_bmp_buffer_get_type( void );
|
||||
|
||||
#ifdef ENABLE_MAGICKLOAD
|
||||
#ifdef HAVE_MAGICK6
|
||||
@ -79,7 +81,9 @@ g_module_check_init( GModule *module )
|
||||
|
||||
#ifdef ENABLE_MAGICKSAVE
|
||||
vips_foreign_save_magick_file_get_type();
|
||||
vips_foreign_save_magick_bmp_file_get_type();
|
||||
vips_foreign_save_magick_buffer_get_type();
|
||||
vips_foreign_save_magick_bmp_buffer_get_type();
|
||||
#endif /*ENABLE_MAGICKSAVE*/
|
||||
|
||||
return( NULL );
|
||||
|
Loading…
Reference in New Issue
Block a user