From 582a7f18108f7a3c5ca13bd2e36852e5a75eea08 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 31 Oct 2015 10:43:08 +0000 Subject: [PATCH] shrink2 now done big mem saving, still a bit slower though --- TODO | 14 ++++++-------- doc/gtk-doc.make | 20 ++++++++++++-------- libvips/include/vips/resample.h | 2 ++ libvips/resample/Makefile.am | 1 + libvips/resample/resample.c | 2 ++ libvips/resample/shrink2.c | 14 +++++--------- libvips/resample/shrinkh.c | 14 +++++++------- libvips/resample/shrinkv.c | 14 +++++++------- 8 files changed, 42 insertions(+), 39 deletions(-) diff --git a/TODO b/TODO index 9b516bd1..a6fd2dc1 100644 --- a/TODO +++ b/TODO @@ -14,17 +14,15 @@ we would then only need to demand the source a line at a time, and the intermediate image would be much smaller ... possible cache savings as well - added shrink2 for the new code + currently a bit slower than old shrink, much less mem though - current state on work machine, debug build + try: - $ time vips shrink wtc.jpg x.v 10 10 - memory: high-water mark 238.09 MB - real 0m1.178s - user 0m1.384s - sys 0m0.064s + * special path for RGB and mono - done h/v, get shrink2 done and bench against plain shrink + * for shrinkh, prepare input in batches? + + * change loop indexing? don't use *p++ etc., it'll break vectorization - add bandjoinconst ... append a band (or bands?) from a constant diff --git a/doc/gtk-doc.make b/doc/gtk-doc.make index e7916563..9ccd0b04 100644 --- a/doc/gtk-doc.make +++ b/doc/gtk-doc.make @@ -25,6 +25,7 @@ TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) SETUP_FILES = \ $(content_files) \ + $(expand_content_files) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt @@ -86,7 +87,7 @@ GTK_DOC_V_SETUP_0=@echo " DOC Preparing build"; setup-build.stamp: -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - files=`echo $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types`; \ + files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \ if test "x$$files" != "x" ; then \ for file in $$files ; do \ destdir=`dirname $(abs_builddir)/$$file`; \ @@ -118,7 +119,7 @@ scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ scanobj_options=""; \ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ scanobj_options="--verbose"; \ fi; \ @@ -162,17 +163,17 @@ GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V)) GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references"; -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \ mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkhtml_options="$$mkhtml_options --verbose"; \ fi; \ fi; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ fi; \ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) @@ -194,11 +195,11 @@ GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V)) GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_PDF_0=@echo " DOC Building PDF"; -pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \ mkpdf_options=""; \ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkpdf_options="$$mkpdf_options --verbose"; \ fi; \ @@ -223,12 +224,15 @@ clean-local: @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ rm -f $(DOC_MODULE).types; \ fi + @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \ + rm -f $(DOC_MODULE)-sections.txt; \ + fi distclean-local: @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - rm -f $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types; \ + rm -f $(SETUP_FILES) $(DOC_MODULE).types; \ fi maintainer-clean-local: diff --git a/libvips/include/vips/resample.h b/libvips/include/vips/resample.h index 7807e08d..acb94e54 100644 --- a/libvips/include/vips/resample.h +++ b/libvips/include/vips/resample.h @@ -43,6 +43,8 @@ int vips_shrink( VipsImage *in, VipsImage **out, __attribute__((sentinel)); int vips_shrinkh( VipsImage *in, VipsImage **out, int xshrink, ... ); int vips_shrinkv( VipsImage *in, VipsImage **out, int yshrink, ... ); +int vips_shrink2( VipsImage *in, VipsImage **out, + int xshrink, int yshrink, ... ); int vips_similarity( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_resize( VipsImage *in, VipsImage **out, double scale, ... ) diff --git a/libvips/resample/Makefile.am b/libvips/resample/Makefile.am index bb9f8db2..c9d6a5ec 100644 --- a/libvips/resample/Makefile.am +++ b/libvips/resample/Makefile.am @@ -8,6 +8,7 @@ libresample_la_SOURCES = \ shrink.c \ shrinkh.c \ shrinkv.c \ + shrink2.c \ interpolate.c \ transform.c \ bicubic.cpp \ diff --git a/libvips/resample/resample.c b/libvips/resample/resample.c index 83d8fe7b..b971436b 100644 --- a/libvips/resample/resample.c +++ b/libvips/resample/resample.c @@ -114,6 +114,7 @@ vips_resample_operation_init( void ) extern GType vips_shrink_get_type( void ); extern GType vips_shrinkh_get_type( void ); extern GType vips_shrinkv_get_type( void ); + extern GType vips_shrink2_get_type( void ); extern GType vips_quadratic_get_type( void ); extern GType vips_affine_get_type( void ); extern GType vips_similarity_get_type( void ); @@ -122,6 +123,7 @@ vips_resample_operation_init( void ) vips_shrink_get_type(); vips_shrinkh_get_type(); vips_shrinkv_get_type(); + vips_shrink2_get_type(); vips_quadratic_get_type(); vips_affine_get_type(); vips_similarity_get_type(); diff --git a/libvips/resample/shrink2.c b/libvips/resample/shrink2.c index dc0dc59d..e890dacd 100644 --- a/libvips/resample/shrink2.c +++ b/libvips/resample/shrink2.c @@ -69,19 +69,15 @@ vips_shrink2_build( VipsObject *object ) VipsResample *resample = VIPS_RESAMPLE( object ); VipsShrink2 *shrink = (VipsShrink2 *) object; VipsImage **t = (VipsImage **) - vips_object_local_array( object, 1 ); - - VipsImage *in; + vips_object_local_array( object, 2 ); if( VIPS_OBJECT_CLASS( vips_shrink2_parent_class )->build( object ) ) return( -1 ); - in = resample->in; - - if( vips_shrinkh( in, &t[0], shrink->xshrink, NULL ) || - vips_shrinkv( t[0], &t[1], shrink->yshrink, NULL ) ) + if( vips_shrinkh( resample->in, &t[0], shrink->xshrink, NULL ) || + vips_shrinkv( t[0], &t[1], shrink->yshrink, NULL ) || + vips_image_write( t[1], resample->out ) ) return( -1 ); - in = t[1]; return( 0 ); } @@ -102,7 +98,7 @@ vips_shrink2_class_init( VipsShrink2Class *class ) vobject_class->description = _( "shrink an image" ); vobject_class->build = vips_shrink2_build; - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED; VIPS_ARG_INT( class, "xshrink", 8, _( "Xshrink" ), diff --git a/libvips/resample/shrinkh.c b/libvips/resample/shrinkh.c index 149cc7ef..e3a48692 100644 --- a/libvips/resample/shrinkh.c +++ b/libvips/resample/shrinkh.c @@ -106,9 +106,9 @@ vips_shrinkh_start( VipsImage *out, void *a, void *b ) /* Integer shrink. */ #define ISHRINK( TYPE ) { \ - int *sum = (int *) seq->sum; \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ + int * restrict sum = (int *) seq->sum; \ + TYPE * restrict p = (TYPE *) in; \ + TYPE * restrict q = (TYPE *) out; \ \ for( x = 0; x < width; x++ ) { \ for( b = 0; b < bands; b++ ) \ @@ -127,9 +127,9 @@ vips_shrinkh_start( VipsImage *out, void *a, void *b ) /* Float shrink. */ #define FSHRINK( TYPE ) { \ - double *sum = (double *) seq->sum; \ - TYPE *p = (TYPE *) in; \ - TYPE *q = (TYPE *) out; \ + double * restrict sum = (double *) seq->sum; \ + TYPE * restrict p = (TYPE *) in; \ + TYPE * restrict q = (TYPE *) out; \ \ for( x = 0; x < width; x++ ) { \ for( b = 0; b < bands; b++ ) \ @@ -324,7 +324,7 @@ vips_shrinkh_class_init( VipsShrinkhClass *class ) vobject_class->description = _( "shrink an image horizontally" ); vobject_class->build = vips_shrinkh_build; - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED; VIPS_ARG_INT( class, "xshrink", 8, _( "Xshrink" ), diff --git a/libvips/resample/shrinkv.c b/libvips/resample/shrinkv.c index 820c430d..034d61d6 100644 --- a/libvips/resample/shrinkv.c +++ b/libvips/resample/shrinkv.c @@ -144,8 +144,8 @@ vips_shrinkv_start( VipsImage *out, void *a, void *b ) } #define ADD( ACC_TYPE, TYPE ) { \ - ACC_TYPE *sum = (ACC_TYPE *) seq->sum; \ - TYPE *p = (TYPE *) in; \ + ACC_TYPE * restrict sum = (ACC_TYPE *) seq->sum; \ + TYPE * restrict p = (TYPE *) in; \ \ for( x = 0; x < sz; x++ ) \ sum[x] += p[x]; \ @@ -196,8 +196,8 @@ vips_shrinkv_add_line( VipsShrinkv *shrink, VipsShrinkvSequence *seq, /* Integer average. */ #define IAVG( TYPE ) { \ - int *sum = (int *) seq->sum; \ - TYPE *q = (TYPE *) out; \ + int * restrict sum = (int *) seq->sum; \ + TYPE * restrict q = (TYPE *) out; \ \ for( x = 0; x < sz; x++ ) \ q[x] = (sum[x] + shrink->yshrink / 2) / shrink->yshrink; \ @@ -206,8 +206,8 @@ vips_shrinkv_add_line( VipsShrinkv *shrink, VipsShrinkvSequence *seq, /* Float average. */ #define FAVG( TYPE ) { \ - double *sum = (double *) seq->sum; \ - TYPE *q = (TYPE *) out; \ + double * restrict sum = (double *) seq->sum; \ + TYPE * restrict q = (TYPE *) out; \ \ for( x = 0; x < sz; x++ ) \ q[x] = sum[x] / shrink->yshrink; \ @@ -407,7 +407,7 @@ vips_shrinkv_class_init( VipsShrinkvClass *class ) vobject_class->description = _( "shrink an image vertically" ); vobject_class->build = vips_shrinkv_build; - operation_class->flags = VIPS_OPERATION_SEQUENTIAL; + operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED; VIPS_ARG_INT( class, "yshrink", 9, _( "Yshrink" ),