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 Copyright (C) 2026 Guillaume Stutin.
29
30 darktable is free software: you can redistribute it and/or modify
31 it under the terms of the GNU General Public License as published by
32 the Free Software Foundation, either version 3 of the License, or
33 (at your option) any later version.
34
35 darktable is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with darktable. If not, see <http://www.gnu.org/licenses/>.
42*/
43
53#include "darktable.h"
54#include "common/paths.h" // DT_PATH_MAX
55#include "common/xmp_sidecar.h"
56#include "common/film.h"
58#include "history/history.h"
59#include "common/image.h"
60#include "caches/image_cache.h"
62#include "common/l10n.h"
63
64#include <inttypes.h>
65#include <libintl.h>
66
67#ifdef __APPLE__
68#include "osx/osx.h"
69#endif
70
71#ifdef _WIN32
72#include "win/main_wrapper.h"
73#endif
74
75#define DT_MAX_STYLE_NAME_LENGTH 128
76
77// Make sure it's OK to limit output extension length
78#define DT_MAX_OUTPUT_EXT_LENGTH 5
79
80static void usage(const char *progname)
81{
82 fprintf(stderr, "usage: %s [<input file or dir>] [<xmp file>] <output destination> [options] [--core <darktable options>]\n", progname);
83 fprintf(stderr, "\n");
84 fprintf(stderr, "options:\n");
85 fprintf(stderr, " --width <max width> default: 0 = full resolution\n");
86 fprintf(stderr, " --height <max height> default: 0 = full resolution\n");
87 fprintf(stderr, " --bpp <bpp>, unsupported\n");
88 fprintf(stderr, " --export_masks <0|1|false|true>, default: false\n");
89 fprintf(stderr, " --style <style name>\n");
90 fprintf(stderr, " --apply-custom-presets <0|1|false|true>, default: true\n");
91 fprintf(stderr, " disable for multiple instances\n");
92 fprintf(stderr, " --out-ext <extension>, default from output destination or '.jpg'\n");
93 fprintf(stderr, " if specified, takes preference over output\n");
94 fprintf(stderr, " --import <file or dir> specify input file or dir, can be used'\n");
95 fprintf(stderr, " multiple times instead of input file\n");
96 fprintf(stderr, " --imgid <id> process an image already in the library, using its\n");
97 fprintf(stderr, " editing history from library.db (no input file, no XMP;\n");
98 fprintf(stderr, " can be used multiple times; only the output is positional)\n");
99 fprintf(stderr, "\n");
100 fprintf(stderr, " the output destination may contain $(VARIABLES) expanded by the disk\n");
101 fprintf(stderr, " storage, e.g. '/path/$(FILE_NAME)-myfix' with --out-ext tiff produces\n");
102 fprintf(stderr, " /path/<original basename>-myfix.tiff\n");
103 fprintf(stderr, " --icc-type <type> specify icc type, default to NONE\n");
104 fprintf(stderr, " use --help icc-type for list of supported types\n");
105 fprintf(stderr, " --icc-file <file> specify icc filename, default to NONE\n");
106 fprintf(stderr, " --icc-intent <intent> specify icc intent, default to LAST\n");
107 fprintf(stderr, " use --help icc-intent for list of supported intents\n");
108 fprintf(stderr, " --verbose\n");
109 fprintf(stderr, " --help,-h [option]\n");
110 fprintf(stderr, " --version\n");
111}
112
113static void icc_types()
114{
115 // TODO: Can this be automated to keep in sync with colorspaces.h?
116 fprintf(stderr, "available ICC types:\n");
117 fprintf(stderr, " NONE\n");
118 fprintf(stderr, " FILE\n");
119 fprintf(stderr, " SRGB\n");
120 fprintf(stderr, " ADOBERGB\n");
121 fprintf(stderr, " LIN_REC709\n");
122 fprintf(stderr, " LIN_REC2020\n");
123 fprintf(stderr, " XYZ\n");
124 fprintf(stderr, " LAB\n");
125 fprintf(stderr, " INFRARED\n");
126 fprintf(stderr, " DISPLAY\n");
127 fprintf(stderr, " EMBEDDED_ICC\n");
128 fprintf(stderr, " EMBEDDED_MATRIX\n");
129 fprintf(stderr, " STANDARD_MATRIX\n");
130 fprintf(stderr, " ENHANCED_MATRIX\n");
131 fprintf(stderr, " VENDOR_MATRIX\n");
132 fprintf(stderr, " ALTERNATE_MATRIX\n");
133 fprintf(stderr, " BRG\n");
134 fprintf(stderr, " EXPORT\n"); // export and softproof are categories and will return NULL with dt_colorspaces_get_profile()
135 fprintf(stderr, " SOFTPROOF\n");
136 fprintf(stderr, " WORK\n");
137 fprintf(stderr, " REC709\n");
138 fprintf(stderr, " PROPHOTO_RGB\n");
139 fprintf(stderr, " PQ_REC2020\n");
140 fprintf(stderr, " HLG_REC2020\n");
141 fprintf(stderr, " PQ_P3\n");
142 fprintf(stderr, " HLG_P3\n");
143 fprintf(stderr, " DISPLAY_P3\n");
144}
145
146#define ICC_FROM_STR(name) if(!strcmp(option, #name)) return DT_COLORSPACE_ ## name;
178#undef ICC_FROM_STR
179
180static void icc_intents()
181{
182 // TODO: Can this be automated to keep in sync with colorspaces.h?
183 fprintf(stderr, "available ICC intents:\n");
184 fprintf(stderr, " PERCEPTUAL\n");
185 fprintf(stderr, " RELATIVE_COLORIMETRIC\n");
186 fprintf(stderr, " SATURATION\n");
187 fprintf(stderr, " ABSOLUTE_COLORIMETRIC\n");
188}
189#define ICC_INTENT_FROM_STR(name) if(!strcmp(option, #name)) return DT_INTENT_ ## name;
198#undef ICC_INTENT_FROM_STR
199
200int main(int argc, char *arg[])
201{
202#ifdef __APPLE__
204#endif
205
206 // get valid locale dir
207 char localedir[DT_PATH_MAX] = { 0 };
208 dt_loc_resolve_localedir(localedir, sizeof(localedir));
210
211 // gtk_parse_args may trigger GTK initialization, so disable GTK locale handling first.
213 if(!gtk_parse_args(&argc, &arg)) exit(1);
214
215 // parse command line arguments
216 char *input_filename = NULL;
217 char *xmp_filename = NULL;
218 gchar *output_filename = NULL;
219 gchar *output_ext = NULL;
220 char *style = NULL;
221 int file_counter = 0;
222 int width = 0, height = 0, bpp = 0;
223 gboolean verbose = FALSE, custom_presets = TRUE, export_masks = FALSE,
225
226 GList* inputs = NULL;
227 GList* imgids = NULL;
228
230 gchar *icc_filename = NULL;
232
233 int k;
234 for(k = 1; k < argc; k++)
235 {
236 if(arg[k][0] == '-')
237 {
238 if(!strcmp(arg[k], "--help") || !strcmp(arg[k], "-h"))
239 {
240 usage(arg[0]);
241 if(k+1 < argc) {
242 if(!strcmp(arg[k+1], "icc-type"))
243 icc_types();
244 if(!strcmp(arg[k+1], "icc-intent"))
245 icc_intents();
246 }
247 exit(1);
248 }
249 else if(!strcmp(arg[k], "--version"))
250 {
251 printf("this is ansel-cli %s\ncopyright (c) 2012-%s johannes hanika, tobias ellinghaus\n",
253 exit(0);
254 }
255 else if(!strcmp(arg[k], "--width") && argc > k + 1)
256 {
257 k++;
258 width = MAX(atoi(arg[k]), 0);
259 }
260 else if(!strcmp(arg[k], "--height") && argc > k + 1)
261 {
262 k++;
263 height = MAX(atoi(arg[k]), 0);
264 }
265 else if(!strcmp(arg[k], "--bpp") && argc > k + 1)
266 {
267 k++;
268 bpp = MAX(atoi(arg[k]), 0);
269 fprintf(stderr, _("TODO: sorry, due to API restrictions we currently cannot set the BPP to %d.\n"), bpp);
270 }
271 else if(!strcmp(arg[k], "--export_masks") && argc > k + 1)
272 {
273 k++;
274 gchar *str = g_ascii_strup(arg[k], -1);
275 if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE"))
276 export_masks = FALSE;
277 else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE"))
278 export_masks = TRUE;
279 else
280 {
281 fprintf(stderr, _("unknown option for --export_masks: %s.\n"), arg[k]);
282 usage(arg[0]);
283 exit(1);
284 }
285 dt_free(str);
286 }
287 else if(!strcmp(arg[k], "--style") && argc > k + 1)
288 {
289 k++;
290 style = arg[k];
291 }
292 else if(!strcmp(arg[k], "--apply-custom-presets") && argc > k + 1)
293 {
294 k++;
295 gchar *str = g_ascii_strup(arg[k], -1);
296 if(!g_strcmp0(str, "0") || !g_strcmp0(str, "FALSE"))
298 else if(!g_strcmp0(str, "1") || !g_strcmp0(str, "TRUE"))
300 else
301 {
302 fprintf(stderr, _("unknown option for --apply-custom-presets: %s.\n"), arg[k]);
303 usage(arg[0]);
304 exit(1);
305 }
306 dt_free(str);
307 }
308 else if(!strcmp(arg[k], "--out-ext") && argc > k + 1)
309 {
310 k++;
312 {
313 fprintf(stderr, _("too long ext for --out-ext: %s.\n"), arg[k]);
314 usage(arg[0]);
315 exit(1);
316 }
317 if (*arg[k] == '.')
318 {
319 //remove dot ;)
320 arg[k]++;
321 }
323 }
324 else if(!strcmp(arg[k], "--import") && argc > k + 1)
325 {
326 k++;
328 inputs = g_list_prepend(inputs, g_strdup(arg[k]));
329 else
330 fprintf(stderr, _("notice: input file or dir '%s' doesn't exist, skipping\n"), arg[k]);
331 }
332 else if(!strcmp(arg[k], "--imgid") && argc > k + 1)
333 {
334 k++;
335 const int imgid = atoi(arg[k]);
336
337 if(imgid > 0)
338 imgids = g_list_append(imgids, GINT_TO_POINTER(imgid));
339 else
340 {
341 fprintf(stderr, _("incorrect image id for --imgid: '%s'\n"), arg[k]);
342 usage(arg[0]);
343 exit(1);
344 }
345 }
346 else if(!strcmp(arg[k], "--icc-type") && argc > k + 1)
347 {
348 k++;
349 gchar *str = g_ascii_strup(arg[k], -1);
350 icc_type = get_icc_type(str);
351 dt_free(str);
352 if(icc_type >= DT_COLORSPACE_LAST){
353 fprintf(stderr, _("incorrect ICC type for --icc-type: '%s'\n"), arg[k]);
354 icc_types();
355 usage(arg[0]);
356 exit(1);
357 }
358 }
359 else if(!strcmp(arg[k], "--icc-file") && argc > k + 1)
360 {
361 k++;
363 {
364 if(icc_filename)
365 dt_free(icc_filename);
366 icc_filename = g_strdup(arg[k]);
367 }
368 else
369 fprintf(stderr, _("notice: ICC file '%s' doesn't exist, skipping\n"), arg[k]);
370 }
371 else if(!strcmp(arg[k], "--icc-intent") && argc > k + 1)
372 {
373 k++;
374 gchar *str = g_ascii_strup(arg[k], -1);
375 icc_intent = get_icc_intent(str);
376 dt_free(str);
377 if(icc_intent >= DT_INTENT_LAST){
378 fprintf(stderr, _("incorrect ICC intent for --icc-intent: '%s'\n"), arg[k]);
379 icc_intents();
380 usage(arg[0]);
381 exit(1);
382 }
383 }
384 else if(!strcmp(arg[k], "-v") || !strcmp(arg[k], "--verbose"))
385 {
386 verbose = TRUE;
387 }
388 else if(!strcmp(arg[k], "--core"))
389 {
390 // everything from here on should be passed to the core
391 k++;
392 break;
393 }
394 else
395 {
396 fprintf(stderr, _("warning: unknown option '%s'\n"), arg[k]);
397 }
398 }
399 else
400 {
401 if(file_counter == 0)
403 else if(file_counter == 1)
404 xmp_filename = arg[k];
405 else if(file_counter == 2)
406 {
408 }
409 file_counter++;
410 }
411 }
412
413 int m_argc = 0;
414 char **m_arg = malloc(sizeof(char *) * (5 + argc - k + 1));
415 m_arg[m_argc++] = "ansel-cli";
416
417 // --imgid mode reads the image and its editing history from the user's library.db, so the
418 // default library must be used. Every other mode keeps the throwaway in-memory library.
419 if(IS_NULL_PTR(imgids))
420 {
421 m_arg[m_argc++] = "--library";
422 m_arg[m_argc++] = ":memory:";
423 }
424
425 m_arg[m_argc++] = "--conf";
426 m_arg[m_argc++] = "write_sidecar_files=FALSE";
427 for(; k < argc; k++) m_arg[m_argc++] = arg[k];
428 m_arg[m_argc] = NULL;
429
430 if(imgids && (inputs || file_counter != 1))
431 {
432 // --imgid takes no input file and no XMP: the only positional argument is the output
433 if(inputs || file_counter > 1)
434 fprintf(stderr, _("error: --imgid cannot be combined with input files or an XMP (history comes from library.db)\n"));
435 else
436 fprintf(stderr, _("error: --imgid requires an output destination\n"));
437
438 usage(arg[0]);
439 dt_free(m_arg);
441 {
443 }
444 if(output_ext)
445 {
447 }
448 g_list_free(imgids);
449 if(inputs)
450 {
452 inputs = NULL;
453 }
454 exit(1);
455 }
456 else if(imgids)
457 {
458 // the single positional argument is the output destination
463 }
464 else if( (inputs && file_counter < 1) || (IS_NULL_PTR(inputs) && file_counter < 2) || file_counter > 3)
465 {
466 usage(arg[0]);
467 dt_free(m_arg);
469 {
471 }
472 if(output_ext)
473 {
475 }
476 if(inputs)
477 {
479 inputs = NULL;
480 }
481 exit(1);
482 }
483 else if(inputs && file_counter == 1)
484 {
485 //user specified inputs as options, and only dest is present
490 }
491 else if (inputs && file_counter == 2)
492 {
493 // inputs as options, xmp & output specified
499 }
500 else if (inputs && file_counter == 3)
501 {
502 fprintf(stderr, _("error: input file and import opts specified! that's not supported!\n"));
503 usage(arg[0]);
504 dt_free(m_arg);
506 {
508 }
509 if(output_ext)
510 {
512 }
514 inputs = NULL;
515 exit(1);
516 }
517 else if(file_counter == 2)
518 {
519 // assume no xmp file given
524 }
525
526 if(IS_NULL_PTR(inputs) && input_filename)
527 {
528 // input is present as param
529 inputs = g_list_prepend(inputs, g_strdup(input_filename));
531 }
532
534 {
537 {
538 output_ext = g_strdup("jpg");
539 }
540 fprintf(stderr, _("notice: output location is a directory. assuming '%s/$(FILE_NAME).%s' output pattern"), output_filename, output_ext);
541 fprintf(stderr, "\n");
544 if(g_str_has_suffix(temp_of, "/"))
545 temp_of[strlen(temp_of) - 1] = '\0';
546 output_filename = g_strconcat(temp_of, "/$(FILE_NAME)", NULL);
548 }
549
550 // the output file already exists, so there will be a sequence number added
552 {
554 //output file exists or there's output ext specified and it's same as file...
555 fprintf(stderr, "%s\n", _("output file already exists, it will get renamed"));
556 }
557 //TODO: test if file with replaced ext exists
558 // or not if we decide we don't replace file ext with output ext specified
559 }
560
561 // init dt without gui and without data.db:
563 {
564 dt_free(m_arg);
566 if(output_ext)
567 {
569 }
570 if(inputs)
571 {
573 inputs = NULL;
574 }
575 exit(1);
576 }
577
578 GList *id_list = NULL;
579
580 // --imgid mode: the images are already in the library with their history; just check they exist
581 for(GList *l = imgids; !IS_NULL_PTR(l); l = g_list_next(l))
582 {
583 const int imgid = GPOINTER_TO_INT(l->data);
584 const dt_image_t *image = dt_image_cache_get(imgid, 'r');
585
586 if(image && image->id == imgid)
587 {
590 }
591 else
592 {
593 if(image)
595 fprintf(stderr, _("error: no image with id %d in the library"), imgid);
596 fprintf(stderr, "\n");
597 }
598 }
599
600 g_list_free(imgids);
601 imgids = NULL;
602
603 for(GList *l = inputs; !IS_NULL_PTR(l); l=g_list_next(l))
604 {
605 gchar* input = l->data;
606
608 {
609 const int filmid = dt_film_import(input);
610 if(!filmid)
611 {
612 // one of inputs was a failure, no prob
613 fprintf(stderr, _("error: can't open folder %s"), input);
614 fprintf(stderr, "\n");
615 continue;
616 }
618 }
619 else
620 {
621 dt_film_t film;
622 int filmid = 0;
623
624 gchar *directory = g_path_get_dirname(input);
625 filmid = dt_film_new(&film, directory);
626 const int32_t id = dt_image_import(filmid, input, TRUE);
628 if(!id)
629 {
630 fprintf(stderr, _("error: can't open file %s"), input);
631 fprintf(stderr, "\n");
632 continue;
633 }
635 }
636 }
637
638 //we no longer need inputs
639 if(inputs)
640 {
642 inputs = NULL;
643 }
644
645 const int total = g_list_length(id_list);
646
647 if(total == 0)
648 {
649 fprintf(stderr, _("no images to export, aborting\n"));
650 dt_free(m_arg);
652 if(output_ext)
653 {
655 }
656 exit(1);
657 }
658
659 // attach xmp, if requested:
660 if(xmp_filename)
661 {
663 {
664 int id = GPOINTER_TO_INT(iter->data);
665 dt_image_t *image = dt_image_cache_get(id, 'w');
666 if(dt_exif_xmp_read(image, xmp_filename, 1) != 0)
667 {
668 fprintf(stderr, _("error: can't open xmp file %s"), xmp_filename);
669 fprintf(stderr, "\n");
670 dt_free(m_arg);
672 if(output_ext)
673 {
675 }
676 exit(1);
677 }
678 // don't write new xmp:
680 }
681 }
682
683 // print the history stack. only look at the first image and assume all got the same processing applied
684 if(verbose)
685 {
686 int id = GPOINTER_TO_INT(id_list->data);
687 gchar *history = dt_history_get_items_as_string(id);
688 if(history)
689 printf("%s\n", history);
690 else
691 printf("[%s]\n", _("empty history stack"));
692 }
693
695 {
696 // by this point we're sure output is not dir, there's no output ext specified
697 // so only place to look for it is in filename
698 // try to find out the export format from the output_filename
699 char *ext = strrchr(output_filename, '.');
701 {
702 // too long ext, no point in wasting time
703 fprintf(stderr, _("too long output file extension: %s\n"), ext);
704 usage(arg[0]);
706 exit(1);
707 }
708 else if(!ext || strlen(ext) <= 1)
709 {
710 // no ext or empty ext, no point in wasting time
711 fprintf(stderr, _("no output file extension given\n"));
712 usage(arg[0]);
714 exit(1);
715 }
716 *ext = '\0';
717 ext++;
719 } else {
720 // check and remove redundant file ext
721 char *ext = strrchr(output_filename, '.');
722 if(ext && !strcmp(output_ext, ext+1))
723 {
724 *ext = '\0';
725 }
726 }
727
728 if(!strcmp(output_ext, "jpg"))
729 {
731 output_ext = g_strdup("jpeg");
732 }
733
734 if(!strcmp(output_ext, "tif"))
735 {
737 output_ext = g_strdup("tiff");
738 }
739
740 // init the export data structures
744
745 storage = dt_imageio_get_storage_by_name("disk"); // only exporting to disk makes sense
746 if(IS_NULL_PTR(storage))
747 {
748 fprintf(
749 stderr, "%s\n",
750 _("cannot find disk storage module. please check your installation, something seems to be broken."));
751 dt_free(m_arg);
754 exit(1);
755 }
756
757 sdata = storage->get_params(storage);
758 if(IS_NULL_PTR(sdata))
759 {
760 fprintf(stderr, "%s\n", _("failed to get parameters from storage module, aborting export ..."));
761 dt_free(m_arg);
764 exit(1);
765 }
766
767 // and now for the really ugly hacks. don't tell your children about this one or they won't sleep at night
768 // any longer ...
770 // all is good now, the last line didn't happen.
772
774 if(IS_NULL_PTR(format))
775 {
776 fprintf(stderr, _("unknown extension '.%s'"), output_ext);
777 fprintf(stderr, "\n");
778 dt_free(m_arg);
780 exit(1);
781 }
782
783 fdata = format->get_params(format);
784 if(IS_NULL_PTR(fdata))
785 {
786 fprintf(stderr, "%s\n", _("failed to get parameters from format module, aborting export ..."));
787 dt_free(m_arg);
789 exit(1);
790 }
791
792 uint32_t w, h, fw, fh, sw, sh;
793 fw = fh = sw = sh = 0;
794 storage->dimension(storage, sdata, &sw, &sh);
795 format->dimension(format, fdata, &fw, &fh);
796
797 if(sw == 0 || fw == 0)
798 w = sw > fw ? sw : fw;
799 else
800 w = sw < fw ? sw : fw;
801
802 if(sh == 0 || fh == 0)
803 h = sh > fh ? sh : fh;
804 else
805 h = sh < fh ? sh : fh;
806
807 fdata->max_width = width;
808 fdata->max_height = height;
809 fdata->max_width = (w != 0 && fdata->max_width > w) ? w : fdata->max_width;
810 fdata->max_height = (h != 0 && fdata->max_height > h) ? h : fdata->max_height;
811 fdata->style[0] = '\0';
812
813 if(style)
814 {
815 g_strlcpy((char *)fdata->style, style, DT_MAX_STYLE_NAME_LENGTH);
816 fdata->style[127] = '\0';
817 }
818
819 if(storage->initialize_store)
820 {
821 storage->initialize_store(storage, sdata, &format, &fdata, &id_list, TRUE);
822
823 format->set_params(format, fdata, format->params_size(format));
824 storage->set_params(storage, sdata, storage->params_size(storage));
825 }
826
827 // TODO: add a callback to set the bpp without going through the config
828
829 int num = 1, res = 0;
830 for(GList *iter = id_list; iter; iter = g_list_next(iter), num++)
831 {
832 const int id = GPOINTER_TO_INT(iter->data);
833 // TODO: have a parameter in command line to get the export presets
834 dt_export_metadata_t metadata;
836 metadata.list = NULL;
837 // the size is the command line's: no scale factor, whatever the GUI's export module is set to
838 if(storage->store(storage, sdata, id, format, fdata, 0.0, num, total, TRUE, export_masks,
839 icc_type, icc_filename, icc_intent, &metadata) != 0)
840 res = 1;
841 }
842
843 // cleanup time
844 if(storage->finalize_store) storage->finalize_store(storage, sdata);
845 storage->free_params(storage, sdata);
846 format->free_params(format, fdata);
848 id_list = NULL;
850
851 if(icc_filename)
852 {
853 dt_free(icc_filename);
854 }
855
856 dt_cleanup();
857
858 dt_free(m_arg);
859 exit(res);
860}
861
862// clang-format off
863// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
864// vim: shiftwidth=2 expandtab tabstop=2 cindent
865// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
866// 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:1864
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data)
Definition darktable.c:885
gchar * directory
documentation root given after –doc, or NULL
const int res
Definition dtpthread.h:351
void dt_loc_resolve_localedir(char *localedir, size_t bufsize)
Resolve the locale directory the way dt_loc_init() does, creating it if missing, but set no global an...
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:398
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:92
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:96
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
Definition mem_alloc.h:184
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
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_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
Definition paths.h:57
#define DT_MAX_PATH_FOR_PARAMS
Definition paths.h:65
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:401
#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,...