11using System ;
22using System . IO ;
33using System . Linq ;
4+ using System . Security ;
45using System . Text . RegularExpressions ;
56using System . Threading ;
67using System . Threading . Tasks ;
@@ -25,8 +26,15 @@ internal static class TerrainTextureGeoReferencedRasterMetadataReader
2526 CancellationToken cancellationToken )
2627 {
2728 ArgumentNullException . ThrowIfNull ( source ) ;
28- await using Stream stream = await source . OpenReadAsync ( cancellationToken ) ;
29- return await TryReadMetadataAsync ( stream , cancellationToken ) ;
29+ try
30+ {
31+ await using Stream stream = await source . OpenReadAsync ( cancellationToken ) ;
32+ return await TryReadMetadataAsync ( stream , cancellationToken ) ;
33+ }
34+ catch ( Exception exception ) when ( IsCandidateRasterReadFailure ( exception ) )
35+ {
36+ return null ;
37+ }
3038 }
3139
3240 public static async Task < GeoReferencedRasterMetadata ? > TryReadMetadataAsync (
@@ -38,42 +46,45 @@ internal static class TerrainTextureGeoReferencedRasterMetadataReader
3846 return null ;
3947 }
4048
41- ImageInfo imageInfo ;
4249 try
4350 {
44- imageInfo = await Image . IdentifyAsync ( sourcePath , cancellationToken )
45- ?? throw new InvalidOperationException ( $ "Failed to identify raster '{ sourcePath } '.") ;
51+ ImageInfo ? identifiedImage = await Image . IdentifyAsync ( sourcePath , cancellationToken ) ;
52+ if ( identifiedImage is null )
53+ {
54+ return null ;
55+ }
56+
57+ ImageInfo imageInfo = identifiedImage ;
58+ ExifProfile ? exifProfile = imageInfo . Metadata . ExifProfile ;
59+ GeoTiffTagSnapshot ? tiffTags = await GeoTiffTagReader . TryReadAsync ( sourcePath , cancellationToken ) ;
60+
61+ double [ ] ? tiePoints = TryGetDoubleArray ( exifProfile , ExifTag . ModelTiePoint )
62+ ?? tiffTags ? . ModelTiePoint ;
63+ double [ ] ? pixelScale = TryGetDoubleArray ( exifProfile , ExifTag . PixelScale )
64+ ?? tiffTags ? . PixelScale ;
65+ double [ ] ? modelTransform = TryGetDoubleArray ( exifProfile , ExifTag . ModelTransform )
66+ ?? tiffTags ? . ModelTransform ;
67+ ushort [ ] ? geoKeyDirectory = TryGetUnsignedShortArray ( exifProfile , "GeoKeyDirectoryTag" )
68+ ?? tiffTags ? . GeoKeyDirectory ;
69+ double [ ] ? geoDoubleParams = TryGetNamedDoubleArray ( exifProfile , "GeoDoubleParamsTag" )
70+ ?? tiffTags ? . GeoDoubleParams ;
71+ string ? geoAsciiParams = TryGetNamedString ( exifProfile , "GeoAsciiParamsTag" )
72+ ?? tiffTags ? . GeoAsciiParams ;
73+
74+ return TryCreateMetadata (
75+ imageInfo . Width ,
76+ imageInfo . Height ,
77+ tiePoints ,
78+ pixelScale ,
79+ modelTransform ,
80+ geoKeyDirectory ,
81+ geoDoubleParams ,
82+ geoAsciiParams ) ;
4683 }
47- catch ( UnknownImageFormatException )
84+ catch ( Exception exception ) when ( IsCandidateRasterReadFailure ( exception ) )
4885 {
4986 return null ;
5087 }
51-
52- ExifProfile ? exifProfile = imageInfo . Metadata . ExifProfile ;
53- GeoTiffTagSnapshot ? tiffTags = await GeoTiffTagReader . TryReadAsync ( sourcePath , cancellationToken ) ;
54-
55- double [ ] ? tiePoints = TryGetDoubleArray ( exifProfile , ExifTag . ModelTiePoint )
56- ?? tiffTags ? . ModelTiePoint ;
57- double [ ] ? pixelScale = TryGetDoubleArray ( exifProfile , ExifTag . PixelScale )
58- ?? tiffTags ? . PixelScale ;
59- double [ ] ? modelTransform = TryGetDoubleArray ( exifProfile , ExifTag . ModelTransform )
60- ?? tiffTags ? . ModelTransform ;
61- ushort [ ] ? geoKeyDirectory = TryGetUnsignedShortArray ( exifProfile , "GeoKeyDirectoryTag" )
62- ?? tiffTags ? . GeoKeyDirectory ;
63- double [ ] ? geoDoubleParams = TryGetNamedDoubleArray ( exifProfile , "GeoDoubleParamsTag" )
64- ?? tiffTags ? . GeoDoubleParams ;
65- string ? geoAsciiParams = TryGetNamedString ( exifProfile , "GeoAsciiParamsTag" )
66- ?? tiffTags ? . GeoAsciiParams ;
67-
68- return TryCreateMetadata (
69- imageInfo . Width ,
70- imageInfo . Height ,
71- tiePoints ,
72- pixelScale ,
73- modelTransform ,
74- geoKeyDirectory ,
75- geoDoubleParams ,
76- geoAsciiParams ) ;
7788 }
7889
7990 public static async Task < GeoReferencedRasterMetadata ? > TryReadMetadataAsync (
@@ -90,42 +101,55 @@ internal static class TerrainTextureGeoReferencedRasterMetadataReader
90101 try
91102 {
92103 stream . Seek ( 0 , SeekOrigin . Begin ) ;
93- imageInfo = await Image . IdentifyAsync ( stream , cancellationToken )
94- ?? throw new InvalidOperationException ( "Failed to identify raster stream." ) ;
104+ ImageInfo ? identifiedImage = await Image . IdentifyAsync ( stream , cancellationToken ) ;
105+ if ( identifiedImage is null )
106+ {
107+ return null ;
108+ }
109+
110+ imageInfo = identifiedImage ;
111+ ExifProfile ? exifProfile = imageInfo . Metadata . ExifProfile ;
112+ stream . Seek ( 0 , SeekOrigin . Begin ) ;
113+ GeoTiffTagSnapshot ? tiffTags = await GeoTiffTagReader . TryReadAsync ( stream , cancellationToken ) ;
114+
115+ double [ ] ? tiePoints = TryGetDoubleArray ( exifProfile , ExifTag . ModelTiePoint )
116+ ?? tiffTags ? . ModelTiePoint ;
117+ double [ ] ? pixelScale = TryGetDoubleArray ( exifProfile , ExifTag . PixelScale )
118+ ?? tiffTags ? . PixelScale ;
119+ double [ ] ? modelTransform = TryGetDoubleArray ( exifProfile , ExifTag . ModelTransform )
120+ ?? tiffTags ? . ModelTransform ;
121+ ushort [ ] ? geoKeyDirectory = TryGetUnsignedShortArray ( exifProfile , "GeoKeyDirectoryTag" )
122+ ?? tiffTags ? . GeoKeyDirectory ;
123+ double [ ] ? geoDoubleParams = TryGetNamedDoubleArray ( exifProfile , "GeoDoubleParamsTag" )
124+ ?? tiffTags ? . GeoDoubleParams ;
125+ string ? geoAsciiParams = TryGetNamedString ( exifProfile , "GeoAsciiParamsTag" )
126+ ?? tiffTags ? . GeoAsciiParams ;
127+
128+ return TryCreateMetadata (
129+ imageInfo . Width ,
130+ imageInfo . Height ,
131+ tiePoints ,
132+ pixelScale ,
133+ modelTransform ,
134+ geoKeyDirectory ,
135+ geoDoubleParams ,
136+ geoAsciiParams ) ;
95137 }
96- catch ( UnknownImageFormatException )
138+ catch ( Exception exception ) when ( IsCandidateRasterReadFailure ( exception ) )
97139 {
98140 return null ;
99141 }
100-
101- ExifProfile ? exifProfile = imageInfo . Metadata . ExifProfile ;
102- stream . Seek ( 0 , SeekOrigin . Begin ) ;
103- GeoTiffTagSnapshot ? tiffTags = await GeoTiffTagReader . TryReadAsync ( stream , cancellationToken ) ;
104-
105- double [ ] ? tiePoints = TryGetDoubleArray ( exifProfile , ExifTag . ModelTiePoint )
106- ?? tiffTags ? . ModelTiePoint ;
107- double [ ] ? pixelScale = TryGetDoubleArray ( exifProfile , ExifTag . PixelScale )
108- ?? tiffTags ? . PixelScale ;
109- double [ ] ? modelTransform = TryGetDoubleArray ( exifProfile , ExifTag . ModelTransform )
110- ?? tiffTags ? . ModelTransform ;
111- ushort [ ] ? geoKeyDirectory = TryGetUnsignedShortArray ( exifProfile , "GeoKeyDirectoryTag" )
112- ?? tiffTags ? . GeoKeyDirectory ;
113- double [ ] ? geoDoubleParams = TryGetNamedDoubleArray ( exifProfile , "GeoDoubleParamsTag" )
114- ?? tiffTags ? . GeoDoubleParams ;
115- string ? geoAsciiParams = TryGetNamedString ( exifProfile , "GeoAsciiParamsTag" )
116- ?? tiffTags ? . GeoAsciiParams ;
117-
118- return TryCreateMetadata (
119- imageInfo . Width ,
120- imageInfo . Height ,
121- tiePoints ,
122- pixelScale ,
123- modelTransform ,
124- geoKeyDirectory ,
125- geoDoubleParams ,
126- geoAsciiParams ) ;
127142 }
128143
144+ private static bool IsCandidateRasterReadFailure ( Exception exception ) =>
145+ exception is UnknownImageFormatException
146+ or IOException
147+ or UnauthorizedAccessException
148+ or SecurityException
149+ or InvalidDataException
150+ or OverflowException
151+ or ArgumentOutOfRangeException ;
152+
129153 internal static GeoReferencedRasterMetadata ? TryCreateMetadata (
130154 int pixelWidth ,
131155 int pixelHeight ,
0 commit comments