diff --git a/ChangeLog b/ChangeLog index 779d5c48..75cf5fbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ - try to improve vips_resize() quality a little more - vips_resize() can do non-square resizes - dzsave removes tile metadata by default, thanks Benjamin +- added vips_image_new_from_memory_copy() 7/5/15 started 8.1.1 - oop, vips-8.0 wrapper script should be vips-8.1, thanks Danilo diff --git a/doc/gtk-doc.make b/doc/gtk-doc.make index e7916563..9ccd0b04 100644 --- a/doc/gtk-doc.make +++ b/doc/gtk-doc.make @@ -25,6 +25,7 @@ TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) SETUP_FILES = \ $(content_files) \ + $(expand_content_files) \ $(DOC_MAIN_SGML_FILE) \ $(DOC_MODULE)-sections.txt \ $(DOC_MODULE)-overrides.txt @@ -86,7 +87,7 @@ GTK_DOC_V_SETUP_0=@echo " DOC Preparing build"; setup-build.stamp: -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - files=`echo $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types`; \ + files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \ if test "x$$files" != "x" ; then \ for file in $$files ; do \ destdir=`dirname $(abs_builddir)/$$file`; \ @@ -118,7 +119,7 @@ scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ scanobj_options=""; \ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ scanobj_options="--verbose"; \ fi; \ @@ -162,17 +163,17 @@ GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V)) GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references"; -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \ mkhtml_options=""; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkhtml_options="$$mkhtml_options --verbose"; \ fi; \ fi; \ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ fi; \ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) @@ -194,11 +195,11 @@ GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V)) GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY)) GTK_DOC_V_PDF_0=@echo " DOC Building PDF"; -pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) +pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files) $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \ mkpdf_options=""; \ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ - if test "$(?)" = "0"; then \ + if test "$$?" = "0"; then \ if test "x$(V)" = "x1"; then \ mkpdf_options="$$mkpdf_options --verbose"; \ fi; \ @@ -223,12 +224,15 @@ clean-local: @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \ rm -f $(DOC_MODULE).types; \ fi + @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \ + rm -f $(DOC_MODULE)-sections.txt; \ + fi distclean-local: @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - rm -f $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types; \ + rm -f $(SETUP_FILES) $(DOC_MODULE).types; \ fi maintainer-clean-local: diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 48fc8068..2a362d9a 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -429,6 +429,8 @@ VipsImage *vips_image_new_from_file_raw( const char *filename, int xsize, int ysize, int bands, guint64 offset ); VipsImage *vips_image_new_from_memory( const void *data, size_t size, int width, int height, int bands, VipsBandFormat format ); +VipsImage *vips_image_new_from_memory_copy( const void *data, size_t size, + int width, int height, int bands, VipsBandFormat format ); VipsImage *vips_image_new_from_buffer( const void *buf, size_t len, const char *option_string, ... ) __attribute__((sentinel)); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 5969857b..a68d2781 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -6,6 +6,8 @@ * - vips_image_write() didn't ref non-partial sources * 18/4/15 * - add vips_image_copy_memory() + * 25/11/15 + * - add vips_image_new_from_memory_copy() */ /* @@ -1979,9 +1981,15 @@ vips_image_new_from_file_raw( const char *filename, * responsibility for the area of memory, it's up to you to make sure it's * freed when the image is closed. See for example #VipsObject::close. * + * Because VIPS is "borrowing" @data from the caller, this function is + * extremely dangerous. Unless you are very careful, you will get crashes or + * memory corruption. Use vips_image_new_from_memory_copy() instead if you are + * at all unsure. + * * Use vips_copy() to set other image properties. * - * See also: vips_image_new(), vips_image_write_to_memory(). + * See also: vips_image_new(), vips_image_write_to_memory(), + * vips_image_new_from_memory_copy(). * * Returns: (transfer full): the new #VipsImage, or %NULL on error. */ @@ -2014,7 +2022,7 @@ vips_image_new_from_memory( const void *data, size_t size, if( size > 0 && size < VIPS_IMAGE_SIZEOF_IMAGE( image ) ) { vips_error( "VipsImage", - _( "buffer too small --- " + _( "memory area too small --- " "should be %zd bytes, you passed %zd" ), VIPS_IMAGE_SIZEOF_IMAGE( image ), size ); VIPS_UNREF( image ); @@ -2024,6 +2032,54 @@ vips_image_new_from_memory( const void *data, size_t size, return( image ); } +static void +vips_image_new_from_memory_copy_cb( VipsImage *image, void *data_copy ) +{ + vips_tracked_free( data_copy ); +} + +/** + * vips_image_new_from_memory_copy: + * @data: (array length=size) (element-type guint8) (transfer none): start of memory area + * @size: length of memory area + * @width: image width + * @height: image height + * @bands: image bands (or bytes per pixel) + * @format: image format + * + * Like vips_image_new_from_memory(), but VIPS will make a copy of the memory + * area. This + * means more memory use and an extra copy operation, but is much simpler and + * safer. + * + * See also: vips_image_new_from_memory(). + * + * Returns: (transfer full): the new #VipsImage, or %NULL on error. + */ +VipsImage * +vips_image_new_from_memory_copy( const void *data, size_t size, + int width, int height, int bands, VipsBandFormat format ) +{ + void *data_copy; + VipsImage *image; + + vips_check_init(); + + if( !(data_copy = vips_tracked_malloc( size )) ) + return( NULL ); + memcpy( data_copy, data, size ); + if( !(image = vips_image_new_from_memory( data_copy, size, + width, height, bands, format )) ) { + vips_tracked_free( data_copy ); + return( NULL ); + } + + g_signal_connect( image, "close", + G_CALLBACK( vips_image_new_from_memory_copy_cb ), data_copy ); + + return( image ); +} + /** * vips_image_new_from_buffer: * @buf: (array length=len) (element-type guint8) (transfer none): image data