Skip to content

Commit 3bfde97

Browse files
committed
More tests, new macro protection for targets vulnerable to excessive inlining
1 parent db5ec5c commit 3bfde97

22 files changed

Lines changed: 3073 additions & 106 deletions

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ jobs:
121121
- name: Compile (${{ matrix.target }})
122122
run: |
123123
mkdir -p bin
124-
CMD="haxe --class-path tests/generated/src --main Main --library vision --library format --library utest -debug"
124+
CMD="haxe --class-path tests/generated/src --main Main --library vision --library format --library utest -debug -D vision_skip_golden -D vision_skip_invalid_tests"
125125
if [ "${{ matrix.target }}" = "java" ] || [ "${{ matrix.target }}" = "jvm" ]; then
126126
CMD="$CMD --no-inline"
127127
fi

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 2.1.1
1+
# 2.2.0
22

33
### `Image.hx`
44
- **Added `Image.copyImageFrom`**

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,3 +269,4 @@ If you see some code that you think is not understandable, or some place that la
269269
| `vision_higher_width_cap` | allows using images wider than 65535 pixels, but makes the image byte offset bigger (11 to 21 bytes) (for more information about the byte offset, [click here](https://github.com/ShaharMS/Vision/blob/ed042871963e7456161c00017e4c2bf79a1f26cc/src/vision/ds/Image.hx#L37)). Also allows image views to be wider & taller than 65535 pixels. | 1.2.0 - now |
270270
| `vision_fancy_array_access` | Enables a fancy, shortened way to access arrays of multi-dimensional arrays (specifically Array2D) using double square brackets: `array[[x, y]]`. This is enabled by default. When disabled, only direct `get` and `set` calls are allowed. | 2.0.0 - now |
271271
| `vision_hlc_color_compile` | When compiling to C code using the C transpiler of Hashlink, the word TRANSPARENT can clash with existing `#define`s in the resulting C code. To work around this, the defines disables `Color.TRANSPARENT`. You can use `Color.TRANSPARENT_COLOR` instead. | 2.0.0 - now |
272+
| `vision_disable_inline_protection` | Disables the inline-stripping build macro used on java, jvm, and lua targets. Leave this off unless you explicitly want inline fields preserved on those targets. Pay attention - inlining was disabled on these targets because of errors related to variable count/function size | 2.2.0 - now |

compile.hxml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@
2727

2828
#--define vision_fancy_array_access
2929
--macro addGlobalMetadata('', '@:build(vision.helpers.Array2DMacro.build())')
30+
--macro addGlobalMetadata('', '@:build(vision.helpers.InlineProtectionMacro.build())')
3031

extraParams.hxml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# https://github.com/Laerdal/opentype.hx/issues/2
22
# --resource assets/NotoSans-Regular.ttf
3-
--macro addGlobalMetadata('', '@:build(vision.helpers.Array2DMacro.build())')
3+
--macro addGlobalMetadata('', '@:build(vision.helpers.Array2DMacro.build())')
4+
--macro addGlobalMetadata('', '@:build(vision.helpers.InlineProtectionMacro.build())')

haxelib.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vision",
33
"license": "MIT",
4-
"version": "2.1.0",
4+
"version": "2.2.0",
55
"description": "Vision is a simple, powerful and flexible computer vision & image processing library for Haxe.",
66
"contributors": ["ShaharMS"],
77
"releasenote": "K-Means, color filtering, Image hashing, and many QOL additions :D",

src/vision/ds/Image.hx

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ abstract Image(ByteArray) {
112112
@param color The color to fill the image with. if unspecified, the image is transparent.
113113
**/
114114
public inline function new(width:Int, height:Int, color:Color = 0x00000000) {
115+
#end
115116
this = new ByteArray(width * height * 4 + OFFSET);
116117
#if vision_higher_width_cap this.setInt32 #else this.setUInt16 #end (0, width);
117118
#if vision_higher_width_cap this.setInt32 #else this.setUInt16 #end (WIDTH_BYTES, 0);
@@ -131,7 +132,13 @@ abstract Image(ByteArray) {
131132

132133
inline function getColorFromStartingBytePos(position:Int):Color {
133134
position += OFFSET;
134-
return new Color(this[position] << 24 | this[position + 1] << 16 | this[position + 2] << 8 | this[position + 3]);
135+
var value = this[position] << 24 | this[position + 1] << 16 | this[position + 2] << 8 | this[position + 3];
136+
#if (python || php || lua)
137+
var signedValue:haxe.Int32 = value;
138+
signedValue = signedValue + 0;
139+
value = signedValue;
140+
#end
141+
return new Color(value);
135142
}
136143

137144
inline function setColorFromStartingBytePos(position:Int, c:Color) {
@@ -616,8 +623,15 @@ abstract Image(ByteArray) {
616623
@see Ray2D
617624
**/
618625
public inline function drawRay2D(line:Ray2D, color:Color) {
619-
var p1 = IntPoint2D.fromPoint2D(line.getPointAtY(0));
620-
var p2 = IntPoint2D.fromPoint2D(line.getPointAtY(height - 1));
626+
var p1:IntPoint2D;
627+
var p2:IntPoint2D;
628+
if (line.slope == 0) {
629+
p1 = new IntPoint2D(0, Std.int(line.point.y));
630+
p2 = new IntPoint2D(width - 1, Std.int(line.point.y));
631+
} else {
632+
p1 = IntPoint2D.fromPoint2D(line.getPointAtY(0));
633+
p2 = IntPoint2D.fromPoint2D(line.getPointAtY(height - 1));
634+
}
621635
var x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;
622636
var dx = Math.abs(x2 - x1);
623637
var dy = Math.abs(y2 - y1);
@@ -737,8 +751,8 @@ abstract Image(ByteArray) {
737751
}
738752

739753
var p0 = IntPoint2D.fromPoint2D(line.start);
740-
var p1 = IntPoint2D.fromPoint2D(line.end);
741-
var p2 = IntPoint2D.fromPoint2D(control);
754+
var p1 = IntPoint2D.fromPoint2D(control);
755+
var p2 = IntPoint2D.fromPoint2D(line.end);
742756
var i = 0.;
743757
var step = 1 / accuracy;
744758
while (i <= 1) {
@@ -748,6 +762,8 @@ abstract Image(ByteArray) {
748762
}
749763
i += step;
750764
}
765+
if (hasPixel(p0.x, p0.y)) setPixel(p0.x, p0.y, color);
766+
if (hasPixel(p2.x, p2.y)) setPixel(p2.x, p2.y, color);
751767
}
752768

753769
/**
@@ -779,16 +795,21 @@ abstract Image(ByteArray) {
779795
return {x: x, y: y};
780796
}
781797

798+
var p0 = IntPoint2D.fromPoint2D(line.start);
799+
var p3 = IntPoint2D.fromPoint2D(line.end);
800+
var p1 = IntPoint2D.fromPoint2D(control1);
801+
var p2 = IntPoint2D.fromPoint2D(control2);
782802
var i = 0.;
783803
var step = 1 / accuracy;
784-
while (i < 1) {
785-
var p =
786-
inline bezier(i, line.start, line.end, control1, control2);
804+
while (i <= 1) {
805+
var p = inline bezier(i, p0, p1, p2, p3);
787806
if (hasPixel(p.x, p.y)) {
788807
setPixel(p.x, p.y, color);
789808
}
790809
i += step;
791810
}
811+
if (hasPixel(p0.x, p0.y)) setPixel(p0.x, p0.y, color);
812+
if (hasPixel(p3.x, p3.y)) setPixel(p3.x, p3.y, color);
792813
}
793814

794815
// https://github.com/Laerdal/opentype.hx/issues/2
@@ -1656,7 +1677,7 @@ abstract Image(ByteArray) {
16561677
}
16571678

16581679
private class PixelIterator {
1659-
var i = 4;
1680+
var i = 0;
16601681
var img:Image;
16611682

16621683
public inline function new(img:Image) {
@@ -1667,11 +1688,11 @@ private class PixelIterator {
16671688
final x = i % img.width;
16681689
final y = Math.floor(i / img.width);
16691690
var pixel:Pixel = {x: x, y: y, color: img.getPixel(x, y)};
1670-
i += 4;
1691+
i++;
16711692
return pixel;
16721693
}
16731694

16741695
public inline function hasNext():Bool {
1675-
return i < (cast img:ByteArray).length;
1696+
return i < (img.width * img.height);
16761697
}
16771698
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package vision.helpers;
2+
3+
#if macro
4+
import haxe.macro.Context;
5+
import haxe.macro.Expr;
6+
7+
class InlineProtectionMacro {
8+
public static function build():Array<Field> {
9+
if (Context.defined("vision_disable_inline_protection")) {
10+
return null;
11+
}
12+
var isTarget = Context.defined("java") || Context.defined("jvm") || Context.defined("lua");
13+
if (!isTarget) {
14+
return null;
15+
}
16+
17+
var fields = Context.getBuildFields();
18+
for (field in fields) {
19+
var access = field.access;
20+
if (access == null) {
21+
continue;
22+
}
23+
var hasInline = false;
24+
for (entry in access) {
25+
if (entry == AInline) {
26+
hasInline = true;
27+
break;
28+
}
29+
}
30+
if (!hasInline) {
31+
continue;
32+
}
33+
var filtered:Array<Access> = [];
34+
for (entry in access) {
35+
if (entry != AInline) {
36+
filtered.push(entry);
37+
}
38+
}
39+
field.access = filtered;
40+
}
41+
return fields;
42+
}
43+
}
44+
#end

test.hxml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
--class-path tests/generated/src
1+
--cwd tests/generated
2+
--class-path src
23
--main Main
34

45
--library vision

0 commit comments

Comments
 (0)