Merge branch '8.6'
This commit is contained in:
commit
5b55dd8ed4
@ -16,8 +16,9 @@
|
|||||||
- set "interlaced=1" for interlaced JPG and PNG images
|
- set "interlaced=1" for interlaced JPG and PNG images
|
||||||
|
|
||||||
12/3/18 started 8.6.4
|
12/3/18 started 8.6.4
|
||||||
- better fitting of fonts with overhanging edges, thanks Adrià
|
- better fitting of fonts with overhanging edges [Adrià]
|
||||||
- lower stack use in radsave to help musl [Jacob Thrane Lund]
|
- revise C++ example [fangqiao]
|
||||||
|
- strict round down on jpeg shrink on load [davidwood]
|
||||||
|
|
||||||
12/2/18 started 8.6.3
|
12/2/18 started 8.6.3
|
||||||
- use pkg-config to find libjpeg, if we can
|
- use pkg-config to find libjpeg, if we can
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<programlisting language="cpp">
|
<programlisting language="cpp">
|
||||||
/* compile with:
|
/* 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>
|
#include <vips/vips8>
|
||||||
@ -36,44 +36,26 @@ using namespace vips;
|
|||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
GOptionContext *context;
|
|
||||||
GOptionGroup *main_group;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
if (VIPS_INIT (argv[0]))
|
if (VIPS_INIT (argv[0]))
|
||||||
vips_error_exit (NULL);
|
vips_error_exit (NULL);
|
||||||
|
|
||||||
context = g_option_context_new( "" );
|
if (argc != 3)
|
||||||
|
vips_error_exit ("usage: %s input-file output-file", argv[0]);
|
||||||
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 in = VImage::new_from_file (argv[1],
|
||||||
VImage::option()->
|
VImage::option ()->set ("access", VIPS_ACCESS_SEQUENTIAL));
|
||||||
set( "access", VIPS_ACCESS_SEQUENTIAL ) );
|
|
||||||
|
|
||||||
double avg = in.avg ();
|
double avg = in.avg ();
|
||||||
|
|
||||||
printf ("avg = %g\n", avg);
|
printf ("avg = %g\n", avg);
|
||||||
printf ("width = %d\n", in.width ());
|
printf ("width = %d\n", in.width ());
|
||||||
|
|
||||||
VImage in = VImage::new_from_file( argv[1],
|
in = VImage::new_from_file (argv[1],
|
||||||
VImage::option()->
|
VImage::option ()->set ("access", VIPS_ACCESS_SEQUENTIAL));
|
||||||
set( "access", VIPS_ACCESS_SEQUENTIAL ) );
|
|
||||||
|
|
||||||
VImage out = in.embed (10, 10, 1000, 1000,
|
VImage out = in.embed (10, 10, 1000, 1000,
|
||||||
VImage::option()->
|
VImage::option ()->
|
||||||
set( "extend", "background" )->
|
set ("extend", "background")->
|
||||||
set ("background", 128));
|
set ("background", 128));
|
||||||
|
|
||||||
out.write_to_file (argv[2]);
|
out.write_to_file (argv[2]);
|
||||||
@ -86,12 +68,13 @@ main( int argc, char **argv )
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
Everything before <code>VImage in = VImage::..</code> is exactly
|
Everything before <code>VImage in = VImage::..</code> is exactly
|
||||||
as the C API. This boilerplate gives the example a set of standard
|
as the C API. vips_error_exit() just prints the arguments plus the
|
||||||
command-line flags.
|
libvips error log and exits with an error code.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<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:
|
in the same way, the differences being:
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
@ -96,6 +96,8 @@
|
|||||||
* that
|
* that
|
||||||
* 9/4/18
|
* 9/4/18
|
||||||
* - set interlaced=1 for interlaced images
|
* - set interlaced=1 for interlaced images
|
||||||
|
* 10/4/18
|
||||||
|
* - strict round down on shrink-on-load
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -153,8 +155,6 @@
|
|||||||
/* Stuff we track during a read.
|
/* Stuff we track during a read.
|
||||||
*/
|
*/
|
||||||
typedef struct _ReadJpeg {
|
typedef struct _ReadJpeg {
|
||||||
VipsImage *out;
|
|
||||||
|
|
||||||
/* Shrink by this much during load. 1, 2, 4, 8.
|
/* Shrink by this much during load. 1, 2, 4, 8.
|
||||||
*/
|
*/
|
||||||
int shrink;
|
int shrink;
|
||||||
@ -179,6 +179,13 @@ typedef struct _ReadJpeg {
|
|||||||
* during load.
|
* during load.
|
||||||
*/
|
*/
|
||||||
gboolean autorotate;
|
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;
|
} ReadJpeg;
|
||||||
|
|
||||||
/* This can be called many times.
|
/* This can be called many times.
|
||||||
@ -230,7 +237,6 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean autorotate )
|
|||||||
if( !(jpeg = VIPS_NEW( out, ReadJpeg )) )
|
if( !(jpeg = VIPS_NEW( out, ReadJpeg )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
jpeg->out = out;
|
|
||||||
jpeg->shrink = shrink;
|
jpeg->shrink = shrink;
|
||||||
jpeg->fail = fail;
|
jpeg->fail = fail;
|
||||||
jpeg->filename = NULL;
|
jpeg->filename = NULL;
|
||||||
@ -410,6 +416,18 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
|
|
||||||
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_FATSTRIP, NULL );
|
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
|
/* Interlaced jpegs need lots of memory to read, so our caller needs
|
||||||
* to know.
|
* to know.
|
||||||
*/
|
*/
|
||||||
@ -691,15 +709,20 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
printf( "read_jpeg_image: starting decompress\n" );
|
printf( "read_jpeg_image: starting decompress\n" );
|
||||||
#endif /*DEBUG*/
|
#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],
|
if( vips_image_generate( t[0],
|
||||||
NULL, read_jpeg_generate, NULL,
|
NULL, read_jpeg_generate, NULL,
|
||||||
jpeg, NULL ) ||
|
jpeg, NULL ) ||
|
||||||
vips_sequential( t[0], &t[1],
|
vips_sequential( t[0], &t[1],
|
||||||
"tile_height", 8,
|
"tile_height", 8,
|
||||||
NULL ) )
|
NULL ) ||
|
||||||
|
vips_extract_area( t[1], &t[2],
|
||||||
|
0, 0, jpeg->output_width, jpeg->output_height, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
im = t[1];
|
im = t[2];
|
||||||
if( jpeg->autorotate )
|
if( jpeg->autorotate )
|
||||||
im = read_jpeg_rotate( VIPS_OBJECT( out ), im );
|
im = read_jpeg_rotate( VIPS_OBJECT( out ), im );
|
||||||
|
|
||||||
@ -738,6 +761,11 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
|||||||
if( read_jpeg_header( jpeg, out ) )
|
if( read_jpeg_header( jpeg, out ) )
|
||||||
return( -1 );
|
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.
|
/* Swap width and height if we're going to rotate this image.
|
||||||
*/
|
*/
|
||||||
if( jpeg->autorotate ) {
|
if( jpeg->autorotate ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user