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