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 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 ); }
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 ); }
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 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 ); }
int im_vips2dz( IMAGE *in, const char *filename ) { char *p, *q; char name[FILENAME_MAX]; char mode[FILENAME_MAX]; char buf[FILENAME_MAX]; int i; VipsForeignDzLayout layout = VIPS_FOREIGN_DZ_LAYOUT_DZ; char *suffix = ".jpeg"; int overlap = 0; int tile_size = 256; VipsForeignDzDepth depth = VIPS_FOREIGN_DZ_DEPTH_1PIXEL; gboolean centre = FALSE; VipsAngle angle = VIPS_ANGLE_0; /* We can't use im_filename_split() --- it assumes that we have a * filename with an extension before the ':', and filename here is * actually a dirname. * * Just split on the first ':'. */ im_strncpy( name, filename, FILENAME_MAX ); if( (p = strchr( name, ':' )) ) { *p = '\0'; im_strncpy( mode, p + 1, FILENAME_MAX ); } strcpy( buf, mode ); p = &buf[0]; if( (q = im_getnextoption( &p )) ) { if( (i = vips_enum_from_nick( "im_vips2dz", VIPS_TYPE_FOREIGN_DZ_LAYOUT, q )) < 0 ) return( -1 ); layout = i; } if( (q = im_getnextoption( &p )) ) suffix = g_strdup( q ); if( (q = im_getnextoption( &p )) ) overlap = atoi( q ); if( (q = im_getnextoption( &p )) ) tile_size = atoi( q ); if( (q = im_getnextoption( &p )) ) { if( (i = vips_enum_from_nick( "im_vips2dz", VIPS_TYPE_FOREIGN_DZ_DEPTH, q )) < 0 ) return( -1 ); depth = i; } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "cen", q ) ) centre = TRUE; } if( (q = im_getnextoption( &p )) ) { if( (i = vips_enum_from_nick( "im_vips2dz", VIPS_TYPE_ANGLE, q )) < 0 ) return( -1 ); angle = i; } if( vips_dzsave( in, name, "layout", layout, "suffix", suffix, "overlap", overlap, "tile_size", tile_size, "depth", depth, "centre", centre, "angle", angle, NULL ) ) return( -1 ); 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 ); }