Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core:image add support for option .flip_vertical #4826

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions core/image/bmp/bmp.odin
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,9 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
case: return img, .Unsupported_Compression
}

// Flipped vertically
if info.height < 0 {
pixels := mem.slice_data_cast([]RGB_Pixel, img.pixels.buf[:])
for y in 0..<img.height / 2 {
for x in 0..<img.width {
top := y * img.width + x
bot := (img.height - y - 1) * img.width + x

pixels[top], pixels[bot] = pixels[bot], pixels[top]
}
}
// is flipped XOR user wants to flip
if (int(info.height < 0) ~ int(.vertical_flip in options)) == 1 {
image.vertical_flip(img)
}
return
}
Expand Down
14 changes: 14 additions & 0 deletions core/image/common.odin
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
List of contributors:
Jeroen van Rijn: Initial implementation, optimization.
Ginger Bill: Cosmetic changes.
DerTee: Vertical flip.
*/

// package image implements a general 2D image library to be used with other image related packages
package image

import "core:bytes"
import "core:mem"
import "core:slice"
import "core:io"
import "core:compress"
import "base:runtime"
Expand Down Expand Up @@ -146,6 +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
vertical_flip, // flip image vertically on load

// Unimplemented
do_not_expand_grayscale,
Expand Down Expand Up @@ -1438,6 +1441,17 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo
return true
}

vertical_flip :: proc(img: ^Image) {
pixels := img.pixels.buf[:]
bpp := img.depth/8 * img.channels
bytes_per_line := img.width * bpp
for y in 0..<img.height / 2 {
top := y * bytes_per_line
bot := (img.height - y - 1) * bytes_per_line
slice.ptr_swap_non_overlapping(&pixels[top], &pixels[bot], bytes_per_line)
}
}

/*
Helper functions to read and write data from/to a Context, etc.
*/
Expand Down
8 changes: 6 additions & 2 deletions core/image/netpbm/netpbm.odin
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -47,6 +48,9 @@ load_from_bytes :: proc(data: []byte, allocator := context.allocator) -> (img: ^
}
img.metadata = info

if .vertical_flip in options {
image.vertical_flip(img)
}
return img, nil
}

Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions core/image/png/png.odin
Original file line number Diff line number Diff line change
Expand Up @@ -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 .vertical_flip in options {
image.vertical_flip(img)
}
return img, nil
}

Expand Down
4 changes: 4 additions & 0 deletions core/image/qoi/qoi.odin
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
return img, .Post_Processing_Error
}

if .vertical_flip in options {
image.vertical_flip(img)
}

return
}

Expand Down
3 changes: 3 additions & 0 deletions core/image/tga/tga.odin
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
}
line += 1 if origin_is_top else -1
}
if .vertical_flip in options {
image.vertical_flip(img)
}
return img, nil
}

Expand Down