redo im_rot*() as a class

This commit is contained in:
John Cupitt 2011-11-04 14:45:56 +00:00
parent 5f0db6a093
commit 7352d51053
15 changed files with 536 additions and 526 deletions

View File

@ -4,7 +4,7 @@
im_flophor(), im_flipver(), im_insert(), im_insert_noexpand(), im_lrjoin(),
im_tbjoin(), im_extract_area(), im_extract_bands(), im_extract_areabands(),
im_replicate(), im_clip2fmt(), im_gbandjoin(), im_bandjoin(), im_invert(),
im_lintra(), im_lintra_vec(), im_black()
im_lintra(), im_lintra_vec(), im_black(), im_rot90, im_rot180(), im_rot270()
redone as classes
- added argument priorites to help control arg ordering
- generate has a 'stop' param to signal successful early termination

70
TODO
View File

@ -24,6 +24,41 @@
move format to new-style and try it
- also VipsFormat ... could this replace vips_image_new_from_string()? or
could we call this from vips_image_new_from_string()?
at the moment, VipsFormat subclasses never get made, we just use the classes
... we'd need to start making real vipsformat objects for this to work
how would this work?
at the moment we have
image = vips_image_new_from_file( filename );
build a VipsImage with filename "r"
we also have the new CLI thing
obj = vips_object_new_from_string( class, str );
calls class->new_from_string( first-component(str) ), then sets
optional args from rest-of-str(str), then does _build()
image-class->new_from_string() just make a vipsimage "r" str
the _build() uses VipsFormat() to load via im_tiff2vips() or whatever
so ... we could change vips_image_new_from_file() to be
VIPS_IMAGE( vips_object_new_from_string( VipsImageClass, str ) )
we could also make VipsImage::new_from_string() make a real VipsFormat
object, then load options could be set from the str
how does save work? we call image-class->output_to_arg(obj, str), which in
turn calls vips_image_write(), which in turn uses VipsFormat
@ -127,41 +162,6 @@
- also VipsFormat ... could this replace vips_image_new_from_string()? or
could we call this from vips_image_new_from_string()?
at the moment, VipsFormat subclasses never get made, we just use the classes
... we'd need to start making real vipsformat objects for this to work
how would this work?
at the moment we have
image = vips_image_new_from_file( filename );
build a VipsImage with filename "r"
we also have the new CLI thing
obj = vips_object_new_from_string( class, str );
calls class->new_from_string( first-component(str) ), then sets
optional args from rest-of-str(str), then does _build()
image-class->new_from_string() just make a vipsimage "r" str
the _build() uses VipsFormat() to load via im_tiff2vips() or whatever
so ... we could change vips_image_new_from_file() to be
VIPS_IMAGE( vips_object_new_from_string( VipsImageClass, str ) )
we could also make VipsImage::new_from_string() make a real VipsFormat
object, then load options could be set from the str
how does save work? we call image-class->output_to_arg(obj, str), which in
turn calls vips_image_write(), which in turn uses VipsFormat

View File

@ -13,6 +13,7 @@ libconversion_la_SOURCES = \
cast.c \
bandjoin.c \
black.c \
rot.c \
conver_dispatch.c \
im_c2amph.c \
im_c2rect.c \
@ -24,9 +25,6 @@ libconversion_la_SOURCES = \
im_msb.c \
im_grid.c \
im_ri2c.c \
im_rot180.c \
im_rot270.c \
im_rot90.c \
im_scale.c \
im_insert.c \
im_scaleps.c \

View File

@ -113,6 +113,7 @@ vips_conversion_operation_init( void )
extern GType vips_cast_get_type( void );
extern GType vips_bandjoin_get_type( void );
extern GType vips_black_get_type( void );
extern GType vips_rot_get_type( void );
vips_copy_get_type();
vips_embed_get_type();
@ -125,5 +126,6 @@ vips_conversion_operation_init( void )
vips_cast_get_type();
vips_bandjoin_get_type();
vips_black_get_type();
vips_rot_get_type();
}

View File

@ -72,7 +72,7 @@
*
* Flips an image left-right or up-down.
*
* See also: im_rot90().
* See also: #VipsRot.
*
* Returns: 0 on success, -1 on error
*/
@ -84,7 +84,7 @@ typedef struct _VipsFlip {
*/
VipsImage *in;
/* Swap bytes on the way through.
/* Left-right or up-down.
*/
VipsDirection direction;

View File

@ -1,156 +0,0 @@
/* im_rot180
*
* Copyright: 1991, N. Dessipris
* Written on: 28/10/91
* Updated on: 2/4/92, J.Cupitt
* bugs in im_la90rot fixed, now works for any type.
* 19/7/93 JC
* - IM_CODING_LABQ allowed now
* 15/11/94 JC
* - name changed
* - memory leaks fixed
* 8/2/95 JC
* - oops! memory allocation problem fixed
* 18/5/95 JC
* - IM_MAXLINES increased
* 13/8/96 JC
* - rewritten for partials
* - adapted from im_rot90
* 14/4/04
* - sets Xoffset / Yoffset
* 24/3/09
* - added IM_CODING_RAD support
* 1/2/10
* - 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., 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 <string.h>
#include <vips/vips.h>
static int
rot180_gen( REGION *or, void *seq, void *a, void *b )
{
REGION *ir = (REGION *) seq;
IMAGE *in = (IMAGE *) a;
/* Output area.
*/
Rect *r = &or->valid;
int le = r->left;
int ri = IM_RECT_RIGHT(r);
int to = r->top;
int bo = IM_RECT_BOTTOM(r);
int x, y;
/* Pixel geometry.
*/
int ps;
/* Find the area of the input image we need.
*/
Rect need;
need.left = in->Xsize - ri;
need.top = in->Ysize - bo;
need.width = r->width;
need.height = r->height;
if( im_prepare( ir, &need ) )
return( -1 );
/* Find PEL size and line skip for ir.
*/
ps = IM_IMAGE_SIZEOF_PEL( in );
/* Rotate the bit we now have.
*/
for( y = to; y < bo; y++ ) {
/* Start of this output line.
*/
PEL *q = (PEL *) IM_REGION_ADDR( or, le, y );
/* Corresponding position in ir.
*/
PEL *p = (PEL *) IM_REGION_ADDR( ir,
need.left + need.width - 1,
need.top + need.height - (y - to) - 1 );
/* Blap across!
*/
for( x = le; x < ri; x++ ) {
memcpy( q, p, ps );
q += ps;
p -= ps;
}
}
return( 0 );
}
/**
* im_rot180:
* @in: input image
* @out: output image
*
* Rotate an image 180 degrees.
*
* See also: im_rot90(), im_rot270(), im_affinei_all().
*
* Returns: 0 on success, -1 on error
*/
int
im_rot180( IMAGE *in, IMAGE *out )
{
if( im_piocheck( in, out ) ||
im_check_coding_known( "im_rot180", in ) )
return( -1 );
if( im_cp_desc( out, in ) ||
im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
return( -1 );
if( im_generate( out,
im_start_one, rot180_gen, im_stop_one, in, NULL ) )
return( -1 );
out->Xoffset = in->Xsize;
out->Yoffset = in->Ysize;
return( 0 );
}

View File

@ -1,162 +0,0 @@
/* im_rot270
*
* Copyright: 1991, N. Dessipris
* Written on: 28/10/91
* Updated on: 2/4/92, J.Cupitt
* bugs in im_la90rot fixed, now works for any type.
* 19/7/93 JC
* - IM_CODING_LABQ allowed now
* 15/11/94 JC
* - name changed
* - memory leaks fixed
* 8/2/95 JC
* - oops! memory allocation problem fixed
* 18/5/95 JC
* - IM_MAXLINES increased
* 13/8/96 JC
* - rewritten for partials
* 6/11/02 JC
* - speed-up ... replace memcpy() with a loop for small pixels
* 14/4/04
* - sets Xoffset / Yoffset
* 24/3/09
* - added IM_CODING_RAD support
* 1/2/10
* - 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., 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 <string.h>
#include <vips/vips.h>
/* Rotate a small piece.
*/
static int
rot270_gen( REGION *or, void *seq, void *a, void *b )
{
REGION *ir = (REGION *) seq;
IMAGE *in = (IMAGE *) a;
/* Output area.
*/
Rect *r = &or->valid;
int le = r->left;
int ri = IM_RECT_RIGHT(r);
int to = r->top;
int bo = IM_RECT_BOTTOM(r);
int x, y, i;
/* Pixel geometry.
*/
int ps, ls;
/* Find the area of the input image we need.
*/
Rect need;
need.left = in->Xsize - bo;
need.top = le;
need.width = r->height;
need.height = r->width;
if( im_prepare( ir, &need ) )
return( -1 );
/* Find PEL size and line skip for ir.
*/
ps = IM_IMAGE_SIZEOF_PEL( in );
ls = IM_REGION_LSKIP( ir );
/* Rotate the bit we now have.
*/
for( y = to; y < bo; y++ ) {
/* Start of this output line.
*/
PEL *q = (PEL *) IM_REGION_ADDR( or, le, y );
/* Corresponding position in ir.
*/
PEL *p = (PEL *) IM_REGION_ADDR( ir,
need.left + need.width - (y - to) - 1,
need.top );
for( x = le; x < ri; x++ ) {
for( i = 0; i < ps; i++ )
q[i] = p[i];
q += ps;
p += ls;
}
}
return( 0 );
}
/**
* im_rot270:
* @in: input image
* @out: output image
*
* Rotate an image 270 degrees.
*
* See also: im_rot180(), im_rot90(), im_affinei_all().
*
* Returns: 0 on success, -1 on error
*/
int
im_rot270( IMAGE *in, IMAGE *out )
{
if( im_piocheck( in, out ) ||
im_check_coding_known( "im_rot270", in ) )
return( -1 );
if( im_cp_desc( out, in ) ||
im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
return( -1 );
out->Xsize = in->Ysize;
out->Ysize = in->Xsize;
if( im_generate( out,
im_start_one, rot270_gen, im_stop_one, in, NULL ) )
return( -1 );
out->Xoffset = 0;
out->Yoffset = in->Xsize;
return( 0 );
}

View File

@ -1,162 +0,0 @@
/* im_rot90
*
* Copyright: 1991, N. Dessipris
* Written on: 28/10/91
* Updated on: 2/4/92, J.Cupitt
* bugs in im_la90rot fixed, now works for any type.
* 19/7/93 JC
* - IM_CODING_LABQ allowed now
* 15/11/94 JC
* - name changed
* - memory leaks fixed
* 8/2/95 JC
* - oops! memory allocation problem fixed
* 18/5/95 JC
* - IM_MAXLINES increased
* 13/8/96 JC
* - rewritten for partials
* 6/11/02 JC
* - speed-up ... replace memcpy() with a loop for small pixels
* 14/4/04
* - sets Xoffset / Yoffset
* 24/3/09
* - added IM_CODING_RAD support
* 1/2/10
* - 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., 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 <string.h>
#include <vips/vips.h>
/* Rotate a small piece.
*/
static int
rot90_gen( REGION *or, void *seq, void *a, void *b )
{
REGION *ir = (REGION *) seq;
IMAGE *in = (IMAGE *) a;
/* Output area.
*/
Rect *r = &or->valid;
int le = r->left;
int ri = IM_RECT_RIGHT(r);
int to = r->top;
int bo = IM_RECT_BOTTOM(r);
int x, y, i;
/* Pixel geometry.
*/
int ps, ls;
/* Find the area of the input image we need.
*/
Rect need;
need.left = to;
need.top = in->Ysize - ri;
need.width = r->height;
need.height = r->width;
if( im_prepare( ir, &need ) )
return( -1 );
/* Find PEL size and line skip for ir.
*/
ps = IM_IMAGE_SIZEOF_PEL( in );
ls = IM_REGION_LSKIP( ir );
/* Rotate the bit we now have.
*/
for( y = to; y < bo; y++ ) {
/* Start of this output line.
*/
PEL *q = (PEL *) IM_REGION_ADDR( or, le, y );
/* Corresponding position in ir.
*/
PEL *p = (PEL *) IM_REGION_ADDR( ir,
need.left + y - to,
need.top + need.height - 1 );
for( x = le; x < ri; x++ ) {
for( i = 0; i < ps; i++ )
q[i] = p[i];
q += ps;
p -= ls;
}
}
return( 0 );
}
/**
* im_rot90:
* @in: input image
* @out: output image
*
* Rotate an image 90 degrees.
*
* See also: im_rot180(), im_rot270(), im_affinei_all().
*
* Returns: 0 on success, -1 on error
*/
int
im_rot90( IMAGE *in, IMAGE *out )
{
if( im_piocheck( in, out ) ||
im_check_coding_known( "im_rot90", in ) )
return( -1 );
if( im_cp_desc( out, in ) ||
im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
return( -1 );
out->Xsize = in->Ysize;
out->Ysize = in->Xsize;
if( im_generate( out,
im_start_one, rot90_gen, im_stop_one, in, NULL ) )
return( -1 );
out->Xoffset = in->Ysize;
out->Yoffset = 0;
return( 0 );
}

398
libvips/conversion/rot.c Normal file
View File

@ -0,0 +1,398 @@
/* im_rot90
*
* Copyright: 1991, N. Dessipris
* Written on: 28/10/91
* Updated on: 2/4/92, J.Cupitt
* bugs in im_la90rot fixed, now works for any type.
* 19/7/93 JC
* - IM_CODING_LABQ allowed now
* 15/11/94 JC
* - name changed
* - memory leaks fixed
* 8/2/95 JC
* - oops! memory allocation problem fixed
* 18/5/95 JC
* - IM_MAXLINES increased
* 13/8/96 JC
* - rewritten for partials
* 6/11/02 JC
* - speed-up ... replace memcpy() with a loop for small pixels
* 14/4/04
* - sets Xoffset / Yoffset
* 24/3/09
* - added IM_CODING_RAD support
* 1/2/10
* - cleanups
* - gtkdoc
* 4/11/11
* - rewrite as a class
*/
/*
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
*/
/*
#define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/debug.h>
#include "conversion.h"
/**
* VipsRot:
* @in: input image
* @out: output image
* @direction: rot horizontally or vertically
*
* Rots an image left-right or up-down.
*
* See also: #VipsFlip.
*
* Returns: 0 on success, -1 on error
*/
typedef struct _VipsRot {
VipsConversion parent_instance;
/* The input image.
*/
VipsImage *in;
/* Rotate by ...
*/
VipsAngle angle;
} VipsRot;
typedef VipsConversionClass VipsRotClass;
G_DEFINE_TYPE( VipsRot, vips_rot, VIPS_TYPE_CONVERSION );
static int
vips_rot90_gen( VipsRegion *or, void *seq, void *a, void *b,
gboolean *stop )
{
VipsRegion *ir = (VipsRegion *) seq;
VipsImage *in = (VipsImage *) a;
/* Output area.
*/
VipsRect *r = &or->valid;
int le = r->left;
int ri = IM_RECT_RIGHT(r);
int to = r->top;
int bo = IM_RECT_BOTTOM(r);
int x, y, i;
/* Pixel geometry.
*/
int ps, ls;
/* Find the area of the input image we need.
*/
VipsRect need;
need.left = to;
need.top = in->Ysize - ri;
need.width = r->height;
need.height = r->width;
if( vips_region_prepare( ir, &need ) )
return( -1 );
/* Find PEL size and line skip for ir.
*/
ps = VIPS_IMAGE_SIZEOF_PEL( in );
ls = VIPS_REGION_LSKIP( ir );
/* Rotate the bit we now have.
*/
for( y = to; y < bo; y++ ) {
/* Start of this output line.
*/
PEL *q = (PEL *) VIPS_REGION_ADDR( or, le, y );
/* Corresponding position in ir.
*/
PEL *p = (PEL *) VIPS_REGION_ADDR( ir,
need.left + y - to,
need.top + need.height - 1 );
for( x = le; x < ri; x++ ) {
for( i = 0; i < ps; i++ )
q[i] = p[i];
q += ps;
p -= ls;
}
}
return( 0 );
}
static int
vips_rot180_gen( VipsRegion *or, void *seq, void *a, void *b,
gboolean *stop )
{
VipsRegion *ir = (VipsRegion *) seq;
VipsImage *in = (VipsImage *) a;
/* Output area.
*/
VipsRect *r = &or->valid;
int le = r->left;
int ri = IM_RECT_RIGHT(r);
int to = r->top;
int bo = IM_RECT_BOTTOM(r);
int x, y;
/* Pixel geometry.
*/
int ps;
/* Find the area of the input image we need.
*/
Rect need;
need.left = in->Xsize - ri;
need.top = in->Ysize - bo;
need.width = r->width;
need.height = r->height;
if( vips_region_prepare( ir, &need ) )
return( -1 );
/* Find PEL size and line skip for ir.
*/
ps = VIPS_IMAGE_SIZEOF_PEL( in );
/* Rotate the bit we now have.
*/
for( y = to; y < bo; y++ ) {
/* Start of this output line.
*/
PEL *q = (PEL *) VIPS_REGION_ADDR( or, le, y );
/* Corresponding position in ir.
*/
PEL *p = (PEL *) VIPS_REGION_ADDR( ir,
need.left + need.width - 1,
need.top + need.height - (y - to) - 1 );
/* Blap across!
*/
for( x = le; x < ri; x++ ) {
memcpy( q, p, ps );
q += ps;
p -= ps;
}
}
return( 0 );
}
static int
vips_rot270_gen( VipsRegion *or, void *seq, void *a, void *b,
gboolean *stop )
{
VipsRegion *ir = (VipsRegion *) seq;
VipsImage *in = (VipsImage *) a;
/* Output area.
*/
VipsRect *r = &or->valid;
int le = r->left;
int ri = IM_RECT_RIGHT(r);
int to = r->top;
int bo = IM_RECT_BOTTOM(r);
int x, y, i;
/* Pixel geometry.
*/
int ps, ls;
/* Find the area of the input image we need.
*/
VipsRect need;
need.left = in->Xsize - bo;
need.top = le;
need.width = r->height;
need.height = r->width;
if( vips_region_prepare( ir, &need ) )
return( -1 );
/* Find PEL size and line skip for ir.
*/
ps = VIPS_IMAGE_SIZEOF_PEL( in );
ls = VIPS_REGION_LSKIP( ir );
/* Rotate the bit we now have.
*/
for( y = to; y < bo; y++ ) {
/* Start of this output line.
*/
PEL *q = (PEL *) VIPS_REGION_ADDR( or, le, y );
/* Corresponding position in ir.
*/
PEL *p = (PEL *) VIPS_REGION_ADDR( ir,
need.left + need.width - (y - to) - 1,
need.top );
for( x = le; x < ri; x++ ) {
for( i = 0; i < ps; i++ )
q[i] = p[i];
q += ps;
p += ls;
}
}
return( 0 );
}
static int
vips_rot_build( VipsObject *object )
{
VipsConversion *conversion = VIPS_CONVERSION( object );
VipsRot *rot = (VipsRot *) object;
VipsGenerateFn generate_fn;
VipsDemandStyle hint;
if( VIPS_OBJECT_CLASS( vips_rot_parent_class )->build( object ) )
return( -1 );
if( rot->angle == VIPS_ANGLE_0 )
return( vips_image_write( rot->in, conversion->out ) );
if( vips_image_pio_input( rot->in ) ||
vips_image_pio_output( conversion->out ) )
return( -1 );
if( vips_image_copy_fields( conversion->out, rot->in ) )
return( -1 );
switch( rot->angle ) {
case VIPS_ANGLE_90:
generate_fn = vips_rot90_gen;
hint = VIPS_DEMAND_STYLE_SMALLTILE;
conversion->out->Xsize = rot->in->Ysize;
conversion->out->Ysize = rot->in->Xsize;
conversion->out->Xoffset = rot->in->Ysize;
conversion->out->Yoffset = 0;
break;
case VIPS_ANGLE_180:
generate_fn = vips_rot180_gen;
hint = VIPS_DEMAND_STYLE_THINSTRIP;
conversion->out->Xoffset = rot->in->Xsize;
conversion->out->Yoffset = rot->in->Ysize;
break;
case VIPS_ANGLE_270:
generate_fn = vips_rot270_gen;
hint = VIPS_DEMAND_STYLE_SMALLTILE;
conversion->out->Xsize = rot->in->Ysize;
conversion->out->Ysize = rot->in->Xsize;
conversion->out->Xoffset = 0;
conversion->out->Yoffset = rot->in->Xsize;
break;
default:
g_assert( 0 );
}
vips_demand_hint( conversion->out, hint, rot->in, NULL );
if( vips_image_generate( conversion->out,
vips_start_one, generate_fn, vips_stop_one,
rot->in, rot ) )
return( -1 );
return( 0 );
}
static void
vips_rot_class_init( VipsRotClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
VIPS_DEBUG_MSG( "vips_rot_class_init\n" );
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
vobject_class->nickname = "rot";
vobject_class->description = _( "rotate an image" );
vobject_class->build = vips_rot_build;
VIPS_ARG_IMAGE( class, "in", 1,
_( "Input" ),
_( "Input image" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsRot, in ) );
VIPS_ARG_ENUM( class, "angle", 6,
_( "Angle" ),
_( "Angle to rotate image" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsRot, angle ),
VIPS_TYPE_ANGLE, VIPS_ANGLE_90 );
}
static void
vips_rot_init( VipsRot *rot )
{
}
int
vips_rot( VipsImage *in, VipsImage **out, VipsAngle angle, ... )
{
va_list ap;
int result;
va_start( ap, angle );
result = vips_call_split( "rot", ap, in, out, angle );
va_end( ap );
return( result );
}

View File

@ -1096,6 +1096,54 @@ im_fliphor( IMAGE *in, IMAGE *out )
return( 0 );
}
int
im_rot90( IMAGE *in, IMAGE *out )
{
VipsImage *t;
if( vips_rot( in, &t, VIPS_ANGLE_90, NULL ) )
return( -1 );
if( vips_image_write( t, out ) ) {
g_object_unref( t );
return( -1 );
}
g_object_unref( t );
return( 0 );
}
int
im_rot180( IMAGE *in, IMAGE *out )
{
VipsImage *t;
if( vips_rot( in, &t, VIPS_ANGLE_180, NULL ) )
return( -1 );
if( vips_image_write( t, out ) ) {
g_object_unref( t );
return( -1 );
}
g_object_unref( t );
return( 0 );
}
int
im_rot270( IMAGE *in, IMAGE *out )
{
VipsImage *t;
if( vips_rot( in, &t, VIPS_ANGLE_270, NULL ) )
return( -1 );
if( vips_image_write( t, out ) ) {
g_object_unref( t );
return( -1 );
}
g_object_unref( t );
return( 0 );
}
int
im_flipver( IMAGE *in, IMAGE *out )
{

View File

@ -114,6 +114,27 @@ typedef enum {
VIPS_ALIGN_LAST
} VipsAlign;
/**
* VipsAngle:
* @VIPS_ANGLE_0; no rotate
* @VIPS_ANGLE_90; 90 degrees anti-clockwise
* @VIPS_ANGLE_180; 180 degree rotate
* @VIPS_ANGLE_270; 90 degrees clockwise
*
* See vips_rot() and so on.
*
* Fixed rotate angles.
*
* See also: vips_rot().
*/
typedef enum {
VIPS_ANGLE_0,
VIPS_ANGLE_90,
VIPS_ANGLE_180,
VIPS_ANGLE_270,
VIPS_ANGLE_LAST
} VipsAngle;
int vips_copy( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel));
int vips_embed( VipsImage *in, VipsImage **out,
@ -142,6 +163,8 @@ int vips_bandjoin2( VipsImage *in1, VipsImage *in2, VipsImage **out, ... )
__attribute__((sentinel));
int vips_black( VipsImage **out, int width, int height, ... )
__attribute__((sentinel));
int vips_rot( VipsImage *in, VipsImage **out, VipsAngle angle, ... )
__attribute__((sentinel));
@ -172,10 +195,6 @@ int im_insertset( VipsImage *main, VipsImage *sub, VipsImage *out, int n, int *x
int im_grid( VipsImage *in, VipsImage *out, int tile_height, int across, int down );
int im_wrap( VipsImage *in, VipsImage *out, int x, int y );
int im_rot90( VipsImage *in, VipsImage *out );
int im_rot180( VipsImage *in, VipsImage *out );
int im_rot270( VipsImage *in, VipsImage *out );
int im_subsample( VipsImage *in, VipsImage *out, int xshrink, int yshrink );
int im_zoom( VipsImage *in, VipsImage *out, int xfac, int yfac );

View File

@ -13,6 +13,8 @@ GType vips_direction_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_DIRECTION (vips_direction_get_type())
GType vips_align_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ALIGN (vips_align_get_type())
GType vips_angle_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_ANGLE (vips_angle_get_type())
/* enumerations from "../../../libvips/include/vips/util.h" */
GType vips_token_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_TOKEN (vips_token_get_type())

View File

@ -559,6 +559,10 @@ int im_bandjoin( VipsImage *in1, VipsImage *in2, VipsImage *out );
int im_gbandjoin( VipsImage **in, VipsImage *out, int n );
int im_black( VipsImage *out, int x, int y, int bands );
int im_rot90( VipsImage *in, VipsImage *out );
int im_rot180( VipsImage *in, VipsImage *out );
int im_rot270( VipsImage *in, VipsImage *out );
/* ruby-vips uses this

View File

@ -63,6 +63,26 @@ vips_align_get_type( void )
return( etype );
}
GType
vips_angle_get_type( void )
{
static GType etype = 0;
if( etype == 0 ) {
static const GEnumValue values[] = {
{VIPS_ANGLE_0, "VIPS_ANGLE_0", "0"},
{VIPS_ANGLE_90, "VIPS_ANGLE_90", "90"},
{VIPS_ANGLE_180, "VIPS_ANGLE_180", "180"},
{VIPS_ANGLE_270, "VIPS_ANGLE_270", "270"},
{VIPS_ANGLE_LAST, "VIPS_ANGLE_LAST", "last"},
{0, NULL, NULL}
};
etype = g_enum_register_static( "VipsAngle", values );
}
return( etype );
}
/* enumerations from "../../libvips/include/vips/util.h" */
GType
vips_token_get_type( void )

View File

@ -724,4 +724,3 @@ vips_guess_libdir( const char *argv0, const char *env_name )
return( libdir );
}