From 3268bd0aaf8683e40e54e820fb33c35ae16d2e62 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 26 Mar 2010 10:03:37 +0000 Subject: [PATCH] hist hacking --- TODO | 2 ++ libvips/convolution/im_compass.c | 17 +++++---------- libvips/convolution/im_sharpen.c | 5 +---- libvips/histograms_lut/tone.c | 35 +++++++++++------------------- libvips/include/vips/mask.h | 3 +++ libvips/mask/rw_mask.c | 34 +++++++++++++++++++++++++++++ libvips/mosaicing/global_balance.c | 34 ++++++++--------------------- 7 files changed, 68 insertions(+), 62 deletions(-) diff --git a/TODO b/TODO index 465a95f4..95882bcd 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +- new is_monotonic() needs testing ... move somewhere else? tone.c isn't an + obvious place for it - lots of stupid little files in hist, eg. im_hsp.c ... paste them into larger modules diff --git a/libvips/convolution/im_compass.c b/libvips/convolution/im_compass.c index 8f24f811..c60262eb 100644 --- a/libvips/convolution/im_compass.c +++ b/libvips/convolution/im_compass.c @@ -78,10 +78,8 @@ im_compass( IMAGE *in, IMAGE *out, INTMASK *mask ) for( i = 0; i < 8; i++ ) { if( im_conv( in, filtered[i], mask ) || - !(mask = (INTMASK *) im_local( out, - (im_construct_fn) im_rotate_imask45, - (im_callback_fn) im_free_imask, - mask, mask->filename, NULL )) ) + !(mask = im_local_imask( out, + im_rotate_imask45( mask, mask->filename ) )) ) return( -1 ); } @@ -119,10 +117,8 @@ im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask ) for( i = 0; i < 4; i++ ) { if( im_conv( in, filtered[i], mask ) || - !(mask = (INTMASK *) im_local( out, - (im_construct_fn) im_rotate_imask45, - (im_callback_fn) im_free_imask, - mask, mask->filename, NULL )) ) + !(mask = im_local_imask( out, + im_rotate_imask45( mask, mask->filename ) )) ) return( -1 ); } @@ -155,9 +151,8 @@ im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask ) if( im_open_local_array( out, t, 4, "im_gradient", "p" ) ) return( -1 ); - if( !(rmask = (INTMASK *) im_local( out, - (im_construct_fn) im_rotate_imask90, - (im_callback_fn) im_free_imask, mask, mask->filename, NULL )) ) + if( !(rmask = im_local_imask( out, + im_rotate_imask90( mask, mask->filename ) )) ) return( -1 ); if( im_conv( in, t[0], mask ) || diff --git a/libvips/convolution/im_sharpen.c b/libvips/convolution/im_sharpen.c index 7a1f1350..70aba1af 100644 --- a/libvips/convolution/im_sharpen.c +++ b/libvips/convolution/im_sharpen.c @@ -333,10 +333,7 @@ im_sharpen( IMAGE *in, IMAGE *out, /* Set up data structures we need. First, the convolution mask we will * use. */ - if( !(mask = (INTMASK *) im_local( out, - (im_construct_fn) sharpen_mask_new, - (im_callback_fn) im_free_imask, - GINT_TO_POINTER( mask_size ), NULL, NULL )) ) + if( !(mask = im_local_imask( out, sharpen_mask_new( mask_size ) )) ) return( -1 ); /* Make the lut we will use. We need to scale up x1, x2, x3 to the diff --git a/libvips/histograms_lut/tone.c b/libvips/histograms_lut/tone.c index ac729e54..df66aa5f 100644 --- a/libvips/histograms_lut/tone.c +++ b/libvips/histograms_lut/tone.c @@ -337,38 +337,29 @@ im_tone_build( IMAGE *out, int im_ismonotonic( IMAGE *lut, int *out ) { - IMAGE *t[3]; + IMAGE *t[2]; + INTMASK *mask; double m; - if( im_open_local_array( lut, t, 3, "im_ismonotonic", "p" ) || - im_check_hist( "im_ismonotonic", lut ) ) + if( im_check_hist( "im_ismonotonic", lut ) || + im_open_local_array( lut, t, 2, "im_ismonotonic", "p" ) ) return( -1 ); - /* Can be either a horizontal or vertical LUT. - */ - if( lut->Xsize != 1 && lut->Ysize != 1 ) { - im_error( "im_ismonotonic", - "%s", _( "not 1 by n or n by 1 image" ) ); + if( !(mask = im_local_imask( lut, + im_create_imaskv( "im_ismonotonic", 2, 1, 1, -1 ) )) ) return( -1 ); - } - - /* Extract two areas, offset by 1 pixel. - */ + mask->offset = 128; if( lut->Xsize == 1 ) { - if( im_extract_area( lut, t[0], 0, 0, 1, lut->Ysize - 1 ) || - im_extract_area( lut, t[1], 0, 1, 1, lut->Ysize - 1 ) ) - return( -1 ); - } - else { - if( im_extract_area( lut, t[0], 0, 0, lut->Xsize - 1, 1 ) || - im_extract_area( lut, t[1], 1, 0, lut->Xsize - 1, 1 ) ) + if( !(mask = im_local_imask( lut, + im_rotate_imask90( mask, mask->filename ) )) ) return( -1 ); } - /* Now t2 should be >= than t1 everywhere! + /* We want >=128 everywhere, ie. no -ve transitions. */ - if( im_moreeq( t[1], t[0], t[2] ) || - im_min( t[2], &m ) ) + if( im_conv( lut, t[0], mask ) || + im_moreeqconst( t[0], t[1], 128 ) || + im_min( t[1], &m ) ) return( -1 ); *out = m; diff --git a/libvips/include/vips/mask.h b/libvips/include/vips/mask.h index b98e356c..abfc48f4 100644 --- a/libvips/include/vips/mask.h +++ b/libvips/include/vips/mask.h @@ -103,6 +103,9 @@ int im_lu_solve( const DOUBLEMASK *lu, double *vec ); DOUBLEMASK *im_matinv( const DOUBLEMASK *mat, const char *name ); int im_matinv_inplace( DOUBLEMASK *mat ); +DOUBLEMASK *im_local_dmask( struct _VipsImage *out, DOUBLEMASK *mask ); +INTMASK *im_local_imask( struct _VipsImage *out, INTMASK *mask ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/mask/rw_mask.c b/libvips/mask/rw_mask.c index e22bd237..25d02ebc 100644 --- a/libvips/mask/rw_mask.c +++ b/libvips/mask/rw_mask.c @@ -774,3 +774,37 @@ im_print_dmask( DOUBLEMASK *m ) printf( "\n" ); } } + +/* Make a DOUBLEMASK local to an image descriptor. + */ +DOUBLEMASK * +im_local_dmask( VipsImage *out, DOUBLEMASK *mask ) +{ + if( !mask ) + return( NULL ); + + if( im_add_close_callback( out, + (im_callback_fn) im_free_dmask, mask, NULL ) ) { + im_free_dmask( mask ); + return( NULL ); + } + + return( mask ); +} + +/* Make an INTMASK local to an image descriptor. + */ +INTMASK * +im_local_imask( VipsImage *out, INTMASK *mask ) +{ + if( !mask ) + return( NULL ); + + if( im_add_close_callback( out, + (im_callback_fn) im_free_imask, mask, NULL ) ) { + im_free_imask( mask ); + return( NULL ); + } + + return( mask ); +} diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index 28443eec..ed7862e2 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -969,23 +969,6 @@ print_overlap_errors( JoinNode *node, double *fac, double *total ) } #endif /*DEBUG*/ -/* Make a DOUBLEMASK local to an image descriptor. - */ -static DOUBLEMASK * -local_mask( IMAGE *out, DOUBLEMASK *mask ) -{ - if( !mask ) - return( NULL ); - - if( im_add_close_callback( out, - (im_callback_fn) im_free_dmask, mask, NULL ) ) { - im_free_dmask( mask ); - return( NULL ); - } - - return( mask ); -} - /* Extract a rect. */ static int @@ -1052,7 +1035,7 @@ find_image_stats( IMAGE *in, IMAGE *mask, Rect *area ) /* Get stats from masked image. */ - if( !(stats = local_mask( in, im_stats( t[3] ) )) ) + if( !(stats = im_local_dmask( in, im_stats( t[3] ) )) ) return( NULL ); /* Number of non-zero pixels in mask. @@ -1464,8 +1447,9 @@ find_factors( SymbolTable *st, double gamma ) /* Make output matricies. */ - if( !(K = local_mask( st->im, im_create_dmask( "K", 1, st->novl ) )) || - !(M = local_mask( st->im, + if( !(K = im_local_dmask( st->im, + im_create_dmask( "K", 1, st->novl ) )) || + !(M = im_local_dmask( st->im, im_create_dmask( "M", st->nim-1, st->novl ) )) ) return( -1 ); fill_matricies( st, gamma, K, M ); @@ -1476,15 +1460,15 @@ find_factors( SymbolTable *st, double gamma ) /* Calculate LMS. */ - if( !(m1 = local_mask( st->im, im_mattrn( M, "lms:1" ) )) ) + if( !(m1 = im_local_dmask( st->im, im_mattrn( M, "lms:1" ) )) ) return( -1 ); - if( !(m2 = local_mask( st->im, im_matmul( m1, M, "lms:2" ) )) ) + if( !(m2 = im_local_dmask( st->im, im_matmul( m1, M, "lms:2" ) )) ) return( -1 ); - if( !(m3 = local_mask( st->im, im_matinv( m2, "lms:3" ) )) ) + if( !(m3 = im_local_dmask( st->im, im_matinv( m2, "lms:3" ) )) ) return( -1 ); - if( !(m4 = local_mask( st->im, im_matmul( m3, m1, "lms:4" ) )) ) + if( !(m4 = im_local_dmask( st->im, im_matmul( m3, m1, "lms:4" ) )) ) return( -1 ); - if( !(m5 = local_mask( st->im, im_matmul( m4, K, "lms:5" ) )) ) + if( !(m5 = im_local_dmask( st->im, im_matmul( m4, K, "lms:5" ) )) ) return( -1 ); /* Make array of correction factors.