ImageMagick supports binary metadata with `ResetImageProfileIterator()`
etc.
Implementing support gives us xmp / ipct / icc support, plus perhaps
some others.
seems to work, still to do:
- tests
- try:
```
$ vipsthumbnail NordicsLIQUOR-SFBag_300_cmyk.JPG
(vipsthumbnail:7868): VIPS-WARNING **: 16:53:17.166: profile incompatible with image
```
see https://github.com/libvips/libvips/issues/1186
TIFF pyramids of images with a very extreme aspect raio could see layer
width or height drop to 0 before the image fitted in a single tile. This
change stops pyramid creation when width or height drop to 1.
See https://github.com/libvips/libvips/issues/1188
Fixes two issues:
1. vips_text() in autofit mode could set the wrong DPI, since it set the
DPI in its own copy of the variable, but did not do a final update on
the DPI setting that FT uses for rendering.
2. vips_text() in autofit mode allocated a new context each time, rather
than reusing the context for that call. This caused a small memory leak.
See https://github.com/libvips/libvips/issues/1174
the auto_rotate option of thumbnail was default TRUE which made it
useless from the CLI, since GOption only allows --switch, not
--switch=false
deprecate auto_rotate, add no_rotate, but allow either to be used
see https://github.com/libvips/libvips/issues/1146
- move x/y into composite and out of composite base, have separate x/y int
params for composite2
- upsize later for a small speed improvement
- doc comment
- note in changelog
see https://github.com/jcupitt/libvips/pull/934
eg. VImage::width() is now
int VImage::width() const;
ie. it does not alter the image objects. In factr we can mark almost all
members const.
see https://github.com/jcupitt/libvips/issues/983
Add a "background" option to pdfload to help support PDFs with a
transparent background. For example:
vips copy transparent.pdf[background=0] x.png
see https://github.com/jcupitt/libvips/issues/995
We had a global we incremented to allocate property ids, but of course that
won't work with DLLs. Instead, add vips_argument_get_id() and call that to
allocate new prop ids.
See:
https://github.com/jcupitt/libvips/issues/985
You must now include vips7 support explicitly with
#include <vips/vips7compat.h>
in your code just after including `vips.h`.
The old vips7 names, such as `Rect`, were starting to cause problems
with other packages like opencv.
Some magick coders (eg. ICO) don't sniff the filetype from the data, so
when you try to load from a string, imagemagick is unable to pick the
right decode path.
Add a @format option so callers can hint the filetype.
see https://github.com/jcupitt/pyvips/issues/39
libjpeg rounds up on shrink-on-load. In some cases this can leave a dark
line along the right and bottom edge, since it only contains (for
example) 1/4 of a pixel of data.
This change adds a crop after jpeg load so that only complete pixels are
output.
See https://github.com/lovell/sharp/issues/1185
If O_TNMPFILE is available, use it. This is a linux extension that
creates an unlinked file, so it'll be closed by the system when the last
associated fd is closed.
see https://github.com/jcupitt/libvips/pull/930
Before, they could make B_W for one-band output. This caused problems
with (for example) two black image bandjoined: the second band then
looked like an alpha to hasalpha() and enabled premultiply/unpremultiply
for operations like affine.
Now, it's always MULTIBAND. This is the generic multiband image type, so
you don't get any unexpected alpha handling.
The result of hasalpha is used to turn on things like
premultiplication, so we should be rather conservative
about when we signal this. We don't want to premultiply
things that should not be premultiplied.
Check Type as well as bands.
See: https://github.com/jcupitt/libvips/issues/918
libpng has started throwing hard errors if the profile does not match
the image -- this can happen all the time with perofiles inherited from
images that have been processed.
Test profiles before save and drop them (with a warning) if they are
incompatible with the image.
vips__get_bytes() used to fail if the file was too small for the
allocated buffer, which was a problem for svg, since files can be extremely
small.
This change makes vips__get_bytes() return the number of bytes read, so
the is_a testers can work on files smaller than the max header size.
icc_import can take a fallback input profile in case the embedded one is
broken or missing. If we use the fallback profile, this change attaches
it to the output image.
This means that icc_import will always output an image with the icc
profile that was used to import it. This helps to make the behaviour of
`thumbnail` more consistent.
See https://github.com/jcupitt/libvips/issues/152
If a delayed load failed, it could leave the pipeline only half-set up.
Sebsequent threads could then segv.
Set a load-has-failed flag and test before generate.
See https://github.com/jcupitt/libvips/issues/893
We were rounding up with ceil() when intize-ing convolution masks.
However, the vector path has a true range of (1.0, -1.0], so a mask with
1.0 as the max (for example) was actually triggering the overflow detector
and falling back to the C path.
Round up with ceil(x + 1) instead, so 1.0 (for example) will be mapped
to 0.5 and won't overflow.
vips_sink() used to just fire off threads willy nilly -- this could
cause problems with sequential images if a worker fell too far behind
the pack
copy over the area locking mechanism from vips_sink_memory(): new
threads are now stalled if an old thread has not finished
the new window manager code in 8.6.1 changed the prototype of an internal
function which was visible in the public API
this patch renames the function, adds it to an internal header instead,
and adds a stub for the old prototype
see https://github.com/jcupitt/libvips/issues/854
images under the disc threshold opened in random access mode from
sequential loaders would have the seq tag set on them, causing
performance problems with vips_resize()
see https://github.com/jcupitt/libvips/issues/840
make the code for error during jpeg buffer write a little cleaner --
rather than calling the jpeg term method ourselves, have a separate
destroy function for the write buffer
we were repeatedly free-ing and new-ing input mmap windows ... this made
things like zoom out on large images in nip2 much slower than they
needed to be
the deepzoom spec wants tiles to be written along the right and bottom,
even of those tiles contain no new pixels
this patch seems to work, but needs testing
see: https://github.com/jcupitt/libvips/issues/795
we were leaving a few bits of the original image around after
vips_image_copy_memory(), including the progress signal ... if earlier images
were freed, perhaps by a GC in a language binding, we could get a dangling
pointer
thanks Nakilon, see https://github.com/jcupitt/ruby-vips/issues/140
"intent" lets you set the rendering intent for any ICC conversions --
the default is the (more correct) relative, but "perceptual" can look
better
see https://github.com/jcupitt/libvips/issues/714
we were only replacing enumtypes if it had changed, but this meant that
make usually thought it was out of date compared to the source files,
and rebuilt it, which needed perl
now we always replace it, so (hopefully) perl is no longer a
compile-time dependency
we were only failing on libjpeg errors, but libjpeg treats very serious
things thaht we want to be able to catch (like truncated files) as warnings
... we must therefore error out if fail is set and libjpeg issues a warning
see https://github.com/lovell/sharp/issues/793
If VIPS_WARNING is defined, suppress all warning messages from vips by
installing a null log handler.
Libraries should not call g_log_set_handler(), it is supposed to be for
the application layer, but this can be awkward to set up if you are using
libvips from something like Ruby.
This env var hack is a workaround.
see https://github.com/jcupitt/ruby-vips/issues/119
see https://github.com/jcupitt/libvips/issues/544
the old 'disc' flag to open defaulted TRUE and disabled read via disc if you
set it FALSE, which was very confusing
replace it with a flag called 'memory' which defaults FALSE and forces
read via memory if set TRUE
'disc' is still there and still works, it's just tagged as deprecated
see https://github.com/jcupitt/libvips/issues/677
The base64 encode limit was 1MB, but some huge profiles can get over
that, so it's now 10MB.
transform_save_string_blob() was incorrectly setting a refstring not a
blob as an error fallback, potentially leaving a dangling pointer.
Thanks Jaume!
See https://github.com/jcupitt/libvips/issues/666
clarify policy on file read errors and warnings:
* if the file format library reports a warning, we log it in vips, but
that's all
* if the file format library reports an error, we log it, but try to
continue
* if the file format library reports an error and fail is set, we log it
and fail
all loaders now implement this
we had INT as the default, but this will cause serious precision loss
with many masks ... instead, have float (always correct) as the default
and let people turn on int if they cn
vips_math2_const(), vips_boolean_const() and vips_relational_const() had
the const and oper args reversed from the Python/CLI/C++ API
add something to check for arg priority conflicts and resolve the
conflicts it found
we weren't multiplying through alpha in vips_region_shrink(), causing
fringing on pyramids with transparent elements
thanks sickrandir!
see https://github.com/jcupitt/libvips/issues/599
previously the list of maxima or minima found by max/min were in found
order, so essentially random
they now sort equal values by y then x coordinate, so the results are
consistent between runs, provided there are fewer maxima / minima than
are being tracked
vips_hist_local() has a new param, max_slope, which sets the maximum
amount that the local contrast can be boosted by -- CLAHE
see https://github.com/jcupitt/libvips/issues/268
also fix a couple of small range problems
- scale by 255, not 256, to avoid an overflow
- cum hist includes the current value, so sum to <= target, not < target
--vips-cache-max, --vips-cache-max-memory and --vips-cache-max-files were not
working and probably hadn't been for a while
vipsthumbnail.c turns off the operation cache, it's not useful for
the same operation repeated across many files
helps bindings (which struglle with vips_image_map()) get a list of
header fields
works from py, but not ruby, I guess gchar** isn't a supported type for
ruby-gnome
see https://github.com/jcupitt/libvips/issues/533
older libgsfs can't save zip64 and will fail silently for very large
output trees ... improve the slightly sketchy >4gb detection in dzsave
this a a version of the patch in https://github.com/jcupitt/libvips/pull/462
rework header.c
- built-in enum fields, like "interpretation" are handled as enums, not
ints
- vips_image_get_*() functions always convert to the target type if they
can
- rename "field" to "name" in the docs
- clarify docs
the extra check on bandfmt in sizeof() in 8.3.2 was causing some performance
problems ... move the check to file read, so we only do it once
per image, not once per pixel or scanline
thanks Lovell!
- transparency was broken if image had no extension block
- load image to memory, test for transparency and mono/colour, write 1,
2, 3, or 4 band image to output, depending on what we found
vips_resize() uses to just use nearest when upsizing, following standard
practice in repro. This is often unfortunate for image processing, where
small nearest upsizes will produce obvious aliasing.
It now picks a VipsInterpolate which corresponds (roughly) to the
selected VipsKernel and uses that with affine for any upsizing.
vips_resize() used to do most of a downsize with vips_shrink() and the
final 200 - 300% with vips_reduce(). This was correct for lanczos2/3,
but not right for linear/cubic, which need more shrink and less
reduce to avoid aliasing.
This patch makes vips_resize() leave the final 100 - 200% to
vips_reduce() for linear/cubic, and leave everything to reduce for
nearest.
oops, it was missing
also, change the return type from void to VImage. This makes chaining
possible, eg.:
VImage memory = im.write( Viameg::new_memory() );
when you write to a non-partial image, you create a sink ... so
vips_image_write() only needs to ref the input when writing to partials
this change makes it much easier to (for example) combine many images in
bounded space, see for example:
https://gist.github.com/jcupitt/c516325ebef7601b5da610af5619c9b2
We were freeing pixel buffers on thread exit. This was convenient, but
meant that main thread buffers were not freed until program exit. As a
result, long-running programs which created main thread buffers would
slowly fill the operation cache with useless junk, forcing everything else out.
This change also frees pixel buffers on image close. This makes the
cache work much better in long-running programs, and can substantially
reduce memory use.
See https://github.com/jcupitt/libvips/issues/466
threads keep pixel buffers in thread-private storage, and free these
buffers on thread exit ... this means buffers created by the main thread will
only be freed on program exit!
if your program creates any main-thread buffers, these buffers will
eventually fill the operation cache and force everything else out,
making the cache useless
this patch explicitly frees main-thread pixel buffers on image close
when jpg compression is on, tiffsave now converts the input image for
jpg save ... previously, it would try to send a tiff-formatted image
(eg. perhaps with an alpha channel, or float data), which would fail
see https://github.com/jcupitt/libvips/issues/449
vips_unpremultiply() always outputs float. If you save the output of
vipsthumbnail to a format that supports float files, like tiff, it won't
ever get cast back to the source format.
Example:
$ vipsheader Opera-icon-high-res.png
Opera-icon-high-res.png: 3056x3325 uchar, 4 bands, srgb, pngload
$ vipsthumbnail Opera-icon-high-res.png -o x.tif
$ vipsheader x.tif
x.tif: 117x128 float, 4 bands, scrgb, tiffload
This change makes it note and restore BandFmt aropund pre/unpremultiply.
See https://github.com/jcupitt/libvips/issues/447
GM is still using the old page interface of subimage/subrange, IM has
deprecated that in favour of scene/number_scenes
we were accidentally just supporting the new IM system ... this change
adds support for GM as well, plus a configure test to pick one
see https://github.com/jcupitt/libvips/issues/423
jpeg write is more careful about removing exif tags that have been
removed from the image metadata
it failed previously if there were multiple Orientation tags
you can now put options like [scale=2] at the end of out_format ...
these are stripped before running the command, but use to load the
output image back into libvips again
added VIPS_COUNT_PIXELS(), use like this:
static int vips_shrinkh_gen( VipsRegion *or, ... )
{
VIPS_COUNT_PIXELS( or, "vips_shrinkh_gen" );
}
and on image close, if more than 100% of the pixels have been
calculated, you get a warning
only if you enable debugging, since this hurts perf slightly
vips has built-in support for rad, analyze and ppm ... add configure
switches to disable these readers
useful to reduce the attack surface in some applications
we had a custom wrapper for bandjoin(), but bandrank(), a function with
an almost identical interface, did not ... this was confusing
bandrank() now has a custom wrapper too ... this breaks API
unfortunately, but hopefully very few people were using this thing and
it's better to make this change as soon as possible
before, im.cast(uchar, shift = true) where im was float and tagged as
rgb16 would not shift the image, since it's unclear how much to shift a float
type by
now we do two casts: first, we guess the numeric range from the
interpretation, so rgb16 would be ushort, so we cast float->ushort;
second, we cast to the target type and do the shift on the way
see https://github.com/jcupitt/libvips/issues/397
thanks apacheark
we were not setting the access hint on arrayimage args, so
arrayjoin "$(echo *.jpg)" x.tif[bigtiff] --across 10
would open all the jpg images to memory, usually, in random mode
now arrayimage args see the operation's access hint (seq in this case),
for much better behaviour
also, we allow any whitespace as an arg separator in arrayimage from
string
it was a bit granular (since it was designed for offset work), make sharpen
easier to adjust for smaller effects
- new 'sigma' parameter
- greater parameter range
- more self-tests
- Remove the nocache stuff for prog jpg images. There was no saving in
practice, since operations downstream could be cached.
nocache is for objects that can change, not for memory saving
- Call _destroy on the decompress object much earlier, it frees a huge
amount of memoey for prog jpg images.
progressive jpg images need loads of memory, we shouldn't cache them by
default ... our called can hold a ref if they want to keep the image
around
see https://github.com/jcupitt/libvips/issues/387
Previously vips just called Mat_Open() to test if a file was a Matlab
save file, but this is rather unreliable. For example, some JPEG files
can crash libmatio, and it can incorrectly think that at least some JP2
files are Matlab save files.
Instead, look for "MATLAB 5.0" at the start of the file. This is really too
specific, the first 116 bytes of a Matlab save file are freeform text,
but in practice all Matlab writers use the first few bytes to record the
file type.
See https://github.com/jcupitt/libvips/issues/385
works, but is no faster, how odd
john@kiwi:~/pics$ time vips magickload nipguide.pdf[40] x.tif
real 0m0.244s
user 0m0.212s
sys 0m0.040s
$ time vips magickload nipguide.pdf x.tif --page 40
real 0m7.035s
user 0m6.900s
sys 0m0.152s
both give same result
We had exception specs on the C++ interface, but C++11 does not support
them and some compilers have never honoured them. Remove all specs.
Thanks Lovell.
See https://github.com/jcupitt/libvips/issues/362
we had both a class member bandjoin, and an instance member
Vips.Image.bandjoin([i1, i2, i3..])
i1.ibandjoin([i2, i3..])
this was confusing and annoying ... get rid of the class one and just
use bandjoin everywhere, so this is now the way to do it:
i1.bandjoin([i2, i3..])
oh argh class and instance methods are in the same namespace, so we have
to rename the instance one as ibandjoin
also, start adding a test for arrayjoin
takes a copy of a memory area when making an image ... this helps bindings
for languages which don't have much control over memory
see https://github.com/jcupitt/libvips/issues/346
dzsave now uses :strip => true for all tiles. There's no point adding
all the metadata to every tile, so hopefully this won't break anything.
Thanks Benjamin, see: https://github.com/jcupitt/libvips/issues/349
doesn't seem to slow us down significantly ... before:
$ time vips dzsave CMU-1.svs x --layout google --background "243 243 243 255"
real 1m1.940s
user 2m15.004s
sys 0m37.092s
after:
$ time vips dzsave CMU-1.svs x --layout google --background "243 243 243 255"
strip_work: skipping blank tile 176 x 67
strip_work: skipping blank tile 21 x 112
real 1m3.503s
user 2m16.012s
sys 0m40.328s
small improvements to vips_resize() quality:
* turn down the anti-alias filter a little so we don't smudge out texture
* don't do the final sharpening pass if we skipped the anti-alias filter
* fix a >/>= mixup which meant we didn't sharpen for small resizes