Get rid of the fixed neighbor structures
authorAndreas Eversberg <jolly@eversberg.eu>
Thu, 16 Apr 2015 16:49:30 +0000 (18:49 +0200)
committerroot <root@dion.jolly.ten>
Thu, 14 May 2015 19:09:20 +0000 (21:09 +0200)
lib/multigrid.c

index da6d151..4c0724b 100644 (file)
@@ -58,17 +58,6 @@ void ASSERT_FLOW(int w, int h, int k, const darray_t *flow, const darray_t *flow
 #define NEIGHBORS_2D 9
 #define NEIGHBORS_3D 27
 
-struct neighbors_2d {
-       int num;                        /* # of neighbors */
-       int index[NEIGHBORS_2D];        /* index of neighbors in an array */
-       double weight[NEIGHBORS_2D];    /* calculated weight of neighbors */
-};
-struct neighbors_3d {
-       int num;                        /* # of neighbors */
-       int index[NEIGHBORS_3D];        /* index of neighbors in an array */
-       double weight[NEIGHBORS_3D];    /* calculated weight of neighbors */
-};
-
 static struct neigh_off {
        int x, y, z;
 } neigh_off[NEIGHBORS_3D] = {
@@ -827,6 +816,16 @@ void multiply(const darray_t *array, double factor)
 }
 
 /* create an array of neighbors and use flow vectors
+ *
+ * the elements of the array consist of:
+ *  int num
+ *  int index[neighbors]
+ *  double weight[neighbors]
+ * num specifies the number of neighbors used.
+ * neighbors is fixed for all entries in the array and depends on 2d or 3d
+ * image. since the number of neighbors depends on the dimensions of an image,
+ * they are not fixed. a structure cannot be used in this case.
+ *
  * flow_x and flow_x are the vectors that point to neighbors of the next z plane
  * flow_x and flow_x are the vectors that point to neighbors of the previous z plane
  */
@@ -837,8 +836,8 @@ unsigned char *gen_neighbor(int w, int h, int k, const darray_t *flow, const dar
        int index;
        double *flow_x_ptr, *flow_y_ptr, *flow_ix_ptr, *flow_iy_ptr;
        unsigned char *neighbors, *ret_neighbors;
+       int nb_num, index_offset;
        unsigned long nb_size;
-       int nb_num;
        int *i_index;
 
        ASSERT_FLOW(w, h, k, flow, flow_i);
@@ -848,7 +847,8 @@ unsigned char *gen_neighbor(int w, int h, int k, const darray_t *flow, const dar
        flow_iy_ptr = flow_ix_ptr + w*h*(k-1);
 
        nb_num = (k==1) ? NEIGHBORS_2D : NEIGHBORS_3D;
-       nb_size = (k==1) ? sizeof(struct neighbors_2d) : sizeof(struct neighbors_3d);
+       nb_size = sizeof(int) + (sizeof(int) + sizeof(double)) * nb_num;
+       index_offset = sizeof(int);
        ret_neighbors = neighbors = calloc(w*h*k, nb_size);
 //     printf("alloc neighbor grid=%lu Mbytes\n", nb_size*w*h*k/1024/1024);
        if (!ret_neighbors) {
@@ -859,10 +859,7 @@ unsigned char *gen_neighbor(int w, int h, int k, const darray_t *flow, const dar
        for (z = 0; z < k; z++) {
                for (y = 0; y < h; y++) {
                        for (x = 0; x < w; x++) {
-                               if (k==1)
-                                       i_index = ((struct neighbors_2d *)neighbors)->index;
-                               else
-                                       i_index = ((struct neighbors_3d *)neighbors)->index;
+                               i_index = (int *)(neighbors+index_offset);
                                for (i = 0, n = 0; i < nb_num; i++) {
                                        /* xx, yy, zz is the neighbor of color source
                                         * The first neighbor is always the point itself!
@@ -903,10 +900,7 @@ unsigned char *gen_neighbor(int w, int h, int k, const darray_t *flow, const dar
                                                continue;
                                        i_index[n++] = index;
                                }
-                               if (k == 1)
-                                       ((struct neighbors_2d *)neighbors)->num = n;
-                               else
-                                       ((struct neighbors_3d *)neighbors)->num = n;
+                               *((int *)neighbors) = n;
                                neighbors += nb_size;
                        }
                }
@@ -923,6 +917,7 @@ void weighten(const darray_t *luminance, unsigned char *neighbors)
        double sqdiff[NEIGHBORS_3D];
        double log0_01 = log(0.01);
        double *lum_ptr;
+       int nb_num, index_offset, weight_offset;
        unsigned long nb_size;
        int *i_index; double *w_index;
 
@@ -932,20 +927,17 @@ void weighten(const darray_t *luminance, unsigned char *neighbors)
        k = darrayGetDimensions(luminance)[2];
        lum_ptr = darrayGetPr(luminance);
 
-       nb_size = (k==1) ? sizeof(struct neighbors_2d) : sizeof(struct neighbors_3d);
+       nb_num = (k==1) ? NEIGHBORS_2D : NEIGHBORS_3D;
+       nb_size = sizeof(int) + (sizeof(int) + sizeof(double)) * nb_num;
+       index_offset = sizeof(int);
+       weight_offset = sizeof(int) + sizeof(int) * nb_num;
 
        for (z = 0; z < k; z++) {
                for (y = 0; y < h; y++) {
                        for (x = 0; x < w; x++, neighbors += nb_size) {
-                               if (k==1) {
-                                       num = ((struct neighbors_2d *)neighbors)->num;
-                                       i_index = ((struct neighbors_2d *)neighbors)->index;
-                                       w_index = ((struct neighbors_2d *)neighbors)->weight;
-                               } else {
-                                       num = ((struct neighbors_3d *)neighbors)->num;
-                                       i_index = ((struct neighbors_3d *)neighbors)->index;
-                                       w_index = ((struct neighbors_3d *)neighbors)->weight;
-                               }
+                               num = *((int *)neighbors);
+                               i_index = (int *)(neighbors+index_offset);
+                               w_index = (double *)(neighbors+weight_offset);
                                /* Be sure that we have at least 3 neighbors.
                                 * This applies for every corner in a plane.
                                 * The first point in the neighbor list iss the point itself.
@@ -1013,6 +1005,7 @@ static void smooth(int level, darray_t *value, const darray_t *mark, const darra
        int x, y, z, w, h, k, i, num;
        double *value_ptr, *value_line_ptr, *mark_line_ptr, *init_line_ptr;
        double val;
+       int nb_num, index_offset, weight_offset;
        unsigned long nb_size;
        int *i_index; double *w_index;
 
@@ -1027,7 +1020,10 @@ static void smooth(int level, darray_t *value, const darray_t *mark, const darra
        ASSERT(k == darrayGetDimensions(mark)[2], "z-sizes of mark array is different");
        value_ptr = darrayGetPr(value);
 
-       nb_size = (k==1) ? sizeof(struct neighbors_2d) : sizeof(struct neighbors_3d);
+       nb_num = (k==1) ? NEIGHBORS_2D : NEIGHBORS_3D;
+       nb_size = sizeof(int) + (sizeof(int) + sizeof(double)) * nb_num;
+       index_offset = sizeof(int);
+       weight_offset = sizeof(int) + sizeof(int) * nb_num;
 
        for (z = 0; z < k; z++) {
                for (y = 0; y < h; y++) {
@@ -1035,15 +1031,9 @@ static void smooth(int level, darray_t *value, const darray_t *mark, const darra
                        mark_line_ptr = darrayGetPr(mark) + y*w + z*w*h;
                        init_line_ptr = darrayGetPr(init) + y*w + z*w*h;
                        for (x = 0; x < w; x++, neighbors += nb_size) {
-                               if (k==1) {
-                                       num = ((struct neighbors_2d *)neighbors)->num;
-                                       i_index = ((struct neighbors_2d *)neighbors)->index;
-                                       w_index = ((struct neighbors_2d *)neighbors)->weight;
-                               } else {
-                                       num = ((struct neighbors_3d *)neighbors)->num;
-                                       i_index = ((struct neighbors_3d *)neighbors)->index;
-                                       w_index = ((struct neighbors_3d *)neighbors)->weight;
-                               }
+                               num = *((int *)neighbors);
+                               i_index = (int *)(neighbors+index_offset);
+                               w_index = (double *)(neighbors+weight_offset);
                                /* if pixle is marked */
                                darrayCheckPr(mark, mark_line_ptr + x, 1);
                                if (mark_line_ptr[x] < 0.5) {
@@ -1082,6 +1072,7 @@ static double residual(int level, darray_t *value, const darray_t *mark, const d
        int x, y, z, w, h, k, i, num;
        double *value_ptr, *mark_line_ptr, *init_line_ptr;
        double val, residual = 0;
+       int nb_num, index_offset, weight_offset;
        unsigned long nb_size;
        int *i_index; double *w_index;
 
@@ -1096,22 +1087,19 @@ static double residual(int level, darray_t *value, const darray_t *mark, const d
        ASSERT(k == darrayGetDimensions(mark)[2], "z-sizes of mark array is different");
        value_ptr = darrayGetPr(value);
 
-       nb_size = (k==1) ? sizeof(struct neighbors_2d) : sizeof(struct neighbors_3d);
+       nb_num = (k==1) ? NEIGHBORS_2D : NEIGHBORS_3D;
+       nb_size = sizeof(int) + (sizeof(int) + sizeof(double)) * nb_num;
+       index_offset = sizeof(int);
+       weight_offset = sizeof(int) + sizeof(int) * nb_num;
 
        for (z = 0; z < k; z++) {
                for (y = 0; y < h; y++) {
                        init_line_ptr = darrayGetPr(init) + y*w + z*w*h;
                        mark_line_ptr = darrayGetPr(mark) + y*w + z*w*h;
                        for (x = 0; x < w; x++, neighbors += nb_size) {
-                               if (k==1) {
-                                       num = ((struct neighbors_2d *)neighbors)->num;
-                                       i_index = ((struct neighbors_2d *)neighbors)->index;
-                                       w_index = ((struct neighbors_2d *)neighbors)->weight;
-                               } else {
-                                       num = ((struct neighbors_3d *)neighbors)->num;
-                                       i_index = ((struct neighbors_3d *)neighbors)->index;
-                                       w_index = ((struct neighbors_3d *)neighbors)->weight;
-                               }
+                               num = *((int *)neighbors);
+                               i_index = (int *)(neighbors+index_offset);
+                               w_index = (double *)(neighbors+weight_offset);
                                /* if pixle is marked, no residual */
                                darrayCheckPr(mark, mark_line_ptr + x, 1);
                                if (mark_line_ptr[x] < 0.5)