mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Utilize union #shared_nil to core:image Error
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user