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