moreconst fixes, sinkdisc fixes, constant vector clip added

This commit is contained in:
John Cupitt 2010-06-23 15:45:43 +00:00
parent 1c51b0217b
commit 75fdc5ae4e
4 changed files with 75 additions and 27 deletions

View File

@ -1,5 +1,8 @@
12/5/10 started 7.22.1 12/5/10 started 7.22.1
- fix a problem with tiff pyramid write and >1cpu, thanks Ruven - fix a problem with tiff pyramid write and >1cpu, thanks Ruven
- constant ops clip to target range
- oops, moreconst and moreeqconst were the same
- better buffer handling in sinkdisc for single-line images
12/5/10 started 7.22.0 12/5/10 started 7.22.0
- bump and rename - bump and rename

View File

@ -14,6 +14,8 @@
* 27/8/08 * 27/8/08
* - revise upcasting system * - revise upcasting system
* - add gtkdoc comments * - add gtkdoc comments
* 23/6/10
* - constant ops clip to target range
*/ */
/* /*
@ -170,6 +172,15 @@ im_remainder( IMAGE *in1, IMAGE *in2, IMAGE *out )
(im_wrapmany_fn) remainder_buffer, NULL ) ); (im_wrapmany_fn) remainder_buffer, NULL ) );
} }
/* Cast a vector of double to a vector of TYPE, clipping to a range.
*/
#define CAST_CLIP( TYPE, N, X ) { \
TYPE *tq = (TYPE *) q; \
\
for( i = 0; i < n; i++ ) \
tq[i] = (TYPE) IM_CLIP( N, p[i], X ); \
}
/* Cast a vector of double to a vector of TYPE. /* Cast a vector of double to a vector of TYPE.
*/ */
#define CAST( TYPE ) { \ #define CAST( TYPE ) { \
@ -203,16 +214,45 @@ make_pixel( IMAGE *out, VipsBandFmt fmt, int n, double *p )
return( NULL ); return( NULL );
switch( fmt ) { switch( fmt ) {
case IM_BANDFMT_CHAR: CAST( signed char ); break; case IM_BANDFMT_CHAR:
case IM_BANDFMT_UCHAR: CAST( unsigned char ); break; CAST_CLIP( signed char, SCHAR_MIN, SCHAR_MAX );
case IM_BANDFMT_SHORT: CAST( signed short ); break; break;
case IM_BANDFMT_USHORT: CAST( unsigned short ); break;
case IM_BANDFMT_INT: CAST( signed int ); break; case IM_BANDFMT_UCHAR:
case IM_BANDFMT_UINT: CAST( unsigned int ); break; CAST_CLIP( unsigned char, 0, UCHAR_MAX );
case IM_BANDFMT_FLOAT: CAST( float ); break; break;
case IM_BANDFMT_DOUBLE: CAST( double ); break;
case IM_BANDFMT_COMPLEX: CASTC( float ); break; case IM_BANDFMT_SHORT:
case IM_BANDFMT_DPCOMPLEX: CASTC( double ); break; CAST_CLIP( signed short, SCHAR_MIN, SCHAR_MAX );
break;
case IM_BANDFMT_USHORT:
CAST_CLIP( unsigned short, 0, USHRT_MAX );
break;
case IM_BANDFMT_INT:
CAST_CLIP( signed int, INT_MIN, INT_MAX );
break;
case IM_BANDFMT_UINT:
CAST_CLIP( unsigned int, 0, UINT_MAX );
break;
case IM_BANDFMT_FLOAT:
CAST( float );
break;
case IM_BANDFMT_DOUBLE:
CAST( double );
break;
case IM_BANDFMT_COMPLEX:
CASTC( float );
break;
case IM_BANDFMT_DPCOMPLEX:
CASTC( double );
break;
default: default:
g_assert( 0 ); g_assert( 0 );

View File

@ -3,6 +3,8 @@
* 19/3/10 * 19/3/10
* - from im_wbuffer.c * - from im_wbuffer.c
* - move on top of VipsThreadpool, instead of im_threadgroup_t * - move on top of VipsThreadpool, instead of im_threadgroup_t
* 23/6/10
* - better buffer handling for single-line images
*/ */
/* /*
@ -253,13 +255,11 @@ wbuffer_new( Write *write )
return( wbuffer ); return( wbuffer );
} }
/* Write and swap buffers. /* Block until the previous write completes, then write the front buffer.
*/ */
static int static int
wbuffer_flush( Write *write ) wbuffer_flush( Write *write )
{ {
WriteBuffer *t;
VIPS_DEBUG_MSG( "wbuffer_flush:\n" ); VIPS_DEBUG_MSG( "wbuffer_flush:\n" );
/* Block until the other buffer has been written. We have to do this /* Block until the other buffer has been written. We have to do this
@ -287,12 +287,6 @@ wbuffer_flush( Write *write )
wbuffer_write( write->buf ); wbuffer_write( write->buf );
#endif /*HAVE_THREADS*/ #endif /*HAVE_THREADS*/
/* Swap buffers.
*/
t = write->buf;
write->buf = write->buf_back;
write->buf_back = t;
return( 0 ); return( 0 );
} }
@ -355,7 +349,8 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop )
write->y += write->tile_height; write->y += write->tile_height;
if( write->y >= IM_RECT_BOTTOM( &write->buf->area ) ) { if( write->y >= IM_RECT_BOTTOM( &write->buf->area ) ) {
/* Write and swap buffers. /* Block until the last write is done, then set write
* of the front buffer going.
*/ */
if( wbuffer_flush( write ) ) if( wbuffer_flush( write ) )
return( -1 ); return( -1 );
@ -367,6 +362,16 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop )
return( 0 ); return( 0 );
} }
/* Swap buffers.
*/
{
WriteBuffer *t;
t = write->buf;
write->buf = write->buf_back;
write->buf_back = t;
}
/* Position buf at the new y. /* Position buf at the new y.
*/ */
if( wbuffer_position( write->buf, if( wbuffer_position( write->buf,
@ -518,16 +523,14 @@ vips_sink_disc( VipsImage *im, VipsRegionWrite write_fn, void *a )
&write ) ) &write ) )
result = -1; result = -1;
/* We've set all the buffers writing, but not waited for the BG /* Just before allocate signalled stop, it set write.buf writing. We
* writer to finish. This can take a while: it has to wait for the * need to wait for this write to finish.
* last worker to make the last tile.
* *
* We can't just free the buffers (which will wait for the bg threads * We can't just free the buffers (which will wait for the bg threads
* to finish), since the bg thread might see the kill before it gets a * to finish), since the bg thread might see the kill before it gets a
* chance to write. * chance to write.
*/ */
if( write.buf->area.top > 0 ) im_semaphore_down( &write.buf->done );
im_semaphore_down( &write.buf_back->done );
im__end_eval( im ); im__end_eval( im );

View File

@ -22,6 +22,8 @@
* - gtkdoc * - gtkdoc
* - use new im__arith_binary*() functions * - use new im__arith_binary*() functions
* - more meta-programming * - more meta-programming
* 23/6/10
* - oops, moreconst and moreeqconst were the same
*/ */
/* /*
@ -521,7 +523,7 @@ im_lesseq_vec( IMAGE *in, IMAGE *out, int n, double *c )
} }
#define MORE_REAL( Q, A, B ) { \ #define MORE_REAL( Q, A, B ) { \
if( (A) >= (B) ) \ if( (A) > (B) ) \
Q = 255; \ Q = 255; \
else \ else \
Q = 0; \ Q = 0; \
@ -531,7 +533,7 @@ im_lesseq_vec( IMAGE *in, IMAGE *out, int n, double *c )
double m1 = (A)[0] * (A)[0] + (A)[1] * (A)[1]; \ double m1 = (A)[0] * (A)[0] + (A)[1] * (A)[1]; \
double m2 = (B)[0] * (B)[0] + (B)[1] * (B)[1]; \ double m2 = (B)[0] * (B)[0] + (B)[1] * (B)[1]; \
\ \
if( m1 >= m2 ) \ if( m1 > m2 ) \
Q = 255; \ Q = 255; \
else \ else \
Q = 0; \ Q = 0; \