CR2RE Pipeline Reference Manual 1.6.7
hdrl_multiiter.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2016 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27
28#include "hdrl_multiiter.h"
29#include "hdrl_iter.h"
30
31#include <cpl.h>
32#include <assert.h>
33
34/*-----------------------------------------------------------------------------
35 Static Prototypes
36 -----------------------------------------------------------------------------*/
37
38/*----------------------------------------------------------------------------*/
43/*----------------------------------------------------------------------------*/
44
45/*-----------------------------------------------------------------------------
46 Function codes
47 -----------------------------------------------------------------------------*/
48#define MAX_ITERS 32
49
50typedef struct {
51 const cpl_frameset * frames;
52 hdrl_iter * iters[MAX_ITERS];
53 intptr_t niters;
54 void * data[MAX_ITERS];
55} hdrl_multiiter_state;
56
57static cpl_size hdrl_multiiter_length(hdrl_iter * it);
58static void hdrl_multiiter_delete(void * it);
59static void * hdrl_multiiter_next(hdrl_iter * it);
60
61/* ---------------------------------------------------------------------------*/
78/* ---------------------------------------------------------------------------*/
79hdrl_iter *
80hdrl_multiiter_new(intptr_t niters, hdrl_iter * iters[], hdrl_iter_flags flags)
81{
82 cpl_ensure(niters > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
83 cpl_ensure(iters, CPL_ERROR_NULL_INPUT, NULL);
84 hdrl_multiiter_state * state = cpl_calloc(sizeof(*state), 1);
85 state->niters = niters;
86 cpl_size nlen = hdrl_iter_length(iters[0]);
87 for (intptr_t i = 0; i < niters; i++) {
88 state->iters[i] = iters[i];
89 /* TODO add broadcasting */
90 if (!(flags & HDRL_ITER_ALLOW_EMPTY) &&
91 hdrl_iter_length(iters[i]) != nlen) {
92 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
93 "Iterator length must match");
94 }
95 }
96
97 return hdrl_iter_init(&hdrl_multiiter_next, NULL,
98 &hdrl_multiiter_length,
99 &hdrl_multiiter_delete,
100 HDRL_ITER_INPUT | HDRL_ITER_IMAGE | flags,
101 state);
102}
103
104static cpl_size hdrl_multiiter_length(hdrl_iter * it)
105{
106 hdrl_multiiter_state * state = hdrl_iter_state(it);
107 return hdrl_iter_length(state->iters[0]);
108}
109
110static void hdrl_multiiter_delete(void * it)
111{
112 if (!it)
113 return;
114 hdrl_multiiter_state * state = hdrl_iter_state(it);
115 for (intptr_t i = 0; i < state->niters; i++) {
116 hdrl_iter_delete(state->iters[i]);
117 }
118 cpl_free(state);
119}
120
121
122static void * hdrl_multiiter_next(hdrl_iter * it)
123{
124 hdrl_multiiter_state * state = hdrl_iter_state(it);
125 int done = 0;
126 for (intptr_t i = 0; i < state->niters; i++) {
127 state->data[i] = hdrl_iter_next(state->iters[i]);
128 if (state->data[i] == NULL) {
129 done++;
130 }
131 assert(hdrl_iter_check(it, HDRL_ITER_ALLOW_EMPTY) ||
132 (done && !state->data[i]) || (!done && state->data[i]));
133 }
134 /* if empties are allowed we are done when all iterators are done */
135 if (hdrl_iter_check(it, HDRL_ITER_ALLOW_EMPTY)) {
136 return done == state->niters ? NULL : state->data;
137 }
138 else {
139 return done ? NULL : state->data;
140 }
141}
142
hdrl_iter * hdrl_multiiter_new(intptr_t niters, hdrl_iter *iters[], hdrl_iter_flags flags)
iterate over multiple iterators