From dd39cdcf27a4d8c2c0472f4cab2eb96fc80cf8b7 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Wed, 18 Mar 2026 23:44:08 +0100 Subject: jpg: add JFIF segment for APP0 marker Automatically parse APP0 as a JFIF segment. The following does not yet work: * The extended JFIF segment marked by `JFXX` is not recognized. * The thumbnail is not loaded but tossed, so it cannot be used currently --- src/jpg/jfif.zig | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/jpg/jfif.zig (limited to 'src/jpg/jfif.zig') diff --git a/src/jpg/jfif.zig b/src/jpg/jfif.zig new file mode 100644 index 0000000..91c95df --- /dev/null +++ b/src/jpg/jfif.zig @@ -0,0 +1,52 @@ +const std = @import("std"); + +pub const Version = packed struct { + major: u8, + minor: u8, + + pub fn format(self: @This(), writer: *std.Io.Writer) !void { + try writer.print("v{}.{}", .{self.major, self.minor}); + } +}; + +pub const Unit = enum(u8) { + none = 0, + pixels_per_inch = 1, + pixels_per_cm = 2, +}; + +const Self = @This(); + +version: Version, +unit: Unit, +density: struct { x: u16, y: u16 }, +thumbnail: struct { x: u8, y: u8 }, + +const identifier: []const u8 = "JFIF\x00"; + +pub fn read(reader: *std.Io.Reader) !Self { + const ident = try reader.peekArray(identifier.len); + + if (!std.mem.eql(u8, ident, identifier)) { + return error.WrongIdentifier; + } + reader.toss(identifier.len); + + var self: Self = undefined; + self.version.major = try reader.takeByte(); + self.version.minor = try reader.takeByte(); + + self.unit = @enumFromInt(try reader.takeByte()); + + self.density.x = try reader.takeInt(u16, .big); + self.density.y = try reader.takeInt(u16, .big); + + self.thumbnail.x = try reader.takeInt(u8, .big); + self.thumbnail.y = try reader.takeInt(u8, .big); + + // WARNING: we do not decode the thumbnail yet. + const size = 3 * self.thumbnail.x * self.thumbnail.y; + reader.toss(size); + + return self; +} -- cgit v1.2.3-70-g09d2