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_sintra(), im_costra(), im_tantra(), im_asintra(), im_acostra(),
|
||||
im_atantra(), im_exptra(), im_exp10tra(), im_logtra(), im_log10tra(),
|
||||
im_abs()
|
||||
im_abs(), im_sign()
|
||||
redone as classes
|
||||
- added argument priorites to help control arg ordering
|
||||
- generate has a 'stop' param to signal successful early termination
|
||||
|
@ -16,7 +16,7 @@ libarithmetic_la_SOURCES = \
|
||||
im_multiply.c \
|
||||
im_point_bilinear.c \
|
||||
im_remainder.c \
|
||||
im_sign.c \
|
||||
sign.c \
|
||||
im_stats.c \
|
||||
statistic.c \
|
||||
statistic.h \
|
||||
|
@ -70,16 +70,18 @@
|
||||
#include "arithmetic.h"
|
||||
#include "unary.h"
|
||||
|
||||
/**
|
||||
/**
|
||||
* VipsAbs:
|
||||
* @in: input #VipsImage
|
||||
* @out: output #VipsImage
|
||||
*
|
||||
* For unsigned formats, this operation calculates (max - @in), eg. (255 -
|
||||
* @in) for uchar. For signed and float formats, this operation calculates (-1
|
||||
* * @in).
|
||||
* This operation finds the absolute value of an image. It does a copy for
|
||||
* unsigned integer types, negate for negative values 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
|
||||
*/
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
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
|
||||
im_abs( IMAGE *in, IMAGE *out )
|
||||
{
|
||||
|
@ -86,6 +86,8 @@ int vips_math( VipsImage *in, VipsImage **out,
|
||||
__attribute__((sentinel));
|
||||
int vips_abs( VipsImage *in, VipsImage **out, ... )
|
||||
__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_recomb( VipsImage *in, VipsImage *out, DOUBLEMASK *recomb );
|
||||
|
||||
int im_sign( VipsImage *in, VipsImage *out );
|
||||
int im_floor( VipsImage *in, VipsImage *out );
|
||||
int im_rint( 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_vec( int n, double *a, VipsImage *in, double *b, 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_costra( VipsImage *in, VipsImage *out );
|
||||
|
Loading…
Reference in New Issue
Block a user