// ######################################################################
void env_stdio_write_gray(const struct env_image* iimage,
                          const char* outstem, const char* name, int c)
{
        if (!env_img_initialized(iimage))
                return;

        // if outstem is the empty string, then the user wanted us to
        // suppress output:
        if (outstem[0] == '\0')
                return;

        char fname[256];
        snprintf(fname, sizeof(fname),
                 "%s-%s%06d.pnm", outstem, name, c);

        FILE* const f = fopen(fname, "wb");
        if (f == 0)
                lfatal("%s: couldn't open PNM file for writing (errno=%d, %s)",
                       fname, errno, strerror(errno));

        //REV: so they are P5 (binary, greyscale), dim * dim images, with max value 255.
        if (fprintf(f, "P5\n%d %d\n255\n",
                    (int) iimage->dims.w, (int) iimage->dims.h) < 0)
                lfatal("%s: fprintf() failed (errno=%d, %s)",
                       fname, errno, strerror(errno));

        const intg32* const src = env_img_pixels(iimage);
        const env_size_t sz = env_img_size(iimage);
        byte* bimage =
                (byte*) env_allocate(sz * sizeof(byte));

        for (env_size_t i = 0; i < sz; ++i)
        {
                // the caller is supposed to have already ensured that
                // the intg32 image has been downsampled to a [0,255]
                // range, so let's verify that:
                ENV_ASSERT(src[i] >= 0 && src[i] <= 255);
                bimage[i] = (byte) src[i];
        }
        
        //REV: they aren't using any newlines!
        if (fwrite(bimage, 1, sz, f) != sz)
        {
                env_deallocate(bimage);
                lfatal("%s: fwrite() failed (errno=%d, %s)",
                       fname, errno, strerror(errno));
        }

        env_deallocate(bimage);

        if (fclose(f) != 0)
                lfatal("%s: fclose() failed (errno=%d, %s)",
                       fname, errno, strerror(errno));
}
Example #2
0
// ######################################################################
void env_mt_chan_orientation(const char* tagName,
                             const struct env_params* envp,
                             const struct env_math* imath,
                             const struct env_image* img,
                             env_chan_status_func* status_func,
                             void* status_userdata,
                             struct env_image* result)
{
        env_img_make_empty(result);

        if (envp->num_orientations == 0)
                return;

        struct env_pyr hipass9;
        env_pyr_init(&hipass9, env_max_pyr_depth(envp));
        env_pyr_build_hipass_9(img,
                               envp->cs_lev_min,
                               imath,
                               &hipass9);

        char buf[17] =
                {
                        's', 't', 'e', 'e', 'r', 'a', 'b', 'l', 'e', // 0--8
                        '(', '_', '_', // 9--11
                        '/', '_', '_', ')', '\0' // 12--16
                };

        ENV_ASSERT(envp->num_orientations <= 99);

        buf[13] = '0' + (envp->num_orientations / 10);
        buf[14] = '0' + (envp->num_orientations % 10);

        struct env_job* jobs =
                env_allocate(envp->num_orientations * sizeof(struct env_job));

        ENV_ASSERT2(jobs != 0, "env_allocate failed");

        struct env_ori_subjob_data* jobdata =
                env_allocate(envp->num_orientations
                             * sizeof(struct env_ori_subjob_data));

        ENV_ASSERT2(jobdata != 0, "env_allocate failed");

        for (env_size_t i = 0; i < envp->num_orientations; ++i)
        {
                // theta = (180.0 * i) / envp->num_orientations +
                // 90.0, where ENV_TRIG_TABSIZ is equivalent to 360.0
                // or 2*pi
                const env_size_t thetaidx =
                        (ENV_TRIG_TABSIZ * i)
                        / (2 * envp->num_orientations)
                        + (ENV_TRIG_TABSIZ / 4);

                ENV_ASSERT(thetaidx < ENV_TRIG_TABSIZ);

                buf[10] = '0' + ((i+1) / 10);
                buf[11] = '0' + ((i+1) % 10);

                jobdata[i].envp = envp;
                jobdata[i].imath = imath;
                jobdata[i].dims = img->dims;
                jobdata[i].hipass9 = &hipass9;
                jobdata[i].thetaidx = thetaidx;
                jobdata[i].status_func = status_func;
                jobdata[i].status_userdata = status_userdata;
                env_img_init_empty(&jobdata[i].chanOut);
                for (env_size_t c = 0; c < sizeof(buf); ++c)
                        jobdata[i].channame[c] = buf[c];

                jobs[i].callback = &env_ori_subjob_run;
                jobs[i].userdata = &jobdata[i];
        }

        env_run_jobs(&jobs[0], envp->num_orientations);

        for (env_size_t i = 0; i < envp->num_orientations; ++i)
        {
                struct env_image* chanOut = &jobdata[i].chanOut;

                if (!env_img_initialized(result))
                {
                        env_img_resize_dims(result, chanOut->dims);
                        env_c_image_div_scalar
                                (env_img_pixels(chanOut),
                                 env_img_size(chanOut),
                                 (intg32) envp->num_orientations,
                                 env_img_pixelsw(result));
                }
                else
                {
                        ENV_ASSERT(env_dims_equal(chanOut->dims,
                                                  result->dims));
                        env_c_image_div_scalar_accum
                                (env_img_pixels(chanOut),
                                 env_img_size(chanOut),
                                 (intg32) envp->num_orientations,
                                 env_img_pixelsw(result));
                }

                env_img_make_empty(chanOut);
        }

        env_pyr_make_empty(&hipass9);

        ENV_ASSERT(env_img_initialized(result));

        env_max_normalize_inplace(result, INTMAXNORMMIN, INTMAXNORMMAX,
                                  envp->maxnorm_type,
                                  envp->range_thresh);

        if (status_func)
                (*status_func)(status_userdata, tagName, result);

        env_deallocate(jobdata);
        env_deallocate(jobs);
}
Example #3
0
// ######################################################################
void env_mt_motion_channel_input_and_consume_pyr(
        struct env_motion_channel* chan,
        const char* tagName,
        const struct env_params* envp,
        const struct env_math* imath,
        const struct env_dims inputdims,
        struct env_pyr* unshiftedCur,
        env_chan_status_func* status_func,
        void* status_userdata,
        struct env_image* result)
{
        env_img_make_empty(result);

        if (chan->num_directions != envp->num_motion_directions)
        {
                env_motion_channel_destroy(chan);
                env_motion_channel_init(chan, envp);
        }

        if (chan->num_directions == 0)
                return;

        char buf[17] =
                {
                        'r', 'e', 'i', 'c', 'h', 'a', 'r', 'd', 't', // 0--8
                        '(', '_', '_', // 9--11
                        '/', '_', '_', ')', '\0' // 12--16
                };

        ENV_ASSERT(chan->num_directions <= 99);

        buf[13] = '0' + (chan->num_directions / 10);
        buf[14] = '0' + (chan->num_directions % 10);

        struct env_job* jobs =
                env_allocate(chan->num_directions * sizeof(struct env_job));

        ENV_ASSERT2(jobs != 0, "env_allocate failed");

        struct env_direction_job_data* jobdata =
                env_allocate(chan->num_directions
                             * sizeof(struct env_direction_job_data));

        ENV_ASSERT2(jobdata != 0, "env_allocate failed");

        // compute Reichardt motion detection into several directions
        for (env_size_t dir = 0; dir < chan->num_directions; ++dir)
        {
                buf[10] = '0' + ((dir+1) / 10);
                buf[11] = '0' + ((dir+1) % 10);

                jobdata[dir].chan = chan;
                jobdata[dir].dir = dir;
                jobdata[dir].envp = envp;
                jobdata[dir].imath = imath;
                jobdata[dir].inputdims = inputdims;
                jobdata[dir].unshiftedCur = unshiftedCur;
                jobdata[dir].status_func = status_func;
                jobdata[dir].status_userdata = status_userdata;
                env_img_init_empty(&jobdata[dir].chanOut);
                for (env_size_t c = 0; c < sizeof(buf); ++c)
                        jobdata[dir].channame[c] = buf[c];

                jobs[dir].callback = &env_direction_job_run;
                jobs[dir].userdata = &jobdata[dir];
        }

        env_run_jobs(&jobs[0], chan->num_directions);

        for (env_size_t dir = 0; dir < chan->num_directions; ++dir)
        {
                struct env_image* chanOut = &jobdata[dir].chanOut;

                if (env_img_initialized(chanOut))
                {
                        if (!env_img_initialized(result))
                        {
                                env_img_resize_dims(result, chanOut->dims);
                                env_c_image_div_scalar
                                        (env_img_pixels(chanOut),
                                         env_img_size(chanOut),
                                         (intg32) chan->num_directions,
                                         env_img_pixelsw(result));
                        }
                        else
                        {
                                ENV_ASSERT
                                        (env_dims_equal(chanOut->dims,
                                                        result->dims));
                                env_c_image_div_scalar_accum
                                        (env_img_pixels(chanOut),
                                         env_img_size(chanOut),
                                         (intg32) chan->num_directions,
                                         env_img_pixelsw(result));
                        }
                }

                env_img_make_empty(chanOut);
        }

        if (env_img_initialized(result))
        {
                env_max_normalize_inplace(result,
                                          INTMAXNORMMIN, INTMAXNORMMAX,
                                          envp->maxnorm_type,
                                          envp->range_thresh);
                if (status_func)
                        (*status_func)(status_userdata, tagName, result);
        }

        env_pyr_swap(unshiftedCur, &chan->unshifted_prev);
        env_pyr_make_empty(unshiftedCur);

        env_deallocate(jobdata);
        env_deallocate(jobs);
}