any size mask for rot90
This commit is contained in:
parent
97a5ff1607
commit
c93443aaca
@ -1,5 +1,7 @@
|
||||
30/11/10 started 7.24.0
|
||||
- bump for new stable
|
||||
- added im_dmask2imask(), im_imask2dmask()
|
||||
- im_rotate_*mask90() can do masks of any size (thanks Adam)
|
||||
|
||||
18/7/10 started 7.23.0
|
||||
- im_vips2bufjpeg() writes to a linked list, so it will work for any size
|
||||
|
5
TODO
5
TODO
@ -118,11 +118,6 @@ g++ -shared -nostdlib /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crti.o
|
||||
- quite a few hist operations have no GUI ... lhisteq, for example? or
|
||||
histspec?
|
||||
|
||||
- im_rotate_imask90 only works for square, odd-sized masks, argh
|
||||
|
||||
just use im_rot90? have a small wrapper to let you use image functions on
|
||||
masks
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -88,6 +88,9 @@ DOUBLEMASK *im_dup_dmask( DOUBLEMASK *in, const char *filename );
|
||||
|
||||
INTMASK *im_scale_dmask( DOUBLEMASK *in, const char *filename );
|
||||
void im_norm_dmask( DOUBLEMASK *mask );
|
||||
DOUBLEMASK *im_imask2dmask( INTMASK *in, const char *filename );
|
||||
INTMASK *im_dmask2imask( DOUBLEMASK *in, const char *filename );
|
||||
|
||||
INTMASK *im_rotate_imask90( INTMASK *in, const char *filename );
|
||||
INTMASK *im_rotate_imask45( INTMASK *in, const char *filename );
|
||||
DOUBLEMASK *im_rotate_dmask90( DOUBLEMASK *in, const char *filename );
|
||||
|
@ -1,54 +1,5 @@
|
||||
/* @(#) Functions to create offsets for rotating square masks.
|
||||
* @(#) Usage
|
||||
* @(#) int *im_offsets45( size )
|
||||
* @(#) int size;
|
||||
* @(#)
|
||||
* @(#) Returns an int pointer to valid offsets on sucess and -1 on error
|
||||
* @(#)
|
||||
*
|
||||
* @(#) Usage
|
||||
* @(#) int *im_offsets90( size )
|
||||
* @(#) int size;
|
||||
* @(#)
|
||||
* @(#) Returns an int pointer to valid offsets on sucess and -1 on error
|
||||
* @(#)
|
||||
/* Functions to create offsets for rotating square masks.
|
||||
*
|
||||
* @(#) Functions to rotate square masks
|
||||
* @(#)
|
||||
* @(#) Usage
|
||||
* @(#) INTMASK *im_rotate_imask45( mask, name )
|
||||
* @(#) INTMASK *mask;
|
||||
* @(#)
|
||||
* @(#) Returns an pointer to INTMASK which keeps the original mask rotated
|
||||
* @(#) by 45 degrees clockwise.
|
||||
* @(#) The filename member of the returned mask is set to name
|
||||
* @(#)
|
||||
* @(#) Usage
|
||||
* @(#) DOUBLEMASK *im_rotate_dmask45( mask, name )
|
||||
* @(#) DOUBLEMASK *mask;
|
||||
* @(#)
|
||||
* @(#) Returns an pointer to INTMASK which keeps the original mask rotated
|
||||
* @(#) by 45 degrees clockwise.
|
||||
* @(#) The filename member of the returned mask is set to name
|
||||
* @(#)
|
||||
* @(#) Usage
|
||||
* @(#) INTMASK *im_rotate_imask90( mask, name )
|
||||
* @(#) INTMASK *mask;
|
||||
* @(#)
|
||||
* @(#) Returns an pointer to INTMASK which keeps the original mask rotated
|
||||
* @(#) by 90 degrees clockwise.
|
||||
* @(#) The filename member of the returned mask is set to name
|
||||
* @(#)
|
||||
* @(#) Usage
|
||||
* @(#) DOUBLEMASK *im_rotate_dmask90( mask, name )
|
||||
* @(#) DOUBLEMASK *mask;
|
||||
* @(#)
|
||||
* @(#) Returns an pointer to DOUBLEMASK which keeps the original mask rotated
|
||||
* @(#) by 90 degrees clockwise.
|
||||
* @(#) The filename member of the returned mask is set to name
|
||||
* @(#)
|
||||
*
|
||||
*
|
||||
* Author: N. Dessipris (Copyright, N. Dessipris 1991)
|
||||
* Written on: 08/05/1991
|
||||
* Modified on: 28/05/1991
|
||||
@ -59,6 +10,8 @@
|
||||
* - many bugs and mem leaks fixed
|
||||
* 1/3/99 JC
|
||||
* - oops, fns were not preserving scale and offset
|
||||
* 1/12/10
|
||||
* - allow any size mask for the 90 degree rotates by using im_rot90().
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -191,7 +144,7 @@ im_offsets90( int size )
|
||||
int x, y, k;
|
||||
int *offsets;
|
||||
|
||||
if( !(offsets = IM_ARRAY( NULL, size*size, int )) )
|
||||
if( !(offsets = IM_ARRAY( NULL, size * size, int )) )
|
||||
return( NULL );
|
||||
|
||||
for( k = 0, y = 0; y < size; y++ ) {
|
||||
@ -206,92 +159,6 @@ im_offsets90( int size )
|
||||
return( offsets );
|
||||
}
|
||||
|
||||
/* Tye pf offset-generating function.
|
||||
*/
|
||||
typedef int *(*offset_fn)( int );
|
||||
|
||||
/* Rotate a dmask with a set of offsets.
|
||||
*/
|
||||
static DOUBLEMASK *
|
||||
rotdmask( offset_fn fn, DOUBLEMASK *m, const char *name )
|
||||
{
|
||||
DOUBLEMASK *out;
|
||||
int size = m->xsize * m->ysize;
|
||||
int *offsets;
|
||||
int i;
|
||||
|
||||
if( m->xsize != m->ysize || (m->xsize % 2) == 0 ) {
|
||||
im_error( "im_rotate_mask", "%s",
|
||||
_( "mask should be square of even size" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( !(offsets = fn( m->xsize )) )
|
||||
return( NULL );
|
||||
if( !(out = im_create_dmask( name, m->xsize, m->ysize )) ) {
|
||||
im_free( offsets );
|
||||
return( NULL );
|
||||
}
|
||||
out->scale = m->scale;
|
||||
out->offset = m->offset;
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
out->coeff[i] = m->coeff[offsets[i]];
|
||||
|
||||
im_free( offsets );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/* Rotate an imask with a set of offsets.
|
||||
*/
|
||||
static INTMASK *
|
||||
rotimask( offset_fn fn, INTMASK *m, const char *name )
|
||||
{
|
||||
INTMASK *out;
|
||||
int size = m->xsize * m->ysize;
|
||||
int *offsets;
|
||||
int i;
|
||||
|
||||
if( m->xsize != m->ysize || (m->xsize % 2) == 0 ) {
|
||||
im_error( "im_rotate_mask", "%s",
|
||||
_( "mask should be square of even size" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( !(offsets = fn( m->xsize )) )
|
||||
return( NULL );
|
||||
if( !(out = im_create_imask( name, m->xsize, m->ysize )) ) {
|
||||
im_free( offsets );
|
||||
return( NULL );
|
||||
}
|
||||
out->scale = m->scale;
|
||||
out->offset = m->offset;
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
out->coeff[i] = m->coeff[offsets[i]];
|
||||
|
||||
im_free( offsets );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_rotate_dmask90:
|
||||
* @in: input matrix
|
||||
* @filename: name for output matrix
|
||||
*
|
||||
* Returns a mask which is the argument mask rotated by 90 degrees.
|
||||
* Pass the filename to set for the output.
|
||||
*
|
||||
* See also: im_rotate_dmask45().
|
||||
*
|
||||
* Returns: the result matrix on success, or %NULL on error.
|
||||
*/
|
||||
DOUBLEMASK *
|
||||
im_rotate_dmask90( DOUBLEMASK *in, const char *filename )
|
||||
{
|
||||
return( rotdmask( im_offsets90, in, filename ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_rotate_dmask45:
|
||||
* @in: input matrix
|
||||
@ -307,25 +174,31 @@ im_rotate_dmask90( DOUBLEMASK *in, const char *filename )
|
||||
DOUBLEMASK *
|
||||
im_rotate_dmask45( DOUBLEMASK *in, const char *filename )
|
||||
{
|
||||
return( rotdmask( im_offsets45, in, filename ) );
|
||||
}
|
||||
DOUBLEMASK *out;
|
||||
int size = in->xsize * in->ysize;
|
||||
int *offsets;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* im_rotate_imask90:
|
||||
* @in: input matrix
|
||||
* @filename: name for output matrix
|
||||
*
|
||||
* Returns a mask which is the argument mask rotated by 90 degrees.
|
||||
* Pass the filename to set for the output.
|
||||
*
|
||||
* See also: im_rotate_imask45().
|
||||
*
|
||||
* Returns: the result matrix on success, or %NULL on error.
|
||||
*/
|
||||
INTMASK *
|
||||
im_rotate_imask90( INTMASK *in, const char *filename )
|
||||
{
|
||||
return( rotimask( im_offsets90, in, filename ) );
|
||||
if( in->xsize != in->ysize || (in->xsize % 2) == 0 ) {
|
||||
im_error( "im_rotate_dmask45", "%s",
|
||||
_( "mask should be square of odd size" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( !(offsets = im_offsets45( in->xsize )) )
|
||||
return( NULL );
|
||||
if( !(out = im_create_dmask( filename, in->xsize, in->ysize )) ) {
|
||||
im_free( offsets );
|
||||
return( NULL );
|
||||
}
|
||||
out->scale = in->scale;
|
||||
out->offset = in->offset;
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
out->coeff[i] = in->coeff[offsets[i]];
|
||||
|
||||
im_free( offsets );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -343,5 +216,122 @@ im_rotate_imask90( INTMASK *in, const char *filename )
|
||||
INTMASK *
|
||||
im_rotate_imask45( INTMASK *in, const char *filename )
|
||||
{
|
||||
return( rotimask( im_offsets45, in, filename ) );
|
||||
INTMASK *out;
|
||||
int size = in->xsize * in->ysize;
|
||||
int *offsets;
|
||||
int i;
|
||||
|
||||
if( in->xsize != in->ysize || (in->xsize % 2) == 0 ) {
|
||||
im_error( "im_rotate_imask45", "%s",
|
||||
_( "mask should be square of odd size" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( !(offsets = im_offsets45( in->xsize )) )
|
||||
return( NULL );
|
||||
if( !(out = im_create_imask( filename, in->xsize, in->ysize )) ) {
|
||||
im_free( offsets );
|
||||
return( NULL );
|
||||
}
|
||||
out->scale = in->scale;
|
||||
out->offset = in->offset;
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
out->coeff[i] = in->coeff[offsets[i]];
|
||||
|
||||
im_free( offsets );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/* The type of the vips operations we support.
|
||||
*/
|
||||
typedef int (*vips_fn)( IMAGE *in, IMAGE *out );
|
||||
|
||||
/* Pass a mask through a vips operation, eg. im_rot90().
|
||||
*/
|
||||
static INTMASK *
|
||||
vapplyimask( INTMASK *in, const char *name, vips_fn fn )
|
||||
{
|
||||
IMAGE *x;
|
||||
IMAGE *t[2];
|
||||
DOUBLEMASK *d[2];
|
||||
INTMASK *out;
|
||||
|
||||
if( !(x = im_open( name, "p" )) )
|
||||
return( NULL );
|
||||
if( !(d[0] = im_local_dmask( x, im_imask2dmask( in, name ) )) ||
|
||||
im_open_local_array( x, t, 2, name, "p" ) ||
|
||||
im_mask2vips( d[0], t[0] ) ||
|
||||
fn( t[0], t[1] ) ||
|
||||
!(d[1] = im_local_dmask( x, im_vips2mask( t[1], name ) )) ||
|
||||
!(out = im_dmask2imask( d[1], name )) ) {
|
||||
im_close( x );
|
||||
return( NULL );
|
||||
}
|
||||
im_close( x );
|
||||
|
||||
out->scale = in->scale;
|
||||
out->offset = in->offset;
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
static DOUBLEMASK *
|
||||
vapplydmask( DOUBLEMASK *in, const char *name, vips_fn fn )
|
||||
{
|
||||
IMAGE *x;
|
||||
IMAGE *t[2];
|
||||
DOUBLEMASK *out;
|
||||
|
||||
if( !(x = im_open( name, "p" )) )
|
||||
return( NULL );
|
||||
if( im_open_local_array( x, t, 2, name, "p" ) ||
|
||||
im_mask2vips( in, t[0] ) ||
|
||||
fn( t[0], t[1] ) ||
|
||||
!(out = im_vips2mask( t[1], name )) ) {
|
||||
im_close( x );
|
||||
return( NULL );
|
||||
}
|
||||
im_close( x );
|
||||
|
||||
out->scale = in->scale;
|
||||
out->offset = in->offset;
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_rotate_imask90:
|
||||
* @in: input matrix
|
||||
* @filename: name for output matrix
|
||||
*
|
||||
* Returns a mask which is the argument mask rotated by 90 degrees.
|
||||
* Pass the filename to set for the output.
|
||||
*
|
||||
* See also: im_rotate_imask45().
|
||||
*
|
||||
* Returns: the result matrix on success, or %NULL on error.
|
||||
*/
|
||||
INTMASK *
|
||||
im_rotate_imask90( INTMASK *in, const char *filename )
|
||||
{
|
||||
return( vapplyimask( in, filename, im_rot90 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_rotate_dmask90:
|
||||
* @in: input matrix
|
||||
* @filename: name for output matrix
|
||||
*
|
||||
* Returns a mask which is the argument mask rotated by 90 degrees.
|
||||
* Pass the filename to set for the output.
|
||||
*
|
||||
* See also: im_rotate_dmask45().
|
||||
*
|
||||
* Returns: the result matrix on success, or %NULL on error.
|
||||
*/
|
||||
DOUBLEMASK *
|
||||
im_rotate_dmask90( DOUBLEMASK *in, const char *filename )
|
||||
{
|
||||
return( vapplydmask( in, filename, im_rot90 ) );
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
* 27/4/95 JC
|
||||
* - oops! forgot to init IM_ARRAY() memory to zero
|
||||
* 7/8/96 JC
|
||||
* - im_scale_dmask rewritten
|
||||
* - im_scale_dmask() rewritten
|
||||
* 7/5/98 JC
|
||||
* - im_read_*mask() rewritten, now more robust
|
||||
* - im_write_*mask() rewritten
|
||||
@ -594,11 +594,8 @@ im_scale_dmask( DOUBLEMASK *in, const char *filename )
|
||||
int i;
|
||||
int isum;
|
||||
|
||||
if( !filename || in->xsize <= 0 || in->ysize <= 0 ) {
|
||||
im_error( "im_scale_dmask", "%s", _( "bad arguments" ) );
|
||||
return( NULL );
|
||||
}
|
||||
if( !(out = im_create_imask( filename, in->xsize, in->ysize )) )
|
||||
if( im_check_dmask( "im_scale_dmask", in ) ||
|
||||
!(out = im_create_imask( filename, in->xsize, in->ysize )) )
|
||||
return( NULL );
|
||||
|
||||
/* Find mask max.
|
||||
@ -634,16 +631,78 @@ im_scale_dmask( DOUBLEMASK *in, const char *filename )
|
||||
}
|
||||
|
||||
/**
|
||||
* im_norm_dmask:
|
||||
* @mask: mask to scale
|
||||
* im_dmask2imask:
|
||||
* @in: mask to convert
|
||||
* @filename: filename for returned mask
|
||||
*
|
||||
* Normalise the dmask. Apply the scale and offset to each element and return
|
||||
* a mask with scale 1, offset zero.
|
||||
* Make an imask from the dmask, rounding to nearest.
|
||||
*
|
||||
* See also: im_scale_dmask().
|
||||
*
|
||||
* Returns: the converted mask, or NULL on error.
|
||||
*/
|
||||
INTMASK *
|
||||
im_dmask2imask( DOUBLEMASK *in, const char *filename )
|
||||
{
|
||||
const int size = in->xsize * in->ysize;
|
||||
|
||||
INTMASK *out;
|
||||
int i;
|
||||
|
||||
if( im_check_dmask( "im_dmask2imask", in ) ||
|
||||
!(out = im_create_imask( filename, in->xsize, in->ysize )) )
|
||||
return( NULL );
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
out->coeff[i] = IM_RINT( in->coeff[i] );
|
||||
out->offset = IM_RINT( in->offset );
|
||||
out->scale = IM_RINT( in->scale );
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_imask2dmask:
|
||||
* @in: mask to convert
|
||||
* @filename: filename for returned mask
|
||||
*
|
||||
* Make a dmask from the imask.
|
||||
*
|
||||
* See also: im_dmask2imask().
|
||||
*
|
||||
* Returns: the converted mask, or NULL on error.
|
||||
*/
|
||||
DOUBLEMASK *
|
||||
im_imask2dmask( INTMASK *in, const char *filename )
|
||||
{
|
||||
const int size = in->xsize * in->ysize;
|
||||
|
||||
DOUBLEMASK *out;
|
||||
int i;
|
||||
|
||||
if( im_check_imask( "im_imask2dmask", in ) ||
|
||||
!(out = im_create_dmask( filename, in->xsize, in->ysize )) )
|
||||
return( NULL );
|
||||
|
||||
for( i = 0; i < size; i++ )
|
||||
out->coeff[i] = in->coeff[i];
|
||||
out->offset = in->offset;
|
||||
out->scale = in->scale;
|
||||
|
||||
return( out );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_norm_dmask:
|
||||
* @mask: mask to scale
|
||||
*
|
||||
* Normalise the dmask. Apply the scale and offset to each element to make
|
||||
* a mask with scale 1, offset zero.
|
||||
*
|
||||
* See also: im_scale_dmask().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
void
|
||||
im_norm_dmask( DOUBLEMASK *mask )
|
||||
{
|
||||
@ -652,7 +711,8 @@ im_norm_dmask( DOUBLEMASK *mask )
|
||||
|
||||
int i;
|
||||
|
||||
if( 1.0 == scale && 0.0 == mask->offset )
|
||||
if( im_check_dmask( "im_norm_dmask", mask ) ||
|
||||
(1.0 == scale && 0.0 == mask->offset) )
|
||||
return;
|
||||
|
||||
for( i = 0; i < n; i++ )
|
||||
@ -679,7 +739,8 @@ im_dup_imask( INTMASK *in, const char *filename )
|
||||
INTMASK *out;
|
||||
int i;
|
||||
|
||||
if( !(out = im_create_imask( filename, in->xsize, in->ysize )) )
|
||||
if( im_check_imask( "im_dup_imask", in ) ||
|
||||
!(out = im_create_imask( filename, in->xsize, in->ysize )) )
|
||||
return( NULL );
|
||||
|
||||
out->offset = in->offset;
|
||||
@ -708,7 +769,8 @@ im_dup_dmask( DOUBLEMASK *in, const char *filename )
|
||||
DOUBLEMASK *out;
|
||||
int i;
|
||||
|
||||
if( !(out = im_create_dmask( filename, in->xsize, in->ysize )) )
|
||||
if( im_check_dmask( "im_dup_dmask", in ) ||
|
||||
!(out = im_create_dmask( filename, in->xsize, in->ysize )) )
|
||||
return( NULL );
|
||||
|
||||
out->offset = in->offset;
|
||||
@ -781,7 +843,8 @@ im_write_imask_name( INTMASK *in, const char *filename )
|
||||
FILE *fp;
|
||||
int x, y, i;
|
||||
|
||||
if( !(fp = open_write( filename )) )
|
||||
if( im_check_imask( "im_write_imask_name", in ) ||
|
||||
!(fp = open_write( filename )) )
|
||||
return( -1 );
|
||||
|
||||
if( write_line( fp, "%d %d", in->xsize, in->ysize ) ) {
|
||||
@ -845,7 +908,8 @@ im_write_dmask_name( DOUBLEMASK *in, const char *filename )
|
||||
FILE *fp;
|
||||
int x, y, i;
|
||||
|
||||
if( !(fp = open_write( filename )) )
|
||||
if( im_check_dmask( "im_write_dmask_name", in ) ||
|
||||
!(fp = open_write( filename )) )
|
||||
return( -1 );
|
||||
|
||||
if( write_line( fp, "%d %d", in->xsize, in->ysize ) ) {
|
||||
@ -1014,7 +1078,7 @@ im_print_dmask( DOUBLEMASK *in )
|
||||
DOUBLEMASK *
|
||||
im_local_dmask( VipsImage *out, DOUBLEMASK *mask )
|
||||
{
|
||||
if( !mask )
|
||||
if( im_check_dmask( "im_local_dmask", mask ) )
|
||||
return( NULL );
|
||||
|
||||
if( im_add_close_callback( out,
|
||||
@ -1041,7 +1105,7 @@ im_local_dmask( VipsImage *out, DOUBLEMASK *mask )
|
||||
INTMASK *
|
||||
im_local_imask( VipsImage *out, INTMASK *mask )
|
||||
{
|
||||
if( !mask )
|
||||
if( im_check_imask( "im_local_dmask", mask ) )
|
||||
return( NULL );
|
||||
|
||||
if( im_add_close_callback( out,
|
||||
|
Loading…
Reference in New Issue
Block a user