diff --git a/TODO b/TODO index bb970142..a4035c59 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,12 @@ +- try: + + $ vips dzsave k2.jpg x --layout google --overlap 200 + ... + extract_area: bad extract area + + bottom tiles are not being clipped? + + - colour needs to split _build() into preprocess / process / postprocess phases diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c index 8986eb1d..d3720f47 100644 --- a/libvips/foreign/dzsave.c +++ b/libvips/foreign/dzsave.c @@ -112,9 +112,9 @@ /* #define DEBUG_VERBOSE + */ #define DEBUG #define VIPS_DEBUG - */ #ifdef HAVE_CONFIG_H #include @@ -375,8 +375,7 @@ struct _Layer { */ VipsImage *image; - /* The top of this strip of tiles, excluding the overlap. Go up from - * this to get to the top pixel we write in each one. + /* The top of this strip of tiles. */ int y; @@ -414,6 +413,11 @@ struct _VipsForeignSaveDz { Layer *layer; /* x2 shrink pyr layer */ + /* We step by tile_size - overlap as we move across the image ... + * make a note of it. + */ + int tile_step; + /* Count zoomify tiles we write. */ int tile_count; @@ -481,7 +485,8 @@ vips_foreign_save_dz_dispose( GObject *gobject ) VIPS_FREE( dz->root_name ); VIPS_FREE( dz->file_suffix ); - G_OBJECT_CLASS( vips_foreign_save_dz_parent_class )->dispose( gobject ); + G_OBJECT_CLASS( vips_foreign_save_dz_parent_class )-> + dispose( gobject ); } /* Build a pyramid. @@ -503,8 +508,8 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, layer->width = width; layer->height = height; - layer->tiles_across = ROUND_UP( width, dz->tile_size ) / dz->tile_size; - layer->tiles_down = ROUND_UP( height, dz->tile_size ) / dz->tile_size; + layer->tiles_across = ROUND_UP( width, dz->tile_step ) / dz->tile_step; + layer->tiles_down = ROUND_UP( height, dz->tile_step ) / dz->tile_step; layer->real_pixels = *real_pixels; @@ -543,8 +548,7 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, vips__region_no_ownership( layer->strip ); vips__region_no_ownership( layer->copy ); - /* Build a line of tiles here. Normally strips are height + 2 * - * overlap, but the first row is missing the top edge. + /* Build a line of tiles here. * * Expand the strip if necessary to make sure we have an even * number of lines. @@ -554,7 +558,7 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, strip.left = 0; strip.top = 0; strip.width = layer->image->Xsize; - strip.height = dz->tile_size + dz->overlap; + strip.height = dz->tile_size; if( (strip.height & 1) == 1 ) strip.height += 1; if( vips_region_buffer( layer->strip, &strip ) ) { @@ -638,7 +642,8 @@ write_dzi( VipsForeignSaveDz *dz ) if( (p = (char *) vips__find_rightmost_brackets( buf )) ) *p = '\0'; - gsf_output_printf( out, "\n" ); + gsf_output_printf( out, "\n" ); gsf_output_printf( out, "height; line.left = 0; - line.top = layer->y - dz->overlap; + line.top = layer->y; line.width = image.width; - line.height = dz->tile_size + 2 * dz->overlap; + line.height = dz->tile_size; vips_rect_intersectrect( &image, &line, &line ); @@ -963,16 +968,16 @@ strip_allocate( VipsThreadState *state, void *a, gboolean *stop ) /* Position this tile. */ - state->pos.left = strip->x - dz->overlap; + state->pos.left = strip->x; state->pos.top = 0; - state->pos.width = dz->tile_size + 2 * dz->overlap; - state->pos.height = state->im->Ysize; + state->pos.width = dz->tile_size; + state->pos.height = dz->tile_size; vips_rect_intersectrect( &image, &state->pos, &state->pos ); state->x = strip->x; state->y = layer->y; - strip->x += dz->tile_size; + strip->x += dz->tile_step; if( vips_rect_isempty( &state->pos ) ) { *stop = TRUE; @@ -1055,6 +1060,10 @@ tile_name( Layer *layer, int x, int y ) return( NULL ); } +#ifdef DEBUG_VERBOSE + printf( "tile_name: writing to %s\n", name ); +#endif /*DEBUG_VERBOSE*/ + return( out ); } @@ -1124,10 +1133,6 @@ strip_work( VipsThreadState *state, void *a ) x = t; } -#ifdef DEBUG_VERBOSE - printf( "strip_work: writing to %s\n", buf ); -#endif /*DEBUG_VERBOSE*/ - vips_image_set_int( x, "hide-progress", 1 ); if( vips_image_write_to_buffer( x, dz->suffix, &buf, &len, NULL ) ) { g_object_unref( x ); @@ -1140,7 +1145,7 @@ strip_work( VipsThreadState *state, void *a ) g_mutex_lock( vips__global_lock ); out = tile_name( layer, - state->x / dz->tile_size, state->y / dz->tile_size ); + state->x / dz->tile_step, state->y / dz->tile_step ); status = gsf_output_write( out, len, buf ); dz->bytes_written += len; @@ -1197,10 +1202,15 @@ strip_save( Layer *layer ) vips_thread_state_new, strip_allocate, strip_work, NULL, &strip ) ) { strip_free( &strip ); + printf( "strip_save: error: %s\n", vips_error_buffer() ); return( -1 ); } strip_free( &strip ); +#ifdef DEBUG + printf( "strip_save: success\n" ); +#endif /*DEBUG*/ + return( 0 ); } @@ -1272,6 +1282,11 @@ strip_shrink( Layer *layer ) VipsRect target; VipsRect source; +#ifdef DEBUG + printf( "strip_shrink: %d lines in layer %d to layer %d\n", + from->valid.height, layer->n, below->n ); +#endif/*DEBUG*/ + /* We may have an extra column of pixels on the right or * bottom that need filling: generate them. */ @@ -1307,6 +1322,11 @@ strip_shrink( Layer *layer ) target.width = source.width / 2; target.height = source.height / 2; + if( below->n == 0 ) { + printf( "strip_shrink: generating %d lines in layer 0\n", + target.height ); + } + /* None? All done. */ if( vips_rect_isempty( &target ) ) @@ -1336,7 +1356,7 @@ strip_shrink( Layer *layer ) * * - write a line of tiles * - shrink what we can to the layer below - * - move our strip down by the tile height + * - move our strip down by the tile step * - copy the overlap with the previous strip */ static int @@ -1348,6 +1368,11 @@ strip_arrived( Layer *layer ) VipsRect overlap; VipsRect image_area; +#ifdef DEBUG + printf( "strip_arrived: layer %d, strip at %d, height %d\n", + layer->n, layer->y, layer->strip->valid.height ); +#endif/*DEBUG*/ + if( strip_save( layer ) ) return( -1 ); @@ -1360,11 +1385,11 @@ strip_arrived( Layer *layer ) * Expand the strip if necessary to make sure we have an even * number of lines. */ - layer->y += dz->tile_size; + layer->y += dz->tile_step; new_strip.left = 0; - new_strip.top = layer->y - dz->overlap; + new_strip.top = layer->y; new_strip.width = layer->image->Xsize; - new_strip.height = dz->tile_size + 2 * dz->overlap; + new_strip.height = dz->tile_size; image_area.left = 0; image_area.top = 0; @@ -1534,6 +1559,9 @@ vips_foreign_save_dz_build( VipsObject *object ) save->ready = z; } + /* How much we step by as we write tiles. + */ + dz->tile_step = dz->tile_size - dz->overlap; /* The real pixels we have from our input. This is about to get * expanded with background.