static int vips_similarity_build( VipsObject *object ) { VipsResample *resample = VIPS_RESAMPLE( object ); VipsSimilarity *similarity = (VipsSimilarity *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); double a, b, c, d; if( VIPS_OBJECT_CLASS( vips_similarity_parent_class )->build( object ) ) return( -1 ); a = similarity->scale * cos( VIPS_RAD( similarity->angle ) ); b = sin( VIPS_RAD( similarity->angle ) ); c = -b; d = a; if( vips_affine( resample->in, &t[0], a, b, c, d, "interpolate", similarity->interpolate, "odx", similarity->odx, "ody", similarity->ody, "idx", similarity->idx, "idy", similarity->idy, NULL ) || vips_image_write( t[0], resample->out ) ) return( -1 ); return( 0 ); }
static int vips_min_build( VipsObject *object ) { VipsStatistic *statistic = VIPS_STATISTIC( object ); VipsMin *min = (VipsMin *) object; if( VIPS_OBJECT_CLASS( vips_min_parent_class )->build( object ) ) return( -1 ); /* Don't set if there's no value (eg. if every pixel is NaN). This * will trigger an error later. */ if( min->set ) { double m; /* For speed we accumulate min^2 for complex. */ m = min->min; if( vips_bandfmt_iscomplex( vips_image_get_format( statistic->in ) ) ) m = sqrt( m ); /* We have to set the props via g_object_set() to stop vips * complaining they are unset. */ g_object_set( min, "out", m, "x", min->x, "y", min->y, NULL ); } return( 0 ); }
static int vips_bandjoin_build( VipsObject *object ) { VipsBandary *bandary = (VipsBandary *) object; VipsBandjoin *bandjoin = (VipsBandjoin *) object; if( bandjoin->in ) { bandary->in = vips_array_image_get( bandjoin->in, &bandary->n ); if( bandary->n == 1 ) return( vips_bandary_copy( bandary ) ); else { int i; bandary->out_bands = 0; for( i = 0; i < bandary->n; i++ ) if( bandary->in[i] ) bandary->out_bands += bandary->in[i]->Bands; } } if( VIPS_OBJECT_CLASS( vips_bandjoin_parent_class )->build( object ) ) return( -1 ); return( 0 ); }
static int vips_sequential_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsSequential *sequential = (VipsSequential *) object; VipsImage *t; VIPS_DEBUG_MSG( "vips_sequential_build\n" ); if( VIPS_OBJECT_CLASS( vips_sequential_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( sequential->in ) ) return( -1 ); if( vips_linecache( sequential->in, &t, "tile_height", sequential->tile_height, "access", sequential->access, NULL ) ) return( -1 ); vips_object_local( object, t ); if( vips_image_pipelinev( conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, t, NULL ) ) return( -1 ); if( vips_image_generate( conversion->out, vips_start_one, vips_sequential_generate, vips_stop_one, t, sequential ) ) return( -1 ); return( 0 ); }
static void vips_interpolate_bicubic_class_init( VipsInterpolateBicubicClass *iclass ) { VipsObjectClass *object_class = VIPS_OBJECT_CLASS( iclass ); VipsInterpolateClass *interpolate_class = VIPS_INTERPOLATE_CLASS( iclass ); object_class->nickname = "bicubic"; object_class->description = _( "Bicubic interpolation (Catmull-Rom)" ); interpolate_class->interpolate = vips_interpolate_bicubic_interpolate; interpolate_class->window_size = 4; /* Build the tables of pre-computed coefficients. */ for( int x = 0; x < VIPS_TRANSFORM_SCALE + 1; x++ ) { calculate_coefficients_catmull( (float) x / VIPS_TRANSFORM_SCALE, vips_bicubic_matrixf[x] ); for( int i = 0; i < 4; i++ ) vips_bicubic_matrixi[x][i] = vips_bicubic_matrixf[x][i] * VIPS_INTERPOLATE_SCALE; } }
static int vips_tile_cache_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsTileCache *cache = (VipsTileCache *) object; VIPS_DEBUG_MSG( "vips_tile_cache_build\n" ); if( VIPS_OBJECT_CLASS( vips_tile_cache_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( cache->in ) ) return( -1 ); if( vips_image_copy_fields( conversion->out, cache->in ) ) return( -1 ); vips_demand_hint( conversion->out, VIPS_DEMAND_STYLE_SMALLTILE, cache->in, NULL ); if( vips_image_generate( conversion->out, vips_start_one, vips_tile_cache_gen, vips_stop_one, cache->in, cache ) ) return( -1 ); return( 0 ); }
static int vips_statistic_build( VipsObject *object ) { VipsStatistic *statistic = VIPS_STATISTIC( object ); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); const char *domain = class->nickname; #ifdef DEBUG printf( "vips_statistic_build: " ); vips_object_print_name( object ); printf( "\n" ); #endif /*DEBUG*/ if( VIPS_OBJECT_CLASS( vips_statistic_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( statistic->in ) || vips_check_uncoded( domain, statistic->in ) ) return( -1 ); if( vips_sink( statistic->in, vips_statistic_scan_start, vips_statistic_scan, vips_statistic_scan_stop, statistic, NULL ) ) return( -1 ); return( 0 ); }
static int vips_worley_build( VipsObject *object ) { VipsCreate *create = VIPS_CREATE( object ); VipsWorley *worley = (VipsWorley *) object; if( VIPS_OBJECT_CLASS( vips_worley_parent_class )->build( object ) ) return( -1 ); /* Be careful if width is a multiple of cell_size. */ worley->cells_across = ROUND_UP( worley->width, worley->cell_size ) / worley->cell_size; worley->cells_down = ROUND_UP( worley->height, worley->cell_size ) / worley->cell_size; worley->seed = g_random_double() * 0xffffffffu; vips_image_init_fields( create->out, worley->width, worley->height, 1, VIPS_FORMAT_INT, VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W, 1.0, 1.0 ); vips_image_pipelinev( create->out, VIPS_DEMAND_STYLE_ANY, NULL ); if( vips_image_generate( create->out, vips_worley_start, vips_worley_gen, vips_worley_stop, worley, NULL ) ) return( -1 ); return( 0 ); }
static int vips_min_build( VipsObject *object ) { VipsStatistic *statistic = VIPS_STATISTIC( object ); VipsMin *min = (VipsMin *) object; double m; if( VIPS_OBJECT_CLASS( vips_min_parent_class )->build( object ) ) return( -1 ); /* For speed we accumulate min^2 for complex. */ m = min->min; if( vips_bandfmt_iscomplex( vips_image_get_format( statistic->in ) ) ) m = sqrt( m ); /* We have to set the props via g_object_set() to stop vips * complaining they are unset. */ g_object_set( min, "out", m, "x", min->x, "y", min->y, NULL ); return( 0 ); }
static int vips_region_build( VipsObject *object ) { VipsRegion *region = VIPS_REGION( object ); VipsImage *image = region->im; VIPS_DEBUG_MSG( "vips_region_build: %p\n", region ); if( VIPS_OBJECT_CLASS( vips_region_parent_class )->build( object ) ) return( -1 ); vips__region_take_ownership( region ); /* We're usually inside the ss lock anyway. But be safe ... */ VIPS_GATE_START( "vips_region_build: wait" ); g_mutex_lock( image->sslock ); VIPS_GATE_STOP( "vips_region_build: wait" ); image->regions = g_slist_prepend( image->regions, region ); g_mutex_unlock( image->sslock ); return( 0 ); }
static int vips_replicate_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsReplicate *replicate = (VipsReplicate *) object; if( VIPS_OBJECT_CLASS( vips_replicate_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( replicate->in ) ) return( -1 ); if( vips_image_copy_fields( conversion->out, replicate->in ) ) return( -1 ); vips_demand_hint( conversion->out, VIPS_DEMAND_STYLE_SMALLTILE, replicate->in, NULL ); conversion->out->Xsize *= replicate->across; conversion->out->Ysize *= replicate->down; if( vips_image_generate( conversion->out, vips_start_one, vips_replicate_gen, vips_stop_one, replicate->in, replicate ) ) return( -1 ); return( 0 ); }
static int vips_sequential_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsSequential *sequential = (VipsSequential *) object; VIPS_DEBUG_MSG( "vips_sequential_build\n" ); if( VIPS_OBJECT_CLASS( vips_sequential_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( sequential->in ) ) return( -1 ); if( vips_image_copy_fields( conversion->out, sequential->in ) ) return( -1 ); vips_demand_hint( conversion->out, VIPS_DEMAND_STYLE_FATSTRIP, sequential->in, NULL ); if( vips_image_generate( conversion->out, vips_start_one, vips_sequential_generate, vips_stop_one, sequential->in, sequential ) ) return( -1 ); return( 0 ); }
static int vips_merge_build( VipsObject *object ) { VipsMerge *merge = (VipsMerge *) object; g_object_set( merge, "out", vips_image_new(), NULL ); if( VIPS_OBJECT_CLASS( vips_merge_parent_class )->build( object ) ) return( -1 ); switch( merge->direction ) { case VIPS_DIRECTION_HORIZONTAL: if( im_lrmerge( merge->ref, merge->sec, merge->out, merge->dx, merge->dy, merge->mblend ) ) return( -1 ); break; case VIPS_DIRECTION_VERTICAL: if( im_tbmerge( merge->ref, merge->sec, merge->out, merge->dx, merge->dy, merge->mblend ) ) return( -1 ); break; default: g_assert( 0 ); } return( 0 ); }
static int vips_foreign_load_webp_build( VipsObject *object ) { if( VIPS_OBJECT_CLASS( vips_foreign_load_webp_parent_class )-> build( object ) ) return( -1 ); return( 0 ); }
static int vips_scale_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsScale *scale = (VipsScale *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 7 ); double mx; double mn; if( VIPS_OBJECT_CLASS( vips_scale_parent_class )->build( object ) ) return( -1 ); if( vips_stats( scale->in, &t[0], NULL ) ) return( -1 ); mn = *VIPS_MATRIX( t[0], 0, 0 ); mx = *VIPS_MATRIX( t[0], 1, 0 ); if( mn == mx ) { /* Range of zero: just return black. */ if( vips_black( &t[1], scale->in->Xsize, scale->in->Ysize, "bands", scale->in->Bands, NULL ) || vips_image_write( t[1], conversion->out ) ) return( -1 ); } else if( scale->log ) { double f = 255.0 / log10( 1.0 + pow( mx, scale->exp ) ); if( vips_pow_const1( scale->in, &t[2], scale->exp, NULL ) || vips_linear1( t[2], &t[3], 1.0, 1.0, NULL ) || vips_log10( t[3], &t[4], NULL ) || vips_linear1( t[4], &t[5], f, 0.0, "uchar", TRUE, NULL ) || vips_image_write( t[5], conversion->out ) ) return( -1 ); } else { double f = 255.0 / (mx - mn); /* Add .5 to get round-to-nearest. */ double a = -(mn * f) + 0.5; if( vips_linear1( scale->in, &t[2], f, a, "uchar", TRUE, NULL ) || vips_image_write( t[2], conversion->out ) ) return( -1 ); } return( 0 ); }
static int vips_bandary_build( VipsObject *object ) { VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( object ); VipsBandaryClass *class = VIPS_BANDARY_GET_CLASS( object ); VipsConversion *conversion = VIPS_CONVERSION( object ); VipsBandary *bandary = VIPS_BANDARY( object ); int i; VipsImage **decode; VipsImage **format; VipsImage **size; if( VIPS_OBJECT_CLASS( vips_bandary_parent_class )->build( object ) ) return( -1 ); if( bandary->n <= 0 ) { vips_error( object_class->nickname, "%s", _( "no input images" ) ); return( -1 ); } if( bandary->n > MAX_INPUT_IMAGES ) { vips_error( object_class->nickname, "%s", _( "too many input images" ) ); return( -1 ); } decode = (VipsImage **) vips_object_local_array( object, bandary->n ); format = (VipsImage **) vips_object_local_array( object, bandary->n ); size = (VipsImage **) vips_object_local_array( object, bandary->n ); for( i = 0; i < bandary->n; i++ ) if( vips_image_decode( bandary->in[i], &decode[i] ) ) return( -1 ); if( vips__formatalike_vec( decode, format, bandary->n ) || vips__sizealike_vec( format, size, bandary->n ) ) return( -1 ); bandary->ready = size; if( vips_image_pipeline_array( conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, bandary->ready ) ) return( -1 ); conversion->out->Bands = bandary->out_bands; if( class->format_table ) conversion->out->BandFmt = class->format_table[bandary->ready[0]->BandFmt]; if( vips_image_generate( conversion->out, vips_start_many, vips_bandary_gen, vips_stop_many, bandary->ready, bandary ) ) return( -1 ); return( 0 ); }
/* JPEGs get special treatment. libjpeg supports fast shrink-on-read, * so if we have a JPEG, we can ask VIPS to load a lower resolution * version. */ static int thumbnail( const char *filename ) { VipsFormatClass *format; int shrink; if( verbose ) printf( "thumbnailing %s\n", filename ); if( !(format = vips_format_for_file( filename )) ) return( -1 ); if( verbose ) printf( "detected format as %s\n", VIPS_OBJECT_CLASS( format )->nickname ); shrink = 1; if( strcmp( VIPS_OBJECT_CLASS( format )->nickname, "jpeg" ) == 0 ) { IMAGE *im; /* This will just read in the header and is quick. */ if( !(im = im_open( filename, "r" )) ) return( -1 ); shrink = calculate_shrink( im->Xsize, im->Ysize, NULL ); im_close( im ); if( shrink > 8 ) shrink = 8; else if( shrink > 4 ) shrink = 4; else if( shrink > 2 ) shrink = 2; else shrink = 1; if( verbose ) printf( "using fast jpeg shrink, factor %d\n", shrink ); } return( thumbnail2( filename, shrink ) ); }
static int sink_thread_state_build( VipsObject *object ) { SinkThreadState *state = (SinkThreadState *) object; Sink *sink = (Sink *) ((VipsThreadState *) state)->a; if( !(state->reg = vips_region_new( sink->t )) || sink_call_start( sink, state ) ) return( -1 ); return( VIPS_OBJECT_CLASS( sink_thread_state_parent_class )->build( object ) ); }
static int vips_labelregions_build( VipsObject *object ) { VipsMorphology *morphology = VIPS_MORPHOLOGY( object ); VipsImage *in = morphology->in; VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 ); VipsImage *mask; int segments; int *m; int x, y; if( VIPS_OBJECT_CLASS( vips_labelregions_parent_class )-> build( object ) ) return( -1 ); /* Create the zero mask image in memory. */ mask = vips_image_new_memory(); g_object_set( object, "mask", mask, NULL ); if( vips_black( &t[0], in->Xsize, in->Ysize, NULL ) || vips_cast( t[0], &t[1], VIPS_FORMAT_INT, NULL ) || vips_image_write( t[1], mask ) ) return( -1 ); segments = 1; m = (int *) mask->data; for( y = 0; y < mask->Ysize; y++ ) { for( x = 0; x < mask->Xsize; x++ ) { if( !m[x] ) { /* Use a direct path for speed. */ if( vips__draw_flood_direct( mask, in, segments, x, y ) ) return( -1 ); segments += 1; } } m += mask->Xsize; } g_object_set( object, "segments", segments, NULL ); return( 0 ); }
static int vips_ifthenelse_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsIfthenelse *ifthenelse = (VipsIfthenelse *) object; VipsImage *all[3]; VipsImage **band = (VipsImage **) vips_object_local_array( object, 3 ); VipsImage **size = (VipsImage **) vips_object_local_array( object, 3 ); VipsImage **format = (VipsImage **) vips_object_local_array( object, 3 ); if( VIPS_OBJECT_CLASS( vips_ifthenelse_parent_class )->build( object ) ) return( -1 ); /* We have to have the condition image last since we want the output * image to inherit its properties from the then/else parts. */ all[0] = ifthenelse->in1; all[1] = ifthenelse->in2; all[2] = ifthenelse->cond; /* No need to check input images, sizealike and friends will do this * for us. */ /* Cast our input images up to a common bands and size. */ if( vips__bandalike_vec( "VipsIfthenelse", all, band, 3, 0 ) || vips__sizealike_vec( band, size, 3 ) ) return( -1 ); /* Condition is cast to uchar, then/else to a common type. */ if( vips_cast( size[2], &format[2], VIPS_FORMAT_UCHAR, NULL ) ) return( -1 ); if( vips__formatalike_vec( size, format, 2 ) ) return( -1 ); if( vips_image_copy_fields_array( conversion->out, format ) ) return( -1 ); vips_demand_hint_array( conversion->out, VIPS_DEMAND_STYLE_SMALLTILE, format ); if( vips_image_generate( conversion->out, vips_start_many, vips_ifthenelse_gen, vips_stop_many, format, ifthenelse ) ) return( -1 ); return( 0 ); }
static int vips_abs_build( VipsObject *object ) { VipsUnary *unary = (VipsUnary *) object; if( unary->in && vips_band_format_isuint( unary->in->BandFmt ) ) return( vips_unary_copy( unary ) ); if( VIPS_OBJECT_CLASS( vips_abs_parent_class )->build( object ) ) return( -1 ); return( 0 ); }
static int vips_XYZ2scRGB_build( VipsObject *object ) { if( VIPS_OBJECT_CLASS( vips_XYZ2scRGB_parent_class )->build( object ) ) return( -1 ); /* We've converted to sRGB without a profile. We must remove any ICC * profile left over from import or there will be a mismatch between * pixel values and the attached profile. */ vips_image_remove( VIPS_COLOUR( object )->out, VIPS_META_ICC_NAME ); 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_similarity_build( VipsObject *object ) { VipsResample *resample = VIPS_RESAMPLE( object ); VipsSimilarity *similarity = (VipsSimilarity *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 4 ); if( VIPS_OBJECT_CLASS( vips_similarity_parent_class )->build( object ) ) return( -1 ); /* Use vips_reduce(), if we can. */ if( similarity->interpolate && strcmp( VIPS_OBJECT_GET_CLASS( similarity->interpolate )-> nickname, "bicubic" ) == 0 && similarity->angle == 0.0 && similarity->idx == 0.0 && similarity->idy == 0.0 && similarity->odx == 0.0 && similarity->ody == 0.0 ) { if( vips_reduce( resample->in, &t[0], 1.0 / similarity->scale, 1.0 / similarity->scale, NULL ) ) return( -1 ); } else { double a = similarity->scale * cos( VIPS_RAD( similarity->angle ) ); double b = similarity->scale * -sin( VIPS_RAD( similarity->angle ) ); double c = -b; double d = a; if( vips_affine( resample->in, &t[0], a, b, c, d, "interpolate", similarity->interpolate, "odx", similarity->odx, "ody", similarity->ody, "idx", similarity->idx, "idy", similarity->idy, NULL ) ) return( -1 ); } if( vips_image_write( t[0], resample->out ) ) 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 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_bandary_build( VipsObject *object ) { VipsConversion *conversion = VIPS_CONVERSION( object ); VipsBandary *bandary = (VipsBandary *) object; int i; VipsImage **format; VipsImage **size; if( VIPS_OBJECT_CLASS( vips_bandary_parent_class )->build( object ) ) return( -1 ); if( bandary->n <= 0 ) { vips_error( "VipsBandary", "%s", _( "no input images" ) ); return( -1 ); } if( bandary->n > MAX_INPUT_IMAGES ) { vips_error( "VipsBandary", "%s", _( "too many input images" ) ); return( -1 ); } if( vips_image_pio_output( conversion->out ) ) return( -1 ); for( i = 0; i < bandary->n; i++ ) if( vips_image_pio_input( bandary->in[i] ) || vips_check_uncoded( "VipsBandary", bandary->in[i] ) ) return( -1 ); format = (VipsImage **) vips_object_local_array( object, bandary->n ); size = (VipsImage **) vips_object_local_array( object, bandary->n ); if( vips__formatalike_vec( bandary->in, format, bandary->n ) || vips__sizealike_vec( format, size, bandary->n ) ) return( -1 ); bandary->ready = size; if( vips_image_copy_fields_array( conversion->out, bandary->ready ) ) return( -1 ); vips_demand_hint_array( conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, bandary->ready ); conversion->out->Bands = bandary->out_bands; if( vips_image_generate( conversion->out, vips_start_many, vips_bandary_gen, vips_stop_many, bandary->ready, bandary ) ) return( -1 ); return( 0 ); }
static int vips_foreign_save_matrix_build( VipsObject *object ) { VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSaveMatrix *matrix = (VipsForeignSaveMatrix *) object; if( VIPS_OBJECT_CLASS( vips_foreign_save_matrix_parent_class )-> build( object ) ) return( -1 ); if( vips__matrix_write( save->ready, matrix->filename ) ) return( -1 ); return( 0 ); }
static int vips_foreign_save_vips_build( VipsObject *object ) { VipsForeignSave *save = (VipsForeignSave *) object; VipsForeignSaveVips *vips = (VipsForeignSaveVips *) object; if( VIPS_OBJECT_CLASS( vips_foreign_save_vips_parent_class )-> build( object ) ) return( -1 ); if( vips_image_write_to_file( save->ready, vips->filename ) ) return( -1 ); return( 0 ); }
static int vips_shrink_build( VipsObject *object ) { VipsResample *resample = VIPS_RESAMPLE( object ); VipsShrink *shrink = (VipsShrink *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 3 ); int xshrink_int; int yshrink_int; if( VIPS_OBJECT_CLASS( vips_shrink_parent_class )->build( object ) ) return( -1 ); xshrink_int = (int) shrink->xshrink; yshrink_int = (int) shrink->yshrink; if( xshrink_int != shrink->xshrink || yshrink_int != shrink->yshrink ) { /* Shrink by int factors, affine to final size. */ int target_width = resample->in->Xsize / shrink->xshrink; int target_height = resample->in->Ysize / shrink->yshrink; double xresidual; double yresidual; if( vips_shrinkv( resample->in, &t[0], yshrink_int, NULL ) || vips_shrinkh( t[0], &t[1], xshrink_int, NULL ) ) return( -1 ); xresidual = (double) target_width / t[1]->Xsize; yresidual = (double) target_height / t[1]->Ysize; if( vips_affine( t[1], &t[2], xresidual, 0.0, 0.0, yresidual, NULL ) || vips_image_write( t[2], resample->out ) ) return( -1 ); } else { if( vips_shrinkv( resample->in, &t[0], shrink->yshrink, NULL ) || vips_shrinkh( t[0], &t[1], shrink->xshrink, NULL ) || vips_image_write( t[1], resample->out ) ) return( -1 ); } return( 0 ); }