CR2RE Pipeline Reference Manual 1.7.0
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/*----------------------------------------------------------------------------*/
383/*----------------------------------------------------------------------------*/
384void hdrl_imagelist_delete(hdrl_imagelist * himlist)
385{
386 if (himlist != NULL) {
387 hdrl_imagelist_empty(himlist);
388 hdrl_imagelist_unwrap(himlist);
389 }
390}
391
392/*----------------------------------------------------------------------------*/
402/*----------------------------------------------------------------------------*/
403void hdrl_imagelist_empty(hdrl_imagelist * himlist)
404{
405 if (himlist != NULL) {
406 while (himlist->ni > 0) { /* An iteration may unset more than 1 image */
407
408 cpl_size i = himlist->ni - 1;
409 hdrl_image *del = hdrl_imagelist_unset(himlist, i);
410
411 /* If this image was inserted more than once into the list,
412 the other insertions must be unset without a delete. */
413 while (--i >= 0) {
414 if (himlist->images[i] == del) {
415 /* This image was inserted more than once in the list */
416 del = hdrl_imagelist_unset(himlist, i);
417 }
418 }
419
421 }
422 }
423}
424
425/*----------------------------------------------------------------------------*/
437/*----------------------------------------------------------------------------*/
438hdrl_imagelist * hdrl_imagelist_duplicate(const hdrl_imagelist * himlist)
439{
440 hdrl_imagelist * out;
441 cpl_size i;
442
443 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
444
445 /* Create the new imagelist */
446 out = hdrl_imagelist_new();
447
448 /* Duplicate the images */
449 for (i=0; i<himlist->ni; i++) {
450 hdrl_imagelist_set(out, hdrl_image_duplicate(himlist->images[i]), i);
451 }
452
453 return out;
454}
455
456/*----------------------------------------------------------------------------*/
467/*----------------------------------------------------------------------------*/
468int hdrl_imagelist_is_consistent(const hdrl_imagelist * himlist)
469{
470 cpl_ensure(himlist != NULL, CPL_ERROR_NULL_INPUT, -1);
471 if (himlist->ni == 0) return 1;
472
473 /* Check the images */
474 // TODO
475 return 0;
476}
477
478/*----------------------------------------------------------------------------*/
489/*----------------------------------------------------------------------------*/
491 const hdrl_imagelist * himlist,
492 FILE * stream)
493{
494 const int msgmin = (int)strlen(HDRL_MSG) - 5;
495
496 int i;
497
498 cpl_ensure_code(himlist != NULL, CPL_ERROR_NULL_INPUT);
499 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
500
501 cpl_ensure_code( fprintf(stream, HDRL_MSG, (int)himlist->ni) >= msgmin,
502 CPL_ERROR_FILE_IO );
503
504 for (i = 0; i < himlist -> ni; i++) {
505 const hdrl_image * image = hdrl_imagelist_get_const(himlist, i);
506 const int imsgmin = (int)strlen(HDRL_IMSG) - 5;
507
508 cpl_ensure_code( fprintf(stream, HDRL_IMSG, i, (int)himlist->ni) >= imsgmin,
509 CPL_ERROR_FILE_IO );
510
511 cpl_ensure_code( !hdrl_image_dump_structure(image, stream),
512 cpl_error_get_code() );
513 }
514
515 return CPL_ERROR_NONE;
516}
517
518/*----------------------------------------------------------------------------*/
535/*----------------------------------------------------------------------------*/
537 const hdrl_imagelist * himlist,
538 cpl_size llx,
539 cpl_size lly,
540 cpl_size urx,
541 cpl_size ury,
542 FILE * stream)
543{
544 cpl_size i;
545
546 cpl_ensure_code(himlist != NULL, CPL_ERROR_NULL_INPUT);
547 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
548
549 for (i = 0; i < himlist -> ni; i++) {
550 const hdrl_image * image = hdrl_imagelist_get_const(himlist, i);
551 const int imsgmin = (int)strlen(HDRL_IMSG) - 5;
552
553 cpl_ensure_code( fprintf(stream, HDRL_IMSG, (int)i,
554 (int)himlist->ni) >= imsgmin, CPL_ERROR_FILE_IO );
555
556 cpl_ensure_code( !hdrl_image_dump_window(image, llx, lly, urx, ury,
557 stream),
558 cpl_error_get_code() );
559 }
560 return CPL_ERROR_NONE;
561}
562
563/*----------------------------------------------------------------------------*/
574/*----------------------------------------------------------------------------*/
575void hdrl_imagelist_unwrap(hdrl_imagelist * himlist)
576{
577 if (himlist != NULL) {
578 cpl_free(himlist->images);
579 cpl_free(himlist);
580 }
581 return;
582}
583
584typedef struct {
585 const hdrl_imagelist * hlist;
586 cpl_size ny;
587 cpl_size prev_pos;
588 cpl_size pos;
589 cpl_size nrows;
590 cpl_size overlap;
591 hdrl_imagelist * last_view;
592} hdrl_imagelist_row_slices_iter;
593
594static void * hdrl_imagelist_row_slices_next(hdrl_iter * it)
595{
596 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
597 if (s->pos > s->ny) {
598 return NULL;
599 }
600 cpl_size lower = CX_MAX(s->pos - s->overlap, 1);
601 cpl_size upper = CX_MIN(s->pos + s->nrows + s->overlap - 1, s->ny);
602 /* const iterator means you cannot modify the data but the created views
603 * can have a NULL bpm which can be faster e.g. when calling
604 * cpl_image_new_from_accepted on the view */
605 /* TODO could set memory readonly? */
606 hdrl_imagelist * view;
607
608 CPL_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
609 if (hdrl_iter_check(it, HDRL_ITER_CONST)) {
610 view = (hdrl_imagelist*)
611 hdrl_imagelist_const_row_view((hdrl_imagelist*)s->hlist,
612 lower, upper);
613 }
614 else {
615 view = hdrl_imagelist_row_view((hdrl_imagelist*)s->hlist,
616 lower, upper);
617 }
618 CPL_DIAG_PRAGMA_POP;
619
620 s->prev_pos = s->pos;
621 s->pos = CX_MIN(s->pos + s->nrows - 1, s->ny) + 1;
622 if (hdrl_iter_check(it, HDRL_ITER_OWNS_DATA)) {
623 hdrl_imagelist_delete(s->last_view);
624 s->last_view = view;
625 }
626 return view;
627}
628
629hdrl_il_rowsliceiter_data
630hdrl_imagelist_iter_row_slices_get_data(const hdrl_iter * it)
631{
632 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
633
634 if (s->prev_pos == 1) {
635 return (hdrl_il_rowsliceiter_data){1., CX_MIN(s->nrows, s->ny)};
636 }
637 else {
638 return (hdrl_il_rowsliceiter_data){s->overlap + 1, s->overlap + s->pos - s->prev_pos};
639 }
640}
641
642static cpl_size hdrl_imagelist_row_slices_length(hdrl_iter * it)
643{
644 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
645 return s->ny / s->nrows + ((s->ny % s->nrows) != 0);
646}
647
648static void hdrl_imagelist_iter_delete(void * it)
649{
650 if (!it)
651 return;
652 hdrl_imagelist_row_slices_iter * s = hdrl_iter_state(it);
653 hdrl_imagelist_delete(s->last_view);
654 cpl_free(s);
655}
656
657/* TODO, add offset and stride for parallel processing? or imagelist_split? */
658hdrl_iter * hdrl_imagelist_get_iter_row_slices(const hdrl_imagelist * hlist,
659 cpl_size nrows,
660 cpl_size overlap,
661 hdrl_iter_flags flags)
662{
663 cpl_ensure(hlist, CPL_ERROR_NULL_INPUT, NULL);
664 /* 0 accepted for now, could mean choosen by function */
665 cpl_ensure(nrows >= 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
666 cpl_ensure(hdrl_imagelist_get_size(hlist) > 0,
667 CPL_ERROR_ILLEGAL_INPUT, NULL);
668
669 hdrl_imagelist_row_slices_iter * state = cpl_malloc(sizeof(*state));
670 state->hlist = hlist;
671 state->ny = hdrl_imagelist_get_size_y(hlist);
672 state->prev_pos = 1;
673 state->pos = 1;
674 state->overlap = CX_MAX(overlap, 0);
675 state->nrows = CX_MAX(nrows, 1);
676 state->last_view = NULL;
677
678 return hdrl_iter_init(hdrl_imagelist_row_slices_next, NULL,
679 hdrl_imagelist_row_slices_length,
680 hdrl_imagelist_iter_delete,
681 HDRL_ITER_INPUT | HDRL_ITER_IMAGELIST | flags,
682 state);
683}
684
685
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.