small things

This commit is contained in:
Ryan Oldenburg 2021-01-22 23:33:05 -06:00
parent 6ec1db5a81
commit 11164fa236
4 changed files with 88 additions and 85 deletions

View file

@ -1,4 +1,4 @@
import vmath import chroma, vmath
type type
PixieError* = object of ValueError ## Raised if an operation fails. PixieError* = object of ValueError ## Raised if an operation fails.
@ -8,3 +8,25 @@ proc fractional*(v: float32): float32 {.inline.} =
## -13.7868723 -> 0.7868723 ## -13.7868723 -> 0.7868723
result = abs(v) result = abs(v)
result = result - floor(result) result = result - floor(result)
func lerp*(a, b: Color, v: float32): Color {.inline.} =
result.r = lerp(a.r, b.r, v)
result.g = lerp(a.g, b.g, v)
result.b = lerp(a.b, b.b, v)
result.a = lerp(a.a, b.a, v)
proc toAlphy*(c: Color): Color =
## Converts a color to premultiplied alpha from straight.
result.r = c.r * c.a
result.g = c.g * c.a
result.b = c.b * c.a
result.a = c.a
proc fromAlphy*(c: Color): Color =
## Converts a color to from premultiplied alpha to straight.
if c.a == 0:
return
result.r = c.r / c.a
result.g = c.g / c.a
result.b = c.b / c.a
result.a = c.a

View file

@ -95,35 +95,36 @@ proc fill*(image: Image, rgba: ColorRgba) {.inline.} =
## Fills the image with a solid color. ## Fills the image with a solid color.
fillUnsafe(image.data, rgba, 0, image.data.len) fillUnsafe(image.data, rgba, 0, image.data.len)
when defined(release): proc flipHorizontal*(image: Image) =
{.pop.} ## Flips the image around the Y axis.
let w = image.width div 2
for y in 0 ..< image.height:
for x in 0 ..< w:
let
rgba1 = image.getRgbaUnsafe(x, y)
rgba2 = image.getRgbaUnsafe(image.width - x - 1, y)
image.setRgbaUnsafe(image.width - x - 1, y, rgba1)
image.setRgbaUnsafe(x, y, rgba2)
proc draw*(a, b: Image, mat: Mat3, blendMode = bmNormal) proc flipVertical*(image: Image) =
proc draw*(a, b: Image, pos = vec2(0, 0), blendMode = bmNormal) {.inline.} ## Flips the image around the X axis.
let h = image.height div 2
proc invert*(image: Image) = for y in 0 ..< h:
## Inverts all of the colors and alpha. for x in 0 ..< image.width:
var i: int let
when defined(amd64): rgba1 = image.getRgbaUnsafe(x, y)
let vec255 = mm_set1_epi8(255) rgba2 = image.getRgbaUnsafe(x, image.height - y - 1)
while i < image.data.len - 4: image.setRgbaUnsafe(x, image.height - y - 1, rgba1)
var m = mm_loadu_si128(image.data[i].addr) image.setRgbaUnsafe(x, y, rgba2)
m = mm_sub_epi8(vec255, m)
mm_storeu_si128(image.data[i].addr, m)
i += 4
for j in i ..< image.data.len:
var rgba = image.data[j]
rgba.r = 255 - rgba.r
rgba.g = 255 - rgba.g
rgba.b = 255 - rgba.b
rgba.a = 255 - rgba.a
image.data[j] = rgba
proc subImage*(image: Image, x, y, w, h: int): Image = proc subImage*(image: Image, x, y, w, h: int): Image =
## Gets a sub image of the main image. ## Gets a sub image from this image.
## TODO handle images out of bounds faster
# doAssert x >= 0 and y >= 0 if x < 0 or x + w > image.width:
# doAssert x + w <= image.width and y + h <= image.height raise newException(PixieError, "Param x value " & $x & " is out of bounds")
if y < 0 or y + h > image.height:
raise newException(PixieError, "Param y value " & $y & " is out of bounds")
result = newImage(w, h) result = newImage(w, h)
for y2 in 0 ..< h: for y2 in 0 ..< h:
for x2 in 0 ..< w: for x2 in 0 ..< w:
@ -159,49 +160,29 @@ proc magnifyBy2*(image: Image, scale2x: int): Image =
proc magnifyBy2*(image: Image): Image = proc magnifyBy2*(image: Image): Image =
image.magnifyBy2(2) image.magnifyBy2(2)
proc flipHorizontal*(image: Image) = when defined(release):
## Flips the image around the Y axis. {.pop.}
let w = image.width div 2
for y in 0 ..< image.height:
for x in 0 ..< w:
let
rgba1 = image.getRgbaUnsafe(x, y)
rgba2 = image.getRgbaUnsafe(image.width - x - 1, y)
image.setRgbaUnsafe(image.width - x - 1, y, rgba1)
image.setRgbaUnsafe(x, y, rgba2)
proc flipVertical*(image: Image) = proc draw*(a, b: Image, mat: Mat3, blendMode = bmNormal)
## Flips the image around the X axis. proc draw*(a, b: Image, pos = vec2(0, 0), blendMode = bmNormal) {.inline.}
let h = image.height div 2
for y in 0 ..< h:
for x in 0 ..< image.width:
let
rgba1 = image.getRgbaUnsafe(x, y)
rgba2 = image.getRgbaUnsafe(x, image.height - y - 1)
image.setRgbaUnsafe(x, image.height - y - 1, rgba1)
image.setRgbaUnsafe(x, y, rgba2)
func lerp(a, b: Color, v: float32): Color {.inline.} = proc invert*(image: Image) =
result.r = lerp(a.r, b.r, v) ## Inverts all of the colors and alpha.
result.g = lerp(a.g, b.g, v) var i: int
result.b = lerp(a.b, b.b, v) when defined(amd64):
result.a = lerp(a.a, b.a, v) let vec255 = mm_set1_epi8(255)
while i < image.data.len - 4:
proc toAlphy*(c: Color): Color = var m = mm_loadu_si128(image.data[i].addr)
## Converts a color to premultiplied alpha from straight. m = mm_sub_epi8(vec255, m)
result.r = c.r * c.a mm_storeu_si128(image.data[i].addr, m)
result.g = c.g * c.a i += 4
result.b = c.b * c.a for j in i ..< image.data.len:
result.a = c.a var rgba = image.data[j]
rgba.r = 255 - rgba.r
proc fromAlphy*(c: Color): Color = rgba.g = 255 - rgba.g
## Converts a color to from premultiplied alpha to straight. rgba.b = 255 - rgba.b
if c.a == 0: rgba.a = 255 - rgba.a
return image.data[j] = rgba
result.r = c.r / c.a
result.g = c.g / c.a
result.b = c.b / c.a
result.a = c.a
proc toAlphy*(image: Image) = proc toAlphy*(image: Image) =
## Converts an image to premultiplied alpha from straight. ## Converts an image to premultiplied alpha from straight.

View file

@ -1,16 +0,0 @@
import pixie, chroma, vmath
block:
var a = newImage(101, 101)
a.fill(rgba(255, 0, 0, 255))
var b = newImage(50, 50)
b.fill(rgba(0, 255, 0, 255))
a.draw(b, vec2(0, 0))
a.writeFile("tests/images/flipped1.png")
a.flipVertical()
a.writeFile("tests/images/flipped2.png")
a.flipHorizontal()
a.writeFile("tests/images/flipped3.png")

View file

@ -1,4 +1,4 @@
import pixie, chroma, strutils, os import pixie, chroma, strutils, os, vmath
proc writeAndCheck(image: Image, fileName: string) = proc writeAndCheck(image: Image, fileName: string) =
image.writeFile(fileName) image.writeFile(fileName)
@ -106,3 +106,19 @@ block:
# var c = a.draw(b, translate(vec2(25, 25)) * rotationMat3(PI/2)) # var c = a.draw(b, translate(vec2(25, 25)) * rotationMat3(PI/2))
# c.writeAndCheck("tests/images/drawOverwriteRot.png") # c.writeAndCheck("tests/images/drawOverwriteRot.png")
block:
let
a = newImage(101, 101)
b = newImage(50, 50)
a.fill(rgba(255, 0, 0, 255))
b.fill(rgba(0, 255, 0, 255))
a.draw(b, vec2(0, 0))
a.writeFile("tests/images/flipped1.png")
a.flipVertical()
a.writeFile("tests/images/flipped2.png")
a.flipHorizontal()
a.writeFile("tests/images/flipped3.png")