Merge pull request #190 from lovell/png-set-filter
Expose ability to control libpng's row filter
This commit is contained in:
commit
1589e84360
@ -2487,6 +2487,7 @@ vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
|||||||
* @compression: compression level
|
* @compression: compression level
|
||||||
* @interlace: interlace image
|
* @interlace: interlace image
|
||||||
* @profile: ICC profile to embed
|
* @profile: ICC profile to embed
|
||||||
|
* @filter: libpng row filter flag(s)
|
||||||
*
|
*
|
||||||
* Write a VIPS image to a file as PNG.
|
* Write a VIPS image to a file as PNG.
|
||||||
*
|
*
|
||||||
@ -2506,6 +2507,8 @@ vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
|||||||
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
||||||
* profile from the VIPS header will be attached.
|
* profile from the VIPS header will be attached.
|
||||||
*
|
*
|
||||||
|
* Use @filter to specify one or more filters (instead of adaptive filtering).
|
||||||
|
*
|
||||||
* The image is automatically converted to RGB, RGBA, Monochrome or Mono +
|
* The image is automatically converted to RGB, RGBA, Monochrome or Mono +
|
||||||
* alpha before saving. Images with more than one byte per band element are
|
* alpha before saving. Images with more than one byte per band element are
|
||||||
* saved as 16-bit PNG, others are saved as 8-bit PNG.
|
* saved as 16-bit PNG, others are saved as 8-bit PNG.
|
||||||
@ -2539,6 +2542,7 @@ vips_pngsave( VipsImage *in, const char *filename, ... )
|
|||||||
* @compression: compression level
|
* @compression: compression level
|
||||||
* @interlace: interlace image
|
* @interlace: interlace image
|
||||||
* @profile: ICC profile to embed
|
* @profile: ICC profile to embed
|
||||||
|
* @filter: libpng row filter flag(s)
|
||||||
*
|
*
|
||||||
* As vips_pngsave(), but save to a memory buffer.
|
* As vips_pngsave(), but save to a memory buffer.
|
||||||
*
|
*
|
||||||
|
@ -59,6 +59,7 @@ typedef struct _VipsForeignSavePng {
|
|||||||
int compression;
|
int compression;
|
||||||
gboolean interlace;
|
gboolean interlace;
|
||||||
char *profile;
|
char *profile;
|
||||||
|
VipsForeignPngFilter filter;
|
||||||
} VipsForeignSavePng;
|
} VipsForeignSavePng;
|
||||||
|
|
||||||
typedef VipsForeignSaveClass VipsForeignSavePngClass;
|
typedef VipsForeignSaveClass VipsForeignSavePngClass;
|
||||||
@ -124,12 +125,21 @@ vips_foreign_save_png_class_init( VipsForeignSavePngClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsForeignSavePng, profile ),
|
G_STRUCT_OFFSET( VipsForeignSavePng, profile ),
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
|
VIPS_ARG_FLAGS( class, "filter", 12,
|
||||||
|
_( "Filter" ),
|
||||||
|
_( "libpng row filter flag(s)" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignSavePng, filter ),
|
||||||
|
VIPS_TYPE_FOREIGN_PNG_FILTER,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_ALL );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_foreign_save_png_init( VipsForeignSavePng *png )
|
vips_foreign_save_png_init( VipsForeignSavePng *png )
|
||||||
{
|
{
|
||||||
png->compression = 6;
|
png->compression = 6;
|
||||||
|
png->filter = VIPS_FOREIGN_PNG_FILTER_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _VipsForeignSavePngFile {
|
typedef struct _VipsForeignSavePngFile {
|
||||||
@ -155,7 +165,7 @@ vips_foreign_save_png_file_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips__png_write( save->ready, png_file->filename,
|
if( vips__png_write( save->ready, png_file->filename,
|
||||||
png->compression, png->interlace, png->profile ) )
|
png->compression, png->interlace, png->profile, png->filter ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -213,7 +223,7 @@ vips_foreign_save_png_buffer_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips__png_write_buf( save->ready, &obuf, &olen,
|
if( vips__png_write_buf( save->ready, &obuf, &olen,
|
||||||
png->compression, png->interlace, png->profile ) )
|
png->compression, png->interlace, png->profile, png->filter ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||||
|
@ -783,7 +783,8 @@ write_png_block( VipsRegion *region, VipsRect *area, void *a )
|
|||||||
/* Write a VIPS image to PNG.
|
/* Write a VIPS image to PNG.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
write_vips( Write *write, int compress, int interlace, const char *profile )
|
write_vips( Write *write, int compress, int interlace, const char *profile,
|
||||||
|
VipsForeignPngFilter filter )
|
||||||
{
|
{
|
||||||
VipsImage *in = write->in;
|
VipsImage *in = write->in;
|
||||||
|
|
||||||
@ -824,6 +825,10 @@ write_vips( Write *write, int compress, int interlace, const char *profile )
|
|||||||
*/
|
*/
|
||||||
png_set_compression_level( write->pPng, compress );
|
png_set_compression_level( write->pPng, compress );
|
||||||
|
|
||||||
|
/* Set row filter.
|
||||||
|
*/
|
||||||
|
png_set_filter( write->pPng, 0, filter );
|
||||||
|
|
||||||
bit_depth = in->BandFmt == VIPS_FORMAT_UCHAR ? 8 : 16;
|
bit_depth = in->BandFmt == VIPS_FORMAT_UCHAR ? 8 : 16;
|
||||||
|
|
||||||
switch( in->Bands ) {
|
switch( in->Bands ) {
|
||||||
@ -921,7 +926,8 @@ write_vips( Write *write, int compress, int interlace, const char *profile )
|
|||||||
|
|
||||||
int
|
int
|
||||||
vips__png_write( VipsImage *in, const char *filename,
|
vips__png_write( VipsImage *in, const char *filename,
|
||||||
int compress, int interlace, const char *profile )
|
int compress, int interlace, const char *profile,
|
||||||
|
VipsForeignPngFilter filter )
|
||||||
{
|
{
|
||||||
Write *write;
|
Write *write;
|
||||||
|
|
||||||
@ -940,7 +946,7 @@ vips__png_write( VipsImage *in, const char *filename,
|
|||||||
|
|
||||||
/* Convert it!
|
/* Convert it!
|
||||||
*/
|
*/
|
||||||
if( write_vips( write, compress, interlace, profile ) ) {
|
if( write_vips( write, compress, interlace, profile, filter ) ) {
|
||||||
vips_error( "vips2png",
|
vips_error( "vips2png",
|
||||||
_( "unable to write \"%s\"" ), filename );
|
_( "unable to write \"%s\"" ), filename );
|
||||||
|
|
||||||
@ -1027,7 +1033,7 @@ user_write_data( png_structp png_ptr, png_bytep data, png_size_t length )
|
|||||||
int
|
int
|
||||||
vips__png_write_buf( VipsImage *in,
|
vips__png_write_buf( VipsImage *in,
|
||||||
void **obuf, size_t *olen, int compression, int interlace,
|
void **obuf, size_t *olen, int compression, int interlace,
|
||||||
const char *profile )
|
const char *profile, VipsForeignPngFilter filter )
|
||||||
{
|
{
|
||||||
WriteBuf *wbuf;
|
WriteBuf *wbuf;
|
||||||
Write *write;
|
Write *write;
|
||||||
@ -1043,7 +1049,7 @@ vips__png_write_buf( VipsImage *in,
|
|||||||
|
|
||||||
/* Convert it!
|
/* Convert it!
|
||||||
*/
|
*/
|
||||||
if( write_vips( write, compression, interlace, profile ) ) {
|
if( write_vips( write, compression, interlace, profile, filter ) ) {
|
||||||
write_buf_free( wbuf );
|
write_buf_free( wbuf );
|
||||||
vips_error( "vips2png",
|
vips_error( "vips2png",
|
||||||
"%s", _( "unable to write to buffer" ) );
|
"%s", _( "unable to write to buffer" ) );
|
||||||
|
@ -46,10 +46,11 @@ int vips__png_read_buffer( char *buffer, size_t length, VipsImage *out,
|
|||||||
int vips__png_header_buffer( char *buffer, size_t length, VipsImage *out );
|
int vips__png_header_buffer( char *buffer, size_t length, VipsImage *out );
|
||||||
|
|
||||||
int vips__png_write( VipsImage *in, const char *filename,
|
int vips__png_write( VipsImage *in, const char *filename,
|
||||||
int compress, int interlace, const char *profile );
|
int compress, int interlace, const char *profile,
|
||||||
|
VipsForeignPngFilter filter );
|
||||||
int vips__png_write_buf( VipsImage *in,
|
int vips__png_write_buf( VipsImage *in,
|
||||||
void **obuf, size_t *olen, int compression, int interlace,
|
void **obuf, size_t *olen, int compression, int interlace,
|
||||||
const char *profile );
|
const char *profile, VipsForeignPngFilter filter );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ GType vips_foreign_tiff_predictor_get_type (void) G_GNUC_CONST;
|
|||||||
#define VIPS_TYPE_FOREIGN_TIFF_PREDICTOR (vips_foreign_tiff_predictor_get_type())
|
#define VIPS_TYPE_FOREIGN_TIFF_PREDICTOR (vips_foreign_tiff_predictor_get_type())
|
||||||
GType vips_foreign_tiff_resunit_get_type (void) G_GNUC_CONST;
|
GType vips_foreign_tiff_resunit_get_type (void) G_GNUC_CONST;
|
||||||
#define VIPS_TYPE_FOREIGN_TIFF_RESUNIT (vips_foreign_tiff_resunit_get_type())
|
#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_dz_layout_get_type (void) G_GNUC_CONST;
|
GType vips_foreign_dz_layout_get_type (void) G_GNUC_CONST;
|
||||||
#define VIPS_TYPE_FOREIGN_DZ_LAYOUT (vips_foreign_dz_layout_get_type())
|
#define VIPS_TYPE_FOREIGN_DZ_LAYOUT (vips_foreign_dz_layout_get_type())
|
||||||
GType vips_foreign_dz_depth_get_type (void) G_GNUC_CONST;
|
GType vips_foreign_dz_depth_get_type (void) G_GNUC_CONST;
|
||||||
|
@ -436,6 +436,28 @@ int vips_matrixprint( VipsImage *in, ... )
|
|||||||
int vips_magickload( const char *filename, VipsImage **out, ... )
|
int vips_magickload( const char *filename, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VipsForeignPngFilter:
|
||||||
|
* @VIPS_FOREIGN_PNG_FILTER_NONE
|
||||||
|
* @VIPS_FOREIGN_PNG_FILTER_SUB
|
||||||
|
* @VIPS_FOREIGN_PNG_FILTER_UP
|
||||||
|
* @VIPS_FOREIGN_PNG_FILTER_AVG
|
||||||
|
* @VIPS_FOREIGN_PNG_FILTER_PAETH
|
||||||
|
* @VIPS_FOREIGN_PNG_FILTER_ALL
|
||||||
|
*
|
||||||
|
* http://www.w3.org/TR/PNG-Filters.html
|
||||||
|
* The values mirror those of png.h in libpng.
|
||||||
|
*/
|
||||||
|
typedef enum /*< flags >*/ {
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_NONE = 0x08,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_SUB = 0x10,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_UP = 0x20,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_AVG = 0x40,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_PAETH = 0x80,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_ALL = 0xEA,
|
||||||
|
VIPS_FOREIGN_PNG_FILTER_LAST = 0xFF
|
||||||
|
} VipsForeignPngFilter;
|
||||||
|
|
||||||
int vips_pngload( const char *filename, VipsImage **out, ... )
|
int vips_pngload( const char *filename, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
int vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||||
|
@ -106,6 +106,28 @@ vips_foreign_tiff_resunit_get_type( void )
|
|||||||
return( etype );
|
return( etype );
|
||||||
}
|
}
|
||||||
GType
|
GType
|
||||||
|
vips_foreign_png_filter_get_type( void )
|
||||||
|
{
|
||||||
|
static GType etype = 0;
|
||||||
|
|
||||||
|
if( etype == 0 ) {
|
||||||
|
static const GFlagsValue values[] = {
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_NONE, "VIPS_FOREIGN_PNG_FILTER_NONE", "none"},
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_SUB, "VIPS_FOREIGN_PNG_FILTER_SUB", "sub"},
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_UP, "VIPS_FOREIGN_PNG_FILTER_UP", "up"},
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_AVG, "VIPS_FOREIGN_PNG_FILTER_AVG", "avg"},
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_PAETH, "VIPS_FOREIGN_PNG_FILTER_PAETH", "paeth"},
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_ALL, "VIPS_FOREIGN_PNG_FILTER_ALL", "all"},
|
||||||
|
{VIPS_FOREIGN_PNG_FILTER_LAST, "VIPS_FOREIGN_PNG_FILTER_LAST", "last"},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
etype = g_flags_register_static( "VipsForeignPngFilter", values );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( etype );
|
||||||
|
}
|
||||||
|
GType
|
||||||
vips_foreign_dz_layout_get_type( void )
|
vips_foreign_dz_layout_get_type( void )
|
||||||
{
|
{
|
||||||
static GType etype = 0;
|
static GType etype = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user