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,
722 DT_DEBUG_SQL = 1 << 8,
725 DT_DEBUG_NAN = 1 << 11,
726 DT_DEBUG_MASKS = 1 << 12,
727 DT_DEBUG_LUA = 1 << 13,
728 DT_DEBUG_INPUT = 1 << 14,
729 DT_DEBUG_PRINT = 1 << 15,
733 DT_DEBUG_UNDO = 1 << 19,
740 DT_DEBUG_PIPE = 1 << 26,
746
747typedef struct dt_sys_resources_t
748{
749 size_t total_memory; // All RAM on system
750 size_t mipmap_memory; // RAM allocated to mipmap cache
751 size_t headroom_memory; // RAM left to OS & other Apps
752 size_t pixelpipe_memory; // RAM used by the pixelpipe cache (approx.)
754
755typedef struct darktable_t
756{
758
759 int32_t unmuted;
760 GList *iop;
763
764 // Keep track of optional features that may depend on environnement
765 // ond compiling options : OpenCL, libsecret, kwallet
770 struct dt_lib_t *lib;
778 const struct dt_database_t *db;
790
791 // Protects from concurrent writing at export time
792 dt_pthread_mutex_t plugin_threadsafe;
793
794 // Protect appending/removing GList links to the darktable.capabilities list
795 dt_pthread_mutex_t capabilities_threadsafe;
796
797 // Exiv2 readMetadata() was not thread-safe prior to 0.27
798 // FIXME: Is it now ?
799 dt_pthread_mutex_t exiv2_threadsafe;
800
801 // RawSpeed readFile() method is apparently not thread-safe
802 dt_pthread_mutex_t readFile_mutex;
803
804 // Prevent concurrent export/thumbnail pipelines from runnnig at the same time
805 // It brings no additional performance since the CPU is our bottleneck,
806 // and CPU pixel code is already multi-threaded internally through OpenMP
807 dt_pthread_mutex_t pipeline_threadsafe;
808
809 // Building SQL transactions through `dt_database_start_transaction_debug()`
810 // from "too many" threads (like loading all thumbnails from a new collection)
811 // leads to SQL error:
812 // `BEGIN": cannot start a transaction within a transaction`
813 // Also, we need to ensure that image metadata/history reads & writes
814 // happen each in their all time, from all pipeline jobs/threads.
816
817 char *progname;
818 char *datadir;
819 char *sharedir;
822 char *tmpdir;
824 char *cachedir;
826 GList *guides;
828 GList *themes;
831 GTimeZone *utc_tz;
832 GDateTime *origin_gdt;
834
835 // Working message displayed over the main preview when working
838
839typedef struct
840{
841 double clock;
842 double user;
843} dt_times_t;
844
846
847int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data);
848void dt_cleanup();
849void dt_print(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
850/* same as above but without time stamp : nts = no time stamp */
851void dt_print_nts(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
852/* same as above but requires additional DT_DEBUG_VERBOSE flag to be true */
853void dt_vprint(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
854
855// Number of workers, on top of reserved workers (1 for main preview, 1 for thumbnail in darkroom)
856// This is currently set to 2, so 4 workers total, without user config.
857// Workers will process a queue of jobs that they share together (except for reserved ones).
858// It is useless to use more than 2 workers
859// since those jobs very often lock some mutex that prevents concurrent running.
860// All jobs finding an idle worker will "start" immediately, as far as the OS knows from outside the program,
861// but may do nothing internally except for waiting a mutex locked by another worker/thread.
862// In that situation, we loose the ability to flush the queue, since jobs are "running".
863// So it's better to have few workers with long queues, rather
864// than many workers, to be able to control queued jobs.
866
867// Get the remaining memory available for pipeline allocations,
868// once we subtracted caches memory and headroom from system memory
869size_t dt_get_available_mem();
870
871// Get the maximum size for the whole mipmap cache
872size_t dt_get_mipmap_mem();
873
880static inline void memset_zero(void *const buffer, size_t size)
881{
882 // Same as memset_s in C11. memset might be optimized away by compilers, this will not.
883 // Not parallelized or vectorized since it's applied only on "small" tiles.
884 for(size_t k = 0; k < size / sizeof(unsigned char); k++) {
885 unsigned char *const item = (unsigned char *const)buffer + k;
886 *item = 0;
887 }
888}
889
890// check whether the specified mask of modifier keys exactly matches, among the set Shift+Control+(Alt/Meta).
891// ignores the state of any other shifting keys
892static inline gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
893{
894 const GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
895//TODO: on Macs, remap the GDK_CONTROL_MASK bit in desired_modifier_mask to be the bit for the Cmd key
896 return (state & modifiers) == desired_modifier_mask;
897}
898
899// check whether the given modifier state includes AT LEAST the specified mask of modifier keys
900static inline gboolean dt_modifiers_include(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
901{
902//TODO: on Macs, remap the GDK_CONTROL_MASK bit in desired_modifier_mask to be the bit for the Cmd key
903 const GdkModifierType modifiers = gtk_accelerator_get_default_mod_mask();
904 // check whether all modifier bits of interest are turned on
905 return (state & (modifiers & desired_modifier_mask)) == desired_modifier_mask;
906}
907
908int dt_capabilities_check(char *capability);
909void dt_capabilities_add(char *capability);
910void dt_capabilities_remove(char *capability);
912
913static inline double dt_get_wtime(void)
914{
915 struct timeval time;
916 gettimeofday(&time, NULL);
917 return time.tv_sec - 1290608000 + (1.0 / 1000000.0) * time.tv_usec;
918}
919
920static inline void dt_get_times(dt_times_t *t)
921{
922 struct rusage ru;
923
925 t->clock = dt_get_wtime();
926 t->user = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec * (1.0 / 1000000.0);
927}
928
929void dt_show_times(const dt_times_t *start, const char *prefix);
930
931void dt_show_times_f(const dt_times_t *start, const char *prefix, const char *suffix, ...) __attribute__((format(printf, 3, 4)));
932
934gboolean dt_supported_image(const gchar *filename);
935
936// a few macros and helper functions to speed up certain frequently-used GLib operations
937#define g_list_is_singleton(list) ((list) && (!(list)->next))
938static inline gboolean g_list_shorter_than(const GList *list, unsigned len)
939{
940 // instead of scanning the full list to compute its length and then comparing against the limit,
941 // bail out as soon as the limit is reached. Usage: g_list_shorter_than(l,4) instead of g_list_length(l)<4
942 while (len-- > 0)
943 {
944 if (!list) return TRUE;
945 list = g_list_next(list);
946 }
947 return FALSE;
948}
949
950// advance the list by one position, unless already at the final node
951static inline GList *g_list_next_bounded(GList *list)
952{
953 return g_list_next(list) ? g_list_next(list) : list;
954}
955
956static inline const GList *g_list_next_wraparound(const GList *list, const GList *head)
957{
958 return g_list_next(list) ? g_list_next(list) : head;
959}
960
961static inline const GList *g_list_prev_wraparound(const GList *list)
962{
963 // return the prior element of the list, unless already on the first element; in that case, return the last
964 // element of the list.
965 return g_list_previous(list) ? g_list_previous(list) : g_list_last((GList*)list);
966}
967
968void dt_print_mem_usage();
969
970void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui);
971
972// helper function which loads whatever image_to_load points to: single image files or whole directories
973// it tells you if it was a single image or a directory in single_image (when it's not NULL)
974int dt_load_from_string(const gchar *image_to_load, gboolean open_image_in_dr, gboolean *single_image);
975
976#define dt_unreachable_codepath_with_desc(D) \
977 dt_unreachable_codepath_with_caller(D, __FILE__, __LINE__, __FUNCTION__)
978#define dt_unreachable_codepath() dt_unreachable_codepath_with_caller("unreachable", __FILE__, __LINE__, __FUNCTION__)
979static inline void dt_unreachable_codepath_with_caller(const char *description, const char *file,
980 const int line, const char *function)
981{
982 fprintf(stderr, "[dt_unreachable_codepath] {%s} %s:%d (%s) - we should not be here. please report this to "
983 "the developers.",
984 description, file, line, function);
985 __builtin_unreachable();
986}
987
988// Allocate a buffer for 'n' objects each of size 'objsize' bytes for each of the program's threads.
989// Ensures that there is no false sharing among threads by aligning and rounding up the allocation to
990// a multiple of the cache line size. Returns a pointer to the allocated pool and the adjusted number
991// of objects in each thread's buffer. Use dt_get_perthread or dt_get_bythread (see below) to access
992// a specific thread's buffer.
993static inline void *dt_pixelpipe_cache_alloc_perthread_impl(const size_t n, const size_t objsize, size_t* padded_size, const char *message)
994{
995 const size_t alloc_size = n * objsize;
996 const size_t cache_lines = (alloc_size + DT_CACHELINE_BYTES - 1) / DT_CACHELINE_BYTES;
997 *padded_size = DT_CACHELINE_BYTES * cache_lines / objsize;
998 const size_t total_bytes = DT_CACHELINE_BYTES * cache_lines * darktable.num_openmp_threads;
999 void *buf = dt_pixelpipe_cache_alloc_align_cache_impl(darktable.pixelpipe_cache, total_bytes, 0, message);
1000 if(IS_NULL_PTR(buf)) return NULL;
1001 return __builtin_assume_aligned(buf, DT_CACHELINE_BYTES);
1002}
1003
1004#ifndef dt_pixelpipe_cache_alloc_perthread
1005#define dt_pixelpipe_cache_alloc_perthread(n, objsize, padded_size) \
1006 ((void *)dt_pixelpipe_cache_alloc_perthread_impl((n), (objsize), (padded_size), __FILE__ ":" DT_STRINGIFY(__LINE__)))
1007#endif
1008
1009static inline void *dt_pixelpipe_cache_calloc_perthread_impl(const size_t n, const size_t objsize, size_t* padded_size, const char *message)
1010{
1011 void *const buf = (float*)dt_pixelpipe_cache_alloc_perthread_impl(n, objsize, padded_size, message);
1012 if(IS_NULL_PTR(buf)) return NULL;
1013 memset(buf, 0, *padded_size * darktable.num_openmp_threads * objsize);
1014 return buf;
1015}
1016
1017#ifndef dt_pixelpipe_cache_calloc_perthread
1018#define dt_pixelpipe_cache_calloc_perthread(n, objsize, padded_size) \
1019 ((void *)dt_pixelpipe_cache_calloc_perthread_impl((n), (objsize), (padded_size), __FILE__ ":" DT_STRINGIFY(__LINE__)))
1020#endif
1021
1022// Same as dt_pixelpipe_cache_alloc_perthread, but the object is a float.
1023static inline float *dt_pixelpipe_cache_alloc_perthread_float_impl(const size_t n, size_t* padded_size, const char *message)
1024{
1025 return (float*)dt_pixelpipe_cache_alloc_perthread_impl(n, sizeof(float), padded_size, message);
1026}
1027
1028#ifndef dt_pixelpipe_cache_alloc_perthread_float
1029#define dt_pixelpipe_cache_alloc_perthread_float(n, padded_size) \
1030 ((float *)dt_pixelpipe_cache_alloc_perthread_float_impl((n), (padded_size), __FILE__ ":" DT_STRINGIFY(__LINE__)))
1031#endif
1032
1033// Given the buffer and object count returned by dt_pixelpipe_cache_alloc_perthread, return the current thread's private buffer.
1034#define dt_get_perthread(buf, padsize) DT_IS_ALIGNED((buf) + ((padsize) * dt_get_thread_num()))
1035// Given the buffer and object count returned by dt_pixelpipe_cache_alloc_perthread and a thread count in 0..darktable.num_openmp_threads,
1036// return a pointer to the indicated thread's private buffer.
1037#define dt_get_bythread(buf, padsize, tnum) DT_IS_ALIGNED((buf) + ((padsize) * (tnum)))
1038
1039// Scramble bits in str to create an (hopefully) unique hash representing the state of str
1040// Dan Bernstein algo v2 http://www.cse.yorku.ca/~oz/hash.html
1041// hash should be inited to 5381 if first run, or from a previous hash computed with this function.
1042static inline uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
1043{
1044 for(size_t i = 0; i < size; i++)
1045 hash = ((hash << 5) + hash) ^ str[i];
1046
1047 return hash;
1048}
1049
1051#define DT_MAX_FILENAME_LEN 256
1052
1053#ifndef PATH_MAX
1054/*
1055 * from /usr/include/linux/limits.h (Linux 3.16.5)
1056 * Some systems might not define it (e.g. Hurd)
1057 *
1058 * We do NOT depend on any specific value of this env variable.
1059 * If you want constant value across all systems, use DT_MAX_PATH_FOR_PARAMS!
1060 */
1061#define PATH_MAX 4096
1062#endif
1063
1064/*
1065 * ONLY TO BE USED FOR PARAMS!!! (e.g. dt_imageio_disk_t)
1066 *
1067 * WARNING: this should *NEVER* be changed, as it will break params,
1068 * created with previous DT_MAX_PATH_FOR_PARAMS.
1069 */
1070#define DT_MAX_PATH_FOR_PARAMS 4096
1071
1072static inline gchar *dt_string_replace(const char *string, const char *to_replace)
1073{
1074 if(IS_NULL_PTR(string) || IS_NULL_PTR(to_replace)) return NULL;
1075 gchar **split = g_strsplit(string, to_replace, -1);
1076 gchar *text = g_strjoinv("", split);
1077 g_strfreev(split);
1078 return text;
1079}
1080
1081// Remove underscore from GUI labels containing mnemonics
1082static inline gchar *delete_underscore(const char *s)
1083{
1084 return dt_string_replace(s, "_");
1085}
1086
1094static inline gchar *strip_markup(const char *s)
1095{
1096 if(IS_NULL_PTR(s)) return g_strdup("");
1097
1098 PangoAttrList *attrs = NULL;
1099 gchar *plain = NULL;
1100
1101 const gchar *underscore = "_";
1102 gunichar mnemonic = underscore[0];
1103 if(!pango_parse_markup(s, -1, mnemonic, &attrs, &plain, NULL, NULL))
1104 plain = delete_underscore(s);
1105
1106 pango_attr_list_unref(attrs);
1107 return plain;
1108}
1109
1118void dt_concat_path_file(char destination[PATH_MAX], const char path[PATH_MAX], const char *const file);
1119
1120#ifdef __cplusplus
1121}
1122#endif
1123
1124// clang-format off
1125// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
1126// vim: shiftwidth=2 expandtab tabstop=2 cindent
1127// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
1128// 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)
const float i
Definition colorspaces_inline_conversions.h:440
const float n
Definition colorspaces_inline_conversions.h:678
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
Definition common/metadata.c:61
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:880
void dt_show_times(const dt_times_t *start, const char *prefix)
Definition darktable.c:1486
static gchar * dt_string_replace(const char *string, const char *to_replace)
Definition darktable.h:1072
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:900
dt_debug_thread_t
Definition darktable.h:712
@ DT_DEBUG_LIGHTTABLE
Definition darktable.h:724
@ DT_DEBUG_UNDO
Definition darktable.h:733
@ DT_DEBUG_INPUT
Definition darktable.h:728
@ DT_DEBUG_PRINT
Definition darktable.h:729
@ DT_DEBUG_OPENCL
Definition darktable.h:721
@ DT_DEBUG_PIPE
Definition darktable.h:740
@ DT_DEBUG_PIPECACHE
Definition darktable.h:719
@ DT_DEBUG_HISTORY
Definition darktable.h:739
@ DT_DEBUG_CAMERA_SUPPORT
Definition darktable.h:730
@ DT_DEBUG_NAN
Definition darktable.h:725
@ DT_DEBUG_DEMOSAIC
Definition darktable.h:736
@ DT_DEBUG_MEMORY
Definition darktable.h:723
@ DT_DEBUG_PERF
Definition darktable.h:718
@ DT_DEBUG_VERBOSE
Definition darktable.h:742
@ DT_DEBUG_PARAMS
Definition darktable.h:735
@ DT_DEBUG_CONTROL
Definition darktable.h:716
@ DT_DEBUG_COLORPROFILE
Definition darktable.h:743
@ DT_DEBUG_CACHE
Definition darktable.h:715
@ DT_DEBUG_ALWAYS
Definition darktable.h:713
@ DT_DEBUG_SIGNAL
Definition darktable.h:734
@ DT_DEBUG_PWSTORAGE
Definition darktable.h:720
@ DT_DEBUG_SHORTCUTS
Definition darktable.h:737
@ DT_DEBUG_IMAGEIO
Definition darktable.h:732
@ DT_DEBUG_DEV
Definition darktable.h:717
@ DT_DEBUG_NOCACHE_REUSE
Definition darktable.h:744
@ DT_DEBUG_IMPORT
Definition darktable.h:741
@ DT_DEBUG_IOPORDER
Definition darktable.h:731
@ DT_DEBUG_MASKS
Definition darktable.h:726
@ DT_DEBUG_TILING
Definition darktable.h:738
@ DT_DEBUG_SQL
Definition darktable.h:722
@ DT_DEBUG_LUA
Definition darktable.h:727
void dt_pixelpipe_cache_free_align_cache(struct dt_dev_pixelpipe_cache_t *cache, void **mem, const char *message)
Definition pixelpipe_cache.c:1586
void dt_cleanup()
Definition darktable.c:1274
void gboolean dt_supported_image(const gchar *filename)
check if file is a supported image
Definition darktable.c:298
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:1094
darktable_t darktable
Definition darktable.c:173
static void * dt_alloc_align_internal(size_t size)
Definition darktable.h:409
void dt_print_mem_usage()
Definition darktable.c:1707
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:1583
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:993
static const GList * g_list_next_wraparound(const GList *list, const GList *head)
Definition darktable.h:956
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:432
#define dt_free(ptr)
Definition darktable.h:456
void dt_capabilities_remove(char *capability)
Definition darktable.c:1690
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:920
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data)
Definition darktable.c:437
static float * dt_pixelpipe_cache_alloc_perthread_float_impl(const size_t n, size_t *padded_size, const char *message)
Definition darktable.h:1023
#define omp_get_thread_num()
Definition darktable.h:255
static const GList * g_list_prev_wraparound(const GList *list)
Definition darktable.h:961
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:1082
static uint64_t dt_hash(uint64_t hash, const char *str, size_t size)
Definition darktable.h:1042
size_t dt_get_mipmap_mem()
Definition darktable.c:1593
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:979
int dt_load_from_string(const gchar *image_to_load, gboolean open_image_in_dr, gboolean *single_image)
Definition darktable.c:314
#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:951
char * dt_version_major_minor()
Definition darktable.c:267
void dt_configure_runtime_performance(dt_sys_resources_t *resources, gboolean init_gui)
Definition darktable.c:1598
static const dt_aligned_pixel_simd_t value
Definition darktable.h:577
void dt_capabilities_add(char *capability)
Definition darktable.c:1679
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:913
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:1009
void dt_capabilities_cleanup()
Definition darktable.c:1700
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)
Definition pixelpipe_cache.c:1538
static gboolean dt_modifier_is(const GdkModifierType state, const GdkModifierType desired_modifier_mask)
Definition darktable.h:892
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:1588
int dt_capabilities_check(char *capability)
Definition darktable.c:1666
#define PATH_MAX
Definition darktable.h:1061
#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:938
#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
Definition iop_profile.h:225
float *const restrict const size_t k
Definition luminance_mask.h:78
size_t size
Definition mipmap_cache.c:3
c
Definition derive_filmic_v6_gamut_mapping.py:35
float dt_aligned_pixel_t[4]
Definition noiseprofile.c:28
@ DT_SIGNAL_COUNT
Definition signal.h:318
const float uint32_t state[4]
Definition src/develop/noise_generator.h:72
unsigned __int64 uint64_t
Definition strptime.c:75
Definition darktable.h:756
struct dt_dbus_t * dbus
Definition darktable.h:785
struct dt_undo_t * undo
Definition darktable.h:786
char * tmpdir
Definition darktable.h:822
dt_pthread_mutex_t readFile_mutex
Definition darktable.h:802
char * cachedir
Definition darktable.h:824
struct dt_lib_t * lib
Definition darktable.h:770
int32_t unmuted_signal_dbg_acts
Definition darktable.h:829
struct dt_imageio_t * imageio
Definition darktable.h:783
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
Definition darktable.h:789
int32_t num_openmp_threads
Definition darktable.h:757
struct dt_l10n_t * l10n
Definition darktable.h:788
struct dt_gui_gtk_t * gui
Definition darktable.h:774
dt_pthread_rwlock_t database_threadsafe
Definition darktable.h:815
struct dt_colorspaces_t * color_profiles
Definition darktable.h:787
GList * capabilities
Definition darktable.h:766
GTimeZone * utc_tz
Definition darktable.h:831
char * sharedir
Definition darktable.h:819
struct dt_collection_t * collection
Definition darktable.h:780
struct dt_mipmap_cache_t * mipmap_cache
Definition darktable.h:775
struct dt_selection_t * selection
Definition darktable.h:781
GList * iop
Definition darktable.h:760
dt_pthread_mutex_t exiv2_threadsafe
Definition darktable.h:799
struct dt_sys_resources_t dtresources
Definition darktable.h:833
dt_pthread_mutex_t plugin_threadsafe
Definition darktable.h:792
char * moduledir
Definition darktable.h:820
dt_pthread_mutex_t capabilities_threadsafe
Definition darktable.h:795
GList * iop_order_list
Definition darktable.h:761
const struct dt_database_t * db
Definition darktable.h:778
GList * iop_order_rules
Definition darktable.h:762
struct dt_control_signal_t * signals
Definition darktable.h:773
struct dt_bauhaus_t * bauhaus
Definition darktable.h:777
struct dt_opencl_t * opencl
Definition darktable.h:784
char * configdir
Definition darktable.h:823
char * datadir
Definition darktable.h:818
GList * themes
Definition darktable.h:828
int32_t unmuted
Definition darktable.h:759
struct dt_image_cache_t * image_cache
Definition darktable.h:776
struct dt_develop_t * develop
Definition darktable.h:769
struct dt_points_t * points
Definition darktable.h:782
char * localedir
Definition darktable.h:821
dt_pthread_mutex_t pipeline_threadsafe
Definition darktable.h:807
struct dt_view_manager_t * view_manager
Definition darktable.h:771
char * kerneldir
Definition darktable.h:825
JsonParser * noiseprofile_parser
Definition darktable.h:767
GList * guides
Definition darktable.h:826
gboolean unmuted_signal_dbg[DT_SIGNAL_COUNT]
Definition darktable.h:830
char * main_message
Definition darktable.h:836
char * progname
Definition darktable.h:817
struct dt_conf_t * conf
Definition darktable.h:768
GDateTime * origin_gdt
Definition darktable.h:832
const struct dt_pwstorage_t * pwstorage
Definition darktable.h:779
double start_wtime
Definition darktable.h:827
struct dt_control_t * control
Definition darktable.h:772
Definition bauhaus.h:234
Definition collection.h:169
Definition colorspaces.h:172
Definition conf.h:80
Definition signal.c:50
Definition control.h:179
Definition database.c:99
Definition dbus.h:30
Definition pixelpipe_cache.h:56
Definition develop.h:159
Definition gtk.h:133
Definition image_cache.h:39
Definition imageio_module.h:122
Definition l10n.h:35
Definition lib.h:54
Definition mipmap_cache.h:94
Definition opencl.h:219
Definition points.h:51
Definition pwstorage.h:49
Definition selection.c:48
Definition darktable.h:748
size_t headroom_memory
Definition darktable.h:751
size_t total_memory
Definition darktable.h:749
size_t mipmap_memory
Definition darktable.h:750
size_t pixelpipe_memory
Definition darktable.h:752
Definition darktable.h:840
double clock
Definition darktable.h:841
double user
Definition darktable.h:842
Definition undo.h:70
Definition view.h:199
Definition getrusage.h:33
struct timeval ru_utime
Definition getrusage.h:34
#define MAX(a, b)
Definition thinplate.c:29