Merge branch 'master' of github.com:jcupitt/libvips
This commit is contained in:
commit
3570f61f3d
@ -14,6 +14,8 @@
|
||||
- added vips_mapim() ... resample with an index image, plus test
|
||||
- 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
|
||||
|
@ -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:
|
||||
|
@ -434,14 +434,14 @@ vips_max_class_init( VipsMaxClass *class )
|
||||
_( "Horizontal position of maximum" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMax, x ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "y", 3,
|
||||
_( "y" ),
|
||||
_( "Vertical position of maximum" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMax, y ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "size", 4,
|
||||
_( "Size" ),
|
||||
|
@ -437,14 +437,14 @@ vips_min_class_init( VipsMinClass *class )
|
||||
_( "Horizontal position of minimum" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMin, x ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "y", 3,
|
||||
_( "y" ),
|
||||
_( "Vertical position of minimum" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMin, y ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "size", 4,
|
||||
_( "Size" ),
|
||||
|
@ -285,21 +285,21 @@ vips_copy_class_init( VipsCopyClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, width ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 4,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, height ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "bands", 5,
|
||||
_( "Bands" ),
|
||||
_( "Number of bands in image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, bands ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "format", 6,
|
||||
_( "Format" ),
|
||||
@ -341,14 +341,14 @@ vips_copy_class_init( VipsCopyClass *class )
|
||||
_( "Horizontal offset of origin" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, xoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
-VIPS_MAX_COORD, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "yoffset", 12,
|
||||
_( "Yoffset" ),
|
||||
_( "Vertical offset of origin" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, yoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
-VIPS_MAX_COORD, VIPS_MAX_COORD, 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -126,14 +126,14 @@ vips_wrap_class_init( VipsWrapClass *class )
|
||||
_( "Left edge of input in output" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsWrap, x ),
|
||||
-1000000, 1000000, 0 );
|
||||
-VIPS_MAX_COORD, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "y", 4,
|
||||
_( "y" ),
|
||||
_( "Top edge of input in output" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsWrap, y ),
|
||||
-1000000, 1000000, 0 );
|
||||
-VIPS_MAX_COORD, VIPS_MAX_COORD, 0 );
|
||||
|
||||
}
|
||||
|
||||
|
@ -130,21 +130,21 @@ vips_black_class_init( VipsBlackClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsBlack, width ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 5,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsBlack, height ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "bands", 6,
|
||||
_( "Bands" ),
|
||||
_( "Number of bands in image" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsBlack, bands ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -103,14 +103,14 @@ vips_fractsurf_class_init( VipsFractsurfClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsFractsurf, width ),
|
||||
1, 1000000, 64 );
|
||||
1, VIPS_MAX_COORD, 64 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 5,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsFractsurf, height ),
|
||||
1, 1000000, 64 );
|
||||
1, VIPS_MAX_COORD, 64 );
|
||||
|
||||
VIPS_ARG_DOUBLE( class, "fractal_dimension", 8,
|
||||
_( "Fractal dimension" ),
|
||||
|
@ -154,14 +154,14 @@ vips_gaussnoise_class_init( VipsGaussnoiseClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsGaussnoise, width ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 5,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsGaussnoise, height ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_DOUBLE( class, "mean", 6,
|
||||
_( "Mean" ),
|
||||
|
@ -144,14 +144,14 @@ vips_point_class_init( VipsPointClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsPoint, width ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 3,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsPoint, height ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_BOOL( class, "uchar", 4,
|
||||
_( "Uchar" ),
|
||||
|
@ -298,7 +298,7 @@ vips_text_class_init( VipsTextClass *class )
|
||||
_( "Maximum image width in pixels" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsText, width ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "align", 7,
|
||||
_( "Align" ),
|
||||
|
@ -194,35 +194,35 @@ vips_xyz_class_init( VipsXyzClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsXyz, width ),
|
||||
1, 1000000, 64 );
|
||||
1, VIPS_MAX_COORD, 64 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 5,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsXyz, height ),
|
||||
1, 1000000, 64 );
|
||||
1, VIPS_MAX_COORD, 64 );
|
||||
|
||||
VIPS_ARG_INT( class, "csize", 6,
|
||||
_( "csize" ),
|
||||
_( "Size of third dimension" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsXyz, csize ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "dsize", 7,
|
||||
_( "dsize" ),
|
||||
_( "Size of fourth dimension" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsXyz, dsize ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "esize", 8,
|
||||
_( "esize" ),
|
||||
_( "Size of fifth dimension" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsXyz, esize ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,8 @@
|
||||
* - allow zip > 4gb if we have a recent libgsf
|
||||
* 9/9/15
|
||||
* - better overlap handling, thanks robclouth
|
||||
* 25/11/15
|
||||
* - always strip tile metadata
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1141,8 +1143,12 @@ strip_work( VipsThreadState *state, void *a )
|
||||
x = t;
|
||||
}
|
||||
|
||||
/* Hopefully no one will want the same metadata on all the tiles.
|
||||
*/
|
||||
vips_image_set_int( x, "hide-progress", 1 );
|
||||
if( vips_image_write_to_buffer( x, dz->suffix, &buf, &len, NULL ) ) {
|
||||
if( vips_image_write_to_buffer( x, dz->suffix, &buf, &len,
|
||||
"strip", TRUE,
|
||||
NULL ) ) {
|
||||
g_object_unref( x );
|
||||
return( -1 );
|
||||
}
|
||||
|
@ -124,21 +124,21 @@ vips_foreign_load_raw_class_init( VipsForeignLoadRawClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadRaw, width ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 11,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadRaw, height ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "bands", 12,
|
||||
_( "Bands" ),
|
||||
_( "Number of bands in image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadRaw, bands ),
|
||||
0, 1000000, 0 );
|
||||
0, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_UINT64( class, "offset", 13,
|
||||
_( "Size of header" ),
|
||||
|
@ -1126,9 +1126,9 @@ parse_header( ReadTiff *rtiff, VipsImage *out )
|
||||
*/
|
||||
|
||||
if( width <= 0 ||
|
||||
width > 10000000 ||
|
||||
width > VIPS_MAX_COORD ||
|
||||
height <= 0 ||
|
||||
height > 10000000 ) {
|
||||
height > VIPS_MAX_COORD ) {
|
||||
vips_error( "tiff2vips",
|
||||
"%s", _( "width/height out of range" ) );
|
||||
return( -1 );
|
||||
|
@ -69,7 +69,9 @@
|
||||
* - omit oversized jpeg markers
|
||||
* 15/7/15
|
||||
* - exif tags use @name, not @title
|
||||
* - set arbitrary exif tags from metadata
|
||||
* - set arbitrary exif tags from metadata
|
||||
* 25/11/15
|
||||
* - don't write JFIF headers if we are stripping, thanks Benjamin
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -940,9 +942,9 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
#ifdef HAVE_JPEG_EXT_PARAMS
|
||||
/* Reset compression profile to libjpeg defaults
|
||||
*/
|
||||
if( jpeg_c_int_param_supported( &write->cinfo, JINT_COMPRESS_PROFILE ) ) {
|
||||
jpeg_c_set_int_param( &write->cinfo, JINT_COMPRESS_PROFILE, JCP_FASTEST );
|
||||
}
|
||||
if( jpeg_c_int_param_supported( &write->cinfo, JINT_COMPRESS_PROFILE ) )
|
||||
jpeg_c_set_int_param( &write->cinfo,
|
||||
JINT_COMPRESS_PROFILE, JCP_FASTEST );
|
||||
#endif
|
||||
|
||||
/* Rest to default.
|
||||
@ -955,61 +957,62 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
write->cinfo.optimize_coding = optimize_coding;
|
||||
|
||||
#ifdef HAVE_JPEG_EXT_PARAMS
|
||||
/* Apply trellis quantisation to each 8x8 block. Infers "optimize_coding".
|
||||
/* Apply trellis quantisation to each 8x8 block. Implies
|
||||
* "optimize_coding".
|
||||
*/
|
||||
if( trellis_quant ) {
|
||||
if ( jpeg_c_bool_param_supported(
|
||||
&write->cinfo, JBOOLEAN_TRELLIS_QUANT ) ) {
|
||||
if( jpeg_c_bool_param_supported( &write->cinfo,
|
||||
JBOOLEAN_TRELLIS_QUANT ) ) {
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_TRELLIS_QUANT, TRUE );
|
||||
write->cinfo.optimize_coding = TRUE;
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s", _( "trellis_quant unsupported" ) );
|
||||
}
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "trellis_quant unsupported" ) );
|
||||
}
|
||||
/* Apply overshooting to samples with extreme values e.g. 0 & 255 for 8-bit.
|
||||
|
||||
/* Apply overshooting to samples with extreme values e.g. 0 & 255
|
||||
* for 8-bit.
|
||||
*/
|
||||
if( overshoot_deringing ) {
|
||||
if ( jpeg_c_bool_param_supported(
|
||||
&write->cinfo, JBOOLEAN_OVERSHOOT_DERINGING ) ) {
|
||||
if( jpeg_c_bool_param_supported( &write->cinfo,
|
||||
JBOOLEAN_OVERSHOOT_DERINGING ) )
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_OVERSHOOT_DERINGING, TRUE );
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s", _( "overshoot_deringing unsupported" ) );
|
||||
}
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "overshoot_deringing unsupported" ) );
|
||||
}
|
||||
/* Split the spectrum of DCT coefficients into separate scans.
|
||||
* Requires progressive output. Must be set before jpeg_simple_progression.
|
||||
* Requires progressive output. Must be set before
|
||||
* jpeg_simple_progression.
|
||||
*/
|
||||
if( optimize_scans ) {
|
||||
if( progressive ) {
|
||||
if( jpeg_c_bool_param_supported(
|
||||
&write->cinfo, JBOOLEAN_OPTIMIZE_SCANS ) ) {
|
||||
jpeg_c_set_bool_param( &write->cinfo, JBOOLEAN_OPTIMIZE_SCANS, TRUE );
|
||||
}
|
||||
else {
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring optimize_scans" ) );
|
||||
}
|
||||
if( jpeg_c_bool_param_supported( &write->cinfo,
|
||||
JBOOLEAN_OPTIMIZE_SCANS ) )
|
||||
jpeg_c_set_bool_param( &write->cinfo,
|
||||
JBOOLEAN_OPTIMIZE_SCANS, TRUE );
|
||||
else
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "Ignoring optimize_scans" ) );
|
||||
}
|
||||
else {
|
||||
else
|
||||
vips_warn( "vips2jpeg", "%s",
|
||||
_( "Ignoring optimize_scans for baseline" ) );
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Using jpeglib.h without extension parameters, warn of ignored options.
|
||||
/* Using jpeglib.h without extension parameters, warn of ignored
|
||||
* options.
|
||||
*/
|
||||
if ( trellis_quant ) {
|
||||
if( trellis_quant )
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring trellis_quant" ) );
|
||||
}
|
||||
if ( overshoot_deringing ) {
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring overshoot_deringing" ) );
|
||||
}
|
||||
if ( optimize_scans ) {
|
||||
if( overshoot_deringing )
|
||||
vips_warn( "vips2jpeg",
|
||||
"%s", _( "Ignoring overshoot_deringing" ) );
|
||||
if( optimize_scans )
|
||||
vips_warn( "vips2jpeg", "%s", _( "Ignoring optimize_scans" ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable progressive write.
|
||||
@ -1028,6 +1031,11 @@ write_vips( Write *write, int qfac, const char *profile,
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't write the APP0 JFIF headers if we are stripping.
|
||||
*/
|
||||
if( strip )
|
||||
write->cinfo.write_JFIF_header = FALSE;
|
||||
|
||||
/* Build compress tables.
|
||||
*/
|
||||
jpeg_start_compress( &write->cinfo, TRUE );
|
||||
|
@ -313,14 +313,14 @@ vips_hist_local_class_init( VipsHistLocalClass *class )
|
||||
_( "Window width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsHistLocal, width ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 5,
|
||||
_( "Height" ),
|
||||
_( "Window height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsHistLocal, height ),
|
||||
1, 1000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -47,6 +47,15 @@ extern "C" {
|
||||
#define VIPS_MAGIC_INTEL (0xb6a6f208U)
|
||||
#define VIPS_MAGIC_SPARC (0x08f2a6b6U)
|
||||
|
||||
/* We have a maximum value for a coordinate at various points for sanity
|
||||
* checking. For example, vips_black() has a max with and height. We use int
|
||||
* for width/height so we could go up to 2bn, but it's good to have a lower
|
||||
* value set so we can see crazy numbers early.
|
||||
*
|
||||
* This was 1m for a while, but someone found a use for a 4m wide image.
|
||||
*/
|
||||
#define VIPS_MAX_COORD (10000000)
|
||||
|
||||
typedef enum {
|
||||
VIPS_DEMAND_STYLE_ERROR = -1,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE,
|
||||
@ -429,6 +438,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));
|
||||
|
@ -193,7 +193,7 @@ vips__link_break_all( VipsImage *image )
|
||||
|
||||
typedef struct _LinkMap {
|
||||
gboolean upstream;
|
||||
int *serial;
|
||||
int serial;
|
||||
VipsSListMap2Fn fn;
|
||||
void *a;
|
||||
void *b;
|
||||
@ -206,9 +206,9 @@ vips__link_mapp( VipsImage *image, LinkMap *map )
|
||||
|
||||
/* Loop?
|
||||
*/
|
||||
if( image->serial == *map->serial )
|
||||
if( image->serial == map->serial )
|
||||
return( NULL );
|
||||
image->serial = *map->serial;
|
||||
image->serial = map->serial;
|
||||
|
||||
if( (res = map->fn( image, map->a, map->b )) )
|
||||
return( res );
|
||||
@ -240,8 +240,6 @@ vips__link_map( VipsImage *image, gboolean upstream,
|
||||
GSList *p;
|
||||
void *result;
|
||||
|
||||
serial += 1;
|
||||
|
||||
images = NULL;
|
||||
|
||||
/* The function might do anything, including removing images
|
||||
@ -251,13 +249,19 @@ vips__link_map( VipsImage *image, gboolean upstream,
|
||||
*/
|
||||
|
||||
map.upstream = upstream;
|
||||
map.serial = &serial;
|
||||
map.fn = (VipsSListMap2Fn) vips__link_map_cb;
|
||||
map.a = (void *) &images;
|
||||
map.b = NULL;
|
||||
|
||||
/* We will be walking the tree of images and updating the ->serial
|
||||
* member. There will be intense confusion if two threads try to do
|
||||
* this at the same time.
|
||||
*/
|
||||
g_mutex_lock( vips__global_lock );
|
||||
|
||||
serial += 1;
|
||||
map.serial = serial;
|
||||
|
||||
vips__link_mapp( image, &map );
|
||||
|
||||
for( p = images; p; p = p->next )
|
||||
|
@ -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()
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1117,21 +1119,21 @@ vips_image_class_init( VipsImageClass *class )
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_SET_ALWAYS,
|
||||
G_STRUCT_OFFSET( VipsImage, Xsize ),
|
||||
1, 1000000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 3,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_SET_ALWAYS,
|
||||
G_STRUCT_OFFSET( VipsImage, Ysize ),
|
||||
1, 1000000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_INT( class, "bands", 4,
|
||||
_( "Bands" ),
|
||||
_( "Number of bands in image" ),
|
||||
VIPS_ARGUMENT_SET_ALWAYS,
|
||||
G_STRUCT_OFFSET( VipsImage, Bands ),
|
||||
1, 1000000000, 1 );
|
||||
1, VIPS_MAX_COORD, 1 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "format", 5,
|
||||
_( "Format" ),
|
||||
@ -1173,14 +1175,14 @@ vips_image_class_init( VipsImageClass *class )
|
||||
_( "Horizontal offset of origin" ),
|
||||
VIPS_ARGUMENT_SET_ALWAYS,
|
||||
G_STRUCT_OFFSET( VipsImage, Xoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
-VIPS_MAX_COORD, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "yoffset", 11,
|
||||
_( "Yoffset" ),
|
||||
_( "Vertical offset of origin" ),
|
||||
VIPS_ARGUMENT_SET_ALWAYS,
|
||||
G_STRUCT_OFFSET( VipsImage, Yoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
-VIPS_MAX_COORD, VIPS_MAX_COORD, 0 );
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 12,
|
||||
_( "Filename" ),
|
||||
@ -1415,6 +1417,8 @@ vips_image_invalidate_all_cb( VipsImage *image )
|
||||
void
|
||||
vips_image_invalidate_all( VipsImage *image )
|
||||
{
|
||||
VIPS_DEBUG_MSG( "vips_image_invalidate_all: %p\n", image );
|
||||
|
||||
(void) vips__link_map( image, FALSE,
|
||||
(VipsSListMap2Fn) vips_image_invalidate_all_cb, NULL, NULL );
|
||||
}
|
||||
@ -1979,9 +1983,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 +2024,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 +2034,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
|
||||
|
@ -7,6 +7,9 @@
|
||||
* mem use
|
||||
* 20/1/14
|
||||
* - bg render thread quits on shutdown
|
||||
* 1/12/15
|
||||
* - don't do anything to out or mask after they have closed
|
||||
* - only run the bg render thread when there's work to do
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -135,6 +138,11 @@ typedef struct _Render {
|
||||
/* Hash of tiles with positions. Tiles can be dirty or painted.
|
||||
*/
|
||||
GHashTable *tiles;
|
||||
|
||||
/* A shutdown flag. If ->out or ->mask close, we must no longer do
|
||||
* anything to them until we shut down too.
|
||||
*/
|
||||
gboolean shutdown;
|
||||
} Render;
|
||||
|
||||
/* Our per-thread state.
|
||||
@ -158,10 +166,6 @@ G_DEFINE_TYPE( RenderThreadState, render_thread_state, VIPS_TYPE_THREAD_STATE );
|
||||
*/
|
||||
static GThread *render_thread = NULL;
|
||||
|
||||
/* Number of renders with dirty tiles. render_thread queues up on this.
|
||||
*/
|
||||
static VipsSemaphore render_dirty_sem;
|
||||
|
||||
/* Set this to ask the render thread to quit.
|
||||
*/
|
||||
static gboolean render_kill = FALSE;
|
||||
@ -217,14 +221,8 @@ render_free( Render *render )
|
||||
g_assert( render->ref_count == 0 );
|
||||
|
||||
g_mutex_lock( render_dirty_lock );
|
||||
if( g_slist_find( render_dirty_all, render ) ) {
|
||||
if( g_slist_find( render_dirty_all, render ) )
|
||||
render_dirty_all = g_slist_remove( render_dirty_all, render );
|
||||
|
||||
/* We could vips_semaphore_upn( &render_dirty_sem, -1 ), but
|
||||
* what's the point. We'd just wake up the bg thread
|
||||
* for no reason.
|
||||
*/
|
||||
}
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
|
||||
vips_g_mutex_free( render->ref_count_lock );
|
||||
@ -275,22 +273,16 @@ render_unref( Render *render )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Wait for a render with dirty tiles.
|
||||
/* Get the first render with dirty tiles.
|
||||
*/
|
||||
static Render *
|
||||
render_dirty_get( void )
|
||||
{
|
||||
Render *render;
|
||||
|
||||
/* Wait for a render with dirty tiles.
|
||||
*/
|
||||
vips_semaphore_down( &render_dirty_sem );
|
||||
|
||||
g_mutex_lock( render_dirty_lock );
|
||||
|
||||
/* Just take the head of the jobs list ... we sort when we add. If
|
||||
* render_free() is called between our semaphore letting us in
|
||||
* and the _lock(), render_dirty_all can be NULL.
|
||||
/* Just take the head of the jobs list ... we sort when we add.
|
||||
*/
|
||||
render = NULL;
|
||||
if( render_dirty_all ) {
|
||||
@ -433,51 +425,22 @@ render_work( VipsThreadState *state, void *a )
|
||||
/* All downstream images must drop caches, since we've (effectively)
|
||||
* modified render->out.
|
||||
*/
|
||||
vips_image_invalidate_all( render->out );
|
||||
if( render->mask )
|
||||
if( !render->shutdown )
|
||||
vips_image_invalidate_all( render->out );
|
||||
if( !render->shutdown &&
|
||||
render->mask )
|
||||
vips_image_invalidate_all( render->mask );
|
||||
|
||||
/* Now clients can update.
|
||||
*/
|
||||
if( render->notify )
|
||||
if( !render->shutdown &&
|
||||
render->notify )
|
||||
render->notify( render->out, &tile->area, render->a );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
render_dirty_sort( Render *a, Render *b )
|
||||
{
|
||||
return( b->priority - a->priority );
|
||||
}
|
||||
|
||||
/* Add to the jobs list, if it has work to be done.
|
||||
*/
|
||||
static void
|
||||
render_dirty_put( Render *render )
|
||||
{
|
||||
g_mutex_lock( render_dirty_lock );
|
||||
|
||||
if( render->dirty ) {
|
||||
if( !g_slist_find( render_dirty_all, render ) ) {
|
||||
render_dirty_all = g_slist_prepend( render_dirty_all,
|
||||
render );
|
||||
render_dirty_all = g_slist_sort( render_dirty_all,
|
||||
(GCompareFunc) render_dirty_sort );
|
||||
|
||||
/* Ask the bg thread to stop and reschedule, if it's
|
||||
* running.
|
||||
*/
|
||||
VIPS_DEBUG_MSG_GREEN( "render_dirty_put: "
|
||||
"reschedule\n" );
|
||||
render_reschedule = TRUE;
|
||||
|
||||
vips_semaphore_up( &render_dirty_sem );
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
}
|
||||
static void render_dirty_put( Render *render );
|
||||
|
||||
/* Main loop for RenderThreads.
|
||||
*/
|
||||
@ -515,9 +478,15 @@ render_thread_main( void *client )
|
||||
render_unref( render );
|
||||
}
|
||||
|
||||
/* We are exiting, so render_thread must now be NULL.
|
||||
*/
|
||||
render_thread = NULL;
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Called from vips_shutdown().
|
||||
*/
|
||||
void
|
||||
vips__render_shutdown( void )
|
||||
{
|
||||
@ -532,36 +501,52 @@ vips__render_shutdown( void )
|
||||
GThread *thread;
|
||||
|
||||
thread = render_thread;
|
||||
render_thread = NULL;
|
||||
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
|
||||
render_reschedule = TRUE;
|
||||
render_kill = TRUE;
|
||||
vips_semaphore_up( &render_dirty_sem );
|
||||
(void) g_thread_join( thread );
|
||||
}
|
||||
else
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
}
|
||||
|
||||
/* Create our set of RenderThread. Assume we're single-threaded here.
|
||||
*/
|
||||
static int
|
||||
render_thread_create( void )
|
||||
static int
|
||||
render_dirty_sort( Render *a, Render *b )
|
||||
{
|
||||
if( !render_dirty_lock ) {
|
||||
render_dirty_lock = vips_g_mutex_new();
|
||||
vips_semaphore_init( &render_dirty_sem, 0, "render_dirty_sem" );
|
||||
return( b->priority - a->priority );
|
||||
}
|
||||
|
||||
/* Add to the jobs list, if it has work to be done.
|
||||
*/
|
||||
static void
|
||||
render_dirty_put( Render *render )
|
||||
{
|
||||
g_mutex_lock( render_dirty_lock );
|
||||
|
||||
if( render->dirty ) {
|
||||
if( !g_slist_find( render_dirty_all, render ) ) {
|
||||
render_dirty_all = g_slist_prepend( render_dirty_all,
|
||||
render );
|
||||
render_dirty_all = g_slist_sort( render_dirty_all,
|
||||
(GCompareFunc) render_dirty_sort );
|
||||
|
||||
/* Make sure there is a bg render thread, and get it to
|
||||
* reschedule.
|
||||
*/
|
||||
if( !render_thread ) {
|
||||
render_thread = vips_g_thread_new( "sink_screen",
|
||||
render_thread_main, NULL );
|
||||
g_assert( render_thread );
|
||||
}
|
||||
VIPS_DEBUG_MSG_GREEN( "render_dirty_put: "
|
||||
"reschedule\n" );
|
||||
render_reschedule = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( !render_thread ) {
|
||||
if( !(render_thread = vips_g_thread_new( "sink_screen",
|
||||
render_thread_main, NULL )) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
g_mutex_unlock( render_dirty_lock );
|
||||
}
|
||||
|
||||
static guint
|
||||
@ -590,6 +575,13 @@ render_close_cb( VipsImage *image, Render *render )
|
||||
{
|
||||
VIPS_DEBUG_MSG_AMBER( "render_close_cb\n" );
|
||||
|
||||
/* The output image or mask are closing. This render will stick
|
||||
* around for a while, since threads can still be running, but it
|
||||
* must no longer reference ->out or ->mask (for example, invalidating
|
||||
* them).
|
||||
*/
|
||||
render->shutdown = TRUE;
|
||||
|
||||
render_unref( render );
|
||||
|
||||
/* If this render is being worked on, we want to jog the bg thread,
|
||||
@ -639,6 +631,8 @@ render_new( VipsImage *in, VipsImage *out, VipsImage *mask,
|
||||
|
||||
render->dirty = NULL;
|
||||
|
||||
render->shutdown = FALSE;
|
||||
|
||||
/* Both out and mask must close before we can free the render.
|
||||
*/
|
||||
g_signal_connect( out, "close",
|
||||
@ -918,20 +912,12 @@ tile_copy( Tile *tile, VipsRegion *to )
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
image_start( IMAGE *out, void *a, void *b )
|
||||
{
|
||||
Render *render = (Render *) a;
|
||||
|
||||
return( vips_region_new( render->in ) );
|
||||
}
|
||||
|
||||
/* Loop over the output region, filling with data from cache.
|
||||
*/
|
||||
static int
|
||||
image_fill( VipsRegion *out, void *seq, void *a, void *b, gboolean *stop )
|
||||
{
|
||||
Render *render = (Render *) a;
|
||||
Render *render = (Render *) b;
|
||||
int tile_width = render->tile_width;
|
||||
int tile_height = render->tile_height;
|
||||
VipsRegion *reg = (VipsRegion *) seq;
|
||||
@ -979,16 +965,6 @@ image_fill( VipsRegion *out, void *seq, void *a, void *b, gboolean *stop )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
image_stop( void *seq, void *a, void *b )
|
||||
{
|
||||
VipsRegion *reg = (VipsRegion *) seq;
|
||||
|
||||
g_object_unref( reg );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* The mask image is 255 / 0 for the state of painted for each tile.
|
||||
*/
|
||||
static int
|
||||
@ -1038,6 +1014,12 @@ mask_fill( VipsRegion *out, void *seq, void *a, void *b, gboolean *stop )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_sink_screen_init( void )
|
||||
{
|
||||
render_dirty_lock = vips_g_mutex_new();
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_sink_screen:
|
||||
* @in: input image
|
||||
@ -1095,12 +1077,11 @@ vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask,
|
||||
int priority,
|
||||
VipsSinkNotify notify_fn, void *a )
|
||||
{
|
||||
static GOnce once = G_ONCE_INIT;
|
||||
|
||||
Render *render;
|
||||
|
||||
/* Make sure the bg work threads are ready.
|
||||
*/
|
||||
if( render_thread_create() )
|
||||
return( -1 );
|
||||
g_once( &once, (GThreadFunc) vips_sink_screen_init, NULL );
|
||||
|
||||
if( tile_width <= 0 || tile_height <= 0 ||
|
||||
max_tiles < -1 ) {
|
||||
@ -1131,7 +1112,7 @@ vips_sink_screen( VipsImage *in, VipsImage *out, VipsImage *mask,
|
||||
VIPS_DEBUG_MSG( "vips_sink_screen: max = %d, %p\n", max_tiles, render );
|
||||
|
||||
if( vips_image_generate( out,
|
||||
image_start, image_fill, image_stop, render, NULL ) )
|
||||
vips_start_one, image_fill, vips_stop_one, in, render ) )
|
||||
return( -1 );
|
||||
if( mask &&
|
||||
vips_image_generate( mask,
|
||||
|
@ -183,9 +183,9 @@ vips_mapim_region_minmax( VipsRegion *region, VipsRect *r, VipsRect *bounds )
|
||||
TYPE py = p1[1]; \
|
||||
\
|
||||
if( px < 0 || \
|
||||
px > resample->in->Xsize || \
|
||||
px >= resample->in->Xsize || \
|
||||
py < 0 || \
|
||||
py > resample->in->Ysize ) { \
|
||||
py >= resample->in->Ysize ) { \
|
||||
for( z = 0; z < ps; z++ ) \
|
||||
q[z] = 0; \
|
||||
} \
|
||||
|
Loading…
Reference in New Issue
Block a user