Skip to content

Instantly share code, notes, and snippets.

@LambdaSix
Created December 22, 2023 15:18
Show Gist options
  • Save LambdaSix/5ba0e42c57c39f100dc765bac35f6ff9 to your computer and use it in GitHub Desktop.
Save LambdaSix/5ba0e42c57c39f100dc765bac35f6ff9 to your computer and use it in GitHub Desktop.
FileTypes.cs
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