about summary refs log tree commit diff
path: root/generator/pamtris/utils.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2018-08-12 21:09:59 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2018-08-12 21:09:59 +0000
commit2c880103c0b55ca5c15bc9e957c3460cdd20d18b (patch)
tree540e473de8e09581c1901bc4e69e9218c2ffd756 /generator/pamtris/utils.c
parent8709c6e659f2e13153bbc9348ec51f2f13103978 (diff)
downloadnetpbm-mirror-2c880103c0b55ca5c15bc9e957c3460cdd20d18b.tar.gz
netpbm-mirror-2c880103c0b55ca5c15bc9e957c3460cdd20d18b.tar.xz
netpbm-mirror-2c880103c0b55ca5c15bc9e957c3460cdd20d18b.zip
Add Pamtris
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3298 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'generator/pamtris/utils.c')
-rw-r--r--generator/pamtris/utils.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/generator/pamtris/utils.c b/generator/pamtris/utils.c
new file mode 100644
index 00000000..550cc41d
--- /dev/null
+++ b/generator/pamtris/utils.c
@@ -0,0 +1,178 @@
+#include <stdlib.h>
+
+#include "common.h"
+
+void
+step_up(fract *       vars,
+        const fract * steps,
+        uint8_t       elements,
+        int32_t       div) {
+
+    unsigned int i;
+
+    for (i = 0; i < elements; ++i) {
+        uint32_t negative_mask = -steps[i].negative_flag;
+        vars[i].q += steps[i].q;
+        vars[i].r += steps[i].r;
+
+        {
+            uint32_t overdiv_mask = -(((uint32_t)~(vars[i].r - div)) >> 31);
+                /*  = ~0 if var->r >= div; 0 otherwise. */
+
+            vars[i].q += (negative_mask | 1) & overdiv_mask;
+                /* = (-1 if the step is negative; 1 otherwise) &'ed with
+                   overdiv_mask.  vars[i].r -= div & overdiv_mask;
+                */
+        }
+    }
+}
+
+
+
+void
+multi_step_up(fract *       vars,
+              const fract * steps,
+              uint8_t       elements,
+              int32_t       times,
+              int32_t       div) {
+
+    unsigned int i;
+
+    for (i = 0; i < elements; i++) {
+        uint32_t negative_mask = -steps[i].negative_flag;
+
+        vars[i].q += times * steps[i].q;
+        vars[i].r += times * steps[i].r;
+
+        if(vars[i].r >= div && div != 0) {
+            int32_t r_q = vars[i].r / div;
+            int32_t r_r = vars[i].r % div;
+
+            vars[i].q += (-r_q & negative_mask) | (r_q & ~negative_mask);
+                /* = -r_q if the step is negative; r_q, otherwise. */
+            vars[i].r = r_r;
+        }
+    }
+}
+
+
+
+void
+gen_steps(const int32_t * begin,
+          const int32_t * end,
+          fract         * out, uint8_t elements, int32_t div) {
+
+    if (div > 1) {
+        unsigned int i;
+
+        for (i = 0; i < elements; i++) {
+            int32_t delta = end[i] - begin[i];
+
+            out[i].q = delta / div;
+            out[i].r = abs(delta % div);
+            out[i].negative_flag = ((uint32_t)delta) >> 31;
+        }
+    } else {
+        unsigned int i;
+
+        for (i = 0; i < elements; i++) {
+            int32_t delta = end[i] - begin[i];
+
+            out[i].q = delta;
+            out[i].r = 0;
+            out[i].negative_flag = ((uint32_t)delta) >> 31;
+        }
+    }
+}
+
+
+
+void
+fract_to_int32_array(const fract * in,
+                     int32_t *     out,
+                     uint8_t       elements) {
+
+    unsigned int i;
+
+    for (i = 0; i < elements; i++) {
+        out[i] = in[i].q;
+    }
+}
+
+
+
+void
+int32_to_fract_array(const int32_t * in,
+                     fract *         out,
+                     uint8_t         elements) {
+
+    unsigned int i;
+
+    for (i = 0; i < elements; i++) {
+        out[i].q = in[i];
+        out[i].r = 0;
+    }
+}
+
+
+
+static void
+swap(uint8_t * a,
+     uint8_t * b) {
+/*----------------------------------------------------------------------------
+  Swap the contents pointed to by a and b.
+-----------------------------------------------------------------------------*/
+    uint8_t temp = *a;
+    *a = *b;
+    *b = temp;
+}
+
+
+
+void
+sort3(uint8_t *       index_array,
+      const int32_t * y_array,
+      const int32_t * x_array) {
+
+    uint8_t * ia = index_array;
+    const int32_t * ya = y_array;
+    const int32_t * xa = x_array;
+
+    if (ya[0] == ya[1] && ya[1] == ya[2]) {
+        /* In case the vertices represent a degenerate horizontal triangle, we
+           sort according to relative X coordinate, as opposed to Y.
+        */
+        ya = xa;
+    }
+
+    if (ya[ia[2]] < ya[ia[1]]) {
+        swap(ia, ia + 2);
+        if (ya[ia[2]] < ya[ia[1]]) {
+            swap(ia + 1, ia + 2);
+            if (ya[ia[1]] < ya[ia[0]]) {
+                swap(ia, ia + 1);
+            }
+        }
+    } else if (ya[ia[1]] < ya[ia[0]]) {
+        swap(ia, ia + 1);
+        if (ya[ia[2]] < ya[ia[1]]) {
+            swap(ia + 1, ia + 2);
+        }
+    }
+
+    if (ya == xa) {
+        return;
+    }
+
+    if (ya[ia[0]] == ya[ia[1]]) {
+        if (xa[ia[1]] < xa[ia[0]]) {
+            swap(ia, ia + 1);
+        }
+    } else if (ya[ia[1]] == ya[ia[2]]) {
+        if (xa[ia[2]] < xa[ia[1]]) {
+            swap(ia + 1, ia + 2);
+        }
+    }
+}
+
+