CR2RE Pipeline Reference Manual 1.6.7
hdrl_frameiter.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_frameiter.h"
29#include "hdrl_iter.h"
30
31#include <cpl.h>
32
33/*-----------------------------------------------------------------------------
34 Static Prototypes
35 -----------------------------------------------------------------------------*/
36
37/*----------------------------------------------------------------------------*/
42/*----------------------------------------------------------------------------*/
43
44/*-----------------------------------------------------------------------------
45 Function codes
46 -----------------------------------------------------------------------------*/
47#define MAX_DIM 32
48
49typedef struct {
50 /* frameset being iterated */
51 const cpl_frameset * frames;
52 /* number of axes being iterated */
53 intptr_t naxes;
54 /* global index/counter */
55 intptr_t index;
56 /* dimensions of iteration space */
57 intptr_t dim[MAX_DIM];
58 /* current position */
59 intptr_t pos[MAX_DIM];
60 /* current count in dimension */
61 intptr_t cnt[MAX_DIM];
62 /* offsets in data */
63 intptr_t offsets[MAX_DIM];
64 /* iteration strides */
65 intptr_t strides[MAX_DIM];
66 /* iteration axes */
67 intptr_t axes[MAX_DIM];
68 /* last iteration axis */
69 intptr_t naxes_max;
70 hdrl_frameiter_data data;
71} hdrl_frameiter_state;
72
73static cpl_size hdrl_frameiter_length(hdrl_iter * it);
74static void hdrl_frameiter_delete(void * it);
75static void * hdrl_frameiter_next(hdrl_iter * it);
76
77/* ---------------------------------------------------------------------------*/
109/* ---------------------------------------------------------------------------*/
110hdrl_iter *
111hdrl_frameiter_new(const cpl_frameset * frames, hdrl_iter_flags flags,
112 intptr_t naxes,
113 intptr_t * axes, intptr_t * offsets, intptr_t * strides,
114 intptr_t * dims)
115{
116 hdrl_frameiter_state * state = cpl_calloc(sizeof(*state), 1);
117 state->frames = frames;
118 state->naxes = naxes;
119 /* negative to indicate no iteration has happened yet */
120 state->index = -1;
121 /* setup dimensions from data, adapted for user parameters later */
122 state->dim[HDRL_FRAMEITER_AXIS_FRAME] = cpl_frameset_get_size(frames);
123 for (cpl_size i = 0; i < cpl_frameset_get_size(frames); i++) {
124 const cpl_frame * frm = cpl_frameset_get_position_const(frames, i);
125 const char * fn = cpl_frame_get_filename(frm);
126 cpl_size next = cpl_frame_get_nextensions(frm);
127 // todo check shape equality over all frames/ext
128 state->dim[HDRL_FRAMEITER_AXIS_EXT] = next + 1;
129 for (cpl_size j = 0; j < next + 1; j++) {
130 cpl_propertylist * plist =
131 cpl_propertylist_load_regexp(fn, j, "NAXIS.*", 0);
132 if (!cpl_propertylist_has(plist, "NAXIS")) {
133 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "NO DATA");
134 }
135 state->naxes_max = HDRL_FRAMEITER_AXIS_EXT + cpl_propertylist_get_int(plist, "NAXIS");
136 for (int k = 0; k < cpl_propertylist_get_int(plist, "NAXIS"); k++) {
137 char * buf = cpl_sprintf("NAXIS%d", k + 1);
138 state->dim[HDRL_FRAMEITER_AXIS_NAXIS1 + k] = cpl_propertylist_get_int(plist, buf);
139 cpl_free(buf);
140 }
141 cpl_propertylist_delete(plist);
142 }
143 }
144 if (state->naxes_max > HDRL_FRAMEITER_AXIS_NAXIS2 ||
145 naxes > HDRL_FRAMEITER_AXIS_NAXIS2) {
146 cpl_error_set_message(cpl_func, CPL_ERROR_UNSUPPORTED_MODE,
147 "UNSUPPORTED MODE");
148 }
149 if (cpl_error_get_code()) {
150 cpl_free(state);
151 return NULL;
152 }
153
154 /* setup iteration space in data */
155 for (intptr_t i = 0; i < naxes; i++) {
156 intptr_t offset = offsets == NULL ? 0 : offsets[i];
157 intptr_t stride = strides == NULL ? 1 : strides[i];
158 state->pos[axes[i]] = offset;
159 state->offsets[axes[i]] = offset;
160 state->strides[axes[i]] = stride;
161 if (dims && dims[i] > 0) {
162 /* TODO error checking? */
163 state->dim[axes[i]] = dims[i];
164 }
165 else {
166 state->dim[axes[i]] -= offset;
167 if (stride != 0) {
168 if (state->dim[axes[i]] % stride) {
169 state->dim[axes[i]] /= stride;
170 state->dim[axes[i]] += 1;
171 }
172 else {
173 state->dim[axes[i]] /= stride;
174 }
175 }
176 }
177 state->axes[i] = axes[i];
178 }
179 return hdrl_iter_init(&hdrl_frameiter_next, NULL,
180 &hdrl_frameiter_length,
181 &hdrl_frameiter_delete,
182 HDRL_ITER_INPUT | HDRL_ITER_IMAGE | flags, state);
183}
184
185static cpl_size hdrl_frameiter_length(hdrl_iter * it)
186{
187 hdrl_frameiter_state * state = hdrl_iter_state(it);
188 intptr_t sz = 1;
189 for (intptr_t i = 0; i < state->naxes; i++) {
190 sz *= state->dim[state->axes[i]];
191 }
192 return sz;
193}
194
195static void hdrl_frameiter_delete(void * it)
196{
197 if (!it)
198 return;
199 hdrl_frameiter_state * state = hdrl_iter_state(it);
200 if (hdrl_iter_check(it, HDRL_ITER_OWNS_DATA)) {
201 cpl_image_delete(state->data.image);
202 cpl_propertylist_delete(state->data.plist);
203 }
204 cpl_free(state);
205}
206
207static cpl_boolean hdrl_frameiter_done(hdrl_iter * it)
208{
209 hdrl_frameiter_state * state = hdrl_iter_state(it);
210 return state->index >= hdrl_frameiter_length(it);
211}
212
213static void get_data(hdrl_frameiter_state * state)
214{
215 if (state->naxes == 2 && state->naxes_max == HDRL_FRAMEITER_AXIS_NAXIS2) {
216
217 if (state->axes[0] <= HDRL_FRAMEITER_AXIS_EXT &&
218 state->axes[1] <= HDRL_FRAMEITER_AXIS_EXT ){
219
220 cpl_msg_debug(cpl_func, "Getting frame %zd, ext %zd",
221 state->pos[HDRL_FRAMEITER_AXIS_FRAME],
222 state->pos[HDRL_FRAMEITER_AXIS_EXT]);
223
224 const cpl_frame *frm = cpl_frameset_get_position_const(
225 state->frames, state->pos[HDRL_FRAMEITER_AXIS_FRAME]);
226
227 state->data.image = cpl_image_load(cpl_frame_get_filename(frm),
228 CPL_TYPE_UNSPECIFIED, 0, state->pos[HDRL_FRAMEITER_AXIS_EXT]);
229
230 state->data.plist = cpl_propertylist_load(
231 cpl_frame_get_filename(frm), state->pos[HDRL_FRAMEITER_AXIS_EXT]);
232
233 } else {
234 cpl_error_set_message(cpl_func, CPL_ERROR_UNSUPPORTED_MODE, "UNSUPPORTED MODE");
235 }
236
237 } else if (state->naxes == 1 &&
238 state->axes[0] == HDRL_FRAMEITER_AXIS_FRAME ){
239 /*
240 cpl_msg_debug(cpl_func, "Getting frame %zd, ext 0",
241 state->pos[HDRL_FRAMEITER_AXIS_FRAME]);
242 */
243 const cpl_frame * frm = cpl_frameset_get_position_const(
244 state->frames, state->pos[HDRL_FRAMEITER_AXIS_FRAME]);
245
246 state->data.image = cpl_image_load(
247 cpl_frame_get_filename(frm), CPL_TYPE_UNSPECIFIED, 0, 0);
248
249 state->data.plist = cpl_propertylist_load(
250 cpl_frame_get_filename(frm), 0);
251
252 } else if (state->naxes == 1 &&
253 state->axes[0] == HDRL_FRAMEITER_AXIS_EXT ){
254
255 cpl_msg_debug(cpl_func, "Getting frame 0, ext %zd",
256 state->pos[HDRL_FRAMEITER_AXIS_EXT]);
257
258 const cpl_frame * frm = cpl_frameset_get_position_const(
259 state->frames, 0);
260
261 state->data.image = cpl_image_load(cpl_frame_get_filename(frm),
262 CPL_TYPE_UNSPECIFIED, 0, state->pos[HDRL_FRAMEITER_AXIS_EXT]);
263
264 state->data.plist = cpl_propertylist_load(cpl_frame_get_filename(frm),
265 state->pos[HDRL_FRAMEITER_AXIS_EXT]);
266
267 } else {
268 cpl_error_set_message(cpl_func, CPL_ERROR_UNSUPPORTED_MODE, "UNSUPPORTED MODE");
269 }
270}
271
272static void * hdrl_frameiter_next(hdrl_iter * it)
273{
274 hdrl_frameiter_state * state = hdrl_iter_state(it);
275 /* iterate to next position and return data, iterator starts at first
276 * position */
277 state->index++;
278 for (intptr_t i = state->naxes - 1; state->index > 0 && i >= 0; i--) {
279 intptr_t idx = state->axes[i];
280 if (state->cnt[idx] + 1 < state->dim[idx]) {
281 state->cnt[idx]++;
282 state->pos[idx] += state->strides[idx];
283 break;
284 }
285 else {
286 state->cnt[idx] = 0;
287 state->pos[idx] = state->offsets[idx];
288 }
289 }
290
291 if (hdrl_iter_check(it, HDRL_ITER_OWNS_DATA)) {
292 cpl_image_delete(state->data.image);
293 cpl_propertylist_delete(state->data.plist);
294 state->data.image = NULL;
295 state->data.plist = NULL;
296 }
297
298 if (hdrl_frameiter_done(it)) {
299 return NULL;
300 }
301
302 get_data(state);
303 return &state->data;
304
305}
306
hdrl_iter * hdrl_frameiter_new(const cpl_frameset *frames, hdrl_iter_flags flags, intptr_t naxes, intptr_t *axes, intptr_t *offsets, intptr_t *strides, intptr_t *dims)
create iterator over cpl_frameset