add exif support to png load/save (#3168)
* start adding exif in png the "Exif\0\0" header isn't being added and removed correctly needs tests * all done tested with linpng and libspng
This commit is contained in:
parent
ef1300a288
commit
e3289ad2c1
@ -23,6 +23,7 @@ master
|
|||||||
- fits write doesn't duplicate header fields
|
- fits write doesn't duplicate header fields
|
||||||
- add @wrap to vips_text()
|
- add @wrap to vips_text()
|
||||||
- GIF load supports truncated frames [tlsa]
|
- GIF load supports truncated frames [tlsa]
|
||||||
|
- EXIF support for PNG load and save
|
||||||
|
|
||||||
9/11/22 started 8.13.4
|
9/11/22 started 8.13.4
|
||||||
- missing include in mosaic_fuzzer [ServOKio]
|
- missing include in mosaic_fuzzer [ServOKio]
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
* - use libspng for save
|
* - use libspng for save
|
||||||
* 15/7/22 [lovell]
|
* 15/7/22 [lovell]
|
||||||
* - default filter to none
|
* - default filter to none
|
||||||
|
* 17/11/22
|
||||||
|
* - add exif save
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -56,6 +58,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <vips/vips.h>
|
#include <vips/vips.h>
|
||||||
|
#include <vips/internal.h>
|
||||||
|
|
||||||
#include "pforeign.h"
|
#include "pforeign.h"
|
||||||
#include "quantise.h"
|
#include "quantise.h"
|
||||||
@ -244,6 +247,25 @@ vips_foreign_save_spng_metadata( VipsForeignSaveSpng *spng, VipsImage *in )
|
|||||||
g_free( str );
|
g_free( str );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( vips_image_get_typeof( in, VIPS_META_EXIF_NAME ) ) {
|
||||||
|
struct spng_exif exif;
|
||||||
|
|
||||||
|
if( vips__exif_update( in ) ||
|
||||||
|
vips_image_get_blob( in, VIPS_META_EXIF_NAME,
|
||||||
|
(const void **) &exif.data, &exif.length ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
/* libspng does not want the JFIF "Exif\0\0" prefix.
|
||||||
|
*/
|
||||||
|
if( exif.length >= 6 &&
|
||||||
|
vips_isprefix( "Exif", exif.data ) ) {
|
||||||
|
exif.data += 6;
|
||||||
|
exif.length -= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
spng_set_exif( spng->ctx, &exif );
|
||||||
|
}
|
||||||
|
|
||||||
if( vips_image_map( in, vips_foreign_save_spng_comment, spng ) )
|
if( vips_image_map( in, vips_foreign_save_spng_comment, spng ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@
|
|||||||
* - add "unlimited" flag to png load
|
* - add "unlimited" flag to png load
|
||||||
* 13/1/22
|
* 13/1/22
|
||||||
* - raise libpng pixel size limit to VIPS_MAX_COORD
|
* - raise libpng pixel size limit to VIPS_MAX_COORD
|
||||||
|
* 17/11/22
|
||||||
|
* - add exif read/write
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -638,6 +640,17 @@ png2vips_header( Read *read, VipsImage *out )
|
|||||||
}
|
}
|
||||||
#endif /*PNG_bKGD_SUPPORTED*/
|
#endif /*PNG_bKGD_SUPPORTED*/
|
||||||
|
|
||||||
|
#ifdef PNG_eXIf_SUPPORTED
|
||||||
|
{
|
||||||
|
png_uint_32 num_exif;
|
||||||
|
png_bytep exif;
|
||||||
|
|
||||||
|
if( png_get_eXIf_1( read->pPng, read->pInfo, &num_exif, &exif ) )
|
||||||
|
vips_image_set_blob_copy( out, VIPS_META_EXIF_NAME,
|
||||||
|
exif, num_exif );
|
||||||
|
}
|
||||||
|
#endif /*PNG_eXIf_SUPPORTED*/
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1173,8 +1186,30 @@ write_vips( Write *write,
|
|||||||
g_free( str );
|
g_free( str );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( vips_image_map( in,
|
#ifdef PNG_eXIf_SUPPORTED
|
||||||
write_png_comment, write ) )
|
if( vips_image_get_typeof( in, VIPS_META_EXIF_NAME ) ) {
|
||||||
|
const void *data;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
if( vips__exif_update( in ) ||
|
||||||
|
vips_image_get_blob( in, VIPS_META_EXIF_NAME,
|
||||||
|
&data, &length ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
/* libpng does not want the JFIF "Exif\0\0" prefix.
|
||||||
|
*/
|
||||||
|
if( length >= 6 &&
|
||||||
|
vips_isprefix( "Exif", (char *) data ) ) {
|
||||||
|
data += 6;
|
||||||
|
length -= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_set_eXIf_1( write->pPng, write->pInfo,
|
||||||
|
length, (png_bytep) data );
|
||||||
|
}
|
||||||
|
#endif /*PNG_eXIf_SUPPORTED*/
|
||||||
|
|
||||||
|
if( vips_image_map( in, write_png_comment, write ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,6 +457,25 @@ class TestForeign:
|
|||||||
# we can't test palette save since we can't be sure libimagequant is
|
# we can't test palette save since we can't be sure libimagequant is
|
||||||
# available and there's no easy test for its presence
|
# available and there's no easy test for its presence
|
||||||
|
|
||||||
|
# see if we have exif parsing: our test jpg image has this field
|
||||||
|
x = pyvips.Image.new_from_file(JPEG_FILE)
|
||||||
|
if x.get_typeof("exif-ifd0-Orientation") != 0:
|
||||||
|
# we need a copy of the image to set the new metadata on
|
||||||
|
# otherwise we get caching problems
|
||||||
|
|
||||||
|
# can set, save and load new orientation
|
||||||
|
x = pyvips.Image.new_from_file(JPEG_FILE)
|
||||||
|
x = x.copy()
|
||||||
|
|
||||||
|
x.set("orientation", 2)
|
||||||
|
|
||||||
|
filename = temp_filename(self.tempdir, '.png')
|
||||||
|
x.write_to_file(filename)
|
||||||
|
|
||||||
|
x = pyvips.Image.new_from_file(filename)
|
||||||
|
y = x.get("orientation")
|
||||||
|
assert y == 2
|
||||||
|
|
||||||
@skip_if_no("tiffload")
|
@skip_if_no("tiffload")
|
||||||
def test_tiff(self):
|
def test_tiff(self):
|
||||||
def tiff_valid(im):
|
def tiff_valid(im):
|
||||||
|
Loading…
Reference in New Issue
Block a user