Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
darktable.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2012 johannes hanika.
4 Copyright (C) 2010-2011 Henrik Andersson.
5 Copyright (C) 2010, 2012 Pascal de Bruijn.
6 Copyright (C) 2010 Richard Hughes.
7 Copyright (C) 2010-2020 Tobias Ellinghaus.
8 Copyright (C) 2011, 2014-2015 Bruce Guenter.
9 Copyright (C) 2011-2013, 2017 Ulrich Pegelow.
10 Copyright (C) 2012 Ammon Riley.
11 Copyright (C) 2012 Christian Himpel.
12 Copyright (C) 2012 Christian Tellefsen.
13 Copyright (C) 2012 James C. McPherson.
14 Copyright (C) 2012 Jean-Sébastien Pédron.
15 Copyright (C) 2012-2014 Jérémy Rosen.
16 Copyright (C) 2012 Moritz Lipp.
17 Copyright (C) 2012 Richard Wonka.
18 Copyright (C) 2012 Simon Spannagel.
19 Copyright (C) 2013, 2021 Aldric Renaudin.
20 Copyright (C) 2013, 2015, 2019-2021 Pascal Obry.
21 Copyright (C) 2013-2017 Roman Lebedev.
22 Copyright (C) 2014-2015 Pedro Côrte-Real.
23 Copyright (C) 2015 Matthias Gehre.
24 Copyright (C) 2016-2019 Peter Budai.
25 Copyright (C) 2016 Stuart Henderson.
26 Copyright (C) 2018-2020, 2022-2026 Aurélien PIERRE.
27 Copyright (C) 2018-2019 Edgardo Hoszowski.
28 Copyright (C) 2018 parafin.
29 Copyright (C) 2018 rawfiner.
30 Copyright (C) 2019-2020 Andreas Schneider.
31 Copyright (C) 2019-2022 Hanno Schwalm.
32 Copyright (C) 2019 Heiko Bauke.
33 Copyright (C) 2020 David-Tillmann Schaefer.
34 Copyright (C) 2020-2021 Diederik Ter Rahe.
35 Copyright (C) 2020-2021 Hubert Kowalski.
36 Copyright (C) 2020-2021 Ralf Brown.
37 Copyright (C) 2021 Hubert Figuière.
38 Copyright (C) 2021 Paolo DePetrillo.
39 Copyright (C) 2021 Robert Bridge.
40 Copyright (C) 2021 Roman Khatko.
41 Copyright (C) 2022 Martin Bařinka.
42 Copyright (C) 2022 Philippe Weyland.
43 Copyright (C) 2023-2025 Alynx Zhou.
44 Copyright (C) 2023 lologor.
45 Copyright (C) 2023 Luca Zulberti.
46
47 darktable is free software: you can redistribute it and/or modify
48 it under the terms of the GNU General Public License as published by
49 the Free Software Foundation, either version 3 of the License, or
50 (at your option) any later version.
51
52 darktable is distributed in the hope that it will be useful,
53 but WITHOUT ANY WARRANTY; without even the implied warranty of
54 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55 GNU General Public License for more details.
56
57 You should have received a copy of the GNU General Public License
58 along with darktable. If not, see <http://www.gnu.org/licenses/>.
59*/
60
61#pragma once
62
63
64// just to be sure. the build system should set this for us already:
65#if defined __DragonFly__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
66#define _WITH_DPRINTF
67#define _WITH_GETLINE
68#elif !defined _XOPEN_SOURCE && !defined _WIN32
69#define _XOPEN_SOURCE 700 // for localtime_r and dprintf
70#endif
71
72// needs to be defined before any system header includes for control/conf.h to work in C++ code
73#define __STDC_FORMAT_MACROS
74
75#if !defined(O_BINARY)
76// To have portable g_open() on *nix and on Windows
77#define O_BINARY 0
78#endif
79
80#include "external/ThreadSafetyAnalysis.h"
81
82#ifdef HAVE_CONFIG_H
83#include "config.h"
84#endif
85#include "common/database.h"
86#include "common/fp_mode.h"
87#include "common/dtpthread.h"
88#include "common/utility.h"
89#ifdef _WIN32
90#include "win/getrusage.h"
91#else
92#include <sys/resource.h>
93#endif
94#include <stdint.h>
95#include <glib.h>
96#include <glib/gstdio.h>
97#include <glib/gi18n.h>
98#include <inttypes.h>
99#include <json-glib/json-glib.h>
100#include <math.h>
101#include <sqlite3.h>
102#include <stdio.h>
103#include <sys/time.h>
104#include <sys/types.h>
105#include <unistd.h>
106
107#ifndef _RELEASE
108#include "common/poison.h"
109#endif
110
112
113// for signal debugging symbols
114#include "control/signal.h"
115
116#ifdef __cplusplus
117extern "C" {
118#endif
119
120#define DT_MODULE_VERSION 23 // version of dt's module interface
121
122// version of current performance configuration version
123// if you want to run an updated version of the performance configuration later
124// bump this number and make sure you have an updated logic in dt_configure_performance()
125#define DT_CURRENT_PERFORMANCE_CONFIGURE_VERSION 11
126#define DT_PERF_INFOSIZE 4096
127
128// every module has to define this:
129#ifdef _DEBUG
130#define DT_MODULE(MODVER) \
131 int dt_module_dt_version() \
132 { \
133 return -DT_MODULE_VERSION; \
134 } \
135 int dt_module_mod_version() \
136 { \
137 return MODVER; \
138 }
139#else
140#define DT_MODULE(MODVER) \
141 int dt_module_dt_version() \
142 { \
143 return DT_MODULE_VERSION; \
144 } \
145 int dt_module_mod_version() \
146 { \
147 return MODVER; \
148 }
149#endif
150
151#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE) DT_MODULE(MODVER)
152
153// ..to be able to compare it against this:
154static inline int dt_version()
155{
156#ifdef _DEBUG
157 return -DT_MODULE_VERSION;
158#else
159 return DT_MODULE_VERSION;
160#endif
161}
162
163// returns the darktable version as <major>.<minor>
165
166#undef STR_HELPER
167#define STR_HELPER(x) #x
168
169#undef STR
170#define STR(x) STR_HELPER(x)
171
172#define DT_IMAGE_DBLOCKS 64
173
174// When included by a C++ file, restrict qualifiers are not allowed
175#ifdef __cplusplus
176#define DT_RESTRICT
177#else
178#define DT_RESTRICT restrict
179#endif
180
181// Default code for imgid meaning the picture is unknown or invalid
182#define UNKNOWN_IMAGE -1
183
184#ifdef __cplusplus
185}
186#endif
187
188/********************************* */
189
196#if defined _WIN32
197#include "win/win.h"
198#endif
199
200#ifdef __APPLE__
201#include <mach/mach.h>
202#include <sys/sysctl.h>
203#endif
204
205#if defined(__DragonFly__) || defined(__FreeBSD__)
206typedef unsigned int u_int;
207#include <sys/sysctl.h>
208#include <sys/types.h>
209#endif
210#if defined(__NetBSD__) || defined(__OpenBSD__)
211#include <sys/param.h>
212#include <sys/sysctl.h>
213#endif
214
215#if defined(__aarch64__)
216#include <arm_neon.h>
217#endif
218
219#if defined(__x86_64__) || defined(__i386__)
220#include <xmmintrin.h> // needed for _mm_stream_ps
221#endif
222
223#ifdef _OPENMP
224# include <omp.h>
225
226#ifndef dt_omp_nontemporal
227// Clang 10+ supports the nontemporal() OpenMP directive
228// GCC 9 recognizes it as valid, but does not do anything with it
229// GCC 10+ ???
230#if (__clang__+0 >= 10 || __GNUC__ >= 9)
231# define dt_omp_nontemporal(...) nontemporal(__VA_ARGS__)
232#else
233// GCC7/8 only support OpenMP 4.5, which does not have the nontemporal() directive.
234# define dt_omp_nontemporal(var, ...)
235#endif
236#endif /* dt_omp_nontemporal */
237
238#define OMP_PRAGMA(x) _Pragma(#x)
239#define __OMP_PARALLEL__(...) OMP_PRAGMA(omp parallel default(firstprivate) __VA_ARGS__)
240#define __OMP_PARALLEL_FOR__(...) OMP_PRAGMA(omp parallel for default(firstprivate) schedule(static) __VA_ARGS__)
241#define __OMP_PARALLEL_FOR_SIMD__(...) OMP_PRAGMA(omp parallel for simd default(firstprivate) schedule(simd:static) __VA_ARGS__)
242#define __OMP_FOR_SIMD__(...) OMP_PRAGMA(omp for simd schedule(simd:static) __VA_ARGS__)
243#define __OMP_FOR__(...) OMP_PRAGMA(omp for schedule(static) __VA_ARGS__)
244#define __OMP_SIMD__(...) OMP_PRAGMA(omp simd __VA_ARGS__)
245#define __OMP_DECLARE_SIMD__(...) OMP_PRAGMA(omp declare simd __VA_ARGS__)
246
247// CLang 20 supports OpenMP 5.1 default(firstprivate) but only for C files.
248// C++ files still need to use default(none) until further notice.
249// Change that when baseline CLang is upgraded.
250#define __OMP_PARALLEL_FOR_CPP__(...) OMP_PRAGMA(omp parallel for default(none) schedule(static) __VA_ARGS__)
251
252#else /* _OPENMP */
253
254# define omp_get_max_threads() 1
255# define omp_get_thread_num() 0
256
257#define __OMP_PARALLEL__(...)
258#define __OMP_PARALLEL_FOR__(...)
259#define __OMP_PARALLEL_FOR_SIMD__(...)
260#define __OMP_FOR_SIMD__(...)
261#define __OMP_FOR__(...)
262#define __OMP_SIMD__(...)
263#define __OMP_DECLARE_SIMD__(...)
264
265#define __OMP_PARALLEL_FOR_CPP__(...)
266
267#endif /* _OPENMP */
268
269#ifdef __cplusplus
270extern "C" {
271#endif
272
281#define IS_NULL_PTR(p) \
282 ({ \
283 __typeof__(p) _tmp = (p); \
284 (void)sizeof(char[ \
285 (__builtin_classify_type(_tmp) == 5) ? 1 : -1 \
286 ]); \
287 _tmp == NULL; \
288 })
289
290
291static inline int dt_get_thread_num()
292{
293#ifdef _OPENMP
294 return omp_get_thread_num();
295#else
296 return 0;
297#endif
298}
299
300/* Create cloned functions for various CPU SSE generations */
301/* See for instructions https://hannes.hauswedell.net/post/2017/12/09/fmv/ */
302/* TL;DR : use only on SIMD functions containing low-level paralellized/vectorized loops */
303#if __has_attribute(target_clones) && !defined(_WIN32) && !defined(NATIVE_ARCH) && !defined(_DEBUG)
304
305 /*
306 * Apple note:
307 * - arm64 vs x86_64 is handled by the universal binary, not target_clones.
308 * - target_clones on Apple is only useful within one slice.
309 * - the x86-64-v2/v3/v4 strings are not accepted by all Apple Clang versions.
310 *
311 * Therefore:
312 * - on Apple arm64: disable clones here,
313 * - on Apple x86_64: require explicit opt-in once the toolchain is validated.
314 */
315
316 #if defined(__APPLE__)
317
318 #if defined(__aarch64__) || defined(__arm64__)
319 #define __DT_CLONE_TARGETS__
320
321 #elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
322
323 /*
324 * Enable this from your build system only after verifying that the local
325 * Apple Clang accepts:
326 * target_clones("default","arch=x86-64","arch=x86-64-v2","arch=x86-64-v3","arch=x86-64-v4")
327 *
328 * Example:
329 * -DDT_APPLE_X86_TARGET_CLONES=1
330 */
331 #if defined(DT_APPLE_X86_TARGET_CLONES)
332 #define __DT_CLONE_TARGETS__ \
333 __attribute__((target_clones( \
334 "default", \
335 "arch=x86-64", \
336 "arch=x86-64-v2", \
337 "arch=x86-64-v3", \
338 "arch=x86-64-v4" \
339 )))
340 #else
341 #define __DT_CLONE_TARGETS__
342 #endif
343
344 #else
345 #define __DT_CLONE_TARGETS__
346 #endif
347
348 #elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
349 #define __DT_CLONE_TARGETS__ \
350 __attribute__((target_clones( \
351 "default", \
352 "arch=x86-64", \
353 "arch=x86-64-v2", \
354 "arch=x86-64-v3", \
355 "arch=x86-64-v4" \
356 )))
357
358 #elif defined(__PPC64__)
359 /* __PPC64__ is the only macro tested for in is_supported_platform.h, other macros would fail there anyway. */
360 #define __DT_CLONE_TARGETS__ __attribute__((target_clones("default","cpu=power9")))
361
362 #else
363 #define __DT_CLONE_TARGETS__
364 #endif
365
366#else
367 #define __DT_CLONE_TARGETS__
368#endif
369
370/* Helper to force stack vectors to be aligned on DT_CACHELINE_BYTES blocks to enable AVX2 */
371#define DT_IS_ALIGNED(x) __builtin_assume_aligned(x, DT_CACHELINE_BYTES)
372
373// Configure the size of a CPU cacheline in bytes, floats, and pixels. On most current architectures,
374// a cacheline contains 64 bytes, but Apple Silicon (M-series processors) uses 128-byte cache lines.
375#if defined(__APPLE__) && defined(__aarch64__)
376 #define DT_CACHELINE_BYTES 128
377 #define DT_CACHELINE_FLOATS 32
378 #define DT_CACHELINE_PIXELS 8
379#else
380 #define DT_CACHELINE_BYTES 64
381 #define DT_CACHELINE_FLOATS 16
382 #define DT_CACHELINE_PIXELS 4
383#endif /* __APPLE__ && __aarch64__ */
384
385// Helper to force heap vectors to be aligned on 64 byte blocks to enable AVX2
386// If this is applied to a struct member and the struct is allocated on the heap, then it must be allocated
387// on a 64 byte boundary to avoid crashes or undefined behavior because of unaligned memory access.
388#define DT_ALIGNED_ARRAY __attribute__((aligned(DT_CACHELINE_BYTES)))
389#define DT_ALIGNED_PIXEL __attribute__((aligned(16)))
390
391
392static inline gboolean dt_is_aligned(const void *pointer, size_t byte_count)
393{
394 return (uintptr_t)pointer % byte_count == 0;
395}
396
397static inline size_t dt_round_size(const size_t size, const size_t alignment)
398{
399 // Round the size of a buffer to the closest higher multiple
400 return ((size % alignment) == 0) ? size : ((size - 1) / alignment + 1) * alignment;
401}
402
403static inline size_t dt_round_size_sse(const size_t size)
404{
405 // Round the size of a buffer to the closest 64 higher multiple
406 return dt_round_size(size, 64);
407}
408
409static inline void *dt_alloc_align_internal(size_t size)
410{
411 const size_t alignment = DT_CACHELINE_BYTES;
412 const size_t aligned_size = dt_round_size(size, alignment);
413#if defined(__FreeBSD_version) && __FreeBSD_version < 700013
414 return malloc(aligned_size);
415#elif defined(_WIN32)
416 return _aligned_malloc(aligned_size, alignment);
417#else
418 void *ptr = NULL;
419 if(posix_memalign(&ptr, alignment, aligned_size)) return NULL;
420 return ptr;
421#endif
422}
423
424void *dt_alloc_align(size_t size);
425
427
428#define DT_STRINGIFY_HELPER(x) #x
429#define DT_STRINGIFY(x) DT_STRINGIFY_HELPER(x)
430
432 const char *name);
433#define dt_pixelpipe_cache_alloc_align_cache(size, id) \
434 dt_pixelpipe_cache_alloc_align_cache_impl(darktable.pixelpipe_cache, (size), (id), __FILE__ ":" DT_STRINGIFY(__LINE__))
435
436#ifndef dt_pixelpipe_cache_alloc_align
437#define dt_pixelpipe_cache_alloc_align(size, pipe) \
438 dt_pixelpipe_cache_alloc_align_cache((size), (pipe)->type)
439#endif
440
441#ifndef dt_pixelpipe_cache_alloc_align_float
442#define dt_pixelpipe_cache_alloc_align_float(pixels, pipe) \
443 ((float *)dt_pixelpipe_cache_alloc_align((size_t)(pixels) * sizeof(float), (pipe)))
444#endif
445
446#ifndef dt_pixelpipe_cache_alloc_align_float_cache
447#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id) \
448 ((float *)dt_pixelpipe_cache_alloc_align_cache((size_t)(pixels) * sizeof(float), (id)))
449#endif
450
451void dt_pixelpipe_cache_free_align_cache(struct dt_dev_pixelpipe_cache_t *cache, void **mem, const char *message);
452
453#define dt_pixelpipe_cache_free_align(mem) \
454 dt_pixelpipe_cache_free_align_cache(darktable.pixelpipe_cache, (void **)&(mem), __FILE__ ":" DT_STRINGIFY(__LINE__));
455
456#define dt_free(ptr) \
457 if(!IS_NULL_PTR(ptr)) \
458 { \
459 g_free((void *)(ptr)); \
460 *(void **)(&(ptr)) = NULL; \
461 }
462
463static inline void dt_free_gpointer(gpointer ptr)
464{
465 g_free(ptr);
466 ptr = NULL;
467}
468
469#ifdef _WIN32
470 static inline void dt_free_align_ptr(void *mem)
471 {
472 _aligned_free(mem);
473 }
474#else
475 static inline void dt_free_align_ptr(void *mem)
476 {
477 dt_free(mem);
478 }
479#endif
480
481#define dt_free_align(ptr) \
482 if(!IS_NULL_PTR(ptr)) \
483 { \
484 dt_free_align_ptr((void *)(ptr)); \
485 *(void **)(&(ptr)) = NULL; \
486 }
487
488static inline void* dt_calloc_align(size_t size)
489{
490 void *buf = dt_alloc_align(size);
491 if(buf) memset(buf, 0, size);
492 return buf;
493}
494static inline float *dt_alloc_align_float(size_t pixels)
495{
496 return (float*)__builtin_assume_aligned(dt_alloc_align(pixels * sizeof(float)), DT_CACHELINE_BYTES);
497}
498static inline float *dt_calloc_align_float(size_t pixels)
499{
500 float *const buf = (float*)dt_alloc_align(pixels * sizeof(float));
501 if(buf) memset(buf, 0, pixels * sizeof(float));
502 return (float*)__builtin_assume_aligned(buf, DT_CACHELINE_BYTES);
503}
504static inline void * dt_check_sse_aligned(void * pointer)
505{
507 return __builtin_assume_aligned(pointer, DT_CACHELINE_BYTES);
508 else
509 return NULL;
510}
511
512// Most code in dt assumes that the compiler is capable of auto-vectorization. In some cases, this will yield
513// suboptimal code if the compiler in fact does NOT auto-vectorize. Uncomment the following line for such a
514// compiler.
515//#define DT_NO_VECTORIZATION
516
517// For some combinations of compiler and architecture, the compiler may actually emit inferior code if given
518// a hint to vectorize a loop. Uncomment the following line if such a combination is the compilation target.
519//#define DT_NO_SIMD_HINTS
520
521// utility type to ease declaration of aligned small arrays to hold a pixel (and document their purpose)
523// SIMD view matching dt_aligned_pixel_t layout, for explicit 4-float vector math.
524typedef float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)));
525
526static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t dt_simd_set1(const float value)
527{
528 return (dt_aligned_pixel_simd_t){ value, value, value, value };
529}
530
531static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
532dt_simd_abs(const dt_aligned_pixel_simd_t value)
533{
534 dt_aligned_pixel_simd_t out = value;
535 for(int c = 0; c < 4; c++)
536 out[c] = fabsf(value[c]);
537 return out;
538}
539
540static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
541dt_simd_max_zero(const dt_aligned_pixel_simd_t value)
542{
543 dt_aligned_pixel_simd_t out = value;
544 for(int c = 0; c < 4; c++)
545 out[c] = (isfinite(value[c])) ? MAX(value[c], 0.0f) : 0.f;
546 return out;
547}
548
549static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
550dt_simd_copysign(const dt_aligned_pixel_simd_t magnitude, const dt_aligned_pixel_simd_t sign)
551{
552 dt_aligned_pixel_simd_t out = magnitude;
553 for(int c = 0; c < 4; c++)
554 out[c] = copysignf(magnitude[c], sign[c]);
555 return out;
556}
557
558static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
559dt_simd_pow(const dt_aligned_pixel_simd_t base, const dt_aligned_pixel_simd_t exponent)
560{
561 dt_aligned_pixel_simd_t out = base;
562 for(int c = 0; c < 4; c++)
563 out[c] = powf(base[c], exponent[c]);
564 return out;
565}
566
567static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
568dt_load_simd(const float *const pixel)
569{
570 dt_aligned_pixel_simd_t out;
571 __builtin_memcpy(&out, pixel, sizeof(out));
572 return out;
573}
574
575static inline __attribute__((always_inline)) void
576dt_store_simd(float *const pixel, const dt_aligned_pixel_simd_t value)
577{
578 __builtin_memcpy(pixel, &value, sizeof(value));
579}
580
581static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
582dt_load_simd_aligned(const float *const pixel)
583{
584 const float *const in = (const float *const)__builtin_assume_aligned(pixel, 16);
585 return dt_load_simd(in);
586}
587
588static inline __attribute__((always_inline)) void
589dt_store_simd_aligned(float *const pixel, const dt_aligned_pixel_simd_t value)
590{
591 float *const out = (float *const)__builtin_assume_aligned(pixel, 16);
593}
594
595static inline __attribute__((always_inline)) void
596dt_store_simd_nontemporal(float *const pixel, const dt_aligned_pixel_simd_t value)
597{
598 float *const out = (float *const)__builtin_assume_aligned(pixel, 16);
599
600#if defined(__x86_64__) || defined(__i386__)
601 const union
602 {
603 dt_aligned_pixel_simd_t simd;
604 __m128 sse;
605 } cast = { .simd = value };
606 _mm_stream_ps(out, cast.sse);
607#elif defined(__aarch64__)
608 const union
609 {
610 dt_aligned_pixel_simd_t simd;
611 float32x4_t neon;
612 } cast = { .simd = value };
613 vst1q_f32(out, cast.neon);
614#elif (__clang__+0 > 7) && (__clang__+0 < 10)
615 for_each_channel(k,aligned(out:16)) __builtin_nontemporal_store(value[k], out[k]);
616#else
617 for_each_channel(k,aligned(out:16) dt_omp_nontemporal(out)) out[k] = value[k];
618#endif
619}
620
621static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t
622dt_mat3x4_mul_vec4(const dt_aligned_pixel_simd_t in, const dt_aligned_pixel_simd_t row0,
623 const dt_aligned_pixel_simd_t row1, const dt_aligned_pixel_simd_t row2)
624{
625 // Keep the multiply first in each accumulation step so GCC contracts this
626 // into chained FMA instructions in the multiversioned FMA clones too.
627 dt_aligned_pixel_simd_t out = row0 * in[0];
628 out = row1 * in[1] + out;
629 return row2 * in[2] + out;
630}
631
632// To be able to vectorize per-pixel loops, we need to operate on all four channels, but if the compiler does
633// not auto-vectorize, doing so increases computation by 1/3 for a channel which typically is ignored anyway.
634// Select the appropriate number of channels over which to loop to produce the fastest code.
635#ifdef DT_NO_VECTORIZATION
636#define DT_PIXEL_SIMD_CHANNELS 3
637#else
638#define DT_PIXEL_SIMD_CHANNELS 4
639#endif
640
641// A macro which gives us a configurable shorthand to produce the optimal performance when processing all of the
642// channels in a pixel. Its first argument is the name of the variable to be used inside the 'for' loop it creates,
643// while the optional second argument is a set of OpenMP directives, typically specifying variable alignment.
644// If indexing off of the begining of any buffer allocated with dt's image or aligned allocation functions, the
645// alignment to specify is 64; otherwise, use 16, as there may have been an odd number of pixels from the start.
646// Sample usage:
647// for_each_channel(k,aligned(src,dest:16))
648// {
649// src[k] = dest[k] / 3.0f;
650// }
651#if defined(_OPENMP) && defined(OPENMP_SIMD_) && !defined(DT_NO_SIMD_HINTS)
652//https://stackoverflow.com/questions/45762357/how-to-concatenate-strings-in-the-arguments-of-pragma
653#define _DT_Pragma_(x) _Pragma(#x)
654#define _DT_Pragma(x) _DT_Pragma_(x)
655#define for_each_channel(_var, ...) \
656 _DT_Pragma(omp simd __VA_ARGS__) \
657 for (size_t _var = 0; _var < DT_PIXEL_SIMD_CHANNELS; _var++)
658#define for_four_channels(_var, ...) \
659 _DT_Pragma(omp simd __VA_ARGS__) \
660 for (size_t _var = 0; _var < 4; _var++)
661#else
662#define for_each_channel(_var, ...) \
663 for (size_t _var = 0; _var < DT_PIXEL_SIMD_CHANNELS; _var++)
664#define for_four_channels(_var, ...) \
665 for (size_t _var = 0; _var < 4; _var++)
666#endif
667
668
669// copy the RGB channels of a pixel using nontemporal stores if
670// possible; includes the 'alpha' channel as well if faster due to
671// vectorization, but subsequent code should ignore the value of the
672// alpha unless explicitly set afterwards (since it might not have
673// been copied). NOTE: nontemporal stores will actually be *slower*
674// if we immediately access the pixel again. This function should
675// only be used when processing an entire image before doing anything
676// else with the destination buffer.
677static inline void copy_pixel_nontemporal(
678 float *const __restrict__ out,
679 const float *const __restrict__ in)
680{
681 dt_store_simd_nontemporal(out, dt_load_simd(in));
682}
683
684
685// copy the RGB channels of a pixel; includes the 'alpha' channel as well if faster due to vectorization, but
686// subsequent code should ignore the value of the alpha unless explicitly set afterwards (since it might not have
687// been copied)
688static inline void copy_pixel(float *const __restrict__ out, const float *const __restrict__ in)
689{
690 for_each_channel(k,aligned(in,out:16)) out[k] = in[k];
691}
692
693/********************************* */
694
695struct dt_gui_gtk_t;
696struct dt_control_t;
697struct dt_develop_t;
698struct dt_mipmap_cache_t;
699struct dt_image_cache_t;
700struct dt_lib_t;
701struct dt_conf_t;
702struct dt_points_t;
703struct dt_imageio_t;
704struct dt_bauhaus_t;
705struct dt_undo_t;
706struct dt_colorspaces_t;
707struct dt_l10n_t;
708
709typedef float dt_boundingbox_t[4]; //(x,y) of upperleft, then (x,y) of lowerright
710
712{
713 DT_DEBUG_ALWAYS = 0, // always print regardless of debug flags
714 // powers of two, masking
717 DT_DEBUG_DEV = 1 << 2,
718 DT_DEBUG_GTK = 1 << 3,
723 DT_DEBUG_SQL = 1 << 8,
726 DT_DEBUG_NAN = 1 << 11,
727 DT_DEBUG_MASKS = 1 << 12,
728 DT_DEBUG_LUA = 1 << 13,
729 DT_DEBUG_INPUT = 1 << 14,
730 DT_DEBUG_PRINT = 1 << 15,
734 DT_DEBUG_UNDO = 1 << 19,
741 DT_DEBUG_PIPE = 1 << 26,
747
748typedef struct dt_sys_resources_t
749{
750 size_t total_memory; // All RAM on system
751 size_t mipmap_memory; // RAM allocated to mipmap cache
752 size_t headroom_memory; // RAM left to OS & other Apps
753 size_t pixelpipe_memory; // RAM used by the pixelpipe cache (approx.)
755
756typedef struct darktable_t
757{
759
760 int32_t unmuted;
761 GList *iop;
764
765 // Keep track of optional features that may depend on environnement
766 // ond compiling options : OpenCL, libsecret, kwallet
771 struct dt_lib_t *lib;
779 const struct dt_database_t *db;
791
792 // Protects from concurrent writing at export time
793 dt_pthread_mutex_t plugin_threadsafe;
794
795 // Protect appending/removing GList links to the darktable.capabilities list
796 dt_pthread_mutex_t capabilities_threadsafe;
797
798 // Exiv2 readMetadata() was not thread-safe prior to 0.27
799 // FIXME: Is it now ?
800 dt_pthread_mutex_t exiv2_threadsafe;
801
802 // RawSpeed readFile() method is apparently not thread-safe
803 dt_pthread_mutex_t readFile_mutex;
804
805 // Prevent concurrent export/thumbnail pipelines from runnnig at the same time
806 // It brings no additional performance since the CPU is our bottleneck,
807 // and CPU pixel code is already multi-threaded internally through OpenMP
808 dt_pthread_mutex_t pipeline_threadsafe;
809
810 // Building SQL transactions through `dt_database_start_transaction_debug()`
811 // from "too many" threads (like loading all thumbnails from a new collection)
812 // leads to SQL error:
813 // `BEGIN": cannot start a transaction within a transaction`
814 // Also, we need to ensure that image metadata/history reads & writes
815 // happen each in their all time, from all pipeline jobs/threads.
817
818 char *progname;
819 char *datadir;
820 char *sharedir;
823 char *tmpdir;
825 char *cachedir;
827 GList *guides;
829 GList *themes;
832 GTimeZone *utc_tz;
833 GDateTime *origin_gdt;
835
836 // Working message displayed over the main preview when working
839
840typedef struct
841{
842 double clock;
843 double user;
844} dt_times_t;
845
847
848int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data);
849void dt_cleanup();
850void dt_print(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
851/* same as above but without time stamp : nts = no time stamp */
852void dt_print_nts(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
853/* same as above but requires additional DT_DEBUG_VERBOSE flag to be true */
854void dt_vprint(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
855
856// Number of workers, on top of reserved workers (1 for main preview, 1 for thumbnail in darkroom)
857// This is currently set to 2, so 4 workers total, without user config.
858// Workers will process a queue of jobs that they share together (except for reserved ones).
859// It is useless to use more than 2 workers
860// since those jobs very often lock some mutex that prevents concurrent running.
861// All jobs finding an idle worker will "start" immediately, as far as the OS knows from outside the program,
862// but may do nothing internally except for waiting a mutex locked by another worker/thread.
863// In that situation, we loose the ability to flush the queue, since jobs are "running".
864// So it's better to have few workers with long queues, rather
865// than many workers, to be able to control queued jobs.
867
868// Get the remaining memory available for pipeline allocations,
869// once we subtracted caches memory and headroom from system memory
870size_t dt_get_available_mem();
871
872// Get the maximum size for the whole mipmap cache
873size_t dt_get_mipmap_mem();
874
881static inline void memset_zero(void *const buffer, size_t size)
882{
883 // Same as memset_s in C11. memset might be optimized away by compilers, this will not.
884 // Not parallelized or vectorized since it's applied only on "small" tiles.
885 for(size_t k = 0; k < size / sizeof(unsigned char); k++) {
886 unsigned char *const item = (unsigned char *const)buffer + k;
887 *item = 0;
888 }
889}
890
891// check whether the specified mask of modifier keys exactly matches, among the set Shift+Control+(Alt/Meta).
892// ignores the state of any other shifting keys
893static inline gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
894{
895 const GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
896//TODO: on Macs, remap the GDK_CONTROL_MASK bit in desired_modifier_mask to be the bit for the Cmd key
897 return (state & modifiers) == desired_modifier_mask;
898}
899
900// check whether the given modifier state includes AT LEAST the specified mask of modifier keys
901static inline gboolean dt_modifiers_include(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
902{
903//TODO: on Macs, remap the GDK_CONTROL_MASK bit in desired_modifier_mask to be the bit for the Cmd key
904 const GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
905 // check whether all modifier bits of interest are turned on
906 return (state & (modifiers & desired_modifier_mask)) == desired_modifier_mask;
907}
908
909int dt_capabilities_check(char *capability);
910void dt_capabilities_add(char *capability);
911void dt_capabilities_remove(char *capability);
913
914static inline double dt_get_wtime(void)
915{
916 struct timeval time;
917 gettimeofday(&time, NULL);
918 return time.tv_sec - 1290608000 + (1.0 / 1000000.0) * time.tv_usec;
919}
920
921static inline void dt_get_times(dt_times_t *t)
922{
923 struct rusage ru;
924
926 t->clock = dt_get_wtime();
927 t->user = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec * (1.0 / 1000000.0);
928}
929
930void dt_show_times(const dt_times_t *start, const char *prefix);
931
932void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix, ...) __attribute__((format(printf, 3, 4)));
933
935gboolean dt_supported_image(const gchar *filename);
936
937// a few macros and helper functions to speed up certain frequently-used GLib operations
938#define g_list_is_singleton(list) ((list) && (!(list)->next))
939static inline gboolean g_list_shorter_than(const GList *list, unsigned len)
940{
941 // instead of scanning the full list to compute its length and then comparing against the limit,
942 // bail out as soon as the limit is reached. Usage: g_list_shorter_than(l,4) instead of g_list_length(l)<4
943 while (len-- > 0)
944 {
945 if (!list) return TRUE;
946 list = g_list_next(list);
947 }
948 return FALSE;
949}
950
951// advance the list by one position, unless already at the final node
952static inline GList *g_list_next_bounded(GList *list)
953{
954 return g_list_next(list) ? g_list_next(list) : list;
955}
956
957static inline const GList *g_list_next_wraparound(const GList *list, const GList *head)
958{
959 return g_list_next(list) ? g_list_next(list) : head;
960}
961
962static inline const GList *g_list_prev_wraparound(const GList *list)
963{
964 // return the prior element of the list, unless already on the first element; in that case, return the last
965 // element of the list.
966 return g_list_previous(list) ? g_list_previous(list) : g_list_last((GList*)list);
967}
968
969void dt_print_mem_usage();
970
971void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui);
972
973// helper function which loads whatever image_to_load points to: single image files or whole directories
974// it tells you if it was a single image or a directory in single_image (when it's not NULL)
975int dt_load_from_string(const gchar *image_to_load, gboolean open_image_in_dr, gboolean *single_image);
976
977#define dt_unreachable_codepath_with_desc(D) \
978 dt_unreachable_codepath_with_caller(D, __FILE__, __LINE__, __FUNCTION__)
979#define dt_unreachable_codepath() dt_unreachable_codepath_with_caller("unreachable", __FILE__, __LINE__, __FUNCTION__)
980static inline void dt_unreachable_codepath_with_caller(const char *description, const char *file,
981 const int line, const char *function)
982{
983 fprintf(stderr, "[dt_unreachable_codepath] {%s} %s:%d (%s) - we should not be here. please report this to "
984 "the developers.",
985 description, file, line, function);
986 __builtin_unreachable();
987}
988
989// Allocate a buffer for 'n' objects each of size 'objsize' bytes for each of the program's threads.
990// Ensures that there is no false sharing among threads by aligning and rounding up the allocation to
991// a multiple of the cache line size. Returns a pointer to the allocated pool and the adjusted number
992// of objects in each thread's buffer. Use dt_get_perthread or dt_get_bythread (see below) to access
993// a specific thread's buffer.
994static inline void *dt_pixelpipe_cache_alloc_perthread_impl(const size_t n, const size_t objsize, size_t* padded_size, const char *message)
995{
996 const size_t alloc_size = n * objsize;
997 const size_t cache_lines = (alloc_size + DT_CACHELINE_BYTES - 1) / DT_CACHELINE_BYTES;
998 *padded_size = DT_CACHELINE_BYTES * cache_lines / objsize;
999 const size_t total_bytes = DT_CACHELINE_BYTES * cache_lines * darktable.num_openmp_threads;
1000 void *buf = dt_pixelpipe_cache_alloc_align_cache_impl(darktable.pixelpipe_cache, total_bytes, 0, message);
1001 if(IS_NULL_PTR(buf)) return NULL;
1002 return __builtin_assume_aligned(buf, DT_CACHELINE_BYTES);
1003}
1004
1005#ifndef dt_pixelpipe_cache_alloc_perthread
1006#define dt_pixelpipe_cache_alloc_perthread(n, objsize, padded_size) \
1007 ((void *)dt_pixelpipe_cache_alloc_perthread_impl((n), (objsize), (padded_size), __FILE__ ":" DT_STRINGIFY(__LINE__)))
1008#endif
1009
1010static inline void *dt_pixelpipe_cache_calloc_perthread_impl(const size_t n, const size_t objsize, size_t* padded_size, const char *message)
1011{
1012 void *const buf = (float*)dt_pixelpipe_cache_alloc_perthread_impl(n, objsize, padded_size, message);
1013 if(IS_NULL_PTR(buf)) return NULL;
1014 memset(buf, 0, *padded_size * darktable.num_openmp_threads * objsize);
1015 return buf;
1016}
1017
1018#ifndef dt_pixelpipe_cache_calloc_perthread
1019#define dt_pixelpipe_cache_calloc_perthread(n, objsize, padded_size) \
1020 ((void *)dt_pixelpipe_cache_calloc_perthread_impl((n), (objsize), (padded_size), __FILE__ ":" DT_STRINGIFY(__LINE__)))
1021#endif
1022
1023// Same as dt_pixelpipe_cache_alloc_perthread, but the object is a float.
1024static inline float *dt_pixelpipe_cache_alloc_perthread_float_impl(const size_t n, size_t* padded_size, const char *message)
1025{
1026 return (float*)dt_pixelpipe_cache_alloc_perthread_impl(n, sizeof(float), padded_size, message);
1027}
1028
1029#ifndef dt_pixelpipe_cache_alloc_perthread_float
1030#define dt_pixelpipe_cache_alloc_perthread_float(n, padded_size) \
1031 ((float *)dt_pixelpipe_cache_alloc_perthread_float_impl((n), (padded_size), __FILE__ ":" DT_STRINGIFY(__LINE__)))
1032#endif
1033
1034// Given the buffer and object count returned by dt_pixelpipe_cache_alloc_perthread, return the current thread's private buffer.
1035#define dt_get_perthread(buf, padsize) DT_IS_ALIGNED((buf) + ((padsize) * dt_get_thread_num()))
1036// Given the buffer and object count returned by dt_pixelpipe_cache_alloc_perthread and a thread count in 0..darktable.num_openmp_threads,
1037// return a pointer to the indicated thread's private buffer.
1038#define dt_get_bythread(buf, padsize, tnum) DT_IS_ALIGNED((buf) + ((padsize) * (tnum)))
1039
1040// Scramble bits in str to create an (hopefully) unique hash representing the state of str
1041// Dan Bernstein algo v2 http://www.cse.yorku.ca/~oz/hash.html
1042// hash should be inited to 5381 if first run, or from a previous hash computed with this function.
1043static inline uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
1044{
1045 for(size_t i = 0; i < size; i++)
1046 hash = ((hash << 5) + hash) ^ str[i];
1047
1048 return hash;
1049}
1050
1052#define DT_MAX_FILENAME_LEN 256
1053
1054#ifndef PATH_MAX
1055/*
1056 * from /usr/include/linux/limits.h (Linux 3.16.5)
1057 * Some systems might not define it (e.g. Hurd)
1058 *
1059 * We do NOT depend on any specific value of this env variable.
1060 * If you want constant value across all systems, use DT_MAX_PATH_FOR_PARAMS!
1061 */
1062#define PATH_MAX 4096
1063#endif
1064
1065/*
1066 * ONLY TO BE USED FOR PARAMS!!! (e.g. dt_imageio_disk_t)
1067 *
1068 * WARNING: this should *NEVER* be changed, as it will break params,
1069 * created with previous DT_MAX_PATH_FOR_PARAMS.
1070 */
1071#define DT_MAX_PATH_FOR_PARAMS 4096
1072
1073static inline gchar *dt_string_replace(const char *string, const char *to_replace)
1074{
1075 if(IS_NULL_PTR(string) || IS_NULL_PTR(to_replace)) return NULL;
1076 gchar **split = g_strsplit(string, to_replace, -1);
1077 gchar *text = g_strjoinv("", split);
1078 g_strfreev(split);
1079 return text;
1080}
1081
1082// Remove underscore from GUI labels containing mnemonics
1083static inline gchar *delete_underscore(const char *s)
1084{
1085 return dt_string_replace(s, "_");
1086}
1087
1095static inline gchar *strip_markup(const char *s)
1096{
1097 if(IS_NULL_PTR(s)) return g_strdup("");
1098
1099 PangoAttrList *attrs = NULL;
1100 gchar *plain = NULL;
1101
1102 const gchar *underscore = "_";
1103 gunichar mnemonic = underscore[0];
1104 if(!pango_parse_markup(s, -1, mnemonic, &attrs, &plain, NULL, NULL))
1105 plain = delete_underscore(s);
1106
1107 pango_attr_list_unref(attrs);
1108 return plain;
1109}
1110
1119void dt_concat_path_file(char destination[PATH_MAX], const char path[PATH_MAX], const char *const file);
1120
1121#ifdef __cplusplus
1122}
1123#endif
1124
1125// clang-format off
1126// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
1127// vim: shiftwidth=2 expandtab tabstop=2 cindent
1128// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
1129// clang-format on
const char ** description(struct dt_iop_module_t *self)
Definition ashift.c:160
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
return vector dt_simd_set1(valid ?(scaling+NORM_MIN) :NORM_MIN)
dt_store_simd_aligned(out, dt_mat3x4_mul_vec4(vin, dt_colormatrix_row_to_simd(matrix, 0), dt_colormatrix_row_to_simd(matrix, 1), dt_colormatrix_row_to_simd(matrix, 2)))
char * name
static const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t row1
Definition darktable.h:623
#define DT_ALIGNED_PIXEL
Definition darktable.h:389
dt_store_simd(out, value)
static void memset_zero(void *const buffer, size_t size)
Set the memory buffer to zero as a pack of unsigned char.
Definition darktable.h:881
void dt_show_times(const dt_times_t *start, const char *prefix)
Definition darktable.c:1580
static gchar * dt_string_replace(const char *string, const char *to_replace)
Definition darktable.h:1073
static float * dt_calloc_align_float(size_t pixels)
Definition darktable.h:498
static void * dt_calloc_align(size_t size)
Definition darktable.h:488
static gboolean dt_modifiers_include(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:901
dt_debug_thread_t
Definition darktable.h:712
@ DT_DEBUG_LIGHTTABLE
Definition darktable.h:725
@ DT_DEBUG_UNDO
Definition darktable.h:734
@ DT_DEBUG_INPUT
Definition darktable.h:729
@ DT_DEBUG_PRINT
Definition darktable.h:730
@ DT_DEBUG_OPENCL
Definition darktable.h:722
@ DT_DEBUG_GTK
Definition darktable.h:718
@ DT_DEBUG_PIPE
Definition darktable.h:741
@ DT_DEBUG_PIPECACHE
Definition darktable.h:720
@ DT_DEBUG_HISTORY
Definition darktable.h:740
@ DT_DEBUG_CAMERA_SUPPORT
Definition darktable.h:731
@ DT_DEBUG_NAN
Definition darktable.h:726
@ DT_DEBUG_DEMOSAIC
Definition darktable.h:737
@ DT_DEBUG_MEMORY
Definition darktable.h:724
@ DT_DEBUG_PERF
Definition darktable.h:719
@ DT_DEBUG_VERBOSE
Definition darktable.h:743
@ DT_DEBUG_PARAMS
Definition darktable.h:736
@ DT_DEBUG_CONTROL
Definition darktable.h:716
@ DT_DEBUG_COLORPROFILE
Definition darktable.h:744
@ DT_DEBUG_CACHE
Definition darktable.h:715
@ DT_DEBUG_ALWAYS
Definition darktable.h:713
@ DT_DEBUG_SIGNAL
Definition darktable.h:735
@ DT_DEBUG_PWSTORAGE
Definition darktable.h:721
@ DT_DEBUG_SHORTCUTS
Definition darktable.h:738
@ DT_DEBUG_IMAGEIO
Definition darktable.h:733
@ DT_DEBUG_DEV
Definition darktable.h:717
@ DT_DEBUG_NOCACHE_REUSE
Definition darktable.h:745
@ DT_DEBUG_IMPORT
Definition darktable.h:742
@ DT_DEBUG_IOPORDER
Definition darktable.h:732
@ DT_DEBUG_MASKS
Definition darktable.h:727
@ DT_DEBUG_TILING
Definition darktable.h:739
@ DT_DEBUG_SQL
Definition darktable.h:723
@ DT_DEBUG_LUA
Definition darktable.h:728
void dt_pixelpipe_cache_free_align_cache(struct dt_dev_pixelpipe_cache_t *cache, void **mem, const char *message)
void dt_cleanup()
Definition darktable.c:1311
void gboolean dt_supported_image(const gchar *filename)
check if file is a supported image
Definition darktable.c:312
static void copy_pixel(float *const __restrict__ out, const float *const __restrict__ in)
Definition darktable.h:688
return out
Definition darktable.h:555
static void dt_free_align_ptr(void *mem)
Definition darktable.h:475
#define for_each_channel(_var,...)
Definition darktable.h:662
float dt_boundingbox_t[4]
Definition darktable.h:709
static float * dt_alloc_align_float(size_t pixels)
Definition darktable.h:494
static size_t dt_round_size_sse(const size_t size)
Definition darktable.h:403
void void dt_print_nts(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
static void * dt_check_sse_aligned(void *pointer)
Definition darktable.h:504
static gchar * strip_markup(const char *s)
Remove Pango/Gtk markup and accels mnemonics from text labels. If the markup parsing fails,...
Definition darktable.h:1095
darktable_t darktable
Definition darktable.c:181
static void * dt_alloc_align_internal(size_t size)
Definition darktable.h:409
void dt_print_mem_usage()
Definition darktable.c:1801
static void dt_free_gpointer(gpointer ptr)
Definition darktable.h:463
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
Definition darktable.h:524
static void copy_pixel_nontemporal(float *const __restrict__ out, const float *const __restrict__ in)
Definition darktable.h:677
void void void int dt_worker_threads()
Definition darktable.c:1677
static void * dt_pixelpipe_cache_alloc_perthread_impl(const size_t n, const size_t objsize, size_t *padded_size, const char *message)
Definition darktable.h:994
static const GList * g_list_next_wraparound(const GList *list, const GList *head)
Definition darktable.h:957
static const dt_aligned_pixel_simd_t sign
Definition darktable.h:551
static int dt_get_thread_num()
Definition darktable.h:291
void * dt_alloc_align(size_t size)
Definition darktable.c:446
#define dt_free(ptr)
Definition darktable.h:456
void dt_capabilities_remove(char *capability)
Definition darktable.c:1784
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
static void dt_get_times(dt_times_t *t)
Definition darktable.h:921
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data)
Definition darktable.c:451
static float * dt_pixelpipe_cache_alloc_perthread_float_impl(const size_t n, size_t *padded_size, const char *message)
Definition darktable.h:1024
#define omp_get_thread_num()
Definition darktable.h:255
static const GList * g_list_prev_wraparound(const GList *list)
Definition darktable.h:962
void void void dt_vprint(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
static int dt_version()
Definition darktable.h:154
static gchar * delete_underscore(const char *s)
Definition darktable.h:1083
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
Definition darktable.h:1043
size_t dt_get_mipmap_mem()
Definition darktable.c:1687
static size_t dt_round_size(const size_t size, const size_t alignment)
Definition darktable.h:397
static void dt_unreachable_codepath_with_caller(const char *description, const char *file, const int line, const char *function)
Definition darktable.h:980
int dt_load_from_string(const gchar *image_to_load, gboolean open_image_in_dr, gboolean *single_image)
Definition darktable.c:328
#define DT_MODULE_VERSION
Definition darktable.h:120
static const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t row2
Definition darktable.h:624
static GList * g_list_next_bounded(GList *list)
Definition darktable.h:952
char * dt_version_major_minor()
Definition darktable.c:281
void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui)
Definition darktable.c:1692
static const dt_aligned_pixel_simd_t value
Definition darktable.h:577
void dt_capabilities_add(char *capability)
Definition darktable.c:1773
void dt_concat_path_file(char destination[4096], const char path[4096], const char *const file)
Append a constant filename to a variable, stack-based, fixed-sized, directory, and add a / in-between...
static double dt_get_wtime(void)
Definition darktable.h:914
static void * dt_pixelpipe_cache_calloc_perthread_impl(const size_t n, const size_t objsize, size_t *padded_size, const char *message)
Definition darktable.h:1010
void dt_capabilities_cleanup()
Definition darktable.c:1794
static gboolean dt_is_aligned(const void *pointer, size_t byte_count)
Definition darktable.h:392
static const dt_aligned_pixel_simd_t exponent
Definition darktable.h:560
void * dt_pixelpipe_cache_alloc_align_cache_impl(struct dt_dev_pixelpipe_cache_t *cache, size_t size, int id, const char *name)
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:893
void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix,...) __attribute__((format(printf
static const dt_aligned_pixel_simd_t row0
Definition darktable.h:622
size_t dt_get_available_mem()
Definition darktable.c:1682
int dt_capabilities_check(char *capability)
Definition darktable.c:1760
#define PATH_MAX
Definition darktable.h:1062
#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 darktable.h:281
#define DT_CACHELINE_BYTES
Definition darktable.h:380
static gboolean g_list_shorter_than(const GList *list, unsigned len)
Definition darktable.h:939
#define dt_pthread_rwlock_t
Definition dtpthread.h:389
int getrusage(int who, struct rusage *usage)
Definition getrusage.c:56
#define RUSAGE_SELF
Definition getrusage.h:53
const int t
float *const restrict const size_t k
size_t size
Definition mipmap_cache.c:3
float dt_aligned_pixel_t[4]
@ DT_SIGNAL_COUNT
Definition signal.h:319
const float uint32_t state[4]
unsigned __int64 uint64_t
Definition strptime.c:75
struct dt_dbus_t * dbus
Definition darktable.h:786
struct dt_undo_t * undo
Definition darktable.h:787
char * tmpdir
Definition darktable.h:823
dt_pthread_mutex_t readFile_mutex
Definition darktable.h:803
char * cachedir
Definition darktable.h:825
struct dt_lib_t * lib
Definition darktable.h:771
int32_t unmuted_signal_dbg_acts
Definition darktable.h:830
struct dt_imageio_t * imageio
Definition darktable.h:784
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
Definition darktable.h:790
int32_t num_openmp_threads
Definition darktable.h:758
struct dt_l10n_t * l10n
Definition darktable.h:789
struct dt_gui_gtk_t * gui
Definition darktable.h:775
dt_pthread_rwlock_t database_threadsafe
Definition darktable.h:816
struct dt_colorspaces_t * color_profiles
Definition darktable.h:788
GList * capabilities
Definition darktable.h:767
GTimeZone * utc_tz
Definition darktable.h:832
char * sharedir
Definition darktable.h:820
struct dt_collection_t * collection
Definition darktable.h:781
struct dt_mipmap_cache_t * mipmap_cache
Definition darktable.h:776
struct dt_selection_t * selection
Definition darktable.h:782
GList * iop
Definition darktable.h:761
dt_pthread_mutex_t exiv2_threadsafe
Definition darktable.h:800
struct dt_sys_resources_t dtresources
Definition darktable.h:834
dt_pthread_mutex_t plugin_threadsafe
Definition darktable.h:793
char * moduledir
Definition darktable.h:821
dt_pthread_mutex_t capabilities_threadsafe
Definition darktable.h:796
GList * iop_order_list
Definition darktable.h:762
const struct dt_database_t * db
Definition darktable.h:779
GList * iop_order_rules
Definition darktable.h:763
struct dt_control_signal_t * signals
Definition darktable.h:774
struct dt_bauhaus_t * bauhaus
Definition darktable.h:778
struct dt_opencl_t * opencl
Definition darktable.h:785
char * configdir
Definition darktable.h:824
char * datadir
Definition darktable.h:819
GList * themes
Definition darktable.h:829
int32_t unmuted
Definition darktable.h:760
struct dt_image_cache_t * image_cache
Definition darktable.h:777
struct dt_develop_t * develop
Definition darktable.h:770
struct dt_points_t * points
Definition darktable.h:783
char * localedir
Definition darktable.h:822
dt_pthread_mutex_t pipeline_threadsafe
Definition darktable.h:808
struct dt_view_manager_t * view_manager
Definition darktable.h:772
char * kerneldir
Definition darktable.h:826
JsonParser * noiseprofile_parser
Definition darktable.h:768
GList * guides
Definition darktable.h:827
gboolean unmuted_signal_dbg[DT_SIGNAL_COUNT]
Definition darktable.h:831
char * main_message
Definition darktable.h:837
char * progname
Definition darktable.h:818
struct dt_conf_t * conf
Definition darktable.h:769
GDateTime * origin_gdt
Definition darktable.h:833
const struct dt_pwstorage_t * pwstorage
Definition darktable.h:780
double start_wtime
Definition darktable.h:828
struct dt_control_t * control
Definition darktable.h:773
Definition lib.h:54
size_t pixelpipe_memory
Definition darktable.h:753
double clock
Definition darktable.h:842
double user
Definition darktable.h:843
struct timeval ru_utime
Definition getrusage.h:34
#define MAX(a, b)
Definition thinplate.c:29