mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-08 11:44:21 -04:00
Refactor ChunkCompression
to use BinaryReader
and BinaryWriter
(#1162)
* Refactor compressChunk to use BinaryWriter * Refactor decompressChunk to use BinaryReader * Back to fat switch we go * Yeet // @import("../utils.zig"); * Update src/server/storage.zig
This commit is contained in:
parent
2b3547d103
commit
867e908981
@ -261,10 +261,12 @@ pub const ChunkCompression = struct { // MARK: ChunkCompression
|
|||||||
};
|
};
|
||||||
pub fn compressChunk(allocator: main.utils.NeverFailingAllocator, ch: *chunk.Chunk, allowLossy: bool) []const u8 {
|
pub fn compressChunk(allocator: main.utils.NeverFailingAllocator, ch: *chunk.Chunk, allowLossy: bool) []const u8 {
|
||||||
if(ch.data.paletteLength == 1) {
|
if(ch.data.paletteLength == 1) {
|
||||||
const data = allocator.alloc(u8, 8);
|
var writer = BinaryWriter.initCapacity(allocator, .big, @sizeOf(CompressionAlgo) + @sizeOf(u32));
|
||||||
std.mem.writeInt(u32, data[0..4], @intFromEnum(CompressionAlgo.uniform), .big);
|
|
||||||
std.mem.writeInt(u32, data[4..8], ch.data.palette[0].toInt(), .big);
|
writer.writeEnum(CompressionAlgo, .uniform);
|
||||||
return data;
|
writer.writeInt(u32, ch.data.palette[0].toInt());
|
||||||
|
|
||||||
|
return writer.data.toOwnedSlice();
|
||||||
}
|
}
|
||||||
if(ch.data.paletteLength < 256) {
|
if(ch.data.paletteLength < 256) {
|
||||||
var uncompressedData: [chunk.chunkVolume]u8 = undefined;
|
var uncompressedData: [chunk.chunkVolume]u8 = undefined;
|
||||||
@ -298,71 +300,77 @@ pub const ChunkCompression = struct { // MARK: ChunkCompression
|
|||||||
const compressedData = main.utils.Compression.deflate(main.stackAllocator, &uncompressedData, .default);
|
const compressedData = main.utils.Compression.deflate(main.stackAllocator, &uncompressedData, .default);
|
||||||
defer main.stackAllocator.free(compressedData);
|
defer main.stackAllocator.free(compressedData);
|
||||||
|
|
||||||
const data = allocator.alloc(u8, 4 + 1 + 4*ch.data.paletteLength + compressedData.len);
|
var writer = BinaryWriter.initCapacity(allocator, .big, @sizeOf(CompressionAlgo) + @sizeOf(u8) + @sizeOf(u32)*ch.data.paletteLength + compressedData.len);
|
||||||
std.mem.writeInt(i32, data[0..4], @intFromEnum(CompressionAlgo.deflate_with_8bit_palette), .big);
|
|
||||||
data[4] = @intCast(ch.data.paletteLength);
|
|
||||||
for(0..ch.data.paletteLength) |i| {
|
|
||||||
std.mem.writeInt(u32, data[5 + 4*i ..][0..4], ch.data.palette[i].toInt(), .big);
|
|
||||||
}
|
|
||||||
@memcpy(data[5 + 4*ch.data.paletteLength ..], compressedData);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
var uncompressedData: [chunk.chunkVolume*@sizeOf(u32)]u8 = undefined;
|
|
||||||
for(0..chunk.chunkVolume) |i| {
|
|
||||||
std.mem.writeInt(u32, uncompressedData[4*i ..][0..4], ch.data.getValue(i).toInt(), .big);
|
|
||||||
}
|
|
||||||
const compressedData = main.utils.Compression.deflate(main.stackAllocator, &uncompressedData, .default);
|
|
||||||
defer main.stackAllocator.free(compressedData);
|
|
||||||
const data = allocator.alloc(u8, 4 + compressedData.len);
|
|
||||||
|
|
||||||
@memcpy(data[4..], compressedData);
|
writer.writeEnum(CompressionAlgo, .deflate_with_8bit_palette);
|
||||||
std.mem.writeInt(i32, data[0..4], @intFromEnum(CompressionAlgo.deflate), .big);
|
writer.writeInt(u8, @intCast(ch.data.paletteLength));
|
||||||
return data;
|
|
||||||
|
for(0..ch.data.paletteLength) |i| {
|
||||||
|
writer.writeInt(u32, ch.data.palette[i].toInt());
|
||||||
|
}
|
||||||
|
writer.writeSlice(compressedData);
|
||||||
|
return writer.data.toOwnedSlice();
|
||||||
|
}
|
||||||
|
var uncompressedWriter = BinaryWriter.initCapacity(main.stackAllocator, .big, chunk.chunkVolume*@sizeOf(u32));
|
||||||
|
defer uncompressedWriter.deinit();
|
||||||
|
|
||||||
|
for(0..chunk.chunkVolume) |i| {
|
||||||
|
uncompressedWriter.writeInt(u32, ch.data.getValue(i).toInt());
|
||||||
|
}
|
||||||
|
const compressedData = main.utils.Compression.deflate(main.stackAllocator, uncompressedWriter.data.items, .default);
|
||||||
|
defer main.stackAllocator.free(compressedData);
|
||||||
|
|
||||||
|
var compressedWriter = BinaryWriter.initCapacity(allocator, .big, @sizeOf(CompressionAlgo) + compressedData.len);
|
||||||
|
|
||||||
|
compressedWriter.writeEnum(CompressionAlgo, .deflate);
|
||||||
|
compressedWriter.writeSlice(compressedData);
|
||||||
|
|
||||||
|
return compressedWriter.data.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decompressChunk(ch: *chunk.Chunk, _data: []const u8) error{corrupted}!void {
|
pub fn decompressChunk(ch: *chunk.Chunk, _data: []const u8) !void {
|
||||||
std.debug.assert(ch.data.paletteLength == 1);
|
std.debug.assert(ch.data.paletteLength == 1);
|
||||||
var data = _data;
|
|
||||||
if(data.len < 4) return error.corrupted;
|
var reader = BinaryReader.init(_data, .big);
|
||||||
const algo: CompressionAlgo = @enumFromInt(std.mem.readInt(u32, data[0..4], .big));
|
const compressionAlgorithm = try reader.readEnum(CompressionAlgo);
|
||||||
data = data[4..];
|
|
||||||
switch(algo) {
|
switch(compressionAlgorithm) {
|
||||||
.deflate, .deflate_with_position => {
|
.deflate, .deflate_with_position => {
|
||||||
if(algo == .deflate_with_position) data = data[16..];
|
if(compressionAlgorithm == .deflate_with_position) _ = try reader.readSlice(16);
|
||||||
const _inflatedData = main.stackAllocator.alloc(u8, chunk.chunkVolume*4);
|
const decompressedData = main.stackAllocator.alloc(u8, chunk.chunkVolume*@sizeOf(u32));
|
||||||
defer main.stackAllocator.free(_inflatedData);
|
defer main.stackAllocator.free(decompressedData);
|
||||||
const _inflatedLen = main.utils.Compression.inflateTo(_inflatedData, data[0..]) catch return error.corrupted;
|
|
||||||
if(_inflatedLen != chunk.chunkVolume*4) {
|
const decompressedLength = try main.utils.Compression.inflateTo(decompressedData, reader.remaining);
|
||||||
return error.corrupted;
|
if(decompressedLength != chunk.chunkVolume*@sizeOf(u32)) return error.corrupted;
|
||||||
}
|
|
||||||
data = _inflatedData;
|
var decompressedReader = BinaryReader.init(decompressedData, .big);
|
||||||
|
|
||||||
for(0..chunk.chunkVolume) |i| {
|
for(0..chunk.chunkVolume) |i| {
|
||||||
ch.data.setValue(i, main.blocks.Block.fromInt(std.mem.readInt(u32, data[0..4], .big)));
|
ch.data.setValue(i, main.blocks.Block.fromInt(try decompressedReader.readInt(u32)));
|
||||||
data = data[4..];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.deflate_with_8bit_palette => {
|
.deflate_with_8bit_palette => {
|
||||||
const paletteLength = data[0];
|
const paletteLength = try reader.readInt(u8);
|
||||||
data = data[1..];
|
|
||||||
ch.data.deinit();
|
ch.data.deinit();
|
||||||
ch.data.initCapacity(paletteLength);
|
ch.data.initCapacity(paletteLength);
|
||||||
|
|
||||||
for(0..paletteLength) |i| {
|
for(0..paletteLength) |i| {
|
||||||
ch.data.palette[i] = main.blocks.Block.fromInt(std.mem.readInt(u32, data[0..4], .big));
|
ch.data.palette[i] = main.blocks.Block.fromInt(try reader.readInt(u32));
|
||||||
data = data[4..];
|
|
||||||
}
|
}
|
||||||
const _inflatedData = main.stackAllocator.alloc(u8, chunk.chunkVolume);
|
|
||||||
defer main.stackAllocator.free(_inflatedData);
|
const decompressedData = main.stackAllocator.alloc(u8, chunk.chunkVolume);
|
||||||
const _inflatedLen = main.utils.Compression.inflateTo(_inflatedData, data[0..]) catch return error.corrupted;
|
defer main.stackAllocator.free(decompressedData);
|
||||||
if(_inflatedLen != chunk.chunkVolume) {
|
|
||||||
return error.corrupted;
|
const decompressedLength = try main.utils.Compression.inflateTo(decompressedData, reader.remaining);
|
||||||
}
|
if(decompressedLength != chunk.chunkVolume) return error.corrupted;
|
||||||
data = _inflatedData;
|
|
||||||
for(0..chunk.chunkVolume) |i| {
|
for(0..chunk.chunkVolume) |i| {
|
||||||
ch.data.setRawValue(i, data[i]);
|
ch.data.setRawValue(i, decompressedData[i]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.uniform => {
|
.uniform => {
|
||||||
ch.data.palette[0] = main.blocks.Block.fromInt(std.mem.readInt(u32, data[0..4], .big));
|
ch.data.palette[0] = main.blocks.Block.fromInt(try reader.readInt(u32));
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
return error.corrupted;
|
return error.corrupted;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user