static int vips_foreign_save_tiff_build( VipsObject *object ) { VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSaveTiff *tiff = (VipsForeignSaveTiff *) object; const char *p; if( VIPS_OBJECT_CLASS( vips_foreign_save_tiff_parent_class )-> build( object ) ) return( -1 ); /* Default xres/yres to the values from the image. */ if( !vips_object_argument_isset( object, "xres" ) ) tiff->xres = save->ready->Xres * 10.0; if( !vips_object_argument_isset( object, "yres" ) ) tiff->yres = save->ready->Yres * 10.0; /* resunit param overrides resunit metadata. */ if( !vips_object_argument_isset( object, "resunit" ) && vips_image_get_typeof( save->ready, VIPS_META_RESOLUTION_UNIT ) && !vips_image_get_string( save->ready, VIPS_META_RESOLUTION_UNIT, &p ) && vips_isprefix( "in", p ) ) tiff->resunit = VIPS_FOREIGN_TIFF_RESUNIT_INCH; if( tiff->resunit == VIPS_FOREIGN_TIFF_RESUNIT_INCH ) { tiff->xres *= 2.54; tiff->yres *= 2.54; } if( vips__tiff_write( save->ready, tiff->filename, tiff->compression, tiff->Q, tiff->predictor, tiff->profile, tiff->tile, tiff->tile_width, tiff->tile_height, tiff->pyramid, tiff->squash, tiff->miniswhite, tiff->resunit, tiff->xres, tiff->yres, tiff->bigtiff, tiff->rgbjpeg, tiff->properties ) ) return( -1 ); return( 0 ); }
static int vips_foreign_load_pdf_build( VipsObject *object ) { VipsForeignLoadPdf *pdf = (VipsForeignLoadPdf *) object; if( !vips_object_argument_isset( object, "scale" ) ) pdf->scale = pdf->dpi / 72.0; if( VIPS_OBJECT_CLASS( vips_foreign_load_pdf_parent_class )-> build( object ) ) return( -1 ); return( 0 ); }
static int vips_foreign_load_svg_build( VipsObject *object ) { VipsForeignLoadSvg *svg = (VipsForeignLoadSvg *) object; if( !vips_object_argument_isset( object, "scale" ) ) svg->scale = svg->dpi / 72.0; if( VIPS_OBJECT_CLASS( vips_foreign_load_svg_parent_class )-> build( object ) ) return( -1 ); return( 0 ); }
static void * vips_object_equal_arg( VipsObject *object, GParamSpec *pspec, VipsArgumentClass *argument_class, VipsArgumentInstance *argument_instance, void *a, void *b ) { VipsObject *other = (VipsObject *) a; const char *name = g_param_spec_get_name( pspec ); GType type = G_PARAM_SPEC_VALUE_TYPE( pspec ); GValue v1 = { 0, }; GValue v2 = { 0, }; gboolean equal; /* Only test assigned input constructor args. */ if( !(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) || !(argument_class->flags & VIPS_ARGUMENT_INPUT) || !argument_instance->assigned ) return( NULL ); /* If this is an optional arg, we need to check that this was * assigned on @other as well. */ if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) && !vips_object_argument_isset( other, name ) ) /* Optional and was not set on other ... we've found a * difference! */ return( object ); g_value_init( &v1, type ); g_value_init( &v2, type ); g_object_get_property( G_OBJECT( object ), name, &v1 ); g_object_get_property( G_OBJECT( other ), name, &v2 ); equal = vips_value_equal( pspec, &v1, &v2 ); g_value_unset( &v1 ); g_value_unset( &v2 ); /* Stop (return non-NULL) if we've found a difference. */ return( !equal ? object : NULL ); }
static int vips_colourspace_build( VipsObject *object ) { VipsColourspace *colourspace = (VipsColourspace *) object; int i, j; VipsImage *x; VipsImage **t = (VipsImage **) vips_object_local_array( object, 1 ); VipsImage **pipe = (VipsImage **) vips_object_local_array( object, MAX_STEPS ); VipsInterpretation interpretation; /* Verify that all input args have been set. */ if( VIPS_OBJECT_CLASS( vips_colourspace_parent_class )-> build( object ) ) return( -1 ); x = colourspace->in; /* Unpack radiance-coded images. We can't use interpretation for this, * since rad images can be scRGB or XYZ. */ if( x->Coding == VIPS_CODING_RAD ) { if( vips_rad2float( x, &t[0], NULL ) ) return( -1 ); x = t[0]; } if( vips_object_argument_isset( object, "source_space" ) ) interpretation = colourspace->source_space; else interpretation = vips_image_guess_interpretation( x ); /* Treat RGB as sRGB. If you want some other treatment, * you'll need to use the icc funcs. */ if( interpretation == VIPS_INTERPRETATION_RGB ) interpretation = VIPS_INTERPRETATION_sRGB; /* No conversion necessary. */ if( interpretation == colourspace->space ) { g_object_set( colourspace, "out", vips_image_new(), NULL ); return( vips_image_write( colourspace->in, colourspace->out ) ); } for( i = 0; i < VIPS_NUMBER( vips_colour_routes ); i++ ) if( vips_colour_routes[i].from == interpretation && vips_colour_routes[i].to == colourspace->space ) break; if( i == VIPS_NUMBER( vips_colour_routes ) ) { vips_error( "vips_colourspace", _( "no known route between '%s' and '%s'" ), vips_enum_nick( VIPS_TYPE_INTERPRETATION, interpretation ), vips_enum_nick( VIPS_TYPE_INTERPRETATION, colourspace->space ) ); return( -1 ); } for( j = 0; vips_colour_routes[i].route[j]; j++ ) { if( vips_colour_routes[i].route[j]( x, &pipe[j], NULL ) ) return( -1 ); x = pipe[j]; } g_object_set( colourspace, "out", vips_image_new(), NULL ); if( vips_image_write( x, colourspace->out ) ) return( -1 ); return( 0 ); }
static int vips_resize_build( VipsObject *object ) { VipsResample *resample = VIPS_RESAMPLE( object ); VipsResize *resize = (VipsResize *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); VipsImage *in; int window_size; int int_shrink; int int_shrink_width; double residual; double sigma; if( VIPS_OBJECT_CLASS( vips_resize_parent_class )->build( object ) ) return( -1 ); if( !vips_object_argument_isset( object, "interpolate" ) ) { VipsInterpolate *interpolate; char *nick; if( vips_type_find( "VipsInterpolate", "bicubic" ) ) nick = "bicubic"; else nick = "bilinear"; interpolate = vips_interpolate_new( nick ); g_object_set( object, "interpolate", interpolate, NULL ); VIPS_UNREF( interpolate ); } in = resample->in; window_size = resize->interpolate ? vips_interpolate_get_window_size( resize->interpolate ) : 2; /* If the factor is > 1.0, we need to zoom rather than shrink. * Just set the int part to 1 in this case. */ int_shrink = resize->scale > 1.0 ? 1 : floor( 1.0 / resize->scale ); /* We want to shrink by less for interpolators with larger windows. */ int_shrink = VIPS_MAX( 1, int_shrink / VIPS_MAX( 1, window_size / 2 ) ); /* Size after int shrink. */ int_shrink_width = in->Xsize / int_shrink; /* Therefore residual scale factor is. */ residual = (in->Xsize * resize->scale) / int_shrink_width; /* A copy for enlarge resize. */ if( vips_shrink( in, &t[0], int_shrink, int_shrink, NULL ) ) return( -1 ); in = t[0]; /* We want to make sure we read the image sequentially. * However, the convolution we may be doing later will force us * into SMALLTILE or maybe FATSTRIP mode and that will break * sequentiality. * * So ... read into a cache where tiles are scanlines, and make sure * we keep enough scanlines to be able to serve a line of tiles. * * We use a threaded tilecache to avoid a deadlock: suppose thread1, * evaluating the top block of the output, is delayed, and thread2, * evaluating the second block, gets here first (this can happen on * a heavily-loaded system). * * With an unthreaded tilecache (as we had before), thread2 will get * the cache lock and start evaling the second block of the shrink. * When it reaches the png reader it will stall until the first block * has been used ... but it never will, since thread1 will block on * this cache lock. */ if( int_shrink > 1 ) { int tile_width; int tile_height; int nlines; vips_get_tile_size( in, &tile_width, &tile_height, &nlines ); if( vips_tilecache( in, &t[6], "tile_width", in->Xsize, "tile_height", 10, "max_tiles", 1 + (nlines * 2) / 10, "access", VIPS_ACCESS_SEQUENTIAL, "threaded", TRUE, NULL ) ) return( -1 ); in = t[6]; } /* If the final affine will be doing a large downsample, we can get * nasty aliasing on hard edges. Blur before affine to smooth this out. * * Don't blur for very small shrinks, blur with radius 1 for x1.5 * shrinks, blur radius 2 for x2.5 shrinks and above, etc. */ sigma = ((1.0 / residual) - 0.5) / 1.5; if( residual < 1.0 && sigma > 0.1 ) { if( vips_gaussblur( in, &t[2], sigma, NULL ) ) return( -1 ); in = t[2]; } if( vips_affine( in, &t[3], residual, 0, 0, residual, "interpolate", resize->interpolate, "idx", resize->idx, "idy", resize->idy, NULL ) ) return( -1 ); in = t[3]; /* If we are upsampling, don't sharpen. */ if( int_shrink > 1 ) { t[5] = vips_image_new_matrixv( 3, 3, -1.0, -1.0, -1.0, -1.0, 32.0, -1.0, -1.0, -1.0, -1.0 ); vips_image_set_double( t[5], "scale", 24 ); if( vips_conv( in, &t[4], t[5], NULL ) ) return( -1 ); in = t[4]; } if( vips_image_write( in, resample->out ) ) return( -1 ); return( 0 ); }