mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
util: introduce helper for detecting file types
This commit is contained in:

committed by
Mitchell Hashimoto

parent
a5f1413a1c
commit
ca5f301eb1
102
src/file_type.zig
Normal file
102
src/file_type.zig
Normal file
@ -0,0 +1,102 @@
|
||||
const std = @import("std");
|
||||
|
||||
const type_details: []const struct {
|
||||
typ: FileType,
|
||||
sigs: []const []const ?u8,
|
||||
exts: []const []const u8,
|
||||
} = &.{
|
||||
.{
|
||||
.typ = .jpeg,
|
||||
.sigs = &.{
|
||||
&.{ 0xFF, 0xD8, 0xFF, 0xDB },
|
||||
&.{ 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01 },
|
||||
&.{ 0xFF, 0xD8, 0xFF, 0xEE },
|
||||
&.{ 0xFF, 0xD8, 0xFF, 0xE1, null, null, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 },
|
||||
&.{ 0xFF, 0xD8, 0xFF, 0xE0 },
|
||||
},
|
||||
.exts = &.{ ".jpg", ".jpeg", ".jfif" },
|
||||
},
|
||||
.{
|
||||
.typ = .png,
|
||||
.sigs = &.{&.{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }},
|
||||
.exts = &.{".png"},
|
||||
},
|
||||
.{
|
||||
.typ = .gif,
|
||||
.sigs = &.{
|
||||
&.{ 'G', 'I', 'F', '8', '7', 'a' },
|
||||
&.{ 'G', 'I', 'F', '8', '9', 'a' },
|
||||
},
|
||||
.exts = &.{".gif"},
|
||||
},
|
||||
.{
|
||||
.typ = .bmp,
|
||||
.sigs = &.{&.{ 'B', 'M' }},
|
||||
.exts = &.{".bmp"},
|
||||
},
|
||||
.{
|
||||
.typ = .qoi,
|
||||
.sigs = &.{&.{ 'q', 'o', 'i', 'f' }},
|
||||
.exts = &.{".qoi"},
|
||||
},
|
||||
.{
|
||||
.typ = .webp,
|
||||
.sigs = &.{
|
||||
&.{ 0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50 },
|
||||
},
|
||||
.exts = &.{".webp"},
|
||||
},
|
||||
};
|
||||
|
||||
/// This is a helper for detecting file types based on magic bytes.
|
||||
///
|
||||
/// Ref: https://en.wikipedia.org/wiki/List_of_file_signatures
|
||||
pub const FileType = enum {
|
||||
/// JPEG image file.
|
||||
jpeg,
|
||||
|
||||
/// PNG image file.
|
||||
png,
|
||||
|
||||
/// GIF image file.
|
||||
gif,
|
||||
|
||||
/// BMP image file.
|
||||
bmp,
|
||||
|
||||
/// QOI image file.
|
||||
qoi,
|
||||
|
||||
/// WebP image file.
|
||||
webp,
|
||||
|
||||
/// Unknown file format.
|
||||
unknown,
|
||||
|
||||
/// Detect file type based on the magic bytes
|
||||
/// at the start of the provided file contents.
|
||||
pub fn detect(contents: []const u8) FileType {
|
||||
inline for (type_details) |typ| {
|
||||
inline for (typ.sigs) |signature| {
|
||||
if (contents.len >= signature.len) {
|
||||
for (contents[0..signature.len], signature) |f, sig| {
|
||||
if (sig) |s| if (f != s) break;
|
||||
} else {
|
||||
return typ.typ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return .unknown;
|
||||
}
|
||||
|
||||
/// Guess file type from its extension.
|
||||
pub fn guessFromExtension(extension: []const u8) FileType {
|
||||
inline for (type_details) |typ| {
|
||||
inline for (typ.exts) |ext| {
|
||||
if (std.ascii.eqlIgnoreCase(extension, ext)) return typ.typ;
|
||||
}
|
||||
}
|
||||
return .unknown;
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user