Created
December 22, 2023 15:18
-
-
Save LambdaSix/5ba0e42c57c39f100dc765bac35f6ff9 to your computer and use it in GitHub Desktop.
FileTypes.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public FormContentType getFormContentType(Stream dataStream) | |
{ | |
if (IsTiff(dataStream)) | |
{ | |
return FormContentType.Tiff; | |
} | |
else if (IsPDF(dataStream)) | |
{ | |
return FormContentType.Pdf; | |
} | |
else if (IsPNG(dataStream)) | |
{ | |
return FormContentType.Png; | |
} | |
else if (IsJpeg(dataStream)) | |
{ | |
return FormContentType.Jpeg; | |
} | |
return FormContentType.Json; | |
} | |
private bool IsTiff(Stream stream) | |
{ | |
stream.Seek(0, SeekOrigin.Begin); | |
// TIFF must be at least 8 bytes long. | |
if (stream.Length < 8) | |
return false; | |
// First two bytes are either II or MM, II Intel little-endian or MM Motorola big-endian | |
byte[] header = new byte[2]; | |
stream.Read(header, 0, header.Length); | |
if (header[0] != header[1] || (header[0] != 0x49 && header[0] != 0x4d)) | |
return false; | |
// Work out which endian type the file is then read the next two bytes which | |
// should be 4 and 2. | |
bool isIntel = header[0] == 0x49; | |
byte[] t = new byte[2]; | |
stream.Read(t, 0, 2); | |
ushort mN = isIntel ? t[0] : t[1]; | |
stream.Seek(0, SeekOrigin.Begin); | |
if (mN != 42) | |
return false; | |
return true; | |
} | |
private bool IsPDF(Stream stream) | |
{ | |
// PDF's begin with the byteSeq, but it may appear anywhere within the first 1024 bytes. | |
stream.Seek(0, SeekOrigin.Begin); | |
var byteSeq = new byte[] { 0x25, 0x50, 0x44, 0x46 }; | |
byte[] buffer = new byte[stream.Length >= 1024 ? 1024 : stream.Length]; | |
int bytesRead; | |
do | |
{ | |
bytesRead = stream.Read(buffer, 0, 1024); | |
} while (bytesRead < buffer.Length); | |
var counter = 0; | |
do | |
{ | |
if (buffer.Skip(counter).Take(byteSeq.Length).SequenceEqual(byteSeq)) | |
return true; | |
} while (++counter <= buffer.Length); | |
stream.Seek(0, SeekOrigin.Begin); | |
return false; | |
} | |
private bool IsPNG(Stream stream) | |
{ | |
// Should always just be the first 8 bytes. | |
var byteSeq = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; | |
stream.Seek(0, SeekOrigin.Begin); | |
byte[] buffer = new byte[byteSeq.Length]; | |
stream.Read(buffer, 0, buffer.Length); | |
return buffer.SequenceEqual(byteSeq); | |
} | |
private bool IsJpeg(Stream stream) | |
{ | |
// JPEG container is marked with a 3-byte sequence, extended kinds of JPEG | |
// are further into the header. | |
var byteSeq = new byte[] { 0xFF, 0xD8, 0xFF }; | |
stream.Seek(0, SeekOrigin.Begin); | |
byte[] buffer = new byte[byteSeq.Length]; | |
stream.Read(buffer, 0, buffer.Length); | |
return buffer.SequenceEqual(byteSeq); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment