Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
ansel-cli/main.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2012, 2014-2015 johannes hanika.
4 Copyright (C) 2012, 2014-2016, 2019-2021 Pascal Obry.
5 Copyright (C) 2012-2017, 2019-2020 Tobias Ellinghaus.
6 Copyright (C) 2013-2014 Jérémy Rosen.
7 Copyright (C) 2013-2014 Pascal de Bruijn.
8 Copyright (C) 2013 Thomas Pryds.
9 Copyright (C) 2014 Pedro Côrte-Real.
10 Copyright (C) 2014-2016 Roman Lebedev.
11 Copyright (C) 2017, 2020 Heiko Bauke.
12 Copyright (C) 2018 Bill Ferguson.
13 Copyright (C) 2018 Michael Mayer.
14 Copyright (C) 2019 Denis Dyakov.
15 Copyright (C) 2019 parafin.
16 Copyright (C) 2019 Philippe Weyland.
17 Copyright (C) 2020 bobobo1618.
18 Copyright (C) 2020 David-Tillmann Schaefer.
19 Copyright (C) 2020 Hubert Kowalski.
20 Copyright (C) 2021 Aldric Renaudin.
21 Copyright (C) 2021 Christian Kreibich.
22 Copyright (C) 2021 Hanno Schwalm.
23 Copyright (C) 2021 Ralf Brown.
24 Copyright (C) 2022-2023, 2025 Aurélien PIERRE.
25 Copyright (C) 2022 Martin Bařinka.
26 Copyright (C) 2022 Miloš Komarčević.
27 Copyright (C) 2023 Alynx Zhou.
28
29 darktable is free software: you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation, either version 3 of the License, or
32 (at your option) any later version.
33
34 darktable is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with darktable. If not, see <http://www.gnu.org/licenses/>.
41*/
42
52#include "darktable.h"
53#include "common/xmp_sidecar.h"
54#include "common/film.h"
56#include "history/history.h"
57#include "common/image.h"
58#include "caches/image_cache.h"
60#include "common/l10n.h"
61
62#include <inttypes.h>
63#include <libintl.h>
64
65#ifdef __APPLE__
66#include "osx/osx.h"
67#endif
68
69#ifdef _WIN32
70#include "win/main_wrapper.h"
71#endif
72
73#define DT_MAX_STYLE_NAME_LENGTH 128
74
75// Make sure it's OK to limit output extension length
76#define DT_MAX_OUTPUT_EXT_LENGTH 5
77
78static void usage(const char *progname)
79{
80 fprintf(stderr, "usage: %s [<input file or dir>] [<xmp file>] <output destination> [options] [--core <darktable options>]\n", progname);
81 fprintf(stderr, "\n");
82 fprintf(stderr, "options:\n");
83 fprintf(stderr, " --width <max width> default: 0 = full resolution\n");
84 fprintf(stderr, " --height <max height> default: 0 = full resolution\n");
85 fprintf(stderr, " --bpp <bpp>, unsupported\n");
86 fprintf(stderr, " --export_masks <0|1|false|true>, default: false\n");
87 fprintf(stderr, " --style <style name>\n");
88 fprintf(stderr, " --apply-custom-presets <0|1|false|true>, default: true\n");
89 fprintf(stderr, " disable for multiple instances\n");
90 fprintf(stderr, " --out-ext <extension>, default from output destination or '.jpg'\n");
91 fprintf(stderr, " if specified, takes preference over output\n");
92 fprintf(stderr, " --import <file or dir> specify input file or dir, can be used'\n");
93 fprintf(stderr, " multiple times instead of input file\n");
94 fprintf(stderr, " --imgid <id> process an image already in the library, using its\n");
95 fprintf(stderr, " editing history from library.db (no input file, no XMP;\n");
96 fprintf(stderr, " can be used multiple times; only the output is positional)\n");
97 fprintf(stderr, "\n");
98 fprintf(stderr, " the output destination may contain $(VARIABLES) expanded by the disk\n");
99 fprintf(stderr, " storage, e.g. '/path/$(FILE_NAME)-myfix' with --out-ext tiff produces\n");
100 fprintf(stderr, " /path/<original basename>-myfix.tiff\n");
101 fprintf(stderr, " --icc-type <type> specify icc type, default to NONE\n");
102 fprintf(stderr, " use --help icc-type for list of supported types\n");
103 fprintf(stderr, " --icc-file <file> specify icc filename, default to NONE\n");
104 fprintf(stderr, " --icc-intent <intent> specify icc intent, default to LAST\n");
105 fprintf(stderr, " use --help icc-intent for list of supported intents\n");
106 fprintf(stderr, " --verbose\n");
107 fprintf(stderr, " --help,-h [option]\n");
108 fprintf(stderr, " --version\n");
109}
110
111static void icc_types()
112{
113 // TODO: Can this be automated to keep in sync with colorspaces.h?
114 fprintf(stderr, "available ICC types:\n");
115 fprintf(stderr, " NONE\n");
116 fprintf(stderr, " FILE\n");
117 fprintf(stderr, " SRGB\n");
118 fprintf(stderr, " ADOBERGB\n");
119 fprintf(stderr, " LIN_REC709\n");
120 fprintf(stderr, " LIN_REC2020\n");
121 fprintf(stderr, " XYZ\n");
122 fprintf(stderr, " LAB\n");
123 fprintf(stderr, " INFRARED\n");
124 fprintf(stderr, " DISPLAY\n");
125 fprintf(stderr, " EMBEDDED_ICC\n");
126 fprintf(stderr, " EMBEDDED_MATRIX\n");
127 fprintf(stderr, " STANDARD_MATRIX\n");
128 fprintf(stderr, " ENHANCED_MATRIX\n");
129 fprintf(stderr, " VENDOR_MATRIX\n");
130 fprintf(stderr, " ALTERNATE_MATRIX\n");
131 fprintf(stderr, " BRG\n");
132 fprintf(stderr, " EXPORT\n"); // export and softproof are categories and will return NULL with dt_colorspaces_get_profile()
133 fprintf(stderr, " SOFTPROOF\n");
134 fprintf(stderr, " WORK\n");
135 fprintf(stderr, " REC709\n");
136 fprintf(stderr, " PROPHOTO_RGB\n");
137 fprintf(stderr, " PQ_REC2020\n");
138 fprintf(stderr, " HLG_REC2020\n");
139 fprintf(stderr, " PQ_P3\n");
140 fprintf(stderr, " HLG_P3\n");
141 fprintf(stderr, " DISPLAY_P3\n");
142}
143
144#define ICC_FROM_STR(name) if(!strcmp(option, #name)) return DT_COLORSPACE_ ## name;
176#undef ICC_FROM_STR
177
178static void icc_intents()
179{
180 // TODO: Can this be automated to keep in sync with colorspaces.h?
181 fprintf(stderr, "available ICC intents:\n");
182 fprintf(stderr, " PERCEPTUAL\n");
183 fprintf(stderr, " RELATIVE_COLORIMETRIC\n");
184 fprintf(stderr, " SATURATION\n");
185 fprintf(stderr, " ABSOLUTE_COLORIMETRIC\n");
186}
187#define ICC_INTENT_FROM_STR(name) if(!strcmp(option, #name)) return DT_INTENT_ ## name;
196#undef ICC_INTENT_FROM_STR
197
198int main(int argc, char *arg[])
199{
200#ifdef __APPLE__
202#endif
203
204 // get valid locale dir
206 char localedir[PATH_MAX] = { 0 };
207 dt_loc_get_localedir(localedir, sizeof(localedir));
209
210 // gtk_parse_args may trigger GTK initialization, so disable GTK locale handling first.
212 if(!gtk_parse_args(&argc, &arg)) exit(1);
213
214 // parse command line arguments
215 char *input_filename = NULL;
216 char *xmp_filename = NULL;
217 gchar *output_filename = NULL;
218 gchar *output_ext = NULL;
219 char *style = NULL;
220 int file_counter = 0;
221 int width = 0, height = 0, bpp = 0;
222 gboolean verbose = FALSE, custom_presets = TRUE, export_masks = FALSE,
224
225 GList* inputs = NULL;
226 GList* imgids = NULL;
227
229 gchar *icc_filename = NULL;
231
232 int k;
233 for(k = 1; k < argc; k++)
234 {
235 if(arg[k][0] == '-')
236 {
237 if(!strcmp(arg[k], "--help") || !strcmp(arg[k], "-h"))
238 {
239 usage(arg[0]);
240 if(k+1 < argc) {
241 if(!strcmp(arg[k+1], "icc-type"))
242 icc_types();
243 if(!strcmp(arg[k+1], "icc-intent"))
244 icc_intents();
245 }
246 exit(1);
247 }
248 else if(!strcmp(arg[k], "--version"))
249 {
250 printf("this is ansel-cli %s\ncopyright (c) 2012-%s johannes hanika, tobias ellinghaus\n",
252 exit(0);
253 }
254 else if(!strcmp(arg[k], "--width") && argc > k + 1)
255 {
256 k++;
257 width = MAX(atoi(arg[k]), 0);
258 }
259 else if(!strcmp(arg[k], "--height") && argc > k + 1)
260 {
261 k++;
262 height = MAX(atoi(arg[k]), 0);
263 }
264 else if(!strcmp(arg[k], "--bpp") && argc > k + 1)
265 {
266 k++;
267 bpp = MAX(atoi(arg[k]), 0);
268 fprintf(stderr, _("TODO: sorry, due to API restrictions we currently cannot set the BPP to %d.\n"), bpp);
269 }
270 else if(!strcmp(arg[k], "--export_masks") && argc > k + 1)
271 {
272 k++;
273 gchar *str = g_ascii_strup(arg[k], -1);
274 if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE"))
275 export_masks = FALSE;
276 else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE"))
277 export_masks = TRUE;
278 else
279 {
280 fprintf(stderr, _("unknown option for --export_masks: %s.\n"), arg[k]);
281 usage(arg[0]);
282 exit(1);
283 }
284 dt_free(str);
285 }
286 else if(!strcmp(arg[k], "--style") && argc > k + 1)
287 {
288 k++;
289 style = arg[k];
290 }
291 else if(!strcmp(arg[k], "--apply-custom-presets") && argc > k + 1)
292 {
293 k++;
294 gchar *str = g_ascii_strup(arg[k], -1);
295 if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE"))
297 else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE"))
299 else
300 {
301 fprintf(stderr, _("unknown option for --apply-custom-presets: %s.\n"), arg[k]);
302 usage(arg[0]);
303 exit(1);
304 }
305 dt_free(str);
306 }
307 else if(!strcmp(arg[k], "--out-ext") && argc > k + 1)
308 {
309 k++;
311 {
312 fprintf(stderr, _("too long ext for --out-ext: %s.\n"), arg[k]);
313 usage(arg[0]);
314 exit(1);
315 }
316 if (*arg[k] == '.')
317 {
318 //remove dot ;)
319 arg[k]++;
320 }
322 }
323 else if(!strcmp(arg[k], "--import") && argc > k + 1)
324 {
325 k++;
327 inputs = g_list_prepend(inputs, g_strdup(arg[k]));
328 else
329 fprintf(stderr, _("notice: input file or dir '%s' doesn't exist, skipping\n"), arg[k]);
330 }
331 else if(!strcmp(arg[k], "--imgid") && argc > k + 1)
332 {
333 k++;
334 const int imgid = atoi(arg[k]);
335
336 if(imgid > 0)
337 imgids = g_list_append(imgids, GINT_TO_POINTER(imgid));
338 else
339 {
340 fprintf(stderr, _("incorrect image id for --imgid: '%s'\n"), arg[k]);
341 usage(arg[0]);
342 exit(1);
343 }
344 }
345 else if(!strcmp(arg[k], "--icc-type") && argc > k + 1)
346 {
347 k++;
348 gchar *str = g_ascii_strup(arg[k], -1);
349 icc_type = get_icc_type(str);
350 dt_free(str);
351 if(icc_type >= DT_COLORSPACE_LAST){
352 fprintf(stderr, _("incorrect ICC type for --icc-type: '%s'\n"), arg[k]);
353 icc_types();
354 usage(arg[0]);
355 exit(1);
356 }
357 }
358 else if(!strcmp(arg[k], "--icc-file") && argc > k + 1)
359 {
360 k++;
362 {
363 if(icc_filename)
364 dt_free(icc_filename);
365 icc_filename = g_strdup(arg[k]);
366 }
367 else
368 fprintf(stderr, _("notice: ICC file '%s' doesn't exist, skipping\n"), arg[k]);
369 }
370 else if(!strcmp(arg[k], "--icc-intent") && argc > k + 1)
371 {
372 k++;
373 gchar *str = g_ascii_strup(arg[k], -1);
374 icc_intent = get_icc_intent(str);
375 dt_free(str);
376 if(icc_intent >= DT_INTENT_LAST){
377 fprintf(stderr, _("incorrect ICC intent for --icc-intent: '%s'\n"), arg[k]);
378 icc_intents();
379 usage(arg[0]);
380 exit(1);
381 }
382 }
383 else if(!strcmp(arg[k], "-v") || !strcmp(arg[k], "--verbose"))
384 {
385 verbose = TRUE;
386 }
387 else if(!strcmp(arg[k], "--core"))
388 {
389 // everything from here on should be passed to the core
390 k++;
391 break;
392 }
393 else
394 {
395 fprintf(stderr, _("warning: unknown option '%s'\n"), arg[k]);
396 }
397 }
398 else
399 {
400 if(file_counter == 0)
402 else if(file_counter == 1)
403 xmp_filename = arg[k];
404 else if(file_counter == 2)
405 {
407 }
408 file_counter++;
409 }
410 }
411
412 int m_argc = 0;
413 char **m_arg = malloc(sizeof(char *) * (5 + argc - k + 1));
414 m_arg[m_argc++] = "ansel-cli";
415
416 // --imgid mode reads the image and its editing history from the user's library.db, so the
417 // default library must be used. Every other mode keeps the throwaway in-memory library.
418 if(IS_NULL_PTR(imgids))
419 {
420 m_arg[m_argc++] = "--library";
421 m_arg[m_argc++] = ":memory:";
422 }
423
424 m_arg[m_argc++] = "--conf";
425 m_arg[m_argc++] = "write_sidecar_files=FALSE";
426 for(; k < argc; k++) m_arg[m_argc++] = arg[k];
427 m_arg[m_argc] = NULL;
428
429 if(imgids && (inputs || file_counter != 1))
430 {
431 // --imgid takes no input file and no XMP: the only positional argument is the output
432 if(inputs || file_counter > 1)
433 fprintf(stderr, _("error: --imgid cannot be combined with input files or an XMP (history comes from library.db)\n"));
434 else
435 fprintf(stderr, _("error: --imgid requires an output destination\n"));
436
437 usage(arg[0]);
438 dt_free(m_arg);
440 {
442 }
443 if(output_ext)
444 {
446 }
447 g_list_free(imgids);
448 if(inputs)
449 {
451 inputs = NULL;
452 }
453 exit(1);
454 }
455 else if(imgids)
456 {
457 // the single positional argument is the output destination
462 }
463 else if( (inputs && file_counter < 1) || (IS_NULL_PTR(inputs) && file_counter < 2) || file_counter > 3)
464 {
465 usage(arg[0]);
466 dt_free(m_arg);
468 {
470 }
471 if(output_ext)
472 {
474 }
475 if(inputs)
476 {
478 inputs = NULL;
479 }
480 exit(1);
481 }
482 else if(inputs && file_counter == 1)
483 {
484 //user specified inputs as options, and only dest is present
489 }
490 else if (inputs && file_counter == 2)
491 {
492 // inputs as options, xmp & output specified
498 }
499 else if (inputs && file_counter == 3)
500 {
501 fprintf(stderr, _("error: input file and import opts specified! that's not supported!\n"));
502 usage(arg[0]);
503 dt_free(m_arg);
505 {
507 }
508 if(output_ext)
509 {
511 }
513 inputs = NULL;
514 exit(1);
515 }
516 else if(file_counter == 2)
517 {
518 // assume no xmp file given
523 }
524
525 if(IS_NULL_PTR(inputs) && input_filename)
526 {
527 // input is present as param
528 inputs = g_list_prepend(inputs, g_strdup(input_filename));
530 }
531
533 {
536 {
537 output_ext = g_strdup("jpg");
538 }
539 fprintf(stderr, _("notice: output location is a directory. assuming '%s/$(FILE_NAME).%s' output pattern"), output_filename, output_ext);
540 fprintf(stderr, "\n");
543 if(g_str_has_suffix(temp_of, "/"))
544 temp_of[strlen(temp_of) - 1] = '\0';
545 output_filename = g_strconcat(temp_of, "/$(FILE_NAME)", NULL);
547 }
548
549 // the output file already exists, so there will be a sequence number added
551 {
553 //output file exists or there's output ext specified and it's same as file...
554 fprintf(stderr, "%s\n", _("output file already exists, it will get renamed"));
555 }
556 //TODO: test if file with replaced ext exists
557 // or not if we decide we don't replace file ext with output ext specified
558 }
559
560 // init dt without gui and without data.db:
562 {
563 dt_free(m_arg);
565 if(output_ext)
566 {
568 }
569 if(inputs)
570 {
572 inputs = NULL;
573 }
574 exit(1);
575 }
576
577 GList *id_list = NULL;
578
579 // --imgid mode: the images are already in the library with their history; just check they exist
580 for(GList *l = imgids; !IS_NULL_PTR(l); l = g_list_next(l))
581 {
582 const int imgid = GPOINTER_TO_INT(l->data);
583 const dt_image_t *image = dt_image_cache_get(imgid, 'r');
584
585 if(image && image->id == imgid)
586 {
589 }
590 else
591 {
592 if(image)
594 fprintf(stderr, _("error: no image with id %d in the library"), imgid);
595 fprintf(stderr, "\n");
596 }
597 }
598
599 g_list_free(imgids);
600 imgids = NULL;
601
602 for(GList *l = inputs; !IS_NULL_PTR(l); l=g_list_next(l))
603 {
604 gchar* input = l->data;
605
607 {
608 const int filmid = dt_film_import(input);
609 if(!filmid)
610 {
611 // one of inputs was a failure, no prob
612 fprintf(stderr, _("error: can't open folder %s"), input);
613 fprintf(stderr, "\n");
614 continue;
615 }
617 }
618 else
619 {
620 dt_film_t film;
621 int filmid = 0;
622
623 gchar *directory = g_path_get_dirname(input);
624 filmid = dt_film_new(&film, directory);
625 const int32_t id = dt_image_import(filmid, input, TRUE);
626 dt_free(directory);
627 if(!id)
628 {
629 fprintf(stderr, _("error: can't open file %s"), input);
630 fprintf(stderr, "\n");
631 continue;
632 }
634 }
635 }
636
637 //we no longer need inputs
638 if(inputs)
639 {
641 inputs = NULL;
642 }
643
644 const int total = g_list_length(id_list);
645
646 if(total == 0)
647 {
648 fprintf(stderr, _("no images to export, aborting\n"));
649 dt_free(m_arg);
651 if(output_ext)
652 {
654 }
655 exit(1);
656 }
657
658 // attach xmp, if requested:
659 if(xmp_filename)
660 {
662 {
663 int id = GPOINTER_TO_INT(iter->data);
664 dt_image_t *image = dt_image_cache_get(id, 'w');
665 if(dt_exif_xmp_read(image, xmp_filename, 1) != 0)
666 {
667 fprintf(stderr, _("error: can't open xmp file %s"), xmp_filename);
668 fprintf(stderr, "\n");
669 dt_free(m_arg);
671 if(output_ext)
672 {
674 }
675 exit(1);
676 }
677 // don't write new xmp:
679 }
680 }
681
682 // print the history stack. only look at the first image and assume all got the same processing applied
683 if(verbose)
684 {
685 int id = GPOINTER_TO_INT(id_list->data);
686 gchar *history = dt_history_get_items_as_string(id);
687 if(history)
688 printf("%s\n", history);
689 else
690 printf("[%s]\n", _("empty history stack"));
691 }
692
694 {
695 // by this point we're sure output is not dir, there's no output ext specified
696 // so only place to look for it is in filename
697 // try to find out the export format from the output_filename
698 char *ext = strrchr(output_filename, '.');
700 {
701 // too long ext, no point in wasting time
702 fprintf(stderr, _("too long output file extension: %s\n"), ext);
703 usage(arg[0]);
705 exit(1);
706 }
707 else if(!ext || strlen(ext) <= 1)
708 {
709 // no ext or empty ext, no point in wasting time
710 fprintf(stderr, _("no output file extension given\n"));
711 usage(arg[0]);
713 exit(1);
714 }
715 *ext = '\0';
716 ext++;
718 } else {
719 // check and remove redundant file ext
720 char *ext = strrchr(output_filename, '.');
721 if(ext && !strcmp(output_ext, ext+1))
722 {
723 *ext = '\0';
724 }
725 }
726
727 if(!strcmp(output_ext, "jpg"))
728 {
730 output_ext = g_strdup("jpeg");
731 }
732
733 if(!strcmp(output_ext, "tif"))
734 {
736 output_ext = g_strdup("tiff");
737 }
738
739 // init the export data structures
743
744 storage = dt_imageio_get_storage_by_name("disk"); // only exporting to disk makes sense
745 if(IS_NULL_PTR(storage))
746 {
747 fprintf(
748 stderr, "%s\n",
749 _("cannot find disk storage module. please check your installation, something seems to be broken."));
750 dt_free(m_arg);
753 exit(1);
754 }
755
756 sdata = storage->get_params(storage);
757 if(IS_NULL_PTR(sdata))
758 {
759 fprintf(stderr, "%s\n", _("failed to get parameters from storage module, aborting export ..."));
760 dt_free(m_arg);
763 exit(1);
764 }
765
766 // and now for the really ugly hacks. don't tell your children about this one or they won't sleep at night
767 // any longer ...
769 // all is good now, the last line didn't happen.
771
773 if(IS_NULL_PTR(format))
774 {
775 fprintf(stderr, _("unknown extension '.%s'"), output_ext);
776 fprintf(stderr, "\n");
777 dt_free(m_arg);
779 exit(1);
780 }
781
782 fdata = format->get_params(format);
783 if(IS_NULL_PTR(fdata))
784 {
785 fprintf(stderr, "%s\n", _("failed to get parameters from format module, aborting export ..."));
786 dt_free(m_arg);
788 exit(1);
789 }
790
791 uint32_t w, h, fw, fh, sw, sh;
792 fw = fh = sw = sh = 0;
793 storage->dimension(storage, sdata, &sw, &sh);
794 format->dimension(format, fdata, &fw, &fh);
795
796 if(sw == 0 || fw == 0)
797 w = sw > fw ? sw : fw;
798 else
799 w = sw < fw ? sw : fw;
800
801 if(sh == 0 || fh == 0)
802 h = sh > fh ? sh : fh;
803 else
804 h = sh < fh ? sh : fh;
805
806 fdata->max_width = width;
807 fdata->max_height = height;
808 fdata->max_width = (w != 0 && fdata->max_width > w) ? w : fdata->max_width;
809 fdata->max_height = (h != 0 && fdata->max_height > h) ? h : fdata->max_height;
810 fdata->style[0] = '\0';
811
812 if(style)
813 {
814 g_strlcpy((char *)fdata->style, style, DT_MAX_STYLE_NAME_LENGTH);
815 fdata->style[127] = '\0';
816 }
817
818 if(storage->initialize_store)
819 {
820 storage->initialize_store(storage, sdata, &format, &fdata, &id_list, TRUE);
821
822 format->set_params(format, fdata, format->params_size(format));
823 storage->set_params(storage, sdata, storage->params_size(storage));
824 }
825
826 // TODO: add a callback to set the bpp without going through the config
827
828 int num = 1, res = 0;
829 for(GList *iter = id_list; iter; iter = g_list_next(iter), num++)
830 {
831 const int id = GPOINTER_TO_INT(iter->data);
832 // TODO: have a parameter in command line to get the export presets
833 dt_export_metadata_t metadata;
835 metadata.list = NULL;
836 if(storage->store(storage, sdata, id, format, fdata, num, total, TRUE, export_masks,
837 icc_type, icc_filename, icc_intent, &metadata) != 0)
838 res = 1;
839 }
840
841 // cleanup time
842 if(storage->finalize_store) storage->finalize_store(storage, sdata);
843 storage->free_params(storage, sdata);
844 format->free_params(format, fdata);
846 id_list = NULL;
847
848 if(icc_filename)
849 {
850 dt_free(icc_filename);
851 }
852
853 dt_cleanup();
854
855 dt_free(m_arg);
856 exit(res);
857}
858
859// clang-format off
860// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
861// vim: shiftwidth=2 expandtab tabstop=2 cindent
862// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
863// clang-format on
static void usage(const char *progname)
static void icc_types()
static dt_iop_color_intent_t get_icc_intent(const char *option)
#define DT_MAX_OUTPUT_EXT_LENGTH
#define ICC_INTENT_FROM_STR(name)
static dt_colorspaces_color_profile_type_t get_icc_type(const char *option)
#define DT_MAX_STYLE_NAME_LENGTH
#define ICC_FROM_STR(name)
static void icc_intents()
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
static dt_aligned_pixel_t XYZ
int32_t dt_image_import(const int32_t film_id, const char *filename, gboolean raise_signals)
const char darktable_package_version[]
#define GETTEXT_PACKAGE
const char darktable_last_commit_year[]
void dt_cleanup()
Definition darktable.c:1840
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data)
Definition darktable.c:878
void dt_loc_get_localedir(char *localedir, size_t bufsize)
void dt_loc_init(const char *datadir, const char *moduledir, const char *localedir, const char *configdir, const char *cachedir, const char *tmpdir, const char *kerneldir)
int dt_film_new(dt_film_t *film, const char *directory)
Definition film.c:129
GList * dt_film_get_image_ids(const int filmid)
Definition film.c:383
int dt_film_import(const char *dirname)
Definition film.c:187
char * dt_history_get_items_as_string(const int32_t imgid)
void dt_image_cache_write_release(dt_image_t *img, dt_image_cache_write_mode_t mode)
dt_image_t * dt_image_cache_get(const int32_t imgid, char mode)
void dt_image_cache_read_release(const dt_image_t *img)
@ DT_IMAGE_CACHE_RELAXED
Definition image_cache.h:50
int bpp
dt_imageio_module_format_t * dt_imageio_get_format_by_name(const char *name)
dt_imageio_module_storage_t * dt_imageio_get_storage_by_name(const char *name)
void dt_l10n_disable_setlocale_early(void)
Definition l10n.c:91
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65
static void dt_free_gpointer(gpointer ptr)
Definition mem_alloc.h:104
#define dt_free(ptr)
Definition mem_alloc.h:97
uint32_t dt_lib_export_metadata_default_flags(void)
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
void dt_osx_prepare_environment()
Definition osx.mm:213
#define DT_MAX_PATH_FOR_PARAMS
Definition paths.h:54
#define PATH_MAX
Definition paths.h:45
dt_iop_color_intent_t
ICC rendering intent, as stored in iop params and in conf.
@ DT_INTENT_LAST
Count of real intents, and the codebase's "unset" marker – never a user choice.
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_NONE
No profile / "take it from the image settings". Never matches a list entry.
@ DT_COLORSPACE_LAST
Count, not a colour space. The last usable value is DT_COLORSPACE_LAST - 1.
int main()
Definition prova.c:47
int32_t id
Definition image.h:377
#define MAX(a, b)
Definition thinplate.c:29
int dt_exif_xmp_read(dt_image_t *img, const char *filename, const int history_only)
The XMP document that carries an image's development: history stack, mask shapes, module order,...