diff --git a/whatsnew-8.4.md b/whatsnew-8.4.md deleted file mode 100644 index 72d534be..00000000 --- a/whatsnew-8.4.md +++ /dev/null @@ -1,177 +0,0 @@ -libvips 8.4 should be out by the end of September 2016. This page introduces the main features. - -## New operators - -There are some fun new operators. `vips_perlin()` and `vips_worley()` -make Perlin and Worley noise. They are useful for generating -synthetic random textures. The implementations in vips can generate images of -any size very quickly. - -Here's an example of a marble texture simulated with a Perlin noise generator -using the Ruby libvips binding. - -``` -#!/usr/bin/ruby - -require 'vips' - -size = 1024 - -# perlin's "turbulence" image -def turbulence(size) - layers = [] - iterations = Math.log(size, 2) - 2 - (0 ... iterations).each do |i| - layer = Vips::Image.perlin(size, size, :cell_size => size / 2 ** i) - layer = layer.abs * (1.0 / (i + 1)) - layers << layer - end - - layers.reduce(:+) -end - -# make a 256 element colour map: a linear fade from start to stop, with -# start and stop as CIELAB colours, the output map as sRGB -def gradient(start, stop) - lut = Vips::Image.identity / 255 - lut = lut * start + (lut * -1 + 1) * stop - lut.colourspace(:srgb, :source_space => :lab) -end - -# an image where the pixel value is 0 .. 4 * 360 across -angles = Vips::Image.xyz(size, size)[0] * 360 * 4 / size - -# make a turbulent stripe pattern using 0 .. 255 -stripe = ((angles + turbulence(size) * 700).sin + 1) * 128 - -# make a colour map (a smooth gradient from white to dark brown) then map -# our turbulent image through it -dark_brown = [7.45, 4.3, 8] -white = [100, 0, 0] -stripe = stripe.maplut(gradient(dark_brown, white)) - -stripe.write_to_file ARGV[0] -``` - -## Rewritten convolution - -The convolution functions were the old vips7 ones with a small -wrapper. They've now been rewritten for vips8, and the vector path has -been completely replaced. It can be up to about 2x faster. - -The old vips7 vector path was based on int arithmetic, so this mask -(a simple 3x3 average), for example: - -``` -3 3 9 0 -1 1 1 -1 1 1 -1 1 1 -``` - -Would be computed as nine adds, followed by a divide by the constant 9, -with round-to-nearest. This was obviously accurate, but dividing -by a constant is slow. - -The new path first computes a fixed-point float approximation of the -int mask. In this case it'll settle on this: - -``` -3 3 1 0 -3 3 3 -3 4 4 -4 4 4 -``` - -Where 3 is approximately 1/9 in 3.5 bit fixed-point, and the whole -mask sums to 1.0 (the sum of the int mask), or 32 in 3.5 bit. - -It's not possible to match each element and the sum at the same time, -so vips uses an iterative algorithm to find the approximation that -matches the sum exactly, matches each element as well as it can, and -which spreads any error through the mask. In this case, the mix of 3 and 4 -is there to make the sum work. There's an error test and a fallback: -if the maximum possible error is over 10%, it'll switch to a non-vector -path based on exact int arithmetic. You can use `--vips-info` to see -what path ends up being taken. - -Now there's a fixed-point version of the mask, vips can compute the -convolution as 9 fused multiply-adds, followed by an add and a 5-bit shift -to get back to the nearest int. Getting rid of the divide-by-a-constant -gives a nice speed improvement. On my laptop with vips 8.3 and a 10k x 10k -pixel RGB image I see: - -``` -$ time vips conv wtc.v x7.v avg.mat --vips-info -real 0m1.311s -user 0m1.376s -sys 0m0.372s -``` - -With vips 8.4 it's now: - -``` -$ time vips convi wtc.v x8.v avg.mat --vips-info -info: convi: using vector path -real 0m0.774s -user 0m0.888s -sys 0m0.352s - -``` - -The peak error is small: - -``` -$ vips subtract x7.v x8.v x.v -$ vips abs x.v x2.v -$ vips max x2.v -11.000000 -``` - -## Image resize - -`vips_resize()` has seen some good improvements. - -* There's a new `centre` option which switches over to centre-convention for - subsampling. This makes it a much better match for ImageMagick. - `vipsthumbnail` uses this new option. -* It now does round-to-nearest when calculating image bounds. This makes it - much simpler to calculate a shrink factor which will produce an image of a - specific size. -* A series of changes improve accuracy for the linear and cubic kernels, and - improve spatial accuracy. -* It used to simply use nearest for upsampling, in line with things like PDF, - but this is not a good choice for many applications. It now upsizes with - bicubic by default. - -## Unicode on Windows - -This is only a small thing, but the Windows build now supports Unicode -filenames. - -## File format support - -As usual, there are a lot of improvements to file format read and write. - -* Thanks to work by Felix Bünemann, `webp` read and write supports many more - options. -* andris has improved `pdfload` so you can load many pages in a single - operation. -* Many people have worked on `dzsave` Google mode. It's now better at - skipping blank tiles and supports tile overlaps. Felix Bünemann added - support for compressed zip output. -* Henri Chain has added `radsave_buffer` to improve Radiance support. -* TIFF files with an orientation tag should now autorotate, `tiffsave` - has better jpeg compression support, and it knows about the `strip` - metadata option. -* The load-via-libMagick operator now supports IM7. -* The GIF loader is much smarter about guessing the number of colour channels. -* PNG save supports `strip`. -* The SVG loader supports `svgz` compressed files thanks to Felix Bünemann. - -## Other - -Improvements to the build system, reductions in memory use, many small -bug fixes, improvements to the C++ binding, improvements to the Python binding, -many small performance fixes. As usual, the ChanegLog has more detail if -you're interested. diff --git a/whatsnew-8.5.md b/whatsnew-8.5.md deleted file mode 100644 index b6b1b2ee..00000000 --- a/whatsnew-8.5.md +++ /dev/null @@ -1,184 +0,0 @@ -libvips 8.5 should be out by the end of March 2017. This page introduces the -main features. - -## New operators - -Almost all of the logic from the `vipsthumbnail` program is now in a pair of -new operators, `vips_thumbnail()` and `vips_thumbnail_buffer()`. These are very -handy for the various scripting languages with vips bindings: you can now make -a high-quality, high-speed thumbnail in PHP (for example) with just: - -```php -$filename = ...; -$image = Vips\Image::thumbnail($filename, 200, ["height" => 200]); -$image.writeToFile("my-thumbnail.jpg"); -``` - -The new thumbnail operator has also picked up some useful features: - -* **Smart crop** A new cropping mode called `attention` searches the image for - edges, skin tones and areas of saturated colour, and attempts to position the - crop box over the most significant feature. There's a `vips_smartcrop()` - operator as well. - -* **Crop constraints** Thanks to tomasc, libvips has crop constraints. You - can set it to only thumbnail if the image is larger or smaller than the target - (the `<` and `>` modifiers in imagemagick), and to crop to a width or height. - -* **Buffer sources** `vips_thumbnail_buffer()` will thumbnail an image held as - a formatted block of data in memory. This is useful for cloud services, where - the filesystem is often rather slow. - -CLAHE, or Contrast-Limited Adaptive Histogram Equalisation, is a simple way to -make local histogram equalisation more useful. - -Plain local equalization removes -all global brightness variation and can make images hard to understand. -The `hist_local` operator now has a `max-slope` parameter you can use to limit -how much equalisation can alter your image. A value of 3 generally works well. - -## Toilet roll images - -libvips used to let you pick single pages out of multi-page images, such -as PDFs, but had little support for processing entire documents. - -libvips 8.5 now has good support for toilet roll images. You can load a -multipage image as a very tall, thin strip, process the whole thing, and write -back to another multi-page file. The extra feature is an `n` parameter which -gives the number of pages to load, or -1 to load all pages. - -For example, (OME- -TIFF)[https://www.openmicroscopy.org/site/support/ome-model/ome-tiff] -is a standard for microscopy data that stores volumetric images as multi-page -TIFFs. They have some (sample -data)[https://www.openmicroscopy.org/site/support/ome-model/ome-tiff/data.html] -including a 4D image of an embryo. - -Each TIFF contains 10 slices. Normally you just see page 0: - -``` -$ vipsheader tubhiswt_C0_TP13.ome.tif -tubhiswt_C0_TP13.ome.tif: 512x512 uchar, 1 band, b-w, tiffload -``` - -Use `n=-1` and you see all the pages as a very tall strip: - -``` -$ vipsheader tubhiswt_C0_TP13.ome.tif[n=-1] -tubhiswt_C0_TP13.ome.tif: 512x5120 uchar, 1 band, b-w, tiffload -``` - -You can work with PDF, TIFF, GIF and all imagemagick-supported formats in -this way. - -You can write this tall strip to another file, and it will be broken up into -pages: - -``` -$ vips copy tubhiswt_C0_TP13.ome.tif[n=-1] x.tif -$ vipsheader x.tif -x.tif: 512x512 uchar, 1 band, b-w, tiffload -$ vipsheader x.tif[n=-1] -x.tif: 512x5120 uchar, 1 band, b-w, tiffload -``` - -The extra magic is a `page-height` property that images carry around that says -how long each sheet of toilet paper is. - -There are clearly some restrictions with this style of multi-page document -handling: all pages must have identical width, height and colour depth; and image -processing operators have no idea they are dealing with a multi-page document, -so if you do something like `resize`, you'll need to update `page-height`. -You'll also need to be careful about edge effects if you're using spatial -filters. - -## Computation reordering - -Thanks to the developer of -(PhotoFlow)[https://github.com/aferrero2707/PhotoFlow], a non-destructive image -editor with a libvips backend, libvips can now reorder computations to reduce -recalculation. This can (sometimes) produce a dramatic speedup. - -This has been (discussed on the libvips -blog)[http://libvips.blogspot.co.uk/2017/01/automatic-computation-reordering.html], -but briefly, the order in which operator arguments are evaluated can have a -big effect on runtime due to the way libvips tries to cache and reuse results -behind the scenes. - -The blog post has some examples and some graphs. - -## New sequential mode - -libvips sequential mode has been around for a while. This is the thing libvips -uses to stream pixels through your computer, from input file to output file, -without having to have the whole image in memory all at the same time. When it -works, it give a nice performance boost and a large drop in memory use. - -There are some more complex cases where it didn't work. Consider this Python -program: - -```python -#!/usr/bin/python - -import sys -import random - -import gi -gi.require_version('Vips', '8.0') -from gi.repository import Vips - -composite = Vips.Image.black(10000, 10000) - -for filename in sys.argv[2:]: - tile = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL) - x = random.randint(0, composite.width - tile.width) - y = random.randint(0, composite.height - tile.height) - composite = composite.insert(tile, x, y) - -composite.write_to_file(sys.argv[1]) -``` - -It makes a large 10,000 x 10,000 pixel image, then inserts all of the images -you list at random positions, then writes the result. - -You'd think this could work with sequential mode, but sadly with earlier -libvipses it will sometimes fail. The problem is that images can cover each -other, so while writing, libvips can discover that it only needs the bottom few -pixels of one of the input images. The image loaders used to track the current -read position, and if a request came in for some pixels way down the image, -they'd assume one of the evaluation threads had run ahead of the rest and -needed to be stalled. Once stalled, it was only restarted on a long timeout, -causing performance to drop through the floor. - -libvips 8.5 has a new implementation of sequential mode that changes the way -threads are kept together as images are processed. Rather than trying to add -constraints to load operations, instead it puts the constraints into operations -that can cause threads to become spread out, such as vertical shrink. - -As a result of this change, many more things can run in sequential mode, and -out of order reads should be impossible. - -## `libxml2` swapped out for `expat` - -libvips has used libxml2 as its XML parser since dinosaurs roamed the Earth. -Now libvips is based on gobject, the XML parser selected by glib, expat, makes -more sense, since it will already be linked. - -It's nice to be able to remove a required dependency for a change. - -## File format support - -As usual, there are a range of improvements to file format read and write. - -* Thanks to a push from Felix Bünemann, TIFF now supports load and save to and - from memory buffers. -* `dzsave` can write to memory (as a zip file) as well. -* Again, thanks to pushing from Felix, libvips now supports ICC, XMP and IPCT - metadata for WebP images. -* FITS images support `bzero` and `bscale`. -* `tiffload` memory use is now much lower for images with large strips. - -## Other - -Many small bug fixes, improvements to the C++ binding. As usual, the -ChangeLog has more detail, if you're interested.