hist hacking

This commit is contained in:
John Cupitt 2010-03-24 15:26:03 +00:00
parent 29b9747e42
commit 7d170f4ab9
1 changed files with 57 additions and 55 deletions

View File

@ -40,6 +40,10 @@
* - much, much faster! * - much, much faster!
* 12/5/09 * 12/5/09
* - fix signed/unsigned warning * - fix signed/unsigned warning
* 24/3/10
* - gtkdoc
* - small cleanups
* - oop, would fail for signed int histograms
*/ */
/* /*
@ -88,31 +92,22 @@
static int static int
normalise( IMAGE *in, IMAGE *out ) normalise( IMAGE *in, IMAGE *out )
{ {
IMAGE *t1 = im_open_local( out, "im_histplot:2", "p" ); if( im_check_uncoded( "im_histplot", in ) ||
double min, max; im_check_noncomplex( "im_histplot", in ) )
if( in->Coding != IM_CODING_NONE ) {
im_error( "im_histplot", "%s", _( "uncoded only" ) );
return( -1 ); return( -1 );
}
if( vips_bandfmt_iscomplex( in->BandFmt ) ) {
im_error( "im_histplot", "%s", _( "non-complex only" ) );
return( -1 );
}
if( vips_bandfmt_isuint( in->BandFmt ) ) { if( vips_bandfmt_isuint( in->BandFmt ) ) {
/* Trivial case.
*/
if( im_copy( in, out ) ) if( im_copy( in, out ) )
return( -1 ); return( -1 );
} }
else if( vips_bandfmt_isint( in->BandFmt ) ) { else if( vips_bandfmt_isint( in->BandFmt ) ) {
/* Move min up to 0. incheck(), because we have to min() so we IMAGE *t1;
* might as well save the calcs. double min;
/* Move min up to 0.
*/ */
if( !t1 || if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
im_incheck( in ) || im_min( in, &min ) ||
im_min( in, &max ) ||
im_lintra( 1.0, in, -min, t1 ) ) im_lintra( 1.0, in, -min, t1 ) )
return( -1 ); return( -1 );
} }
@ -120,6 +115,9 @@ normalise( IMAGE *in, IMAGE *out )
/* Float image: scale min--max to 0--any. Output square /* Float image: scale min--max to 0--any. Output square
* graph. * graph.
*/ */
IMAGE *t1;
DOUBLEMASK *stats;
double min, max;
int any; int any;
if( in->Xsize == 1 ) if( in->Xsize == 1 )
@ -127,13 +125,13 @@ normalise( IMAGE *in, IMAGE *out )
else else
any = in->Xsize; any = in->Xsize;
/* incheck(), because we have to min()/max() so we if( !(stats = im_stats( in )) )
* might as well save the calcs. return( -1 );
*/ min = stats->coeff[0];
if( !t1 || max = stats->coeff[1];
im_incheck( in ) || im_free_dmask( stats );
im_min( in, &min ) ||
im_max( in, &max ) || if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
im_lintra( any / (max - min), in, im_lintra( any / (max - min), in,
-min * any / (max - min), out ) ) -min * any / (max - min), out ) )
return( -1 ); return( -1 );
@ -153,7 +151,6 @@ normalise( IMAGE *in, IMAGE *out )
} \ } \
} }
/* Generate function. /* Generate function.
*/ */
static int static int
@ -170,10 +167,8 @@ make_vert_gen( REGION *or, void *seq, void *a, void *b )
int x, y, z; int x, y, z;
for( y = to; y < bo; y++ ) { for( y = to; y < bo; y++ ) {
unsigned char *q = (unsigned char *) PEL *q = (PEL *) IM_REGION_ADDR( or, le, y );
IM_REGION_ADDR( or, le, y ); PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, y );
unsigned char *p = (unsigned char *)
IM_IMAGE_ADDR( in, 0, y );
switch( in->BandFmt ) { switch( in->BandFmt ) {
case IM_BANDFMT_UCHAR: VERT( unsigned char ); break; case IM_BANDFMT_UCHAR: VERT( unsigned char ); break;
@ -186,9 +181,7 @@ make_vert_gen( REGION *or, void *seq, void *a, void *b )
case IM_BANDFMT_DOUBLE: VERT( double ); break; case IM_BANDFMT_DOUBLE: VERT( double ); break;
default: default:
im_error( "im_histplot", g_assert( 0 );
"%s", _( "internal error #8255" ) );
return( -1 );
} }
} }
@ -206,7 +199,6 @@ make_vert_gen( REGION *or, void *seq, void *a, void *b )
} \ } \
} }
/* Generate function. /* Generate function.
*/ */
static int static int
@ -225,10 +217,8 @@ make_horz_gen( REGION *or, void *seq, void *a, void *b )
int x, y, z; int x, y, z;
for( x = le; x < ri; x++ ) { for( x = le; x < ri; x++ ) {
unsigned char *q = (unsigned char *) PEL *q = (PEL *) IM_REGION_ADDR( or, x, to );
IM_REGION_ADDR( or, x, to ); PEL *p = (PEL *) IM_IMAGE_ADDR( in, x, 0 );
unsigned char *p = (unsigned char *)
IM_IMAGE_ADDR( in, x, 0 );
switch( in->BandFmt ) { switch( in->BandFmt ) {
case IM_BANDFMT_UCHAR: HORZ( unsigned char ); break; case IM_BANDFMT_UCHAR: HORZ( unsigned char ); break;
@ -241,9 +231,7 @@ make_horz_gen( REGION *or, void *seq, void *a, void *b )
case IM_BANDFMT_DOUBLE: HORZ( double ); break; case IM_BANDFMT_DOUBLE: HORZ( double ); break;
default: default:
im_error( "im_histplot", g_assert( 0 );
"%s", _( "internal error #8255" ) );
return( -1 );
} }
} }
@ -255,7 +243,6 @@ make_horz_gen( REGION *or, void *seq, void *a, void *b )
static int static int
plot( IMAGE *in, IMAGE *out ) plot( IMAGE *in, IMAGE *out )
{ {
IMAGE *t[5];
double max; double max;
int tsize; int tsize;
int xsize; int xsize;
@ -267,13 +254,9 @@ plot( IMAGE *in, IMAGE *out )
/* Find range we will plot. /* Find range we will plot.
*/ */
if( im_open_local_array( out, t, 5, "im_histplot", "p" ) || if( im_max( in, &max ) )
im_max( in, &max ) )
return( -1 ); return( -1 );
if( max < 0 ) { g_assert( max >= 0 );
im_error( "im_histplot", "%s", _( "internal error #8254" ) );
return( -1 );
}
if( in->BandFmt == IM_BANDFMT_UCHAR ) if( in->BandFmt == IM_BANDFMT_UCHAR )
tsize = 256; tsize = 256;
else else
@ -322,20 +305,39 @@ plot( IMAGE *in, IMAGE *out )
return( 0 ); return( 0 );
} }
/**
* im_histplot:
* @in: input image
* @out: output image
*
* Plot a 1 by any or any by 1 image file as a max by any or
* any by max image using these rules:
*
* <emphasis>unsigned char</emphasis> max is always 256
*
* <emphasis>other unsigned integer types</emphasis> output 0 - maxium
* value of @in.
*
* <emphasis>signed int types</emphasis> min moved to 0, max moved to max + min.
*
* <emphasis>float types</emphasis> min moved to 0, max moved to any
* (square output)
*
* See also: im_histindexed(), im_histeq().
*
* Returns: 0 on success, -1 on error
*/
int int
im_histplot( IMAGE *hist, IMAGE *histplot ) im_histplot( IMAGE *hist, IMAGE *histplot )
{ {
IMAGE *norm = im_open_local( histplot, "im_histplot:1", "p" ); IMAGE *t1;
if( !norm ) if( im_check_hist( "im_histplot", hist ) )
return( -1 ); return( -1 );
if( hist->Xsize != 1 && hist->Ysize != 1 ) {
im_error( "im_histplot", "%s", _( "Xsize or Ysize not 1" ) );
return( -1 );
}
if( normalise( hist, norm ) || if( !(t1 = im_open_local( histplot, "im_histplot:1", "p" )) ||
plot( norm, histplot ) ) normalise( hist, t1 ) ||
plot( t1, histplot ) )
return( -1 ); return( -1 );
return( 0 ); return( 0 );