remove the old im_shrink()

too much debugging still on though argh
This commit is contained in:
John Cupitt 2012-06-14 14:50:37 +01:00
parent 021ba9a01c
commit c3ae8dafc0
8 changed files with 29 additions and 388 deletions

View File

@ -2106,3 +2106,19 @@ im_argb2rgba( VipsImage *in, VipsImage *out )
*/
return( im_copy( in, out ) );
}
int
im_shrink( VipsImage *in, VipsImage *out, double xshrink, double yshrink )
{
VipsImage *x;
if( vips_shrink( in, &x, xshrink, yshrink, NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}

View File

@ -44,7 +44,6 @@ int im_affinei( VipsImage *in, VipsImage *out,
int im_affinei_all( VipsImage *in, VipsImage *out, VipsInterpolate *interpolate,
double a, double b, double c, double d, double dx, double dy ) ;
int im_shrink( VipsImage *in, VipsImage *out, double xshrink, double yshrink );
int im_rightshift_size( VipsImage *in, VipsImage *out,
int xshift, int yshift, int band_fmt );
@ -56,6 +55,9 @@ int im_match_linear_search( VipsImage *ref, VipsImage *sec, VipsImage *out,
int xr2, int yr2, int xs2, int ys2,
int hwindowsize, int hsearchsize );
int vips_shrink( VipsImage *in, VipsImage *out,
double xshrink, double yshrink, ... )
__attribute__((sentinel));

View File

@ -650,6 +650,8 @@ int im_recomb( VipsImage *in, VipsImage *out, DOUBLEMASK *recomb );
int im_argb2rgba( VipsImage *in, VipsImage *out );
int im_shrink( VipsImage *in, VipsImage *out, double xshrink, double yshrink );
/* ruby-vips uses this
*/
#define vips_class_map_concrete_all vips_class_map_all

View File

@ -1621,8 +1621,9 @@ vips_image_write_gen( VipsRegion *or,
VipsRegion *ir = (VipsRegion *) seq;
VipsRect *r = &or->valid;
printf( "vips_image_write_gen: "
printf( "vips_image_write_gen: %p "
"left = %d, top = %d, width = %d, height = %d\n",
or->im,
r->left, r->top, r->width, r->height );
/* Copy with pointers.

View File

@ -38,8 +38,8 @@
*/
/*
#define VIPS_DEBUG
*/
#define VIPS_DEBUG
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -327,7 +327,7 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop )
VipsRect image;
VipsRect tile;
VIPS_DEBUG_MSG( "wbuffer_allocate_fn:\n" );
VIPS_DEBUG_MSG( "wbuffer_allocate_fn:\n" );
/* Is the state x/y OK? New line or maybe new buffer or maybe even
* all done.
@ -386,7 +386,9 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop )
*/
wstate->buf = write->buf;
VIPS_DEBUG_MSG( " allocated %d x %d:\n", tile.left, tile.top );
VIPS_DEBUG_MSG( " allocated "
"left = %d, top = %d, width = %d, height = %d\n",
tile.left, tile.top, tile.width, tile.height );
/* Add to the number of writers on the buffer.
*/

View File

@ -10,7 +10,6 @@ libresample_la_SOURCES = \
shrink.c \
im_affine.c \
interpolate.c \
im_shrink.c \
im_rightshift_size.c \
transform.c \
resample_dispatch.c \
@ -28,7 +27,6 @@ libresample_la_SOURCES = \
shrink.c \
im_affine.c \
interpolate.c \
im_shrink.c \
im_rightshift_size.c \
transform.c \
resample_dispatch.c

View File

@ -1,380 +0,0 @@
/* shrink with a box filter
*
* Copyright: 1990, N. Dessipris.
*
* Authors: Nicos Dessipris and Kirk Martinez
* Written on: 29/04/1991
* Modified on: 2/11/92, 22/2/93 Kirk Martinez - Xres Yres & cleanup
incredibly inefficient for box filters as LUTs are used instead of +
Needs converting to a smoother filter: eg Gaussian! KM
* 15/7/93 JC
* - rewritten for partial v2
* - ANSIfied
* - now shrinks any non-complex type
* - no longer cloned from im_convsub()
* - could be much better! see km comments above
* 3/8/93 JC
* - rounding bug fixed
* 11/1/94 JC
* - problems with .000001 and round up/down ignored! Try shrink 3738
* pixel image by 9.345000000001
* 7/10/94 JC
* - IM_NEW and IM_ARRAY added
* - more typedef
* 3/7/95 JC
* - IM_CODING_LABQ handling added here
* 20/12/08
* - fall back to im_copy() for 1/1 shrink
* 2/2/11
* - gtk-doc
* 10/2/12
* - shrink in chunks to reduce peak memuse for large shrinks
* - simpler
*/
/*
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 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>
/* Our main parameter struct.
*/
typedef struct {
IMAGE *in;
IMAGE *out;
double xshrink; /* Shrink factors */
double yshrink;
int mw; /* Size of area we average */
int mh;
int np; /* Number of pels we average */
} ShrinkInfo;
/* Our per-sequence parameter struct. Somewhere to sum band elements.
*/
typedef struct {
REGION *ir;
VipsPel *sum;
} SeqInfo;
/* Free a sequence value.
*/
static int
shrink_stop( void *vseq, void *a, void *b )
{
SeqInfo *seq = (SeqInfo *) vseq;
IM_FREEF( im_region_free, seq->ir );
return( 0 );
}
/* Make a sequence value.
*/
static void *
shrink_start( IMAGE *out, void *a, void *b )
{
IMAGE *in = (IMAGE *) a;
ShrinkInfo *st = (ShrinkInfo *) b;
SeqInfo *seq;
if( !(seq = IM_NEW( out, SeqInfo )) )
return( NULL );
/* Init!
*/
seq->ir = NULL;
seq->sum = NULL;
seq->ir = im_region_create( in );
seq->sum = (void *) IM_ARRAY( out, in->Bands, double );
if( !seq->sum || !seq->ir ) {
shrink_stop( seq, in, st );
return( NULL );
}
return( (void *) seq );
}
/* Integer shrink.
*/
#define ISHRINK( TYPE ) { \
int *sum = (int *) seq->sum; \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
\
for( b = 0; b < bands; b++ ) \
sum[b] = 0; \
\
for( y1 = 0; y1 < st->mh; y1++ ) { \
for( i = 0, x1 = 0; x1 < st->mw; x1++ ) \
for( b = 0; b < bands; b++, i++ ) \
sum[b] += p[i]; \
\
p += ls; \
} \
\
for( b = 0; b < bands; b++ ) \
q[b] = (sum[b] + st->np / 2) / st->np; \
}
/* Float shrink.
*/
#define FSHRINK( TYPE ) { \
double *sum = (double *) seq->sum; \
TYPE *p = (TYPE *) in; \
TYPE *q = (TYPE *) out; \
\
for( b = 0; b < bands; b++ ) \
sum[b] = 0.0; \
\
for( y1 = 0; y1 < st->mh; y1++ ) { \
for( i = 0, x1 = 0; x1 < st->mw; x1++ ) \
for( b = 0; b < bands; b++, i++ ) \
sum[b] += p[i]; \
\
p += ls; \
} \
\
for( b = 0; b < bands; b++ ) \
q[b] = sum[b] / st->np; \
}
/* Generate an area of @or. @ir is large enough.
*/
static void
shrink_gen2( ShrinkInfo *st, SeqInfo *seq,
REGION *or, REGION *ir,
int left, int top, int width, int height )
{
const int bands = st->in->Bands;
const int sizeof_pixel = VIPS_IMAGE_SIZEOF_PEL( st->in );
const int ls = VIPS_REGION_LSKIP( ir ) /
VIPS_IMAGE_SIZEOF_ELEMENT( st->in );
int x, y, i;
int x1, y1, b;
for( y = 0; y < height; y++ ) {
VipsPel *out = IM_REGION_ADDR( or, left, top + y );
for( x = 0; x < width; x++ ) {
int ix = (left + x) * st->xshrink;
int iy = (top + y) * st->yshrink;
VipsPel *in = IM_REGION_ADDR( ir, ix, iy );
switch( st->in->BandFmt ) {
case IM_BANDFMT_UCHAR:
ISHRINK( unsigned char ); break;
case IM_BANDFMT_CHAR:
ISHRINK( char ); break;
case IM_BANDFMT_USHORT:
ISHRINK( unsigned short ); break;
case IM_BANDFMT_SHORT:
ISHRINK( short ); break;
case IM_BANDFMT_UINT:
ISHRINK( unsigned int ); break;
case IM_BANDFMT_INT:
ISHRINK( int ); break;
case IM_BANDFMT_FLOAT:
FSHRINK( float ); break;
case IM_BANDFMT_DOUBLE:
FSHRINK( double ); break;
default:
g_assert( 0 );
}
out += sizeof_pixel;
}
}
}
/* Shrink a REGION.
*/
static int
shrink_gen( REGION *or, void *vseq, void *a, void *b )
{
SeqInfo *seq = (SeqInfo *) vseq;
ShrinkInfo *st = (ShrinkInfo *) b;
REGION *ir = seq->ir;
Rect *r = &or->valid;
/* How do we chunk up the image? We don't want to prepare the whole of
* the input region corresponding to *r since it could be huge.
*
* Each pixel of *r will depend on roughly mw x mh
* pixels, so we walk *r in chunks which map to the tile size.
*
*/
int xstep = 1 + VIPS__TILE_WIDTH / st->mw;
int ystep = 1 + VIPS__TILE_HEIGHT / st->mh;
int x, y;
#ifdef DEBUG
printf( "shrink_gen: generating %d x %d at %d x %d\n",
r->width, r->height, r->left, r->top );
#endif /*DEBUG*/
for( y = 0; y < r->height; y += ystep )
for( x = 0; x < r->width; x += xstep ) {
/* Clip the this rect against the demand size.
*/
int width = VIPS_MIN( xstep, r->width - x );
int height = VIPS_MIN( ystep, r->height - y );
Rect s;
s.left = (r->left + x) * st->xshrink;
s.top = (r->top + y) * st->yshrink;
s.width = 1 + ceil( width * st->xshrink );
s.height = 1 + ceil( height * st->yshrink );
#ifdef DEBUG
printf( "shrink_gen: requesting %d x %d at %d x %d\n",
s.width, s.height, s.left, s.top );
#endif /*DEBUG*/
if( im_prepare( ir, &s ) )
return( -1 );
shrink_gen2( st, seq,
or, ir,
r->left + x, r->top + y, width, height );
}
return( 0 );
}
static int
shrink( IMAGE *in, IMAGE *out, double xshrink, double yshrink )
{
ShrinkInfo *st;
/* Prepare output. Note: we round the output width down!
*/
if( im_cp_desc( out, in ) )
return( -1 );
out->Xsize = in->Xsize / xshrink;
out->Ysize = in->Ysize / yshrink;
out->Xres = in->Xres / xshrink;
out->Yres = in->Yres / yshrink;
if( out->Xsize <= 0 || out->Ysize <= 0 ) {
im_error( "im_shrink",
"%s", _( "image has shrunk to nothing" ) );
return( -1 );
}
/* Build and attach state struct.
*/
if( !(st = IM_NEW( out, ShrinkInfo )) )
return( -1 );
st->in = in;
st->out = out;
st->xshrink = xshrink;
st->yshrink = yshrink;
st->mw = ceil( xshrink );
st->mh = ceil( yshrink );
st->np = st->mw * st->mh;
/* Set demand hints. We want THINSTRIP, as we will be demanding a
* large area of input for each output line.
*/
if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
return( -1 );
/* Generate!
*/
if( im_generate( out,
shrink_start, shrink_gen, shrink_stop, in, st ) )
return( -1 );
return( 0 );
}
/**
* im_shrink:
* @in: input image
* @out: output image
* @xshrink: horizontal shrink
* @yshrink: vertical shrink
*
* Shrink @in by a pair of factors with a simple box filter.
*
* You will get aliasing for non-integer shrinks. In this case, shrink with
* this function to the nearest integer size above the target shrink, then
* downsample to the exact size with im_affinei() and your choice of
* interpolator.
*
* im_rightshift_size() is faster for factors which are integer powers of two.
*
* See also: im_rightshift_size(), im_affinei().
*
* Returns: 0 on success, -1 on error
*/
int
im_shrink( IMAGE *in, IMAGE *out, double xshrink, double yshrink )
{
if( im_check_noncomplex( "im_shrink", in ) ||
im_check_coding_known( "im_shrink", in ) ||
im_piocheck( in, out ) )
return( -1 );
if( xshrink < 1.0 || yshrink < 1.0 ) {
im_error( "im_shrink",
"%s", _( "shrink factors should be >= 1" ) );
return( -1 );
}
if( xshrink == 1 && yshrink == 1 ) {
return( im_copy( in, out ) );
}
else if( in->Coding == IM_CODING_LABQ ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "im_shrink:1", "p" ) ||
im_LabQ2LabS( in, t[0] ) ||
shrink( t[0], t[1], xshrink, yshrink ) ||
im_LabS2LabQ( t[1], out ) )
return( -1 );
}
else
if( shrink( in, out, xshrink, yshrink ) )
return( -1 );
return( 0 );
}

View File

@ -62,8 +62,8 @@
*/
/*
#define DEBUG
*/
#define DEBUG
#ifdef HAVE_CONFIG_H
#include <config.h>