/* Read a few bytes from the start of a file. For sniffing file types. * Filename may contain a mode. */ int vips__get_bytes( const char *filename, unsigned char buf[], int len ) { char name[FILENAME_MAX]; char mode[FILENAME_MAX]; int fd; /* Split off the mode part. */ im_filename_split( filename, name, mode ); /* File may not even exist (for tmp images for example!) * so no hasty messages. And the file might be truncated, so no error * on read either. */ if( (fd = open( name, MODE_READONLY )) == -1 ) return( 0 ); if( read( fd, buf, len ) != len ) { close( fd ); return( 0 ); } close( fd ); return( 1 ); }
int im_vips2png( IMAGE *in, const char *filename ) { int compression; int interlace; char *p, *q; char name[FILENAME_MAX]; char mode[FILENAME_MAX]; char buf[FILENAME_MAX]; /* Extract write mode from filename and parse. */ im_filename_split( filename, name, mode ); strcpy( buf, mode ); p = &buf[0]; compression = 6; interlace = 0; if( (q = im_getnextoption( &p )) ) compression = atoi( q ); if( (q = im_getnextoption( &p )) ) interlace = atoi( q ); return( vips_pngsave( in, name, "compression", compression, "interlace", interlace, NULL ) ); }
static int webp2vips( const char *name, IMAGE *out, gboolean header_only ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; im_filename_split( name, filename, mode ); #ifdef HAVE_LIBWEBP if( header_only ) { if( vips__webp_read_file_header( filename, out, 1 ) ) return( -1 ); } else { if( vips__webp_read_file( filename, out, 1 ) ) return( -1 ); } #else vips_error( "im_webp2vips", "%s", _( "no webp support in your libvips" ) ); return( -1 ); #endif /*HAVE_LIBWEBP*/ return( 0 ); }
int im_png2vips( const char *name, IMAGE *out ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; gboolean sequential; VipsImage *x; im_filename_split( name, filename, mode ); sequential = FALSE; p = &mode[0]; if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "seq", q ) ) sequential = TRUE; } if( vips_pngload( filename, &x, "sequential", sequential, NULL ) ) return( -1 ); if( vips_image_write( x, out ) ) { g_object_unref( x ); return( -1 ); } g_object_unref( x ); return( 0 ); }
/** * im_vips2csv: * @in: image to save * @filename: file to write to * * Save a CSV (comma-separated values) file. The image is written * one line of text per scanline. Complex numbers are written as * "(real,imaginary)" and will need extra parsing I guess. The image must * have a single band. * * Write options can be embedded in the filename. The options can be given * in any order and are: * * <itemizedlist> * <listitem> * <para> * <emphasis>sep:separator-string</emphasis> * The string to use to separate numbers in the output. * The default is "\\t" (tab). * </para> * </listitem> * </itemizedlist> * * For example: * * |[ * im_csv2vips( in, "fred.csv:sep:\t" ); * ]| * * Will write to fred.csv, separating numbers with tab characters. * * See also: #VipsFormat, im_csv2vips(), im_write_dmask(), im_vips2ppm(). * * Returns: 0 on success, -1 on error. */ int im_vips2csv( IMAGE *in, const char *filename ) { char *separator = "\t"; char name[FILENAME_MAX]; char mode[FILENAME_MAX]; FILE *fp; char *p, *q, *r; /* Parse mode string. */ im_filename_split( filename, name, mode ); p = &mode[0]; while( (q = im_getnextoption( &p )) ) { if( im_isprefix( "sep", q ) && (r = im_getsuboption( q )) ) separator = r; } if( im_incheck( in ) || im_check_mono( "im_vips2csv", in ) || im_check_uncoded( "im_vips2csv", in ) ) return( -1 ); if( !(fp = im__file_open_write( name, TRUE )) ) return( -1 ); if( vips2csv( in, fp, separator ) ) { fclose( fp ); return( -1 ); } fclose( fp ); return( 0 ); }
static int tiff2vips( const char *name, IMAGE *out, gboolean header_only ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; int page; int seq; im_filename_split( name, filename, mode ); page = 0; seq = 0; p = &mode[0]; if( (q = im_getnextoption( &p )) ) { page = atoi( q ); } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "seq", q ) ) seq = 1; } /* We need to be compatible with the pre-sequential mode * im_tiff2vips(). This returned a "t" if given a "p" image, since it * used writeline. * * If we're writing the image to a "p", switch it to a "t". And only * for non-tiled (strip) images which we write with writeline. * * Don't do this for header read, since we don't want to force a * malloc if all we are doing is looking at fields. */ #ifdef HAVE_TIFF if( !header_only && !seq && !vips__istifftiled( filename ) && out->dtype == VIPS_IMAGE_PARTIAL ) { if( vips__image_wio_output( out ) ) return( -1 ); } if( header_only ) { if( vips__tiff_read_header( filename, out, page ) ) return( -1 ); } else { if( vips__tiff_read( filename, out, page ) ) return( -1 ); } #else vips_error( "im_tiff2vips", _( "no TIFF support in your libvips" ) ); return( -1 ); #endif /*HAVE_TIFF*/ return( 0 ); }
static int isopenslide( const char *name ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; im_filename_split( name, filename, mode ); return( vips_foreign_is_a( "openslideload", filename ) ); }
static VipsFormatFlags tiff_flags( const char *name ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; im_filename_split( name, filename, mode ); return( vips_foreign_flags( "tiffload", filename ) ); }
static VipsFormatFlags openslide_flags( const char *name ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; im_filename_split( name, filename, mode ); return( (VipsFormatFlags) vips_foreign_flags( "openslideload", filename ) ); }
int im_jpeg2vips( const char *name, IMAGE *out ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; int shrink; gboolean fail_on_warn; VipsImage *t; /* By default, we ignore any warnings. We want to get as much of * the user's data as we can. */ fail_on_warn = FALSE; /* Parse the filename. */ im_filename_split( name, filename, mode ); p = &mode[0]; shrink = 1; if( (q = im_getnextoption( &p )) ) { shrink = atoi( q ); if( shrink != 1 && shrink != 2 && shrink != 4 && shrink != 8 ) { im_error( "im_jpeg2vips", _( "bad shrink factor %d" ), shrink ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "fail", q ) ) fail_on_warn = TRUE; } if( vips_jpegload( filename, &t, "shrink", shrink, "fail", fail_on_warn, NULL ) ) return( -1 ); if( vips_image_write( t, out ) ) { g_object_unref( t ); return( -1 ); } g_object_unref( t ); return( 0 ); }
/* Do a image call. */ static void apply_image_call( Reduce *rc, const char *name, HeapNode **arg, PElement *out ) { Heap *heap = rc->heap; PElement rhs; char buf[FILENAME_MAX]; char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *fn; Imageinfo *ii; /* Get string. */ PEPOINTRIGHT( arg[0], &rhs ); (void) reduce_get_string( rc, &rhs, buf, FILENAME_MAX ); /* The buf might be something like n3862.pyr.tif:1, ie. contain some * load options. Split and search just for the filename component. */ im_filename_split( buf, filename, mode ); /* Try to load image from given string. */ if( !(fn = path_find_file( filename )) ) reduce_throw( rc ); /* Reattach the mode and load. */ im_snprintf( buf, FILENAME_MAX, "%s:%s", fn, mode ); if( !(ii = imageinfo_new_input( main_imageinfogroup, NULL, heap, buf )) ) { IM_FREE( fn ); reduce_throw( rc ); } IM_FREE( fn ); PEPUTP( out, ELEMENT_MANAGED, ii ); MANAGED_UNREF( ii ); }
static int im_openslide2vips( const char *name, IMAGE *out ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; char *associated; int level; char *endptr; VipsImage *t; im_filename_split( name, filename, mode ); level = 0; associated = NULL; p = &mode[0]; if( (q = im_getnextoption( &p )) ) { level = strtoul( q, &endptr, 10 ); if( *endptr ) { vips_error( "openslide2vips", "%s", _( "level must be a number" ) ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) associated = q; if( vips_openslideload( filename, &t, "level", level, "associated", associated, NULL ) ) return( -1 ); if( vips_image_write( t, out ) ) { g_object_unref( t ); return( -1 ); } g_object_unref( t ); return( 0 ); }
static int jpeg2vips( const char *name, IMAGE *out, gboolean header_only ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; int shrink; int seq; gboolean fail_on_warn; /* By default, we ignore any warnings. We want to get as much of * the user's data as we can. */ fail_on_warn = FALSE; /* Parse the filename. */ im_filename_split( name, filename, mode ); p = &mode[0]; shrink = 1; seq = 0; if( (q = im_getnextoption( &p )) ) { shrink = atoi( q ); if( shrink != 1 && shrink != 2 && shrink != 4 && shrink != 8 ) { im_error( "im_jpeg2vips", _( "bad shrink factor %d" ), shrink ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "fail", q ) ) fail_on_warn = TRUE; } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "seq", q ) ) seq = 1; } /* Don't use vips_jpegload() ... we call the jpeg func directly in * order to avoid the foreign.c mechanisms for load-via-disc and stuff * like that. */ /* We need to be compatible with the pre-sequential mode * im_jpeg2vips(). This returned a "t" if given a "p" image, since it * used writeline. * * If we're writing the image to a "p", switch it to a "t". */ if( !header_only && !seq && out->dtype == VIPS_IMAGE_PARTIAL ) { if( vips__image_wio_output( out ) ) return( -1 ); } #ifdef HAVE_JPEG if( vips__jpeg_read_file( filename, out, header_only, shrink, fail_on_warn, TRUE ) ) return( -1 ); #else vips_error( "im_jpeg2vips", "%s", _( "no JPEG support in your libvips" ) ); return( -1 ); #endif /*HAVE_JPEG*/ return( 0 ); }
/** * im_vips2jpeg: * @in: image to save * @filename: file to write to * * Write a VIPS image to a file as JPEG. * * You can embed options in the filename. They have the form: * * |[ * filename.jpg:<emphasis>compression</emphasis>,<emphasis>profile</emphasis> * ]| * * <itemizedlist> * <listitem> * <para> * <emphasis>compression</emphasis> * Compress with this quality factor. Default 75. * </para> * </listitem> * <listitem> * <para> * <emphasis>profile</emphasis> * Attach this ICC profile. For example, "fred.jpg:,/home/john/srgb.icc" will * embed the profile stored in the file "/home/john/srgb.icc" in the JPEG * image. This does not affect the pixels which are written, just the way * they are tagged. You can use the special string "none" to mean * "don't attach a profile". * </para> * </listitem> * </itemizedlist> * * If no profile is specified in the save string and the VIPS header * contains an ICC profile named IM_META_ICC_NAME ("icc-profile-data"), the * profile from the VIPS header will be attached. * * The image is automatically converted to RGB, Monochrome or CMYK before * saving. Any metadata attached to the image is saved as EXIF, if possible. * * Example: * * |[ * im_vips2jpeg( in, "fred.jpg:99,none" ); * ]| * * Will write "fred.jpg" at high-quality with no ICC profile. * * See also: #VipsFormat, im_jpeg2vips(). * * Returns: 0 on success, -1 on error. */ int im_vips2jpeg( IMAGE *in, const char *filename ) { Write *write; int qfac = 75; char *profile = NULL; char *p, *q; char name[FILENAME_MAX]; char mode[FILENAME_MAX]; char buf[FILENAME_MAX]; /* Parse mode from filename. */ im_filename_split( filename, name, mode ); strcpy( buf, mode ); p = &buf[0]; if( (q = im_getnextoption( &p )) ) { if( strcmp( q, "" ) != 0 ) qfac = atoi( mode ); } if( (q = im_getnextoption( &p )) ) { if( strcmp( q, "" ) != 0 ) profile = q; } if( (q = im_getnextoption( &p )) ) { im_error( "im_vips2jpeg", _( "unknown extra options \"%s\"" ), q ); return( -1 ); } if( !(write = write_new( in )) ) return( -1 ); if( setjmp( write->eman.jmp ) ) { /* Here for longjmp() from new_error_exit(). */ write_destroy( write ); return( -1 ); } /* Can't do this in write_new(), has to be after we've made the * setjmp(). */ jpeg_create_compress( &write->cinfo ); /* Make output. */ if( !(write->eman.fp = im__file_open_write( name, FALSE )) ) { write_destroy( write ); return( -1 ); } jpeg_stdio_dest( &write->cinfo, write->eman.fp ); /* Convert! */ if( write_vips( write, qfac, profile ) ) { write_destroy( write ); return( -1 ); } write_destroy( write ); return( 0 ); }
/* Read a JPEG file into a VIPS image. */ static int jpeg2vips( const char *name, IMAGE *out, gboolean header_only ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; int shrink; struct jpeg_decompress_struct cinfo; ErrorManager eman; FILE *fp; int result; gboolean invert_pels; gboolean fail_on_warn; /* By default, we ignore any warnings. We want to get as much of * the user's data as we can. */ fail_on_warn = FALSE; /* Parse the filename. */ im_filename_split( name, filename, mode ); p = &mode[0]; shrink = 1; if( (q = im_getnextoption( &p )) ) { shrink = atoi( q ); if( shrink != 1 && shrink != 2 && shrink != 4 && shrink != 8 ) { im_error( "im_jpeg2vips", _( "bad shrink factor %d" ), shrink ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "fail", q ) ) fail_on_warn = TRUE; } /* Make jpeg dcompression object. */ cinfo.err = jpeg_std_error( &eman.pub ); eman.pub.error_exit = new_error_exit; eman.pub.output_message = new_output_message; eman.fp = NULL; if( setjmp( eman.jmp ) ) { /* Here for longjmp() from new_error_exit(). */ jpeg_destroy_decompress( &cinfo ); return( -1 ); } jpeg_create_decompress( &cinfo ); /* Make input. */ if( !(fp = im__file_open_read( filename, NULL, FALSE )) ) return( -1 ); eman.fp = fp; jpeg_stdio_src( &cinfo, fp ); /* Need to read in APP1 (EXIF metadata) and APP2 (ICC profile). */ jpeg_save_markers( &cinfo, JPEG_APP0 + 1, 0xffff ); jpeg_save_markers( &cinfo, JPEG_APP0 + 2, 0xffff ); /* Convert! */ result = read_jpeg_header( &cinfo, out, &invert_pels, shrink ); if( !header_only && !result ) result = read_jpeg_image( &cinfo, out, invert_pels ); /* Close and tidy. */ fclose( fp ); eman.fp = NULL; jpeg_destroy_decompress( &cinfo ); if( eman.pub.num_warnings != 0 ) { if( fail_on_warn ) { im_error( "im_jpeg2vips", "%s", im_error_buffer() ); result = -1; } else { im_warn( "im_jpeg2vips", _( "read gave %ld warnings" ), eman.pub.num_warnings ); im_warn( "im_jpeg2vips", "%s", im_error_buffer() ); } } return( result ); }
int im_vips2tiff( IMAGE *in, const char *filename ) { char *p, *q, *r; char name[FILENAME_MAX]; char mode[FILENAME_MAX]; char buf[FILENAME_MAX]; VipsForeignTiffCompression compression = VIPS_FOREIGN_TIFF_COMPRESSION_NONE; int Q = 75; VipsForeignTiffPredictor predictor = VIPS_FOREIGN_TIFF_PREDICTOR_NONE; char *profile = NULL; gboolean tile = FALSE; int tile_width = 128; int tile_height = 128; gboolean pyramid = FALSE; gboolean squash = FALSE; VipsForeignTiffResunit resunit = VIPS_FOREIGN_TIFF_RESUNIT_CM; double xres = in->Xres * 10.0; double yres = in->Yres * 10.0; gboolean bigtiff = FALSE; im_filename_split( filename, name, mode ); strcpy( buf, mode ); p = &buf[0]; if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "none", q ) ) compression = VIPS_FOREIGN_TIFF_COMPRESSION_NONE; else if( im_isprefix( "packbits", q ) ) compression = VIPS_FOREIGN_TIFF_COMPRESSION_PACKBITS; else if( im_isprefix( "ccittfax4", q ) ) compression = VIPS_FOREIGN_TIFF_COMPRESSION_CCITTFAX4; else if( im_isprefix( "lzw", q ) ) { compression = VIPS_FOREIGN_TIFF_COMPRESSION_LZW; if( (r = im_getsuboption( q )) ) { int i; if( sscanf( r, "%d", &i ) != 1 ) { im_error( "im_vips2tiff", "%s", _( "bad predictor " "parameter" ) ); return( -1 ); } predictor = i; } } else if( im_isprefix( "deflate", q ) ) { compression = VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE; if( (r = im_getsuboption( q )) ) { int i; if( sscanf( r, "%d", &i ) != 1 ) { im_error( "im_vips2tiff", "%s", _( "bad predictor " "parameter" ) ); return( -1 ); } predictor = i; } } else if( im_isprefix( "jpeg", q ) ) { compression = VIPS_FOREIGN_TIFF_COMPRESSION_JPEG; if( (r = im_getsuboption( q )) ) if( sscanf( r, "%d", &Q ) != 1 ) { im_error( "im_vips2tiff", "%s", _( "bad JPEG quality " "parameter" ) ); return( -1 ); } } else { im_error( "im_vips2tiff", _( "unknown compression mode " "\"%s\"\nshould be one of \"none\", " "\"packbits\", \"ccittfax4\", \"lzw\", " "\"deflate\" or \"jpeg\"" ), q ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "tile", q ) ) { tile = TRUE; if( (r = im_getsuboption( q )) ) { if( sscanf( r, "%dx%d", &tile_width, &tile_height ) != 2 ) { im_error( "im_vips2tiff", "%s", _( "bad tile sizes" ) ); return( -1 ); } } } else if( im_isprefix( "strip", q ) ) tile = FALSE; else { im_error( "im_vips2tiff", _( "unknown layout mode " "\"%s\"\nshould be one of \"tile\" or " "\"strip\"" ), q ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "pyramid", q ) ) pyramid = TRUE; else if( im_isprefix( "flat", q ) ) pyramid = FALSE; else { im_error( "im_vips2tiff", _( "unknown multi-res mode " "\"%s\"\nshould be one of \"flat\" or " "\"pyramid\"" ), q ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "onebit", q ) ) squash = TRUE; else if( im_isprefix( "manybit", q ) ) squash = FALSE; else { im_error( "im_vips2tiff", _( "unknown format " "\"%s\"\nshould be one of \"onebit\" or " "\"manybit\"" ), q ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "res_cm", q ) ) resunit = VIPS_FOREIGN_TIFF_RESUNIT_CM; else if( im_isprefix( "res_inch", q ) ) resunit = VIPS_FOREIGN_TIFF_RESUNIT_INCH; else { im_error( "im_vips2tiff", _( "unknown resolution unit " "\"%s\"\nshould be one of \"res_cm\" or " "\"res_inch\"" ), q ); return( -1 ); } if( (r = im_getsuboption( q )) ) { if( sscanf( r, "%lfx%lf", &xres, &yres ) != 2 ) { if( sscanf( r, "%lf", &xres ) != 1 ) { im_error( "im_vips2tiff", "%s", _( "bad resolution values" ) ); return( -1 ); } yres = xres; } /* vips resolutions are always in pixels/mm. If the * user specifies ",res_inch:72x72" then they are * using pixels/inch instead and we must convert. */ if( resunit == VIPS_FOREIGN_TIFF_RESUNIT_INCH ) { xres /= 2.54; yres /= 2.54; } } } if( (q = im_getnextoption( &p )) && strcmp( q, "" ) != 0 ) profile = im_strdup( NULL, q ); if( (q = im_getnextoption( &p )) && strcmp( q, "8" ) == 0 ) bigtiff = TRUE; if( (q = im_getnextoption( &p )) ) { im_error( "im_vips2tiff", _( "unknown extra options \"%s\"" ), q ); return( -1 ); } if( vips_tiffsave( in, name, "compression", compression, "Q", Q, "predictor", predictor, "profile", profile, "tile", tile, "tile_width", tile_width, "tile_height", tile_height, "pyramid", pyramid, "squash", squash, "resunit", resunit, "xres", xres, "yres", yres, "bigtiff", bigtiff, NULL ) ) return( -1 ); return( 0 ); }