mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Remove unneeded semicolons from the core library
This commit is contained in:
+210
-210
@@ -47,41 +47,41 @@ Options :: struct {
|
||||
level: u8,
|
||||
}
|
||||
|
||||
Error :: compress.Error;
|
||||
E_General :: compress.General_Error;
|
||||
E_ZLIB :: compress.ZLIB_Error;
|
||||
E_Deflate :: compress.Deflate_Error;
|
||||
Error :: compress.Error
|
||||
E_General :: compress.General_Error
|
||||
E_ZLIB :: compress.ZLIB_Error
|
||||
E_Deflate :: compress.Deflate_Error
|
||||
|
||||
DEFLATE_MAX_CHUNK_SIZE :: 65535;
|
||||
DEFLATE_MAX_LITERAL_SIZE :: 65535;
|
||||
DEFLATE_MAX_DISTANCE :: 32768;
|
||||
DEFLATE_MAX_LENGTH :: 258;
|
||||
DEFLATE_MAX_CHUNK_SIZE :: 65535
|
||||
DEFLATE_MAX_LITERAL_SIZE :: 65535
|
||||
DEFLATE_MAX_DISTANCE :: 32768
|
||||
DEFLATE_MAX_LENGTH :: 258
|
||||
|
||||
HUFFMAN_MAX_BITS :: 16;
|
||||
HUFFMAN_FAST_BITS :: 9;
|
||||
HUFFMAN_FAST_MASK :: ((1 << HUFFMAN_FAST_BITS) - 1);
|
||||
HUFFMAN_MAX_BITS :: 16
|
||||
HUFFMAN_FAST_BITS :: 9
|
||||
HUFFMAN_FAST_MASK :: ((1 << HUFFMAN_FAST_BITS) - 1)
|
||||
|
||||
Z_LENGTH_BASE := [31]u16{
|
||||
3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,
|
||||
67,83,99,115,131,163,195,227,258,0,0,
|
||||
};
|
||||
}
|
||||
|
||||
Z_LENGTH_EXTRA := [31]u8{
|
||||
0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,
|
||||
};
|
||||
}
|
||||
|
||||
Z_DIST_BASE := [32]u16{
|
||||
1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
|
||||
257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0,
|
||||
};
|
||||
}
|
||||
|
||||
Z_DIST_EXTRA := [32]u8{
|
||||
0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0,
|
||||
};
|
||||
}
|
||||
|
||||
Z_LENGTH_DEZIGZAG := []u8{
|
||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
|
||||
};
|
||||
}
|
||||
|
||||
Z_FIXED_LENGTH := [288]u8{
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||
@@ -93,17 +93,17 @@ Z_FIXED_LENGTH := [288]u8{
|
||||
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,
|
||||
};
|
||||
}
|
||||
|
||||
Z_FIXED_DIST := [32]u8{
|
||||
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
Accelerate all cases in default tables.
|
||||
*/
|
||||
ZFAST_BITS :: 9;
|
||||
ZFAST_MASK :: ((1 << ZFAST_BITS) - 1);
|
||||
ZFAST_BITS :: 9
|
||||
ZFAST_MASK :: ((1 << ZFAST_BITS) - 1)
|
||||
|
||||
/*
|
||||
ZLIB-style Huffman encoding.
|
||||
@@ -116,22 +116,22 @@ Huffman_Table :: struct {
|
||||
firstsymbol: [16]u16,
|
||||
size: [288]u8,
|
||||
value: [288]u16,
|
||||
};
|
||||
}
|
||||
|
||||
// Implementation starts here
|
||||
@(optimization_mode="speed")
|
||||
z_bit_reverse :: #force_inline proc(n: u16, bits: u8) -> (r: u16) {
|
||||
assert(bits <= 16);
|
||||
assert(bits <= 16)
|
||||
// NOTE: Can optimize with llvm.bitreverse.i64 or some bit twiddling
|
||||
// by reversing all of the bits and masking out the unneeded ones.
|
||||
r = n;
|
||||
r = ((r & 0xAAAA) >> 1) | ((r & 0x5555) << 1);
|
||||
r = ((r & 0xCCCC) >> 2) | ((r & 0x3333) << 2);
|
||||
r = ((r & 0xF0F0) >> 4) | ((r & 0x0F0F) << 4);
|
||||
r = ((r & 0xFF00) >> 8) | ((r & 0x00FF) << 8);
|
||||
r = n
|
||||
r = ((r & 0xAAAA) >> 1) | ((r & 0x5555) << 1)
|
||||
r = ((r & 0xCCCC) >> 2) | ((r & 0x3333) << 2)
|
||||
r = ((r & 0xF0F0) >> 4) | ((r & 0x0F0F) << 4)
|
||||
r = ((r & 0xFF00) >> 8) | ((r & 0x00FF) << 8)
|
||||
|
||||
r >>= (16 - bits);
|
||||
return;
|
||||
r >>= (16 - bits)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -145,16 +145,16 @@ grow_buffer :: proc(buf: ^[dynamic]u8) -> (err: compress.Error) {
|
||||
/*
|
||||
Double until we reach the maximum allowed.
|
||||
*/
|
||||
new_size := min(len(buf) << 1, compress.COMPRESS_OUTPUT_ALLOCATE_MAX);
|
||||
resize(buf, new_size);
|
||||
new_size := min(len(buf) << 1, compress.COMPRESS_OUTPUT_ALLOCATE_MAX)
|
||||
resize(buf, new_size)
|
||||
if len(buf) != new_size {
|
||||
/*
|
||||
Resize failed.
|
||||
*/
|
||||
return .Resize_Failed;
|
||||
return .Resize_Failed
|
||||
}
|
||||
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -167,17 +167,17 @@ write_byte :: #force_inline proc(z: ^$C, c: u8) -> (err: io.Error) #no_bounds_ch
|
||||
Resize if needed.
|
||||
*/
|
||||
if int(z.bytes_written) + 1 >= len(z.output.buf) {
|
||||
e := grow_buffer(&z.output.buf);
|
||||
e := grow_buffer(&z.output.buf)
|
||||
if e != nil {
|
||||
return .Short_Write;
|
||||
return .Short_Write
|
||||
}
|
||||
}
|
||||
|
||||
#no_bounds_check {
|
||||
z.output.buf[z.bytes_written] = c;
|
||||
z.output.buf[z.bytes_written] = c
|
||||
}
|
||||
z.bytes_written += 1;
|
||||
return .None;
|
||||
z.bytes_written += 1
|
||||
return .None
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
@@ -192,20 +192,20 @@ repl_byte :: proc(z: ^$C, count: u16, c: u8) -> (err: io.Error) #no_bounds_chec
|
||||
Resize if needed.
|
||||
*/
|
||||
if int(z.bytes_written) + int(count) >= len(z.output.buf) {
|
||||
e := grow_buffer(&z.output.buf);
|
||||
e := grow_buffer(&z.output.buf)
|
||||
if e != nil {
|
||||
return .Short_Write;
|
||||
return .Short_Write
|
||||
}
|
||||
}
|
||||
|
||||
#no_bounds_check {
|
||||
for _ in 0..<count {
|
||||
z.output.buf[z.bytes_written] = c;
|
||||
z.bytes_written += 1;
|
||||
z.output.buf[z.bytes_written] = c
|
||||
z.bytes_written += 1
|
||||
}
|
||||
}
|
||||
|
||||
return .None;
|
||||
return .None
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
@@ -216,178 +216,178 @@ repl_bytes :: proc(z: ^$C, count: u16, distance: u16) -> (err: io.Error) {
|
||||
the output stream, just give it _that_ slice.
|
||||
*/
|
||||
|
||||
offset := i64(distance);
|
||||
offset := i64(distance)
|
||||
|
||||
if int(z.bytes_written) + int(count) >= len(z.output.buf) {
|
||||
e := grow_buffer(&z.output.buf);
|
||||
e := grow_buffer(&z.output.buf)
|
||||
if e != nil {
|
||||
return .Short_Write;
|
||||
return .Short_Write
|
||||
}
|
||||
}
|
||||
|
||||
#no_bounds_check {
|
||||
for _ in 0..<count {
|
||||
c := z.output.buf[z.bytes_written - offset];
|
||||
z.output.buf[z.bytes_written] = c;
|
||||
z.bytes_written += 1;
|
||||
c := z.output.buf[z.bytes_written - offset]
|
||||
z.output.buf[z.bytes_written] = c
|
||||
z.bytes_written += 1
|
||||
}
|
||||
}
|
||||
|
||||
return .None;
|
||||
return .None
|
||||
}
|
||||
|
||||
|
||||
allocate_huffman_table :: proc(allocator := context.allocator) -> (z: ^Huffman_Table, err: Error) {
|
||||
return new(Huffman_Table, allocator), nil;
|
||||
return new(Huffman_Table, allocator), nil
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) {
|
||||
sizes: [HUFFMAN_MAX_BITS+1]int;
|
||||
next_code: [HUFFMAN_MAX_BITS]int;
|
||||
sizes: [HUFFMAN_MAX_BITS+1]int
|
||||
next_code: [HUFFMAN_MAX_BITS]int
|
||||
|
||||
k := int(0);
|
||||
k := int(0)
|
||||
|
||||
mem.zero_slice(sizes[:]);
|
||||
mem.zero_slice(z.fast[:]);
|
||||
mem.zero_slice(sizes[:])
|
||||
mem.zero_slice(z.fast[:])
|
||||
|
||||
for v in code_lengths {
|
||||
sizes[v] += 1;
|
||||
sizes[v] += 1
|
||||
}
|
||||
sizes[0] = 0;
|
||||
sizes[0] = 0
|
||||
|
||||
for i in 1..<(HUFFMAN_MAX_BITS+1) {
|
||||
if sizes[i] > (1 << uint(i)) {
|
||||
return E_Deflate.Huffman_Bad_Sizes;
|
||||
return E_Deflate.Huffman_Bad_Sizes
|
||||
}
|
||||
}
|
||||
code := int(0);
|
||||
code := int(0)
|
||||
|
||||
for i in 1..<HUFFMAN_MAX_BITS {
|
||||
next_code[i] = code;
|
||||
z.firstcode[i] = u16(code);
|
||||
z.firstsymbol[i] = u16(k);
|
||||
code = code + sizes[i];
|
||||
next_code[i] = code
|
||||
z.firstcode[i] = u16(code)
|
||||
z.firstsymbol[i] = u16(k)
|
||||
code = code + sizes[i]
|
||||
if sizes[i] != 0 {
|
||||
if code - 1 >= (1 << u16(i)) {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths
|
||||
}
|
||||
}
|
||||
z.maxcode[i] = code << (HUFFMAN_MAX_BITS - uint(i));
|
||||
code <<= 1;
|
||||
k += int(sizes[i]);
|
||||
z.maxcode[i] = code << (HUFFMAN_MAX_BITS - uint(i))
|
||||
code <<= 1
|
||||
k += int(sizes[i])
|
||||
}
|
||||
|
||||
z.maxcode[HUFFMAN_MAX_BITS] = 0x10000; // Sentinel
|
||||
c: int;
|
||||
z.maxcode[HUFFMAN_MAX_BITS] = 0x10000 // Sentinel
|
||||
c: int
|
||||
|
||||
for v, ci in code_lengths {
|
||||
if v != 0 {
|
||||
c = next_code[v] - int(z.firstcode[v]) + int(z.firstsymbol[v]);
|
||||
fastv := u16((u16(v) << 9) | u16(ci));
|
||||
z.size[c] = u8(v);
|
||||
z.value[c] = u16(ci);
|
||||
c = next_code[v] - int(z.firstcode[v]) + int(z.firstsymbol[v])
|
||||
fastv := u16((u16(v) << 9) | u16(ci))
|
||||
z.size[c] = u8(v)
|
||||
z.value[c] = u16(ci)
|
||||
if v <= ZFAST_BITS {
|
||||
j := z_bit_reverse(u16(next_code[v]), v);
|
||||
j := z_bit_reverse(u16(next_code[v]), v)
|
||||
for j < (1 << ZFAST_BITS) {
|
||||
z.fast[j] = fastv;
|
||||
j += (1 << v);
|
||||
z.fast[j] = fastv
|
||||
j += (1 << v)
|
||||
}
|
||||
}
|
||||
next_code[v] += 1;
|
||||
next_code[v] += 1
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check {
|
||||
code := u16(compress.peek_bits_lsb(z,16));
|
||||
code := u16(compress.peek_bits_lsb(z,16))
|
||||
|
||||
k := int(z_bit_reverse(code, 16));
|
||||
s: u8;
|
||||
k := int(z_bit_reverse(code, 16))
|
||||
s: u8
|
||||
|
||||
#no_bounds_check for s = HUFFMAN_FAST_BITS+1; ; {
|
||||
if k < t.maxcode[s] {
|
||||
break;
|
||||
break
|
||||
}
|
||||
s += 1;
|
||||
s += 1
|
||||
}
|
||||
if s >= 16 {
|
||||
return 0, E_Deflate.Bad_Huffman_Code;
|
||||
return 0, E_Deflate.Bad_Huffman_Code
|
||||
}
|
||||
// code size is s, so:
|
||||
b := (k >> (16-s)) - int(t.firstcode[s]) + int(t.firstsymbol[s]);
|
||||
b := (k >> (16-s)) - int(t.firstcode[s]) + int(t.firstsymbol[s])
|
||||
if b >= size_of(t.size) {
|
||||
return 0, E_Deflate.Bad_Huffman_Code;
|
||||
return 0, E_Deflate.Bad_Huffman_Code
|
||||
}
|
||||
if t.size[b] != s {
|
||||
return 0, E_Deflate.Bad_Huffman_Code;
|
||||
return 0, E_Deflate.Bad_Huffman_Code
|
||||
}
|
||||
|
||||
compress.consume_bits_lsb(z, s);
|
||||
compress.consume_bits_lsb(z, s)
|
||||
|
||||
r = t.value[b];
|
||||
return r, nil;
|
||||
r = t.value[b]
|
||||
return r, nil
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
decode_huffman :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check {
|
||||
if z.num_bits < 16 {
|
||||
if z.num_bits > 63 {
|
||||
return 0, E_ZLIB.Code_Buffer_Malformed;
|
||||
return 0, E_ZLIB.Code_Buffer_Malformed
|
||||
}
|
||||
compress.refill_lsb(z);
|
||||
compress.refill_lsb(z)
|
||||
if z.num_bits > 63 {
|
||||
return 0, E_General.Stream_Too_Short;
|
||||
return 0, E_General.Stream_Too_Short
|
||||
}
|
||||
}
|
||||
#no_bounds_check b := t.fast[z.code_buffer & ZFAST_MASK];
|
||||
#no_bounds_check b := t.fast[z.code_buffer & ZFAST_MASK]
|
||||
if b != 0 {
|
||||
s := u8(b >> ZFAST_BITS);
|
||||
compress.consume_bits_lsb(z, s);
|
||||
return b & 511, nil;
|
||||
s := u8(b >> ZFAST_BITS)
|
||||
compress.consume_bits_lsb(z, s)
|
||||
return b & 511, nil
|
||||
}
|
||||
return decode_huffman_slowpath(z, t);
|
||||
return decode_huffman_slowpath(z, t)
|
||||
}
|
||||
|
||||
@(optimization_mode="speed")
|
||||
parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err: Error) #no_bounds_check {
|
||||
#no_bounds_check for {
|
||||
value, e := decode_huffman(z, z_repeat);
|
||||
value, e := decode_huffman(z, z_repeat)
|
||||
if e != nil {
|
||||
return err;
|
||||
return err
|
||||
}
|
||||
if value < 256 {
|
||||
e := write_byte(z, u8(value));
|
||||
e := write_byte(z, u8(value))
|
||||
if e != .None {
|
||||
return E_General.Output_Too_Short;
|
||||
return E_General.Output_Too_Short
|
||||
}
|
||||
} else {
|
||||
if value == 256 {
|
||||
// End of block
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
value -= 257;
|
||||
length := Z_LENGTH_BASE[value];
|
||||
value -= 257
|
||||
length := Z_LENGTH_BASE[value]
|
||||
if Z_LENGTH_EXTRA[value] > 0 {
|
||||
length += u16(compress.read_bits_lsb(z, Z_LENGTH_EXTRA[value]));
|
||||
length += u16(compress.read_bits_lsb(z, Z_LENGTH_EXTRA[value]))
|
||||
}
|
||||
|
||||
value, e = decode_huffman(z, z_offset);
|
||||
value, e = decode_huffman(z, z_offset)
|
||||
if e != nil {
|
||||
return E_Deflate.Bad_Huffman_Code;
|
||||
return E_Deflate.Bad_Huffman_Code
|
||||
}
|
||||
|
||||
distance := Z_DIST_BASE[value];
|
||||
distance := Z_DIST_BASE[value]
|
||||
if Z_DIST_EXTRA[value] > 0 {
|
||||
distance += u16(compress.read_bits_lsb(z, Z_DIST_EXTRA[value]));
|
||||
distance += u16(compress.read_bits_lsb(z, Z_DIST_EXTRA[value]))
|
||||
}
|
||||
|
||||
if z.bytes_written < i64(distance) {
|
||||
// Distance is longer than we've decoded so far.
|
||||
return E_Deflate.Bad_Distance;
|
||||
return E_Deflate.Bad_Distance
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -402,17 +402,17 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
|
||||
Replicate the last outputted byte, length times.
|
||||
*/
|
||||
if length > 0 {
|
||||
c := z.output.buf[z.bytes_written - i64(distance)];
|
||||
e := repl_byte(z, length, c);
|
||||
c := z.output.buf[z.bytes_written - i64(distance)]
|
||||
e := repl_byte(z, length, c)
|
||||
if e != .None {
|
||||
return E_General.Output_Too_Short;
|
||||
return E_General.Output_Too_Short
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if length > 0 {
|
||||
e := repl_bytes(z, length, distance);
|
||||
e := repl_bytes(z, length, distance)
|
||||
if e != .None {
|
||||
return E_General.Output_Too_Short;
|
||||
return E_General.Output_Too_Short
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -430,27 +430,27 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
|
||||
*/
|
||||
|
||||
if !raw {
|
||||
size, size_err := compress.input_size(ctx);
|
||||
size, size_err := compress.input_size(ctx)
|
||||
if size < 6 || size_err != nil {
|
||||
return E_General.Stream_Too_Short;
|
||||
return E_General.Stream_Too_Short
|
||||
}
|
||||
|
||||
cmf, _ := compress.read_u8(ctx);
|
||||
cmf, _ := compress.read_u8(ctx)
|
||||
|
||||
method := Compression_Method(cmf & 0xf);
|
||||
method := Compression_Method(cmf & 0xf)
|
||||
if method != .DEFLATE {
|
||||
return E_General.Unknown_Compression_Method;
|
||||
return E_General.Unknown_Compression_Method
|
||||
}
|
||||
|
||||
if cinfo := (cmf >> 4) & 0xf; cinfo > 7 {
|
||||
return E_ZLIB.Unsupported_Window_Size;
|
||||
return E_ZLIB.Unsupported_Window_Size
|
||||
}
|
||||
flg, _ := compress.read_u8(ctx);
|
||||
flg, _ := compress.read_u8(ctx)
|
||||
|
||||
fcheck := flg & 0x1f;
|
||||
fcheck_computed := (cmf << 8 | flg) & 0x1f;
|
||||
fcheck := flg & 0x1f
|
||||
fcheck_computed := (cmf << 8 | flg) & 0x1f
|
||||
if fcheck != fcheck_computed {
|
||||
return E_General.Checksum_Failed;
|
||||
return E_General.Checksum_Failed
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -458,7 +458,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
|
||||
They're application specific and PNG doesn't use them.
|
||||
*/
|
||||
if fdict := (flg >> 5) & 1; fdict != 0 {
|
||||
return E_ZLIB.FDICT_Unsupported;
|
||||
return E_ZLIB.FDICT_Unsupported
|
||||
}
|
||||
|
||||
// flevel := Compression_Level((flg >> 6) & 3);
|
||||
@@ -471,36 +471,36 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
|
||||
}
|
||||
|
||||
// Parse ZLIB stream without header.
|
||||
inflate_raw(z=ctx, expected_output_size=expected_output_size) or_return;
|
||||
inflate_raw(z=ctx, expected_output_size=expected_output_size) or_return
|
||||
|
||||
if !raw {
|
||||
compress.discard_to_next_byte_lsb(ctx);
|
||||
compress.discard_to_next_byte_lsb(ctx)
|
||||
|
||||
adler_b: [4]u8;
|
||||
adler_b: [4]u8
|
||||
for _, i in adler_b {
|
||||
adler_b[i], _ = compress.read_u8_prefer_code_buffer_lsb(ctx);
|
||||
adler_b[i], _ = compress.read_u8_prefer_code_buffer_lsb(ctx)
|
||||
}
|
||||
adler := transmute(u32be)adler_b;
|
||||
adler := transmute(u32be)adler_b
|
||||
|
||||
output_hash := hash.adler32(ctx.output.buf[:]);
|
||||
output_hash := hash.adler32(ctx.output.buf[:])
|
||||
|
||||
if output_hash != u32(adler) {
|
||||
return E_General.Checksum_Failed;
|
||||
return E_General.Checksum_Failed
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Check alignment of reserve/resize.
|
||||
|
||||
@(optimization_mode="speed")
|
||||
inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.allocator) -> (err: Error) #no_bounds_check {
|
||||
expected_output_size := expected_output_size;
|
||||
expected_output_size := expected_output_size
|
||||
|
||||
/*
|
||||
Always set up a minimum allocation size.
|
||||
*/
|
||||
expected_output_size = max(max(expected_output_size, compress.COMPRESS_OUTPUT_ALLOCATE_MIN), 512);
|
||||
expected_output_size = max(max(expected_output_size, compress.COMPRESS_OUTPUT_ALLOCATE_MIN), 512)
|
||||
|
||||
// fmt.printf("\nZLIB: Expected Payload Size: %v\n\n", expected_output_size);
|
||||
|
||||
@@ -508,34 +508,34 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
|
||||
/*
|
||||
Try to pre-allocate the output buffer.
|
||||
*/
|
||||
reserve(&z.output.buf, expected_output_size);
|
||||
resize (&z.output.buf, expected_output_size);
|
||||
reserve(&z.output.buf, expected_output_size)
|
||||
resize (&z.output.buf, expected_output_size)
|
||||
};
|
||||
|
||||
if len(z.output.buf) != expected_output_size {
|
||||
return .Resize_Failed;
|
||||
return .Resize_Failed
|
||||
}
|
||||
|
||||
z.num_bits = 0;
|
||||
z.code_buffer = 0;
|
||||
z.num_bits = 0
|
||||
z.code_buffer = 0
|
||||
|
||||
z_repeat: ^Huffman_Table;
|
||||
z_offset: ^Huffman_Table;
|
||||
codelength_ht: ^Huffman_Table;
|
||||
defer free(z_repeat);
|
||||
defer free(z_offset);
|
||||
defer free(codelength_ht);
|
||||
z_repeat: ^Huffman_Table
|
||||
z_offset: ^Huffman_Table
|
||||
codelength_ht: ^Huffman_Table
|
||||
defer free(z_repeat)
|
||||
defer free(z_offset)
|
||||
defer free(codelength_ht)
|
||||
|
||||
z_repeat = allocate_huffman_table(allocator=context.allocator) or_return;
|
||||
z_offset = allocate_huffman_table(allocator=context.allocator) or_return;
|
||||
codelength_ht = allocate_huffman_table(allocator=context.allocator) or_return;
|
||||
z_repeat = allocate_huffman_table(allocator=context.allocator) or_return
|
||||
z_offset = allocate_huffman_table(allocator=context.allocator) or_return
|
||||
codelength_ht = allocate_huffman_table(allocator=context.allocator) or_return
|
||||
|
||||
final := u32(0);
|
||||
type := u32(0);
|
||||
final := u32(0)
|
||||
type := u32(0)
|
||||
|
||||
for {
|
||||
final = compress.read_bits_lsb(z, 1);
|
||||
type = compress.read_bits_lsb(z, 2);
|
||||
final = compress.read_bits_lsb(z, 1)
|
||||
type = compress.read_bits_lsb(z, 2)
|
||||
|
||||
// fmt.printf("Final: %v | Type: %v\n", final, type);
|
||||
|
||||
@@ -544,16 +544,16 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
|
||||
// Uncompressed block
|
||||
|
||||
// Discard bits until next byte boundary
|
||||
compress.discard_to_next_byte_lsb(z);
|
||||
compress.discard_to_next_byte_lsb(z)
|
||||
|
||||
uncompressed_len := i16(compress.read_bits_lsb(z, 16));
|
||||
length_check := i16(compress.read_bits_lsb(z, 16));
|
||||
uncompressed_len := i16(compress.read_bits_lsb(z, 16))
|
||||
length_check := i16(compress.read_bits_lsb(z, 16))
|
||||
|
||||
// fmt.printf("LEN: %v, ~LEN: %v, NLEN: %v, ~NLEN: %v\n", uncompressed_len, ~uncompressed_len, length_check, ~length_check);
|
||||
|
||||
|
||||
if ~uncompressed_len != length_check {
|
||||
return E_Deflate.Len_Nlen_Mismatch;
|
||||
return E_Deflate.Len_Nlen_Mismatch
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -561,116 +561,116 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
|
||||
and a single Adler32 update after.
|
||||
*/
|
||||
#no_bounds_check for uncompressed_len > 0 {
|
||||
compress.refill_lsb(z);
|
||||
lit := compress.read_bits_lsb(z, 8);
|
||||
write_byte(z, u8(lit));
|
||||
uncompressed_len -= 1;
|
||||
compress.refill_lsb(z)
|
||||
lit := compress.read_bits_lsb(z, 8)
|
||||
write_byte(z, u8(lit))
|
||||
uncompressed_len -= 1
|
||||
}
|
||||
case 3:
|
||||
return E_Deflate.BType_3;
|
||||
return E_Deflate.BType_3
|
||||
case:
|
||||
// log.debugf("Err: %v | Final: %v | Type: %v\n", err, final, type);
|
||||
if type == 1 {
|
||||
// Use fixed code lengths.
|
||||
build_huffman(z_repeat, Z_FIXED_LENGTH[:]) or_return;
|
||||
build_huffman(z_offset, Z_FIXED_DIST[:]) or_return;
|
||||
build_huffman(z_repeat, Z_FIXED_LENGTH[:]) or_return
|
||||
build_huffman(z_offset, Z_FIXED_DIST[:]) or_return
|
||||
} else {
|
||||
lencodes: [286+32+137]u8;
|
||||
codelength_sizes: [19]u8;
|
||||
lencodes: [286+32+137]u8
|
||||
codelength_sizes: [19]u8
|
||||
|
||||
//i: u32;
|
||||
n: u32;
|
||||
n: u32
|
||||
|
||||
compress.refill_lsb(z, 14);
|
||||
hlit := compress.read_bits_no_refill_lsb(z, 5) + 257;
|
||||
hdist := compress.read_bits_no_refill_lsb(z, 5) + 1;
|
||||
hclen := compress.read_bits_no_refill_lsb(z, 4) + 4;
|
||||
ntot := hlit + hdist;
|
||||
compress.refill_lsb(z, 14)
|
||||
hlit := compress.read_bits_no_refill_lsb(z, 5) + 257
|
||||
hdist := compress.read_bits_no_refill_lsb(z, 5) + 1
|
||||
hclen := compress.read_bits_no_refill_lsb(z, 4) + 4
|
||||
ntot := hlit + hdist
|
||||
|
||||
#no_bounds_check for i in 0..<hclen {
|
||||
s := compress.read_bits_lsb(z, 3);
|
||||
codelength_sizes[Z_LENGTH_DEZIGZAG[i]] = u8(s);
|
||||
s := compress.read_bits_lsb(z, 3)
|
||||
codelength_sizes[Z_LENGTH_DEZIGZAG[i]] = u8(s)
|
||||
}
|
||||
build_huffman(codelength_ht, codelength_sizes[:]) or_return;
|
||||
build_huffman(codelength_ht, codelength_sizes[:]) or_return
|
||||
|
||||
n = 0;
|
||||
c: u16;
|
||||
n = 0
|
||||
c: u16
|
||||
|
||||
for n < ntot {
|
||||
c = decode_huffman(z, codelength_ht) or_return;
|
||||
c = decode_huffman(z, codelength_ht) or_return
|
||||
|
||||
if c < 0 || c >= 19 {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths
|
||||
}
|
||||
if c < 16 {
|
||||
lencodes[n] = u8(c);
|
||||
n += 1;
|
||||
lencodes[n] = u8(c)
|
||||
n += 1
|
||||
} else {
|
||||
fill := u8(0);
|
||||
compress.refill_lsb(z, 7);
|
||||
fill := u8(0)
|
||||
compress.refill_lsb(z, 7)
|
||||
switch c {
|
||||
case 16:
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 2) + 3);
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 2) + 3)
|
||||
if n == 0 {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths
|
||||
}
|
||||
fill = lencodes[n - 1];
|
||||
fill = lencodes[n - 1]
|
||||
case 17:
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 3) + 3);
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 3) + 3)
|
||||
case 18:
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 7) + 11);
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 7) + 11)
|
||||
case:
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths
|
||||
}
|
||||
|
||||
if ntot - n < u32(c) {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths
|
||||
}
|
||||
|
||||
nc := n + u32(c);
|
||||
nc := n + u32(c)
|
||||
#no_bounds_check for ; n < nc; n += 1 {
|
||||
lencodes[n] = fill;
|
||||
lencodes[n] = fill
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if n != ntot {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths
|
||||
}
|
||||
|
||||
build_huffman(z_repeat, lencodes[:hlit]) or_return;
|
||||
build_huffman(z_offset, lencodes[hlit:ntot]) or_return;
|
||||
build_huffman(z_repeat, lencodes[:hlit]) or_return
|
||||
build_huffman(z_offset, lencodes[hlit:ntot]) or_return
|
||||
}
|
||||
parse_huffman_block(z, z_repeat, z_offset) or_return;
|
||||
parse_huffman_block(z, z_repeat, z_offset) or_return
|
||||
}
|
||||
if final == 1 {
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if int(z.bytes_written) != len(z.output.buf) {
|
||||
resize(&z.output.buf, int(z.bytes_written));
|
||||
resize(&z.output.buf, int(z.bytes_written))
|
||||
}
|
||||
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
|
||||
inflate_from_byte_array :: proc(input: []u8, buf: ^bytes.Buffer, raw := false, expected_output_size := -1) -> (err: Error) {
|
||||
ctx := compress.Context_Memory_Input{};
|
||||
ctx := compress.Context_Memory_Input{}
|
||||
|
||||
ctx.input_data = input;
|
||||
ctx.output = buf;
|
||||
ctx.input_data = input
|
||||
ctx.output = buf
|
||||
|
||||
return inflate_from_context(ctx=&ctx, raw=raw, expected_output_size=expected_output_size);
|
||||
return inflate_from_context(ctx=&ctx, raw=raw, expected_output_size=expected_output_size)
|
||||
}
|
||||
|
||||
inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := false, expected_output_size := -1) -> (err: Error) {
|
||||
ctx := compress.Context_Memory_Input{};
|
||||
ctx := compress.Context_Memory_Input{}
|
||||
|
||||
ctx.input_data = input;
|
||||
ctx.output = buf;
|
||||
ctx.input_data = input
|
||||
ctx.output = buf
|
||||
|
||||
return inflate_raw(z=&ctx, expected_output_size=expected_output_size);
|
||||
return inflate_raw(z=&ctx, expected_output_size=expected_output_size)
|
||||
}
|
||||
|
||||
inflate :: proc{inflate_from_context, inflate_from_byte_array};
|
||||
Reference in New Issue
Block a user