34 #include <cxmessages.h>
39 #include <cpl_recipe.h>
40 #include <cpl_plugininfo.h>
41 #include <cpl_parameterlist.h>
42 #include <cpl_frameset.h>
43 #include <cpl_propertylist.h>
52 #include "gistacking.h"
58 #define GIMASTERBIAS_BIAS_EXTENSION_IMG 0
59 #define GIMASTERBIAS_BIAS_EXTENSION_PL 0
60 #define GIMASTERBIAS_BAD_PIXEL_EXTENSION 0
63 static cxint giframestack(cpl_parameterlist*, cpl_frameset*);
72 giframestack_create(cpl_plugin* plugin)
75 cpl_recipe* recipe = (cpl_recipe*)plugin;
86 recipe->parameters = cpl_parameterlist_new();
87 cx_assert(recipe->parameters != NULL);
105 giframestack_exec(cpl_plugin* plugin)
108 cpl_recipe* recipe = (cpl_recipe*)plugin;
113 if (recipe->parameters == NULL || recipe->frames == NULL) {
117 status = giframestack(recipe->parameters, recipe->frames);
129 giframestack_destroy(cpl_plugin* plugin)
132 cpl_recipe* recipe = (cpl_recipe*)plugin;
141 cpl_parameterlist_delete(recipe->parameters);
143 giraffe_error_clear();
154 giframestack(cpl_parameterlist* config, cpl_frameset* set)
157 const cxchar*
const _id =
"giframestack";
163 cxdouble exptime = 0.;
165 cx_string *tag = NULL;
167 cx_list *frames = NULL;
168 cx_list *images = NULL;
170 cx_list_iterator position;
174 cpl_propertylist *properties = NULL;
176 cpl_frame* frame = NULL;
178 cpl_frameset_iterator *it = NULL;
180 GiImage *image = NULL;
181 GiImage *result = NULL;
182 GiImage **stack = NULL;
184 GiStackingConfig *setup = NULL;
186 GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
193 cpl_msg_error(_id,
"Invalid parameter list! Aborting ...");
207 cpl_msg_info(_id,
"Searching for frames to combine ...");
209 it = cpl_frameset_iterator_new(set);
211 frame = cpl_frameset_iterator_get(it);
214 cpl_msg_error(_id,
"Empty input frameset encountered!");
216 cpl_frameset_iterator_delete(it);
230 while (status != 0 && count < cpl_frameset_get_size(set)) {
232 cpl_frameset_iterator_advance(it, 1);
234 frame = cpl_frameset_iterator_get(it);
241 cpl_frameset_iterator_delete(it);
244 if (count == cpl_frameset_get_size(set)) {
245 cpl_msg_error(_id,
"The input frameset does not contain any "
257 tag = cx_string_create(cpl_frame_get_tag(frame));
266 cpl_msg_info(_id,
"Selecting '%s' frames for combination.",
269 frames = cx_list_new();
270 cx_list_push_back(frames, frame);
272 images = cx_list_new();
273 cx_list_push_back(images, image);
276 frame = cpl_frameset_find(set, cx_string_get(tag));
278 if (frame == cx_list_front(frames)) {
279 frame = cpl_frameset_find(set, NULL);
282 while (frame != NULL) {
284 if (frame != cx_list_front(frames)) {
290 cpl_frame_get_filename(frame), 0);
300 cx_list_push_back(frames, frame);
301 cx_list_push_back(images, _image);
306 cpl_msg_warning(_id,
"Ignoring frame '%s' because of "
308 cpl_frame_get_filename(frame));
323 frame = cpl_frameset_find(set, NULL);
333 count = cx_list_size(images);
335 if (count < setup->min_nr_frames) {
337 cpl_msg_error(_id,
"Not enough frames (%" CPL_SIZE_FORMAT
338 "). Stacking method '%d' requires at least %d frames! "
339 "Aborting...", count, setup->stackmethod,
340 setup->min_nr_frames);
345 cx_list_delete(frames);
348 cx_string_delete(tag);
363 cpl_msg_info(_id,
"Combining %" CPL_SIZE_FORMAT
" frames (%s) ...", count,
366 stack = cx_calloc(count + 1,
sizeof(GiImage*));
369 position = cx_list_begin(images);
371 while (position != cx_list_end(images)) {
372 stack[i] = cx_list_get(images, position);
373 position = cx_list_next(images, position);
379 if (result == NULL) {
381 cpl_msg_error(_id,
"Frame combination failed! Aborting ...");
389 cx_list_delete(frames);
392 cx_string_delete(tag);
413 cpl_msg_info(_id,
"Updating combined frame properties ...");
416 cx_assert(properties != NULL);
421 if (properties == NULL) {
423 cpl_msg_error(_id,
"Updating combined frame properties failed!");
431 cx_list_delete(frames);
434 cx_string_delete(tag);
441 giraffe_error_push();
443 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.);
444 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
447 position = cx_list_begin(images);
449 while (position != cx_list_end(images)) {
451 cpl_propertylist* p =
454 exptime += cpl_propertylist_get_double(p, GIALIAS_EXPTIME);
455 position = cx_list_next(images, position);
459 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptime);
461 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, count);
463 cpl_propertylist_erase(properties, GIALIAS_EXPTIME);
464 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
467 if (cpl_error_get_code() != CPL_ERROR_NONE) {
469 cpl_msg_error(_id,
"Updating combined frame properties failed!");
477 cx_list_delete(frames);
480 cx_string_delete(tag);
494 cpl_msg_info(_id,
"Writing combined frame ...");
498 cx_string_append(tag,
"_COMBINED");
501 CPL_FRAME_LEVEL_FINAL, TRUE, TRUE);
505 cpl_msg_error(_id,
"Cannot create local file! Aborting ...");
513 cx_list_delete(frames);
516 cx_string_delete(tag);
523 cpl_frameset_insert(set, frame);
536 cx_list_delete(frames);
539 cx_string_delete(tag);
553 cpl_plugin_get_info(cpl_pluginlist* list)
556 cpl_recipe* recipe = cx_calloc(1,
sizeof *recipe);
557 cpl_plugin* plugin = &recipe->interface;
560 cpl_plugin_init(plugin,
562 GIRAFFE_BINARY_VERSION,
563 CPL_PLUGIN_TYPE_RECIPE,
565 "Creates a stacked image from a set of raw images.",
572 giframestack_destroy);
574 cpl_pluginlist_append(list, plugin);
cxint giraffe_image_add_info(GiImage *image, const GiRecipeInfo *info, const cpl_frameset *set)
Add additional frame information to an image.
GiImage * giraffe_stacking_stack_images(GiImage **img_array, const GiStackingConfig *config)
Stack a list of images using one of four different kinds of stacking and return the resulting image...
cxint giraffe_image_load(GiImage *self, const cxchar *filename, cxint position)
Gets image data and properties from a file.
void giraffe_stacking_config_destroy(GiStackingConfig *config)
Destroys a setup structure for the stacking of images.
void giraffe_image_delete(GiImage *self)
Destroys an image.
GiImage * giraffe_image_new(cpl_type type)
Creates an empty image container.
GiStackingConfig * giraffe_stacking_config_create(cpl_parameterlist *list)
Creates a setup structure for the stacking of images.
const cxchar * giraffe_get_license(void)
Get the pipeline copyright and license.
void giraffe_stacking_config_add(cpl_parameterlist *list)
Adds parameters for the stacking of images.
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
cxint giraffe_image_set_properties(GiImage *self, cpl_propertylist *properties)
Attaches a property list to an image.
cpl_frame * giraffe_frame_create_image(GiImage *image, const cxchar *tag, cpl_frame_level level, cxbool save, cxbool update)
Create an image product frame.
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.