im_aconv() almost working

This commit is contained in:
John Cupitt 2011-06-08 14:49:28 +01:00
parent cca955136d
commit 788a43b8b1

View File

@ -59,9 +59,9 @@
*/ */
/* /*
*/
#define DEBUG #define DEBUG
#define VIPS_DEBUG #define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
@ -133,8 +133,8 @@ typedef struct _Boxes {
* the index into start/end we add, row[] is the row we take it from. * the index into start/end we add, row[] is the row we take it from.
*/ */
int n_vlines; int n_vlines;
int row[MAX_LINES];
int band[MAX_LINES]; int band[MAX_LINES];
int row[MAX_LINES];
/* Each hline has a factor during gather, eg. -1 for -ve lobes. /* Each hline has a factor during gather, eg. -1 for -ve lobes.
*/ */
@ -436,17 +436,18 @@ boxes_new( IMAGE *in, IMAGE *out, DOUBLEMASK *mask, int n_layers, int cluster )
*/ */
printf( "lines:\n" ); printf( "lines:\n" );
for( y = 0; y < boxes->n_vlines; y++ ) { for( y = 0; y < boxes->n_vlines; y++ ) {
printf( "%3d - %2d x ", y, boxes->factor[z] ); int b = boxes->band[y];
for( x = 0; x < 55; x++ ) {
int rx = x * (mask->xsize + 1) / 55; printf( "%3d %3d - %2d x ", y, b, boxes->factor[y] );
int b = boxes->band[y]; for( x = 0; x < 50; x++ ) {
int rx = x * (mask->xsize + 1) / 50;
if( rx >= boxes->start[b] && rx < boxes->end[b] ) if( rx >= boxes->start[b] && rx < boxes->end[b] )
printf( "#" ); printf( "#" );
else else
printf( " " ); printf( " " );
} }
printf( " %3d .. %3d\n", boxes->start[z], boxes->end[z] ); printf( " %3d .. %3d\n", boxes->start[b], boxes->end[b] );
} }
printf( "area = %d\n", boxes->area ); printf( "area = %d\n", boxes->area );
printf( "rounding = %d\n", boxes->rounding ); printf( "rounding = %d\n", boxes->rounding );
@ -508,7 +509,7 @@ aconv_start( IMAGE *out, void *a, void *b )
/* There will always be more vlines than hlines, so make the arrays /* There will always be more vlines than hlines, so make the arrays
* vlines big and we'll have room for both. * vlines big and we'll have room for both.
*/ */
g_assert( boxes->n_vlines > boxes->n_hlines ); g_assert( boxes->n_vlines >= boxes->n_hlines );
seq->start = IM_ARRAY( out, boxes->n_vlines, int ); seq->start = IM_ARRAY( out, boxes->n_vlines, int );
seq->end = IM_ARRAY( out, boxes->n_vlines, int ); seq->end = IM_ARRAY( out, boxes->n_vlines, int );
@ -623,33 +624,29 @@ aconv_hgenerate( REGION *or, void *vseq, void *a, void *b )
for( i = 0; i < bands; i++ ) { for( i = 0; i < bands; i++ ) {
int *seq_sum = (int *) seq->sum; int *seq_sum = (int *) seq->sum;
PEL *p; PEL *p;
int *q; int *q;
int sum;
p = i + (PEL *) IM_REGION_ADDR( ir, r->left, r->top + y ); p = i + (PEL *) IM_REGION_ADDR( ir, r->left, r->top + y );
q = i + (int *) IM_REGION_ADDR( or, r->left, r->top + y ); q = i * n_hlines +
(int *) IM_REGION_ADDR( or, r->left, r->top + y );
sum = 0;
for( z = 0; z < n_hlines; z++ ) { for( z = 0; z < n_hlines; z++ ) {
seq_sum[z] = 0; seq_sum[z] = 0;
for( x = boxes->start[z]; x < boxes->end[z]; x++ ) for( x = boxes->start[z]; x < boxes->end[z]; x++ )
seq_sum[z] += p[x * istride]; seq_sum[z] += p[x * istride];
sum += boxes->factor[z] * seq_sum[z]; q[z] = seq_sum[z];
} }
*q = sum;
q += ostride; q += ostride;
for( x = 1; x < r->width; x++ ) { for( x = 1; x < r->width; x++ ) {
sum = 0;
for( z = 0; z < n_hlines; z++ ) { for( z = 0; z < n_hlines; z++ ) {
seq_sum[z] += p[seq->end[z]]; seq_sum[z] += p[seq->end[z]];
seq_sum[z] -= p[seq->start[z]]; seq_sum[z] -= p[seq->start[z]];
sum += seq_sum[z]; q[z] = seq_sum[z];
} }
p += istride; p += istride;
*q = sum;
q += ostride; q += ostride;
} }
} }
@ -715,7 +712,6 @@ aconv_horizontal( Boxes *boxes, IMAGE *in, IMAGE *out )
if( im_cp_desc( out, in ) ) if( im_cp_desc( out, in ) )
return( -1 ); return( -1 );
out->Xsize -= boxes->mask->xsize - 1; out->Xsize -= boxes->mask->xsize - 1;
out->Ysize -= boxes->mask->ysize - 1;
if( out->Xsize <= 0 || out->Ysize <= 0 ) { if( out->Xsize <= 0 || out->Ysize <= 0 ) {
im_error( "im_aconv", "%s", _( "image too small for mask" ) ); im_error( "im_aconv", "%s", _( "image too small for mask" ) );
return( -1 ); return( -1 );
@ -773,7 +769,7 @@ aconv_vgenerate( REGION *or, void *vseq, void *a, void *b )
* ease of direction change. * ease of direction change.
*/ */
istride = IM_REGION_LSKIP( ir ) / istride = IM_REGION_LSKIP( ir ) /
IM_IMAGE_SIZEOF_ELEMENT( boxes->in ); IM_IMAGE_SIZEOF_ELEMENT( in );
ostride = IM_REGION_LSKIP( or ) / ostride = IM_REGION_LSKIP( or ) /
IM_IMAGE_SIZEOF_ELEMENT( boxes->out ); IM_IMAGE_SIZEOF_ELEMENT( boxes->out );
@ -787,27 +783,26 @@ aconv_vgenerate( REGION *or, void *vseq, void *a, void *b )
boxes->row[z] * istride; boxes->row[z] * istride;
} }
switch( in->BandFmt ) { switch( boxes->in->BandFmt ) {
case IM_BANDFMT_UCHAR: case IM_BANDFMT_UCHAR:
for( x = 0; x < sz; x++ ) { for( y = 0; y < r->height; y++ ) {
int *p; int *p;
PEL *q; PEL *q;
int sum; int sum;
p = x * boxes->n_hlines + p = (int *) IM_REGION_ADDR( ir, r->left, r->top + y );
(int *) IM_REGION_ADDR( ir, r->left, r->top ); q = (PEL *) IM_REGION_ADDR( or, r->left, r->top + y );
q = x + (PEL *) IM_REGION_ADDR( or, r->left, r->top );
for( y = 0; y < r->height; y++ ) { for( x = 0; x < sz; x++ ) {
sum = 0; sum = 0;
for( z = 0; z < n_vlines; z++ ) for( z = 0; z < n_vlines; z++ )
sum += boxes->factor[z] * p[seq->start[z]]; sum += boxes->factor[z] * p[seq->start[z]];
p += istride; p += boxes->n_hlines;
sum = (sum + boxes->rounding) / boxes->area; sum = (sum + boxes->rounding) / boxes->area;
CLIP_UCHAR( sum ); CLIP_UCHAR( sum );
*q = sum; *q = sum;
q += ostride; q += 1;
} }
} }
@ -870,7 +865,6 @@ aconv_vertical( Boxes *boxes, IMAGE *in, IMAGE *out )
*/ */
if( im_cp_desc( out, in ) ) if( im_cp_desc( out, in ) )
return( -1 ); return( -1 );
out->Xsize -= boxes->mask->xsize - 1;
out->Ysize -= boxes->mask->ysize - 1; out->Ysize -= boxes->mask->ysize - 1;
if( out->Xsize <= 0 || out->Ysize <= 0 ) { if( out->Xsize <= 0 || out->Ysize <= 0 ) {
im_error( "im_aconv", "%s", _( "image too small for mask" ) ); im_error( "im_aconv", "%s", _( "image too small for mask" ) );
@ -927,17 +921,17 @@ im_aconv( IMAGE *in, IMAGE *out, DOUBLEMASK *mask, int n_layers, int cluster )
return( -1 ); return( -1 );
/* /*
if( im_embed( in, t[0], 1, n_mask / 2, n_mask / 2, */
in->Xsize + n_mask - 1, in->Ysize + n_mask - 1 ) || if( im_embed( in, t[0], 1, mask->xsize / 2, mask->ysize / 2,
in->Xsize + mask->xsize - 1, in->Ysize + mask->ysize - 1 ) ||
aconv_horizontal( boxes, t[0], t[1] ) || aconv_horizontal( boxes, t[0], t[1] ) ||
aconv_vertical( boxes, t[1], out ) ) aconv_vertical( boxes, t[1], out ) )
return( -1 ); return( -1 );
*/
/* For testing .. just try one direction. /* For testing .. just try one direction.
*/
if( aconv_horizontal( boxes, in, out ) ) if( aconv_horizontal( boxes, in, out ) )
return( -1 ); return( -1 );
*/
out->Xoffset = 0; out->Xoffset = 0;
out->Yoffset = 0; out->Yoffset = 0;