What's New in 7.28

From VipsWiki

Revision as of 09:33, 26 February 2012; view current revision
←Older revision | Newer revision→
Jump to: navigation, search

This page summarises the changes for version 7.28. We have a detailed VIPS ChangeLog and nip2 ChangeLog, but as headlines:

libvips rewrite 
About a third of libvips has been rewritten with the new framework that's been created for vips8. New operations are faster, more flexible and easier to use. There's full compatibility with the old interface as well. See below for some examples.
OpenSlide support 
libvips now supports OpenSlide, an image format for biological slides. Contributed by Benjamin Gilbert.
Better file format support 
Improvements to jpeg, png and tiff handling let you manipulate EXIF tags, support better jpeg-in-tiff compression and support a wider range of png images.
Sequential mode read 
A new image read mode lets you perform some operations (like thumbnailing) on some image formats much more quickly. See below.
Operation cache 
libvips now keeps a cache of recent operations: when you perform a calculation, it'll reuse old results from the cache when it can. This can produce a huge speedup in complex programs.
Minor nip2 improvements 
There's a new image header browser, fixes to help the Unity interface on Ubuntu, a new right-click menu for images and some more Matrix operations. See below.
Better Windows build 
The Windows version has been built with a new version of the GTK toolkit that should be quite a bit better. There are improvements to appearance, speed, file dialogs, drag and drop and copy paste support.

Plus the usual minor speed-ups, portability improvements, enhancements and bug fixes. What's New in 7.26 is still there if you're interested.

libvips rewrite

In 7.26 we introduced a new core for libvips. In this version we've started rewriting libvips operators to use this new system. A set of compatibility functions now implement the old vips7 interface on top of these new operators.

One of the big new features is optional output arguments. For example, VipsMin is an operation that finds the minimum value of an image. You can run it from the command-line like this:

   $ vips min fred.jpg
   12

Very similar to the old im_min(). But now there are also optional output arguments to get the position of the minimum:

   $ vips min --x --y fred.jpg
   12
   2345
   245

Run with no arguments to get a handy help display:

$ vips min
usage:
  min in out 
where:
  in           - Input image, input VipsImage
  out          - Output value, output gdouble
optional arguments:
  y            - Vertical position of minimum, output gint
  x            - Horizontal position of minimum, output gint
min: too few arguments

You get the same API in Python, Ruby, Javascript, nip2, C and C++:

   >> m = im.min()
   >> print m
   12
   >> m, x, y = im.min(x = True, y = True)
   VipsImage *fred;
   double m;
   int x, y;
   vips_min( fred, &m,
     "x", &x,
     "y", &y,
     NULL );

Args only need a few of lines of code to add to a class and everything else is generated for you automatically at runtime. For example, the optional --x arg for VipsMin is declared like this:

   VIPS_ARG_INT( class, "x", 2,
     _( "x" ), _( "Horizontal position of minimum" ),
     VIPS_ARGUMENT_OPTIONAL_OUTPUT,
     G_STRUCT_OFFSET( VipsMin, x ),
     0, 1000000, 0 );

That binds an optional int arg with the range locked to 0 to 10000000 to the member x of the class VipsMin. Your bit of C just needs to assign that member and the value will appear in all languages and all interfaces.

VipsJoin has one of the fanciest ones. At a minimum it's:

   $ vips join left.v right.v out.v horizontal

to join two images left-right, but there are also extra optional arguments, for example:

   $ vips join --expand --background 0,255,0 --align centre --shim 50 left.v right.v out.v horizontal

to join left-right with a 50 pixel gap, the output expanded to hold all of both left and right, and the background painted green.

New file format system

You used to specify file formats and give them options like this:

   $ vips im_vips2tiff myfile.v newfile.tiff:jpeg

meaning load the file myfile.v, then write it to newfile.tiff in TIFF format with jpeg compression.

The vips8 equivalent is called tiffsave. If you run it with no arguments you get a nice help display:

   $ vips tiffsave
   usage:
      tiffsave in filename
   where:
      in           - Image to save, input VipsImage
      filename     - Filename to save to, input gchararray
   optional arguments:
      compression  - Compression for this file, input VipsTiffCompression
      Q            - Q factor, input gint
      predictor    - Compression prediction, input VipsTiffPredictor
      profile      - ICC profile to embed, input gchararray
      tile         - Write a tiled tiff, input gboolean
      tile-width   - Tile width in pixels, input gint
      tile-height  - Tile height in pixels, input gint
      pyramid      - Write a pyramidal tiff, input gboolean
      squash       - Squash images down to 1 bit, input gboolean
      resunit      - Resolution unit, input VipsTiffResunit
      bigtiff      - Write a bigtiff image, input gboolean

and you can do the equivalent of the old vips7 command above like this:

   $ vips tiffsave myfile.v newfile.tiff --compression jpeg

You can also embed options in the filename using the standard vips8 syntax. For example:

   $ vips invert fred.jpg jim.tif[compression=jpeg]

Which will load fred.jpg, invert it, then save as a jpeg-compressed tiff.

The old vips7 system is still there and working, though it's now just a thin skin over the new system, so it's fully backwards-compatible.

Sequential mode read

Many image formats only really support sequential reading. For example, libpng provides png_read_row(), a function which reads the next line of pixels from a file. You call it once for each line in the image to get every pixel.

However, many operations require random access to pixels. For example, a 90-degree rotate will need to read a column of pixels for every output line it writes. If it just used png_read_row() it would need to decompress the input image many, many times in order to create the output.

To prevent this, libvips will first decompress the entire image to a large temporary area and then process from that. This temporary area is in memory for small files or on disc for large files.

Not all operations need random access to their source pixels. For example, thumbnailing, the process of shrinking images for display, can work strictly top-to-bottom. To help speed up operations of this type, libvips has a new hint that you can give to read operations to indicate that you only need sequential access.

$ time vips --vips-leak copy wtc.jpg[sequential] wtc.tif
real    0m4.903s
user    0m1.384s
sys     0m0.512s
memory: high-water mark 70.73 MB

(where wtc.jpg is a 10,000 by 10,000 pixel RGB image and --vips-leak makes libvips print peak memory use)

Here the [sequential] hint means that we will only need top-to-bottom access to the pixels in wtc.jpg. When libvips opens this image it will not decompress to a temporary buffer but, instead, stream pixels from the jpeg decompressor directly through the operation. This saves first writing and then reading the 300 MB temporary area.

The sequential mode reader keeps a few hundred lines behind the current read point in a cache so it can handle some small amount of non-sequential access. If you try something that's very non-sequential after giving the [sequential] hint, you get an error.

$ time vips flip wtc.png[sequential] wtc.tif vertical
VipsSequential: non-sequential read --- at position 0 in file, but position 9344 requested 

Without the [sequential] hint you get the current libvips behaviour, which is noticeably slower and of course makes much more disc traffic:

$ time vips copy wtc.jpg wtc.tif
real    0m6.004s
user    0m1.588s
sys     0m1.208s
memory: high-water mark 77.46 MB

The jpeg, stripped tiff and png readers now support sequential mode read.

The libvips thumbnailing utility, vipsthumbnail, now turns on sequential mode for you, so you get this nice behaviour automatically.

You can see a good speedup when building large pyramids:

$ time vips copy world.topo.bathy.200405.3x21600x21600.A1.jpg A1-pyr.tif[compression=jpeg,tile,pyramid]
real 1m12.996s
user 0m22.845s
sys 0m4.552s

$ time vips copy world.topo.bathy.200405.3x21600x21600.A1.jpg[sequential] A1-pyr.tif[compression=jpeg,tile,pyramid]
real 0m24.218s
user 0m22.277s
sys 0m1.172s
Personal tools