From 11164fa236b384d0e9738dea1553bdc8f8ea6952 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Fri, 22 Jan 2021 23:33:05 -0600 Subject: [PATCH] small things --- src/pixie/common.nim | 24 ++++++++- src/pixie/images.nim | 115 ++++++++++++++++++------------------------ tests/test_flips.nim | 16 ------ tests/test_images.nim | 18 ++++++- 4 files changed, 88 insertions(+), 85 deletions(-) delete mode 100644 tests/test_flips.nim diff --git a/src/pixie/common.nim b/src/pixie/common.nim index 973c057..ef15b0c 100644 --- a/src/pixie/common.nim +++ b/src/pixie/common.nim @@ -1,4 +1,4 @@ -import vmath +import chroma, vmath type PixieError* = object of ValueError ## Raised if an operation fails. @@ -8,3 +8,25 @@ proc fractional*(v: float32): float32 {.inline.} = ## -13.7868723 -> 0.7868723 result = abs(v) 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 diff --git a/src/pixie/images.nim b/src/pixie/images.nim index 0843530..91260d9 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -95,35 +95,36 @@ proc fill*(image: Image, rgba: ColorRgba) {.inline.} = ## Fills the image with a solid color. fillUnsafe(image.data, rgba, 0, image.data.len) -when defined(release): - {.pop.} +proc flipHorizontal*(image: Image) = + ## 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 draw*(a, b: Image, pos = vec2(0, 0), blendMode = bmNormal) {.inline.} - -proc invert*(image: Image) = - ## Inverts all of the colors and alpha. - var i: int - when defined(amd64): - let vec255 = mm_set1_epi8(255) - while i < image.data.len - 4: - var m = mm_loadu_si128(image.data[i].addr) - 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 flipVertical*(image: Image) = + ## Flips the image around the X axis. + 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) proc subImage*(image: Image, x, y, w, h: int): Image = - ## Gets a sub image of the main image. - ## TODO handle images out of bounds faster - # doAssert x >= 0 and y >= 0 - # doAssert x + w <= image.width and y + h <= image.height + ## Gets a sub image from this image. + + if x < 0 or x + w > image.width: + 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) for y2 in 0 ..< h: for x2 in 0 ..< w: @@ -159,49 +160,29 @@ proc magnifyBy2*(image: Image, scale2x: int): Image = proc magnifyBy2*(image: Image): Image = image.magnifyBy2(2) -proc flipHorizontal*(image: Image) = - ## 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) +when defined(release): + {.pop.} -proc flipVertical*(image: Image) = - ## Flips the image around the X axis. - 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) +proc draw*(a, b: Image, mat: Mat3, blendMode = bmNormal) +proc draw*(a, b: Image, pos = vec2(0, 0), blendMode = bmNormal) {.inline.} -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 +proc invert*(image: Image) = + ## Inverts all of the colors and alpha. + var i: int + when defined(amd64): + let vec255 = mm_set1_epi8(255) + while i < image.data.len - 4: + var m = mm_loadu_si128(image.data[i].addr) + 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 toAlphy*(image: Image) = ## Converts an image to premultiplied alpha from straight. diff --git a/tests/test_flips.nim b/tests/test_flips.nim deleted file mode 100644 index ae23dfb..0000000 --- a/tests/test_flips.nim +++ /dev/null @@ -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") diff --git a/tests/test_images.nim b/tests/test_images.nim index a46c712..1ef0e11 100644 --- a/tests/test_images.nim +++ b/tests/test_images.nim @@ -1,4 +1,4 @@ -import pixie, chroma, strutils, os +import pixie, chroma, strutils, os, vmath proc writeAndCheck(image: Image, fileName: string) = image.writeFile(fileName) @@ -106,3 +106,19 @@ block: # var c = a.draw(b, translate(vec2(25, 25)) * rotationMat3(PI/2)) # 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")