diff --git a/src/bmp_valid.zig b/src/bmp_valid.zig new file mode 100644 index 0000000..81c6759 --- /dev/null +++ b/src/bmp_valid.zig @@ -0,0 +1,26 @@ +const std = @import("std"); + +pub const BMPValidError = error{InvalidMagic}; + +const VALID_MAGICS = [_][]const u8{ + "BM", + "BA", + + "CI", + "CP", + "IC", + "PT", +}; + +pub fn magicValid(magic: []const u8) !void { + var valid = false; + + for (VALID_MAGICS) |valid_magic| { + if (std.mem.eql(u8, magic, valid_magic)) valid = true; + } + + if (!valid) { + std.debug.warn("\tINVALID HEADER: '{}'\n", magic); + return BMPValidError.InvalidMagic; + } +} diff --git a/src/image.zig b/src/image.zig index 16e682f..3e38903 100644 --- a/src/image.zig +++ b/src/image.zig @@ -2,6 +2,7 @@ const std = @import("std"); const lv2 = @import("lv2_helpers.zig"); const c = lv2.c; const custom = @import("custom.zig"); +const bmp = @import("bmp_valid.zig"); const plugins = @import("plugin.zig"); @@ -235,6 +236,22 @@ pub const Image = struct { std.debug.warn("\timage: reopened on '{}'\n", self.curpath); } + pub fn checkValid(self: *Image) !void { + var file = try std.fs.File.openRead(self.path); + defer file.close(); + + // main bmp header: + // 2 bytes for magic header + // 4 bytes for size in bytes + // 2 bytes ? + // 2 bytes ? + // 4 bytes for pixel array offset + var magic = [2]u8{ 0, 0 }; + _ = try file.read(&magic); + + try bmp.magicValid(&magic); + } + /// Run a plugin over the image. /// This setups a new lilv world/plugin among other things. /// The internal SNDFILE pointer is modified to point to the output of the @@ -354,6 +371,7 @@ pub const Image = struct { _ = c.sf_close(self.sndfile); try self.reopen(tmpnam); + try self.checkValid(); var time_taken = timer.read(); std.debug.warn("\ttook {d:.2}ms running plugin\n", time_taken / std.time.millisecond); @@ -441,5 +459,6 @@ pub const Image = struct { // reopen the file as SFM_READ so we can run plugin chains etc try self.reopen(tmpnam); + try self.checkValid(); } };