Utilize union #shared_nil to core:image Error

This commit is contained in:
gingerBill
2022-03-24 12:06:18 +00:00
parent b6b3377786
commit 17e36bd5e1
4 changed files with 39 additions and 33 deletions
+6 -1
View File
@@ -47,7 +47,7 @@ when size_of(uintptr) == 8 {
} }
Error :: union { Error :: union #shared_nil {
General_Error, General_Error,
Deflate_Error, Deflate_Error,
ZLIB_Error, ZLIB_Error,
@@ -58,6 +58,7 @@ Error :: union {
} }
General_Error :: enum { General_Error :: enum {
None = 0,
File_Not_Found, File_Not_Found,
Cannot_Open_File, Cannot_Open_File,
File_Too_Short, File_Too_Short,
@@ -76,6 +77,7 @@ General_Error :: enum {
} }
GZIP_Error :: enum { GZIP_Error :: enum {
None = 0,
Invalid_GZIP_Signature, Invalid_GZIP_Signature,
Reserved_Flag_Set, Reserved_Flag_Set,
Invalid_Extra_Data, Invalid_Extra_Data,
@@ -100,6 +102,7 @@ GZIP_Error :: enum {
} }
ZIP_Error :: enum { ZIP_Error :: enum {
None = 0,
Invalid_ZIP_File_Signature, Invalid_ZIP_File_Signature,
Unexpected_Signature, Unexpected_Signature,
Insert_Next_Disk, Insert_Next_Disk,
@@ -107,6 +110,7 @@ ZIP_Error :: enum {
} }
ZLIB_Error :: enum { ZLIB_Error :: enum {
None = 0,
Unsupported_Window_Size, Unsupported_Window_Size,
FDICT_Unsupported, FDICT_Unsupported,
Unsupported_Compression_Level, Unsupported_Compression_Level,
@@ -114,6 +118,7 @@ ZLIB_Error :: enum {
} }
Deflate_Error :: enum { Deflate_Error :: enum {
None = 0,
Huffman_Bad_Sizes, Huffman_Bad_Sizes,
Huffman_Bad_Code_Lengths, Huffman_Bad_Code_Lengths,
Inflate_Error, Inflate_Error,
+28 -28
View File
@@ -48,9 +48,9 @@ Options :: struct {
} }
Error :: compress.Error Error :: compress.Error
E_General :: compress.General_Error General_Error :: compress.General_Error
E_ZLIB :: compress.ZLIB_Error ZLIB_Error :: compress.ZLIB_Error
E_Deflate :: compress.Deflate_Error Deflate_Error :: compress.Deflate_Error
DEFLATE_MAX_CHUNK_SIZE :: 65535 DEFLATE_MAX_CHUNK_SIZE :: 65535
DEFLATE_MAX_LITERAL_SIZE :: 65535 DEFLATE_MAX_LITERAL_SIZE :: 65535
@@ -258,7 +258,7 @@ build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) {
for i in 1 ..< HUFFMAN_MAX_BITS { for i in 1 ..< HUFFMAN_MAX_BITS {
if sizes[i] > (1 << uint(i)) { if sizes[i] > (1 << uint(i)) {
return E_Deflate.Huffman_Bad_Sizes return .Huffman_Bad_Sizes
} }
} }
code := int(0) code := int(0)
@@ -270,7 +270,7 @@ build_huffman :: proc(z: ^Huffman_Table, code_lengths: []u8) -> (err: Error) {
code = code + sizes[i] code = code + sizes[i]
if sizes[i] != 0 { if sizes[i] != 0 {
if code - 1 >= (1 << u16(i)) { if code - 1 >= (1 << u16(i)) {
return E_Deflate.Huffman_Bad_Code_Lengths return .Huffman_Bad_Code_Lengths
} }
} }
z.maxcode[i] = code << (HUFFMAN_MAX_BITS - uint(i)) z.maxcode[i] = code << (HUFFMAN_MAX_BITS - uint(i))
@@ -314,15 +314,15 @@ decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Erro
s += 1 s += 1
} }
if s >= 16 { if s >= 16 {
return 0, E_Deflate.Bad_Huffman_Code return 0, .Bad_Huffman_Code
} }
// code size is s, so: // 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) { if b >= size_of(t.size) {
return 0, E_Deflate.Bad_Huffman_Code return 0, .Bad_Huffman_Code
} }
if t.size[b] != s { if t.size[b] != s {
return 0, E_Deflate.Bad_Huffman_Code return 0, .Bad_Huffman_Code
} }
compress.consume_bits_lsb(z, s) compress.consume_bits_lsb(z, s)
@@ -335,11 +335,11 @@ decode_huffman_slowpath :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Erro
decode_huffman :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check { decode_huffman :: proc(z: ^$C, t: ^Huffman_Table) -> (r: u16, err: Error) #no_bounds_check {
if z.num_bits < 16 { if z.num_bits < 16 {
if z.num_bits > 63 { if z.num_bits > 63 {
return 0, E_ZLIB.Code_Buffer_Malformed return 0, .Code_Buffer_Malformed
} }
compress.refill_lsb(z) compress.refill_lsb(z)
if z.num_bits > 63 { if z.num_bits > 63 {
return 0, E_General.Stream_Too_Short return 0, .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]
@@ -361,7 +361,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
if value < 256 { if value < 256 {
e := write_byte(z, u8(value)) e := write_byte(z, u8(value))
if e != .None { if e != .None {
return E_General.Output_Too_Short return .Output_Too_Short
} }
} else { } else {
if value == 256 { if value == 256 {
@@ -377,7 +377,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
value, e = decode_huffman(z, z_offset) value, e = decode_huffman(z, z_offset)
if e != nil { if e != nil {
return E_Deflate.Bad_Huffman_Code return .Bad_Huffman_Code
} }
distance := Z_DIST_BASE[value] distance := Z_DIST_BASE[value]
@@ -387,7 +387,7 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
if z.bytes_written < i64(distance) { if z.bytes_written < i64(distance) {
// Distance is longer than we've decoded so far. // Distance is longer than we've decoded so far.
return E_Deflate.Bad_Distance return .Bad_Distance
} }
/* /*
@@ -405,14 +405,14 @@ parse_huffman_block :: proc(z: ^$C, z_repeat, z_offset: ^Huffman_Table) -> (err:
c := z.output.buf[z.bytes_written - i64(distance)] c := z.output.buf[z.bytes_written - i64(distance)]
e := repl_byte(z, length, c) e := repl_byte(z, length, c)
if e != .None { if e != .None {
return E_General.Output_Too_Short return .Output_Too_Short
} }
} }
} else { } else {
if length > 0 { if length > 0 {
e := repl_bytes(z, length, distance) e := repl_bytes(z, length, distance)
if e != .None { if e != .None {
return E_General.Output_Too_Short return .Output_Too_Short
} }
} }
} }
@@ -432,25 +432,25 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
if !raw { if !raw {
size, size_err := compress.input_size(ctx) size, size_err := compress.input_size(ctx)
if size < 6 || size_err != nil { if size < 6 || size_err != nil {
return E_General.Stream_Too_Short return .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 { if method != .DEFLATE {
return E_General.Unknown_Compression_Method return .Unknown_Compression_Method
} }
if cinfo := (cmf >> 4) & 0xf; cinfo > 7 { if cinfo := (cmf >> 4) & 0xf; cinfo > 7 {
return E_ZLIB.Unsupported_Window_Size return .Unsupported_Window_Size
} }
flg, _ := compress.read_u8(ctx) flg, _ := compress.read_u8(ctx)
fcheck := flg & 0x1f fcheck := flg & 0x1f
fcheck_computed := (cmf << 8 | flg) & 0x1f fcheck_computed := (cmf << 8 | flg) & 0x1f
if fcheck != fcheck_computed { if fcheck != fcheck_computed {
return E_General.Checksum_Failed return .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. They're application specific and PNG doesn't use them.
*/ */
if fdict := (flg >> 5) & 1; fdict != 0 { if fdict := (flg >> 5) & 1; fdict != 0 {
return E_ZLIB.FDICT_Unsupported return .FDICT_Unsupported
} }
// flevel := Compression_Level((flg >> 6) & 3); // flevel := Compression_Level((flg >> 6) & 3);
@@ -485,7 +485,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
output_hash := hash.adler32(ctx.output.buf[:]) output_hash := hash.adler32(ctx.output.buf[:])
if output_hash != u32(adler) { if output_hash != u32(adler) {
return E_General.Checksum_Failed return .Checksum_Failed
} }
} }
return nil return nil
@@ -555,7 +555,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
if ~uncompressed_len != length_check { if ~uncompressed_len != length_check {
return E_Deflate.Len_Nlen_Mismatch return .Len_Nlen_Mismatch
} }
/* /*
@@ -571,7 +571,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
assert(uncompressed_len == 0) assert(uncompressed_len == 0)
case 3: case 3:
return E_Deflate.BType_3 return .BType_3
case: case:
// fmt.printf("Err: %v | Final: %v | Type: %v\n", err, final, type) // fmt.printf("Err: %v | Final: %v | Type: %v\n", err, final, type)
if type == 1 { if type == 1 {
@@ -604,7 +604,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
c = decode_huffman(z, codelength_ht) or_return c = decode_huffman(z, codelength_ht) or_return
if c < 0 || c >= 19 { if c < 0 || c >= 19 {
return E_Deflate.Huffman_Bad_Code_Lengths return .Huffman_Bad_Code_Lengths
} }
if c < 16 { if c < 16 {
lencodes[n] = u8(c) lencodes[n] = u8(c)
@@ -616,7 +616,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
case 16: 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 { if n == 0 {
return E_Deflate.Huffman_Bad_Code_Lengths return .Huffman_Bad_Code_Lengths
} }
fill = lencodes[n - 1] fill = lencodes[n - 1]
case 17: case 17:
@@ -624,11 +624,11 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
case 18: 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: case:
return E_Deflate.Huffman_Bad_Code_Lengths return .Huffman_Bad_Code_Lengths
} }
if ntot - n < u32(c) { if ntot - n < u32(c) {
return E_Deflate.Huffman_Bad_Code_Lengths return .Huffman_Bad_Code_Lengths
} }
nc := n + u32(c) nc := n + u32(c)
@@ -639,7 +639,7 @@ inflate_raw :: proc(z: ^$C, expected_output_size := -1, allocator := context.all
} }
if n != ntot { if n != ntot {
return E_Deflate.Huffman_Bad_Code_Lengths return .Huffman_Bad_Code_Lengths
} }
build_huffman(z_repeat, lencodes[:hlit]) or_return build_huffman(z_repeat, lencodes[:hlit]) or_return
+2 -1
View File
@@ -118,7 +118,7 @@ Option :: enum {
} }
Options :: distinct bit_set[Option] Options :: distinct bit_set[Option]
Error :: union { Error :: union #shared_nil {
General_Image_Error, General_Image_Error,
PNG_Error, PNG_Error,
@@ -137,6 +137,7 @@ General_Image_Error :: enum {
} }
PNG_Error :: enum { PNG_Error :: enum {
None = 0,
Invalid_PNG_Signature, Invalid_PNG_Signature,
IHDR_Not_First_Chunk, IHDR_Not_First_Chunk,
IHDR_Corrupt, IHDR_Corrupt,
+3 -3
View File
@@ -439,7 +439,7 @@ when false {
flags: int = O_WRONLY|O_CREATE|O_TRUNC flags: int = O_WRONLY|O_CREATE|O_TRUNC
if len(image.pixels) == 0 || len(image.pixels) < image.width * image.height * int(image.channels) { if len(image.pixels) == 0 || len(image.pixels) < image.width * image.height * int(image.channels) {
return E_PNG.Invalid_Image_Dimensions return .Invalid_Image_Dimensions
} }
mode: int = 0 mode: int = 0
@@ -450,7 +450,7 @@ when false {
fd, fderr := open(filename, flags, mode) fd, fderr := open(filename, flags, mode)
if fderr != 0 { if fderr != 0 {
return E_General.Cannot_Open_File return .Cannot_Open_File
} }
defer close(fd) defer close(fd)
@@ -473,7 +473,7 @@ when false {
case 3: ihdr.color_type = Color_Type{.Color} case 3: ihdr.color_type = Color_Type{.Color}
case 4: ihdr.color_type = Color_Type{.Color, .Alpha} case 4: ihdr.color_type = Color_Type{.Color, .Alpha}
case:// Unhandled case:// Unhandled
return E_PNG.Unknown_Color_Type return .Unknown_Color_Type
} }
h := make_chunk(ihdr, .IHDR) h := make_chunk(ihdr, .IHDR)
write_chunk(fd, h) write_chunk(fd, h)