add vips_image_set_blob_copy()
and use it where we can
This commit is contained in:
parent
8fa3b0aa1c
commit
cff4af34ca
@ -7,6 +7,7 @@
|
|||||||
- revise vips_cast() to improve behaviour with uint images [erdmann]
|
- revise vips_cast() to improve behaviour with uint images [erdmann]
|
||||||
- add bandand()/or()/eor() to cplusplus binding [clcaalu]
|
- add bandand()/or()/eor() to cplusplus binding [clcaalu]
|
||||||
- implement shrink-on-load for tiff pyramids [jcupitt]
|
- implement shrink-on-load for tiff pyramids [jcupitt]
|
||||||
|
- added vips_image_set_blob_copy() [jcupitt]
|
||||||
|
|
||||||
23/9/18 started 8.7.1
|
23/9/18 started 8.7.1
|
||||||
- update function list in docs [janko-m]
|
- update function list in docs [janko-m]
|
||||||
|
@ -447,22 +447,6 @@ vips_image_resolution_from_exif( VipsImage *image, ExifData *ed )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
vips_exif_get_thumbnail( VipsImage *im, ExifData *ed )
|
|
||||||
{
|
|
||||||
if( ed->size > 0 ) {
|
|
||||||
char *thumb_copy;
|
|
||||||
|
|
||||||
thumb_copy = g_malloc( ed->size );
|
|
||||||
memcpy( thumb_copy, ed->data, ed->size );
|
|
||||||
|
|
||||||
vips_image_set_blob( im, "jpeg-thumbnail-data",
|
|
||||||
(VipsCallbackFn) g_free, thumb_copy, ed->size );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need to fwd ref this.
|
/* Need to fwd ref this.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@ -516,7 +500,9 @@ vips__exif_parse( VipsImage *image )
|
|||||||
exif_data_foreach_content( ed,
|
exif_data_foreach_content( ed,
|
||||||
(ExifDataForeachContentFunc) vips_exif_get_content, ¶ms );
|
(ExifDataForeachContentFunc) vips_exif_get_content, ¶ms );
|
||||||
|
|
||||||
vips_exif_get_thumbnail( image, ed );
|
vips_image_set_blob_copy( image,
|
||||||
|
"jpeg-thumbnail-data", ed->data, ed->size );
|
||||||
|
|
||||||
exif_data_free( ed );
|
exif_data_free( ed );
|
||||||
|
|
||||||
/* Orientation handling. ifd0 has the Orientation tag for the main
|
/* Orientation handling. ifd0 has the Orientation tag for the main
|
||||||
|
@ -309,8 +309,6 @@ find_chroma_subsample( struct jpeg_decompress_struct *cinfo )
|
|||||||
static int
|
static int
|
||||||
attach_blob( VipsImage *im, const char *field, void *data, int data_length )
|
attach_blob( VipsImage *im, const char *field, void *data, int data_length )
|
||||||
{
|
{
|
||||||
char *data_copy;
|
|
||||||
|
|
||||||
/* Only use the first one.
|
/* Only use the first one.
|
||||||
*/
|
*/
|
||||||
if( vips_image_get_typeof( im, field ) ) {
|
if( vips_image_get_typeof( im, field ) ) {
|
||||||
@ -325,11 +323,7 @@ attach_blob( VipsImage *im, const char *field, void *data, int data_length )
|
|||||||
printf( "attach_blob: attaching %d bytes of %s\n", data_length, field );
|
printf( "attach_blob: attaching %d bytes of %s\n", data_length, field );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
if( !(data_copy = vips_malloc( NULL, data_length )) )
|
vips_image_set_blob_copy( im, field, data, data_length );
|
||||||
return( -1 );
|
|
||||||
memcpy( data_copy, data, data_length );
|
|
||||||
vips_image_set_blob( im, field,
|
|
||||||
(VipsCallbackFn) vips_free, data_copy, data_length );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -500,14 +500,9 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
|||||||
|
|
||||||
for( i = 0; i < nim->num_ext; i++ ) {
|
for( i = 0; i < nim->num_ext; i++ ) {
|
||||||
nifti1_extension *ext = &nim->ext_list[i];
|
nifti1_extension *ext = &nim->ext_list[i];
|
||||||
char *data_copy;
|
|
||||||
|
|
||||||
vips_snprintf( txt, 256, "nifti-ext-%d-%d", i, ext->ecode );
|
vips_snprintf( txt, 256, "nifti-ext-%d-%d", i, ext->ecode );
|
||||||
if( !(data_copy = vips_malloc( NULL, ext->esize )) )
|
vips_image_set_blob_copy( out, txt, ext->edata, ext->esize );
|
||||||
return( -1 );
|
|
||||||
memcpy( data_copy, ext->edata, ext->esize );
|
|
||||||
vips_image_set_blob( out, txt,
|
|
||||||
(VipsCallbackFn) vips_free, data_copy, ext->esize );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nim->ny > 1 )
|
if( nim->ny > 1 )
|
||||||
|
@ -1353,43 +1353,37 @@ rtiff_set_header( Rtiff *rtiff, VipsImage *out )
|
|||||||
*/
|
*/
|
||||||
if( TIFFGetField( rtiff->tiff,
|
if( TIFFGetField( rtiff->tiff,
|
||||||
TIFFTAG_ICCPROFILE, &data_length, &data ) ) {
|
TIFFTAG_ICCPROFILE, &data_length, &data ) ) {
|
||||||
if( vips_image_set_blob_copy( rtiff, out,
|
vips_image_set_blob_copy( out,
|
||||||
VIPS_META_ICC_NAME, data_length, data ) )
|
VIPS_META_ICC_NAME, data, data_length );
|
||||||
return( -1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read any XMP metadata.
|
/* Read any XMP metadata.
|
||||||
*/
|
*/
|
||||||
if( TIFFGetField( rtiff->tiff,
|
if( TIFFGetField( rtiff->tiff,
|
||||||
TIFFTAG_XMLPACKET, &data_length, &data ) ) {
|
TIFFTAG_XMLPACKET, &data_length, &data ) ) {
|
||||||
if( vips_image_set_blob_copy( rtiff, out,
|
vips_image_set_blob_copy( out,
|
||||||
VIPS_META_XMP_NAME, data_length, data ) )
|
VIPS_META_XMP_NAME, data, data_length );
|
||||||
return( -1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read any IPTC metadata.
|
/* Read any IPTC metadata.
|
||||||
*/
|
*/
|
||||||
if( TIFFGetField( rtiff->tiff,
|
if( TIFFGetField( rtiff->tiff,
|
||||||
TIFFTAG_RICHTIFFIPTC, &data_length, &data ) ) {
|
TIFFTAG_RICHTIFFIPTC, &data_length, &data ) ) {
|
||||||
if( vips_image_set_blob_copy( rtiff, out,
|
vips_image_set_blob_copy( out,
|
||||||
VIPS_META_IPTC_NAME, data_length, data ) )
|
VIPS_META_IPTC_NAME, data, data_length );
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* Older versions of libvips used this misspelt name :-( attach
|
/* Older versions of libvips used this misspelt name :-( attach
|
||||||
* under this name too for compatibility.
|
* under this name too for compatibility.
|
||||||
*/
|
*/
|
||||||
if( vips_image_set_blob_copy( rtiff, out,
|
vips_image_set_blob_copy( out, "ipct-data", data, data_length );
|
||||||
"ipct-data", data_length, data ) )
|
|
||||||
return( -1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read any photoshop metadata.
|
/* Read any photoshop metadata.
|
||||||
*/
|
*/
|
||||||
if( TIFFGetField( rtiff->tiff,
|
if( TIFFGetField( rtiff->tiff,
|
||||||
TIFFTAG_PHOTOSHOP, &data_length, &data ) ) {
|
TIFFTAG_PHOTOSHOP, &data_length, &data ) ) {
|
||||||
if( vips_image_set_blob_copy( rtiff, out,
|
vips_image_set_blob_copy( out,
|
||||||
VIPS_META_PHOTOSHOP_NAME, data_length, data ) )
|
VIPS_META_PHOTOSHOP_NAME, data, data_length );
|
||||||
return( -1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IMAGEDESCRIPTION often has useful metadata.
|
/* IMAGEDESCRIPTION often has useful metadata.
|
||||||
|
@ -448,19 +448,14 @@ png2vips_header( Read *read, VipsImage *out )
|
|||||||
*/
|
*/
|
||||||
if( png_get_iCCP( read->pPng, read->pInfo,
|
if( png_get_iCCP( read->pPng, read->pInfo,
|
||||||
&name, &compression_type, &profile, &proflen ) ) {
|
&name, &compression_type, &profile, &proflen ) ) {
|
||||||
void *profile_copy;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "png2vips_header: attaching %d bytes of ICC profile\n",
|
printf( "png2vips_header: attaching %d bytes of ICC profile\n",
|
||||||
proflen );
|
proflen );
|
||||||
printf( "png2vips_header: name = \"%s\"\n", name );
|
printf( "png2vips_header: name = \"%s\"\n", name );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
if( !(profile_copy = vips_malloc( NULL, proflen )) )
|
vips_image_set_blob_copy( out,
|
||||||
return( -1 );
|
VIPS_META_ICC_NAME, profile, proflen );
|
||||||
memcpy( profile_copy, profile, proflen );
|
|
||||||
vips_image_set_blob( out, VIPS_META_ICC_NAME,
|
|
||||||
(VipsCallbackFn) vips_free, profile_copy, proflen );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity-check line size.
|
/* Sanity-check line size.
|
||||||
|
@ -254,18 +254,9 @@ read_header( Read *read, VipsImage *out )
|
|||||||
|
|
||||||
WebPData data;
|
WebPData data;
|
||||||
|
|
||||||
if( WebPMuxGetChunk( mux, webp, &data ) == WEBP_MUX_OK ) {
|
if( WebPMuxGetChunk( mux, webp, &data ) == WEBP_MUX_OK )
|
||||||
void *blob;
|
vips_image_set_blob_copy( out,
|
||||||
|
vips, data.bytes, data.size );
|
||||||
if( !(blob = vips_malloc( NULL, data.size )) ) {
|
|
||||||
WebPMuxDelete( mux );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( blob, data.bytes, data.size );
|
|
||||||
vips_image_set_blob( out, vips,
|
|
||||||
(VipsCallbackFn) vips_free, blob, data.size );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebPMuxDelete( mux );
|
WebPMuxDelete( mux );
|
||||||
|
@ -196,7 +196,7 @@ int vips_image_get_area( const VipsImage *image,
|
|||||||
void vips_image_set_blob( VipsImage *image,
|
void vips_image_set_blob( VipsImage *image,
|
||||||
const char *name, VipsCallbackFn free_fn, void *data, size_t length );
|
const char *name, VipsCallbackFn free_fn, void *data, size_t length );
|
||||||
void vips_image_set_blob_copy( VipsImage *image,
|
void vips_image_set_blob_copy( VipsImage *image,
|
||||||
const char *name, void *data, size_t length );
|
const char *name, const void *data, size_t length );
|
||||||
int vips_image_get_blob( const VipsImage *image, const char *name,
|
int vips_image_get_blob( const VipsImage *image, const char *name,
|
||||||
void **data, size_t *length );
|
void **data, size_t *length );
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
* - vips_image_get_*() all convert everything to target type if they can
|
* - vips_image_get_*() all convert everything to target type if they can
|
||||||
* - rename "field" as "name" in docs
|
* - rename "field" as "name" in docs
|
||||||
* 21/11/18
|
* 21/11/18
|
||||||
* - get_string will allow BLOB, G_STRING and REF_STRING
|
* - get_string will allow G_STRING and REF_STRING
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1368,60 +1368,32 @@ vips_image_set_blob( VipsImage *image,
|
|||||||
* @length: length of memory area
|
* @length: length of memory area
|
||||||
*
|
*
|
||||||
* Attaches @blob as a metadata item on @image under the name @name, taking
|
* Attaches @blob as a metadata item on @image under the name @name, taking
|
||||||
* a copy of the memory area. A convenience function over vips_image_set_blob().
|
* a copy of the memory area. A convenience function over
|
||||||
*
|
* vips_image_set_blob().
|
||||||
* One more byte is allocated and a secret null added to the end, although
|
|
||||||
* this extra length is not recorded. This makes reading the value out later
|
|
||||||
* as a C string safer and more convenient.
|
|
||||||
*
|
*
|
||||||
* See also: vips_image_get_blob(), vips_image_set().
|
* See also: vips_image_get_blob(), vips_image_set().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vips_image_set_blob_copy( VipsImage *image,
|
vips_image_set_blob_copy( VipsImage *image,
|
||||||
const char *name, void *data, size_t length )
|
const char *name, const void *data, size_t length )
|
||||||
{
|
{
|
||||||
void *data_copy;
|
void *data_copy;
|
||||||
|
|
||||||
if( !data ||
|
if( !data ||
|
||||||
length == 0 )
|
length == 0 )
|
||||||
return( 0 );
|
return;
|
||||||
|
|
||||||
|
/* We add an extra, secret null byte at the end, just in case this blob
|
||||||
|
* is read as a C string. The libtiff reader (for example) attaches
|
||||||
|
* XMP XML as a blob, for example.
|
||||||
|
*/
|
||||||
if( !(data_copy = vips_malloc( NULL, length + 1 )) )
|
if( !(data_copy = vips_malloc( NULL, length + 1 )) )
|
||||||
return( -1 );
|
return;
|
||||||
memcpy( data_copy, data, length );
|
memcpy( data_copy, data, length );
|
||||||
((unsigned char *) data_copy)[length] = '\0';
|
((unsigned char *) data_copy)[length] = '\0';
|
||||||
|
|
||||||
vips_image_set_blob( out, field,
|
vips_image_set_blob( image,
|
||||||
(VipsCallbackFn) vips_free, data_copy, length );
|
name, (VipsCallbackFn) vips_free, data_copy, length );
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set a blob on an image from a libtiff pointer/length. We don't null
|
|
||||||
* terminate, even though most of these things are strings, because we want to
|
|
||||||
* be able to write them back unaltered.
|
|
||||||
*
|
|
||||||
* Null-termination, checking for utf-8, checking for embedded null characters
|
|
||||||
* etc. must all be done on readout from the blob.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
rtiff_set_blob( Rtiff *rtiff, VipsImage *out, const char *field,
|
|
||||||
uint32 data_length, unsigned char *data )
|
|
||||||
{
|
|
||||||
unsigned char *data_copy;
|
|
||||||
|
|
||||||
if( !data ||
|
|
||||||
data_length == 0 )
|
|
||||||
return( 0 );
|
|
||||||
|
|
||||||
if( !(data_copy = vips_malloc( NULL, data_length )) )
|
|
||||||
return( -1 );
|
|
||||||
memcpy( data_copy, data, data_length );
|
|
||||||
|
|
||||||
vips_image_set_blob( out, field,
|
|
||||||
(VipsCallbackFn) vips_free, data_copy, data_length );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1564,8 +1536,7 @@ vips_image_set_double( VipsImage *image, const char *name, double d )
|
|||||||
*
|
*
|
||||||
* Gets @out from @im under the name @name.
|
* Gets @out from @im under the name @name.
|
||||||
* The field must be of type
|
* The field must be of type
|
||||||
* G_STRING, VIPS_TYPE_REFSTRING or VIPS_TYPE_BLOB. If it's a BLOB, it must be
|
* G_STRING, VIPS_TYPE_REFSTRING.
|
||||||
* null-terminated.
|
|
||||||
*
|
*
|
||||||
* Do not free @out.
|
* Do not free @out.
|
||||||
*
|
*
|
||||||
@ -1583,24 +1554,8 @@ vips_image_get_string( const VipsImage *image, const char *name,
|
|||||||
|
|
||||||
if( vips_image_get( image, name, &value ) )
|
if( vips_image_get( image, name, &value ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( G_VALUE_TYPE( &value ) == VIPS_TYPE_BLOB ) {
|
|
||||||
char *str;
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
str = vips_value_get_blob( &value, &length );
|
if( G_VALUE_TYPE( &value ) == VIPS_TYPE_REF_STRING ) {
|
||||||
if( length <= 0 ||
|
|
||||||
str[length] != '\0' ) {
|
|
||||||
g_value_unset( &value );
|
|
||||||
vips_error( "VipsImage",
|
|
||||||
_( "field \"%s\" is not null-terminated" ),
|
|
||||||
name );
|
|
||||||
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = str;
|
|
||||||
}
|
|
||||||
else if( G_VALUE_TYPE( &value ) == VIPS_TYPE_REF_STRING ) {
|
|
||||||
VipsArea *area;
|
VipsArea *area;
|
||||||
|
|
||||||
area = g_value_get_boxed( &value );
|
area = g_value_get_boxed( &value );
|
||||||
|
Loading…
Reference in New Issue
Block a user