CR2RE Pipeline Reference Manual 1.6.10
hdrl_image.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_elemop.h"
29#include "hdrl_image.h"
30#include "hdrl_image_defs.h"
31#include "hdrl_utils.h"
32#include "hdrl_buffer.h"
33
34#include <cpl.h>
35#include <string.h>
36#include <math.h>
37
38/*----------------------------------------------------------------------------*/
46/*----------------------------------------------------------------------------*/
47
50/*-----------------------------------------------------------------------------
51 Functions
52 -----------------------------------------------------------------------------*/
53
54static void _hdrl_image_delete(hdrl_image * himg);
55static void _hdrl_image_delete_buffer(hdrl_image * himg);
56static void _hdrl_image_sync_mask(hdrl_image * himg);
57
58/* ---------------------------------------------------------------------------*/
64/* ---------------------------------------------------------------------------*/
65static cpl_error_code
66hdrl_image_check_consistent(const cpl_image * image,
67 const cpl_image * error)
68{
69 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
70 if (error) {
71 cpl_size inx = cpl_image_get_size_x(image);
72 cpl_size iny = cpl_image_get_size_y(image);
73 cpl_size enx = cpl_image_get_size_x(error);
74 cpl_size eny = cpl_image_get_size_y(error);
75 const cpl_mask * ibpm = cpl_image_get_bpm_const(image);
76 const cpl_mask * ebpm = cpl_image_get_bpm_const(error);
77 cpl_ensure_code(inx == enx, CPL_ERROR_INCOMPATIBLE_INPUT);
78 cpl_ensure_code(iny == eny, CPL_ERROR_INCOMPATIBLE_INPUT);
79
80 if (ibpm && ebpm) {
81 const cpl_binary * dibpm = cpl_mask_get_data_const(ibpm);
82 const cpl_binary * debpm = cpl_mask_get_data_const(ebpm);
83 if (memcmp(dibpm, debpm, inx * iny) != 0) {
84 cpl_msg_warning(cpl_func, "Image and error bad pixel mask "
85 "not equal, ignoring mask of error image");
86 }
87 }
88 else if (ibpm == NULL && ebpm) {
89 cpl_msg_warning(cpl_func, "Image and error bad pixel mask "
90 "not equal, ignoring mask of error image");
91 }
92 }
93
94 return CPL_ERROR_NONE;
95}
96
97
98/* ---------------------------------------------------------------------------*/
104/* ---------------------------------------------------------------------------*/
105cpl_image * hdrl_image_get_image(hdrl_image * himg)
106{
107 cpl_ensure(himg, CPL_ERROR_NULL_INPUT, NULL);
108 return himg->image;
109}
110
111/* ---------------------------------------------------------------------------*/
117/* ---------------------------------------------------------------------------*/
118const cpl_image * hdrl_image_get_image_const(const hdrl_image * himg)
119{
120 cpl_ensure(himg, CPL_ERROR_NULL_INPUT, NULL);
121 return himg->image;
122}
123
124/* ---------------------------------------------------------------------------*/
130/* ---------------------------------------------------------------------------*/
131cpl_image * hdrl_image_get_error(hdrl_image * himg)
132{
133 cpl_ensure(himg, CPL_ERROR_NULL_INPUT, NULL);
134 return himg->error;
135}
136
137/* ---------------------------------------------------------------------------*/
143/* ---------------------------------------------------------------------------*/
144const cpl_image * hdrl_image_get_error_const(const hdrl_image * himg)
145{
146 cpl_ensure(himg, CPL_ERROR_NULL_INPUT, NULL);
147 return himg->error;
148}
149
150/* ---------------------------------------------------------------------------*/
156/* ---------------------------------------------------------------------------*/
157cpl_mask * hdrl_image_get_mask(hdrl_image * himg)
158{
159 cpl_ensure(himg, CPL_ERROR_NULL_INPUT, NULL);
160 if (cpl_image_get_bpm_const(hdrl_image_get_image(himg)) == NULL) {
161 /* call adds mask, also add a mask to the errors */
162 cpl_image_get_bpm(hdrl_image_get_error(himg));
163 }
164
165 return cpl_image_get_bpm(hdrl_image_get_image(himg));
166}
167
168/* ---------------------------------------------------------------------------*/
174/* ---------------------------------------------------------------------------*/
175const cpl_mask * hdrl_image_get_mask_const(const hdrl_image * himg)
176{
177 cpl_ensure(himg, CPL_ERROR_NULL_INPUT, NULL);
178 return cpl_image_get_bpm_const(hdrl_image_get_image_const(himg));
179}
180
181
182
183/* ---------------------------------------------------------------------------*/
190/* ---------------------------------------------------------------------------*/
191hdrl_image *
192hdrl_image_wrap(cpl_image * img, cpl_image * err, hdrl_free * destructor,
193 cpl_boolean sync_mask)
194{
195 hdrl_image * himg;
196 cpl_ensure(img, CPL_ERROR_NULL_INPUT, NULL);
197 cpl_ensure(err, CPL_ERROR_NULL_INPUT, NULL);
198 cpl_ensure(cpl_image_get_type(img) == HDRL_TYPE_DATA,
199 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
200 cpl_ensure(cpl_image_get_type(err) == HDRL_TYPE_ERROR,
201 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
202
203 himg = cpl_malloc(sizeof(*himg));
204 himg->image = img;
205 himg->error = err;
206
207 if (destructor) {
208 himg->fp_free = destructor;
209 }
210 else {
211 himg->fp_free = (hdrl_free*)_hdrl_image_delete;
212 }
213
214 if (sync_mask) {
215 _hdrl_image_sync_mask(himg);
216 }
217
218 return himg;
219}
220
221
222/* ---------------------------------------------------------------------------*/
227/* ---------------------------------------------------------------------------*/
228void hdrl_image_unwrap(hdrl_image * himg)
229{
230 cpl_free(himg);
231}
232
233
234/* ---------------------------------------------------------------------------*/
246/* ---------------------------------------------------------------------------*/
247static hdrl_image * _hdrl_image_create(const cpl_image * image,
248 const cpl_image * error,
249 cpl_boolean check_consistent)
250{
251 cpl_image * himage = NULL, * herror = NULL;
252
253 if (check_consistent && hdrl_image_check_consistent(image, error)) {
254 return NULL;
255 }
256
257 himage = cpl_image_cast(image, HDRL_TYPE_DATA);
258 if (error) {
259 herror = cpl_image_cast(error, HDRL_TYPE_ERROR);
260 }
261 else {
262 /* set error to zero */
263 herror = cpl_image_new(cpl_image_get_size_x(image),
264 cpl_image_get_size_y(image),
265 HDRL_TYPE_ERROR);
266 }
267
268 /* sync image and error bpm ignoring what is in error before */
269 if (cpl_image_get_bpm_const(image)) {
270 cpl_image_reject_from_mask(herror,
271 cpl_image_get_bpm_const(image));
272 }
273 else {
274 cpl_image_accept_all(herror);
275 }
276
277 return hdrl_image_wrap(himage, herror, NULL, CPL_FALSE);
278}
279
280
281/* ---------------------------------------------------------------------------*/
294/* ---------------------------------------------------------------------------*/
295hdrl_image * hdrl_image_create(const cpl_image * image,
296 const cpl_image * error)
297{
298 return _hdrl_image_create(image, error, CPL_TRUE);
299}
300
301/* ---------------------------------------------------------------------------*/
310/* ---------------------------------------------------------------------------*/
311hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
312{
313 cpl_image * himage = cpl_image_new(nx, ny, HDRL_TYPE_DATA);
314 cpl_image * herror = cpl_image_new(nx, ny, HDRL_TYPE_ERROR);
315
316 if (cpl_error_get_code()) {
317 cpl_image_delete(himage);
318 cpl_image_delete(herror);
319 return NULL;
320 }
321
322 return hdrl_image_wrap(himage, herror, NULL, CPL_FALSE);
323}
324
325hdrl_image *
326hdrl_image_new_from_buffer(cpl_size nx, cpl_size ny, hdrl_buffer * buf)
327{
328 char * p = hdrl_buffer_allocate(buf, nx * ny * (sizeof(hdrl_data_t) +
329 sizeof(hdrl_error_t)));
330 cpl_image * himage = cpl_image_wrap(nx, ny, HDRL_TYPE_DATA, p);
331 cpl_image * herror = cpl_image_wrap(nx, ny, HDRL_TYPE_ERROR,
332 p + nx * ny * sizeof(hdrl_data_t));
333
334 if (cpl_error_get_code()) {
335 cpl_image_delete(himage);
336 cpl_image_delete(herror);
337 return NULL;
338 }
339
340 return hdrl_image_wrap(himage, herror,
341 (hdrl_free*)&_hdrl_image_delete_buffer,
342 CPL_FALSE);
343}
344
345/* ---------------------------------------------------------------------------*/
349/* ---------------------------------------------------------------------------*/
350static void _hdrl_image_delete(hdrl_image * himg)
351{
352 if (himg) {
353 cpl_image_delete(himg->image);
354 cpl_image_delete(himg->error);
355 cpl_free(himg);
356 }
357}
358
359/* ---------------------------------------------------------------------------*/
363/* ---------------------------------------------------------------------------*/
364static void _hdrl_image_delete_buffer(hdrl_image * himg)
365{
366 if (himg) {
367 cpl_image_unwrap(himg->image);
368 cpl_image_unwrap(himg->error);
369 cpl_free(himg);
370 }
371}
372
373/* ---------------------------------------------------------------------------*/
378/* ---------------------------------------------------------------------------*/
379void hdrl_image_delete(hdrl_image * himg)
380{
381 if (himg) {
382 himg->fp_free(himg);
383 }
384}
385
386/* ---------------------------------------------------------------------------*/
390/* ---------------------------------------------------------------------------*/
391hdrl_image * hdrl_image_duplicate(const hdrl_image * himg)
392{
393 return _hdrl_image_create(hdrl_image_get_image_const(himg),
394 hdrl_image_get_error_const(himg), CPL_FALSE);
395}
396
397/* ---------------------------------------------------------------------------*/
406/* ---------------------------------------------------------------------------*/
407cpl_error_code hdrl_image_reject_from_mask(hdrl_image * self,
408 const cpl_mask * map)
409{
410 if (hdrl_image_get_mask_const(self) != map) {
411 cpl_image_reject_from_mask(hdrl_image_get_image(self), map);
412 }
413 return cpl_image_reject_from_mask(hdrl_image_get_error(self), map);
414}
415
416
417/* ---------------------------------------------------------------------------*/
426/* ---------------------------------------------------------------------------*/
427cpl_error_code hdrl_image_reject(hdrl_image * self,
428 cpl_size xpos, cpl_size ypos)
429{
430 cpl_image_reject(hdrl_image_get_image(self), xpos, ypos);
431 return cpl_image_reject(hdrl_image_get_error(self), xpos, ypos);
432}
433
434
435/* ---------------------------------------------------------------------------*/
444/* ---------------------------------------------------------------------------*/
445int hdrl_image_is_rejected(hdrl_image * self, cpl_size xpos, cpl_size ypos)
446{
447 cpl_ensure(self, CPL_ERROR_NULL_INPUT, -1);
448 return cpl_image_is_rejected(hdrl_image_get_image(self), xpos, ypos);
449}
450
451
452/* ---------------------------------------------------------------------------*/
460/* ---------------------------------------------------------------------------*/
461cpl_size hdrl_image_count_rejected(const hdrl_image * self)
462{
463 cpl_ensure(self, CPL_ERROR_NULL_INPUT, -1);
464 return cpl_image_count_rejected(hdrl_image_get_image_const(self));
465}
466
467
468/* ---------------------------------------------------------------------------*/
476/* ---------------------------------------------------------------------------*/
477cpl_error_code hdrl_image_reject_value(hdrl_image * self, cpl_value mode)
478{
479 return cpl_image_reject_value(hdrl_image_get_image(self), mode);
480}
481
482
483/* ---------------------------------------------------------------------------*/
492/* ---------------------------------------------------------------------------*/
493cpl_error_code hdrl_image_accept(hdrl_image * self,
494 cpl_size xpos, cpl_size ypos)
495{
496 cpl_image_accept(hdrl_image_get_image(self), xpos, ypos);
497 return cpl_image_accept(hdrl_image_get_error(self), xpos, ypos);
498}
499
500/* ---------------------------------------------------------------------------*/
507/* ---------------------------------------------------------------------------*/
508cpl_error_code hdrl_image_accept_all(hdrl_image * self)
509{
510 cpl_image_accept_all(hdrl_image_get_image(self));
511 cpl_image_accept_all(hdrl_image_get_error(self));
512 return cpl_error_get_code();
513}
514
515
516/* ---------------------------------------------------------------------------*/
524/* ---------------------------------------------------------------------------*/
525cpl_size hdrl_image_get_size_x(const hdrl_image * self)
526{
527 return cpl_image_get_size_x(hdrl_image_get_image_const(self));
528}
529
530
531/* ---------------------------------------------------------------------------*/
539/* ---------------------------------------------------------------------------*/
540cpl_size hdrl_image_get_size_y(const hdrl_image * self)
541{
542 return cpl_image_get_size_y(hdrl_image_get_image_const(self));
543}
544
545
546/* ---------------------------------------------------------------------------*/
558/* ---------------------------------------------------------------------------*/
559hdrl_value hdrl_image_get_pixel(const hdrl_image * self,
560 cpl_size xpos, cpl_size ypos,
561 int * pis_rejected)
562{
563 int d;
564 hdrl_value v;
565 v.data = cpl_image_get(hdrl_image_get_image_const(self), xpos, ypos, &d);
566
567 /* NULL allowed, different than CPL */
568 if (pis_rejected) {
569 *pis_rejected = d;
570 }
571 if (d) {
572 v.data = NAN;
573 v.error = NAN;
574 }
575 else {
576 v.error = cpl_image_get(hdrl_image_get_error_const(self),
577 xpos, ypos, &d);
578 }
579
580 return v;
581}
582
583
584/* ---------------------------------------------------------------------------*/
593/* ---------------------------------------------------------------------------*/
594cpl_error_code hdrl_image_set_pixel(hdrl_image * self,
595 cpl_size xpos, cpl_size ypos,
596 hdrl_value value)
597{
598 /* nan may be used as a bad pixel value */
599 cpl_ensure_code(value.error >= 0 || isnan(value.error), CPL_ERROR_ILLEGAL_INPUT);
600
601 if (cpl_image_set(hdrl_image_get_image(self), xpos, ypos, value.data)) {
602 return cpl_error_get_code();
603 }
604
605 return cpl_image_set(hdrl_image_get_error(self), xpos, ypos, value.error);
606}
607
608
609/* ---------------------------------------------------------------------------*/
624/* ---------------------------------------------------------------------------*/
626 const hdrl_image * self,
627 cpl_size llx,
628 cpl_size lly,
629 cpl_size urx,
630 cpl_size ury)
631{
632 const cpl_size nx = hdrl_image_get_size_x(self);
633 const cpl_size ny = hdrl_image_get_size_y(self);
634 if (llx < 1) llx += nx;
635 if (lly < 1) lly += ny;
636 if (urx < 1) urx += nx;
637 if (ury < 1) ury += ny;
638
639 cpl_image * img = cpl_image_extract(hdrl_image_get_image_const(self),
640 llx, lly, urx, ury);
641 cpl_image * err = cpl_image_extract(hdrl_image_get_error_const(self),
642 llx, lly, urx, ury);
643
644 if (cpl_error_get_code()) {
645 cpl_image_delete(img);
646 cpl_image_delete(err);
647 return NULL;
648 }
649
650 return hdrl_image_wrap(img, err, NULL, CPL_FALSE);
651}
652
653
654/* ---------------------------------------------------------------------------*/
662/* ---------------------------------------------------------------------------*/
663cpl_error_code hdrl_image_turn(hdrl_image * self, int rot)
664{
665 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
666 cpl_image_turn(hdrl_image_get_image(self), rot);
667 cpl_image_turn(hdrl_image_get_error(self), rot);
668 return cpl_error_get_code();
669}
670
671
672/* ---------------------------------------------------------------------------*/
685/* ---------------------------------------------------------------------------*/
686cpl_error_code hdrl_image_copy(hdrl_image * dst, const hdrl_image * src,
687 cpl_size xpos, cpl_size ypos)
688{
689 cpl_ensure_code(dst, CPL_ERROR_NULL_INPUT);
690 cpl_ensure_code(src, CPL_ERROR_NULL_INPUT);
691 cpl_image_copy(hdrl_image_get_image(dst), hdrl_image_get_image_const(src),
692 xpos, ypos);
693 cpl_image_copy(hdrl_image_get_error(dst), hdrl_image_get_error_const(src),
694 xpos, ypos);
695
696 return cpl_error_get_code();
697}
698
699
700/* ---------------------------------------------------------------------------*/
714/* ---------------------------------------------------------------------------*/
715cpl_error_code hdrl_image_insert(hdrl_image * self,
716 const cpl_image * image,
717 const cpl_image * error,
718 cpl_size xpos, cpl_size ypos)
719{
720 cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
721 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
722 cpl_image_copy(hdrl_image_get_image(self), image, xpos, ypos);
723 if (error) {
724 cpl_image_copy(hdrl_image_get_error(self), error, xpos, ypos);
725 }
726 /* sync error mask */
727 if (cpl_image_get_bpm_const(image)) {
728 const cpl_mask * msrc = cpl_image_get_bpm_const(image);
729 cpl_mask * mdst = cpl_image_get_bpm(hdrl_image_get_error(self));
730 cpl_mask_copy(mdst, msrc, xpos, ypos);
731 }
732
733 return cpl_error_get_code();
734}
735
736
737/* ---------------------------------------------------------------------------*/
741/* ---------------------------------------------------------------------------*/
742
743static void _hdrl_image_sync_mask(hdrl_image * himg)
744{
745 const cpl_mask * m = hdrl_image_get_mask_const(himg);
746 if (m) {
748 }
749 else {
750 cpl_image_accept_all(hdrl_image_get_error(himg));
751 }
752}
753
754/*----------------------------------------------------------------------------*/
766/*----------------------------------------------------------------------------*/
768 const hdrl_image * himg,
769 FILE * stream)
770{
771 return cpl_image_dump_structure(hdrl_image_get_image_const(himg), stream);
772}
773
774/*----------------------------------------------------------------------------*/
792/*----------------------------------------------------------------------------*/
794 const hdrl_image * himg,
795 cpl_size llx,
796 cpl_size lly,
797 cpl_size urx,
798 cpl_size ury,
799 FILE * stream)
800{
801 return cpl_image_dump_window(hdrl_image_get_image_const(himg),
802 llx, lly, urx, ury, stream);
803
804}
805
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
Definition: hdrl_image.c:559
int hdrl_image_is_rejected(hdrl_image *self, cpl_size xpos, cpl_size ypos)
return if pixel is marked bad
Definition: hdrl_image.c:445
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
Definition: hdrl_image.c:594
cpl_error_code hdrl_image_reject_value(hdrl_image *self, cpl_value mode)
Reject pixels with the specified special value(s)
Definition: hdrl_image.c:477
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
Definition: hdrl_image.c:407
cpl_error_code hdrl_image_turn(hdrl_image *self, int rot)
Rotate an image by a multiple of 90 degrees clockwise.
Definition: hdrl_image.c:663
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
Definition: hdrl_image.c:391
cpl_error_code hdrl_image_copy(hdrl_image *dst, const hdrl_image *src, cpl_size xpos, cpl_size ypos)
Copy one image into another.
Definition: hdrl_image.c:686
cpl_mask * hdrl_image_get_mask(hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:157
hdrl_image * hdrl_image_extract(const hdrl_image *self, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury)
extract copy of window from image
Definition: hdrl_image.c:625
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_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:131
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
Definition: hdrl_image.c:540
const cpl_mask * hdrl_image_get_mask_const(const hdrl_image *himg)
get cpl bad pixel mask from image
Definition: hdrl_image.c:175
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
Definition: hdrl_image.c:525
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
Definition: hdrl_image.c:144
cpl_error_code hdrl_image_insert(hdrl_image *self, const cpl_image *image, const cpl_image *error, cpl_size xpos, cpl_size ypos)
Copy cpl images into an hdrl image.
Definition: hdrl_image.c:715
cpl_size hdrl_image_count_rejected(const hdrl_image *self)
return number of rejected pixels
Definition: hdrl_image.c:461
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_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:105
cpl_error_code hdrl_image_reject(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as bad
Definition: hdrl_image.c:427
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
Definition: hdrl_image.c:118
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
Definition: hdrl_image.c:311
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
cpl_error_code hdrl_image_accept(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as good
Definition: hdrl_image.c:493
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
Definition: hdrl_image.c:379
cpl_error_code hdrl_image_accept_all(hdrl_image *self)
Accept all pixels in an image.
Definition: hdrl_image.c:508