153 lines
3.9 KiB
C
153 lines
3.9 KiB
C
/* an image plus a constant
|
|
*
|
|
* 11/11/11
|
|
* - from arith_binary_const
|
|
* 21/8/19
|
|
* - revise to fix out of range comparisons
|
|
*/
|
|
|
|
/*
|
|
|
|
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 <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <vips/vips.h>
|
|
|
|
#include "unaryconst.h"
|
|
|
|
G_DEFINE_ABSTRACT_TYPE( VipsUnaryConst, vips_unary_const, VIPS_TYPE_UNARY );
|
|
|
|
static int
|
|
vips_unary_const_build( VipsObject *object )
|
|
{
|
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
|
VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object );
|
|
VipsUnary *unary = (VipsUnary *) object;
|
|
VipsUnaryConst *uconst = (VipsUnaryConst *) object;
|
|
|
|
/* If we have a three-element vector we need to bandup the image to
|
|
* match.
|
|
*/
|
|
uconst->n = 1;
|
|
if( uconst->c )
|
|
uconst->n = VIPS_MAX( uconst->n, uconst->c->n );
|
|
if( unary->in )
|
|
uconst->n = VIPS_MAX( uconst->n, unary->in->Bands );
|
|
arithmetic->base_bands = uconst->n;
|
|
|
|
if( unary->in &&
|
|
uconst->c ) {
|
|
if( vips_check_vector( class->nickname,
|
|
uconst->c->n, unary->in ) )
|
|
return( -1 );
|
|
}
|
|
|
|
/* Some operations need int constants, for example boolean AND, SHIFT
|
|
* etc.
|
|
*
|
|
* Some can use int constants as an optimisation, for example (x <
|
|
* 12). It depends on the value though: obviously (x < 12.5) should
|
|
* not use the int form.
|
|
*
|
|
* For complex images, we double the vector length and set the
|
|
* imaginary part to 0.
|
|
*/
|
|
if( uconst->c ) {
|
|
gboolean is_complex =
|
|
vips_band_format_iscomplex( unary->in->BandFmt );
|
|
int step = is_complex ? 2 : 1;
|
|
int n = step * uconst->n;
|
|
double *c = (double *) uconst->c->data;
|
|
|
|
int i;
|
|
|
|
uconst->c_int = VIPS_ARRAY( object, n, int );
|
|
uconst->c_double = VIPS_ARRAY( object, n, double );
|
|
if( !uconst->c_int ||
|
|
!uconst->c_double )
|
|
return( -1 );
|
|
memset( uconst->c_int, 0, n * sizeof( int ) );
|
|
memset( uconst->c_double, 0, n * sizeof( double ) );
|
|
|
|
for( i = 0; i < n; i += step )
|
|
uconst->c_double[i] =
|
|
c[VIPS_MIN( i / step, uconst->c->n - 1)];
|
|
|
|
for( i = 0; i < n; i += step )
|
|
uconst->c_int[i] = uconst->c_double[i];
|
|
|
|
uconst->is_int = TRUE;
|
|
for( i = 0; i < n; i += step )
|
|
if( uconst->c_int[i] != uconst->c_double[i] ) {
|
|
uconst->is_int = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( VIPS_OBJECT_CLASS( vips_unary_const_parent_class )->
|
|
build( object ) )
|
|
return( -1 );
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
static void
|
|
vips_unary_const_class_init( VipsUnaryConstClass *class )
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
|
|
|
gobject_class->set_property = vips_object_set_property;
|
|
gobject_class->get_property = vips_object_get_property;
|
|
|
|
object_class->nickname = "unary_const";
|
|
object_class->description = _( "unary operations with a constant" );
|
|
object_class->build = vips_unary_const_build;
|
|
|
|
VIPS_ARG_BOXED( class, "c", 201,
|
|
_( "c" ),
|
|
_( "Array of constants" ),
|
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
|
G_STRUCT_OFFSET( VipsUnaryConst, c ),
|
|
VIPS_TYPE_ARRAY_DOUBLE );
|
|
}
|
|
|
|
static void
|
|
vips_unary_const_init( VipsUnaryConst *uconst )
|
|
{
|
|
}
|