clean up foreign
various cosmetic changes: - pngsave_buffer now uses Write, not WriteBuf, same change for radsave_buffer - move C wrappers out to class defs from foreign.c - use g_free() not vips_free() for buffer free from low-level savers - fix var names in some comments - various style changes for radiance.c
This commit is contained in:
parent
0cdfc8396c
commit
50468a07a2
3
TODO
3
TODO
@ -1,3 +1,6 @@
|
||||
- setting suffs on the base rad class made hdr save fail silently, why was
|
||||
there no message?
|
||||
|
||||
- add more webp tests to py suite
|
||||
|
||||
- try moving some more of the CLI tests to py
|
||||
|
@ -40,8 +40,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -50,6 +48,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
|
||||
#include "fits.h"
|
||||
|
||||
typedef struct _VipsForeignLoadFits {
|
||||
@ -133,3 +133,36 @@ vips_foreign_load_fits_init( VipsForeignLoadFits *fits )
|
||||
}
|
||||
|
||||
#endif /*HAVE_CFITSIO*/
|
||||
|
||||
/**
|
||||
* vips_fitsload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Read a FITS image file into a VIPS image.
|
||||
*
|
||||
* This operation can read images with up to three dimensions. Any higher
|
||||
* dimensions must be empty.
|
||||
*
|
||||
* It can read 8, 16 and 32-bit integer images, signed and unsigned, float and
|
||||
* double.
|
||||
*
|
||||
* FITS metadata is attached with the "fits-" prefix.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_fitsload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "fitsload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -43,14 +43,14 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#ifdef HAVE_CFITSIO
|
||||
|
||||
#include "fits.h"
|
||||
|
||||
typedef struct _VipsForeignSaveFits {
|
||||
@ -148,3 +148,28 @@ vips_foreign_save_fits_init( VipsForeignSaveFits *fits )
|
||||
}
|
||||
|
||||
#endif /*HAVE_CFITSIO*/
|
||||
|
||||
/**
|
||||
* vips_fitssave:
|
||||
* @in: image to save
|
||||
* @filename: file to write to
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Write a VIPS image to a file in FITS format.
|
||||
*
|
||||
* See also: vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_fitssave( VipsImage *in, const char *filename, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, filename );
|
||||
result = vips_call_split( "fitssave", ap, in, filename );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,8 +42,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_GIFLIB
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -55,6 +53,8 @@
|
||||
#include <vips/internal.h>
|
||||
#include <vips/debug.h>
|
||||
|
||||
#ifdef HAVE_GIFLIB
|
||||
|
||||
#include <gif_lib.h>
|
||||
|
||||
/* giflib 5 is rather different :-( functions have error returns and there's
|
||||
@ -734,5 +734,80 @@ vips_foreign_load_gif_buffer_init( VipsForeignLoadGifBuffer *buffer )
|
||||
{
|
||||
}
|
||||
|
||||
#endif /*HAVE_RSVG*/
|
||||
#endif /*HAVE_GIFLIB*/
|
||||
|
||||
/**
|
||||
* vips_gifload:
|
||||
* @filename: file to load
|
||||
* @out: output image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %ginit, page (frame) to read
|
||||
*
|
||||
* Read a GIF file into a VIPS image. Rendering uses the giflib library.
|
||||
*
|
||||
* Use @page to set page number (frame number) to read.
|
||||
*
|
||||
* The whole GIF is parsed and read into memory on header access, the whole
|
||||
* GIF is rendered on first pixel access.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_gifload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "gifload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_gifload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %ginit, page (frame) to read
|
||||
*
|
||||
* Read a GIF-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_gifload(), but read from a memory buffer.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_gifload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_gifload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "gifload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
@ -43,13 +43,17 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#ifdef HAVE_EXIF
|
||||
#ifdef UNTAGGED_EXIF
|
||||
#include <exif-data.h>
|
||||
@ -64,10 +68,6 @@
|
||||
#endif /*UNTAGGED_EXIF*/
|
||||
#endif /*HAVE_EXIF*/
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "vipsjpeg.h"
|
||||
|
||||
typedef struct _VipsForeignLoadJpeg {
|
||||
@ -343,3 +343,122 @@ vips_foreign_load_jpeg_buffer_init( VipsForeignLoadJpegBuffer *buffer )
|
||||
}
|
||||
|
||||
#endif /*HAVE_JPEG*/
|
||||
|
||||
/**
|
||||
* vips_jpegload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @shrink: %gint, shrink by this much on load
|
||||
* * @fail: %gboolean, fail on warnings
|
||||
* * @autorotate: %gboolean, use exif Orientation tag to rotate the image during load
|
||||
*
|
||||
* Read a JPEG file into a VIPS image. It can read most 8-bit JPEG images,
|
||||
* including CMYK and YCbCr.
|
||||
*
|
||||
* @shrink means shrink by this integer factor during load. Possible values
|
||||
* are 1, 2, 4 and 8. Shrinking during read is very much faster than
|
||||
* decompressing the whole image and then shrinking later.
|
||||
*
|
||||
* Setting @fail to %TRUE makes the JPEG reader fail on any warnings.
|
||||
* This can be useful for detecting truncated files, for example. Normally
|
||||
* reading these produces a warning, but no fatal error.
|
||||
*
|
||||
* Setting @autorotate to %TRUE will make the loader interpret the EXIF
|
||||
* Orientation field and automatically rotate the image appropriately during
|
||||
* load. After rotation, the Orientation tag will be removed to prevent
|
||||
* accidental double-rotation.
|
||||
*
|
||||
* Using @autorotate can be much slower than doing the rotate later
|
||||
* in processing. See vips_autorot().
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* |[
|
||||
* vips_jpegload( "fred.jpg", &out,
|
||||
* "shrink", 8,
|
||||
* "fail", TRUE,
|
||||
* NULL );
|
||||
* ]|
|
||||
*
|
||||
* Any embedded ICC profiles are ignored: you always just get the RGB from
|
||||
* the file. Instead, the embedded profile will be attached to the image as
|
||||
* @VIPS_META_ICC_NAME ("icc-profile-data"). You need to use something like
|
||||
* vips_icc_import() to get CIE values from the file.
|
||||
*
|
||||
* EXIF metadata is attached as @VIPS_META_EXIF_NAME ("exif-data"), IPCT as
|
||||
* @VIPS_META_IPCT_NAME ("ipct-data"), and XMP as VIPS_META_XMP_NAME
|
||||
* ("xmp-data").
|
||||
*
|
||||
* The int metadata item "jpeg-multiscan" is set to the result of
|
||||
* jpeg_has_multiple_scans(). Interlaced jpeg images need a large amount of
|
||||
* memory to load, so this field gives callers a chance to handle these
|
||||
* images differently.
|
||||
*
|
||||
* The EXIF thumbnail, if present, is attached to the image as
|
||||
* "jpeg-thumbnail-data". See vips_image_get_blob().
|
||||
*
|
||||
* This function only reads the image header and does not decompress any pixel
|
||||
* data. Decompression only occurs when pixels are accessed.
|
||||
*
|
||||
* See also: vips_jpegload_buffer(), vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_jpegload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "jpegload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_jpegload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @shrink: %gint, shrink by this much on load
|
||||
* * @fail: %gboolean, fail on warnings
|
||||
*
|
||||
* Read a JPEG-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_jpegload(), but read from a memory buffer.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_jpegload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "jpegload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -41,13 +41,17 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#ifdef HAVE_EXIF
|
||||
#ifdef UNTAGGED_EXIF
|
||||
#include <exif-data.h>
|
||||
@ -62,10 +66,6 @@
|
||||
#endif /*UNTAGGED_EXIF*/
|
||||
#endif /*HAVE_EXIF*/
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "vipsjpeg.h"
|
||||
|
||||
typedef struct _VipsForeignSaveJpeg {
|
||||
@ -310,7 +310,9 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object )
|
||||
jpeg->optimize_scans, jpeg->quant_table ) )
|
||||
return( -1 );
|
||||
|
||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||
/* obuf is a g_free() buffer, not vips_free().
|
||||
*/
|
||||
blob = vips_blob_new( (VipsCallbackFn) g_free, obuf, olen );
|
||||
g_object_set( file, "buffer", blob, NULL );
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
@ -405,3 +407,210 @@ vips_foreign_save_jpeg_mime_init( VipsForeignSaveJpegMime *mime )
|
||||
}
|
||||
|
||||
#endif /*HAVE_JPEG*/
|
||||
|
||||
/**
|
||||
* vips_jpegsave:
|
||||
* @in: image to save
|
||||
* @filename: file to write to
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @Q: %gint, quality factor
|
||||
* * @profile: filename of ICC profile to attach
|
||||
* * @optimize_coding: %gboolean, compute optimal Huffman coding tables
|
||||
* * @interlace: %gboolean, write an interlaced (progressive) jpeg
|
||||
* * @strip: %gboolean, remove all metadata from image
|
||||
* * @no-subsample: %gboolean, disable chroma subsampling
|
||||
* * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block
|
||||
* * @overshoot_deringing: %gboolean, overshoot samples with extreme values
|
||||
* * @optimize_scans: %gboolean, split DCT coefficients into separate scans
|
||||
* * @quant_table: %gint, quantization table index
|
||||
*
|
||||
* Write a VIPS image to a file as JPEG.
|
||||
*
|
||||
* Use @Q to set the JPEG compression factor. Default 75.
|
||||
*
|
||||
* Use @profile to give the filename of a profile to be embedded in the JPEG.
|
||||
* 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".
|
||||
*
|
||||
* If no profile is specified and the VIPS header
|
||||
* contains an ICC profile named VIPS_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.
|
||||
*
|
||||
* EXIF data is constructed from @VIPS_META_EXIF_NAME ("exif-data"), then
|
||||
* modified with any other related tags on the image before being written to
|
||||
* the file.
|
||||
*
|
||||
* IPCT as @VIPS_META_IPCT_NAME ("ipct-data") and XMP as VIPS_META_XMP_NAME
|
||||
* ("xmp-data") are coded and attached.
|
||||
*
|
||||
* If @optimize_coding is set, the Huffman tables are optimised. This is
|
||||
* sllightly slower and produces slightly smaller files.
|
||||
*
|
||||
* If @interlace is set, the jpeg files will be interlaced (progressive jpeg,
|
||||
* in jpg parlance). These files may be better for display over a slow network
|
||||
* conection, but need much more memory to encode and decode.
|
||||
*
|
||||
* If @strip is set, no EXIF data, IPCT data, ICC profile or XMP metadata is
|
||||
* written into the output file.
|
||||
*
|
||||
* If @no-subsample is set, chrominance subsampling is disabled. This will
|
||||
* improve quality at the cost of larger file size. Useful for high Q factors.
|
||||
*
|
||||
* If @trellis_quant is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0), apply trellis quantisation to each 8x8 block.
|
||||
* Reduces file size but increases compression time.
|
||||
*
|
||||
* If @overshoot_deringing is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0), apply overshooting to samples with extreme values
|
||||
* for example 0 and 255 for 8-bit. Overshooting may reduce ringing artifacts
|
||||
* from compression, in particular in areas where black text appears on a
|
||||
* white background.
|
||||
*
|
||||
* If @optimize_scans is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0), split the spectrum of DCT coefficients into
|
||||
* separate scans. Reduces file size but increases compression time.
|
||||
*
|
||||
* If @quant_table is set and the version of libjpeg supports it
|
||||
* (e.g. mozjpeg >= 3.0) it selects the quantization table to use:
|
||||
*
|
||||
* * 0 — Tables from JPEG Annex K (vips and libjpeg default)
|
||||
* * 1 — Flat table
|
||||
* * 2 — Table tuned for MSSIM on Kodak image set
|
||||
* * 3 — Table from ImageMagick by N. Robidoux (current mozjpeg default)
|
||||
* * 4 — Table tuned for PSNR-HVS-M on Kodak image set
|
||||
* * 5 — Table from Relevance of Human Vision to JPEG-DCT Compression (1992)
|
||||
* * 6 — Table from DCTune Perceptual Optimization of Compressed Dental
|
||||
* X-Rays (1997)
|
||||
* * 7 — Table from A Visual Detection Model for DCT Coefficient
|
||||
* Quantization (1993)
|
||||
* * 8 — Table from An Improved Detection Model for DCT Coefficient
|
||||
* Quantization (1993)
|
||||
*
|
||||
* Quantization table 0 is the default in vips and libjpeg(-turbo), but it
|
||||
* tends to favor detail over color accuracy, producting colored patches and
|
||||
* stripes as well as heavy banding in flat areas at high compression ratios.
|
||||
* Quantization table 2 is a good candidate to try if the default quantization
|
||||
* table produces banding or color shifts and is well suited for hires images.
|
||||
* Quantization table 3 is the default in mozjpeg and has been tuned to produce
|
||||
* good results at the default quality setting; banding at high compression.
|
||||
* Quantization table 4 is the most accurate at the cost of compression ratio.
|
||||
* Tables 5-7 are based on older research papers, but generally achieve worse
|
||||
* compression ratios and/or quality than 2 or 4.
|
||||
*
|
||||
* See also: vips_jpegsave_buffer(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_jpegsave( VipsImage *in, const char *filename, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, filename );
|
||||
result = vips_call_split( "jpegsave", ap, in, filename );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_jpegsave_buffer:
|
||||
* @in: image to save
|
||||
* @buf: return output buffer here
|
||||
* @len: return output length here
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @Q: JPEG quality factor
|
||||
* * @profile: attach this ICC profile
|
||||
* * @optimize_coding: compute optimal Huffman coding tables
|
||||
* * @interlace: write an interlaced (progressive) jpeg
|
||||
* * @strip: remove all metadata from image
|
||||
* * @no-subsample: disable chroma subsampling
|
||||
* * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block
|
||||
* * @overshoot_deringing: %gboolean, overshoot samples with extreme values
|
||||
* * @optimize_scans: %gboolean, split DCT coefficients into separate scans
|
||||
* * @quant_table: %gint, quantization table index
|
||||
*
|
||||
* As vips_jpegsave(), but save to a memory buffer.
|
||||
*
|
||||
* The address of the buffer is returned in @obuf, the length of the buffer in
|
||||
* @olen. You are responsible for freeing the buffer with g_free() when you
|
||||
* are done with it.
|
||||
*
|
||||
* See also: vips_jpegsave(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_jpegsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsArea *area;
|
||||
int result;
|
||||
|
||||
area = NULL;
|
||||
|
||||
va_start( ap, len );
|
||||
result = vips_call_split( "jpegsave_buffer", ap, in, &area );
|
||||
va_end( ap );
|
||||
|
||||
if( !result &&
|
||||
area ) {
|
||||
if( buf ) {
|
||||
*buf = area->data;
|
||||
area->free_fn = NULL;
|
||||
}
|
||||
if( len )
|
||||
*len = area->length;
|
||||
|
||||
vips_area_unref( area );
|
||||
}
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_jpegsave_mime:
|
||||
* @in: image to save
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @Q: JPEG quality factor
|
||||
* * @profile: attach this ICC profile
|
||||
* * @optimize_coding: compute optimal Huffman coding tables
|
||||
* * @strip: remove all metadata from image
|
||||
* * @no-subsample: disable chroma subsampling
|
||||
* * @trellis_quant: %gboolean, apply trellis quantisation to each 8x8 block
|
||||
* * @overshoot_deringing: %gboolean, overshoot samples with extreme values
|
||||
* * @optimize_scans: %gboolean, split DCT coefficients into separate scans
|
||||
* * @quant_table: %gint, quantization table index
|
||||
*
|
||||
* As vips_jpegsave(), but save as a mime jpeg on stdout.
|
||||
*
|
||||
* See also: vips_jpegsave(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_jpegsave_mime( VipsImage *in, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, in );
|
||||
result = vips_call_split( "jpegsave_mime", ap, in );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -46,8 +46,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -56,6 +54,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_MAGICK
|
||||
|
||||
#include "magick.h"
|
||||
|
||||
typedef struct _VipsForeignLoadMagick {
|
||||
@ -298,3 +298,91 @@ vips_foreign_load_magick_buffer_init( VipsForeignLoadMagickBuffer *buffer )
|
||||
}
|
||||
|
||||
#endif /*HAVE_MAGICK*/
|
||||
|
||||
/**
|
||||
* vips_magickload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @all_frames: %gboolean, load all frames in sequence
|
||||
* * @density: string, canvas resolution for rendering vector formats like SVG
|
||||
*
|
||||
* Read in an image using libMagick, the ImageMagick library. This library can
|
||||
* read more than 80 file formats, including SVG, BMP, EPS, DICOM and many
|
||||
* others.
|
||||
* The reader can handle any ImageMagick image, including the float and double
|
||||
* formats. It will work with any quantum size, including HDR. Any metadata
|
||||
* attached to the libMagick image is copied on to the VIPS image.
|
||||
*
|
||||
* The reader should also work with most versions of GraphicsMagick. See the
|
||||
* "--with-magickpackage" configure option.
|
||||
*
|
||||
* Normally it will only load the first image in a many-image sequence (such
|
||||
* as a GIF). Set @all_frames to true to read the whole image sequence.
|
||||
*
|
||||
* @density is "WxH" in DPI, e.g. "600x300" or "600" (default is "72x72"). See
|
||||
* the [density
|
||||
* docs](http://www.imagemagick.org/script/command-line-options.php#density)
|
||||
* on the imagemagick website.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_magickload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "magickload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_magickload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @all_frames: %gboolean, load all frames in sequence
|
||||
* * @density: string, canvas resolution for rendering vector formats like SVG
|
||||
*
|
||||
* Read an image memory block using libMagick into a VIPS image. Exactly as
|
||||
* vips_magickload(), but read from a memory source.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_magickload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_magickload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "magickload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -42,8 +42,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_MATIO
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -52,6 +50,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_MATIO
|
||||
|
||||
#include "matlab.h"
|
||||
|
||||
typedef struct _VipsForeignLoadMat {
|
||||
@ -143,3 +143,33 @@ vips_foreign_load_mat_init( VipsForeignLoadMat *mat )
|
||||
}
|
||||
|
||||
#endif /*HAVE_MATIO*/
|
||||
|
||||
/**
|
||||
* vips_matload:
|
||||
* @filename: file to load
|
||||
* @out: output image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Read a Matlab save file into a VIPS image.
|
||||
*
|
||||
* This operation searches the save
|
||||
* file for the first array variable with between 1 and 3 dimensions and loads
|
||||
* it as an image. It will not handle complex images. It does not handle
|
||||
* sparse matrices.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_matload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "matload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -40,8 +40,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_OPENEXR
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -50,6 +48,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_OPENEXR
|
||||
|
||||
#include "openexr2vips.h"
|
||||
|
||||
typedef struct _VipsForeignLoadOpenexr {
|
||||
@ -154,3 +154,35 @@ vips_foreign_load_openexr_init( VipsForeignLoadOpenexr *openexr )
|
||||
}
|
||||
|
||||
#endif /*HAVE_OPENEXR*/
|
||||
|
||||
/**
|
||||
* vips_openexrload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Read a OpenEXR file into a VIPS image.
|
||||
*
|
||||
* The reader can handle scanline and tiled OpenEXR images. It can't handle
|
||||
* OpenEXR colour management, image attributes, many pixel formats, anything
|
||||
* other than RGBA.
|
||||
*
|
||||
* This reader uses the rather limited OpenEXR C API. It should really be
|
||||
* redone in C++.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_openexrload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "openexrload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -47,8 +47,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_OPENSLIDE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -57,6 +55,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_OPENSLIDE
|
||||
|
||||
#include "openslide2vips.h"
|
||||
|
||||
typedef struct _VipsForeignLoadOpenslide {
|
||||
@ -219,3 +219,50 @@ vips_foreign_load_openslide_init( VipsForeignLoadOpenslide *openslide )
|
||||
}
|
||||
|
||||
#endif /*HAVE_OPENSLIDE*/
|
||||
|
||||
/**
|
||||
* vips_openslideload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @level: load this level
|
||||
* * @associated: load this associated image
|
||||
* * @autocrop: crop to image bounds
|
||||
*
|
||||
* Read a virtual slide supported by the OpenSlide library into a VIPS image.
|
||||
* OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle,
|
||||
* and Ventana formats.
|
||||
*
|
||||
* To facilitate zooming, virtual slide formats include multiple scaled-down
|
||||
* versions of the high-resolution image. These are typically called
|
||||
* "levels". By default, vips_openslideload() reads the highest-resolution
|
||||
* level (level 0). Set @level to the level number you want.
|
||||
*
|
||||
* In addition to the slide image itself, virtual slide formats sometimes
|
||||
* include additional images, such as a scan of the slide's barcode.
|
||||
* OpenSlide calls these "associated images". To read an associated image,
|
||||
* set @associated to the image's name.
|
||||
* A slide's associated images are listed in the
|
||||
* "slide-associated-images" metadata item.
|
||||
*
|
||||
* The output of this operator is always RGBA.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_openslideload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "openslideload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -42,8 +42,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_POPPLER
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -53,6 +51,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_POPPLER
|
||||
|
||||
#include <cairo.h>
|
||||
#include <poppler.h>
|
||||
|
||||
@ -649,3 +649,113 @@ vips_foreign_load_pdf_buffer_init( VipsForeignLoadPdfBuffer *buffer )
|
||||
|
||||
#endif /*HAVE_POPPLER*/
|
||||
|
||||
/**
|
||||
* vips_pdfload:
|
||||
* @filename: file to load
|
||||
* @out: output image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page, numbered from zero
|
||||
* * @n: %gint, load this many pages
|
||||
* * @dpi: %gdouble, render at this DPI
|
||||
* * @scale: %gdouble, scale render by this factor
|
||||
*
|
||||
* Render a PDF file into a VIPS image. Rendering uses the libpoppler library
|
||||
* and should be fast.
|
||||
*
|
||||
* The output image is always RGBA --- CMYK PDFs will be
|
||||
* converted. If you need CMYK bitmaps, you should use vips_magickload()
|
||||
* instead.
|
||||
*
|
||||
* Rendering is progressive, that is, the image is rendered in strips equal in
|
||||
* height to the tile height. If your PDF contains large image files and
|
||||
* they span several strips in the output image, they will be decoded multiple
|
||||
* times. To fix this, increase the the tile height, for example:
|
||||
*
|
||||
* |[
|
||||
* vips copy huge.pdf x.png --vips-tile-height=1024
|
||||
* ]|
|
||||
*
|
||||
* Will process images in 1024-pixel high strips, potentially much faster,
|
||||
* though of course also using a lot more memory.
|
||||
*
|
||||
* Use @page to select a page to render, numbering from zero.
|
||||
*
|
||||
* Use @n to select the number of pages to render. The default is 1. Pages are
|
||||
* rendered in a vertical column, with each individual page aligned to the
|
||||
* left. Set to -1 to mean "until the end of the document". Use vips_grid()
|
||||
* to change page layout.
|
||||
*
|
||||
* Use @dpi to set the rendering resolution. The default is 72. Alternatively,
|
||||
* you can scale the rendering from the default 1 point == 1 pixel by
|
||||
* setting @scale.
|
||||
*
|
||||
* The operation fills a number of header fields with metadata, for example
|
||||
* "pdf-author". They may be useful.
|
||||
*
|
||||
* This function only reads the image header and does not render any pixel
|
||||
* data. Rendering occurs when pixels are accessed.
|
||||
*
|
||||
* See also: vips_image_new_from_file(), vips_magickload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_pdfload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "pdfload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_pdfload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page, numbered from zero
|
||||
* * @n: %gint, load this many pages
|
||||
* * @dpi: %gdouble, render at this DPI
|
||||
* * @scale: %gdouble, scale render by this factor
|
||||
*
|
||||
* Read a PDF-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_pdfload(), but read from a memory buffer.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_pdfload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_pdfload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "pdfload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
@ -223,3 +223,72 @@ vips_foreign_load_png_buffer_init( VipsForeignLoadPngBuffer *png )
|
||||
|
||||
#endif /*HAVE_PNG*/
|
||||
|
||||
/**
|
||||
* vips_pngload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Read a PNG file into a VIPS image. It can read all png images, including 8-
|
||||
* and 16-bit images, 1 and 3 channel, with and without an alpha channel.
|
||||
*
|
||||
* Any ICC profile is read and attached to the VIPS image.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_pngload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "pngload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_pngload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Read a PNG-formatted memory block into a VIPS image. It can read all png
|
||||
* images, including 8- and 16-bit images, 1 and 3 channel, with and without
|
||||
* an alpha channel.
|
||||
*
|
||||
* Any ICC profile is read and attached to the VIPS image.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_pngload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "pngload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,14 +43,14 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#ifdef HAVE_PNG
|
||||
|
||||
#include "vipspng.h"
|
||||
|
||||
typedef struct _VipsForeignSavePng {
|
||||
@ -226,7 +226,10 @@ vips_foreign_save_png_buffer_build( VipsObject *object )
|
||||
png->compression, png->interlace, png->profile, png->filter ) )
|
||||
return( -1 );
|
||||
|
||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||
/* vips__png_write_buf() makes a buffer that needs g_free(), not
|
||||
* vips_free().
|
||||
*/
|
||||
blob = vips_blob_new( (VipsCallbackFn) g_free, obuf, olen );
|
||||
g_object_set( object, "buffer", blob, NULL );
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
@ -260,3 +263,110 @@ vips_foreign_save_png_buffer_init( VipsForeignSavePngBuffer *buffer )
|
||||
}
|
||||
|
||||
#endif /*HAVE_PNG*/
|
||||
|
||||
/**
|
||||
* vips_pngsave:
|
||||
* @in: image to save
|
||||
* @filename: file to write to
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @compression: compression level
|
||||
* * @interlace: interlace image
|
||||
* * @profile: ICC profile to embed
|
||||
* * @filter: #VipsForeignPngFilter row filter flag(s)
|
||||
*
|
||||
* Write a VIPS image to a file as PNG.
|
||||
*
|
||||
* @compression means compress with this much effort (0 - 9). Default 6.
|
||||
*
|
||||
* Set @interlace to %TRUE to interlace the image with ADAM7
|
||||
* interlacing. Beware
|
||||
* than an interlaced PNG can be up to 7 times slower to write than a
|
||||
* non-interlaced image.
|
||||
*
|
||||
* Use @profile to give the filename of a profile to be embedded in the PNG.
|
||||
* 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".
|
||||
*
|
||||
* If @profile is specified and the VIPS header
|
||||
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
||||
* profile from the VIPS header will be attached.
|
||||
*
|
||||
* Use @filter to specify one or more filters (instead of adaptive filtering),
|
||||
* see #VipsForeignPngFilter.
|
||||
*
|
||||
* The image is automatically converted to RGB, RGBA, Monochrome or Mono +
|
||||
* alpha before saving. Images with more than one byte per band element are
|
||||
* saved as 16-bit PNG, others are saved as 8-bit PNG.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_pngsave( VipsImage *in, const char *filename, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, filename );
|
||||
result = vips_call_split( "pngsave", ap, in, filename );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_pngsave_buffer:
|
||||
* @in: image to save
|
||||
* @buf: return output buffer here
|
||||
* @len: return output length here
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @compression: compression level
|
||||
* * @interlace: interlace image
|
||||
* * @profile: ICC profile to embed
|
||||
* * @filter: libpng row filter flag(s)
|
||||
*
|
||||
* As vips_pngsave(), but save to a memory buffer.
|
||||
*
|
||||
* The address of the buffer is returned in @buf, the length of the buffer in
|
||||
* @len. You are responsible for freeing the buffer with g_free() when you
|
||||
* are done with it.
|
||||
*
|
||||
* See also: vips_pngsave(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_pngsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsArea *area;
|
||||
int result;
|
||||
|
||||
area = NULL;
|
||||
|
||||
va_start( ap, len );
|
||||
result = vips_call_split( "pngsave_buffer", ap, in, &area );
|
||||
va_end( ap );
|
||||
|
||||
if( !result &&
|
||||
area ) {
|
||||
if( buf ) {
|
||||
*buf = area->data;
|
||||
area->free_fn = NULL;
|
||||
}
|
||||
if( len )
|
||||
*len = area->length;
|
||||
|
||||
vips_area_unref( area );
|
||||
}
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
* - put the reader globals into a struct so we can have many active
|
||||
* readers
|
||||
* 23/5/16
|
||||
* - Add buffer save functions
|
||||
* - add buffer save functions
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -817,13 +817,18 @@ scanline_read( Buffer *buffer, COLR *scanline, int width )
|
||||
/* write an RLE scanline. Write magic header.
|
||||
*/
|
||||
static void
|
||||
rle_scanline_write( COLR *scanline, int width, unsigned char *buffer, int *buffer_pos )
|
||||
rle_scanline_write( COLR *scanline, int width,
|
||||
unsigned char *buffer, int *length )
|
||||
{
|
||||
#define PUTC( CH ) { \
|
||||
buffer[(*buffer_pos)++] = (CH); \
|
||||
g_assert( *buffer_pos <= MAX_LINE ); \
|
||||
}
|
||||
int i, j, beg, cnt;
|
||||
|
||||
#define PUTC( CH ) { \
|
||||
buffer[(*length)++] = (CH); \
|
||||
g_assert( *length <= MAX_LINE ); \
|
||||
}
|
||||
|
||||
*length = 0;
|
||||
|
||||
PUTC( 2 );
|
||||
PUTC( 2 );
|
||||
PUTC( width >> 8 );
|
||||
@ -831,7 +836,7 @@ rle_scanline_write( COLR *scanline, int width, unsigned char *buffer, int *buffe
|
||||
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
for( j = 0; j < width; ) {
|
||||
/* Not needed, but keeps gcc used-before-set wsrning
|
||||
/* Not needed, but keeps gcc used-before-set warning
|
||||
* quiet.
|
||||
*/
|
||||
cnt = 1;
|
||||
@ -883,20 +888,21 @@ rle_scanline_write( COLR *scanline, int width, unsigned char *buffer, int *buffe
|
||||
static int
|
||||
scanline_write( COLR *scanline, int width, FILE *fp )
|
||||
{
|
||||
unsigned char buffer[MAX_LINE];
|
||||
int buffer_pos = 0;
|
||||
|
||||
if( width < MINELEN ||
|
||||
width > MAXELEN )
|
||||
/* Write as a flat scanline.
|
||||
*/
|
||||
return( fwrite( scanline, sizeof( COLR ), width, fp ) - width );
|
||||
else {
|
||||
/* An RLE scanline.
|
||||
*/
|
||||
unsigned char buffer[MAX_LINE];
|
||||
int length;
|
||||
|
||||
/* An RLE scanline.
|
||||
*/
|
||||
rle_scanline_write( scanline, width, buffer, &buffer_pos );
|
||||
rle_scanline_write( scanline, width, buffer, &length );
|
||||
|
||||
return( fwrite( buffer, 1, buffer_pos, fp ) - buffer_pos );
|
||||
return( fwrite( buffer, 1, length, fp ) - length );
|
||||
}
|
||||
}
|
||||
|
||||
/* What we track during radiance file read.
|
||||
@ -1165,9 +1171,14 @@ vips__rad_load( const char *filename, VipsImage *out, gboolean readbehind )
|
||||
*/
|
||||
typedef struct {
|
||||
VipsImage *in;
|
||||
char *filename;
|
||||
|
||||
char *filename;
|
||||
FILE *fout;
|
||||
|
||||
char *buf;
|
||||
size_t len;
|
||||
size_t alloc;
|
||||
|
||||
char format[256];
|
||||
double expos;
|
||||
COLOR colcor;
|
||||
@ -1177,22 +1188,17 @@ typedef struct {
|
||||
} Write;
|
||||
|
||||
static void
|
||||
write_destroy_file( Write *write )
|
||||
write_destroy( Write *write )
|
||||
{
|
||||
VIPS_FREE( write->filename );
|
||||
VIPS_FREEF( fclose, write->fout );
|
||||
VIPS_FREE( write->buf );
|
||||
|
||||
vips_free( write );
|
||||
}
|
||||
|
||||
static void
|
||||
write_destroy( Write *write )
|
||||
{
|
||||
vips_free( write );
|
||||
}
|
||||
|
||||
static Write *
|
||||
write_new( VipsImage *in)
|
||||
write_new( VipsImage *in )
|
||||
{
|
||||
Write *write;
|
||||
int i;
|
||||
@ -1201,6 +1207,14 @@ write_new( VipsImage *in)
|
||||
return( NULL );
|
||||
|
||||
write->in = in;
|
||||
|
||||
write->filename = NULL;
|
||||
write->fout = NULL;
|
||||
|
||||
write->buf = NULL;
|
||||
write->len = 0;
|
||||
write->alloc = 0;
|
||||
|
||||
strcpy( write->format, COLRFMT );
|
||||
write->expos = 1.0;
|
||||
for( i = 0; i < 3; i++ )
|
||||
@ -1254,7 +1268,7 @@ vips2rad_make_header( Write *write )
|
||||
static int
|
||||
vips2rad_put_header( Write *write )
|
||||
{
|
||||
vips2rad_make_header(write);
|
||||
vips2rad_make_header( write );
|
||||
|
||||
fprintf( write->fout, "#?RADIANCE\n" );
|
||||
|
||||
@ -1317,124 +1331,99 @@ vips__rad_save( VipsImage *in, const char *filename )
|
||||
!write->fout ||
|
||||
vips2rad_put_header( write ) ||
|
||||
vips2rad_put_data( write ) ) {
|
||||
write_destroy_file( write );
|
||||
write_destroy( write );
|
||||
return( -1 );
|
||||
}
|
||||
write_destroy_file( write );
|
||||
write_destroy( write );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
typedef struct _WriteBuf {
|
||||
char *buf;
|
||||
size_t len;
|
||||
size_t alloc;
|
||||
} WriteBuf;
|
||||
|
||||
static void
|
||||
write_buf_free( WriteBuf *wbuf )
|
||||
write_buf_grow( Write *write, size_t grow_len )
|
||||
{
|
||||
VIPS_FREE( wbuf->buf );
|
||||
VIPS_FREE( wbuf );
|
||||
}
|
||||
size_t new_len = write->len + grow_len;
|
||||
|
||||
static WriteBuf *
|
||||
write_buf_new( void )
|
||||
{
|
||||
WriteBuf *wbuf;
|
||||
if( new_len > write->alloc ) {
|
||||
size_t proposed_alloc = (16 + write->alloc) * 3 / 2;
|
||||
|
||||
if( !(wbuf = VIPS_NEW( NULL, WriteBuf )) )
|
||||
return( NULL );
|
||||
write->alloc = VIPS_MAX( proposed_alloc, new_len );
|
||||
|
||||
wbuf->buf = NULL;
|
||||
wbuf->len = 0;
|
||||
wbuf->alloc = 0;
|
||||
|
||||
return( wbuf );
|
||||
}
|
||||
|
||||
static void
|
||||
write_buf_grow( WriteBuf *wbuf, size_t grow_len )
|
||||
{
|
||||
size_t new_len = wbuf->len + grow_len;
|
||||
|
||||
if( new_len > wbuf->alloc ) {
|
||||
size_t proposed_alloc = (16 + wbuf->alloc) * 3 / 2;
|
||||
|
||||
wbuf->alloc = VIPS_MAX( proposed_alloc, new_len );
|
||||
|
||||
/* There's no vips_realloc(), so we call g_realloc() directly.
|
||||
* This is safe, since vips_malloc() / vips_free() are wrappers
|
||||
* over g_malloc() / g_free().
|
||||
*
|
||||
* FIXME: add vips_realloc().
|
||||
/* Our caller must free with g_free(), so we must use
|
||||
* g_realloc().
|
||||
*/
|
||||
wbuf->buf = g_realloc( wbuf->buf, wbuf->alloc );
|
||||
write->buf = g_realloc( write->buf, write->alloc );
|
||||
|
||||
VIPS_DEBUG_MSG( "write_buf_grow: grown to %zd bytes\n",
|
||||
wbuf->alloc );
|
||||
write->alloc );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bprintf( WriteBuf *wbuf, const char *fmt, ... )
|
||||
bprintf( Write *write, const char *fmt, ... )
|
||||
{
|
||||
int length = 0;
|
||||
char *write_start = NULL;
|
||||
int length;
|
||||
char *write_start;
|
||||
va_list ap;
|
||||
|
||||
/* Determine required size */
|
||||
va_start(ap, fmt);
|
||||
length = vsnprintf(write_start, length, fmt, ap);
|
||||
va_end(ap);
|
||||
/* Determine required size.
|
||||
*/
|
||||
va_start( ap, fmt );
|
||||
length = vsnprintf( NULL, 0, fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
write_buf_grow( wbuf, length + 1 );
|
||||
write_buf_grow( write, length + 1 );
|
||||
|
||||
write_start = wbuf->buf + wbuf->len;
|
||||
write_start = write->buf + write->len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
length = vsnprintf(write_start, length + 1, fmt, ap);
|
||||
va_end(ap);
|
||||
va_start( ap, fmt );
|
||||
length = vsnprintf( write_start, length + 1, fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
wbuf->len += length;
|
||||
write->len += length;
|
||||
|
||||
g_assert( wbuf->len <= wbuf->alloc );
|
||||
g_assert( write->len <= write->alloc );
|
||||
}
|
||||
|
||||
#define bputformat(s,wb) bprintf(wb, "%s%s\n", FMTSTR, s)
|
||||
#define bputformat( write, s ) \
|
||||
bprintf( write, "%s%s\n", FMTSTR, s )
|
||||
|
||||
#define bputexpos(ex,wb) bprintf(wb,"%s%e\n",EXPOSSTR,ex)
|
||||
#define bputexpos( write, ex ) \
|
||||
bprintf( write, "%s%e\n", EXPOSSTR, ex )
|
||||
|
||||
#define bputcolcor(cc,wb) bprintf(wb,"%s %f %f %f\n",COLCORSTR, \
|
||||
(cc)[RED],(cc)[GRN],(cc)[BLU])
|
||||
#define bputcolcor( write, cc ) \
|
||||
bprintf( write, "%s %f %f %f\n", \
|
||||
COLCORSTR, (cc)[RED], (cc)[GRN], (cc)[BLU] )
|
||||
|
||||
#define bputaspect(pa,wb) bprintf(wb,"%s%f\n",ASPECTSTR,pa)
|
||||
#define bputaspect( write, pa ) \
|
||||
bprintf( write, "%s%f\n", ASPECTSTR, pa )
|
||||
|
||||
#define bputprims(p,wb) bprintf(wb, \
|
||||
"%s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n",\
|
||||
PRIMARYSTR, \
|
||||
(p)[RED][CIEX],(p)[RED][CIEY], \
|
||||
(p)[GRN][CIEX],(p)[GRN][CIEY], \
|
||||
(p)[BLU][CIEX],(p)[BLU][CIEY], \
|
||||
(p)[WHT][CIEX],(p)[WHT][CIEY])
|
||||
#define bputprims( write, p ) \
|
||||
bprintf( write, "%s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n", \
|
||||
PRIMARYSTR, \
|
||||
(p)[RED][CIEX], (p)[RED][CIEY], \
|
||||
(p)[GRN][CIEX], (p)[GRN][CIEY], \
|
||||
(p)[BLU][CIEX], (p)[BLU][CIEY], \
|
||||
(p)[WHT][CIEX], (p)[WHT][CIEY] )
|
||||
|
||||
#define bputsresolu(rs,wb) bprintf(wb,"%s",resolu2str(resolu_buf,rs))
|
||||
#define bputsresolu( write, rs ) \
|
||||
bprintf( write, "%s", resolu2str( resolu_buf, rs ) )
|
||||
|
||||
static int
|
||||
vips2rad_put_header_buf( WriteBuf *wbuf, Write *write )
|
||||
vips2rad_put_header_buf( Write *write )
|
||||
{
|
||||
vips2rad_make_header(write);
|
||||
vips2rad_make_header( write );
|
||||
|
||||
bprintf( wbuf, "#?RADIANCE\n" );
|
||||
bprintf( write, "#?RADIANCE\n" );
|
||||
|
||||
bputformat( write->format, wbuf );
|
||||
bputexpos( write->expos, wbuf );
|
||||
bputcolcor( write->colcor, wbuf );
|
||||
bprintf( wbuf, "SOFTWARE=vips %s\n", vips_version_string() );
|
||||
bputaspect( write->aspect, wbuf );
|
||||
bputprims( write->prims, wbuf );
|
||||
bprintf( wbuf, "\n" );
|
||||
bputsresolu( &write->rs, wbuf );
|
||||
bputformat( write, write->format );
|
||||
bputexpos( write, write->expos );
|
||||
bputcolcor( write, write->colcor );
|
||||
bprintf( write, "SOFTWARE=vips %s\n", vips_version_string() );
|
||||
bputaspect( write, write->aspect );
|
||||
bputprims( write, write->prims );
|
||||
bprintf( write, "\n" );
|
||||
bputsresolu( write, &write->rs );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -1442,41 +1431,42 @@ vips2rad_put_header_buf( WriteBuf *wbuf, Write *write )
|
||||
/* Write a single scanline to buffer.
|
||||
*/
|
||||
static int
|
||||
scanline_write_buf( COLR *scanline, int width, WriteBuf *wbuf )
|
||||
scanline_write_buf( Write *write, COLR *scanline, int width )
|
||||
{
|
||||
int buffer_pos = 0;
|
||||
unsigned char *buffer;
|
||||
|
||||
write_buf_grow( wbuf, MAX_LINE );
|
||||
unsigned char *buffer = (unsigned char *) wbuf->buf + wbuf->len;
|
||||
write_buf_grow( write, MAX_LINE );
|
||||
buffer = (unsigned char *) write->buf + write->len;
|
||||
|
||||
if( width < MINELEN ||
|
||||
width > MAXELEN ) {
|
||||
/* Write as a flat scanline.
|
||||
*/
|
||||
memcpy( buffer, scanline, sizeof( COLR ) * width );
|
||||
wbuf->len += sizeof( COLR ) * width;
|
||||
write->len += sizeof( COLR ) * width;
|
||||
}
|
||||
else {
|
||||
int length;
|
||||
|
||||
return( 0 );
|
||||
/* An RLE scanline.
|
||||
*/
|
||||
rle_scanline_write( scanline, width, buffer, &length );
|
||||
write->len += length;
|
||||
}
|
||||
|
||||
/* An RLE scanline.
|
||||
*/
|
||||
rle_scanline_write( scanline, width, buffer, &buffer_pos );
|
||||
|
||||
wbuf->len += buffer_pos;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips2rad_put_data_block_buf( VipsRegion *region, VipsRect *area, void *a )
|
||||
{
|
||||
WriteBuf *wbuf = (WriteBuf *) a;
|
||||
Write *write = (Write *) a;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < area->height; i++ ) {
|
||||
VipsPel *p = VIPS_REGION_ADDR( region, 0, area->top + i );
|
||||
|
||||
if( scanline_write_buf( (COLR *) p, area->width, wbuf ) )
|
||||
if( scanline_write_buf( write, (COLR *) p, area->width ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
@ -1484,9 +1474,9 @@ vips2rad_put_data_block_buf( VipsRegion *region, VipsRect *area, void *a )
|
||||
}
|
||||
|
||||
static int
|
||||
vips2rad_put_data_buf( WriteBuf *wbuf, Write *write )
|
||||
vips2rad_put_data_buf( Write *write )
|
||||
{
|
||||
if( vips_sink_disc( write->in, vips2rad_put_data_block_buf, wbuf ) )
|
||||
if( vips_sink_disc( write->in, vips2rad_put_data_block_buf, write ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -1496,7 +1486,6 @@ int
|
||||
vips__rad_save_buf( VipsImage *in, void **obuf, size_t *olen )
|
||||
{
|
||||
Write *write;
|
||||
WriteBuf *wbuf;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "vips2rad: writing to buffer\n" );
|
||||
@ -1505,27 +1494,22 @@ vips__rad_save_buf( VipsImage *in, void **obuf, size_t *olen )
|
||||
if( vips_image_pio_input( in ) ||
|
||||
vips_check_coding_rad( "vips2rad", in ) )
|
||||
return( -1 );
|
||||
if( !(wbuf = write_buf_new()) )
|
||||
if( !(write = write_new( in )) )
|
||||
return( -1 );
|
||||
if( !(write = write_new( in )) ) {
|
||||
write_buf_free( wbuf );
|
||||
|
||||
if( vips2rad_put_header_buf( write ) ||
|
||||
vips2rad_put_data_buf( write ) ) {
|
||||
write_destroy( write );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips2rad_put_header_buf( wbuf, write ) ||
|
||||
vips2rad_put_data_buf( wbuf, write ) ) {
|
||||
write_destroy( write );
|
||||
write_buf_free( wbuf );
|
||||
return( -1 );
|
||||
}
|
||||
*obuf = write->buf;
|
||||
write->buf = NULL;
|
||||
if( olen )
|
||||
*olen = write->len;
|
||||
|
||||
write_destroy( write );
|
||||
|
||||
*obuf = wbuf->buf;
|
||||
wbuf->buf = NULL;
|
||||
if( olen )
|
||||
*olen = wbuf->len;
|
||||
|
||||
write_buf_free( wbuf );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* 2/12/11
|
||||
* - wrap a class around the rad writer
|
||||
* 23/5/16
|
||||
* - split into file and buffer save classes
|
||||
* - split into file and buffer save classes
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -190,7 +190,10 @@ vips_foreign_save_rad_buffer_build( VipsObject *object )
|
||||
if( vips__rad_save_buf( save->ready, &obuf, &olen ) )
|
||||
return( -1 );
|
||||
|
||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||
/* vips__rad_save_buf() makes a buffer that needs g_free(), not
|
||||
* vips_free().
|
||||
*/
|
||||
blob = vips_blob_new( (VipsCallbackFn) g_free, obuf, olen );
|
||||
g_object_set( object, "buffer", blob, NULL );
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
@ -223,7 +226,6 @@ vips_foreign_save_rad_buffer_init( VipsForeignSaveRadBuffer *buffer )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif /*HAVE_RADIANCE*/
|
||||
|
||||
/**
|
||||
@ -262,8 +264,8 @@ vips_radsave( VipsImage *in, const char *filename, ... )
|
||||
*
|
||||
* As vips_radsave(), but save to a memory buffer.
|
||||
*
|
||||
* The address of the buffer is returned in @obuf, the length of the buffer in
|
||||
* @olen. You are responsible for freeing the buffer with g_free() when you
|
||||
* The address of the buffer is returned in @buf, the length of the buffer in
|
||||
* @len. You are responsible for freeing the buffer with g_free() when you
|
||||
* are done with it.
|
||||
*
|
||||
* See also: vips_radsave(), vips_image_write_to_file().
|
||||
|
@ -40,8 +40,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_RSVG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -52,6 +50,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_RSVG
|
||||
|
||||
#include <cairo.h>
|
||||
#include <librsvg/rsvg.h>
|
||||
|
||||
@ -453,3 +453,82 @@ vips_foreign_load_svg_buffer_init( VipsForeignLoadSvgBuffer *buffer )
|
||||
|
||||
#endif /*HAVE_RSVG*/
|
||||
|
||||
/**
|
||||
* vips_svgload:
|
||||
* @filename: file to load
|
||||
* @out: output image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @dpi: %gdouble, render at this DPI
|
||||
* * @scale: %gdouble, scale render by this factor
|
||||
*
|
||||
* Render a SVG file into a VIPS image. Rendering uses the librsvg library
|
||||
* and should be fast.
|
||||
*
|
||||
* Use @dpi to set the rendering resolution. The default is 72. Alternatively,
|
||||
* you can scale the rendering from the default 1 point == 1 pixel by @scale.
|
||||
*
|
||||
* This function only reads the image header and does not render any pixel
|
||||
* data. Rendering occurs when pixels are accessed.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_svgload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "svgload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_svgload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @dpi: %gdouble, render at this DPI
|
||||
* * @scale: %gdouble, scale render by this factor
|
||||
*
|
||||
* Read a SVG-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_svgload(), but read from a memory buffer.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_svgload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_svgload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "svgload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,6 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -50,6 +48,8 @@
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
#include "tiff.h"
|
||||
|
||||
typedef struct _VipsForeignLoadTiff {
|
||||
@ -280,3 +280,81 @@ vips_foreign_load_tiff_buffer_init( VipsForeignLoadTiffBuffer *buffer )
|
||||
}
|
||||
|
||||
#endif /*HAVE_TIFF*/
|
||||
|
||||
/**
|
||||
* vips_tiffload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: int, load this page
|
||||
*
|
||||
* Read a TIFF file into a VIPS image. It is a full baseline TIFF 6 reader,
|
||||
* with extensions for tiled images, multipage images, LAB colour space,
|
||||
* pyramidal images and JPEG compression. including CMYK and YCbCr.
|
||||
*
|
||||
* @page means load this page from the file. By default the first page (page
|
||||
* 0) is read.
|
||||
*
|
||||
* Any ICC profile is read and attached to the VIPS image. Any XMP metadata is
|
||||
* read and attached to the image.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_tiffload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "tiffload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_tiffload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @page: %gint, load this page
|
||||
*
|
||||
* Read a TIFF-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_tiffload(), but read from a memory source.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_tiffload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "tiffload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -47,14 +47,14 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#ifdef HAVE_TIFF
|
||||
|
||||
#include "tiff.h"
|
||||
|
||||
typedef struct _VipsForeignSaveTiff {
|
||||
@ -296,3 +296,103 @@ vips_foreign_save_tiff_init( VipsForeignSaveTiff *tiff )
|
||||
}
|
||||
|
||||
#endif /*HAVE_TIFF*/
|
||||
|
||||
/**
|
||||
* vips_tiffsave:
|
||||
* @in: image to save
|
||||
* @filename: file to write to
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @compression: use this #VipsForeignTiffCompression
|
||||
* * @Q: %gint quality factor
|
||||
* * @predictor: use this #VipsForeignTiffPredictor
|
||||
* * @profile: filename of ICC profile to attach
|
||||
* * @tile: set %TRUE to write a tiled tiff
|
||||
* * @tile_width: %gint for tile size
|
||||
* * @tile_height: %gint for tile size
|
||||
* * @pyramid: set %TRUE to write an image pyramid
|
||||
* * @squash: set %TRUE to squash 8-bit images down to 1 bit
|
||||
* * @miniswhite: set %TRUE to write 1-bit images as MINISWHITE
|
||||
* * @resunit: #VipsForeignTiffResunit for resolution unit
|
||||
* * @xres: %gdouble horizontal resolution in pixels/mm
|
||||
* * @yres: %gdouble vertical resolution in pixels/mm
|
||||
* * @bigtiff: set %TRUE to write a BigTiff file
|
||||
*
|
||||
* Write a VIPS image to a file as TIFF.
|
||||
*
|
||||
* Use @compression to set the tiff compression. Currently jpeg, packbits,
|
||||
* fax4, lzw, none and deflate are supported. The default is no compression.
|
||||
* JPEG compression is a good lossy compressor for photographs, packbits is
|
||||
* good for 1-bit images, and deflate is the best lossless compression TIFF
|
||||
* can do. LZW has patent problems and is no longer recommended.
|
||||
*
|
||||
* Use @Q to set the JPEG compression factor. Default 75.
|
||||
*
|
||||
* Use @predictor to set the predictor for lzw and deflate compression.
|
||||
*
|
||||
* Predictor is not set by default. There are three predictor values recognised
|
||||
* at the moment (2007, July): 1 is no prediction, 2 is a horizontal
|
||||
* differencing and 3 is a floating point predictor. Refer to the libtiff
|
||||
* specifications for further discussion of various predictors. In short,
|
||||
* predictor helps to better compress image, especially in case of digital
|
||||
* photos or scanned images and bit depths > 8. Try it to find whether it
|
||||
* works for your images.
|
||||
*
|
||||
* Use @profile to give the filename of a profile to be embedded in the TIFF.
|
||||
* 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".
|
||||
*
|
||||
* If no profile is specified and the VIPS header
|
||||
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
|
||||
* profile from the VIPS header will be attached.
|
||||
*
|
||||
* Set @tile to TRUE to write a tiled tiff. By default tiff are written in
|
||||
* strips. Use @tile_width and @tile_height to set the tile size. The defaiult
|
||||
* is 128 by 128.
|
||||
*
|
||||
* Set @pyramid to write the image as a set of images, one per page, of
|
||||
* decreasing size.
|
||||
*
|
||||
* Set @squash to make 8-bit uchar images write as 1-bit TIFFs. Values >128
|
||||
* are written as white, values <=128 as black. Normally vips will write
|
||||
* MINISBLACK TIFFs where black is a 0 bit, but if you set @miniswhite, it
|
||||
* will use 0 for a white bit. Many pre-press applications only work with
|
||||
* images which use this sense. @miniswhite only affects one-bit images, it
|
||||
* does nothing for greyscale images.
|
||||
*
|
||||
* Use @resunit to override the default resolution unit.
|
||||
* The default
|
||||
* resolution unit is taken from the header field "resolution-unit"
|
||||
* (#VIPS_META_RESOLUTION_UNIT in C). If this field is not set, then
|
||||
* VIPS defaults to cm.
|
||||
*
|
||||
* Use @xres and @yres to override the default horizontal and vertical
|
||||
* resolutions. By default these values are taken from the VIPS image header.
|
||||
* libvips resolution is always in pixels per millimetre.
|
||||
*
|
||||
* Set @bigtiff to attempt to write a bigtiff.
|
||||
* Bigtiff is a variant of the TIFF
|
||||
* format that allows more than 4GB in a file.
|
||||
*
|
||||
* If @in has a field called VIPS_META_XMP_NAME ("xmp-data") it is written to
|
||||
* the tiff image.
|
||||
*
|
||||
* See also: vips_tiffload(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_tiffsave( VipsImage *in, const char *filename, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, filename );
|
||||
result = vips_call_split( "tiffsave", ap, in, filename );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -146,3 +146,28 @@ static void
|
||||
vips_foreign_load_vips_init( VipsForeignLoadVips *vips )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_vipsload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Read in a vips image.
|
||||
*
|
||||
* See also: vips_vipssave().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_vipsload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "vipsload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -710,6 +710,11 @@ typedef struct {
|
||||
VipsImage *memory;
|
||||
|
||||
FILE *fp;
|
||||
|
||||
char *buf;
|
||||
size_t len;
|
||||
size_t alloc;
|
||||
|
||||
png_structp pPng;
|
||||
png_infop pInfo;
|
||||
png_bytep *row_pointer;
|
||||
@ -720,6 +725,7 @@ write_finish( Write *write )
|
||||
{
|
||||
VIPS_FREEF( fclose, write->fp );
|
||||
VIPS_UNREF( write->memory );
|
||||
VIPS_FREE( write->buf );
|
||||
if( write->pPng )
|
||||
png_destroy_write_struct( &write->pPng, &write->pInfo );
|
||||
}
|
||||
@ -740,6 +746,10 @@ write_new( VipsImage *in )
|
||||
memset( write, 0, sizeof( Write ) );
|
||||
write->in = in;
|
||||
write->memory = NULL;
|
||||
write->fp = NULL;
|
||||
write->buf = NULL;
|
||||
write->len = 0;
|
||||
write->alloc = 0;
|
||||
g_signal_connect( in, "close",
|
||||
G_CALLBACK( write_destroy ), write );
|
||||
|
||||
@ -976,72 +986,41 @@ vips__png_write( VipsImage *in, const char *filename,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
typedef struct _WriteBuf {
|
||||
char *buf;
|
||||
size_t len;
|
||||
size_t alloc;
|
||||
} WriteBuf;
|
||||
|
||||
static void
|
||||
write_buf_free( WriteBuf *wbuf )
|
||||
write_grow( Write *write, size_t grow_len )
|
||||
{
|
||||
VIPS_FREE( wbuf->buf );
|
||||
VIPS_FREE( wbuf );
|
||||
}
|
||||
size_t new_len = write->len + grow_len;
|
||||
|
||||
static WriteBuf *
|
||||
write_buf_new( void )
|
||||
{
|
||||
WriteBuf *wbuf;
|
||||
if( new_len > write->alloc ) {
|
||||
size_t proposed_alloc = (16 + write->alloc) * 3 / 2;
|
||||
|
||||
if( !(wbuf = VIPS_NEW( NULL, WriteBuf )) )
|
||||
return( NULL );
|
||||
write->alloc = VIPS_MAX( proposed_alloc, new_len );
|
||||
|
||||
wbuf->buf = NULL;
|
||||
wbuf->len = 0;
|
||||
wbuf->alloc = 0;
|
||||
|
||||
return( wbuf );
|
||||
}
|
||||
|
||||
static void
|
||||
write_buf_grow( WriteBuf *wbuf, size_t grow_len )
|
||||
{
|
||||
size_t new_len = wbuf->len + grow_len;
|
||||
|
||||
if( new_len > wbuf->alloc ) {
|
||||
size_t proposed_alloc = (16 + wbuf->alloc) * 3 / 2;
|
||||
|
||||
wbuf->alloc = VIPS_MAX( proposed_alloc, new_len );
|
||||
|
||||
/* There's no vips_realloc(), so we call g_realloc() directly.
|
||||
* This is safe, since vips_malloc() / vips_free() are wrappers
|
||||
* over g_malloc() / g_free().
|
||||
*
|
||||
* FIXME: add vips_realloc().
|
||||
/* Our result mujst be freedd with g_free(), so it's OK to use
|
||||
* g_realloc().
|
||||
*/
|
||||
wbuf->buf = g_realloc( wbuf->buf, wbuf->alloc );
|
||||
write->buf = g_realloc( write->buf, write->alloc );
|
||||
|
||||
VIPS_DEBUG_MSG( "write_buf_grow: grown to %zd bytes\n",
|
||||
wbuf->alloc );
|
||||
write->alloc );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
user_write_data( png_structp png_ptr, png_bytep data, png_size_t length )
|
||||
{
|
||||
WriteBuf *wbuf = (WriteBuf *) png_get_io_ptr( png_ptr );
|
||||
Write *write = (Write *) png_get_io_ptr( png_ptr );
|
||||
|
||||
char *write_start;
|
||||
|
||||
write_buf_grow( wbuf, length );
|
||||
write_grow( write, length );
|
||||
|
||||
write_start = wbuf->buf + wbuf->len;
|
||||
write_start = write->buf + write->len;
|
||||
memcpy( write_start, data, length );
|
||||
|
||||
wbuf->len += length;
|
||||
write->len += length;
|
||||
|
||||
g_assert( wbuf->len <= wbuf->alloc );
|
||||
g_assert( write->len <= write->alloc );
|
||||
}
|
||||
|
||||
int
|
||||
@ -1049,36 +1028,28 @@ vips__png_write_buf( VipsImage *in,
|
||||
void **obuf, size_t *olen, int compression, int interlace,
|
||||
const char *profile, VipsForeignPngFilter filter )
|
||||
{
|
||||
WriteBuf *wbuf;
|
||||
Write *write;
|
||||
|
||||
if( !(wbuf = write_buf_new()) )
|
||||
if( !(write = write_new( in )) )
|
||||
return( -1 );
|
||||
if( !(write = write_new( in )) ) {
|
||||
write_buf_free( wbuf );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
png_set_write_fn( write->pPng, wbuf, user_write_data, NULL );
|
||||
png_set_write_fn( write->pPng, write, user_write_data, NULL );
|
||||
|
||||
/* Convert it!
|
||||
*/
|
||||
if( write_vips( write, compression, interlace, profile, filter ) ) {
|
||||
write_buf_free( wbuf );
|
||||
vips_error( "vips2png",
|
||||
"%s", _( "unable to write to buffer" ) );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
write_finish( write );
|
||||
|
||||
*obuf = wbuf->buf;
|
||||
wbuf->buf = NULL;
|
||||
*obuf = write->buf;
|
||||
write->buf = NULL;
|
||||
if( olen )
|
||||
*olen = wbuf->len;
|
||||
*olen = write->len;
|
||||
|
||||
write_buf_free( wbuf );
|
||||
write_finish( write );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -123,3 +123,28 @@ vips_foreign_save_vips_init( VipsForeignSaveVips *vips )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_vipssave:
|
||||
* @in: image to save
|
||||
* @filename: file to write to
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Write @in to @filename in VIPS format.
|
||||
*
|
||||
* See also: vips_vipsload().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_vipssave( VipsImage *in, const char *filename, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, filename );
|
||||
result = vips_call_split( "vipssave", ap, in, filename );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
|
@ -43,12 +43,12 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_LIBWEBP
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#ifdef HAVE_LIBWEBP
|
||||
|
||||
#include "webp.h"
|
||||
|
||||
typedef struct _VipsForeignLoadWebp {
|
||||
@ -278,3 +278,75 @@ vips_foreign_load_webp_buffer_init( VipsForeignLoadWebpBuffer *buffer )
|
||||
}
|
||||
|
||||
#endif /*HAVE_LIBWEBP*/
|
||||
|
||||
/**
|
||||
* vips_webpload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @shrink: %gint, shrink by this much on load
|
||||
*
|
||||
* Read a WebP file into a VIPS image.
|
||||
*
|
||||
* Use @shrink to specify a shrink-on-load factor.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_webpload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "webpload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_webpload_buffer:
|
||||
* @buf: memory area to load
|
||||
* @len: size of memory area
|
||||
* @out: image to write
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @shrink: %gint, shrink by this much on load
|
||||
*
|
||||
* Read a WebP-formatted memory block into a VIPS image. Exactly as
|
||||
* vips_webpload(), but read from a memory buffer.
|
||||
*
|
||||
* You must not free the buffer while @out is active. The
|
||||
* #VipsObject::postclose signal on @out is a good place to free.
|
||||
*
|
||||
* See also: vips_webpload()
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_webpload_buffer( void *buf, size_t len, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsBlob *blob;
|
||||
int result;
|
||||
|
||||
/* We don't take a copy of the data or free it.
|
||||
*/
|
||||
blob = vips_blob_new( NULL, buf, len );
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "webpload_buffer", ap, blob, out );
|
||||
va_end( ap );
|
||||
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
@ -41,12 +41,12 @@
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#ifdef HAVE_LIBWEBP
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
#ifdef HAVE_LIBWEBP
|
||||
|
||||
#include "webp.h"
|
||||
|
||||
typedef struct _VipsForeignSaveWebp {
|
||||
@ -258,7 +258,9 @@ vips_foreign_save_webp_buffer_build( VipsObject *object )
|
||||
webp->alpha_q ) )
|
||||
return( -1 );
|
||||
|
||||
blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen );
|
||||
/* obuf is a g_free() buffer, not vips_free().
|
||||
*/
|
||||
blob = vips_blob_new( (VipsCallbackFn) g_free, obuf, olen );
|
||||
g_object_set( file, "buffer", blob, NULL );
|
||||
vips_area_unref( VIPS_AREA( blob ) );
|
||||
|
||||
@ -352,3 +354,138 @@ vips_foreign_save_webp_mime_init( VipsForeignSaveWebpMime *mime )
|
||||
}
|
||||
|
||||
#endif /*HAVE_LIBWEBP*/
|
||||
|
||||
/**
|
||||
* vips_webpsave:
|
||||
* @in: image to save
|
||||
* @filename: file to write to
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @Q: %gint quality factor
|
||||
* * @lossless: %gboolean enables lossless compression
|
||||
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
|
||||
* * @smart_subsample: %gboolean enables high quality chroma subsampling
|
||||
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
|
||||
* * @alpha_q: %gint set alpha quality in lossless mode
|
||||
*
|
||||
* Write an image to a file in WebP format.
|
||||
*
|
||||
* By default, images are saved in lossy format, with
|
||||
* @Q giving the WebP quality factor. It has the range 0 - 100, with the
|
||||
* default 75.
|
||||
*
|
||||
* Use @preset to hint the image type to the lossy compressor. The default is
|
||||
* #VIPS_FOREIGN_WEBP_PRESET_DEFAULT.
|
||||
* Set @smart_subsample to enable high quality chroma subsampling.
|
||||
* Use @alpha_q to set the quality for the alpha channel in lossy mode. It has
|
||||
* the range 1 - 100, with the default 100.
|
||||
*
|
||||
* Set @lossless to use lossless compression, or combine @near_lossless
|
||||
* with @Q 80, 60, 40 or 20 to apply increasing amounts of preprocessing
|
||||
* which improves the near-lossless compression ratio by up to 50%.
|
||||
*
|
||||
* See also: vips_webpload(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_webpsave( VipsImage *in, const char *filename, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, filename );
|
||||
result = vips_call_split( "webpsave", ap, in, filename );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_webpsave_buffer:
|
||||
* @in: image to save
|
||||
* @buf: return output buffer here
|
||||
* @len: return output length here
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @Q: %gint quality factor
|
||||
* * @lossless: %gboolean enables lossless compression
|
||||
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
|
||||
* * @smart_subsample: %gboolean enables high quality chroma subsampling
|
||||
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
|
||||
* * @alpha_q: %gint set alpha quality in lossless mode
|
||||
*
|
||||
* As vips_webpsave(), but save to a memory buffer.
|
||||
*
|
||||
* The address of the buffer is returned in @buf, the length of the buffer in
|
||||
* @len. You are responsible for freeing the buffer with g_free() when you
|
||||
* are done with it.
|
||||
*
|
||||
* See also: vips_webpsave().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_webpsave_buffer( VipsImage *in, void **buf, size_t *len, ... )
|
||||
{
|
||||
va_list ap;
|
||||
VipsArea *area;
|
||||
int result;
|
||||
|
||||
area = NULL;
|
||||
|
||||
va_start( ap, len );
|
||||
result = vips_call_split( "webpsave_buffer", ap, in, &area );
|
||||
va_end( ap );
|
||||
|
||||
if( !result &&
|
||||
area ) {
|
||||
if( buf ) {
|
||||
*buf = area->data;
|
||||
area->free_fn = NULL;
|
||||
}
|
||||
if( len )
|
||||
*len = area->length;
|
||||
|
||||
vips_area_unref( area );
|
||||
}
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_webpsave_mime:
|
||||
* @in: image to save
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Optional arguments:
|
||||
*
|
||||
* * @Q: %gint quality factor
|
||||
* * @lossless: %gboolean enables lossless compression
|
||||
* * @preset: #VipsForeignWebpPreset choose lossy compression preset
|
||||
* * @smart_subsample: %gboolean enables high quality chroma subsampling
|
||||
* * @near_lossless: %gboolean preprocess in lossless mode (controlled by Q)
|
||||
* * @alpha_q: %gint set alpha quality in lossless mode
|
||||
*
|
||||
* As vips_webpsave(), but save as a mime webp on stdout.
|
||||
*
|
||||
* See also: vips_webpsave(), vips_image_write_to_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_webpsave_mime( VipsImage *in, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, in );
|
||||
result = vips_call_split( "webpsave_mime", ap, in );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user