mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 03:40:08 +00:00
Minor stylistic code changes to compress and image packages
This commit is contained in:
@@ -200,4 +200,4 @@ read_bits_no_refill_lsb :: #force_inline proc(z: ^Context, width: u8) -> u32 {
|
||||
discard_to_next_byte_lsb :: proc(z: ^Context) {
|
||||
discard := u8(z.num_bits & 7);
|
||||
consume_bits_lsb(z, discard);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ main :: proc() {
|
||||
|
||||
if len(args) < 2 {
|
||||
stderr("No input file specified.\n");
|
||||
err := gzip.load(&TEST, &buf);
|
||||
err := gzip.load(TEST, &buf);
|
||||
if gzip.is_kind(err, gzip.E_General.OK) {
|
||||
stdout("Displaying test vector: ");
|
||||
stdout(bytes.buffer_to_string(&buf));
|
||||
@@ -50,7 +50,7 @@ main :: proc() {
|
||||
if file == "-" {
|
||||
// Read from stdin
|
||||
s := os.stream_from_handle(os.stdin);
|
||||
err = gzip.load(&s, &buf);
|
||||
err = gzip.load(s, &buf);
|
||||
} else {
|
||||
err = gzip.load(file, &buf);
|
||||
}
|
||||
@@ -67,4 +67,4 @@ main :: proc() {
|
||||
stdout(bytes.buffer_to_string(&buf));
|
||||
}
|
||||
os.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,39 +45,39 @@ Header_Flag :: enum u8 {
|
||||
Header_Flags :: distinct bit_set[Header_Flag; u8];
|
||||
|
||||
OS :: enum u8 {
|
||||
FAT = 0,
|
||||
Amiga = 1,
|
||||
VMS = 2,
|
||||
Unix = 3,
|
||||
VM_CMS = 4,
|
||||
Atari_TOS = 5,
|
||||
HPFS = 6,
|
||||
Macintosh = 7,
|
||||
Z_System = 8,
|
||||
CP_M = 9,
|
||||
TOPS_20 = 10,
|
||||
NTFS = 11,
|
||||
QDOS = 12,
|
||||
FAT = 0,
|
||||
Amiga = 1,
|
||||
VMS = 2,
|
||||
Unix = 3,
|
||||
VM_CMS = 4,
|
||||
Atari_TOS = 5,
|
||||
HPFS = 6,
|
||||
Macintosh = 7,
|
||||
Z_System = 8,
|
||||
CP_M = 9,
|
||||
TOPS_20 = 10,
|
||||
NTFS = 11,
|
||||
QDOS = 12,
|
||||
Acorn_RISCOS = 13,
|
||||
_Unknown = 14,
|
||||
Unknown = 255,
|
||||
_Unknown = 14,
|
||||
Unknown = 255,
|
||||
}
|
||||
OS_Name :: #partial [OS]string{
|
||||
.FAT = "FAT",
|
||||
.Amiga = "Amiga",
|
||||
.VMS = "VMS/OpenVMS",
|
||||
.Unix = "Unix",
|
||||
.VM_CMS = "VM/CMS",
|
||||
.Atari_TOS = "Atari TOS",
|
||||
.HPFS = "HPFS",
|
||||
.Macintosh = "Macintosh",
|
||||
.Z_System = "Z-System",
|
||||
.CP_M = "CP/M",
|
||||
.TOPS_20 = "TOPS-20",
|
||||
.NTFS = "NTFS",
|
||||
.QDOS = "QDOS",
|
||||
.FAT = "FAT",
|
||||
.Amiga = "Amiga",
|
||||
.VMS = "VMS/OpenVMS",
|
||||
.Unix = "Unix",
|
||||
.VM_CMS = "VM/CMS",
|
||||
.Atari_TOS = "Atari TOS",
|
||||
.HPFS = "HPFS",
|
||||
.Macintosh = "Macintosh",
|
||||
.Z_System = "Z-System",
|
||||
.CP_M = "CP/M",
|
||||
.TOPS_20 = "TOPS-20",
|
||||
.NTFS = "NTFS",
|
||||
.QDOS = "QDOS",
|
||||
.Acorn_RISCOS = "Acorn RISCOS",
|
||||
.Unknown = "Unknown",
|
||||
.Unknown = "Unknown",
|
||||
};
|
||||
|
||||
Compression :: enum u8 {
|
||||
@@ -96,13 +96,13 @@ E_ZLIB :: compress.ZLIB_Error;
|
||||
E_Deflate :: compress.Deflate_Error;
|
||||
is_kind :: compress.is_kind;
|
||||
|
||||
load_from_slice :: proc(slice: ^[]u8, buf: ^bytes.Buffer, allocator := context.allocator) -> (err: Error) {
|
||||
load_from_slice :: proc(slice: []u8, buf: ^bytes.Buffer, allocator := context.allocator) -> (err: Error) {
|
||||
|
||||
r := bytes.Reader{};
|
||||
bytes.reader_init(&r, slice^);
|
||||
bytes.reader_init(&r, slice);
|
||||
stream := bytes.reader_to_stream(&r);
|
||||
|
||||
err = load_from_stream(&stream, buf, allocator);
|
||||
err = load_from_stream(stream, buf, allocator);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -111,18 +111,16 @@ load_from_file :: proc(filename: string, buf: ^bytes.Buffer, allocator := contex
|
||||
data, ok := os.read_entire_file(filename, allocator);
|
||||
defer delete(data);
|
||||
|
||||
err = E_General.File_Not_Found;
|
||||
if ok {
|
||||
err = load_from_slice(&data, buf, allocator);
|
||||
return;
|
||||
} else {
|
||||
return E_General.File_Not_Found;
|
||||
err = load_from_slice(data, buf, allocator);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
load_from_stream :: proc(stream: ^io.Stream, buf: ^bytes.Buffer, allocator := context.allocator) -> (err: Error) {
|
||||
|
||||
load_from_stream :: proc(stream: io.Stream, buf: ^bytes.Buffer, allocator := context.allocator) -> (err: Error) {
|
||||
ctx := compress.Context{
|
||||
input = stream^,
|
||||
input = stream,
|
||||
};
|
||||
buf := buf;
|
||||
ws := bytes.buffer_to_stream(buf);
|
||||
@@ -313,4 +311,4 @@ load_from_stream :: proc(stream: ^io.Stream, buf: ^bytes.Buffer, allocator := co
|
||||
return E_General.OK;
|
||||
}
|
||||
|
||||
load :: proc{load_from_file, load_from_slice, load_from_stream};
|
||||
load :: proc{load_from_file, load_from_slice, load_from_stream};
|
||||
|
||||
@@ -7,30 +7,30 @@ import "core:fmt"
|
||||
|
||||
main :: proc() {
|
||||
|
||||
ODIN_DEMO: []u8 = {
|
||||
ODIN_DEMO := []u8{
|
||||
120, 156, 101, 144, 77, 110, 131, 48, 16, 133, 215, 204, 41, 158, 44,
|
||||
69, 73, 32, 148, 182, 75, 35, 14, 208, 125, 47, 96, 185, 195, 143,
|
||||
69, 73, 32, 148, 182, 75, 35, 14, 208, 125, 47, 96, 185, 195, 143,
|
||||
130, 13, 50, 38, 81, 84, 101, 213, 75, 116, 215, 43, 246, 8, 53,
|
||||
82, 126, 8, 181, 188, 152, 153, 111, 222, 147, 159, 123, 165, 247, 170,
|
||||
98, 24, 213, 88, 162, 198, 244, 157, 243, 16, 186, 115, 44, 75, 227,
|
||||
5, 77, 115, 72, 137, 222, 117, 122, 179, 197, 39, 69, 161, 170, 156,
|
||||
50, 144, 5, 68, 130, 4, 49, 126, 127, 190, 191, 144, 34, 19, 57,
|
||||
69, 74, 235, 209, 140, 173, 242, 157, 155, 54, 158, 115, 162, 168, 12,
|
||||
82, 126, 8, 181, 188, 152, 153, 111, 222, 147, 159, 123, 165, 247, 170,
|
||||
98, 24, 213, 88, 162, 198, 244, 157, 243, 16, 186, 115, 44, 75, 227,
|
||||
5, 77, 115, 72, 137, 222, 117, 122, 179, 197, 39, 69, 161, 170, 156,
|
||||
50, 144, 5, 68, 130, 4, 49, 126, 127, 190, 191, 144, 34, 19, 57,
|
||||
69, 74, 235, 209, 140, 173, 242, 157, 155, 54, 158, 115, 162, 168, 12,
|
||||
181, 239, 246, 108, 17, 188, 174, 242, 224, 20, 13, 199, 198, 235, 250,
|
||||
194, 166, 129, 86, 3, 99, 157, 172, 37, 230, 62, 73, 129, 151, 252,
|
||||
70, 211, 5, 77, 31, 104, 188, 160, 113, 129, 215, 59, 205, 22, 52,
|
||||
123, 160, 83, 142, 255, 242, 89, 123, 93, 149, 200, 50, 188, 85, 54,
|
||||
252, 18, 248, 192, 238, 228, 235, 198, 86, 224, 118, 224, 176, 113, 166,
|
||||
112, 67, 106, 227, 159, 122, 215, 88, 95, 110, 196, 123, 205, 183, 224,
|
||||
98, 53, 8, 104, 213, 234, 201, 147, 7, 248, 192, 14, 170, 29, 25,
|
||||
98, 53, 8, 104, 213, 234, 201, 147, 7, 248, 192, 14, 170, 29, 25,
|
||||
171, 15, 18, 59, 138, 112, 63, 23, 205, 110, 254, 136, 109, 78, 231,
|
||||
63, 234, 138, 133, 204,
|
||||
63, 234, 138, 133, 204,
|
||||
};
|
||||
|
||||
buf: bytes.Buffer;
|
||||
|
||||
// We can pass ", true" to inflate a raw DEFLATE stream instead of a ZLIB wrapped one.
|
||||
err := zlib.inflate(&ODIN_DEMO, &buf);
|
||||
err := zlib.inflate(ODIN_DEMO, &buf);
|
||||
defer bytes.buffer_destroy(&buf);
|
||||
|
||||
if !zlib.is_kind(err, zlib.E_General.OK) {
|
||||
@@ -39,4 +39,4 @@ main :: proc() {
|
||||
s := bytes.buffer_to_string(&buf);
|
||||
fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s);
|
||||
assert(len(s) == 438);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ Compression_Method :: enum u8 {
|
||||
Compression_Level :: enum u8 {
|
||||
Fastest = 0,
|
||||
Fast = 1,
|
||||
Default = 2,
|
||||
Maximum = 3,
|
||||
Default = 2,
|
||||
Maximum = 3,
|
||||
}
|
||||
|
||||
Options :: struct {
|
||||
@@ -68,19 +68,19 @@ Z_LENGTH_DEZIGZAG := []u8{
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 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, 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 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, 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,
|
||||
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,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -94,12 +94,12 @@ ZFAST_MASK :: ((1 << ZFAST_BITS) - 1);
|
||||
JPEG packs from left, ZLIB from right. We can't share code.
|
||||
*/
|
||||
Huffman_Table :: struct {
|
||||
fast: [1 << ZFAST_BITS]u16,
|
||||
firstcode: [16]u16,
|
||||
maxcode: [17]int,
|
||||
firstsymbol: [16]u16,
|
||||
size: [288]u8,
|
||||
value: [288]u16,
|
||||
fast: [1 << ZFAST_BITS]u16,
|
||||
firstcode: [16]u16,
|
||||
maxcode: [17]int,
|
||||
firstsymbol: [16]u16,
|
||||
size: [288]u8,
|
||||
value: [288]u16,
|
||||
};
|
||||
|
||||
// Implementation starts here
|
||||
@@ -218,19 +218,19 @@ decode_huffman_slowpath :: proc(z: ^Context, t: ^Huffman_Table) -> (r: u16, err:
|
||||
if (s >= 16) {
|
||||
return 0, E_Deflate.Bad_Huffman_Code;
|
||||
}
|
||||
// code size is s, so:
|
||||
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;
|
||||
}
|
||||
if t.size[b] != s {
|
||||
return 0, E_Deflate.Bad_Huffman_Code;
|
||||
}
|
||||
// code size is s, so:
|
||||
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;
|
||||
}
|
||||
if t.size[b] != s {
|
||||
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, E_General.OK;
|
||||
r = t.value[b];
|
||||
return r, E_General.OK;
|
||||
}
|
||||
|
||||
decode_huffman :: proc(z: ^Context, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check {
|
||||
@@ -254,7 +254,6 @@ decode_huffman :: proc(z: ^Context, t: ^Huffman_Table) -> (r: u16, err: Error) #
|
||||
}
|
||||
|
||||
parse_huffman_block :: proc(z: ^Context, z_repeat, z_offset: ^Huffman_Table) -> (err: Error) #no_bounds_check {
|
||||
|
||||
#no_bounds_check for {
|
||||
value, e := decode_huffman(z, z_repeat);
|
||||
if !is_kind(e, E_General.OK) {
|
||||
@@ -267,8 +266,8 @@ parse_huffman_block :: proc(z: ^Context, z_repeat, z_offset: ^Huffman_Table) ->
|
||||
}
|
||||
} else {
|
||||
if value == 256 {
|
||||
// End of block
|
||||
return E_General.OK;
|
||||
// End of block
|
||||
return E_General.OK;
|
||||
}
|
||||
|
||||
value -= 257;
|
||||
@@ -370,7 +369,7 @@ inflate_from_stream :: proc(using ctx: ^Context, raw := false, allocator := cont
|
||||
}
|
||||
|
||||
fdict := (flg >> 5) & 1;
|
||||
/*
|
||||
/*
|
||||
We don't handle built-in dictionaries for now.
|
||||
They're application specific and PNG doesn't use them.
|
||||
*/
|
||||
@@ -449,7 +448,8 @@ inflate_from_stream_raw :: proc(z: ^Context, allocator := context.allocator) ->
|
||||
|
||||
// log.debugf("Final: %v | Type: %v\n", final, type);
|
||||
|
||||
if type == 0 {
|
||||
switch type {
|
||||
case 0:
|
||||
// Uncompressed block
|
||||
|
||||
// Discard bits until next byte boundary
|
||||
@@ -471,9 +471,9 @@ inflate_from_stream_raw :: proc(z: ^Context, allocator := context.allocator) ->
|
||||
write_byte(z, u8(lit));
|
||||
uncompressed_len -= 1;
|
||||
}
|
||||
} else if type == 3 {
|
||||
case 3:
|
||||
return E_Deflate.BType_3;
|
||||
} else {
|
||||
case:
|
||||
// log.debugf("Err: %v | Final: %v | Type: %v\n", err, final, type);
|
||||
if type == 1 {
|
||||
// Use fixed code lengths.
|
||||
@@ -487,12 +487,12 @@ inflate_from_stream_raw :: proc(z: ^Context, allocator := context.allocator) ->
|
||||
}
|
||||
} else {
|
||||
lencodes: [286+32+137]u8;
|
||||
codelength_sizes: [19]u8;
|
||||
codelength_sizes: [19]u8;
|
||||
|
||||
//i: u32;
|
||||
n: u32;
|
||||
//i: u32;
|
||||
n: u32;
|
||||
|
||||
compress.refill_lsb(z, 14);
|
||||
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;
|
||||
@@ -525,34 +525,35 @@ inflate_from_stream_raw :: proc(z: ^Context, allocator := context.allocator) ->
|
||||
} else {
|
||||
fill := u8(0);
|
||||
compress.refill_lsb(z, 7);
|
||||
if c == 16 {
|
||||
switch c {
|
||||
case 16:
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 2) + 3);
|
||||
if n == 0 {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
}
|
||||
fill = lencodes[n - 1];
|
||||
} else if c == 17 {
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 3) + 3);
|
||||
} else if c == 18 {
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 7) + 11);
|
||||
} else {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
}
|
||||
if n == 0 {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
}
|
||||
fill = lencodes[n - 1];
|
||||
case 17:
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 3) + 3);
|
||||
case 18:
|
||||
c = u16(compress.read_bits_no_refill_lsb(z, 7) + 11);
|
||||
case:
|
||||
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);
|
||||
#no_bounds_check for ; n < nc; n += 1 {
|
||||
lencodes[n] = fill;
|
||||
}
|
||||
nc := n + u32(c);
|
||||
#no_bounds_check for ; n < nc; n += 1 {
|
||||
lencodes[n] = fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if n != ntot {
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
}
|
||||
return E_Deflate.Huffman_Bad_Code_Lengths;
|
||||
}
|
||||
|
||||
err = build_huffman(z_repeat, lencodes[:hlit]);
|
||||
if !is_kind(err, E_General.OK) {
|
||||
@@ -577,11 +578,11 @@ inflate_from_stream_raw :: proc(z: ^Context, allocator := context.allocator) ->
|
||||
return E_General.OK;
|
||||
}
|
||||
|
||||
inflate_from_byte_array :: proc(input: ^[]u8, buf: ^bytes.Buffer, raw := false) -> (err: Error) {
|
||||
inflate_from_byte_array :: proc(input: []u8, buf: ^bytes.Buffer, raw := false) -> (err: Error) {
|
||||
ctx := Context{};
|
||||
|
||||
r := bytes.Reader{};
|
||||
bytes.reader_init(&r, input^);
|
||||
bytes.reader_init(&r, input);
|
||||
rs := bytes.reader_to_stream(&r);
|
||||
ctx.input = rs;
|
||||
|
||||
@@ -594,9 +595,9 @@ inflate_from_byte_array :: proc(input: ^[]u8, buf: ^bytes.Buffer, raw := false)
|
||||
return err;
|
||||
}
|
||||
|
||||
inflate_from_byte_array_raw :: proc(input: ^[]u8, buf: ^bytes.Buffer, raw := false) -> (err: Error) {
|
||||
inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := false) -> (err: Error) {
|
||||
return inflate_from_byte_array(input, buf, true);
|
||||
}
|
||||
|
||||
inflate :: proc{inflate_from_stream, inflate_from_byte_array};
|
||||
inflate_raw :: proc{inflate_from_stream_raw, inflate_from_byte_array_raw};
|
||||
inflate_raw :: proc{inflate_from_stream_raw, inflate_from_byte_array_raw};
|
||||
|
||||
Reference in New Issue
Block a user