From 7c2014ee887335474e20285523a214cac0f87b59 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sat, 30 Jan 2021 19:44:28 -0600 Subject: [PATCH] faster superImage + tests --- src/pixie/images.nim | 30 ++++++++++++++++++++++++----- tests/images/superimage1.png | Bin 0 -> 106 bytes tests/images/superimage2.png | Bin 0 -> 105 bytes tests/images/superimage3.png | Bin 0 -> 392 bytes tests/images/superimage4.png | Bin 0 -> 387 bytes tests/images/superimage5.png | Bin 0 -> 519 bytes tests/images/superimage6.png | Bin 0 -> 129 bytes tests/test_images.nim | 36 +++++++++++++++++++++++++++++++++++ 8 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 tests/images/superimage1.png create mode 100644 tests/images/superimage2.png create mode 100644 tests/images/superimage3.png create mode 100644 tests/images/superimage4.png create mode 100644 tests/images/superimage5.png create mode 100644 tests/images/superimage6.png diff --git a/src/pixie/images.nim b/src/pixie/images.nim index 973dd66..b952492 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -16,6 +16,9 @@ when defined(release): proc newImage*(width, height: int): Image = ## Creates a new image with the parameter dimensions. + if width < 0 or height < 0: + raise newException(PixieError, "Image width and height must be positive") + result = Image() result.width = width result.height = height @@ -143,11 +146,28 @@ proc subImage*(image: Image, x, y, w, h: int): Image = ) proc superImage*(image: Image, x, y, w, h: int): Image = - ## Cuts either a sub image or super image with padded transparency. - result = newImage(w, h) - for y2 in 0 ..< h: - for x2 in 0 ..< w: - result.setRgbaUnsafe(x2, y2, image[x2 + x, y2 + y]) + ## Either cuts a sub image or returns a super image with padded transparency. + if x >= 0 and x + w <= image.width and y >= 0 and y + h <= image.height: + result = image.subImage(x, y, w, h) + elif abs(x) >= image.width or abs(y) >= image.height: + # Nothing to copy, just an empty new image + result = newImage(w, h) + else: + let + readOffsetX = max(x, 0) + readOffsetY = max(y, 0) + writeOffsetX = max(0 - x, 0) + writeOffsetY = max(0 - y, 0) + copyWidth = max(min(image.width, w) - abs(x), 0) + copyHeight = max(min(image.height, h) - abs(y), 0) + + result = newImage(w, h) + for y2 in 0 ..< copyHeight: + copyMem( + result.data[result.dataIndex(writeOffsetX, writeOffsetY + y2)].addr, + image.data[image.dataIndex(readOffsetX, readOffsetY + y2)].addr, + copyWidth * 4 + ) proc minifyBy2*(image: Image, power = 1): Image = ## Scales the image down by an integer scale. diff --git a/tests/images/superimage1.png b/tests/images/superimage1.png new file mode 100644 index 0000000000000000000000000000000000000000..56eff27d4dd332eade9fd85d31b9d9afa749aabd GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=p{I*uNCjhZnu6G$^dILhI7kTP zE1WP;I<{9 literal 0 HcmV?d00001 diff --git a/tests/images/superimage2.png b/tests/images/superimage2.png new file mode 100644 index 0000000000000000000000000000000000000000..2e903a2525f3d192672c95e8ad0cd514ba7b9b27 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=fv1aONCjhZ+5#g9(+NceQf*V3 z8F>!>=lL%w#o_!Ymcyur!yrpR4k)pM;p${whNJ!>)>%~ni-39=JYD@<);T3K0RWbl B8dU%Q literal 0 HcmV?d00001 diff --git a/tests/images/superimage3.png b/tests/images/superimage3.png new file mode 100644 index 0000000000000000000000000000000000000000..1e7232f602796b7dfe49c7041e0acf07fc895191 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%q}r7F#3DCIEGX(zP)Y8)nFjNaIm>1 zCVt(G2yU}oXC}PXziIV)hUK=IZ%@84{{2DwHP`Qw?dIodf^? literal 0 HcmV?d00001 diff --git a/tests/images/superimage4.png b/tests/images/superimage4.png new file mode 100644 index 0000000000000000000000000000000000000000..1b58d462506507d90e7fbce4568ed79ae1d5b146 GIT binary patch literal 387 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%q}r7FnW2qIEGX(zP(|{)!@LxaPUBF zO#HeV5!`0G&N%$KlRLfijLhvb-%`HKto<>yw6%8E#smMA3+5asWIE0%qmE$Q*|jd% zU;UrBr}j^+JTy5>)wC12GyA~d?`z+$KOs$TN0c)?nW8)S^+aA~VBj)%y85}Sb4q9e E03_3qWB>pF literal 0 HcmV?d00001 diff --git a/tests/images/superimage5.png b/tests/images/superimage5.png new file mode 100644 index 0000000000000000000000000000000000000000..4ed0c8eddaa9c098efdaabda9c21c6abd02c39de GIT binary patch literal 519 zcmeAS@N?(olHy`uVBq!ia0vp^6(G#P1|%(0%q}r7FrM>taSW+oe0%30SF?ct%LRw} znEiW>-V<-h4VS%Vd~mjtTCq=DcLo!m`hx-tqTKGm_p0@8f1a<7zrF39?f0$U;@|H6 z%qahm%_8jmJC-{N54za;FFs)7U6=7ef;aENpy$r;min_-vo`)do6XO^EYn$PVw(TA z9Q9N{^?UjB2J!zJ*C+ou_WDiwwo)E74vRSrhdHT4+)-tew>Q0hLh4V^|9N%{=ZuLr b_zt_gTe~DWM4fCb-}@ literal 0 HcmV?d00001 diff --git a/tests/images/superimage6.png b/tests/images/superimage6.png new file mode 100644 index 0000000000000000000000000000000000000000..3343ca4df8ae9362e54ca8cfb8f5d97e8549a7b7 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=ho_5UNCjhZ+K=-e<}YLv{g
gTe~DWM4fOWY-G literal 0 HcmV?d00001 diff --git a/tests/test_images.nim b/tests/test_images.nim index 79822bf..326de43 100644 --- a/tests/test_images.nim +++ b/tests/test_images.nim @@ -43,3 +43,39 @@ block: a.writeFile("tests/images/flipped2.png") a.flipHorizontal() a.writeFile("tests/images/flipped3.png") + +block: + let + a = readImage("tests/images/flipped1.png") + b = a.superImage(-10, 0, 20, 20) + b.writeFile("tests/images/superimage1.png") + +block: + let + a = readImage("tests/images/flipped1.png") + b = a.superImage(-10, -10, 20, 20) + b.writeFile("tests/images/superimage2.png") + +block: + let + a = readImage("tests/images/flipped1.png") + b = a.superImage(90, 0, 120, 120) + b.writeFile("tests/images/superimage3.png") + +block: + let + a = readImage("tests/images/flipped1.png") + b = a.superImage(90, 90, 120, 120) + b.writeFile("tests/images/superimage4.png") + +block: + let + a = readImage("tests/images/flipped1.png") + b = a.superImage(-10, -10, 120, 120) + b.writeFile("tests/images/superimage5.png") + +block: + let + a = readImage("tests/images/flipped1.png") + b = a.superImage(45, 45, 20, 20) + b.writeFile("tests/images/superimage6.png")