From 011fd99a1aaf73fad125579d5b73895e149cc47d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 19 May 2014 14:53:47 +0100 Subject: [PATCH] start fixing up the auto-decode stuff --- README.md | 2 ++ TODO | 13 ++++++++++++ libvips/arithmetic/linear.c | 13 +----------- libvips/arithmetic/measure.c | 27 +++++++++++++++++++++---- libvips/conversion/extract.c | 10 ++++++--- libvips/conversion/insert.c | 19 +----------------- libvips/foreign/vipspng.c | 4 ++-- libvips/include/vips/image.h | 2 ++ libvips/iofuncs/image.c | 39 ++++++++++++++++++++++++++++++++++++ 9 files changed, 90 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 2ede97aa..8f49da41 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # libvips : an image processing library +[![Build Status](https://secure.travis-ci.org/jcupitt/libvips.png)](http://travis-ci.org/jcupitt/libvips) + libvips is a 2D image processing library. Compared to similar libraries, [libvips runs quickly and uses little memory](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use). diff --git a/TODO b/TODO index 6d5b93c4..0fc2be23 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,16 @@ +- should we decode to LAB, rather than LABS, by default? + + causing all sorts of problems + +- have a decode-to-float flag? + +- when do we want LABS? for speed in conv ... have a special unpacker there? + + any time we won't be breaking bands apart or using a constant, I guess? + +- change measure to use the regular decoder + + - quickly wrap the useful bits of mosaicing/ nip2 uses: diff --git a/libvips/arithmetic/linear.c b/libvips/arithmetic/linear.c index a44b296b..e8eb4ded 100644 --- a/libvips/arithmetic/linear.c +++ b/libvips/arithmetic/linear.c @@ -125,18 +125,7 @@ vips_linear_build( VipsObject *object ) int bands; int i; - /* How many bands will our input image have after decoding? - */ - switch( unary->in->Coding ) { - case VIPS_CODING_RAD: - case VIPS_CODING_LABQ: - bands = 3; - break; - - default: - bands = unary->in->Bands; - break; - } + vips_image_decode_predict( unary->in, &bands, NULL ); /* If we have a three-element vector we need to bandup the image to * match. diff --git a/libvips/arithmetic/measure.c b/libvips/arithmetic/measure.c index b279e48a..cba1ee5d 100644 --- a/libvips/arithmetic/measure.c +++ b/libvips/arithmetic/measure.c @@ -21,6 +21,8 @@ * - changes for im_extract() broke averaging * 9/11/11 * - redo as a class + * 19/5/14 + * - add auto-unpack */ /* @@ -91,6 +93,7 @@ vips_measure_build( VipsObject *object ) VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); VipsMeasure *measure = (VipsMeasure *) object; + VipsImage *ready; int bands; double pw; double ph; @@ -101,7 +104,23 @@ vips_measure_build( VipsObject *object ) if( VIPS_OBJECT_CLASS( vips_measure_parent_class )->build( object ) ) return( -1 ); - bands = vips_image_get_bands( measure->in ); + /* We can't use vips_image_decode(), we want Lab, not LabS. + */ + if( measure->in->Coding == VIPS_CODING_LABQ ) { + if( vips_LabQ2Lab( measure->in, &ready, NULL ) ) + return( -1 ); + } + else if( measure->in->Coding == VIPS_CODING_RAD ) { + if( vips_rad2float( measure->in, &ready, NULL ) ) + return( -1 ); + } + else { + if( vips_copy( measure->in, &ready, NULL ) ) + return( -1 ); + } + vips_object_local( measure, ready ); + + bands = vips_image_get_bands( ready ); g_object_set( object, "out", vips_image_new_matrix( bands, measure->h * measure->v ), @@ -111,11 +130,11 @@ vips_measure_build( VipsObject *object ) */ if( !vips_object_argument_isset( object, "width" ) ) g_object_set( object, - "width", vips_image_get_width( measure->in ), + "width", vips_image_get_width( ready ), NULL ); if( !vips_object_argument_isset( object, "height" ) ) g_object_set( object, - "height", vips_image_get_height( measure->in ), + "height", vips_image_get_height( ready ), NULL ); /* How large are the patches we are to measure? @@ -141,7 +160,7 @@ vips_measure_build( VipsObject *object ) /* Extract and measure. */ - if( vips_extract_area( measure->in, &t[0], + if( vips_extract_area( ready, &t[0], x, y, w, h, NULL ) || vips_extract_band( t[0], &t[1], b, NULL ) || diff --git a/libvips/conversion/extract.c b/libvips/conversion/extract.c index 0453b123..6dfddb28 100644 --- a/libvips/conversion/extract.c +++ b/libvips/conversion/extract.c @@ -371,18 +371,22 @@ vips_extract_band_build( VipsObject *object ) VipsExtractBand *extract = (VipsExtractBand *) object; if( extract->in ) { + int bands; + + vips_image_decode_predict( extract->in, &bands, NULL ); + bandary->n = 1; bandary->in = &extract->in; bandary->out_bands = extract->n; - if( extract->band + extract->n > extract->in->Bands ) { + if( extract->band + extract->n > bands ) { vips_error( class->nickname, "%s", _( "bad extract band" ) ); return( -1 ); } - if( extract->band == 0 && - extract->n == extract->in->Bands ) + if( extract->band == 0 && + extract->n == bands ) return( vips_bandary_copy( bandary ) ); } diff --git a/libvips/conversion/insert.c b/libvips/conversion/insert.c index 03117419..2c8cdbf9 100644 --- a/libvips/conversion/insert.c +++ b/libvips/conversion/insert.c @@ -232,24 +232,7 @@ vips__vector_to_ink( const char *domain, printf( "vips__vector_to_ink: starting\n" ); #endif /*VIPS_DEBUG*/ - /* We need to know the bands and format we are matching to. But im may - * be coded, so simulate decoding. We can't call vips_image_decode() - * on im, since vips__vector_to_ink() needs to be able to work during - * im's construction and im may not be ready yet. - */ - if( im->Coding == VIPS_CODING_LABQ ) { - bands = 3; - format = VIPS_FORMAT_SHORT; - } - else if( im->Coding == VIPS_CODING_RAD ) { - bands = 3; - format = VIPS_FORMAT_FLOAT; - } - else { - bands = im->Bands; - format = im->BandFmt; - } - + vips_image_decode_predict( im, &bands, &format ); ones = VIPS_ARRAY( im, n, double ); for( i = 0; i < n; i++ ) ones[i] = 1.0; diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index 31ae0895..c462e225 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -440,8 +440,8 @@ png2vips_generate( VipsRegion *or, int y; #ifdef DEBUG - printf( "png2vips_generate: line %d, %d rows\n", - r->top, r->height ); + printf( "png2vips_generate: line %d, %d rows\n", r->top, r->height ); + printf( "png2vips_generate: y_top = %d\n", read->y_pos ); #endif /*DEBUG*/ /* We're inside a tilecache where tiles are the full image width, so diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 253864db..507db029 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -430,6 +430,8 @@ VipsImage *vips_image_new_temp_file( const char *format ); int vips_image_write( VipsImage *image, VipsImage *out ); int vips_image_write_to_file( VipsImage *image, const char *filename ); +int vips_image_decode_predict( VipsImage *im, + int *bands, VipsBandFormat *format ); int vips_image_decode( VipsImage *in, VipsImage **out ); int vips_image_encode( VipsImage *in, VipsImage **out, VipsCoding coding ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 5a70ddc5..81846892 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -2030,6 +2030,45 @@ vips_image_decode( VipsImage *in, VipsImage **out ) return( 0 ); } +/** + * vips_image_decode_predict: + * @in: image to decode + * @bands: predict bands here + * @format: predict format here + * + * We often need to know what an image will decode to without actuaklly + * decoding it, for example, in arg checking. + * + * See also: vips_image_decode(). + */ +int +vips_image_decode_predict( VipsImage *im, + int *out_bands, VipsBandFormat *out_format ) +{ + VipsBandFormat format; + int bands; + + if( im->Coding == VIPS_CODING_LABQ ) { + bands = 3; + format = VIPS_FORMAT_SHORT; + } + else if( im->Coding == VIPS_CODING_RAD ) { + bands = 3; + format = VIPS_FORMAT_FLOAT; + } + else { + bands = im->Bands; + format = im->BandFmt; + } + + if( out_bands ) + *out_bands = bands; + if( out_format ) + *out_format = format; + + return( 0 ); +} + /** * vips_image_encode: * @in: image to encode