summaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter04Test.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter06Test.java16
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter09Test.java10
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter10Test.java26
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter11Test.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter12Test.java95
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter13Test.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter15Test.java19
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter16Test.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter17aTest.java10
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter17bTest.java27
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter18Test.java22
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter19Test.java10
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter20Test.java19
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter21AllocTest.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter21Test.java65
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter22Test.java13
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter23AllocTest.java37
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter23Test.java319
-rw-r--r--src/test/java/com/seaofnodes/simple/Eval2.java47
-rw-r--r--src/test/java/com/seaofnodes/simple/LiteralTest.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java2
-rw-r--r--src/test/java/com/seaofnodes/simple/MergeSortTest.java1
-rw-r--r--src/test/java/com/seaofnodes/simple/Simple.java8
-rw-r--r--src/test/java/com/seaofnodes/simple/SpillStats.java5
-rw-r--r--src/test/java/com/seaofnodes/simple/TestC.java24
-rw-r--r--src/test/java/com/seaofnodes/simple/TypeTest.java107
-rw-r--r--src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java43
-rw-r--r--src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java7
-rw-r--r--src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java3
-rw-r--r--src/test/java/com/seaofnodes/simple/fuzzer/Fuzzer.java8
-rw-r--r--src/test/java/com/seaofnodes/simple/fuzzer/FuzzerUtils.java4
-rw-r--r--src/test/java/com/seaofnodes/simple/fuzzer/Reducer.java11
-rw-r--r--src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java207
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/and1.smp10
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/and2.smp16
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/and3.smp14
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/funptr.c4
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/large.smp5344
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/or1.smp12
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/or2.smp23
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/print.smp8
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/ptrand.smp10
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/stringHash.smp5
-rw-r--r--src/test/java/com/seaofnodes/simple/progs/stringHash21.smp31
45 files changed, 6369 insertions, 285 deletions
diff --git a/src/test/java/com/seaofnodes/simple/Chapter04Test.java b/src/test/java/com/seaofnodes/simple/Chapter04Test.java
index e5a16680..ce808084 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter04Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter04Test.java
@@ -91,7 +91,7 @@ public class Chapter04Test {
// Adding functions means `main` does not constant fold the incoming arg value
@Ignore @Test
public void testConstantArg() {
- CodeGen code = new CodeGen("return arg; ", TypeInteger.constant(2), 123L).parse();
+ CodeGen code = new CodeGen("return arg; ", TypeInteger.constant(2), 123L, true).parse();
assertEquals("return 2;", code.expr().in(1).toString());
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter06Test.java b/src/test/java/com/seaofnodes/simple/Chapter06Test.java
index b6bc2bf3..1ff875b4 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter06Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter06Test.java
@@ -104,7 +104,7 @@ else if( arg==3 )
else
a=5;
return a;
-""", TypeInteger.constant(2), 123L).parse().opto();
+""", TypeInteger.constant(2), 123L, true).parse().opto();
assertEquals("return 5;", code.print());
}
@@ -124,7 +124,7 @@ else if( arg==3 )
else
a=5;
return a;
-""", TypeInteger.constant(1), 123L).parse().opto();
+""", TypeInteger.constant(1), 123L, true).parse().opto();
assertEquals("return 3;", code.print());
}
@@ -164,7 +164,7 @@ else if( arg==3 )
else
a=5;
return a;
-""", TypeInteger.constant(1), 123L);
+""", TypeInteger.constant(1), 123L, true);
code.parse().opto();
assertEquals("return 3;", code.print());
}
@@ -185,7 +185,7 @@ else if( arg==3 )
else
a=5;
return a;
-""", TypeInteger.constant(3), 123L);
+""", TypeInteger.constant(3), 123L, true);
code.parse().opto();
assertEquals("return 4;", code.print());
}
@@ -220,7 +220,7 @@ if( arg ) {
else b = 3;
}
return a+b;
-""", TypeInteger.constant(1), 123L);
+""", TypeInteger.constant(1), 123L, true);
code.parse().opto();
assertEquals("return 4;", code.print());
}
@@ -238,7 +238,7 @@ if( arg ) {
else b = 3;
}
return a+b;
-""", TypeInteger.constant(0), 123L);
+""", TypeInteger.constant(0), 123L, true);
code.parse().opto();
assertEquals("return 1;", code.print());
}
@@ -277,7 +277,7 @@ if( arg ) {
else b = 3;
}
return a+b+c;
-""", TypeInteger.constant(1), 123L);
+""", TypeInteger.constant(1), 123L, true);
code.parse().opto();
assertEquals("return 6;", code.print());
}
@@ -297,7 +297,7 @@ if( arg ) {
else b = 3;
}
return a+b+c;
-""", TypeInteger.constant(2), 123L);
+""", TypeInteger.constant(2), 123L, true);
code.parse().opto();
assertEquals("return 5;", code.print());
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter09Test.java b/src/test/java/com/seaofnodes/simple/Chapter09Test.java
index 551880b1..54a14a25 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter09Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter09Test.java
@@ -126,9 +126,10 @@ while(v1+arg) {
v0=1;
v1=v2;
}
+return 0;
""");
code.parse().opto();
- assertEquals("Stop[ ]", code.print()); // No explicit return: omit default main.
+ assertEquals("return 0;", code.print());
}
@Test
@@ -208,9 +209,9 @@ return -0+0+0;
@Test
public void testFuzz3() {
- CodeGen code = new CodeGen("int v0=0; while(0==69) while(v0) return 0;");
+ CodeGen code = new CodeGen("int v0=0; while(0==69) while(v0) return 0; return 0;");
code.parse().opto();
- assertEquals("Stop[ ]", code.print()); // The only return is unreachable.
+ assertEquals("return 0;", code.print());
}
@Test
@@ -254,9 +255,10 @@ return 0!=0;
int v0=0;
while(0==1) while(v0)
v0=1+v0;
+return 0;
""");
code.parse().opto();
- assertEquals("Stop[ ]", code.print());
+ assertEquals("return 0;", code.print());
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/src/test/java/com/seaofnodes/simple/Chapter10Test.java
index bcb73eb9..0f4ca169 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter10Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter10Test.java
@@ -37,7 +37,8 @@ public class Chapter10Test {
"if (null != p) return p.x; return -1;",
"if (!!!!p) return p.x; return -1;",
"if (!!!p) return -1; return p.x;",
- "int b = !!p; if (b) return p.x + b - 1; return -1;"
+ "int b = !!p; if (b) return p.x + b - 1; return -1;",
+ "if (!(p == null || arg == 0)) return p.x; return -1;"
} ) {
CodeGen code = new CodeGen(NULLABLE_POINT_SOURCE+body).parse().opto().typeCheck();
assertEquals(body,"-1",Eval2.eval(code,0));
@@ -46,6 +47,21 @@ public class Chapter10Test {
}
@Test
+ public void testShortCircuitGuardScheduling() {
+ // The call result exists only on the RHS path, not above the merge.
+ CodeGen code = new CodeGen("""
+ val f = { int n -> (n+1)&7; };
+ int x = 0;
+ if (!!(arg && (x=f(arg)))) return x;
+ return -1;
+ """).driver(CodeGen.Phase.TypeCheck);
+ assertEquals("-1",Eval2.eval(code,0));
+ assertEquals("2",Eval2.eval(code,1));
+ assertEquals("-1",Eval2.eval(code,7));
+ code.driver(CodeGen.Phase.LocalSched);
+ }
+
+ @Test
public void testNullGuardErrors() {
for( String body : new String[] {
"return p.x;",
@@ -173,7 +189,7 @@ if (arg) bar = null;
bar.a = 1;
return bar.a;
""");
- try { code.parse().opto(); fail(); }
+ try { code.parse().opto().typeCheck(); fail(); }
catch( Exception e ) { assertEquals("Type null is not of declared type *Bar",e.getMessage()); }
}
@@ -194,12 +210,12 @@ return bar.a;
public void testIf3() {
CodeGen code = new CodeGen("""
struct Bar { int a; };
-Bar bar = null;
+!Bar !bar = null;
if (arg) bar = null;
bar.a = 1;
return bar.a;
""");
- try { code.parse(); fail(); }
+ try { code.parse().opto().typeCheck(); fail(); }
catch( Exception e ) { assertEquals("Type null is not of declared type *Bar", e.getMessage()); }
}
@@ -348,7 +364,7 @@ return new s0;
int v0=null.f0;
""");
try { code.parse(); fail(); }
- catch( Exception e ) { assertEquals("Accessing unknown field 'f0' from 'null'",e.getMessage()); }
+ catch( Exception e ) { assertEquals("Syntax error, expected ;: .",e.getMessage()); }
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
index 439333ca..3d5d2686 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter11Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter11Test.java
@@ -53,7 +53,7 @@ public class Chapter11Test {
// Seed 97 exposed a store selecting a bulk predecessor without queuing
// it. Keep both the worklist assertion and the final heap check.
for (int seed : new int[]{0,97,123,456}) {
- var code = new CodeGen(Chapter10Test.NESTED_MEMORY,com.seaofnodes.simple.type.TypeInteger.BOT,seed).parse();
+ var code = new CodeGen(Chapter10Test.NESTED_MEMORY,com.seaofnodes.simple.type.TypeInteger.BOT,seed,false).parse();
code.opto();
assertEquals("S{x=9,y=25,z=17}",Eval2.eval(code,4));
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/src/test/java/com/seaofnodes/simple/Chapter12Test.java
index d8b072a2..ac3b81ec 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter12Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter12Test.java
@@ -42,22 +42,22 @@ return head.next.i;
public void testLinkedList1() {
CodeGen code = new CodeGen(
"""
-struct LLI { !LLI? !next; int i; };
+struct LLI { !LLI? !next; int q; };
!LLI? !head = null;
while( arg ) {
!LLI !x = new LLI;
x.next = head;
- x.i = arg;
+ x.q = arg;
head = x;
arg = arg-1;
}
if( !head ) return 0;
LLI? next = head.next;
if( next==null ) return 1;
-return next.i;
+return next.q;
""");
- code.parse().opto();
- assertEquals("return Phi(Region,0,1,.i);", code.print());
+ code.parse().opto().typeCheck();
+ assertEquals("return Phi(Region,0,1,.q);", code.print());
assertEquals("2", Eval2.eval(code, 3));
}
@@ -110,10 +110,10 @@ return n.next;
"""
struct M { int m; };
struct N { !M !next; int i; };
-N n = new N { next = null; }
+N n = new N { next = null; };
return n.next;
""");
- try { code.parse().opto(); fail(); }
+ try { code.parse().opto().typeCheck(); fail(); }
catch( Exception e ) { assertEquals("Type null is not of declared type *M",e.getMessage()); }
}
@@ -126,7 +126,7 @@ struct N { !N? !next; int i; };
n.i = 3.14;
return n.i;
""");
- code.parse().opto();
+ code.parse().opto().typeCheck();
assertEquals("3",Eval2.eval(code,0));
}
@@ -134,7 +134,7 @@ return n.i;
public void testNullRef4() {
CodeGen code = new CodeGen("return -null-5/null-5;");
try { code.parse().opto().typeCheck(); fail(); }
- catch( Exception e ) { assertEquals("Cannot '+' null",e.getMessage()); }
+ catch( Exception e ) { assertEquals("Cannot '//' null",e.getMessage()); }
}
@Test public void testNullRef5() {
@@ -182,7 +182,7 @@ return new S1.s=new S2;
public void testcheckNull() {
CodeGen code = new CodeGen(
"""
-struct I {int i;};
+struct I { int i; };
struct P { !I? !pi; };
!P !p1 = new P;
!P !p2 = new P;
@@ -199,32 +199,52 @@ return p1.pi.i + 1;
public void testCoRecur2() {
CodeGen code = new CodeGen(
"""
-struct A { !L? !a; !T? !b; !F? !c; }; !A? !a = new A;
-struct B { !M? !a; !U? !b; !G? !c; }; !B? !b = new B;
-struct C { !N? !a; !V? !b; !H? !c; }; !C? !c = new C;
-struct D { !O? !a; !W? !b; !I? !c; }; !D? !d = new D;
-struct E { !P? !a; !X? !b; !J? !c; }; !E? !e = new E;
-struct F { !Q? !a; !Y? !b; !K? !c; }; !F? !f = new F;
-struct G { !R? !a; !Z? !b; !L? !c; }; !G? !g = new G;
-struct H { !S? !a; !A? !b; !M? !c; }; !H? !h = new H;
-struct I { !T? !a; !B? !b; !N? !c; }; !I? !i = new I;
-struct J { !U? !a; !C? !b; !O? !c; }; !J? !j = new J;
-struct K { !V? !a; !D? !b; !P? !c; }; !K? !k = new K;
-struct L { !W? !a; !E? !b; !Q? !c; }; !L? !l = new L;
-struct M { !X? !a; !F? !b; !R? !c; }; !M? !m = new M;
-struct N { !Y? !a; !G? !b; !S? !c; }; !N? !n = new N;
-struct O { !Z? !a; !H? !b; !T? !c; }; !O? !o = new O;
-struct P { !A? !a; !I? !b; !U? !c; }; !P? !p = new P;
-struct Q { !B? !a; !J? !b; !V? !c; }; !Q? !q = new Q;
-struct R { !C? !a; !K? !b; !W? !c; }; !R? !r = new R;
-struct S { !D? !a; !L? !b; !X? !c; }; !S? !s = new S;
-struct T { !E? !a; !M? !b; !Y? !c; }; !T? !t = new T;
-struct U { !F? !a; !N? !b; !Z? !c; }; !U? !u = new U;
-struct V { !G? !a; !O? !b; !A? !c; }; !V? !v = new V;
-struct W { !H? !a; !P? !b; !B? !c; }; !W? !w = new W;
-struct X { !I? !a; !Q? !b; !C? !c; }; !X? !x = new X;
-struct Y { !J? !a; !R? !b; !D? !c; }; !Y? !y = new Y;
-struct Z { !K? !a; !S? !b; !E? !c; }; !Z? !z = new Z;
+struct A { !B? !f0; !C? !f1; }; !A !a = new A;
+struct B { !C? !f0; !A? !f1; }; !B !b = new B;
+struct C { !A? !f0; !B? !f1; }; !C !c = new C;
+
+a.f0=b; a.f1=c;
+b.f0=c; b.f1=a;
+c.f0=a; c.f1=b;
+
+return a.f0.f1.f0.f1.f0;
+
+""");
+ code.parse().opto().typeCheck().GCM().localSched();
+ assertEquals("return B;", code._stop.toString());
+ assertEquals("B{f0=C},f1=A{f0=$cyclic,f1=$cyclic}}", Eval2.eval(code, 0));
+ }
+
+ @Test
+ public void testCoRecur3() {
+ CodeGen code = new CodeGen(
+"""
+struct A { !L? !a; !T? !b; !F? !c; }; !A !a = new A;
+struct B { !M? !a; !U? !b; !G? !c; }; !B !b = new B;
+struct C { !N? !a; !V? !b; !H? !c; }; !C !c = new C;
+struct D { !O? !a; !W? !b; !I? !c; }; !D !d = new D;
+struct E { !P? !a; !X? !b; !J? !c; }; !E !e = new E;
+struct F { !Q? !a; !Y? !b; !K? !c; }; !F !f = new F;
+struct G { !R? !a; !Z? !b; !L? !c; }; !G !g = new G;
+struct H { !S? !a; !A? !b; !M? !c; }; !H !h = new H;
+struct I { !T? !a; !B? !b; !N? !c; }; !I !i = new I;
+struct J { !U? !a; !C? !b; !O? !c; }; !J !j = new J;
+struct K { !V? !a; !D? !b; !P? !c; }; !K !k = new K;
+struct L { !W? !a; !E? !b; !Q? !c; }; !L !l = new L;
+struct M { !X? !a; !F? !b; !R? !c; }; !M !m = new M;
+struct N { !Y? !a; !G? !b; !S? !c; }; !N !n = new N;
+struct O { !Z? !a; !H? !b; !T? !c; }; !O !o = new O;
+struct P { !A? !a; !I? !b; !U? !c; }; !P !p = new P;
+struct Q { !B? !a; !J? !b; !V? !c; }; !Q !q = new Q;
+struct R { !C? !a; !K? !b; !W? !c; }; !R !r = new R;
+struct S { !D? !a; !L? !b; !X? !c; }; !S !s = new S;
+struct T { !E? !a; !M? !b; !Y? !c; }; !T !t = new T;
+struct U { !F? !a; !N? !b; !Z? !c; }; !U !u = new U;
+struct V { !G? !a; !O? !b; !A? !c; }; !V !v = new V;
+struct W { !H? !a; !P? !b; !B? !c; }; !W !w = new W;
+struct X { !I? !a; !Q? !b; !C? !c; }; !X !x = new X;
+struct Y { !J? !a; !R? !b; !D? !c; }; !Y !y = new Y;
+struct Z { !K? !a; !S? !b; !E? !c; }; !Z !z = new Z;
a.a=l; a.b=t; a.c=f;
b.a=m; b.b=u; b.c=g;
@@ -258,7 +278,6 @@ return a.b.c.a.b.c.a.b.c.a.b.c.a.b.c.a.b.c;
""");
code.parse().opto().typeCheck().GCM().localSched();
assertEquals("return R;", code._stop.toString());
- assertEquals("R{a=C{a=N{a=Y{a=J{a=U{a=F{a=Q{a=B{a=M{a=X{a=I{a=T{a=E{a=P{a=A{a=L{a=W{a=H{a=S{a=D{a=O{a=Z{a=K{a=V{a=G{a=$cyclic,b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic}", Eval2.eval(code, 0));
+ assertEquals("R{a=C{a=N},b=V},c=H}},b=K{a=$cyclic,b=D{a=O},b=W},c=I}},c=P}},c=$cyclic}", Eval2.eval(code, 0));
}
-
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/src/test/java/com/seaofnodes/simple/Chapter13Test.java
index 66e12e42..63f1d12c 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter13Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter13Test.java
@@ -22,7 +22,7 @@ while(---- -arg) {
}
}
{
- int kzEl_r7EYz=3*----0!=-arg<(37*--97!=0/arg==arg)<=-(--arg!=0);
+ int kzEl_r7EYz = (3*----0!=-arg) < (37*--97!=0/arg==arg) <= -(--arg!=0);
while(kzEl_r7EYz<---1) {
kzEl_r7EYz=kzEl_r7EYz+kzEl_r7EYz*arg>=24;
if(7) continue;
diff --git a/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/src/test/java/com/seaofnodes/simple/Chapter15Test.java
index 074cd8ba..d0a42ccf 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter15Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter15Test.java
@@ -4,8 +4,8 @@ import com.seaofnodes.simple.codegen.CodeGen;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import org.junit.Ignore;
import org.junit.Test;
+import org.junit.Ignore;
import static org.junit.Assert.*;
public class Chapter15Test {
@@ -51,7 +51,7 @@ output[i] = 1;
return output;
""");
code.parse().opto();
- assertEquals("return [u8];", code.print());
+ assertEquals("return []u8;", code.print());
assertEquals("\u0001", Eval2.eval(code, 0));
}
@@ -103,8 +103,8 @@ struct A { int i; };
return a;
""");
code.parse().opto();
- assertEquals("return [*A?];", code.print());
- assertEquals("*A {int !i; }?[ null,null]", Eval2.eval(code, 0));
+ assertEquals("return []*A?;", code.print());
+ assertEquals("*A {i64 !i; }?[ null,null]", Eval2.eval(code, 0));
}
@Test
@@ -176,7 +176,7 @@ return root;
""");
code.parse().opto();
assertEquals("return Tree;", code.print());
- assertEquals("Tree{_kids=*Tree?[ Tree{_kids=null},null]}", Eval2.eval(code, 0));
+ assertEquals("Tree{_kids=*Tree {*[]*Tree?? !_kids; }?[ Tree{_kids=null},null]}", Eval2.eval(code, 0));
}
@Test
@@ -214,12 +214,12 @@ return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6
assertEquals("1006", Eval2.eval(code, 4));
}
- @Test
+ @Test @Ignore
public void sieveOEratosthenes() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/sieve.smp"));
CodeGen code = new CodeGen(src+"return sieve(arg);");
code.parse().opto();
- assertEquals("return [u32];", code.print());
+ assertEquals("return []u32;", code.print());
assertEquals("u32[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
@@ -256,9 +256,10 @@ return new flt;
CodeGen code = new CodeGen(
"""
flt is = new int[2];
+return is;
""");
- try { code.parse().opto(); fail(); }
- catch( Exception e ) { assertEquals("Type *[int] is not of declared type flt",e.getMessage()); }
+ try { code.parse().opto().typeCheck(); fail(); }
+ catch( Exception e ) { assertEquals("Type *[]i64 is not of declared type flt",e.getMessage()); }
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter16Test.java b/src/test/java/com/seaofnodes/simple/Chapter16Test.java
index 362388d6..f73cbf57 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter16Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter16Test.java
@@ -1,8 +1,6 @@
package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.CodeGen;
-import com.seaofnodes.simple.evaluator.Evaluator;
-import com.seaofnodes.simple.node.StopNode;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
diff --git a/src/test/java/com/seaofnodes/simple/Chapter17aTest.java b/src/test/java/com/seaofnodes/simple/Chapter17aTest.java
index 16ffe967..8597b799 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter17aTest.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter17aTest.java
@@ -1,8 +1,6 @@
package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.CodeGen;
-import com.seaofnodes.simple.evaluator.Evaluator;
-import com.seaofnodes.simple.node.StopNode;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -51,7 +49,7 @@ return p;
public void testStructFinal1() {
CodeGen code = new CodeGen("""
struct Point { int x=3, y=4; };
-Point p = new Point { x=5; y=6; };
+~Point p = new Point { x=5; y=6; };
p.x++;
return p;
""");
@@ -63,7 +61,7 @@ return p;
public void testStructFinal2() {
CodeGen code = new CodeGen("""
struct Point { int x=3, y=4; };
-Point p = new Point;
+~Point p = new Point;
p.x++;
return p;
""");
@@ -88,8 +86,8 @@ Point p = new Point;
p.x++;
return p;
""");
- try { code.parse().opto(); fail(); }
- catch( Exception e ) { assertEquals("Cannot reassign final 'x'",e.getMessage()); }
+ try { code.parse().opto().typeCheck(); fail(); }
+ catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter17bTest.java b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
index e8f6e0bd..24dc0229 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
@@ -125,7 +125,7 @@ return s.x;
@Test public void testInt10() {
CodeGen code = new CodeGen("flt x = 1.5; x++; int i = x; return i;");
- code.parse().opto();
+ code.parse().opto().typeCheck();
assertEquals("2",Eval2.eval(code,0));
}
@@ -172,13 +172,13 @@ return s.x;
}
@Test public void testVar6() {
- CodeGen code = new CodeGen("struct S{int x;}; S s=new S; s.x++; return s.x; // Error initializer so x is immutable ");
+ CodeGen code = new CodeGen("struct S{int x;}; ~S s = new S; s.x++; return s.x; // Error initializer so x is immutable ");
try { code.parse().opto().typeCheck(); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@Test public void testVar7() {
- CodeGen code = new CodeGen("struct S{int x;}; S s=new S{x=3;}; s.x++; return s.x; // Error initializer so x is immutable ");
+ CodeGen code = new CodeGen("struct S{int x;}; ~S s = new S{x=3;}; s.x++; return s.x; // Error initializer so x is immutable ");
try { code.parse().opto().typeCheck(); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@@ -216,6 +216,7 @@ foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable
~Foo xfoo = foo; // Throw away mutability
xfoo.bar.x++; // Error, cannot mutate through xfoo
+return xfoo.bar.x;
""");
try { code.parse().opto().typeCheck(); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
@@ -276,7 +277,7 @@ return new A {
if (arg) b = new B; // Constructor ends with partial init of b
}.b;
""");
- try { code.parse().opto(); fail(); }
+ try { code.parse(); fail(); }
catch( Exception e ) { assertEquals("'A' is not fully initialized, field 'b' needs to be set in a constructor",e.getMessage()); }
}
@@ -286,7 +287,7 @@ return new A {
"""
struct S{};
val x = 1;
-val s = new S{x = 2;};
+~S s = new S{x = 2;};
return x;
"""
);
@@ -309,7 +310,7 @@ focus(me);
return me;
"""
);
- try { code.parse().opto().typeCheck(); fail(); }
+ try { code.parse(); fail(); }
catch( Exception e ) { assertEquals("Syntax error, expected =expression: ;",e.getMessage()); }
}
@@ -493,15 +494,15 @@ return new A;
@Test
public void testForward1() {
CodeGen code = new CodeGen("""
-struct A{
+struct A {
!B?[]? !nil_array_of_b;
- !B?[] not_array_of_b = new !B?[0];
+ !B?[] !array_of_b;
};
-return new A.not_array_of_b;
+return new A{array_of_b = new !B?[0]; }.array_of_b;
""");
code.parse().opto();
- assertEquals("return [*B?];", code.print());
- assertEquals("*B?[]", Eval2.eval(code,0));
+ assertEquals("return []*B?;", code.print());
+ assertEquals("*B {... }?[]", Eval2.eval(code,0));
}
// ---------------------------------------------------------------
@@ -550,8 +551,8 @@ for( int j=0; j<nprimes; j++ )
return rez;
""");
code.parse().opto().typeCheck().GCM();
- assertEquals("return [int];", code.print());
- assertEquals("int[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
+ assertEquals("return []i64;", code.print());
+ assertEquals("i64[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index 6eb4d6f4..902344ed 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -102,13 +102,13 @@ public class Chapter18Test {
@Test public void testPrintingForwardReferenceScope() throws Exception {
new CodeGen("return 0;").parse();
- var declared = TypeMemPtr.make(TypeStruct.makeFRef("PrintForward"));
+ var declared = TypeMemPtr.make(TypeStruct.open("PrintForward"));
var scope = new ScopeNode();
scope.define("ptr",declared,false,new ConstantNode(TypeInteger.ZERO),null);
- Parser.TYPES.put("PrintForward",TypeMemPtr.make(TypeStruct.make("PrintForward")));
+ Parser.TYPES.put("PrintForward",TypeMemPtr.make(TypeStruct.make("PrintForward",false)));
var field = Var.class.getDeclaredField("_type");
field.setAccessible(true);
- var v = scope._vars.get(0);
+ var v = scope.var(0);
org.junit.Assert.assertSame(declared,field.get(v));
scope.toString();
org.junit.Assert.assertSame(declared,field.get(v));
@@ -171,7 +171,7 @@ return x2;
};
""");
code.parse().opto();
- assertEquals("return (Parm_x(sq,int)*x);", code._stop.toString());
+ assertEquals("return (Parm_x(sq,i64)*x);", code._stop.toString());
//assertEquals("{ int -> int #1}", Eval2.eval(code, 3));
}
@@ -185,7 +185,7 @@ var sq = { int x ->
return sq(arg)+sq(3);
""");
code.driver(Phase.LocalSched);
- assertEquals("Stop[ return (Parm_x(sq,int)*x); return (#2+#2); ]", code._stop.toString());
+ assertEquals("Stop[ return (#2+#2); return (Parm_x(sq,i64)*x); ]", code._stop.toString());
assertEquals("13", Eval2.eval(code, 2));
}
@@ -223,7 +223,7 @@ var fcn = arg ? { int x -> x*x; } : { int x -> x+x; };
return fcn(3);
""");
code.parse().opto();
- assertEquals("Stop[ return (Parm_x($fun2,int,3)<<1); return (Parm_x($fun1,int,3)*x); return #2; ]", code._stop.toString());
+ assertEquals("Stop[ return #2; return (Parm_x($fun21,i64,3)*x); return (Parm_x($fun22,i64,3)<<1); ]", code._stop.toString());
assertEquals("6", Eval2.eval(code, 0));
assertEquals("9", Eval2.eval(code, 1));
}
@@ -233,7 +233,7 @@ return fcn(3);
public void testFcn5() {
CodeGen code = new CodeGen("val fact = { int x -> x <= 1 ? 1 : x*fact(x-1); }; return fact(arg);");
code.parse().opto().typeCheck();
- assertEquals("Stop[ return Phi(Region,1,(Parm_x(fact,int,arg,(x-1))*#2)); return #2; ]", code._stop.toString());
+ assertEquals("Stop[ return #2; return Phi(Region,1,(Parm_x(fact,i64,arg,(x-1))*#2)); ]", code._stop.toString());
assertEquals( "1", Eval2.eval(code, 0));
assertEquals( "1", Eval2.eval(code, 1));
assertEquals( "2", Eval2.eval(code, 2));
@@ -265,7 +265,7 @@ val g = {->2;};
return 2;
""");
code.parse().opto().typeCheck().GCM();
- assertEquals("Stop[ return 2; return 1; return 1; ]", code._stop.toString());
+ assertEquals("Stop[ return 1; return 1; return 2; ]", code._stop.toString());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -283,7 +283,7 @@ for(;;) {
}
""");
code.driver(Phase.LocalSched);
- assertEquals("Stop[ return Parm_i(x,int); return #2; ]", code._stop.toString());
+ assertEquals("Stop[ return #2; return Parm_i(x,i64); ]", code._stop.toString());
assertEquals("3", Eval2.eval(code, 0));
}
@@ -359,7 +359,7 @@ for(;;) {
return 0;
""");
try { code.parse().opto().typeCheck(); fail(); }
- catch( Exception e ) { assertEquals("Might be null calling { int -> int #1}?",e.getMessage()); }
+ catch( Exception e ) { assertEquals("Might be null calling { i64 -> i64 #21}?",e.getMessage()); }
}
@@ -455,7 +455,7 @@ if (i2i) return i2i(arg);
return f2f(o)(1);
""");
code.driver(Phase.LocalSched);
- assertEquals("Stop[ return Parm_i(i2i.o,int); return Phi(Region,#2,1); ]", code._stop.toString());
+ assertEquals("Stop[ return Phi(Region,#2,1); return Parm_i(i2i.o,i64); ]", code._stop.toString());
assertEquals("1", Eval2.eval(code, 2));
}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/src/test/java/com/seaofnodes/simple/Chapter19Test.java
index 4564e513..23b45e46 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter19Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter19Test.java
@@ -15,7 +15,7 @@ import static org.junit.Assert.*;
public class Chapter19Test {
@Test public void testPrintingFunctionLookup() {
var code = new CodeGen("return 0;").parse();
- var tfp = TypeFunPtr.make((byte)2,TypeTuple.make(TypeInteger.constant(987654)),TypeInteger.constant(123456),1L<<30);
+ var tfp = TypeFunPtr.make((byte)2,false,new Type[]{TypeInteger.constant(987654)},TypeInteger.constant(123456),1L<<30);
var con = new ConstantNode(tfp);
var call = new CallNode(null,code._start,con,con);
// Diagnostic lookup may construct/intern the return-erased linker key.
@@ -49,7 +49,7 @@ return 0;
public void testString() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
CodeGen code = new CodeGen(src).parse().opto().typeCheck().GCM().localSched();
- assertEquals("Stop[ return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); return Phi(Region,1,0,0,1); ]", code._stop.toString());
+ assertEquals("Stop[ return Phi(Region,1,0,0,1); return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); ]", code._stop.toString());
//assertEquals("-4898613127354160978", Eval2.eval(code, 2));
}
@@ -327,7 +327,7 @@ return A[1];
public void sieveOfEratosthenes() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/sieve.smp"));
CodeGen code = new CodeGen(src).driver(Phase.LocalSched,"x86_64_v2", "SystemV");
- assertEquals("return [u32];", code.print());
+ assertEquals("return []u32;", code.print());
//assertEquals("u32[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
@@ -340,7 +340,7 @@ val fcn = arg ? { int x -> x*x; } : { int x -> x+x; };
return fcn(2)*10 + fcn(3);
""");
code.driver(Phase.LocalSched,"x86_64_v2", "SystemV");
- assertEquals("Stop[ return (shli,Parm_x($fun2,int)); return (mul,Parm_x($fun1,int),x); return (add,#2,(muli,#2)); ]", code.print());
+ assertEquals("Stop[ return (add,#2,(muli,#2)); return (mul,Parm_x($fun21,i64),x); return (shli,Parm_x($fun22,i64)); ]", code.print());
}
@Test
@@ -351,7 +351,7 @@ val sq = { int x -> x*x; };
return sq(arg) + sq(3);
""");
code.driver(Phase.LocalSched,"x86_64_v2", "SystemV");
- assertEquals("Stop[ return (mul,Parm_x(sq,int),x); return (add,#2,#2); ]", code.print());
+ assertEquals("Stop[ return (add,#2,#2); return (mul,Parm_x(sq,i64),x); ]", code.print());
}
@Test public void testSelectedMemory() {
diff --git a/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/src/test/java/com/seaofnodes/simple/Chapter20Test.java
index 3575e461..08a23ef0 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter20Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter20Test.java
@@ -71,7 +71,7 @@ return f(s);
// The entry of g can disappear before its Return is folded into f.
// Exercise both worklist orders; deleting the entry does not kill 123.
for( int seed=0; seed<64; seed++ ) {
- CodeGen code = new CodeGen(src,com.seaofnodes.simple.type.TypeInteger.BOT,seed).parse().opto().typeCheck();
+ CodeGen code = new CodeGen(src,com.seaofnodes.simple.type.TypeInteger.BOT,seed,true).parse().opto().typeCheck();
assertEquals("seed "+seed, "123", Eval2.eval(code,0));
}
}
@@ -121,9 +121,9 @@ return f(s);
}
@Test public void testAlloc0() {
- testTarget("return new u8[arg];","x86_64_v2","SystemV",4,"return [u8];");
- testTarget("return new u8[arg];","riscv","SystemV",5,"return [u8];");
- testTarget("return new u8[arg];","arm","SystemV",5,"return [u8];");
+ testTarget("return new u8[arg];","x86_64_v2","SystemV",4,"return []u8;");
+ testTarget("return new u8[arg];","riscv","SystemV",5,"return []u8;");
+ testTarget("return new u8[arg];","arm","SystemV",5,"return []u8;");
}
@Test public void testBasic1() {
@@ -238,14 +238,9 @@ s.cs[0] = 67; // C
s.cs[1] = 108; // l
hashCode(s);
""";
- // Without an explicit return, default main must be removed completely.
- // Seed 0 previously left a loop with a missing branch successor.
- for( String cpu : new String[]{"x86_64_v2","riscv","arm"} )
- new CodeGen(src,com.seaofnodes.simple.type.TypeInteger.BOT,0)
- .driver(CodeGen.Phase.Encoding,cpu,"SystemV");
- testTarget(src,"x86_64_v2", "SystemV",0,null);
- testTarget(src,"riscv" , "SystemV",1,null);
- testTarget(src,"arm" , "SystemV",0,null);
+ testTarget(src,"x86_64_v2", "SystemV",9,null);
+ testTarget(src,"riscv" , "SystemV",4,null);
+ testTarget(src,"arm" , "SystemV",1,null);
}
@Test
diff --git a/src/test/java/com/seaofnodes/simple/Chapter21AllocTest.java b/src/test/java/com/seaofnodes/simple/Chapter21AllocTest.java
index b81483d8..bab7a86a 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter21AllocTest.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter21AllocTest.java
@@ -46,7 +46,7 @@ return sqrt(arg) + sqrt(arg+2);
@Test
public void testString() throws IOException {
- String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash21.smp"));
Chapter21Test.testCPU(src,"x86_64_v2", "SystemV", 9,null);
Chapter21Test.testCPU(src,"riscv" , "SystemV", 3,null);
Chapter21Test.testCPU(src,"arm" , "SystemV", 1,null);
diff --git a/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 2c91de0d..30d22fc9 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -8,6 +8,7 @@ import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.cpus.arm.arm;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
+import com.seaofnodes.simple.util.SB;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -150,6 +151,30 @@ public class Chapter21Test {
assertTrue("Ordinary calls must survive optimization",checkArmCalls(src,"run",4,27)>0);
}
+ @Test public void testArmVectorGrowth() throws IOException {
+ String src = """
+ struct _Vec {
+ u32 !len;
+ int[] !buf;
+ val grow = { int sz ->
+ var buf2 = new int[sz];
+ for( int i=0; i<len; i++ ) buf2[i]=buf[i];
+ buf=buf2;
+ };
+ val add = { int e ->
+ if( len>=buf# ) grow(buf#*2);
+ buf[len++]=e;
+ return self;
+ };
+ };
+ val run = { int arg ->
+ val v = new _Vec{buf=new int[4];}.add(2).add(3).add(5).add(7).add(11);
+ return v.len*100+v.buf[arg];
+ };
+ """;
+ checkArmCalls(src,"run",4,511);
+ }
+
private static int checkArmCalls(String src, String entryName, int arg, int result) throws IOException {
CodeGen code = new CodeGen(src).driver("arm","SystemV",null);
byte[] image = new byte[1<<20];
@@ -192,19 +217,8 @@ public class Chapter21Test {
}
- @Test public void testArmSubtractRegisters() {
- EvalArm64 cpu = new EvalArm64(new byte[16],16);
- cpu.st4(0,0xCB020020); // SUB X0,X1,X2, no shift or flag update.
- for( long[] pair : new long[][]{{7,3},{3,7},{Long.MIN_VALUE,1},{1L<<40,3}} ) {
- cpu._pc = 0;
- cpu.regs[1] = pair[0]; cpu.regs[2] = pair[1];
- cpu.N=true; cpu.Z=false; cpu.C=true; cpu.V=true;
- assertEquals(0,cpu.step(1));
- assertEquals(pair[0]-pair[1],cpu.regs[0]);
- assertTrue(cpu.N); assertFalse(cpu.Z); assertTrue(cpu.C); assertTrue(cpu.V);
- }
- }
-
+ @Test public void testCoalescing() { com.seaofnodes.simple.codegen.RegAllocTestSupport.coalescing(); }
+ @Test public void testCopyForward() throws Exception { com.seaofnodes.simple.codegen.RegAllocTestSupport.copyForward(); }
@Test public void testNarrowStores() throws IOException {
for( String type : new String[]{"i8","u8","i16","u16"} ) {
@@ -252,8 +266,20 @@ public class Chapter21Test {
fail("A failing native program must fail the test, even with empty stdout");
}
- @Test public void testCoalescing() { com.seaofnodes.simple.codegen.RegAllocTestSupport.coalescing(); }
- @Test public void testCopyForward() throws Exception { com.seaofnodes.simple.codegen.RegAllocTestSupport.copyForward(); }
+ @Test public void testArmSubtractRegisters() {
+ EvalArm64 cpu = new EvalArm64(new byte[16],16);
+ cpu.st4(0,0xCB020020); // SUB X0,X1,X2, no shift or flag update.
+ for( long[] pair : new long[][]{{7,3},{3,7},{Long.MIN_VALUE,1},{1L<<40,3}} ) {
+ cpu._pc = 0;
+ cpu.regs[1] = pair[0]; cpu.regs[2] = pair[1];
+ cpu.N=true; cpu.Z=false; cpu.C=true; cpu.V=true;
+ assertEquals(0,cpu.step(1));
+ assertEquals(pair[0]-pair[1],cpu.regs[0]);
+ assertTrue(cpu.N); assertFalse(cpu.Z); assertTrue(cpu.C); assertTrue(cpu.V);
+ }
+ }
+
+
@Test public void testRisc64BitStore() {
byte[] mem = new byte[24];
EvalRisc5 cpu = new EvalRisc5(mem,mem.length);
@@ -283,6 +309,7 @@ public class Chapter21Test {
}
+ // Enabled in Chapter 23; measured there by Chapter23AllocTest.
@Test @Ignore
public void testJig() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/jig.smp"));
@@ -389,7 +416,7 @@ public class Chapter21Test {
String sprimes = sb.p("]").toString();
// Compile, link against native C; expect the above string of primes to be printed out by C
- TestC.run("sieve",sprimes, 185);
+ TestC.run("sieve",sprimes, 186);
// Evaluate on RISC5 emulator; expect return of an array of primes in
// the simulated heap.
@@ -405,7 +432,7 @@ public class Chapter21Test {
// Evaluate on ARM5 emulator; expect return of an array of primes in
// the simulated heap.
- EvalArm64 A5 = TestArm64.build("sieve", 100, 91, false);
+ EvalArm64 A5 = TestArm64.build("sieve", 100, 94, false);
int trap_arm = A5.step(10000);
assertEquals(0, trap_arm);
int ary_arm = (int)A5.regs[arm.X0];
@@ -419,14 +446,14 @@ public class Chapter21Test {
String fib = "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]";
TestC.run("fib", fib, 24);
- EvalRisc5 R5 = TestRisc5.build("fib", 9, 16, false);
+ EvalRisc5 R5 = TestRisc5.build("fib", 9, 17, false);
int trap = R5.step(100);
assertEquals(0,trap);
// Return register A0 holds fib(8)==55
assertEquals(55,R5.regs[riscv.A0]);
// arm
- EvalArm64 A5 = TestArm64.build("fib", 9, 16, false);
+ EvalArm64 A5 = TestArm64.build("fib", 9, 17, false);
int trap_arm = A5.step(100);
assertEquals(0,trap_arm);
// Return register X0 holds fib(8)==55
diff --git a/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/src/test/java/com/seaofnodes/simple/Chapter22Test.java
index 2d94b8f0..ea210e3f 100644
--- a/src/test/java/com/seaofnodes/simple/Chapter22Test.java
+++ b/src/test/java/com/seaofnodes/simple/Chapter22Test.java
@@ -84,7 +84,7 @@ public class Chapter22Test {
val test_cmp={->return c_i32()==-1;};
""";
for( String conv : new String[]{"SystemV","Win64"} )
- TestC.run(src,conv,conv.equals("SystemV") ? "sysv_abi" : "ms_abi",
+ TestC.run(src,conv,com.seaofnodes.simple.type.TypeInteger.BOT,conv.equals("SystemV") ? "sysv_abi" : "ms_abi",
"src/test/java/com/seaofnodes/simple/progs/c_returns.c",
"build/objs/c_returns"+conv,"S","",-1);
}
@@ -108,7 +108,7 @@ public class Chapter22Test {
assertEquals(0,cpu.step(1000));
assertEquals(0,cpu._pc);
cpu._pc = (int)cpu.regs[riscv.A0]; // Call the returned address.
- cpu.regs[riscv.A0] = 0x2000;
+ cpu.regs[library ? riscv.A1 : riscv.A0] = 0x2000; // Methods also receive self.
assertEquals(0,cpu.step(1000));
assertEquals(0,cpu._pc);
if( library ) assertEquals("ok",cpu._stdout.toString());
@@ -119,7 +119,7 @@ public class Chapter22Test {
assertEquals(0,cpu.step(1000));
assertEquals(0,cpu._pc);
cpu._pc = (int)cpu.regs[0];
- cpu.regs[0] = 0x2000;
+ cpu.regs[library ? 1 : 0] = 0x2000;
assertEquals(0,cpu.step(1000));
assertEquals(0,cpu._pc);
if( library ) assertEquals("ok",cpu._stdout.toString());
@@ -138,6 +138,7 @@ public class Chapter22Test {
"build/objs/funptr"+(TestC.OS.startsWith("Windows") ? ".exe" : "")));
}
+
@Test public void testRiscvRightShifts() {
// SRAI, SRLI, SRA, SRL: a0 = -32 shifted by 4.
int[] ops = {0x40455513,0x00455513,0x40b55533,0x00b55533};
@@ -185,7 +186,7 @@ public class Chapter22Test {
testCPU(src,"arm","SystemV",0,"return Top;");
}
-
+ // Enabled in Chapter 23; measured there by Chapter23AllocTest.
@Test @Ignore
public void testJig() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/jig.smp"));
@@ -351,7 +352,7 @@ return cc.cz;
@Test
public void testHelloWorld() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/helloWorld.smp"));
- TestC.run(src,TestC.CALL_CONVENTION,null,null,"build/objs/helloWorld","","Hello, World!",0);
+ TestC.run(src,TestC.CALL_CONVENTION,null, null,null,"build/objs/helloWorld","","Hello, World!",0);
// Evaluate on RISC5 emulator
EvalRisc5 R5 = TestRisc5.build("helloWorld", 0, 2, false);
@@ -392,7 +393,7 @@ return sum(is);
@Test @Ignore
public void testEcho() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/echo.smp"));
- TestC.run(src,TestC.CALL_CONVENTION,null,null,"build/objs/echo","","",0);
+ TestC.run(src,TestC.CALL_CONVENTION,null, null,null,"build/objs/echo","","",0);
// Evaluate on RISC5 emulator
EvalRisc5 R5 = TestRisc5.build("echo", 0, 2, false);
diff --git a/src/test/java/com/seaofnodes/simple/Chapter23AllocTest.java b/src/test/java/com/seaofnodes/simple/Chapter23AllocTest.java
new file mode 100644
index 00000000..f3cc7512
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/Chapter23AllocTest.java
@@ -0,0 +1,37 @@
+package com.seaofnodes.simple;
+
+import java.io.IOException;
+import java.nio.file.*;
+import org.junit.Ignore;
+import org.junit.Test;
+
+// Revised or newly enabled allocation examples in Chapter 23.
+public class Chapter23AllocTest {
+ @Test
+ public void testString() throws IOException {
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp"));
+ Chapter23Test.testCPU(src,"x86_64_v2", "SystemV", 9,null);
+ Chapter23Test.testCPU(src,"riscv" , "SystemV", 3,null);
+ Chapter23Test.testCPU(src,"arm" , "SystemV", 1,null);
+ }
+
+ @Ignore
+ @Test
+ public void testJig21() throws IOException {
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/jig.smp"));
+ Chapter23Test.testCPU(src,"x86_64_v2", "Win64" ,-1,null);
+ Chapter23Test.testCPU(src,"riscv" , "SystemV",-1,null);
+ Chapter23Test.testCPU(src,"arm" , "SystemV",-1,null);
+ }
+
+ @Ignore
+ @Test
+ public void testJig22() throws IOException {
+ String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/jig.smp"));
+ //String src = Files.readString(Path.of("docs/examples/BubbleSort.smp"));
+ Chapter23Test.testCPU(src,"x86_64_v2", "Win64" ,-1,null);
+ Chapter23Test.testCPU(src,"riscv" , "SystemV",-1,null);
+ Chapter23Test.testCPU(src,"arm" , "SystemV",-1,null);
+ }
+
+}
diff --git a/src/test/java/com/seaofnodes/simple/Chapter23Test.java b/src/test/java/com/seaofnodes/simple/Chapter23Test.java
new file mode 100644
index 00000000..0feaa5de
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/Chapter23Test.java
@@ -0,0 +1,319 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.isa.eval.EvalRisc5;
+
+import com.seaofnodes.isa.eval.EvalArm64;
+
+import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.*;
+
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.node.cpus.riscv.riscv;
+import com.seaofnodes.simple.type.TypeInteger;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class Chapter23Test {
+ @Test public void testPopularUses() { com.seaofnodes.simple.codegen.RegAllocTestSupport.popularUses(); }
+
+ @Test public void testDiagnosticTypeAccessors() throws Exception {
+ new CodeGen("return 0;").parse();
+ var tfp = TypeFunPtr.TEST;
+ var field = Type.class.getDeclaredField("VISIT");
+ field.setAccessible(true);
+ var visit = (java.util.Map<Object,Type>)field.get(null);
+ var marker = new Object();
+ visit.put(marker,Type.BOTTOM);
+ try {
+ assertEquals(0,TypeInteger.ZERO.alignment());
+ assertEquals(0,TypeInteger.ZERO.value());
+ org.junit.Assert.assertTrue(tfp._isConstant());
+ org.junit.Assert.assertSame(Type.BOTTOM,visit.get(marker));
+ assertEquals(1,visit.size());
+ } finally { visit.clear(); }
+ }
+
+
+ @Test
+ public void testOrRhsLoopLocal() throws IOException {
+ checkOrRhsLoop("""
+ struct S { int f; };
+ int x = 0;
+ int result = (arg & 1) || (new S {
+ while (x < 3) x++;
+ f = ++x;
+ }).f;
+ return x * 10 + result;
+ """);
+ }
+
+ @Test
+ public void testOrRhsLoopMemory() throws IOException {
+ checkOrRhsLoop("""
+ struct S { int f; };
+ !S !s = new S;
+ int result = (arg & 1) || (new S {
+ while (s.f < 3) s.f++;
+ s.f++;
+ f = s.f;
+ }).f;
+ return s.f * 10 + result;
+ """);
+ }
+
+ private static void checkOrRhsLoop(String src) throws IOException {
+ CodeGen code = new CheckedCodeGen(src).driver("riscv", "SystemV", null);
+ SpillStats.record(code,"Chapter23","riscv","SystemV");
+ for (int arg : new int[]{0, 1, 2, 3}) {
+ byte[] image = new byte[1 << 20];
+ System.arraycopy(code._encoding.bits(), 0, image, 0, code._encoding._bits.size());
+ EvalRisc5 r5 = new EvalRisc5(image, 1 << 16);
+ r5.regs[riscv.A0] = arg;
+ assertEquals("Execution must finish", 0, r5.step(1000));
+ // False LHS runs the loop and final increment, returning 4.
+ // True LHS skips all RHS effects and returns the LHS value, 1.
+ assertEquals("OR result and side effects for arg=" + arg,
+ (arg & 1) == 0 ? 44 : 1, r5.regs[riscv.A0]);
+ }
+ }
+
+ @Ignore
+ @Test
+ public void testJig() throws IOException {
+ String src =
+"""
+var apply = { i64 x, { i64 -> u32 } fcn ->
+ return fcn(x);
+}
+""";
+ }
+
+ @Test @Ignore
+ public void myOwnSake2() throws IOException {
+ TestC.runS("print","Or",0);
+ }
+
+ static CodeGen testCPU( String src, String cpu, String os, int spills, String stop ) {
+ CodeGen code = new CheckedCodeGen(src).driver(CodeGen.Phase.Encoding,cpu,os);
+ SpillStats.record(code,"Chapter23",cpu,os);
+ SpillStats.checkSpills(spills,code._regAlloc._spillScaled);
+ if( stop != null )
+ assertEquals(stop, code._stop.toString());
+ return code;
+ }
+
+ @Test
+ public void testOr() throws IOException {
+ TestC.runS("or1","Or",0);
+
+ // Evaluate on RISC5 emulator
+ EvalRisc5 R5 = TestRisc5.build("or1", 0, 2, false);
+ int trap = R5.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("Or",R5._stdout.toString());
+
+ // Evaluate on ARM emulator
+ EvalArm64 arm = TestArm64.build("or1", 0, 2, false);
+ trap = arm.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,arm.regs[0]);
+ assertEquals("Or",arm._stdout.toString());
+ }
+
+ @Test
+ public void testAnd() throws IOException {
+ TestC.runS("and1","And",0);
+
+ // Evaluate on RISC5 emulator
+ EvalRisc5 R5 = TestRisc5.build("and1", 0, 2, false);
+ int trap = R5.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("And",R5._stdout.toString());
+
+ // Evaluate on ARM emulator
+ EvalArm64 arm = TestArm64.build("and1", 0, 2, false);
+ trap = arm.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,arm.regs[0]);
+ assertEquals("And",arm._stdout.toString());
+ }
+
+ @Test
+ public void testAndPtr() throws IOException {
+ String src =
+"""
+struct S { !S? !fld; };
+val ptr = arg == 1 ? null : new S{fld = arg==1 ? null : new S{fld = null;};};
+return ptr && ptr.fld ? "true" : "false";
+ """;
+ CodeGen code = new CodeGen(src).parse().opto().typeCheck();
+ assertEquals("[97-117][ 116,114,117,101]", Eval2.eval(code, 0));
+
+ // Evaluate on RISC5 emulator
+ EvalRisc5 R5 = TestRisc5.build("ptrand", 1, 8, false);
+ int trap = R5.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("false",R5._stdout.toString());
+
+ // Evaluate on ARM emulator
+ EvalArm64 arm = TestArm64.build("ptrand", 1, 8, false);
+ trap = arm.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,arm.regs[0]);
+ assertEquals("false",arm._stdout.toString());
+ }
+
+ // conditional side effect
+ @Test
+ public void testCondSideEffAnd() throws IOException {
+ TestC.runS("and2","Effected",0);
+
+ // Evaluate on RISC5 emulator
+ EvalRisc5 R5 = TestRisc5.build("and2", 0, 2, false);
+ int trap = R5.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("Effected",R5._stdout.toString());
+
+ // Evaluate on ARM emulator
+ EvalArm64 arm = TestArm64.build("and2", 0, 2, false);
+ trap = arm.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,arm.regs[0]);
+ assertEquals("Effected",arm._stdout.toString());
+ }
+
+
+ @Test
+ public void testCondSideEffOr() throws IOException {
+ TestC.runS("or2","Effected",0);
+
+ // Evaluate on RISC5 emulator
+ EvalRisc5 R5 = TestRisc5.build("or2", 0, 2, false);
+ int trap = R5.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("Effected",R5._stdout.toString());
+
+ // Evaluate on ARM emulator
+ EvalArm64 arm = TestArm64.build("or2", 0, 2, false);
+ trap = arm.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,arm.regs[0]);
+ assertEquals("Effected",arm._stdout.toString());
+ }
+
+ // test it with function calls
+ @Test
+ public void testFuncCall() throws IOException {
+ TestC.runS("and3","Or",0);
+
+ // Evaluate on RISC5 emulator
+ EvalRisc5 R5 = TestRisc5.build("and3", 0, 2, false);
+ int trap = R5.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("Or",R5._stdout.toString());
+
+ // Evaluate on ARM emulator
+ EvalArm64 arm = TestArm64.build("and3", 0, 2, false);
+ trap = arm.step(100);
+ assertEquals(0,trap);
+ assertEquals(0,arm.regs[0]);
+ assertEquals("Or",arm._stdout.toString());
+ }
+
+ @Test
+ public void testFRefFields() {
+ String src =
+"""
+// A hypothetical scanner class
+struct Scan {
+ int !x;
+ u8[~] !buf;
+ // Skip whitespace
+ val skip = { !Scan s ->
+ while( s.buf[s.x] <= ' ' )
+ s.x++;
+ };
+ // Peek a character; if matched consume it, else false.
+ val peek = { !Scan !s, u8 c ->
+ skip(s);
+ if( s.buf[s.x] != c ) return false;
+ s.x++;
+ return true;
+ };
+};
+!Scan !s = new Scan{ buf = " q"; };
+return Scan.peek(s,'q');
+ """;
+
+ CodeGen code = new CodeGen(src).parse().opto().typeCheck();
+ assertEquals("return Phi(Region,0,1);", code._stop.toString());
+ assertEquals("1", Eval2.eval(code, 0));
+ testCPU(src,"x86_64_v2", "Win64" ,23,null);
+ };
+
+ @Test
+ public void testFRefFields2() {
+ String src =
+"""
+// A hypothetical scanner class
+struct Scan {
+ int !x;
+ u8[~] !buf;
+ // Skip whitespace
+ val skip = { ->
+ while( buf[x] <= ' ' )
+ x++;
+ return self;
+ };
+};
+~Scan s = new Scan{ buf = " q"; };
+return s.skip().x;
+ """;
+
+ try { new CodeGen(src).parse().opto().typeCheck(); fail(); }
+ catch( Exception e ) { org.junit.Assert.assertTrue(e.getMessage().startsWith("Argument #0 isa")); }
+ };
+
+
+ @Test
+ public void testMethod() {
+ String src =
+"""
+// A hypothetical scanner class
+struct Scan {
+ int !x;
+ u8[~] !buf;
+ // Skip whitespace
+ val skip = { ->
+ while( buf[x] <= ' ' )
+ x++;
+ };
+ val require = { u8 ch ->
+ skip();
+ buf[x++]==ch;
+ };
+};
+!Scan !s = new Scan{ buf = " [1,2]"; };
+return s.require('[');
+ """;
+
+ CodeGen code = new CodeGen(src).parse().opto().typeCheck();
+ assertEquals("return (.[]==91);", code._stop.toString());
+ assertEquals("1", Eval2.eval(code, 0));
+ testCPU(src,"x86_64_v2", "Win64" ,4,null);
+ };
+
+
+}
diff --git a/src/test/java/com/seaofnodes/simple/Eval2.java b/src/test/java/com/seaofnodes/simple/Eval2.java
index bbf88f1a..908cc2e0 100644
--- a/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -4,6 +4,8 @@ import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.print.IRPrinter;
import com.seaofnodes.simple.type.*;
+import com.seaofnodes.simple.util.SB;
+import com.seaofnodes.simple.util.Utils;
import java.util.*;
public abstract class Eval2 {
@@ -115,7 +117,7 @@ public abstract class Eval2 {
public static String eval( CodeGen code, long arg ) { return eval(code,arg,1000); }
public static String eval( CodeGen code, long arg, int timeout ) {
if( code._start.uctrl()==null ) return ""; // The empty program
- SB trace = null; // new SB(); // TRACE, set to null for off, new SB() for on
+ SB trace = null; // = new SB(); // TRACE, set to null for off, new SB() for on
// Force local scheduling phase
code.driver(CodeGen.Phase.LocalSched);
// Set global, so don't have to pass everywhere
@@ -311,9 +313,22 @@ public abstract class Eval2 {
return switch ( t ) {
case TypeInteger i -> i.isConstant() ? (Long )i.value() : "INT";
case TypeFloat f -> f.isConstant() ? (Double)f.value() : "FLT";
- case TypeMemPtr tmp -> tmp;
case TypeFunPtr tfp -> tfp;
case TypeMem mem -> "MEM";
+ case TypeMemPtr tmp -> {
+ // Unknown-caller inputs are type placeholders, not heap constants.
+ if( !tmp.isConstant() ) yield tmp;
+ if( tmp._obj.isAry() ) { // Constant array ptr
+ TypeConAry con = (TypeConAry)tmp._obj.field("[]")._t;
+ Object[] xs = new Object[con.len()];
+ for( int i=0; i<con.len(); i++ )
+ xs[i] = con.at8(i);
+ yield xs;
+
+ } else {
+ throw Utils.TODO(); // Constant non-array ptr
+ }
+ }
default -> null;
};
}
@@ -322,8 +337,7 @@ public abstract class Eval2 {
private static int offToIdx( long off, TypeStruct t) {
off -= t.aryBase();
int scale = t.aryScale();
- long mask = (1L << scale)-1;
- assert (off & mask) == 0;
+ assert (off & ((1L << scale)-1)) == 0;
return (int)(off>>scale);
}
@@ -337,7 +351,7 @@ public abstract class Eval2 {
if( n!=x || n<0 )
throw new NegativeArraySizeException(""+n);
Object[] ary = new Object[n]; // Array body
- var elem = type._fields[1]._type;
+ var elem = type._fields[1]._t;
if (elem instanceof TypeInteger) {
Arrays.fill( ary, 0L );
} else if (elem instanceof TypeFloat) {
@@ -351,7 +365,7 @@ public abstract class Eval2 {
int num = type._fields.length;
Object[] ptr = new Object[num];
for( int i=0; i<num; i++ )
- ptr[i] = con(type._fields[i]._type.makeZero());
+ ptr[i] = con(type._fields[i]._t.makeZero());
return ptr;
}
@@ -359,11 +373,12 @@ public abstract class Eval2 {
Object f = val(ld.ptr());
// Check for dense constant array
if( f instanceof TypeMemPtr tmp ) {
- assert tmp._obj._con != TypeConAry.BOT;
- if( ld._name.equals("#") )
- return (long)tmp._obj._con.len();
- int idx = offToIdx(x(ld.off()),tmp._obj);
- return tmp._obj._con.at(idx);
+ //assert tmp._obj._con != TypeConAry.BOT;
+ //if( ld._name.equals("#") )
+ // return (long)tmp._obj._con.len();
+ //int idx = offToIdx(x(ld.off()),tmp._obj);
+ //return tmp._obj._con.at(idx);
+ throw Utils.TODO();
}
Object[] fs = (Object[])f;
if( ld._name.equals("#") )
@@ -421,14 +436,11 @@ public abstract class Eval2 {
case TypeMemPtr tmp -> {
if( visit.containsKey(x) ) yield sb.p("$cyclic");
visit.put(x,x);
- // Since never can close the type cycle, without cyclic types, have
- // to handle FRefs even here
- if( tmp.isFRef() )
- tmp = tmp.makeFrom(((TypeMemPtr)Parser.TYPES.get(tmp._obj._name))._obj);
+ assert !tmp.isFRef();
Object[] xs = (Object[])x; // Array of fields
if( tmp._obj.isAry() ) {
- Type elem = tmp._obj._fields[1]._type;
+ Type elem = tmp._obj._fields[1]._t;
if( elem == TypeInteger.U8 ) {
// Shortcut u8[] as a String
for( Object o : xs )
@@ -436,6 +448,7 @@ public abstract class Eval2 {
} else {
// Array of elements
elem.print(sb).p("[ ");
+ if( elem instanceof TypeConAry ) elem = TypeInteger.ZERO;
for( Object o : xs )
_print( elem, o, sb, visit ).p( "," );
sb.unchar().p("]");
@@ -444,7 +457,7 @@ public abstract class Eval2 {
sb.p(tmp._obj._name).p("{");
Field[] flds = tmp._obj._fields;
for( int i=0; i<flds.length; i++ )
- _print( flds[i]._type,xs[i], sb.p(flds[i]._fname).p("="), visit ).p(",");
+ _print( flds[i]._t,xs[i], sb.p(flds[i]._fname).p("="), visit ).p(",");
sb.unchar().p("}");
}
yield sb;
diff --git a/src/test/java/com/seaofnodes/simple/LiteralTest.java b/src/test/java/com/seaofnodes/simple/LiteralTest.java
index 2375f213..09ee30f5 100644
--- a/src/test/java/com/seaofnodes/simple/LiteralTest.java
+++ b/src/test/java/com/seaofnodes/simple/LiteralTest.java
@@ -22,7 +22,7 @@ public class LiteralTest {
private static void assertString(String text, byte[] expected) {
var code = new CodeGen("return \"" + text + "\";").parse().opto().typeCheck();
TypeMemPtr ptr = (TypeMemPtr)code.expr()._type;
- TypeConAryB bytes = (TypeConAryB)ptr._obj._con;
+ TypeConAryB bytes = (TypeConAryB)ptr._obj.field("[]")._t;
assertArrayEquals(text, expected, bytes._ary);
}
diff --git a/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java b/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
index 4bd36256..52c0a573 100644
--- a/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
+++ b/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
@@ -176,7 +176,7 @@ public class MemoryEncodingTest {
c.append("return 0;\n}\n");
Files.writeString(Path.of(file+".c"),c);
TestC.run("val memory = { int arg -> "+SOURCES[p]+" };",
- TestC.CALL_CONVENTION,"",file+".c",file,"S","",-1);
+ TestC.CALL_CONVENTION,null,"",file+".c",file,"S","",-1);
}
}
}
diff --git a/src/test/java/com/seaofnodes/simple/MergeSortTest.java b/src/test/java/com/seaofnodes/simple/MergeSortTest.java
index 788bd9c2..39cacd98 100644
--- a/src/test/java/com/seaofnodes/simple/MergeSortTest.java
+++ b/src/test/java/com/seaofnodes/simple/MergeSortTest.java
@@ -3,6 +3,7 @@ package com.seaofnodes.simple;
import com.seaofnodes.isa.eval.EvalRisc5;
import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.util.SB;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
import java.io.IOException;
import java.nio.file.Files;
diff --git a/src/test/java/com/seaofnodes/simple/Simple.java b/src/test/java/com/seaofnodes/simple/Simple.java
index cd795fae..aef810d1 100644
--- a/src/test/java/com/seaofnodes/simple/Simple.java
+++ b/src/test/java/com/seaofnodes/simple/Simple.java
@@ -2,12 +2,12 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.print.*;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.io.InputStreamReader;
+import com.seaofnodes.simple.util.Utils;
import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.stream.Collectors;
public class Simple {
diff --git a/src/test/java/com/seaofnodes/simple/SpillStats.java b/src/test/java/com/seaofnodes/simple/SpillStats.java
index 82cffef8..6af51b33 100644
--- a/src/test/java/com/seaofnodes/simple/SpillStats.java
+++ b/src/test/java/com/seaofnodes/simple/SpillStats.java
@@ -28,7 +28,8 @@ public class SpillStats extends RunListener {
// The same native helpers serve old and new program cohorts.
public static void recordNative(CodeGen code, String cpu, String abi) {
- String cohort = ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter22Test.class
+ String cohort = ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter23Test.class
+ ? "Chapter23" : ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter22Test.class
? "Chapter22" : "Chapter21";
record(code,cohort,cpu,abi);
}
@@ -46,7 +47,7 @@ public class SpillStats extends RunListener {
}
public static void main(String[] args) throws ClassNotFoundException {
- if( args.length==0 ) args = new String[]{"Chapter20Test","Chapter21Test","Chapter21AllocTest","Chapter22Test","BrainFuckTest","MergeSortTest"};
+ if( args.length==0 ) args = new String[]{"Chapter20Test","Chapter21Test","Chapter21AllocTest","Chapter22Test","Chapter23Test","Chapter23AllocTest","BrainFuckTest","MergeSortTest"};
Class<?>[] tests = new Class<?>[args.length];
for( int i=0; i<args.length; i++ )
tests[i] = Class.forName("com.seaofnodes.simple."+args[i]);
diff --git a/src/test/java/com/seaofnodes/simple/TestC.java b/src/test/java/com/seaofnodes/simple/TestC.java
index 44c06128..2e61211a 100644
--- a/src/test/java/com/seaofnodes/simple/TestC.java
+++ b/src/test/java/com/seaofnodes/simple/TestC.java
@@ -2,6 +2,9 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen;
import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.type.TypeInteger;
+import com.seaofnodes.simple.util.Ary;
+import com.seaofnodes.simple.util.Utils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -28,7 +31,7 @@ public abstract class TestC {
}
// Compile and run a simple program
- public static void run( String dir, String file, String expected, int spills ) throws IOException {
+ public static void run( String dir, String file, TypeInteger arg, String expected, int spills, boolean standalone) throws IOException {
// Files
String cfile = dir+"/"+file+".c" ;
String sfile = dir+"/"+file+".smp";
@@ -36,16 +39,29 @@ public abstract class TestC {
// Compile and export Simple
String src = Files.readString(Path.of(sfile));
- run(src,CALL_CONVENTION,"",cfile,efile,"S",expected,spills);
+ run(src,CALL_CONVENTION,arg, "",standalone? null: cfile,efile,"S",expected,spills);
+ }
+ public static void run(String dir, String file, String expected, int spills ) throws IOException {
+ run(dir, file,null, expected, spills, false);
+ }
+
+ public static void runS(String file, String expected, int spills ) throws IOException {
+ run("src/test/java/com/seaofnodes/simple/progs", file, null, expected, spills, true);
}
- public static void run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException {
+ public static void runS(String file, TypeInteger arg, String expected, int spills ) throws IOException {
+ run("src/test/java/com/seaofnodes/simple/progs", file, arg, expected, spills, true);
+ }
+
+
+ public static void run( String src, String simple_conv, TypeInteger arg, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException {
String bin = efile+xtn;
String obj = bin+".o";
String exe = OS.startsWith("Windows") ? bin+".exe" : bin;
// Compile simple, emit ELF
- CodeGen code = new CheckedCodeGen(src).driver( CPU_PORT, simple_conv, obj);
+ CodeGen code = new CheckedCodeGen(src, arg).driver( CPU_PORT, simple_conv, obj);
SpillStats.recordNative(code,CPU_PORT,simple_conv);
+
String result = gcc(obj, c_conv, cfile, false, exe );
assertEquals(expected,result);
diff --git a/src/test/java/com/seaofnodes/simple/TypeTest.java b/src/test/java/com/seaofnodes/simple/TypeTest.java
index 551bddad..b21af9ee 100644
--- a/src/test/java/com/seaofnodes/simple/TypeTest.java
+++ b/src/test/java/com/seaofnodes/simple/TypeTest.java
@@ -7,27 +7,50 @@ import static org.junit.Assert.assertSame;
public class TypeTest {
+ // Struct hashes omit field types, so interning compares unlike leaf kinds.
+ @Test
+ public void testCyclicLeafKinds() {
+ TypeStruct bottom = TypeStruct.make("B14LeafKinds",false,
+ Field.make("x",Type.BOTTOM,2,false, false));
+ TypeStruct one = TypeStruct.make("B14LeafKinds",false,
+ Field.make("x",TypeFloat.constant(1.0),2,false, false));
+ TypeStruct two = TypeStruct.make("B14LeafKinds",false,
+ Field.make("x",TypeFloat.constant(2.0),2,false, false));
+
+ // Meeting creates a new struct while cyclic equality is active. Its
+ // float leaf must compare unequal to the previously interned BOTTOM.
+ TypeStruct meet = (TypeStruct)one.meet(two);
+ assertSame(TypeFloat.F32,meet._fields[0]._t);
+ assertSame(meet,two.meet(one));
+ assertSame(meet,TypeStruct.make("B14LeafKinds",false,
+ Field.make("x",TypeFloat.F32,2,false, false)));
+ assertSame(bottom,meet.meet(bottom));
+ assertSame(meet.dual(),one.dual().join(two.dual()));
+ }
+
// Test basic properties and GLB
@Test
public void testTypeAdHoc() {
Assert.assertEquals( Type.BOTTOM, TypeInteger.TRUE.meet(TypeNil.NIL) );
- Assert.assertEquals( Type.BOTTOM, TypeInteger.TOP.meet(TypeNil.NIL) );
-
-
- TypeStruct s1 = TypeStruct.make("s1", new Field[]{
- Field.make("a", TypeInteger.BOT,-1, false),
- Field.make("b", TypeInteger.BOT,-2, false) });
- TypeStruct s2 = TypeStruct.make("s2", new Field[]{
- Field.make("a", TypeInteger.BOT,-3, false),
- Field.make("b", TypeInteger.BOT,-4, false) });
- Assert.assertEquals(s1.makeRO(), s1.glb(false));
+ Assert.assertEquals( Type.BOTTOM, TypeInteger.TOP .meet(TypeNil.NIL) );
+
+ TypeStruct s1 = TypeStruct.make("s1",false,
+ Field.make("a", TypeInteger.BOT,-1, false, false),
+ Field.make("b", TypeInteger.BOT,-2, false, false) );
+ TypeStruct s2 = TypeStruct.make("s2",false,
+ Field.make("a", TypeInteger.BOT,-3, false, false),
+ Field.make("b", TypeInteger.BOT,-4, false, false) );
+ TypeStruct x1ro = (TypeStruct)s1.makeRO();
+ TypeMemPtr p1 = TypeMemPtr.make(s1);
+ Assert.assertEquals(x1ro, ((TypeMemPtr)p1.glb(false))._obj);
Assert.assertNotEquals(s1, s1.dual());
- Assert.assertEquals(s1.makeRO(), s1.dual().glb(false));
+ TypeStruct s1dglb = ((TypeMemPtr)p1.dual().glb(false))._obj;
+ Assert.assertTrue(x1ro.isa(s1dglb));
- TypeMem m1 = TypeMem.make(1,TypeNil.NIL);
- TypeMem m2 = TypeMem.make(2,TypeInteger.U16);
- TypeMem m3 = TypeMem.make(3,TypeFloat.F64);
- TypeMem m4 = TypeMem.make(4,TypeInteger.BOT);
+ TypeMem m1 = TypeMem.make(2,TypeNil.NIL);
+ TypeMem m2 = TypeMem.make(3,TypeInteger.U16);
+ TypeMem m3 = TypeMem.make(4,TypeFloat.F64);
+ TypeMem m4 = TypeMem.make(5,TypeInteger.BOT);
Assert.assertNotEquals(m1, m2);
Assert.assertNotEquals(m2, m3);
@@ -35,11 +58,11 @@ public class TypeTest {
Assert.assertEquals(TypeStruct.BOT, s1.meet(s2));
Assert.assertEquals(TypeMem .BOT, m1.meet(m2));
- Assert.assertEquals(TypeMem.make(0,Type.BOTTOM), m1.meet(m3));
+ Assert.assertEquals(TypeMem.make(1,Type.BOTTOM), m1.meet(m3));
Assert.assertEquals(TypeMem .BOT, m3.meet(m4));
- Assert.assertEquals(TypeMem.make(1,Type.BOTTOM), m1.glb(false));
- Assert.assertEquals(TypeMem.make(1,Type.XNIL), m1.dual());
+ Assert.assertEquals(TypeMem.make(2,Type.BOTTOM), m1.glb(false));
+ Assert.assertEquals(TypeMem.make(2,Type.XNIL), m1.dual());
Assert.assertEquals(m4.dual(), m4.glb(false).dual());
TypeMemPtr ptr1 = TypeMemPtr.make(s1);
@@ -55,11 +78,13 @@ public class TypeTest {
Assert.assertEquals(s2, ptr2nil._obj);
Assert.assertNotEquals(ptr1, ptr2);
- Assert.assertNotEquals(ptr1, ptr1.glb(false));
- Assert.assertEquals(ptr1nil.makeFrom(s1.glb(false)).makeRO(), ptr1.glb(false));
+ Type p1glb = ptr1.glb(false);
+ Assert.assertNotEquals(ptr1, p1glb );
+ Assert.assertTrue(((TypeMemPtr)p1glb)._ro);
+ Assert.assertTrue(ptr1nil.isa(p1glb));
Assert.assertEquals(ptr1, ptr1.dual().dual());
- Assert.assertEquals(ptr1.glb(false).makeFrom(s1.dual().glb(false)), ptr1.dual().glb(false));
+ Assert.assertTrue(p1glb.makeRO().isa( ptr1.dual().glb(false)));
Assert.assertEquals(TypeMemPtr.makeNullable(TypeStruct.BOT).withAccess(false), ptr1.meet(ptr2nil));
Assert.assertEquals(ptr1nil, ptr1.meet(TypeNil.NIL));
@@ -77,6 +102,19 @@ public class TypeTest {
Assert.assertEquals(TypePtr.XNPTR, NULL_join_PTR);
Type ptr1_dual = ptr1.dual();
Type nullableptr1_dual = ptr1nil.dual();
+
+ // Cyclic check
+ TypeStruct S1 = ((TypeMemPtr)TypeStruct.SFLT2.field("s1")._t)._obj;
+ Assert.assertFalse(s1.isFinal());
+ Type s1ro = S1.makeRO();
+ Type s1ro2 = S1.makeRO();
+ Assert.assertSame(s1ro,s1ro2);
+ Assert.assertTrue(s1ro.isFinal());
+
+ Assert.assertFalse(S1.isConstant());
+ Type s1glb = S1.field("s2")._t.glb(false);
+ Type s1glb2 = S1.field("s2")._t.glb(false);
+ Assert.assertSame(s1glb,s1glb2);
}
// Test theoretical properties.
@@ -150,9 +188,32 @@ public class TypeTest {
// Test cyclic types and meets
@Test
public void testCyclic0() {
- Type d0 = TypeStruct.S1.dual();
+ Type d0 = TypeStruct.SFLT2.dual();
Type d1 = d0.dual();
- assertSame(TypeStruct.S1,d1);
+ assertSame(TypeStruct.SFLT2,d1);
+ }
+
+ @Test
+ public void testGLB() {
+ Type[] ts = Type.gather();
+ for( Type t0 : ts )
+ if( !(t0 instanceof Field || t0 instanceof TypeStruct || t0 instanceof TypeTuple || t0 instanceof TypeConAry ) )
+ Assert.assertTrue(t0.isa(t0.glb(false)));
}
+ @Test
+ public void testList() {
+ TypeStruct list = TypeStruct.open("List");
+ TypeMemPtr plist = TypeMemPtr.makeNullable(list);
+ list = list.add(Field.make("next", plist, 2, false, false ) );
+ list = list.add(Field.make("x", TypeInteger.BOT, 3, false, false));
+ // Make a cyclic type
+ list = list.close();
+ // Fields are mutable
+ Assert.assertFalse(list.isFinal());
+ TypeStruct flist = (TypeStruct)list.makeRO();
+ Assert.assertTrue(flist.isFinal());
+ Assert.assertNotSame( list, flist );
+
+ }
}
diff --git a/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java b/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
index 2d9860a6..ad898be3 100644
--- a/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
+++ b/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
@@ -118,9 +118,52 @@ public class RegAllocTestSupport {
assertTrue(BuildLRG.run(0,new RegAlloc(code)));
}
+ private static class CallOp extends CallNode implements MachNode {
+ CallOp(Node ctrl, Node def) { super(null,ctrl,null,def,def); }
+ @Override public RegMask regmap(int i) { return i==2 ? A : i==3 ? B : null; }
+ @Override public RegMask outregmap() { return null; }
+ @Override public void encoding(Encoding enc) { throw new AssertionError(); }
+ }
+
+ public static void popularUses() {
+ for( int calls=0; calls<=2; calls++ ) {
+ CodeGen code = graph();
+ RegAlloc alloc = new RegAlloc(code);
+ RegionNode block = new RegionNode(null,code._start,code._start);
+ Op def = new Op(new RegMask(7L),null,null,false,block);
+ LRG lrg = alloc.newLRG(def);
+ lrg._machDef = def;
+ lrg._mask = new RegMask(0L);
+ Op ab = new Op(null,new RegMask(3L),null,false,block,def);
+ Op bc = new Op(null,new RegMask(6L),null,false,block,def);
+ Op a = new Op(null,A,null,false,block,def,def);
+ Op b = new Op(null,B,null,false,block,def);
+ Op dep = new Op(null,null,null,false,block,def);
+ CallOp call = calls>0 ? new CallOp(block,def) : null;
+ if( calls==2 ) new CallOp(block,def);
+ boolean split = alloc.splitEmptyMaskByUse((byte)0,lrg);
+ assertEquals(calls<2,split);
+ if( !split ) { assertSame(def,a.in(1)); assertSame(def,b.in(1)); continue; }
+ // Two shared copies, even with overlapping masks and repeated inputs.
+ assertTrue(a.in(1) instanceof SplitNode);
+ assertTrue(b.in(1) instanceof SplitNode);
+ assertNotSame(a.in(1),b.in(1));
+ assertSame(a.in(1),a.in(2));
+ assertSame(b.in(1),ab.in(1));
+ assertSame(b.in(1),bc.in(1));
+ assertSame(def,dep.in(1)); // A scheduling dependency has no register.
+ assertEquals(3,def.nOuts()); // Two copies and the dependency.
+ if( call!=null ) {
+ assertSame(a.in(1),call.in(2));
+ assertSame(b.in(1),call.in(3));
+ }
+ }
+ }
+
// Check the scheduled graph before encoding adds untyped branches or rewrites tail calls.
public static class CheckedCodeGen extends CodeGen {
public CheckedCodeGen(String src) { super(src); }
+ public CheckedCodeGen(String src, TypeInteger arg) { super(src,arg); }
@Override public CodeGen regAlloc() {
super.regAlloc();
checkRegisters(this);
diff --git a/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java b/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
index cb98971b..20aac367 100644
--- a/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
+++ b/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
@@ -1,9 +1,8 @@
package com.seaofnodes.simple.evaluator;
-import com.seaofnodes.simple.Utils;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.*;
-
+import com.seaofnodes.simple.util.Utils;
import java.util.*;
public class Evaluator {
@@ -190,7 +189,7 @@ public class Evaluator {
if( n < 0 )
throw new NegativeArraySizeException(""+n);
body = new Object[(int)n+1]; // Array body
- var elem = type._fields[1]._type;
+ var elem = type._fields[1]._t;
if (elem instanceof TypeInteger) {
for (int i=0; i<n; i++) body[i+1] = 0L;
} else if (elem instanceof TypeFloat) {
@@ -203,7 +202,7 @@ public class Evaluator {
} else {
body = new Object[num = type._fields.length];
for( int i=0; i<num; i++ )
- body[i] = switch( alloc._ptr._obj._fields[i]._type ) {
+ body[i] = switch( alloc._ptr._obj._fields[i]._t ) {
case TypeInteger ti -> 0L;
case TypeFloat tf -> 0D;
default -> null;
diff --git a/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java b/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java
index 7ba9272f..fee0f2a8 100644
--- a/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java
+++ b/src/test/java/com/seaofnodes/simple/evaluator/Scheduler.java
@@ -1,9 +1,8 @@
package com.seaofnodes.simple.evaluator;
-import com.seaofnodes.simple.Utils;
import com.seaofnodes.simple.node.*;
import com.seaofnodes.simple.type.Type;
-
+import com.seaofnodes.simple.util.Utils;
import java.util.*;
/**
diff --git a/src/test/java/com/seaofnodes/simple/fuzzer/Fuzzer.java b/src/test/java/com/seaofnodes/simple/fuzzer/Fuzzer.java
index 586924b2..b29eb2c3 100644
--- a/src/test/java/com/seaofnodes/simple/fuzzer/Fuzzer.java
+++ b/src/test/java/com/seaofnodes/simple/fuzzer/Fuzzer.java
@@ -22,7 +22,7 @@ import java.util.function.Consumer;
*/
public class Fuzzer {
- private static final int EVAL_TIMEOUT = 1000;
+ private static final int EVAL_TIMEOUT = 10000;
/**
* List of exceptions already encountered.
@@ -82,10 +82,10 @@ public class Fuzzer {
private static void runCheck(String script, boolean valid) {
CodeGen code1;
try {
- code1 = FuzzerUtils.parse(script, 123);
+ code1 = FuzzerUtils.parse(script, 123, true);
} catch (RuntimeException e1) {
try {
- FuzzerUtils.parse(script, 456);
+ FuzzerUtils.parse(script, 456, false);
} catch (RuntimeException e2) {
if (FuzzerUtils.isExceptionFromSameCause(e1, e2)) {
if (!valid || e1.getClass() == Parser.ParseException.class) return;
@@ -95,7 +95,7 @@ public class Fuzzer {
}
throw e1;
}
- CodeGen code2 = FuzzerUtils.parse(script, 456);
+ CodeGen code2 = FuzzerUtils.parse(script, 456, false);
checkGraphs(code1, code2, 0);
checkGraphs(code1, code2, 1);
checkGraphs(code1, code2, 10);
diff --git a/src/test/java/com/seaofnodes/simple/fuzzer/FuzzerUtils.java b/src/test/java/com/seaofnodes/simple/fuzzer/FuzzerUtils.java
index b2be5b5f..45558541 100644
--- a/src/test/java/com/seaofnodes/simple/fuzzer/FuzzerUtils.java
+++ b/src/test/java/com/seaofnodes/simple/fuzzer/FuzzerUtils.java
@@ -94,13 +94,13 @@ class FuzzerUtils {
/**
* Parse and optimize using the given worklist seed
*/
- public static CodeGen parse(String script, long workListSeed) {
+ public static CodeGen parse(String script, long workListSeed, boolean reset) {
var err = System.err;
var out = System.out;
try {
System.setErr(NULL_PRINT_STREAM);
System.setOut(NULL_PRINT_STREAM);
- var code = new CodeGen(script, TypeInteger.BOT, workListSeed);
+ var code = new CodeGen(script, TypeInteger.BOT, workListSeed, reset);
return code.driver(CodeGen.Phase.LocalSched);
} finally {
System.setErr(err);
diff --git a/src/test/java/com/seaofnodes/simple/fuzzer/Reducer.java b/src/test/java/com/seaofnodes/simple/fuzzer/Reducer.java
index 3731b40c..856e6a24 100644
--- a/src/test/java/com/seaofnodes/simple/fuzzer/Reducer.java
+++ b/src/test/java/com/seaofnodes/simple/fuzzer/Reducer.java
@@ -41,14 +41,15 @@ public class Reducer {
new Replace(Pattern.compile("(?<=\\n|^)[^\\n]+(?=\\n|$)"), true, ""),
new Replace(Pattern.compile("(?<=[+\\-*/<>=(])--"), ""),
new Replace(Pattern.compile("\\b--"), "+"),
- new Replace(Pattern.compile("-"), ""),
+ new Replace(Pattern.compile("[-!]"), ""),
new Replace(Pattern.compile("\\b\\+-"), "-"),
- new Replace(Pattern.compile("(?<![+\\-*/<>=])(?:-|\\*|/|>=|<=|>|<|!=|==)(?![+\\-*/<>=])"), "+"),
+ new Replace(Pattern.compile("(?<![+\\-*/<>=&|])(?:-|\\*|/|>=|<=|>>>|>>|>|<<|<|!=|==|&&|\\|\\||&|\\||^)(?![+*/<>=&|])"), "+"),
+ new Replace(Pattern.compile("\\?([^;]+):"), "+"),
new Replace(Pattern.compile("\\{((?:[^{}]|\\{})+)(?:\\n[ \\t]*)?}"), "", "{}", 1),
new Replace(Pattern.compile("(?<=\\n|^)([ \\t]*)\\{\\n(.*?)\\n\\1}", Pattern.DOTALL), 2),
new Replace(Pattern.compile("\\(([^()]+)\\)"), 1),
- new Replace(Pattern.compile("\\d+\\+"), ""),
- new Replace(Pattern.compile("\\+\\d+"), ""),
+ new Replace(Pattern.compile("\\d+ ?\\+ ?"), ""),
+ new Replace(Pattern.compile(" ?\\+ ?\\d+"), ""),
new Replace(Pattern.compile("\\n\\n+"), "\n"),
new Replace(Pattern.compile("^\\n+|\\n+$"), ""),
new Replace(Pattern.compile("else *"), ""),
@@ -105,7 +106,7 @@ public class Reducer {
* Clean up variable names from the random ones generated by the fuzzer.
*/
private String cleanVariables(String script) {
- var matcher = Pattern.compile("\\b([0-9a-zA-Z_]+) ([0-9a-zA-Z_]+)").matcher(script);
+ var matcher = Pattern.compile("\\b([0-9a-zA-Z_]+) !?([0-9a-zA-Z_]+)").matcher(script);
int[] num = {0, 0};
while (matcher.find()) {
var type = matcher.group(1);
diff --git a/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java b/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java
index 79547c0d..6ec066e9 100644
--- a/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java
+++ b/src/test/java/com/seaofnodes/simple/fuzzer/ScriptGenerator.java
@@ -20,12 +20,9 @@ import static com.seaofnodes.simple.Parser.KEYWORDS;
public class ScriptGenerator {
private static final int MAX_STATEMENTS_PER_BLOCK = 5;
- private static final int MAX_BINARY_EXPRESSIONS_PER_EXPRESSION = 10;
- private static final int MAX_UNARY_EXPRESSIONS_PER_EXPRESSION = 6;
private static final int MAX_NAME_LENGTH = 10;
private static final int MAX_BLOCK_DEPTH = 4;
private static final int MAX_EXPRESSION_DEPTH = 10;
- private static final int MAX_SUFFIX_RECURSIVE_DEPTH = 10;
/**
* Number of spaces per indentation
@@ -44,14 +41,6 @@ public class ScriptGenerator {
* Flag for a statement that it contains a final if statement without an else branch.
*/
private static final int FLAG_IF_WITHOUT_ELSE = 0x02;
- /**
- * Binary operators.
- */
- private static final String[] BINARY_OP = {"==", "!=", "<", "<=", ">", ">=", "+", "-", "*", "/", "&", ">>", ">>>", "<<"};
- /**
- * Unary operators.
- */
- private static final String[] UNARY_OP = {"-"};
private static class Type {
final String name;
@@ -147,10 +136,6 @@ public class ScriptGenerator {
*/
private int depth = MAX_BLOCK_DEPTH;
/**
- * The depth of expressions allowed.
- */
- private int exprDepth = MAX_EXPRESSION_DEPTH;
- /**
* Current variables in scope.
*/
private final ArrayList<Variable> variables = new ArrayList<>();
@@ -568,7 +553,7 @@ public class ScriptGenerator {
*/
public int genIf() {
sb.append("if(");
- genExpression(TYPE_BOOL, true);
+ genExpression(TYPE_BOOL, true, true);
sb.append(") ");
var stop = genStatementBlock();
if ((stop & FLAG_IF_WITHOUT_ELSE) == 0 && random.nextInt(10) > 3) {
@@ -614,7 +599,7 @@ public class ScriptGenerator {
*/
public int genWhile() {
sb.append("while(");
- genExpression(TYPE_BOOL, true);
+ genExpression(TYPE_BOOL, true, true);
sb.append(") ");
loopDepth++;
genStatementBlock();
@@ -640,17 +625,17 @@ public class ScriptGenerator {
indentation += INDENTATION;
String name = getVarName();
printIndentation().append("int ").append(name).append("=");
- genExpression(TYPE_INT, true);
+ genExpression(TYPE_INT, true, false);
sb.append(";\n");
addVariable(name, TYPE_INT);
printIndentation().append("while(").append(name).append("<");
- genExpression(TYPE_INT, true);
+ genShift(TYPE_INT, true, false, MAX_EXPRESSION_DEPTH);
sb.append(") {\n");
indentation += INDENTATION;
depth--;
loopDepth++;
printIndentation().append(name).append("=").append(name).append("+");
- genExpression(TYPE_INT, true);
+ genExpression(TYPE_INT, true, false);
sb.append(";\n");
genStatements();
loopDepth--;
@@ -677,7 +662,7 @@ public class ScriptGenerator {
sb.append(generateInvalid() ? getRandomName() : declType(type)).append(" !").append(name);
if (!(type instanceof TypeNullable) || random.nextBoolean()) {
sb.append("=");
- genExpression(type, true);
+ genExpression(type, true, type==TYPE_BOOL);
}
sb.append(";");
addVariable(name, type);
@@ -712,7 +697,7 @@ public class ScriptGenerator {
declared = field.type;
}
sb.append("=");
- genExpression(declared, true);
+ genExpression(declared, true, declared==TYPE_BOOL);
sb.append(";");
return 0;
}
@@ -724,43 +709,127 @@ public class ScriptGenerator {
public int genReturn() {
var type = getType();
sb.append("return ");
- genExpression(type, true);
+ genExpression(type, true, false);
sb.append(";");
return FLAG_STOP;
}
- /**
- * Generate a binary expression.
- * This method does not care about operator precedence.
- */
- public void genExpression(Type type, boolean change) {
+ public void genExpression(Type type, boolean change, boolean preferLogical) {
+ genExpression(type, change, preferLogical, MAX_EXPRESSION_DEPTH);
+ }
+
+ public void genExpression(Type type, boolean change, boolean preferLogical, int d) {
if (change && generateInvalid()) type = getType();
- if (!(type instanceof TypeInt) && type != TYPE_FLT) {
- genUnary(type, false);
- return;
+ if (d > 0 && random.nextInt(10)==0) {
+ genLogical(TYPE_INT, true, true, d);
+ sb.append("?");
+ genExpression(type, true, preferLogical, d-1);
+ sb.append(":");
+ genExpression(type, false, preferLogical, d-1);
+ } else {
+ genLogical(type, false, preferLogical, d);
+ }
+ }
+
+ public void genLogical(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ genBitwise(type, false, preferLogical, d);
+ while (d-->0 && random.nextInt(preferLogical?5:50) == 0) {
+ sb.append(random.nextBoolean()?"&&":"||");
+ genBitwise(type, true, preferLogical, d);
+ }
+ }
+
+ public void genBitwise(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ genComparison(type, false, preferLogical, d);
+ while (type instanceof TypeInt && d-->0 && random.nextInt(preferLogical?50:5)==0) {
+ sb.append("&|^".charAt(random.nextInt(3)));
+ genComparison(type, true, preferLogical, d);
+ }
+ }
+
+ public void genComparison(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ if (d > 0 && type instanceof TypeInt && random.nextInt(preferLogical?5:50)==0) {
+ type = getType();
+ genComparison(type, true, preferLogical, d-1);
+ sb.append(random.nextBoolean()?"==":"!=");
+ }
+ genChaining(type, false, preferLogical, d);
+ }
+
+ public void genChaining(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ if (d>0 && type instanceof TypeInt && random.nextInt(preferLogical?5:50)==0) {
+ genShift(TYPE_INT, true, false, d);
+ char c = random.nextBoolean()?'>':'<';
+ sb.append(c);
+ if (random.nextInt(4)==0) sb.append('=');
+ genShift(TYPE_INT, true, false, --d);
+ while (d-->0 && random.nextInt(preferLogical?5:50)==0) {
+ if (generateInvalid()) c = c=='>' ? '<' : '>';
+ sb.append(c);
+ if (random.nextInt(4)==0) sb.append('=');
+ genShift(TYPE_INT, true, false, d);
+ }
+ } else {
+ genShift(type, false, preferLogical, d);
}
- var num = randLog(MAX_BINARY_EXPRESSIONS_PER_EXPRESSION);
- while(num-->0) {
- genUnary(type, false);
- sb.append(BINARY_OP[random.nextInt(BINARY_OP.length)]);
+ }
+
+ private static final String[] SHIFTS = {">>", ">>>", "<<"};
+
+ public void genShift(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ genAddition(type, false, preferLogical, d);
+ while (d-- > 0 && type instanceof TypeInt && random.nextInt(50)==0) {
+ sb.append(SHIFTS[random.nextInt(3)]);
+ genAddition(type, true, preferLogical, d);
+ }
+ }
+
+ public void genAddition(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ genMultiplication(type, false, preferLogical, d);
+ while (d-- > 0 && (type instanceof TypeInt || type==TYPE_FLT) && random.nextInt(50)==0) {
+ sb.append(random.nextBoolean()?" + ":" - ");
+ genMultiplication(type, true, preferLogical, d);
+ }
+ }
+
+ public void genMultiplication(Type type, boolean change, boolean preferLogical, int d) {
+ if (change && generateInvalid()) type = getType();
+ genUnary(type, false, preferLogical, d);
+ while (d-- > 0 && (type instanceof TypeInt || type==TYPE_FLT) && random.nextInt(50)==0) {
+ sb.append(random.nextBoolean()?'*':'/');
+ genUnary(type, true, preferLogical, d);
}
- genUnary(type, false);
}
/**
* Generate a unary expression.
*/
- public void genUnary(Type type, boolean change) {
+ public void genUnary(Type type, boolean change, boolean preferLogical, int d) {
if (change && generateInvalid()) type = getType();
if (!(type instanceof TypeInt) && type != TYPE_FLT) {
- genSuffix(type, false);
+ genSuffix(type, false, preferLogical, d);
return;
}
- var num = randLog(MAX_UNARY_EXPRESSIONS_PER_EXPRESSION);
- while(num-->0) {
- sb.append(UNARY_OP[random.nextInt(UNARY_OP.length)]);
+ while (d>0 && random.nextInt(5)==0) {
+ d--;
+ boolean what = type instanceof TypeInt && random.nextInt(preferLogical?2:20) == 0;
+ sb.append(what?'!':'-');
+ }
+ if (random.nextInt(10)==0) {
+ var t = type;
+ var v = findVisibleVariablesMatching(va->va.type.isa(t));
+ if (v != null) {
+ sb.append(random.nextBoolean()?"--":"++").append(v.name);
+ return;
+ }
}
- genSuffix(type, false);
+ genSuffix(type, false, preferLogical, d);
}
public TypeStruct.Field getField(Type type) {
@@ -780,45 +849,45 @@ public class ScriptGenerator {
throw new AssertionError();
}
- /**
- * Generate
- */
- public void genSuffix(Type type, boolean change) {
- genSuffixRecursive(type, change, MAX_SUFFIX_RECURSIVE_DEPTH);
- }
-
- public void genSuffixRecursive(Type type, boolean change, int depth) {
+ public void genSuffix(Type type, boolean change, boolean preferLogical, int d) {
if (change && generateInvalid()) type = getType();
- if (depth > 0 && random.nextBoolean()) {
- if (generateInvalid()) {
- var field = getRandomName();
- var t = getType();
- genSuffixRecursive(t, true, depth-1);
- sb.append(".").append(field);
+ if (d > 0 && random.nextBoolean() && genField(type, d-1)) return;
+ if (d > 0 && random.nextInt(10) == 0) {
+ if (random.nextBoolean() && genField(type, d-1)) return;
+ var t = type;
+ var v = findVisibleVariablesMatching(va -> va.type.isa(t));
+ if (v != null) {
+ sb.append(v.name).append(random.nextBoolean() ? "--" : "++");
return;
- } else {
- var field = getField(type);
- if (field != null) {
- genSuffixRecursive(field.struct, true, depth-1);
- sb.append(".").append(field.name);
- return;
- }
}
}
- genPrimary(type, false);
+ genPrimary(type, false, preferLogical, d);
+ }
+
+ public boolean genField(Type type, int d) {
+ if (generateInvalid()) {
+ var field = getRandomName();
+ var t = getType();
+ genSuffix(t, true, false, d);
+ sb.append(".").append(field);
+ } else {
+ var field = getField(type);
+ if (field == null) return false;
+ genSuffix(field.struct, true, false, d);
+ sb.append(".").append(field.name);
+ }
+ return true;
}
/**
* Generate a primary expression.
*/
- public void genPrimary(Type type, boolean change) {
+ public void genPrimary(Type type, boolean change, boolean preferLogical, int d) {
if (change && generateInvalid()) type = getType();
var rand = random.nextInt(10);
- if (rand == 0 && exprDepth != 0) {
+ if (d > 0 && rand == 0) {
sb.append("(");
- exprDepth--;
- genExpression(type, false);
- exprDepth++;
+ genExpression(type, false, preferLogical, d-1);
sb.append(")");
} else if (rand < 6) {
genVariable(type);
diff --git a/src/test/java/com/seaofnodes/simple/progs/and1.smp b/src/test/java/com/seaofnodes/simple/progs/and1.smp
new file mode 100644
index 00000000..ef4c904f
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/and1.smp
@@ -0,0 +1,10 @@
+// -*- mode: java; -*-
+int a = 1;
+int b = 1;
+
+if(a && b) {
+ sys.io.p("And");
+} else {
+ sys.io.p("Or");
+}
+return 0;
diff --git a/src/test/java/com/seaofnodes/simple/progs/and2.smp b/src/test/java/com/seaofnodes/simple/progs/and2.smp
new file mode 100644
index 00000000..2a463c94
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/and2.smp
@@ -0,0 +1,16 @@
+// -*- mode: java; -*-
+int a = 1;
+int b = 1;
+
+int x=1;
+int y=1;
+int z=0;
+
+int g = x++ && y++ && z++;
+
+if(x == 2 && y == 2 && z == 1 && g == 0) {
+ sys.io.p("Effected");
+} else {
+ sys.io.p("Not effected");
+}
+return 0;
diff --git a/src/test/java/com/seaofnodes/simple/progs/and3.smp b/src/test/java/com/seaofnodes/simple/progs/and3.smp
new file mode 100644
index 00000000..aadbdfed
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/and3.smp
@@ -0,0 +1,14 @@
+// -*- mode: java; -*-
+int a = 1;
+int b = 1;
+
+var sq = { int x ->
+ x*x;
+};
+
+if(a && sq(0)) {
+ sys.io.p("And");
+} else {
+ sys.io.p("Or");
+}
+return 0;
diff --git a/src/test/java/com/seaofnodes/simple/progs/funptr.c b/src/test/java/com/seaofnodes/simple/progs/funptr.c
index 7545992d..2abe6e74 100644
--- a/src/test/java/com/seaofnodes/simple/progs/funptr.c
+++ b/src/test/java/com/seaofnodes/simple/progs/funptr.c
@@ -2,7 +2,7 @@
#include <stdint.h>
typedef int64_t (*Function)(void);
-typedef int64_t (*Printer)(void *);
+typedef int64_t (*Printer)(void *, void *);
extern Function factory(int64_t);
extern Printer printer(void);
@@ -10,6 +10,6 @@ int main(void) {
assert(factory(1)() == 42);
assert(factory(0)() == 43);
struct { uint32_t length; char data[2]; } text = {2, {'o','k'}};
- printer()(&text);
+ printer()(0, &text); // Unused class receiver, then the byte array.
return 0;
}
diff --git a/src/test/java/com/seaofnodes/simple/progs/large.smp b/src/test/java/com/seaofnodes/simple/progs/large.smp
new file mode 100644
index 00000000..73271e66
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/large.smp
@@ -0,0 +1,5344 @@
+
+struct stbi_io_callbacks {
+ { i64 u8[] int -> int } read = "C"; // fill 'data' with 'size' bytes. return number of bytes actually read
+ { i64 int -> int } skip = "C"; // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
+ { i64 -> int } eof = "C"; // returns nonzero if we are at end of file/data
+};
+
+struct stbi__context {
+ u32 img_x, img_y;
+ int img_n, img_out_n;
+
+ !stbi_io_callbacks !io;
+ u8[]io_user_data;
+
+ int read_from_callbacks;
+ int buflen;
+ u8[] buffer_start;
+ int callback_already_read;
+
+ u8[] img_buffer;
+ int img_buffer_end;
+ u8[] img_buffer_original;
+ int img_buffer_original_end;
+};
+
+{ stbi__context -> u8 } stbi__get8 = "C";
+
+val sample = { !stbi__context !s, int pal_len ->
+ var palette = new u8[1024];
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+ for (int i=0; i < pal_len; ++i) {
+ palette[i*4+3] = 0;
+
+ palette[i*4+0] = stbi__get8(s);
+ palette[i*4+1] = stbi__get8(s);
+ palette[i*4+2] = stbi__get8(s);
+ palette[i*4+3] = 255;
+ for (int j=0; j < pal_len; ++j) {
+ palette[j*4+3] = 0;
+
+ palette[j*4+0] = stbi__get8(s);
+ palette[j*4+1] = stbi__get8(s);
+ palette[j*4+2] = stbi__get8(s);
+ palette[j*4+3] = 255;
+ }
+ }
+
+ return palette;
+};
diff --git a/src/test/java/com/seaofnodes/simple/progs/or1.smp b/src/test/java/com/seaofnodes/simple/progs/or1.smp
new file mode 100644
index 00000000..f5f526c3
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/or1.smp
@@ -0,0 +1,12 @@
+// -*- mode: java; -*-
+int a = 1;
+int b = 0;
+
+if(a++ || b++ ) {
+ if(b == 0 && a == 2) {
+ sys.io.p("Or");
+ }
+} else{
+ sys.io.p("And");
+}
+return 0;
diff --git a/src/test/java/com/seaofnodes/simple/progs/or2.smp b/src/test/java/com/seaofnodes/simple/progs/or2.smp
new file mode 100644
index 00000000..ac688b5a
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/or2.smp
@@ -0,0 +1,23 @@
+// -*- mode: java; -*-
+int a = 1;
+int b = 1;
+
+int x = -1;
+int y=1;
+int z= -1;
+
+int g = x++ || y++ || z++;
+
+int switch = 0;
+if(x == 4 || y == 4 || z == 4) {
+ switch = -1;
+} else {
+ switch = 1;
+}
+int cd = 1;
+if((x == 0 && y == 1 && z==-1) && switch && g) {
+ sys.io.p("Effected");
+} else {
+ sys.io.p("Not effected");
+}
+return 0;
diff --git a/src/test/java/com/seaofnodes/simple/progs/print.smp b/src/test/java/com/seaofnodes/simple/progs/print.smp
new file mode 100644
index 00000000..3bb86268
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/print.smp
@@ -0,0 +1,8 @@
+int x = 1;
+
+int y = 2;
+if(x == 1) {
+y = 1;
+}
+
+return y; \ No newline at end of file
diff --git a/src/test/java/com/seaofnodes/simple/progs/ptrand.smp b/src/test/java/com/seaofnodes/simple/progs/ptrand.smp
new file mode 100644
index 00000000..8b8af571
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/ptrand.smp
@@ -0,0 +1,10 @@
+struct S { !S? !fld; };
+
+val ptr = arg == 1 ? null : new S{fld = arg==1 ? null : new S{fld = null;};};
+if( ptr && ptr.fld ) {
+ sys.io.p("true");
+} else {
+ sys.io.p("false");
+}
+
+return 0;
diff --git a/src/test/java/com/seaofnodes/simple/progs/stringHash.smp b/src/test/java/com/seaofnodes/simple/progs/stringHash.smp
index 257f79f9..7344fcdd 100644
--- a/src/test/java/com/seaofnodes/simple/progs/stringHash.smp
+++ b/src/test/java/com/seaofnodes/simple/progs/stringHash.smp
@@ -23,9 +23,8 @@ val hashCode = { !String self ->
val _hashCodeString = { !String self ->
int hash=0;
- if( self.cs )
- for( int i=0; i< self.cs#; i++ )
- hash = hash*31 + self.cs[i];
+ for( int i=0; i< self.cs#; i++ )
+ hash = hash*31 + self.cs[i];
if( !hash ) hash = 123456789;
return hash;
};
diff --git a/src/test/java/com/seaofnodes/simple/progs/stringHash21.smp b/src/test/java/com/seaofnodes/simple/progs/stringHash21.smp
new file mode 100644
index 00000000..257f79f9
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/progs/stringHash21.smp
@@ -0,0 +1,31 @@
+// -*- mode: java; -*-
+struct String {
+ u8[] cs;
+ int _hashCode;
+};
+
+// Compare two Strings
+val equals = { !String !self, !String s ->
+ if( self == s ) return true;
+ if( self.cs# != s.cs# ) return false;
+ for( int i=0; i< self.cs#; i++ )
+ if( self.cs[i] != s.cs[i] )
+ return false;
+ return true;
+};
+
+// Return the String hashCode (cached, and never 0)
+val hashCode = { !String self ->
+ self._hashCode
+ ? self._hashCode
+ : (self._hashCode = _hashCodeString(self));
+};
+
+val _hashCodeString = { !String self ->
+ int hash=0;
+ if( self.cs )
+ for( int i=0; i< self.cs#; i++ )
+ hash = hash*31 + self.cs[i];
+ if( !hash ) hash = 123456789;
+ return hash;
+};