diff --git a/core/bytes/util.odin b/core/bytes/util.odin deleted file mode 100644 index a93e3e479..000000000 --- a/core/bytes/util.odin +++ /dev/null @@ -1,187 +0,0 @@ -package bytes - -/* - Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-2 license. - - List of contributors: - Jeroen van Rijn: Initial implementation. - - `bytes.Buffer` type conversion helpers. -*/ - -import "core:intrinsics" -import "core:mem" - -need_endian_conversion :: proc($FT: typeid, $TT: typeid) -> (res: bool) { - - // true if platform endian - f: bool; - t: bool; - - when ODIN_ENDIAN == "little" { - f = intrinsics.type_is_endian_platform(FT) || intrinsics.type_is_endian_little(FT); - t = intrinsics.type_is_endian_platform(TT) || intrinsics.type_is_endian_little(TT); - - return f != t; - } else { - f = intrinsics.type_is_endian_platform(FT) || intrinsics.type_is_endian_big(FT); - t = intrinsics.type_is_endian_platform(TT) || intrinsics.type_is_endian_big(TT); - - return f != t; - } - - return; -} - -/* - Input: - count: number of elements - $TT: destination type - $FT: source type - from_buffer: buffer to convert - force_convert: cast each element separately - - Output: - res: Converted/created buffer of []TT. - backing: ^bytes.Buffer{} backing the converted data. - alloc: Buffer was freshly allocated because we couldn't convert in-place. Points to `from_buffer` if `false`. - err: True if we passed too few elements or allocation failed, etc. - - If `from_buffer` is empty, the input type $FT is ignored and `create_buffer_of_type` is called to create a fresh buffer. - - This helper will try to do as little work as possible, so if you're converting between two equally sized types, - and they have compatible endianness, the contents will simply be reinterpreted using `slice_data_cast`. - - If you want each element to be converted in this case, set `force_convert` to `true`. - - For example, converting `[]u8{0, 60}` from `[]f16` to `[]u16` will return `[15360]` when simply reinterpreted, - and `[1]` if force converted. - - Should you for example want to promote `[]f16` to `[]f32` (or truncate `[]f32` to `[]f16`), the size of these elements - being different will result in a conversion anyway, so this flag is unnecessary in cases like these. - - Example: - fmt.println("Convert []f16le (x2) to []f32 (x2)."); - b := []u8{0, 60, 0, 60}; // == []f16{1.0, 1.0} - - res, backing, had_to_allocate, err := bytes.buffer_convert_to_type(2, f32, f16le, b); - fmt.printf("res : %v\n", res); // [1.000, 1.000] - fmt.printf("backing : %v\n", backing); // &Buffer{buf = [0, 0, 128, 63, 0, 0, 128, 63], off = 0, last_read = Invalid} - fmt.printf("allocated: %v\n", had_to_allocate); // true - fmt.printf("err : %v\n", err); // false - - if had_to_allocate { defer bytes.buffer_destroy(backing); } - - fmt.println("\nConvert []f16le (x2) to []u16 (x2)."); - - res2: []u16; - res2, backing, had_to_allocate, err = bytes.buffer_convert_to_type(2, u16, f16le, b); - fmt.printf("res : %v\n", res2); // [15360, 15360] - fmt.printf("backing : %v\n", backing); // Buffer.buf points to `b` because it could be converted in-place. - fmt.printf("allocated: %v\n", had_to_allocate); // false - fmt.printf("err : %v\n", err); // false - - if had_to_allocate { defer bytes.buffer_destroy(backing); } - - fmt.println("\nConvert []f16le (x2) to []u16 (x2), force_convert=true."); - - res2, backing, had_to_allocate, err = bytes.buffer_convert_to_type(2, u16, f16le, b, true); - fmt.printf("res : %v\n", res2); // [1, 1] - fmt.printf("backing : %v\n", backing); // Buffer.buf points to `b` because it could be converted in-place. - fmt.printf("allocated: %v\n", had_to_allocate); // false - fmt.printf("err : %v\n", err); // false - - if had_to_allocate { defer bytes.buffer_destroy(backing); } -*/ -buffer_convert_to_type :: proc(count: int, $TT: typeid, $FT: typeid, from_buffer: []u8, force_convert := false) -> ( - res: []TT, backing: ^Buffer, alloc: bool, err: bool) { - - backing = new(Buffer); - - if len(from_buffer) > 0 { - /* - Check if we've been given enough input elements. - */ - from := mem.slice_data_cast([]FT, from_buffer); - if len(from) != count { - err = true; - return; - } - - /* - We can early out if the types are exactly identical. - This needs to be `when`, or res = from will fail if the types are different. - */ - when FT == TT { - res = from; - buffer_init(backing, from_buffer); - return; - } - - /* - We can do a data cast if in-size == out-size and no endian conversion is needed. - */ - convert := need_endian_conversion(FT, TT); - convert |= (size_of(TT) * count != len(from_buffer)); - convert |= force_convert; - - if !convert { - // It's just a data cast - res = mem.slice_data_cast([]TT, from_buffer); - buffer_init(backing, from_buffer); - - if len(res) != count { - err = true; - } - return; - } else { - if size_of(TT) * count == len(from_buffer) { - /* - Same size, can do an in-place Endianness conversion. - If `force_convert`, this also handles the per-element cast instead of slice_data_cast. - */ - res = mem.slice_data_cast([]TT, from_buffer); - buffer_init(backing, from_buffer); - for v, i in from { - res[i] = TT(v); - } - } else { - /* - Result is a different size, we need to allocate an output buffer. - */ - size := size_of(TT) * count; - buffer_init_allocator(backing, size, size, context.allocator); - alloc = true; - res = mem.slice_data_cast([]TT, backing.buf[:]); - if len(res) != count { - err = true; - return; - } - - for v, i in from { - res[i] = TT(v); - } - } - } - } else { - /* - The input buffer is empty, so we'll have to create a new one for []TT of length count. - */ - res, backing, err = buffer_create_of_type(count, TT); - alloc = true; - } - - return; -} - -buffer_create_of_type :: proc(count: int, $TT: typeid) -> (res: []TT, backing: ^Buffer, err: bool) { - backing = new(Buffer); - size := size_of(TT) * count; - buffer_init_allocator(backing, size, size, context.allocator); - res = mem.slice_data_cast([]TT, backing.buf[:]); - if len(res) != count { - err = true; - } - return; -} \ No newline at end of file diff --git a/core/image/png/example.odin b/core/image/png/example.odin index 3891a88e5..f96ef01b2 100644 --- a/core/image/png/example.odin +++ b/core/image/png/example.odin @@ -9,12 +9,12 @@ package png Jeroen van Rijn: Initial implementation. Ginger Bill: Cosmetic changes. - An example of how to use `png.load`. + An example of how to use `load`. */ import "core:compress" import "core:image" -import "core:image/png" +// import "core:image/png" import "core:bytes" import "core:fmt" @@ -31,33 +31,33 @@ main :: proc() { file = "../../../misc/logo-slim.png"; - img, err = png.load(file, options); - defer png.destroy(img); + img, err = load(file, options); + defer destroy(img); if err != nil { fmt.printf("Trying to read PNG file %v returned %v\n", file, err); } else { - v: ^png.Info; + v: ^Info; fmt.printf("Image: %vx%vx%v, %v-bit.\n", img.width, img.height, img.channels, img.depth); - if img.metadata_ptr != nil && img.metadata_type == png.Info { - v = (^png.Info)(img.metadata_ptr); + if img.metadata_ptr != nil && img.metadata_type == Info { + v = (^Info)(img.metadata_ptr); // Handle ancillary chunks as you wish. // We provide helper functions for a few types. for c in v.chunks { #partial switch c.header.type { case .tIME: - t, _ := png.core_time(c); + t, _ := core_time(c); fmt.printf("[tIME]: %v\n", t); case .gAMA: - fmt.printf("[gAMA]: %v\n", png.gamma(c)); + fmt.printf("[gAMA]: %v\n", gamma(c)); case .pHYs: - phys := png.phys(c); + phys := phys(c); if phys.unit == .Meter { xm := f32(img.width) / f32(phys.ppu_x); ym := f32(img.height) / f32(phys.ppu_y); - dpi_x, dpi_y := png.phys_to_dpi(phys); + dpi_x, dpi_y := phys_to_dpi(phys); fmt.printf("[pHYs] Image resolution is %v x %v pixels per meter.\n", phys.ppu_x, phys.ppu_y); fmt.printf("[pHYs] Image resolution is %v x %v DPI.\n", dpi_x, dpi_y); fmt.printf("[pHYs] Image dimensions are %v x %v meters.\n", xm, ym); @@ -65,7 +65,7 @@ main :: proc() { fmt.printf("[pHYs] x: %v, y: %v pixels per unknown unit.\n", phys.ppu_x, phys.ppu_y); } case .iTXt, .zTXt, .tEXt: - res, ok_text := png.text(c); + res, ok_text := text(c); if ok_text { if c.header.type == .iTXt { fmt.printf("[iTXt] %v (%v:%v): %v\n", res.keyword, res.language, res.keyword_localized, res.text); @@ -73,11 +73,11 @@ main :: proc() { fmt.printf("[tEXt/zTXt] %v: %v\n", res.keyword, res.text); } } - defer png.text_destroy(res); + defer text_destroy(res); case .bKGD: fmt.printf("[bKGD] %v\n", img.background); case .eXIf: - res, ok_exif := png.exif(c); + res, ok_exif := exif(c); if ok_exif { /* Other than checking the signature and byte order, we don't handle Exif data. @@ -86,45 +86,45 @@ main :: proc() { fmt.printf("[eXIf] %v\n", res); } case .PLTE: - plte, plte_ok := png.plte(c); + plte, plte_ok := plte(c); if plte_ok { fmt.printf("[PLTE] %v\n", plte); } else { fmt.printf("[PLTE] Error\n"); } case .hIST: - res, ok_hist := png.hist(c); + res, ok_hist := hist(c); if ok_hist { fmt.printf("[hIST] %v\n", res); } case .cHRM: - res, ok_chrm := png.chrm(c); + res, ok_chrm := chrm(c); if ok_chrm { fmt.printf("[cHRM] %v\n", res); } case .sPLT: - res, ok_splt := png.splt(c); + res, ok_splt := splt(c); if ok_splt { fmt.printf("[sPLT] %v\n", res); } - png.splt_destroy(res); + splt_destroy(res); case .sBIT: - if res, ok_sbit := png.sbit(c); ok_sbit { + if res, ok_sbit := sbit(c); ok_sbit { fmt.printf("[sBIT] %v\n", res); } case .iCCP: - res, ok_iccp := png.iccp(c); + res, ok_iccp := iccp(c); if ok_iccp { fmt.printf("[iCCP] %v\n", res); } - png.iccp_destroy(res); + iccp_destroy(res); case .sRGB: - if res, ok_srgb := png.srgb(c); ok_srgb { + if res, ok_srgb := srgb(c); ok_srgb { fmt.printf("[sRGB] Rendering intent: %v\n", res); } case: type := c.header.type; - name := png.chunk_type_to_name(&type); + name := chunk_type_to_name(&type); fmt.printf("[%v]: %v\n", name, c.data); } }