/** * vips_image_get_data: * @image: image to get data for * * Return a pointer to the image's pixel data, if possible. This can involve * allocating large amounts of memory and performing a long computation. Image * pixels are laid out in band-packed rows. * * Since this function modifies @image, it is not threadsafe. Only call it on * images which you are sure have not been shared with another thread. * * See also: vips_image_wio_input(), vips_image_copy_memory(). * * Returns: (transfer none): a pointer to pixel data, if possible. */ const void * vips_image_get_data( VipsImage *image ) { if( vips_image_wio_input( image ) ) return( NULL ); return( image->data ); }
static int vips_recomb_build( VipsObject *object ) { VipsConversion *conversion = (VipsConversion *) object; VipsRecomb *recomb = (VipsRecomb *) object; VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 ); if( VIPS_OBJECT_CLASS( vips_recomb_parent_class )->build( object ) ) return( -1 ); if( vips_image_pio_input( recomb->in ) || vips_check_uncoded( "VipsRecomb", recomb->in ) || vips_check_noncomplex( "VipsRecomb", recomb->in ) ) return( -1 ); if( vips_image_pio_input( recomb->m ) || vips_check_uncoded( "VipsRecomb", recomb->m ) || vips_check_noncomplex( "VipsRecomb", recomb->m ) || vips_check_mono( "VipsRecomb", recomb->m ) ) return( -1 ); if( recomb->in->Bands != recomb->m->Xsize ) { vips_error( "VipsRecomb", "%s", _( "bands in must equal matrix width" ) ); return( -1 ); } if( vips_cast( recomb->m, &t[0], VIPS_FORMAT_DOUBLE, NULL ) || vips_image_wio_input( t[0] ) ) return( -1 ); recomb->coeff = (double *) VIPS_IMAGE_ADDR( t[0], 0, 0 ); if( vips_image_copy_fields( conversion->out, recomb->in ) ) return( -1 ); vips_demand_hint( conversion->out, VIPS_DEMAND_STYLE_THINSTRIP, recomb->in, NULL ); conversion->out->Bands = recomb->m->Ysize; if( vips_bandfmt_isint( recomb->in->BandFmt ) ) conversion->out->BandFmt = VIPS_FORMAT_FLOAT; if( vips_image_generate( conversion->out, vips_start_one, vips_recomb_gen, vips_stop_one, recomb->in, recomb ) ) return( -1 ); return( 0 ); }
int vips__csv_write( VipsImage *in, const char *filename, const char *separator ) { FILE *fp; if( vips_check_mono( "vips2csv", in ) || vips_check_uncoded( "vips2csv", in ) || vips_image_wio_input( in ) ) return( -1 ); if( !(fp = vips__file_open_write( filename, TRUE )) ) return( -1 ); if( vips2csv( in, fp, separator ) ) { fclose( fp ); return( -1 ); } fclose( fp ); return( 0 ); }
/** * vips_check_matrix: * @domain: the originating domain for the error message * @im: image to check * @out: put image as in-memory doubles here * * Matrix images must have width and height less than 1000 and have 1 band. * * Return 0 if the image will pass as a matrix, or -1 and set an error * message otherwise. * * @out is set to be @im cast to double and stored in memory. Use * VIPS_IMAGE_ADDR() to address values in @out. @out is unreffed for you * when @im is unreffed. * * See also: vips_error(). * * Returns: 0 if OK, -1 otherwise. */ int vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out ) { if( im->Xsize > 1000 || im->Ysize > 1000 ) { vips_error( domain, "%s", _( "matrix image too large" ) ); return( -1 ); } if( im->Bands != 1 ) { vips_error( domain, "%s", _( "matrix image must have one band" ) ); return( -1 ); } if( vips_cast( im, out, VIPS_FORMAT_DOUBLE, NULL ) ) return( -1 ); vips_object_local( im, *out ); if( vips_image_wio_input( *out ) ) return( -1 ); return( 0 ); }
int vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen, int Q, gboolean lossless ) { webp_encoder encoder; if( vips_image_wio_input( in ) ) return( -1 ); if( in->Bands == 4 ) encoder = WebPEncodeRGBA; else encoder = WebPEncodeRGB; if( !(*olen = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ), in->Xsize, in->Ysize, VIPS_IMAGE_SIZEOF_LINE( in ), Q, (uint8_t **) obuf )) ) { vips_error( "vips2webp", "%s", _( "unable to encode" ) ); return( -1 ); } return( 0 ); }
int vips__webp_write_file( VipsImage *in, const char *filename, int Q, gboolean lossless ) { size_t len; uint8_t *buffer; FILE *fp; if( vips_image_wio_input( in ) ) return( -1 ); if( lossless ) { webp_encoder_lossless encoder; if( in->Bands == 4 ) encoder = WebPEncodeLosslessRGBA; else encoder = WebPEncodeLosslessRGB; if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ), in->Xsize, in->Ysize, VIPS_IMAGE_SIZEOF_LINE( in ), &buffer )) ) { vips_error( "vips2webp", "%s", _( "unable to encode" ) ); return( -1 ); } } else { webp_encoder encoder; if( in->Bands == 4 ) encoder = WebPEncodeRGBA; else encoder = WebPEncodeRGB; if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ), in->Xsize, in->Ysize, VIPS_IMAGE_SIZEOF_LINE( in ), Q, &buffer )) ) { vips_error( "vips2webp", "%s", _( "unable to encode" ) ); return( -1 ); } } if( !(fp = vips__file_open_write( filename, FALSE )) ) { free( buffer ); return( -1 ); } if( vips__file_write( buffer, len, 1, fp ) ) { fclose( fp ); free( buffer ); return( -1 ); } fclose( fp ); free( buffer ); return( 0 ); }
/* Write a VIPS image to PNG. */ static int write_vips( Write *write, int compress, int interlace, const char *profile, VipsForeignPngFilter filter ) { VipsImage *in = write->in; int bit_depth; int color_type; int interlace_type; int i, nb_passes; g_assert( in->BandFmt == VIPS_FORMAT_UCHAR || in->BandFmt == VIPS_FORMAT_USHORT ); g_assert( in->Coding == VIPS_CODING_NONE ); g_assert( in->Bands > 0 && in->Bands < 5 ); /* Catch PNG errors. */ if( setjmp( png_jmpbuf( write->pPng ) ) ) return( -1 ); /* Check input image. If we are writing interlaced, we need to make 7 * passes over the image. We advertise ourselves as seq, so to ensure * we only suck once from upstream, switch to WIO. */ if( interlace ) { if( vips_image_wio_input( in ) ) return( -1 ); } else { if( vips_image_pio_input( in ) ) return( -1 ); } if( compress < 0 || compress > 9 ) { vips_error( "vips2png", "%s", _( "compress should be in [0,9]" ) ); return( -1 ); } /* Set compression parameters. */ png_set_compression_level( write->pPng, compress ); /* Set row filter. */ png_set_filter( write->pPng, 0, filter ); bit_depth = in->BandFmt == VIPS_FORMAT_UCHAR ? 8 : 16; switch( in->Bands ) { case 1: color_type = PNG_COLOR_TYPE_GRAY; break; case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; case 3: color_type = PNG_COLOR_TYPE_RGB; break; case 4: color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; default: vips_error( "vips2png", _( "can't save %d band image as png" ), in->Bands ); return( -1 ); } interlace_type = interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; png_set_IHDR( write->pPng, write->pInfo, in->Xsize, in->Ysize, bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); /* Set resolution. libpng uses pixels per meter. */ png_set_pHYs( write->pPng, write->pInfo, VIPS_RINT( in->Xres * 1000 ), VIPS_RINT( in->Yres * 1000 ), PNG_RESOLUTION_METER ); /* Set ICC Profile. */ if( profile ) { if( strcmp( profile, "none" ) != 0 ) { void *data; size_t length; if( !(data = vips__file_read_name( profile, VIPS_ICC_DIR, &length )) ) return( -1 ); #ifdef DEBUG printf( "write_vips: " "attaching %zd bytes of ICC profile\n", length ); #endif /*DEBUG*/ png_set_iCCP( write->pPng, write->pInfo, "icc", PNG_COMPRESSION_TYPE_BASE, data, length ); } } else if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) { void *data; size_t length; if( vips_image_get_blob( in, VIPS_META_ICC_NAME, &data, &length ) ) return( -1 ); #ifdef DEBUG printf( "write_vips: attaching %zd bytes of ICC profile\n", length ); #endif /*DEBUG*/ png_set_iCCP( write->pPng, write->pInfo, "icc", PNG_COMPRESSION_TYPE_BASE, data, length ); } png_write_info( write->pPng, write->pInfo ); /* If we're an intel byte order CPU and this is a 16bit image, we need * to swap bytes. */ if( bit_depth > 8 && !vips_amiMSBfirst() ) png_set_swap( write->pPng ); if( interlace ) nb_passes = png_set_interlace_handling( write->pPng ); else nb_passes = 1; /* Write data. */ for( i = 0; i < nb_passes; i++ ) if( vips_sink_disc( in, write_png_block, write ) ) return( -1 ); /* The setjmp() was held by our background writer: reset it. */ if( setjmp( png_jmpbuf( write->pPng ) ) ) return( -1 ); png_write_end( write->pPng, write->pInfo ); return( 0 ); }