CR2RE Pipeline Reference Manual 1.6.10
hdrl_imagelist_io.c
1/*
2 * This file is part of the HDRL
3 * Copyright (C) 2013,2014 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_image.h"
29#include "hdrl_imagelist.h"
30#include "hdrl_imagelist_defs.h"
31#include "hdrl_imagelist_view.h"
32#include "hdrl_iter.h"
33
34#include <cpl.h>
35#include <assert.h>
36#include <string.h>
37
38/*-----------------------------------------------------------------------------
39 Defines
40 -----------------------------------------------------------------------------*/
41
42#define HDRL_MSG "Imagelist with %d image(s)\n"
43#define HDRL_IMSG "Image nb %d of %d in imagelist\n"
44
45/*-----------------------------------------------------------------------------
46 Static Prototypes
47 -----------------------------------------------------------------------------*/
48
49/*----------------------------------------------------------------------------*/
54/*----------------------------------------------------------------------------*/
55
56/*-----------------------------------------------------------------------------
57 Function codes
58 -----------------------------------------------------------------------------*/
59
60/* ---------------------------------------------------------------------------*/
69/* ---------------------------------------------------------------------------*/
70static void hdrl_imagelist_set_capacity(hdrl_imagelist * h, cpl_size size)
71{
72 h->capacity = CX_MAX(h->ni, CX_MAX(128, size));
73 h->images = cpl_realloc(h->images, h->capacity * sizeof(h->images[0]));
74}
75
76/*----------------------------------------------------------------------------*/
83/*----------------------------------------------------------------------------*/
84hdrl_imagelist * hdrl_imagelist_new(void)
85{
86 hdrl_imagelist * h = cpl_calloc(1, sizeof(hdrl_imagelist));
87 hdrl_imagelist_set_capacity(h, 128);
88 return h;
89}
90
91/*----------------------------------------------------------------------------*/
101/*----------------------------------------------------------------------------*/
102hdrl_imagelist * hdrl_imagelist_create(
103 cpl_imagelist * imlist,
104 cpl_imagelist * errlist)
105{
106 hdrl_imagelist * himlist ;
107 cpl_image * error ;
108
109 /* Check Entries */
110 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
111 if (errlist) {
112 cpl_ensure(cpl_imagelist_get_size(imlist) ==
113 cpl_imagelist_get_size(errlist), CPL_ERROR_ILLEGAL_INPUT, NULL);
114 }
115
116 /* Create the new HDRL image list */
117 himlist = hdrl_imagelist_new() ;
118
119 /* Loop on the input image list */
120 for (cpl_size i = 0; i < cpl_imagelist_get_size(imlist); i++) {
121 /* Get the error image */
122 hdrl_image * tmp ;
123 if (errlist) {
124 error = cpl_imagelist_get(errlist, i) ;
125 } else {
126 error = NULL ;
127 }
128 /* Create the HDRL image */
129 tmp = hdrl_image_create(cpl_imagelist_get_const(imlist, i), error) ;
130
131 /* Fill the HDRL image list */
132 hdrl_imagelist_set(himlist, tmp, i);
133
134 }
135 return himlist ;
136}
137
138/*----------------------------------------------------------------------------*/
147/*----------------------------------------------------------------------------*/
148cpl_size hdrl_imagelist_get_size(const hdrl_imagelist * himlist)
149{
150 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
151 assert( himlist->ni >= 0 );
152 return himlist->ni;
153}
154
155/*----------------------------------------------------------------------------*/
167/*----------------------------------------------------------------------------*/
168cpl_size hdrl_imagelist_get_size_x(const hdrl_imagelist * himlist)
169{
170 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
171 cpl_ensure(himlist->ni > 0, CPL_ERROR_ILLEGAL_INPUT, -1);
173}
174
175/*----------------------------------------------------------------------------*/
187/*----------------------------------------------------------------------------*/
188cpl_size hdrl_imagelist_get_size_y(const hdrl_imagelist * himlist)
189{
190 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
191 cpl_ensure(himlist->ni > 0, CPL_ERROR_ILLEGAL_INPUT, -1);
193}
194
195/*----------------------------------------------------------------------------*/
209/*----------------------------------------------------------------------------*/
211 const hdrl_imagelist * himlist,
212 cpl_size inum)
213{
214 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
215 cpl_ensure(inum >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
216 cpl_ensure(inum < himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
217 return himlist->images[inum];
218}
219
220/*----------------------------------------------------------------------------*/
228/*----------------------------------------------------------------------------*/
229const hdrl_image * hdrl_imagelist_get_const(
230 const hdrl_imagelist * himlist,
231 cpl_size inum)
232{
233 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
234 cpl_ensure(inum >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
235 cpl_ensure(inum < himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
236 return himlist->images[inum];
237}
238
239/*----------------------------------------------------------------------------*/
273/*----------------------------------------------------------------------------*/
274cpl_error_code hdrl_imagelist_set(
275 hdrl_imagelist * himlist,
276 hdrl_image * himg,
277 cpl_size pos)
278{
279 cpl_ensure_code(himlist, CPL_ERROR_NULL_INPUT);
280 cpl_ensure_code(himg, CPL_ERROR_NULL_INPUT);
281 cpl_ensure_code(pos >= 0, CPL_ERROR_ILLEGAL_INPUT);
282 cpl_ensure_code(pos <= himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE);
283
284 /* Do nothing if the image is already there */
285 if (pos < himlist->ni && himg == himlist->images[pos])
286 return CPL_ERROR_NONE;
287
288 if (pos > 0 || himlist->ni > 1) {
289 /* Require images to have the same size and type */
290 cpl_ensure_code(hdrl_image_get_size_x(himg) ==
291 hdrl_image_get_size_x(himlist->images[0]),
292 CPL_ERROR_INCOMPATIBLE_INPUT);
293 cpl_ensure_code(hdrl_image_get_size_y(himg) ==
294 hdrl_image_get_size_y(himlist->images[0]),
295 CPL_ERROR_INCOMPATIBLE_INPUT);
296 // TODO : type of hdrl_image ??
297 //cpl_ensure_code(hdrl_image_get_type(himg) ==
298 // hdrl_image_get_type(himlist->images[0]),
299 // CPL_ERROR_TYPE_MISMATCH);
300 }
301
302 if (pos == himlist->ni) {
303 /* double buffer if required */
304 if (pos >= himlist->capacity) {
305 hdrl_imagelist_set_capacity(himlist, 2 * pos);
306 }
307 himlist->ni++;
308 } else {
309 /* Check if the image at the position to be overwritten
310 is present in only one position */
311 int i;
312
313 for (i = 0; i < himlist->ni; i++) {
314 if (i != pos && himlist->images[i] == himlist->images[pos]) break;
315 }
316 if (i == himlist->ni) {
317 /* The image at the position to be overwritten
318 is present in only one position, so delete it */
319 hdrl_image_delete(himlist->images[pos]);
320 }
321 }
322
323 himlist->images[pos] = himg;
324
325 return CPL_ERROR_NONE;
326}
327
328/*----------------------------------------------------------------------------*/
346/*----------------------------------------------------------------------------*/
348 hdrl_imagelist * himlist,
349 cpl_size pos)
350{
351 hdrl_image * out;
352 cpl_size i;
353
354 cpl_ensure(himlist, CPL_ERROR_NULL_INPUT, NULL);
355 cpl_ensure(pos >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
356 cpl_ensure(pos < himlist->ni, CPL_ERROR_ACCESS_OUT_OF_RANGE, NULL);
357
358 /* Get pointer to image to be removed */
359 out = himlist->images[pos];
360
361 /* Move the following images one position towards zero */
362 for (i=pos + 1; i < himlist->ni; i++) {
363 himlist->images[i-1] = himlist->images[i];
364 }
365
366 /* Decrement of the size */
367 himlist->ni--;
368
369 /* shrink the buffer if its significantly too large */
370 if (himlist->ni < himlist->capacity / 2) {
371 hdrl_imagelist_set_capacity(himlist, himlist->ni / 2);
372 }
373
374 return out;
375}
376
377/*----------------------------------------------------------------------------*/
384/*----------------------------------------------------------------------------*/
385void hdrl_imagelist_delete(hdrl_imagelist * himlist)
386{
387 if (himlist != NULL) {
388 hdrl_imagelist_empty(himlist);
389 hdrl_imagelist_unwrap(himlist);
390 }
391}
392
393/*----------------------------------------------------------------------------*/
404/*----------------------------------------------------------------------------*/
405void hdrl_imagelist_empty(hdrl_imagelist * himlist)
406{
407 if (himlist != NULL) {
408 while (himlist->ni > 0) { /* An iteration may unset more than 1 image */
409
410 cpl_size i = himlist->ni - 1;
411 hdrl_image *del = hdrl_imagelist_unset(himlist, i);
412
413 /* If this image was inserted more than once into the list,
414 the other insertions must be unset without a delete. */
415 while (--i >= 0) {
416 if (himlist->images[i] == del) {
417 /* This image was inserted more than once in the list */
418 del = hdrl_imagelist_unset(himlist, i);
419 }
420 }
421
423 }
424 }
425}
426
427/*----------------------------------------------------------------------------*/
439/*----------------------------------------------------------------------------*/
440hdrl_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist * himlist)
441{
442 hdrl_imagelist * out;
443 cpl_size i;
444
445 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
446
447 /* Create the new imagelist */
448 out = hdrl_imagelist_new();
449
450 /* Duplicate the images */
451 for (i=0; i<himlist->ni; i++) {
452 hdrl_imagelist_set(out, hdrl_image_duplicate(himlist->images[i]), i);
453 }
454
455 return out;
456}
457
458/*----------------------------------------------------------------------------*/
469/*----------------------------------------------------------------------------*/
470int hdrl_imagelist_is_consistent(const hdrl_imagelist * himlist)
471{
472 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
473 if (himlist->ni == 0) return 1;
474
475 /* Check the images */
476 // TODO
477 return 0;
478}
479
480/*----------------------------------------------------------------------------*/
491/*----------------------------------------------------------------------------*/
493 const hdrl_imagelist * himlist,
494 FILE * stream)
495{
496 const int msgmin = (int)strlen(HDRL_MSG) - 5;
497
498 int i;
499
500 cpl_ensure_code(himlist != NULL, CPL_ERROR_NULL_INPUT);
501 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
502
503 cpl_ensure_code( fprintf(stream, HDRL_MSG, (int)himlist->ni) >= msgmin,
504 CPL_ERROR_FILE_IO );
505
506 for (i = 0; i < himlist -> ni; i++) {
507 const hdrl_image * image = hdrl_imagelist_get_const(himlist, i);
508 const int imsgmin = (int)strlen(HDRL_IMSG) - 5;
509
510 cpl_ensure_code( fprintf(stream, HDRL_IMSG, i, (int)himlist->ni) >= imsgmin,
511 CPL_ERROR_FILE_IO );
512
513 cpl_ensure_code( !hdrl_image_dump_structure(image, stream),
514 cpl_error_get_code() );
515 }
516
517 return CPL_ERROR_NONE;
518}
519
520/*----------------------------------------------------------------------------*/
537/*----------------------------------------------------------------------------*/
539 const hdrl_imagelist * himlist,
540 cpl_size llx,
541 cpl_size lly,
542 cpl_size urx,
543 cpl_size ury,
544 FILE * stream)
545{
546 cpl_size i;
547
548 cpl_ensure_code(himlist != NULL, CPL_ERROR_NULL_INPUT);
549 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
550
551 for (i = 0; i < himlist -> ni; i++) {
552 const hdrl_image * image = hdrl_imagelist_get_const(himlist, i);
553 const int imsgmin = (int)strlen(HDRL_IMSG) - 5;
554
555 cpl_ensure_code( fprintf(stream, HDRL_IMSG, (int)i,
556 (int)himlist->ni) >= imsgmin, CPL_ERROR_FILE_IO );
557
558 cpl_ensure_code( !hdrl_image_dump_window(image, llx, lly, urx, ury,
559 stream),
560 cpl_error_get_code() );
561 }
562 return CPL_ERROR_NONE;
563}
564
565/*----------------------------------------------------------------------------*/
576/*----------------------------------------------------------------------------*/
577void hdrl_imagelist_unwrap(hdrl_imagelist * himlist)
578{
579 if (himlist != NULL) {
580 cpl_free(himlist->images);
581 cpl_free(himlist);
582 }
583 return;
584}
585
586typedef struct {
587 const hdrl_imagelist * hlist;
588 cpl_size ny;
589 cpl_size prev_pos;
590 cpl_size pos;
591 cpl_size nrows;
592 cpl_size overlap;
593 hdrl_imagelist * last_view;
594} hdrl_imagelist_row_slices_iter;
595
596static void * hdrl_imagelist_row_slices_next(hdrl_iter * it)
597{
598 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
599 if (s->pos > s->ny) {
600 return NULL;
601 }
602 cpl_size lower = CX_MAX(s->pos - s->overlap, 1);
603 cpl_size upper = CX_MIN(s->pos + s->nrows + s->overlap - 1, s->ny);
604 /* const iterator means you cannot modify the data but the created views
605 * can have a NULL bpm which can be faster e.g. when calling
606 * cpl_image_new_from_accepted on the view */
607 /* TODO could set memory readonly? */
608 hdrl_imagelist * view;
609
610 CPL_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
611 if (hdrl_iter_check(it, HDRL_ITER_CONST)) {
612 view = (hdrl_imagelist*)
613 hdrl_imagelist_const_row_view((hdrl_imagelist*)s->hlist,
614 lower, upper);
615 }
616 else {
617 view = hdrl_imagelist_row_view((hdrl_imagelist*)s->hlist,
618 lower, upper);
619 }
620 CPL_DIAG_PRAGMA_POP;
621
622 s->prev_pos = s->pos;
623 s->pos = CX_MIN(s->pos + s->nrows - 1, s->ny) + 1;
624 if (hdrl_iter_check(it, HDRL_ITER_OWNS_DATA)) {
625 hdrl_imagelist_delete(s->last_view);
626 s->last_view = view;
627 }
628 return view;
629}
630
631hdrl_il_rowsliceiter_data
632hdrl_imagelist_iter_row_slices_get_data(const hdrl_iter * it)
633{
634 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
635
636 if (s->prev_pos == 1) {
637 return (hdrl_il_rowsliceiter_data){1., CX_MIN(s->nrows, s->ny)};
638 }
639 else {
640 return (hdrl_il_rowsliceiter_data){s->overlap + 1, s->overlap + s->pos - s->prev_pos};
641 }
642}
643
644static cpl_size hdrl_imagelist_row_slices_length(hdrl_iter * it)
645{
646 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
647 return s->ny / s->nrows + ((s->ny % s->nrows) != 0);
648}
649
650static void hdrl_imagelist_iter_delete(void * it)
651{
652 if (!it)
653 return;
654 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
655 hdrl_imagelist_delete(s->last_view);
656 cpl_free(s);
657}
658
659/* TODO, add offset and stride for parallel processing? or imagelist_split? */
660hdrl_iter * hdrl_imagelist_get_iter_row_slices(const hdrl_imagelist * hlist,
661 cpl_size nrows,
662 cpl_size overlap,
663 hdrl_iter_flags flags)
664{
665 cpl_ensure(hlist, CPL_ERROR_NULL_INPUT, NULL);
666 /* 0 accepted for now, could mean choosen by function */
667 cpl_ensure(nrows >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
668 cpl_ensure(hdrl_imagelist_get_size(hlist) > 0,
669 CPL_ERROR_ILLEGAL_INPUT, NULL);
670
671 hdrl_imagelist_row_slices_iter * state = cpl_malloc(sizeof(*state));
672 state->hlist = hlist;
673 state->ny = hdrl_imagelist_get_size_y(hlist);
674 state->prev_pos = 1;
675 state->pos = 1;
676 state->overlap = CX_MAX(overlap, 0);
677 state->nrows = CX_MAX(nrows, 1);
678 state->last_view = NULL;
679
680 return hdrl_iter_init(hdrl_imagelist_row_slices_next, NULL,
681 hdrl_imagelist_row_slices_length,
682 hdrl_imagelist_iter_delete,
683 HDRL_ITER_INPUT | HDRL_ITER_IMAGELIST | flags,
684 state);
685}
686
687
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
cpl_error_code hdrl_image_dump_window(const hdrl_image *himg, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury, FILE *stream)
Dump pixel values in a HDRL image.
Definition: hdrl_image.c:793
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
Definition: hdrl_image.c:540
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
Definition: hdrl_image.c:525
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
Definition: hdrl_image.c:295
cpl_error_code hdrl_image_dump_structure(const hdrl_image *himg, FILE *stream)
Dump structural information of a HDRL image.
Definition: hdrl_image.c:767
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
hdrl_image * hdrl_imagelist_unset(hdrl_imagelist *himlist, cpl_size pos)
Remove an image from an imagelist.
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
cpl_size hdrl_imagelist_get_size_y(const hdrl_imagelist *himlist)
Get number of rows of images in the imagelist.
hdrl_imagelist * hdrl_imagelist_create(cpl_imagelist *imlist, cpl_imagelist *errlist)
Create an hdrl_imagelist out of 2 cpl_imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
const hdrl_image * hdrl_imagelist_get_const(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
void hdrl_imagelist_empty(hdrl_imagelist *himlist)
Empty an imagelist and deallocate all its images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
int hdrl_imagelist_is_consistent(const hdrl_imagelist *himlist)
Determine if an imagelist contains images of equal size and type.
cpl_error_code hdrl_imagelist_dump_window(const hdrl_imagelist *himlist, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury, FILE *stream)
Dump pixel values of images in a imagelist.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.
hdrl_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist *himlist)
Duplicate an image list.
cpl_size hdrl_imagelist_get_size_x(const hdrl_imagelist *himlist)
Get number of colums of images in the imagelist.
cpl_error_code hdrl_imagelist_dump_structure(const hdrl_imagelist *himlist, FILE *stream)
Dump structural information of images in an imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.