Add option to keep I and mI arrays and "neighbor pixle weights" structure
[colorize.git] / lib / colorize.c
index 88ab413..96bd385 100644 (file)
@@ -19,7 +19,7 @@
  *     second dimension = height
  *     fourth dimension = time
  */
-int colorize_prepare(struct colorize *col)
+int colorize_prepare(struct colorize *col, int alloc)
 {
        int dimensions[4];
        int ww, hh, kk, last_kk, d, temp, z;
@@ -46,34 +46,40 @@ int colorize_prepare(struct colorize *col)
                temp=(temp+1)>>1;
        ASSERT(col->max_depth >= 2, "image too small");
 
-       col->nb_list = calloc(col->max_depth, sizeof(struct neighbors *));
+       if (alloc)
+               col->nb_list = calloc(col->max_depth, sizeof(struct neighbors *));
        if (!col->nb_list) {
                rc = -1;
                goto error;
        }
-       col->marks = calloc(col->max_depth, sizeof(darray_t *));
+       if (alloc)
+               col->marks = calloc(col->max_depth, sizeof(darray_t *));
        if (!col->marks) {
                rc = -1;
                goto error;
        }
-       col->values = calloc(col->max_depth, sizeof(darray_t *));
+       if (alloc)
+               col->values = calloc(col->max_depth, sizeof(darray_t *));
        if (!col->values) {
                rc = -1;
                goto error;
        }
-       col->flows = calloc(col->max_depth, sizeof(darray_t *));
+       if (alloc)
+               col->flows = calloc(col->max_depth, sizeof(darray_t *));
        if (!col->flows) {
                rc = -1;
                goto error;
        }
-       col->flows_i = calloc(col->max_depth, sizeof(darray_t *));
+       if (alloc)
+               col->flows_i = calloc(col->max_depth, sizeof(darray_t *));
        if (!col->flows_i) {
                rc = -1;
                goto error;
        }
        if (col->scalexyz) {
                /* the flows_xy are scaled in xy in the current level */
-               col->flows_xy = calloc(col->max_depth, sizeof(darray_t *));
+               if (alloc)
+                       col->flows_xy = calloc(col->max_depth, sizeof(darray_t *));
                if (!col->flows_xy) {
                        rc = -1;
                        goto error;
@@ -98,7 +104,8 @@ int colorize_prepare(struct colorize *col)
                dimensions[0] = ww;
                dimensions[1] = hh;
                dimensions[2] = last_kk;
-               col->marks[d] = darrayCreate(3, dimensions);
+               if (alloc)
+                       col->marks[d] = darrayCreate(3, dimensions);
                if (!col->marks[d]) {
                        rc = -1;
                        goto error;
@@ -107,12 +114,14 @@ int colorize_prepare(struct colorize *col)
                dimensions[1] = hh;
                dimensions[2] = last_kk-1;
                dimensions[3] = 2;
-               col->flows[d] = darrayCreate(4, dimensions);
+               if (alloc)
+                       col->flows[d] = darrayCreate(4, dimensions);
                if (!col->flows[d]) {
                        rc = -1;
                        goto error;
                }
-               col->flows_i[d] = darrayCreate(4, dimensions);
+               if (alloc)
+                       col->flows_i[d] = darrayCreate(4, dimensions);
                if (!col->flows_i[d]) {
                        rc = -1;
                        goto error;
@@ -122,7 +131,8 @@ int colorize_prepare(struct colorize *col)
                        dimensions[1] = (hh+1)>>1;
                        dimensions[2] = kk-1;
                        dimensions[3] = 2;
-                       col->flows_xy[d] = darrayCreate(4, dimensions);
+                       if (alloc)
+                               col->flows_xy[d] = darrayCreate(4, dimensions);
                        if (!col->flows_xy[d]) {
                                rc = -1;
                                goto error;
@@ -198,7 +208,8 @@ int colorize_prepare(struct colorize *col)
                dimensions[0] = ww;
                dimensions[1] = hh;
                dimensions[2] = kk;
-               col->values[d] = darrayCreate(3, dimensions);
+               if (alloc)
+                       col->values[d] = darrayCreate(3, dimensions);
                if (!col->values[d]) {
                        rc = -1;
                        goto error;
@@ -206,13 +217,15 @@ int colorize_prepare(struct colorize *col)
 
                /* generate array of neighbors */
 #ifndef TEST_NO_RENDER
-               col->nb_list[d] = gen_neighbor(ww, hh, kk, col->flows[d], col->flows_i[d]);
+               if (alloc)
+                       col->nb_list[d] = gen_neighbor(ww, hh, kk, col->flows[d], col->flows_i[d]);
                if (!col->nb_list[d]) {
                        rc = -1;
                        goto error;
                }
                /* weighten */
-               weighten(luminance, col->nb_list[d]);
+               if (alloc)
+                       weighten(luminance, col->nb_list[d]);
 #endif
 
                last_kk = kk;
@@ -226,7 +239,8 @@ int colorize_prepare(struct colorize *col)
        dimensions[0] = col->w;
        dimensions[1] = col->h;
        dimensions[2] = col->k;
-       col->init = darrayCreate(3, dimensions);
+       if (alloc)
+               col->init = darrayCreate(3, dimensions);
        if (!col->init) {
                rc = -1;
                goto error;
@@ -481,32 +495,45 @@ void colorize_free(struct colorize *col)
        darrayDestroy(col->init);
 }
 
-int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int scalexyz, char **feat_names)
+int colorize(const darray_t *image, const darray_t *image_mark, const darray_t *flow, const darray_t *flow_i, int inner_iter, int outer_iter, int quick, int scalexyz, char **feat_names, struct colorize **_col)
 {
-       struct colorize col;
+       struct colorize *col;
        int rc = -1;
+       int alloc = 0;
+
+       if (!_col || !(*_col)) {
+               col = calloc(sizeof(*col), 1);
+               memset(col, 0, sizeof(*col));
+               col->image = image;
+               col->image_mark = image_mark;
+               col->flow = flow;
+               col->flow_i = flow_i;
+               col->inner_iter = inner_iter;
+               col->outer_iter = outer_iter;
+               col->scalexyz = scalexyz;
+               alloc = 1;
+       }
+       /* use or assign *_col */
+       if (_col) {
+               if (!(*_col))
+                       *_col = col;
+               else
+                       col = *_col;
+       }
 
-       memset(&col, 0, sizeof(col));
-       col.image = image;
-       col.image_mark = image_mark;
-       col.flow = flow;
-       col.flow_i = flow_i;
-       col.inner_iter = inner_iter;
-       col.outer_iter = outer_iter;
-       col.scalexyz = scalexyz;
-
-       rc = colorize_prepare(&col);
+       rc = colorize_prepare(col, alloc);
        if (rc < 0)
                goto error;
 
-       rc = colorize_solve(&col, 0, feat_names);
+       rc = colorize_solve(col, quick, feat_names);
        if (rc < 0)
                goto error;
 
        rc = 0;
 
 error:
-       colorize_free(&col);
+       if (!_col)
+               colorize_free(col);
 
        return rc;
 }