Howdy - I’m trying to read in JPEG files and I haven’t explored this with Zig at this point. I need to just get the raw image content because I’m going to unquantize it for data to train an image classification transformer. I’ve resized all of them so that the dimensions are correct, now I just need to get to the image byte content.
I’m aware that there’s meta-data that I need to skip over and I’m looking up how that’s done but I’m wondering if anyone here has some experience with JPEGs and Zig that they’re willing to share? Thanks in advance
Meanwhile my file system is telling me that the size of the file is 2674 bytes long. That basically means that the search found the head at the very beginning of the file and the tail at the very end - the whole file is bounded between the two. I’m a little confused by that because I was under the impression that there’s a lot more meta-data upfront, so if anyone can offer some insights here then that’d be grand.
Thanks! I looked into it and it turns out that reading the raw bytes won’t be a great strategy, so I went with writing a python script to convert it back to RGB and write it out to a file from there. I looked for some jpg utils online and found several file handling libraries for Zig but jpg’s were unimplemented. Looks like there’s still a lot of work to do be done there.
Stb image handles the most common subtype of JPEG 1 and is trivial to integrate into a C or Zig project. If you need more subtypes, libjpeg-turbo can handle almost everything from JPEG 1, but integrating it is annoying. I had to to have the build system compile the assembly files using NASM, and manually create the header files from the templates, as Zig’s header file creation from templates is buggy. I can share what I did to integrate it, if you need.
If you need the more recent versions of JPEG, it becomes a real pain.
Thanks @LucasSantos91, I really appreciate the offer. It may come to that at some point - I’ll let you know if I do. I’m sure a lot of these rough patches will get smoothed over as Zig has more time to develop and libraries continue to mature.
zigimg has a JPEG decoder (actually, I think it’s partially broken). Note that it won’t give you the raw YCbCr data, just RGB. I’m currently working on a multimedia library for zig, but it is in the early stages. @nektro wrote a simple (and , in my opinion, quite beautiful) JPEG decoder in Zig for her UI toolkit: ~nektro/magnolia-desktop: src/e/Image/jpg.zig - sourcehut git. It will also just give you RGB.
I’m using an arena allocator. The deinit on the arena takes care of that:
pub fn deinit(self: ArenaAllocator) void {
// NOTE: When changing this, make sure `reset()` is adjusted accordingly!
var it = self.state.buffer_list.first;
while (it) |node| {
// this has to occur before the free because the free frees node
const next_it = node.next;
const align_bits = std.math.log2_int(usize, @alignOf(BufNode));
const alloc_buf = @as([*]u8, @ptrCast(node))[0..node.data];
self.child_allocator.rawFree(alloc_buf, align_bits, @returnAddress());
it = next_it;
}
}
I think it might be helpful to see how its done with uncompressed BMP, like if you want to do a pure Zig implementation with GL. You could also write a command line app which compresses BMP into JPEG. I’m not sure how practical all that is for your specific case, but it should give you a better perspective on dealing with JPEG in general