add --with-gmic configure option
This commit is contained in:
parent
ea2d6e5283
commit
ca2ae681cd
@ -15,8 +15,7 @@
|
||||
- better extra band handling by colour, again
|
||||
- move zoomify ImageProperties file, now a better match to the offical tool
|
||||
- rename VIPS_ANGLE_180 as VIPS_ANGLE_D180 etc. to help python
|
||||
- update cimg
|
||||
- add gmic
|
||||
- update cimg, add gmic, plus a configure option to turn it on
|
||||
|
||||
8/9/14 started 7.40.10
|
||||
- icc_import and icc_transform checks the input profile for compatibility
|
||||
|
8
TODO
8
TODO
@ -1,3 +1,11 @@
|
||||
- im_greyc_mask compat is not working?
|
||||
|
||||
vips im_greyc_mask k2.jpg x.jpg k4.jpg 1 100 0.5 0.5 0.5 0.5 0.5 0.5 1
|
||||
1 1
|
||||
|
||||
vips_gmic_gen is never called
|
||||
|
||||
|
||||
- python:
|
||||
|
||||
- could import like this:
|
||||
|
16
configure.ac
16
configure.ac
@ -665,6 +665,19 @@ if test x"$with_pangoft2" != "xno"; then
|
||||
])
|
||||
fi
|
||||
|
||||
# g'mic ... embedding the gmic interpreter needs a C++ compiler and a lot of
|
||||
# patience. And tolerance for huge object files.
|
||||
AC_ARG_WITH([gmic],
|
||||
AS_HELP_STRING([--with-gmic], [build with gmic (default: no)]))
|
||||
|
||||
if test x"$with_gmic" == "xyes"; then
|
||||
AC_DEFINE(HAVE_GMIC,1,[define to enable the gmic interpreter.])
|
||||
AM_CONDITIONAL(ENABLE_GMIC, true)
|
||||
else
|
||||
AM_CONDITIONAL(ENABLE_GMIC, false)
|
||||
with_gmic=no
|
||||
fi
|
||||
|
||||
# hmm, these don't have .pc files on ubuntu 5.10, how odd
|
||||
FIND_ZIP(
|
||||
[with_zip=yes],
|
||||
@ -869,4 +882,5 @@ file import/export with libjpeg: $with_jpeg
|
||||
image pyramid export: $with_gsf
|
||||
(requires libgsf-1 1.14.27 or later)
|
||||
use libexif to load/save JPEG metadata: $with_libexif
|
||||
build Python binding: $with_python])
|
||||
build Python binding: $with_python
|
||||
embed gmic interpreter: $with_gmic])
|
||||
|
@ -1,11 +1,20 @@
|
||||
noinst_LTLIBRARIES = libcimg.la
|
||||
|
||||
OPTIONAL_SRC =
|
||||
OPTIONAL_DIST =
|
||||
|
||||
if ENABLE_GMIC
|
||||
OPTIONAL_SRC += vips_gmic.cpp gmic.cpp
|
||||
else
|
||||
OPTIONAL_DIST += vips_gmic.cpp gmic.cpp
|
||||
endif
|
||||
|
||||
libcimg_la_SOURCES = \
|
||||
CImg.h \
|
||||
cimg_dispatch.c \
|
||||
cimg.cpp \
|
||||
vips_gmic.cpp \
|
||||
gmic.cpp
|
||||
gmic_def.h \
|
||||
gmic.h \
|
||||
cimg.c \
|
||||
$(OPTIONAL_SRC)
|
||||
|
||||
# various cimg settings as well
|
||||
# display=0 means don't build the cimg display stuff
|
||||
@ -31,6 +40,8 @@ AM_CPPFLAGS = \
|
||||
endif
|
||||
|
||||
# used by the final libvips link rather than us
|
||||
EXTRA_DIST = dummy2.cc
|
||||
EXTRA_DIST = \
|
||||
dummy2.cc \
|
||||
$(OPTIONAL_DIST)
|
||||
|
||||
AM_CPPFLAGS += -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
|
||||
|
95
libvips/cimg/cimg.c
Normal file
95
libvips/cimg/cimg.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* pass images through gmic
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright (C) 1991-2005 The National Gallery
|
||||
|
||||
This library 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.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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 library; 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
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
/**
|
||||
* SECTION: cimg
|
||||
* @short_description: pass images through the gmic interpreter
|
||||
* @see_also: <link linkend="libvips-boolean">boolean</link>
|
||||
* @stability: Stable
|
||||
* @include: vips/vips.h
|
||||
*
|
||||
* Pass images through the gmic interpreter.
|
||||
*/
|
||||
|
||||
/**
|
||||
* vips_gmic:
|
||||
* @in: (array length=n) (transfer none): array of input images
|
||||
* @out: output image
|
||||
* @n: number of input images
|
||||
* @padding: overlap tiles by this much
|
||||
* @x_scale:
|
||||
* @y_scale:
|
||||
* @command: command to execute
|
||||
*
|
||||
* Returns: 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
vips_gmic( VipsImage **in, VipsImage **out, int n,
|
||||
int padding, double x_scale, double y_scale, const char *command, ... )
|
||||
{
|
||||
VipsArrayImage *array;
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
array = vips_array_image_new( in, n );
|
||||
va_start( ap, command );
|
||||
result = vips_call_split( "gmic", ap, array, out,
|
||||
padding, x_scale, y_scale, command );
|
||||
va_end( ap );
|
||||
vips_area_unref( VIPS_AREA( array ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/* Called from iofuncs to init all operations in this dir. Use a plugin system
|
||||
* instead?
|
||||
*/
|
||||
void
|
||||
vips_cimg_operation_init( void )
|
||||
{
|
||||
#ifdef HAVE_GMIC
|
||||
extern GType vips_gmic_get_type( void );
|
||||
#endif /*HAVE_GMIC*/
|
||||
|
||||
#ifdef HAVE_GMIC
|
||||
vips_gmic_get_type();
|
||||
#endif /*HAVE_GMIC*/
|
||||
}
|
@ -1,288 +0,0 @@
|
||||
/* Pass VIPS images through CImg
|
||||
*
|
||||
* JC, 15/10/07
|
||||
* 29/4/10
|
||||
* - oop, should be smalltile, probably
|
||||
* - tiny cleanups
|
||||
* - gtkdoc
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
/* CImg needs to call pthread directly, this is the preproc magic they
|
||||
* prefer.
|
||||
*/
|
||||
#if defined(sun) || defined(__sun) || defined(linux) || defined(__linux) \
|
||||
|| defined(__linux__) || defined(__CYGWIN__) || defined(BSD) || defined(__FreeBSD__) \
|
||||
|| defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__) || defined(sgi) \
|
||||
|| defined(__sgi)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "CImg.h"
|
||||
using namespace cimg_library;
|
||||
|
||||
/* Save params here.
|
||||
*/
|
||||
struct Greyc {
|
||||
IMAGE *in;
|
||||
IMAGE *out;
|
||||
IMAGE *mask;
|
||||
IMAGE **arry;
|
||||
|
||||
int iterations;
|
||||
float amplitude;
|
||||
float dl;
|
||||
float da;
|
||||
float gauss_prec;
|
||||
int interpolation;
|
||||
bool fast_approx;
|
||||
};
|
||||
|
||||
// copy part of a vips region into a cimg
|
||||
template<typename T> static CImg<T> *
|
||||
vips_to_cimg( REGION *in, Rect *area )
|
||||
{
|
||||
IMAGE *im = in->im;
|
||||
CImg<T> *img = new CImg<T>( area->width, area->height, 1, im->Bands );
|
||||
|
||||
for( int y = 0; y < area->height; y++ ) {
|
||||
T *p = (T *) IM_REGION_ADDR( in, area->left, area->top + y );
|
||||
|
||||
for( int x = 0; x < area->width; x++ ) {
|
||||
for( int z = 0; z < im->Bands; z++ )
|
||||
(*img)( x, y, z ) = p[z];
|
||||
|
||||
p += im->Bands;
|
||||
}
|
||||
}
|
||||
|
||||
return( img );
|
||||
}
|
||||
|
||||
// write a CImg to a vips region
|
||||
// fill out->valid, img has pixels in img_rect
|
||||
template<typename T> static void
|
||||
cimg_to_vips( CImg<T> *img, Rect *img_rect, REGION *out )
|
||||
{
|
||||
IMAGE *im = out->im;
|
||||
Rect *valid = &out->valid;
|
||||
|
||||
g_assert( im_rect_includesrect( img_rect, valid ) );
|
||||
|
||||
int x_off = valid->left - img_rect->left;
|
||||
int y_off = valid->top - img_rect->top;
|
||||
|
||||
for( int y = 0; y < valid->height; y++ ) {
|
||||
T *p = (T *) IM_REGION_ADDR( out, valid->left, valid->top + y );
|
||||
|
||||
for( int x = 0; x < valid->width; x++ ) {
|
||||
for( int z = 0; z < im->Bands; z++ )
|
||||
p[z] = static_cast<T>( (*img)(
|
||||
x + x_off, y + y_off, z ) );
|
||||
|
||||
p += im->Bands;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> static int
|
||||
greyc_gen( REGION *out, REGION **in, IMAGE **arry, Greyc *greyc )
|
||||
{
|
||||
static const int tile_border = 4;
|
||||
|
||||
Rect *ir = &out->valid;
|
||||
Rect need;
|
||||
Rect image;
|
||||
|
||||
CImg<T> *img;
|
||||
CImg<unsigned char> *msk;
|
||||
|
||||
need = *ir;
|
||||
im_rect_marginadjust( &need, tile_border );
|
||||
image.left = 0;
|
||||
image.top = 0;
|
||||
image.width = in[0]->im->Xsize;
|
||||
image.height = in[0]->im->Ysize;
|
||||
im_rect_intersectrect( &need, &image, &need );
|
||||
if( im_prepare( in[0], &need ) )
|
||||
return( -1 );
|
||||
if( in[1] && im_prepare( in[1], &need ) )
|
||||
return( -1 );
|
||||
|
||||
img = NULL;
|
||||
msk = NULL;
|
||||
|
||||
try {
|
||||
img = vips_to_cimg<T>( in[0], &need );
|
||||
if( in[1] )
|
||||
msk = vips_to_cimg<unsigned char>( in[1], &need );
|
||||
else
|
||||
// empty mask
|
||||
msk = new CImg<unsigned char>();
|
||||
|
||||
for( int i = 0; i < greyc->iterations; i++ )
|
||||
img->blur_anisotropic( *msk,
|
||||
greyc->amplitude,
|
||||
greyc->dl, greyc->da, greyc->gauss_prec,
|
||||
greyc->interpolation, greyc->fast_approx );
|
||||
|
||||
cimg_to_vips<T>( img, &need, out );
|
||||
}
|
||||
catch( CImgException e ) {
|
||||
if( img )
|
||||
delete( img );
|
||||
if( msk )
|
||||
delete( msk );
|
||||
|
||||
im_error( "GREYCstoration", "%s", e.what() );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( img )
|
||||
delete( img );
|
||||
if( msk )
|
||||
delete( msk );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
// Hmm, strange double-cast needed
|
||||
typedef int (*generate_fn)( REGION *out, REGION **in,
|
||||
IMAGE **im, Greyc *greyc );
|
||||
|
||||
// as a plain C function
|
||||
/**
|
||||
* im_greyc_mask:
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
* @mask: input mask
|
||||
* @iterations: number of iterations to perform (eg. 1)
|
||||
* @amplitude: scaling factor (eg. 40)
|
||||
* @sharpness: (unused)
|
||||
* @anisotropy: (unused)
|
||||
* @alpha: (unused)
|
||||
* @sigma: (unused)
|
||||
* @dl: spatial integration step (eg. 0.8)
|
||||
* @da: angular integration step (eg. 30)
|
||||
* @gauss_prec: precision (eg. 2)
|
||||
* @interpolation: interpolation (eg. 0 for nearest-neighbour)
|
||||
*
|
||||
* This operation calls the blur_anisotropic() method of the CImag image
|
||||
* processing library. It is handy for denoising images and for upscaling.
|
||||
*
|
||||
* See also: im_conv().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_greyc_mask( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||
int iterations,
|
||||
float amplitude, float sharpness, float anisotropy,
|
||||
float alpha, float sigma,
|
||||
float dl, float da, float gauss_prec,
|
||||
int interpolation, int fast_approx )
|
||||
{
|
||||
IMAGE **arry;
|
||||
Greyc *greyc;
|
||||
|
||||
if( im_piocheck( in, out ) ||
|
||||
im_check_uncoded( "im_greyc_mask", in ) ||
|
||||
im_check_u8or16orf( "im_greyc_mask", in ) )
|
||||
return( -1 );
|
||||
if( mask ) {
|
||||
if( im_pincheck( mask ) ||
|
||||
im_check_uncoded( "im_greyc_mask", mask ) ||
|
||||
im_check_size_same( "im_greyc_mask", in, mask ) ||
|
||||
im_check_format( "im_greyc_mask",
|
||||
mask, IM_BANDFMT_UCHAR ) )
|
||||
return( -1 );
|
||||
}
|
||||
if( im_cp_desc( out, in ) ||
|
||||
!(arry = im_allocate_input_array( out, in, mask, NULL )) ||
|
||||
!(greyc = IM_NEW( out, Greyc )) ||
|
||||
im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
greyc->in = in;
|
||||
greyc->out = out;
|
||||
greyc->mask = mask;
|
||||
greyc->arry = arry;
|
||||
greyc->iterations = iterations;
|
||||
greyc->amplitude = amplitude;
|
||||
greyc->dl = dl;
|
||||
greyc->da = da;
|
||||
greyc->gauss_prec = gauss_prec;
|
||||
greyc->interpolation = interpolation;
|
||||
greyc->fast_approx = fast_approx;
|
||||
|
||||
switch( in->BandFmt ) {
|
||||
case IM_BANDFMT_UCHAR:
|
||||
if( im_generate( out,
|
||||
im_start_many,
|
||||
// double-cast to give g++ enough context to expand the
|
||||
// template correctly
|
||||
(im_generate_fn) (
|
||||
(generate_fn) greyc_gen<unsigned char>),
|
||||
im_stop_many, arry, greyc ) )
|
||||
return( -1 );
|
||||
break;
|
||||
|
||||
case IM_BANDFMT_USHORT:
|
||||
if( im_generate( out,
|
||||
im_start_many,
|
||||
(im_generate_fn) (
|
||||
(generate_fn) greyc_gen<unsigned short>),
|
||||
im_stop_many, arry, greyc ) )
|
||||
return( -1 );
|
||||
break;
|
||||
|
||||
case IM_BANDFMT_FLOAT:
|
||||
if( im_generate( out,
|
||||
im_start_many,
|
||||
(im_generate_fn) (
|
||||
(generate_fn) greyc_gen<float>),
|
||||
im_stop_many, arry, greyc ) )
|
||||
return( -1 );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
@ -349,21 +349,3 @@ static void
|
||||
vips_gmic_init( VipsGMic *vipsgmic )
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
vips_gmic( VipsImage **in, VipsImage **out, int n,
|
||||
int padding, double x_scale, double y_scale, const char *command, ...)
|
||||
{
|
||||
VipsArrayImage *array;
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
array = vips_array_image_new( in, n );
|
||||
va_start( ap, command );
|
||||
result = vips_call_split( "gmic", ap, array, out,
|
||||
padding, x_scale, y_scale, command );
|
||||
va_end( ap );
|
||||
vips_area_unref( VIPS_AREA( array ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ vips_bandjoinv( VipsImage **in, VipsImage **out, int n, va_list ap )
|
||||
|
||||
/**
|
||||
* vips_bandjoin:
|
||||
* @in: array of input images
|
||||
* @in: (array length=n) (transfer none): array of input images
|
||||
* @out: output image
|
||||
* @n: number of input images
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
|
@ -1,6 +1,7 @@
|
||||
noinst_LTLIBRARIES = libdeprecated.la
|
||||
|
||||
libdeprecated_la_SOURCES = \
|
||||
cimg_dispatch.c \
|
||||
inplace_dispatch.c \
|
||||
tone.c \
|
||||
freq_dispatch.c \
|
||||
|
@ -5343,3 +5343,29 @@ vips__init( const char *argv0 )
|
||||
{
|
||||
return( vips_init( argv0 ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_greyc_mask( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||
int iterations,
|
||||
float amplitude, float sharpness, float anisotropy,
|
||||
float alpha, float sigma,
|
||||
float dl, float da, float gauss_prec,
|
||||
int interpolation, int fast_approx )
|
||||
{
|
||||
VipsImage *input_images[2];
|
||||
VipsImage *output_image;
|
||||
char *command;
|
||||
int result;
|
||||
|
||||
input_images[0] = in;
|
||||
input_images[1] = mask;
|
||||
command = g_strdup_printf( "-smooth %g,%g,%g,%g,%g,%g,%g,%g,%d,%d",
|
||||
amplitude, sharpness, anisotropy,
|
||||
alpha, sigma, dl, da, gauss_prec,
|
||||
interpolation, fast_approx );
|
||||
result = vips_gmic( input_images, &output_image, 2,
|
||||
4, 1, 1, command, NULL );
|
||||
g_free( command );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -40,13 +40,8 @@ extern "C" {
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
int im_greyc_mask( VipsImage *in, VipsImage *out, VipsImage *mask,
|
||||
int iterations, float amplitude, float sharpness, float anisotropy,
|
||||
float alpha, float sigma, float dl, float da, float gauss_prec,
|
||||
int interpolation, int fast_approx );
|
||||
|
||||
int vips_gmic( int n, VipsImage** out, const char* command,
|
||||
int padding, float x_scale, float y_scale, ... )
|
||||
int vips_gmic( VipsImage **in, VipsImage **out, int n,
|
||||
int padding, double x_scale, double y_scale, const char *command, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -216,6 +216,7 @@ void vips_morphology_operation_init( void );
|
||||
void vips_convolution_operation_init( void );
|
||||
void vips_draw_operation_init( void );
|
||||
void vips_mosaicing_operation_init( void );
|
||||
void vips_cimg_operation_init( void );
|
||||
|
||||
guint64 vips__parse_size( const char *size_string );
|
||||
int vips__substitute( char *buf, size_t len, char *sub );
|
||||
|
@ -1225,6 +1225,11 @@ int *im_offsets45( int size );
|
||||
int im_conv_f_raw( VipsImage *in, VipsImage *out, DOUBLEMASK *mask );
|
||||
int im_convsep_f_raw( VipsImage *in, VipsImage *out, DOUBLEMASK *mask );
|
||||
|
||||
int im_greyc_mask( VipsImage *in, VipsImage *out, VipsImage *mask,
|
||||
int iterations, float amplitude, float sharpness, float anisotropy,
|
||||
float alpha, float sigma, float dl, float da, float gauss_prec,
|
||||
int interpolation, int fast_approx );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -285,9 +285,7 @@ vips_init( const char *argv0 )
|
||||
vips_morphology_operation_init();
|
||||
vips_draw_operation_init();
|
||||
vips_mosaicing_operation_init();
|
||||
|
||||
extern int vips_gmic_get_type( void );
|
||||
vips_gmic_get_type();
|
||||
vips_cimg_operation_init();
|
||||
|
||||
/* Load up any plugins in the vips libdir. We don't error on failure,
|
||||
* it's too annoying to have VIPS refuse to start because of a broken
|
||||
|
Loading…
Reference in New Issue
Block a user