diff --git a/README.md b/README.md index 2fd8dd1..636122f 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,17 @@ A library and application to decompress or view squashfs archives. ## Current State -Overall works, but currently is completely single threaded and is missing some features. Extraction is slow. Only properly work on Linux, any other OSes probably won't work fully. +Overall works, but currently is missing some features (see below). Extraction is a bit slow compared to the normal `unsquashfs` (from my _very_ basic testing it's about ~3x slower). Only properly work on Linux, any other OSes probably won't work fully and are untested. ## Build options > `-Duse_c_libs` -Instead of using Zig's standard library for decompression +Instead of using Zig's standard library for decompression, use the system's C libraries. Has the benefit of being much faster and enabling LZO and LZ4 decompression. + +> `-Dallow_lzo` + +Enable compiling with LZO decompression support. The LZO library currently has some issues with Zig when imported so it's easier to just disable it by default. Only has an effect when using `-Duse_c_libs=true`. > `-Dversion` @@ -24,12 +28,11 @@ Most features are present except for the following: * mod_time is not set on extraction * xattrs are not applied on extraction -* Only zstd c library is implemented (all others result in error.TODO). -* When using Zig decompression libraries then lzo and lz4 compression types are unavailable. I don't _really_ plan on spending the time to find and validate a library since neither is popular. +* When using Zig decompression libraries then lzo and lz4 compression types are unavailable. I don't _currently_ plan on spending the time to find and validate a library since neither is popular. ## Building considerations -Compilation without `use_c_libs` works completely fine, but Zig has issues with some symbols from the lzo library that needs to be manually fixed. In particular you need to fix the definitions for `lzo_bytep` and `lzo_voidp` to be `*u8` and `?*anyopaque` respectively. +Compilation without `use_c_libs` works completely fine, but Zig has issues with some symbols from the lzo library that needs to be manually fixed. In particular you need to fix the definitions for `lzo_bytep` and `lzo_voidp` to be `*u8` and `?*anyopaque` respectively. Due to this, you have to manually enable LZO decompression using `-Dallow_lzo=true` when building. ```zig pub const lzo_bytep = @compileError("unable to translate C expr: unexpected token ''"); diff --git a/build.zig b/build.zig index 1bf30bb..c4d3509 100644 --- a/build.zig +++ b/build.zig @@ -2,10 +2,12 @@ const std = @import("std"); pub fn build(b: *std.Build) !void { const use_c_libs_option = b.option(bool, "use_c_libs", "Use C versions of decompression libraries instead of the Zig standard library ones"); + const allow_lzo = b.option(bool, "allow_lzo", "Compile with lzo support"); const version_string_option = b.option([]const u8, "version", "Version of the library/binary"); const zig_squashfs_options = b.addOptions(); zig_squashfs_options.addOption(bool, "use_c_libs", use_c_libs_option orelse false); + zig_squashfs_options.addOption(bool, "allow_lzo", allow_lzo orelse false); const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseFast }); diff --git a/src/archive.zig b/src/archive.zig index 6c7ca0f..e52990e 100644 --- a/src/archive.zig +++ b/src/archive.zig @@ -16,7 +16,10 @@ const Table = @import("table.zig").Table; const MetadataReader = @import("util/metadata.zig"); const OffsetFile = @import("util/offset_file.zig"); -const config = if (builtin.is_test) .{ .use_c_libs = true } else @import("config"); +const config = if (builtin.is_test) .{ + .use_c_libs = true, + .allow_lzo = false, +} else @import("config"); /// Information about a fragment section. Multiple fragments are contained in the block described by a single FragEntry. /// The offset into the block and fragment size is stored in the file's inode. @@ -79,7 +82,7 @@ pub fn initAdvanced(alloc: std.mem.Allocator, fil: File, offset: u64, threads: u .xz => Decomp.xzDecompress, .zstd => Decomp.zstdDecompress, .lz4 => if (config.use_c_libs) Decomp.cLz4 else return error.Lz4Unsupported, - .lzo => if (config.use_c_libs) Decomp.cLzo else return error.LzoUnsupported, + .lzo => if (config.use_c_libs and config.allow_lzo) Decomp.lzoDecompress else return error.LzoUnsupported, }, .super = super, diff --git a/src/decomp.zig b/src/decomp.zig index 63cd749..ce43515 100644 --- a/src/decomp.zig +++ b/src/decomp.zig @@ -5,15 +5,19 @@ const std = @import("std"); const Reader = std.Io.Reader; const builtin = @import("builtin"); -const config = if (builtin.is_test) .{ .use_c_libs = true } else @import("config"); +const config = if (builtin.is_test) .{ + .use_c_libs = true, + .allow_lzo = false, +} else @import("config"); const c = @cImport({ if (config.use_c_libs) { @cInclude("zlib.h"); @cInclude("lzma.h"); - @cInclude("lzo/minilzo.h"); @cInclude("lz4.h"); @cInclude("zstd.h"); + if (config.allow_lzo) + @cInclude("lzo/minilzo.h"); } }); @@ -176,7 +180,7 @@ pub const zstdDecompress = if (config.use_c_libs) cZstd else zigZstd; pub fn zigZstd(alloc: std.mem.Allocator, in: []u8, out: []u8) anyerror!usize { var rdr: Reader = .fixed(in); - const buf = try alloc.alloc(u8, std.compress.zstd.default_window_len + std.compress.zstd.block_size_max); + const buf = try alloc.alloc(u8, 1024 * 1024); defer alloc.free(buf); var decomp = std.compress.zstd.Decompress.init(&rdr, buf, .{}); return decomp.reader.readSliceShort(out) catch |err| {