improve fail-on handling for GIF load
fail-on truncated and warning now works for GIF load
This commit is contained in:
parent
b32bc70de7
commit
3ebb21491d
@ -18,6 +18,7 @@ master
|
|||||||
- threadpools size dynamically with load
|
- threadpools size dynamically with load
|
||||||
- operations can hint threadpool size
|
- operations can hint threadpool size
|
||||||
- support for N-colour ICC profiles
|
- support for N-colour ICC profiles
|
||||||
|
- GIF load supports truncated frames [tlsa]
|
||||||
|
|
||||||
11/10/22 started 8.13.3
|
11/10/22 started 8.13.3
|
||||||
- improve rules for 16-bit heifsave [johntrunc]
|
- improve rules for 16-bit heifsave [johntrunc]
|
||||||
|
@ -359,19 +359,44 @@ vips_foreign_load_nsgif_header( VipsForeignLoad *load )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
vips_source_minimise( gif->source );
|
vips_source_minimise( gif->source );
|
||||||
|
|
||||||
|
/* Treat errors from _scan() as warnings. If libnsgif really can't do
|
||||||
|
* something it'll fail gracefully later when we try to read out
|
||||||
|
* frame data.
|
||||||
|
*/
|
||||||
result = nsgif_data_scan( gif->anim, size, (void *) data );
|
result = nsgif_data_scan( gif->anim, size, (void *) data );
|
||||||
VIPS_DEBUG_MSG( "nsgif_data_scan() = %s\n", nsgif_strerror( result ) );
|
VIPS_DEBUG_MSG( "nsgif_data_scan() = %s\n", nsgif_strerror( result ) );
|
||||||
|
switch( result ) {
|
||||||
|
case NSGIF_ERR_END_OF_DATA:
|
||||||
|
if( load->fail_on >= VIPS_FAIL_ON_TRUNCATED ) {
|
||||||
|
vips_foreign_load_nsgif_error( gif, result );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning( "%s", nsgif_strerror( result ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSGIF_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if( load->fail_on >= VIPS_FAIL_ON_WARNING ) {
|
||||||
|
vips_foreign_load_nsgif_error( gif, result );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning( "%s", nsgif_strerror( result ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell libnsgif that that's all the data we have. This will let us
|
||||||
|
* read out any truncated final frames.
|
||||||
|
*/
|
||||||
nsgif_data_complete( gif->anim );
|
nsgif_data_complete( gif->anim );
|
||||||
gif->info = nsgif_get_info(gif->anim);
|
|
||||||
|
gif->info = nsgif_get_info( gif->anim );
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
print_animation( gif->anim, gif->info );
|
print_animation( gif->anim, gif->info );
|
||||||
#endif /*VERBOSE*/
|
#endif /*VERBOSE*/
|
||||||
if( result != NSGIF_OK &&
|
|
||||||
load->fail_on >= VIPS_FAIL_ON_WARNING ) {
|
|
||||||
vips_foreign_load_nsgif_error( gif, result );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !gif->info->frame_count ) {
|
if( !gif->info->frame_count ) {
|
||||||
vips_error( class->nickname, "%s", _( "no frames in GIF" ) );
|
vips_error( class->nickname, "%s", _( "no frames in GIF" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
BIN
test/test-suite/images/garden.gif
Normal file
BIN
test/test-suite/images/garden.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 MiB |
BIN
test/test-suite/images/truncated.gif
Normal file
BIN
test/test-suite/images/truncated.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -7,7 +7,7 @@ import pytest
|
|||||||
|
|
||||||
import pyvips
|
import pyvips
|
||||||
from helpers import \
|
from helpers import \
|
||||||
JPEG_FILE, SRGB_FILE, MATLAB_FILE, PNG_FILE, TIF_FILE, OME_FILE, \
|
IMAGES, JPEG_FILE, SRGB_FILE, MATLAB_FILE, PNG_FILE, TIF_FILE, OME_FILE, \
|
||||||
ANALYZE_FILE, GIF_FILE, WEBP_FILE, EXR_FILE, FITS_FILE, OPENSLIDE_FILE, \
|
ANALYZE_FILE, GIF_FILE, WEBP_FILE, EXR_FILE, FITS_FILE, OPENSLIDE_FILE, \
|
||||||
PDF_FILE, SVG_FILE, SVGZ_FILE, SVG_GZ_FILE, GIF_ANIM_FILE, DICOM_FILE, \
|
PDF_FILE, SVG_FILE, SVGZ_FILE, SVG_GZ_FILE, GIF_ANIM_FILE, DICOM_FILE, \
|
||||||
BMP_FILE, NIFTI_FILE, ICO_FILE, TGA_FILE, SGI_FILE, AVIF_FILE, \
|
BMP_FILE, NIFTI_FILE, ICO_FILE, TGA_FILE, SGI_FILE, AVIF_FILE, \
|
||||||
@ -1012,6 +1012,32 @@ class TestForeign:
|
|||||||
x2 = pyvips.Image.new_from_file(GIF_ANIM_DISPOSE_PREVIOUS_EXPECTED_PNG_FILE)
|
x2 = pyvips.Image.new_from_file(GIF_ANIM_DISPOSE_PREVIOUS_EXPECTED_PNG_FILE)
|
||||||
assert (x1 - x2).abs().max() == 0
|
assert (x1 - x2).abs().max() == 0
|
||||||
|
|
||||||
|
@skip_if_no("gifload")
|
||||||
|
def test_gifload_truncated(self):
|
||||||
|
# should load with just a warning
|
||||||
|
truncated_gif = os.path.join(IMAGES, "truncated.gif")
|
||||||
|
im = pyvips.Image.new_from_file(truncated_gif)
|
||||||
|
assert im.width == 575
|
||||||
|
|
||||||
|
# should fail on truncation and warning
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
im = pyvips.Image.new_from_file(truncated_gif, fail_on="warning")
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
im = pyvips.Image.new_from_file(truncated_gif, fail_on="truncated")
|
||||||
|
|
||||||
|
@skip_if_no("gifload")
|
||||||
|
def test_gifload_frame_error(self):
|
||||||
|
# should load with just a warning
|
||||||
|
truncated_gif = os.path.join(IMAGES, "garden.gif")
|
||||||
|
im = pyvips.Image.new_from_file(truncated_gif)
|
||||||
|
assert im.width == 800
|
||||||
|
|
||||||
|
# should fail on warning only
|
||||||
|
im = pyvips.Image.new_from_file(truncated_gif, fail_on="truncated")
|
||||||
|
assert im.width == 800
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
im = pyvips.Image.new_from_file(truncated_gif, fail_on="warning")
|
||||||
|
|
||||||
@skip_if_no("svgload")
|
@skip_if_no("svgload")
|
||||||
def test_svgload(self):
|
def test_svgload(self):
|
||||||
def svg_valid(im):
|
def svg_valid(im):
|
||||||
|
Loading…
Reference in New Issue
Block a user