@@ -173,10 +173,6 @@ typedef struct _VipsForeignLoadHeif {
173
173
*/
174
174
struct heif_reader * reader ;
175
175
176
- /* When we see EOF from read(), record the source length here.
177
- */
178
- gint64 length ;
179
-
180
176
} VipsForeignLoadHeif ;
181
177
182
178
typedef struct _VipsForeignLoadHeifClass {
@@ -920,6 +916,11 @@ vips_foreign_load_heif_get_position( void *userdata )
920
916
return ( vips_source_seek ( heif -> source , 0L , SEEK_CUR ) );
921
917
}
922
918
919
+ /* libheif read() does not work like unix read().
920
+ *
921
+ * This method is cannot return EOF. Instead, the separate wait_for_file_size()
922
+ * is called beforehand to make sure that there's enough data there.
923
+ */
923
924
static int
924
925
vips_foreign_load_heif_read ( void * data , size_t size , void * userdata )
925
926
{
@@ -928,16 +929,6 @@ vips_foreign_load_heif_read( void *data, size_t size, void *userdata )
928
929
gint64 result ;
929
930
930
931
result = vips_source_read ( heif -> source , data , size );
931
- /* On EOF, make a note of the file length.
932
- *
933
- * libheif can sometimes ask for zero bytes, be careful not to
934
- * interpret that as EOF.
935
- */
936
- if ( size > 0 &&
937
- result == 0 &&
938
- heif -> length == -1 )
939
- result = heif -> length =
940
- vips_source_seek ( heif -> source , 0L , SEEK_CUR );
941
932
if ( result < 0 )
942
933
return ( -1 );
943
934
@@ -954,30 +945,33 @@ vips_foreign_load_heif_seek( gint64 position, void *userdata )
954
945
return ( 0 );
955
946
}
956
947
948
+ /* libheif calls this to mean "I intend to read() to this position, please
949
+ * check it is OK".
950
+ */
957
951
static enum heif_reader_grow_status
958
952
vips_foreign_load_heif_wait_for_file_size ( gint64 target_size , void * userdata )
959
953
{
960
954
VipsForeignLoadHeif * heif = (VipsForeignLoadHeif * ) userdata ;
961
955
956
+ gint64 old_position ;
957
+ gint64 result ;
962
958
enum heif_reader_grow_status status ;
963
959
964
- if ( heif -> source -> data != NULL && target_size > heif -> source -> length )
965
- /* Target size is beyond known buffer length
960
+ /* We seek the VipsSource to the position and check for errors.
961
+ */
962
+ old_position = vips_source_seek ( heif -> source , 0L , SEEK_CUR );
963
+ result = vips_source_seek ( heif -> source , target_size , SEEK_SET );
964
+ vips_source_seek ( heif -> source , old_position , SEEK_SET );
965
+
966
+ if ( result < 0 )
967
+ /* Unable to seek to this point, so it's beyond EOF.
966
968
*/
967
969
status = heif_reader_grow_status_size_beyond_eof ;
968
- else if ( heif -> length == -1 )
969
- /* We've not seen EOF yet, so seeking to any point is fine (as
970
- * far as we know).
971
- */
972
- status = heif_reader_grow_status_size_reached ;
973
- else if ( target_size <= heif -> length )
974
- /* We've seen EOF, and this target is less than that.
975
- */
976
- status = heif_reader_grow_status_size_reached ;
977
970
else
978
- /* We've seen EOF, we know the length, and this is too far.
971
+ /* Successfully read to the requested point, but the requested
972
+ * point is not necessarily EOF.
979
973
*/
980
- status = heif_reader_grow_status_size_beyond_eof ;
974
+ status = heif_reader_grow_status_size_reached ;
981
975
982
976
return ( status );
983
977
}
@@ -986,7 +980,6 @@ static void
986
980
vips_foreign_load_heif_init ( VipsForeignLoadHeif * heif )
987
981
{
988
982
heif -> n = 1 ;
989
- heif -> length = -1 ;
990
983
991
984
heif -> reader = VIPS_ARRAY ( NULL , 1 , struct heif_reader );
992
985
0 commit comments