fix indexed hist combine mode

it now tracks which bins have been inited, so min works
This commit is contained in:
John Cupitt 2017-11-25 21:23:10 +00:00
parent ee4186ae8f
commit 0363ac6ab9

View File

@ -62,6 +62,7 @@ typedef struct {
int size; /* Length of bins */ int size; /* Length of bins */
int mx; /* Maximum value we have seen */ int mx; /* Maximum value we have seen */
double *bins; /* All the bins! */ double *bins; /* All the bins! */
int *init; /* TRUE for bin has been initialised */
} Histogram; } Histogram;
typedef struct _VipsHistFindIndexed { typedef struct _VipsHistFindIndexed {
@ -108,12 +109,15 @@ histogram_new( VipsHistFindIndexed *indexed )
256 : 65536; 256 : 65536;
hist->mx = 0; hist->mx = 0;
hist->bins = NULL; hist->bins = NULL;
hist->init = NULL;
if( !(hist->bins = VIPS_ARRAY( indexed, bands * hist->size, double )) || if( !(hist->bins = VIPS_ARRAY( indexed, bands * hist->size, double )) ||
!(hist->init = VIPS_ARRAY( indexed, hist->size, int )) ||
!(hist->reg = vips_region_new( indexed->index_ready )) ) !(hist->reg = vips_region_new( indexed->index_ready )) )
return( NULL ); return( NULL );
memset( hist->bins, 0, bands * hist->size * sizeof( double ) ); memset( hist->bins, 0, bands * hist->size * sizeof( double ) );
memset( hist->init, 0, hist->size * sizeof( int ) );
return( hist ); return( hist );
} }
@ -233,13 +237,34 @@ vips_hist_find_indexed_stop( VipsStatistic *statistic, void *seq )
Histogram *hist = indexed->hist; Histogram *hist = indexed->hist;
int bands = statistic->ready->Bands; int bands = statistic->ready->Bands;
int i; int i, j;
double *bins;
double *sub_bins;
int *init;
int *sub_init;
/* Add on sub-data.
*/
hist->mx = VIPS_MAX( hist->mx, sub_hist->mx ); hist->mx = VIPS_MAX( hist->mx, sub_hist->mx );
for( i = 0; i < bands * hist->size; i++ )
COMBINE( indexed->combine, hist->bins[i], sub_hist->bins[i] ); bins = hist->bins;
sub_bins = sub_hist->bins;
init = hist->init;
sub_init = sub_hist->init;
for( i = 0; i <= sub_hist->mx; i++ ) {
if( sub_init[i] ) {
if( init[i] )
for( j = 0; j < bands; j++ )
COMBINE( indexed->combine,
bins[j], sub_bins[j] );
else {
for( j = 0; j < bands; j++ )
bins[j] = sub_bins[j];
init[i] = TRUE;
}
}
bins += bands;
sub_bins += bands;
}
VIPS_UNREF( sub_hist->reg ); VIPS_UNREF( sub_hist->reg );
@ -253,10 +278,17 @@ vips_hist_find_indexed_stop( VipsStatistic *statistic, void *seq )
TYPE *tv = (TYPE *) in; \ TYPE *tv = (TYPE *) in; \
\ \
for( x = 0; x < n; x++ ) { \ for( x = 0; x < n; x++ ) { \
double *bin = hist->bins + i[x] * bands; \ int ix = i[x]; \
double *bin = hist->bins + ix * bands; \
\ \
if( hist->init[ix] ) \
for( z = 0; z < bands; z++ ) \ for( z = 0; z < bands; z++ ) \
COMBINE( indexed->combine, bin[z], tv[z] ); \ COMBINE( indexed->combine, bin[z], tv[z] ); \
else { \
for( z = 0; z < bands; z++ ) \
bin[z] = tv[z]; \
hist->init[ix] = TRUE; \
} \
\ \
tv += bands; \ tv += bands; \
} \ } \
@ -312,8 +344,14 @@ vips_hist_find_indexed_uchar_scan( VipsHistFindIndexed *indexed,
if( ix > mx ) \ if( ix > mx ) \
mx = ix; \ mx = ix; \
\ \
if( hist->init[ix] ) \
for( z = 0; z < bands; z++ ) \ for( z = 0; z < bands; z++ ) \
COMBINE( indexed->combine, bin[z], tv[z] ); \ COMBINE( indexed->combine, bin[z], tv[z] ); \
else { \
for( z = 0; z < bands; z++ ) \
bin[z] = tv[z]; \
hist->init[ix] = TRUE; \
} \
\ \
tv += bands; \ tv += bands; \
} \ } \