00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include <math.h>
00033
00034 #include <cxmessages.h>
00035 #include <cxmemory.h>
00036 #include <cxlist.h>
00037
00038 #include <cpl_recipe.h>
00039 #include <cpl_plugininfo.h>
00040 #include <cpl_parameterlist.h>
00041 #include <cpl_frameset.h>
00042 #include <cpl_propertylist.h>
00043 #include <cpl_msg.h>
00044
00045 #include "gialias.h"
00046 #include "giframe.h"
00047 #include "giimage.h"
00048 #include "gifibers.h"
00049 #include "gibias.h"
00050 #include "gimath.h"
00051 #include "gistacking.h"
00052 #include "giqclog.h"
00053 #include "gierror.h"
00054 #include "giutils.h"
00055
00056
00057 #define GIMASTERBIAS_BIAS_EXTENSION_IMG 0
00058 #define GIMASTERBIAS_BIAS_EXTENSION_PL 0
00059 #define GIMASTERBIAS_BAD_PIXEL_EXTENSION 0
00060
00061
00062 static cxint giframestack(cpl_parameterlist*, cpl_frameset*);
00063
00064
00065
00066
00067
00068
00069
00070 static cxint
00071 giframestack_create(cpl_plugin* plugin)
00072 {
00073
00074 cpl_recipe* recipe = (cpl_recipe*)plugin;
00075
00076 giraffe_error_init();
00077
00078
00079
00080
00081
00082
00083
00084
00085 recipe->parameters = cpl_parameterlist_new();
00086 cx_assert(recipe->parameters != NULL);
00087
00088
00089
00090
00091
00092 giraffe_stacking_config_add(recipe->parameters);
00093
00094 return 0;
00095
00096 }
00097
00098
00099
00100
00101
00102
00103 static cxint
00104 giframestack_exec(cpl_plugin* plugin)
00105 {
00106
00107 cpl_recipe* recipe = (cpl_recipe*)plugin;
00108
00109 cxint status = 0;
00110
00111
00112 if (recipe->parameters == NULL || recipe->frames == NULL) {
00113 return 1;
00114 }
00115
00116 status = giframestack(recipe->parameters, recipe->frames);
00117
00118 if (status != 0) {
00119 return 1;
00120 }
00121
00122 return 0;
00123
00124 }
00125
00126
00127 static cxint
00128 giframestack_destroy(cpl_plugin* plugin)
00129 {
00130
00131 cpl_recipe* recipe = (cpl_recipe*)plugin;
00132
00133
00134
00135
00136
00137
00138
00139
00140 cpl_parameterlist_delete(recipe->parameters);
00141
00142 giraffe_error_clear();
00143
00144 return 0;
00145
00146 }
00147
00148
00149
00150
00151
00152 static cxint
00153 giframestack(cpl_parameterlist* config, cpl_frameset* set)
00154 {
00155
00156 const cxchar* const _id = "giframestack";
00157
00158
00159 cxint i = 0;
00160 cxint status = 0;
00161 cxint count = 0;
00162
00163 cxdouble exptime = 0.;
00164
00165 cx_string* tag = NULL;
00166
00167 cx_list* frames = NULL;
00168 cx_list* images = NULL;
00169
00170 cx_list_iterator position;
00171
00172 cpl_propertylist* properties = NULL;
00173
00174 cpl_frame* frame = NULL;
00175
00176 GiImage* image = NULL;
00177 GiImage* result = NULL;
00178 GiImage** stack = NULL;
00179
00180 GiStackingConfig* setup = NULL;
00181
00182 GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
00183
00184
00185
00186 setup = giraffe_stacking_config_create(config);
00187
00188 if (setup == NULL) {
00189 cpl_msg_error(_id, "Invalid parameter list! Aborting ...");
00190 return 1;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 cpl_msg_info(_id, "Searching for frames to combine ...");
00204
00205 frame = cpl_frameset_get_first(set);
00206
00207 if (frame == NULL) {
00208 cpl_msg_error(_id, "Empty input frameset encountered!");
00209
00210 giraffe_stacking_config_destroy(setup);
00211 setup = NULL;
00212
00213 return 1;
00214 }
00215
00216
00217 image = giraffe_image_new(CPL_TYPE_DOUBLE);
00218
00219 status = giraffe_image_load(image, cpl_frame_get_filename(frame), 0);
00220
00221 while (status != 0 && count < cpl_frameset_get_size(set)) {
00222
00223 frame = cpl_frameset_get_next(set);
00224
00225 status = giraffe_image_load(image, cpl_frame_get_filename(frame), 0);
00226 ++count;
00227
00228 }
00229
00230 if (count == cpl_frameset_get_size(set)) {
00231 cpl_msg_error(_id, "The input frameset does not contain any "
00232 "images.");
00233
00234 giraffe_image_delete(image);
00235 image = NULL;
00236
00237 giraffe_stacking_config_destroy(setup);
00238 setup = NULL;
00239
00240 return 1;
00241 }
00242
00243 tag = cx_string_create(cpl_frame_get_tag(frame));
00244
00245
00246
00247
00248
00249
00250
00251
00252 cpl_msg_info(_id, "Selecting '%s' frames for combination.",
00253 cx_string_get(tag));
00254
00255 frames = cx_list_new();
00256 cx_list_push_back(frames, frame);
00257
00258 images = cx_list_new();
00259 cx_list_push_back(images, image);
00260
00261
00262 frame = cpl_frameset_find(set, cx_string_get(tag));
00263
00264 if (frame == cx_list_front(frames)) {
00265 frame = cpl_frameset_find(set, NULL);
00266 }
00267
00268 while (frame != NULL) {
00269
00270 if (frame != cx_list_front(frames)) {
00271
00272 GiImage* _image = giraffe_image_new(CPL_TYPE_DOUBLE);
00273
00274
00275 status = giraffe_image_load(_image,
00276 cpl_frame_get_filename(frame), 0);
00277
00278 if (status == 0) {
00279
00280 cxint nx = cpl_image_get_size_x(giraffe_image_get(_image));
00281 cxint ny = cpl_image_get_size_y(giraffe_image_get(_image));
00282
00283 if (nx == cpl_image_get_size_x(giraffe_image_get(image)) &&
00284 ny == cpl_image_get_size_y(giraffe_image_get(image))) {
00285
00286 cx_list_push_back(frames, frame);
00287 cx_list_push_back(images, _image);
00288
00289 }
00290 else {
00291
00292 cpl_msg_warning(_id, "Ignoring frame '%s' because of "
00293 "different size!",
00294 cpl_frame_get_filename(frame));
00295
00296 giraffe_image_delete(_image);
00297 _image = NULL;
00298
00299 }
00300
00301 }
00302 else {
00303 giraffe_image_delete(_image);
00304 _image = NULL;
00305 }
00306
00307 }
00308
00309 frame = cpl_frameset_find(set, NULL);
00310
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 count = cx_list_size(images);
00320
00321 if (count < setup->min_nr_frames) {
00322
00323 cpl_msg_error(_id, "Not enough frames (%d). Stacking method '%d' "
00324 "requires at least %d frames! Aborting...", count,
00325 setup->stackmethod, setup->min_nr_frames);
00326
00327 cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00328 images = NULL;
00329
00330 cx_list_delete(frames);
00331 frames = NULL;
00332
00333 cx_string_delete(tag);
00334 tag = NULL;
00335
00336 giraffe_stacking_config_destroy(setup);
00337 setup = NULL;
00338
00339 return 1;
00340
00341 }
00342
00343
00344
00345
00346
00347
00348 cpl_msg_info(_id, "Combining %d frames (%s) ...", count,
00349 cx_string_get(tag));
00350
00351 stack = cx_calloc(count + 1, sizeof(GiImage*));
00352
00353 i = 0;
00354 position = cx_list_begin(images);
00355
00356 while (position != cx_list_end(images)) {
00357 stack[i] = cx_list_get(images, position);
00358 position = cx_list_next(images, position);
00359 ++i;
00360 }
00361
00362 result = giraffe_stacking_stack_images(stack, setup);
00363
00364 if (result == NULL) {
00365
00366 cpl_msg_error(_id,"Frame combination failed! Aborting ...");
00367
00368 cx_free(stack);
00369 stack = NULL;
00370
00371 cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00372 images = NULL;
00373
00374 cx_list_delete(frames);
00375 frames = NULL;
00376
00377 cx_string_delete(tag);
00378 tag = NULL;
00379
00380 giraffe_stacking_config_destroy(setup);
00381 setup = NULL;
00382
00383 return 1;
00384
00385 }
00386
00387 cx_free(stack);
00388 stack = NULL;
00389
00390 giraffe_stacking_config_destroy(setup);
00391 setup = NULL;
00392
00393
00394
00395
00396
00397
00398 cpl_msg_info(_id, "Updating combined frame properties ...");
00399
00400 properties = giraffe_image_get_properties(cx_list_front(images));
00401 cx_assert(properties != NULL);
00402
00403 giraffe_image_set_properties(result, properties);
00404 properties = giraffe_image_get_properties(result);
00405
00406 if (properties == NULL) {
00407
00408 cpl_msg_error(_id, "Updating combined frame properties failed!");
00409
00410 giraffe_image_delete(result);
00411 result = NULL;
00412
00413 cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00414 images = NULL;
00415
00416 cx_list_delete(frames);
00417 frames = NULL;
00418
00419 cx_string_delete(tag);
00420 tag = NULL;
00421
00422 return 1;
00423
00424 }
00425
00426 giraffe_error_push();
00427
00428 cpl_propertylist_update_double(properties, GIALIAS_BZERO, 0.);
00429 cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
00430
00431 exptime = 0.;
00432 position = cx_list_begin(images);
00433
00434 while (position != cx_list_end(images)) {
00435
00436 cpl_propertylist* p =
00437 giraffe_image_get_properties(cx_list_get(images, position));
00438
00439 exptime += cpl_propertylist_get_double(p, GIALIAS_EXPTIME);
00440 position = cx_list_next(images, position);
00441
00442 }
00443
00444 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptime);
00445
00446 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, count);
00447
00448 cpl_propertylist_erase(properties, GIALIAS_EXPTIME);
00449 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
00450
00451
00452 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00453
00454 cpl_msg_error(_id, "Updating combined frame properties failed!");
00455
00456 giraffe_image_delete(result);
00457 result = NULL;
00458
00459 cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00460 images = NULL;
00461
00462 cx_list_delete(frames);
00463 frames = NULL;
00464
00465 cx_string_delete(tag);
00466 tag = NULL;
00467
00468 return 1;
00469
00470 }
00471
00472 giraffe_error_pop();
00473
00474
00475
00476
00477
00478
00479 cpl_msg_info(_id, "Writing combined frame ...");
00480
00481 giraffe_image_add_info(result, &info, set);
00482
00483 cx_string_append(tag, "_COMBINED");
00484
00485 frame = giraffe_frame_create_image(result, cx_string_get(tag),
00486 CPL_FRAME_LEVEL_FINAL, TRUE, TRUE);
00487
00488 if (frame == NULL) {
00489
00490 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
00491
00492 giraffe_image_delete(result);
00493 result = NULL;
00494
00495 cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00496 images = NULL;
00497
00498 cx_list_delete(frames);
00499 frames = NULL;
00500
00501 cx_string_delete(tag);
00502 tag = NULL;
00503
00504 return 1;
00505
00506 }
00507
00508 cpl_frameset_insert(set, frame);
00509
00510
00511
00512
00513
00514
00515 giraffe_image_delete(result);
00516 result = NULL;
00517
00518 cx_list_destroy(images, (cx_free_func)giraffe_image_delete);
00519 images = NULL;
00520
00521 cx_list_delete(frames);
00522 frames = NULL;
00523
00524 cx_string_delete(tag);
00525 tag = NULL;
00526
00527 return 0;
00528
00529 }
00530
00531
00532
00533
00534
00535
00536
00537 int
00538 cpl_plugin_get_info(cpl_pluginlist* list)
00539 {
00540
00541 cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
00542 cpl_plugin* plugin = &recipe->interface;
00543
00544
00545 cpl_plugin_init(plugin,
00546 CPL_PLUGIN_API,
00547 GIRAFFE_BINARY_VERSION,
00548 CPL_PLUGIN_TYPE_RECIPE,
00549 "giframestack",
00550 "Creates a stacked image from a set of raw images.",
00551 "TBD",
00552 "Giraffe Pipeline",
00553 PACKAGE_BUGREPORT,
00554 giraffe_get_license(),
00555 giframestack_create,
00556 giframestack_exec,
00557 giframestack_destroy);
00558
00559 cpl_pluginlist_append(list, plugin);
00560
00561 return 0;
00562
00563 }