diff --git a/ChangeLog b/ChangeLog index e39cf239..81b990c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +11/2/15 started 8.0 +- remove old doc stuff +- add fliphor(), flipver(), rot90(), rot180(), rot270() convenience methods to + Python +- add shift option to cast +- better alpha handling for 16 <-> 8 bit colour conversions + 6/2/15 started 7.42.3 - bump version for back-compat ABI change - added vips_image_memory(), an alias for vips_image_new_memory() diff --git a/TODO b/TODO index 65241e87..b5257557 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,41 @@ +- at the moment we have a policy of just ignoring extra bands + + we are proposing to change this to modify band 2, 4 or 5, if present, when + going to and from RGB16 or GREY16 + + if we make this change, we must support it for all transforms of this type, + not just for a couple, or it'll be incredibly confusing + + vips_process_n() could use cast(shift = TRUE) + + vips_colour_build() could use cast shift too + + + + +- use vips_sRGB2RGB16() + + +- check vips_sRGB2scRGB() with a 16-bit source ... what does it do for alpha? + + alpha is untouched ... rgb->0-1, alpha stays at 0-65535 + + maybe should move everything to 0-1? otherwise when we do scRGB2sRGB we'll + (effectively) do alpha * 256 + + but what if we then do scRGB -> XYZ (for example), should alpha stay 0 - 1? + + + + + + +- we have + + im.flip("horizontal") + + maybe add fliphor() and flipver() as convenience functions, cf. .sin() etc. + - why can't we do im = Vips.Image.new_from_file(sys.argv[1], access = "sequential") @@ -8,11 +46,11 @@ im.embed(10, 10, 100, 100, extend = "copy") + what about -- msb in colour should not touch alpha channel + im = Vips.Image.jpegload(sys.argv[1], access = "sequential") - ... or should it? should converting RGBA from 8 to 16-bit touch alpha too? - probably + nope, fails too diff --git a/bootstrap.sh b/bootstrap.sh index fb677233..824d93e9 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -13,15 +13,14 @@ rm -f swig/vipsCC/*.cxx rm -f swig/vipsCC/VImage.h rm -f swig/vipsCC/VImage.py python/vipsCC/VError.py python/vipsCC/VMask.py python/vipsCC/Display.py rm -f benchmark/temp* -( cd doc ; \ - mkdir poop ; \ - mv reference/libvips-docs.xml.in poop ; \ - mv reference/Makefile.am poop ; \ - mv reference/images poop ; \ - mv reference/*.xml poop ; \ - mv reference/*.py poop ; \ - rm -rf reference/* ; \ - mv poop/* reference ; \ +( mkdir poop ; \ + mv doc/libvips-docs.xml.in poop ; \ + mv doc/Makefile.am poop ; \ + mv doc/images poop ; \ + mv doc/*.xml poop ; \ + mv doc/*.py poop ; \ + rm -rf doc/* ; \ + mv poop/* doc ; \ rmdir poop \ ) @@ -45,7 +44,7 @@ cp $ACDIR/lcmessage.m4 m4 cp $ACDIR/progtest.m4 m4 cp $ACDIR/introspection.m4 m4 -gtkdocize --copy --docdir doc/reference --flavour no-tmpl || exit 1 +gtkdocize --copy --docdir doc --flavour no-tmpl || exit 1 # some systems need libtoolize, some glibtoolize ... how annoying echo testing for glibtoolize ... diff --git a/configure.ac b/configure.ac index 01ca4928..cc79065f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips], [7.42.3], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [8.0.0], [vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ(2.62) @@ -16,9 +16,9 @@ AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning -m4_define([vips_major_version], [7]) -m4_define([vips_minor_version], [42]) -m4_define([vips_micro_version], [3]) +m4_define([vips_major_version], [8]) +m4_define([vips_minor_version], [0]) +m4_define([vips_micro_version], [0]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) @@ -38,7 +38,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date` # binary interface changes not backwards compatible?: reset age to 0 LIBRARY_CURRENT=41 -LIBRARY_REVISION=0 +LIBRARY_REVISION=1 LIBRARY_AGE=1 # patched into include/vips/version.h @@ -59,7 +59,7 @@ GOBJECT_INTROSPECTION_CHECK([1.30.0]) # gir needs a list of source files to scan for introspection # # build with a glob and a list of files to exclude from scanning -# see also IGNORE_HFILES in doc/reference/Makefile.am +# see also IGNORE_HFILES in doc/Makefile.am introspection_sources=$(cd libvips ; find . -name "*.c") filter_list="deprecated " @@ -839,8 +839,7 @@ AC_OUTPUT([ swig/vipsCC/Makefile man/Makefile doc/Makefile - doc/reference/Makefile - doc/reference/libvips-docs.xml + doc/libvips-docs.xml po/Makefile.in ]) diff --git a/doc/Makefile.am b/doc/Makefile.am index 64e9e534..9e8da204 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,7 +1,187 @@ +## Process this file with automake to produce Makefile.in -SUBDIRS = reference +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 -EXTRA_DIST = \ - html \ - pdf \ - src +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=libvips + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +#DOC_MODULE_VERSION=2 + + +# The top-level XML file (SGML in the past). You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# Directories containing the source code. +# gtk-doc will search all .c and .h files beneath these paths +# for inline comments documenting functions and macros. +# e.g. DOC_SOURCE_DIR=$(top_srcdir)/gtk $(top_srcdir)/gdk +DOC_SOURCE_DIR=$(top_srcdir)/libvips + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS=--rebuild-types + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml +MKDB_OPTIONS=--xml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/libvips/include/vips/*.h +CFILE_GLOB=$(top_srcdir)/libvips/*/*.c + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES= + +# Header files or dirs to ignore when scanning. Use base file/dir names +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code + +IGNORE_VIPS_INCLUDE = \ + almostdeprecated.h \ + cimg_funcs.h \ + deprecated.h \ + vips7compat.h \ + dispatch.h \ + enumtypes.h \ + internal.h \ + thread.h \ + intl.h \ + format.h \ + mask.h \ + private.h \ + video.h + +# ignore all .h files in libvips/*, these are internal +IGNORE_VIPS_C = \ + binary.h \ + hough.h \ + nary.h \ + parithmetic.h \ + statistic.h \ + unaryconst.h \ + unary.h \ + CImg.h \ + pcolour.h \ + bandary.h \ + pconversion.h \ + correlation.h \ + pconvolution.h \ + pcreate.h \ + pmask.h \ + point.h \ + drawink.h \ + pdraw.h \ + analyze2vips.h \ + csv.h \ + dbh.h \ + fits.h \ + jpeg.h \ + magick.h \ + matlab.h \ + openexr2vips.h \ + openslide2vips.h \ + ppm.h \ + radiance.h \ + tiff.h \ + vipsjpeg.h \ + vipspng.h \ + webp.h \ + pfreqfilt.h \ + hist_unary.h \ + phistogram.h \ + base64.h \ + sink.h \ + vipsmarshal.h \ + pmorphology.h \ + global_balance.h \ + pmosaicing.h \ + presample.h \ + templates.h + +IGNORE_HFILES = $(IGNORE_VIPS_INCLUDE) $(IGNORE_VIPS_C) + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES = \ + $(top_srcdir)/doc/images/interconvert.png + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files = \ + using-command-line.xml \ + using-C.xml \ + using-python.xml \ + using-cpp.xml \ + extending.xml \ + function-list.xml \ + file-format.xml \ + binding.xml + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files = \ + using-command-line.xml \ + using-C.xml \ + using-python.xml \ + using-cpp.xml \ + extending.xml \ + function-list.xml \ + file-format.xml \ + binding.xml + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS = @VIPS_CFLAGS@ @VIPS_INCLUDES@ +GTKDOC_LIBS = @VIPS_CFLAGS@ ${top_builddir}/libvips/libvips.la @VIPS_LIBS@ + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += \ + images \ + gen-function-list.py + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +DISTCLEANFILES = libvips.types + +# Comment this out if you want 'make check' to test you doc status +# and run some sanity checks +if ENABLE_GTK_DOC +TESTS_ENVIRONMENT = \ + DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ + SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) +#TESTS = $(GTKDOC_CHECK) +endif + +-include $(top_srcdir)/git.mk diff --git a/doc/reference/binding.xml b/doc/binding.xml similarity index 100% rename from doc/reference/binding.xml rename to doc/binding.xml diff --git a/doc/reference/extending.xml b/doc/extending.xml similarity index 100% rename from doc/reference/extending.xml rename to doc/extending.xml diff --git a/doc/reference/file-format.xml b/doc/file-format.xml similarity index 100% rename from doc/reference/file-format.xml rename to doc/file-format.xml diff --git a/doc/reference/function-list.xml b/doc/function-list.xml similarity index 100% rename from doc/reference/function-list.xml rename to doc/function-list.xml diff --git a/doc/reference/gen-function-list.py b/doc/gen-function-list.py similarity index 100% rename from doc/reference/gen-function-list.py rename to doc/gen-function-list.py diff --git a/doc/gtk-doc.make b/doc/gtk-doc.make new file mode 100644 index 00000000..e7916563 --- /dev/null +++ b/doc/gtk-doc.make @@ -0,0 +1,289 @@ +# -*- mode: makefile -*- + +#################################### +# Everything below here is generic # +#################################### + +if GTK_DOC_USE_LIBTOOL +GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +GTKDOC_RUN = $(LIBTOOL) --mode=execute +else +GTKDOC_CC = $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +GTKDOC_LD = $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +GTKDOC_RUN = +endif + +# We set GPATH here; this gives us semantics for GNU make +# which are more like other make's VPATH, when it comes to +# whether a source that is a target of one rule is then +# searched for in VPATH/GPATH. +# +GPATH = $(srcdir) + +TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) + +SETUP_FILES = \ + $(content_files) \ + $(DOC_MAIN_SGML_FILE) \ + $(DOC_MODULE)-sections.txt \ + $(DOC_MODULE)-overrides.txt + +EXTRA_DIST = \ + $(HTML_IMAGES) \ + $(SETUP_FILES) + +DOC_STAMPS=setup-build.stamp scan-build.stamp sgml-build.stamp \ + html-build.stamp pdf-build.stamp \ + sgml.stamp html.stamp pdf.stamp + +SCANOBJ_FILES = \ + $(DOC_MODULE).args \ + $(DOC_MODULE).hierarchy \ + $(DOC_MODULE).interfaces \ + $(DOC_MODULE).prerequisites \ + $(DOC_MODULE).signals + +REPORT_FILES = \ + $(DOC_MODULE)-undocumented.txt \ + $(DOC_MODULE)-undeclared.txt \ + $(DOC_MODULE)-unused.txt + +gtkdoc-check.test: Makefile + $(AM_V_GEN)echo "#!/bin/sh -e" > $@; \ + echo "$(GTKDOC_CHECK_PATH) || exit 1" >> $@; \ + chmod +x $@ + +CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) gtkdoc-check.test + +if GTK_DOC_BUILD_HTML +HTML_BUILD_STAMP=html-build.stamp +else +HTML_BUILD_STAMP= +endif +if GTK_DOC_BUILD_PDF +PDF_BUILD_STAMP=pdf-build.stamp +else +PDF_BUILD_STAMP= +endif + +all-gtk-doc: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) +.PHONY: all-gtk-doc + +if ENABLE_GTK_DOC +all-local: all-gtk-doc +endif + +docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) + +$(REPORT_FILES): sgml-build.stamp + +#### setup #### + +GTK_DOC_V_SETUP=$(GTK_DOC_V_SETUP_$(V)) +GTK_DOC_V_SETUP_=$(GTK_DOC_V_SETUP_$(AM_DEFAULT_VERBOSITY)) +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`; \ + if test "x$$files" != "x" ; then \ + for file in $$files ; do \ + destdir=`dirname $(abs_builddir)/$$file`; \ + test -d "$$destdir" || mkdir -p "$$destdir"; \ + test -f $(abs_srcdir)/$$file && \ + cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \ + done; \ + fi; \ + fi + $(AM_V_at)touch setup-build.stamp + + +#### scan #### + +GTK_DOC_V_SCAN=$(GTK_DOC_V_SCAN_$(V)) +GTK_DOC_V_SCAN_=$(GTK_DOC_V_SCAN_$(AM_DEFAULT_VERBOSITY)) +GTK_DOC_V_SCAN_0=@echo " DOC Scanning header files"; + +GTK_DOC_V_INTROSPECT=$(GTK_DOC_V_INTROSPECT_$(V)) +GTK_DOC_V_INTROSPECT_=$(GTK_DOC_V_INTROSPECT_$(AM_DEFAULT_VERBOSITY)) +GTK_DOC_V_INTROSPECT_0=@echo " DOC Introspecting gobjects"; + +scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB) + $(GTK_DOC_V_SCAN)_source_dir='' ; \ + for i in $(DOC_SOURCE_DIR) ; do \ + _source_dir="$${_source_dir} --source-dir=$$i" ; \ + done ; \ + gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES) + $(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 "x$(V)" = "x1"; then \ + scanobj_options="--verbose"; \ + fi; \ + fi; \ + CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \ + gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \ + else \ + for i in $(SCANOBJ_FILES) ; do \ + test -f $$i || touch $$i ; \ + done \ + fi + $(AM_V_at)touch scan-build.stamp + +$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp + @true + +#### xml #### + +GTK_DOC_V_XML=$(GTK_DOC_V_XML_$(V)) +GTK_DOC_V_XML_=$(GTK_DOC_V_XML_$(AM_DEFAULT_VERBOSITY)) +GTK_DOC_V_XML_0=@echo " DOC Building XML"; + +sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) + $(GTK_DOC_V_XML)_source_dir='' ; \ + for i in $(DOC_SOURCE_DIR) ; do \ + _source_dir="$${_source_dir} --source-dir=$$i" ; \ + done ; \ + gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS) + $(AM_V_at)touch sgml-build.stamp + +sgml.stamp: sgml-build.stamp + @true + +#### html #### + +GTK_DOC_V_HTML=$(GTK_DOC_V_HTML_$(V)) +GTK_DOC_V_HTML_=$(GTK_DOC_V_HTML_$(AM_DEFAULT_VERBOSITY)) +GTK_DOC_V_HTML_0=@echo " DOC Building HTML"; + +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) + $(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 "x$(V)" = "x1"; then \ + mkhtml_options="$$mkhtml_options --verbose"; \ + fi; \ + fi; \ + gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ + 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) + -@test "x$(HTML_IMAGES)" = "x" || \ + for file in $(HTML_IMAGES) ; do \ + if test -f $(abs_srcdir)/$$file ; then \ + cp $(abs_srcdir)/$$file $(abs_builddir)/html; \ + fi; \ + if test -f $(abs_builddir)/$$file ; then \ + cp $(abs_builddir)/$$file $(abs_builddir)/html; \ + fi; \ + done; + $(GTK_DOC_V_XREF)gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) + $(AM_V_at)touch html-build.stamp + +#### pdf #### + +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) + $(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 "x$(V)" = "x1"; then \ + mkpdf_options="$$mkpdf_options --verbose"; \ + fi; \ + fi; \ + if test "x$(HTML_IMAGES)" != "x"; then \ + for img in $(HTML_IMAGES); do \ + part=`dirname $$img`; \ + echo $$mkpdf_options | grep >/dev/null "\-\-imgdir=$$part "; \ + if test $$? != 0; then \ + mkpdf_options="$$mkpdf_options --imgdir=$$part"; \ + fi; \ + done; \ + fi; \ + gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_options $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS) + $(AM_V_at)touch pdf-build.stamp + +############## + +clean-local: + @rm -f *~ *.bak + @rm -rf .libs + @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ + rm -f $(DOC_MODULE).types; \ + 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; \ + fi + +maintainer-clean-local: + @rm -rf xml html + +install-data-local: + @installfiles=`echo $(builddir)/html/*`; \ + if test "$$installfiles" = '$(builddir)/html/*'; \ + then echo 1>&2 'Nothing to install' ; \ + else \ + if test -n "$(DOC_MODULE_VERSION)"; then \ + installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ + else \ + installdir="$(DESTDIR)$(TARGET_DIR)"; \ + fi; \ + $(mkinstalldirs) $${installdir} ; \ + for i in $$installfiles; do \ + echo ' $(INSTALL_DATA) '$$i ; \ + $(INSTALL_DATA) $$i $${installdir}; \ + done; \ + if test -n "$(DOC_MODULE_VERSION)"; then \ + mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ + $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ + fi; \ + $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \ + fi + +uninstall-local: + @if test -n "$(DOC_MODULE_VERSION)"; then \ + installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ + else \ + installdir="$(DESTDIR)$(TARGET_DIR)"; \ + fi; \ + rm -rf $${installdir} + +# +# Require gtk-doc when making dist +# +if HAVE_GTK_DOC +dist-check-gtkdoc: docs +else +dist-check-gtkdoc: + @echo "*** gtk-doc is needed to run 'make dist'. ***" + @echo "*** gtk-doc was not found when 'configure' ran. ***" + @echo "*** please install gtk-doc and rerun 'configure'. ***" + @false +endif + +dist-hook: dist-check-gtkdoc all-gtk-doc dist-hook-local + @mkdir $(distdir)/html + @cp ./html/* $(distdir)/html + @-cp ./$(DOC_MODULE).pdf $(distdir)/ + @-cp ./$(DOC_MODULE).types $(distdir)/ + @-cp ./$(DOC_MODULE)-sections.txt $(distdir)/ + @cd $(distdir) && rm -f $(DISTCLEANFILES) + @$(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html + +.PHONY : dist-hook-local docs diff --git a/doc/reference/images/interconvert.png b/doc/images/interconvert.png similarity index 100% rename from doc/reference/images/interconvert.png rename to doc/images/interconvert.png diff --git a/doc/reference/images/interconvert.svg b/doc/images/interconvert.svg similarity index 100% rename from doc/reference/images/interconvert.svg rename to doc/images/interconvert.svg diff --git a/doc/libvips-docs.xml b/doc/libvips-docs.xml new file mode 100644 index 00000000..5a5769a6 --- /dev/null +++ b/doc/libvips-docs.xml @@ -0,0 +1,98 @@ + + + +]> + + + VIPS Reference Manual + + For VIPS 7.42.3. + The latest version of this documentation can be found on the + VIPS website. + + + + + VIPS Overview + + VIPS is a free image processing system. It is good with large + images (images larger than the amount of RAM you have available), with + many CPUs (speed scales linearly to at least 32 threads), for working + with colour, for scientific analysis and for general research + and development. As well as JPEG, TIFF and PNG images, it also + supports scientific formats like FITS, Matlab, Analyze, PFM, + Radiance and OpenSlide. It works on many UNIX-like platforms, + as well as Windows and OS X. VIPS is released under the GNU Library + General Public License (GNU LGPL). + + + + + + + + + + + + + + Core VIPS API + + + + + + + + + + + + + + + + + + VIPS operation API by section + + + + + + + + + + + + + + + + + Other API (no gtkdoc comments yet) + + + + + + + + Object Hierarchy + + + + + API Index + + + + + + diff --git a/doc/reference/libvips-docs.xml.in b/doc/libvips-docs.xml.in similarity index 100% rename from doc/reference/libvips-docs.xml.in rename to doc/libvips-docs.xml.in diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am deleted file mode 100644 index c1c0da84..00000000 --- a/doc/reference/Makefile.am +++ /dev/null @@ -1,187 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# We require automake 1.6 at least. -AUTOMAKE_OPTIONS = 1.6 - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE=libvips - -# Uncomment for versioned docs and specify the version of the module, e.g. '2'. -#DOC_MODULE_VERSION=2 - - -# The top-level XML file (SGML in the past). You can change this if you want to. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml - -# Directories containing the source code. -# gtk-doc will search all .c and .h files beneath these paths -# for inline comments documenting functions and macros. -# e.g. DOC_SOURCE_DIR=$(top_srcdir)/gtk $(top_srcdir)/gdk -DOC_SOURCE_DIR=$(top_srcdir)/libvips - -# Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS= - -# Extra options to supply to gtkdoc-scan. -# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" -SCAN_OPTIONS=--rebuild-types - -# Extra options to supply to gtkdoc-mkdb. -# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml -MKDB_OPTIONS=--xml-mode --output-format=xml - -# Extra options to supply to gtkdoc-mktmpl -# e.g. MKTMPL_OPTIONS=--only-section-tmpl -MKTMPL_OPTIONS= - -# Extra options to supply to gtkdoc-mkhtml -MKHTML_OPTIONS= - -# Extra options to supply to gtkdoc-fixref. Not normally needed. -# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS= - -# Used for dependencies. The docs will be rebuilt if any of these change. -# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h -# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c -HFILE_GLOB=$(top_srcdir)/libvips/include/vips/*.h -CFILE_GLOB=$(top_srcdir)/libvips/*/*.c - -# Extra header to include when scanning, which are not under DOC_SOURCE_DIR -# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h -EXTRA_HFILES= - -# Header files or dirs to ignore when scanning. Use base file/dir names -# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code - -IGNORE_VIPS_INCLUDE = \ - almostdeprecated.h \ - cimg_funcs.h \ - deprecated.h \ - vips7compat.h \ - dispatch.h \ - enumtypes.h \ - internal.h \ - thread.h \ - intl.h \ - format.h \ - mask.h \ - private.h \ - video.h - -# ignore all .h files in libvips/*, these are internal -IGNORE_VIPS_C = \ - binary.h \ - hough.h \ - nary.h \ - parithmetic.h \ - statistic.h \ - unaryconst.h \ - unary.h \ - CImg.h \ - pcolour.h \ - bandary.h \ - pconversion.h \ - correlation.h \ - pconvolution.h \ - pcreate.h \ - pmask.h \ - point.h \ - drawink.h \ - pdraw.h \ - analyze2vips.h \ - csv.h \ - dbh.h \ - fits.h \ - jpeg.h \ - magick.h \ - matlab.h \ - openexr2vips.h \ - openslide2vips.h \ - ppm.h \ - radiance.h \ - tiff.h \ - vipsjpeg.h \ - vipspng.h \ - webp.h \ - pfreqfilt.h \ - hist_unary.h \ - phistogram.h \ - base64.h \ - sink.h \ - vipsmarshal.h \ - pmorphology.h \ - global_balance.h \ - pmosaicing.h \ - presample.h \ - templates.h - -IGNORE_HFILES = $(IGNORE_VIPS_INCLUDE) $(IGNORE_VIPS_C) - -# Images to copy into HTML directory. -# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES = \ - $(top_srcdir)/doc/reference/images/interconvert.png - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -# e.g. content_files=running.sgml building.sgml changes-2.0.sgml -content_files = \ - using-command-line.xml \ - using-C.xml \ - using-python.xml \ - using-cpp.xml \ - extending.xml \ - function-list.xml \ - file-format.xml \ - binding.xml - -# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded -# These files must be listed here *and* in content_files -# e.g. expand_content_files=running.sgml -expand_content_files = \ - using-command-line.xml \ - using-C.xml \ - using-python.xml \ - using-cpp.xml \ - extending.xml \ - function-list.xml \ - file-format.xml \ - binding.xml - -# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. -# Only needed if you are using gtkdoc-scangobj to dynamically query widget -# signals and properties. -# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) -# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) -GTKDOC_CFLAGS = @VIPS_CFLAGS@ @VIPS_INCLUDES@ -GTKDOC_LIBS = @VIPS_CFLAGS@ ${top_builddir}/libvips/libvips.la @VIPS_LIBS@ - -# This includes the standard gtk-doc make rules, copied by gtkdocize. -include gtk-doc.make - -# Other files to distribute -# e.g. EXTRA_DIST += version.xml.in -EXTRA_DIST += \ - images \ - gen-function-list.py - -# Files not to distribute -# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types -# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt -DISTCLEANFILES = libvips.types - -# Comment this out if you want 'make check' to test you doc status -# and run some sanity checks -if ENABLE_GTK_DOC -TESTS_ENVIRONMENT = \ - DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ - SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) -#TESTS = $(GTKDOC_CHECK) -endif - --include $(top_srcdir)/git.mk diff --git a/doc/src/Makefile b/doc/src/Makefile deleted file mode 100644 index c2c1a952..00000000 --- a/doc/src/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# - -PDF = vipsmanual.pdf -SRC = \ - applintro.tex \ - cppintro.tex \ - fileformat.tex \ - func.tex \ - format.tex \ - iosys.tex \ - ipio.tex \ - mydefs.tex \ - operintro.tex \ - packages.tex \ - pio.tex \ - refintro.tex \ - vdisplay.tex \ - verror.tex \ - vimage.tex \ - vipsmanual.tex \ - vmask.tex \ - wio.tex - -destdir = ../ - -all: $(PDF) html - -install: all $(PDF) html - -rm -rf ${destdir}/pdf/*.pdf - -rm -rf ${destdir}/html/vips* - -rm -rf ${destdir}/html/figs - -mkdir -p ${destdir}/pdf - -mkdir -p ${destdir}/html - -cp $(PDF) ${destdir}/pdf - -cp -r vipsmanual/* ${destdir}/html - -$(PDF): $(SRC) - pdflatex vipsmanual.tex - pdflatex vipsmanual.tex - -.PHONY: html -html: - -rm -rf vipsmanual - mkdir vipsmanual - htlatex vipsmanual.tex html.cfg,3 "" -dvipsmanual/ - cp -r figs vipsmanual - -rm vipsmanual/figs/*.svg - -rm vipsmanual/*.png - -.PHONY: clean -clean: - -rm -f *.4ct - -rm -f *.4tc - -rm -f *.log - -rm -f *.xref - -rm -f *.tmp - -rm -f *.html - -rm -f *.css - -rm -f *.lg - -rm -f *.idv - -rm -f *.aux - -rm -f *.dvi - -rm -f *.lof - -rm -f *.lot - -rm -f *.toc - -rm -f *.pdf - -rm -rf vipsmanual diff --git a/doc/src/applintro.tex b/doc/src/applintro.tex deleted file mode 100644 index f1bb3de4..00000000 --- a/doc/src/applintro.tex +++ /dev/null @@ -1,51 +0,0 @@ -\section{Introduction} -\mylabel{sec:appl} - -This chapter explains how to call VIPS functions from C programs. It does not -explain how to write new image processing operations (see \pref{sec:oper}), -only how to call the ones that VIPS provides. If you want to call VIPS -functions from C++ programs, you can either use the interface described here -or you can try out the much nicer C++ interface described in \pref{sec:cpp}. - -See \pref{sec:ref} for an introduction to the image processing operations -available in the library. \fref{fg:architecture} tries to show -an overview of this structure. - -\begin{fig2} -\figw{5in}{arch.png} -\caption{VIPS software architecture} -\label{fg:architecture} -\end{fig2} - -VIPS includes a set of UNIX manual pages. Enter (for example): - -\begin{verbatim} -example% man im_extract -\end{verbatim} - -\noindent -to get an explanation of the \verb+im_extract()+ function. - -All the command-line VIPS operations will print help text too. For example: - -\begin{verbatim} -example% vips im_extract -usage: vips im_extract input output - left top width height band -where: - input is of type "image" - output is of type "image" - left is of type "integer" - top is of type "integer" - width is of type "integer" - height is of type "integer" - band is of type "integer" -extract area/band, from package - "conversion" -flags: (PIO function) - (coordinate transformer) - (area operation) - (result can be cached) -vips: error calling function -im_run_command: too few arguments -\end{verbatim} diff --git a/doc/src/cppintro.tex b/doc/src/cppintro.tex deleted file mode 100644 index 20bea9b9..00000000 --- a/doc/src/cppintro.tex +++ /dev/null @@ -1,108 +0,0 @@ -\section{Introduction} -\mylabel{sec:cpp} - -This chapter describes the C++ API for the VIPS image processing library. -The C++ API is as efficient as the C interface to VIPS, but is -far easier to use: almost all creation, destruction and error handling issues -are handled for you automatically. - -The Python interface is a very simple wrapping of this C++ API generated -automatically with SWIG. It adds a few utility methods noted below, but -otherwise the two interfaces are identical other than language -syntax. - -\subsection{If you've used the C API} - -To show how much easier the VIPS C++ API is to use, compare \fref{fg:negative} -to \fref{fg:invert-c++}. \fref{fg:invert-py} is the same thing in Python. - -A typical build line for the C++ program might be: - -\begin{verbatim} -g++ invert.cc \ - `pkg-config vipsCC-7.18 \ - --cflags --libs` -\end{verbatim} - -The key points are: - -\begin{itemize} - -\item -You just include \verb++ --- this then gets all of the -other includes you need. Everything is in the \verb+vips+ namespace. - -\item -The C++ API replaces all of the VIPS C types --- \verb+IMAGE+ becomes -\verb+VImage+ and so on. The C++ API also includes \verb+VDisplay+, -\verb+VMask+ and \verb+VError+. - -\item -Image processing operations are member functions of the \verb+VImage+ class ---- here, \verb+VImage( argv[1] )+ creates a new \verb+VImage+ object using -the first argument to initialise it (the input filename). It then calls the -member function \verb+invert()+, which inverts the \verb+VImage+ and returns a -new \verb+VImage+. Finally it calls the member function \verb+write()+, which -writes the result image to the named file. - -\item -The VIPS C++ API uses exceptions --- the \verb+VError+ class is covered -later. If you run this program with a bad input file, for example, you get the -following output: - -\begin{verbatim} -$ invert jim fred -invert: VIPS error: format_for_file: - file "jim" not found -\end{verbatim} - -\end{itemize} - -\begin{fig2} -\begin{verbatim} -#include -#include - -int -main (int argc, char **argv) -{ - if (argc != 3) - { - std::cerr << "usage: " << argv[0] << " infile outfile\n"; - return (1); - } - - try - { - vips::VImage fred (argv[1]); - - fred.invert ().write (argv[2]); - } - catch (vips::VError e) - { - e.perror (argv[0]); - } - - return (0); -} -\end{verbatim} -\caption{\texttt{invert} program in C++} -\label{fg:invert-c++} -\end{fig2} - -\begin{fig2} -\begin{verbatim} -#!/usr/bin/python - -import sys -from vipsCC import * - -try: - a = VImage.VImage (sys.argv[1]) - a.invert ().write (sys.argv[2]) -except VError.VError, e: - e.perror (sys.argv[0]) -\end{verbatim} -\caption{\texttt{invert} program in Python} -\label{fg:invert-py} -\end{fig2} diff --git a/doc/src/figs/arch.png b/doc/src/figs/arch.png deleted file mode 100644 index 2719aea8..00000000 Binary files a/doc/src/figs/arch.png and /dev/null differ diff --git a/doc/src/figs/arch.svg b/doc/src/figs/arch.svg deleted file mode 100644 index 6e44ee30..00000000 --- a/doc/src/figs/arch.svg +++ /dev/null @@ -1,385 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - Python binding - - - - C++ binding - - - VIPS imageprocessingoperations - User imageprocessingoperations - - VIPS IO system - Function dispatch - - - - Command-lineinterface - - - - diff --git a/doc/src/figs/arch8.svg b/doc/src/figs/arch8.svg deleted file mode 100644 index 6ff90ceb..00000000 --- a/doc/src/figs/arch8.svg +++ /dev/null @@ -1,705 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - VipsObject - - - - GObject - - - - VipsRegion - - - - VipsImage - - - - VipsOperation - - - - VipsArithmetic - - - - VipsBinary - - - - VipsAdd - - - - - - - GObjectintrospection - - - - - - Python - - - - Python - - - - - Ruby - - - - JS - - - - - nip2 - - - - C++ - - - - CLI - - - - - - - - - - - diff --git a/doc/src/figs/interconvert.png b/doc/src/figs/interconvert.png deleted file mode 100644 index bc98d461..00000000 Binary files a/doc/src/figs/interconvert.png and /dev/null differ diff --git a/doc/src/figs/interconvert.svg b/doc/src/figs/interconvert.svg deleted file mode 100644 index f505bd1d..00000000 --- a/doc/src/figs/interconvert.svg +++ /dev/null @@ -1,505 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - Lab - - - - XYZ - - - - LCh - - - - disp - - - - Yxy - - - - UCS - - - - LabQ - - - - LabS - - - - ICC - - - - - - - - - - Any VIPS RGB space - Any device withan ICC profile - - diff --git a/doc/src/fileformat.tex b/doc/src/fileformat.tex deleted file mode 100644 index a8fabbe6..00000000 --- a/doc/src/fileformat.tex +++ /dev/null @@ -1,173 +0,0 @@ -\section{The VIPS file format} - -VIPS has its own very simple file format. It is used inside VIPS to hold -images during computation. You can save images in VIPS format if you want, -but the VIPS format is not widely used and you may have problems reading -your images into other packages. - -If you intend to keep an image, it's much better to save it as TIFF, -JPEG, PNG, PBM/PGM/PPM or HDR. VIPS can transparently read and write all -these formats. - -\subsection{VIPS file header} -\label{sec:header} - -All VIPS image files start with a 64-byte header giving basic information -about the image dimensions, see \tref{fg:header}. This is followed by the -image data. This is usually just the pixel values in native format (ie. the -byte order used by the machine that wrote the file) laid out left-to-right and -top-to-bottom. After the image data comes a block of optional XML which holds -extra image metadata, such as ICC profiles and image history. -You can use the command-line program \verb+header+ to extract the XML from an -image and \verb+edvips+ to replace it, see the man pages. - -The \ct{Type} field, the \ct{Xres}/\ct{Yres} fields, and the -\ct{Xoffset}/\ct{Yoffset} fields are advisory. VIPS maintains their value -(if you convert an image to \cielab{} colour space with \ct{im\_XYZ2Lab()}, -for example, VIPS will set \ct{Type} to be \ct{IM\_TYPE\_LAB}), but never -uses these values itself in determining the action of an image processing -function. These fields are to help the user and to help application -programs built on VIPS which are trying to present image data to the user -in a meaningful way. - -The \ct{BandFmt}, \ct{Coding} and \ct{Type} fields can take the values -shown in tables~\ref{fg:bandfmt}, \ref{fg:coding} and \ref{fg:type}. The C++ -and Python names for these values are slightly different, for historical -reasons. - -\begin{tab2} -\begin{center} -\begin{tabular}{|l|l|l|} -\hline -Bytes & Represent & VIPS name \\ -\hline -0--3 & VIPS magic number (in hex, 08 f2 f6 b6) & \\ -4--7 & Number of pels per horizontal line (integer) & \ct{Xsize} \\ -8--11 & Number of horizontal lines (integer) & \ct{Ysize} \\ -12--15 & Number of bands (integer) & \ct{Bands} \\ -16--19 & Unused (legacy) & \ct{Bbits} \\ -20--23 & Band format (eg. \ct{IM\_BANDFMT\_USHORT}) & \ct{BandFmt} \\ -24--27 & Coding type (eg. \ct{IM\_CODING\_NONE}) & \ct{Coding} \\ -28--31 & Type (eg. \ct{IM\_TYPE\_LAB}) & \ct{Type} \\ -32--35 & Horizontal resolution (float, pixels mm$^{-1}$) & \ct{Xres} \\ -36--39 & Vertical resolution (float, pixels mm$^{-1}$) & \ct{Yres} \\ -40--43 & Unused (legacy) & \ct{Length} \\ -44--45 & Unused (legacy) & \ct{Compression} \\ -46--47 & Unused (legacy) & \ct{Level} \\ -48--51 & Horizontal offset of origin & \ct{Xoffset} \\ -52--55 & Vertical offset of origin & \ct{Yoffset} \\ -56--63 & For future expansion (all zeros for now) & \\ -\hline -\end{tabular} -\end{center} -\caption{VIPS header\label{fg:header}} -\end{tab2} - -\begin{tab2} -\begin{center} -\begin{tabular}{|l|l|l|l|} -\hline -\ct{BandFmt} & C++ and Python name & Value & Meaning \\ -\hline -\ct{IM\_BANDFMT\_NOTSET} & \ct{FMTNOTSET} & -1 & \\ -\ct{IM\_BANDFMT\_UCHAR} & \ct{FMTUCHAR} & 0 & Unsigned 8-bit int \\ -\ct{IM\_BANDFMT\_CHAR} & \ct{FMTCHAR} & 1 & Signed 8-bit int \\ -\ct{IM\_BANDFMT\_USHORT} & \ct{FMTUSHORT} & 2 & Unsigned 16-bit int \\ -\ct{IM\_BANDFMT\_SHORT} & \ct{FMTSHORT} & 3 & Signed 16-bit int \\ -\ct{IM\_BANDFMT\_UINT} & \ct{FMTUINT} & 4 & Unsigned 32-bit int \\ -\ct{IM\_BANDFMT\_INT} & \ct{FMTINT} & 5 & Signed 32-bit int \\ -\ct{IM\_BANDFMT\_FLOAT} & \ct{FMTFLOAT} & 6 & 32-bit IEEE float \\ -\ct{IM\_BANDFMT\_COMPLEX} & \ct{FMTCOMPLEX} & 7 & Complex (2 floats) \\ -\ct{IM\_BANDFMT\_DOUBLE} & \ct{FMTDOUBLE} & 8 & 64-bit IEEE double \\ -\ct{IM\_BANDFMT\_DPCOMPLEX} & \ct{FMTDPCOMPLEX} & 9 & Complex (2 doubles) \\ -\hline -\end{tabular} -\end{center} -\caption{Possible values for \ct{BandFmt}\label{fg:bandfmt}} -\end{tab2} - -\begin{tab2} -\begin{center} -\begin{tabular}{|l|l|l|l|} -\hline -\ct{Coding} & C++ and Python name & Value & Meaning \\ -\hline -\ct{IM\_CODING\_NONE} & \ct{NOCODING} & 0 & VIPS computation format \\ -\ct{IM\_CODING\_LABQ} & \ct{LABQ} & 2 & LABQ storage format \\ -\ct{IM\_CODING\_RAD} & \ct{RAD} & 6 & Radiance storage format \\ -\hline -\end{tabular} -\end{center} -\caption{Possible values for \texttt{Coding}\label{fg:coding}} -\end{tab2} - -\begin{tab2} -\begin{center} -\begin{tabular}{|l|l|l|l|} -\hline -\ct{Type} & C++ and Python name & Value & Meaning \\ -\hline -\ct{IM\_TYPE\_MULTIBAND} & \ct{MULTIBAND} & 0 & Some multiband image \\ -\ct{IM\_TYPE\_B\_W} & \ct{B\_W} & 1 & Some single band image \\ -\ct{IM\_TYPE\_HISTOGRAM} & \ct{HISTOGRAM} & 10 & Histogram or LUT \\ -\ct{IM\_TYPE\_FOURIER} & \ct{FOURIER} & 24 & Image in Fourier space \\ -\ct{IM\_TYPE\_XYZ} & \ct{XYZ} & 12 & \ciexyz{} colour space \\ -\ct{IM\_TYPE\_LAB} & \ct{LAB} & 13 & \cielab{} colour space \\ -\ct{IM\_TYPE\_CMYK} & \ct{CMYK} & 15 & \ct{im\_icc\_export()} \\ -\ct{IM\_TYPE\_LABQ} & \ct{LABQ} & 16 & 32-bit \cielab{} \\ -\ct{IM\_TYPE\_RGB} & \ct{RGB} & 17 & Some RGB \\ -\ct{IM\_TYPE\_UCS} & \ct{UCS} & 18 & \cieucs{} colour space \\ -\ct{IM\_TYPE\_LCH} & \ct{LCH} & 19 & \cielch{} colour space \\ -\ct{IM\_TYPE\_LABS} & \ct{LABS} & 21 & 48-bit \cielab{} \\ -\ct{IM\_TYPE\_sRGB} & \ct{sRGB} & 22 & sRGB colour space \\ -\ct{IM\_TYPE\_YXY} & \ct{YXY} & 23 & \cieyxy{} colour space \\ -\ct{IM\_TYPE\_RGB16} & \ct{RGB16} & 25 & 16-bit RGB \\ -\ct{IM\_TYPE\_GREY16} & \ct{GREY16} & 26 & 16-bit monochrome \\ -\hline -\end{tabular} -\end{center} -\caption{Possible values for \texttt{Type}\label{fg:type}} -\end{tab2} - -\subsection{Computation formats} - -This type of image has \ct{Coding} set to \ct{IM\_CODING\_NONE}. The -header is then followed by a large array of pixels, laid out left-to-right, -top-to-bottom. Each pixel contains the specified number of bands. Each band -has the specified band format, which may be an 8-, 16- or 32-bit integer -(either signed or unsigned), a single or double precision IEEE floating -point number, or a pair of single or double precision floats forming a -complex number. - -All values are stored in the host-machine's native number representation (that -is, either most-significant first, as in SPARC and 680x0 machines, or -least-significant first, for Intel and DEC machines). If necessary, the VIPS -library will automatically byte-swap for you during read. - -\subsection{Storage formats} - -All storage formats have other values for the \ct{Coding} field. This -release supports \ct{IM\_CODING\_LABQ} and \ct{IM\_CODING\_RAD}. - -\ct{IM\_CODING\_LABQ} stores $L^{*}$, $a^{*}$ and $b^{*}$ for each pixel, -with 10 bits for $L^{*}$ and 11 bits for each of $a^{*}$ and $b^{*}$. These -32 bits are packed into 4 bytes, with the most significant 8 bits of each -value in the first 3 bytes, and the left-over bits packed into the final -byte as 2:3:3. - -This format is a little awkward to process. Some VIPS functions can work -directly on \ct{IM\_CODING\_LABQ} images (\ct{im\_extract\_area()}, for -example), but most will require you to unpack the image to one of the -computation formats (for example with \ct{im\_LabQ2Lab()}) first. - -\ct{IM\_CODING\_RAD} stores $RGB$ or $XYZ$ float images as 8 bytes of mantissa -and then 8 bytes of exponent, shared between the three channels. This coding -style is used by the Radiance family of programs (and the HDR format) commonly -used for HDR imaging. This style of image is generated when you load an HDR -image. - -This format is a little awkward to process. Some VIPS functions can work -directly on \ct{IM\_CODING\_RAD} images (\ct{im\_extract\_area()}, for -example), but most will require you to unpack the image to one of the -computation formats with \ct{im\_rad2float()} first. - diff --git a/doc/src/format.tex b/doc/src/format.tex deleted file mode 100644 index b175c8d8..00000000 --- a/doc/src/format.tex +++ /dev/null @@ -1,133 +0,0 @@ -\section{Image formats} -\label{sec:format} - -VIPS has a simple system for adding support for new image file formats. -You can ask VIPS to find a format to load a file with or to select a image -file writer based on a filename. Convenience functions copy a file to an -\verb+IMAGE+, or an \verb+IMAGE+ to a file. New formats may be added to -VIPS by simply defining a new subclass of \verb+VipsFormat+. - -This is a parallel API to \verb+im_open()+, see \pref{sec:open}. The -format system is useful for images which are large or slow to open, -because you pass a descriptor to write to and so control how and where -the decompressed image is held. \verb+im_open()+ is useful for images in -formats which can be directly read from disc, since you will avoid a copy -operation and can directly control the disc file. The inplace operations -(see \pref{sec:inplace}), for example, will only work directly on disc -images if you use \verb+im_open()+. - -\subsection{How a format is represented} - -See the man page for \verb+VipsFormat+ for full details, but briefly, an image -format consists of the following items: - -\begin{itemize} -\item -A name, a name that can be shows to the user, and a list of possible filename -suffixes (\verb+.tif+, for example) - -\item -A function which tests for a file being in that format, a function which loads -just the header of the file (that is, it reads properties like width and -height and does not read any pixel data) and a function which loads the pixel -data - -\item -A function which will write an \verb+IMAGE+ to a file in the format - -\item -And finally a function which examines a file in the format and returns flags -indicating how VIPS should deal with the file. The only flag in the current -version is one indicating that the file can be opened lazily - -\end{itemize} - -\subsection{The format class} - -The interface to the format system is defined by the abstract base class -\verb+VipsFormat+. Formats subclass this and implement some or all of the -methods. Any of the functions may be left NULL and VIPS will try to make do -with what you do supply. Of course a format with all functions as NULL will -not be very useful. - -As an example, \fref{fg:newformat} shows how to register a new format in a -plugin. - -\begin{fig2} -\begin{verbatim} -static const char *my_suffs[] = { ".me", NULL }; - -static int -is_myformat( const char *filename ) -{ - unsigned char buf[2]; - - if( im__get_bytes( filename, buf, 2 ) && - (int) buf[0] == 0xff && - (int) buf[1] == 0xd8 ) - return( 1 ); - - return( 0 ); -} - -// This format adds no new members. -typedef VipsFormat VipsFormatMyformat; -typedef VipsFormatClass VipsFormatMyformatClass; - -static void -vips_format_myformat_class_init( VipsFormatMyformatClass *class ) -{ - VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsFormatClass *format_class = (VipsFormatClass *) class; - - object_class->nickname = "myformat"; - object_class->description = _( "My format" ); - - format_class->is_a = is_myformat; - format_class->header = my_header; - format_class->load = my_read; - format_class->save = my_write; - format_class->get_flags = my_get_flags; - format_class->priority = 100; - format_class->suffs = my_suffs; -} - -static void -vips_format_myformat_init( VipsFormatMyformat *object ) -{ -} - -G_DEFINE_TYPE( VipsFormatMyformat, vips_format_myformat, VIPS_TYPE_FORMAT ); - -char * -g_module_check_init( GModule *self ) -{ - // register the type - vips_format_myformat_get_type(); -} -\end{verbatim} -\caption{Registering a format in a plugin} -\label{fg:newformat} -\end{fig2} - -\subsection{Finding a format} - -You can loop over the subclasses of \verb+VipsFormat+ in order of priority -with \verb+vips_format_map()+. Like all the map functions in VIPS, this take -a function and applies it to every element in the table until the function -returns non-zero or until the table ends. - -You find an \verb+VipsFormatClass+ to use to open a file with -\verb+vips_format_for_file()+. This finds the first format whose \verb+is_a()+ -function returns true or whose suffix list matches the suffix of the filename, -setting an error message and returning NULL if no format is found. - -You find a format to write a file with \verb+vips_format_for_name()+. This -returns the first format with a save function whose suffix list matches the -suffix of the supplied filename. - -\subsection{Convenience functions} - -A pair of convenience functions, \verb+vips_format_write()+ and -\verb+vips_format_read()+, will copy an image to and from disc using the -appropriate format. diff --git a/doc/src/func.tex b/doc/src/func.tex deleted file mode 100644 index e83ac2d9..00000000 --- a/doc/src/func.tex +++ /dev/null @@ -1,697 +0,0 @@ -\section{Function dispatch and plug-ins} - -(This chapter is on the verge of being deprecated. We have started building a -replacement based on \verb+GObject+, see \pref{sec:object}.) - -As image processing libraries increase in size it becomes progressively more -difficult to build applications which present the operations the library -offers to the user. Every time a new operation is added, every user interface -needs to be adapted --- a job which can rapidly become unmanageable. - -To address this problem VIPS includes a simple database which stores an -abstract description of every image processing operation. User interfaces, -rather than having special code wired into them for each operation, can -simply interrogate the database and present what they find to the user. - -The operation database is extensible. You can define new operations, and even -new types, and add them to VIPS. These new operations will then automatically -appear in all VIPS user interfaces with no extra programming effort. Plugins -can extend the database at runtime: when VIPS starts, it loads all the plugins -in the VIPS library area. - -\subsection{Simple plugin example} - -As an example, consider this function: - -\begin{verbatim} -#include - -#include - -/* The function we define. Call this - * from other parts of your C - * application. - */ -int -double_integer( int in ) -{ - return( in * 2 ); -} -\end{verbatim} - -\noindent -The source for all the example code in this section is in the vips-examples -package. - -The first step is to make a layer over this function which will make it -look like a standard VIPS function. VIPS insists on the following pattern: - -\begin{itemize} - -\item -The function should be int-valued, and return 0 for success and non-zero -for error. It should set \verb+im_error()+. - -\item -The function should take a single argument: a pointer to a -\verb+NULL+-terminated array of \verb+im_objects+. - -\item -Each \verb+im_object+ represents one argument to the function (either output -or input) in the form specified by the corresponding entry in the function's -argument descriptor. - -\end{itemize} - -The argument descriptor is an array of structures, each describing one -argument. For this example, it is: - -\begin{verbatim} -/* Describe the type of our function. - * One input int, and one output int. - */ -static im_arg_desc arg_types[] = { - IM_INPUT_INT( "in" ), - IM_OUTPUT_INT( "out" ) -}; -\end{verbatim} - -\verb+IM_INPUT_INT()+ and \verb+IM_OUTPUT_INT()+ are macros defined in -\verb++ which make argument types easy to define. Other -macros available are listed in table~\ref{tab:type}. - -\begin{tab2} -\begin{center} -\begin{tabular}{|l|l|l|} -\hline -Macro & Meaning & - \texttt{im\_object} has type \\ -\hline -\texttt{IM\_INPUT\_INT} & Input int & - \texttt{int *} \\ -\texttt{IM\_INPUT\_INTVEC} & Input vector of int & - \texttt{im\_intvec\_object *} \\ -\texttt{IM\_INPUT\_IMASK} & Input int array & - \texttt{im\_mask\_object *} \\ - -\texttt{IM\_OUTPUT\_INT} & Output int & - \texttt{int *} \\ -\texttt{IM\_INPUT\_INTVEC} & Output vector of int & - \texttt{im\_intvec\_object *} \\ -\texttt{IM\_OUTPUT\_IMASK} & Output int array to file & - \texttt{im\_mask\_object *} \\ - -\texttt{IM\_INPUT\_DOUBLE} & Input double & - \texttt{double *} \\ -\texttt{IM\_INPUT\_DOUBLEVEC} & Input vector of double & - \texttt{im\_realvec\_object *} \\ -\texttt{IM\_INPUT\_DMASK} & Input double array & - \texttt{im\_mask\_object *} \\ - -\texttt{IM\_OUTPUT\_DOUBLE} & Output double & - \texttt{double *} \\ -\texttt{IM\_OUTPUT\_DOUBLEVEC} & Output vector of double & - \texttt{im\_realvec\_object *} \\ -\texttt{IM\_OUTPUT\_DMASK} & Output double array to file & - \texttt{im\_mask\_object *} \\ -\texttt{IM\_OUTPUT\_DMASK\_STATS}& Output double array to screen & - \\ - -\texttt{IM\_OUTPUT\_COMPLEX} & Output complex & - \texttt{double *} \\ - -\texttt{IM\_INPUT\_STRING} & Input string & - \texttt{char *} \\ -\texttt{IM\_OUTPUT\_STRING} & Output string & - \texttt{char *} \\ - -\texttt{IM\_INPUT\_IMAGE} & Input image & - \texttt{IMAGE *} \\ -\texttt{IM\_INPUT\_IMAGEVEC} & Vector of input images & - \texttt{IMAGE **} \\ -\texttt{IM\_OUTPUT\_IMAGE} & Output image & - \texttt{IMAGE *} \\ -\texttt{IM\_RW\_IMAGE} & Read-write image & - \texttt{IMAGE *} \\ - -\texttt{IM\_INPUT\_DISPLAY} & Input display & - \texttt{im\_col\_display *} \\ -\texttt{IM\_OUTPUT\_DISPLAY} & Output display & - \texttt{im\_col\_display *} \\ - - -\texttt{IM\_INPUT\_GVALUE} & Input GValue & - \texttt{GValue *} \\ -\texttt{IM\_OUTPUT\_GVALUE} & Output GValue & - \texttt{GValue *} \\ - -\texttt{IM\_INPUT\_INTERPOLATE} & Input VipsInterpolate & - \texttt{VipsInterpolate *} \\ -\hline -\end{tabular} -\end{center} -\caption{Argument type macros\label{tab:type}} -\end{tab2} - -The argument to the type macro is the name of the argument. These names -are used by user-interface programs to provide feedback, and sometimes as -variable names. The order in which you list the arguments is the order in -which user-interfaces will present them to the user. You should use the -following conventions when selecting names and an order for your arguments: - -\begin{itemize} - -\item -Names should be entirely in lower-case and contain no special characters, -apart from the digits 0-9 and the underscore character `\_'. - -\item -Names should indicate the function of the argument. For example, -\verb+im_add()+ has the following argument names: - -\begin{verbatim} -example% vips -help im_add -vips: args: in1 in2 out -where: - in1 is of type "image" - in2 is of type "image" - out is of type "image" -add two images, from package - "arithmetic" -flags: - (PIO function) - (no coordinate transformation) - (point-to-point operation) -\end{verbatim} - -\item -You should order arguments with large input objects first, then output -objects, then any extra arguments or options. For example, \verb+im_extract()+ -has the following sequence of arguments: - -\begin{verbatim} -example% vips -help im_extract -vips: args: input output left top - width height channel -where: - input is of type "image" - output is of type "image" - left is of type "integer" - top is of type "integer" - width is of type "integer" - height is of type "integer" - channel is of type "integer" -extract area/band, from package - "conversion" -flags: - (PIO function) - (no coordinate transformation) - (point-to-point operation) -\end{verbatim} - -\end{itemize} - -This function sits over \verb+double_integer()+, providing VIPS with an -interface which it can call: - -\begin{verbatim} -/* Call our function via a VIPS - * im_object vector. - */ -static int -double_vec( im_object *argv ) -{ - int *in = (int *) argv[0]; - int *out = (int *) argv[1]; - - *out = double_integer( *in ); - - /* Always succeed. - */ - return( 0 ); -} -\end{verbatim} - -Finally, these two pieces of information (the argument description and -the VIPS-style function wrapper) can be gathered together into a function -description. - -\begin{verbatim} -/* Description of double_integer. - */ -static im_function double_desc = { - "double_integer", - "double an integer", - 0, - double_vec, - IM_NUMBER( arg_types ), - arg_types -}; -\end{verbatim} -\label{sec:number} - -\verb+IM_NUMBER()+ is a macro which returns the number of elements in a -static array. The \verb+flags+ field contains hints which user-interfaces -can use for various optimisations. At present, the possible values are: - -\begin{description} - -\item[\texttt{IM\_FN\_PIO}] -This function uses the VIPS PIO system (see \pref{sec:pio}). - -\item[\texttt{IM\_FN\_TRANSFORM}] -This the function transforms coordinates. - -\item[\texttt{IM\_FN\_PTOP}] -This is a point-to-point operation, that is, it can be replaced with a -look-up table. - -\item[\texttt{IM\_FN\_NOCACHE}] -This operation has side effects and should not be cached. Useful for video -grabbers, for example. - -\end{description} - -This function description now needs to be added to the VIPS function database. -VIPS groups sets of related functions together in packages. There is only -a single function in this example, so we can just write: - -\begin{verbatim} -/* Group up all the functions in this - * file. - */ -static im_function - *function_list[] = { - &double_desc -}; - -/* Define the package_table symbol. - * This is what VIPS looks for when - * loading the plugin. - */ -im_package package_table = { - "example", - IM_NUMBER( function_list ), - function_list -}; -\end{verbatim} - -The package has to be named \verb+package_table+, and has to be exported -from the file (that is, not a static). VIPS looks for a symbol of this name -when it opens your object file. - -This file needs to be made into a dynamically loadable object. On my machine, -I can do this with: - -\begin{verbatim} -example% gcc -fPIC -DPIC -c - `pkg-config vips-7.12 --cflags` - plug.c -o plug.o -example% gcc -shared plug.o - -o double.plg -\end{verbatim} - -You can now use \verb+double.plg+ with any of the VIPS applications which -support function dispatch. For example: - -\begin{verbatim} -example% vips -plugin double.plg \ - double_integer 12 -24 -example% -\end{verbatim} - -When VIPS starts up, it looks for a directory in the library directory called -\verb+vips-+, with the vips major and minor versions numbers as extensions, -and loads all files in there with the suffix \verb+.plg+. So for example, on -my machine, the plugin directory is \verb+/usr/lib/vips-7.16+ and any plugins -in that directory are automatically loaded into any VIPS programs on startup. - -\subsection{A more complicated example} - -This section lists the source for \verb+im_extract()+'s function -description. Almost all functions in the VIPS library have descriptors --- -if you are not sure how to write a description, it's usually easiest to -copy one from a similar function in the library. - -\begin{verbatim} -/* Args to im_extract. - */ -static im_arg_desc - extract_args[] = { - IM_INPUT_IMAGE( "input" ), - IM_OUTPUT_IMAGE( "output" ), - IM_INPUT_INT( "left" ), - IM_INPUT_INT( "top" ), - IM_INPUT_INT( "width" ), - IM_INPUT_INT( "height" ), - IM_INPUT_INT( "channel" ) -}; - -/* Call im_extract via arg vector. - */ -static int -extract_vec( im_object *argv ) -{ - IMAGE_BOX box; - - box.xstart = *((int *) argv[2]); - box.ystart = *((int *) argv[3]); - box.xsize = *((int *) argv[4]); - box.ysize = *((int *) argv[5]); - box.chsel = *((int *) argv[6]); - - return( im_extract( - argv[0], argv[1], &box ) ); -} - -/* Description of im_extract. - */ -static im_function - extract_desc = { - "im_extract", - "extract area/band", - IM_FN_PIO | IM_FN_TRANSFORM, - extract_vec, - NUMBER( extract_args ), - extract_args -}; -\end{verbatim} - -\subsection{Adding new types} - -The VIPS type mechanism is extensible. User plug-ins can add new types -and user-interfaces can (to a certain extent) provide interfaces to these -user-defined types. - -Here is the definition of \verb+im_arg_desc+: - -\begin{verbatim} -/* Describe a VIPS command argument. - */ -typedef struct { - char *name; - im_type_desc *desc; - im_print_obj_fn print; -} im_arg_desc; -\end{verbatim} - -The \verb+name+ field is the argument name above. The \verb+desc+ field -points to a structure defining the argument type, and the \verb+print+ field -is an (optionally \verb+NULL+) pointer to a function which VIPS will call -for output arguments after your function successfully completes and before -the object is destroyed. It can be used to print results to the terminal, -or to copy results into a user-interface layer. - -\begin{verbatim} -/* Success on an argument. This is - * called if the image processing - * function succeeds and should be - * used to (for example) print - * output. - */ -typedef int (*im_print_obj_fn) - ( im_object obj ); -\end{verbatim} - -\verb+im_type_desc+ is defined as: - -\begin{verbatim} -/* Describe a VIPS type. - */ -typedef struct { - im_arg_type type; - int size; - im_type_flags flags; - im_init_obj_fn init; - im_dest_obj_fn dest; -} im_type_desc; -\end{verbatim} - -Where \verb+im_arg_type+ is defined as - -\begin{verbatim} -/* Type names. You may define your - * own, but if you use one of these, - * then you should use the built-in - * VIPS type converters. - */ -#define IM_TYPE_IMAGEVEC "imagevec" -#define IM_TYPE_DOUBLEVEC "doublevec" -#define IM_TYPE_INTVEC "intvec" -#define IM_TYPE_DOUBLE "double" -#define IM_TYPE_INT "integer" -#define IM_TYPE_COMPLEX "complex" -#define IM_TYPE_STRING "string" -#define IM_TYPE_IMASK "intmask" -#define IM_TYPE_DMASK "doublemask" -#define IM_TYPE_IMAGE "image" -#define IM_TYPE_DISPLAY "display" -#define IM_TYPE_GVALUE "gvalue" -typedef char *im_arg_type; -\end{verbatim} - -In other words, it's just a string. When you add a new type, you just need -to choose a new unique string to name it. Be aware that the string is printed -to the user by various parts of VIPS, and so needs to be ``human-readable''. -The flags are: - -\begin{verbatim} -/* These bits are ored together to - * make the flags in a type - * descriptor. - * - * IM_TYPE_OUTPUT: set to indicate - * output, otherwise input. - * - * IM_TYPE_ARG: Two ways of making - * an im_object --- with and without - * a command-line string to help you - * along. Arguments with a string - * are thing like IMAGE descriptors, - * which require a filename to - * initialise. Arguments without are - * things like output numbers, where - * making the object simply involves - * allocating storage. - */ - -typedef enum { - IM_TYPE_OUTPUT = 0x1, - IM_TYPE_ARG = 0x2 -} im_type_flags; -\end{verbatim} - -And the \verb+init+ and \verb+destroy+ functions are: - -\begin{verbatim} -/* Initialise and destroy objects. - * The "str" argument to the init - * function will not be supplied - * if this is not an ARG type. - */ -typedef int (*im_init_obj_fn) - ( im_object *obj, char *str ); -typedef int (*im_dest_obj_fn) - ( im_object obj ); -\end{verbatim} - -As an example, here is the definition for a new type of unsigned -integers. First, we need to define the \verb+init+ and \verb+print+ -functions. These transform objects of the type to and from string -representation. - -\begin{verbatim} -/* Init function for unsigned int - * input. - */ -static int -uint_init( im_object *obj, char *str ) -{ - unsigned int *i = (int *) *obj; - - if( sscanf( str, "%d", i ) != 1 || - *i < 0 ) { - im_error( "uint_init", - "bad format" ); - return( -1 ); - } - - return( 0 ); -} - -/* Print function for unsigned int - * output. - */ -static int -uint_print( im_object obj ) -{ - unsigned int *i = - (unsigned int *) obj; - - printf( "%d\n", (int) *i ); - - return( 0 ); -} -\end{verbatim} - -Now we can define the type itself. We make two of these --- one for unsigned -int used as input, and one for output. - -\begin{verbatim} -/* Name our type. - */ -#define TYPE_UINT "uint" - -/* Input unsigned int type. - */ -static im_type_desc input_uint = { - TYPE_UINT, /* Its an int */ - sizeof( unsigned int ),/* Memory */ - IM_TYPE_ARG, /* Needs arg */ - uint_init, /* Init */ - NULL /* Destroy */ -}; - -/* Output unsigned int type. - */ -static im_type_desc output_uint = { - TYPE_UINT, /* It's an int */ - sizeof( unsigned int ),/* Memory */ - IM_TYPE_OUTPUT, /* It's output */ - NULL, /* Init */ - NULL /* Destroy */ -}; -\end{verbatim} - -Finally, we can define two macros to make structures of type -\verb+im_arg_desc+ for us. - -\begin{verbatim} -#define INPUT_UINT( S ) \ - { S, &input_uint, NULL } -#define OUTPUT_UINT( S ) \ - { S, &output_uint, uint_print } -\end{verbatim} - -For more examples, see the definitions for the built-in VIPS types. - -\subsection{Using function dispatch in your application} - -VIPS provides a set of functions for adding new image processing functions -to the VIPS function database, finding functions by name, and calling -functions. See the manual pages for full details. - -\subsubsection{Adding and removing functions} - -\begin{verbatim} -im_package *im_load_plugin( - const char *name ); -\end{verbatim} - -This function opens the named file, searches it for a symbol named -\verb+package_table+, and adds any functions it finds to the VIPS function -database. When you search for a function, any plug-ins are searched first, -so you can override standard VIPS function with your own code. - -The function returns a pointer to the package it added, or \verb+NULL+ -on error. - -\begin{verbatim} -int im_close_plugins( void ) -\end{verbatim} - -This function closes all plug-ins, removing then from the VIPS function -database. It returns non-zero on error. - -\subsubsection{Searching the function database} - -\begin{verbatim} -void *im_map_packages( - im_list_map_fn fn, void *a ) -\end{verbatim} - -This function applies the argument function \verb+fn+ to every package -in the database, starting with the most recently added package. As with -\verb+im_list_map()+, the argument function should return \verb+NULL+ -to continue searching, or non-\verb+NULL+ to terminate the search -early. \verb+im_map_packages()+ returns \verb+NULL+ if \verb+fn+ returned -\verb+NULL+ for all arguments. The extra argument \verb+a+ is carried around -by VIPS for your use. - -For example, this fragment of code prints the names of all loaded packages -to \verb+fd+: - -\begin{verbatim} -static void * -print_package_name( im_package *pack, - FILE *fp ) -{ - (void) fprintf( fp, - "package: \"%s\"\n", - pack->name ); - - /* Continue search. - */ - return( NULL ); -} - -static void -print_packages( FILE *fp ) -{ - (void) im_map_packages( - (im_list_map_fn) - print_package_name, fp ); -} -\end{verbatim} - -VIPS defines three convenience functions based on \verb+im_map_packages()+ -which simplify searching for specific functions: - -\begin{verbatim} -im_function * - im_find_function( char *name ) -im_package * - im_find_package( char *name ) -im_package * - im_package_of_function( char *name ) -\end{verbatim} - -\subsubsection{Building argument structures and running commands} - -\begin{verbatim} -int im_free_vargv( im_function *fn, - im_object *vargv ) -int im_allocate_vargv( - im_function *fn, - im_object *vargv ) -\end{verbatim} - -These two functions allocate space for and free VIPS argument lists. The -allocate function simply calls \verb+im_malloc()+ to allocate any store -that the types require (and also initializes it to zero). The free function -just calls \verb+im_free()+ for any storage that was allocated. - -Note that neither of these functions calls the \verb+init+, \verb+dest+ -or \verb+print+ functions for the types --- that's up to you. - -\begin{verbatim} -int im_run_command( char *name, - int argc, char **argv ) -\end{verbatim} - -This function does everything. In effect, - -\begin{verbatim} -im_run_command( "im_invert", 2, - { "fred.v", "fred2.v", NULL } ) -\end{verbatim} - -is exactly equivalent to - -\begin{verbatim} -system( "vips im_invert fred.v " - "fred2.v" ) -\end{verbatim} - -but no process is forked. diff --git a/doc/src/html.cfg b/doc/src/html.cfg deleted file mode 100644 index c8033ad9..00000000 --- a/doc/src/html.cfg +++ /dev/null @@ -1,17 +0,0 @@ -% configuration file for output of nipguide as html -\Preamble{html} -\begin{document} - -% stop the mono font shrinkage we do for paper output -\renewenvironment{ctd}{\begin{quote}\tt}{\end{quote}} - -% make a label -% in html, write an extra label which we can link to nip's help system -\renewcommand{\mylabel}[1]{ - \label{#1} - \HCode{} -} - -% supress " on page xx" if we're making HTML -\renewcommand{\onpage}[1]{} -\EndPreamble diff --git a/doc/src/interpolate.tex b/doc/src/interpolate.tex deleted file mode 100644 index 4478720a..00000000 --- a/doc/src/interpolate.tex +++ /dev/null @@ -1,162 +0,0 @@ -\section{Interpolators} -\label{sec:interpolate} - -VIPS has a general system for representing pixel interpolators. You can select -an interpolator to pass to other VIPS operations, such as \verb+im_affinei()+, -you can add new interpolators, and you can write operations which take a -general interpolator as a parameter. - -An interpolator is a function of the form: - -\begin{verbatim} -typedef void (*VipsInterpolateMethod)( VipsInterpolate *, - PEL *out, REGION *in, double x, double y ); -\end{verbatim} - -\noindent -given the set of input pixels \verb+in+, it has to calculate a value for the -fractional position $(x, y)$ and write this value to the memory pointed to by -\verb+out+. - -VIPS uses corner convention, so the value of pixel $(0, 0)$ is the value of -the surface the interpolator fits at the fractional position $(0.0, 0.0)$. - -\subsection{How an interpolator is represented} - -See the man page for \verb+VipsInterpolate+ for full details, but briefly, -an interpolator is a subclass of \verb+VipsInterpolate+ implementing the -following items: - -\begin{itemize} -\item -An interpolation method, with the type signature above. - -\item -A function \verb+get_window_size()+ which returns the size of the area of -pixels that the interpolator needs in order to calculate a value. For example, -a bilinear interpolator needs the four pixels surrounding the point to be -calculated, or a 2 by 2 window, so window size should be 2. - -\item -Or if the window size is constant, you can leave \verb+get_window_size()+ -NULL and just set the int value \verb+window_size+. - -\end{itemize} - -\subsection{A sample interpolator} - -As an example, \fref{fg:newinterpolator} shows how to register a new -interpolator in a plugin. - -\begin{fig2} -\begin{verbatim} -// This interpolator adds no new members. -typedef VipsInterpolate Myinterpolator; -typedef VipsInterpolateClass MyinterpolatorClass; - -G_DEFINE_TYPE( Myinterpolator, myinterpolator, VIPS_TYPE_INTERPOLATE ); - -static void -myinterpolator_interpolate( VipsInterpolate *interpolate, - PEL *out, REGION *in, double x, double y ) -{ - MyinterpolatorClass *class = - MYINTERPOLATOR_GET_CLASS( interpolate ); - - /* Nearest-neighbor. - */ - memcpy( out, - IM_REGION_ADDR( in, floor( x ), floor( y ) ), - IM_IMAGE_SIZEOF_PEL( in->im ) ); -} - -static void -myinterpolator_class_init( MyinterpolatorClass *class ) -{ - VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsInterpolateClass *interpolate_class = (VipsInterpolateClass *) class; - - object_class->nickname = "myinterpolator"; - object_class->description = _( "My interpolator" ); - - interpolate_class->interpolate = myinterpolator_interpolate; -} - -static void -myinterpolate_init( Myinterpolate *object ) -{ -} - -char * -g_module_check_init( GModule *self ) -{ - // register the type - myinterpolator_get_type(); -} -\end{verbatim} -\caption{Registering an interpolator in a plugin} -\label{fg:newinterpolator} -\end{fig2} - -\subsection{Writing a VIPS operation that takes an interpolator as an argument} - -Operations just take a \verb+VipsInterpolate+ as an argument, for example: - -\begin{verbatim} -int im_affinei_all( IMAGE *in, IMAGE *out, - VipsInterpolate *interpolate, - double a, double b, double c, double d, - double dx, double dy ); -\end{verbatim} - -To use the interpolator, use \verb+vips_interpolate()+: - -\begin{verbatim} -void vips_interpolate( VipsInterpolate *interpolate, - PEL *out, REGION *in, double x, double y ); -\end{verbatim} - -\noindent -This looks up the interpolate method for the object and calls it for you. - -You can save the cost of the lookup in an inner loop with -\verb+vips_interpolate_get_method()+: - -\begin{verbatim} -VipsInterpolateMethod - vips_interpolate_get_method( - VipsInterpolate *interpolate ); -\end{verbatim} - -\subsection{Passing an interpolator to a VIPS operation} - -You can build an instance of a \verb+VipsInterpolator+ with -the \verb+vips_object_*()+ family of functions, see \pref{sec:object}. - -Convenience functions return a static instance of one of the standard -interpolators: - -\begin{verbatim} -VipsInterpolate *vips_interpolate_nearest_static( void ); -VipsInterpolate *vips_interpolate_bilinear_static( void ); -\end{verbatim} - -\noindent -Don't free the result. - -Finally, \verb+vips_interpolate_new()+ makes a \verb+VipsInterpolate+ from a -nickname: - -\begin{verbatim} -VipsInterpolate *vips_interpolate_new( const char *nickname ); -\end{verbatim} - -For example: - -\begin{verbatim} -VipsInterpolate *interpolate = vips_interpolate_new( "nohalo" ); -\end{verbatim} - -\noindent -You must drop your ref after you're done with the object with -\verb+g_object_unref()+. diff --git a/doc/src/iosys.tex b/doc/src/iosys.tex deleted file mode 100644 index f79b797d..00000000 --- a/doc/src/iosys.tex +++ /dev/null @@ -1,836 +0,0 @@ -\section{Core C API} - -VIPS is built on top of several other libraries, two of which, glib and -gobject, are exposed at various points in the C API. - -You can read up on glib at the GTK+ website: - -\begin{verbatim} -http://www.gtk.org -\end{verbatim} - -There's also an excellent book by Matthias Warkus, \emph{The Official -GNOME 2 Developer's Guide}, which covers the same material in a tutorial -manner. - -\subsection{Startup} - -Before calling any VIPS function, you need to start VIPS up: - -\begin{verbatim} -int im_init_world( const char *argv0 ); -\end{verbatim} - -The \verb+argv0+ argument is the value of \verb+argv[0]+ your -program was passed by the host operating system. VIPS uses this with -\verb+im_guess_prefix()+ and \verb+im_guess_libdir()+ to try to find various -VIPS data files. - -If you don't call this function, VIPS will call it for you the first time you -use a VIPS function. But it won't be able to get the \verb+argv0+ value for -you, so it may not be able to find it's data files. - -VIPS also offers the optional: - -\begin{verbatim} -GOptionGroup *im_get_option_group( void ); -\end{verbatim} - -You can use this with GOption to parse your program's command-line arguments. -It adds several useful VIPS flags, including \verb+--vips-concurrency+. - -\fref{fg:hello} shows both these functions in use. Again, the GOption stuff is -optional and just lets VIPS add some flags to your program. You do need the -\verb+im_init_world()+ though. - -\begin{fig2} -\begin{verbatim} -#include -#include - -static gboolean print_stuff; - -static GOptionEntry options[] = { - { "print", 'p', 0, G_OPTION_ARG_NONE, &print_stuff, - "print \"hello world!\"", NULL }, - { NULL } -}; - -int -main( int argc, char **argv ) -{ - GOptionContext *context; - GError *error = NULL; - - if( im_init_world( argv[0] ) ) - error_exit( "unable to start VIPS" ); - - context = g_option_context_new( "- my program" ); - g_option_context_add_main_entries( context, - options, "main" ); - g_option_context_add_group( context, im_get_option_group() ); - if( !g_option_context_parse( context, &argc, &argv, &error ) ) { - if( error ) { - fprintf( stderr, "%s\n", error->message ); - g_error_free( error ); - } - error_exit( "try \"%s --help\"", g_get_prgname() ); - } - g_option_context_free( context ); - - if( print_stuff ) - printf( "hello, world!\n" ); - - return( 0 ); -} -\end{verbatim} -\caption{Hello World for VIPS} -\label{fg:hello} -\end{fig2} - -\subsection{Image descriptors} - -The base level of the VIPS I/O system provides \verb+IMAGE+ descriptors. -An image represented by a descriptor may be an image file on disc, an area -of memory that has been allocated for the image, an output file, a delayed -computation, and so on. Programs need (usually) only know that they have -a descriptor, they do not see many of the details. \fref{fg:image} -shows the definition of the \verb+IMAGE+ descriptor. - -\begin{fig2} -\begin{verbatim} -typedef struct { - /* Fields from image header. - */ - int Xsize; /* Pels per line */ - int Ysize; /* Lines */ - int Bands; /* Number of bands */ - int Bbits; /* Bits per band */ - int BandFmt; /* Band format */ - int Coding; /* Coding type */ - int Type; /* Type of file */ - float XRes; /* Horizontal res in pels/mm */ - float YRes; /* Vertical res in pels/mm */ - int Length; /* Obsolete (unused) */ - short Compression; /* Obsolete (unused) */ - short Level; /* Obsolete (unused) */ - int Xoffset; /* Position of origin */ - int Yoffset; - - /* Derived fields that may be read by the user. - */ - char *filename; /* File name */ - im_time_t *time; /* Timing for eval callback */ - int kill; /* Set to non-zero to block eval */ - - ... and lots of other private fields used by VIPS for - ... housekeeping. -} IMAGE; -\end{verbatim} -\caption{The \texttt{IMAGE} descriptor} -\label{fg:image} -\end{fig2} - -The first set of fields simply come from the image file header: -see \pref{sec:header} for a full description of all the fields. The next -set are maintained for you by the VIPS I/O system. \verb+filename+ is the -name of the file that this image came from. If you have attached an eval -callback to this image, \verb+time+ points to a set of timing statistics -which can be used by user-interfaces built on VIPS to provide feedback -about the progress of evaluation --- see \pref{sec:eval}. Finally, if you -set \verb+kill+ to non-zero, VIPS will block any pipelines which use this -descriptor as an intermediate. See \pref{sec:block}. - -The remaining fields are private and are used by VIPS for housekeeping. - -\subsection{Header fields} -\label{sec:fields} - -You can access header fields either directly (as \verb+im->Xsize+, for -example) or programmatically with \verb+im_header_int()+ and friends. For -example: - -\begin{verbatim} -int i; - -im_header_int( im, "Xsize", &i ); -\end{verbatim} - -There's also \verb+im_header_map()+ to loop over header fields, and -\verb+im_header_get_type+ to test the type of fields. These functions work for -image meta fields as well, see \pref{sec:meta}. - -\subsection{Opening and closing} -\label{sec:open} - -Descriptors are created with \verb+im_open()+. You can also read images with -the format system: see \pref{sec:format}. The two APIs are complimentary, -though \verb+im_open()+ is more useful. - -At the command-line, try: - -\begin{verbatim} -$ vips list classes -\end{verbatim} - -/noindent -to see a list of all the supported file formats. - -\verb+im_open()+ takes a file name and a string representing the mode with -which the descriptor is to be opened: - -\begin{verbatim} -IMAGE *im_open( const char *filename, - const char *mode ) -\end{verbatim} - -The possible values for mode are: - -\begin{description} - -\item[\texttt{"r"}] -The file is opened read-only. -If you open a non-VIPS image, or a VIPS image written on a machine with a -different byte ordering, \verb+im_open()+ will automatically convert it to -native VIPS format. If the underlying file does not support random access -(JPEG, for example), the entire file will be converted in memory. - -VIPS can read images in many file formats. You can control the details of -the conversion with extra characters embedded in the filename. For example: - -\begin{verbatim} -fred = im_open( "fred.tif:2", - "r" ); -\end{verbatim} - -\noindent -will read page 2 of a multi-page TIFF. See the man pages for details. - -\item[\texttt{"w"}] -An \verb+IMAGE+ descriptor is created which, when written to, will write -pixels to disc in the specified file. Any existing file of that name is -deleted. - -VIPS looks at the filename suffix to determine the save format. If there -is no suffix, or the filename ends in \verb+".v"+, the image is written -in VIPS native format. - -If you want to control the details of the conversion to the disc format (such -as setting the Q factor for a JPEG, for example), you embed extra control -characters in the filename. For example: - -\begin{verbatim} -fred = im_open( "fred.jpg:95", - "w" ); -\end{verbatim} - -\noindent -writes to \verb+fred+ will write a JPEG with Q 95. Again, see the man pages -for the conversion functions for details. - -\item[\texttt{"t"}] -As the \verb+"w"+ mode, but pels written to the descriptor will be saved -in a temporary memory buffer. - -\item[\texttt{"p"}] -This creates a special partial image. Partial images are used to join VIPS -operations together, see \pref{sec:joinup}. - -\item[\texttt{"rw"}] -As the \verb+"r"+ mode, but the image is mapped into the caller's address -space read-write. This mode is only provided for the use of paintbox-style -applications which need to directly modify an image. Most programs should -use the \verb+"w"+ mode for image output. - -\end{description} - -If an error occurs opening the image, \verb+im_open()+ calls -\verb+im_error()+ with a string describing the cause of the error and -returns \verb+NULL+. \verb+im_error()+ has type - -\begin{verbatim} -void im_error( const char *domain, - const char *format, ... ) -\end{verbatim} - -\noindent -The first argument is a string giving the name of the thing that raised -the error (just \verb+"im_open"+, for example). The format and subsequent -arguments work exactly as \verb+printf()+. It formats the message and -appends the string formed to the error log. You can get a pointer to the -error text with \verb+im_error_buffer()+. - -\begin{verbatim} -const char *im_error_buffer() -\end{verbatim} - -\noindent -Applications may display this string to give users feedback about the -cause of the error. The VIPS exit function, \verb+error_exit()+, prints -\verb+im_error_buffer()+ to \verb+stderr+ and terminates the program with an -error code of 1. - -\begin{verbatim} -void error_exit( const char *format, - ... ) -\end{verbatim} - -\noindent -There are other functions for handling errors: see the man page for -\verb+im_error()+. - -Descriptors are closed with \verb+im_close()+. It has type: - -\begin{verbatim} -int im_close( IMAGE *im ) -\end{verbatim} - -\verb+im_close()+ returns 0 on success and non-zero on error. - -\subsection{Examples} -\label{sec:examples} - -As an example, \fref{fg:widthheight} will print the width and height -of an image stored on disc. - -\begin{fig2} -\begin{verbatim} -#include -#include - -int -main( int argc, char **argv ) -{ - IMAGE *im; - - /* Check arguments. - */ - if( im_init_world( argv[0] ) ) - error_exit( "unable to start VIPS" ); - if( argc != 2 ) - error_exit( "usage: %s filename", argv[0] ); - - /* Open file. - */ - if( !(im = im_open( argv[1], "r" )) ) - error_exit( "unable to open %s for input", argv[1] ); - - /* Process. - */ - printf( "width = %d, height = %d\n", im->Xsize, im->Ysize ); - - /* Close. - */ - if( im_close( im ) ) - error_exit( "unable to close %s", argv[1] ); - - return( 0 ); -} -\end{verbatim} -\label{fg:widthheight} -\caption{Print width and height of an image} -\end{fig2} - -To compile this example, use: - -\begin{verbatim} -cc `pkg-config vips-7.14 \ - --cflags --libs` myfunc.c -\end{verbatim} - -As a slightly more complicated example, \fref{fg:negative} -will calculate the photographic negative of an image. - -\begin{fig2} -\begin{verbatim} -#include -#include - -int -main( int argc, char **argv ) -{ - IMAGE *in, *out; - - /* Check arguments. - */ - if( im_init_world( argv[0] ) ) - error_exit( "unable to start VIPS" ); - if( argc != 3 ) - error_exit( "usage: %s infile outfile", argv[0] ); - - /* Open images for read and write, invert, update the history with our - * args, and close. - */ - if( !(in = im_open( argv[1], "r" )) || - !(out = im_open( argv[2], "w" )) || - im_invert( in, out ) || - im_updatehist( out, argc, argv ) || - im_close( in ) || - im_close( out ) ) - error_exit( argv[0] ); - - return( 0 ); -} -\end{verbatim} -\label{fg:negative} -\caption{Find photographic negative} -\end{fig2} - -\subsection{Metadata} -\label{sec:meta} - -VIPS lets you attach arbitrary metadata to an IMAGE. For example, ICC -profiles, EXIF tags, image history, whatever you like. VIPS will efficiently -propagate metadata as images are processed (usually just by copying -pointers) and will automatically save and load metadata from VIPS files -(see \pref{sec:header}). - -A piece of metadata is a value and an identifying name. A set of -convenience functions let you set and get int, double, string and blob. For -example: - -\begin{verbatim} -int im_meta_set_int( IMAGE *, - const char *field, int ); -int im_meta_get_int( IMAGE *, - const char *field, int * ); -\end{verbatim} - -So you can do: - -\begin{verbatim} -if( im_meta_set_int( im, "poop", 42 ) ) - return( -1 ); -\end{verbatim} - -\noindent -to create an int called \verb+"poop"+, then at some later point (possibly much, -much later), in an image distantly derived from \verb+im+, you can use: - -\begin{verbatim} -int i; - -if( im_meta_get_int( im, "poop", &i ) ) - return( -1 ); -\end{verbatim} - -\noindent -And get the value 42 back. - -You can use \verb+im_meta_set()+ and \verb+im_meta_get()+ to attach arbitrary -\verb+GValue+ to images. See the man page for \verb+im_meta_set()+ for -full details. - -You can test for a field being present with \verb+im_meta_get_type()+ (you'll -get \verb+G_TYPE_INT+ back for \verb+"poop"+, for example, or 0 if it is not -defined for this image). - -\subsection{History} -\label{sec:history} - -VIPS tracks the history of an image, that is, the sequence of operations which -have led to the creation of an image. You can view a VIPS image's history with -the \verb+header+ command, or with \nip{}'s \ct{View Header} menu. Whenever an -application performs an action, it should append a line of shell script to the -history which would perform the same action. - -The call to \verb+im_updatehist()+ in \fref{fg:negative} adds a line to the -image history noting the invocation of this program, its arguments, and the -time and date at which it was run. You may also find \verb+im_histlin()+ -helpful. It has type: - -\begin{verbatim} -void im_histlin( IMAGE *im, - const char *fmt, ... ) -\end{verbatim} - -\noindent -It formats its arguments as \verb+printf()+ and appends the string formed -to the image history. - -You read an image's history with \verb+im_history_get()+. It returns the -entire history of an image, one action per line. No need to free the result. - -\begin{verbatim} -const char * - im_history_get( IMAGE *im ); -\end{verbatim} - -\subsection{Eval callbacks} -\label{sec:eval} - -VIPS lets you attach callbacks to image descriptors. These are functions -you provide which VIPS will call when certain events occur. See -\pref{sec:callback} for more detail. - -Eval callbacks are called repeatedly during evaluation and can be used by -user-interface programs to give feedback about the progress of evaluation. - -\subsection{Detailed rules for descriptors} - -These rules are intended to answer awkward questions. - -\begin{enumerate} - -\item -You can output to a descriptor only once. - -\item -You can use a descriptor as an input many times. - -\item -You can only output to a descriptor that was opened with modes \verb+"w"+, -\verb+"t"+ and \verb+"p"+. - -\item -You can only use a descriptor as input if it was opened with modes \verb+"r"+ -or \verb+"rw"+. - -\item -If you have output to a descriptor, you may subsequently use it as an -input. \verb+"w"+ descriptors are automatically changed to \verb+"r"+ -descriptors. - -If the function you are passing the descriptor to uses WIO (see -\pref{sec:limit}), then \verb+"p"+ descriptors become \verb+"t"+. -If the function you are passing the descriptor to uses PIO, then \verb+"p"+ -descriptors are unchanged. - -\end{enumerate} - -\subsection{Automatic resource deallocation} - -VIPS lets you allocate resources local to an image descriptor, that is, -when the descriptor is closed, all resources which were allocated local to -that descriptor are automatically released for you. - -\subsubsection{Local image descriptors} - -VIPS provides a function which will open a new image local to -an existing image. \verb+im_open_local()+ has type: - -\begin{verbatim} -IMAGE *im_open_local( IMAGE *im, - const char *filename, - const char *mode ) -\end{verbatim} - -It behaves exactly as \verb+im_open()+, except that you do not need to close -the descriptor it returns. It will be closed automatically when its parent -descriptor \verb+im+ is closed. - -\begin{fig2} -\begin{verbatim} -/* Add another image to the accumulated total. - */ -static int -sum1( IMAGE *acc, IMAGE **in, int nin, IMAGE *out ) -{ - IMAGE *t; - - if( nin == 0 ) - /* All done ... copy to out. - */ - return( im_copy( acc, out ) ); - - /* Make a new intermediate, and add to it.. - */ - return( !(t = im_open_local( out, "sum1:1", "p" )) || - im_add( acc, in[0], t ) || - sum1( t, in + 1, nin - 1, out ) ); -} - -/* Sum the array of images in[]. nin is the number of images in - * in[], out is the descriptor we write the final image to. - */ -int -total( IMAGE **in, int nin, IMAGE *out ) -{ - /* Check that we have at least one image. - */ - if( nin <= 0 ) { - im_error( "total", "nin should be > 0" ); - return( -1 ); - } - - /* More than 1, sum recursively. - */ - return( sum1( in[0], in + 1, nin - 1, out ) ); -} -\end{verbatim} -\caption{Sum an array of images} -\label{fg:addemup} -\end{fig2} - -\fref{fg:addemup} is a function which will sum an array of images. -We need never close any of the (unknown) number of intermediate images which -we open. They will all be closed for us by our caller, when our caller -finally closes \verb+out+. VIPS lets local images themselves have local -images and automatically makes sure that all are closed in the correct order. - -It is very important that these intermediate images are made local to -\verb+out+ rather than \verb+in+, for reasons which should become apparent -in the section on combining operations below. - -There's also \verb+im_open_local_array()+ for when you need a lot of local -descriptors, see the man page. - -\subsubsection{Local memory allocation} -\label{sec:malloc} - -VIPS includes a set of functions for memory allocation local to an image -descriptor. The base memory allocation function is \verb+im_malloc()+. It -has type: - -\begin{verbatim} -void *im_malloc( IMAGE *, size_t ) -\end{verbatim} - -It operates exactly as the standard \verb+malloc()+ C library function, -except that the area of memory it allocates is local to an image. -If \verb+im_malloc()+ is unable to allocate memory, it returns -\verb+NULL+. If you pass \verb+NULL+ instead of a valid image descriptor, -then \verb+im_malloc()+ allocates memory globally and you must free it -yourself at some stage. - -To free memory explicitly, use \verb+im_free()+: - -\begin{verbatim} -int im_free( void * ) -\end{verbatim} - -\noindent -\verb+im_free()+ always returns 0, so you can use it as an argument to a -callback. - -Three macros make memory allocation even easier. \verb+IM_NEW()+ allocates -a new object. You give it a descriptor and a type, and it returns a pointer -to enough space to hold an object of that type. It has type: - -\begin{verbatim} -type-name *IM_NEW( IMAGE *, type-name ) -\end{verbatim} - -The second macro, \verb+IM_ARRAY()+, is very similar, but allocates -space for an array of objects. Note that, unlike the usual \verb+calloc()+ -C library function, it does not initialise the array to zero. It has type: - -\begin{verbatim} -type-name *IM_ARRAY( IMAGE *, int, type-name ) -\end{verbatim} - -Finally, \verb+IM_NUMBER()+ returns the number of elements in an array of -defined size. See the man pages for a series of examples, or -see \pref{sec:number}. - -\subsubsection{Other local operations} - -The above facilities are implemented with the VIPS core function -\verb+im_add_close_callback()+. You can use this facility to make your own -local resource allocators for other types of object --- see the manual page -for more help. - -\subsection{Error handling} - -All VIPS operations return 0 on success and non-zero on error, setting -\verb+im_error()+. As a consequence, when a VIPS function fails, you do not -need to generate an error message --- you can simply propagate the error back -up to your caller. If however you detect some error yourself (for example, -the bad parameter in the example above), you must call \verb+im_error()+ -to let your caller know what the problem was. - -VIPS provides two more functions for error message handling: \verb+im_warn()+ -and \verb+im_diag()+. These are intended to be used for less serious -messages, as their names suggest. Currently, they simply format and print -their arguments to \verb+stderr+, optionally suppressed by the setting of an -environment variable. Future releases of VIPS may allow more sophisticated -trapping of these functions to allow their text to be easily presented to -the user by VIPS applications. See the manual pages. - -\subsection{Joining operations together} -\label{sec:joinup} - -VIPS lets you join image processing operations together so that they -behave as a single unit. \fref{fg:join} shows the definition of the -function \verb+im_Lab2disp()+ from the VIPS library. This function converts -an image in \cielab{} colour space to an RGB image for a monitor. The -monitor characteristics (gamma, phosphor type, etc.) are described by the -\verb+im_col_display+ structure, see the man page for \verb+im_col_XYZ2rgb()+. - -\begin{fig2} -\begin{verbatim} -int -im_Lab2disp( IMAGE *in, IMAGE *out, struct im_col_display *disp ) -{ - IMAGE *t1; - - if( !(t1 = im_open_local( out, "im_Lab2disp:1", "p" )) || - im_Lab2XYZ( in, t1 ) || - im_XYZ2disp( t1, out, disp ) ) - return( -1 ); - - return( 0 ); -} -\end{verbatim} -\caption{Two image-processing operations joined together} -\label{fg:join} -\end{fig2} - -The special \verb+"p"+ mode (for partial) used to open the image descriptor -used as the intermediate image in this function `glues' the two operations -together. When you use \verb+im_Lab2disp()+, the two operations inside it -will execute together and no extra storage is necessary for the intermediate -image (\verb+t1+ in this example). This is important if you want to process -images larger than the amount of RAM you have on your machine. - -As an added bonus, if you have more than one CPU in your computer, the work -will be automatically spread across the processors for you. You can control -this parallelization with the \verb+IM_CONCURRENCY+ environment variable, -\verb+im_concurrency_set()+, and with the \verb+--vips-concurrency+ -command-line switch. See the man page for \verb+im_generate()+. - -\subsubsection{How it works} - -When a VIPS function is asked to output to a \verb+"p"+ image descriptor, -all the fields in the descriptor are set (the output image size and type -are set, for example), but no image data is actually generated. Instead, -the function attaches callbacks to the image descriptor which VIPS can use -later to generate any piece of the output image that might be needed. - -When a VIPS function is asked to output to a \verb+"w"+ or a \verb+"t"+ -descriptor (a real disc file or a real memory buffer), it evaluates -immediately and its evaluation in turn forces the evaluation of any earlier -\verb+"p"+ images. - -In the example in \fref{fg:join}, whether or not any pixels are really -processed when \verb+im_Lab2disp()+ is called depends upon the mode in -which \verb+out+ was opened. If \verb+out+ is also a partial image, then -no pixels will be calculated --- instead, a pipeline of VIPS operations -will be constructed behind the scenes and attached to \verb+out+. - -Conversely, if \verb+out+ is a real image (that is, either \verb+"w"+ -or \verb+"t"+), then the final VIPS operation in the function -(\verb+im_XYZ2disp()+) will output the entire image to \verb+out+, causing -the earlier parts of \verb+im_Lab2disp()+ (and indeed possibly some earlier -pieces of program, if \verb+in+ was also a \verb+"p"+ image) to run. - -When a VIPS pipeline does finally evaluate, all of the functions in the -pipeline execute together, sucking image data through the system in small -pieces. As a consequence, no intermediate images are generated, large -amounts of RAM are not needed, and no slow disc I/O needs to be performed. - -Since VIPS partial I/O is demand-driven rather than data-driven this works -even if some of the operations perform coordinate transformations. We could, -for example, include a call to \verb+im_affine()+, which performs -arbitrary rotation and scaling, and everything would still work correctly. - -\subsubsection{Pitfalls with partials} - -To go with all of the benefits that partial image I/O brings, there are -also some problems. The most serious is that you are often not quite certain -when computation will happen. This can cause problems if you close an input -file, thinking that it is finished with, when in fact that file has not -been processed yet. Doing this results in dangling pointers and an almost -certain core-dump. - -You can prevent this from happening with careful use of -\verb+im_open_local()+. If you always open local to your output image, -you can be sure that the input will not be closed before the output has been -generated to a file or memory buffer. You do not need to be so careful with -non-image arguments. VIPS functions which take extra non-image arguments -(a matrix, perhaps) are careful to make their own copy of the object before -returning. - -\subsubsection{Non-image output} - -Some VIPS functions consume images, but make no image -output. \verb+im_stats()+ for example, scans an image calculating various -statistical values. When you use \verb+im_stats()+, it behaves as a data -sink, sucking image data through any earlier pipeline stages. - -\subsubsection{Calculating twice} - -In some circumstances, the same image data can be generated twice. -\fref{fg:thrmean} is a function which finds the mean value of an -image, and writes a new image in which pixels less than the mean are set to -0 and images greater than the mean are set to 255. - -\begin{fig2} -\begin{verbatim} -int -threshold_at_mean( IMAGE *in, IMAGE *out ) -{ - double mean; - - if( im_avg( in, &mean ) || - im_moreconst( in, out, mean ) ) - return( -1 ); - - return( 0 ); -} -\end{verbatim} -\caption{Threshold an image at the mean value} -\label{fg:thrmean} -\end{fig2} - -This seems straightforward --- but consider if image \verb+in+ were a -\verb+"p"+, and represented the output of a large pipeline of operations. The -call to \verb+im_avg()+ would force the evaluation of the entire pipeline, -and throw it all away, keeping only the average value. The subsequent call to -\verb+im_moreconst()+ will cause the pipeline to be evaluated a second time. - -When designing a program, it is sensible to pay attention to these -issues. It might be faster, in some cases, to output to a file before -calling \verb+im_avg()+, find the average of the disc file, and then run -\verb+im_moreconst()+ from that. There's also \verb+im_cache()+ which can keep -recent parts of a very large image. - -\subsubsection{Blocking computation} -\label{sec:block} - -\verb+IMAGE+ descriptors have a flag called \verb+kill+ which can be used -to block computation. If \verb+im->kill+ is set to a non-zero value, -then any VIPS pipelines which use \verb+im+ as an intermediate will fail -with an error message. This is useful for user-interface writers --- -suppose your interface is forced to close an image which many other images -are using as a source of data. You can just set the \verb+kill+ flag in all -of the deleted image's immediate children and prevent any dangling pointers -from being followed. - -\subsubsection{Limitations} -\label{sec:limit} - -Not all VIPS operations are partial-aware. These non-partial operations -use a pre-VIPS 7.0 I/O scheme in which the whole of the input image has to -be present at the same time. In some cases, this is because partial I/O -simply makes no sense --- for example, a Fourier Transform can produce no -output until it has seen all of the input. \verb+im_fwfft()+ is therefore -not a partial operation. In other cases, we have simply not got around to -rewriting the old non-partial operation in the newer partial style. - -You can mix partial and non-partial VIPS operations freely, without worrying -about which type they are. The only effect will be on the time your pipeline -takes to execute, and the memory requirements of the intermediate images. VIPS -uses the following rules when you mix the two styles of operation: - -\begin{enumerate} - -\item -When a non-partial operation is asked to output to a partial image descriptor, -the \verb+"p"+ descriptor is magically transformed into a \verb+"t"+ -descriptor. - -\item -When a non-partial operation is asked to read from a \verb+"p"+ descriptor, -the \verb+"p"+ descriptor is turned into a \verb+"t"+ type, and any earlier -stages in the pipeline forced to evaluate into that memory buffer. - -The non-partial operation then processes from the memory buffer. - -\end{enumerate} - -These rules have the consequence that you may only process very large images -if you only use partial operations. If you use any non-partial operations, -then parts of your pipelines will fall back to old whole-image I/O and you -will need to think carefully about where your intermediates should be stored. - diff --git a/doc/src/ipio.tex b/doc/src/ipio.tex deleted file mode 100644 index c0f39806..00000000 --- a/doc/src/ipio.tex +++ /dev/null @@ -1,56 +0,0 @@ -\section{Programming in-place functions} - -VIPS includes a little support for in-place functions --- functions -which operate directly on an image, both reading and writing from the same -descriptor via the data pointer. This is an extremely dangerous way to -handle IO, since any bugs in your program will trash your input image. - -Operations of this type should call \verb+im_rwcheck()+ instead of -\verb+im_incheck()+. \verb+im_rwcheck()+ tries to get a descriptor ready -for in-place writing. For example, a function which cleared an image to -black might be written as: - -\begin{verbatim} -#include -#include - -#include - -int -black_inplace( IMAGE *im ) -{ - /* Check that we can RW to im. - */ - if( im_rwcheck( im ) ) - return( -1 ); - - /* Zap the image! - */ - memset( im->data, 0, - IM_IMAGE_SIZEOF_LINE( im ) * - im->Ysize ); - - return( 0 ); -} -\end{verbatim} - -This function might be called from an application as: - -\begin{verbatim} -#include -#include - -#include - -void -zap( char *name ) -{ - IMAGE *im; - - if( !(im = im_open( name, "rw" )) || - black_inplace( im ) || - im_updatehist( im, "zap image" ) || - im_close( im ) ) - error_exit( "failure!" ); -} -\end{verbatim} diff --git a/doc/src/mydefs.tex b/doc/src/mydefs.tex deleted file mode 100644 index 5310b8ce..00000000 --- a/doc/src/mydefs.tex +++ /dev/null @@ -1,113 +0,0 @@ -% My defs - -% Computer Text, Computer text=>, Computer Text Display -\newcommand{\ct}[1]{\texttt{#1}} -\newcommand{\ctr}[1]{\ct{#1} / } - -\newenvironment{ctd}{\begin{quote}\footnotesize\tt}{\end{quote}} -\pagecolor{white} - -% abbreviations -\newcommand{\vips}{\ct{vips}} -\newcommand{\nip}{\ct{nip2}} -\newcommand{\bs}{$\backslash$} -\newcommand{\rtp}{\^{ }} -\newcommand{\cielab}{\emph{CIE~}$L^{*}a^{*}b^{*}$} -\newcommand{\ciexyz}{\emph{CIE XYZ}} -\newcommand{\cieyxy}{\emph{CIE Yxy}} -\newcommand{\cielch}{\emph{CIE LCh}} -\newcommand{\cieucs}{\emph{UCS(1:1)}} -\newcommand{\cross}{$\times{}$} - -% make a label ... override this for HTML output -\newcommand{\mylabel}[1]{\label{#1}} - -% generate " on page xx" if a label is referring to something on another page -% override this for HTML output -\newcounter{boink} -\newcommand{\onpage}[1]{% -\addtocounter{boink}{1}% -\label{atref\theboink{}}% -\ifthenelse{\pageref{atref\theboink{}}=\pageref{#1}}% -{}% -{ on page~\pageref{#1}}} - -% format a reference to a section .. "$3.11 on page 37" -\newcommand{\pref}[1]{\S\ref{#1}\onpage{#1}} -\newcommand{\tref}[1]{Table~\ref{#1}\onpage{#1}} -\newcommand{\fref}[1]{Figure~\ref{#1}\onpage{#1}} -\newcommand{\cref}[1]{Chapter~\ref{#1}\onpage{#1}} -\newcommand{\aref}[1]{Appendix~\ref{#1}\onpage{#1}} - -% Insert a file ... height and name. -\newcommand{\fig}[2]{ - \begin{center} - \includegraphics[height=#1]{figs/#2} - \end{center} -} - -% Insert a file ... width and name. -\newcommand{\figw}[2]{ - \begin{center} - \includegraphics[width=#1]{figs/#2} - \end{center} -} - -% make a 2-column figure ... define our own so we can easily override in html -% output -\newenvironment{fig2}{\begin{figure*}}{\end{figure*}} - -% same for 2-col tables -\newenvironment{tab2}{\begin{table*}}{\end{table*}} - -% environment for setting ip defs -\newenvironment{ipdef}{ -\par -\samepage -\begin{ctd} -\begin{tabular}{@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}ll@{\hspace{0.2em}}lllllllllllllllllllllllllllll} -~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & ~ & ~~~ & \\[-1.3em] -}{ -\end{tabular} -\end{ctd} -\par -} - -% causes problems for htlatex :-( -% make this a noop for now -% \newcommand{\dtxt}[1]{\multicolumn{25}{@{\hspace{0.2em}}l}{#1}} -\newcommand{\dtxt}[1]{#1} - -% Insert a blank page -\newcommand{\blankpage}{% -\newpage -~~~~ -\pagestyle{plain} -\newpage -% Another one necessary in twocolumn mode -~~~~ -\newpage -\pagestyle{fancy} -} - -%\addtolength{\headheight}{3pt} - -% Make text a bit wider, since we are two column. -\addtolength{\textwidth}{0.5in} -\addtolength{\oddsidemargin}{-0.25in} -\addtolength{\evensidemargin}{-0.25in} - -% twocolumn seems to remove the binding offset ... add it back -%\addtolength{\oddsidemargin}{-0.2in} -%\addtolength{\evensidemargin}{0.2in} - -% More space between headers and footers and the body -\addtolength{\topmargin}{-0.5em} -\addtolength{\headsep}{0.5em} -\addtolength{\footskip}{0.5em} - -% Swap left and right binding offsets -\newlength{\fred} -\setlength{\fred}{\oddsidemargin} -\setlength{\oddsidemargin}{\evensidemargin} -\setlength{\evensidemargin}{\fred} diff --git a/doc/src/object.tex b/doc/src/object.tex deleted file mode 100644 index 610c0953..00000000 --- a/doc/src/object.tex +++ /dev/null @@ -1,134 +0,0 @@ -\section{The VIPS base class: \texttt{VipsObject}} -\label{sec:object} - -VIPS is in the process of moving to an object system based on \verb+GObject+. -You can read about the \verb+GObjec+ library at the GTK+ website: - -\begin{verbatim} -http://www.gtk.org -\end{verbatim} - -We've implemented two new subsystems (\verb+VipsFormat+ and -\verb+VipsInterpolate+) on top of \verb+VipsObject+ but not yet moved the core -VIPS types over. As a result, \verb+VipsObject+ is still developing and is -likely to change in the next release. - -This section quickly summarises enough of the \verb+VipsObject+ system to let -you use the two derived APIs but that's all. Full documentation will come when -this system stabilises. - -\subsection{Properties} - -Like the rest of VIPS, \verb+VipsObject+ is a functional type. You can set -properties during object construction, but not after that point. You may read -properties at any time after construction, but not before. - -To enforce these rules, VIPS extends the standard \verb+GObject+ property -system and adds a new phase to object creation. An object has the following -stages in its life: - -\subsubsection{Lookup} - -\verb+vips_type_find()+ is a convenience function that looks up a type by its -nickname relative to a base class. For example: - -\begin{verbatim} -GType type = - vips_type_find( "VipsInterpolate", "bilinear" ); -\end{verbatim} - -\noindent -finds a subclass of \verb+VipsInterpolate+ nicknamed `bilinear'. You can look -up types by their full name of course, but these can be rather unwieldy -(\verb+VipsInterpolateBilinear+ in this case, for example). - -\subsubsection{Create} - -Build an instance with \verb+g_object_new()+. For example: - -\begin{verbatim} -VipsObject *object = - g_object_new( type, - "sharpness", 12.0, - NULL ); -\end{verbatim} - -You can set any of the object's properties in the constructor. You can -continue to set, but not read, any other properties, for example: - -\begin{verbatim} -g_object_set( object, - "sharpness", 12.0, - NULL ); -\end{verbatim} - -You can loop over an object's required and optional parameters with -\verb+vips_argument_map()+. - -\subsubsection{Build} - -Once all of the required any any of the optional object parameters have been -set, call \verb+vips_object_build()+: - -\begin{verbatim} -int vips_object_build( VipsObject *object ); -\end{verbatim} - -This function checks that all the parameters have been set correctly and -starts the object working. It returns non-zero on error, setting -\verb+im_error_string()+. - -\subsubsection{Use} - -The object is now fully working. You can read results from it, or pass it on -other objects. When you're finished with it, drop your reference to end its -life. - -\begin{verbatim} -g_object_unref( object ); -\end{verbatim} - -\subsection{Convenience functions} - -Two functions simplify building and printing objects. -\verb+vips_object_new_from_string()+ makes a new object which is a subclass of -a named base class. - -\begin{verbatim} -VipsObject * - vips_object_new_from_string( - const char *basename, const char *p ); -\end{verbatim} - -This is the function used by \verb+IM_INPUT_INTERPOLATE()+, for example, to -parse command-line arguments. The syntax is: - -\begin{verbatim} -nickname [ ( required-arg1, - ... - required-argn, - optional-arg-name = value, - ... - optional-argm-name = value ) ] -\end{verbatim} - -So values for all the required arguments, in the correct order, then name = -value for all the optional arguments you want to set. Parameters may be -enclosed in round or curly braces. - -\verb+vips_object_to_string()+ is the exact opposite: it generates the -construct string for any constructed -\verb+VipsObject+. - -\verb+vips_object_new()+ wraps up the business of creating and checking an -object. It makes the object, uses the supplied function to attach any -arguments, then builds the object and returns NULL on failure or the new -object on success. - -A switch to the \verb+vips+ command-line program is handy for listing subtypes -of \verb+VipsObject+. Try: - -\begin{verbatim} -$ vips list classes -\end{verbatim} - diff --git a/doc/src/operintro.tex b/doc/src/operintro.tex deleted file mode 100644 index 5d9ee25d..00000000 --- a/doc/src/operintro.tex +++ /dev/null @@ -1,100 +0,0 @@ -\section{Introduction} -\mylabel{sec:oper} - -This chapter explains how to write image processing operations using the -VIPS image I/O (input-output) system. For background, you should probably -take a look at \pref{sec:appl}. This is supposed to be a tutorial, if you -need detailed information on any particular function, use the on-line UNIX -manual pages. - -\subsection{Why use VIPS?} - -If you use the VIPS image I/O system, you get a number of benefits: - -\begin{description} - -\item[Threading] -If your computer has more than one CPU, the VIPS I/O system will automatically -split your image processing operation into separate threads (provided you -use PIO, see below). You should get an approximately linear speed-up as -you add more CPUs. - -\item[Pipelining] -Provided you use PIO (again, see below), VIPS can automatically join -operations together. A sequence of image processing operations will all -execute together, with image data flowing through the processing pipeline -in small pieces. This makes it possible to perform complex processing on -very large images with no need to worry about storage management. - -\item[Composition] -Because VIPS can efficiently compose image processing operations, you can -implement your new operation in small, reusable, easy-to-understand -pieces. VIPS already has a lot of these: many new operations can be -implemented by simply composing existing operations. - -\item[Large files] -Provided you use PIO and as long as the underlying OS supports large files -(that is, files larger than 2GB), VIPS operations can work on files larger -than can be addressed with 32 bits on a plain 32-bit machine. VIPS operations -only see 32 bit addresses; the VIPS I/O system transparently maps these to -64 bit operations for I/O. Large file support is included on most machines -after about 1998. - -\item[Abstraction] -VIPS operations see only arrays of numbers in native format. Details of -representation (big/little endian, VIPS/TIFF/JPEG file format, etc.) are -hidden from you. - -\item[Interfaces] -Once you have your image processing operation implemented, it automatically -appears in all of the VIPS interfaces. VIPS comes with a GUI (\nip{}), a -UNIX command-line interface (\vips{}) and a C++ and Python API. - -\item[Portability] -VIPS operations can be compiled on most unixes, Mac OS X and Windows NT, 2000 -and XP without modification. Mostly. - -\end{description} - -\subsection{I/O styles} - -The I/O system supports three styles of input-output. - -\begin{description} - -\item[Whole-image I/O (WIO)] -This style is a largely a left-over from VIPS 6.x. WIO image-processing -operations have all of the input image given to them in a large memory -array. They can read any of the input pels at will with simple pointer -arithmetic. - -\item[Partial-image I/O (PIO)] -In this style operations only have a small part of the input image available -to them at any time. When PIO operations are joined together into a pipeline, -images flow through them in small pieces, with all the operations in a -pipeline executing at the same time. - -\item[In-place] -The third style allows pels to be read and written anywhere in -the image at any time, and is used by the VIPS in-place operations, such -as \verb+im_fastline()+. You should only use it for operations which would -just be impossibly inefficient to write with either of the other two styles. - -\end{description} - -WIO operations are easy to program, but slow and inflexible when images -become large. PIO operations are harder to program, but scale well as images -become larger, and are automatically parallelized by the VIPS I/O system. - -If you can face it, and if your algorithm can be expressed in this way, you -should write your operations using PIO. Whichever you choose, applications -which call your operation will see no difference, except in execution speed. - -If your image processing operation performs no coordinate transformations, -that is, if your output image is the same size as your input image or images, -and if each output pixel depends only upon the pixel at the corresponding -position in the input images, then you can use the \verb+im_wrapone()+ -and \verb+im_wrapmany()+ operations. These take a simple buffer-processing -operation supplied by you and wrap it up as a full-blown PIO operation. -See~\pref{sec:wrapone}. - diff --git a/doc/src/packages.tex b/doc/src/packages.tex deleted file mode 100644 index f3fde6b1..00000000 --- a/doc/src/packages.tex +++ /dev/null @@ -1,889 +0,0 @@ -\section{VIPS packages} -\mylabel{sec:packages} - -\subsection{Arithmetic} - -See \fref{fg:arithmetic}. - -Arithmetic functions work on images as if each band element were a separate -number. All operations are point-to-point --- each output element depends -exactly upon the corresponding input element. All (except in a few cases -noted in the manual pages) will work with images of any type (or any mixture -of types), of any size and of any number of bands. - -Arithmetic operations try to preserve precision by increasing the number of -bits in the output image when necessary. Generally, this follows the ANSI C -conventions for type promotion --- so multiplying two \verb+IM_BANDFMT_UCHAR+ -images together, for example, produces a \verb+IM_BANDFMT_USHORT+ image, and -taking the \verb+im_costra()+ of a \verb+IM_BANDFMT_USHORT+ image produces -a \verb+IM_BANDFMT_FLOAT+ image. The details of the type conversions are -in the manual pages. - -\begin{fig2} -\begin{verbatim} -$ vips list arithmetic -im_abs - absolute value -im_acostra - acos of image (result in degrees) -im_add - add two images -im_asintra - asin of image (result in degrees) -im_atantra - atan of image (result in degrees) -im_avg - average value of image -im_point_bilinear - interpolate value at single point, linearly -im_bandmean - average image bands -im_ceil - round to smallest integal value not less than -im_cmulnorm - multiply two complex images, normalising output -im_costra - cos of image (angles in degrees) -im_cross_phase - phase of cross power spectrum of two complex images -im_deviate - standard deviation of image -im_divide - divide two images -im_exp10tra - 10^pel of image -im_expntra - x^pel of image -im_expntra_vec - [x,y,z]^pel of image -im_exptra - e^pel of image -im_fav4 - average of 4 images -im_floor - round to largest integal value not greater than -im_gadd - calculate a*in1 + b*in2 + c = outfile -im_invert - photographic negative -im_lintra - calculate a*in + b = outfile -im_linreg - pixelwise linear regression -im_lintra_vec - calculate a*in + b -> out, a and b vectors -im_litecor - calculate max(white)*factor*(in/white), if clip == 1 -im_log10tra - log10 of image -im_logtra - ln of image -im_max - maximum value of image -im_maxpos - position of maximum value of image -im_maxpos_avg - position of maximum value of image, averaging in case of draw -im_maxpos_vec - position and value of n maxima of image -im_measure - measure averages of a grid of patches -im_min - minimum value of image -im_minpos - position of minimum value of image -im_minpos_vec - position and value of n minima of image -im_multiply - multiply two images -im_powtra - pel^x ofbuildimage -im_powtra_vec - pel^[x,y,z] of image -im_remainder - remainder after integer division -im_remainderconst - remainder after integer division by a constant -im_remainderconst_vec - remainder after integer division by a vector of constants -im_rint - round to nearest integal value -im_sign - unit vector in direction of value -im_sintra - sin of image (angles in degrees) -im_stats - many image statistics in one pass -im_subtract - subtract two images -im_tantra - tan of image (angles in degrees) -\end{verbatim} -\caption{Arithmetic functions} -\label{fg:arithmetic} -\end{fig2} - -\subsection{Relational} - -See \fref{fg:relational}. - -Relational functions compare images to other images or to constants. They -accept any image or pair of images (provided they are the same size and -have the same number of bands --- their types may differ) and produce a -\verb+IM_BANDFMT_UCHAR+ image with the same number of bands as the input -image, with 255 in every band element for which the condition is true and -0 elsewhere. - -They may be combined with the boolean functions to form complex relational -conditions. Use \verb+im_max()+ (or \verb+im_min()+) to find out if a -condition is true (or false) for a whole image. - -\begin{fig2} -\begin{verbatim} -$ vips list relational -im_blend - use cond image to blend between images in1 and in2 -im_equal - two images equal in value -im_equal_vec - image equals doublevec -im_equalconst - image equals const -im_ifthenelse - use cond image to choose pels from image in1 or in2 -im_less - in1 less than in2 in value -im_less_vec - in less than doublevec -im_lessconst - in less than const -im_lesseq - in1 less than or equal to in2 in value -im_lesseq_vec - in less than or equal to doublevec -im_lesseqconst - in less than or equal to const -im_more - in1 more than in2 in value -im_more_vec - in more than doublevec -im_moreconst - in more than const -im_moreeq - in1 more than or equal to in2 in value -im_moreeq_vec - in more than or equal to doublevec -im_moreeqconst - in more than or equal to const -im_notequal - two images not equal in value -im_notequal_vec - image does not equal doublevec -im_notequalconst - image does not equal const -\end{verbatim} -\caption{Relational functions} -\label{fg:relational} -\end{fig2} - -\subsection{Boolean} - -See \fref{fg:boolean}. - -The boolean functions perform boolean arithmetic on pairs of -\verb+IM_BANDFMT_UCHAR+ images. They are useful for combining the results of -the relational and morphological functions. You can use -\verb+im_eorconst()+ with 255 as \verb+im_not()+. - -\begin{fig2} -\begin{verbatim} -$ vips list boolean -im_andimage - bitwise and of two images -im_andimageconst - bitwise and of an image with a constant -im_andimage_vec - bitwise and of an image with a vector constant -im_orimage - bitwise or of two images -im_orimageconst - bitwise or of an image with a constant -im_orimage_vec - bitwise or of an image with a vector constant -im_eorimage - bitwise eor of two images -im_eorimageconst - bitwise eor of an image with a constant -im_eorimage_vec - bitwise eor of an image with a vector constant -im_shiftleft - shift integer image n bits to left -im_shiftright - shift integer image n bits to right -\end{verbatim} -\caption{Boolean functions} -\label{fg:boolean} -\end{fig2} - -\subsection{Colour} -\label{sec:colour} - -See \fref{fg:colour}. - -The colour functions can be divided into two main types. First, functions to -transform images between the different colour spaces supported by VIPS: -\verb+RGB+ (also referred to as \verb+disp+), \verb+sRGB+, \verb+XYZ+, -\verb+Yxy+, \verb+Lab+, \verb+LabQ+, \verb+LabS+, \verb+LCh+ and -\verb+UCS+), and second, functions for calculating colour difference -metrics. Figure~\ref{fg:convert} shows how the VIPS colour spaces -interconvert. - -\begin{fig2} -\figw{5in}{interconvert.png} -\caption{VIPS colour space conversion} -\label{fg:convert} -\end{fig2} - -The colour spaces supported by VIPS are: - -\begin{description} - -\item[\texttt{LabQ}] -This is the principal VIPS colorimetric storage format. See the -man page for \verb+im_LabQ2Lab()+ for an explanation. You cannot perform -calculations on \verb+LabQ+ images. They are for storage only. Also refered -to as \verb+LABPACK+. - -\item[\texttt{LabS}] -This format represents coordinates in \cielab{} space as a three- -band \verb+IM_BANDFMT_SHORT+ image, scaled to fit the full range of bits. It is -the best format for computation, being relatively compact, quick, and -accurate. Colour values expressed in this way are hard to visualise. - -\item[\texttt{Lab}] -\verb+Lab+ colourspace represents \cielab{} colour values with a three-band -\verb+IM_BANDFMT_FLOAT+ image. This is the simplest format for general work: adding the -constant 50 to the L channel, for example, has the expected result. - -\item[\texttt{XYZ}] -\ciexyz{} colour space represented as a three-band \verb+IM_BANDFMT_FLOAT+ -image. - -\item[\texttt{XYZ}] -\cieyxy{} colour space represented as a three-band \verb+IM_BANDFMT_FLOAT+ -image. - -\item[\texttt{RGB}] -(also refered to as \verb+disp+) This format is similar to the RGB colour -systems used in other packages. If you want to export your image to a PC, -for example, convert your colorimetric image to \verb+RGB+, then turn it -to TIFF with \verb+im_vips2tiff()+. You need to supply a structure which -characterises your display. See the manual page for \verb+im_col_XYZ2rgb()+ -for hints on these guys. - -VIPS also supports \verb+sRGB+. This is a version of RGB with a carefully -defined and standard conversion from XYZ. See: - -\begin{verbatim} -http://www.color.org/ -\end{verbatim} - -\item[\texttt{LCh}] -Like \verb+Lab+, but rectangular $ab$ coordinates are replaced with polar $Ch$ -(Chroma and hue) coordinates. Hue angles are expressed in degrees. - -\item[\texttt{UCS}] -A colour space based on the CMC(1:1) colour difference measurement. This -is a highly uniform colour space, much better than \cielab{} for expressing -small differences. Conversions to and from \verb+UCS+ are extremely slow. - -\end{description} - -All VIPS colourspaces assume a D65 illuminant. - -The colour-difference functions calculate either $\Delta{}E$ \cielab{} (1976 -or 2000) or $\Delta{}E$ CMC(1:1) on two images in \verb+Lab+, \verb+XYZ+ -or \verb+disp+ colour space. - -\begin{fig2} -\begin{verbatim} -$ vips list colour -im_LCh2Lab - convert LCh to Lab -im_LCh2UCS - convert LCh to UCS -im_Lab2LCh - convert Lab to LCh -im_Lab2LabQ - convert Lab to LabQ -im_Lab2LabS - convert Lab to LabS -im_Lab2UCS - convert Lab to UCS -im_Lab2XYZ - convert D65 Lab to XYZ -im_Lab2XYZ_temp - convert Lab to XYZ, with a specified colour temperature -im_Lab2disp - convert Lab to displayable -im_LabQ2LabS - convert LabQ to LabS -im_LabQ2Lab - convert LabQ to Lab -im_LabQ2XYZ - convert LabQ to XYZ -im_LabQ2disp - convert LabQ to displayable -im_LabS2LabQ - convert LabS to LabQ -im_LabS2Lab - convert LabS to Lab -im_UCS2LCh - convert UCS to LCh -im_UCS2Lab - convert UCS to Lab -im_UCS2XYZ - convert UCS to XYZ -im_XYZ2Lab - convert D65 XYZ to Lab -im_XYZ2Lab_temp - convert XYZ to Lab, with a specified colour temperature -im_XYZ2UCS - convert XYZ to UCS -im_XYZ2Yxy - convert XYZ to Yxy -im_XYZ2disp - convert XYZ to displayble -im_XYZ2sRGB - convert XYZ to sRGB -im_Yxy2XYZ - convert Yxy to XYZ -im_dE00_fromLab - calculate delta-E CIE2000 for two Lab images -im_dECMC_fromLab - calculate delta-E CMC(1:1) for two Lab images -im_dECMC_fromdisp - calculate delta-E CMC(1:1) for two displayable images -im_dE_fromLab - calculate delta-E for two Lab images -im_dE_fromXYZ - calculate delta-E for two XYZ images -im_dE_fromdisp - calculate delta-E for two displayable images -im_disp2Lab - convert displayable to Lab -im_disp2XYZ - convert displayable to XYZ -im_float2rad - convert float to Radiance packed -im_icc_ac2rc - convert LAB from AC to RC using an ICC profile -im_icc_export - convert a float LAB to an 8-bit device image with an ICC profile -im_icc_export_depth - convert a float LAB to device space with an ICC profile -im_icc_import - convert a device image to float LAB with an ICC profile -im_icc_import_embedded - convert a device image to float LAB using the embedded profile -im_icc_present - test for presence of ICC library -im_icc_transform - convert between two device images with a pair of ICC profiles -im_lab_morph - morph colourspace of a LAB image -im_rad2float - convert Radiance packed to float -im_sRGB2XYZ - convert sRGB to XYZ -\end{verbatim} -\caption{Colour functions} -\label{fg:colour} -\end{fig2} - -\subsection{Conversion} - -See \fref{fg:conversion}. - -These functions may be split into three broad groups: functions which convert -between the VIPS numeric formats (\verb+im_clip2fmt()+, for example, converts -an image of any type to the specified \verb+IM_BANDFMT+), functions -supporting complex arithmetic (\verb+im_c2amph()+, for example, converts -a complex image from rectangular to polar co ordinates) and functions -which perform some simple geometric conversion (\verb+im_extract()+ forms -a sub-image). - -\verb+gbandjoin+ and the C function \verb+im_gbandjoin()+ will do a bandwise -join of many images at the same time. See the manual pages. - -\begin{fig2} -\begin{verbatim} -$ vips list conversion -im_bandjoin - bandwise join of two images -im_bernd - extract from pyramid as jpeg -im_black - generate black image -im_c2amph - convert real and imaginary to phase and amplitude -im_c2imag - extract imaginary part of complex image -im_c2ps - find power spectrum of complex image -im_c2real - extract real part of complex image -im_c2rect - convert phase and amplitude to real and imaginary -im_clip2c - convert to signed 8-bit integer -im_clip2cm - convert to complex -im_clip2d - convert to double-precision float -im_clip2dcm - convert to double complex -im_clip2f - convert to single-precision float -im_clip2fmt - convert image format to ofmt -im_clip2i - convert to signed 32-bit integer -im_clip2s - convert to signed 16-bit integer -im_clip2ui - convert to unsigned 32-bit integer -im_clip2us - convert to unsigned 16-bit integer -im_clip - convert to unsigned 8-bit integer -im_copy - copy image -im_copy_morph - copy image, setting pixel layout -im_copy_swap - copy image, swapping byte order -im_copy_set - copy image, setting informational fields -im_copy_set_meta - copy image, setting a meta field -im_extract_area - extract area -im_extract_areabands - extract area and bands -im_extract_band - extract band -im_extract_bands - extract several bands -im_extract - extract area/band -im_falsecolour - turn luminance changes into chrominance changes -im_fliphor - flip image left-right -im_flipver - flip image top-bottom -im_gbandjoin - bandwise join of many images -im_grid - chop a tall thin image into a grid of images -im_insert - insert sub-image into main image at position -im_insert_noexpand - insert sub-image into main image at position, no expansion -im_lrjoin - join two images left-right -im_mask2vips - convert DOUBLEMASK to VIPS image -im_msb - convert to uchar by discarding bits -im_msb_band - convert to single band uchar by discarding bits -im_print - print string to stdout -im_recomb - linear recombination with mask -im_replicate - replicate an image horizontally and vertically -im_ri2c - join two non-complex images to form complex -\end{verbatim} -\caption{Conversion functions} -\label{fg:conversion} -\end{fig2} - -\begin{fig2} -\begin{verbatim} -im_rot180 - rotate image 180 degrees -im_rot270 - rotate image 270 degrees clockwise -im_rot90 - rotate image 90 degrees clockwise -im_scale - scale image linearly to fit range 0-255 -im_scaleps - logarithmic scale of image to fit range 0-255 -im_rightshift_size - decrease size by a power-of-two factor -im_slice - slice an image using two thresholds -im_subsample - subsample image by integer factors -im_system - run command on image -im_tbjoin - join two images top-bottom -im_text - generate text image -im_thresh - slice an image at a threshold -im_vips2mask - convert VIPS image to DOUBLEMASK -im_wrap - shift image origin, wrapping at sides -im_zoom - simple zoom of an image by integer factors -\end{verbatim} -\caption{Conversion functions (cont.)} -\end{fig2} - -\subsection{Matricies} - -See \fref{fg:matricies}. - -VIPS uses matricies for morphological operations, for convolutions, and -for some colour-space conversions. There are two types of matrix: integer -(\verb+INTMASK+) and double precision floating point (\verb+DOUBLEMASK+). - -For convenience, both types are stored in files as ASCII. The first -line of the file should start with the matrix dimensions, width first, -then on the same line an optional scale and offset. The two size fields -should be integers; the scale and offset may be floats. Subsequent lines -should contain the matrix elements, one row per line. The scale and -offset are the conventional ones used to represent non-integer values in -convolution masks --- in other words: - -\[ -result = {value \over scale} + offset -\] - -If the scale and offset are missing, they default to 1.0 and 0.0. See the -sections on convolution for more on the use of these fields. So as an example, -a 4 by 4 identity matrix would be stored as: - -\begin{verbatim} -4 4 -1 0 0 0 -0 1 0 0 -0 0 1 0 -0 0 0 1 -\end{verbatim} - -And a 3 by 3 mask for block averaging with convolution might be stored as: - -\begin{verbatim} -3 3 9 0 -1 1 1 -1 1 1 -1 1 1 -\end{verbatim} - -\noindent -(in other words, sum all the pels in every 3 by 3 area, and divide by 9). - -This matrix contains only integer elements and so could be used as an -argument to functions expecting both \verb+INTMASK+ and \verb+DOUBLEMASK+ -matricies. However, masks containing floating-point values (such as the -output of \verb+im_matinv()+) can only be used as arguments to functions -expecting \verb+DOUBLEMASK+s. - -A set of functions for mask input and output are also available for -C-programmers --- see the manual pages for \verb+im_read_dmask()+. For -other matrix functions, see also the convolution sections and the arithmetic -sections. - -\begin{fig2} -\begin{verbatim} -$ vips list matrix -im_matcat - append matrix in2 to the end of matrix in1 -im_matinv - invert matrix -im_matmul - multiply matrix in1 by matrix in2 -im_mattrn - transpose matrix -\end{verbatim} -\caption{Matrix functions} -\label{fg:matricies} -\end{fig2} - -\subsection{Convolution} - -See \fref{fg:convolution}. - -The functions available in the convolution package can be split into five -main groups. - -First, are the convolution functions. The most useful function is -\verb+im_conv()+ which will convolve any non-complex type with an -\verb+INTMASK+ matrix. The output image will have the same size, type, and -number of bands as the input image. Of the other \verb+im_conv()+ functions, -functions whose name ends in \verb+_raw+ do not add a black border around the -output image, functions ending in \verb+f+ use a \verb+DOUBLEMASK+ matrix -and write float (or double) output, and functions containing \verb+sep+ -are for seperable convolutions. \verb+im_compass()+, \verb+im_lindetect()+ -and \verb+im_gradient()+ convolve with rotating masks. \verb+im_embed()+ -is used by the convolution functions to add the border to the output. - -Next, are the build functions. \verb+im_gauss_*mask()+ and its ilk -generate gaussian masks, \verb+im_log_*mask()+ generate logs of Laplacians. -\verb+im_addgnoise()+ and \verb+im_gaussnoise()+ create or add gaussian -noise to an image. - -Two functions do correlation: \verb+im_fastcor()+ does a quick and dirty -correlation, \verb+im_spcor()+ calculates true spatial correlation, and is -rather slow. - -Some functions are provided for analysing images: \verb+im_zerox()+ counts -zero-crossing points in an image, \verb+im_mpercent()+ finds a threshold -that will isolate a percentage of points in an image. - -Finally, \verb+im_resize_linear()+ and \verb+im_shrink()+ do as you would -expect. - -\begin{fig2} -\begin{verbatim} -$ vips list convolution -im_addgnoise - add gaussian noise with mean 0 and std. dev. sigma -im_compass - convolve with 8-way rotating integer mask -im_contrast_surface - find high-contrast points in an image -im_contrast_surface_raw - find high-contrast points in an image -im_conv - convolve -im_conv_raw - convolve, no border -im_convf - convolve, with DOUBLEMASK -im_convf_raw - convolve, with DOUBLEMASK, no border -im_convsep - seperable convolution -im_convsep_raw - seperable convolution, no border -im_convsepf - seperable convolution, with DOUBLEMASK -im_convsepf_raw - seperable convolution, with DOUBLEMASK, no border -im_convsub - convolve uchar to uchar, sub-sampling by xskip, yskip -im_dmask_xsize - horizontal size of a doublemask -im_dmask_ysize - vertical size of a doublemask -im_embed - embed in within a set of borders -im_fastcor - fast correlate in2 within in1 -im_fastcor_raw - fast correlate in2 within in1, no border -im_gauss_dmask - generate gaussian DOUBLEMASK -im_gauss_imask - generate gaussian INTMASK -im_gauss_imask_sep - generate separable gaussian INTMASK -im_gaussnoise - generate image of gaussian noise with specified statistics -im_grad_x - horizontal difference image -im_grad_y - vertical difference image -im_gradcor - non-normalised correlation of gradient of in2 within in1 -im_gradcor_raw - non-normalised correlation of gradient of in2 within in1, no padding -im_gradient - convolve with 2-way rotating mask -im_imask_xsize - horizontal size of an intmask -im_imask_ysize - vertical size of an intmask -im_rank_image - point-wise pixel rank -im_lindetect - convolve with 4-way rotating mask -im_log_dmask - generate laplacian of gaussian DOUBLEMASK -im_log_imask - generate laplacian of gaussian INTMASK -im_maxvalue - point-wise maximum value -im_mpercent - find threshold above which there are percent values -im_phasecor_fft - non-normalised correlation of gradient of in2 within in1 -im_rank - rank filter nth element of xsize/ysize window -im_rank_raw - rank filter nth element of xsize/ysize window, no border -im_read_dmask - read matrix of double from file -im_resize_linear - resize to X by Y pixels with linear interpolation -im_rotate_dmask45 - rotate DOUBLEMASK clockwise by 45 degrees -im_rotate_dmask90 - rotate DOUBLEMASK clockwise by 90 degrees -im_rotate_imask45 - rotate INTMASK clockwise by 45 degrees -im_rotate_imask90 - rotate INTMASK clockwise by 90 degrees -im_sharpen - sharpen high frequencies of L channel of LabQ -im_shrink - shrink image by xfac, yfac times -im_spcor - normalised correlation of in2 within in1 -im_spcor_raw - normalised correlation of in2 within in1, no black padding -im_stretch3 - stretch 3%, sub-pixel displace by xdisp/ydisp -im_zerox - find +ve or -ve zero crossings in image -\end{verbatim} -\caption{Convolution functions} -\label{fg:convolution} -\end{fig2} - -\subsection{In-place operations} -\label{sec:inplace} - -See \fref{fg:inplace}. - -A few of the in-place operations are available from the command-line. Most are -not. - -\begin{fig2} -\begin{verbatim} -$ vips list inplace -im_circle - plot circle on image -im_flood_blob_copy - flood while pixel == start pixel -im_insertplace - draw image sub inside image main at position (x,y) -im_line - draw line between points (x1,y1) and (x2,y2) -im_lineset - draw line between points (x1,y1) and (x2,y2) -\end{verbatim} -\caption{In-place operations} -\label{fg:inplace} -\end{fig2} - -\subsection{Frequency filtering} - -See \fref{fg:freq}. - -The basic Fourier functions are \verb+im_fwfft()+ and -\verb+im_invfft()+, which calculate the fast-fourier transform and inverse -transform of an image. Also \verb+im_invfftr()+, which just returns the real -part of the inverse transform. -The Fourier image has its origin at pel (0,0) --- -for viewing, use \verb+im_rotquad()+ to move the origin to the centre of -the image. - -Once an image is in the frequency domain, it can be filtered by multiplying -it with a mask image. The VIPS mask generator is \verb+im_create_fmask()+ -see the manual page for details of the arguments, but it will create low -pass, high pass, ring pass and band pass filters, which may each be ideal, -Gaussian or Butterworth. There is also a fractal mask option. - -The other functions in the package build on these base -facilities. \verb+im_freqflt()+ transforms an input image to -Fourier space, multiplies it by a mask image, and transforms it back -again. \verb+im_flt_image_freq()+ will create a mask image of the correct -size for you, and call \verb+im_freqflt()+. \verb+im_disp_ps()+ will call -the right combinations of functions to make a displayable power spectrum -for an image. - -\begin{fig2} -\begin{verbatim} -$ vips list freq_filt -im_create_fmask - create frequency domain filter mask -im_disp_ps - make displayable power spectrum -im_flt_image_freq - frequency domain filter image -im_fractsurf - generate a fractal surface of given dimension -im_freqflt - frequency-domain filter of in with mask -im_fwfft - forward fast-fourier transform -im_rotquad - rotate image quadrants to move origin to centre -im_invfft - inverse fast-fourier transform -im_invfftr - real part of inverse fast-fourier transform -\end{verbatim} -\caption{Fourier functions} -\label{fg:freq} -\end{fig2} - -\subsection{Histograms and LUTs} - -See \fref{fg:hist}. - -VIPS represents histograms and look-up tables in the same way --- as images. - -They should have either \verb+Xsize+ or \verb+Ysize+ set to 1, and the -other dimension set to the number of elements in the table. The table can be -of any size, have any band format, and have any number of bands. - -Use \verb+im_histgr()+ to find the histogram of an image. Use -\verb+im_histnD()+ to find the n-dimensional histogram of an n-band -image. Perform operations on histograms with \verb+im_histcum()+, -\verb+im_histnorm()+, \verb+im_histspec()+, \verb+im_invertlut()+. Visualise -histograms with \verb+im_histplot()+. Use a histogram (or LUT) to transform -an image with \verb+im_maplut()+. Build a histogram from scratch with -\verb+im_identity()+ or \verb+im_identity_ushort()+. - -Use \verb+im_lhist*()+ for local histogram equalisation, and -\verb+im_stdif*()+ for statisticaol differencing. The \verb+im_tone_*()+ -functions are for operations on the L channel of a LAB image. Other -functions are useful combinations of these basic operations. - -\begin{fig2} -\begin{verbatim} -$ vips list histograms_lut -im_gammacorrect - gamma-correct image -im_heq - histogram-equalise image -im_hist - find and graph histogram of image -im_histcum - turn histogram to cumulative histogram -im_histeq - form histogram equalistion LUT -im_histgr - find histogram of image -im_histnD - find 1D, 2D or 3D histogram of image -im_histnorm - form normalised histogram -im_histplot - plot graph of histogram -im_histspec - find histogram which will make pdf of in match ref -im_hsp - match stats of in to stats of ref -im_identity - generate identity histogram -im_identity_ushort - generate ushort identity histogram -im_ismonotonic - test LUT for monotonicity -im_lhisteq - local histogram equalisation -im_lhisteq_raw - local histogram equalisation, no border -im_invertlut - generate correction table from set of measures -im_buildlut - generate LUT table from set of x/y positions -im_maplut - map image through LUT -im_project - find horizontal and vertical projections of an image -im_stdif - statistical differencing -im_stdif_raw - statistical differencing, no border -im_tone_analyse - analyse in and create LUT for tone adjustment -im_tone_build - create LUT for tone adjustment of LabS images -im_tone_build_range - create LUT for tone adjustment -im_tone_map - map L channel of LabS or LabQ image through LUT -\end{verbatim} -\caption{Histogram/LUT functions} -\label{fg:hist} -\end{fig2} - -\subsection{Morphology} - -See \fref{fg:morph}. - -The morphological functions are used on one-band \verb+IM_BANDFMT_UCHAR+ binary -images (images containing only zero and not-zero). They search images -for particular patterns of pixels (specified with the mask argument), -either adding or removing pixels when they find a match. They are useful -for cleaning up images --- for example, you might threshold an image, and -then use one of the morphological functions to remove all single isolated -pixels from the result. - -If you combine the morphological operators with the mask rotators -(\verb+im_rotate_imask45()+, for example) and apply them repeatedly, you -can achieve very complicated effects: you can thin, prune, fill, open edges, -close gaps, and many others. For example, see `Fundamentals of Digital -Image Processing' by A. Jain, pp 384-388, Prentice-Hall, 1989 for more ideas. - -Beware that VIPS reverses the usual image processing convention, by assuming -white objects on a black background. - -The mask you give to the morphological functions should contain only the -values 0 (for background), 128 (for don't care) and 255 (for object). The -mask must have odd length sides --- the origin of the mask is taken to be -the centre value. For example, the mask: - -\begin{verbatim} -3 3 -128 255 128 -255 0 255 -128 255 128 -\end{verbatim} - -\noindent -applied to an image with \verb+im_erode()+, will find all black pixels -4-way connected with white pixels. Essentially, \verb+im_dilate()+ -sets pixels in the output if any part of the mask matches, whereas -\verb+im_erode()+ sets pixels only if all of the mask matches. - -The \verb+_raw()+ version of the functions do not add a black border to the -output. \verb+im_cntlines()+ and \verb+im_profile+ are occasionally useful for -analysing results. - -See the boolean operations \verb+im_and()+, \verb+im_or()+ and -\verb+im_eor()+ for analogues of the usual set difference and set -union operations. - -\begin{fig2} -\begin{verbatim} -$ vips list morphology -im_cntlines - count horizontal or vertical lines -im_dilate - dilate image with mask, adding a black border -im_dilate_raw - dilate image with mask -im_erode - erode image with mask, adding a black border -im_erode_raw - erode image with mask -im_profile - find first horizontal/vertical edge -\end{verbatim} -\caption{Morphological functions} -\label{fg:morph} -\end{fig2} - -\subsection{Mosaicing} - -See \fref{fg:mosaicing}. - -These functions are useful for joining many small images together to make one -large image. They can cope with unstable contrast, and arbitary sub-image -layout, but will not do any geometric correction. The mosaicing functions -can be grouped into layers: - -The lowest level functions are \verb+im_correl()+. and \verb+im_affine()+. -\verb+im_correl()+ searches a large image for a small sub-image, returning -the position of the best sub-image match. \verb+im_affine()+ performs -a general affine transform on an image: that is, any transform in which -parallel lines remain parallel. - -Next, \verb+im_lrmerge()+ and \verb+im_tbmerge()+ blend two images together -left-right or up-down. - -Next up are \verb+im_lrmosaic()+ and \verb+im_tbmosaic()+. These use the -two low-level merge operations to join two images given just an approximate -overlap as a start point. Optional extra parameters let you do 'balancing' -too: if your images have come from a source where there is no precise -control over the exposure (for example, images from a tube camera, or a -set of images scanned from photographic sources), \verb+im_lrmosaic()+ -and \verb+im_tbmosaic()+ will adjust the contrast of the left image to -match the right, the right to the left, or both to some middle value. - -The functions \verb+im_lrmosaic1()+ and \verb+im_tbmosaic1()+ are first-order -analogues of the basic mosaic functions: they take two tie-points and use -them to rotate and scale the right-hand or bottom image before starting to join. - -Finally, \verb+im_global_balance()+ can be used to re-balance a mosaic -which has been assembled with these functions. It will generally do a -better job than the low-level balancer built into \verb+im_lrmosaic()+ -and \verb+im_tbmosaic()+. See the man page. \verb+im_remosaic()+ uses the same -techniques, but will reassemble the image from a different set of source -images. - -\begin{fig2} -\begin{verbatim} -$ vips list mosaicing -im_align_bands - align the bands of an image -im_correl - search area around sec for match for area around ref -im__find_lroverlap - search for left-right overlap of ref and sec -im__find_tboverlap - search for top-bottom overlap of ref and sec -im_global_balance - automatically rebuild mosaic with balancing -im_global_balancef - automatically rebuild mosaic with balancing, float output -im_lrmerge - left-right merge of in1 and in2 -im_lrmerge1 - first-order left-right merge of ref and sec -im_lrmosaic - left-right mosaic of ref and sec -im_lrmosaic1 - first-order left-right mosaic of ref and sec -im_match_linear - resample ref so that tie-points match -im_match_linear_search - search sec, then resample so that tie-points match -im_maxpos_subpel - subpixel position of maximum of (phase correlation) image -im_remosaic - automatically rebuild mosaic with new files -im_tbmerge - top-bottom merge of in1 and in2 -im_tbmerge1 - first-order top-bottom merge of in1 and in2 -im_tbmosaic - top-bottom mosaic of in1 and in2 -im_tbmosaic1 - first-order top-bottom mosaic of ref and sec -\end{verbatim} -caption{Mosaic functions} -\label{fg:mosaicing} -\end{fig2} - -\subsection{CImg functions} - -See \fref{fg:cimg}. - -These operations wrap the anisotropic blur function from the CImg library. -They are useful for removing noise from images. - -\begin{fig2} -\begin{verbatim} -$ vips list cimg -im_greyc - noise-removing filter -im_greyc_mask - noise-removing filter, with a mask -\end{verbatim} -\caption{CImg functions} -\label{fg:cimg} -\end{fig2} - -\subsection{Other} - -See \fref{fg:other}. - -These functions generate various test images. You can combine them with -the arithmetic and rotate functions to build more complicated images. - -The \verb+im_benchmark*()+ operations are for testing the VIPS SMP system. - -\begin{fig2} -\begin{verbatim} -$ vips list other -im_benchmark - do something complicated for testing -im_benchmark2 - do something complicated for testing -im_benchmarkn - do something complicated for testing -im_eye - generate IM_BANDFMT_UCHAR [0,255] frequency/amplitude image -im_grey - generate IM_BANDFMT_UCHAR [0,255] grey scale image -im_feye - generate IM_BANDFMT_FLOAT [-1,1] frequency/amplitude image -im_fgrey - generate IM_BANDFMT_FLOAT [0,1] grey scale image -im_fzone - generate IM_BANDFMT_FLOAT [-1,1] zone plate image -im_make_xy - generate image with pixel value equal to coordinate -im_zone - generate IM_BANDFMT_UCHAR [0,255] zone plate image -\end{verbatim} -\caption{Other functions} -\label{fg:other} -\end{fig2} - -\subsection{IO functions} - -See \fref{fg:io}. - -These functions are related to the image IO system. - -\begin{fig2} -\begin{verbatim} -$ vips list iofuncs -im_binfile - open a headerless binary file -im_cache - cache results of an operation -im_guess_prefix - guess install area -im_guess_libdir - guess library area -im_header_get_type - return field type -im_header_int - extract int fields from header -im_header_double - extract double fields from header -im_header_string - extract string fields from header -im_version - VIPS version number -im_version_string - VIPS version string -\end{verbatim} -\caption{IO functions} -\label{fg:io} -\end{fig2} - -\subsection{Format functions} - -See \fref{fg:format}. - -These functions convert to and from various image formats. See -\pref{sec:format} for a nice API over these. VIPS can read more than these -formats, see the man page for \verb+VipsFormat+. - -\begin{fig2} -\begin{verbatim} -$ vips list format -im_csv2vips - read a file in csv format -im_jpeg2vips - convert from jpeg -im_magick2vips - load file with libMagick -im_png2vips - convert PNG file to VIPS image -im_exr2vips - convert an OpenEXR file to VIPS -im_ppm2vips - read a file in pbm/pgm/ppm format -im_analyze2vips - read a file in analyze format -im_tiff2vips - convert TIFF file to VIPS image -im_vips2csv - write an image in csv format -im_vips2jpeg - convert to jpeg -im_vips2mimejpeg - convert to jpeg as mime type on stdout -im_vips2png - convert VIPS image to PNG file -im_vips2ppm - write a file in pbm/pgm/ppm format -im_vips2tiff - convert VIPS image to TIFF file -\end{verbatim} -\caption{Format functions} -\label{fg:format} -\end{fig2} - -\subsection{Resample functions} - -See \fref{fg:resample}. - -These functions resample images with various interpolators. - -\begin{fig2} -\begin{verbatim} -$ vips list resample -im_affine - affine transform -im_affinei - affine transform -im_affinei_all - affine transform of whole image -im_similarity_area - output area xywh of similarity transformation -im_similarity - similarity transformation -\end{verbatim} -\caption{Resample functions} -\label{fg:resample} -\end{fig2} diff --git a/doc/src/pio.tex b/doc/src/pio.tex deleted file mode 100644 index f2e45e01..00000000 --- a/doc/src/pio.tex +++ /dev/null @@ -1,854 +0,0 @@ -\section{Programming PIO functions} -\label{sec:pio} - -The VIPS PIO system has a number of advantages over WIO, as summarised in -the introduction. On the other hand, they are a bit more complicated. - -\subsection{Easy PIO with \texttt{im\_wrapone()} and \texttt{im\_wrapmany()}} -\label{sec:wrapone} - -PIO is a very general image IO system, and because of this flexibility, -can be complicated to program. As a convenience, VIPS offers an easy-to-use -layer over PIO with the funtions \verb+im_wrapone()+ and \verb+im_wrapmany()+. - -If your image processing function is uninterested in coordinates, that is, -if your input and output images are the same size, and each output pixel -depends only upon the value of the corresponding pixel in the input image -or images, then these functions are for you. - -Consider the \verb+invert()+ function of figure~\ref{fg:invert}. First, -we have to write the core of this as a buffer-processing function: - -\begin{verbatim} -#include -#include - -#include - -/* p points to a buffer of pixels which - * need inverting, q points to the buffer - * we should write the result to, and n - * is the number of pels present. - */ -static void -invert_buffer( unsigned char *p, - unsigned char *q, int n ) -{ - int i; - - for( i = 0; i < n; i++ ) - q[i] = 255 - p[i]; -} -\end{verbatim} - -Now we have to wrap up this very primitive expression of the invert operation -as a PIO function. We use \verb+im_wrapone()+ to do this. It has type: - -\begin{verbatim} -int -im_wrapone( IMAGE *in, IMAGE *out, - im_wrapone_fn fn, void *a, void *b ) -\end{verbatim} - -\noindent -where: - -\begin{verbatim} -void -(*im_wrapone_fn)(void *in, void *out, - int n, void *a, void *b ) -\end{verbatim} - -\noindent -almost the same type as our buffer-processing function above. The values -\verb+a+ and \verb+b+ are carried around by VIPS for whatever use you -fancy. \verb+invert()+ can now be written as: - -\begin{verbatim} -int -invert( IMAGE *in, IMAGE *out ) -{ - /* Check parameters. - */ - if( in->BandFmt != IM_BANDFMT_UCHAR || - in->Bands != 1 || - in->Coding != IM_CODING_NONE ) { - im_error( "invert", "bad image" ); - return( -1 ); - } - - /* Set fields in output image. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - - /* Process! We don't use either of the - * user parameters in this function, - * so leave them as NULL. - */ - if( im_wrapone( in, out, - (im_wrapone_fn) invert_buffer, - NULL, NULL ) ) - return( -1 ); - - return( 0 ); -} -\end{verbatim} - -And that's all there is to it. This function will have all of the desirable -properties of PIO functions, while being as easy to program as the WIO -\verb+invert()+ earlier in this chapter. - -This version of \verb+invert()+ is not very general: it will only accept -one-band unsigned char images. It is easy to modify for n-band images: - -\begin{verbatim} -/* As before, but use one of the user - * parameters to pass in the number of - * bands in the image. - */ -static void -invert_buffer( unsigned char *p, - unsigned char *q, int n, - IMAGE *in ) -{ - int i; - int sz = n * in->Bands; - - for( i = 0; i < sz; i++ ) - q[i] = 255 - p[i]; -} -\end{verbatim} - -We must also modify \verb+invert()+: - -\begin{verbatim} -int -invert( IMAGE *in, IMAGE *out ) -{ - /* Check parameters. - */ - if( in->BandFmt != IM_BANDFMT_UCHAR || - in->Coding != IM_CODING_NONE ) { - im_error( "invert", "bad image" ); - return( -1 ); - } - - /* Set fields in output image. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - - /* Process! The first user-parameter - * is the number of bands involved. - */ - if( im_wrapone( in, out, - (im_wrapone_fn)invert_buffer, - in, NULL ) ) - return( -1 ); - - return( 0 ); -} -\end{verbatim} - -There are two significant hidden traps here. First, inside the buffer -processing functions, you may only read the contents of the user parameters -\verb+a+ and \verb+b+, you may not write to them. This is because on a -multi-CPU machine, several copies of your buffer-processing functions will -be run in parallel --- if they all write to the same place, there will be -complete confusion. If you need writeable parameters (for example, to count -and report overflows), you can't use \verb+im_wrapone()+, you'll have to -use the PIO system in all its gory detail, see below. - -Secondly, your buffer processing function may not be called immediately. VIPS -may decide to delay evaluation of your operation until long after the call -to \verb+invert()+ has returned. As a result, care is needed to ensure -that you never read anything in your buffer-processing function that may -have been freed. The best way to ensure this is to use the local resource -allocators, such as \verb+im_open_local()+ and \verb+im_malloc()+. This issue -is discussed at length in the sections below, and in \pref{sec:appl}. - -\verb+im_wrapone()+ is for operations which take exactly one input image. VIPS -provides a second function, \verb+im_wrapmany()+, which works for any number -of input images. The type of \verb+im_wrapmany()+ is slightly different: - -\begin{verbatim} -int -im_wrapmany( IMAGE **in, IMAGE *out, - im_wrapmany_fn fn, void *a, void *b ) -\end{verbatim} - -\noindent - -\begin{verbatim} -void -(*im_wrapmany_fn)( void **in, void *out, - int n, void *a, void *b ) -\end{verbatim} - -\noindent -\verb+im_wrapmany()+ takes a \verb+NULL+-terminated array of input images, -and creates a \verb+NULL+-terminated array of buffers for the use of your -buffer processing function. A function to add two \verb+IM_BANDFMT_UCHAR+ -images to make a \verb+IM_BANDFMT_UCHAR+ image might be written as: - -\begin{verbatim} -static void -add_buffer( unsigned char **in, - unsigned short *out, int n, - IMAGE *in ) -{ - int i; - int sz = n * in->Bands; - unsigned char *p1 = in[0]; - unsigned char *p2 = in[1]; - - for( i = 0; i < sz; i++ ) - out[i] = p1[i] + p2[i]; -} -\end{verbatim} - -This can be made into a PIO function with: - -\begin{verbatim} -int -add_uchar( IMAGE *i1, IMAGE *i2, - IMAGE *out ) -{ - IMAGE *invec[3]; - - /* Check parameters. We don't need to - * check that i1 and i2 are the same - * size, im_wrapmany() does that for - * us. - */ - if( i1->BandFmt != IM_BANDFMT_UCHAR || - i1->Coding != IM_CODING_NONE || - i2->BandFmt != IM_BANDFMT_UCHAR || - i2->Coding != IM_CODING_NONE || - i1->Bands != i2->Bands ) { - im_error( "add_uchar", "bad in" ); - return( -1 ); - } - - /* Set fields in output image. As - * input image, but we want a USHORT. - */ - if( im_cp_desc( out, i1 ) ) - return( -1 ); - out->BandFmt = IM_BANDFMT_USHORT; - out->Bbits = IM_BBITS_SHORT; - - /* Process! The first user-parameter - * is the number of bands involved. - * invec is a NULL-terminated array of - * input images. - */ - invec[0] = i1; invec[1] = i2; - invec[2] = NULL; - if( im_wrapmany( invec, out, - (im_wrapone_fn)add_buffer, - i1, NULL ) ) - return( -1 ); - - return( 0 ); -} -\end{verbatim} - -\subsection{Region descriptors} - -Regions are the next layer of abstraction above image descriptors. A region -is a small part of an image, held in memory ready for processing. A region -is defined as: - -\begin{verbatim} -typedef struct { - Rect valid; - IMAGE *im; - - ... and some other private fields, - ... used by VIPS for housekeeping -} REGION; -\end{verbatim} - -\noindent -where \verb+valid+ holds the sub-area of image \verb+im+ that this region -represents, and \verb+Rect+ is defined as: - -\begin{verbatim} -typedef struct { - int left, top; - int width, height; -} Rect; -\end{verbatim} - -\noindent -two macros are available for \verb+Rect+ calculations: - -\begin{verbatim} -int IM_RECT_RIGHT( Rect *r ) -int IM_RECT_BOTTOM( Rect *r ) -\end{verbatim} - -\noindent -where \verb+IM_RECT_RIGHT()+ returns \verb+left+ + \verb+width+, and -\verb+IM_RECT_BOTTOM()+ returns \verb+top+ + \verb+height+. A small library -of C functions are also available for \verb+Rect+ algebra, see the manual -pages for \verb+im_rect_intersectrect()+. - -Regions are created with \verb+im_region_create()+. This has type: - -\begin{verbatim} -REGION *im_region_create( IMAGE *im ) -\end{verbatim} - -\noindent -\verb+im_region_create()+ returns a pointer to a new region structure, -or \verb+NULL+ on error. Regions returned by \verb+im_region_create()+ -are blank --- they contain no image data and cannot be read from or written -to. See the next couple of sections for calls to fill regions with data. - -Regions are destroyed with \verb+im_region_free()+. It has type: - -\begin{verbatim} -int im_region_free( REGION *reg ) -\end{verbatim} - -\noindent -And, as usual, returns 0 on success and non-zero on error, setting -\verb+im_error()+. You must free all regions you create. If you close -an image without freeing all the regions defined on that image, the image is -just marked for future closure --- it is not actually closed until the final -region is freed. This behaviour helps to prevent dangling pointers, and it -is not difficult to make sure you free all regions --- see the examples below. - -\subsection{Image input with regions} - -Before you can read from a region, you need to call \verb+im_prepare()+ -to fill the region with image data. It has type: - -\begin{verbatim} -int im_prepare( REGION *reg, Rect *r ) -\end{verbatim} - -Area \verb+r+ of the image on which \verb+reg+ has been created is prepared -and attached to the region. - -Exactly what this preparation involves depends upon the image --- it can -vary from simply adjusting some pointers, to triggering the evaluation of a -series of other functions. If it returns successfully, \verb+im_prepare()+ -guarantees that all pixels within \verb+reg->valid+ may be accessed. Note -that this may be smaller or larger than \verb+r+, since \verb+im_prepare()+ -clips \verb+r+ against the size of the image. - -Programs can access image data in the region by calling the macro -\verb+IM_REGION_ADDR()+. It has type - -\begin{verbatim} -char *IM_REGION_ADDR( REGION *reg, - int x, int y ) -\end{verbatim} - -Provided that point (x,y) lies inside \verb+reg->valid+, -\verb+IM_REGION_ADDR()+ returns a pointer to pel $(x,y)$. Adding to the result -of \verb+IM_REGION_ADDR()+ moves to the right along the line of pels, provided -you stay strictly within \verb+reg->valid+. Add \verb+IM_REGION_LSKIP()+ -to move down a line, see below. \verb+IM_REGION_ADDR()+ has some other -useful features --- see the manual page. - -Other macros are available to ease address calculation: - -\begin{verbatim} -int IM_REGION_LSKIP( REGION *reg ) -int IM_REGION_N_ELEMENTS( REGION *reg ) -int IM_REGION_SIZEOF_LINE( REGION *reg ) -\end{verbatim} - -\noindent -These find the number of bytes to add to the result of \verb+IM_REGION_ADDR()+ -to move down a line, the number of band elements across the region and the -number of bytes across the region. - -\fref{fg:paverage} is a version of \verb+average()+ which uses -regions rather than WIO input. Two things: first, we should really be -using \verb+vips_sink()+, see \pref{sec:sequence}, to do the rectangle -algebra for us. Secondly, note that we call \verb+im_pincheck()+ rather -than \verb+im_incheck()+. \verb+im_pincheck()+ signals to the IO system -that you are a PIO-aware function, giving \verb+im_prepare()+ much more -flexibility in the sorts of preparation it can do. Also see the manual -pages for \verb+im_poutcheck()+ and \verb+im_piocheck()+. - -\begin{fig2} -\begin{verbatim} -#include -#include -#include -#include - -int -average( IMAGE *im, double *out ) -{ - int total, i, y; - REGION *reg; - Rect area, *r; - - /* Check im. - */ - if( im_pincheck( im ) ) - return( -1 ); - if( im->BandFmt != IM_BANDFMT_UCHAR || im->Coding != IM_CODING_NONE ) { - im_error( "average", "uncoded uchar images only" ); - return( -1 ); - } - - /* Make a region on im which we can use for reading. - */ - if( !(reg = im_region_create( im )) ) - return( -1 ); -\end{verbatim} -\caption{First PIO average of image} -\label{fg:paverage} -\end{fig2} - -\begin{fig2} -\begin{verbatim} - /* Move area over the image in 100x100 pel chunks. - * im_prepare() will clip against the edges of the image - * for us. - */ - total = 0; - r = ®->valid; - area.width = 100; area.height = 100; - for( area.top = 0; area.top < im->Ysize; area.top += 100 ) - for( area.left = 0; area.left < im->Xsize; - area.left += 100 ) { - /* Fill reg with pels. - */ - if( im_prepare( reg, &area ) ) { - /* We must free the region! - */ - im_region_free( reg ); - return( -1 ); - } - - /* Loop over reg, adding to our total. - */ - for( y = r->top; y < IM_RECT_BOTTOM( r ); y++ ) { - unsigned char *p = IM_REGION_ADDR( reg, r->left, y ); - - for( i = 0; i < IM_REGION_N_ELEMENTS( reg ); i++ ) - total += p[i]; - } - } - - /* Make sure we free the region. - */ - im_region_free( reg ); - - /* Find average. - */ - *out = (double) total / (IM_IMAGE_N_ELEMENTS( im ) * im->Ysize); - - return( 0 ); -} -\end{verbatim} -\caption{First PIO average of image (cont.)} -\end{fig2} - -This version of \verb+average()+ can be called in exactly the same way as -the previous one, but this version has the great advantage of not needing -to have the whole of the input image available at once. - -We can do one better than this --- if the image is being split into small -pieces, we can assign each piece to a separate thread of execution and get -parallelism. To support this splitting of tasks, VIPS has the notion of -a sequence. - -\subsection{Splitting into sequences} -\label{sec:sequence} - -A sequence comes in three parts: a start function, a processing function, -and a stop function. When VIPS starts up a new sequence, it runs the -start function. Start functions return sequence values: a void pointer -representing data local to this sequence. VIPS then repeatedly calls the -processing function, passing in the sequence value and a new piece of image -data for processing. Finally, when processing is complete, VIPS cleans up by -calling the stop function, passing in the sequence value as an argument. The -types look like this: - -\begin{verbatim} -void * -(*start_fn)( IMAGE *out, - void *a, void *b ) -int -(*process_fn)( REGION *reg, - void *seq, void *a, void *b ) -int -(*stop_fn)( void *seq, void *a, void *b ) -\end{verbatim} - -\noindent -The values \verb+a+ and \verb+b+ are carried around by VIPS for your use. - -For functions like \verb+average()+ which consume images but produce no image -output, VIPS provides \verb+vips_sink()+. This has type: - -\begin{verbatim} -int vips_sink( VipsImage *in, - VipsStart start, - VipsGenerate generate, - VipsStop stop, - void *a, void *b ) -\end{verbatim} - -VIPS starts one or more sequences, runs one or more processing functions -over image \verb+in+ until all of \verb+in+ has been consumed, and then closes -all of the sequences down and returns. VIPS guarantees that the regions -the \verb+process_fn()+ is given will be complete and disjoint, that is, -every pixel in the image will be passed through exactly one sequence. To -make it possible for the sequences to each contribute to the result of the -function in an orderly manner, VIPS also guarantees that all start and stop -functions are mutually exclusive. - -An example should make this clearer. This version of \verb+average()+ -is very similar to the average function in the VIPS library --- it is only -missing polymorphism. - -\begin{fig2} -\begin{verbatim} -#include -#include -#include -#include - -/* Start function for average(). We allocate a small piece of - * storage which this sequence will accumulate its total in. Our - * sequence value is just a pointer to this storage area. - * - * The first of the two pointers VIPS carries around for us is a - * pointer to the space where we store the grand total. - */ -static int * -average_start( IMAGE *out ) -{ - int *seq = IM_NEW( out, int ); - - if( !seq ) - return( NULL ); - *seq = 0; - - return( seq ); -} - -/* Stop function for average(). Add the total which has - * accumulated in our sequence value to the grand total for - * the program. - */ -static int -average_stop( int *seq, int *gtotal ) -{ - /* Stop functions are mutually exclusive, so we can write - * to gtotal without clashing with any other stop functions. - */ - *gtotal += *seq; - - return( 0 ); -} -\end{verbatim} -\caption{Final PIO average of image} -\label{fg:p2average} -\end{fig2} - -\begin{fig2} -\begin{verbatim} -/* Process function for average(). Total this region, and - * add that total to the sequence value. - */ -static int -average_process( REGION *reg, int *seq ) -{ - int total, i, y; - Rect *r = ®->valid; - - /* Get the appropriate part of the input image ready. - */ - if( im_prepare( reg, r ) ) - return( -1 ); - - /* Loop over the region. - */ - total = 0; - for( y = r->top; y < IM_RECT_BOTTOM( r ); y++ ) { - unsigned char *p = IM_REGION_ADDR( reg, r->left, y ); - - for( i = 0; i < IM_REGION_N_ELEMENTS( reg ); i++ ) - total += p[i]; - } - - /* Add to the total for this sequence. - */ - *seq += total; - - return( 0 ); -} -\end{verbatim} -\caption{Final PIO average of image (cont.)} -\end{fig2} - -\begin{fig2} -\begin{verbatim} -/* Find average of image. - */ -int -average( IMAGE *im, double *out ) -{ - /* Accumulate grand total here. - */ - int gtotal = 0; - - /* Prepare im for PIO reading. - */ - if( im_pincheck( im ) ) - return( -1 ); - - /* Check it is the sort of thing we can process. - */ - if( im->BandFmt != IM_BANDFMT_UCHAR || - im->Coding != IM_CODING_NONE ) { - im_error( "average", "uncoded uchar images only" ); - return( -1 ); - } - - /* Loop over the image in pieces, and possibly in parallel. - */ - if( vips_sink( im, - average_start, average_process, average_stop, - >otal, NULL ) ) - return( -1 ); - - /* Calculate average. - */ - *out = (double) gtotal / (IM_IMAGE_N_ELEMENTS( im ) * im->Ysize); - - return( 0 ); -} -\end{verbatim} -\caption{Final PIO average of image (cont.)} -\end{fig2} - -There are a couple of variations on \verb+im_prepare()+: you can use -\verb+im_prepare_to()+ to force writing to a particular place, and -\verb+im_prepare_thread()+ to use threaded evaluation. See the man pages. - -\subsection{Output to regions} -\label{sec:generate} - -Regions are written to in just the same way they are read from --- by -writing to a pointer found with the \verb+IM_REGION_ADDR()+ macro. - -\verb+vips_sink()+ does input --- \verb+im_generate()+ does output. It -has the same type as \verb+vips_sink()+: - -\begin{verbatim} -int -im_generate( IMAGE *out, - void *(*start_fn)(), - int (*process_fn)(), - int (*stop_fn)(), - void *a, void *b ) -\end{verbatim} - -The region given to the process function is ready for output. Each time -the process function is called, it should fill in the pels in the region -it was given. Note that, unlike \verb+vips_sink()+, the areas the process -function is asked to produce are not guaranteed to be either disjoint or -complete. Again, VIPS may start up many process functions if it sees fit. - -Here is \verb+invert()+, rewritten to use PIO. This piece of code makes use -of a pair of standard start and stop functions provided by the VIPS library: -\verb+im_start_one()+ and \verb+im_stop_one()+. They assume that the first -of the two user arguments to \verb+im_generate()+ is the input image. They are -defined as: - -\begin{verbatim} -REGION * -im_start_one( IMAGE *out, IMAGE *in ) -{ - return( im_region_create( in ) ); -} -\end{verbatim} - -\noindent -and: - -\begin{verbatim} -int -im_stop_one( REGION *seq ) -{ - return( im_region_free( seq ) ); -} -\end{verbatim} - -They are useful for simple functions which expect only one input -image. See the manual page for \verb+im_start_many()+ for many-input -functions. - -\begin{fig2} -\begin{verbatim} -#include -#include -#include -#include - -/* Process function for invert(). Build the pixels in or - * from the appropriate pixels in ir. - */ -static int -invert_process( REGION *or, REGION *ir ) -{ - Rect *r = &or->valid; - int i, y; - - /* Ask for the part of ir we need to make or. In this - * case, the two areas will be the same. - */ - if( im_prepare( ir, r ) ) - return( -1 ); - - /* Loop over or writing pels calculated from ir. - */ - for( y = r->top; y < IM_RECT_BOTTOM( r ); y++ ) { - unsigned char *p = IM_REGION_ADDR( ir, r->left, y ); - unsigned char *q = IM_REGION_ADDR( or, r->left, y ); - - for( i = 0; i < IM_REGION_N_ELEMENTS( or ); i++ ) - q[i] = 255 - p[i]; - } - - /* Success! - */ - return( 0 ); -} -\end{verbatim} -\caption{PIO invert} -\label{fg:p2invert} -\end{fig2} - -\begin{fig2} -\begin{verbatim} -/* Invert an image. - */ -int -invert( IMAGE *in, IMAGE *out ) -{ - /* Check descriptors for PIO compatibility. - */ - if( im_piocheck( in, out ) ) - return( -1 ); - - /* Check input image for compatibility with us. - */ - if( in->BandFmt != IM_BANDFMT_UCHAR || in->Coding != IM_CODING_NONE ) { - im_error( "invert", "uncoded uchar images only" ); - return( -1 ); - } - - /* out inherits from in, as before. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - - /* Set demand hints for out. - */ - if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) ) - return( -1 ); - - /* Build out in pieces, and possibly in parallel! - */ - if( im_generate( out, - im_start_one, invert_process, im_stop_one, - in, NULL ) ) - return( -1 ); - - return( 0 ); -} -\end{verbatim} -\caption{PIO invert (cont.)} -\end{fig2} - -Functions have some choice about the way they write their output. Usually, they -should just write to the region they were given by \verb+im_generate()+. They -can, if they wish, set up the region for output to some other place. See -the manual page for \verb+im_region_region()+. See also the source for -\verb+im_copy()+ and \verb+im_extract()+ for examples of these tricks. - -Note also the call to \verb+im_demand_hint()+. This function hints to the IO -system, suggesting the sorts of shapes of region this function is happiest -with. VIPS supports four basic shapes --- choosing the correct shape can -have a dramatic effect on the speed of your function. See the man page for -full details. - -\subsection{Callbacks} -\label{sec:callback} - -VIPS lets you attach callbacks to image descriptors. These are functions -you provide that VIPS will call when certain events occur. There are more -callbacks than are listed here: see the man page for full details. - -\subsubsection{Close callbacks} - -These callbacks are invoked just before an image is closed. They are useful -for freeing objects which are associated with the image. All callbacks are -triggered in the reverse order to the order in which they were attached. This -is sometimes important when freeing objects which contain pointers to -other objects. Close callbacks are guaranteed to be called, and to be called -exactly once. - -Use \verb+im_add_close_callback()+ to add a close callback: - -\begin{verbatim} -typedef int (*im_callback)( void *, void * ) -int im_add_close_callback( IMAGE *, - im_callback_fn, - void *, void * ) -\end{verbatim} - -As with \verb+im_generate()+, the two \verb+void *+ pointers -are carried around for you by VIPS and may be used as your -function sees fit. - -\subsubsection{Preclose callbacks} - -Preclose callbacks are called before any shutdown has occured. Everything is -still alive and your callback can do anything to the image. Preclose callbacks -are guaranteed to be called, and to be called exactly once. See the manual -page for \verb+im_add_preclose_callback()+ for full details. - -\subsubsection{Eval callbacks} - -These are callbacks which are invoked periodically by VIPS during evaluation. -The callback has access to a struct containing information about the progress -of evaluation, useful for user-interfaces built on top of VIPS. See the -manual page for \verb+im_add_eval_callback()+ for full details. - -\subsection{Memory allocation revisited} - -When you are using PIO, memory allocation becomes rather more complicated than -it was before. There are essentially two types of memory which your function -might want to use for working space: memory which is associated with each -instance of your function (remember that two copies of you function may be -joined together in a pipeline and be running at the same time --- you can't -just use global variables), and memory which is local to each sequence -which VIPS starts on your argument image. - -The first type, memory local to this function instance, typically holds -copies of any parameters passed to your image processing function, and links -to any read-only tables used by sequences which you run over the image. This -should be allocated in your main function. - -The second type of memory, memory local to a sequence, should be allocated -in a start function. Because this space is private to a sequence, it may be -written to. Start and stop functions are guaranteed -to be single-threaded, so you may write to the function-local memory within -them. - diff --git a/doc/src/refintro.tex b/doc/src/refintro.tex deleted file mode 100644 index 0c2b5efa..00000000 --- a/doc/src/refintro.tex +++ /dev/null @@ -1,114 +0,0 @@ -\section{Introduction} -\mylabel{sec:ref} - -{/bf -VIPS reference documentation is in the process of switching to gtkdoc. -Half-done manuals are distributed with VIPS, and they should be all done by -the next version. - -In the meantime, this old and slightly outdated chapter has been left -unchanged from the previous version. -} - -This chapter introduces the functions available in the VIPS image -processing library. For detailed information on particular functions, -refer to the UNIX on-line manual pages. Enter (for example): - -\begin{verbatim} -example% man im_abs -\end{verbatim} - -for information on the function \verb+im_abs()+. - -All the comand-line vips operations will print help text too. For example: - -\begin{verbatim} -example% vips im_extract -usage: vips im_extract input output - left top width height band -where: - input is of type "image" - output is of type "image" - left is of type "integer" - top is of type "integer" - width is of type "integer" - height is of type "integer" - band is of type "integer" -extract area/band, from package - "conversion" -flags: (PIO function) - (coordinate transformer) - (area operation) - (result can be cached) -vips: error calling function -im_run_command: too few arguments -\end{verbatim} - -Once you have found a function you need to use, you can call it from a C -program (see \pref{sec:appl}), you can call -it from C++ or Python (see \pref{sec:cpp}), you can call -it from the \nip{} ((see the \emph{nip Manual}), or SIAM graphical -user-interfaces, or you can run it from the UNIX command line with the -\vips{} program. For example: - -\begin{verbatim} -$ vips im_vips2tiff cam.v t1.tif none -$ vips im_tiff2vips t1.tif t2.v.v 0 -$ vips im_equal cam.v t2.v t3.v -$ vips im_min t3.v -255 -\end{verbatim} - -VIPS may have been set up at your site with a set of links which call the -vips program for you. You may also be able to type: - -\begin{verbatim} -$ im_vips2tiff cam.v t1.tif none -$ im_tiff2vips t1.tif t2.v.v 0 -$ im_equal cam.v t2.v t3.v -$ im_min t3.v -\end{verbatim} - -There are a few VIPS programs which you cannot run with \vips{}, either -because their arguments are a very strange, or because they are complete -mini-applications (like \verb+vips2dj+). These programs are listed in -table~\ref{tb:nondb}, see the man pages for full details. - -\begin{tab2} -\centerline{ -\begin{tabular}{|l|l|} -\hline -Name & Description \\ -\hline -\texttt{binfile} & Read RAW image \\ -\texttt{debugim} & Print an image pixel by pixel \\ -\texttt{edvips} & Change fields in a VIPS header \\ -\texttt{header} & Print fields from a VIPS header \\ -\texttt{printlines} & Print an image a line at a time \\ -\texttt{vips} & VIPS universal main program \\ -\texttt{vips-7.14} & VIPS wrapper script \\ -\texttt{find\_mosaic} & Analyse a set of images for overlaps \\ -\texttt{mergeup} & Join a set of images together \\ -\texttt{cooc\_features} & Calculate features of a co-occurence matrix \\ -\texttt{cooc} & Calculate a co-occurence matrix \\ -\texttt{glds\_features} & Calculate features of a grey-level - distribution matrix \\ -\texttt{glds} & Calculate a grey-level distribution matrix \\ -\texttt{simcontr} & Demonstrate simultaneous contrast \\ -\texttt{sines} & Generate a sinusoidal test pattern \\ -\texttt{spatres} & Generate a spatial resolution test pattern \\ -\texttt{squares} & Generate some squares \\ -\texttt{batch\_crop} & Crop a lot of images \\ -\texttt{batch\_image\_convert} & File format convert a lot of images \\ -\texttt{batch\_rubber\_sheet} & Warp a lot of images \\ -\texttt{light\_correct} & Correct a set of images for shading errors \\ -\texttt{mitsub} & Format a VIPS image for output to a Mitsubishi 3600 \\ -\texttt{shrink\_width} & Shrink to a specific width \\ -\texttt{vdump} & VIPS to mono Postscript \\ -\texttt{vips2dj} & VIPS to high-quality colour Postscript \\ -\hline -\end{tabular} -} -\caption{Miscellaneous programs} -\label{tb:nondb} -\end{tab2} diff --git a/doc/src/vdisplay.tex b/doc/src/vdisplay.tex deleted file mode 100644 index f244be71..00000000 --- a/doc/src/vdisplay.tex +++ /dev/null @@ -1,75 +0,0 @@ -\section{The \texttt{VDisplay} class} - -The \verb+VDisplay+ class is an abstraction over the VIPS \verb+im_col_display+ -type which gives convenient and safe representation of VIPS display profiles. - -VIPS display profiles are now mostly obsolete. You're better off using the -ICC colour management \verb+VImage+ member functions \verb+ICC_export()+ and -\verb+ICC_import()+. - -\subsection{Constructors} - -There are two constructors for \verb+VDisplay+: - -\begin{verbatim} -VDisplay( const char *name ); -VDisplay(); -\end{verbatim} - -The first form initialises the display from one of the standard VIPS display -types. For example: - -\begin{verbatim} -VDisplay fred( "sRGB" ); -VDisplay jim( "ultra2-20/2/98" ); -\end{verbatim} - -Makes \verb+fred+ a profile for making images in sRGB format, and \verb+jim+ a -profile representing my workstation display, as of 20/2/98. The second form -of constructor makes an uninitialised display. - -\subsection{Projection functions} - -A set of member functions of \verb+VDisplay+ provide read and write access to -the fields in the display. - -\begin{verbatim} -char *name(); -VDisplayType &type(); -matrix &mat(); -float &YCW(); -float &xCW(); -float &yCW(); -float &YCR(); -float &YCG(); -float &YCB(); -int &Vrwr(); -int &Vrwg(); -int &Vrwb(); -float &Y0R(); -float &Y0G(); -float &Y0B(); -float &gammaR(); -float &gammaG(); -float &gammaB(); -float &B(); -float &P(); -\end{verbatim} - -Where \verb+VDisplayType+ is defined as: - -\begin{verbatim} -enum VDisplayType { - BARCO, - DUMB -}; -\end{verbatim} - -And \verb+matrix+ is defined as: - -\begin{verbatim} -typedef float matrix[3][3]; -\end{verbatim} - -For a description of all the fields in a VIPS display profile, see the manual -page for \verb+im_XYZ2RGB()+. diff --git a/doc/src/verror.tex b/doc/src/verror.tex deleted file mode 100644 index 5680e43e..00000000 --- a/doc/src/verror.tex +++ /dev/null @@ -1,76 +0,0 @@ -\section{The \texttt{VError} class} - -The \verb+VError+ class is the class thrown by the VIPS C++ API when an -error is detected. It is derived from \verb+std::exception+ in the usual way. - -\subsection{Constructors} - -There are two constructors for \verb+VError+: - -\begin{verbatim} -VError( std::string str ); -VError(); -\end{verbatim} - -The first form creates an error object initialised with the specified -string, the last form creates an empty error object. - -\subsection{Projection functions} - -A function gives access to the string held by \verb+VError+: - -\begin{verbatim} -const char *what(); -\end{verbatim} - -You can also send to an \verb+ostream+. - -\begin{verbatim} -std::ostream& operator<<( - std::ostream&, const error& ); -\end{verbatim} - -\subsection{Computing with \texttt{VError}} - -Two member functions let you append elements to an error: - -\begin{verbatim} -VError &app( std::string txt ); -VError &app( const int i ); -\end{verbatim} - -For example: - -\begin{verbatim} -VError wombat; -int n = 12; - -wombat.app( "possum: no more than " ). - app( n ).app( " elements\n" ); -throw( wombat ); -\end{verbatim} - -\noindent -will throw a \verb+VError+ with a diagnostic of: - -\begin{verbatim} -possum: no more than 12 elements -\end{verbatim} - -The member function \verb+perror()+ prints the error message to \verb+stdout+ -and exits with a code of 1. - -\begin{verbatim} -void perror( const char * ); -void perror(); -\end{verbatim} - -\subsection{Convenience function} - -The convenience function \verb+verror+ creates an \verb+VError+ with the -specified error string, and throws it. If you pass \verb+""+ for the string, -verror uses the contents of the VIPS error buffer instead. - -\begin{verbatim} -extern void verror( std::string str = "" ); -\end{verbatim} diff --git a/doc/src/vimage.tex b/doc/src/vimage.tex deleted file mode 100644 index 10be1d96..00000000 --- a/doc/src/vimage.tex +++ /dev/null @@ -1,372 +0,0 @@ -\section{The \texttt{VImage} class} - -The \verb+VImage+ class is a layer over the VIPS \verb+IMAGE+ type. It -automates almost all of the image creation and destruction issues that -complicate the C API, it automates error handling, and it provides a -convenient system for composing operations. - -\subsection{Constructors} - -There are two principal constructors for \verb+VImage+: - -\begin{verbatim} -VImage::VImage( const char *name, - const char *mode = "r" ); -VImage::VImage(); -\end{verbatim} - -The first form creates a new \verb+VImage+, linking it to the named file. -\verb+mode+ sets the mode for the file: it can take the following values: - -\begin{description} - -\item[\texttt{"r"}] -The named image file is opened read-only. This is the default mode. - -\item[\texttt{"w"}] -A \verb+VImage+ is created which, when written to, will write pixels to disc -in the specified file. Any existing file of this name is deleted. - -\item[\texttt{"t"}] -As the \verb'"w"' mode, but pixels written to the \verb+VImage+ will be saved -in a temporary memory buffer. - -\item[\texttt{"p"}] -This creates a special `partial' image. Partial images represent -intermediate results, and are used to join VIPS operations together, -see~\pref{sec:compute}. - -\item[\texttt{"rw"}] -As the \verb'"r"' mode, but the image is mapped into your address space -read-write. This mode is useful for paintbox-style -applications which need to directly modify an image. See \pref{sec:inplace}. - -\end{description} - -The second form of constructor is shorthand for: - -\begin{verbatim} -VImage( "VImage:1", "p" ) -\end{verbatim} - -\noindent -It is used for representing intermediate results of computations. - -Two further constructors are handy for wrapping \verb+VImage+ around existing -images. - -\begin{verbatim} -VImage( void *buffer, - int width, int height, int bands, - TBandFmt format ); -VImage( void *image ); -\end{verbatim} - -\noindent -The first constructor makes a \verb+VImage+ from an area of memory (perhaps -from another image processing system), and the second makes a \verb+VImage+ -from an \verb+IMAGE+. - -In both these two cases, the VIPS C++ API does not assume responsibility -for the resources: it's up to you to make sure the buffer is freed. - -The Python interface adds the usual \verb+frombuffer+ and -\verb+fromstring+ methods. - -\begin{verbatim} -VImage.fromstring (string, - width, height, bands, format) -> - VImage -\end{verbatim} - -\begin{verbatim} -VImage.frombuffer (buffer, - width, height, bands, format) -> - VImage -\end{verbatim} - -\noindent -Use \verb+fromstring+ to avoid worries about object lifetime, but you'll see a -lot of copies and high memory use. Use \verb+frombuffer+ for speed, but you -have to manage object lifetime yourself. - -They are useful for moving images into VIPS from other image processing -libraries. There's also a utility function, \verb+vips_from_PIL_mode+, which -turns a PIL mode into a VIPS band, format, type triple. - -\begin{verbatim} -VImage.vips_from_PIL_mode (mode) -> - (bands, format, type) -\end{verbatim} - -See also \verb+tobuffer+ and \verb+tostring+ below. - -\subsection{File conversion} - -VIPS can read and write a number of different file formats. Information about -file format conversion is taken from the filename. For example: - -\begin{verbatim} -VImage jim( "fred.jpg" ); -\end{verbatim} - -\noindent -This will decompress the file \verb+fred.jpg+ to a memory buffer, wrap a VIPS -image around the buffer and build a reference to it called \verb+jim+. - -Options are passed to the file format converters embedded in the filename. For -example: - -\begin{verbatim} -VImage out( "jen.tif:deflate", "w" ); -\end{verbatim} - -\noindent -Writing to the descriptor \verb+out+ will cause a TIFF image to be written to -disc with deflate compression. - -See the manual page for \verb+im_open(3)+ for details of all the file formats -and conversions available. See the man page for \verb+VipsFormat(3)+ for a -lower-level API which lets you control more of the detail of reading and -writing data and is more suitable for large files. - -\subsection{Projection functions} - -A set of member functions of \verb+VImage+ provide access to the fields in -the header: - -\begin{verbatim} -int Xsize(); -int Ysize(); -int Bands(); -TBandFmt BandFmt(); -TCoding Coding(); -TType Type(); -float Xres(); -float Yres(); -int Length(); -TCompression Compression(); -short Level(); -int Xoffset(); -int Yoffset(); -\end{verbatim} - -\noindent -Where \verb+TBandFmt+, \verb+TCoding+, \verb+TType+ and \verb+TCompression+ -are \verb+enum+s for the types in the VIPS file header. See -section~\pref{sec:header} for an explanation of all of these fields. - -Two functions give access to the filename and history -fields maintained by the VIPS IO system. - -\begin{verbatim} -char *filename(); -char *Hist(); -\end{verbatim} - -You can get and set extra metadata fields with \verb+meta_get()+ and -\verb+meta_set()+. They read and write \verb+GValue+ objects, see -\pref{sec:meta}. - -\begin{verbatim} -void meta_set( const char *field, GValue *value ); -void meta_get( const char *field, GValue *value_copy ); -GType meta_get_type( const char *field ); -\end{verbatim} - -A set of convenience functions build on these two to provide accessors for -common types. - -\begin{verbatim} -int meta_get_int( const char *field ) -double meta_get_double( const char *field ) -const char *meta_get_string( const char *field ) -void *meta_get_area( const char *field ) -void *meta_get_blob( const char *field, size_t *length ) - -void meta_set( const char *field, int value ) -void meta_set( const char *field, double value ) -void meta_set( const char *field, const char *value ) -void meta_set( const char *field, - VCallback free_fn, void *value ) -void meta_set( const char *field, - VCallback free_fn, void *value, size_t length ) -\end{verbatim} - -The \verb+image()+ member function provides access to the \verb+IMAGE+ -descriptor underlying the C++ API. See the \pref{sec:appl} for details. - -\begin{verbatim} -void *image(); -\end{verbatim} - -The \verb+data()+ member function returns a pointer to an array of pixel data -for the image. - -\begin{verbatim} -void *data() const; -\end{verbatim} - -\noindent -This can be very slow and use huge amounts of RAM. - -The Python interface adds \verb+tobuffer+ and \verb+tostring+. These -operations call \verb+data()+ to generate the image pixels and then either -copy it and return the copy as a string, or wrap the pixels up as a Python -buffer object. - -Use \verb+tostring+ to avoid worries about object lifetime, but you'll see a -lot of copies and high memory use. Use \verb+tobuffer+ for speed, but you -have to manage object lifetime yourself. - -They are useful for moving images from VIPS into other image processing -libraries. There's also a utility function, \verb+PIL_mode_from_vips+, which -makes a PIL mode from a VIPS image. - -\begin{verbatim} -VImage.PIL_mode_from_vips (vips-image) -> - mode -\end{verbatim} - -See also \verb+frombuffer+ and \verb+fromstring+ above. - -\subsection{Assignment} - -\verb+VImage+ defines copy and assignment, with reference-counted, -pointer-style semantics. For example, if you write: - -\begin{verbatim} -VImage fred( "fred.v" ); -VImage jim( "jim.v" ); - -fred = jim; -\end{verbatim} - -This will automatically close the file \verb+fred.v+, and make the variable -\verb+fred+ point to the image \verb+jim.v+ instead. Both \verb+jim+ and -\verb+fred+ now point to the same underlying image object. - -Internally, a \verb+VImage+ object is just a pointer to a reference-counting -block, which in turn holds a pointer to the underlying VIPS \verb+IMAGE+ type. -You can therefore efficiently pass \verb+VImage+ objects to functions by -value, and return \verb+VImage+ objects as function results. - -\subsection{Computing with \texttt{VImage}s} -\label{sec:compute} - -All VIPS image processing operations are member functions of the \verb+VImage+ -class. For example: - -\begin{verbatim} -VImage fred( "fred.v" ); -VImage jim( "jim.v" ); - -VImage result = fred.cos() + jim; -\end{verbatim} - -Will apply \verb+im_costra()+ to \verb+fred.v+, making an image where each -pixel is the cosine of the corresponding pixel in \verb+fred.v+; then add that -image to \verb+jim.v+. Finally, the result will be held in \verb+result+. - -VIPS is a demand-driven image processing system: when it computes expressions -like this, no actual pixels are calculated (although you can use the -projection functions on images --- \verb+result.BandFmt()+ for example). When -you finally write the result to a file (or use some operation that needs pixel -values, such as \verb+min()+, find minimum value), VIPS evaluates all of the -operations you have called to that point in parallel. If you have more than one -CPU in your machine, the load is spread over the available processors. This -means that there is no limit to the size of the images you can process. - -\pref{sec:packages} lists all of the VIPS packages. These general -rules apply: - -\begin{itemize} - -\item -VIPS operation names become C++ member function names by dropping the -\verb+im_+ prefix, and if present, the \verb+tra+ postfix, the \verb+const+ -postfix and the \verb+_vec+ postfix. For example, the -VIPS operation \verb+im_extract()+ becomes \verb+extract()+, and -\verb+im_costra()+ becomes \verb+cos()+. - -\item -The \verb+VImage+ object to which you apply the member function is the first -input image, the member function returns the first output. If there is no -image input, the member is declared \verb+static+. - -For example, \verb+im_project(3)+ returns two images. You can call it from -Python like this: - -\begin{verbatim} -hout = VImage.VImage () -vout = im.project (hout) -\end{verbatim} - -\noindent -In other words, \verb+.project()+ writes the second result to the -\verb+VImage+ you pass as an argument. - -\item -\verb+INTMASK+ and \verb+DOUBLEMASK+ types become \verb+VMask+ objects, -\verb+im_col_display+ types become \verb+VDisplay+ objects. - -\item -Several C API functions can map to the same C++ API member. For example, -\verb+im_andimage+, \verb+im_andimage_vec+ and \verb+im_andimageconst+ all map -to the member \verb+andimage+. The API relies on overloading to -discriminate between these functions. - -\end{itemize} - -This part of the C++ API is generated automatically from the VIPS function -database, so it should all be up-to-date. - -There are a set of arithmetic operators defined for your convenience. You can -generally write any arithmetic expression and include \verb+VImage+ in there. - -\begin{verbatim} -VImage fred( "fred.v" ); -VImage jim( "jim.v" ); - -Vimage v = int((fred + jim) / 2); -\end{verbatim} - -\subsection{Writing results} - -Once you have computed some result, you can write it to a file with the member -\verb+write()+. It takes the following forms: - -\begin{verbatim} -VImage write( const char *name ); -VImage write( VImage out ); -VImage write(); -\end{verbatim} - -The first form simply writes the image to the named file. The second form -writes the image to the specified \verb+VImage+ object, for example: - -\begin{verbatim} -VImage fred( "fred.v" ); -VImage jim( "jim buffer", "t" ); - -Vimage v = (fred + 42).write( jim ); -\end{verbatim} - -\noindent -This creates a temporary memory buffer called \verb+jim+, and fills it with -the result of adding 42 to every pixel in \verb+fred.v+. - -The final form of \verb+write()+ writes the image to a memory buffer, and -returns that. - -\subsection{Type conversions} - -Two type conversions are defined: you can cast \verb+VImage+ to a -\verb+VDMask+ and to a \verb+VIMask+. - -\begin{verbatim} -operator VDMask(); -operator VIMask(); -\end{verbatim} - -These operations are slow and need a lot of memory! Emergencies only. diff --git a/doc/src/vipsmanual.tex b/doc/src/vipsmanual.tex deleted file mode 100644 index 703f5896..00000000 --- a/doc/src/vipsmanual.tex +++ /dev/null @@ -1,95 +0,0 @@ -\documentclass[a4paper,twocolumn,dvips]{book} -\usepackage[dvips=false,pdftex=false,vtex=false]{geometry} -\usepackage{ifpdf} -\ifpdf - \usepackage[pdftex]{graphicx,color} -\else - \usepackage{graphicx,color} -\fi -\usepackage{times} -\usepackage{fancyhdr} -\usepackage{ifthen} - -\input{mydefs} - -\fancyhead{} % clear all fields -\fancyhead[LE,RO]{\leftmark} % left-even, right-odd -\fancyhead[RE,LO]{VIPS Manual} % right-even, left-odd -\fancyfoot[LE,RO]{\thepage} % left-even, right-odd -\fancyfoot[RE,LO]{November 2014} - -\begin{document} - -\pagenumbering{roman} - -\begin{titlepage} -\thispagestyle{empty} -\begin{center} -\huge -VIPS Manual\\ -\large Version 7.42\\ -\vspace{0.5in} -\large -John Cupitt, -Kirk Martinez\\ -\end{center} - -VIPS is currently (v. 7.42, November 2014) in an API transition. The API as -documented in 7.24 is still complete and supported and is the one you should -use. The 8.0 API is not yet done and may still change before completion. - -% hmm ... must be a better way to get the quote at the bottom of the page -\vspace{5in} - -This manual formatted \today -\setcounter{page}{1} -\end{titlepage} - -% \blankpage -\tableofcontents -\thispagestyle{plain} - -% \blankpage -\listoffigures -\thispagestyle{plain} - -% \blankpage -\listoftables -\thispagestyle{plain} - -% \blankpage -\pagenumbering{arabic} -\thispagestyle{plain} -\cfoot{} - -\chapter{VIPS from C++ and Python} - -\input{cppintro} -\input{fileformat} -\input{vimage} -\input{vmask} -\input{vdisplay} -\input{verror} - -\chapter{VIPS for C programmers} - -\input{applintro} -\input{iosys} -\input{func} -\input{object} -\input{format} -\input{interpolate} - -\chapter{Writing VIPS operations} - -\input{operintro} -\input{wio} -\input{pio} -\input{ipio} - -\chapter{VIPS reference} - -\input{refintro} -\input{packages} - -\end{document} diff --git a/doc/src/vmask.tex b/doc/src/vmask.tex deleted file mode 100644 index 57b5ce0c..00000000 --- a/doc/src/vmask.tex +++ /dev/null @@ -1,175 +0,0 @@ -\section{The \texttt{VMask} class} - -The \verb+VMask+ class is an abstraction over the VIPS \verb+DOUBLEMASK+ and -\verb+INTMASK+ types which gives convenient and safe representation of -matrices. - -\verb+VMask+ has two sub-classes, \verb+VIMask+ and \verb+VDMask+. These -represent matrices of integers and doubles respectively. - -\subsection{Constructors} - -There are four constructors for \verb+VIMask+ and \verb+VDMask+: - -\begin{verbatim} -VIMask( int xsize, int ysize ); -VIMask( int xsize, int ysize, - int scale, int offset, ... ); -VIMask( int xsize, int ysize, - int scale, int offset, - std::vector coeff ); -VIMask( const char *name ); -VIMask(); -VDMask( int xsize, int ysize ); -VDMask( int xsize, int ysize, - double scale, double offset, ... ); -VDMask( int xsize, int ysize, - double scale, double offset, - std::vector coeff ); -VDMask( const char *name ); -VDMask(); -\end{verbatim} - -The first form creates an empty matrix, with the specified dimensions; -the second form initialises a matrix from a varargs list; the third form -sets the matrix from a vector of coefficients; the fourth from the named file. -The final form makes a mask object with no contents yet. - -The varargs constructors are not wrapped in Python --- use the vector -constructor instead. For example: - -\begin{verbatim} -m = VMask.VIMask (3, 3, 1, 0, - [-1, -1, -1, - -1, 8, -1, - -1, -1, -1]) -\end{verbatim} - -\subsection{Projection functions} - -A set of member functions of \verb+VIMask+ provide access to the fields in -the matrix: - -\begin{verbatim} -int xsize() const; -int ysize() const; -int scale() const; -int offset() const; -const char *filename() const; -\end{verbatim} - -\verb+VDMask+ is the same, except that the \verb+scale()+ and \verb+offset()+ -members return \verb+double+. \verb+VMask+ allows all operations that are -common to \verb+VIMask+ and \verb+VDMask+. - -\subsection{Assignment} - -\verb+VMask+ defines copy and assignment with pointer-style -semantics. You can write stuff like: - -\begin{verbatim} -VIMask fred( "mask" ); -VMask jim; - -jim = fred; -\end{verbatim} - -This reads the file \verb+mask+, noting a pointer to the mask in \verb+fred+. -It then makes \verb+jim+ also point to it, so \verb+jim+ and \verb+fred+ are -sharing the same underlying matrix values. - -Internally, a \verb+VMask+ object is just a pointer to a reference-counting -block, which in turn holds a pointer to the underlying VIPS \verb+MASK+ type. -You can therefore efficiently pass \verb+VMask+ objects to functions by -value, and return \verb+VMask+ objects as function results. - -\subsection{Computing with \texttt{VMask}} - -You can use \verb+[]+ to get at matrix elements, numbered left-to-right, -top-to-bottom. Alternatively, use \verb+()+ to address elements by $x,y$ -position. For example: - -\begin{verbatim} -VIMask fred( "mask" ); - -for( int i = 0; i < fred.xsize(); i++ ) - fred[i] = 12; -\end{verbatim} - -\noindent -will set the first line of the matrix to 12, and: - -\begin{verbatim} -VDMask fred( "mask" ); - -for( int x = 0; x < fred.xsize(); x++ ) - fred(x, x) = 12.0; -\end{verbatim} - -\noindent -will set the leading diagonal to 12. - -These don't work well in Python, so there's an extra member, \verb+get()+, -which will get an element by $x,y$ position. - -\begin{verbatim} -x = mat.get (2, 4) -\end{verbatim} - -See the member functions below for other operations on \verb+VMask+. - -\subsection{\texttt{VIMask} operations} - -The following operations are defined for \verb+VIMask+: - -\begin{verbatim} -// Cast to VDMask and VImage -operator VDMask(); -operator VImage(); - -// Build gaussian and log masks -static VIMask gauss( double, double ); -static VIMask gauss_sep( double, double ); -static VIMask log( double, double ); - -// Rotate -VIMask rotate45(); -VIMask rotate90(); - -// Transpose, invert, join and multiply -VDMask trn() ; -VDMask inv(); -VDMask cat( VDMask ); -VDMask mul( VDMask ); -\end{verbatim} - -\subsection{\texttt{VDMask} operations} - -The following operations are defined for \verb+VDMask+: - -\begin{verbatim} -// Cast to VIMask and VImage -operator VIMask(); -operator VImage(); - -// Build gauss and log masks -static VDMask gauss( double, double ); -static VDMask log( double, double ); - -// Rotate -VDMask rotate45(); -VDMask rotate90(); - -// Scale to intmask -VIMask scalei(); - -// Transpose, invert, join and multiply -VDMask trn(); -VDMask inv(); -VDMask cat( VDMask ); -VDMask mul( VDMask ); -\end{verbatim} - -\subsection{Output of masks} - -You can output masks with the usual \verb+<<+ operator. diff --git a/doc/src/wio.tex b/doc/src/wio.tex deleted file mode 100644 index 6f8eb278..00000000 --- a/doc/src/wio.tex +++ /dev/null @@ -1,363 +0,0 @@ -\section{Programming WIO operations} - -WIO is the style for you if you want ease of programming, or if your -algorithm must have the whole of the input image available at the same -time. For example, a Fourier transform operation is unable to produce any -output until it has seen the whole of the input image. - -\subsection{Input from an image} - -In WIO input, the whole of the image data is made available to the program -via the \verb+data+ field of the descriptor. To make an image ready for reading -in this style, programs should call \verb+im_incheck()+: - -\begin{verbatim} -int im_incheck( IMAGE *im ) -\end{verbatim} - -\noindent -If it succeeds, it returns 0, if it fails, it returns non-zero and -sets \verb+im_error()+. On success, VIPS guarantees that all of the -user-accessible fields in the descriptor contain valid data, and that all -of the image data may be read by simply reading from the \verb+data+ field -(see below for an example). This will only work for images less than about -2GB in size. - -VIPS has some simple macros to help address calculations on images: - -\begin{verbatim} -int IM_IMAGE_SIZEOF_ELEMENT( IMAGE * ) -int IM_IMAGE_SIZEOF_PEL( IMAGE * ) -int IM_IMAGE_SIZEOF_LINE( IMAGE * ) -int IM_IMAGE_N_ELEMENTS( IMAGE * ) -char *IM_IMAGE_ADDR( IMAGE *, - int x, int y ) -\end{verbatim} - -\noindent -These macros calculate \verb+sizeof()+ a band element, a pel and a horizontal -line of pels. \verb+IM_IMAGE_N_ELEMENTS+ returns the number of band elements -across an image. \verb+IM_IMAGE_ADDR+ calculates the address of a pixel in an -image. If \verb+DEBUG+ is defined, it does bounds checking too. - -\begin{fig2} -\begin{verbatim} -#include -#include - -#include - -int -average( IMAGE *im, double *out ) -{ - int x, y; - long total; - - /* Prepare for reading. - */ - if( im_incheck( im ) ) - return( -1 ); - - /* Check that this is the kind of image we can process. - */ - if( im->BandFmt != IM_BANDFMT_UCHAR || - im->Coding != IM_CODING_NONE ) { - im_error( "average", "uncoded uchar images only" ); - return( -1 ); - } - - /* Loop over the image, summing pixels. - */ - total = 0; - for( y = 0; y < im->Ysize; y++ ) { - unsigned char *p = (unsigned char *) IM_IMAGE_ADDR( im, 0, y ); - - for( x = 0; x < IM_IMAGE_N_ELEMENTS( im ); x++ ) - total += p[x]; - } - - /* Calculate average. - */ - *out = (double) total / - (IM_IMAGE_N_ELEMENTS( im ) * im->Ysize)); - - /* Success! - */ - return( 0 ); -} -\end{verbatim} -\caption{Find average of image} -\label{fg:average} -\end{fig2} - -\fref{fg:average} is a simple WIO operation which calculates the -average of an unsigned char image. It will work for any size image, with any -number of bands. See~\pref{sec:poly} for techniques for making operations -which will work for any image type. This operation might be called from an -application with: - -\begin{verbatim} -#include -#include - -#include - -void -find_average( char *name ) -{ - IMAGE *im; - double avg; - - if( !(im = im_open( name, "r" )) || - average( im, &avg ) || - im_close( im ) ) - error_exit( "failure!" ); - - printf( "Average of \"%s\" is %G\n", - name, avg ); -} -\end{verbatim} - -\noindent -When you write an image processing operation, you can test it by writing -a VIPS function descriptor and calling it from the \vips{} universal -main program, or from the \nip{} interface. See \pref{sec:appl}. - -\subsection{Output to an image} - -Before attempting WIO output, programs should call \verb+im_outcheck()+. It -has type: - -\begin{verbatim} -int im_outcheck( IMAGE *im ) -\end{verbatim} - -\noindent -If \verb+im_outcheck()+ succeeds, VIPS guarantees that WIO output is sensible. - -Programs should then set fields in the output descriptor to describe -the sort of image they wish to write (size, type, and so on) and call -\verb+im_setupout()+. It has type: - -\begin{verbatim} -int im_setupout( IMAGE *im ) -\end{verbatim} - -\noindent -\verb+im_setupout()+ creates the output file or memory buffer, using the -size and type fields that were filled in by the program between the calls to -\verb+im_outcheck()+ and \verb+im_setupout()+, and gets it ready for writing. - -Pels are written with \verb+im_writeline()+. This takes a y position (pel -(0,0) is in the top-left-hand corner of the image), a descriptor and a -pointer to a line of pels. It has type: - -\begin{verbatim} -int im_writeline( int y, - IMAGE *im, unsigned char *pels ) -\end{verbatim} - -Two convenience functions are available to make this process slightly -easier. \verb+im_iocheck()+ is useful for programs which take one input -image and produce one image output. It simply calls \verb+im_incheck()+ -and \verb+im_outcheck()+. It has type: - -\begin{verbatim} -int im_iocheck( IMAGE *in, IMAGE *out ) -\end{verbatim} - -The second convenience function copies the fields describing size, type, -metadata and history from one image descriptor to another. It is useful when -the output -image will be similar in size and type to the input image. It has type: - -\begin{verbatim} -int im_cp_desc( IMAGE *out, IMAGE *in ) -\end{verbatim} - -\noindent -There's also \verb+im_cp_descv()+, see the man page. - -\begin{fig2} -\begin{verbatim} -#include -#include - -#include -#include - -int -invert( IMAGE *in, IMAGE *out ) -{ - int x, y; - unsigned char *buffer; - - /* Check images. - */ - if( im_iocheck( in, out ) ) - return( -1 ); - if( in->BandFmt != IM_BANDFMT_UCHAR || in->Coding != IM_CODING_NONE ) { - im_error( "invert", "uncoded uchar images only" ); - return( -1 ); - } - - /* Make output image. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - if( im_setupout( out ) ) - return( -1 ); - - /* Allocate a line buffer and make sure it will be freed correctly. - */ - if( !(buffer = IM_ARRAY( out, - IM_IMAGE_SIZEOF_LINE( in ), unsigned char )) ) - return( -1 ); - - /* Loop over the image! - */ - for( y = 0; y < in->Ysize; y++ ) { - unsigned char *p = (unsigned char *) IM_IMAGE_ADDR( in, 0, y ); - - for( x = 0; x < IM_IMAGE_N_ELEMENTS( in ); x++ ) - buffer[x] = 255 - p[x]; - if( im_writeline( y, out, buffer ) ) - return( -1 ); - } - - return( 0 ); -} -\end{verbatim} -\caption{Invert an image} -\label{fg:invert} -\end{fig2} - -\fref{fg:invert} is a WIO VIPS operation which finds the photographic -negative of an unsigned char image. See \pref{sec:malloc} for an explanation -of \verb+IM_ARRAY+. This operation might be called from an -application with: - -\begin{verbatim} -#include -#include - -#include - -void -find_negative( char *inn, char *outn ) -{ - IMAGE *in, *out; - - if( !(in = im_open( inn, "r" )) || - !(out = im_open( outn, "w" )) || - invert( in, out ) || - im_updatehist( out, "invert" ) || - im_close( in ) || - im_close( out ) ) - error_exit( "failure!" ); -} -\end{verbatim} - -See \pref{sec:history} for an explanation of the call to \verb+im_updatehist()+. - -\subsection{Polymorphism} -\label{sec:poly} - -Most image processing operations in the VIPS library can operate on -images of any type (\verb+IM_BANDFMT_UCHAR+, as in our examples above, -also \verb+IM_BANDFMT_UINT+ etc.). This is usually implemented with code -replication: the operation contains loops for processing every kind of image, -and when called, invokes the appropriate loop for the image it is given. - -As an example, figure~\ref{fg:exp} calculates \verb+exp()+ for every pel -in an image. If the input image is \verb+double+, we write \verb+double+ -output. If it is any other non-complex type, we write \verb+float+. If it -is complex, we flag an error (\verb+exp()+ of a complex number is fiddly). -The example uses an image type predicate, \verb+im_iscomplex()+. There are -a number of these predicate functions, see the manual page. - -\begin{fig2} -\begin{verbatim} -#include -#include -#include - -#include -#include - -/* Exponential transform. - */ -int -exptra( IMAGE *in, IMAGE *out ) -{ - int x, y; - unsigned char *buffer; - - /* Check descriptors. - */ - if( im_iocheck( in, out ) ) - return( -1 ); - if( in->Coding != IM_CODING_NONE || im_iscomplex( in ) ) { - im_error( "exptra", "uncoded non-complex only" ); - return( -1 ); - } - - /* Make output image. - */ - if( im_cp_desc( out, in ) ) - return( -1 ); - if( in->BandFmt != IM_BANDFMT_DOUBLE ) - out->BandFmt = IM_BANDFMT_FLOAT; - if( im_setupout( out ) ) - return( -1 ); -\end{verbatim} -\caption{Calculate \texttt{exp()} for an image} -\label{fg:exp} -\end{fig2} - -\begin{fig2} -\begin{verbatim} - /* Allocate a line buffer. - */ - if( !(buffer = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( in ), unsigned char )) ) - return( -1 ); - -/* Our inner loop, parameterised for both the input and output - * types. Note the use of `\', since macros have to be all on - * one line. - */ -#define loop(IN, OUT) { \ - for( y = 0; y < in->Ysize; y++ ) { \ - IN *p = (IN *) IM_IMAGE_ADDR( in, 0, y ); \ - OUT *q = (OUT *) buffer; \ - \ - for( x = 0; x < IM_IMAGE_N_ELEMENTS( in ); x++ ) \ - q[x] = exp( p[x] ); \ - if( im_writeline( y, out, buffer ) ) \ - return( -1 ); \ - } \ -} - - /* Switch for all the types we can handle. - */ - switch( in->BandFmt ) { - case IM_BANDFMT_UCHAR: loop( unsigned char, float ); break; - case IM_BANDFMT_CHAR: loop( char, float ); break; - case IM_BANDFMT_USHORT:loop( unsigned short, float ); break; - case IM_BANDFMT_SHORT: loop( short, float ); break; - case IM_BANDFMT_UINT: loop( unsigned int, float ); break; - case IM_BANDFMT_INT: loop( int, float ); break; - case IM_BANDFMT_FLOAT: loop( float, float ); break; - case IM_BANDFMT_DOUBLE:loop( double, double ); break; - default: - im_error( "exptra", "internal error" ); - return( -1 ); - } - - /* Success. - */ - return( 0 ); -} -\end{verbatim} -\caption{Calculate \texttt{exp()} for an image (cont)} -\end{fig2} diff --git a/doc/reference/using-C.xml b/doc/using-C.xml similarity index 100% rename from doc/reference/using-C.xml rename to doc/using-C.xml diff --git a/doc/reference/using-command-line.xml b/doc/using-command-line.xml similarity index 100% rename from doc/reference/using-command-line.xml rename to doc/using-command-line.xml diff --git a/doc/reference/using-cpp.xml b/doc/using-cpp.xml similarity index 100% rename from doc/reference/using-cpp.xml rename to doc/using-cpp.xml diff --git a/doc/reference/using-python.xml b/doc/using-python.xml similarity index 100% rename from doc/reference/using-python.xml rename to doc/using-python.xml diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 0e15e44d..014906cf 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -402,6 +402,7 @@ vips_colour_build( VipsObject *object ) */ if( vips_cast( extra_bands[i], &t1, out->BandFmt, + "shift", TRUE, NULL ) ) { g_object_unref( out ); return( -1 ); diff --git a/libvips/colour/colourspace.c b/libvips/colour/colourspace.c index cbefe3e7..21a980c4 100644 --- a/libvips/colour/colourspace.c +++ b/libvips/colour/colourspace.c @@ -73,17 +73,34 @@ vips_scRGB2RGB16( VipsImage *in, VipsImage **out, ... ) return( vips_scRGB2sRGB( in, out, "depth", 16, NULL ) ); } +/* Do these two with a simple cast ... since we're just cast shifting, we can + * short-circuit the extra band processing in vips_colour_build(). + */ + static int vips_RGB162sRGB( VipsImage *in, VipsImage **out, ... ) { - if( vips_msb( in, out, NULL ) ) + if( vips_cast( in, out, VIPS_FORMAT_UCHAR, + "shift", TRUE, + NULL ) ) return( -1 ); - (*out)->Type = VIPS_INTERPRETATION_sRGB; return( 0 ); } +static int +vips_sRGB2RGB16( VipsImage *in, VipsImage **out, ... ) +{ + if( vips_cast( in, out, VIPS_FORMAT_USHORT, + "shift", TRUE, + NULL ) ) + return( -1 ); + (*out)->Type = VIPS_INTERPRETATION_RGB16; + + return( 0 ); +} + /* Process the first @n bands with @fn, detach and reattach remaining bands. */ static int @@ -102,7 +119,9 @@ vips_process_n( const char *domain, VipsImage *in, VipsImage **out, "n", in->Bands - n, NULL ) || fn( t[0], &t[2], NULL ) || - vips_cast( t[1], &t[3], t[2]->BandFmt, NULL ) || + vips_cast( t[1], &t[3], t[2]->BandFmt, + "shift", TRUE, + NULL ) || vips_bandjoin2( t[2], t[3], out, NULL ) ) { g_object_unref( scope ); return( -1 ); diff --git a/libvips/conversion/cast.c b/libvips/conversion/cast.c index 50bcba40..0fae1aae 100644 --- a/libvips/conversion/cast.c +++ b/libvips/conversion/cast.c @@ -47,6 +47,8 @@ * - redone as a class * 10/4/12 * - cast to uint now removes <0 values + * 11/2/15 + * - add @shift option */ /* @@ -101,6 +103,7 @@ typedef struct _VipsCast { VipsImage *in; VipsBandFormat format; + gboolean shift; int underflow; /* Number of underflows */ int overflow; /* Number of overflows */ @@ -179,6 +182,33 @@ vips_cast_start( VipsImage *out, void *a, void *b ) return( seq ); } +/* Rightshift an integer type, ie. sizeof(ITYPE) > sizeof(OTYPE). + */ +#define VIPS_SHIFT_RIGHT( ITYPE, OTYPE ) { \ + ITYPE * restrict p = (ITYPE *) in; \ + OTYPE * restrict q = (OTYPE *) out; \ + int n = ((int) sizeof( ITYPE ) << 3) - ((int) sizeof( OTYPE ) << 3); \ + \ + g_assert( sizeof( ITYPE ) > sizeof( OTYPE ) ); \ + \ + for( x = 0; x < sz; x++ ) \ + q[x] = p[x] >> n; \ +} + +/* Leftshift an integer type, ie. sizeof(ITYPE) < sizeof(OTYPE). We need to + * copy the bottom bit up into the fresh new bits + */ +#define VIPS_SHIFT_LEFT( ITYPE, OTYPE ) { \ + ITYPE * restrict p = (ITYPE *) in; \ + OTYPE * restrict q = (OTYPE *) out; \ + int n = ((int) sizeof( OTYPE ) << 3) - ((int) sizeof( ITYPE ) << 3); \ + \ + g_assert( sizeof( ITYPE ) < sizeof( OTYPE ) ); \ + \ + for( x = 0; x < sz; x++ ) \ + q[x] = (p[x] << n) | (((p[x] & 1) << n) - (p[x] & 1)); \ +} + /* Cast int types to an int type. */ #define VIPS_CLIP_INT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \ @@ -194,6 +224,21 @@ vips_cast_start( VipsImage *out, void *a, void *b ) } \ } +/* Int to int handling. + */ +#define VIPS_INT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \ + if( cast->shift && \ + sizeof( ITYPE ) > sizeof( OTYPE ) ) { \ + VIPS_SHIFT_RIGHT( ITYPE, OTYPE ); \ + } \ + else if( cast->shift ) { \ + VIPS_SHIFT_LEFT( ITYPE, OTYPE ); \ + } \ + else { \ + VIPS_CLIP_INT_INT( ITYPE, OTYPE, VIPS_CLIP ); \ + } \ +} + /* Cast float types to an int type. */ #define VIPS_CLIP_FLOAT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \ @@ -348,42 +393,42 @@ vips_cast_gen( VipsRegion *or, void *vseq, void *a, void *b, switch( cast->in->BandFmt ) { case VIPS_FORMAT_UCHAR: BAND_SWITCH_INNER( unsigned char, - VIPS_CLIP_INT_INT, + VIPS_INT_INT, VIPS_CLIP_REAL_FLOAT, VIPS_CLIP_REAL_COMPLEX ); break; case VIPS_FORMAT_CHAR: BAND_SWITCH_INNER( signed char, - VIPS_CLIP_INT_INT, + VIPS_INT_INT, VIPS_CLIP_REAL_FLOAT, VIPS_CLIP_REAL_COMPLEX ); break; case VIPS_FORMAT_USHORT: BAND_SWITCH_INNER( unsigned short, - VIPS_CLIP_INT_INT, + VIPS_INT_INT, VIPS_CLIP_REAL_FLOAT, VIPS_CLIP_REAL_COMPLEX ); break; case VIPS_FORMAT_SHORT: BAND_SWITCH_INNER( signed short, - VIPS_CLIP_INT_INT, + VIPS_INT_INT, VIPS_CLIP_REAL_FLOAT, VIPS_CLIP_REAL_COMPLEX ); break; case VIPS_FORMAT_UINT: BAND_SWITCH_INNER( unsigned int, - VIPS_CLIP_INT_INT, + VIPS_INT_INT, VIPS_CLIP_REAL_FLOAT, VIPS_CLIP_REAL_COMPLEX ); break; case VIPS_FORMAT_INT: BAND_SWITCH_INNER( signed int, - VIPS_CLIP_INT_INT, + VIPS_INT_INT, VIPS_CLIP_REAL_FLOAT, VIPS_CLIP_REAL_COMPLEX ); break; @@ -499,6 +544,13 @@ vips_cast_class_init( VipsCastClass *class ) VIPS_ARGUMENT_REQUIRED_INPUT, G_STRUCT_OFFSET( VipsCast, format ), VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR ); + + VIPS_ARG_BOOL( class, "shift", 7, + _( "Shift" ), + _( "Shift integer values up and down" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsCast, shift ), + FALSE ); } static void @@ -519,13 +571,22 @@ vips_castv( VipsImage *in, VipsImage **out, VipsBandFormat format, va_list ap ) * @format: format to convert to * @...: %NULL-terminated list of optional named arguments * + * Optional arguments: + * + * @shift: integer values are shifted + * * Convert @in to @format. You can convert between any pair of formats. * Floats are truncated (not rounded). Out of range values are clipped. * * Casting from complex to real returns the real part. * + * If @shift is %TRUE, integer values are shifted up and down. For example, + * casting from unsigned 8 bit to unsigned 16 bit would + * shift every value left by 8 bits. The bottom bit is copied into the new + * bits, so 255 would become 65535. + * * See also: vips_scale(), vips_complexform(), vips_real(), vips_imag(), - * vips_cast_uchar(). + * vips_cast_uchar(), vips_msb(). * * Returns: 0 on success, -1 on error */ diff --git a/tools/Makefile.am b/tools/Makefile.am index e9d0f625..f8425dec 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,11 +20,11 @@ bin_SCRIPTS = \ batch_rubber_sheet \ batch_crop \ vipsprofile \ - vips-7.42 + vips-8.0 EXTRA_DIST = \ vipsprofile \ - vips-7.42 \ + vips-8.0 \ light_correct.in \ shrink_width.in \ batch_image_convert.in \ diff --git a/tools/vips-8.0 b/tools/vips-8.0 new file mode 100755 index 00000000..bcc1007b --- /dev/null +++ b/tools/vips-8.0 @@ -0,0 +1,129 @@ +#!/bin/bash +# +# Start script for VIPS + +# need extended regexps, hence we insist on bash above +shopt -s extglob +# set -x + +# name we were invoked as +bname=`basename $0` + +# check args +if [[ $# < 1 ]]; then + echo "usage: $bname [command ...]" + echo "examples:" + echo " $bname man im_invert" + echo " $bname vips im_invert /pics/tmp/fred.jpg /pics/tmp/fred2.tif" + exit 1 +fi + +# prepend a path component to an environment variable +# be careful to avoid trailing : characters if the var is not defined, they +# can cause security problems +function prepend_var () { + # we have to use eval to do double indirection, I think + eval value="\$$1" + if [ "x$value" = x ]; then + export $1=$2 + else + export $1=$2:$value + fi +} + +# try to extract the prefix from a path to an executable +# eg. "/home/john/vips/bin/fred" -> "/home/john/vips" +function find_prefix () { + # try to canonicalise the path + ep_canon=$1 + + # relative path? prefix with pwd + if [ ${ep_canon:0:1} != "/" ]; then + ep_canon=`pwd`/$ep_canon + fi + + # replace any "/./" with "/" + ep_canon=${ep_canon//\/.\//\/} + + # any "xxx/../" can go + ep_canon=${ep_canon//+([^\/])\/..\//} + + # trailing "xxx/.." can go + ep_canon=${ep_canon/%+([^\/])\/../} + + # remove trailing "/bin/xxx" to get the prefix + ep_prefix=${ep_canon/%\/bin\/+([^\/])/} + + # was there anything to remove in that final step? if not, the path + # must be wrong + if [ x$ep_prefix == x$ep_canon ]; then + return 1 + fi + + echo $ep_prefix; + + return 0 +} + +# try to guess the install prefix from $0 +function guess_prefix () { + # $0 is a file? must be us + if [ -f $0 ]; then + find_prefix $0 + return + fi + + # nope, extract program name from $0 and try looking along the + # searchpath for it + name=`basename $0` + + fred=$PATH + while [ x$fred != x"" ]; do + path=${fred/:*/}/$name + fred=${fred/*([^:])?(:)/} + + if [ -f $path ]; then + find_prefix $path + return + fi + done + + # not found on path either ... give up! + return 1 +} + +prefix=`guess_prefix`; + +if [ $? != 0 ]; then + echo "unable to find $0 from the file name, or from your PATH" + echo "either run directly, or add the install bin area to " + echo "your PATH" + exit 1 +fi + +export VIPSHOME=$prefix + +# add VIPSHOME to man pages +prepend_var MANPATH $VIPSHOME/man + +# add the VIPS lib area to the library path +case `uname` in +HPUX) + libvar=SHLIB_PATH + ;; + +Darwin) + libvar=DYLD_LIBRARY_PATH + ;; + +*) + libvar=LD_LIBRARY_PATH + ;; +esac +prepend_var $libvar $VIPSHOME/lib + +# add VIPS bin area to path +prepend_var PATH $VIPSHOME/bin + +# run, passing in args we were passed +exec $*