add vips_image_set_blob_copy()

and use it where we can
This commit is contained in:
John Cupitt 2018-11-23 16:27:39 +00:00
parent 8fa3b0aa1c
commit cff4af34ca
9 changed files with 35 additions and 124 deletions

View File

@ -7,6 +7,7 @@
- revise vips_cast() to improve behaviour with uint images [erdmann]
- add bandand()/or()/eor() to cplusplus binding [clcaalu]
- implement shrink-on-load for tiff pyramids [jcupitt]
- added vips_image_set_blob_copy() [jcupitt]
23/9/18 started 8.7.1
- update function list in docs [janko-m]

View File

@ -447,22 +447,6 @@ vips_image_resolution_from_exif( VipsImage *image, ExifData *ed )
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.
*/
static int
@ -516,7 +500,9 @@ vips__exif_parse( VipsImage *image )
exif_data_foreach_content( ed,
(ExifDataForeachContentFunc) vips_exif_get_content, &params );
vips_exif_get_thumbnail( image, ed );
vips_image_set_blob_copy( image,
"jpeg-thumbnail-data", ed->data, ed->size );
exif_data_free( ed );
/* Orientation handling. ifd0 has the Orientation tag for the main

View File

@ -309,8 +309,6 @@ find_chroma_subsample( struct jpeg_decompress_struct *cinfo )
static int
attach_blob( VipsImage *im, const char *field, void *data, int data_length )
{
char *data_copy;
/* Only use the first one.
*/
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 );
#endif /*DEBUG*/
if( !(data_copy = vips_malloc( NULL, data_length )) )
return( -1 );
memcpy( data_copy, data, data_length );
vips_image_set_blob( im, field,
(VipsCallbackFn) vips_free, data_copy, data_length );
vips_image_set_blob_copy( im, field, data, data_length );
return( 0 );
}

View File

@ -500,14 +500,9 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
for( i = 0; i < nim->num_ext; i++ ) {
nifti1_extension *ext = &nim->ext_list[i];
char *data_copy;
vips_snprintf( txt, 256, "nifti-ext-%d-%d", i, ext->ecode );
if( !(data_copy = vips_malloc( NULL, ext->esize )) )
return( -1 );
memcpy( data_copy, ext->edata, ext->esize );
vips_image_set_blob( out, txt,
(VipsCallbackFn) vips_free, data_copy, ext->esize );
vips_image_set_blob_copy( out, txt, ext->edata, ext->esize );
}
if( nim->ny > 1 )

View File

@ -1353,43 +1353,37 @@ rtiff_set_header( Rtiff *rtiff, VipsImage *out )
*/
if( TIFFGetField( rtiff->tiff,
TIFFTAG_ICCPROFILE, &data_length, &data ) ) {
if( vips_image_set_blob_copy( rtiff, out,
VIPS_META_ICC_NAME, data_length, data ) )
return( -1 );
vips_image_set_blob_copy( out,
VIPS_META_ICC_NAME, data, data_length );
}
/* Read any XMP metadata.
*/
if( TIFFGetField( rtiff->tiff,
TIFFTAG_XMLPACKET, &data_length, &data ) ) {
if( vips_image_set_blob_copy( rtiff, out,
VIPS_META_XMP_NAME, data_length, data ) )
return( -1 );
vips_image_set_blob_copy( out,
VIPS_META_XMP_NAME, data, data_length );
}
/* Read any IPTC metadata.
*/
if( TIFFGetField( rtiff->tiff,
TIFFTAG_RICHTIFFIPTC, &data_length, &data ) ) {
if( vips_image_set_blob_copy( rtiff, out,
VIPS_META_IPTC_NAME, data_length, data ) )
return( -1 );
vips_image_set_blob_copy( out,
VIPS_META_IPTC_NAME, data, data_length );
/* Older versions of libvips used this misspelt name :-( attach
* under this name too for compatibility.
*/
if( vips_image_set_blob_copy( rtiff, out,
"ipct-data", data_length, data ) )
return( -1 );
vips_image_set_blob_copy( out, "ipct-data", data, data_length );
}
/* Read any photoshop metadata.
*/
if( TIFFGetField( rtiff->tiff,
TIFFTAG_PHOTOSHOP, &data_length, &data ) ) {
if( vips_image_set_blob_copy( rtiff, out,
VIPS_META_PHOTOSHOP_NAME, data_length, data ) )
return( -1 );
vips_image_set_blob_copy( out,
VIPS_META_PHOTOSHOP_NAME, data, data_length );
}
/* IMAGEDESCRIPTION often has useful metadata.

View File

@ -448,19 +448,14 @@ png2vips_header( Read *read, VipsImage *out )
*/
if( png_get_iCCP( read->pPng, read->pInfo,
&name, &compression_type, &profile, &proflen ) ) {
void *profile_copy;
#ifdef DEBUG
printf( "png2vips_header: attaching %d bytes of ICC profile\n",
proflen );
printf( "png2vips_header: name = \"%s\"\n", name );
#endif /*DEBUG*/
if( !(profile_copy = vips_malloc( NULL, proflen )) )
return( -1 );
memcpy( profile_copy, profile, proflen );
vips_image_set_blob( out, VIPS_META_ICC_NAME,
(VipsCallbackFn) vips_free, profile_copy, proflen );
vips_image_set_blob_copy( out,
VIPS_META_ICC_NAME, profile, proflen );
}
/* Sanity-check line size.

View File

@ -254,18 +254,9 @@ read_header( Read *read, VipsImage *out )
WebPData data;
if( WebPMuxGetChunk( mux, webp, &data ) == WEBP_MUX_OK ) {
void *blob;
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 );
}
if( WebPMuxGetChunk( mux, webp, &data ) == WEBP_MUX_OK )
vips_image_set_blob_copy( out,
vips, data.bytes, data.size );
}
WebPMuxDelete( mux );

View File

@ -196,7 +196,7 @@ int vips_image_get_area( const VipsImage *image,
void vips_image_set_blob( VipsImage *image,
const char *name, VipsCallbackFn free_fn, void *data, size_t length );
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,
void **data, size_t *length );

View File

@ -27,7 +27,7 @@
* - vips_image_get_*() all convert everything to target type if they can
* - rename "field" as "name" in docs
* 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
*
* 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().
*
* 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.
* a copy of the memory area. A convenience function over
* vips_image_set_blob().
*
* See also: vips_image_get_blob(), vips_image_set().
*/
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 )
{
void *data_copy;
if( !data ||
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 )) )
return( -1 );
return;
memcpy( data_copy, data, length );
((unsigned char *) data_copy)[length] = '\0';
vips_image_set_blob( out, field,
(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 );
vips_image_set_blob( image,
name, (VipsCallbackFn) vips_free, data_copy, length );
}
/**
@ -1564,8 +1536,7 @@ vips_image_set_double( VipsImage *image, const char *name, double d )
*
* Gets @out from @im under the name @name.
* The field must be of type
* G_STRING, VIPS_TYPE_REFSTRING or VIPS_TYPE_BLOB. If it's a BLOB, it must be
* null-terminated.
* G_STRING, VIPS_TYPE_REFSTRING.
*
* 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 ) )
return( -1 );
if( G_VALUE_TYPE( &value ) == VIPS_TYPE_BLOB ) {
char *str;
size_t length;
str = vips_value_get_blob( &value, &length );
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 ) {
if( G_VALUE_TYPE( &value ) == VIPS_TYPE_REF_STRING ) {
VipsArea *area;
area = g_value_get_boxed( &value );