Browse Source

Minor stylistic code changes to compress and image packages

gingerBill 4 years ago
parent
commit
5f617c56e1

+ 1 - 1
core/compress/common.odin

@@ -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_to_next_byte_lsb :: proc(z: ^Context) {
 	discard := u8(z.num_bits & 7);
 	discard := u8(z.num_bits & 7);
 	consume_bits_lsb(z, discard);
 	consume_bits_lsb(z, discard);
-}
+}

+ 3 - 3
core/compress/gzip/example.odin

@@ -34,7 +34,7 @@ main :: proc() {
 
 
 	if len(args) < 2 {
 	if len(args) < 2 {
 		stderr("No input file specified.\n");
 		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) {
 		if gzip.is_kind(err, gzip.E_General.OK) {
 			stdout("Displaying test vector: ");
 			stdout("Displaying test vector: ");
 			stdout(bytes.buffer_to_string(&buf));
 			stdout(bytes.buffer_to_string(&buf));
@@ -50,7 +50,7 @@ main :: proc() {
 		if file == "-" {
 		if file == "-" {
 			// Read from stdin
 			// Read from stdin
 			s := os.stream_from_handle(os.stdin);
 			s := os.stream_from_handle(os.stdin);
-			err = gzip.load(&s, &buf);
+			err = gzip.load(s, &buf);
 		} else {
 		} else {
 			err = gzip.load(file, &buf);
 			err = gzip.load(file, &buf);
 		}
 		}
@@ -67,4 +67,4 @@ main :: proc() {
 		stdout(bytes.buffer_to_string(&buf));
 		stdout(bytes.buffer_to_string(&buf));
 	}
 	}
 	os.exit(0);
 	os.exit(0);
-}
+}

+ 38 - 40
core/compress/gzip/gzip.odin

@@ -45,39 +45,39 @@ Header_Flag :: enum u8 {
 Header_Flags :: distinct bit_set[Header_Flag; u8];
 Header_Flags :: distinct bit_set[Header_Flag; u8];
 
 
 OS :: enum 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,
 	Acorn_RISCOS = 13,
-	_Unknown = 14,
-	Unknown = 255,
+	_Unknown     = 14,
+	Unknown      = 255,
 }
 }
 OS_Name :: #partial [OS]string{
 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",
 	.Acorn_RISCOS = "Acorn RISCOS",
-	.Unknown = "Unknown",
+	.Unknown      = "Unknown",
 };
 };
 
 
 Compression :: enum u8 {
 Compression :: enum u8 {
@@ -96,13 +96,13 @@ E_ZLIB    :: compress.ZLIB_Error;
 E_Deflate :: compress.Deflate_Error;
 E_Deflate :: compress.Deflate_Error;
 is_kind   :: compress.is_kind;
 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{};
 	r := bytes.Reader{};
-	bytes.reader_init(&r, slice^);
+	bytes.reader_init(&r, slice);
 	stream := bytes.reader_to_stream(&r);
 	stream := bytes.reader_to_stream(&r);
 
 
-	err = load_from_stream(&stream, buf, allocator);
+	err = load_from_stream(stream, buf, allocator);
 
 
 	return err;
 	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);
 	data, ok := os.read_entire_file(filename, allocator);
 	defer delete(data);
 	defer delete(data);
 
 
+	err = E_General.File_Not_Found;
 	if ok {
 	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{
 	ctx := compress.Context{
-		input  = stream^,
+		input  = stream,
 	};
 	};
 	buf := buf;
 	buf := buf;
 	ws := bytes.buffer_to_stream(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;
 	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};

+ 11 - 11
core/compress/zlib/example.odin

@@ -7,30 +7,30 @@ import "core:fmt"
 
 
 main :: proc() {
 main :: proc() {
 
 
-	ODIN_DEMO: []u8 = {
+	ODIN_DEMO := []u8{
 		120, 156, 101, 144,  77, 110, 131,  48,  16, 133, 215, 204,  41, 158,  44,
 		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,
 		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,
 		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,
 		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,
 		 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,
 		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,
 		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,
 		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,
 		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;
 	buf: bytes.Buffer;
 
 
 	// We can pass ", true" to inflate a raw DEFLATE stream instead of a ZLIB wrapped one.
 	// 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);
 	defer bytes.buffer_destroy(&buf);
 
 
 	if !zlib.is_kind(err, zlib.E_General.OK) {
 	if !zlib.is_kind(err, zlib.E_General.OK) {
@@ -39,4 +39,4 @@ main :: proc() {
 	s := bytes.buffer_to_string(&buf);
 	s := bytes.buffer_to_string(&buf);
 	fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s);
 	fmt.printf("Input: %v bytes, output (%v bytes):\n%v\n", len(ODIN_DEMO), len(s), s);
 	assert(len(s) == 438);
 	assert(len(s) == 438);
-}
+}

+ 67 - 66
core/compress/zlib/zlib.odin

@@ -21,8 +21,8 @@ Compression_Method :: enum u8 {
 Compression_Level :: enum u8 {
 Compression_Level :: enum u8 {
 	Fastest = 0,
 	Fastest = 0,
 	Fast    = 1,
 	Fast    = 1,
-    Default = 2,
-    Maximum = 3,
+	Default = 2,
+	Maximum = 3,
 }
 }
 
 
 Options :: struct {
 Options :: struct {
@@ -68,19 +68,19 @@ Z_LENGTH_DEZIGZAG := []u8{
 };
 };
 
 
 Z_FIXED_LENGTH := [288]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{
 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.
 	JPEG packs from left, ZLIB from right. We can't share code.
 */
 */
 Huffman_Table :: struct {
 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
 // Implementation starts here
@@ -218,19 +218,19 @@ decode_huffman_slowpath :: proc(z: ^Context, t: ^Huffman_Table) -> (r: u16, err:
 	if (s >= 16) {
 	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]);
-   	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);
-
-   	r = t.value[b];
-   	return r, E_General.OK;
+	// 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);
+
+	r = t.value[b];
+	return r, E_General.OK;
 }
 }
 
 
 decode_huffman :: proc(z: ^Context, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check {
 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 {
 parse_huffman_block :: proc(z: ^Context, z_repeat, z_offset: ^Huffman_Table) -> (err: Error) #no_bounds_check {
-
 	#no_bounds_check for {
 	#no_bounds_check for {
 		value, e := decode_huffman(z, z_repeat);
 		value, e := decode_huffman(z, z_repeat);
 		if !is_kind(e, E_General.OK) {
 		if !is_kind(e, E_General.OK) {
@@ -267,8 +266,8 @@ parse_huffman_block :: proc(z: ^Context, z_repeat, z_offset: ^Huffman_Table) ->
 			}
 			}
 		} else {
 		} else {
 			if value == 256 {
 			if value == 256 {
-         		// End of block
-         		return E_General.OK;
+      				// End of block
+      				return E_General.OK;
 			}
 			}
 
 
 			value -= 257;
 			value -= 257;
@@ -370,7 +369,7 @@ inflate_from_stream :: proc(using ctx: ^Context, raw := false, allocator := cont
 		}
 		}
 
 
 		fdict   := (flg >> 5) & 1;
 		fdict   := (flg >> 5) & 1;
-		/* 
+		/*
 			We don't handle built-in dictionaries for now.
 			We don't handle built-in dictionaries for now.
 			They're application specific and PNG doesn't use them.
 			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);
 		// log.debugf("Final: %v | Type: %v\n", final, type);
 
 
-		if type == 0 {
+		switch type {
+		case 0:
 			// Uncompressed block
 			// Uncompressed block
 
 
 			// Discard bits until next byte boundary
 			// 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));
 				write_byte(z, u8(lit));
 				uncompressed_len -= 1;
 				uncompressed_len -= 1;
 			}
 			}
-		} else if type == 3 {
+		case 3:
 			return E_Deflate.BType_3;
 			return E_Deflate.BType_3;
-		} else {
+		case:
 			// log.debugf("Err: %v | Final: %v | Type: %v\n", err, final, type);
 			// log.debugf("Err: %v | Final: %v | Type: %v\n", err, final, type);
 			if type == 1 {
 			if type == 1 {
 				// Use fixed code lengths.
 				// Use fixed code lengths.
@@ -487,12 +487,12 @@ inflate_from_stream_raw :: proc(z: ^Context, allocator := context.allocator) ->
 				}
 				}
 			} else {
 			} else {
 				lencodes: [286+32+137]u8;
 				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;
 				hlit  := compress.read_bits_no_refill_lsb(z, 5) + 257;
 				hdist := compress.read_bits_no_refill_lsb(z, 5) + 1;
 				hdist := compress.read_bits_no_refill_lsb(z, 5) + 1;
 				hclen := compress.read_bits_no_refill_lsb(z, 4) + 4;
 				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 {
 					} else {
 						fill := u8(0);
 						fill := u8(0);
 						compress.refill_lsb(z, 7);
 						compress.refill_lsb(z, 7);
-						if c == 16 {
+						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;
-			            	}
-			            	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) {
 						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 {
 				if n != ntot {
-			   		return E_Deflate.Huffman_Bad_Code_Lengths;
-			   	}
+					return E_Deflate.Huffman_Bad_Code_Lengths;
+				}
 
 
 				err = build_huffman(z_repeat, lencodes[:hlit]);
 				err = build_huffman(z_repeat, lencodes[:hlit]);
 				if !is_kind(err, E_General.OK) {
 				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;
 	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{};
 	ctx := Context{};
 
 
 	r := bytes.Reader{};
 	r := bytes.Reader{};
-	bytes.reader_init(&r, input^);
+	bytes.reader_init(&r, input);
 	rs := bytes.reader_to_stream(&r);
 	rs := bytes.reader_to_stream(&r);
 	ctx.input = rs;
 	ctx.input = rs;
 
 
@@ -594,9 +595,9 @@ inflate_from_byte_array :: proc(input: ^[]u8, buf: ^bytes.Buffer, raw := false)
 	return err;
 	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);
 	return inflate_from_byte_array(input, buf, true);
 }
 }
 
 
 inflate     :: proc{inflate_from_stream, inflate_from_byte_array};
 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};

+ 2 - 2
core/image/png/example.odin

@@ -194,7 +194,7 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b
 	}
 	}
 	defer close(fd);
 	defer close(fd);
 
 
-	write_string(fd, 
+	write_string(fd,
 		fmt.tprintf("P6\n%v %v\n%v\n", width, height, (1 << depth -1)),
 		fmt.tprintf("P6\n%v %v\n%v\n", width, height, (1 << depth -1)),
 	);
 	);
 
 
@@ -324,4 +324,4 @@ write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: b
 		}
 		}
 	}
 	}
 	return true;
 	return true;
-}
+}

+ 91 - 96
core/image/png/helpers.odin

@@ -76,102 +76,102 @@ core_time :: proc(c: Chunk) -> (t: coretime.Time, ok: bool) {
 	using png_time;
 	using png_time;
 	return coretime.datetime_to_time(
 	return coretime.datetime_to_time(
 		int(year), int(month), int(day),
 		int(year), int(month), int(day),
-		int(hour), int(minute), int(second));
+		int(hour), int(minute), int(second),
+	);
 }
 }
 
 
 text :: proc(c: Chunk) -> (res: Text, ok: bool) {
 text :: proc(c: Chunk) -> (res: Text, ok: bool) {
 	 #partial switch c.header.type {
 	 #partial switch c.header.type {
-		case .tEXt:
-			ok = true;
-
-			fields := bytes.split(s=c.data, sep=[]u8{0}, allocator=context.temp_allocator);
-			if len(fields) == 2 {
-				res.keyword = strings.clone(string(fields[0]));
-				res.text    = strings.clone(string(fields[1]));
-			} else {
-				ok = false;
-			}
-			return;
-		case .zTXt:
-			ok = true;
-
-			fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator);
-			if len(fields) != 3 || len(fields[1]) != 0 {
-				// Compression method must be 0=Deflate, which thanks to the split above turns
-				// into an empty slice
-				ok = false; return;
-			}
-
-			// Set up ZLIB context and decompress text payload.
-			buf: bytes.Buffer;
-			zlib_error := zlib.inflate_from_byte_array(&fields[2], &buf);
-			defer bytes.buffer_destroy(&buf);
-			if !is_kind(zlib_error, E_General.OK) {
-				ok = false; return;
-			}
+	case .tEXt:
+		ok = true;
 
 
+		fields := bytes.split(s=c.data, sep=[]u8{0}, allocator=context.temp_allocator);
+		if len(fields) == 2 {
 			res.keyword = strings.clone(string(fields[0]));
 			res.keyword = strings.clone(string(fields[0]));
-			res.text = strings.clone(bytes.buffer_to_string(&buf));
-			return;
-		case .iTXt:
-			ok = true;
+			res.text    = strings.clone(string(fields[1]));
+		} else {
+			ok = false;
+		}
+		return;
+	case .zTXt:
+		ok = true;
 
 
-			s := string(c.data);
-			null := strings.index_byte(s, 0);
-			if null == -1 {
-				ok = false; return;
-			}
-			if len(c.data) < null + 4 {
-				// At a minimum, including the \0 following the keyword, we require 5 more bytes.
-				ok = false;	return;
-			}
-			res.keyword = strings.clone(string(c.data[:null]));
-			rest := c.data[null+1:];
+		fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator);
+		if len(fields) != 3 || len(fields[1]) != 0 {
+			// Compression method must be 0=Deflate, which thanks to the split above turns
+			// into an empty slice
+			ok = false; return;
+		}
 
 
-			compression_flag := rest[:1][0];
-			if compression_flag > 1 {
-				ok = false; return;
-			}
-			compression_method := rest[1:2][0];
-			if compression_flag == 1 && compression_method > 0 {
-				// Only Deflate is supported
-				ok = false; return;
-			}
-			rest = rest[2:];
+		// Set up ZLIB context and decompress text payload.
+		buf: bytes.Buffer;
+		zlib_error := zlib.inflate_from_byte_array(fields[2], &buf);
+		defer bytes.buffer_destroy(&buf);
+		if !is_kind(zlib_error, E_General.OK) {
+			ok = false; return;
+		}
 
 
-			// We now expect an optional language keyword and translated keyword, both followed by a \0
-			null = strings.index_byte(string(rest), 0);
-			if null == -1 {
-				ok = false; return;
-			}
-			res.language = strings.clone(string(rest[:null]));
-			rest = rest[null+1:];
+		res.keyword = strings.clone(string(fields[0]));
+		res.text = strings.clone(bytes.buffer_to_string(&buf));
+		return;
+	case .iTXt:
+		ok = true;
 
 
-			null = strings.index_byte(string(rest), 0);
-			if null == -1 {
-				ok = false; return;
-			}
-			res.keyword_localized = strings.clone(string(rest[:null]));
-			rest = rest[null+1:];
-			if compression_flag == 0 {
-				res.text = strings.clone(string(rest));
-			} else {
-				// Set up ZLIB context and decompress text payload.
-				buf: bytes.Buffer;
-				zlib_error := zlib.inflate_from_byte_array(&rest, &buf);
-				defer bytes.buffer_destroy(&buf);
-				if !is_kind(zlib_error, E_General.OK) {
-					
-					ok = false; return;
-				}
+		s := string(c.data);
+		null := strings.index_byte(s, 0);
+		if null == -1 {
+			ok = false; return;
+		}
+		if len(c.data) < null + 4 {
+			// At a minimum, including the \0 following the keyword, we require 5 more bytes.
+			ok = false;	return;
+		}
+		res.keyword = strings.clone(string(c.data[:null]));
+		rest := c.data[null+1:];
 
 
-				res.text = strings.clone(bytes.buffer_to_string(&buf));
-			}
-			return;
-		case:
-			// PNG text helper called with an unrecognized chunk type.
+		compression_flag := rest[:1][0];
+		if compression_flag > 1 {
+			ok = false; return;
+		}
+		compression_method := rest[1:2][0];
+		if compression_flag == 1 && compression_method > 0 {
+			// Only Deflate is supported
 			ok = false; return;
 			ok = false; return;
+		}
+		rest = rest[2:];
 
 
+		// We now expect an optional language keyword and translated keyword, both followed by a \0
+		null = strings.index_byte(string(rest), 0);
+		if null == -1 {
+			ok = false; return;
+		}
+		res.language = strings.clone(string(rest[:null]));
+		rest = rest[null+1:];
+
+		null = strings.index_byte(string(rest), 0);
+		if null == -1 {
+			ok = false; return;
+		}
+		res.keyword_localized = strings.clone(string(rest[:null]));
+		rest = rest[null+1:];
+		if compression_flag == 0 {
+			res.text = strings.clone(string(rest));
+		} else {
+			// Set up ZLIB context and decompress text payload.
+			buf: bytes.Buffer;
+			zlib_error := zlib.inflate_from_byte_array(rest, &buf);
+			defer bytes.buffer_destroy(&buf);
+			if !is_kind(zlib_error, E_General.OK) {
+
+				ok = false; return;
+			}
+
+			res.text = strings.clone(bytes.buffer_to_string(&buf));
+		}
+		return;
+	case:
+		// PNG text helper called with an unrecognized chunk type.
+		ok = false; return;
 	}
 	}
 }
 }
 
 
@@ -199,7 +199,7 @@ iccp :: proc(c: Chunk) -> (res: iCCP, ok: bool) {
 
 
 	// Set up ZLIB context and decompress iCCP payload
 	// Set up ZLIB context and decompress iCCP payload
 	buf: bytes.Buffer;
 	buf: bytes.Buffer;
-	zlib_error := zlib.inflate_from_byte_array(&fields[2], &buf);
+	zlib_error := zlib.inflate_from_byte_array(fields[2], &buf);
 	if !is_kind(zlib_error, E_General.OK) {
 	if !is_kind(zlib_error, E_General.OK) {
 		bytes.buffer_destroy(&buf);
 		bytes.buffer_destroy(&buf);
 		ok = false; return;
 		ok = false; return;
@@ -458,19 +458,14 @@ when false {
 			interlace_method   = .None,
 			interlace_method   = .None,
 		};
 		};
 
 
-		if channels == 1 {
-			ihdr.color_type = Color_Type{};
-		} else if channels == 2 {
-			ihdr.color_type = Color_Type{.Alpha};
-		} else if channels == 3 {
-			ihdr.color_type = Color_Type{.Color};
-		} else if channels == 4 {
-			ihdr.color_type = Color_Type{.Color, .Alpha};
-		} else {
-			// Unhandled
+		switch channels {
+		case 1: ihdr.color_type = Color_Type{};
+		case 2: ihdr.color_type = Color_Type{.Alpha};
+		case 3: ihdr.color_type = Color_Type{.Color};
+		case 4: ihdr.color_type = Color_Type{.Color, .Alpha};
+		case:// Unhandled
 			return E_PNG.Unknown_Color_Type;
 			return E_PNG.Unknown_Color_Type;
 		}
 		}
-
 		h := make_chunk(ihdr, .IHDR);
 		h := make_chunk(ihdr, .IHDR);
 		write_chunk(fd, h);
 		write_chunk(fd, h);
 
 
@@ -518,4 +513,4 @@ when false {
 
 
 		return E_General.OK;
 		return E_General.OK;
 	}
 	}
-}
+}

+ 362 - 361
core/image/png/png.odin

@@ -350,9 +350,9 @@ chunk_type_to_name :: proc(type: ^Chunk_Type) -> string {
 	return strings.string_from_ptr(t, 4);
 	return strings.string_from_ptr(t, 4);
 }
 }
 
 
-load_from_slice :: proc(slice: ^[]u8, options: Options = {}, allocator := context.allocator) -> (img: ^Image, err: Error) {
+load_from_slice :: proc(slice: []u8, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
 	r := bytes.Reader{};
 	r := bytes.Reader{};
-	bytes.reader_init(&r, slice^);
+	bytes.reader_init(&r, slice);
 	stream := bytes.reader_to_stream(&r);
 	stream := bytes.reader_to_stream(&r);
 
 
 	/*
 	/*
@@ -360,17 +360,17 @@ load_from_slice :: proc(slice: ^[]u8, options: Options = {}, allocator := contex
 		This way the stream reader could avoid the copy into the temp memory returned by it,
 		This way the stream reader could avoid the copy into the temp memory returned by it,
 		and instead return a slice into the original memory that's already owned by the caller.
 		and instead return a slice into the original memory that's already owned by the caller.
 	*/
 	*/
-	img, err = load_from_stream(&stream, options, allocator);
+	img, err = load_from_stream(stream, options, allocator);
 
 
 	return img, err;
 	return img, err;
 }
 }
 
 
-load_from_file :: proc(filename: string, options: Options = {}, allocator := context.allocator) -> (img: ^Image, err: Error) {
+load_from_file :: proc(filename: string, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
 	data, ok := os.read_entire_file(filename, allocator);
 	data, ok := os.read_entire_file(filename, allocator);
 	defer delete(data);
 	defer delete(data);
 
 
 	if ok {
 	if ok {
-		img, err = load_from_slice(&data, options, allocator);
+		img, err = load_from_slice(data, options, allocator);
 		return;
 		return;
 	} else {
 	} else {
 		img = new(Image);
 		img = new(Image);
@@ -378,7 +378,7 @@ load_from_file :: proc(filename: string, options: Options = {}, allocator := con
 	}
 	}
 }
 }
 
 
-load_from_stream :: proc(stream: ^io.Stream, options: Options = {}, allocator := context.allocator) -> (img: ^Image, err: Error) {
+load_from_stream :: proc(stream: io.Stream, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {
 	options := options;
 	options := options;
 	if .info in options {
 	if .info in options {
 		options |= {.return_metadata, .do_not_decompress_image};
 		options |= {.return_metadata, .do_not_decompress_image};
@@ -396,7 +396,7 @@ load_from_stream :: proc(stream: ^io.Stream, options: Options = {}, allocator :=
 	img.sidecar = nil;
 	img.sidecar = nil;
 
 
 	ctx := compress.Context{
 	ctx := compress.Context{
-		input  = stream^,
+		input = stream,
 	};
 	};
 
 
 	signature, io_error := compress.read_data(&ctx, Signature);
 	signature, io_error := compress.read_data(&ctx, Signature);
@@ -669,7 +669,7 @@ load_from_stream :: proc(stream: ^io.Stream, options: Options = {}, allocator :=
 	}
 	}
 
 
 	buf: bytes.Buffer;
 	buf: bytes.Buffer;
-	zlib_error := zlib.inflate(&idat, &buf);
+	zlib_error := zlib.inflate(idat, &buf);
 	defer bytes.buffer_destroy(&buf);
 	defer bytes.buffer_destroy(&buf);
 
 
 	if !is_kind(zlib_error, E_General.OK) {
 	if !is_kind(zlib_error, E_General.OK) {
@@ -817,8 +817,7 @@ load_from_stream :: proc(stream: ^io.Stream, options: Options = {}, allocator :=
 				}
 				}
 			}
 			}
 		} else {
 		} else {
-			// This should be impossible.
-			assert(false);
+			unreachable();
 		}
 		}
 
 
 		img.pixels = t;
 		img.pixels = t;
@@ -845,145 +844,145 @@ load_from_stream :: proc(stream: ^io.Stream, options: Options = {}, allocator :=
 		o16 := mem.slice_data_cast([]u16, t.buf[:]);
 		o16 := mem.slice_data_cast([]u16, t.buf[:]);
 
 
 		switch (raw_image_channels) {
 		switch (raw_image_channels) {
-			case 1:
-				// Gray without Alpha. Might have tRNS alpha.
-				key   := u16(0);
-				if seen_trns {
-					key = mem.slice_data_cast([]u16, trns.data)[0];
-				}
+		case 1:
+			// Gray without Alpha. Might have tRNS alpha.
+			key   := u16(0);
+			if seen_trns {
+				key = mem.slice_data_cast([]u16, trns.data)[0];
+			}
 
 
-				for len(p16) > 0 {
-					r := p16[0];
+			for len(p16) > 0 {
+				r := p16[0];
 
 
-					alpha := u16(1); // Default to full opaque
+				alpha := u16(1); // Default to full opaque
 
 
-					if seen_trns {
-						if r == key {
-							if seen_bkgd {
-								c := img.background.([3]u16);
-								r = c[0];
-							} else {
-								alpha = 0; // Keyed transparency
-							}
+				if seen_trns {
+					if r == key {
+						if seen_bkgd {
+							c := img.background.([3]u16);
+							r = c[0];
+						} else {
+							alpha = 0; // Keyed transparency
 						}
 						}
 					}
 					}
+				}
 
 
-					if premultiply {
-						o16[0] = r * alpha;
-						o16[1] = r * alpha;
-						o16[2] = r * alpha;
-					} else {
-						o16[0] = r;
-						o16[1] = r;
-						o16[2] = r;
-					}
-
-					if out_image_channels == 4 {
-						o16[3] = alpha * 65535;
-					}
-
-					p16 = p16[1:];
-					o16 = o16[out_image_channels:];
+				if premultiply {
+					o16[0] = r * alpha;
+					o16[1] = r * alpha;
+					o16[2] = r * alpha;
+				} else {
+					o16[0] = r;
+					o16[1] = r;
+					o16[2] = r;
 				}
 				}
-			case 2:
-				// Gray with alpha, we shouldn't have a tRNS chunk.
-				for len(p16) > 0 {
-					r := p16[0];
-					if premultiply {
-						alpha := p16[1];
-						c := u16(f32(r) * f32(alpha) / f32(65535));
-						o16[0] = c;
-						o16[1] = c;
-						o16[2] = c;
-					} else {
-						o16[0] = r;
-						o16[1] = r;
-						o16[2] = r;
-					}
 
 
-					if .alpha_drop_if_present not_in options {
-						o16[3] = p16[1];
-					}
+				if out_image_channels == 4 {
+					o16[3] = alpha * 65535;
+				}
 
 
-					p16 = p16[2:];
-					o16 = o16[out_image_channels:];
+				p16 = p16[1:];
+				o16 = o16[out_image_channels:];
+			}
+		case 2:
+			// Gray with alpha, we shouldn't have a tRNS chunk.
+			for len(p16) > 0 {
+				r := p16[0];
+				if premultiply {
+					alpha := p16[1];
+					c := u16(f32(r) * f32(alpha) / f32(65535));
+					o16[0] = c;
+					o16[1] = c;
+					o16[2] = c;
+				} else {
+					o16[0] = r;
+					o16[1] = r;
+					o16[2] = r;
 				}
 				}
-			case 3:
-				/*
-					Color without Alpha.
-					We may still have a tRNS chunk or `.alpha_add_if_missing`.
-				*/
 
 
-				key: []u16;
-				if seen_trns {
-					key = mem.slice_data_cast([]u16, trns.data);
+				if .alpha_drop_if_present not_in options {
+					o16[3] = p16[1];
 				}
 				}
 
 
-				for len(p16) > 0 {
-					r     := p16[0];
-					g     := p16[1];
-					b     := p16[2];
-
-					alpha := u16(1); // Default to full opaque
-
-					if seen_trns {
-						if r == key[0] && g == key[1] && b == key[2] {
-							if seen_bkgd {
-								c := img.background.([3]u16);
-								r = c[0];
-								g = c[1];
-								b = c[2];
-							} else {
-								alpha = 0; // Keyed transparency
-							}
-						}
-					}
+				p16 = p16[2:];
+				o16 = o16[out_image_channels:];
+			}
+		case 3:
+			/*
+				Color without Alpha.
+				We may still have a tRNS chunk or `.alpha_add_if_missing`.
+			*/
 
 
-					if premultiply {
-						o16[0] = r * alpha;
-						o16[1] = g * alpha;
-						o16[2] = b * alpha;
-					} else {
-						o16[0] = r;
-						o16[1] = g;
-						o16[2] = b;
-					}
+			key: []u16;
+			if seen_trns {
+				key = mem.slice_data_cast([]u16, trns.data);
+			}
+
+			for len(p16) > 0 {
+				r     := p16[0];
+				g     := p16[1];
+				b     := p16[2];
 
 
-					if out_image_channels == 4 {
-						o16[3] = alpha * 65535;
+				alpha := u16(1); // Default to full opaque
+
+				if seen_trns {
+					if r == key[0] && g == key[1] && b == key[2] {
+						if seen_bkgd {
+							c := img.background.([3]u16);
+							r = c[0];
+							g = c[1];
+							b = c[2];
+						} else {
+							alpha = 0; // Keyed transparency
+						}
 					}
 					}
+				}
 
 
-					p16 = p16[3:];
-					o16 = o16[out_image_channels:];
+				if premultiply {
+					o16[0] = r * alpha;
+					o16[1] = g * alpha;
+					o16[2] = b * alpha;
+				} else {
+					o16[0] = r;
+					o16[1] = g;
+					o16[2] = b;
 				}
 				}
-			case 4:
-				// Color with Alpha, can't have tRNS.
-				for len(p16) > 0 {
-					r     := p16[0];
-					g     := p16[1];
-					b     := p16[2];
-					a     := p16[3];
 
 
-					if premultiply {
-						alpha := f32(a) / 65535.0;
-						o16[0] = u16(f32(r) * alpha);
-						o16[1] = u16(f32(g) * alpha);
-						o16[2] = u16(f32(b) * alpha);
-					} else {
-						o16[0] = r;
-						o16[1] = g;
-						o16[2] = b;
-					}
+				if out_image_channels == 4 {
+					o16[3] = alpha * 65535;
+				}
 
 
-					if .alpha_drop_if_present not_in options {
-						o16[3] = a;
-					}
+				p16 = p16[3:];
+				o16 = o16[out_image_channels:];
+			}
+		case 4:
+			// Color with Alpha, can't have tRNS.
+			for len(p16) > 0 {
+				r     := p16[0];
+				g     := p16[1];
+				b     := p16[2];
+				a     := p16[3];
+
+				if premultiply {
+					alpha := f32(a) / 65535.0;
+					o16[0] = u16(f32(r) * alpha);
+					o16[1] = u16(f32(g) * alpha);
+					o16[2] = u16(f32(b) * alpha);
+				} else {
+					o16[0] = r;
+					o16[1] = g;
+					o16[2] = b;
+				}
 
 
-					p16 = p16[4:];
-					o16 = o16[out_image_channels:];
+				if .alpha_drop_if_present not_in options {
+					o16[3] = a;
 				}
 				}
-			case:
-				unreachable("We should never seen # channels other than 1-4 inclusive.");
+
+				p16 = p16[4:];
+				o16 = o16[out_image_channels:];
+			}
+		case:
+			unreachable("We should never seen # channels other than 1-4 inclusive.");
 		}
 		}
 
 
 		img.pixels = t;
 		img.pixels = t;
@@ -1011,143 +1010,143 @@ load_from_stream :: proc(stream: ^io.Stream, options: Options = {}, allocator :=
 		o := mem.slice_data_cast([]u8, t.buf[:]);
 		o := mem.slice_data_cast([]u8, t.buf[:]);
 
 
 		switch (raw_image_channels) {
 		switch (raw_image_channels) {
-			case 1:
-				// Gray without Alpha. Might have tRNS alpha.
-				key   := u8(0);
-				if seen_trns {
-					key = u8(mem.slice_data_cast([]u16be, trns.data)[0]);
-				}
+		case 1:
+			// Gray without Alpha. Might have tRNS alpha.
+			key   := u8(0);
+			if seen_trns {
+				key = u8(mem.slice_data_cast([]u16be, trns.data)[0]);
+			}
 
 
-				for len(p) > 0 {
-					r := p[0];
-					alpha := u8(1);
-
-					if seen_trns {
-						if r == key {
-							if seen_bkgd {
-								c := img.background.([3]u16);
-								r = u8(c[0]);
-							} else {
-								alpha = 0; // Keyed transparency
-							}
-						}
-						if premultiply {
-							o[0] = r * alpha;
-							o[1] = r * alpha;
-							o[2] = r * alpha;
+			for len(p) > 0 {
+				r := p[0];
+				alpha := u8(1);
+
+				if seen_trns {
+					if r == key {
+						if seen_bkgd {
+							c := img.background.([3]u16);
+							r = u8(c[0]);
+						} else {
+							alpha = 0; // Keyed transparency
 						}
 						}
-					} else {
-						o[0] = r;
-						o[1] = r;
-						o[2] = r;
 					}
 					}
-
-					if out_image_channels == 4 {
-						o[3] = alpha * 255;
+					if premultiply {
+						o[0] = r * alpha;
+						o[1] = r * alpha;
+						o[2] = r * alpha;
 					}
 					}
-
-					p = p[1:];
-					o = o[out_image_channels:];
+				} else {
+					o[0] = r;
+					o[1] = r;
+					o[2] = r;
 				}
 				}
-			case 2:
-				// Gray with alpha, we shouldn't have a tRNS chunk.
-				for len(p) > 0 {
-					r := p[0];
-					if .alpha_premultiply in options {
-						alpha := p[1];
-						c := u8(f32(r) * f32(alpha) / f32(255));
-						o[0] = c;
-						o[1] = c;
-						o[2] = c;
-					} else {
-						o[0] = r;
-						o[1] = r;
-						o[2] = r;
-					}
 
 
-					if .alpha_drop_if_present not_in options {
-						o[3] = p[1];
-					}
+				if out_image_channels == 4 {
+					o[3] = alpha * 255;
+				}
 
 
-					p = p[2:];
-					o = o[out_image_channels:];
+				p = p[1:];
+				o = o[out_image_channels:];
+			}
+		case 2:
+			// Gray with alpha, we shouldn't have a tRNS chunk.
+			for len(p) > 0 {
+				r := p[0];
+				if .alpha_premultiply in options {
+					alpha := p[1];
+					c := u8(f32(r) * f32(alpha) / f32(255));
+					o[0] = c;
+					o[1] = c;
+					o[2] = c;
+				} else {
+					o[0] = r;
+					o[1] = r;
+					o[2] = r;
 				}
 				}
-			case 3:
-				// Color without Alpha. We may still have a tRNS chunk
-				key: []u8;
-				if seen_trns {
-					/*
-						For 8-bit images, the tRNS chunk still contains a triple in u16be.
-						We use only the low byte in this case.
-					*/
-					key = []u8{trns.data[1], trns.data[3], trns.data[5]};
+
+				if .alpha_drop_if_present not_in options {
+					o[3] = p[1];
 				}
 				}
-				for len(p) > 0 {
-					r     := p[0];
-					g     := p[1];
-					b     := p[2];
-
-					alpha := u8(1); // Default to full opaque
-
-					// TODO: Combine the seen_trns cases.
-					if seen_trns {
-						if r == key[0] && g == key[1] && b == key[2] {
-							if seen_bkgd {
-								c := img.background.([3]u16);
-								r = u8(c[0]);
-								g = u8(c[1]);
-								b = u8(c[2]);
-							} else {
-								alpha = 0; // Keyed transparency
-							}
-						}
 
 
-						if .alpha_premultiply in options || .blend_background in options {
-							o[0] = r * alpha;
-							o[1] = g * alpha;
-							o[2] = b * alpha;
+				p = p[2:];
+				o = o[out_image_channels:];
+			}
+		case 3:
+			// Color without Alpha. We may still have a tRNS chunk
+			key: []u8;
+			if seen_trns {
+				/*
+					For 8-bit images, the tRNS chunk still contains a triple in u16be.
+					We use only the low byte in this case.
+				*/
+				key = []u8{trns.data[1], trns.data[3], trns.data[5]};
+			}
+			for len(p) > 0 {
+				r     := p[0];
+				g     := p[1];
+				b     := p[2];
+
+				alpha := u8(1); // Default to full opaque
+
+				// TODO: Combine the seen_trns cases.
+				if seen_trns {
+					if r == key[0] && g == key[1] && b == key[2] {
+						if seen_bkgd {
+							c := img.background.([3]u16);
+							r = u8(c[0]);
+							g = u8(c[1]);
+							b = u8(c[2]);
+						} else {
+							alpha = 0; // Keyed transparency
 						}
 						}
-					} else {
-						o[0] = r;
-						o[1] = g;
-						o[2] = b;
 					}
 					}
 
 
-					if out_image_channels == 4 {
-						o[3] = alpha * 255;
+					if .alpha_premultiply in options || .blend_background in options {
+						o[0] = r * alpha;
+						o[1] = g * alpha;
+						o[2] = b * alpha;
 					}
 					}
+				} else {
+					o[0] = r;
+					o[1] = g;
+					o[2] = b;
+				}
 
 
-					p = p[3:];
-					o = o[out_image_channels:];
+				if out_image_channels == 4 {
+					o[3] = alpha * 255;
 				}
 				}
-			case 4:
-				// Color with Alpha, can't have tRNS.
-				for len(p) > 0 {
-					r     := p[0];
-					g     := p[1];
-					b     := p[2];
-					a     := p[3];
-
-					if .alpha_premultiply in options {
-						alpha := f32(a) / 255.0;
-						o[0] = u8(f32(r) * alpha);
-						o[1] = u8(f32(g) * alpha);
-						o[2] = u8(f32(b) * alpha);
-					} else {
-						o[0] = r;
-						o[1] = g;
-						o[2] = b;
-					}
 
 
-					if .alpha_drop_if_present not_in options {
-						o[3] = a;
-					}
+				p = p[3:];
+				o = o[out_image_channels:];
+			}
+		case 4:
+			// Color with Alpha, can't have tRNS.
+			for len(p) > 0 {
+				r     := p[0];
+				g     := p[1];
+				b     := p[2];
+				a     := p[3];
+
+				if .alpha_premultiply in options {
+					alpha := f32(a) / 255.0;
+					o[0] = u8(f32(r) * alpha);
+					o[1] = u8(f32(g) * alpha);
+					o[2] = u8(f32(b) * alpha);
+				} else {
+					o[0] = r;
+					o[1] = g;
+					o[2] = b;
+				}
 
 
-					p = p[4:];
-					o = o[out_image_channels:];
+				if .alpha_drop_if_present not_in options {
+					o[3] = a;
 				}
 				}
-			case:
-				unreachable("We should never seen # channels other than 1-4 inclusive.");
+
+				p = p[4:];
+				o = o[out_image_channels:];
+			}
+		case:
+			unreachable("We should never seen # channels other than 1-4 inclusive.");
 		}
 		}
 
 
 		img.pixels = t;
 		img.pixels = t;
@@ -1181,13 +1180,13 @@ filter_paeth :: #force_inline proc(left, up, up_left: u8) -> u8 {
 }
 }
 
 
 Filter_Params :: struct #packed {
 Filter_Params :: struct #packed {
-	src     : []u8,
-	dest    : []u8,
-	width   : int,
-	height  : int,
-	depth   : int,
+	src:      []u8,
+	dest:     []u8,
+	width:    int,
+	height:   int,
+	depth:    int,
 	channels: int,
 	channels: int,
-	rescale : bool,
+	rescale:  bool,
 }
 }
 
 
 depth_scale_table :: []u8{0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01};
 depth_scale_table :: []u8{0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01};
@@ -1210,39 +1209,39 @@ defilter_8 :: proc(params: ^Filter_Params) -> (ok: bool) {
 		filter := Row_Filter(src[0]); src = src[1:];
 		filter := Row_Filter(src[0]); src = src[1:];
 		// fmt.printf("Row: %v | Filter: %v\n", y, filter);
 		// fmt.printf("Row: %v | Filter: %v\n", y, filter);
 		switch(filter) {
 		switch(filter) {
-			case .None:
-				copy(dest, src[:row_stride]);
-			case .Sub:
-				for i := 0; i < channels; i += 1 {
-					dest[i] = src[i];
-				}
-				for k := 0; k < nk; k += 1 {
-					dest[channels+k] = (src[channels+k] + dest[k]) & 255;
-				}
-			case .Up:
-				for k := 0; k < row_stride; k += 1 {
-					dest[k] = (src[k] + up[k]) & 255;
-				}
-			case .Average:
-				for i := 0; i < channels; i += 1 {
-					avg := up[i] >> 1;
-					dest[i] = (src[i] + avg) & 255;
-				}
-				for k := 0; k < nk; k += 1 {
-					avg := u8((u16(up[channels+k]) + u16(dest[k])) >> 1);
-					dest[channels+k] = (src[channels+k] + avg) & 255;
-				}
-			case .Paeth:
-				for i := 0; i < channels; i += 1 {
-					paeth := filter_paeth(0, up[i], 0);
-					dest[i] = (src[i] + paeth) & 255;
-				}
-				for k := 0; k < nk; k += 1 {
-					paeth := filter_paeth(dest[k], up[channels+k], up[k]);
-					dest[channels+k] = (src[channels+k] + paeth) & 255;
-				}
-			case:
-				return false;
+		case .None:
+			copy(dest, src[:row_stride]);
+		case .Sub:
+			for i := 0; i < channels; i += 1 {
+				dest[i] = src[i];
+			}
+			for k := 0; k < nk; k += 1 {
+				dest[channels+k] = (src[channels+k] + dest[k]) & 255;
+			}
+		case .Up:
+			for k := 0; k < row_stride; k += 1 {
+				dest[k] = (src[k] + up[k]) & 255;
+			}
+		case .Average:
+			for i := 0; i < channels; i += 1 {
+				avg := up[i] >> 1;
+				dest[i] = (src[i] + avg) & 255;
+			}
+			for k := 0; k < nk; k += 1 {
+				avg := u8((u16(up[channels+k]) + u16(dest[k])) >> 1);
+				dest[channels+k] = (src[channels+k] + avg) & 255;
+			}
+		case .Paeth:
+			for i := 0; i < channels; i += 1 {
+				paeth := filter_paeth(0, up[i], 0);
+				dest[i] = (src[i] + paeth) & 255;
+			}
+			for k := 0; k < nk; k += 1 {
+				paeth := filter_paeth(dest[k], up[channels+k], up[k]);
+				dest[channels+k] = (src[channels+k] + paeth) & 255;
+			}
+		case:
+			return false;
 		}
 		}
 
 
 		src     = src[row_stride:];
 		src     = src[row_stride:];
@@ -1277,45 +1276,45 @@ defilter_less_than_8 :: proc(params: ^Filter_Params) -> (ok: bool) #no_bounds_ch
 		dest = dest[row_offset:];
 		dest = dest[row_offset:];
 
 
 		filter := Row_Filter(src[0]); src = src[1:];
 		filter := Row_Filter(src[0]); src = src[1:];
-		switch(filter) {
-			case .None:
-				copy(dest, src[:row_stride_in]);
-			case .Sub:
-				for i in 0..channels {
-					dest[i] = src[i];
-				}
-				for k in 0..nk {
-					dest[channels+k] = (src[channels+k] + dest[k]) & 255;
-				}
-			case .Up:
-				for k in 0..row_stride_in {
-					dest[k] = (src[k] + up[k]) & 255;
-				}
-			case .Average:
-				for i in 0..channels {
-					avg := up[i] >> 1;
-					dest[i] = (src[i] + avg) & 255;
-				}
-				for k in 0..nk {
-					avg := u8((u16(up[channels+k]) + u16(dest[k])) >> 1);
-					dest[channels+k] = (src[channels+k] + avg) & 255;
-				}
-			case .Paeth:
-				for i in 0..channels {
-					paeth := filter_paeth(0, up[i], 0);
-					dest[i] = (src[i] + paeth) & 255;
-				}
-				for k in 0..nk {
-					paeth := filter_paeth(dest[k], up[channels], up[k]);
-					dest[channels+k] = (src[channels+k] + paeth) & 255;
-				}
-			case:
-				return false;
+		switch filter {
+		case .None:
+			copy(dest, src[:row_stride_in]);
+		case .Sub:
+			for i in 0..channels {
+				dest[i] = src[i];
+			}
+			for k in 0..nk {
+				dest[channels+k] = (src[channels+k] + dest[k]) & 255;
+			}
+		case .Up:
+			for k in 0..row_stride_in {
+				dest[k] = (src[k] + up[k]) & 255;
+			}
+		case .Average:
+			for i in 0..channels {
+				avg := up[i] >> 1;
+				dest[i] = (src[i] + avg) & 255;
+			}
+			for k in 0..nk {
+				avg := u8((u16(up[channels+k]) + u16(dest[k])) >> 1);
+				dest[channels+k] = (src[channels+k] + avg) & 255;
+			}
+		case .Paeth:
+			for i in 0..channels {
+				paeth := filter_paeth(0, up[i], 0);
+				dest[i] = (src[i] + paeth) & 255;
+			}
+			for k in 0..nk {
+				paeth := filter_paeth(dest[k], up[channels], up[k]);
+				dest[channels+k] = (src[channels+k] + paeth) & 255;
+			}
+		case:
+			return false;
 		}
 		}
 
 
-		src     = src [row_stride_in:];
-		up      = dest;
-		dest    = dest[row_stride_in:];
+		src   = src [row_stride_in:];
+		up    = dest;
+		dest  = dest[row_stride_in:];
 	}
 	}
 
 
 	// Let's expand the bits
 	// Let's expand the bits
@@ -1334,7 +1333,8 @@ defilter_less_than_8 :: proc(params: ^Filter_Params) -> (ok: bool) #no_bounds_ch
 	for j := 0; j < height; j += 1 {
 	for j := 0; j < height; j += 1 {
 		src = dest[row_offset:];
 		src = dest[row_offset:];
 
 
-		if depth == 4 {
+		switch depth {
+		case 4:
 			k := row_stride_out;
 			k := row_stride_out;
 			for ; k >= 2; k -= 2 {
 			for ; k >= 2; k -= 2 {
 				c := src[0];
 				c := src[0];
@@ -1347,7 +1347,7 @@ defilter_less_than_8 :: proc(params: ^Filter_Params) -> (ok: bool) #no_bounds_ch
 				dest[0] = scale * (c >> 4);
 				dest[0] = scale * (c >> 4);
 				dest = dest[1:];
 				dest = dest[1:];
 			}
 			}
-		} else if depth == 2 {
+		case 2:
 			k := row_stride_out;
 			k := row_stride_out;
 			for ; k >= 4; k -= 4 {
 			for ; k >= 4; k -= 4 {
 				c := src[0];
 				c := src[0];
@@ -1368,7 +1368,7 @@ defilter_less_than_8 :: proc(params: ^Filter_Params) -> (ok: bool) #no_bounds_ch
 				}
 				}
 				dest = dest[k:];
 				dest = dest[k:];
 			}
 			}
-		} else if depth == 1 {
+		case 1:
 			k := row_stride_out;
 			k := row_stride_out;
 			for ; k >= 8; k -= 8 {
 			for ; k >= 8; k -= 8 {
 				c := src[0];
 				c := src[0];
@@ -1406,6 +1406,7 @@ defilter_less_than_8 :: proc(params: ^Filter_Params) -> (ok: bool) #no_bounds_ch
 				dest = dest[k:];
 				dest = dest[k:];
 
 
 			}
 			}
+
 		}
 		}
 	}
 	}
 
 
@@ -1429,40 +1430,40 @@ defilter_16 :: proc(params: ^Filter_Params) -> (ok: bool) {
 		nk := row_stride - stride;
 		nk := row_stride - stride;
 
 
 		filter := Row_Filter(src[0]); src = src[1:];
 		filter := Row_Filter(src[0]); src = src[1:];
-		switch(filter) {
-			case .None:
-				copy(dest, src[:row_stride]);
-			case .Sub:
-				for i := 0; i < stride; i += 1 {
-					dest[i] = src[i];
-				}
-				for k := 0; k < nk; k += 1 {
-					dest[stride+k] = (src[stride+k] + dest[k]) & 255;
-				}
-			case .Up:
-				for k := 0; k < row_stride; k += 1 {
-					dest[k] = (src[k] + up[k]) & 255;
-				}
-			case .Average:
-				for i := 0; i < stride; i += 1 {
-					avg := up[i] >> 1;
-					dest[i] = (src[i] + avg) & 255;
-				}
-				for k := 0; k < nk; k += 1 {
-					avg := u8((u16(up[stride+k]) + u16(dest[k])) >> 1);
-					dest[stride+k] = (src[stride+k] + avg) & 255;
-				}
-			case .Paeth:
-				for i := 0; i < stride; i += 1 {
-					paeth := filter_paeth(0, up[i], 0);
-					dest[i] = (src[i] + paeth) & 255;
-				}
-				for k := 0; k < nk; k += 1 {
-					paeth := filter_paeth(dest[k], up[stride+k], up[k]);
-					dest[stride+k] = (src[stride+k] + paeth) & 255;
-				}
-			case:
-				return false;
+		switch filter {
+		case .None:
+			copy(dest, src[:row_stride]);
+		case .Sub:
+			for i := 0; i < stride; i += 1 {
+				dest[i] = src[i];
+			}
+			for k := 0; k < nk; k += 1 {
+				dest[stride+k] = (src[stride+k] + dest[k]) & 255;
+			}
+		case .Up:
+			for k := 0; k < row_stride; k += 1 {
+				dest[k] = (src[k] + up[k]) & 255;
+			}
+		case .Average:
+			for i := 0; i < stride; i += 1 {
+				avg := up[i] >> 1;
+				dest[i] = (src[i] + avg) & 255;
+			}
+			for k := 0; k < nk; k += 1 {
+				avg := u8((u16(up[stride+k]) + u16(dest[k])) >> 1);
+				dest[stride+k] = (src[stride+k] + avg) & 255;
+			}
+		case .Paeth:
+			for i := 0; i < stride; i += 1 {
+				paeth := filter_paeth(0, up[i], 0);
+				dest[i] = (src[i] + paeth) & 255;
+			}
+			for k := 0; k < nk; k += 1 {
+				paeth := filter_paeth(dest[k], up[stride+k], up[k]);
+				dest[stride+k] = (src[stride+k] + paeth) & 255;
+			}
+		case:
+			return false;
 		}
 		}
 
 
 		src     = src[row_stride:];
 		src     = src[row_stride:];
@@ -1510,7 +1511,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^IHDR, option
 		if !filter_ok {
 		if !filter_ok {
 			// Caller will destroy buffer for us.
 			// Caller will destroy buffer for us.
 			return E_PNG.Unknown_Filter_Method;
 			return E_PNG.Unknown_Filter_Method;
-		}		
+		}
 	} else {
 	} else {
 		/*
 		/*
 			For deinterlacing we need to make a temporary buffer, defiilter part of the image,
 			For deinterlacing we need to make a temporary buffer, defiilter part of the image,
@@ -1582,7 +1583,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^IHDR, option
 		}
 		}
 	}
 	}
 
 
-	return E_General.OK; 
+	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};