diff --git a/TODO b/TODO index 701fda57..32b3a8bf 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,24 @@ +- shrink does not auto unpack labq or rad, should it? + +- others .. differences in: + +grep -l CODING_LABQ */*.c +conversion/join.c +conversion/msb.c +inplace/im_draw_mask.c +resample/shrink.c + +grep -l CODING_RAD */*.c +conversion/embed.c +inplace/flood.c +inplace/im_draw_image.c + +- add unpack everywhere, eg. arithmetic + + + + +- move vips__image_decode() into the public API - need to do mosaicing and inplace, plus im_label_regions in morph diff --git a/libvips/convolution/conv.c b/libvips/convolution/conv.c index 441cb550..3608b031 100644 --- a/libvips/convolution/conv.c +++ b/libvips/convolution/conv.c @@ -65,7 +65,10 @@ vips_conv_build( VipsObject *object ) VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsConvolution *convolution = (VipsConvolution *) object; VipsConv *conv = (VipsConv *) object; + VipsImage **t = (VipsImage **) + vips_object_local_array( object, 4 ); + VipsImage *in; INTMASK *imsk; DOUBLEMASK *dmsk; @@ -74,6 +77,8 @@ vips_conv_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_conv_parent_class )->build( object ) ) return( -1 ); + in = convolution->in; + /* printf( "vips_conv_build: convolving with:\n" ); vips_matrixprint( convolution->M, NULL ); @@ -86,19 +91,25 @@ vips_conv_build( VipsObject *object ) !im_local_dmask( convolution->out, dmsk ) ) return( -1 ); + /* Unpack for processing. + */ + if( vips__image_decode( in, &t[0] ) ) + return( -1 ); + in = t[0]; + switch( conv->precision ) { case VIPS_PRECISION_INTEGER: - if( im_conv( convolution->in, convolution->out, imsk ) ) + if( im_conv( in, convolution->out, imsk ) ) return( -1 ); break; case VIPS_PRECISION_FLOAT: - if( im_conv_f( convolution->in, convolution->out, dmsk ) ) + if( im_conv_f( in, convolution->out, dmsk ) ) return( -1 ); break; case VIPS_PRECISION_APPROXIMATE: - if( im_aconv( convolution->in, convolution->out, dmsk, + if( im_aconv( in, convolution->out, dmsk, conv->layers, conv->cluster ) ) return( -1 ); break; diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 39c233b6..e29d64df 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -297,6 +297,8 @@ IMAGE *vips__deprecated_open_write( const char *filename ); int vips__input_interpolate_init( im_object *obj, char *str ); +int vips__image_decode( VipsImage *in, VipsImage **out ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/resample/affine.c b/libvips/resample/affine.c index a8988f3e..c8e325f1 100644 --- a/libvips/resample/affine.c +++ b/libvips/resample/affine.c @@ -373,13 +373,33 @@ vips_affine_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) return( 0 ); } +/* Unpack to a format that we can compute with. + */ +int +vips__image_decode( VipsImage *in, VipsImage **out ) +{ + if( in->Coding == VIPS_CODING_LABQ ) { + if( vips_LabQ2LabS( in, out, NULL ) ) + return( -1 ); + } + else if( in->Coding == VIPS_CODING_RAD ) { + if( vips_rad2float( in, out, NULL ) ) + return( -1 ); + } + else { + if( vips_copy( in, out, NULL ) ) + return( -1 ); + } + + return( 0 ); +} + static int vips_affine_build( VipsObject *object ) { VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsResample *resample = VIPS_RESAMPLE( object ); VipsAffine *affine = (VipsAffine *) object; - VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); @@ -465,11 +485,9 @@ vips_affine_build( VipsObject *object ) /* Unpack labq for processing. */ - if( in->Coding == VIPS_CODING_LABQ ) { - if( vips_LabQ2LabS( in, &t[0], NULL ) ) - return( -1 ); - in = t[0]; - } + if( vips__image_decode( in, &t[0] ) ) + return( -1 ); + in = t[0]; /* Add new pixels around the input so we can interpolate at the edges. */ diff --git a/libvips/resample/shrink.c b/libvips/resample/shrink.c index d15731e7..f70b4ded 100644 --- a/libvips/resample/shrink.c +++ b/libvips/resample/shrink.c @@ -310,6 +310,10 @@ vips_shrink_build( VipsObject *object ) VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsResample *resample = VIPS_RESAMPLE( object ); VipsShrink *shrink = (VipsShrink *) object; + VipsImage **t = (VipsImage **) + vips_object_local_array( object, 1 ); + + VipsImage *in; if( VIPS_OBJECT_CLASS( vips_shrink_parent_class )->build( object ) ) return( -1 ); @@ -318,7 +322,9 @@ vips_shrink_build( VipsObject *object ) shrink->mh = ceil( shrink->yshrink ); shrink->np = shrink->mw * shrink->mh; - if( vips_check_noncomplex( class->nickname, resample->in ) ) + in = resample->in; + + if( vips_check_noncomplex( class->nickname, in ) ) return( -1 ); if( shrink->xshrink < 1.0 || @@ -336,14 +342,20 @@ vips_shrink_build( VipsObject *object ) if( shrink->xshrink == 1.0 && shrink->yshrink == 1.0 ) - return( vips_image_write( resample->in, resample->out ) ); + return( vips_image_write( in, resample->out ) ); + + /* Unpack for processing. + */ + if( vips__image_decode( in, &t[0] ) ) + return( -1 ); + in = t[0]; /* THINSTRIP will work, anything else will break seq mode. If you * combine shrink with conv you'll need to use a line cache to maintain * sequentiality. */ if( vips_image_pipelinev( resample->out, - VIPS_DEMAND_STYLE_THINSTRIP, resample->in, NULL ) ) + VIPS_DEMAND_STYLE_THINSTRIP, in, NULL ) ) return( -1 ); /* Size output. Note: we round the output width down! @@ -352,8 +364,8 @@ vips_shrink_build( VipsObject *object ) * example, vipsthumbnail knows the true shrink factor (including the * fractional part), we just see the integer part here. */ - resample->out->Xsize = resample->in->Xsize / shrink->xshrink; - resample->out->Ysize = resample->in->Ysize / shrink->yshrink; + resample->out->Xsize = in->Xsize / shrink->xshrink; + resample->out->Ysize = in->Ysize / shrink->yshrink; if( resample->out->Xsize <= 0 || resample->out->Ysize <= 0 ) { vips_error( class->nickname, @@ -363,7 +375,7 @@ vips_shrink_build( VipsObject *object ) #ifdef DEBUG printf( "vips_shrink_build: shrinking %d x %d image to %d x %d\n", - resample->in->Xsize, resample->in->Ysize, + in->Xsize, in->Ysize, resample->out->Xsize, resample->out->Ysize ); printf( "vips_shrink_build: %d x %d block average\n", shrink->mw, shrink->mh ); @@ -371,7 +383,7 @@ vips_shrink_build( VipsObject *object ) if( vips_image_generate( resample->out, vips_shrink_start, vips_shrink_gen, vips_shrink_stop, - resample->in, shrink ) ) + in, shrink ) ) return( -1 ); return( 0 );