Merge branch 'master' into pdfium-experiment
This commit is contained in:
commit
3d696b9c1e
@ -12,10 +12,13 @@
|
||||
- drop incompatible ICC profiles before save
|
||||
- better hasalpha rules
|
||||
- create funcs always make MULTIBAND (ie. no alpha)
|
||||
- use O_TMPFILE, if available [Alexander--]
|
||||
- set "interlaced=1" for interlaced JPG and PNG images
|
||||
|
||||
12/3/18 started 8.6.4
|
||||
- better fitting of fonts with overhanging edges, thanks Adrià
|
||||
- lower stack use in radsave to help musl [Jacob Thrane Lund]
|
||||
- better fitting of fonts with overhanging edges [Adrià]
|
||||
- revise C++ example [fangqiao]
|
||||
- strict round down on jpeg shrink on load [davidwood]
|
||||
|
||||
12/2/18 started 8.6.3
|
||||
- use pkg-config to find libjpeg, if we can
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
<programlisting language="cpp">
|
||||
/* compile with:
|
||||
* g++ -g -Wall try.cc `pkg-config vips-cpp --cflags --libs`
|
||||
* g++ -g -Wall example.cc `pkg-config vips-cpp --cflags --libs`
|
||||
*/
|
||||
|
||||
#include <vips/vips8>
|
||||
@ -34,64 +34,47 @@
|
||||
using namespace vips;
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
GOptionContext *context;
|
||||
GOptionGroup *main_group;
|
||||
GError *error = NULL;
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (VIPS_INIT (argv[0]))
|
||||
vips_error_exit (NULL);
|
||||
|
||||
if (argc != 3)
|
||||
vips_error_exit ("usage: %s input-file output-file", argv[0]);
|
||||
|
||||
if( VIPS_INIT( argv[0] ) )
|
||||
vips_error_exit( NULL );
|
||||
|
||||
context = g_option_context_new( "" );
|
||||
|
||||
main_group = g_option_group_new( NULL, NULL, NULL, NULL, NULL );
|
||||
g_option_context_set_main_group( context, main_group );
|
||||
g_option_context_add_group( context, vips_get_option_group() );
|
||||
|
||||
if( !g_option_context_parse( context, &argc, &argv, &error ) ) {
|
||||
if( error ) {
|
||||
fprintf( stderr, "%s\n", error->message );
|
||||
g_error_free( error );
|
||||
}
|
||||
|
||||
vips_error_exit( NULL );
|
||||
}
|
||||
|
||||
VImage in = VImage::new_from_file( argv[1],
|
||||
VImage::option()->
|
||||
set( "access", VIPS_ACCESS_SEQUENTIAL ) );
|
||||
|
||||
double avg = in.avg();
|
||||
|
||||
printf( "avg = %g\n", avg );
|
||||
printf( "width = %d\n", in.width() );
|
||||
|
||||
VImage in = VImage::new_from_file( argv[1],
|
||||
VImage::option()->
|
||||
set( "access", VIPS_ACCESS_SEQUENTIAL ) );
|
||||
|
||||
VImage out = in.embed( 10, 10, 1000, 1000,
|
||||
VImage::option()->
|
||||
set( "extend", "background" )->
|
||||
set( "background", 128 ) );
|
||||
|
||||
out.write_to_file( argv[2] );
|
||||
|
||||
vips_shutdown();
|
||||
|
||||
return( 0 );
|
||||
VImage in = VImage::new_from_file (argv[1],
|
||||
VImage::option ()->set ("access", VIPS_ACCESS_SEQUENTIAL));
|
||||
|
||||
double avg = in.avg ();
|
||||
|
||||
printf ("avg = %g\n", avg);
|
||||
printf ("width = %d\n", in.width ());
|
||||
|
||||
in = VImage::new_from_file (argv[1],
|
||||
VImage::option ()->set ("access", VIPS_ACCESS_SEQUENTIAL));
|
||||
|
||||
VImage out = in.embed (10, 10, 1000, 1000,
|
||||
VImage::option ()->
|
||||
set ("extend", "background")->
|
||||
set ("background", 128));
|
||||
|
||||
out.write_to_file (argv[2]);
|
||||
|
||||
vips_shutdown ();
|
||||
|
||||
return (0);
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Everything before <code>VImage in = VImage::..</code> is exactly
|
||||
as the C API. This boilerplate gives the example a set of standard
|
||||
command-line flags.
|
||||
as the C API. vips_error_exit() just prints the arguments plus the
|
||||
libvips error log and exits with an error code.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This line is the C++ equivalent of vips_image_new_from_file(). It works
|
||||
<code>VImage in = VImage::..</code> is the C++ equivalent of
|
||||
vips_image_new_from_file(). It works
|
||||
in the same way, the differences being:
|
||||
|
||||
<itemizedlist>
|
||||
|
@ -54,6 +54,7 @@
|
||||
static int
|
||||
tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
{
|
||||
#ifdef HAVE_TIFF
|
||||
char filename[FILENAME_MAX];
|
||||
char mode[FILENAME_MAX];
|
||||
char *p, *q;
|
||||
@ -84,7 +85,6 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
* malloc if all we are doing is looking at fields.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
if( !header_only &&
|
||||
!seq &&
|
||||
!vips__istifftiled( filename ) &&
|
||||
|
@ -94,6 +94,10 @@
|
||||
* - revert previous warning change: libvips reports serious corruption,
|
||||
* like a truncated file, as a warning and we need to be able to catch
|
||||
* that
|
||||
* 9/4/18
|
||||
* - set interlaced=1 for interlaced images
|
||||
* 10/4/18
|
||||
* - strict round down on shrink-on-load
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -151,8 +155,6 @@
|
||||
/* Stuff we track during a read.
|
||||
*/
|
||||
typedef struct _ReadJpeg {
|
||||
VipsImage *out;
|
||||
|
||||
/* Shrink by this much during load. 1, 2, 4, 8.
|
||||
*/
|
||||
int shrink;
|
||||
@ -177,6 +179,13 @@ typedef struct _ReadJpeg {
|
||||
* during load.
|
||||
*/
|
||||
gboolean autorotate;
|
||||
|
||||
/* cinfo->output_width and height can be larger than we want since
|
||||
* libjpeg rounds up on shrink-on-load. This is the real size we will
|
||||
* output, as opposed to the size we decompress to.
|
||||
*/
|
||||
int output_width;
|
||||
int output_height;
|
||||
} ReadJpeg;
|
||||
|
||||
/* This can be called many times.
|
||||
@ -228,7 +237,6 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean autorotate )
|
||||
if( !(jpeg = VIPS_NEW( out, ReadJpeg )) )
|
||||
return( NULL );
|
||||
|
||||
jpeg->out = out;
|
||||
jpeg->shrink = shrink;
|
||||
jpeg->fail = fail;
|
||||
jpeg->filename = NULL;
|
||||
@ -408,12 +416,29 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out )
|
||||
|
||||
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL );
|
||||
|
||||
/* cinfo->output_width and cinfo->output_height round up with
|
||||
* shrink-on-load. For example, if the image is 1801 pixels across and
|
||||
* we shrink by 4, the output will be 450.25 pixels across,
|
||||
* cinfo->output_width with be 451, and libjpeg will write a black
|
||||
* column of pixels down the right.
|
||||
*
|
||||
* We must strictly round down, since we don't want fractional pixels
|
||||
* along the bottom and right.
|
||||
*/
|
||||
jpeg->output_width = cinfo->image_width / jpeg->shrink;
|
||||
jpeg->output_height = cinfo->image_height / jpeg->shrink;
|
||||
|
||||
/* Interlaced jpegs need lots of memory to read, so our caller needs
|
||||
* to know.
|
||||
*/
|
||||
(void) vips_image_set_int( out, "jpeg-multiscan",
|
||||
jpeg_has_multiple_scans( cinfo ) );
|
||||
|
||||
/* 8.7 adds this for PNG as well, so we have a new format-neutral name.
|
||||
*/
|
||||
if( jpeg_has_multiple_scans( cinfo ) )
|
||||
vips_image_set_int( out, "interlaced", 1 );
|
||||
|
||||
/* Look for EXIF and ICC profile.
|
||||
*/
|
||||
for( p = cinfo->marker_list; p; p = p->next ) {
|
||||
@ -684,15 +709,20 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
||||
printf( "read_jpeg_image: starting decompress\n" );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* We must crop after the seq, or our generate may not be asked for
|
||||
* full lines of pixels and will attempt to write beyond the buffer.
|
||||
*/
|
||||
if( vips_image_generate( t[0],
|
||||
NULL, read_jpeg_generate, NULL,
|
||||
jpeg, NULL ) ||
|
||||
vips_sequential( t[0], &t[1],
|
||||
"tile_height", 8,
|
||||
NULL ) )
|
||||
NULL ) ||
|
||||
vips_extract_area( t[1], &t[2],
|
||||
0, 0, jpeg->output_width, jpeg->output_height, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
im = t[1];
|
||||
im = t[2];
|
||||
if( jpeg->autorotate )
|
||||
im = read_jpeg_rotate( VIPS_OBJECT( out ), im );
|
||||
|
||||
@ -731,6 +761,11 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
||||
if( read_jpeg_header( jpeg, out ) )
|
||||
return( -1 );
|
||||
|
||||
/* Patch in the correct size.
|
||||
*/
|
||||
out->Xsize = jpeg->output_width;
|
||||
out->Ysize = jpeg->output_height;
|
||||
|
||||
/* Swap width and height if we're going to rotate this image.
|
||||
*/
|
||||
if( jpeg->autorotate ) {
|
||||
|
@ -65,6 +65,8 @@
|
||||
* - better behaviour for truncated png files, thanks Yury
|
||||
* 26/4/17
|
||||
* - better @fail handling with truncated PNGs
|
||||
* 9/4/18
|
||||
* - set interlaced=1 for interlaced images
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -438,6 +440,11 @@ png2vips_header( Read *read, VipsImage *out )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Let our caller know. These are very expensive to decode.
|
||||
*/
|
||||
if( interlace_type != PNG_INTERLACE_NONE )
|
||||
vips_image_set_int( out, "interlaced", 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* - use expat for xml read, printf for xml write
|
||||
* 16/8/17
|
||||
* - validate strs as being utf-8 before we write
|
||||
* 9/4/18 Alexander--
|
||||
* - use O_TMPFILE, if available
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -55,6 +57,10 @@
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
/* Enable linux extensions like O_TMPFILE, if available.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
@ -181,28 +187,37 @@ vips__open_image_write( const char *filename, gboolean temp )
|
||||
|
||||
flags = MODE_WRITE;
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
/* Linux-only extension creates an unlinked file. CREAT and TRUNC must
|
||||
* be clear. The filename arg to open() must name a directory.
|
||||
*/
|
||||
if( temp ) {
|
||||
char *dirname;
|
||||
|
||||
flags |= O_TMPFILE;
|
||||
flags &= ~O_CREAT;
|
||||
flags &= ~O_TRUNC;
|
||||
|
||||
dirname = g_path_get_dirname( filename );
|
||||
fd = vips_tracked_open( dirname, flags, 0666 );
|
||||
g_free( dirname );
|
||||
}
|
||||
else
|
||||
fd = vips_tracked_open( filename, flags, 0666 );
|
||||
#else /*!O_TMPFILE*/
|
||||
#ifdef _O_TEMPORARY
|
||||
/* On Windows, setting O_TEMP gets the file automatically
|
||||
/* On Windows, setting _O_TEMPORARY gets the file automatically
|
||||
* deleted on process exit, even if the processes crashes. See
|
||||
* vips_image_rewind() for what we do to help on *nix.
|
||||
*/
|
||||
if( temp )
|
||||
flags |= _O_TEMPORARY;
|
||||
#endif /*_O_TEMPORARY*/
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
/* Added in linux 3.11, but still not available in most glibc. We
|
||||
* unlink the file ourselves anyway, so it doesn't matter if this
|
||||
* fails.
|
||||
*/
|
||||
if( temp )
|
||||
flags |= O_TMPFILE;
|
||||
#endif /*O_TMPFILE*/
|
||||
|
||||
if( (fd = vips_tracked_open( filename, flags, 0666 )) < 0 ) {
|
||||
if( fd < 0 ) {
|
||||
vips_error_system( errno, "VipsImage",
|
||||
_( "unable to write to \"%s\"" ),
|
||||
filename );
|
||||
_( "unable to write to \"%s\"" ), filename );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user