Merge branch 'master' of github.com:libvips/libvips
This commit is contained in:
commit
9c172674bf
144
.github/workflows/ci.yml
vendored
Normal file
144
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
name: CI
|
||||
|
||||
on: [ push, pull_request, workflow_dispatch ]
|
||||
|
||||
jobs:
|
||||
CI:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ contains(matrix.os, 'macos') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
name: [ "Linux x64 (Ubuntu 20.04) - GCC 10" ]
|
||||
os: [ ubuntu-20.04 ]
|
||||
sanitize: [ false ]
|
||||
build:
|
||||
- { cc: gcc, cxx: g++, linker: ld }
|
||||
include:
|
||||
- name: "Linux x64 (Ubuntu 20.04) - Clang 10 with ASan and UBSan"
|
||||
os: ubuntu-20.04
|
||||
sanitize: true
|
||||
build: { cc: clang-10, cxx: clang++-10, linker: ld.lld-10 }
|
||||
- name: "macOS (10.15) - Xcode 12.3"
|
||||
os: macos-10.15
|
||||
sanitize: false
|
||||
build: { cc: clang, cxx: clang++, linker: ld.lld }
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Update apt
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: sudo -E apt-get update -qq -o Acquire::Retries=3
|
||||
|
||||
- name: Add libheif PPA
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo add-apt-repository ppa:strukturag/libde265
|
||||
sudo add-apt-repository ppa:strukturag/libheif
|
||||
|
||||
- name: Install Ubuntu dependencies
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run:
|
||||
sudo -E apt-get install --fix-missing -qq -o Acquire::Retries=3
|
||||
gtk-doc-tools gobject-introspection
|
||||
python3-pip python3-setuptools python3-wheel
|
||||
libfftw3-dev libexif-dev libjpeg-turbo8-dev
|
||||
libpng-dev libwebp-dev libtiff5-dev
|
||||
libheif-dev libexpat1-dev libcfitsio-dev
|
||||
libmatio-dev libnifti-dev liborc-0.4-dev
|
||||
liblcms2-dev libpoppler-glib-dev librsvg2-dev
|
||||
libgif-dev libopenexr-dev libpango1.0-dev
|
||||
libgsf-1-dev libopenslide-dev libffi-dev
|
||||
|
||||
- name: Install macOS dependencies
|
||||
if: contains(matrix.os, 'macos')
|
||||
run:
|
||||
brew install
|
||||
autoconf automake libtool
|
||||
gtk-doc gobject-introspection
|
||||
cfitsio fftw giflib
|
||||
glib libexif libgsf
|
||||
libheif libjpeg-turbo libmatio
|
||||
librsvg libspng libtiff
|
||||
little-cms2 openexr openslide
|
||||
orc pango poppler webp
|
||||
|
||||
- name: Install Clang 10
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
if: contains(matrix.os, 'ubuntu') && matrix.build.cc == 'clang-10'
|
||||
run:
|
||||
sudo -E apt-get install --fix-missing -qq -o Acquire::Retries=3
|
||||
clang-10 libomp-10-dev lld-10 llvm-10
|
||||
|
||||
- name: Prepare build environment
|
||||
run: |
|
||||
echo "CC=${{ matrix.build.cc }}" >> $GITHUB_ENV
|
||||
echo "CXX=${{ matrix.build.cxx }}" >> $GITHUB_ENV
|
||||
echo "LD=${{ matrix.build.linker }}" >> $GITHUB_ENV
|
||||
echo "CPPFLAGS=-Wall" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare Ubuntu environment
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: echo "JOBS=$(nproc)" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare macOS environment
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: |
|
||||
echo "JOBS=$(sysctl -n hw.logicalcpu)" >> $GITHUB_ENV
|
||||
echo "PKG_CONFIG_PATH=/usr/local/opt/jpeg-turbo/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare sanitizers
|
||||
if: matrix.sanitize
|
||||
env:
|
||||
LLVM_PREFIX: /usr/lib/llvm-10
|
||||
run: |
|
||||
ASAN_DSO=`$CC -print-file-name=libclang_rt.asan-x86_64.so`
|
||||
echo "LDSHARED=$CC -shared" >> $GITHUB_ENV
|
||||
echo "CPPFLAGS=-g -fsanitize=address,undefined -fno-omit-frame-pointer -fopenmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" >> $GITHUB_ENV
|
||||
echo "LDFLAGS=-g -fsanitize=address,undefined -shared-libasan -fopenmp=libomp" >> $GITHUB_ENV
|
||||
echo "ASAN_DSO=$ASAN_DSO" >> $GITHUB_ENV
|
||||
echo "ASAN_OPTIONS=suppressions=${{ github.workspace }}/suppressions/asan.supp" >> $GITHUB_ENV
|
||||
echo "LSAN_OPTIONS=suppressions=${{ github.workspace }}/suppressions/lsan.supp" >> $GITHUB_ENV
|
||||
echo "UBSAN_OPTIONS=suppressions=${{ github.workspace }}/suppressions/ubsan.supp:print_stacktrace=1" >> $GITHUB_ENV
|
||||
echo "LD_LIBRARY_PATH=$LLVM_PREFIX/lib:`dirname $ASAN_DSO`" >> $GITHUB_ENV
|
||||
echo "$LLVM_PREFIX/bin" >> $GITHUB_PATH
|
||||
# workaround for https://github.com/google/sanitizers/issues/89
|
||||
# otherwise libIlmImf-2_3.so ends up as <unknown module>
|
||||
echo "DLCLOSE_PRELOAD=${{ github.workspace }}/dlclose.so" >> $GITHUB_ENV
|
||||
echo -e '#include <stdio.h>\nint dlclose(void*handle){return 0;}' | $CC -shared -xc -odlclose.so -
|
||||
|
||||
- name: Configure libvips
|
||||
run:
|
||||
./autogen.sh
|
||||
--disable-dependency-tracking
|
||||
--disable-deprecated || (cat config.log && exit 1)
|
||||
|
||||
- name: Build libvips
|
||||
run: make V=0 -j$JOBS
|
||||
|
||||
- name: Check libvips
|
||||
run: make V=0 check
|
||||
|
||||
- name: Install libvips
|
||||
run: sudo make V=0 install
|
||||
|
||||
- name: Rebuild the shared library cache
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: sudo ldconfig
|
||||
|
||||
- name: Install pyvips
|
||||
run: pip3 install pyvips[test]
|
||||
|
||||
- name: Run test suite
|
||||
env:
|
||||
VIPS_LEAK: 1
|
||||
LD_PRELOAD: ${{ env.ASAN_DSO }} ${{ env.DLCLOSE_PRELOAD }}
|
||||
run: python3 -m pytest -sv --log-cli-level=WARNING test/test-suite
|
84
.github/workflows/test.yml
vendored
84
.github/workflows/test.yml
vendored
@ -1,84 +0,0 @@
|
||||
name: Test
|
||||
|
||||
# to-do:
|
||||
# - add a macos test with brew etc.
|
||||
# - build with clang/asan/etc. and run the fuzz tests
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
- workflow_dispatch # manually triggered workflow
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Update apt
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run:
|
||||
sudo apt-get update -qq -o Acquire::Retries=3
|
||||
|
||||
- name: Add libheif PPA
|
||||
run: |
|
||||
sudo add-apt-repository ppa:strukturag/libde265
|
||||
sudo add-apt-repository ppa:strukturag/libheif
|
||||
|
||||
- name: Install platform dependencies
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run:
|
||||
sudo apt-get install --fix-missing -qq -o Acquire::Retries=3
|
||||
gtk-doc-tools
|
||||
gobject-introspection
|
||||
python3-pip
|
||||
python3-setuptools
|
||||
python3-wheel
|
||||
libfftw3-dev
|
||||
libexif-dev
|
||||
libjpeg-turbo8-dev
|
||||
libpng-dev
|
||||
libwebp-dev
|
||||
libtiff5-dev
|
||||
libheif-dev
|
||||
libexpat1-dev
|
||||
libcfitsio-dev
|
||||
libgsl-dev
|
||||
libmatio-dev
|
||||
libnifti-dev
|
||||
liborc-0.4-dev
|
||||
liblcms2-dev
|
||||
libpoppler-glib-dev
|
||||
librsvg2-dev
|
||||
libgif-dev
|
||||
libopenexr-dev
|
||||
libpango1.0-dev
|
||||
libgsf-1-dev
|
||||
libopenslide-dev
|
||||
libffi-dev
|
||||
|
||||
- name: Configure libvips
|
||||
run: CFLAGS=-Wall CXXFLAGS=-Wall ./autogen.sh
|
||||
--disable-dependency-tracking
|
||||
--disable-deprecated
|
||||
|
||||
- name: Build libvips
|
||||
run: make V=0 -j$(nproc)
|
||||
|
||||
- name: Check libvips
|
||||
run: make V=0 check
|
||||
|
||||
- name: Install libvips
|
||||
run: |
|
||||
sudo make V=0 install
|
||||
sudo ldconfig
|
||||
|
||||
- name: Install pyvips
|
||||
run: pip3 install pyvips pytest
|
||||
|
||||
- name: Run test suite
|
||||
run: python3 -m pytest
|
163
.travis.yml
163
.travis.yml
@ -1,163 +0,0 @@
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
global:
|
||||
- PYTHON=python3
|
||||
- PYVIPS_VERSION=master
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
sources: &common_sources
|
||||
# add support for AVIF files
|
||||
- sourceline: 'ppa:strukturag/libheif'
|
||||
- sourceline: 'ppa:strukturag/libde265'
|
||||
packages: &common_packages
|
||||
- gtk-doc-tools
|
||||
- gobject-introspection
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
- python3-wheel
|
||||
- libfftw3-dev
|
||||
- libexif-dev
|
||||
- libjpeg-turbo8-dev
|
||||
- libpng-dev
|
||||
- libwebp-dev
|
||||
- libtiff5-dev
|
||||
- libheif-dev
|
||||
- libexpat1-dev
|
||||
- libcfitsio-dev
|
||||
- libgsl-dev
|
||||
- libmatio-dev
|
||||
- libnifti-dev
|
||||
- liborc-0.4-dev
|
||||
- liblcms2-dev
|
||||
- libpoppler-glib-dev
|
||||
- librsvg2-dev
|
||||
- libgif-dev
|
||||
- libopenexr-dev
|
||||
- libpango1.0-dev
|
||||
- libgsf-1-dev
|
||||
- libopenslide-dev
|
||||
- libffi-dev
|
||||
homebrew:
|
||||
update: true
|
||||
packages:
|
||||
- ccache
|
||||
- cfitsio
|
||||
- fftw
|
||||
- giflib
|
||||
- glib
|
||||
- gobject-introspection
|
||||
- gtk-doc
|
||||
- libexif
|
||||
- libgsf
|
||||
- libheif
|
||||
- libjpeg-turbo
|
||||
- libmatio
|
||||
- librsvg
|
||||
- libspng
|
||||
- libtiff
|
||||
- little-cms2
|
||||
- openexr
|
||||
- openslide
|
||||
- orc
|
||||
- pango
|
||||
- poppler
|
||||
- webp
|
||||
|
||||
jobs:
|
||||
allow_failures:
|
||||
- os: osx
|
||||
fast_finish: true
|
||||
include:
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: gcc
|
||||
name: "Linux x64 (Ubuntu 18.04) - GCC 10"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- *common_sources
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- *common_packages
|
||||
- libmagick++-dev
|
||||
- g++-10
|
||||
env:
|
||||
- JPEG=/usr
|
||||
- JOBS=`nproc`
|
||||
- WITH_MAGICK=yes
|
||||
- CC="gcc-10"
|
||||
- CXX="g++-10"
|
||||
- LDSHARED="$CC -shared"
|
||||
- CFLAGS="-Wcast-function-type"
|
||||
cache: ccache
|
||||
- os: linux
|
||||
dist: bionic
|
||||
compiler: clang
|
||||
name: "Linux x64 (Ubuntu 18.04) - Clang 10 with ASan and UBSan"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- *common_sources
|
||||
- sourceline: deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-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
|
||||
- CC="clang-10"
|
||||
- CXX="clang++-10"
|
||||
- LDSHARED="$CC -shared"
|
||||
- CFLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -fopenmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION"
|
||||
- CXXFLAGS="$CFLAGS"
|
||||
- LDFLAGS="-fsanitize=address,undefined -shared-libasan -fopenmp=libomp"
|
||||
- ASAN_DSO=`$CC -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:print_stacktrace=1"
|
||||
- LD_LIBRARY_PATH="/usr/lib/llvm-10/lib:`dirname $ASAN_DSO`"
|
||||
- DLCLOSE_PRELOAD="$TRAVIS_BUILD_DIR/dlclose.so"
|
||||
before_script:
|
||||
# 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;}' | $CC -shared -xc -odlclose.so -
|
||||
cache: ccache
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
name: "macOS (10.14.6) - Xcode 11"
|
||||
env:
|
||||
- JPEG=/usr/local/opt/jpeg-turbo
|
||||
- JOBS="`sysctl -n hw.ncpu`"
|
||||
- WITH_MAGICK=no
|
||||
- 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="clang"
|
||||
- CXX="clang++"
|
||||
cache: ccache
|
||||
|
||||
install:
|
||||
- $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:$LD_LIBRARY_PATH"
|
||||
DYLD_LIBRARY_PATH=$PWD/libvips/.libs
|
||||
LD_PRELOAD="$ASAN_DSO $DLCLOSE_PRELOAD"
|
||||
$PYTHON -m pytest -sv --log-cli-level=WARNING test/test-suite
|
@ -16,6 +16,8 @@
|
||||
- avoid NaN in mapim [afontenot]
|
||||
- hist_find outputs a double histogram for large images [erdmann]
|
||||
- fix ref leaks in mosaicing package
|
||||
- run libvips leak test in CI
|
||||
- add vips_fitsload_source()m vips_niftiload_source()
|
||||
|
||||
22/12/20 start 8.10.6
|
||||
- don't seek on bad file descriptors [kleisauke]
|
||||
@ -23,6 +25,8 @@
|
||||
- revise ppmload, fixing a couple of small bugs
|
||||
- signal error on EOF in jpegload more reliably [bozaro]
|
||||
- better error detection in spngload [randy408]
|
||||
- fix includes of glib headers in C++ [lovell]
|
||||
- fix build with more modern librsvg [lovell]
|
||||
|
||||
18/12/20 started 8.10.5
|
||||
- fix potential /0 in animated webp load [lovell]
|
||||
|
@ -1,6 +1,6 @@
|
||||
# libvips : an image processing library
|
||||
|
||||
[![Test](https://github.com/libvips/libvips/workflows/Test/badge.svg)](https://github.com/libvips/libvips/actions?query=workflow%3ATest)
|
||||
[![CI](https://github.com/libvips/libvips/workflows/CI/badge.svg)](https://github.com/libvips/libvips/actions)
|
||||
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libvips.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=2&q=proj:libvips)
|
||||
[![Coverity Status](https://scan.coverity.com/projects/6503/badge.svg)](https://scan.coverity.com/projects/jcupitt-libvips)
|
||||
[![Gitter](https://badges.gitter.im/libvips/devchat.svg)](https://gitter.im/libvips/devchat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
@ -616,11 +616,22 @@ vips_foreign_load_csv_source_build( VipsObject *object )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_csv_source_is_a_source( VipsSource *source )
|
||||
{
|
||||
/* Detecting CSV files automatically is tricky. Define this method to
|
||||
* prevent a warning, but users will need to run the csv loader
|
||||
* explicitly.
|
||||
*/
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_csv_source_class_init( VipsForeignLoadCsvFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
@ -628,6 +639,8 @@ vips_foreign_load_csv_source_class_init( VipsForeignLoadCsvFileClass *class )
|
||||
object_class->nickname = "csvload_source";
|
||||
object_class->build = vips_foreign_load_csv_source_build;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_csv_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
_( "Source" ),
|
||||
_( "Source to load from" ),
|
||||
|
@ -217,7 +217,9 @@ vips_fits_get_header( VipsFits *fits, VipsImage *out )
|
||||
int status;
|
||||
int bitpix;
|
||||
|
||||
int width, height, bands, format, type;
|
||||
int width, height, bands;
|
||||
VipsBandFormat format;
|
||||
VipsInterpretation interpretation;
|
||||
int keysexist;
|
||||
int i;
|
||||
|
||||
@ -318,24 +320,24 @@ vips_fits_get_header( VipsFits *fits, VipsImage *out )
|
||||
|
||||
if( bands == 1 ) {
|
||||
if( format == VIPS_FORMAT_USHORT )
|
||||
type = VIPS_INTERPRETATION_GREY16;
|
||||
interpretation = VIPS_INTERPRETATION_GREY16;
|
||||
else
|
||||
type = VIPS_INTERPRETATION_B_W;
|
||||
interpretation = VIPS_INTERPRETATION_B_W;
|
||||
}
|
||||
else if( bands == 3 ) {
|
||||
if( format == VIPS_FORMAT_USHORT )
|
||||
type = VIPS_INTERPRETATION_RGB16;
|
||||
interpretation = VIPS_INTERPRETATION_RGB16;
|
||||
else
|
||||
type = VIPS_INTERPRETATION_sRGB;
|
||||
interpretation = VIPS_INTERPRETATION_sRGB;
|
||||
}
|
||||
else
|
||||
type = VIPS_INTERPRETATION_MULTIBAND;
|
||||
interpretation = VIPS_INTERPRETATION_MULTIBAND;
|
||||
|
||||
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL );
|
||||
vips_image_init_fields( out,
|
||||
width, height, bands,
|
||||
format,
|
||||
VIPS_CODING_NONE, type, 1.0, 1.0 );
|
||||
VIPS_CODING_NONE, interpretation, 1.0, 1.0 );
|
||||
|
||||
/* Read all keys into meta.
|
||||
*/
|
||||
@ -517,7 +519,8 @@ int
|
||||
vips__fits_read( const char *filename, VipsImage *out )
|
||||
{
|
||||
VipsImage *t;
|
||||
int n_bands;
|
||||
int bands;
|
||||
VipsInterpretation interpretation;
|
||||
|
||||
VIPS_DEBUG_MSG( "fits2vips: reading \"%s\"\n", filename );
|
||||
|
||||
@ -531,22 +534,26 @@ vips__fits_read( const char *filename, VipsImage *out )
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
}
|
||||
n_bands = t->Bands;
|
||||
bands = t->Bands;
|
||||
interpretation = t->Type;
|
||||
g_object_unref( t );
|
||||
|
||||
if( n_bands == 1 ) {
|
||||
if( bands == 1 ) {
|
||||
if( fits2vips( filename, out, 0 ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
VipsImage **x;
|
||||
VipsImage **y;
|
||||
int i;
|
||||
|
||||
t = vips_image_new();
|
||||
x = (VipsImage **) vips_object_local_array( VIPS_OBJECT( t ),
|
||||
n_bands + 1 );
|
||||
bands );
|
||||
y = (VipsImage **) vips_object_local_array( VIPS_OBJECT( t ),
|
||||
3 );
|
||||
|
||||
for( i = 0; i < n_bands; i++ ) {
|
||||
for( i = 0; i < bands; i++ ) {
|
||||
x[i] = vips_image_new();
|
||||
if( fits2vips( filename, x[i], i ) ) {
|
||||
g_object_unref( t );
|
||||
@ -554,8 +561,11 @@ vips__fits_read( const char *filename, VipsImage *out )
|
||||
}
|
||||
}
|
||||
|
||||
if( vips_bandjoin( x, &x[n_bands], n_bands, NULL ) ||
|
||||
vips_image_write( x[n_bands], out ) ) {
|
||||
if( vips_bandjoin( x, &y[0], bands, NULL ) ||
|
||||
vips_copy( y[0], &y[1],
|
||||
"interpretation", interpretation,
|
||||
NULL ) ||
|
||||
vips_image_write( y[1], out ) ) {
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -55,17 +55,85 @@
|
||||
typedef struct _VipsForeignLoadFits {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
/* Filename for load.
|
||||
/* Set by subclasses.
|
||||
*/
|
||||
char *filename;
|
||||
VipsSource *source;
|
||||
|
||||
/* Filename from source.
|
||||
*/
|
||||
const char *filename;
|
||||
|
||||
} VipsForeignLoadFits;
|
||||
|
||||
typedef VipsForeignLoadClass VipsForeignLoadFitsClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadFits, vips_foreign_load_fits,
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadFits, vips_foreign_load_fits,
|
||||
VIPS_TYPE_FOREIGN_LOAD );
|
||||
|
||||
static void
|
||||
vips_foreign_load_fits_dispose( GObject *gobject )
|
||||
{
|
||||
VipsForeignLoadFits *fits = (VipsForeignLoadFits *) gobject;
|
||||
|
||||
VIPS_UNREF( fits->source );
|
||||
|
||||
G_OBJECT_CLASS( vips_foreign_load_fits_parent_class )->
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_fits_build( VipsObject *object )
|
||||
{
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||
VipsForeignLoadFits *fits =
|
||||
(VipsForeignLoadFits *) object;
|
||||
|
||||
/* We can only open source which have an associated filename, since
|
||||
* the fits library works in terms of filenames.
|
||||
*/
|
||||
if( fits->source ) {
|
||||
fits->filename = vips_connection_filename( VIPS_CONNECTION(
|
||||
fits->source ) );
|
||||
if( !fits->filename ) {
|
||||
vips_error( class->nickname, "%s",
|
||||
_( "no filename available" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_fits_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_fits_get_flags_source( VipsSource *source )
|
||||
{
|
||||
return( VIPS_FOREIGN_PARTIAL );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_fits_get_flags( VipsForeignLoad *load )
|
||||
{
|
||||
return( VIPS_FOREIGN_PARTIAL );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_fits_get_flags_filename( const char *filename )
|
||||
{
|
||||
VipsSource *source;
|
||||
VipsForeignFlags flags;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( 0 );
|
||||
flags = vips_foreign_load_fits_get_flags_source( source );
|
||||
VIPS_UNREF( source );
|
||||
|
||||
return( flags );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_fits_header( VipsForeignLoad *load )
|
||||
{
|
||||
@ -103,32 +171,167 @@ vips_foreign_load_fits_class_init( VipsForeignLoadFitsClass *class )
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_foreign_load_fits_dispose;
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "fitsload";
|
||||
object_class->description = _( "load a FITS image" );
|
||||
object_class->nickname = "fitsload_base";
|
||||
object_class->description = _( "FITS loader base class" );
|
||||
object_class->build = vips_foreign_load_fits_build;
|
||||
|
||||
/* is_a() is not that quick ... lower the priority.
|
||||
*/
|
||||
foreign_class->priority = -50;
|
||||
|
||||
foreign_class->suffs = vips__fits_suffs;
|
||||
|
||||
load_class->get_flags_filename =
|
||||
vips_foreign_load_fits_get_flags_filename;
|
||||
load_class->get_flags = vips_foreign_load_fits_get_flags;
|
||||
load_class->is_a = vips__fits_isfits;
|
||||
load_class->header = vips_foreign_load_fits_header;
|
||||
load_class->load = vips_foreign_load_fits_load;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_fits_init( VipsForeignLoadFits *fits )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadFitsFile {
|
||||
VipsForeignLoadFits parent_object;
|
||||
|
||||
/* Filename for load.
|
||||
*/
|
||||
char *filename;
|
||||
|
||||
} VipsForeignLoadFitsFile;
|
||||
|
||||
typedef VipsForeignLoadFitsClass VipsForeignLoadFitsFileClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadFitsFile, vips_foreign_load_fits_file,
|
||||
vips_foreign_load_fits_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_load_fits_file_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignLoadFits *fits = (VipsForeignLoadFits *) object;
|
||||
VipsForeignLoadFitsFile *file = (VipsForeignLoadFitsFile *) object;
|
||||
|
||||
if( file->filename &&
|
||||
!(fits->source = vips_source_new_from_file( file->filename )) )
|
||||
return( -1 );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_fits_file_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_fits_file_class_init( VipsForeignLoadFitsFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "fitsload";
|
||||
object_class->description = _( "load a FITS image" );
|
||||
object_class->build = vips_foreign_load_fits_file_build;
|
||||
|
||||
foreign_class->suffs = vips__fits_suffs;
|
||||
|
||||
load_class->is_a = vips__fits_isfits;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadFits, filename ),
|
||||
G_STRUCT_OFFSET( VipsForeignLoadFitsFile, filename ),
|
||||
NULL );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_fits_init( VipsForeignLoadFits *fits )
|
||||
vips_foreign_load_fits_file_init( VipsForeignLoadFitsFile *file )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadFitsSource {
|
||||
VipsForeignLoadFits parent_object;
|
||||
|
||||
/* Load from a source.
|
||||
*/
|
||||
VipsSource *source;
|
||||
|
||||
} VipsForeignLoadFitsSource;
|
||||
|
||||
typedef VipsForeignLoadFitsClass VipsForeignLoadFitsSourceClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadFitsSource, vips_foreign_load_fits_source,
|
||||
vips_foreign_load_fits_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_load_fits_source_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignLoadFits *fits = (VipsForeignLoadFits *) object;
|
||||
VipsForeignLoadFitsSource *source =
|
||||
(VipsForeignLoadFitsSource *) object;
|
||||
|
||||
if( source->source ) {
|
||||
fits->source = source->source;
|
||||
g_object_ref( fits->source );
|
||||
}
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_fits_source_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_fits_source_is_a_source( VipsSource *source )
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
return( (filename =
|
||||
vips_connection_filename( VIPS_CONNECTION( source ) )) &&
|
||||
vips__fits_isfits( filename ) );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_fits_source_class_init(
|
||||
VipsForeignLoadFitsSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "fitsload_source";
|
||||
object_class->description = _( "load FITS from a source" );
|
||||
object_class->build = vips_foreign_load_fits_source_build;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_fits_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
_( "Source" ),
|
||||
_( "Source to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadFitsSource, source ),
|
||||
VIPS_TYPE_SOURCE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_fits_source_init( VipsForeignLoadFitsSource *fits )
|
||||
{
|
||||
}
|
||||
|
||||
@ -166,3 +369,26 @@ vips_fitsload( const char *filename, VipsImage **out, ... )
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_fitsload_source:
|
||||
* @source: source to load from
|
||||
* @out: (out): decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Exactly as vips_fitsload(), but read from a source.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_fitsload_source( VipsSource *source, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "fitsload_source", ap, source, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -2117,7 +2117,8 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_save_matrix_target_get_type( void );
|
||||
extern GType vips_foreign_print_matrix_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_fits_get_type( void );
|
||||
extern GType vips_foreign_load_fits_file_get_type( void );
|
||||
extern GType vips_foreign_load_fits_source_get_type( void );
|
||||
extern GType vips_foreign_save_fits_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_analyze_get_type( void );
|
||||
@ -2182,7 +2183,8 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_save_heif_buffer_get_type( void );
|
||||
extern GType vips_foreign_save_heif_target_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_nifti_get_type( void );
|
||||
extern GType vips_foreign_load_nifti_file_get_type( void );
|
||||
extern GType vips_foreign_load_nifti_source_get_type( void );
|
||||
extern GType vips_foreign_save_nifti_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_gif_file_get_type( void );
|
||||
@ -2324,7 +2326,8 @@ vips_foreign_operation_init( void )
|
||||
#endif /*ENABLE_MAGICKSAVE*/
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
vips_foreign_load_fits_get_type();
|
||||
vips_foreign_load_fits_file_get_type();
|
||||
vips_foreign_load_fits_source_get_type();
|
||||
vips_foreign_save_fits_get_type();
|
||||
#endif /*HAVE_CFITSIO*/
|
||||
|
||||
@ -2333,7 +2336,8 @@ vips_foreign_operation_init( void )
|
||||
#endif /*HAVE_OPENEXR*/
|
||||
|
||||
#ifdef HAVE_NIFTI
|
||||
vips_foreign_load_nifti_get_type();
|
||||
vips_foreign_load_nifti_file_get_type();
|
||||
vips_foreign_load_nifti_source_get_type();
|
||||
vips_foreign_save_nifti_get_type();
|
||||
#endif /*HAVE_NIFTI*/
|
||||
|
||||
|
@ -74,9 +74,13 @@
|
||||
typedef struct _VipsForeignLoadNifti {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
/* Filename for load.
|
||||
/* Source to load from (set by subclasses).
|
||||
*/
|
||||
char *filename;
|
||||
VipsSource *source;
|
||||
|
||||
/* Filename from source.
|
||||
*/
|
||||
const char *filename;
|
||||
|
||||
/* The NIFTI image loaded to memory.
|
||||
*/
|
||||
@ -99,6 +103,7 @@ vips_foreign_load_nifti_dispose( GObject *gobject )
|
||||
{
|
||||
VipsForeignLoadNifti *nifti = (VipsForeignLoadNifti *) gobject;
|
||||
|
||||
VIPS_UNREF( nifti->source );
|
||||
VIPS_UNREF( nifti->memory );
|
||||
VIPS_FREEF( nifti_image_free, nifti->nim );
|
||||
|
||||
@ -107,38 +112,27 @@ vips_foreign_load_nifti_dispose( GObject *gobject )
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_nifti_is_a( const char *filename )
|
||||
vips_foreign_load_nifti_build( VipsObject *object )
|
||||
{
|
||||
char *hfile;
|
||||
znzFile fp;
|
||||
nifti_1_header nhdr;
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||
VipsForeignLoadNifti *nifti = (VipsForeignLoadNifti *) object;
|
||||
|
||||
/* Unfortunately is_nifti_file() is very slow and produces lots of
|
||||
* output. We have to make our own.
|
||||
/* We can only open source which have an associated filename, since
|
||||
* the nifti library works in terms of filenames.
|
||||
*/
|
||||
|
||||
if( !(hfile = nifti_findhdrname( filename )) )
|
||||
return( 0 );
|
||||
|
||||
fp = znzopen( hfile, "rb", nifti_is_gzfile( hfile ));
|
||||
if( znz_isnull( fp ) ) {
|
||||
free( hfile );
|
||||
return( 0 );
|
||||
if( nifti->source ) {
|
||||
nifti->filename = vips_connection_filename( VIPS_CONNECTION(
|
||||
nifti->source ) );
|
||||
if( !nifti->filename ) {
|
||||
vips_error( class->nickname, "%s",
|
||||
_( "no filename available" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
free( hfile );
|
||||
|
||||
(void) znzread( &nhdr, 1, sizeof( nhdr ), fp );
|
||||
|
||||
znzclose( fp );
|
||||
|
||||
/* Test for sanity both ways around. There's a thing to test for byte
|
||||
* order in niftilib, but it's static :(
|
||||
*/
|
||||
if( nifti_hdr_looks_good( &nhdr ) )
|
||||
return( 1 );
|
||||
swap_nifti_header( &nhdr, FALSE );
|
||||
if( nifti_hdr_looks_good( &nhdr ) )
|
||||
return( 1 );
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_nifti_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -576,14 +570,6 @@ vips_foreign_load_nifti_load( VipsForeignLoad *load )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
const char *vips__nifti_suffs[] = {
|
||||
".nii", ".nii.gz",
|
||||
".hdr", ".hdr.gz",
|
||||
".img", ".img.gz",
|
||||
".nia", ".nia.gz",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
vips_foreign_load_nifti_class_init( VipsForeignLoadNiftiClass *class )
|
||||
{
|
||||
@ -596,29 +582,208 @@ vips_foreign_load_nifti_class_init( VipsForeignLoadNiftiClass *class )
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "niftiload";
|
||||
object_class->nickname = "niftiload_base";
|
||||
object_class->description = _( "load a NIFTI image" );
|
||||
object_class->build = vips_foreign_load_nifti_build;
|
||||
|
||||
/* is_a() is not that quick ... lower the priority.
|
||||
*/
|
||||
foreign_class->priority = -50;
|
||||
|
||||
foreign_class->suffs = vips__nifti_suffs;
|
||||
|
||||
load_class->is_a = vips_foreign_load_nifti_is_a;
|
||||
load_class->header = vips_foreign_load_nifti_header;
|
||||
load_class->load = vips_foreign_load_nifti_load;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_nifti_init( VipsForeignLoadNifti *nifti )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadNiftiFile {
|
||||
VipsForeignLoadNifti parent_object;
|
||||
|
||||
/* Filename for load.
|
||||
*/
|
||||
char *filename;
|
||||
|
||||
} VipsForeignLoadNiftiFile;
|
||||
|
||||
typedef VipsForeignLoadNiftiClass VipsForeignLoadNiftiFileClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadNiftiFile, vips_foreign_load_nifti_file,
|
||||
vips_foreign_load_nifti_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_load_nifti_file_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignLoadNifti *nifti = (VipsForeignLoadNifti *) object;
|
||||
VipsForeignLoadNiftiFile *file = (VipsForeignLoadNiftiFile *) object;
|
||||
|
||||
if( file->filename &&
|
||||
!(nifti->source =
|
||||
vips_source_new_from_file( file->filename )) )
|
||||
return( -1 );
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_nifti_file_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
const char *vips_foreign_nifti_suffs[] = {
|
||||
".nii", ".nii.gz",
|
||||
".hdr", ".hdr.gz",
|
||||
".img", ".img.gz",
|
||||
".nia", ".nia.gz",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
vips_foreign_load_nifti_is_a( const char *filename )
|
||||
{
|
||||
char *hfile;
|
||||
znzFile fp;
|
||||
nifti_1_header nhdr;
|
||||
|
||||
/* Unfortunately is_nifti_file() is very slow and produces lots of
|
||||
* output. We have to make our own.
|
||||
*/
|
||||
|
||||
if( !(hfile = nifti_findhdrname( filename )) )
|
||||
return( 0 );
|
||||
|
||||
fp = znzopen( hfile, "rb", nifti_is_gzfile( hfile ));
|
||||
if( znz_isnull( fp ) ) {
|
||||
free( hfile );
|
||||
return( 0 );
|
||||
}
|
||||
free( hfile );
|
||||
|
||||
(void) znzread( &nhdr, 1, sizeof( nhdr ), fp );
|
||||
|
||||
znzclose( fp );
|
||||
|
||||
/* Test for sanity both ways around. There's a thing to test for byte
|
||||
* order in niftilib, but it's static :(
|
||||
*/
|
||||
if( nifti_hdr_looks_good( &nhdr ) )
|
||||
return( 1 );
|
||||
swap_nifti_header( &nhdr, FALSE );
|
||||
if( nifti_hdr_looks_good( &nhdr ) )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_nifti_file_class_init(
|
||||
VipsForeignLoadNiftiFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "niftiload";
|
||||
object_class->description = _( "load NIfTI volume" );
|
||||
object_class->build = vips_foreign_load_nifti_file_build;
|
||||
|
||||
foreign_class->suffs = vips_foreign_nifti_suffs;
|
||||
|
||||
load_class->is_a = vips_foreign_load_nifti_is_a;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadNifti, filename ),
|
||||
G_STRUCT_OFFSET( VipsForeignLoadNiftiFile, filename ),
|
||||
NULL );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_nifti_init( VipsForeignLoadNifti *nifti )
|
||||
vips_foreign_load_nifti_file_init( VipsForeignLoadNiftiFile *nifti )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadNiftiSource {
|
||||
VipsForeignLoadNifti parent_object;
|
||||
|
||||
/* Load from a source.
|
||||
*/
|
||||
VipsSource *source;
|
||||
|
||||
} VipsForeignLoadNiftiSource;
|
||||
|
||||
typedef VipsForeignLoadNiftiClass VipsForeignLoadNiftiSourceClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadNiftiSource, vips_foreign_load_nifti_source,
|
||||
vips_foreign_load_nifti_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_load_nifti_source_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignLoadNifti *nifti = (VipsForeignLoadNifti *) object;
|
||||
VipsForeignLoadNiftiSource *source =
|
||||
(VipsForeignLoadNiftiSource *) object;
|
||||
|
||||
if( source->source ) {
|
||||
nifti->source = source->source;
|
||||
g_object_ref( nifti->source );
|
||||
}
|
||||
|
||||
if( VIPS_OBJECT_CLASS(
|
||||
vips_foreign_load_nifti_source_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_nifti_source_is_a_source( VipsSource *source )
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
return( (filename =
|
||||
vips_connection_filename( VIPS_CONNECTION( source ) )) &&
|
||||
vips_foreign_load_nifti_is_a( filename ) );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_nifti_source_class_init(
|
||||
VipsForeignLoadNiftiSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "niftiload_source";
|
||||
object_class->description = _( "load NIfTI volumes" );
|
||||
object_class->build = vips_foreign_load_nifti_source_build;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_nifti_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
_( "Source" ),
|
||||
_( "Source to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadNiftiSource, source ),
|
||||
VIPS_TYPE_SOURCE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_nifti_source_init(
|
||||
VipsForeignLoadNiftiSource *nifti )
|
||||
{
|
||||
}
|
||||
|
||||
@ -650,3 +815,26 @@ vips_niftiload( const char *filename, VipsImage **out, ... )
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_niftiload_source:
|
||||
* @source: source to load from
|
||||
* @out: (out): decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Exactly as vips_niftiload(), but read from a source.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_niftiload_source( VipsSource *source, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "niftiload_source", ap, source, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ vips_foreign_save_nifti_class_init( VipsForeignSaveNiftiClass *class )
|
||||
object_class->description = _( "save image to nifti file" );
|
||||
object_class->build = vips_foreign_save_nifti_build;
|
||||
|
||||
foreign_class->suffs = vips__nifti_suffs;
|
||||
foreign_class->suffs = vips_foreign_nifti_suffs;
|
||||
|
||||
save_class->saveable = VIPS_SAVEABLE_ANY;
|
||||
save_class->format_table = vips_nifti_bandfmt;
|
||||
|
@ -229,7 +229,7 @@ int vips__quantise_image( VipsImage *in,
|
||||
VipsImage **index_out, VipsImage **palette_out,
|
||||
int colours, int Q, double dither );
|
||||
|
||||
extern const char *vips__nifti_suffs[];
|
||||
extern const char *vips_foreign_nifti_suffs[];
|
||||
|
||||
VipsBandFormat vips__foreign_nifti_datatype2BandFmt( int datatype );
|
||||
int vips__foreign_nifti_BandFmt2datatype( VipsBandFormat fmt );
|
||||
|
@ -80,13 +80,6 @@
|
||||
*/
|
||||
#define RSVG_MAX_WIDTH (32767)
|
||||
|
||||
/* Old librsvg versions don't include librsvg-features.h by default.
|
||||
* Newer versions deprecate direct inclusion.
|
||||
*/
|
||||
#ifndef LIBRSVG_FEATURES_H
|
||||
#include <librsvg/librsvg-features.h>
|
||||
#endif
|
||||
|
||||
/* A handy #define for we-will-handle-svgz.
|
||||
*/
|
||||
#if LIBRSVG_CHECK_FEATURE(SVGZ) && defined(HAVE_ZLIB)
|
||||
|
@ -33,11 +33,12 @@
|
||||
#ifndef IM_DISPATCH_H
|
||||
#define IM_DISPATCH_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <vips/vips.h>
|
||||
#include <vips/util.h>
|
||||
|
||||
|
@ -671,6 +671,8 @@ int vips_heifsave_target( VipsImage *in, VipsTarget *target, ... )
|
||||
|
||||
int vips_niftiload( const char *filename, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_niftiload_source( VipsSource *source, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_niftisave( VipsImage *in, const char *filename, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
@ -114,9 +114,9 @@ void vips__threadpool_init( void );
|
||||
|
||||
void vips__cache_init( void );
|
||||
|
||||
void vips__print_renders( void );
|
||||
|
||||
void vips__type_leak( void );
|
||||
int vips__print_renders( void );
|
||||
int vips__type_leak( void );
|
||||
int vips__object_leak( void );
|
||||
|
||||
typedef int (*im__fftproc_fn)( VipsImage *, VipsImage *, VipsImage * );
|
||||
int im__fftproc( VipsImage *dummy,
|
||||
|
@ -80,10 +80,6 @@
|
||||
#ifndef VIPS_VIPS_H
|
||||
#define VIPS_VIPS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gmodule.h>
|
||||
@ -93,6 +89,10 @@ extern "C" {
|
||||
*/
|
||||
#include <gio/gio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/* If we're being parsed by SWIG, remove gcc attributes.
|
||||
*/
|
||||
#ifdef SWIG
|
||||
|
@ -200,7 +200,7 @@ vips_error_buffer_copy( void )
|
||||
|
||||
g_mutex_lock( vips__global_lock );
|
||||
msg = g_strdup( vips_buf_all( &vips_error_buf ) );
|
||||
vips_error_clear();
|
||||
vips_buf_rewind( &vips_error_buf );
|
||||
g_mutex_unlock( vips__global_lock );
|
||||
|
||||
return( msg );
|
||||
|
@ -643,13 +643,20 @@ vips_check_init( void )
|
||||
vips_error_clear();
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
vips_leak( void )
|
||||
{
|
||||
char txt[1024];
|
||||
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
||||
int n_leaks;
|
||||
|
||||
vips_object_print_all();
|
||||
n_leaks = 0;
|
||||
|
||||
n_leaks += vips__object_leak();
|
||||
n_leaks += vips__type_leak();
|
||||
n_leaks += vips_tracked_get_allocs();
|
||||
n_leaks += vips_tracked_get_mem();
|
||||
n_leaks += vips_tracked_get_files();
|
||||
|
||||
if( vips_tracked_get_allocs() ||
|
||||
vips_tracked_get_mem() ||
|
||||
@ -664,21 +671,27 @@ vips_leak( void )
|
||||
vips_buf_append_size( &buf, vips_tracked_get_mem_highwater() );
|
||||
vips_buf_appends( &buf, "\n" );
|
||||
|
||||
if( strlen( vips_error_buffer() ) > 0 )
|
||||
if( strlen( vips_error_buffer() ) > 0 ) {
|
||||
vips_buf_appendf( &buf, "error buffer: %s",
|
||||
vips_error_buffer() );
|
||||
n_leaks += strlen( vips_error_buffer() );
|
||||
}
|
||||
|
||||
if( vips__n_active_threads > 0 )
|
||||
if( vips__n_active_threads > 0 ) {
|
||||
vips_buf_appendf( &buf, "threads: %d not joined\n",
|
||||
vips__n_active_threads );
|
||||
n_leaks += vips__n_active_threads;
|
||||
}
|
||||
|
||||
fprintf( stderr, "%s", vips_buf_all( &buf ) );
|
||||
|
||||
vips__print_renders();
|
||||
n_leaks += vips__print_renders();
|
||||
|
||||
#ifdef DEBUG
|
||||
vips_buffer_dump_all();
|
||||
#endif /*DEBUG*/
|
||||
|
||||
return( n_leaks );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -755,8 +768,9 @@ vips_shutdown( void )
|
||||
{
|
||||
static gboolean done = FALSE;
|
||||
|
||||
if( !done )
|
||||
vips_leak();
|
||||
if( !done &&
|
||||
vips_leak() )
|
||||
exit( 1 );
|
||||
|
||||
done = TRUE;
|
||||
}
|
||||
|
@ -3167,23 +3167,34 @@ vips_object_print_all_cb( VipsObject *object, int *n, void *b )
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
void
|
||||
vips_object_print_all( void )
|
||||
int
|
||||
vips__object_leak( void )
|
||||
{
|
||||
int n_leaks;
|
||||
|
||||
n_leaks = 0;
|
||||
|
||||
/* Don't count static objects.
|
||||
*/
|
||||
if( vips__object_all &&
|
||||
g_hash_table_size( vips__object_all ) >
|
||||
vips_object_n_static() ) {
|
||||
int n;
|
||||
|
||||
fprintf( stderr, "%d objects alive:\n",
|
||||
g_hash_table_size( vips__object_all ) );
|
||||
|
||||
n = 0;
|
||||
vips_object_map(
|
||||
(VipsSListMap2Fn) vips_object_print_all_cb, &n, NULL );
|
||||
(VipsSListMap2Fn) vips_object_print_all_cb,
|
||||
&n_leaks, NULL );
|
||||
}
|
||||
|
||||
vips__type_leak();
|
||||
return( n_leaks );
|
||||
}
|
||||
|
||||
void
|
||||
vips_object_print_all( void )
|
||||
{
|
||||
(void) vips__object_leak();
|
||||
(void) vips__type_leak();
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -1146,23 +1146,29 @@ vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
vips__print_renders( void )
|
||||
{
|
||||
int n_leaks;
|
||||
|
||||
n_leaks = 0;
|
||||
|
||||
#ifdef VIPS_DEBUG_AMBER
|
||||
if( render_num_renders > 0 )
|
||||
if( render_num_renders > 0 ) {
|
||||
printf( "%d active renders\n", render_num_renders );
|
||||
n_leaks += render_num_renders;
|
||||
}
|
||||
#endif /*VIPS_DEBUG_AMBER*/
|
||||
|
||||
if( render_dirty_lock ) {
|
||||
int n_dirty;
|
||||
|
||||
g_mutex_lock( render_dirty_lock );
|
||||
|
||||
n_dirty = g_slist_length( render_dirty_all );
|
||||
if( n_dirty > 0 )
|
||||
printf( "%d dirty renders\n", n_dirty );
|
||||
n_leaks += g_slist_length( render_dirty_all );
|
||||
if( render_dirty_all )
|
||||
printf( "dirty renders\n" );
|
||||
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
}
|
||||
|
||||
return( n_leaks );
|
||||
}
|
||||
|
@ -285,9 +285,13 @@ vips_area_new( VipsCallbackFn free_fn, void *data )
|
||||
return( area );
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
vips__type_leak( void )
|
||||
{
|
||||
int n_leaks;
|
||||
|
||||
n_leaks = 0;
|
||||
|
||||
if( vips_area_all ) {
|
||||
GSList *p;
|
||||
|
||||
@ -298,8 +302,12 @@ vips__type_leak( void )
|
||||
|
||||
fprintf( stderr, "\t%p count = %d, bytes = %zd\n",
|
||||
area, area->count, area->length );
|
||||
|
||||
n_leaks += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return( n_leaks );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,5 +3,6 @@ leak:python3
|
||||
leak:bash
|
||||
leak:libfontconfig.so
|
||||
leak:libglib-2.0.so
|
||||
leak:libIlmImf-2_2.so
|
||||
leak:libIlmImf-2_3.so
|
||||
leak:libIlmThread-2_3.so
|
||||
leak:libstdc++.so
|
||||
|
Loading…
Reference in New Issue
Block a user