Merge branch 'master' into add-libnsgif
23
.editorconfig
Normal file
@ -0,0 +1,23 @@
|
||||
# http://editorconfig.org
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{cpp,c,h}]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[Makefile.am]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
|
||||
[configure.ac]
|
||||
indent_style = space
|
||||
indent_size = 2
|
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
open_collective: libvips
|
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
||||
.pytest_cache
|
||||
compile
|
||||
.pytest_cache
|
||||
a.out
|
||||
|
199
.travis.yml
@ -1,118 +1,50 @@
|
||||
language: cpp
|
||||
|
||||
before_script:
|
||||
- $PYTHON -m pip download --no-deps https://github.com/libvips/pyvips/archive/$PYVIPS_VERSION.tar.gz
|
||||
- tar xf $PYVIPS_VERSION.tar.gz
|
||||
- $PYTHON -m pip install --user --upgrade pyvips-$PYVIPS_VERSION/[test]
|
||||
- ./autogen.sh
|
||||
--disable-dependency-tracking
|
||||
--with-jpeg-includes=$JPEG/include
|
||||
--with-jpeg-libraries=$JPEG/lib
|
||||
--with-magick=$WITH_MAGICK
|
||||
- make -j$JOBS -s
|
||||
script:
|
||||
- make -j$JOBS -s -k V=0 VERBOSE=1 check
|
||||
- LD_LIBRARY_PATH=$PWD/libvips/.libs
|
||||
DYLD_LIBRARY_PATH=$PWD/libvips/.libs
|
||||
LD_PRELOAD=$ASAN_DSO
|
||||
$PYTHON -m pytest -v test/test-suite
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- os: osx
|
||||
fast_finish: true
|
||||
include:
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: xenial
|
||||
compiler: gcc
|
||||
env:
|
||||
- PYTHON=python2
|
||||
- PYVIPS_VERSION=master
|
||||
- JPEG=/usr
|
||||
- JOBS=`nproc`
|
||||
- WITH_MAGICK=yes
|
||||
cache: ccache
|
||||
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: xenial
|
||||
compiler: clang
|
||||
env:
|
||||
- PYTHON=python2
|
||||
- PYVIPS_VERSION=master
|
||||
- JPEG=/usr
|
||||
- JOBS=`nproc`
|
||||
- WITH_MAGICK=no
|
||||
- CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -fopenmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"
|
||||
- LDFLAGS="-fsanitize=address,undefined -dynamic-asan -fopenmp=libiomp5"
|
||||
- ASAN_DSO=/usr/local/clang-7.0.0/lib/clang/7.0.0/lib/linux/libclang_rt.asan-x86_64.so
|
||||
- LSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/suppressions/lsan.supp"
|
||||
- UBSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/suppressions/ubsan.supp"
|
||||
# comment these out, I get strange parse errors from asan for some
|
||||
# reason
|
||||
#
|
||||
# ASAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/suppressions/asan.supp"
|
||||
install:
|
||||
# add support for WebP
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebp-dev_0.6.1-2_amd64.deb
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebpdemux2_0.6.1-2_amd64.deb
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebpmux3_0.6.1-2_amd64.deb
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebp6_0.6.1-2_amd64.deb
|
||||
- sudo dpkg -i *.deb
|
||||
cache: ccache
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
env:
|
||||
- PYTHON=python2
|
||||
- PYVIPS_VERSION=master
|
||||
- JPEG=/usr/local
|
||||
- JOBS="`sysctl -n hw.ncpu`"
|
||||
- WITH_MAGICK=yes
|
||||
- PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
- HOMEBREW_NO_AUTO_UPDATE=1
|
||||
cache: ccache
|
||||
env:
|
||||
global:
|
||||
- PYTHON=python3
|
||||
- PYVIPS_VERSION=master
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
sources:
|
||||
sources: &common_sources
|
||||
# use a more recent imagemagick instead of 6.8.9-9
|
||||
- sourceline: 'ppa:opencpu/imagemagick'
|
||||
- sourceline: 'ppa:cran/imagemagick'
|
||||
# add support for HEIF files
|
||||
- sourceline: 'ppa:strukturag/libheif'
|
||||
- sourceline: 'ppa:strukturag/libde265'
|
||||
packages:
|
||||
- automake
|
||||
- gtk-doc-tools
|
||||
packages: &common_packages
|
||||
- automake
|
||||
- gtk-doc-tools
|
||||
- gobject-introspection
|
||||
- libfftw3-dev
|
||||
- libexif-dev
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
- python3-wheel
|
||||
- libfftw3-dev
|
||||
- libexif-dev
|
||||
- libjpeg-turbo8-dev
|
||||
- libpng12-dev
|
||||
- libpng12-dev
|
||||
- libwebp-dev
|
||||
# missing on xenial, unfortunately
|
||||
# - libwebpmux2
|
||||
- libtiff5-dev
|
||||
- libtiff5-dev
|
||||
- libheif-dev
|
||||
- libexpat1-dev
|
||||
- libmagick++-dev
|
||||
- bc
|
||||
- libmagick++-dev
|
||||
- libcfitsio3-dev
|
||||
- libgsl0-dev
|
||||
- libgsl0-dev
|
||||
- libmatio-dev
|
||||
- liborc-0.4-dev
|
||||
- liblcms2-dev
|
||||
- libpoppler-glib-dev
|
||||
- librsvg2-dev
|
||||
- librsvg2-dev
|
||||
- libgif-dev
|
||||
- libopenexr-dev
|
||||
- libpango1.0-dev
|
||||
- libgsf-1-dev
|
||||
- libpango1.0-dev
|
||||
- libgsf-1-dev
|
||||
- libopenslide-dev
|
||||
- libffi-dev
|
||||
- libiomp-dev
|
||||
homebrew:
|
||||
packages:
|
||||
- ccache
|
||||
@ -120,6 +52,7 @@ addons:
|
||||
- gobject-introspection
|
||||
- fftw
|
||||
- libexif
|
||||
- libjpeg-turbo
|
||||
- webp
|
||||
- imagemagick
|
||||
- cfitsio
|
||||
@ -133,3 +66,91 @@ addons:
|
||||
- pango
|
||||
- libgsf
|
||||
- openslide
|
||||
|
||||
jobs:
|
||||
allow_failures:
|
||||
- os: osx
|
||||
fast_finish: true
|
||||
include:
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: xenial
|
||||
compiler: gcc
|
||||
env:
|
||||
- JPEG=/usr
|
||||
- JOBS=`nproc`
|
||||
- WITH_MAGICK=yes
|
||||
cache: ccache
|
||||
- os: linux
|
||||
sudo: required
|
||||
dist: xenial
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- *common_sources
|
||||
- sourceline: deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main
|
||||
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
|
||||
packages:
|
||||
- *common_packages
|
||||
- clang-10
|
||||
- libomp-10-dev
|
||||
env:
|
||||
- JPEG=/usr
|
||||
- JOBS=`nproc`
|
||||
- WITH_MAGICK=no
|
||||
- LDSHARED="clang -shared"
|
||||
- CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -fopenmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"
|
||||
- LDFLAGS="-fsanitize=address,undefined -shared-libasan -fopenmp=libomp"
|
||||
- ASAN_DSO=`clang-10 -print-file-name=libclang_rt.asan-x86_64.so`
|
||||
- ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer-10`
|
||||
- ASAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/suppressions/asan.supp"
|
||||
- LSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/suppressions/lsan.supp"
|
||||
- UBSAN_OPTIONS="suppressions=$TRAVIS_BUILD_DIR/suppressions/ubsan.supp"
|
||||
- LD_LIBRARY_PATH="`dirname $ASAN_DSO`:/usr/lib/llvm-10/lib:$LD_LIBRARY_PATH"
|
||||
- DLCLOSE_PRELOAD="$TRAVIS_BUILD_DIR/dlclose.so"
|
||||
install:
|
||||
# add support for WebP
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebp-dev_0.6.1-2_amd64.deb
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebpdemux2_0.6.1-2_amd64.deb
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebpmux3_0.6.1-2_amd64.deb
|
||||
- wget http://archive.ubuntu.com/ubuntu/pool/main/libw/libwebp/libwebp6_0.6.1-2_amd64.deb
|
||||
- sudo dpkg -i *.deb
|
||||
# switch to Clang 10 using update-alternatives
|
||||
- sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-10 100
|
||||
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-10
|
||||
# workaround for https://github.com/google/sanitizers/issues/89
|
||||
# otherwise libIlmImf-2_2.so ends up as <unknown module>
|
||||
- echo -e '#include <stdio.h>\nint dlclose(void*handle){return 0;}' | clang -shared -xc -odlclose.so -
|
||||
cache: ccache
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
env:
|
||||
- JPEG=/usr/local/opt/jpeg-turbo
|
||||
- JOBS="`sysctl -n hw.ncpu`"
|
||||
- WITH_MAGICK=yes
|
||||
- PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
- PKG_CONFIG_PATH="/usr/local/opt/jpeg-turbo/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
- HOMEBREW_NO_AUTO_UPDATE=1
|
||||
- CC="gcc-9"
|
||||
- CXX="g++-9"
|
||||
cache: ccache
|
||||
|
||||
before_script:
|
||||
- $PYTHON -m pip download --no-deps https://github.com/libvips/pyvips/archive/$PYVIPS_VERSION.tar.gz
|
||||
- tar xf $PYVIPS_VERSION.tar.gz
|
||||
- $PYTHON -m pip install --user --upgrade pyvips-$PYVIPS_VERSION/[test]
|
||||
- ./autogen.sh
|
||||
--disable-dependency-tracking
|
||||
--disable-deprecated
|
||||
--with-jpeg-includes=$JPEG/include
|
||||
--with-jpeg-libraries=$JPEG/lib
|
||||
--with-magick=$WITH_MAGICK
|
||||
- make -j$JOBS -s
|
||||
|
||||
script:
|
||||
- make -j$JOBS -s -k V=0 VERBOSE=1 check
|
||||
- LD_LIBRARY_PATH=$PWD/libvips/.libs
|
||||
DYLD_LIBRARY_PATH=$PWD/libvips/.libs
|
||||
LD_PRELOAD="$ASAN_DSO $DLCLOSE_PRELOAD"
|
||||
$PYTHON -m pytest -sv --log-cli-level=WARNING test/test-suite
|
||||
|
66
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,66 @@
|
||||
libvips Code of Conduct
|
||||
=======================
|
||||
|
||||
libvips, is developed and maintained by a mixed group of professionals and
|
||||
volunteers from all over the world.
|
||||
|
||||
We ask people to adhere to a few ground rules. They apply equally to founders,
|
||||
maintainers, contributors and those seeking help and guidance.
|
||||
|
||||
This is not meant to be an exhaustive list of things you are not allowed to do.
|
||||
We rather would like you to think of it as a guide to enrich our community and
|
||||
the technical community in general with new knowledge and perspectives by
|
||||
allowing everyone to participate.
|
||||
|
||||
This code of conduct applies to all spaces managed by the libvips
|
||||
community. This includes the mailing list, our GitHub projects, face to face
|
||||
events, and any other forums created by the community for communication
|
||||
within the community. In addition, violations of this code outside these
|
||||
spaces may also affect a person's ability to participate within them.
|
||||
|
||||
If you believe someone is violating the code of conduct, we ask that you
|
||||
report it.
|
||||
|
||||
- **Be friendly and patient.**
|
||||
- **Be welcoming.** We strive to be a community that welcomes and supports
|
||||
people of all backgrounds.
|
||||
- **Be considerate.** Your work will be used by other people, and you in turn
|
||||
will depend on the work of others. Any decision you take will affect users
|
||||
and colleagues, and you should take those consequences into account when
|
||||
making decisions. Remember that we're a world-wide community, so you might
|
||||
not be communicating in someone else's primary language.
|
||||
- **Be respectful.** Not all of us will agree all the time, but disagreement
|
||||
is no excuse for poor behavior and poor manners. We might all experience
|
||||
some frustration now and then, but we cannot allow that frustration to turn
|
||||
into a personal attack. It’s important to remember that a community where
|
||||
people feel uncomfortable or threatened is not a productive one. Members of
|
||||
our community should be respectful when dealing with other members as
|
||||
well as with people outside the our community.
|
||||
- **Be careful in the words that you choose.** We are a community of
|
||||
professionals, and we conduct ourselves professionally. Be kind to others.
|
||||
Do not insult or put down other participants. Harassment and other
|
||||
exclusionary behavior aren't acceptable. This includes, but is not limited
|
||||
to:
|
||||
- Violent threats or language directed against another person.
|
||||
- Discriminatory jokes and language.
|
||||
- Posting sexually explicit or violent material.
|
||||
- Posting (or threatening to post) other people's personally identifying
|
||||
information ("doxing").
|
||||
- Personal insults, especially those using racist or sexist terms.
|
||||
- Unwelcome sexual attention.
|
||||
- Advocating for, or encouraging, any of the above behavior.
|
||||
- Repeated harassment of others. In general, if someone asks you to stop,
|
||||
then stop.
|
||||
- **When we disagree, try to understand why.** Disagreements, both social and
|
||||
technical, happen all the time. It is important that we resolve
|
||||
disagreements and differing views constructively. Remember that we’re
|
||||
different. The strength of group software development comes from its
|
||||
varied community, people from a wide range of backgrounds. Different
|
||||
people have different perspectives on issues. Being unable to understand
|
||||
why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t
|
||||
forget we all make mistakes and blaming each other doesn’t get us
|
||||
anywhere. Instead, focus on helping to resolve issues and learning
|
||||
from mistakes.
|
||||
|
||||
Text based on the Code of Conduct of the [Django
|
||||
community](https://www.djangoproject.com/conduct/).
|
80
ChangeLog
@ -1,3 +1,68 @@
|
||||
24/1/20 started 8.10.0
|
||||
- more conformat IIIF output from dzsave [regisrob]
|
||||
- add @id to dzsave to set IIIF id property [regisrob]
|
||||
- add max and min to region shrink [rgluskin]
|
||||
- allow \ as an escape character in vips_break_token() [akemrir]
|
||||
- tiffsave has a "depth" param to set max pyr depth
|
||||
- libtiff LOGLUV images load and save as libvips XYZ
|
||||
- add gifload_source, csvload_source, csvsave_target, matrixload_source,
|
||||
matrixsave_source, pdfload_source, heifload_source, heifsave_target,
|
||||
ppmload_source, ppmsave_target
|
||||
- revise vipsthumbnail flags
|
||||
- add VIPS_LEAK env var
|
||||
- add vips_pipe_read_limit_set(), --vips-pipe-read-limit,
|
||||
VIPS_PIPE_READ_LIMIT
|
||||
- revise gifload to fix BACKGROUND and PREVIOUS dispose [alon-ne]
|
||||
- add subsample_mode, deprecate no_subsample in jpegsave [Elad-Laufer]
|
||||
- add vips_isdirf()
|
||||
- add PAGENUMBER support to tiff write [jclavoie-jive]
|
||||
- add "all" mode to smartcrop
|
||||
- flood fill could stop half-way for some very complex shapes
|
||||
- better handling of unaligned reads in multipage tiffs [petoor]
|
||||
- add experimental libspng reader
|
||||
- mark old --delete option to vipsthumbnail as deprecated [UweOhse]
|
||||
- png save with a bad ICC profile just gives a warning
|
||||
- add "premultipled" option to vips_affine(), clarified vips_resize()
|
||||
behaviour with alpha channels
|
||||
- improve bioformats support with read and write of tiff subifd pyramids
|
||||
- thumbnail exploits subifd pyramids
|
||||
- handle all EXIF orientation cases, deprecate
|
||||
vips_autorot_get_angle() [Elad-Laufer]
|
||||
- load PNGs with libspng, if possible
|
||||
- deprecate heifload autorotate -- it's now always on
|
||||
- revised resize improves accuracy [kleisauke]
|
||||
- add --vips-config flag to show configuration info
|
||||
- add "bitdepth" param to tiff save, deprecate "squash" [MathemanFlo]
|
||||
- tiff load and save now supports 2 and 4 bit data [MathemanFlo]
|
||||
- pngsave @bitdepth parameter lets you write 1, 2 and 4 bit PNGs
|
||||
- ppmsave also uses "bitdepth" now, for consistency
|
||||
- reduce operation cache max to 100
|
||||
- rework the final bits of vips7 for vips8 [kleisauke]
|
||||
- --disable-deprecated now works [kleisauke]
|
||||
- vipsheader allows "stdin" as a filename
|
||||
|
||||
24/4/20 started 8.9.3
|
||||
- better iiif tile naming [IllyaMoskvin]
|
||||
|
||||
31/1/19 started 8.9.2
|
||||
- fix a deadlock with --vips-leak [DarthSim]
|
||||
- better gifload behaviour for DISPOSAL_UNSPECIFIED [DarthSim]
|
||||
- ban ppm max_value < 0
|
||||
- add fuzz corpus to dist
|
||||
- detect read errors correctly in source_sniff
|
||||
- fix regression in autorot [malomalo]
|
||||
- thumbnail on HEIC images could select the thumbnail incorrectly under some
|
||||
size modes [ZorinArsenij]
|
||||
|
||||
20/6/19 started 8.9.1
|
||||
- don't use the new source loaders for new_from_file or new_from_buffer, it
|
||||
will break the loader priority system
|
||||
- fix thumbnail autorot [janko]
|
||||
- fix a warning with magicksave with no delay array [chregu]
|
||||
- fix a race in tiled tiff load [kleisauke]
|
||||
- better imagemagick init [LebronCurry]
|
||||
- lock for metadata changes [jcupitt]
|
||||
|
||||
20/6/19 started 8.9.0
|
||||
- add vips_image_get/set_array_int()
|
||||
- disable webp alpha output if all frame fill the canvas and are solid
|
||||
@ -16,6 +81,21 @@
|
||||
- add @interpretation and @format to rawload
|
||||
- nifti load/save uses double for all floating point metadata
|
||||
- add vips_error_buffer_copy()
|
||||
- add VipsSource and VipsTarget: a universal IO class for loaders and savers
|
||||
- jpeg, png, tiff (though not tiffsave), rad, svg, ppm and webp use the
|
||||
new IO class
|
||||
- rewritten ppm load/save is faster and uses less memory
|
||||
- add @no_strip option to dzsave [kalozka1]
|
||||
- add iiif layout to dzsave
|
||||
- fix use of resolution-unit metadata on tiff save [kayarre]
|
||||
- support TIFF CIELAB images with alpha [angelmixu]
|
||||
- support TIFF with premultiplied alpha in any band
|
||||
- block metadata changes on shared images [pvdz]
|
||||
- RGB and sRGB are synonmous
|
||||
|
||||
17/9/19 started 8.8.4
|
||||
- improve compatibility with older imagemagick versions
|
||||
- remove realpath, since it can fail on systems with grsec
|
||||
|
||||
31/8/19 started 8.8.3
|
||||
- revert sharpen restoring the input colourspace
|
||||
|
@ -14,8 +14,7 @@ EXTRA_DIST = \
|
||||
autogen.sh \
|
||||
vips.pc.in \
|
||||
vips-cpp.pc.in \
|
||||
libvips.supp \
|
||||
lsan.supp \
|
||||
suppressions \
|
||||
depcomp \
|
||||
README.md
|
||||
|
||||
|
136
README.md
@ -1,9 +1,56 @@
|
||||
# libvips : an image processing library
|
||||
|
||||
[](https://travis-ci.org/libvips/libvips)
|
||||
[](https://oss-fuzz.com/coverage-report/job/libfuzzer_asan_libvips/latest)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=2&q=proj:libvips)
|
||||
[](https://scan.coverity.com/projects/jcupitt-libvips)
|
||||
|
||||
# This branch
|
||||
|
||||
Is for experiemtning with [libspng](https://github.com/randy408/libspng).
|
||||
|
||||
## Notes
|
||||
|
||||
Build libspng:
|
||||
|
||||
```
|
||||
cd libspng
|
||||
meson build --prefix=/home/john/vips --libdir=/home/john/vips/lib \
|
||||
--buildtype=release
|
||||
cd build
|
||||
ninja
|
||||
ninja install
|
||||
```
|
||||
|
||||
Installs `spng.pc`.
|
||||
|
||||
Sample code:
|
||||
|
||||
https://github.com/randy408/libspng/blob/master/examples/example.c
|
||||
|
||||
libspng benchmark:
|
||||
|
||||
```
|
||||
$ time vips avg wtc.png
|
||||
117.065766
|
||||
|
||||
real 0m2.972s
|
||||
user 0m3.376s
|
||||
sys 0m0.197s
|
||||
```
|
||||
|
||||
And for libpng:
|
||||
|
||||
```
|
||||
$ time vips avg wtc.png
|
||||
117.065766
|
||||
|
||||
real 0m3.816s
|
||||
user 0m4.177s
|
||||
sys 0m0.221s
|
||||
```
|
||||
|
||||
# Introduction
|
||||
|
||||
libvips is a [demand-driven, horizontally
|
||||
threaded](https://github.com/libvips/libvips/wiki/Why-is-libvips-quick)
|
||||
image processing library. Compared to similar
|
||||
@ -67,7 +114,7 @@ Untar, then in the libvips directory you should just be able to do:
|
||||
./configure
|
||||
|
||||
Check the summary at the end of `configure` carefully. libvips must have
|
||||
`build-essential`, `pkg-config`, `glib2.0-dev`, `libexpat1-dev`.
|
||||
`build-essential`, `pkg-config`, `libglib2.0-dev`, `libexpat1-dev`.
|
||||
|
||||
You'll need the dev packages for the file format support you want. For basic
|
||||
jpeg and tiff support, you'll need `libtiff5-dev`, `libjpeg-turbo8-dev`,
|
||||
@ -89,7 +136,6 @@ Run the test suite with:
|
||||
|
||||
Run a specific test with:
|
||||
|
||||
pytest --verbose
|
||||
pytest test/test-suite/test_foreign.py -k test_tiff
|
||||
|
||||
# Building libvips from git
|
||||
@ -103,7 +149,7 @@ and `gobject-introspection`, see the dependencies section below. For example:
|
||||
|
||||
brew install gtk-doc
|
||||
|
||||
Then build the build system with:
|
||||
Then generate the build system with:
|
||||
|
||||
./autogen.sh --prefix=/home/john/vips
|
||||
|
||||
@ -114,62 +160,12 @@ Debug build:
|
||||
make
|
||||
make install
|
||||
|
||||
Leak check. Use the suppressions file `supp/valgrind.supp`.
|
||||
|
||||
export G_DEBUG=gc-friendly
|
||||
valgrind --suppressions=vips-x.y.z/supp/valgrind.supp \
|
||||
--leak-check=yes \
|
||||
vips ... > vips-vg.log 2>&1
|
||||
|
||||
Memory error debug:
|
||||
|
||||
valgrind --vgdb=yes --vgdb-error=0 vips ...
|
||||
|
||||
valgrind threading check:
|
||||
|
||||
valgrind --tool=helgrind vips ... > vips-vg.log 2>&1
|
||||
|
||||
Clang build:
|
||||
|
||||
CC=clang CXX=clang++ ./configure --prefix=/home/john/vips
|
||||
|
||||
Clang static analysis:
|
||||
|
||||
scan-build ./configure --disable-introspection --disable-debug
|
||||
scan-build -o scan -v make
|
||||
scan-view scan/2013-11-22-2
|
||||
|
||||
Clang dynamic analysis:
|
||||
|
||||
FLAGS="-g -O1 -fno-omit-frame-pointer"
|
||||
CC=clang CXX=clang++ LD=clang \
|
||||
CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" LDFLAGS=-fsanitize=address \
|
||||
./configure --prefix=/home/john/vips
|
||||
|
||||
FLAGS="-O1 -g -fsanitize=thread"
|
||||
FLAGS="$FLAGS -fPIC"
|
||||
FLAGS="$FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls"
|
||||
CC=clang CXX=clang++ LD=clang \
|
||||
CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \
|
||||
LDFLAGS="-fsanitize=thread -fPIC" \
|
||||
./configure --prefix=/home/john/vips \
|
||||
--without-magick \
|
||||
--disable-introspection
|
||||
G_DEBUG=gc-friendly vips copy ~/pics/k2.jpg x.jpg >& log
|
||||
|
||||
Build with the GCC auto-vectorizer and diagnostics (or just -O3):
|
||||
|
||||
FLAGS="-O2 -march=native -ffast-math"
|
||||
FLAGS="$FLAGS -ftree-vectorize -fdump-tree-vect-details"
|
||||
CFLAGS="$FLAGS" CXXFLAGS="$FLAGS" \
|
||||
./configure --prefix=/home/john/vips
|
||||
|
||||
# Dependencies
|
||||
|
||||
libvips has to have `glib2.0-dev` and `libexpat1-dev`. Other dependencies
|
||||
are optional, see below.
|
||||
libvips has to have `libglib2.0-dev` and `libexpat1-dev`. Other dependencies
|
||||
are optional.
|
||||
|
||||
# Optional dependencies
|
||||
## Optional dependencies
|
||||
|
||||
If suitable versions are found, libvips will add support for the following
|
||||
libraries automatically. See `./configure --help` for a set of flags to
|
||||
@ -284,7 +280,7 @@ If available, vips can load and save WebP images.
|
||||
|
||||
### libniftiio
|
||||
|
||||
If available, vips can load and save NIFTI images.
|
||||
If available, vips can load and save NIfTI images.
|
||||
|
||||
### OpenEXR
|
||||
|
||||
@ -300,9 +296,25 @@ files: Aperio, Hamamatsu, Leica, MIRAX, Sakura, Trestle, and Ventana.
|
||||
|
||||
If available, libvips can load and save HEIC images.
|
||||
|
||||
# Disclaimer
|
||||
# Contributors
|
||||
|
||||
No guarantees of performance accompany this software, nor is any
|
||||
responsibility assumed on the part of the authors. Please read the licence
|
||||
agreement.
|
||||
### Code Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute.
|
||||
|
||||
<a href="https://github.com/libvips/libvips/graphs/contributors"><img src="https://opencollective.com/libvips/contributors.svg?width=890&button=false" /></a>
|
||||
|
||||
### Organizations
|
||||
|
||||
Support this project with your organization. Your logo will show up here with a link to your website.
|
||||
|
||||
<a href="https://opencollective.com/libvips/organization/0/website"><img src="https://opencollective.com/libvips/organization/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/1/website"><img src="https://opencollective.com/libvips/organization/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/2/website"><img src="https://opencollective.com/libvips/organization/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/3/website"><img src="https://opencollective.com/libvips/organization/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/4/website"><img src="https://opencollective.com/libvips/organization/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/5/website"><img src="https://opencollective.com/libvips/organization/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/6/website"><img src="https://opencollective.com/libvips/organization/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/7/website"><img src="https://opencollective.com/libvips/organization/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/8/website"><img src="https://opencollective.com/libvips/organization/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/libvips/organization/9/website"><img src="https://opencollective.com/libvips/organization/9/avatar.svg"></a>
|
||||
|
439
TODO
@ -1,439 +0,0 @@
|
||||
- try
|
||||
|
||||
$ vips gaussmat x.mat 0.1 0.1
|
||||
(vips:28376): GLib-GObject-WARNING **: value "-1" of type 'gint' is invalid or out of range for property 'width' of type 'gint'
|
||||
(vips:28376): GLib-GObject-WARNING **: value "-1" of type 'gint' is invalid or out of range for property 'height' of type 'gint'
|
||||
$ more x.mat
|
||||
1 1 0 0
|
||||
5.55604e+180
|
||||
|
||||
check numeric range of SIGMA args, we should standardize
|
||||
|
||||
- rewind should break more things ... does it remove upsteam/downstream? does it
|
||||
just need to remove reorder links?
|
||||
|
||||
perhaps reorder should use upstream/downstream, then it will be broken anyway
|
||||
|
||||
- not sure about utf8 error messages on win
|
||||
|
||||
- strange:
|
||||
|
||||
$ vips similarity --scale 0.33 k2.jpg x.v
|
||||
$ vipsheader k2.jpg
|
||||
k2.jpg: 1450x2048 uchar, 3 bands, srgb, jpegload
|
||||
$ vipsheader x.v
|
||||
x.v: 478x676 uchar, 3 bands, srgb, jpegload
|
||||
|
||||
1450 * 0.33 = 478.5 ... this was rounded down
|
||||
2048 * 0.33 = 675.84 ... this was rounded up
|
||||
|
||||
- add APPROX convsep test?
|
||||
|
||||
- add more webp tests to py suite
|
||||
|
||||
- try moving some more of the CLI tests to py
|
||||
|
||||
- colour needs to split _build() into preprocess / process / postprocess
|
||||
phases
|
||||
|
||||
in icc_import, for example, we want to check that the supplied profile is
|
||||
compatible with the input image as it will be when unpacked and ready for
|
||||
process_line
|
||||
|
||||
see vips_image_expected_bands() in icc_transform.c for the current hacky
|
||||
solution
|
||||
|
||||
|
||||
|
||||
- use the incremental webp decoding api to support seq for webp images
|
||||
|
||||
https://developers.google.com/speed/webp/docs/api#decodingadvancedapi
|
||||
|
||||
doesn't seem to be possible
|
||||
|
||||
- does ruby need to unpack RefString as well? what about C++?
|
||||
|
||||
- are the mosaic functions calling vips_fastcor()? it must be very slow
|
||||
|
||||
add vips_fastcor_direct()
|
||||
|
||||
nope .. it's im_chkpair.c:im_correl()
|
||||
|
||||
im_extract_area(main)
|
||||
im_extract_area(sub)
|
||||
im_extract_band(main)
|
||||
im_extract_band(sub)
|
||||
im_spcor(sub)
|
||||
im_maxpos(sub)
|
||||
|
||||
then im__chkpair() runs that 20 times, then loops ... oh dear
|
||||
|
||||
- perhaps im_maxpos_subpel() / im_minpos_subpel() should be undeprecated,
|
||||
useful with vips_fastcor()
|
||||
|
||||
|
||||
|
||||
- why can't we do
|
||||
|
||||
im = Vips.Image.new_from_file("/data/john/pics/k2.jpg", access = "sequential")
|
||||
|
||||
no idea ... this works fine:
|
||||
|
||||
im.embed(10, 10, 100, 100, extend = "copy")
|
||||
|
||||
test:
|
||||
|
||||
op = Vips.Operation.new("embed")
|
||||
op.props.__setattr__("extend", "copy")
|
||||
op = Vips.Operation.new("jpegload")
|
||||
op.props.__setattr__("access", "sequential")
|
||||
|
||||
first setattr works fine, second fails with invalid literal
|
||||
|
||||
|
||||
|
||||
|
||||
- test other cpp arg types
|
||||
|
||||
input int works
|
||||
input double
|
||||
input enum works
|
||||
input image works
|
||||
input doublevec
|
||||
input imagevec
|
||||
input blob
|
||||
|
||||
output int
|
||||
output double works
|
||||
output enum
|
||||
output image works
|
||||
output doublevec
|
||||
output imagevec
|
||||
output blob
|
||||
|
||||
we probably need to unpack the ink back to double before blending
|
||||
|
||||
|
||||
|
||||
- ink to vec etc must have a way to give a complex constant
|
||||
|
||||
eg. drawink needs a --ink_imag option with the imaginary components of the
|
||||
ink
|
||||
|
||||
look for uses of vips__vector_to_ink() and add extra params to other places
|
||||
too, eg. vips_embed(), vips_insert() etc.
|
||||
|
||||
- vips__ink_to_vector() needs an optional imag return
|
||||
|
||||
- vips_getpoint() needs an optional imag return
|
||||
|
||||
- add porter-duff compositing, see
|
||||
|
||||
https://github.com/libvips/ruby-vips/issues/28
|
||||
|
||||
- now vips_linear() has uchar output, can we do something with orc?
|
||||
|
||||
- do restrict on some more packages, we've just done arithmetic so far
|
||||
|
||||
also resample, colour, some of conversion, create,
|
||||
|
||||
- maybe avg?
|
||||
|
||||
but avg doesn't subclass arithmetic, so we can't
|
||||
|
||||
- for interpolate, we'd need to be able to unroll the vector, so the
|
||||
interpolator would need to be built for the bands / stride / type of the
|
||||
image
|
||||
|
||||
need new API For this since interpolators currently work for any image
|
||||
|
||||
- vips_gaussblur() should switch to float prec if given a float image?
|
||||
|
||||
same for vips_conv()?
|
||||
|
||||
maybe precision is a dumb thing
|
||||
|
||||
- support --strip for other writers
|
||||
|
||||
- vipsthumbnail could shrink-on-load openslide and pyr tiff as well?
|
||||
|
||||
we have "shrink" for jpegload, move this into the base loader
|
||||
|
||||
support it for tiff and openslide as well
|
||||
|
||||
use it from nip2 for zooming? only if the partial flag is set though, we
|
||||
don't want to use it on jpg files
|
||||
|
||||
|
||||
|
||||
- quadratic doesn't work for order 3
|
||||
|
||||
start to get jaggies on lines --- the 3rd differential isn't being
|
||||
initialised correctly for the sub-region?
|
||||
|
||||
seems fine vertically, only get errors on horizontal tile boundaries
|
||||
|
||||
because we step across tiles left to right: y doesn't change, only x does
|
||||
|
||||
not sure it works for order 2 either, we are seeing interpolation errors
|
||||
on image edges
|
||||
|
||||
|
||||
mosaic
|
||||
======
|
||||
|
||||
- balance should use new meta stuff
|
||||
|
||||
- histogram balance option?
|
||||
|
||||
|
||||
resample
|
||||
========
|
||||
|
||||
- check mosaic1, global_balance, similarity etc. use of im__affine
|
||||
|
||||
how can we move them to im_affinei ?
|
||||
|
||||
- perspective transform with a matrix ... base it on the Lenz transformer, but
|
||||
partial
|
||||
|
||||
|
||||
foreign
|
||||
=======
|
||||
|
||||
- magick2vips should spot ICC profiles and attach them as meta
|
||||
|
||||
- interlaced jpg needs massive memory, we should have two jpg read modes, like
|
||||
png
|
||||
|
||||
- add more sequential mode readers
|
||||
|
||||
$ grep -l write_line *.c
|
||||
csv.c
|
||||
matlab.c
|
||||
openexr2vips.c
|
||||
ppm.c
|
||||
radiance.c
|
||||
|
||||
- foreign docs come up as "VipsForeignSave", annoying, why?
|
||||
|
||||
- add nifti support
|
||||
|
||||
http://niftilib.sourceforge.net/
|
||||
|
||||
- add matlab write
|
||||
|
||||
- im_exr2vips can now use c++ api
|
||||
|
||||
see TODO notes in openexr read (though they all need more openexr C API)
|
||||
|
||||
consider openexr write
|
||||
|
||||
- magick should set some header field for n_frames and frame_height? see also
|
||||
analyze
|
||||
|
||||
- im_csv2vips() could use "-" for filename to mean stdin
|
||||
|
||||
but then we'd have to read to a malloced buffer of some sort rather than an
|
||||
image, since we might need to grow it during the read, since we couldn't
|
||||
then seek
|
||||
|
||||
|
||||
packaging
|
||||
=========
|
||||
|
||||
- test _O_TEMPORARY thing on Windows
|
||||
|
||||
|
||||
convolution
|
||||
===========
|
||||
|
||||
- revisit orc conv
|
||||
|
||||
use an 8.8 accumulator ... build the scale into the 8.8 coeffs ... no div at
|
||||
the end, just a shift
|
||||
|
||||
need 8 x 8.8 -> 8.8 for each coeff though
|
||||
|
||||
- im_conv()/im_morph() could have more than 10 programs? try 20 and see if we
|
||||
still have a speedup
|
||||
|
||||
make a base class for vector area operations with a matrix with three vfuncs
|
||||
for init / generate code for one element / end and a gslist of programs, use
|
||||
that as the base for morph and conv
|
||||
|
||||
wait for vipsobject for this
|
||||
|
||||
- we have aconv and aconvsep
|
||||
|
||||
test timing, make sure it;s worth having a separate aconvsep version
|
||||
|
||||
if it is, make im_aconvsep an optimisation: call im_aconvsep_raw() from
|
||||
vips_conv() if mask width or height == 1 and prec == APPROX
|
||||
|
||||
now we can get rid of im_aconvsep() since it's just vips_convsep() with prec
|
||||
set to approx
|
||||
|
||||
aconv needs some more work, get it going at least with gaussian
|
||||
|
||||
|
||||
arithmetic
|
||||
==========
|
||||
|
||||
- HAVE_HYPOT could define a hypot() macro?
|
||||
|
||||
- fix a better NaN policy
|
||||
|
||||
should we not generate images containing NaN (eg. divide tries to avoid /0),
|
||||
or should vips_max() etc. try to avoid NaN in images (eg. vips_max() takes a
|
||||
lot a care to skip NaN, though vips_stats() does not)?
|
||||
|
||||
|
||||
iofuncs
|
||||
=======
|
||||
|
||||
- need vips_image_invalidate_area()
|
||||
|
||||
- look at libpeas for plugin support
|
||||
|
||||
http://live.gnome.org/Libpeas
|
||||
|
||||
- how about
|
||||
|
||||
vips max add[babe.jpg,babe2.jpg]
|
||||
|
||||
does that make any sense?
|
||||
|
||||
vips copy add[babe.jpg,add[babe2.jpg,babe3.jpg]] sum.v
|
||||
|
||||
perhaps use curly brackets for code?
|
||||
|
||||
vips max add{babe.jpg,babe2.jpg}
|
||||
|
||||
no brackets or square brackets for options
|
||||
|
||||
- transform_g_string_array_image() can't handle quoted strings, so filenames
|
||||
with spaces will break
|
||||
|
||||
is there an easy fix? can we reuse code from the csv parser?
|
||||
|
||||
the csv parser just parses FILE* streams, we'd need to break it out
|
||||
|
||||
- note member free stuff in vipsobject docs
|
||||
|
||||
should boxed get freed in finalise rather than dispose?
|
||||
|
||||
vipsobject has few docs atm :(
|
||||
|
||||
- vips_object_set_argument_from_string() needs more arg types
|
||||
|
||||
must be some way to make this more automatic
|
||||
|
||||
- generate the code for vips_add() etc. automatically? it might be
|
||||
nice to have them all in one place at least
|
||||
|
||||
- what does G_UNLIKELY() do? can we use it?
|
||||
|
||||
- look into G_GNUC_DEPRECATED for back compat in vips8
|
||||
|
||||
- should im_rwcheck() copy to disc?
|
||||
|
||||
maybe im_rwcheck_disc() copies to im->filename and maps that
|
||||
|
||||
rather awkward to do atm with the way check.c is structured
|
||||
|
||||
|
||||
swig
|
||||
====
|
||||
|
||||
- swig is not wrapping im_project() correctly ... returns an extra VImage via
|
||||
a param
|
||||
|
||||
- doc strings would be nice, read the SWIG notes on this
|
||||
|
||||
|
||||
new bindings
|
||||
============
|
||||
|
||||
- new binding is still missing constants
|
||||
|
||||
how do boxed types work? confusing
|
||||
|
||||
we need to be able to make a VipsArrayDouble
|
||||
|
||||
- Vips.Image has members like chain, __subclasshook__ etc etc, are we
|
||||
really subclassing it correctly?
|
||||
|
||||
- add __add__ etc overloads
|
||||
|
||||
|
||||
freq_filt
|
||||
=========
|
||||
|
||||
- fft with odd width or height is broken ... DC ends up in the wrong place
|
||||
|
||||
|
||||
libvipsCC
|
||||
=========
|
||||
|
||||
- need new C++ API
|
||||
|
||||
- need an im_init_world() for C++ which does cmd-line args too, so C++ progs
|
||||
can get --vips-progress and stuff automatically
|
||||
|
||||
|
||||
tools
|
||||
=====
|
||||
|
||||
- need a way to make the vips.1 etc. man pages
|
||||
|
||||
gtk has things like docs/reference/gtk/gtk-update-icon-cache.xml and man
|
||||
pages are made from that with xslt
|
||||
|
||||
- get rid of a lot of the command-line programs, who wants to write a man page
|
||||
for batch_image_convert etc yuk
|
||||
|
||||
- can we make man pages for the API as well? probably not from googling a bit
|
||||
|
||||
- rename header, edvips as vipsheader, vipsedit
|
||||
|
||||
maybe have back compat links?
|
||||
|
||||
|
||||
new operations
|
||||
==============
|
||||
|
||||
- bilateral filtering, see:
|
||||
|
||||
http://en.wikipedia.org/wiki/Bilateral_filter
|
||||
http://www.shellandslate.com/fastmedian.html
|
||||
http://people.csail.mit.edu/sparis/bf_course/
|
||||
|
||||
also a mail from Martin Breidt has links to several fast free C
|
||||
implementations
|
||||
|
||||
- http://en.wikipedia.org/wiki/Otsu%27s_method
|
||||
|
||||
- non-linear sharpen: replace each pixel by the lightest or darkest neighbour
|
||||
depending on which is closer in value
|
||||
|
||||
- look at
|
||||
|
||||
There is an order 1 algorithm for doing medians over boxes (truly O(1)
|
||||
per pixel: I checked it carefully; it's like doing means over boxes in
|
||||
order 1 per pixel) in OpenCV since February 2012 I think, due to
|
||||
Perreault (and Hebert).
|
||||
|
||||
It appears to be well respected, at least for 8-bit medians. Very
|
||||
memory intensive. Simple and elegant. No clue if it fits VIPS well
|
||||
(probably not?).
|
||||
|
||||
Article: nomis80.org/ctmf.pdf
|
||||
|
||||
- see
|
||||
|
||||
http://www.dentistry.bham.ac.uk/landinig/software/cdeconv/cdeconv.html
|
||||
|
||||
http://www.nature.com/srep/2015/150730/srep12096/full/srep12096.html
|
||||
|
||||
sounds useful for BM?
|
@ -61,4 +61,6 @@ autoheader
|
||||
$LIBTOOLIZE --copy --force --automake
|
||||
automake --add-missing --copy
|
||||
|
||||
./configure $*
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
./configure $*
|
||||
fi
|
||||
|
152
configure.ac
@ -2,7 +2,7 @@
|
||||
|
||||
# also update the version number in the m4 macros below
|
||||
|
||||
AC_INIT([vips], [8.9.0], [vipsip@jiscmail.ac.uk])
|
||||
AC_INIT([vips], [8.10.0], [vipsip@jiscmail.ac.uk])
|
||||
# required for gobject-introspection
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
@ -17,7 +17,7 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
# user-visible library versioning
|
||||
m4_define([vips_major_version], [8])
|
||||
m4_define([vips_minor_version], [9])
|
||||
m4_define([vips_minor_version], [10])
|
||||
m4_define([vips_micro_version], [0])
|
||||
m4_define([vips_version],
|
||||
[vips_major_version.vips_minor_version.vips_micro_version])
|
||||
@ -38,7 +38,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date -u -r ChangeLog`
|
||||
# binary interface changes not backwards compatible?: reset age to 0
|
||||
|
||||
LIBRARY_CURRENT=54
|
||||
LIBRARY_REVISION=0
|
||||
LIBRARY_REVISION=3
|
||||
LIBRARY_AGE=12
|
||||
|
||||
# patched into include/vips/version.h
|
||||
@ -450,33 +450,12 @@ AC_CHECK_LIB(m,cbrt,[AC_DEFINE(HAVE_CBRT,1,[have cbrt() in libm.])])
|
||||
AC_CHECK_LIB(m,hypot,[AC_DEFINE(HAVE_HYPOT,1,[have hypot() in libm.])])
|
||||
AC_CHECK_LIB(m,atan2,[AC_DEFINE(HAVE_ATAN2,1,[have atan2() in libm.])])
|
||||
|
||||
# have to have these
|
||||
# need glib 2.6 for GOption
|
||||
PKG_CHECK_MODULES(REQUIRED, glib-2.0 >= 2.6 gmodule-2.0 gobject-2.0)
|
||||
PACKAGES_USED="$PACKAGES_USED glib-2.0 gmodule-2.0 gobject-2.0"
|
||||
|
||||
# from 2.12 we have g_base64_encode()
|
||||
PKG_CHECK_MODULES(BASE64_ENCODE, glib-2.0 >= 2.12,
|
||||
[AC_DEFINE(HAVE_BASE64_ENCODE,1,
|
||||
[define if your glib has g_base64_encode().]
|
||||
)
|
||||
],
|
||||
[:
|
||||
]
|
||||
)
|
||||
|
||||
# from 2.14 we have g_option_context_get_help()
|
||||
PKG_CHECK_MODULES(CONTEXT_GET_HELP, glib-2.0 >= 2.14,
|
||||
[AC_DEFINE(HAVE_CONTEXT_GET_HELP,1,
|
||||
[define if your glib has g_option_context_get_help().]
|
||||
)
|
||||
],
|
||||
[:
|
||||
]
|
||||
)
|
||||
# have to have these parts of glib ... we need glib 2.15 for gio
|
||||
PKG_CHECK_MODULES(REQUIRED, glib-2.0 >= 2.15 gmodule-2.0 gobject-2.0 gio-2.0)
|
||||
PACKAGES_USED="$PACKAGES_USED glib-2.0 gmodule-2.0 gobject-2.0 gio-2.0"
|
||||
|
||||
# from 2.28 we have a monotonic timer
|
||||
PKG_CHECK_MODULES(MONOTONIC, glib-2.0 >= 2.28,
|
||||
PKG_CHECK_MODULES(MONOTONIC_TIME, glib-2.0 >= 2.28,
|
||||
[AC_DEFINE(HAVE_MONOTONIC_TIME,1,
|
||||
[define if your glib has g_get_monotonic_time().]
|
||||
)
|
||||
@ -485,11 +464,18 @@ PKG_CHECK_MODULES(MONOTONIC, glib-2.0 >= 2.28,
|
||||
]
|
||||
)
|
||||
|
||||
# the old threading system
|
||||
PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
|
||||
PACKAGES_USED="$PACKAGES_USED gthread-2.0"
|
||||
# from 2.62 we have datetime
|
||||
PKG_CHECK_MODULES(DATE_TIME_FORMAT_ISO8601, glib-2.0 >= 2.62,
|
||||
[AC_DEFINE(HAVE_DATE_TIME_FORMAT_ISO8601,1,
|
||||
[define if your glib has g_date_time_format_iso8601().]
|
||||
)
|
||||
],
|
||||
[:
|
||||
]
|
||||
)
|
||||
|
||||
# from 2.32 there are a new set of thread functions, annoyingly
|
||||
# from 2.32 there are a new set of thread functions, it is no longer
|
||||
# necessary to use g_thread_init() or to link against libgthread
|
||||
PKG_CHECK_MODULES(THREADS, glib-2.0 >= 2.32,
|
||||
[AC_DEFINE(HAVE_MUTEX_INIT,1,[define if your glib has g_mutex_init().])
|
||||
AC_DEFINE(HAVE_COND_INIT,1,[define if your glib has g_cond_init().])
|
||||
@ -498,6 +484,9 @@ PKG_CHECK_MODULES(THREADS, glib-2.0 >= 2.32,
|
||||
AC_DEFINE(HAVE_VALUE_GET_SCHAR,1,
|
||||
[define if your glib has g_value_get_schar().]
|
||||
)
|
||||
],
|
||||
[PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
|
||||
PACKAGES_USED="$PACKAGES_USED gthread-2.0"
|
||||
]
|
||||
)
|
||||
|
||||
@ -553,9 +542,16 @@ PKG_CHECK_MODULES(HAVE_CHECKED_MUL, glib-2.0 >= 2.48,
|
||||
# check for gtk-doc
|
||||
GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
|
||||
|
||||
# we need expat ... we'd love to use expat.pc, but sadly this is only available
|
||||
# for recent linuxes, so we have to use the old and horrible expat.m4
|
||||
AM_WITH_EXPAT
|
||||
# we need expat ... the .pc file for expat is only available
|
||||
# for recent linuxes, so we fall back to AM_WITH_EXPAT
|
||||
PKG_CHECK_MODULES(EXPAT, expat,
|
||||
[expat_found=yes
|
||||
PACKAGES_USED="$PACKAGES_USED expat"
|
||||
],
|
||||
[AM_WITH_EXPAT
|
||||
]
|
||||
)
|
||||
|
||||
if test x"$expat_found" = x"no"; then
|
||||
exit 1
|
||||
fi
|
||||
@ -699,6 +695,16 @@ if test x"$magick6" = x"yes"; then
|
||||
]
|
||||
)
|
||||
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[#include <magick/api.h>],
|
||||
[ColorspaceType colorspace = HCLpColorspace]
|
||||
)],
|
||||
[AC_DEFINE(HAVE_HCLPCOLORSPACE,1,
|
||||
[define if your Magick has HCLpColorspace.])
|
||||
]
|
||||
)
|
||||
|
||||
# GetImageMagick() takes two args under GM, three under IM
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
@ -778,6 +784,19 @@ if test x"$with_orc" != x"no"; then
|
||||
)
|
||||
fi
|
||||
|
||||
# orc 0.4.30+ works with cf-protection, but 0.4.30 has a bug with multiple
|
||||
# definitions of OrcTargetPowerPCFlags, so insist on 0.4.31
|
||||
if test x"$with_orc" = x"yes"; then
|
||||
PKG_CHECK_MODULES(ORC_CF_PROTECTION, orc-0.4 >= 0.4.31,
|
||||
[AC_DEFINE(HAVE_ORC_CF_PROTECTION,1,
|
||||
[define if your orc works with cf-protection.]
|
||||
)
|
||||
],
|
||||
[:
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
# lcms ... refuse to use lcms1
|
||||
AC_ARG_WITH([lcms],
|
||||
AS_HELP_STRING([--without-lcms], [build without lcms (default: test)]))
|
||||
@ -836,14 +855,16 @@ if test x"$with_heif" != x"no"; then
|
||||
PKG_CHECK_MODULES(HEIF, libheif,
|
||||
[with_heif=yes
|
||||
have_h265_decoder=`$PKG_CONFIG libheif --variable builtin_h265_decoder`
|
||||
have_avif_decoder=`$PKG_CONFIG libheif --variable builtin_avif_decoder`
|
||||
# test for !=no so that we work for older libheif which does not have
|
||||
# this variable
|
||||
if test x"$have_h265_decoder" != x"no"; then
|
||||
if test x"$have_h265_decoder" != x"no" -o x"$have_avif_decoder" = x"yes"; then
|
||||
AC_DEFINE(HAVE_HEIF_DECODER,1,
|
||||
[define if your libheif has decode support.])
|
||||
fi
|
||||
have_h265_encoder=`$PKG_CONFIG libheif --variable builtin_h265_encoder`
|
||||
if test x"$have_h265_encoder" != x"no"; then
|
||||
have_avif_encoder=`$PKG_CONFIG libheif --variable builtin_avif_encoder`
|
||||
if test x"$have_h265_encoder" != x"no" -o x"$have_avif_encoder" = x"yes"; then
|
||||
AC_DEFINE(HAVE_HEIF_ENCODER,1,
|
||||
[define if your libheif has encode support.])
|
||||
fi
|
||||
@ -853,6 +874,8 @@ if test x"$with_heif" != x"no"; then
|
||||
with_heif=no
|
||||
have_h265_decoder=
|
||||
have_h265_encoder=
|
||||
have_avif_decoder=
|
||||
have_avif_encoder=
|
||||
]
|
||||
)
|
||||
fi
|
||||
@ -905,16 +928,16 @@ if test x"$with_heif" = x"yes"; then
|
||||
LIBS="$save_LIBS"
|
||||
fi
|
||||
|
||||
# fetch untransformed width/height added in 1.3.4
|
||||
# heif_decoding_options.convert_hdr_to_8bit added in 1.7.0
|
||||
if test x"$with_heif" = x"yes"; then
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $HEIF_LIBS"
|
||||
AC_CHECK_FUNCS(heif_image_handle_get_ispe_width,[
|
||||
AC_DEFINE(HAVE_HEIF_IMAGE_HANDLE_GET_ISPE_WIDTH,1,
|
||||
[define if you have heif_image_handle_get_ispe_width.])
|
||||
],[]
|
||||
)
|
||||
LIBS="$save_LIBS"
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $HEIF_CFLAGS"
|
||||
AC_CHECK_MEMBER([struct heif_decoding_options.convert_hdr_to_8bit],[
|
||||
AC_DEFINE(HAVE_HEIF_DECODING_OPTIONS_CONVERT_HDR_TO_8BIT,1,
|
||||
[define if you have heif_decoding_options.convert_hdr_to_8bit])
|
||||
],[],
|
||||
[#include <libheif/heif.h>])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
fi
|
||||
|
||||
# pdfium
|
||||
@ -1176,6 +1199,21 @@ fi
|
||||
)
|
||||
#fi
|
||||
|
||||
# Look for libspng first
|
||||
AC_ARG_WITH([libspng],
|
||||
AS_HELP_STRING([--without-libspng], [build without libspng (default: test)]))
|
||||
|
||||
if test x"$with_libspng" != x"no"; then
|
||||
PKG_CHECK_MODULES(SPNG, spng >= 0.6,
|
||||
[AC_DEFINE(HAVE_SPNG,1,[define if you have libspng installed.])
|
||||
with_libspng=yes
|
||||
PACKAGES_USED="$PACKAGES_USED spng"
|
||||
],
|
||||
[with_libspng=no
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
# look for PNG with pkg-config ... fall back to our tester
|
||||
AC_ARG_WITH([png],
|
||||
AS_HELP_STRING([--without-png], [build without libpng (default: test)]))
|
||||
@ -1298,23 +1336,21 @@ if test x"$LIB_FUZZING_ENGINE" = x; then
|
||||
LIB_FUZZING_ENGINE="libstandaloneengine.a"
|
||||
fi
|
||||
|
||||
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS
|
||||
# sort includes to get longer, more specific dirs first
|
||||
# helps, for example, selecting graphicsmagick over imagemagick
|
||||
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $EXPAT_CFLAGS $ZLIB_CFLAGS $PANGOFT2_CFLAGS $GSF_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $JPEG_CFLAGS $PNG_CFLAGS $IMAGEQUANT_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $LIBWEBP_CFLAGS $LIBWEBPMUX_CFLAGS $LIBNSGIF_CFLAGS $GIFLIB_INCLUDES $RSVG_CFLAGS $PDFIUM_INCLUDES $POPPLER_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS $LCMS_CFLAGS $HEIF_CFLAGS
|
||||
do
|
||||
echo $i
|
||||
done | sort -ru`
|
||||
VIPS_CFLAGS=`echo $VIPS_CFLAGS`
|
||||
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS
|
||||
VIPS_CFLAGS="$VIPS_CFLAGS $GTHREAD_CFLAGS $GIO_CFLAGS $REQUIRED_CFLAGS $EXPAT_CFLAGS $ZLIB_CFLAGS $PANGOFT2_CFLAGS $GSF_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $JPEG_CFLAGS $SPNG_CFLAGS $PNG_CFLAGS $IMAGEQUANT_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $LIBWEBP_CFLAGS $LIBWEBPMUX_CFLAGS $LIBNSGIF_CFLAGS $GIFLIB_INCLUDES $RSVG_CFLAGS $PDFIUM_INCLUDES $POPPLER_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS $LCMS_CFLAGS $HEIF_CFLAGS"
|
||||
VIPS_CFLAGS="$VIPS_DEBUG_FLAGS $VIPS_CFLAGS"
|
||||
VIPS_INCLUDES="$ZLIB_INCLUDES $PNG_INCLUDES $TIFF_INCLUDES $JPEG_INCLUDES $NIFTI_INCLUDES"
|
||||
VIPS_LIBS="$ZLIB_LIBS $HEIF_LIBS $MAGICK_LIBS $PNG_LIBS $IMAGEQUANT_LIBS $TIFF_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $EXPAT_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $LIBNSGIF_LIBS $GIFLIB_LIBS $RSVG_LIBS $NIFTI_LIBS $PDFIUM_LIBS $POPPLER_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_LIBS $LIBWEBPMUX_LIBS $MATIO_LIBS $EXIF_LIBS -lm"
|
||||
VIPS_LIBS="$ZLIB_LIBS $HEIF_LIBS $MAGICK_LIBS $SPNG_LIBS $PNG_LIBS $IMAGEQUANT_LIBS $TIFF_LIBS $JPEG_LIBS $GTHREAD_LIBS $GIO_LIBS $REQUIRED_LIBS $EXPAT_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $LIBNSGIF_LIBS $GIFLIB_LIBS $RSVG_LIBS $NIFTI_LIBS $PDFIUM_LIBS $POPPLER_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_LIBS $LIBWEBPMUX_LIBS $MATIO_LIBS $EXIF_LIBS -lm"
|
||||
|
||||
# autoconf hates multi-line AC_SUBST so we have to have another copy of this
|
||||
# thing
|
||||
VIPS_CONFIG="native win32: $vips_os_win32, native OS X: $vips_os_darwin, open files in binary mode: $vips_binary_open, enable debug: $enable_debug, enable deprecated library components: $enable_deprecated, enable docs with gtkdoc: $enable_gtk_doc, gobject introspection: $found_introspection, enable radiance support: $with_radiance, enable analyze support: $with_analyze, enable PPM support: $with_ppm, use fftw3 for FFT: $with_fftw, Magick package: $with_magickpackage, Magick API version: $magick_version, load with libMagick: $enable_magickload, save with libMagick: $enable_magicksave, accelerate loops with orc: $with_orc, ICC profile support with lcms: $with_lcms, file import with niftiio: $with_nifti, file import with libheif: $with_heif, file import with OpenEXR: $with_OpenEXR, file import with OpenSlide: $with_openslide, file import with matio: $with_matio, PDF import with PDFium: $with_pdfium, PDF import with poppler-glib: $with_poppler, SVG import with librsvg-2.0: $with_rsvg, zlib: $with_zlib, file import with cfitsio: $with_cfitsio, file import/export with libwebp: $with_libwebp, text rendering with pangoft2: $with_pangoft2, file import/export with libpng: $with_png, support 8bpp PNG quantisation: $with_imagequant, file import/export with libtiff: $with_tiff, file import/export with giflib: $with_giflib, file import/export with libjpeg: $with_jpeg, image pyramid export: $with_gsf, use libexif to load/save JPEG metadata: $with_libexif, file import/export with libspng: $with_libspng, file import/export with libnsgif: $with_libnsgif"
|
||||
AC_SUBST(VIPS_LIBDIR)
|
||||
|
||||
AC_SUBST(VIPS_CFLAGS)
|
||||
AC_SUBST(VIPS_INCLUDES)
|
||||
AC_SUBST(VIPS_LIBS)
|
||||
AC_SUBST(VIPS_CONFIG)
|
||||
AC_SUBST(PACKAGES_USED)
|
||||
AC_SUBST(EXTRA_LIBS_USED)
|
||||
|
||||
@ -1333,6 +1369,7 @@ AC_OUTPUT([
|
||||
libvips/Makefile
|
||||
libvips/arithmetic/Makefile
|
||||
libvips/colour/Makefile
|
||||
libvips/colour/profiles/Makefile
|
||||
libvips/conversion/Makefile
|
||||
libvips/convolution/Makefile
|
||||
libvips/deprecated/Makefile
|
||||
@ -1365,6 +1402,7 @@ AC_OUTPUT([
|
||||
fuzz/Makefile
|
||||
])
|
||||
|
||||
# also add any new items to VIPS_CONFIG above
|
||||
AC_MSG_RESULT([dnl
|
||||
* build options
|
||||
native win32: $vips_os_win32
|
||||
@ -1393,7 +1431,7 @@ file import with OpenEXR: $with_OpenEXR
|
||||
file import with OpenSlide: $with_openslide
|
||||
(requires openslide-3.3.0 or later)
|
||||
file import with matio: $with_matio
|
||||
PDF import with PDFium $with_pdfium
|
||||
PDF import with PDFium: $with_pdfium
|
||||
PDF import with poppler-glib: $with_poppler
|
||||
(requires poppler-glib 0.16.0 or later)
|
||||
SVG import with librsvg-2.0: $with_rsvg
|
||||
@ -1403,6 +1441,8 @@ file import with cfitsio: $with_cfitsio
|
||||
file import/export with libwebp: $with_libwebp
|
||||
(requires libwebp, libwebpmux, libwebpdemux 0.6.0 or later)
|
||||
text rendering with pangoft2: $with_pangoft2
|
||||
file import/export with libspng: $with_libspng
|
||||
(requires libspng-0.6 or later)
|
||||
file import/export with libpng: $with_png
|
||||
(requires libpng-1.2.9 or later)
|
||||
support 8bpp PNG quantisation: $with_imagequant
|
||||
|
@ -11,6 +11,7 @@ lib_LTLIBRARIES = libvips-cpp.la
|
||||
libvips_cpp_la_SOURCES = \
|
||||
VImage.cpp \
|
||||
VInterpolate.cpp \
|
||||
VConnection.cpp \
|
||||
VError.cpp
|
||||
|
||||
libvips_cpp_la_LDFLAGS = \
|
||||
|
178
cplusplus/VConnection.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
/* Object part of the VSource and VTarget class
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 1991-2001 The National Gallery
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
#include <vips/debug.h>
|
||||
|
||||
/*
|
||||
#define VIPS_DEBUG
|
||||
#define VIPS_DEBUG_VERBOSE
|
||||
*/
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
||||
VSource
|
||||
VSource::new_from_descriptor( int descriptor )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_descriptor( descriptor )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_file( const char *filename )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_file( filename )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_blob( VipsBlob *blob )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_blob( blob )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_memory( const void *data,
|
||||
size_t size )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_memory( data, size )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VSource
|
||||
VSource::new_from_options( const char *options )
|
||||
{
|
||||
VipsSource *input;
|
||||
|
||||
if( !(input = vips_source_new_from_options( options )) )
|
||||
throw VError();
|
||||
|
||||
VSource out( input );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VOption *
|
||||
VOption::set( const char *name, const VSource value )
|
||||
{
|
||||
Pair *pair = new Pair( name );
|
||||
|
||||
pair->input = true;
|
||||
g_value_init( &pair->value, VIPS_TYPE_SOURCE );
|
||||
g_value_set_object( &pair->value, value.get_source() );
|
||||
options.push_back( pair );
|
||||
|
||||
return( this );
|
||||
}
|
||||
|
||||
VTarget
|
||||
VTarget::new_to_descriptor( int descriptor )
|
||||
{
|
||||
VipsTarget *output;
|
||||
|
||||
if( !(output = vips_target_new_to_descriptor( descriptor )) )
|
||||
throw VError();
|
||||
|
||||
VTarget out( output );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VTarget
|
||||
VTarget::new_to_file( const char *filename )
|
||||
{
|
||||
VipsTarget *output;
|
||||
|
||||
if( !(output = vips_target_new_to_file( filename )) )
|
||||
throw VError();
|
||||
|
||||
VTarget out( output );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VTarget
|
||||
VTarget::new_to_memory()
|
||||
{
|
||||
VipsTarget *output;
|
||||
|
||||
if( !(output = vips_target_new_to_memory()) )
|
||||
throw VError();
|
||||
|
||||
VTarget out( output );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VOption *
|
||||
VOption::set( const char *name, const VTarget value )
|
||||
{
|
||||
Pair *pair = new Pair( name );
|
||||
|
||||
pair->input = true;
|
||||
g_value_init( &pair->value, VIPS_TYPE_TARGET );
|
||||
g_value_set_object( &pair->value, value.get_target() );
|
||||
options.push_back( pair );
|
||||
|
||||
return( this );
|
||||
}
|
||||
|
||||
VIPS_NAMESPACE_END
|
@ -61,7 +61,7 @@ VInterpolate::new_from_name( const char *name, VOption *options )
|
||||
}
|
||||
|
||||
VOption *
|
||||
VOption::set( const char *name, VInterpolate value )
|
||||
VOption::set( const char *name, const VInterpolate value )
|
||||
{
|
||||
Pair *pair = new Pair( name );
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
import argparse
|
||||
|
||||
from pyvips import Operation, GValue, Error, \
|
||||
from pyvips import Introspect, Operation, GValue, Error, \
|
||||
ffi, gobject_lib, type_map, type_from_name, nickname_find, type_name
|
||||
|
||||
# turn a GType into a C++ type
|
||||
@ -37,12 +37,17 @@ gtype_to_cpp = {
|
||||
GValue.refstr_type: 'char *',
|
||||
GValue.gflags_type: 'int',
|
||||
GValue.image_type: 'VImage',
|
||||
GValue.source_type: 'VSource',
|
||||
GValue.target_type: 'VTarget',
|
||||
GValue.array_int_type: 'std::vector<int>',
|
||||
GValue.array_double_type: 'std::vector<double>',
|
||||
GValue.array_image_type: 'std::vector<VImage>',
|
||||
GValue.blob_type: 'VipsBlob *'
|
||||
}
|
||||
|
||||
cplusplus_suffixes = ('*', '&')
|
||||
cplusplus_keywords = ('case', 'switch')
|
||||
|
||||
# values for VipsArgumentFlags
|
||||
_REQUIRED = 1
|
||||
_INPUT = 16
|
||||
@ -78,67 +83,43 @@ def cppize(name):
|
||||
|
||||
|
||||
def generate_operation(operation_name, declaration_only=False):
|
||||
op = Operation.new_from_name(operation_name)
|
||||
intro = Introspect.get(operation_name)
|
||||
|
||||
# we are only interested in non-deprecated args
|
||||
args = [[name, flags] for name, flags in op.get_args()
|
||||
if not flags & _DEPRECATED]
|
||||
|
||||
# find the first required input image arg, if any ... that will be self
|
||||
member_x = None
|
||||
for name, flags in args:
|
||||
if ((flags & _INPUT) != 0 and
|
||||
(flags & _REQUIRED) != 0 and
|
||||
op.get_typeof(name) == GValue.image_type):
|
||||
member_x = name
|
||||
break
|
||||
|
||||
required_input = [name for name, flags in args
|
||||
if (flags & _INPUT) != 0 and
|
||||
(flags & _REQUIRED) != 0 and
|
||||
name != member_x]
|
||||
|
||||
required_output = [name for name, flags in args
|
||||
if ((flags & _OUTPUT) != 0 and
|
||||
(flags & _REQUIRED) != 0) or
|
||||
((flags & _INPUT) != 0 and
|
||||
(flags & _REQUIRED) != 0 and
|
||||
(flags & _MODIFY) != 0) and
|
||||
name != member_x]
|
||||
required_output = [name for name in intro.required_output if name != intro.member_x]
|
||||
|
||||
has_output = len(required_output) >= 1
|
||||
|
||||
# Add a C++ style comment block with some additional markings (@param,
|
||||
# Add a C++ style comment block with some additional markings (@param,
|
||||
# @return)
|
||||
if declaration_only:
|
||||
result = '\n/**\n * {}.'.format(op.get_description().capitalize())
|
||||
result = '\n/**\n * {}.'.format(intro.description.capitalize())
|
||||
|
||||
for name in required_input:
|
||||
for name in intro.method_args:
|
||||
result += '\n * @param {} {}.' \
|
||||
.format(cppize(name), op.get_blurb(name))
|
||||
.format(cppize(name), intro.details[name]['blurb'])
|
||||
|
||||
if has_output:
|
||||
# skip the first element
|
||||
for name in required_output[1:]:
|
||||
result += '\n * @param {} {}.' \
|
||||
.format(cppize(name), op.get_blurb(name))
|
||||
.format(cppize(name), intro.details[name]['blurb'])
|
||||
|
||||
result += '\n * @param options Optional options.'
|
||||
|
||||
if has_output:
|
||||
result += '\n * @return {}.' \
|
||||
.format(op.get_blurb(required_output[0]))
|
||||
.format(intro.details[required_output[0]]['blurb'])
|
||||
|
||||
result += '\n */\n'
|
||||
else:
|
||||
result = '\n'
|
||||
|
||||
if member_x is None and declaration_only:
|
||||
if intro.member_x is None and declaration_only:
|
||||
result += 'static '
|
||||
if has_output:
|
||||
# the first output arg will be used as the result
|
||||
cpp_type = get_cpp_type(op.get_typeof(required_output[0]))
|
||||
spacing = '' if cpp_type.endswith('*') else ' '
|
||||
cpp_type = get_cpp_type(intro.details[required_output[0]]['type'])
|
||||
spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
|
||||
result += '{0}{1}'.format(cpp_type, spacing)
|
||||
else:
|
||||
result += 'void '
|
||||
@ -146,26 +127,32 @@ def generate_operation(operation_name, declaration_only=False):
|
||||
if not declaration_only:
|
||||
result += 'VImage::'
|
||||
|
||||
result += '{0}( '.format(operation_name)
|
||||
for name in required_input:
|
||||
gtype = op.get_typeof(name)
|
||||
cplusplus_operation = operation_name
|
||||
if operation_name in cplusplus_keywords:
|
||||
cplusplus_operation += '_image'
|
||||
|
||||
result += '{0}( '.format(cplusplus_operation)
|
||||
for name in intro.method_args:
|
||||
details = intro.details[name]
|
||||
gtype = details['type']
|
||||
cpp_type = get_cpp_type(gtype)
|
||||
spacing = '' if cpp_type.endswith('*') else ' '
|
||||
spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
|
||||
result += '{0}{1}{2}, '.format(cpp_type, spacing, cppize(name))
|
||||
|
||||
# output params are passed by reference
|
||||
if has_output:
|
||||
# skip the first element
|
||||
for name in required_output[1:]:
|
||||
gtype = op.get_typeof(name)
|
||||
details = intro.details[name]
|
||||
gtype = details['type']
|
||||
cpp_type = get_cpp_type(gtype)
|
||||
spacing = '' if cpp_type.endswith('*') else ' '
|
||||
spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
|
||||
result += '{0}{1}*{2}, '.format(cpp_type, spacing, cppize(name))
|
||||
|
||||
result += 'VOption *options {0})'.format('= 0 ' if declaration_only else '')
|
||||
|
||||
# if no 'this' available, it's a class method and they are all const
|
||||
if member_x is not None:
|
||||
if intro.member_x is not None:
|
||||
result += ' const'
|
||||
|
||||
if declaration_only:
|
||||
@ -178,17 +165,17 @@ def generate_operation(operation_name, declaration_only=False):
|
||||
if has_output:
|
||||
# the first output arg will be used as the result
|
||||
name = required_output[0]
|
||||
cpp_type = get_cpp_type(op.get_typeof(name))
|
||||
spacing = '' if cpp_type.endswith('*') else ' '
|
||||
cpp_type = get_cpp_type(intro.details[name]['type'])
|
||||
spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
|
||||
result += ' {0}{1}{2};\n\n'.format(cpp_type, spacing, cppize(name))
|
||||
|
||||
result += ' call( "{0}",\n'.format(operation_name)
|
||||
result += ' (options ? options : VImage::option())'
|
||||
if member_x is not None:
|
||||
if intro.member_x is not None:
|
||||
result += '->\n'
|
||||
result += ' set( "{0}", *this )'.format(member_x)
|
||||
result += ' set( "{0}", *this )'.format(intro.member_x)
|
||||
|
||||
all_required = required_input
|
||||
all_required = intro.method_args
|
||||
|
||||
if has_output:
|
||||
# first element needs to be passed by reference
|
||||
@ -223,10 +210,10 @@ def generate_operators(declarations_only=False):
|
||||
nickname = nickname_find(gtype)
|
||||
try:
|
||||
# can fail for abstract types
|
||||
op = Operation.new_from_name(nickname)
|
||||
intro = Introspect.get(nickname)
|
||||
|
||||
# we are only interested in non-deprecated operations
|
||||
if (op.get_flags() & _OPERATION_DEPRECATED) == 0:
|
||||
if (intro.flags & _OPERATION_DEPRECATED) == 0:
|
||||
all_nicknames.append(nickname)
|
||||
except Error:
|
||||
pass
|
||||
|
@ -2,6 +2,7 @@ pkginclude_HEADERS = \
|
||||
VError8.h \
|
||||
VImage8.h \
|
||||
VInterpolate8.h \
|
||||
VConnection8.h \
|
||||
vips8 \
|
||||
vips-operators.h
|
||||
|
||||
|
96
cplusplus/include/vips/VConnection8.h
Normal file
@ -0,0 +1,96 @@
|
||||
// VIPS connection wrapper
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifndef VIPS_VCONNECTION_H
|
||||
#define VIPS_VCONNECTION_H
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
|
||||
class VSource : VObject
|
||||
{
|
||||
public:
|
||||
VSource( VipsSource *input, VSteal steal = STEAL ) :
|
||||
VObject( (VipsObject *) input, steal )
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
VSource new_from_descriptor( int descriptor );
|
||||
|
||||
static
|
||||
VSource new_from_file( const char *filename );
|
||||
|
||||
static
|
||||
VSource new_from_blob( VipsBlob *blob );
|
||||
|
||||
static
|
||||
VSource new_from_memory( const void *data,
|
||||
size_t size );
|
||||
|
||||
static
|
||||
VSource new_from_options( const char *options );
|
||||
|
||||
VipsSource *
|
||||
get_source() const
|
||||
{
|
||||
return( (VipsSource *) VObject::get_object() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class VTarget : VObject
|
||||
{
|
||||
public:
|
||||
VTarget( VipsTarget *output, VSteal steal = STEAL ) :
|
||||
VObject( (VipsObject *) output, steal )
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
VTarget new_to_descriptor( int descriptor );
|
||||
|
||||
static
|
||||
VTarget new_to_file( const char *filename );
|
||||
|
||||
static
|
||||
VTarget new_to_memory();
|
||||
|
||||
VipsTarget *
|
||||
get_target() const
|
||||
{
|
||||
return( (VipsTarget *) VObject::get_object() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
VIPS_NAMESPACE_END
|
||||
|
||||
#endif /*VIPS_VCONNECTION_H*/
|
@ -81,7 +81,7 @@ public:
|
||||
}
|
||||
#endif /*VIPS_DEBUG_VERBOSE*/
|
||||
|
||||
if( !steal ) {
|
||||
if( !steal && vobject ) {
|
||||
#ifdef VIPS_DEBUG_VERBOSE
|
||||
printf( " reffing object\n" );
|
||||
#endif /*VIPS_DEBUG_VERBOSE*/
|
||||
@ -98,22 +98,21 @@ public:
|
||||
VObject( const VObject &a ) :
|
||||
vobject( a.vobject )
|
||||
{
|
||||
g_assert( VIPS_IS_OBJECT( a.vobject ) );
|
||||
g_assert( !vobject ||
|
||||
VIPS_IS_OBJECT( vobject ) );
|
||||
|
||||
#ifdef VIPS_DEBUG_VERBOSE
|
||||
printf( "VObject copy constructor, obj = %p\n",
|
||||
vobject );
|
||||
printf( " reffing object\n" );
|
||||
#endif /*VIPS_DEBUG_VERBOSE*/
|
||||
g_object_ref( vobject );
|
||||
if( vobject )
|
||||
g_object_ref( vobject );
|
||||
}
|
||||
|
||||
// assignment ... we must delete the old ref
|
||||
// old can be NULL, new must not be NULL
|
||||
VObject &operator=( const VObject &a )
|
||||
{
|
||||
VipsObject *old_vobject;
|
||||
|
||||
#ifdef VIPS_DEBUG_VERBOSE
|
||||
printf( "VObject assignment\n" );
|
||||
printf( " reffing %p\n", a.vobject );
|
||||
@ -122,16 +121,16 @@ public:
|
||||
|
||||
g_assert( !vobject ||
|
||||
VIPS_IS_OBJECT( vobject ) );
|
||||
g_assert( a.vobject &&
|
||||
g_assert( !a.vobject ||
|
||||
VIPS_IS_OBJECT( a.vobject ) );
|
||||
|
||||
// delete the old ref at the end ... otherwise "a = a;" could
|
||||
// unref before reffing again
|
||||
old_vobject = vobject;
|
||||
if( a.vobject )
|
||||
g_object_ref( a.vobject );
|
||||
if( vobject )
|
||||
g_object_unref( vobject );
|
||||
vobject = a.vobject;
|
||||
g_object_ref( vobject );
|
||||
if( old_vobject )
|
||||
g_object_unref( old_vobject );
|
||||
|
||||
return( *this );
|
||||
}
|
||||
@ -169,6 +168,8 @@ public:
|
||||
|
||||
class VIPS_CPLUSPLUS_API VImage;
|
||||
class VIPS_CPLUSPLUS_API VInterpolate;
|
||||
class VIPS_CPLUSPLUS_API VSource;
|
||||
class VIPS_CPLUSPLUS_API VTarget;
|
||||
class VIPS_CPLUSPLUS_API VOption;
|
||||
|
||||
class VOption
|
||||
@ -220,8 +221,10 @@ public:
|
||||
VOption *set( const char *name, int value );
|
||||
VOption *set( const char *name, double value );
|
||||
VOption *set( const char *name, const char *value );
|
||||
VOption *set( const char *name, VImage value );
|
||||
VOption *set( const char *name, VInterpolate value );
|
||||
VOption *set( const char *name, const VImage value );
|
||||
VOption *set( const char *name, const VInterpolate value );
|
||||
VOption *set( const char *name, const VSource value );
|
||||
VOption *set( const char *name, const VTarget value );
|
||||
VOption *set( const char *name, std::vector<VImage> value );
|
||||
VOption *set( const char *name, std::vector<double> value );
|
||||
VOption *set( const char *name, std::vector<int> value );
|
||||
@ -510,6 +513,9 @@ public:
|
||||
static VImage new_from_buffer( const std::string &buf,
|
||||
const char *option_string, VOption *options = 0 );
|
||||
|
||||
static VImage new_from_source( VSource source,
|
||||
const char *option_string, VOption *options = 0 );
|
||||
|
||||
static VImage new_matrix( int width, int height );
|
||||
|
||||
static VImage
|
||||
@ -562,6 +568,9 @@ public:
|
||||
void write_to_buffer( const char *suffix, void **buf, size_t *size,
|
||||
VOption *options = 0 ) const;
|
||||
|
||||
void write_to_target( const char *suffix, VTarget target,
|
||||
VOption *options = 0 ) const;
|
||||
|
||||
void *
|
||||
write_to_memory( size_t *size ) const
|
||||
{
|
||||
|
@ -30,12 +30,6 @@
|
||||
#ifndef VIPS_VINTERPOLATE_H
|
||||
#define VIPS_VINTERPOLATE_H
|
||||
|
||||
#include <list>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
VIPS_NAMESPACE_START
|
||||
@ -61,4 +55,4 @@ public:
|
||||
|
||||
VIPS_NAMESPACE_END
|
||||
|
||||
#endif /*VIPS_VIMAGE_H*/
|
||||
#endif /*VIPS_VINTERPOLATE_H*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
// headers for vips operations
|
||||
// Wed Apr 24 15:50:21 CEST 2019
|
||||
// Thu 18 Jun 2020 01:19:31 PM CEST
|
||||
// this file is generated automatically, do not edit!
|
||||
|
||||
/**
|
||||
@ -296,6 +296,14 @@ VImage cache( VOption *options = 0 ) const;
|
||||
*/
|
||||
VImage canny( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Use pixel values to pick cases from an array of images.
|
||||
* @param cases Array of case images.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
VImage case_image( std::vector<VImage> cases, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Cast an image.
|
||||
* @param format Format to cast to.
|
||||
@ -446,7 +454,7 @@ double countlines( VipsDirection direction, VOption *options = 0 ) const;
|
||||
VImage crop( int left, int top, int width, int height, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Load csv from file.
|
||||
* Load csv.
|
||||
* @param filename Filename to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
@ -454,12 +462,27 @@ VImage crop( int left, int top, int width, int height, VOption *options = 0 ) co
|
||||
static VImage csvload( const char *filename, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to csv file.
|
||||
* Load csv.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage csvload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to csv.
|
||||
* @param filename Filename to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void csvsave( const char *filename, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to csv.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void csvsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Calculate de00.
|
||||
* @param right Right-hand input image.
|
||||
@ -774,6 +797,14 @@ static VImage gifload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage gifload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load gif with giflib.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage gifload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Global balance an image mosaic.
|
||||
* @param options Optional options.
|
||||
@ -826,6 +857,14 @@ static VImage heifload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage heifload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load a heif image.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage heifload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image in heif format.
|
||||
* @param filename Filename to load from.
|
||||
@ -840,6 +879,13 @@ void heifsave( const char *filename, VOption *options = 0 ) const;
|
||||
*/
|
||||
VipsBlob *heifsave_buffer( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image in heif format.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void heifsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Form cumulative histogram.
|
||||
* @param options Optional options.
|
||||
@ -1029,6 +1075,14 @@ static VImage jpegload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage jpegload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load image from jpeg source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage jpegload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to jpeg file.
|
||||
* @param filename Filename to save to.
|
||||
@ -1049,6 +1103,13 @@ VipsBlob *jpegsave_buffer( VOption *options = 0 ) const;
|
||||
*/
|
||||
void jpegsave_mime( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to jpeg target.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void jpegsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Label regions in an image.
|
||||
* @param options Optional options.
|
||||
@ -1112,7 +1173,7 @@ void magicksave( const char *filename, VOption *options = 0 ) const;
|
||||
VipsBlob *magicksave_buffer( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Resample with an mapim image.
|
||||
* Resample with a map image.
|
||||
* @param index Index pixels with this.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
@ -1296,13 +1357,28 @@ VImage math2_const( VipsOperationMath2 math2, std::vector<double> c, VOption *op
|
||||
static VImage matload( const char *filename, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load matrix from file.
|
||||
* Invert an matrix.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
VImage matrixinvert( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Load matrix.
|
||||
* @param filename Filename to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage matrixload( const char *filename, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load matrix.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage matrixload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Print matrix.
|
||||
* @param options Optional options.
|
||||
@ -1310,12 +1386,19 @@ static VImage matrixload( const char *filename, VOption *options = 0 );
|
||||
void matrixprint( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to matrix file.
|
||||
* Save image to matrix.
|
||||
* @param filename Filename to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void matrixsave( const char *filename, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to matrix.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void matrixsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Find image maximum.
|
||||
* @param options Optional options.
|
||||
@ -1436,7 +1519,7 @@ static VImage openexrload( const char *filename, VOption *options = 0 );
|
||||
static VImage openslideload( const char *filename, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load pdf with libpoppler.
|
||||
* Load pdf from file.
|
||||
* @param filename Filename to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
@ -1444,13 +1527,21 @@ static VImage openslideload( const char *filename, VOption *options = 0 );
|
||||
static VImage pdfload( const char *filename, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load pdf with libpoppler.
|
||||
* Load pdf from buffer.
|
||||
* @param buffer Buffer to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage pdfload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load pdf from source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage pdfload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Find threshold for percent of pixels.
|
||||
* @param percent Percent of pixels.
|
||||
@ -1492,6 +1583,14 @@ static VImage pngload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage pngload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load png from source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage pngload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to png file.
|
||||
* @param filename Filename to save to.
|
||||
@ -1506,6 +1605,13 @@ void pngsave( const char *filename, VOption *options = 0 ) const;
|
||||
*/
|
||||
VipsBlob *pngsave_buffer( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to target as png.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void pngsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Load ppm from file.
|
||||
* @param filename Filename to load from.
|
||||
@ -1575,6 +1681,22 @@ VImage rad2float( VOption *options = 0 ) const;
|
||||
*/
|
||||
static VImage radload( const char *filename, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load rad from buffer.
|
||||
* @param buffer Buffer to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage radload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load rad from source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage radload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to radiance file.
|
||||
* @param filename Filename to save to.
|
||||
@ -1589,6 +1711,13 @@ void radsave( const char *filename, VOption *options = 0 ) const;
|
||||
*/
|
||||
VipsBlob *radsave_buffer( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to radiance target.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void radsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Rank filter.
|
||||
* @param width Window width in pixels.
|
||||
@ -1931,6 +2060,22 @@ static VImage svgload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage svgload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load svg from source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage svgload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Find the index of the first non-zero pixel in tests.
|
||||
* @param tests Table of images to test.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage switch_image( std::vector<VImage> tests, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Run an external command.
|
||||
* @param cmd_format Command to run.
|
||||
@ -1972,6 +2117,15 @@ static VImage thumbnail_buffer( VipsBlob *buffer, int width, VOption *options =
|
||||
*/
|
||||
VImage thumbnail_image( int width, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Generate thumbnail from source.
|
||||
* @param source Source to load from.
|
||||
* @param width Size to this width.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage thumbnail_source( VSource source, int width, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load tiff from file.
|
||||
* @param filename Filename to load from.
|
||||
@ -1988,6 +2142,14 @@ static VImage tiffload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage tiffload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load tiff from source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage tiffload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to tiff file.
|
||||
* @param filename Filename to save to.
|
||||
@ -2061,6 +2223,14 @@ static VImage webpload( const char *filename, VOption *options = 0 );
|
||||
*/
|
||||
static VImage webpload_buffer( VipsBlob *buffer, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Load webp from source.
|
||||
* @param source Source to load from.
|
||||
* @param options Optional options.
|
||||
* @return Output image.
|
||||
*/
|
||||
static VImage webpload_source( VSource source, VOption *options = 0 );
|
||||
|
||||
/**
|
||||
* Save image to webp file.
|
||||
* @param filename Filename to save to.
|
||||
@ -2075,6 +2245,13 @@ void webpsave( const char *filename, VOption *options = 0 ) const;
|
||||
*/
|
||||
VipsBlob *webpsave_buffer( VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Save image to webp target.
|
||||
* @param target Target to save to.
|
||||
* @param options Optional options.
|
||||
*/
|
||||
void webpsave_target( VTarget target, VOption *options = 0 ) const;
|
||||
|
||||
/**
|
||||
* Make a worley noise image.
|
||||
* @param width Image width in pixels.
|
||||
|
@ -52,5 +52,6 @@
|
||||
#include "VError8.h"
|
||||
#include "VImage8.h"
|
||||
#include "VInterpolate8.h"
|
||||
#include "VConnection8.h"
|
||||
|
||||
#endif /*VIPS_CPLUSPLUS*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
// bodies for vips operations
|
||||
// Wed Apr 24 15:50:21 CEST 2019
|
||||
// Thu 18 Jun 2020 01:19:31 PM CEST
|
||||
// this file is generated automatically, do not edit!
|
||||
|
||||
VImage VImage::CMC2LCh( VOption *options ) const
|
||||
@ -491,6 +491,19 @@ VImage VImage::canny( VOption *options ) const
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::case_image( std::vector<VImage> cases, VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "case",
|
||||
(options ? options : VImage::option())->
|
||||
set( "index", *this )->
|
||||
set( "out", &out )->
|
||||
set( "cases", cases ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::cast( VipsBandFormat format, VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
@ -741,6 +754,18 @@ VImage VImage::csvload( const char *filename, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::csvload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "csvload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::csvsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "csvsave",
|
||||
@ -749,6 +774,14 @@ void VImage::csvsave( const char *filename, VOption *options ) const
|
||||
set( "filename", filename ) );
|
||||
}
|
||||
|
||||
void VImage::csvsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "csvsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
VImage VImage::dE00( VImage right, VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
@ -1205,6 +1238,18 @@ VImage VImage::gifload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::gifload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "gifload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::globalbalance( VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
@ -1284,6 +1329,18 @@ VImage VImage::heifload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::heifload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "heifload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::heifsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "heifsave",
|
||||
@ -1304,6 +1361,14 @@ VipsBlob *VImage::heifsave_buffer( VOption *options ) const
|
||||
return( buffer );
|
||||
}
|
||||
|
||||
void VImage::heifsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "heifsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
VImage VImage::hist_cum( VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
@ -1615,6 +1680,18 @@ VImage VImage::jpegload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::jpegload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "jpegload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::jpegsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "jpegsave",
|
||||
@ -1642,6 +1719,14 @@ void VImage::jpegsave_mime( VOption *options ) const
|
||||
set( "in", *this ) );
|
||||
}
|
||||
|
||||
void VImage::jpegsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "jpegsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
VImage VImage::labelregions( VOption *options ) const
|
||||
{
|
||||
VImage mask;
|
||||
@ -1995,6 +2080,18 @@ VImage VImage::matload( const char *filename, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::matrixinvert( VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "matrixinvert",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "out", &out ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::matrixload( const char *filename, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
@ -2007,6 +2104,18 @@ VImage VImage::matrixload( const char *filename, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::matrixload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "matrixload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::matrixprint( VOption *options ) const
|
||||
{
|
||||
call( "matrixprint",
|
||||
@ -2022,6 +2131,14 @@ void VImage::matrixsave( const char *filename, VOption *options ) const
|
||||
set( "filename", filename ) );
|
||||
}
|
||||
|
||||
void VImage::matrixsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "matrixsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
double VImage::max( VOption *options ) const
|
||||
{
|
||||
double out;
|
||||
@ -2223,6 +2340,18 @@ VImage VImage::pdfload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::pdfload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "pdfload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
int VImage::percent( double percent, VOption *options ) const
|
||||
{
|
||||
int threshold;
|
||||
@ -2286,6 +2415,18 @@ VImage VImage::pngload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::pngload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "pngload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::pngsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "pngsave",
|
||||
@ -2306,6 +2447,14 @@ VipsBlob *VImage::pngsave_buffer( VOption *options ) const
|
||||
return( buffer );
|
||||
}
|
||||
|
||||
void VImage::pngsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "pngsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
VImage VImage::ppmload( const char *filename, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
@ -2413,6 +2562,30 @@ VImage VImage::radload( const char *filename, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::radload_buffer( VipsBlob *buffer, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "radload_buffer",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "buffer", buffer ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::radload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "radload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::radsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "radsave",
|
||||
@ -2433,6 +2606,14 @@ VipsBlob *VImage::radsave_buffer( VOption *options ) const
|
||||
return( buffer );
|
||||
}
|
||||
|
||||
void VImage::radsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "radsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
VImage VImage::rank( int width, int height, int index, VOption *options ) const
|
||||
{
|
||||
VImage out;
|
||||
@ -2977,6 +3158,30 @@ VImage VImage::svgload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::svgload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "svgload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::switch_image( std::vector<VImage> tests, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "switch",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "tests", tests ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::system( const char *cmd_format, VOption *options )
|
||||
{
|
||||
call( "system",
|
||||
@ -3035,6 +3240,19 @@ VImage VImage::thumbnail_image( int width, VOption *options ) const
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::thumbnail_source( VSource source, int width, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "thumbnail_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source )->
|
||||
set( "width", width ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::tiffload( const char *filename, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
@ -3059,6 +3277,18 @@ VImage VImage::tiffload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::tiffload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "tiffload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::tiffsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "tiffsave",
|
||||
@ -3170,6 +3400,18 @@ VImage VImage::webpload_buffer( VipsBlob *buffer, VOption *options )
|
||||
return( out );
|
||||
}
|
||||
|
||||
VImage VImage::webpload_source( VSource source, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
||||
call( "webpload_source",
|
||||
(options ? options : VImage::option())->
|
||||
set( "out", &out )->
|
||||
set( "source", source ) );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
void VImage::webpsave( const char *filename, VOption *options ) const
|
||||
{
|
||||
call( "webpsave",
|
||||
@ -3190,6 +3432,14 @@ VipsBlob *VImage::webpsave_buffer( VOption *options ) const
|
||||
return( buffer );
|
||||
}
|
||||
|
||||
void VImage::webpsave_target( VTarget target, VOption *options ) const
|
||||
{
|
||||
call( "webpsave_target",
|
||||
(options ? options : VImage::option())->
|
||||
set( "in", *this )->
|
||||
set( "target", target ) );
|
||||
}
|
||||
|
||||
VImage VImage::worley( int width, int height, VOption *options )
|
||||
{
|
||||
VImage out;
|
||||
|
@ -1,13 +1,13 @@
|
||||
<refmeta>
|
||||
<refentrytitle>Opening files</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>libvips</refmiscinfo>
|
||||
</refmeta>
|
||||
<refmeta>
|
||||
<refentrytitle>Opening files</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>libvips</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>Opening</refname>
|
||||
<refpurpose>How libvips opens files</refpurpose>
|
||||
</refnamediv>
|
||||
<refnamediv>
|
||||
<refname>Opening</refname>
|
||||
<refpurpose>How libvips opens files</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
libvips now has at least four different ways of opening image files, each
|
||||
best for different file types, file sizes and image use cases. libvips tries
|
||||
|
@ -16,7 +16,7 @@
|
||||
<para>
|
||||
This page tries to explain what the different strategies are and when each is used. If you are running into unexpected memory, disc or CPU use, this might be helpful. <literal>vips_image_new_from_file()</literal> has the official documentation.
|
||||
</para>
|
||||
<refsect3 id="direct-access">
|
||||
<section xml:id="direct-access">
|
||||
<title>Direct access</title>
|
||||
<para>
|
||||
This is the fastest and simplest one. The file is mapped directly into the process’s address space and can be read with ordinary pointer access. Small files are completely mapped; large files are mapped in a series of small windows that are shared and which scroll about as pixels are read. Files which are accessed like this can be read by many threads at once, making them especially quick. They also interact well with the computer’s operating system: your OS will use spare memory to cache recently used chunks of the file.
|
||||
@ -25,10 +25,10 @@
|
||||
For this to be possible, the file format needs to be a simple dump of a memory array. libvips supports direct access for vips, 8-bit binary ppm/pbm/pnm, analyse and raw.
|
||||
</para>
|
||||
<para>
|
||||
libvips has a special direct write mode where pixels can be written directly to the file image. This is used for the <ulink url="libvips-draw.html">draw operators</ulink>.
|
||||
libvips has a special direct write mode where pixels can be written directly to the file image. This is used for the <link xlink:href="libvips-draw.html">draw operators</link>.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="random-access-via-load-library">
|
||||
</section>
|
||||
<section xml:id="random-access-via-load-library">
|
||||
<title>Random access via load library</title>
|
||||
<para>
|
||||
Some image file formats have libraries which allow true random access to image pixels. For example, libtiff lets you read any tile out of a tiled tiff image very quickly. Because the libraries allow true random access, libvips can simply hook the image load library up to the input of the operation pipeline.
|
||||
@ -39,8 +39,8 @@
|
||||
<para>
|
||||
libvips can load tiled tiff, tiled OpenEXR, FITS and OpenSlide images in this manner.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="full-decompression">
|
||||
</section>
|
||||
<section xml:id="full-decompression">
|
||||
<title>Full decompression</title>
|
||||
<para>
|
||||
Many image load libraries do not support random access. In order to use images of this type as inputs to pipelines, libvips has to convert them to a random access format first.
|
||||
@ -54,8 +54,8 @@
|
||||
<para>
|
||||
This is the slowest and most memory-hungry way to read files, but it’s unavoidable for many file formats. Unless you can use the next one!
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="sequential-access">
|
||||
</section>
|
||||
<section xml:id="sequential-access">
|
||||
<title>Sequential access</title>
|
||||
<para>
|
||||
This a fairly recent addition to libvips and is a hybrid of the previous two.
|
||||
@ -90,7 +90,7 @@ $ vips shrink fred.png jim.png 10 10
|
||||
<para>
|
||||
This is done automatically in command-line operation. In programs, you need to set <literal>access</literal> to #VIPS_ACCESS_SEQUENTIAL in calls to functions like vips_image_new_from_file().
|
||||
</para>
|
||||
</refsect3>
|
||||
</section>
|
||||
|
||||
|
||||
</refentry>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<refmeta>
|
||||
<refentrytitle>Using `vipsthumbnail`</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>libvips</refmiscinfo>
|
||||
</refmeta>
|
||||
<refmeta>
|
||||
<refentrytitle>Using `vipsthumbnail`</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>libvips</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>`vipsthumbnail`</refname>
|
||||
<refpurpose>Introduction to `vipsthumbnail`, with examples</refpurpose>
|
||||
</refnamediv>
|
||||
<refnamediv>
|
||||
<refname>`vipsthumbnail`</refname>
|
||||
<refpurpose>Introduction to `vipsthumbnail`, with examples</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
libvips ships with a handy command-line image thumbnailer, `vipsthumbnail`.
|
||||
This page introduces it, with some examples.
|
||||
@ -267,15 +267,19 @@ $ ls -l tn_shark.jpg
|
||||
-rw-r–r– 1 john john 7295 Nov 9 14:33 tn_shark.jpg
|
||||
```
|
||||
|
||||
Now encode with sRGB and delete any embedded profile:
|
||||
Now transform to sRGB and don't attach a profile (you can also use `strip`,
|
||||
though that will remove *all* metadata from the image):
|
||||
|
||||
```
|
||||
$ vipsthumbnail shark.jpg --eprofile /usr/share/color/icc/sRGB.icc --delete
|
||||
$ vipsthumbnail shark.jpg --eprofile srgb -o tn_shark.jpg[profile=none]
|
||||
$ ls -l tn_shark.jpg
|
||||
-rw-r–r– 1 john john 4229 Nov 9 14:33 tn_shark.jpg
|
||||
```
|
||||
|
||||
It’ll look identical to a user, but be almost half the size.
|
||||
(You can use the filename of any RGB profile. The magic string `srgb` selects a
|
||||
high-quality sRGB profile that's built into libvips.)
|
||||
|
||||
`tn_shark.jpg` will look identical to a user, but it's almost half the size.
|
||||
|
||||
You can also specify a fallback input profile to use if the image has no
|
||||
embedded one. This can often happen with CMYK images, producing an error
|
||||
@ -291,23 +295,11 @@ If you supply a CMYK profile, it will be able to convert the image,
|
||||
for example:
|
||||
|
||||
```
|
||||
$ vipsthumbnail kgdev.jpg --iprofile /usr/share/color/icc/colord/FOGRA28L_webcoated.icc
|
||||
$ vipsthumbnail kgdev.jpg --iprofile cmyk
|
||||
```
|
||||
|
||||
I've had good results with this profile:
|
||||
|
||||
https://github.com/libvips/nip2/blob/master/share/nip2/data/cmyk.icm
|
||||
|
||||
It makes nice-looking images from most CMYK files, and is completely free.
|
||||
|
||||
# Auto-rotate
|
||||
|
||||
Many JPEG files have a hint set in the header giving the image orientation. If
|
||||
you strip out the metadata, this hint will be lost, and the image will appear
|
||||
to be rotated.
|
||||
|
||||
If you use the `--rotate` option, `vipsthumbnail` examines the image header and
|
||||
if there's an orientation tag, applies and removes it.
|
||||
(As before, the magic string `cmyk` selects a high-quality CMYK profile that's
|
||||
built into libvips, but you can use any CMYK profile you like.)
|
||||
|
||||
# Final suggestion
|
||||
|
||||
@ -316,7 +308,7 @@ Putting all this together, I suggest this as a sensible set of options:
|
||||
```
|
||||
$ vipsthumbnail fred.jpg \
|
||||
--size 128 \
|
||||
--eprofile srgb \
|
||||
-o tn_%s.jpg[optimize_coding,strip] \
|
||||
--eprofile /usr/share/color/icc/sRGB.icc \
|
||||
--rotate
|
||||
--eprofile srgb
|
||||
```
|
||||
|
@ -21,7 +21,7 @@ $filename = "image.jpg";
|
||||
$image = Vips\Image::thumbnail($filename, 200, ["height" => 200]);
|
||||
$image->writeToFile("my-thumbnail.jpg");
|
||||
</programlisting>
|
||||
<refsect3 id="libvips-options">
|
||||
<section xml:id="libvips-options">
|
||||
<title>libvips options</title>
|
||||
<para>
|
||||
<literal>vipsthumbnail</literal> supports the usual range of vips command-line options. A few of them are useful:
|
||||
@ -38,8 +38,8 @@ $image->writeToFile("my-thumbnail.jpg");
|
||||
<para>
|
||||
<literal>--vips-info</literal> shows a higher level view of the operations that <literal>vipsthumbnail</literal> is running.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="looping">
|
||||
</section>
|
||||
<section xml:id="looping">
|
||||
<title>Looping</title>
|
||||
<para>
|
||||
<literal>vipsthumbnail</literal> can process many images in one command. For example:
|
||||
@ -56,8 +56,8 @@ $ vipsthumbnail *.jpg
|
||||
<programlisting>
|
||||
$ parallel vipsthumbnail ::: *.jpg
|
||||
</programlisting>
|
||||
</refsect3>
|
||||
<refsect3 id="thumbnail-size">
|
||||
</section>
|
||||
<section xml:id="thumbnail-size">
|
||||
<title>Thumbnail size</title>
|
||||
<para>
|
||||
You can set the bounding box of the generated thumbnail with the <literal>--size</literal> option. For example:
|
||||
@ -80,8 +80,8 @@ $ vipsthumbnail shark.jpg --size 200x
|
||||
<para>
|
||||
You can append <literal>!</literal> to force a resize to the exact target size, breaking the aspect ratio.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="cropping">
|
||||
</section>
|
||||
<section xml:id="cropping">
|
||||
<title>Cropping</title>
|
||||
<para>
|
||||
<literal>vipsthumbnail</literal> normally shrinks images to fit within the box set by <literal>--size</literal>. You can use the <literal>--smartcrop</literal> option to crop to fill the box instead. Excess pixels are trimmed away using the strategy you set. For example:
|
||||
@ -92,30 +92,28 @@ $ vipsthumbnail owl.jpg --smartcrop attention -s 128
|
||||
<para>
|
||||
Where <literal>owl.jpg</literal> is an off-centre composition:
|
||||
</para>
|
||||
<figure>
|
||||
<mediaobject>
|
||||
<para>
|
||||
<inlinemediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="owl.jpg" />
|
||||
</imageobject>
|
||||
<textobject><phrase></phrase></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
</inlinemediaobject>
|
||||
</para>
|
||||
<para>
|
||||
Gives this result:
|
||||
</para>
|
||||
<figure>
|
||||
<mediaobject>
|
||||
<para>
|
||||
<inlinemediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="tn_owl.jpg" />
|
||||
</imageobject>
|
||||
<textobject><phrase></phrase></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
</inlinemediaobject>
|
||||
</para>
|
||||
<para>
|
||||
First it shrinks the image to get the vertical axis to 128 pixels, then crops down to 128 pixels across using the <literal>attention</literal> strategy. This one searches the image for features which might catch a human eye, see <literal>vips_smartcrop()</literal> for details.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="linear-light">
|
||||
</section>
|
||||
<section xml:id="linear-light">
|
||||
<title>Linear light</title>
|
||||
<para>
|
||||
Shrinking images involves combining many pixels into one. Arithmetic averaging really ought to be in terms of the number of photons, but (for historical reasons) the values stored in image files are usually related to the voltage that should be applied to the electron gun in a CRT display.
|
||||
@ -142,8 +140,8 @@ real 0m4.660s
|
||||
user 0m4.640s
|
||||
sys 0m0.016s
|
||||
</programlisting>
|
||||
</refsect3>
|
||||
<refsect3 id="output-directory">
|
||||
</section>
|
||||
<section xml:id="output-directory">
|
||||
<title>Output directory</title>
|
||||
<para>
|
||||
You set the thumbnail write parameters with the <literal>-o</literal> option. This is a pattern which the input filename is pasted into to produce the output filename. For example:
|
||||
@ -172,8 +170,8 @@ $ vipsthumbnail fred.jpg ../jim.tif -o mythumbs/tn_%s.jpg
|
||||
<para>
|
||||
Now both input files will have thumbnails written to a subdirectory of their current directory.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="output-format-and-options">
|
||||
</section>
|
||||
<section xml:id="output-format-and-options">
|
||||
<title>Output format and options</title>
|
||||
<para>
|
||||
You can use <literal>-o</literal> to specify the thumbnail image format too. For example:
|
||||
@ -247,8 +245,8 @@ $ vipsthumbnail 42-32157534.jpg -o x.jpg[optimize_coding,strip]
|
||||
$ ls -l x.jpg
|
||||
-rw-r–r– 1 john john 3600 Nov 12 21:27 x.jpg
|
||||
</programlisting>
|
||||
</refsect3>
|
||||
<refsect3 id="colour-management">
|
||||
</section>
|
||||
<section xml:id="colour-management">
|
||||
<title>Colour management</title>
|
||||
<para>
|
||||
<literal>vipsthumbnail</literal> will optionally put images through LittleCMS for you. You can use this to move all thumbnails to the same colour space. All web browsers assume that images without an ICC profile are in sRGB colourspace, so if you move your thumbnails to sRGB, you can strip all the embedded profiles. This can save several kb per thumbnail.
|
||||
@ -262,15 +260,18 @@ $ ls -l tn_shark.jpg
|
||||
-rw-r–r– 1 john john 7295 Nov 9 14:33 tn_shark.jpg
|
||||
</programlisting>
|
||||
<para>
|
||||
Now encode with sRGB and delete any embedded profile:
|
||||
Now transform to sRGB and don’t attach a profile (you can also use <literal>strip</literal>, though that will remove <emphasis>all</emphasis> metadata from the image):
|
||||
</para>
|
||||
<programlisting>
|
||||
$ vipsthumbnail shark.jpg --eprofile /usr/share/color/icc/sRGB.icc --delete
|
||||
$ vipsthumbnail shark.jpg --eprofile srgb -o tn_shark.jpg[profile=none]
|
||||
$ ls -l tn_shark.jpg
|
||||
-rw-r–r– 1 john john 4229 Nov 9 14:33 tn_shark.jpg
|
||||
</programlisting>
|
||||
<para>
|
||||
It’ll look identical to a user, but be almost half the size.
|
||||
(You can use the filename of any RGB profile. The magic string <literal>srgb</literal> selects a high-quality sRGB profile that’s built into libvips.)
|
||||
</para>
|
||||
<para>
|
||||
<literal>tn_shark.jpg</literal> will look identical to a user, but it’s almost half the size.
|
||||
</para>
|
||||
<para>
|
||||
You can also specify a fallback input profile to use if the image has no embedded one. This can often happen with CMYK images, producing an error message like:
|
||||
@ -284,28 +285,13 @@ vips_colourspace: no known route from 'cmyk' to 'srgb'
|
||||
If you supply a CMYK profile, it will be able to convert the image, for example:
|
||||
</para>
|
||||
<programlisting>
|
||||
$ vipsthumbnail kgdev.jpg --iprofile /usr/share/color/icc/colord/FOGRA28L_webcoated.icc
|
||||
$ vipsthumbnail kgdev.jpg --iprofile cmyk
|
||||
</programlisting>
|
||||
<para>
|
||||
I’ve had good results with this profile:
|
||||
(As before, the magic string <literal>cmyk</literal> selects a high-quality CMYK profile that’s built into libvips, but you can use any CMYK profile you like.)
|
||||
</para>
|
||||
<para>
|
||||
https://github.com/libvips/nip2/blob/master/share/nip2/data/cmyk.icm
|
||||
</para>
|
||||
<para>
|
||||
It makes nice-looking images from most CMYK files, and is completely free.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="auto-rotate">
|
||||
<title>Auto-rotate</title>
|
||||
<para>
|
||||
Many JPEG files have a hint set in the header giving the image orientation. If you strip out the metadata, this hint will be lost, and the image will appear to be rotated.
|
||||
</para>
|
||||
<para>
|
||||
If you use the <literal>--rotate</literal> option, <literal>vipsthumbnail</literal> examines the image header and if there’s an orientation tag, applies and removes it.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="final-suggestion">
|
||||
</section>
|
||||
<section xml:id="final-suggestion">
|
||||
<title>Final suggestion</title>
|
||||
<para>
|
||||
Putting all this together, I suggest this as a sensible set of options:
|
||||
@ -313,11 +299,11 @@ $ vipsthumbnail kgdev.jpg --iprofile /usr/share/color/icc/colord/FOGRA28L_webcoa
|
||||
<programlisting>
|
||||
$ vipsthumbnail fred.jpg \
|
||||
--size 128 \
|
||||
--eprofile srgb \
|
||||
-o tn_%s.jpg[optimize_coding,strip] \
|
||||
--eprofile /usr/share/color/icc/sRGB.icc \
|
||||
--rotate
|
||||
--eprofile srgb
|
||||
</programlisting>
|
||||
</refsect3>
|
||||
</section>
|
||||
|
||||
|
||||
</refentry>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<refmeta>
|
||||
<refentrytitle>How to write bindings</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>libvips</refmiscinfo>
|
||||
</refmeta>
|
||||
<refmeta>
|
||||
<refentrytitle>How to write bindings</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
<refmiscinfo>libvips</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>Binding</refname>
|
||||
<refpurpose>Writing bindings for libvips</refpurpose>
|
||||
</refnamediv>
|
||||
<refnamediv>
|
||||
<refname>Binding</refname>
|
||||
<refpurpose>Writing bindings for libvips</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
There are full libvips bindings for quite a few environments now: C, C++,
|
||||
command-line, Ruby, PHP, Lua, Python and JavaScript (node).
|
||||
@ -80,7 +80,7 @@ main( int argc, char **argv )
|
||||
|
||||
/* Call the operation. This will look up the operation+args in the vips
|
||||
* operation cache and either return a previous operation, or build
|
||||
* this one. In either case, we have a new ref we mst release.
|
||||
* this one. In either case, we have a new ref we must release.
|
||||
*/
|
||||
if( !(new_op = vips_cache_operation_build( op )) ) {
|
||||
g_object_unref( op );
|
||||
@ -114,7 +114,7 @@ main( int argc, char **argv )
|
||||
```
|
||||
|
||||
libvips has a couple of extra things to let you examine the arguments and
|
||||
types of an operator at runtime. Use vips_lib.vips_argument_map() to loop
|
||||
types of an operator at runtime. Use vips_argument_map() to loop
|
||||
over all the arguments of an operator, and vips_object_get_argument()
|
||||
to fetch the type and flags of a specific argument.
|
||||
|
||||
@ -151,7 +151,7 @@ operator overloads, and various other useful features.
|
||||
|
||||
# Dynamic language with FFI
|
||||
|
||||
Languages like Ruby, Python, JavaScript and Lua can't call C directly, but
|
||||
Languages like Ruby, Python, JavaScript and LuaJIT can't call C directly, but
|
||||
they do support FFI. The bindings for these languages work rather like C++,
|
||||
but use FFI to call into libvips and run operations.
|
||||
|
||||
@ -216,4 +216,4 @@ $ yelp-build html .
|
||||
```
|
||||
|
||||
To make HTML docs. This is an easy way to see what you can call in the
|
||||
library.
|
||||
library.
|
||||
|
@ -16,7 +16,7 @@
|
||||
<para>
|
||||
This chapter runs through the four main styles that have been found to work well. If you want to write a new binding, one of these should be close to what you need.
|
||||
</para>
|
||||
<refsect3 id="dont-bind-the-top-level-c-api">
|
||||
<section xml:id="dont-bind-the-top-level-c-api">
|
||||
<title>Don’t bind the top-level C API</title>
|
||||
<para>
|
||||
The libvips C API (vips_add() and so on) is very inconvenient and dangerous to use from other languages due to its heavy use of varargs.
|
||||
@ -79,7 +79,7 @@ main( int argc, char **argv )
|
||||
|
||||
/* Call the operation. This will look up the operation+args in the vips
|
||||
* operation cache and either return a previous operation, or build
|
||||
* this one. In either case, we have a new ref we mst release.
|
||||
* this one. In either case, we have a new ref we must release.
|
||||
*/
|
||||
if( !(new_op = vips_cache_operation_build( op )) ) {
|
||||
g_object_unref( op );
|
||||
@ -112,13 +112,13 @@ main( int argc, char **argv )
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
libvips has a couple of extra things to let you examine the arguments and types of an operator at runtime. Use vips_lib.vips_argument_map() to loop over all the arguments of an operator, and vips_object_get_argument() to fetch the type and flags of a specific argument.
|
||||
libvips has a couple of extra things to let you examine the arguments and types of an operator at runtime. Use vips_argument_map() to loop over all the arguments of an operator, and vips_object_get_argument() to fetch the type and flags of a specific argument.
|
||||
</para>
|
||||
<para>
|
||||
Use vips_operation_get_flags() to get general information about an operator.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="compiled-language-which-can-call-c">
|
||||
</section>
|
||||
<section xml:id="compiled-language-which-can-call-c">
|
||||
<title>Compiled language which can call C</title>
|
||||
<para>
|
||||
The C++ binding uses this lower layer to define a function called <literal>VImage::call()</literal> which can call any libvips operator with a not-varargs set of variable arguments.
|
||||
@ -144,23 +144,23 @@ VImage VImage::invert( VOption *options )
|
||||
<para>
|
||||
The <literal>VImage</literal> class also adds automatic reference counting, constant expansion, operator overloads, and various other useful features.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="dynamic-language-with-ffi">
|
||||
</section>
|
||||
<section xml:id="dynamic-language-with-ffi">
|
||||
<title>Dynamic language with FFI</title>
|
||||
<para>
|
||||
Languages like Ruby, Python, JavaScript and Lua can’t call C directly, but they do support FFI. The bindings for these languages work rather like C++, but use FFI to call into libvips and run operations.
|
||||
Languages like Ruby, Python, JavaScript and LuaJIT can’t call C directly, but they do support FFI. The bindings for these languages work rather like C++, but use FFI to call into libvips and run operations.
|
||||
</para>
|
||||
<para>
|
||||
Since these languages are dynamic, they can add another trick: they intercept the method-missing hook and attempt to run any method calls not implemented by the <literal>Image</literal> class as libvips operators. This makes these bindings self-writing: they only contain a small amount of code and just expose everything they find in the libvips class hierarchy.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="dynamic-langauge-without-ffi">
|
||||
</section>
|
||||
<section xml:id="dynamic-langauge-without-ffi">
|
||||
<title>Dynamic langauge without FFI</title>
|
||||
<para>
|
||||
PHP does not have FFI, unfortunately, so for this language a small native module implements the general <literal>vips_call()</literal> function for PHP language types, and a larger pure PHP layer makes it convenient to use.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="gobject-introspection">
|
||||
</section>
|
||||
<section xml:id="gobject-introspection">
|
||||
<title>gobject-introspection</title>
|
||||
<para>
|
||||
The C source code to libvips has been marked up with special comments describing the interface in a standard way. These comments are read by the <literal>gobject-introspection</literal> package when libvips is compiled and used to generate a typelib, a description of how to call the library. Many languages have gobject-introspection packages: all you need to do to call libvips from your favorite language is to start g-o-i, load the libvips typelib, and you should have the whole library available. For example, from Python it’s as simple as:
|
||||
@ -177,8 +177,8 @@ from gi.repository import Vips
|
||||
<para>
|
||||
If you have a choice, I would recommend simply using FFI.
|
||||
</para>
|
||||
</refsect3>
|
||||
<refsect3 id="documentation">
|
||||
</section>
|
||||
<section xml:id="documentation">
|
||||
<title>Documentation</title>
|
||||
<para>
|
||||
You can generate searchable docs from a <code>.gir</code> (the thing that is built from scanning libvips and which in turn turn the typelib is made from) with <command>g-ir-doc-tool</command>, for example:
|
||||
@ -202,7 +202,7 @@ $ yelp-build html .
|
||||
<para>
|
||||
To make HTML docs. This is an easy way to see what you can call in the library.
|
||||
</para>
|
||||
</refsect3>
|
||||
</section>
|
||||
|
||||
|
||||
</refentry>
|
||||
|
68
doc/gen-function-list.py
Executable file → Normal file
@ -15,21 +15,28 @@
|
||||
# <entry>vips_gamma()</entry>
|
||||
# </row>
|
||||
|
||||
from pyvips import Operation, Error, \
|
||||
from pyvips import Introspect, Operation, Error, \
|
||||
ffi, type_map, type_from_name, nickname_find
|
||||
|
||||
# for VipsOperationFlags
|
||||
_OPERATION_DEPRECATED = 8
|
||||
|
||||
|
||||
def gen_function(operation_name):
|
||||
op = Operation.new_from_name(operation_name)
|
||||
def gen_function(operation_name, overloads):
|
||||
intro = Introspect.get(operation_name)
|
||||
|
||||
print('<row>')
|
||||
print(' <entry>{}</entry>'.format(operation_name))
|
||||
print(' <entry>{}</entry>'.format(op.get_description().capitalize()))
|
||||
print(' <entry>vips_{}()</entry>'.format(operation_name))
|
||||
print('</row>')
|
||||
c_operations = 'vips_{}()'.format(operation_name)
|
||||
|
||||
if overloads:
|
||||
c_operations += ', ' + (', '.join('vips_{}()'.format(n) for n in overloads))
|
||||
|
||||
result = '<row>\n'
|
||||
result += ' <entry>{}</entry>\n'.format(operation_name)
|
||||
result += ' <entry>{}</entry>\n'.format(intro.description.capitalize())
|
||||
result += ' <entry>{}</entry>\n'.format(c_operations)
|
||||
result += '</row>'
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def gen_function_list():
|
||||
@ -39,10 +46,10 @@ def gen_function_list():
|
||||
nickname = nickname_find(gtype)
|
||||
try:
|
||||
# can fail for abstract types
|
||||
op = Operation.new_from_name(nickname)
|
||||
intro = Introspect.get(nickname)
|
||||
|
||||
# we are only interested in non-deprecated operations
|
||||
if (op.get_flags() & _OPERATION_DEPRECATED) == 0:
|
||||
if (intro.flags & _OPERATION_DEPRECATED) == 0:
|
||||
all_nicknames.append(nickname)
|
||||
except Error:
|
||||
pass
|
||||
@ -53,15 +60,48 @@ def gen_function_list():
|
||||
|
||||
type_map(type_from_name('VipsOperation'), add_nickname)
|
||||
|
||||
# add 'missing' synonyms by hand
|
||||
all_nicknames.append('crop')
|
||||
|
||||
# make list unique and sort
|
||||
all_nicknames = list(set(all_nicknames))
|
||||
all_nicknames.sort()
|
||||
|
||||
# make dict with overloads
|
||||
overloads = {
|
||||
'bandbool': ['bandand', 'bandor', 'bandeor', 'bandmean'],
|
||||
'bandjoin': ['bandjoin2'],
|
||||
'bandjoin_const': ['bandjoin_const1'],
|
||||
'boolean': ['andimage', 'orimage', 'eorimage', 'lshift', 'rshift'],
|
||||
'cast': ['cast_uchar', 'cast_char', 'cast_ushort', 'cast_short' 'cast_uint', 'cast_int', 'cast_float',
|
||||
'cast_double', 'cast_complex', 'cast_dpcomplex'],
|
||||
'complex': ['polar', 'rect', 'conj'],
|
||||
'complex2': ['cross_phase'],
|
||||
'complexget': ['real', 'imag'],
|
||||
'draw_circle': ['draw_circle1'],
|
||||
'draw_flood': ['draw_flood1'],
|
||||
'draw_line': ['draw_line1'],
|
||||
'draw_mask': ['draw_mask1'],
|
||||
'draw_rect': ['draw_rect1', 'draw_point', 'draw_point1'],
|
||||
'extract_area': ['crop'],
|
||||
'linear': ['linear1'],
|
||||
'math': ['sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'exp', 'exp10', 'log', 'log10'],
|
||||
'math2': ['pow', 'wop'],
|
||||
'rank': ['median'],
|
||||
'relational': ['equal', 'notequal', 'less', 'lesseq', 'more', 'moreeq'],
|
||||
'remainder_const': ['remainder_const1'],
|
||||
'round': ['floor', 'ceil', 'rint'],
|
||||
}
|
||||
|
||||
overloads['boolean_const'] = [o + '_const' for o in overloads['boolean']] + ['boolean_const1'] + \
|
||||
[o + '_const1' for o in overloads['boolean']]
|
||||
|
||||
overloads['math2_const'] = [o + '_const' for o in overloads['boolean']] + ['math2_const1'] + \
|
||||
[o + '_const1' for o in overloads['boolean']]
|
||||
|
||||
overloads['relational_const'] = [o + '_const' for o in overloads['relational']] + ['relational_const1'] + \
|
||||
[o + '_const1' for o in overloads['relational']]
|
||||
|
||||
for nickname in all_nicknames:
|
||||
gen_function(nickname)
|
||||
result = gen_function(nickname, overloads[nickname] if nickname in overloads else None)
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -61,6 +61,8 @@
|
||||
<xi:include href="xml/object.xml"/>
|
||||
<xi:include href="xml/threadpool.xml"/>
|
||||
<xi:include href="xml/buf.xml"/>
|
||||
<xi:include href="xml/connection.xml"/>
|
||||
<xi:include href="xml/sbuf.xml"/>
|
||||
<xi:include href="xml/basic.xml"/>
|
||||
</chapter>
|
||||
|
||||
|
@ -25,4 +25,6 @@ libstandaloneengine_a_SOURCES = StandaloneFuzzTargetMain.c
|
||||
check_PROGRAMS = $(FUZZPROGS)
|
||||
noinst_LIBRARIES = $(FUZZLIBS)
|
||||
|
||||
EXTRA_DIST = $(TESTS)
|
||||
EXTRA_DIST = \
|
||||
$(TESTS) \
|
||||
common_fuzzer_corpus
|
||||
|
Before Width: | Height: | Size: 44 B After Width: | Height: | Size: 44 B |
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 71 B After Width: | Height: | Size: 71 B |
Before Width: | Height: | Size: 166 B After Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 97 B |
@ -1,15 +0,0 @@
|
||||
P2
|
||||
#vips2ppm - Fri Aug 23 12:48:07 2019
|
||||
|
||||
10 10
|
||||
255
|
||||
96 101 113 118 124 130 136 141 147 150
|
||||
81 87 98 101 107 112 117 123 130 135
|
||||
73 78 85 90 95 99 103 110 118 124
|
||||
46 51 60 67 73 81 87 94 103 109
|
||||
34 35 40 48 60 69 77 81 85 88
|
||||
28 26 31 36 45 54 59 64 69 72
|
||||
32 31 41 39 39 40 45 52 61 66
|
||||
38 38 47 42 38 36 38 43 49 53
|
||||
37 38 39 39 37 37 37 36 34 32
|
||||
36 36 38 36 35 34 35 32 28 25
|
@ -1,10 +0,0 @@
|
||||
96 101 113 118 124 130 136 141 147 150
|
||||
81 87 98 101 107 112 117 123 130 135
|
||||
73 78 85 90 95 99 103 110 118 124
|
||||
46 51 60 67 73 81 87 94 103 109
|
||||
34 35 40 48 60 69 77 81 85 88
|
||||
28 26 31 36 45 54 59 64 69 72
|
||||
32 31 41 39 39 40 45 52 61 66
|
||||
38 38 47 42 38 36 38 43 49 53
|
||||
37 38 39 39 37 37 37 36 34 32
|
||||
36 36 38 36 35 34 35 32 28 25
|
|
@ -1,11 +0,0 @@
|
||||
10 10
|
||||
96 101 113 118 124 130 136 141 147 150
|
||||
81 87 98 101 107 112 117 123 130 135
|
||||
73 78 85 90 95 99 103 110 118 124
|
||||
46 51 60 67 73 81 87 94 103 109
|
||||
34 35 40 48 60 69 77 81 85 88
|
||||
28 26 31 36 45 54 59 64 69 72
|
||||
32 31 41 39 39 40 45 52 61 66
|
||||
38 38 47 42 38 36 38 43 49 53
|
||||
37 38 39 39 37 37 37 36 34 32
|
||||
36 36 38 36 35 34 35 32 28 25
|
@ -1,6 +0,0 @@
|
||||
P5
|
||||
#vips2ppm - Fri Aug 23 12:47:38 2019
|
||||
|
||||
10 10
|
||||
255
|
||||
`eqv|‚ˆ<E2809A>“–QWbekpu{‚‡INUZ_cgnv|.3<CIQW^gm"#(0<EMQUX$-6;@EH )''(-4=B&&/*&$&+15%&''%%%$" $$&$#"#
|
@ -1,6 +0,0 @@
|
||||
P6
|
||||
#vips2ppm - Fri Aug 23 12:47:50 2019
|
||||
|
||||
10 10
|
||||
255
|
||||
g[ilaoxm{{s€<73>yˆ†<E280A0>Œ…—<E280A6>‹œ•<C593>¤˜”¥\K[`Rai]klaophwtm}yr„wŒ„•‰…–TBRYHX^P_aUcf[kh_plcvrjzr‰€y‹:(6=-:E7DJ>LQDUWL]\SfcZolbzri|.(/)3#.9+8E7FM@QSHYVM`ZQf]Tg' %*$- *6(5=1?C6HG;OL@VOCW,!)!3$+2",0#-1#05(9</AE8LJ=Q1"%/#%7+/3&-/"+- */!04&7:+>>/B.""/##0$&/#'.!(.!*. --.+.)-," ,"!/##-!#,&+'-*+*'(#%
|
@ -17,11 +17,9 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -19,11 +19,9 @@ test_one_file( const char *name )
|
||||
NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -22,17 +22,15 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
struct mosaic_opt *opt;
|
||||
double d;
|
||||
|
||||
if( size < sizeof(struct mosaic_opt) )
|
||||
if( size < sizeof( struct mosaic_opt ) )
|
||||
return( 0 );
|
||||
|
||||
if( !(ref = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( ref->Xsize > 1024 ||
|
||||
ref->Ysize > 1024 ||
|
||||
ref->Bands > 10 ) {
|
||||
if( ref->Xsize > 100 ||
|
||||
ref->Ysize > 100 ||
|
||||
ref->Bands > 4 ) {
|
||||
g_object_unref( ref );
|
||||
return( 0 );
|
||||
}
|
||||
@ -44,10 +42,10 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
|
||||
/* Extract some bytes from the tail to fuzz the arguments of the API.
|
||||
*/
|
||||
opt = (struct mosaic_opt *) (data + size - sizeof(struct mosaic_opt));
|
||||
opt = (struct mosaic_opt *) (data + size - sizeof( struct mosaic_opt ));
|
||||
|
||||
if( vips_mosaic( ref, sec, &out, (VipsDirection) opt->dir,
|
||||
opt->xref, opt->yref, opt->xsec, opt->ysec, NULL ) ) {
|
||||
opt->xref, opt->yref, opt->xsec, opt->ysec, NULL ) ) {
|
||||
g_object_unref( sec );
|
||||
g_object_unref( ref );
|
||||
return( 0 );
|
||||
|
@ -17,11 +17,9 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -16,11 +16,9 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -16,11 +16,9 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#set -x
|
||||
set -e
|
||||
|
||||
# Glib is build without -fno-omit-frame-pointer. We need
|
||||
# Glib is built without -fno-omit-frame-pointer. We need
|
||||
# to disable the fast unwinder to get full stacktraces.
|
||||
export ASAN_OPTIONS="fast_unwind_on_malloc=0:allocator_may_return_null=1"
|
||||
export UBSAN_OPTIONS="print_stacktrace=1"
|
||||
@ -14,8 +14,12 @@ export VIPS_WARNING=0
|
||||
ret=0
|
||||
|
||||
for fuzzer in *_fuzzer; do
|
||||
find "common_fuzzer_corpus" -type f -not -empty -print0 \
|
||||
| xargs -0 -n1 "./$fuzzer" || ret=1
|
||||
for file in common_fuzzer_corpus/*; do
|
||||
if ! ./$fuzzer $file; then
|
||||
echo FAIL $fuzzer $file
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
exit $ret
|
||||
|
@ -16,11 +16,9 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -17,11 +17,9 @@ LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
return( 0 );
|
||||
|
||||
/* Skip big images. They are likely to timeout.
|
||||
*/
|
||||
if( image->Xsize > 1024 ||
|
||||
image->Ysize > 1024 ||
|
||||
image->Bands > 10 ) {
|
||||
if( image->Xsize > 100 ||
|
||||
image->Ysize > 100 ||
|
||||
image->Bands > 4 ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
OPTIONAL_COMPILE_DIR =
|
||||
OPTIONAL_COMPILE_DIR =
|
||||
OPTIONAL_DIST_DIR =
|
||||
OPTIONAL_LIB =
|
||||
OPTIONAL_LIB =
|
||||
|
||||
if ENABLE_DEPRECATED
|
||||
OPTIONAL_COMPILE_DIR += deprecated
|
||||
@ -24,8 +24,7 @@ SUBDIRS = \
|
||||
iofuncs \
|
||||
morphology \
|
||||
mosaicing \
|
||||
create
|
||||
.
|
||||
create
|
||||
|
||||
lib_LTLIBRARIES = libvips.la
|
||||
|
||||
@ -87,7 +86,7 @@ AM_LDFLAGS = \
|
||||
LDADD = @INTROSPECTION_LIBS@ @VIPS_CFLAGS@ libvips.la @VIPS_LIBS@
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
introspect
|
||||
introspect$(EXEEXT)
|
||||
introspect_SOURCES = \
|
||||
introspect.c
|
||||
|
||||
@ -96,7 +95,7 @@ introspect_SOURCES = \
|
||||
introspection_sources = @vips_introspection_sources@
|
||||
|
||||
# we make the vips8 API
|
||||
Vips-8.0.gir: introspect
|
||||
Vips-8.0.gir: introspect$(EXEEXT)
|
||||
Vips_8_0_gir_INCLUDES = GObject-2.0
|
||||
Vips_8_0_gir_CFLAGS = $(INCLUDES) -I${top_srcdir}/libvips/include
|
||||
Vips_8_0_gir_LIBS = libvips.la
|
||||
|
@ -261,7 +261,7 @@ vips_add_init( VipsAdd *add )
|
||||
* range of possible values.
|
||||
*
|
||||
* Operations on integer images are performed using the processor's vector unit,
|
||||
* if possible. Disable this with --vips-novector or IM_NOVECTOR.
|
||||
* if possible. Disable this with --vips-novector or VIPS_NOVECTOR.
|
||||
*
|
||||
* See also: vips_subtract(), vips_linear().
|
||||
*
|
||||
|
@ -562,7 +562,7 @@ vips_boolean_const_init( VipsBooleanConst *boolean_const )
|
||||
|
||||
static int
|
||||
vips_boolean_constv( VipsImage *in, VipsImage **out,
|
||||
VipsOperationBoolean operation, double *c, int n, va_list ap )
|
||||
VipsOperationBoolean operation, const double *c, int n, va_list ap )
|
||||
{
|
||||
VipsArea *area_c;
|
||||
double *array;
|
||||
@ -609,7 +609,7 @@ vips_boolean_constv( VipsImage *in, VipsImage **out,
|
||||
*/
|
||||
int
|
||||
vips_boolean_const( VipsImage *in, VipsImage **out,
|
||||
VipsOperationBoolean boolean, double *c, int n, ... )
|
||||
VipsOperationBoolean boolean, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -637,7 +637,8 @@ vips_boolean_const( VipsImage *in, VipsImage **out,
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_andimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_andimage_const( VipsImage *in, VipsImage **out,
|
||||
const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -666,7 +667,8 @@ vips_andimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_orimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_orimage_const( VipsImage *in, VipsImage **out,
|
||||
const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -695,7 +697,8 @@ vips_orimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_eorimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_eorimage_const( VipsImage *in, VipsImage **out,
|
||||
const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -724,7 +727,7 @@ vips_eorimage_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_lshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_lshift_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -753,7 +756,7 @@ vips_lshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_rshift_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_rshift_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
@ -150,11 +150,12 @@ vips_hough_circle_vote_endpoints_clip( VipsImage *image,
|
||||
int y, int x1, int x2, int quadrant, void *client )
|
||||
{
|
||||
int r = *((int *) client);
|
||||
guint *line = (guint *) VIPS_IMAGE_ADDR( image, 0, y ) + r;
|
||||
int b = image->Bands;
|
||||
|
||||
if( y >= 0 &&
|
||||
y < image->Ysize ) {
|
||||
guint *line = (guint *) VIPS_IMAGE_ADDR( image, 0, y ) + r;
|
||||
|
||||
if( x1 >=0 &&
|
||||
x1 < image->Xsize )
|
||||
line[x1 * b] += 1;
|
||||
@ -278,6 +279,9 @@ vips_hough_circle_init( VipsHoughCircle *hough_circle )
|
||||
* votes by circle circumference so circles of differing size are given equal
|
||||
* weight.
|
||||
*
|
||||
* The output pixel at (x, y, band) is the strength of the circle centred on
|
||||
* (x, y) and with radius (band).
|
||||
*
|
||||
* Use @max_radius and @min_radius to set the range of radii to search for.
|
||||
*
|
||||
* Use @scale to set how @in coordinates are scaled to @out coordinates. A
|
||||
|
@ -453,7 +453,7 @@ vips_linear_init( VipsLinear *linear )
|
||||
|
||||
static int
|
||||
vips_linearv( VipsImage *in, VipsImage **out,
|
||||
double *a, double *b, int n, va_list ap )
|
||||
const double *a, const double *b, int n, va_list ap )
|
||||
{
|
||||
VipsArea *area_a;
|
||||
VipsArea *area_b;
|
||||
@ -500,7 +500,8 @@ vips_linearv( VipsImage *in, VipsImage **out,
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_linear( VipsImage *in, VipsImage **out, double *a, double *b, int n, ... )
|
||||
vips_linear( VipsImage *in, VipsImage **out,
|
||||
const double *a, const double *b, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
@ -420,7 +420,7 @@ vips_math2_const_init( VipsMath2Const *math2_const )
|
||||
|
||||
static int
|
||||
vips_math2_constv( VipsImage *in, VipsImage **out,
|
||||
VipsOperationMath2 math2, double *c, int n, va_list ap )
|
||||
VipsOperationMath2 math2, const double *c, int n, va_list ap )
|
||||
{
|
||||
VipsArea *area_c;
|
||||
double *array;
|
||||
@ -470,7 +470,7 @@ vips_math2_constv( VipsImage *in, VipsImage **out,
|
||||
*/
|
||||
int
|
||||
vips_math2_const( VipsImage *in, VipsImage **out,
|
||||
VipsOperationMath2 math2, double *c, int n, ... )
|
||||
VipsOperationMath2 math2, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -496,7 +496,7 @@ vips_math2_const( VipsImage *in, VipsImage **out,
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_pow_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_pow_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -523,7 +523,7 @@ vips_pow_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_wop_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_wop_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
@ -598,7 +598,7 @@ vips_relational_const_init( VipsRelationalConst *relational_const )
|
||||
|
||||
static int
|
||||
vips_relational_constv( VipsImage *in, VipsImage **out,
|
||||
VipsOperationRelational relational, double *c, int n, va_list ap )
|
||||
VipsOperationRelational relational, const double *c, int n, va_list ap )
|
||||
{
|
||||
VipsArea *area_c;
|
||||
double *array;
|
||||
@ -645,7 +645,7 @@ vips_relational_constv( VipsImage *in, VipsImage **out,
|
||||
*/
|
||||
int
|
||||
vips_relational_const( VipsImage *in, VipsImage **out,
|
||||
VipsOperationRelational relational, double *c, int n, ... )
|
||||
VipsOperationRelational relational, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -671,7 +671,7 @@ vips_relational_const( VipsImage *in, VipsImage **out,
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_equal_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_equal_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -698,7 +698,8 @@ vips_equal_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_notequal_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_notequal_const( VipsImage *in, VipsImage **out,
|
||||
const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -725,7 +726,7 @@ vips_notequal_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_less_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_less_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -752,7 +753,7 @@ vips_less_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_lesseq_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_lesseq_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -779,7 +780,7 @@ vips_lesseq_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_more_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_more_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
@ -806,7 +807,7 @@ vips_more_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_moreeq_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_moreeq_const( VipsImage *in, VipsImage **out, const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
@ -333,7 +333,7 @@ vips_remainder_const_init( VipsRemainderConst *remainder_const )
|
||||
|
||||
static int
|
||||
vips_remainder_constv( VipsImage *in, VipsImage **out,
|
||||
double *c, int n, va_list ap )
|
||||
const double *c, int n, va_list ap )
|
||||
{
|
||||
VipsArea *area_c;
|
||||
double *array;
|
||||
@ -379,7 +379,8 @@ vips_remainder_constv( VipsImage *in, VipsImage **out,
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
vips_remainder_const( VipsImage *in, VipsImage **out, double *c, int n, ... )
|
||||
vips_remainder_const( VipsImage *in, VipsImage **out,
|
||||
const double *c, int n, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
noinst_LTLIBRARIES = libcolour.la
|
||||
|
||||
SUBDIRS = profiles
|
||||
|
||||
libcolour_la_SOURCES = \
|
||||
profiles.c \
|
||||
profiles.h \
|
||||
@ -42,7 +44,6 @@ profiles.c:
|
||||
./wrap-profiles.sh profiles profiles.c
|
||||
|
||||
EXTRA_DIST = \
|
||||
profiles \
|
||||
wrap-profiles.sh
|
||||
|
||||
AM_CPPFLAGS = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
|
||||
|
@ -493,9 +493,7 @@ static VipsColourRoute vips_colour_routes[] = {
|
||||
* vips_colourspace_issupported:
|
||||
* @image: input image
|
||||
*
|
||||
* Test if @image is in a colourspace that vips_colourspace() can process. For
|
||||
* example, #VIPS_INTERPRETATION_RGB images are not in a well-defined
|
||||
* colourspace, but #VIPS_INTERPRETATION_sRGB ones are.
|
||||
* Test if @image is in a colourspace that vips_colourspace() can process.
|
||||
*
|
||||
* Returns: %TRUE if @image is in a supported colourspace.
|
||||
*/
|
||||
|
@ -282,7 +282,7 @@ vips_icc_build( VipsObject *object )
|
||||
case cmsSigRgbData:
|
||||
colour->interpretation =
|
||||
icc->depth == 8 ?
|
||||
VIPS_INTERPRETATION_RGB :
|
||||
VIPS_INTERPRETATION_sRGB :
|
||||
VIPS_INTERPRETATION_RGB16;
|
||||
colour->format =
|
||||
icc->depth == 8 ?
|
||||
|
@ -89,17 +89,14 @@ vips_profile_load_build( VipsObject *object )
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( g_ascii_strcasecmp( load->name, "none" ) == 0 ) {
|
||||
if( g_ascii_strcasecmp( load->name, "none" ) == 0 )
|
||||
profile = NULL;
|
||||
}
|
||||
else if( (data = vips_profile_fallback_get( load->name, &length )) ) {
|
||||
else if( (data = vips_profile_fallback_get( load->name, &length )) )
|
||||
profile = vips_blob_new( NULL, data, length );
|
||||
}
|
||||
else if( (data = vips__file_read_name( load->name,
|
||||
vips__icc_dir(), &length )) ) {
|
||||
vips__icc_dir(), &length )) )
|
||||
profile = vips_blob_new(
|
||||
(VipsCallbackFn) g_free, data, length );
|
||||
}
|
||||
else {
|
||||
vips_error( class->nickname,
|
||||
_( "unable to load profile \"%s\"" ), load->name );
|
||||
|
3
libvips/colour/profiles/Makefile.am
Normal file
@ -0,0 +1,3 @@
|
||||
EXTRA_DIST = \
|
||||
cmyk.icm \
|
||||
sRGB.icm
|
@ -6,6 +6,9 @@
|
||||
* - test and remove orientation from every ifd
|
||||
* 6/10/18
|
||||
* - don't remove orientation if it's one of the cases we don't handle
|
||||
* 10/5/20
|
||||
* - handle mirrored images
|
||||
* - deprecate vips_autorot_get_angle()
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -54,6 +57,7 @@ typedef struct _VipsAutorot {
|
||||
VipsImage *in;
|
||||
|
||||
VipsAngle angle;
|
||||
gboolean flip;
|
||||
|
||||
} VipsAutorot;
|
||||
|
||||
@ -61,83 +65,6 @@ typedef VipsConversionClass VipsAutorotClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsAutorot, vips_autorot, VIPS_TYPE_CONVERSION );
|
||||
|
||||
/**
|
||||
* vips_autorot_get_angle:
|
||||
* @image: image to fetch orientation from
|
||||
*
|
||||
* Examine the metadata on @im and return the #VipsAngle to rotate by to turn
|
||||
* the image upright.
|
||||
*
|
||||
* See also: vips_autorot().
|
||||
*
|
||||
* Returns: the #VipsAngle to rotate by to make the image upright.
|
||||
*/
|
||||
VipsAngle
|
||||
vips_autorot_get_angle( VipsImage *im )
|
||||
{
|
||||
int orientation;
|
||||
VipsAngle angle;
|
||||
|
||||
if( !vips_image_get_typeof( im, VIPS_META_ORIENTATION ) ||
|
||||
vips_image_get_int( im, VIPS_META_ORIENTATION, &orientation ) )
|
||||
orientation = 1;
|
||||
|
||||
switch( orientation ) {
|
||||
case 6:
|
||||
angle = VIPS_ANGLE_D90;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
angle = VIPS_ANGLE_D270;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
angle = VIPS_ANGLE_D180;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other values do rotate + mirror, don't bother handling them
|
||||
* though, how common can mirroring be.
|
||||
*
|
||||
* See:
|
||||
*
|
||||
* http://www.80sidea.com/archives/2316
|
||||
*/
|
||||
angle = VIPS_ANGLE_D0;
|
||||
break;
|
||||
}
|
||||
|
||||
return( angle );
|
||||
}
|
||||
|
||||
/* TRUE if this is one of the cases we handle.
|
||||
*/
|
||||
static gboolean
|
||||
vips_autorot_handled( VipsImage *im )
|
||||
{
|
||||
int orientation;
|
||||
gboolean handled;
|
||||
|
||||
if( !vips_image_get_typeof( im, VIPS_META_ORIENTATION ) ||
|
||||
vips_image_get_int( im, VIPS_META_ORIENTATION, &orientation ) )
|
||||
orientation = 1;
|
||||
|
||||
switch( orientation ) {
|
||||
case 1:
|
||||
case 3:
|
||||
case 6:
|
||||
case 8:
|
||||
handled = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
handled = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return( handled );
|
||||
}
|
||||
|
||||
static void *
|
||||
vips_autorot_remove_angle_sub( VipsImage *image,
|
||||
const char *field, GValue *value, void *my_data )
|
||||
@ -158,14 +85,14 @@ vips_autorot_remove_angle_sub( VipsImage *image,
|
||||
* vips_autorot_remove_angle: (method)
|
||||
* @image: image to remove orientation from
|
||||
*
|
||||
* Remove the orientation tag on @image. Also remove any exif orientation tags.
|
||||
*
|
||||
* See also: vips_autorot_get_angle().
|
||||
* Remove the orientation tag on @image. Also remove any exif orientation tags.
|
||||
* You must vips_copy() the image before calling this function since it
|
||||
* modifies metadata.
|
||||
*/
|
||||
void
|
||||
vips_autorot_remove_angle( VipsImage *image )
|
||||
{
|
||||
(void) vips_image_remove( image, VIPS_META_ORIENTATION );
|
||||
(void) vips_image_remove( image, VIPS_META_ORIENTATION );
|
||||
(void) vips_image_map( image, vips_autorot_remove_angle_sub, NULL );
|
||||
}
|
||||
|
||||
@ -174,26 +101,87 @@ vips_autorot_build( VipsObject *object )
|
||||
{
|
||||
VipsConversion *conversion = VIPS_CONVERSION( object );
|
||||
VipsAutorot *autorot = (VipsAutorot *) object;
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 1 );
|
||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 3 );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_autorot_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
VipsAngle angle;
|
||||
gboolean flip;
|
||||
VipsImage *in;
|
||||
|
||||
g_object_set( object,
|
||||
"angle", vips_autorot_get_angle( autorot->in ),
|
||||
NULL );
|
||||
in = autorot->in;
|
||||
|
||||
switch( vips_image_get_orientation( in ) ) {
|
||||
case 2:
|
||||
angle = VIPS_ANGLE_D0;
|
||||
flip = TRUE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
angle = VIPS_ANGLE_D180;
|
||||
flip = FALSE;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
angle = VIPS_ANGLE_D180;
|
||||
flip = TRUE;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
angle = VIPS_ANGLE_D90;
|
||||
flip = TRUE;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
angle = VIPS_ANGLE_D90;
|
||||
flip = FALSE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
angle = VIPS_ANGLE_D270;
|
||||
flip = TRUE;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
angle = VIPS_ANGLE_D270;
|
||||
flip = FALSE;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
angle = VIPS_ANGLE_D0;
|
||||
flip = FALSE;
|
||||
break;
|
||||
|
||||
if( vips_autorot_handled( autorot->in ) ) {
|
||||
if( vips_rot( autorot->in, &t[0], autorot->angle, NULL ) )
|
||||
return( -1 );
|
||||
vips_autorot_remove_angle( t[0] );
|
||||
}
|
||||
else {
|
||||
if( vips_copy( autorot->in, &t[0], NULL ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips_image_write( t[0], conversion->out ) )
|
||||
g_object_set( object,
|
||||
"angle", angle,
|
||||
"flip", flip,
|
||||
NULL );
|
||||
|
||||
if( angle != VIPS_ANGLE_D0 ) {
|
||||
if( vips_rot( in, &t[0], angle, NULL ) )
|
||||
return( -1 );
|
||||
in = t[0];
|
||||
}
|
||||
|
||||
if( flip ) {
|
||||
if( vips_flip( in, &t[1], VIPS_DIRECTION_HORIZONTAL, NULL ) )
|
||||
return( -1 );
|
||||
in = t[1];
|
||||
}
|
||||
|
||||
/* We must copy before modifying metadata.
|
||||
*/
|
||||
if( vips_copy( in, &t[2], NULL ) )
|
||||
return( -1 );
|
||||
in = t[2];
|
||||
|
||||
vips_autorot_remove_angle( in );
|
||||
|
||||
if( vips_image_write( in, conversion->out ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -223,13 +211,21 @@ vips_autorot_class_init( VipsAutorotClass *class )
|
||||
_( "Angle image was rotated by" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsAutorot, angle ),
|
||||
VIPS_TYPE_ANGLE, VIPS_ANGLE_D0 );
|
||||
VIPS_TYPE_ANGLE, VIPS_ANGLE_D0 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "flip", 7,
|
||||
_( "Flip" ),
|
||||
_( "Whether the image was flipped or not" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsAutorot, flip ),
|
||||
FALSE );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_autorot_init( VipsAutorot *autorot )
|
||||
{
|
||||
autorot->angle = VIPS_ANGLE_D0;
|
||||
autorot->flip = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,18 +237,14 @@ vips_autorot_init( VipsAutorot *autorot )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @angle: output #VipsAngle the image was rotated by
|
||||
* * @flip: output %gboolean whether the image was flipped
|
||||
*
|
||||
* Look at the image metadata and rotate the image to make it upright. The
|
||||
* #VIPS_META_ORIENTATION tag is removed from @out to prevent accidental
|
||||
* double rotation.
|
||||
* Look at the image metadata and rotate and flip the image to make it
|
||||
* upright. The #VIPS_META_ORIENTATION tag is removed from @out to prevent
|
||||
* accidental double rotation.
|
||||
*
|
||||
* Read @angle to find the amount the image was rotated by.
|
||||
*
|
||||
* vips only supports the four simple rotations, it does not support the
|
||||
* various mirror modes. If the image is using one of these mirror modes, the
|
||||
* image is not rotated and the #VIPS_META_ORIENTATION tag is not removed.
|
||||
*
|
||||
* See also: vips_autorot_get_angle(), vips_autorot_remove_angle(), vips_rot().
|
||||
* Read @angle to find the amount the image was rotated by. Read @flip to
|
||||
* see if the image was also flipped.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
@ -268,4 +260,3 @@ vips_autorot( VipsImage *in, VipsImage **out, ... )
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
@ -126,10 +126,11 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
#define CAST_SHORT( X ) VIPS_CLIP( SHRT_MIN, (X), SHRT_MAX )
|
||||
|
||||
/* We know the source cannot be the same as the dest, so we will only use
|
||||
* CAST_UINT() for an INT source, and vice versa.
|
||||
* CAST_UINT() for an INT source, and vice versa. We don't need to clip to
|
||||
* INT_MAX, since float->int does that for us.
|
||||
*/
|
||||
#define CAST_UINT( X ) VIPS_MAX( 0, (X) )
|
||||
#define CAST_INT( X ) VIPS_MIN( (X), INT_MAX )
|
||||
#define CAST_INT( X ) (X)
|
||||
|
||||
/* Rightshift an integer type, ie. sizeof(ITYPE) > sizeof(OTYPE).
|
||||
*/
|
||||
|
@ -343,6 +343,13 @@ vips_composite_base_max_band( VipsCompositeBase *composite, double *max_band )
|
||||
max_band[2] = 255;
|
||||
break;
|
||||
|
||||
case VIPS_INTERPRETATION_CMYK:
|
||||
max_band[0] = 255;
|
||||
max_band[1] = 255;
|
||||
max_band[2] = 255;
|
||||
max_band[3] = 255;
|
||||
break;
|
||||
|
||||
case VIPS_INTERPRETATION_RGB16:
|
||||
max_band[0] = 65535;
|
||||
max_band[1] = 65535;
|
||||
@ -621,7 +628,7 @@ vips_composite_base_blend( VipsCompositeBase *composite,
|
||||
|
||||
case VIPS_BLEND_MODE_DIFFERENCE:
|
||||
for( int b = 0; b < bands; b++ )
|
||||
f[b] = abs( B[b] - A[b] );
|
||||
f[b] = fabs( B[b] - A[b] );
|
||||
break;
|
||||
|
||||
case VIPS_BLEND_MODE_EXCLUSION:
|
||||
|
@ -214,6 +214,7 @@
|
||||
* @VIPS_INTERESTING_ATTENTION: look for features likely to draw human attention
|
||||
* @VIPS_INTERESTING_LOW: position the crop towards the low coordinate
|
||||
* @VIPS_INTERESTING_HIGH: position the crop towards the high coordinate
|
||||
* @VIPS_INTERESTING_ALL: everything is interesting
|
||||
*
|
||||
* Pick the algorithm vips uses to decide image "interestingness". This is used
|
||||
* by vips_smartcrop(), for example, to decide what parts of the image to
|
||||
|
@ -195,6 +195,11 @@ vips_sequential_build( VipsObject *object )
|
||||
if( vips_linecache( sequential->in, &t,
|
||||
"tile_height", sequential->tile_height,
|
||||
"access", VIPS_ACCESS_SEQUENTIAL,
|
||||
/* We need seq caches to persist across minimise in case
|
||||
* someone is trying to read an image with a series of crop
|
||||
* operations.
|
||||
*/
|
||||
"persistent", TRUE,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
* - move shrink to start of processing
|
||||
* 22/9/18 jcupitt
|
||||
* - add low and high
|
||||
* 19/3/20 jcupitt
|
||||
* - add all
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -345,8 +347,8 @@ vips_smartcrop_build( VipsObject *object )
|
||||
break;
|
||||
|
||||
case VIPS_INTERESTING_CENTRE:
|
||||
left = (smartcrop->in->Xsize - smartcrop->width) / 2;
|
||||
top = (smartcrop->in->Ysize - smartcrop->height) / 2;
|
||||
left = (in->Xsize - smartcrop->width) / 2;
|
||||
top = (in->Ysize - smartcrop->height) / 2;
|
||||
break;
|
||||
|
||||
case VIPS_INTERESTING_ENTROPY:
|
||||
@ -360,8 +362,15 @@ vips_smartcrop_build( VipsObject *object )
|
||||
break;
|
||||
|
||||
case VIPS_INTERESTING_HIGH:
|
||||
left = smartcrop->in->Xsize - smartcrop->width;
|
||||
top = smartcrop->in->Ysize - smartcrop->height;
|
||||
left = in->Xsize - smartcrop->width;
|
||||
top = in->Ysize - smartcrop->height;
|
||||
break;
|
||||
|
||||
case VIPS_INTERESTING_ALL:
|
||||
left = 0;
|
||||
top = 0;
|
||||
smartcrop->width = in->Xsize;
|
||||
smartcrop->height = in->Ysize;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -448,10 +457,10 @@ vips_smartcrop_init( VipsSmartcrop *smartcrop )
|
||||
* Crop an image down to a specified width and height by removing boring parts.
|
||||
*
|
||||
* Use @interesting to pick the method vips uses to decide which bits of the
|
||||
* image should be kept.
|
||||
* image should be kept.
|
||||
*
|
||||
* You can test xoffset / yoffset on @out to find the location of the crop
|
||||
* within the input image.
|
||||
* within the input image.
|
||||
*
|
||||
* See also: vips_extract_area().
|
||||
*
|
||||
|
@ -74,8 +74,8 @@ vips_switch_gen( VipsRegion *or, void *seq, void *a, void *b,
|
||||
if( vips_reorder_prepare_many( or->im, ar, r ) )
|
||||
return( -1 );
|
||||
|
||||
g_assert( ar->im->BandFmt == VIPS_FORMAT_UCHAR );
|
||||
g_assert( ar->im->Bands == 1 );
|
||||
g_assert( ar[0]->im->BandFmt == VIPS_FORMAT_UCHAR );
|
||||
g_assert( ar[0]->im->Bands == 1 );
|
||||
|
||||
for( i = 0; i < swit->n; i++ ) {
|
||||
p[i] = VIPS_REGION_ADDR( ar[i], r->left, r->top );
|
||||
|
@ -35,8 +35,6 @@
|
||||
* - terminate on tile calc error
|
||||
* 7/3/17
|
||||
* - remove "access" on linecache, use the base class instead
|
||||
* 15/2/19
|
||||
* - remove the search for LRU, have a gqueue instead, much faster
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -127,10 +125,6 @@ typedef struct _VipsBlockCache {
|
||||
int tile_height;
|
||||
int max_tiles;
|
||||
|
||||
/* access doesn't actually have any effect now. It used to set
|
||||
* the order for the recycle queue, but there's no efficient way to do
|
||||
* top-most, so we're just always LRU.
|
||||
*/
|
||||
VipsAccess access;
|
||||
gboolean threaded;
|
||||
gboolean persistent;
|
||||
@ -254,6 +248,30 @@ vips_tile_search( VipsBlockCache *cache, int x, int y )
|
||||
return( tile );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_tile_find_is_topper( gpointer element, gpointer user_data )
|
||||
{
|
||||
VipsTile *this = (VipsTile *) element;
|
||||
VipsTile **best = (VipsTile **) user_data;
|
||||
|
||||
if( !*best ||
|
||||
this->pos.top < (*best)->pos.top )
|
||||
*best = this;
|
||||
}
|
||||
|
||||
/* Search the recycle list for the topmost tile.
|
||||
*/
|
||||
static VipsTile *
|
||||
vips_tile_find_topmost( GQueue *recycle )
|
||||
{
|
||||
VipsTile *tile;
|
||||
|
||||
tile = NULL;
|
||||
g_queue_foreach( recycle, vips_tile_find_is_topper, &tile );
|
||||
|
||||
return( tile );
|
||||
}
|
||||
|
||||
/* Find existing tile, make a new tile, or if we have a full set of tiles,
|
||||
* reuse one.
|
||||
*/
|
||||
@ -282,12 +300,18 @@ vips_tile_find( VipsBlockCache *cache, int x, int y )
|
||||
return( tile );
|
||||
}
|
||||
|
||||
/* Reuse an old one, if there are any.
|
||||
/* Reuse an old one, if there are any. We just peek the tile pointer,
|
||||
* it is removed from the recycle list later on _ref.
|
||||
*/
|
||||
if( cache->recycle )
|
||||
/* Gets removed from the recycle list on _ref.
|
||||
*/
|
||||
tile = g_queue_peek_head( cache->recycle );
|
||||
if( cache->recycle ) {
|
||||
if( cache->access == VIPS_ACCESS_RANDOM )
|
||||
tile = g_queue_peek_head( cache->recycle );
|
||||
else
|
||||
/* This is slower :( We have to search the recycle
|
||||
* queue.
|
||||
*/
|
||||
tile = vips_tile_find_topmost( cache->recycle );
|
||||
}
|
||||
|
||||
if( !tile ) {
|
||||
/* There are no tiles we can reuse -- we have to make another
|
||||
@ -913,8 +937,7 @@ vips_line_cache_build( VipsObject *object )
|
||||
block_cache->tile_width = block_cache->in->Xsize;
|
||||
|
||||
/* Output has two buffers n_lines height, so 2 * n_lines is the maximum
|
||||
* non-locality from threading. Add another n_lines for conv / reducev
|
||||
* etc.
|
||||
* non-locality from threading. Double again for conv, rounding, etc.
|
||||
*
|
||||
* tile_height can be huge for things like tiff read, where we can
|
||||
* have a whole strip in a single tile ... we still need to have a
|
||||
@ -922,7 +945,7 @@ vips_line_cache_build( VipsObject *object )
|
||||
* tile boundary.
|
||||
*/
|
||||
block_cache->max_tiles = VIPS_MAX( 2,
|
||||
3 * n_lines / block_cache->tile_height );
|
||||
4 * n_lines / block_cache->tile_height );
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_line_cache_build: n_lines = %d\n",
|
||||
n_lines );
|
||||
|
@ -62,6 +62,7 @@ typedef struct _VipsUnpremultiply {
|
||||
VipsImage *in;
|
||||
|
||||
double max_alpha;
|
||||
int alpha_band;
|
||||
|
||||
} VipsUnpremultiply;
|
||||
|
||||
@ -76,17 +77,21 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
|
||||
OUT * restrict q = (OUT *) out; \
|
||||
\
|
||||
for( x = 0; x < width; x++ ) { \
|
||||
IN alpha = p[bands - 1]; \
|
||||
IN clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \
|
||||
OUT nalpha = (OUT) clip_alpha / max_alpha; \
|
||||
IN alpha = p[alpha_band]; \
|
||||
\
|
||||
if( nalpha == 0 ) \
|
||||
for( i = 0; i < bands - 1; i++ ) \
|
||||
q[i] = 0; \
|
||||
if( alpha != 0 ) { \
|
||||
OUT factor = max_alpha / alpha; \
|
||||
\
|
||||
for( i = 0; i < alpha_band; i++ ) \
|
||||
q[i] = factor * p[i]; \
|
||||
q[alpha_band] = alpha; \
|
||||
} \
|
||||
else \
|
||||
for( i = 0; i < bands - 1; i++ ) \
|
||||
q[i] = p[i] / nalpha; \
|
||||
q[i] = clip_alpha; \
|
||||
for( i = 0; i < alpha_band + 1; i++ ) \
|
||||
q[i] = 0; \
|
||||
\
|
||||
for( i = alpha_band + 1; i < bands; i++ ) \
|
||||
q[i] = p[i]; \
|
||||
\
|
||||
p += bands; \
|
||||
q += bands; \
|
||||
@ -101,20 +106,21 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
|
||||
\
|
||||
for( x = 0; x < width; x++ ) { \
|
||||
IN alpha = p[3]; \
|
||||
IN clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \
|
||||
OUT nalpha = (OUT) clip_alpha / max_alpha; \
|
||||
\
|
||||
if( nalpha == 0 ) { \
|
||||
if( alpha != 0 ) { \
|
||||
OUT factor = max_alpha / alpha; \
|
||||
\
|
||||
q[0] = factor * p[0]; \
|
||||
q[1] = factor * p[1]; \
|
||||
q[2] = factor * p[2]; \
|
||||
q[3] = alpha; \
|
||||
} \
|
||||
else { \
|
||||
q[0] = 0; \
|
||||
q[1] = 0; \
|
||||
q[2] = 0; \
|
||||
q[3] = 0; \
|
||||
} \
|
||||
else { \
|
||||
q[0] = p[0] / nalpha; \
|
||||
q[1] = p[1] / nalpha; \
|
||||
q[2] = p[2] / nalpha; \
|
||||
} \
|
||||
q[3] = clip_alpha; \
|
||||
\
|
||||
p += 4; \
|
||||
q += 4; \
|
||||
@ -141,6 +147,7 @@ vips_unpremultiply_gen( VipsRegion *or, void *vseq, void *a, void *b,
|
||||
int width = r->width;
|
||||
int bands = im->Bands;
|
||||
double max_alpha = unpremultiply->max_alpha;
|
||||
int alpha_band = unpremultiply->alpha_band;
|
||||
|
||||
int x, y, i;
|
||||
|
||||
@ -235,6 +242,11 @@ vips_unpremultiply_build( VipsObject *object )
|
||||
in->Type == VIPS_INTERPRETATION_RGB16 )
|
||||
unpremultiply->max_alpha = 65535;
|
||||
|
||||
/* Is alpha-band unset? Default to the final band for this image.
|
||||
*/
|
||||
if( !vips_object_argument_isset( object, "alpha_band" ) )
|
||||
unpremultiply->alpha_band = in->Bands - 1;
|
||||
|
||||
if( in->BandFmt == VIPS_FORMAT_DOUBLE )
|
||||
conversion->out->BandFmt = VIPS_FORMAT_DOUBLE;
|
||||
else
|
||||
@ -279,6 +291,13 @@ vips_unpremultiply_class_init( VipsUnpremultiplyClass *class )
|
||||
G_STRUCT_OFFSET( VipsUnpremultiply, max_alpha ),
|
||||
0, 100000000, 255 );
|
||||
|
||||
VIPS_ARG_INT( class, "alpha_band", 116,
|
||||
_( "Alpha band" ),
|
||||
_( "Unpremultiply with this alpha" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsUnpremultiply, alpha_band ),
|
||||
0, 100000000, 3 );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -296,10 +315,11 @@ vips_unpremultiply_init( VipsUnpremultiply *unpremultiply )
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @max_alpha: %gdouble, maximum value for alpha
|
||||
* * @alpha_band: %gint, band containing alpha data
|
||||
*
|
||||
* Unpremultiplies any alpha channel.
|
||||
* The final band is taken to be the alpha
|
||||
* and the bands are transformed as:
|
||||
* Band @alpha_band (by default the final band) contains the alpha and all
|
||||
* other bands are transformed as:
|
||||
*
|
||||
* |[
|
||||
* alpha = (int) clip( 0, in[in.bands - 1], @max_alpha );
|
||||
@ -312,8 +332,7 @@ vips_unpremultiply_init( VipsUnpremultiply *unpremultiply )
|
||||
*
|
||||
* So for an N-band image, the first N - 1 bands are divided by the clipped
|
||||
* and normalised final band, the final band is clipped.
|
||||
* If there is only a single band,
|
||||
* the image is passed through unaltered.
|
||||
* If there is only a single band, the image is passed through unaltered.
|
||||
*
|
||||
* The result is
|
||||
* #VIPS_FORMAT_FLOAT unless the input format is #VIPS_FORMAT_DOUBLE, in which
|
||||
|
@ -34,11 +34,6 @@
|
||||
|
||||
*/
|
||||
|
||||
/* This is a simple wrapper over the old vips7 functions. At some point we
|
||||
* should rewrite this as a pure vips8 class and redo the vips7 functions as
|
||||
* wrappers over this.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
|
@ -147,9 +147,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
VipsConvolution parent_instance;
|
||||
|
||||
/* An int version of M.
|
||||
*/
|
||||
VipsImage *iM;
|
||||
int n_point; /* w * h for our matrix */
|
||||
|
||||
/* We make a smaller version of the mask with the zeros squeezed out.
|
||||
@ -853,7 +850,6 @@ vips__image_intize( VipsImage *in, VipsImage **out )
|
||||
static int
|
||||
vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
{
|
||||
int n_point;
|
||||
VipsImage *t;
|
||||
double scale;
|
||||
double *scaled;
|
||||
@ -862,21 +858,17 @@ vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
int shift;
|
||||
int i;
|
||||
|
||||
n_point = M->Xsize * M->Ysize;
|
||||
|
||||
g_assert( convi->n_point == n_point );
|
||||
|
||||
if( vips_check_matrix( "vips2imask", M, &t ) )
|
||||
return( -1 );
|
||||
|
||||
/* Bake the scale into the mask to make a double version.
|
||||
*/
|
||||
scale = vips_image_get_scale( t );
|
||||
if( !(scaled = VIPS_ARRAY( convi, n_point, double )) ) {
|
||||
if( !(scaled = VIPS_ARRAY( convi, convi->n_point, double )) ) {
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
}
|
||||
for( i = 0; i < n_point; i++ )
|
||||
for( i = 0; i < convi->n_point; i++ )
|
||||
scaled[i] = VIPS_MATRIX( t, 0, 0 )[i] / scale;
|
||||
g_object_unref( t );
|
||||
|
||||
@ -896,7 +888,7 @@ vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
|
||||
mx = scaled[0];
|
||||
mn = scaled[0];
|
||||
for( i = 1; i < n_point; i++ ) {
|
||||
for( i = 1; i < convi->n_point; i++ ) {
|
||||
if( scaled[i] > mx )
|
||||
mx = scaled[i];
|
||||
if( scaled[i] < mn )
|
||||
@ -915,7 +907,7 @@ vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
/* We need to sum n_points, so we have to shift right before adding a
|
||||
* new value to make sure we have enough range.
|
||||
*/
|
||||
convi->sexp = ceil( log2( n_point ) );
|
||||
convi->sexp = ceil( log2( convi->n_point ) );
|
||||
if( convi->sexp > 10 ) {
|
||||
g_info( "vips_convi_intize: mask too large" );
|
||||
return( -1 );
|
||||
@ -925,9 +917,9 @@ vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
*/
|
||||
convi->exp = 7 - shift - convi->sexp;
|
||||
|
||||
if( !(convi->mant = VIPS_ARRAY( convi, n_point, int )) )
|
||||
if( !(convi->mant = VIPS_ARRAY( convi, convi->n_point, int )) )
|
||||
return( -1 );
|
||||
for( i = 0; i < n_point; i++ ) {
|
||||
for( i = 0; i < convi->n_point; i++ ) {
|
||||
/* 128 since this is signed.
|
||||
*/
|
||||
convi->mant[i] = VIPS_RINT( 128 * scaled[i] * pow(2, -shift) );
|
||||
@ -965,7 +957,7 @@ vips_convi_intize( VipsConvi *convi, VipsImage *M )
|
||||
|
||||
true_sum = 0.0;
|
||||
int_sum = 0;
|
||||
for( i = 0; i < n_point; i++ ) {
|
||||
for( i = 0; i < convi->n_point; i++ ) {
|
||||
int value;
|
||||
|
||||
true_sum += 128 * scaled[i];
|
||||
@ -1001,7 +993,6 @@ vips_convi_build( VipsObject *object )
|
||||
|
||||
VipsImage *in;
|
||||
VipsImage *M;
|
||||
int n_point;
|
||||
VipsGenerateFn generate;
|
||||
double *coeff;
|
||||
int i;
|
||||
@ -1047,19 +1038,18 @@ vips_convi_build( VipsObject *object )
|
||||
*/
|
||||
if( vips__image_intize( M, &t[1] ) )
|
||||
return( -1 );
|
||||
convi->iM = M = t[1];
|
||||
M = t[1];
|
||||
|
||||
coeff = VIPS_MATRIX( M, 0, 0 );
|
||||
n_point = M->Xsize * M->Ysize;
|
||||
if( !(convi->coeff = VIPS_ARRAY( object, n_point, int )) ||
|
||||
if( !(convi->coeff = VIPS_ARRAY( object, convi->n_point, int )) ||
|
||||
!(convi->coeff_pos =
|
||||
VIPS_ARRAY( object, n_point, int )) )
|
||||
VIPS_ARRAY( object, convi->n_point, int )) )
|
||||
return( -1 );
|
||||
|
||||
/* Squeeze out zero mask elements.
|
||||
*/
|
||||
convi->nnz = 0;
|
||||
for( i = 0; i < n_point; i++ )
|
||||
for( i = 0; i < convi->n_point; i++ )
|
||||
if( coeff[i] ) {
|
||||
convi->coeff[convi->nnz] = coeff[i];
|
||||
convi->coeff_pos[convi->nnz] = i;
|
||||
|
@ -157,19 +157,19 @@ vips_convolution_init( VipsConvolution *convolution )
|
||||
void
|
||||
vips_convolution_operation_init( void )
|
||||
{
|
||||
extern int vips_conv_get_type( void );
|
||||
extern int vips_conva_get_type( void );
|
||||
extern int vips_convf_get_type( void );
|
||||
extern int vips_convi_get_type( void );
|
||||
extern int vips_convsep_get_type( void );
|
||||
extern int vips_convasep_get_type( void );
|
||||
extern int vips_compass_get_type( void );
|
||||
extern int vips_fastcor_get_type( void );
|
||||
extern int vips_spcor_get_type( void );
|
||||
extern int vips_sharpen_get_type( void );
|
||||
extern int vips_gaussblur_get_type( void );
|
||||
extern int vips_sobel_get_type( void );
|
||||
extern int vips_canny_get_type( void );
|
||||
extern GType vips_conv_get_type( void );
|
||||
extern GType vips_conva_get_type( void );
|
||||
extern GType vips_convf_get_type( void );
|
||||
extern GType vips_convi_get_type( void );
|
||||
extern GType vips_convsep_get_type( void );
|
||||
extern GType vips_convasep_get_type( void );
|
||||
extern GType vips_compass_get_type( void );
|
||||
extern GType vips_fastcor_get_type( void );
|
||||
extern GType vips_spcor_get_type( void );
|
||||
extern GType vips_sharpen_get_type( void );
|
||||
extern GType vips_gaussblur_get_type( void );
|
||||
extern GType vips_sobel_get_type( void );
|
||||
extern GType vips_canny_get_type( void );
|
||||
|
||||
vips_conv_get_type();
|
||||
vips_conva_get_type();
|
||||
|
@ -64,7 +64,7 @@ vips_convsep_build( VipsObject *object )
|
||||
VipsConvolution *convolution = (VipsConvolution *) object;
|
||||
VipsConvsep *convsep = (VipsConvsep *) object;
|
||||
VipsImage **t = (VipsImage **)
|
||||
vips_object_local_array( object, 3 );
|
||||
vips_object_local_array( object, 4 );
|
||||
|
||||
VipsImage *in;
|
||||
|
||||
@ -86,19 +86,19 @@ vips_convsep_build( VipsObject *object )
|
||||
in = t[0];
|
||||
}
|
||||
else {
|
||||
if( vips_rot( convolution->M, &t[0], VIPS_ANGLE_D90, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* We must only add the offset once.
|
||||
/* Take a copy, since we must set the offset.
|
||||
*/
|
||||
vips_image_set_double( t[0], "offset", 0 );
|
||||
if( vips_rot( convolution->M, &t[0], VIPS_ANGLE_D90, NULL ) ||
|
||||
vips_copy( t[0], &t[3], NULL ) )
|
||||
return( -1 );
|
||||
vips_image_set_double( t[3], "offset", 0 );
|
||||
|
||||
if( vips_conv( in, &t[1], convolution->M,
|
||||
"precision", convsep->precision,
|
||||
"layers", convsep->layers,
|
||||
"cluster", convsep->cluster,
|
||||
NULL ) ||
|
||||
vips_conv( t[1], &t[2], t[0],
|
||||
vips_conv( t[1], &t[2], t[3],
|
||||
"precision", convsep->precision,
|
||||
"layers", convsep->layers,
|
||||
"cluster", convsep->cluster,
|
||||
|
@ -64,9 +64,12 @@ vips_mask_butterworth_point( VipsMask *mask, double dx, double dy )
|
||||
|
||||
double cnst = (1.0 / ac) - 1.0;
|
||||
double fc2 = fc * fc;
|
||||
double dist2 = fc2 / (dx * dx + dy * dy);
|
||||
double d = dx * dx + dy * dy;
|
||||
|
||||
return( 1.0 / (1.0 + cnst * pow( dist2, order )) );
|
||||
if( d == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( 1.0 / (1.0 + cnst * pow( fc2 / d, order )) );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -30,6 +30,8 @@
|
||||
* - set Xoffset/Yoffset to ink left/top
|
||||
* 27/6/19
|
||||
* - fitting could occasionally terminate early [levmorozov]
|
||||
* 16/5/20 [keiviv]
|
||||
* - don't add fontfiles repeatedly
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -103,6 +105,10 @@ typedef VipsCreateClass VipsTextClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsText, vips_text, VIPS_TYPE_CREATE );
|
||||
|
||||
/* ... single-thread the body of vips_text() with this.
|
||||
*/
|
||||
static GMutex *vips_text_lock = NULL;
|
||||
|
||||
/* Just have one of these and reuse it.
|
||||
*
|
||||
* This does not unref cleanly on many platforms, so we will leak horribly
|
||||
@ -111,9 +117,10 @@ G_DEFINE_TYPE( VipsText, vips_text, VIPS_TYPE_CREATE );
|
||||
*/
|
||||
static PangoFontMap *vips_text_fontmap = NULL;
|
||||
|
||||
/* ... single-thread the body of vips_text() with this.
|
||||
/* All the fontfiles we've loaded. fontconfig lets you add a fontfile
|
||||
* repeatedly, and we obviously don't want that.
|
||||
*/
|
||||
static GMutex *vips_text_lock = NULL;
|
||||
static GHashTable *vips_text_fontfiles = NULL;
|
||||
|
||||
static void
|
||||
vips_text_dispose( GObject *gobject )
|
||||
@ -182,6 +189,7 @@ vips_text_get_extents( VipsText *text, VipsRect *extents )
|
||||
pango_ft2_font_map_set_resolution(
|
||||
PANGO_FT2_FONT_MAP( vips_text_fontmap ), text->dpi, text->dpi );
|
||||
|
||||
VIPS_UNREF( text->layout );
|
||||
if( !(text->layout = text_layout_new( text->context,
|
||||
text->text, text->font,
|
||||
text->width, text->spacing, text->align, text->justify )) )
|
||||
@ -239,6 +247,7 @@ vips_text_autofit( VipsText *text )
|
||||
target.width = text->width;
|
||||
target.height = text->height;
|
||||
previous_dpi = -1;
|
||||
previous_difference = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips_text_autofit: "
|
||||
@ -348,17 +357,26 @@ vips_text_build( VipsObject *object )
|
||||
|
||||
if( !vips_text_fontmap )
|
||||
vips_text_fontmap = pango_ft2_font_map_new();
|
||||
if( !vips_text_fontfiles )
|
||||
vips_text_fontfiles =
|
||||
g_hash_table_new( g_str_hash, g_str_equal );
|
||||
|
||||
text->context = pango_font_map_create_context(
|
||||
PANGO_FONT_MAP( vips_text_fontmap ) );
|
||||
|
||||
if( text->fontfile &&
|
||||
!FcConfigAppFontAddFile( NULL,
|
||||
!g_hash_table_lookup( vips_text_fontfiles, text->fontfile ) ) {
|
||||
if( !FcConfigAppFontAddFile( NULL,
|
||||
(const FcChar8 *) text->fontfile ) ) {
|
||||
vips_error( class->nickname,
|
||||
_( "unable to load font \"%s\"" ), text->fontfile );
|
||||
g_mutex_unlock( vips_text_lock );
|
||||
return( -1 );
|
||||
vips_error( class->nickname,
|
||||
_( "unable to load font \"%s\"" ),
|
||||
text->fontfile );
|
||||
g_mutex_unlock( vips_text_lock );
|
||||
return( -1 );
|
||||
}
|
||||
g_hash_table_insert( vips_text_fontfiles,
|
||||
text->fontfile,
|
||||
g_strdup( text->fontfile ) );
|
||||
}
|
||||
|
||||
/* If our caller set height and not dpi, we adjust dpi until
|
||||
@ -541,7 +559,7 @@ vips_text_init( VipsText *text )
|
||||
* * @fontfile: %gchararray, load this font file
|
||||
* * @width: %gint, image should be no wider than this many pixels
|
||||
* * @height: %gint, image should be no higher than this many pixels
|
||||
* * @align: #VipsAlign, left/centre/right alignment
|
||||
* * @align: #VipsAlign, set justification alignment
|
||||
* * @justify: %gboolean, justify lines
|
||||
* * @dpi: %gint, render at this resolution
|
||||
* * @autofit_dpi: %gint, read out auto-fitted DPI
|
||||
@ -562,11 +580,12 @@ vips_text_init( VipsText *text )
|
||||
*
|
||||
* @width is the number of pixels to word-wrap at. Lines of text wider than
|
||||
* this will be broken at word boundaries.
|
||||
* @align can be used to set the alignment style for multi-line
|
||||
* text. Note that the output image can be wider than @width if there are no
|
||||
* word breaks, or narrower if the lines don't break exactly at @width.
|
||||
*
|
||||
* Set @justify to turn on line justification.
|
||||
* @align can be used to set the alignment style for multi-line
|
||||
* text to the low (left) edge centre, or high (right) edge. Note that the
|
||||
* output image can be wider than @width if there are no
|
||||
* word breaks, or narrower if the lines don't break exactly at @width.
|
||||
*
|
||||
* @height is the maximum number of pixels high the generated text can be. This
|
||||
* only takes effect when @dpi is not set, and @width is set, making a box.
|
||||
|
@ -176,7 +176,7 @@ im_isvips( const char *filename )
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
if( im__get_bytes( filename, buf, 4 ) ) {
|
||||
if( im__get_bytes( filename, buf, 4 ) == 4 ) {
|
||||
if( buf[0] == 0x08 && buf[1] == 0xf2 &&
|
||||
buf[2] == 0xa6 && buf[3] == 0xb6 )
|
||||
/* SPARC-order VIPS image.
|
||||
@ -212,7 +212,7 @@ vips_flags( const char *filename )
|
||||
|
||||
flags = VIPS_FORMAT_PARTIAL;
|
||||
|
||||
if( im__get_bytes( filename, buf, 4 ) &&
|
||||
if( im__get_bytes( filename, buf, 4 ) == 4 &&
|
||||
buf[0] == 0x08 &&
|
||||
buf[1] == 0xf2 &&
|
||||
buf[2] == 0xa6 &&
|
||||
|
@ -61,6 +61,8 @@ im_csv2vips( const char *filename, IMAGE *out )
|
||||
char mode[FILENAME_MAX];
|
||||
char *p, *q, *r;
|
||||
|
||||
VipsImage *x;
|
||||
|
||||
/* Parse mode string.
|
||||
*/
|
||||
im_filename_split( filename, name, mode );
|
||||
@ -76,9 +78,18 @@ im_csv2vips( const char *filename, IMAGE *out )
|
||||
lines = atoi( r );
|
||||
}
|
||||
|
||||
if( vips__csv_read( name, out,
|
||||
start_skip, lines, whitespace, separator, FALSE ) )
|
||||
if( vips_csvload( name, &x,
|
||||
"skip", start_skip,
|
||||
"lines", lines,
|
||||
"whitespace", whitespace,
|
||||
"separator", separator,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
if( vips_image_write( x, out ) ) {
|
||||
g_object_unref( x );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( x );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -111,9 +111,18 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
}
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
if( vips__jpeg_read_file( filename, out,
|
||||
header_only, shrink, fail_on_warn, FALSE ) )
|
||||
{
|
||||
VipsSource *source;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( vips__jpeg_read_source( source, out,
|
||||
header_only, shrink, fail_on_warn, FALSE ) ) {
|
||||
VIPS_UNREF( source );
|
||||
return( -1 );
|
||||
}
|
||||
VIPS_UNREF( source );
|
||||
}
|
||||
#else
|
||||
vips_error( "im_jpeg2vips",
|
||||
"%s", _( "no JPEG support in your libvips" ) );
|
||||
|
@ -83,14 +83,21 @@ png2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
}
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
if( header_only ) {
|
||||
if( vips__png_header( filename, out ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__png_read( filename, out, TRUE ) )
|
||||
return( -1 );
|
||||
}
|
||||
{
|
||||
VipsSource *source;
|
||||
int result;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( header_only )
|
||||
result = vips__png_header_source( source, out );
|
||||
else
|
||||
result = vips__png_read_source( source, out, TRUE );
|
||||
VIPS_UNREF( source );
|
||||
|
||||
if( result )
|
||||
return( result );
|
||||
}
|
||||
#else
|
||||
vips_error( "im_png2vips",
|
||||
"%s", _( "no PNG support in your libvips" ) );
|
||||
|
@ -52,6 +52,57 @@
|
||||
|
||||
#include "../foreign/pforeign.h"
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
static gboolean
|
||||
im_istifftiled( const char *filename )
|
||||
{
|
||||
VipsSource *source;
|
||||
gboolean result;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( FALSE );
|
||||
result = vips__istiff_source( source );
|
||||
VIPS_UNREF( source );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
static int
|
||||
im_tiff_read_header( const char *filename, VipsImage *out,
|
||||
int page, int n, gboolean autorotate )
|
||||
{
|
||||
VipsSource *source;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( vips__tiff_read_header_source( source,
|
||||
out, page, n, autorotate, -1 ) ) {
|
||||
VIPS_UNREF( source );
|
||||
return( -1 );
|
||||
}
|
||||
VIPS_UNREF( source );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
im_tiff_read( const char *filename, VipsImage *out,
|
||||
int page, int n, gboolean autorotate )
|
||||
{
|
||||
VipsSource *source;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( vips__tiff_read_source( source, out, page, n, autorotate, -1 ) ) {
|
||||
VIPS_UNREF( source );
|
||||
return( -1 );
|
||||
}
|
||||
VIPS_UNREF( source );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /*HAVE_TIFF*/
|
||||
|
||||
static int
|
||||
tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
{
|
||||
@ -88,18 +139,18 @@ tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
|
||||
if( !header_only &&
|
||||
!seq &&
|
||||
!vips__istifftiled( filename ) &&
|
||||
!im_istifftiled( filename ) &&
|
||||
out->dtype == VIPS_IMAGE_PARTIAL ) {
|
||||
if( vips__image_wio_output( out ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( header_only ) {
|
||||
if( vips__tiff_read_header( filename, out, page, 1, FALSE ) )
|
||||
if( im_tiff_read_header( filename, out, page, 1, FALSE ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__tiff_read( filename, out, page, 1, FALSE ) )
|
||||
if( im_tiff_read( filename, out, page, 1, FALSE ) )
|
||||
return( -1 );
|
||||
}
|
||||
#else
|
||||
|
@ -51,14 +51,21 @@ webp2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
im_filename_split( name, filename, mode );
|
||||
|
||||
#ifdef HAVE_LIBWEBP
|
||||
if( header_only ) {
|
||||
if( vips__webp_read_file_header( filename, out, 0, 1, 1 ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips__webp_read_file( filename, out, 0, 1, 1 ) )
|
||||
return( -1 );
|
||||
}
|
||||
{
|
||||
VipsSource *source;
|
||||
int result;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( -1 );
|
||||
if( header_only )
|
||||
result = vips__webp_read_header_source( source, out, 0, 1, 1 );
|
||||
else
|
||||
result = vips__webp_read_source( source, out, 0, 1, 1 );
|
||||
VIPS_UNREF( source );
|
||||
|
||||
if( result )
|
||||
return( result );
|
||||
}
|
||||
#else
|
||||
vips_error( "im_webp2vips",
|
||||
"%s", _( "no webp support in your libvips" ) );
|
||||
@ -69,6 +76,25 @@ webp2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips__iswebp( const char *filename )
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
#ifdef HAVE_LIBWEBP
|
||||
VipsSource *source;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( FALSE );
|
||||
result = vips__iswebp_source( source );
|
||||
VIPS_UNREF( source );
|
||||
#else /*!HAVE_LIBWEBP*/
|
||||
result = -1;
|
||||
#endif /*HAVE_LIBWEBP*/
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
int
|
||||
im_webp2vips( const char *name, IMAGE *out )
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ lrmosaic_vec( im_object *argv )
|
||||
int balancetype = *((int *) argv[10]);
|
||||
int mwidth = *((int *) argv[11]);
|
||||
|
||||
return( im_lrmosaic( argv[0], argv[1], argv[2],
|
||||
return( vips_lrmosaic( argv[0], argv[1], argv[2],
|
||||
bandno,
|
||||
xr, yr, xs, ys,
|
||||
halfcorrelation, halfarea,
|
||||
@ -210,7 +210,7 @@ find_lroverlap_vec( im_object *argv )
|
||||
|
||||
if( !(t = im_open( "find_lroverlap_vec", "p" )) )
|
||||
return( -1 );
|
||||
result = im__find_lroverlap( argv[0], argv[1], t,
|
||||
result = vips__find_lroverlap( argv[0], argv[1], t,
|
||||
bandno,
|
||||
xr, yr, xs, ys,
|
||||
halfcorrelation, halfarea,
|
||||
@ -257,7 +257,7 @@ tbmosaic_vec( im_object *argv )
|
||||
int balancetype = *((int *) argv[10]);
|
||||
int mwidth = *((int *) argv[11]);
|
||||
|
||||
return( im_tbmosaic( argv[0], argv[1], argv[2],
|
||||
return( vips_tbmosaic( argv[0], argv[1], argv[2],
|
||||
bandno,
|
||||
x1, y1, x2, y2,
|
||||
halfcorrelation, halfarea,
|
||||
@ -315,7 +315,7 @@ find_tboverlap_vec( im_object *argv )
|
||||
|
||||
if( !(t = im_open( "find_tboverlap_vec", "p" )) )
|
||||
return( -1 );
|
||||
result = im__find_tboverlap( argv[0], argv[1], t,
|
||||
result = vips__find_tboverlap( argv[0], argv[1], t,
|
||||
bandno,
|
||||
xr, yr, xs, ys,
|
||||
halfcorrelation, halfarea,
|
||||
@ -367,7 +367,7 @@ lrmerge_vec( im_object *argv )
|
||||
int dy = *((int *) argv[4]);
|
||||
int mwidth = *((int *) argv[5]);
|
||||
|
||||
return( im_lrmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) );
|
||||
return( vips_lrmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) );
|
||||
}
|
||||
|
||||
/* Call im_lrmerge1 via arg vector.
|
||||
@ -421,7 +421,7 @@ tbmerge_vec( im_object *argv )
|
||||
int dy = *((int *) argv[4]);
|
||||
int mwidth = *((int *) argv[5]);
|
||||
|
||||
return( im_tbmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) );
|
||||
return( vips_tbmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) );
|
||||
}
|
||||
|
||||
/* Call im_tbmerge1 via arg vector.
|
||||
@ -594,7 +594,7 @@ correl_vec( im_object *argv )
|
||||
int *y = (int *) argv[9];
|
||||
double *correlation = (double *) argv[10];
|
||||
|
||||
return( im_correl( argv[0], argv[1],
|
||||
return( vips_correl( argv[0], argv[1],
|
||||
xref, yref, xsec, ysec, cor, area, correlation, x, y ) );
|
||||
}
|
||||
|
||||
|
@ -801,3 +801,15 @@ vips_warn( const char *domain, const char *fmt, ... )
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_autorot_get_angle:
|
||||
* @image: image to fetch orientation from
|
||||
*
|
||||
* This function is deprecated. Use vips_autorot() instead.
|
||||
*/
|
||||
VipsAngle
|
||||
vips_autorot_get_angle( VipsImage *im )
|
||||
{
|
||||
return( VIPS_ANGLE_D0 );
|
||||
}
|
||||
|
||||
|
@ -4370,6 +4370,68 @@ im_profile( IMAGE *in, IMAGE *out, int dir )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_erode( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||
{
|
||||
VipsImage *t1, *t2;
|
||||
|
||||
if( !(t1 = vips_image_new()) ||
|
||||
im_imask2vips( mask, t1 ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_morph( in, &t2, t1, VIPS_OPERATION_MORPHOLOGY_ERODE,
|
||||
NULL ) ) {
|
||||
g_object_unref( t1 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t1 );
|
||||
|
||||
if( vips_image_write( t2, out ) ) {
|
||||
g_object_unref( t2 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t2 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_erode_raw( IMAGE *in, IMAGE *out, INTMASK *m )
|
||||
{
|
||||
return( im_erode( in, out, m ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_dilate( IMAGE *in, IMAGE *out, INTMASK *mask )
|
||||
{
|
||||
VipsImage *t1, *t2;
|
||||
|
||||
if( !(t1 = vips_image_new()) ||
|
||||
im_imask2vips( mask, t1 ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_morph( in, &t2, t1, VIPS_OPERATION_MORPHOLOGY_DILATE,
|
||||
NULL ) ) {
|
||||
g_object_unref( t1 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t1 );
|
||||
|
||||
if( vips_image_write( t2, out ) ) {
|
||||
g_object_unref( t2 );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t2 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_dilate_raw( IMAGE *in, IMAGE *out, INTMASK *m )
|
||||
{
|
||||
return( im_dilate( in, out, m ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_mpercent( IMAGE *in, double percent, int *out )
|
||||
{
|
||||
|
@ -69,7 +69,7 @@
|
||||
* to be a slow way to do it. This is where the draw operations come in.
|
||||
*
|
||||
* To use these operations, use vips_copy() to make a copy of the image you
|
||||
* want to modify, to ensure that no one else is using it, then call a
|
||||
* want to modify to ensure that no one else is using it, then call a
|
||||
* series of draw operations.
|
||||
* Once you are done drawing, return to normal use of vips operations. Any time
|
||||
* you want to start drawing again, you'll need to copy again.
|
||||
|