ERIS Pipeline Reference Manual 1.9.2
eris_nix_lss_utils.c
1/* $Id$
2 *
3 * This file is part of the ERIS/NIX Pipeline
4 * Copyright (C) 2017 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*
22 * $Author$
23 * $Date$
24 * $Rev$
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30
31/*-----------------------------------------------------------------------------
32 Includes
33 -----------------------------------------------------------------------------*/
34
35#include "eris_nix_lss_utils.h"
36#include "eris_nix_dfs.h"
37#include "eris_nix_utils.h"
38
39/*----------------------------------------------------------------------------*/
43/*----------------------------------------------------------------------------*/
44
47/*----------------------------------------------------------------------------*/
61/*----------------------------------------------------------------------------*/
62
63cpl_error_code enlu_divide_slit_response(located_imagelist * jitters) {
64
65 /* check inputs */
66
67 if (cpl_error_get_code() != CPL_ERROR_NONE) return cpl_error_get_code();
68 cpl_ensure_code(jitters, CPL_ERROR_NULL_INPUT);
69
70 cpl_msg_info(cpl_func, "..dividing by slit response");
71
72 for (cpl_size j = 0; j < jitters->size; j++) {
73
74 /* Get copy of background, remove dodgy values */
75
76 cpl_image * bkg_copy = cpl_image_duplicate(
78 jitters->limages[j]->bkg));
79 cpl_image_reject_value(bkg_copy, CPL_VALUE_NOTFINITE);
80
81 /* collapse the background along the dispersion axis to get
82 the slit response profile (sky spectrum should be the same
83 for all slit offsets) */
84 /* we drop 300 pix at the left and at the right as those are anyway not illuminated */
85 cpl_size drop_ll = 300;
86 cpl_size drop_ur = 300;
87 cpl_image * bkg_collapse = cpl_image_collapse_median_create(bkg_copy, 0, drop_ll, drop_ur);
88
89
90
91 /* normalise, bit fiddly as spectrum covers less than half of image
92 ..mask out unilluminated pixels */
93 cpl_size sx = cpl_image_get_size_x(bkg_collapse);
94 double maxval = 0;
95 double medval = 0;
96 double stdval = 0;
97 cpl_size niter = 3;
98 double kappa = 2.0;
99
100 for(cpl_size kk = 0; kk < niter; kk++) {
101 maxval = cpl_image_get_max_window(bkg_collapse,drop_ll,1,sx - drop_ur,1);
102 medval = cpl_image_get_median_window(bkg_collapse,drop_ll,1,sx - drop_ur,1);
103 stdval = cpl_image_get_stdev_window(bkg_collapse,drop_ll,1,sx - drop_ur,1);
104 cpl_msg_warning(cpl_func,"maxval: %g", maxval);
105 cpl_msg_warning(cpl_func,"medval: %g", medval);
106 cpl_msg_warning(cpl_func,"stdval: %g", stdval);
107 cpl_mask_threshold_image(cpl_image_get_bpm(bkg_collapse),
108 bkg_collapse,
109 medval - kappa * stdval,
110 DBL_MAX,
111 CPL_BINARY_0);
112 cpl_image_fill_rejected(bkg_collapse, 0.0);
113 }
114
115 /* ..normalise by median. Do both image and sky background but
116 leave confidence alone - the slit profile is assumed
117 noiseless so confidence unaffected (?) */
118
119 medval = cpl_image_get_median(bkg_collapse);
120 cpl_msg_warning(cpl_func,"medval: %g", medval);
121
122 cpl_image_divide_scalar(bkg_collapse, medval);
123
124 enlu_divide_slit_response_worker(jitters->limages[j]->himage,
125 bkg_collapse);
126 enlu_divide_slit_response_worker(jitters->limages[j]->bkg,
127 bkg_collapse);
128
129
130 /* sanity check, plotted slit profile should be flat */
131/*
132 {
133 cpl_image * bkg_copy = cpl_image_duplicate(
134 hdrl_image_get_image(
135 jitters->limages[j]->bkg));
136 cpl_image_reject_value(bkg_copy, CPL_VALUE_NOTFINITE);
137
138 cpl_image * bkg_collapse = cpl_image_collapse_median_create(bkg_copy,
139 0, 0, 0);
140
141 double maxval = cpl_image_get_max(bkg_collapse);
142 cpl_mask_threshold_image(cpl_image_get_bpm(bkg_collapse),
143 bkg_collapse,
144 0.7 * maxval,
145 DBL_MAX,
146 CPL_BINARY_0);
147 cpl_image_fill_rejected(bkg_collapse, 0.0);
148
149 char* filename = cpl_sprintf("bkg_vector_%d.fits", (int)j);
150 cpl_vector * bkg_vector = cpl_vector_new_from_image_row(bkg_collapse, 1);
151 cpl_vector_save(bkg_vector,
152 filename, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
153 cpl_free(filename);
154 cpl_vector_delete(bkg_vector);
155 }
156*/
157
158 cpl_image_delete(bkg_collapse);
159 cpl_image_delete(bkg_copy);
160 }
161
162 return cpl_error_get_code();
163}
164
165
166/*----------------------------------------------------------------------------*/
173/*----------------------------------------------------------------------------*/
174
175cpl_error_code enlu_divide_slit_response_worker(hdrl_image * himage_2d,
176 cpl_image * response_1d) {
177
178 /* check inputs */
179
180 if (cpl_error_get_code() != CPL_ERROR_NONE) return cpl_error_get_code();
181 cpl_ensure_code(himage_2d, CPL_ERROR_NULL_INPUT);
182 cpl_ensure_code(response_1d, CPL_ERROR_NULL_INPUT);
183
184 /*cpl_msg_info(cpl_func, "enlu_divide_slit_response_worker called");*/
185
186 /* do it the simple but slow way, using hdrl and cpl to access the
187 pixels one by one */
188
189 cpl_size nx = hdrl_image_get_size_x(himage_2d);
190 cpl_size ny = hdrl_image_get_size_y(himage_2d);
191
192 for (cpl_size i = 1; i <= nx; i++) {
193 int slit_ok = 0;
194 double slit = cpl_image_get(response_1d, i, 1, &slit_ok);
195 for (cpl_size j = 1; j <= ny; j++) {
196 int data_ok = 0;
197 hdrl_value data = hdrl_image_get_pixel(himage_2d, i, j, &data_ok);
198
199 if (data_ok==0 && slit_ok==0) {
200 data.data = data.data / slit;
201 data.error = data.error / slit;
202 } else {
203 data = (hdrl_value) {0.0, 0.0};
204 data_ok = 1;
205 }
206 hdrl_image_set_pixel(himage_2d, i, j, data);
207 if (data_ok == 1) {
208 hdrl_image_reject(himage_2d, i, j);
209 }
210 }
211 }
212
213 return cpl_error_get_code();
214}
215
216
217/*----------------------------------------------------------------------------*/
257/*----------------------------------------------------------------------------*/
258
259cpl_matrix * enlu_linepos_2d(const hdrl_image * spectrum2d,
260 const cpl_size slice_index,
261 const cpl_vector * guess_pos) {
262
263 cpl_matrix * line_pos = NULL;
264 cpl_vector * next_guess_pos = NULL;
265 cpl_vector * spectrum1d = NULL;
266
267 if (cpl_error_get_code() != CPL_ERROR_NONE) return NULL;
268
269 cpl_ensure(spectrum2d, CPL_ERROR_NULL_INPUT, NULL);
270 cpl_ensure(guess_pos, CPL_ERROR_NULL_INPUT, NULL);
271 cpl_ensure(cpl_vector_get_size(guess_pos) > 0,
272 CPL_ERROR_ILLEGAL_INPUT, NULL);
273
274 cpl_size nlines = cpl_vector_get_size(guess_pos);
275
276 const cpl_size nx = hdrl_image_get_size_x(spectrum2d);
277 line_pos = cpl_matrix_new(nx, nlines);
278 cpl_matrix_fill(line_pos, NAN);
279
280 /* loop through slices on RH side of image. Remember that cpl_image
281 indeces are 1-based, cpl_vector and cpl_matrix 0-based - fab! */
282
283 next_guess_pos = cpl_vector_duplicate(guess_pos);
284
285 for (cpl_size ix = slice_index; ix < nx; ix++) {
286
287 /* fit the lines in this slice to get accurate peak positions */
288
289 spectrum1d = cpl_vector_new_from_image_column(
290 hdrl_image_get_image_const(spectrum2d), ix+1);
291
292 for (cpl_size line_id=0; line_id < nlines; line_id++) {
293 double line_guess_pos = cpl_vector_get(next_guess_pos, line_id);
294 double fitted_pos = enlu_linepos_1d(spectrum1d, line_guess_pos, 4);
295 if (!isnan(fitted_pos)) {
296
297 /* set the fit peak as the measured position of the line,
298 set next_guess_pos to the actual line positions so that
299 it can follow slow variations with ix */
300
301 cpl_matrix_set(line_pos, ix, line_id, fitted_pos);
302 cpl_vector_set(next_guess_pos, line_id, fitted_pos);
303 }
304 }
305 cpl_vector_delete(spectrum1d);
306 }
307 cpl_vector_delete(next_guess_pos);
308
309 /* now loop through slices on LH side of image */
310
311 next_guess_pos = cpl_vector_duplicate(guess_pos);
312
313 for (cpl_size ix = slice_index-1; ix >= 0; ix--) {
314 spectrum1d = cpl_vector_new_from_image_column(
315 hdrl_image_get_image_const(spectrum2d), ix+1);
316
317 for (cpl_size line_id=0; line_id < nlines; line_id++) {
318 double line_guess_pos = cpl_vector_get(next_guess_pos, line_id);
319 double fitted_pos = enlu_linepos_1d(spectrum1d, line_guess_pos, 4);
320 if (!isnan(fitted_pos)) {
321 cpl_matrix_set(line_pos, ix, line_id, fitted_pos);
322 cpl_vector_set(next_guess_pos, line_id, fitted_pos);
323 }
324 }
325 cpl_vector_delete(spectrum1d);
326 }
327 cpl_vector_delete(next_guess_pos);
328
329 /* Return NULL on error */
330
331 if (cpl_error_get_code() != CPL_ERROR_NONE) {
332 cpl_matrix_delete(line_pos);
333 line_pos = NULL;
334 }
335
336 return line_pos;
337}
338
339
340/*----------------------------------------------------------------------------*/
359/*----------------------------------------------------------------------------*/
360
361double enlu_linepos_1d(const cpl_vector * spectrum1d,
362 const double guess_pos,
363 const cpl_size half_width) {
364
365 if (cpl_error_get_code() != CPL_ERROR_NONE) return NAN;
366 cpl_ensure(spectrum1d, CPL_ERROR_NULL_INPUT, NAN);
367
368 cpl_polynomial * line_fit = NULL;
369 double result = NAN;
370
371 cpl_size istart = (cpl_size) guess_pos - half_width;
372 cpl_size istop = (cpl_size) guess_pos + half_width;
373 cpl_size npos = istop - istart + 1;
374
375 /* set up pixel positions of chunk */
376
377 cpl_matrix * pos_chunk = cpl_matrix_new(1, npos);
378 for (cpl_size i = 0; i < npos; i++) {
379 cpl_matrix_set(pos_chunk, 0, i, (double) (i + istart));
380 }
381
382 /* get spectrum data for chunk, spec_ok goes False if any points
383 bad (=0) or are NaN, the fitting routine can't handle NaNs */
384
385 cpl_vector * spectrum_chunk = cpl_vector_extract(spectrum1d,
386 istart, istop, 1);
387 const double * spectrum_chunk_data = cpl_vector_get_data_const(
388 spectrum_chunk);
389 int spec_ok = 1;
390 for (cpl_size i = 0; i < npos; i++) {
391 spec_ok = spec_ok &&
392 spectrum_chunk_data[i] != 0.0 &&
393 !isnan(spectrum_chunk_data[i]);
394 }
395
396 /* fit a parabola to the line peak if the data are good */
397
398 if (spec_ok) {
399 line_fit = cpl_polynomial_new(1);
400 const cpl_size maxdeg1d = 2;
401 cpl_polynomial_fit(line_fit, pos_chunk, NULL, spectrum_chunk, NULL,
402 CPL_FALSE, NULL, &maxdeg1d);
403
404 /* set the fit peak as the measured position of the line,
405 set next_guess_pos to the actual line positions so that
406 it can follow slow variations with ix */
407
408 cpl_size pow = 1;
409 double poly_b = cpl_polynomial_get_coeff(line_fit, &pow);
410 pow = 2;
411 double poly_c = cpl_polynomial_get_coeff(line_fit, &pow);
412 result = -poly_b / (2.0 * poly_c);
413
414 /* if the fitted line centre is outside the expected range
415 then something has probably gone wrong - errant pixel or
416 something - ignore it */
417
418 if (fabs(result - guess_pos) > half_width) {
419 result = NAN;
420 }
421 }
422
423 cpl_matrix_delete(pos_chunk);
424 cpl_vector_delete(spectrum_chunk);
425 cpl_polynomial_delete(line_fit);
426
427 if (cpl_error_get_code() != CPL_ERROR_NONE) {
428 result = NAN;
429 }
430
431 return result;
432}
433
434
435/*----------------------------------------------------------------------------*/
448/*----------------------------------------------------------------------------*/
449
450cpl_error_code enlu_trace_save(const char * pro_catg,
451 const hdrl_image * image,
452 const cpl_image * confidence,
453 const cpl_size ntraces,
454 const cpl_polynomial * traces[ntraces],
455 const cpl_size nspectra,
456 const cpl_vector * spectra[nspectra],
457 const cpl_size nlines,
458 const cpl_polynomial * lines[nlines],
459 cpl_frameset * frameset,
460 const cpl_parameterlist * parlist,
461 const char * filename,
462 const char * recipe_name) {
463
464 /* checks */
465
466 if (cpl_error_get_code() != CPL_ERROR_NONE) return cpl_error_get_code();
467 cpl_ensure_code(pro_catg, CPL_ERROR_NULL_INPUT);
468 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
469 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
470 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
471 cpl_ensure_code(filename, CPL_ERROR_NULL_INPUT);
472
473 mef_extension_list * mefs = NULL;
474 cpl_propertylist * plist = NULL;
475
476 /* make output propertylist */
477
478 plist = cpl_propertylist_new();
479 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG, pro_catg);
480
481 /* add QC parameters */
482 /* TBD */
483
484 enu_check_error_code("error constructing output propertylist");
485
486 /* save the trace to a DFS-compliant MEF file */
487
488 /* .. how many mefs? */
489
490 cpl_size nmefs = ntraces + nspectra + nlines + 1;
491 mefs = enu_mef_extension_list_new(nmefs);
492 cpl_size imef = 0;
493 mefs->mef[imef] = enu_mef_new_image("CONFIDENCE", confidence, NULL);
494 imef++;
495 for (cpl_size i = 0; i < ntraces; i++) {
496 cpl_propertylist * mef_plist = cpl_propertylist_new();
497 cpl_propertylist_update_string(mef_plist, "DIR", "Y");
498 mefs->mef[imef] = enu_mef_new_table(
499 "TRACE",
501 mef_plist);
502 imef++;
503 }
504 for (cpl_size i = 0; i < nspectra; i++) {
505 mefs->mef[imef] = enu_mef_new_vector("SPECTRUM", spectra[i], NULL);
506 imef++;
507 }
508 for (cpl_size i = 0; i < nlines; i++) {
509 cpl_propertylist * mef_plist = cpl_propertylist_new();
510 cpl_propertylist_update_string(mef_plist, "DIR", "X");
511 mefs->mef[imef] = enu_mef_new_table(
512 "LINE",
514 mef_plist);
515 imef++;
516 }
517
518 enu_dfs_save_himage(frameset,
519 parlist,
520 frameset,
521 CPL_TRUE,
522 image,
523 NULL,
524 mefs,
525 recipe_name,
526 NULL,
527 plist,
528 NULL,
529 PACKAGE "/" PACKAGE_VERSION,
530 filename);
531
532 cleanup:
534 cpl_propertylist_delete(plist);
535
536 return cpl_error_get_code();
537}
538
539
540/*----------------------------------------------------------------------------*/
553/*----------------------------------------------------------------------------*/
554
555cpl_polynomial * enlu_warp_poly_load_from_table(const cpl_table * table) {
556
557 if (cpl_error_get_code() != CPL_ERROR_NONE) return NULL;
558 cpl_ensure(table, CPL_ERROR_NULL_INPUT, NULL);
559
560 /* only handle polynomial degree 2, keeps things simpler */
561
562 cpl_polynomial * result = cpl_polynomial_new(2);
563
564 /* expect table columns 1.dim.power, 2.dim.power, coefficient */
565
566 enu_check(cpl_table_has_column(table, "1.dim.power"),
567 CPL_ERROR_ILLEGAL_INPUT,
568 "table does not have column '1.dim.power'");
569 enu_check(cpl_table_has_column(table, "2.dim.power"),
570 CPL_ERROR_ILLEGAL_INPUT,
571 "table does not have column '2.dim.power'");
572 enu_check(cpl_table_has_column(table, "coefficient"),
573 CPL_ERROR_ILLEGAL_INPUT,
574 "table does not have column 'coefficient'");
575
576 /* loop through the rows and set the polynomial coefficients */
577
578 cpl_size nrow = cpl_table_get_nrow(table);
579 for (cpl_size row=0; row<nrow; row++) {
580 int null1 = 0;
581 int pow1 = cpl_table_get_int(table, "1.dim.power", row, &null1);
582 int null2 = 0;
583 int pow2 = cpl_table_get_int(table, "2.dim.power", row, &null2);
584 int nullcoeff = 0;
585 double coeff = cpl_table_get_double(table, "coefficient", row,
586 &nullcoeff);
587 enu_check(!(null1 || null2 || nullcoeff), CPL_ERROR_ILLEGAL_INPUT,
588 "table contains NULL values");
589
590 cpl_size pows[2] = {pow1, pow2};
591 cpl_polynomial_set_coeff(result, pows, coeff);
592 }
593
594 cleanup:
595 if (cpl_error_get_code() != CPL_ERROR_NONE) {
596 cpl_polynomial_delete(result);
597 result = NULL;
598 }
599 return result;
600}
601
602
603/*----------------------------------------------------------------------------*/
615/*----------------------------------------------------------------------------*/
616
617cpl_table * enlu_warp_poly_save_to_table(const cpl_polynomial * poly) {
618
619 if (cpl_error_get_code() != CPL_ERROR_NONE) return NULL;
620 cpl_ensure(poly, CPL_ERROR_NULL_INPUT, NULL);
621
622 cpl_table * result = NULL;
623
624 /* Is the polynomial 1 or 2d? */
625
626 const cpl_size dimension = cpl_polynomial_get_dimension(poly);
627 enu_check(dimension==1 || dimension==2, CPL_ERROR_ILLEGAL_INPUT,
628 "can only handle polynomial with dimension 1 or 2");
629
630 if (dimension == 1) {
631
632 const cpl_size degree = cpl_polynomial_get_degree(poly);
633 result = cpl_table_new(degree + 1);
634
635 /* construct table columns */
636
637 cpl_table_new_column(result, "1.dim.power", CPL_TYPE_INT);
638 cpl_table_new_column(result, "coefficient", CPL_TYPE_DOUBLE);
639
640 cpl_size nrows = 0;
641 for (cpl_size dim1_power=0; dim1_power<=degree; dim1_power++) {
642 double coeff = cpl_polynomial_get_coeff(poly, &dim1_power);
643 if (coeff != 0.0) {
644 cpl_table_set_int(result, "1.dim.power", nrows, dim1_power);
645 cpl_table_set_double(result, "coefficient", nrows, coeff);
646 nrows++;
647 }
648 }
649 cpl_table_set_size(result, nrows);
650
651 } else if (dimension == 2) {
652
653 const cpl_size degree = cpl_polynomial_get_degree(poly);
654 result = cpl_table_new((degree + 1) * (degree + 1));
655
656 /* construct table columns */
657
658 cpl_table_new_column(result, "1.dim.power", CPL_TYPE_INT);
659 cpl_table_new_column(result, "2.dim.power", CPL_TYPE_INT);
660 cpl_table_new_column(result, "coefficient", CPL_TYPE_DOUBLE);
661
662 cpl_size nrows = 0;
663 for (int dim2_power=0; dim2_power<=degree; dim2_power++) {
664 for (int dim1_power=0; dim1_power<=degree; dim1_power++) {
665 cpl_size pows[2] = {dim1_power, dim2_power};
666 double coeff = cpl_polynomial_get_coeff(poly, pows);
667 if (coeff != 0.0) {
668 cpl_table_set_int(result, "1.dim.power", nrows, dim1_power);
669 cpl_table_set_int(result, "2.dim.power", nrows, dim2_power);
670 cpl_table_set_double(result, "coefficient", nrows, coeff);
671 nrows++;
672 }
673 }
674 }
675 cpl_table_set_size(result, nrows);
676 }
677
678 cleanup:
679
680 if (cpl_error_get_code() != CPL_ERROR_NONE) {
681 cpl_table_delete(result);
682 result = NULL;
683 }
684 return result;
685}
686
cpl_error_code enu_dfs_save_himage(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *provenance, const cpl_boolean prov_raw, const hdrl_image *image, const hdrl_imagelist *imagelist, const mef_extension_list *mefs, const char *recipe, const cpl_frame *inherit_frame, const cpl_propertylist *applist, const cpl_propertylist *wcs_plist, const char *pipe_id, const char *filename)
Save an hdrl_image/imagelist as a DFS-compliant MEF pipeline product.
Definition: eris_nix_dfs.c:423
cpl_error_code enlu_divide_slit_response_worker(hdrl_image *himage_2d, cpl_image *response_1d)
Worker function to divide a 2d image by a 1d response.
cpl_error_code enlu_divide_slit_response(located_imagelist *jitters)
Divide LSS 2d-spectra by the slit response.
double enlu_linepos_1d(const cpl_vector *spectrum1d, const double guess_pos, const cpl_size half_width)
Fit line peak.
cpl_table * enlu_warp_poly_save_to_table(const cpl_polynomial *poly)
Save an LSS polynomial to a cpl_table.
cpl_matrix * enlu_linepos_2d(const hdrl_image *spectrum2d, const cpl_size slice_index, const cpl_vector *guess_pos)
Fit the line peaks of a wave calibration spectrum.
cpl_polynomial * enlu_warp_poly_load_from_table(const cpl_table *table)
Load a LSS warp polynomial from a cpl_table.
cpl_error_code enlu_trace_save(const char *pro_catg, const hdrl_image *image, const cpl_image *confidence, const cpl_size ntraces, const cpl_polynomial *traces[ntraces], const cpl_size nspectra, const cpl_vector *spectra[nspectra], const cpl_size nlines, const cpl_polynomial *lines[nlines], cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *filename, const char *recipe_name)
Save a trace result.
mef_extension * enu_mef_new_image(const char *name, const cpl_image *data, const cpl_propertylist *plist)
Create a mef_extension to hold a cpl_image.
mef_extension * enu_mef_new_table(const char *name, const cpl_table *table, const cpl_propertylist *plist)
Create a mef_extension struct holding a cpl_table.
mef_extension_list * enu_mef_extension_list_new(cpl_size size)
Construct a new mef_extension_list.
mef_extension * enu_mef_new_vector(const char *name, const cpl_vector *vector, const cpl_propertylist *plist)
Create a mef_extension struct holding a cpl_vector.
void enu_mef_extension_list_delete(mef_extension_list *list)
Delete a mef_extension_list and its contents.
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
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_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
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