-
Notifications
You must be signed in to change notification settings - Fork 0
/
ImageTypeChecker.cs
114 lines (102 loc) · 3.96 KB
/
ImageTypeChecker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace UVTileDiscardMapper
{
public static class ImageTypeChecker
{
public static FileType GetImageType(string filePath)
{
FileType result = GetKnownFileType(filePath);
switch (result)
{
case FileType.Unknown:
break;
case FileType.Webp:
case FileType.Webp2:
case FileType.Webp3:
case FileType.WebpLast:
return FileType.Webp;
default:
return result;
}
if (IsSvgImage(filePath))
return FileType.Svg;
else
return FileType.Unknown;
}
private static bool IsSvgImage(string filePath)
{
try
{
// Read the first few bytes of the file to ensure it's text-based
using (StreamReader reader = new StreamReader(filePath))
{
char[] buffer = new char[100];
int bytesRead = reader.Read(buffer, 0, 100);
// Check if the file is text-based
if (bytesRead < 2 || buffer[0] != '<' || buffer[1] != '?')
return false; // Not an XML file
// Check if the content starts with an SVG element
string content = new string(buffer, 0, bytesRead);
return (content.TrimStart().StartsWith("<svg", StringComparison.OrdinalIgnoreCase) || content.TrimStart().StartsWith("<?xml", StringComparison.OrdinalIgnoreCase));
}
}
catch (Exception)
{
// Error occurred while reading the file or parsing XML
return false;
}
}
public enum FileType
{
Unknown,
Jpeg,
JpegEOI,
Bmp,
Gif,
Png,
Webp,
Webp2,
Webp3,
WebpLast,
TiffI,
TiffM,
Svg // This is checked by another method
}
private static readonly Dictionary<FileType, byte[]> KNOWN_FILE_HEADERS = new Dictionary<FileType, byte[]>()
{
{ FileType.Jpeg, new byte[]{ 0xFF, 0xD8 }}, // JPEG
{ FileType.JpegEOI, new byte[]{ 0xFF, 0xD9 }}, // JPEG EOI
{ FileType.TiffI, new byte[]{ 0x49, 0x49, 0x2A, 0x00 }}, // TiffI
{ FileType.TiffM, new byte[]{ 0x4D, 0x4D, 0x00, 0x2A }}, // TiffM
{ FileType.Bmp, new byte[]{ 0x42, 0x4D }}, // BMP
{ FileType.Gif, new byte[]{ 0x47, 0x49, 0x46 }}, // GIF
{ FileType.Png, new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }}, // PNG
{ FileType.Webp, new byte[]{ 0x52, 0x49, 0x46, 0x46, 0xFF, 0xFF, 0xFF, 0xFF, 0x57, 0x45, 0x42, 0x50 } }, // WEBP
{ FileType.Webp2, new byte[]{ 0x52, 0x49, 0x46, 0x46, 0xBC, 0xCE, 0x06, 0x00, 0x57, 0x45, 0x42, 0x50 } }, // WEBP 2nd variation
{ FileType.Webp3, new byte[] { 0x52, 0x49, 0x46, 0x46, 0xBA, 0x2E, 0x08, 0x00, 0x57, 0x45, 0x42, 0x50 } }, // WEBP 3rd variation
{ FileType.WebpLast, new byte[] { 0x52, 0x49, 0x46 } } // WEBP 3rd variation
};
public static FileType GetKnownFileType(string filePath)
{
Stream data = File.OpenRead(filePath);
foreach (var check in KNOWN_FILE_HEADERS)
{
data.Seek(0, SeekOrigin.Begin);
var slice = new byte[check.Value.Length];
data.Read(slice, 0, check.Value.Length);
if (slice.SequenceEqual(check.Value))
{
data.Seek(0, SeekOrigin.Begin);
data.Close();
return check.Key;
}
}
data.Seek(0, SeekOrigin.Begin);
data.Close();
return FileType.Unknown;
}
}
}