Skip to content

What's_New_in_7.14

John Cupitt edited this page Mar 29, 2017 · 1 revision

title: What's New in 7.14 permalink: /What's_New_in_7.14/

We have a detailed VIPS ChangeLog and nip2 ChangeLog, but in headline form:

Integrated GREYCstoration filter : A powerful noise-removing filter, see below. Much better evaluation progress : Almost all long operations now have feedback. Previously, nip2 was only able to give feedback for operations which produced output images. Support for CMYK JPEGs : Both for read and write. Nameable rows : You can name rows now, see below. Per-workspace definitions : You can attach definitions to a workspace, see below. Better command-line mode : A new flag lets you easily pass values to workspaces you run in batch mode, see below. Better programming language : nip2's programming language now has lambdas, left-hand-side pattern matching and list comprehensions, see below. Speedups : nip2 starts about 25% faster and includes various small-ish speedups for various operations. Image display should be noticeably faster. Other : Many small bug-fixes, speedups, enhancements, plugged memory leaks. vips has a bunch of new stuff as well.

GREYCstoration

GREYCstoration is a popular noise removing filter. You can also use it to enlarge images, filling in detail. Click Toolkits / Filter / GREYCstoration.

200px 200px 200px

Samples. Click to enlarge.

As part of this, you can now write chunks of libvips in C++. I've not tried writing a plugin in C++ yet, but I guess it should work.

Nameable rows

Try entering "fred = 12" at the bottom of a column. You should see something like this:

Image:Named-row.png

This is handy for large workspaces. You can have meaningful names for constants or parameters and use them in formula. For example, I was able to swap PC43 for tile_width in one of my workspaces, making it much easier to understand.

Workspace definitions

Drag the left-hand side of nip2's main window (or click View / Workspace Definitions) and you should see something like this:

Image:Workspace-defs.png

Definitions you enter here are saved in the workspace file. For large workspaces it's very common to have a set of definitions that do some specialised task. This lets you keep the workspace and the defs that it needs together.

Passing parameters to workspaces

You can edit workspaces from the command-line with --set. Suppose you have a workspace which does some operation on an image, and you'd like to perform that operation on a whole directory of images. You can do this in nip by loading all the images, grouping them, and operating on the group of images. Sometimes however it's nice to be able to do this from another program, or from the command-line.

This workspace, for example, denoises an image:

Image:Denoise-workspace.png

Now save this workspace as denoise.ws and then from the command-line you can run:

nip2 -bp denoise.ws -o nonoise.png --set 'Workspaces.denoise.A1=Image_file "noisy.png"' --set 'main=Workspaces.denoise.A2'

This runs nip2 in batch mode (-b), asking it to print the value of the symbol main (-p), directing output to the file nonoise.png (-o nonoise.png). The first --set changes A1 to load the file noisy.png, the second --set makes main have the value of A2.

You can do a lot with --set, see the manual for details and examples.

Lambdas, list comprehensions and pattern matching

nip2's programming language has three new features: lambdas, list comprehensions and pattern matching.

Lambdas let you define anonymous local functions. For example, previously you sometimes had to write things like:

map sqrt list {   sqrt x = x ** 0.5; }

ie. define a tiny local function to pass to map or whatever. Lambdas let you define anonymous functions. The syntax is

\ name expression

which means: expression is a function taking a single argument, called "name". So our sqrt example would be:

map (\x x ** 0.5) list

You can nest lambdas to make multiargument functions. For example:

map2 (\x\y x + y) list1 list2

to add two lists.

List comprehensions are a handy shorthand for a set of map, filter and ifthenelse functions. Any time you write a big set of map/filter/ifthenelse, you could probably use a list comprehension instead and save a lot of typing.

nip2 uses Miranda's syntax for this. For example:

[x * x | x <- [1..100]]

which could be read as "the list of all x*x where x is drawn from [1..100]". You can add a series of other generators and qualifiers to the right, separated by semicolons. For example:

[x * x | x <- [1..100]; x % 2 == 0]

for the list of all squares of the even numbers under 100, or:

[(x, y) | x <- [1..100]; y <- [x..100]]

for all pairs of integers in 1 to 100. The components of a list comprehension evaluate more frequently to the right and can refer to things on their left.

Pattern matching lets you use a pattern on the left-hand side of a definition. The pattern gives the 'shape' of the value you are expecting. For example, previously you might have had to write:

a = maxmin obj; mx = a?0; mn = a?1;

where maxmin is a function which returns the maximum and minimum of a list as a pair.

Now you can write:

[mx, mn] = maxmin obj;

which does exactly the same thing. Patterns are quite flexible: you can test for classes, complex numbers, you can slice lists, you can test against constants. See the manual for details.

You can also use patterns in list comprehensions on the left-hand side of <- generators. Sadly, you can't yet use them as function parameters, maybe in 7.16.

Clone this wiki locally