From 8cfc5436f3a6030bea909d12f74e87d48ad78100 Mon Sep 17 00:00:00 2001 From: DerTee Date: Thu, 30 Jan 2025 02:02:24 +0100 Subject: [PATCH 1/3] add core:image:flip_vertically() This is basically the same as the option in stb_image to flip an image. One common use case is loading images for OpenGL which expects pixel data to be upside down, unlike most other graphics APIs and image formats. --- core/image/bmp/bmp.odin | 10 +--------- core/image/common.odin | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index 057c2ffa047..a106279188e 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -244,15 +244,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a // Flipped vertically if info.height < 0 { - pixels := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:]) - for y in 0.. (ok: bo return true } +flip_vertically :: proc(img: ^Image) { + pixels := img.pixels.buf[:] + bpp := img.depth/8 * img.channels + bytes_per_line := img.width * bpp + for y in 0.. Date: Thu, 30 Jan 2025 03:35:55 +0100 Subject: [PATCH 2/3] core:image add support for option .flip_vertical --- core/image/bmp/bmp.odin | 4 ++-- core/image/netpbm/netpbm.odin | 8 ++++++-- core/image/png/png.odin | 3 +++ core/image/qoi/qoi.odin | 4 ++++ core/image/tga/tga.odin | 3 +++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index a106279188e..c6b279cbe0c 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -242,8 +242,8 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a case: return img, .Unsupported_Compression } - // Flipped vertically - if info.height < 0 { + // is flipped XOR user wants to flip + if (int(info.height < 0) ~ int(.flip_vertical in options)) == 1 { image.flip_vertically(img) } return diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index a9dc6599a47..ba2cfb6d283 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -11,6 +11,7 @@ import "core:unicode" import "base:runtime" Image :: image.Image +Options :: image.Options Format :: image.Netpbm_Format Header :: image.Netpbm_Header Info :: image.Netpbm_Info @@ -27,7 +28,7 @@ PFM :: Formats{.Pf, .PF} ASCII :: Formats{.P1, .P2, .P3} BINARY :: Formats{.P4, .P5, .P6} + PAM + PFM -load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^Image, err: Error) { +load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) { context.allocator = allocator img = new(Image) @@ -47,6 +48,9 @@ load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^ } img.metadata = info + if .flip_vertical in options { + image.flip_vertically(img) + } return img, nil } @@ -722,7 +726,7 @@ autoselect_pbm_format_from_image :: proc(img: ^Image, prefer_binary := true, for @(init, private) _register :: proc() { loader :: proc(data: []byte, options: image.Options, allocator: mem.Allocator) -> (img: ^Image, err: Error) { - return load_from_bytes(data, allocator) + return load_from_bytes(data, options, allocator) } destroyer :: proc(img: ^Image) { _ = destroy(img) diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 2d3665e9482..bfdabe43243 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1182,6 +1182,9 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a panic("We should never see bit depths other than 8, 16 and 'Paletted' here.") } + if .flip_vertical in options { + image.flip_vertically(img) + } return img, nil } diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 6b6149e60ae..3c1552030cc 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -323,6 +323,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, .Post_Processing_Error } + if .flip_vertical in options { + image.flip_vertically(img) + } + return } diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 46e37a0cfce..2d2583662f9 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -371,6 +371,9 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } line += 1 if origin_is_top else -1 } + if .flip_vertical in options { + image.flip_vertically(img) + } return img, nil } From d40e436ada3c866a633e9c246423bbed2b020625 Mon Sep 17 00:00:00 2001 From: DerTee Date: Sat, 1 Feb 2025 20:38:18 +0100 Subject: [PATCH 3/3] `core:image`: rename `flip_vertical(ly)` -> `vertical_flip` --- core/image/bmp/bmp.odin | 4 ++-- core/image/common.odin | 4 ++-- core/image/netpbm/netpbm.odin | 4 ++-- core/image/png/png.odin | 4 ++-- core/image/qoi/qoi.odin | 4 ++-- core/image/tga/tga.odin | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index c6b279cbe0c..affeab2a99d 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -243,8 +243,8 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } // is flipped XOR user wants to flip - if (int(info.height < 0) ~ int(.flip_vertical in options)) == 1 { - image.flip_vertically(img) + if (int(info.height < 0) ~ int(.vertical_flip in options)) == 1 { + image.vertical_flip(img) } return } diff --git a/core/image/common.odin b/core/image/common.odin index e25f6259819..85e963ce501 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -148,7 +148,7 @@ Option :: enum { alpha_drop_if_present, // Unimplemented for QOI. Returns error. alpha_premultiply, // Unimplemented for QOI. Returns error. blend_background, // Ignored for non-PNG formats - flip_vertical, + vertical_flip, // flip image vertically on load // Unimplemented do_not_expand_grayscale, @@ -1441,7 +1441,7 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo return true } -flip_vertically :: proc(img: ^Image) { +vertical_flip :: proc(img: ^Image) { pixels := img.pixels.buf[:] bpp := img.depth/8 * img.channels bytes_per_line := img.width * bpp diff --git a/core/image/netpbm/netpbm.odin b/core/image/netpbm/netpbm.odin index ba2cfb6d283..9bda75b06e1 100644 --- a/core/image/netpbm/netpbm.odin +++ b/core/image/netpbm/netpbm.odin @@ -48,8 +48,8 @@ load_from_bytes :: proc(data: []byte, options := Options{}, allocator := context } img.metadata = info - if .flip_vertical in options { - image.flip_vertically(img) + if .vertical_flip in options { + image.vertical_flip(img) } return img, nil } diff --git a/core/image/png/png.odin b/core/image/png/png.odin index bfdabe43243..4bcb1583856 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -1182,8 +1182,8 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a panic("We should never see bit depths other than 8, 16 and 'Paletted' here.") } - if .flip_vertical in options { - image.flip_vertically(img) + if .vertical_flip in options { + image.vertical_flip(img) } return img, nil } diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 3c1552030cc..490b08004e9 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -323,8 +323,8 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a return img, .Post_Processing_Error } - if .flip_vertical in options { - image.flip_vertically(img) + if .vertical_flip in options { + image.vertical_flip(img) } return diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 2d2583662f9..0fdb3f3d138 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -371,8 +371,8 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } line += 1 if origin_is_top else -1 } - if .flip_vertical in options { - image.flip_vertically(img) + if .vertical_flip in options { + image.vertical_flip(img) } return img, nil }