redo im_sign() as a class
This commit is contained in:
parent
11d0a28ccb
commit
18a969c2f8
@ -7,7 +7,7 @@
|
|||||||
im_lintra(), im_lintra_vec(), im_black(), im_rot90, im_rot180(), im_rot270()
|
im_lintra(), im_lintra_vec(), im_black(), im_rot90, im_rot180(), im_rot270()
|
||||||
im_sintra(), im_costra(), im_tantra(), im_asintra(), im_acostra(),
|
im_sintra(), im_costra(), im_tantra(), im_asintra(), im_acostra(),
|
||||||
im_atantra(), im_exptra(), im_exp10tra(), im_logtra(), im_log10tra(),
|
im_atantra(), im_exptra(), im_exp10tra(), im_logtra(), im_log10tra(),
|
||||||
im_abs()
|
im_abs(), im_sign()
|
||||||
redone as classes
|
redone as classes
|
||||||
- added argument priorites to help control arg ordering
|
- added argument priorites to help control arg ordering
|
||||||
- generate has a 'stop' param to signal successful early termination
|
- generate has a 'stop' param to signal successful early termination
|
||||||
|
@ -16,7 +16,7 @@ libarithmetic_la_SOURCES = \
|
|||||||
im_multiply.c \
|
im_multiply.c \
|
||||||
im_point_bilinear.c \
|
im_point_bilinear.c \
|
||||||
im_remainder.c \
|
im_remainder.c \
|
||||||
im_sign.c \
|
sign.c \
|
||||||
im_stats.c \
|
im_stats.c \
|
||||||
statistic.c \
|
statistic.c \
|
||||||
statistic.h \
|
statistic.h \
|
||||||
|
@ -70,16 +70,18 @@
|
|||||||
#include "arithmetic.h"
|
#include "arithmetic.h"
|
||||||
#include "unary.h"
|
#include "unary.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VipsAbs:
|
* VipsAbs:
|
||||||
* @in: input #VipsImage
|
* @in: input #VipsImage
|
||||||
* @out: output #VipsImage
|
* @out: output #VipsImage
|
||||||
*
|
*
|
||||||
* For unsigned formats, this operation calculates (max - @in), eg. (255 -
|
* This operation finds the absolute value of an image. It does a copy for
|
||||||
* @in) for uchar. For signed and float formats, this operation calculates (-1
|
* unsigned integer types, negate for negative values in
|
||||||
* * @in).
|
* signed integer types, <function>fabs(3)</function> for
|
||||||
|
* float types, and calculate modulus for complex
|
||||||
|
* types.
|
||||||
*
|
*
|
||||||
* See also: im_lintra().
|
* See also: im_sign().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
/* im_sign.c
|
|
||||||
*
|
|
||||||
* 9/7/02 JC
|
|
||||||
* - from im_cmulnorm
|
|
||||||
* 9/9/09
|
|
||||||
* - gtkdoc, tidies
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <vips/vips.h>
|
|
||||||
|
|
||||||
#define CSIGN( IN, OUT ) { \
|
|
||||||
IN *p = (IN *) in; \
|
|
||||||
OUT *q = (OUT *) out; \
|
|
||||||
int x; \
|
|
||||||
\
|
|
||||||
for( x = 0; x < n; x++ ) { \
|
|
||||||
IN re = p[0]; \
|
|
||||||
IN im = p[1]; \
|
|
||||||
double fac = sqrt( re * re + im * im ); \
|
|
||||||
\
|
|
||||||
p += 2; \
|
|
||||||
\
|
|
||||||
if( fac == 0.0 ) { \
|
|
||||||
q[0] = 0.0; \
|
|
||||||
q[1] = 0.0; \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
q[0] = re / fac; \
|
|
||||||
q[1] = im / fac; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
q += 2; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SIGN( IN, OUT ) { \
|
|
||||||
IN *p = (IN *) in; \
|
|
||||||
OUT *q = (OUT *) out; \
|
|
||||||
int x; \
|
|
||||||
\
|
|
||||||
for( x = 0; x < n; x++ ) { \
|
|
||||||
IN v = p[x]; \
|
|
||||||
\
|
|
||||||
if( v > 0 ) \
|
|
||||||
q[x] = 1; \
|
|
||||||
else if( v == 0 ) \
|
|
||||||
q[x] = 0; \
|
|
||||||
else \
|
|
||||||
q[x] = -1; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sign buffer processor.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
sign_gen( void *in, void *out, int w, IMAGE *im )
|
|
||||||
{
|
|
||||||
int n = w * im->Bands;
|
|
||||||
|
|
||||||
switch( im->BandFmt ) {
|
|
||||||
case IM_BANDFMT_UCHAR: SIGN( unsigned char, signed char ); break;
|
|
||||||
case IM_BANDFMT_CHAR: SIGN( signed char, signed char ); break;
|
|
||||||
case IM_BANDFMT_USHORT: SIGN( unsigned short, signed char ); break;
|
|
||||||
case IM_BANDFMT_SHORT: SIGN( signed short, signed char ); break;
|
|
||||||
case IM_BANDFMT_UINT: SIGN( unsigned int, signed char ); break;
|
|
||||||
case IM_BANDFMT_INT: SIGN( signed int, signed char ); break;
|
|
||||||
case IM_BANDFMT_FLOAT: SIGN( float, signed char ); break;
|
|
||||||
case IM_BANDFMT_DOUBLE: SIGN( double, signed char ); break;
|
|
||||||
case IM_BANDFMT_COMPLEX: CSIGN( float, float ); break;
|
|
||||||
case IM_BANDFMT_DPCOMPLEX: CSIGN( double, double ); break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
g_assert( 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* im_sign:
|
|
||||||
* @in: input image
|
|
||||||
* @out: output image
|
|
||||||
*
|
|
||||||
* Finds the unit vector in the direction of the pixel value. For non-complex
|
|
||||||
* images, it returns a signed char image with values -1, 0, and 1 for negative,
|
|
||||||
* zero and positive pixels. For complex images, it returns a
|
|
||||||
* complex normalised to length 1.
|
|
||||||
*
|
|
||||||
* See also: im_abs(), im_cmulnorm(), im_c2amph().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
im_sign( IMAGE *in, IMAGE *out )
|
|
||||||
{
|
|
||||||
if( im_piocheck( in, out ) ||
|
|
||||||
im_check_uncoded( "im_sign", in ) ||
|
|
||||||
im_cp_desc( out, in ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( !vips_bandfmt_iscomplex( in->BandFmt ) )
|
|
||||||
out->BandFmt = IM_BANDFMT_CHAR;
|
|
||||||
|
|
||||||
if( im_wrapone( in, out, (im_wrapone_fn) sign_gen, in, NULL ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
186
libvips/arithmetic/sign.c
Normal file
186
libvips/arithmetic/sign.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/* im_sign.c
|
||||||
|
*
|
||||||
|
* 9/7/02 JC
|
||||||
|
* - from im_cmulnorm
|
||||||
|
* 9/9/09
|
||||||
|
* - gtkdoc, tidies
|
||||||
|
* 6/11/11
|
||||||
|
* - redone as a class
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (C) 1991-2005 The National Gallery
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <vips/vips.h>
|
||||||
|
|
||||||
|
#include "arithmetic.h"
|
||||||
|
#include "unary.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VipsSign:
|
||||||
|
* @in: input image
|
||||||
|
* @out: output image
|
||||||
|
*
|
||||||
|
* Finds the unit vector in the direction of the pixel value. For non-complex
|
||||||
|
* images, it returns a signed char image with values -1, 0, and 1 for negative,
|
||||||
|
* zero and positive pixels. For complex images, it returns a
|
||||||
|
* complex normalised to length 1.
|
||||||
|
*
|
||||||
|
* See also: #VipsAbs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef VipsUnary VipsSign;
|
||||||
|
typedef VipsUnaryClass VipsSignClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsSign, vips_sign, VIPS_TYPE_UNARY );
|
||||||
|
|
||||||
|
#define CSIGN( TYPE ) { \
|
||||||
|
TYPE *p = (TYPE *) in; \
|
||||||
|
TYPE *q = (TYPE *) out; \
|
||||||
|
int x; \
|
||||||
|
\
|
||||||
|
for( x = 0; x < sz; x++ ) { \
|
||||||
|
TYPE re = p[0]; \
|
||||||
|
TYPE im = p[1]; \
|
||||||
|
double fac = sqrt( re * re + im * im ); \
|
||||||
|
\
|
||||||
|
p += 2; \
|
||||||
|
\
|
||||||
|
if( fac == 0.0 ) { \
|
||||||
|
q[0] = 0.0; \
|
||||||
|
q[1] = 0.0; \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
q[0] = re / fac; \
|
||||||
|
q[1] = im / fac; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
q += 2; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SIGN( TYPE ) { \
|
||||||
|
TYPE *p = (TYPE *) in; \
|
||||||
|
signed char *q = (signed char *) out; \
|
||||||
|
int x; \
|
||||||
|
\
|
||||||
|
for( x = 0; x < sz; x++ ) { \
|
||||||
|
TYPE v = p[x]; \
|
||||||
|
\
|
||||||
|
if( v > 0 ) \
|
||||||
|
q[x] = 1; \
|
||||||
|
else if( v == 0 ) \
|
||||||
|
q[x] = 0; \
|
||||||
|
else \
|
||||||
|
q[x] = -1; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_sign_buffer( VipsArithmetic *arithmetic, PEL *out, PEL **in, int width )
|
||||||
|
{
|
||||||
|
VipsImage *im = arithmetic->ready[0];
|
||||||
|
int sz = width * im->Bands;
|
||||||
|
|
||||||
|
switch( im->BandFmt ) {
|
||||||
|
case VIPS_FORMAT_UCHAR: SIGN( unsigned char ); break;
|
||||||
|
case VIPS_FORMAT_CHAR: SIGN( signed char ); break;
|
||||||
|
case VIPS_FORMAT_USHORT: SIGN( unsigned short ); break;
|
||||||
|
case VIPS_FORMAT_SHORT: SIGN( signed short ); break;
|
||||||
|
case VIPS_FORMAT_UINT: SIGN( unsigned int ); break;
|
||||||
|
case VIPS_FORMAT_INT: SIGN( signed int ); break;
|
||||||
|
case VIPS_FORMAT_FLOAT: SIGN( float ); break;
|
||||||
|
case VIPS_FORMAT_DOUBLE: SIGN( double ); break;
|
||||||
|
case VIPS_FORMAT_COMPLEX: CSIGN( float ); break;
|
||||||
|
case VIPS_FORMAT_DPCOMPLEX: CSIGN( double ); break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save a bit of typing.
|
||||||
|
*/
|
||||||
|
#define UC VIPS_FORMAT_UCHAR
|
||||||
|
#define C VIPS_FORMAT_CHAR
|
||||||
|
#define US VIPS_FORMAT_USHORT
|
||||||
|
#define S VIPS_FORMAT_SHORT
|
||||||
|
#define UI VIPS_FORMAT_UINT
|
||||||
|
#define I VIPS_FORMAT_INT
|
||||||
|
#define F VIPS_FORMAT_FLOAT
|
||||||
|
#define X VIPS_FORMAT_COMPLEX
|
||||||
|
#define D VIPS_FORMAT_DOUBLE
|
||||||
|
#define DX VIPS_FORMAT_DPCOMPLEX
|
||||||
|
|
||||||
|
static const VipsBandFormat vips_bandfmt_sign[10] = {
|
||||||
|
/* UC C US S UI I F X D DX */
|
||||||
|
C, C, C, C, C, C, C, X, C, DX
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_sign_class_init( VipsSignClass *class )
|
||||||
|
{
|
||||||
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
|
VipsArithmeticClass *aclass = VIPS_ARITHMETIC_CLASS( class );
|
||||||
|
|
||||||
|
object_class->nickname = "sign";
|
||||||
|
object_class->description = _( "unit vector of pixel" );
|
||||||
|
|
||||||
|
vips_arithmetic_set_format_table( aclass, vips_bandfmt_sign );
|
||||||
|
|
||||||
|
aclass->process_line = vips_sign_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_sign_init( VipsSign *sign )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
vips_sign( VipsImage *in, VipsImage **out, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start( ap, out );
|
||||||
|
result = vips_call_split( "sign", ap, in, out );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
@ -1392,6 +1392,23 @@ im_invert( IMAGE *in, IMAGE *out )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_sign( IMAGE *in, IMAGE *out )
|
||||||
|
{
|
||||||
|
VipsImage *t;
|
||||||
|
|
||||||
|
if( vips_sign( in, &t,
|
||||||
|
NULL ) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips_image_write( t, out ) ) {
|
||||||
|
g_object_unref( t );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
g_object_unref( t );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
im_abs( IMAGE *in, IMAGE *out )
|
im_abs( IMAGE *in, IMAGE *out )
|
||||||
{
|
{
|
||||||
|
@ -86,6 +86,8 @@ int vips_math( VipsImage *in, VipsImage **out,
|
|||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_abs( VipsImage *in, VipsImage **out, ... )
|
int vips_abs( VipsImage *in, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
int vips_sign( VipsImage *in, VipsImage **out, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -110,7 +112,6 @@ int im_remainder_vec( VipsImage *in, VipsImage *out, int n, double *c );
|
|||||||
int im_remainderconst( VipsImage *in, VipsImage *out, double c );
|
int im_remainderconst( VipsImage *in, VipsImage *out, double c );
|
||||||
int im_recomb( VipsImage *in, VipsImage *out, DOUBLEMASK *recomb );
|
int im_recomb( VipsImage *in, VipsImage *out, DOUBLEMASK *recomb );
|
||||||
|
|
||||||
int im_sign( VipsImage *in, VipsImage *out );
|
|
||||||
int im_floor( VipsImage *in, VipsImage *out );
|
int im_floor( VipsImage *in, VipsImage *out );
|
||||||
int im_rint( VipsImage *in, VipsImage *out );
|
int im_rint( VipsImage *in, VipsImage *out );
|
||||||
int im_ceil( VipsImage *in, VipsImage *out );
|
int im_ceil( VipsImage *in, VipsImage *out );
|
||||||
|
@ -529,6 +529,7 @@ int im_invert( VipsImage *in, VipsImage *out );
|
|||||||
int im_lintra( double a, VipsImage *in, double b, VipsImage *out );
|
int im_lintra( double a, VipsImage *in, double b, VipsImage *out );
|
||||||
int im_lintra_vec( int n, double *a, VipsImage *in, double *b, VipsImage *out );
|
int im_lintra_vec( int n, double *a, VipsImage *in, double *b, VipsImage *out );
|
||||||
int im_abs( VipsImage *in, VipsImage *out );
|
int im_abs( VipsImage *in, VipsImage *out );
|
||||||
|
int im_sign( VipsImage *in, VipsImage *out );
|
||||||
|
|
||||||
int im_sintra( VipsImage *in, VipsImage *out );
|
int im_sintra( VipsImage *in, VipsImage *out );
|
||||||
int im_costra( VipsImage *in, VipsImage *out );
|
int im_costra( VipsImage *in, VipsImage *out );
|
||||||
|
Loading…
Reference in New Issue
Block a user