diff --git a/ChangeLog b/ChangeLog index 0d52972c..76eb4d15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,9 @@ 31/12/12 started 7.30.7 - better option parsing for "vips", thanks Haida +- small fixes to help OS X +- backported threaded tile cache from next version, im_tile_cache() now + uses it to prevent a deadlock, see comment there 14/11/12 started 7.30.6 - capture tiff warnings earlier diff --git a/libvips/conversion/sequential.c b/libvips/conversion/sequential.c index 505dc434..aabf92c2 100644 --- a/libvips/conversion/sequential.c +++ b/libvips/conversion/sequential.c @@ -64,8 +64,11 @@ #include "conversion.h" /* Stall threads that run ahead for up to this long, in seconds. + * + * This has to be a long time: if we're trying to use all cores on a busy + * system, it could be ages until all the other threads get a chance to run. */ -#define STALL_TIME (0.1) +#define STALL_TIME (1.0) typedef struct _VipsSequential { VipsConversion parent_instance; @@ -134,31 +137,45 @@ vips_sequential_generate( VipsRegion *or, return( -1 ); } - if( r->top > sequential->y_pos && + if( r->top > sequential->y_pos && sequential->y_pos > 0 ) { - /* We have started reading (y_pos > 0) and this request is for - * stuff beyond that, stall for a short while to give other + /* We have started reading (y_pos > 0) and this request is for + * stuff beyond that, stall for a while to give other * threads time to catch up. - * + * * The stall can be cancelled by a signal on @ready. + * + * We don't stall forever, since an error would be better than + * deadlock, and we don't fail on timeout, since the timeout + * may be harmless. */ + GTimeVal time; + VIPS_DEBUG_MSG( "thread %p stalling for up to %gs ...\n", g_thread_self(), STALL_TIME ); - vips_g_cond_timed_wait( sequential->ready, - sequential->lock, STALL_TIME * 1000000 ); + g_get_current_time( &time ); + g_time_val_add( &time, STALL_TIME * 1000000 ); + + /* Exit the loop on timeout or condition passes. We have to + * be wary of spurious wakeups. + */ + while( r->top > sequential->y_pos ) + if( !g_cond_timed_wait( sequential->ready, + sequential->lock, &time ) ) + break; + VIPS_DEBUG_MSG( "thread %p awake again ...\n", g_thread_self() ); } - /* This is a request for something some way down the image, and we've - * either not read anything yet or fallen through from the stall - * above. - * - * Probably the operation is something like extract_area and we should - * skip the initial part of the image. In fact, we read to cache, - * since it may be useful. - */ if( r->top > sequential->y_pos ) { + /* This is a request for something some way down the image, + * and we've fallen through from the stall above. + * + * Probably the operation is something like extract_area and + * we should skip the initial part of the image. In fact, + * we read to cache, since it may be useful. + */ VipsRect area; VIPS_DEBUG_MSG( "thread %p skipping to line %d ...\n", diff --git a/libvips/deprecated/Makefile.am b/libvips/deprecated/Makefile.am index 493439bd..0dc90a28 100644 --- a/libvips/deprecated/Makefile.am +++ b/libvips/deprecated/Makefile.am @@ -63,7 +63,6 @@ libdeprecated_la_SOURCES = \ im_png2vips.c \ im_ppm2vips.c \ im_tiff2vips.c \ - im_tile_cache.c \ im_vips2csv.c \ im_vips2jpeg.c \ im_vips2png.c \ diff --git a/libvips/deprecated/im_tile_cache.c b/libvips/deprecated/im_tile_cache.c deleted file mode 100644 index e0986d58..00000000 --- a/libvips/deprecated/im_tile_cache.c +++ /dev/null @@ -1,412 +0,0 @@ -/* Tile tile cache from tiff2vips ... broken out so it can be shared with - * openexr read. - * - * This isn't the same as im_cache(): we don't sub-divide, and we - * single-thread our callee. - * - * 23/8/06 - * - take ownership of reused tiles in case the cache is being shared - * 13/2/07 - * - release ownership after fillng with pixels in case we read across - * threads - * 4/2/10 - * - gtkdoc - * 12/12/10 - * - use im_prepare_to() and avoid making a sequence for every cache tile - */ - -/* - - This file is part of VIPS. - - VIPS is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - */ - -/* - - These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk - - */ - -/* Turn on debugging output. -#define DEBUG - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include -#include - -#include -#include - -/* A tile in our cache. - */ -typedef struct { - struct _Read *read; - - REGION *region; /* REGION with private mem for data */ - int time; /* Time of last use for flush */ - int x; /* xy pos in VIPS image cods */ - int y; -} Tile; - -/* Stuff we track during a read. - */ -typedef struct _Read { - /* Parameters. - */ - IMAGE *in; - IMAGE *out; - int tile_width; - int tile_height; - int max_tiles; - - /* Cache. - */ - int time; /* Update ticks for LRU here */ - int ntiles; /* Current cache size */ - GMutex *lock; /* Lock everything here */ - GSList *cache; /* List of tiles */ -} Read; - -static void -tile_destroy( Tile *tile ) -{ - Read *read = tile->read; - - read->cache = g_slist_remove( read->cache, tile ); - read->ntiles -= 1; - g_assert( read->ntiles >= 0 ); - tile->read = NULL; - - IM_FREEF( im_region_free, tile->region ); - - im_free( tile ); -} - -static void -read_destroy( Read *read ) -{ - IM_FREEF( vips_g_mutex_free, read->lock ); - - while( read->cache ) { - Tile *tile = (Tile *) read->cache->data; - - tile_destroy( tile ); - } - - im_free( read ); -} - -static Read * -read_new( IMAGE *in, IMAGE *out, - int tile_width, int tile_height, int max_tiles ) -{ - Read *read; - - if( !(read = IM_NEW( NULL, Read )) ) - return( NULL ); - read->in = in; - read->out = out; - read->tile_width = tile_width; - read->tile_height = tile_height; - read->max_tiles = max_tiles; - read->time = 0; - read->ntiles = 0; - read->lock = vips_g_mutex_new(); - read->cache = NULL; - - if( im_add_close_callback( out, - (im_callback_fn) read_destroy, read, NULL ) ) { - read_destroy( read ); - return( NULL ); - } - - return( read ); -} - -static Tile * -tile_new( Read *read ) -{ - Tile *tile; - - if( !(tile = IM_NEW( NULL, Tile )) ) - return( NULL ); - - tile->read = read; - tile->region = NULL; - tile->time = read->time; - tile->x = -1; - tile->y = -1; - read->cache = g_slist_prepend( read->cache, tile ); - g_assert( read->ntiles >= 0 ); - read->ntiles += 1; - - if( !(tile->region = im_region_create( read->in )) ) { - tile_destroy( tile ); - return( NULL ); - } - im__region_no_ownership( tile->region ); - - return( tile ); -} - -static int -tile_move( Tile *tile, int x, int y ) -{ - Rect area; - - tile->x = x; - tile->y = y; - - area.left = x; - area.top = y; - area.width = tile->read->tile_width; - area.height = tile->read->tile_height; - - if( im_region_buffer( tile->region, &area ) ) - return( -1 ); - - return( 0 ); -} - -/* Do we have a tile in the cache? - */ -static Tile * -tile_search( Read *read, int x, int y ) -{ - GSList *p; - - for( p = read->cache; p; p = p->next ) { - Tile *tile = (Tile *) p->data; - - if( tile->x == x && tile->y == y ) - return( tile ); - } - - return( NULL ); -} - -static void -tile_touch( Tile *tile ) -{ - g_assert( tile->read->ntiles >= 0 ); - - tile->time = tile->read->time++; -} - -/* Fill a tile with pixels. - */ -static int -tile_fill( Tile *tile, REGION *in ) -{ - Rect area; - -#ifdef DEBUG - printf( "im_tile_cache: filling tile %d x %d\n", tile->x, tile->y ); -#endif /*DEBUG*/ - - area.left = tile->x; - area.top = tile->y; - area.width = tile->read->tile_width; - area.height = tile->read->tile_height; - - if( im_prepare_to( in, tile->region, &area, area.left, area.top ) ) - return( -1 ); - - tile_touch( tile ); - - return( 0 ); -} - -/* Find existing tile, make a new tile, or if we have a full set of tiles, - * reuse LRU. - */ -static Tile * -tile_find( Read *read, REGION *in, int x, int y ) -{ - Tile *tile; - int oldest; - GSList *p; - - /* In cache already? - */ - if( (tile = tile_search( read, x, y )) ) { - tile_touch( tile ); - - return( tile ); - } - - /* Cache not full? - */ - if( read->max_tiles == -1 || - read->ntiles < read->max_tiles ) { - if( !(tile = tile_new( read )) || - tile_move( tile, x, y ) || - tile_fill( tile, in ) ) - return( NULL ); - - return( tile ); - } - - /* Reuse an old one. - */ - oldest = read->time; - tile = NULL; - for( p = read->cache; p; p = p->next ) { - Tile *t = (Tile *) p->data; - - if( t->time < oldest ) { - oldest = t->time; - tile = t; - } - } - - g_assert( tile ); - -#ifdef DEBUG - printf( "im_tile_cache: reusing tile %d x %d\n", tile->x, tile->y ); -#endif /*DEBUG*/ - - if( tile_move( tile, x, y ) || - tile_fill( tile, in ) ) - return( NULL ); - - return( tile ); -} - -/* Copy rect from from to to. - */ -static void -copy_region( REGION *from, REGION *to, Rect *area ) -{ - int y; - - /* Area should be inside both from and to. - */ - g_assert( im_rect_includesrect( &from->valid, area ) ); - g_assert( im_rect_includesrect( &to->valid, area ) ); - - /* Loop down common area, copying. - */ - for( y = area->top; y < IM_RECT_BOTTOM( area ); y++ ) { - PEL *p = (PEL *) IM_REGION_ADDR( from, area->left, y ); - PEL *q = (PEL *) IM_REGION_ADDR( to, area->left, y ); - - memcpy( q, p, IM_IMAGE_SIZEOF_PEL( from->im ) * area->width ); - } -} - -/* Loop over the output region, filling with data from cache. - */ -static int -tile_cache_fill( REGION *out, void *seq, void *a, void *b ) -{ - REGION *in = (REGION *) seq; - Read *read = (Read *) b; - const int tw = read->tile_width; - const int th = read->tile_height; - Rect *r = &out->valid; - - /* Find top left of tiles we need. - */ - int xs = (r->left / tw) * tw; - int ys = (r->top / th) * th; - - int x, y; - - g_mutex_lock( read->lock ); - - for( y = ys; y < IM_RECT_BOTTOM( r ); y += th ) - for( x = xs; x < IM_RECT_RIGHT( r ); x += tw ) { - Tile *tile; - Rect tarea; - Rect hit; - - if( !(tile = tile_find( read, in, x, y )) ) { - g_mutex_unlock( read->lock ); - return( -1 ); - } - - /* The area of the tile. - */ - tarea.left = x; - tarea.top = y; - tarea.width = tw; - tarea.height = th; - - /* The part of the tile that we need. - */ - im_rect_intersectrect( &tarea, r, &hit ); - - copy_region( tile->region, out, &hit ); - } - - g_mutex_unlock( read->lock ); - - return( 0 ); -} - -/** - * im_tile_cache: - * @in: input image - * @out: output image - * @tile_width: tile width - * @tile_height: tile height - * @max_tiles: maximum number of tiles to cache - * - * This operation behaves rather like im_copy() between images - * @in and @out, except that it keeps a cache of computed pixels. - * This cache is made of up to @max_tiles tiles (a value of -1 for - * means any number of tiles), and each tile is of size @tile_width - * by @tile_height pixels. Each cache tile is made with a single call to - * im_prepare(). - * - * This is a lower-level operation than im_cache() since it does no - * subdivision. It is suitable for caching the output of operations like - * im_exr2vips() on tiled images. - * - * See also: im_cache(). - * - * Returns: 0 on success, -1 on error. - */ -int -im_tile_cache( IMAGE *in, IMAGE *out, - int tile_width, int tile_height, int max_tiles ) -{ - Read *read; - - if( tile_width <= 0 || tile_height <= 0 || max_tiles < -1 ) { - im_error( "im_tile_cache", "%s", _( "bad parameters" ) ); - return( -1 ); - } - - if( im_piocheck( in, out ) || - im_cp_desc( out, in ) || - im_demand_hint( out, IM_ANY, in, NULL ) || - !(read = read_new( in, out, - tile_width, tile_height, max_tiles )) || - im_generate( out, - im_start_one, tile_cache_fill, im_stop_one, in, read ) ) - return( -1 ); - - return( 0 ); -} diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index ae783e84..84a03eac 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2145,6 +2145,7 @@ im_rightshift_size( IMAGE *in, IMAGE *out, return( 0 ); } +<<<<<<< HEAD int im_Lab2XYZ_temp( IMAGE *in, IMAGE *out, double X0, double Y0, double Z0 ) { @@ -2877,6 +2878,47 @@ im_cross_phase( IMAGE *in1, IMAGE *in2, IMAGE *out ) if( vips_call( "cross_phase", in1, in2, &x, NULL ) ) return( -1 ); + + if( im_copy( x, out ) ) { + g_object_unref( x ); + return( -1 ); + } + g_object_unref( x ); + + return( 0 ); +} + +/* This is used by vipsthumbnail and the carrierwave shrinker to cache the + * output of shrink before doing the final affine. + * + * We use the vips8 threaded tilecache to avoid a deadlock: suppose thread1, + * evaluating the top block of the output is delayed, and thread2, evaluating + * the second block gets here first (this can happen on a heavily-loaded + * system). + * + * With an unthreaded tilecache (as we had before), thread2 will get + * the cache lock and start evaling the second block of the shrink. When it + * reaches the png reader it will stall untilthe first block has been used ... + * but it never will, since thread1 will block on this cache lock. + * + * This function is only used in those two places (I think), so it's OK to + * hard-wire this to be a sequential threaded cache. + */ +int +im_tile_cache( IMAGE *in, IMAGE *out, + int tile_width, int tile_height, int max_tiles ) +{ + VipsImage *x; + + if( vips_tilecache( in, &x, + "tile_width", tile_width, + "tile_height", tile_height, + "max_tiles", max_tiles, + "strategy", VIPS_CACHE_SEQUENTIAL, + "threaded", TRUE, + NULL ) ) + return( -1 ); + if( im_copy( x, out ) ) { g_object_unref( x ); return( -1 ); diff --git a/libvips/foreign/vipspng.c b/libvips/foreign/vipspng.c index 0fce2bb0..61bb6355 100644 --- a/libvips/foreign/vipspng.c +++ b/libvips/foreign/vipspng.c @@ -124,6 +124,7 @@ typedef struct { VipsImage *out; FILE *fp; + int y_pos; png_structp pPng; png_infop pInfo; png_bytep *row_pointer; @@ -149,6 +150,7 @@ read_new( const char *name, VipsImage *out ) read->name = vips_strdup( VIPS_OBJECT( out ), name ); read->out = out; read->fp = NULL; + read->y_pos = 0; read->pPng = NULL; read->pInfo = NULL; read->row_pointer = NULL; @@ -421,10 +423,23 @@ png2vips_generate( VipsRegion *or, */ g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) ); + /* And check that y_pos is correct. It should be, since we are inside + * a vips_sequential(). + */ + if( r->top != read->y_pos ) { + printf( "png2vips_generate: y_pos == %d, top == %d\n", + read->y_pos, r->top ); + g_assert( r->top == read->y_pos ); + } + if( setjmp( png_jmpbuf( read->pPng ) ) ) { #ifdef DEBUG - printf( "png2vips_generate: failing in setjmp\n" ); #endif /*DEBUG*/ + printf( "png2vips_generate: failing in setjmp\n" ); + printf( "png2vips_generate: line %d, %d rows\n", + r->top, r->height ); + printf( "png2vips_generate: file %s\n", read->name ); + printf( "png2vips_generate: thread %p\n", g_thread_self() ); return( -1 ); } @@ -433,6 +448,8 @@ png2vips_generate( VipsRegion *or, png_bytep q = (png_bytep) VIPS_REGION_ADDR( or, 0, r->top + y ); png_read_row( read->pPng, q, NULL ); + + read->y_pos += 1; } return( 0 ); @@ -460,7 +477,7 @@ vips__png_isinterlaced( const char *filename ) } int -vips__png_read( const char *name, VipsImage *out ) +vips__png_read( const char *filename, VipsImage *out ) { VipsImage **t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( out ), 3 ); @@ -469,10 +486,10 @@ vips__png_read( const char *name, VipsImage *out ) int interlace_type; #ifdef DEBUG - printf( "png2vips: reading \"%s\"\n", name ); + printf( "vips__png_read: reading \"%s\"\n", filename ); #endif /*DEBUG*/ - if( !(read = read_new( name, out )) ) + if( !(read = read_new( filename, out )) ) return( -1 ); interlace_type = png_get_interlace_type( read->pPng, read->pInfo ); @@ -501,7 +518,7 @@ vips__png_read( const char *name, VipsImage *out ) } #ifdef DEBUG - printf( "png2vips: done\n" ); + printf( "vips__png_read: done\n" ); #endif /*DEBUG*/ return( 0 ); @@ -718,6 +735,10 @@ vips__png_write( VipsImage *in, const char *filename, { Write *write; +#ifdef DEBUG + printf( "vips__png_write: writing \"%s\"\n", filename ); +#endif /*DEBUG*/ + if( !(write = write_new( in )) ) return( -1 ); @@ -738,6 +759,10 @@ vips__png_write( VipsImage *in, const char *filename, write_finish( write ); +#ifdef DEBUG + printf( "vips__png_write: done\n" ); +#endif /*DEBUG*/ + return( 0 ); } diff --git a/libvips/iofuncs/sinkdisc.c b/libvips/iofuncs/sinkdisc.c index 37a3bae5..de287387 100644 --- a/libvips/iofuncs/sinkdisc.c +++ b/libvips/iofuncs/sinkdisc.c @@ -374,8 +374,9 @@ wbuffer_allocate_fn( VipsThreadState *state, void *a, gboolean *stop ) */ wstate->buf = write->buf; - VIPS_DEBUG_MSG( " allocated " + VIPS_DEBUG_MSG( " thread %p allocated " "left = %d, top = %d, width = %d, height = %d\n", + g_thread_self(), tile.left, tile.top, tile.width, tile.height ); /* Add to the number of writers on the buffer. @@ -402,13 +403,15 @@ wbuffer_work_fn( VipsThreadState *state, void *a ) int result; - VIPS_DEBUG_MSG( "wbuffer_work_fn: %p %d x %d\n", - state, state->pos.left, state->pos.top ); + VIPS_DEBUG_MSG( "wbuffer_work_fn: thread %p, %d x %d\n", + g_thread_self(), + state->pos.left, state->pos.top ); result = vips_region_prepare_to( state->reg, wstate->buf->region, &state->pos, state->pos.left, state->pos.top ); - VIPS_DEBUG_MSG( "wbuffer_work_fn: %p result = %d\n", state, result ); + VIPS_DEBUG_MSG( "wbuffer_work_fn: thread %p result = %d\n", + g_thread_self(), result ); /* Tell the bg write thread we've left. */ diff --git a/libvips/resample/shrink.c b/libvips/resample/shrink.c index c20c7149..58dde16f 100644 --- a/libvips/resample/shrink.c +++ b/libvips/resample/shrink.c @@ -352,6 +352,14 @@ vips_shrink_build( VipsObject *object ) return( -1 ); } +#ifdef DEBUG + printf( "vips_shrink_build: shrinking %d x %d image to %d x %d\n", + resample->in->Xsize, resample->in->Ysize, + resample->out->Xsize, resample->out->Ysize ); + printf( "vips_shrink_build: %d x %d block average\n", + shrink->mw, shrink->mh ); +#endif /*DEBUG*/ + if( vips_image_generate( resample->out, vips_shrink_start, vips_shrink_gen, vips_shrink_stop, resample->in, shrink ) ) diff --git a/po/vips7.pot b/po/vips7.pot index df05d736..8c595daa 100644 --- a/po/vips7.pot +++ b/po/vips7.pot @@ -9,7 +9,11 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=glib&keywords=I18N+L10N&component=general\n" +<<<<<<< HEAD "POT-Creation-Date: 2012-11-21 21:39+0000\n" +======= +"POT-Creation-Date: 2013-01-15 13:40+0000\n" +>>>>>>> origin/7.30 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -401,6 +405,7 @@ msgstr "" msgid "Right" msgstr "" +<<<<<<< HEAD #: ../libvips/arithmetic/binary.c:102 msgid "Right-hand image argument" msgstr "" @@ -436,6 +441,45 @@ msgstr "" #: ../libvips/arithmetic/relational.c:552 msgid "relational operations against a constant" +======= +#: ../libvips/arithmetic/measure.c:222 ../libvips/arithmetic/binary.c:95 +#: ../libvips/conversion/extract.c:204 +msgid "Left" +msgstr "" + +#: ../libvips/arithmetic/measure.c:223 ../libvips/conversion/extract.c:205 +msgid "Left edge of extract area" +msgstr "" + +#: ../libvips/arithmetic/measure.c:229 ../libvips/conversion/extract.c:211 +msgid "Top" +msgstr "" + +#: ../libvips/arithmetic/measure.c:230 ../libvips/conversion/extract.c:212 +msgid "Top edge of extract area" +msgstr "" + +#: ../libvips/arithmetic/measure.c:236 ../libvips/conversion/extract.c:218 +#: ../libvips/conversion/black.c:128 ../libvips/conversion/copy.c:334 +#: ../libvips/conversion/embed.c:543 ../libvips/foreign/rawload.c:122 +#: ../libvips/iofuncs/image.c:876 +msgid "Width" +msgstr "" + +#: ../libvips/arithmetic/measure.c:237 ../libvips/conversion/extract.c:219 +msgid "Width of extract area" +msgstr "" + +#: ../libvips/arithmetic/measure.c:243 ../libvips/conversion/extract.c:225 +#: ../libvips/conversion/black.c:135 ../libvips/conversion/copy.c:341 +#: ../libvips/conversion/embed.c:550 ../libvips/foreign/rawload.c:129 +#: ../libvips/iofuncs/image.c:883 +msgid "Height" +msgstr "" + +#: ../libvips/arithmetic/measure.c:244 ../libvips/conversion/extract.c:226 +msgid "Height of extract area" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/arithmetic/measure.c:164 @@ -443,8 +487,17 @@ msgstr "" msgid "patch %d x %d, band %d: avg = %g, sdev = %g" msgstr "" +<<<<<<< HEAD #: ../libvips/arithmetic/measure.c:193 msgid "measure a set of patches on a colour chart" +======= +#: ../libvips/arithmetic/math2.c:206 ../libvips/arithmetic/math2.c:403 +#: ../libvips/arithmetic/complex.c:222 ../libvips/arithmetic/complex.c:476 +#: ../libvips/arithmetic/math.c:205 ../libvips/arithmetic/relational.c:227 +#: ../libvips/arithmetic/relational.c:560 ../libvips/arithmetic/boolean.c:217 +#: ../libvips/arithmetic/boolean.c:519 ../tools/vips.c:978 +msgid "Operation" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/arithmetic/measure.c:197 @@ -471,8 +524,22 @@ msgstr "" msgid "Number of patches down chart" msgstr "" +<<<<<<< HEAD #: ../libvips/arithmetic/measure.c:224 ../libvips/conversion/extract.c:206 msgid "Left edge of extract area" +======= +#: ../libvips/arithmetic/unary.c:87 ../libvips/arithmetic/statistic.c:151 +#: ../libvips/conversion/flip.c:240 ../libvips/conversion/bandmean.c:197 +#: ../libvips/conversion/cast.c:479 ../libvips/conversion/flatten.c:375 +#: ../libvips/conversion/extract.c:198 ../libvips/conversion/extract.c:357 +#: ../libvips/conversion/bandjoin.c:171 ../libvips/conversion/copy.c:321 +#: ../libvips/conversion/rot.c:359 ../libvips/conversion/replicate.c:196 +#: ../libvips/conversion/tilecache.c:424 ../libvips/conversion/embed.c:523 +#: ../libvips/conversion/cache.c:100 ../libvips/conversion/recomb.c:203 +#: ../libvips/conversion/sequential.c:288 ../libvips/foreign/foreign.c:1413 +#: ../libvips/resample/resample.c:89 +msgid "Input" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/arithmetic/measure.c:230 ../libvips/conversion/extract.c:212 @@ -673,9 +740,20 @@ msgstr "" msgid "output" msgstr "" +<<<<<<< HEAD #: ../libvips/colour/icc_transform.c:399 ../libvips/colour/icc_transform.c:600 #: ../libvips/colour/icc_transform.c:811 msgid "unable to load embedded profile" +======= +#: ../libvips/arithmetic/statistic.c:152 ../libvips/conversion/flip.c:241 +#: ../libvips/conversion/cast.c:480 ../libvips/conversion/flatten.c:376 +#: ../libvips/conversion/extract.c:199 ../libvips/conversion/extract.c:358 +#: ../libvips/conversion/copy.c:322 ../libvips/conversion/rot.c:360 +#: ../libvips/conversion/replicate.c:197 ../libvips/conversion/tilecache.c:425 +#: ../libvips/conversion/embed.c:524 ../libvips/conversion/cache.c:101 +#: ../libvips/conversion/sequential.c:289 +msgid "Input image" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/colour/icc_transform.c:407 ../libvips/colour/icc_transform.c:608 @@ -886,6 +964,7 @@ msgstr "" msgid "Background" msgstr "" +<<<<<<< HEAD #: ../libvips/conversion/flatten.c:383 msgid "Background value" msgstr "" @@ -917,6 +996,38 @@ msgstr "" #: ../libvips/conversion/cache.c:106 ../libvips/conversion/tilecache.c:732 #: ../libvips/foreign/dzsave.c:1211 ../libvips/foreign/tiffsave.c:215 msgid "Tile width" +======= +#: ../libvips/conversion/extract.c:148 +msgid "bad extract area" +msgstr "" + +#: ../libvips/conversion/extract.c:192 +msgid "extract an area from an image" +msgstr "" + +#: ../libvips/conversion/extract.c:322 +msgid "bad extract band" +msgstr "" + +#: ../libvips/conversion/extract.c:351 +msgid "extract band from an image" +msgstr "" + +#: ../libvips/conversion/extract.c:363 +msgid "Band" +msgstr "" + +#: ../libvips/conversion/extract.c:364 +msgid "Band to extract" +msgstr "" + +#: ../libvips/conversion/extract.c:370 +msgid "n" +msgstr "" + +#: ../libvips/conversion/extract.c:371 +msgid "Number of bands to extract" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/conversion/cache.c:107 ../libvips/conversion/tilecache.c:733 @@ -1092,6 +1203,7 @@ msgstr "" msgid "Condition input image" msgstr "" +<<<<<<< HEAD #: ../libvips/conversion/ifthenelse.c:482 msgid "Then image" msgstr "" @@ -1134,6 +1246,60 @@ msgstr "" #: ../libvips/conversion/tilecache.c:728 msgid "cache an image as a set of tiles" +======= +#: ../libvips/conversion/tilecache.c:418 ../libvips/conversion/cache.c:96 +msgid "cache an image" +msgstr "" + +#: ../libvips/conversion/tilecache.c:430 ../libvips/conversion/cache.c:113 +#: ../libvips/conversion/sequential.c:301 ../libvips/foreign/tiffsave.c:222 +#: ../libvips/foreign/dzsave.c:927 +msgid "Tile height" +msgstr "" + +#: ../libvips/conversion/tilecache.c:431 ../libvips/conversion/cache.c:114 +#: ../libvips/conversion/sequential.c:302 ../libvips/foreign/tiffsave.c:223 +#: ../libvips/foreign/dzsave.c:928 +msgid "Tile height in pixels" +msgstr "" + +#: ../libvips/conversion/tilecache.c:437 +msgid "Threaded" +msgstr "" + +#: ../libvips/conversion/tilecache.c:438 +msgid "Allow threaded access" +msgstr "" + +#: ../libvips/conversion/tilecache.c:444 +msgid "Strategy" +msgstr "" + +#: ../libvips/conversion/tilecache.c:445 +msgid "Expected access pattern" +msgstr "" + +#: ../libvips/conversion/tilecache.c:728 +msgid "cache an image as a set of tiles" +msgstr "" + +#: ../libvips/conversion/tilecache.c:732 ../libvips/conversion/cache.c:106 +#: ../libvips/foreign/tiffsave.c:215 ../libvips/foreign/dzsave.c:920 +msgid "Tile width" +msgstr "" + +#: ../libvips/conversion/tilecache.c:733 ../libvips/conversion/cache.c:107 +#: ../libvips/foreign/tiffsave.c:216 ../libvips/foreign/dzsave.c:921 +msgid "Tile width in pixels" +msgstr "" + +#: ../libvips/conversion/tilecache.c:739 ../libvips/conversion/cache.c:120 +msgid "Max tiles" +msgstr "" + +#: ../libvips/conversion/tilecache.c:740 ../libvips/conversion/cache.c:121 +msgid "Maximum number of tiles to cache" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/conversion/tilecache.c:896 @@ -1226,6 +1392,7 @@ msgstr "" msgid "Xres" msgstr "" +<<<<<<< HEAD #: ../libvips/conversion/copy.c:377 ../libvips/foreign/tiffsave.c:252 #: ../libvips/iofuncs/image.c:925 msgid "Horizontal resolution in pixels/mm" @@ -1239,6 +1406,18 @@ msgstr "" #: ../libvips/conversion/copy.c:384 ../libvips/foreign/tiffsave.c:259 #: ../libvips/iofuncs/image.c:932 msgid "Vertical resolution in pixels/mm" +======= +#: ../libvips/conversion/sequential.c:284 +msgid "check sequential access" +msgstr "" + +#: ../libvips/conversion/sequential.c:294 +msgid "trace" +msgstr "" + +#: ../libvips/conversion/sequential.c:295 +msgid "trace pixel requests" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/conversion/copy.c:390 ../libvips/iofuncs/image.c:938 @@ -1274,8 +1453,24 @@ msgstr "" msgid "%d underflows and %d overflows detected" msgstr "" +<<<<<<< HEAD #: ../libvips/conversion/cast.c:476 msgid "cast an image" +======= +#: ../libvips/foreign/rawsave.c:166 ../libvips/foreign/radload.c:126 +#: ../libvips/foreign/tiffload.c:149 ../libvips/foreign/ppmsave.c:118 +#: ../libvips/foreign/vipsload.c:133 ../libvips/foreign/pngload.c:136 +#: ../libvips/foreign/openexrload.c:137 ../libvips/foreign/tiffsave.c:171 +#: ../libvips/foreign/analyzeload.c:126 ../libvips/foreign/jpegsave.c:193 +#: ../libvips/foreign/fitsload.c:116 ../libvips/foreign/ppmload.c:126 +#: ../libvips/foreign/csvload.c:132 ../libvips/foreign/magickload.c:146 +#: ../libvips/foreign/openslideload.c:178 ../libvips/foreign/csvsave.c:121 +#: ../libvips/foreign/jpegload.c:245 ../libvips/foreign/rawload.c:115 +#: ../libvips/foreign/matload.c:128 ../libvips/foreign/fitssave.c:128 +#: ../libvips/foreign/radsave.c:119 ../libvips/foreign/vipssave.c:125 +#: ../libvips/foreign/pngsave.c:168 ../libvips/iofuncs/image.c:946 +msgid "Filename" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/conversion/cast.c:489 @@ -1298,6 +1493,7 @@ msgstr "" msgid "bad dimensions" msgstr "" +<<<<<<< HEAD #: ../libvips/conversion/embed.c:544 msgid "embed an image in a larger image" msgstr "" @@ -1312,6 +1508,28 @@ msgstr "" #: ../libvips/conversion/embed.c:584 msgid "Extend" +======= +#: ../libvips/foreign/radload.c:127 ../libvips/foreign/tiffload.c:150 +#: ../libvips/foreign/vipsload.c:134 ../libvips/foreign/pngload.c:137 +#: ../libvips/foreign/openexrload.c:138 ../libvips/foreign/analyzeload.c:127 +#: ../libvips/foreign/fitsload.c:117 ../libvips/foreign/ppmload.c:127 +#: ../libvips/foreign/csvload.c:133 ../libvips/foreign/magickload.c:147 +#: ../libvips/foreign/openslideload.c:179 ../libvips/foreign/jpegload.c:246 +#: ../libvips/foreign/rawload.c:116 ../libvips/foreign/matload.c:129 +msgid "Filename to load from" +msgstr "" + +#: ../libvips/foreign/tiffload.c:137 +msgid "load tiff from file" +msgstr "" + +#: ../libvips/foreign/tiffload.c:156 +msgid "Page" +msgstr "" + +#: ../libvips/foreign/tiffload.c:157 +msgid "Load this page from the file" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/conversion/embed.c:585 @@ -1401,9 +1619,14 @@ msgstr "" msgid "%d overflows and %d underflows detected" msgstr "" +<<<<<<< HEAD #: ../libvips/convolution/im_conv.c:1125 #: ../libvips/convolution/im_conv_f.c:403 msgid "expect 1xN or Nx1 input mask" +======= +#: ../libvips/foreign/radiance.c:959 ../libvips/foreign/tiff2vips.c:1355 +msgid "read error" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/convolution/im_contrast_surface.c:147 @@ -1797,12 +2020,20 @@ msgstr "" msgid "bad page number %d" msgstr "" +<<<<<<< HEAD #: ../libvips/foreign/tiff2vips.c:1547 ../libvips/foreign/tiff2vips.c:1576 +======= +#: ../libvips/foreign/tiff2vips.c:1494 ../libvips/foreign/vips2tiff.c:294 +>>>>>>> origin/7.30 #, c-format msgid "TIFF file does not contain page %d" msgstr "" +<<<<<<< HEAD #: ../libvips/foreign/openexr2vips.c:115 +======= +#: ../libvips/foreign/tiff2vips.c:1547 ../libvips/foreign/tiff2vips.c:1576 +>>>>>>> origin/7.30 #, c-format msgid "EXR error: %s" msgstr "" @@ -2061,12 +2292,21 @@ msgstr "" msgid "Write a tiled tiff" msgstr "" +<<<<<<< HEAD #: ../libvips/foreign/tiffsave.c:229 msgid "Pyramid" msgstr "" #: ../libvips/foreign/tiffsave.c:230 msgid "Write a pyramidal tiff" +======= +#: ../libvips/foreign/vips2tiff.c:1507 +msgid "unsigned 8-bit int, 16-bit int, and 32-bit float only" +msgstr "" + +#: ../libvips/foreign/vips2tiff.c:1514 +msgid "1 to 5 bands only" +>>>>>>> origin/7.30 msgstr "" #: ../libvips/foreign/tiffsave.c:236 @@ -2133,24 +2373,24 @@ msgstr "" msgid "load vips from file" msgstr "" -#: ../libvips/foreign/vipspng.c:241 +#: ../libvips/foreign/vipspng.c:243 msgid "unsupported color type" msgstr "" -#: ../libvips/foreign/vipspng.c:350 +#: ../libvips/foreign/vipspng.c:352 msgid "unable to read PNG header" msgstr "" -#: ../libvips/foreign/vipspng.c:633 +#: ../libvips/foreign/vipspng.c:648 msgid "compress should be in [0,9]" msgstr "" -#: ../libvips/foreign/vipspng.c:730 +#: ../libvips/foreign/vipspng.c:755 #, c-format msgid "unable to write \"%s\"" msgstr "" -#: ../libvips/foreign/vipspng.c:829 +#: ../libvips/foreign/vipspng.c:858 msgid "unable to write to buffer" msgstr "" @@ -3412,6 +3652,7 @@ msgstr "" msgid "not integer shrink factors, expect poor results" msgstr "" +<<<<<<< HEAD #: ../libvips/resample/shrink.c:376 msgid "shrink an image" msgstr "" @@ -3429,6 +3670,25 @@ msgid "Yshrink" msgstr "" #: ../libvips/resample/shrink.c:390 +======= +#: ../libvips/resample/shrink.c:379 +msgid "shrink an image" +msgstr "" + +#: ../libvips/resample/shrink.c:385 +msgid "Xshrink" +msgstr "" + +#: ../libvips/resample/shrink.c:386 +msgid "Horizontal shrink factor" +msgstr "" + +#: ../libvips/resample/shrink.c:392 +msgid "Yshrink" +msgstr "" + +#: ../libvips/resample/shrink.c:393 +>>>>>>> origin/7.30 msgid "Vertical shrink factor" msgstr "" @@ -3662,23 +3922,24 @@ msgstr "" msgid "Need more than one image" msgstr "" -#: ../tools/vips.c:101 +#: ../tools/vips.c:103 msgid "load PLUGIN" msgstr "" -#: ../tools/vips.c:102 +#: ../tools/vips.c:104 msgid "PLUGIN" msgstr "" -#: ../tools/vips.c:104 +#: ../tools/vips.c:106 msgid "print version" msgstr "" -#: ../tools/vips.c:147 +#: ../tools/vips.c:149 #, c-format msgid "no package or function \"%s\"" msgstr "" +<<<<<<< HEAD #: ../tools/vips.c:939 msgid "list classes|packages|all|package-name|operation-name" msgstr "" @@ -3712,6 +3973,41 @@ msgid "[ACTION] [OPTIONS] [PARAMETERS] - VIPS driver program" msgstr "" #: ../tools/vips.c:1166 +======= +#: ../tools/vips.c:927 +msgid "list classes|packages|all|package-name|operation-name" +msgstr "" + +#: ../tools/vips.c:929 +msgid "generate headers for C++ binding" +msgstr "" + +#: ../tools/vips.c:931 +msgid "generate bodies for C++ binding" +msgstr "" + +#: ../tools/vips.c:933 +msgid "generate links for vips/bin" +msgstr "" + +#: ../tools/vips.c:978 +msgid "Operation help" +msgstr "" + +#: ../tools/vips.c:1018 +msgid "[ACTION] [OPTIONS] [PARAMETERS] - VIPS driver program" +msgstr "" + +#: ../tools/vips.c:1177 +msgid "possible actions:\n" +msgstr "" + +#: ../tools/vips.c:1182 +msgid "execute named vips operation" +msgstr "" + +#: ../tools/vips.c:1184 +>>>>>>> origin/7.30 #, c-format msgid "unknown action \"%s\"" msgstr ""