libvips/whatsnew-8.5.md

135 lines
4.7 KiB
Markdown
Raw Normal View History

2017-03-14 15:58:33 +01:00
libvips 8.5 should be out by the end of March 2017. This page introduces the
main features.
2017-03-13 15:56:19 +01:00
2017-03-14 15:58:33 +01:00
## New operators
thumbnail / thumbnail_buffer
2017-03-13 15:56:19 +01:00
How seq used to work:
* The vips sink functions create a set of N threads and scan images
top-to-bottom in tiles, allocating tiles to workers as they finish.
* They have extra logic to keep workers together. They track the position
of the most-delayed worker and if the lead thread gets more than M scanlines
ahead, it stalls until the stragglers catch up.
* There is more logic in the loaders: they keep track of the current
Y position, and if the lead request thread gets ahead of the current
read point, it stalls with a 60s timeout until the intermediate tiles are
requested. This logic is implemented in the `vips_sequential()` operation.
The point of trying to keep thread locality and ordering is that we want
to limit the number of scanlines that loaders have to keep behind the read
point. We want to stream images through memory, not be forced into a load /
process / save model.
This works reasonably well for simple cases, like thumbnailing single images,
but can fail in more complex cases, such as repeated `vips_insert()`. 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(100000, 100000)
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])
```
This makes a 100,000 x 100,000 pixel black image, then inserts a lot of
other files into it and writes the result.
With vips8.4, this could very easily fail. Imagine this situation:
* image1 is very tall and thin
* image2 is short and fat, and by chance covers the centre of image1
* we'll write the top part of image1, then write the body of image2
* after image2 has been written, we need to write the bottom of image1,
so a thread will ask for a set of pixels near the end of image1
* image1 knows that the previous request was for some scanlines near the top,
so it thinks this request must be from a thread that has run way ahead of
the pack and stalls it
And we have a deadlock. In fact, vips wouldn't deadlock, it would just
pause on a 60s timeout on each thread. Sad!
Here's how the new seq works:
* Sinks work as before.
* Loaders use a revised `vips_sequential()` with the stalling logic
removed. All it does now is track the read position, cache a few 100 lines
behind the read point, and makes sure that lines are evaluated in order
with no missing areas.
* Operations like `vips_shrinkv()` which can cause large non-local references
have an extra bit of code which, if the input comes from a sequential source,
adds a an extra `vips_sequential()` operator on the output. This forces
`vips_shrinkv()` input to be sequential.
The old one constrained thread location on output, and on input as well. The
new idea is to get rid of input constraints, and instead add extra code
to the operations which could trigger large non-local references. Rather
than tying threads down to stop them drifting apart, it makes sure they
can never get too far apart in the first place.
Running the test program with git master gives this result:
```
real 1m2.317s
user 2m58.472s
sys 0m7.568s
peak mem: 10gb
```
Not bad!
2017-03-14 15:58:33 +01:00
## Reordering
from blog
## Image resize
smartcrop, more flexible cropping
## 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.