Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
Code health

Generated with tools/code_health.py during the documentation build. The same script, with the same thresholds and the same third-party exclusions, runs in the Ansel repository and in the frozen darktable 5.0 reference tree, so the two published panels can be read side by side.

Vendored code is excluded throughout (src/external/, the integration-test data, the Doxygen theme), matching sonar.exclusions in .sonarcloud.properties. Every number below therefore describes code this repository actually authors.

Size

Measure Value
Files 794
Lines of code 331,020
Comment lines 74,988
Blank lines 61,661
Comment ratio 18.5 %
Language Files Code Comment
C 438 294,784 49,283
C/C++ Header 344 26,725 24,142
C++ 11 9,270 1,519
Objective-C++ 1 241 44

Cyclomatic complexity

Per-function CCN, measured by lizard. The mean is the least interesting number here: maintenance cost lives in the tail, so the counts above each threshold are what to compare.

Measure Value
Functions 12,114
Total CCN 63,291
Mean CCN 5.22
Median CCN 2
90th percentile 11
99th percentile 44
Maximum CCN 229
Mean function length (NLOC) 23.8
Threshold Functions Share
CCN > 15 (worth refactoring) 762 6.3 %
CCN > 25 (hard to test) 340 2.8 %
CCN > 50 95 0.8 %
CCN > 100 17 0.1 %
Longer than 100 lines 446 3.7 %
Longer than 300 lines 44 0.4 %
More than 7 parameters 470 3.9 %

Most complex functions

CCN NLOC Params Function File
229 459 2 _get_base_value src/common/variables.c
189 812 5 process src/iop/cacorrect.c
170 527 1 _cf_reconstruct src/iop/highlights/coefficient_field.c
163 492 7 _lrop src/develop/lightroom.c
162 959 6 amaze_demosaic_RT src/iop/demosaic/amaze.cc
161 668 3 dt_init src/darktable.c
152 571 1 main src/apps/ansel-cli/main.c
132 414 3 get_query_string src/database/collection_query.c
121 962 5 xtrans_fdc_interpolate src/iop/demosaic/markesteijn.c
118 207 3 dt_drawlayer_runtime_manager_update src/iop/drawlayer/runtime.c
113 310 5 mouse_moved src/iop/clipping.c
111 337 3 _cf_stage_cl_selftest src/iop/highlights/selftests.c
111 132 3 gui_changed src/iop/channelmixerrgb.c
110 533 11 _aniso_stage_cl src/iop/highlights/chroma.c
109 342 5 xtrans_markesteijn_interpolate src/iop/demosaic/markesteijn.c
106 308 3 strptime src/win/strptime.c
104 339 6 _sp_chol_factor_cl src/math/sparse_cholesky_cl.h
98 142 1 Lch_to_color_name src/common/color_vocabulary.c
97 535 8 process_markesteijn_cl src/iop/demosaic/markesteijn.c
97 532 0 polar_decomposition src/math/polar_decomposition.h
96 468 8 pixelpipe_process_on_GPU src/develop/pixelpipe_gpu.c
95 301 7 _hl_knee_estimate src/iop/highlights/knee.c
93 394 5 dt_develop_blend_process_cl src/develop/blend.c
93 286 0 dtwin_get_locale src/win/dtwin.c
92 393 12 write_image src/imageio/format/tiff.c
83 303 8 _process_waveform src/libs/histogram.c
83 287 11 _hl_knee_estimate_cl src/iop/highlights/knee.c
82 378 3 dt_lightroom_import src/develop/lightroom.c
81 323 6 _polygon_get_mask_roi src/develop/masks/polygon.c
81 229 6 _polygon_crop_to_roi src/develop/masks/polygon.c
81 89 1 _get_cursor_name src/control/control.c
80 603 3 dt_iop_tonecurve_draw src/iop/filmicrgb.c
80 471 8 process_harmonic_cl src/iop/highlights/process.c
80 248 3 _cf_joint_stage_cl_selftest src/iop/highlights/selftests.c
79 235 3 _hf_stage_cl_selftest src/iop/highlights/selftests.c
77 410 10 _cf_harmonic_fill_cl_n src/iop/highlights/coefficient_field.c
77 274 8 _cf_harmonic_fill_n src/iop/highlights/coefficient_field.c
76 329 1 _metadata_view_update_values src/libs/metadata_view.c
76 283 2 main src/apps/ansel-cmstest/main.c
76 215 6 _extract_pointer_input src/gui/application.c

Longest functions

NLOC CCN Function File
1193 73 _upgrade_library_schema_step src/database/database.c
962 121 xtrans_fdc_interpolate src/iop/demosaic/markesteijn.c
959 162 amaze_demosaic_RT src/iop/demosaic/amaze.cc
812 189 process src/iop/cacorrect.c
668 161 dt_init src/darktable.c
603 80 dt_iop_tonecurve_draw src/iop/filmicrgb.c
571 152 main src/apps/ansel-cli/main.c
535 97 process_markesteijn_cl src/iop/demosaic/markesteijn.c
533 110 _aniso_stage_cl src/iop/highlights/chroma.c
532 97 polar_decomposition src/math/polar_decomposition.h
527 170 _cf_reconstruct src/iop/highlights/coefficient_field.c
492 163 _lrop src/develop/lightroom.c
476 75 dt_opencl_device_init src/common/opencl.c
471 80 process_harmonic_cl src/iop/highlights/process.c
468 96 pixelpipe_process_on_GPU src/develop/pixelpipe_gpu.c
459 229 _get_base_value src/common/variables.c
414 132 get_query_string src/database/collection_query.c
410 77 _cf_harmonic_fill_cl_n src/iop/highlights/coefficient_field.c
394 93 dt_develop_blend_process_cl src/develop/blend.c
393 92 write_image src/imageio/format/tiff.c

Layering

Everything in this section is derived from the include graph. Nothing is declared by hand, and there is no table of "which layer should sit above which" - an earlier version of this panel had one, and it was wrong twice: it encoded one reading of the architecture, and it assumed src/ subdirectories are modules. In darktable they are not. They are drawers - groupings of convenience with no ownership or interface boundary - so "common sits below control" is an assertion the code never made.

The primary unit here is therefore the file, which presumes nothing about how the tree is organised. Directory-level figures follow, labelled as the aggregation over drawers that they are.

Two questions, kept apart:

  • Cycles are absolute. If A depends on B and B on A, no layering of the two exists, whatever anyone believes. Counted as strongly connected components.
  • Backward dependencies are graduated. Order the units so as few includes as possible point backwards; what still does is the minimum set that would have to go for a layering to exist at all. Computed with the Eades-Lin-Smyth feedback-arc-set heuristic, weighted by include count.
Measure Files Directories
Units 808 22
Dependency edges 5,449 201
Cycles 0 1
Units caught in a cycle 0 20
Backward dependencies 0 53
Includes on them 0 342
Share of all includes 0.0 % 8.1 %

Backward dependencies between directories

Aggregated over src/ subdirectories. Read with the caveat above: these are drawers, so a large number here says the include flow between two drawers is two-way, not that a designed boundary was broken.

Derived order, rank 0 first:

system < win < math < colorprofiles < caches < database < metadata < osx < history < control < widgets < common < (root) < pixel < views < develop < imageio < gui < libs < iop < apps < tests

Includes Points backwards From rank To rank
39 control -> common 9 11
29 common -> develop 11 15
29 metadata -> common 6 11
26 views -> develop 14 15
25 views -> gui 14 17
18 develop -> gui 15 17
16 database -> common 5 11
11 colorprofiles -> common 3 11
10 caches -> common 4 11
10 common -> pixel 11 13
8 (root) -> gui 12 17
7 (root) -> develop 12 15
7 gui -> libs 17 18
6 caches -> develop 4 15
6 control -> gui 9 17
6 history -> common 8 11
6 math -> common 2 11
5 views -> libs 14 18
4 caches -> control 4 9
4 common -> (root) 11 12
4 common -> gui 11 17
4 common -> views 11 14
4 control -> develop 9 15
4 database -> metadata 5 6
4 pixel -> develop 13 15

Directory dependency cycles

Directories Cycle
20 (root), caches, colorprofiles, common, control, database, develop, gui, history, imageio, iop, libs, math, metadata, osx, pixel, system, views, widgets, win

Stability

A second graph-derived view, independent of the ordering above; two derivations agreeing is worth more than either alone. Ca counts the directories depending on one, Ce those it depends on, and instability is I = Ce / (Ca + Ce). I = 0 means everything depends on it and it depends on nothing - expensive to change. I = 1 means nothing depends on it.

The Stable Dependencies Principle says a unit should depend only on units at least as stable as itself; an edge with I(from) < I(to) breaks it, letting a volatile unit's churn propagate into a stable one. Computed over directories, so it inherits their weakness as a unit.

Measure Value
Edges breaking the principle 49
Includes on those edges 308
Share of cross-directory includes 7.3 %
Directory Ca Ce I
system 20 1 0.05
osx 6 1 0.14
win 7 2 0.22
math 10 3 0.23
database 13 5 0.28
colorprofiles 12 6 0.33
metadata 13 7 0.35
caches 15 9 0.38
history 8 5 0.38
widgets 9 6 0.4
common 19 17 0.47
imageio 10 11 0.52
pixel 7 8 0.53
develop 13 17 0.57
control 11 16 0.59
gui 9 16 0.64
views 6 13 0.68
libs 6 15 0.71
(root) 5 14 0.74
iop 2 15 0.88
apps 0 10 1.0
tests 0 4 1.0

The application-global header

src/darktable.h is the header every fork of this codebase inherits. A .c including it is a choice local to that file; a header including it pushes the whole application into every file downstream, which is how an include graph stops being a graph and becomes a mesh.

Included by Count
Headers 0
Source files 14
Total 14

Transitive reach

Direct fan-in undercounts, and cycle counts miss this entirely. A header that only 40 files include, but which those 40 pass on, can still end up under most of the codebase. What follows is the transitive answer: how much of the tree depends on each header, and how much each translation unit drags in.

Propagation cost

Propagation cost is the mean share of the system a file can reach: the probability that a change to a random file can, in principle, reach a random other one. It is the standard summary of architectural coupling (MacCormack, Baldwin & Rusnak), and the single number this section is circling.

The core is the largest group of files that all reach one another. Being a cyclic group it has no internal layering by definition, so it can only be understood as a unit. Everything else is classified against the core's thresholds. A healthy system has a small core and a large periphery.

Measure Value
Propagation cost 3.23 %
Core size 0 files (0.0 %)
Peripheral 808
Measure Value
Files in the graph 808
Headers reaching over half the tree 9
Headers reaching over a quarter 39
Headers pulled in per source file, median 42
Headers pulled in per source file, mean 40.2
Worst 127

Headers most of the codebase depends on

Changing one of these means rebuilding, and re-reviewing, that share of the tree. This is the cost a god header imposes, and it is invisible to every cycle metric: a header can sit in no cycle at all and still be here.

Dependents Share of tree Drags in Header
536 66.3 % 0 src/win/win.h
534 66.1 % 1 src/system/macros.h
513 63.5 % 2 src/system/mem_alloc.h
464 57.4 % 0 src/system/openmp.h
450 55.7 % 4 src/system/simd.h
435 53.8 % 0 src/system/dtpthread.h
427 52.8 % 5 src/pixel/format.h
414 51.2 % 0 src/common/paths.h
411 50.9 % 7 src/common/image.h
395 48.9 % 0 src/common/logging.h
380 47.0 % 0 src/colorprofiles/profile_types.h
375 46.4 % 0 src/system/atomic.h
365 45.2 % 1 src/caches/cache.h
344 42.6 % 0 src/common/module_api.h
337 41.7 % 1 src/common/conf.h
334 41.3 % 5 src/math/math.h
322 39.9 % 6 src/math/matrices.h
316 39.1 % 12 src/caches/mipmap_cache.h
306 37.9 % 0 src/common/gui_module_api.h
306 37.9 % 8 src/colorprofiles/colorspaces.h
301 37.3 % 0 src/history/history.h
299 37.0 % 0 src/common/metadata_export.h
297 36.8 % 2 src/imageio/format/imageio_format_api.h
297 36.8 % 1 src/imageio/storage/imageio_storage_api.h
296 36.6 % 13 src/imageio/imageio_module.h
292 36.1 % 21 src/imageio/imageio_core.h
290 35.9 % 0 src/common/dlopencl.h
288 35.6 % 4 src/common/opencl.h
279 34.5 % 0 src/common/introspection.h
279 34.5 % 1 src/system/memory_arena.h

Heaviest supply lines

A header should include only what its own declarations need. Anything beyond that is a supply line its consumers never asked for and cannot see: they compile because something upstream happened to pull in what they use, and the day anyone tidies that away the breakage surfaces in a file nobody touched.

Drags in is how many headers arrive with this one. Multiplied by its dependents, it gives the file-header pairs this single header is responsible for across the tree - the weight it actually imposes, rather than how popular it is.

Burden Dependents Drags in Header
9,072 252 36 src/develop/imageop.h
8,668 197 44 src/develop/develop.h
7,398 274 27 src/develop/pixelpipe_hb.h
6,132 292 21 src/imageio/imageio_core.h
5,771 199 29 src/develop/dev_pixelpipe.h
4,704 96 49 src/develop/masks.h
4,399 83 53 src/develop/blend.h
3,952 104 38 src/develop/imageop_gui.h
3,848 296 13 src/imageio/imageio_module.h
3,792 316 12 src/caches/mipmap_cache.h
2,877 411 7 src/common/image.h
2,493 277 9 src/caches/pixelpipe_cache.h
2,448 306 8 src/colorprofiles/colorspaces.h
2,275 91 25 src/control/control.h
2,257 61 37 src/develop/imageop_math.h
2,255 41 55 src/gui/presets.h
2,247 107 21 src/libs/lib.h
2,135 427 5 src/pixel/format.h
2,115 47 45 src/gui/color_picker_proxy.h
2,106 54 39 src/common/imagebuf.h
2,052 114 18 src/views/view.h
1,932 322 6 src/math/matrices.h
1,845 41 45 src/develop/tiling.h
1,800 450 4 src/system/simd.h
1,670 334 5 src/math/math.h
1,598 94 17 src/gui/window_manager.h
1,596 84 19 src/gui/application.h
1,536 96 16 src/gui/dtgtk/thumbtable.h
1,455 97 15 src/gui/dtgtk/thumbnail.h
1,230 123 10 src/caches/image_cache.h

Translation units pulling in the most headers

Headers pulled File
127 src/darktable.c
119 src/develop/imageop.c
111 src/develop/imageop_gui.c
107 src/views/darkroom.c
106 src/iop/toneequal.c
106 src/iop/drawlayer.c
99 src/gui/application.c
99 src/develop/blend_gui.c
94 src/iop/retouch.c
94 src/iop/colorequal.c
94 src/gui/preferences.c
94 src/develop/masks/masks_gui.c
94 src/libs/histogram.c
93 src/iop/channelmixerrgb.c
93 src/libs/print_settings.c
92 src/libs/lib.c
90 src/libs/export.c
89 src/libs/masks.c
88 src/iop/rgbcurve.c
88 src/iop/colorzones.c

Header coupling

Direct fan-in: how many files include each header. This is the number behind the "included by" graphs on each file page, and the clearest single measure of how entangled the headers are. A header near the top of this table cannot be changed without rebuilding, and re-reviewing, most of the codebase.

Included by Header
264 src/system/macros.h
240 src/system/mem_alloc.h
153 src/develop/imageop.h
144 src/common/module_versioning.h
131 src/system/openmp.h
131 src/develop/develop.h
128 src/common/logging.h
123 src/common/conf.h
116 src/system/target_clones.h
116 src/widgets/bauhaus.h
103 src/develop/imageop_gui.h
93 src/caches/pixelpipe_cache_alloc.h
93 src/iop/iop_api.h
91 src/control/control.h
89 src/system/simd.h
86 src/common/image.h
86 src/widgets/widget_settings.h
83 src/gui/application.h
78 src/control/signal.h
72 src/common/opencl.h
64 src/widgets/label.h
59 src/develop/imageop_math.h
56 src/common/utility.h
53 src/widgets/widget_style.h
47 src/common/imagebuf.h
46 src/math/math.h
43 src/colorprofiles/colorspaces.h
41 src/caches/image_cache.h
41 src/common/file_location.h
41 src/database/database.h
41 src/gui/presets.h
39 src/osx/osx.h
39 src/views/view.h
39 src/gui/color_picker_proxy.h
38 src/libs/lib.h
37 src/common/collection.h
36 src/caches/mipmap_cache.h
36 src/gui/screen_metrics.h
35 src/control/user_message.h
35 src/develop/tiling.h

Symbols per file

From Doxygen's own symbol table. A file with a very large symbol count is doing more than one job; a header with one is an interface.

Measure Value
Files with symbols 805
Symbols total 27,767
Mean per file 34.5
Files with > 100 symbols 66
Files with > 50 symbols 178

Largest interfaces

Symbols Functions Variables Typedefs Macros Enums File
365 99 193 24 37 12 src/iop/ashift.c
274 56 188 16 11 3 src/iop/denoiseprofile.c
270 81 156 17 8 8 src/iop/filmicrgb.c
269 78 146 12 29 4 src/iop/channelmixerrgb.c
239 2 190 8 35 4 src/iop/highlights/common.h
222 113 87 10 8 4 src/iop/retouch.c
219 135 64 13 5 2 src/libs/collect.c
211 80 99 13 15 4 src/widgets/bauhaus.h
209 12 167 24 0 6 src/iop/drawlayer/runtime.h
206 76 116 5 8 1 src/iop/toneequal.c
200 100 82 15 1 2 src/develop/masks_gui.h
199 75 102 11 1 10 src/develop/develop.h
196 85 84 14 2 11 src/common/image.h
190 90 64 8 25 3 src/common/opencl.h
190 98 67 2 16 7 src/iop/liquify.c
176 23 108 22 18 5 src/develop/lightroom.c
174 71 70 8 22 3 src/iop/colorequal.c
168 113 46 4 2 3 src/libs/tagging.c
164 74 81 7 0 2 src/libs/print_settings.c
163 153 0 3 4 3 src/widgets/bauhaus.c
161 98 41 7 13 2 src/libs/histogram.c
160 88 60 4 7 1 src/views/map.c
154 109 23 9 13 0 src/iop/drawlayer.c
153 2 76 75 0 0 src/common/dlopencl.h
153 150 0 0 3 0 src/widgets/paint.c
150 146 0 2 1 1 src/widgets/paint.h
149 58 83 6 0 2 src/iop/clipping.c
149 33 103 6 5 2 src/iop/colorbalancergb.c
146 121 16 3 3 3 src/develop/blend_gui.c
146 42 88 10 6 0 src/iop/basecurve.c
145 123 17 3 2 0 src/develop/masks/masks_gui.c
141 72 52 10 2 5 src/develop/imageop.h
141 42 90 6 1 2 src/develop/pixelpipe_hb.h
141 93 37 6 4 1 src/widgets/accelerators.c
138 37 81 9 6 5 src/iop/demosaic.c
137 43 84 8 0 2 src/database/preset_repository.h
136 48 76 3 9 0 src/control/control.h
135 56 46 20 2 11 src/develop/masks.h
135 43 84 3 3 2 src/gui/lut_viewer.c
132 107 23 2 0 0 src/common/opencl.c
131 4 102 23 1 1 src/common/introspection.h
130 82 35 8 4 1 src/iop/drawlayer/worker.c
126 89 29 5 2 1 src/caches/pixelpipe_cache.c
126 107 14 5 0 0 src/common/image.c
126 48 64 7 3 4 src/views/view.h
125 55 47 8 12 3 src/iop/colorzones.c
120 35 70 11 3 1 src/iop/colorreconstruction.c
120 65 46 7 1 1 src/libs/geotagging.c
120 75 37 3 5 0 src/views/darkroom.c
117 10 103 4 0 0 src/develop/blend_gui.h
117 44 56 9 3 5 src/iop/colorbalance.c
117 47 52 8 7 3 src/iop/rawdenoiseai.c
115 53 54 6 1 1 src/iop/lens.cc
115 37 61 10 5 2 src/iop/tonecurve.c
114 51 45 7 9 2 src/iop/colorprimaries.c
113 95 15 0 3 0 src/colorprofiles/colorspaces.c
113 40 60 9 3 1 src/iop/crystgrain.c
111 63 44 2 1 1 src/develop/supervisor.c
106 45 55 5 1 0 src/iop/filmic.c
105 56 37 6 3 3 src/control/jobs/control_jobs.c

The complete per-file table is in code-health.json, published next to this page.

Modularity

Do the folders correspond to how the code is actually coupled?

The directory layout is treated as a proposed grouping of the dependency graph and scored with Newman modularity Q - the share of edges falling inside groups, minus what random wiring of the same degrees would give. Then a grouping is derived from the graph itself, with Louvain, and scored the same way.

The gap is the answer. If directories really were modules, grouping by directory would be near-optimal and the gap would be small. A large gap means the code does cluster - just not along the lines it is filed under.

Measure Value
Q of the directory layout 0.113
Q of the derived grouping 0.35
Gap 0.236
Directories 22
Derived clusters 74
Files whose directory matches their cluster 449 (55.6 %)
Includes staying inside one directory 1,176 of 5,449 (21.6 %)

Largest derived clusters, in files: 193, 179, 48, 45, 41, 36, 31, 12, 11, 9

How to read this, and how not to

Modularity rewards COMMUNITY structure - groups with dense internal and sparse external links. A well-layered codebase is not community-structured, it is hierarchical, and the two are different shapes. A leaf library factored out precisely so that everything can use it has, by construction, almost all its edges crossing a boundary, and Q marks it down for exactly the property that makes it good design.

So a lower Q is not automatically worse, and this metric should not be read as a verdict the way the cycle and reach figures can be. What it does say reliably is the GAP: both scores here are far below the 0.3 that usually indicates real community structure, while the derived grouping clears it. The code clusters; the folders are not where it clusters. That holds whichever tree is measured, and it is the honest form of the observation that src/ subdirectories are drawers rather than modules.

Header self-containment

Every header compiled on its own, as a translation unit containing nothing but an include of itself. A header that fails is relying on whoever includes it having pulled something in first - the dependency is real and written nowhere, and it breaks the day someone tidies an include in a file that never mentioned this header.

X-macro headers are excluded: they are re-included several times in one translation unit with different macros defined, so compiling one alone is not a question that applies.

Measure Value
Headers checked 315
Self-contained 276
Share 87.6 %
Failing 39
Header First error
src/apps/ansel-chart/colorchart.h /home/runner/work/ansel/ansel/src/apps/ansel-chart/colorchart.h:44:3: error: unknown type name 'dt_aligned_pixel_t'
src/apps/ansel-chart/common.h /home/runner/work/ansel/ansel/src/apps/ansel-chart/colorchart.h:44:3: error: unknown type name 'dt_aligned_pixel_t'
src/apps/ansel-chart/dtcairo.h /home/runner/work/ansel/ansel/src/apps/ansel-chart/colorchart.h:44:3: error: unknown type name 'dt_aligned_pixel_t'
src/common/curl_tools.h /home/runner/work/ansel/ansel/src/common/curl_tools.h:32:31: error: unknown type name 'gboolean'
src/common/metadata_export.h /home/runner/work/ansel/ansel/src/common/metadata_export.h:46:3: error: unknown type name 'int32_t'
src/common/srgb_tone_curve_values.h /home/runner/work/ansel/ansel/src/common/srgb_tone_curve_values.h:23:14: error: unknown type name 'uint16_t'
src/common/times.h /home/runner/work/ansel/ansel/src/common/times.h:46:23: error: 'NULL' undeclared (first use in this function)
src/config.cmake.h /home/runner/work/ansel/ansel/src/config.cmake.h:111:2: error: invalid preprocessing directive cmakedefine
src/gui/drag_and_drop.h /home/runner/work/ansel/ansel/src/gui/drag_and_drop.h:43:14: error: unknown type name 'GtkTargetEntry'
src/gui/dtgtk/preview_window.h /home/runner/work/ansel/ansel/src/gui/dtgtk/preview_window.h:22:36: error: unknown type name 'int32_t'
src/gui/hist_dialog.h /home/runner/work/ansel/ansel/src/gui/hist_dialog.h:32:28: error: unknown type name 'dt_history_copy_item_t'
src/gui/preferences.h /home/runner/work/ansel/ansel/src/gui/preferences.h:33:1: error: unknown type name 'GtkWidget'
src/gui/preferences_dialogs.h /home/runner/work/ansel/ansel/src/gui/preferences_dialogs.h:29:1: error: unknown type name 'GtkWidget'
src/gui/styles.h /home/runner/work/ansel/ansel/src/gui/styles.h:29:31: error: unknown type name 'int32_t'
src/imageio/imageio_avif.h /home/runner/work/ansel/ansel/src/imageio/imageio_avif.h:33:71: error: unknown type name 'dt_colorspaces_cicp_t'; did yo
src/iop/Permutohedral.h /home/runner/work/ansel/ansel/src/iop/Permutohedral.h:64:10: fatal error: algorithm: No such file or directory
src/iop/drawlayer/coordinates.h /home/runner/work/ansel/ansel/src/iop/drawlayer/coordinates.h:26:1: error: unknown type name 'gboolean'
src/iop/drawlayer/module.h /home/runner/work/ansel/ansel/src/iop/drawlayer/coordinates.h:26:1: error: unknown type name 'gboolean'
src/iop/drawlayer/runtime.h /home/runner/work/ansel/ansel/src/iop/drawlayer/coordinates.h:26:1: error: unknown type name 'gboolean'
src/iop/drawlayer/worker.h /home/runner/work/ansel/ansel/src/iop/drawlayer/worker.h:47:31: error: unknown type name 'dt_iop_module_t'
src/iop/equalizer_eaw.h /home/runner/work/ansel/ansel/src/iop/equalizer_eaw.h:51:50: error: 'size_t' undeclared (first use in this function)
src/iop/highlights/gather.h /home/runner/work/ansel/ansel/src/iop/highlights/gather.h:82:71: error: unknown type name 'dt_aligned_pixel_t'
src/iop/highlights/inpaint.h /home/runner/work/ansel/ansel/src/iop/highlights/inpaint.h:64:78: error: unknown type name 'dt_iop_roi_t'
src/iop/highlights/selftests.h /home/runner/work/ansel/ansel/src/iop/highlights/selftests.h:31:65: error: unknown type name 'dt_dev_pixelpipe_t'
src/iop/noise_generator.h /home/runner/work/ansel/ansel/src/math/openmp_maths.h:71:1: error: expected '=', ',', ';', 'asm' or 'attribute' befo
src/libs/colorpicker.h /home/runner/work/ansel/ansel/src/libs/colorpicker.h:50:9: error: unknown type name 'dt_aligned_pixel_t'
src/math/openmp_maths.h /home/runner/work/ansel/ansel/src/math/openmp_maths.h:71:1: error: expected '=', ',', ';', 'asm' or 'attribute' befo
src/pixel/heal.h /home/runner/work/ansel/ansel/src/pixel/heal.h:50:1: error: unknown type name 'cl_int'
src/pixel/illuminants.h /home/runner/work/ansel/ansel/src/pixel/illuminants.h:341:30: error: incompatible type for argument 2 of 'dt_store_simd_
src/pixel/locallaplaciancl.h /home/runner/work/ansel/ansel/src/pixel/locallaplaciancl.h:46:3: error: unknown type name 'size_t'

Documentation coverage

Symbols carrying a brief or detailed description, from Doxygen's own record. A low figure is not automatically bad - self-explanatory code needs no prose - but it bounds how much of the API can be understood without reading its implementation.

Measure Value
Symbols 27,767
Documented 4,918
Coverage 17.7 %
Kind Symbols Documented Coverage
function 15,177 4,136 27.3 %
variable 9,197 471 5.1 %
typedef 1,610 217 13.5 %
macro definition 1,369 40 2.9 %
enumeration 414 54 13.0 %

Files with the most undocumented symbols:

Undocumented of File
363 365 src/iop/ashift.c
272 274 src/iop/denoiseprofile.c
264 270 src/iop/filmicrgb.c
264 269 src/iop/channelmixerrgb.c
239 239 src/iop/highlights/common.h
219 222 src/iop/retouch.c
217 219 src/libs/collect.c
209 211 src/widgets/bauhaus.h
208 209 src/iop/drawlayer/runtime.h
201 206 src/iop/toneequal.c
174 176 src/develop/lightroom.c
173 190 src/iop/liquify.c
168 174 src/iop/colorequal.c
166 168 src/libs/tagging.c
164 164 src/libs/print_settings.c
160 160 src/views/map.c
157 199 src/develop/develop.h
156 200 src/develop/masks_gui.h
155 161 src/libs/histogram.c
153 153 src/common/dlopencl.h
149 149 src/iop/colorbalancergb.c
147 149 src/iop/clipping.c
145 146 src/iop/basecurve.c
141 163 src/widgets/bauhaus.c
141 146 src/develop/blend_gui.c

Change history

Process metrics, over the last 365 days. These predict defects better than static complexity does, and nothing else in this panel can see them: they are not a property of the code as it stands but of how it got there. Complex code nobody touches is harmless; complex code changed weekly is where bugs live.

Measure Value
Commits 2,519
Files touched 1,432
Lines added + deleted 536,142
Authors per file, mean 1.18
Authors per file, most 3
Files with a single author 1,190

Hotspots

Revisions multiplied by cyclomatic complexity. This is the prioritisation metric: what to refactor first, rather than what is merely large. A file high on this list is both hard to reason about and constantly being reasoned about.

Score Revisions CCN Churn File
116,166 114 1,019 22,880 src/iop/drawlayer.c
108,647 119 913 5,873 src/develop/blend_gui.c
108,468 138 786 7,787 src/develop/masks/polygon.c
98,832 213 464 9,216 src/views/darkroom.c
94,374 147 642 8,050 src/develop/masks/brush.c
87,980 106 830 3,418 src/iop/ashift.c
87,234 217 402 6,150 src/develop/develop.c
80,104 124 646 6,103 src/iop/channelmixerrgb.c
73,472 224 328 10,884 src/develop/pixelpipe_hb.c
73,161 99 739 3,121 src/iop/retouch.c
64,262 127 506 5,286 src/develop/dev_history.c
58,089 201 289 15,830 src/develop/masks/masks.c
56,522 59 958 5,165 src/develop/masks/masks_gui.c
56,277 111 507 2,884 src/iop/toneequal.c
52,954 83 638 1,247 src/iop/liquify.c
49,536 96 516 3,834 src/libs/histogram.c
48,133 127 379 3,979 src/develop/dev_pixelpipe.c
47,464 68 698 2,440 src/common/opencl.c
47,151 93 507 3,879 src/iop/filmicrgb.c
44,928 156 288 4,586 src/develop/imageop.c
44,744 94 476 3,020 src/common/image.c
40,044 71 564 1,026 src/iop/clipping.c
35,872 118 304 4,578 src/develop/masks/ellipse.c
33,354 109 306 3,958 src/develop/masks/gradient.c
29,150 50 583 6,454 src/libs/collect.c

Change coupling

Files that keep being changed together. Some of these pairs have no include edge between them at all, which is coupling no static analysis can find - a shared assumption, a duplicated constant, two halves of one idea kept in step by hand. Confidence is how often the rarer of the two changes brings the other with it.

Commits touching more than 20 files are left out of these counts: a sweeping rename couples everything it touches to everything else, which says nothing about the code.

88 pairs meet the threshold (5+ shared commits, 40%+ confidence).

Together Confidence Pair
75 65 % src/develop/masks.h <-> src/develop/masks/masks.c
75 54 % src/develop/masks/brush.c <-> src/develop/masks/polygon.c
68 61 % src/develop/masks/circle.c <-> src/develop/masks/ellipse.c
64 54 % src/develop/masks/brush.c <-> src/develop/masks/ellipse.c
63 57 % src/develop/masks/brush.c <-> src/develop/masks/circle.c
62 42 % src/develop/masks/brush.c <-> src/develop/masks/masks.c
61 56 % src/develop/masks/ellipse.c <-> src/develop/masks/gradient.c
56 63 % src/develop/develop.c <-> src/develop/develop.h
55 50 % src/develop/masks/circle.c <-> src/develop/masks/gradient.c
55 47 % src/develop/masks.h <-> src/develop/masks/brush.c
53 45 % src/develop/masks/ellipse.c <-> src/develop/masks/polygon.c
53 45 % src/develop/masks/ellipse.c <-> src/develop/masks/masks.c
51 47 % src/develop/masks/brush.c <-> src/develop/masks/gradient.c
50 45 % src/develop/masks/circle.c <-> src/develop/masks/polygon.c
50 43 % src/develop/masks.h <-> src/develop/masks/ellipse.c
49 79 % src/develop/pixelpipe_cache.c <-> src/develop/pixelpipe_cache.h
49 45 % src/develop/masks/gradient.c <-> src/develop/masks/polygon.c
49 44 % src/develop/masks/circle.c <-> src/develop/masks/masks.c
34 60 % src/develop/pixelpipe_hb.c <-> src/develop/pixelpipe_hb.h
33 41 % src/develop/masks/brush.c <-> src/develop/masks/group.c
28 45 % src/develop/pixelpipe_cache.h <-> src/develop/pixelpipe_hb.c
21 72 % src/develop/dev_history.c <-> src/develop/dev_history.h
20 62 % src/develop/blend.h <-> src/develop/blend_gui.c
17 71 % src/develop/dev_pixelpipe.c <-> src/develop/dev_pixelpipe.h
17 59 % src/common/image.c <-> src/common/image.h

Most revised files

Revisions Churn File
224 10,884 src/develop/pixelpipe_hb.c
217 6,150 src/develop/develop.c
213 9,216 src/views/darkroom.c
201 15,830 src/develop/masks/masks.c
156 4,586 src/develop/imageop.c
147 8,050 src/develop/masks/brush.c
146 7,492 src/develop/pixelpipe_cache.c
138 7,787 src/develop/masks/polygon.c
127 3,979 src/develop/dev_pixelpipe.c
127 5,286 src/develop/dev_history.c
124 6,103 src/iop/channelmixerrgb.c
119 5,873 src/develop/blend_gui.c
118 4,578 src/develop/masks/ellipse.c
116 3,118 src/develop/masks.h
114 22,880 src/iop/drawlayer.c

Static analysis

cppcheck

Severity Findings
style 433
error 225
warning 19
portability 6
information 3
Findings Rule
203 unknownMacro
112 constVariablePointer
81 constParameterPointer
79 cstyleCast
41 constParameterCallback
26 variableScope
24 unreadVariable
21 knownConditionTrueFalse
9 nullPointerRedundantCheck
9 clarifyCalculation
8 memleak
7 constParameter
7 unusedStructMember
5 uselessAssignmentPtrArg
5 truncLongCastAssignment
5 invalidPointerCast
4 syntaxError
3 uninitvar
3 legacyUninitvar
3 redundantInitialization
3 constVariableReference
3 duplicateCondition
3 constVariable
3 unusedVariable
3 clarifyCondition

clang-tidy

Measure Value
Findings 8,549
Files with findings 268
Findings Check
3,678 bugprone-reserved-identifier
2,691 misc-unused-parameters
734 bugprone-multi-level-implicit-pointer-conversion
531 bugprone-implicit-widening-of-multiplication-result
185 misc-const-correctness
125 cert-err34-c
75 bugprone-branch-clone
63 misc-use-anonymous-namespace
61 misc-no-recursion
52 bugprone-assignment-in-if-condition
49 performance-type-promotion-in-math-fn
40 bugprone-suspicious-string-compare
38 bugprone-incorrect-roundings
37 bugprone-macro-parentheses
31 misc-misplaced-const
31 readability-non-const-parameter
28 bugprone-switch-missing-default-case
24 bugprone-integer-division
8 bugprone-suspicious-memory-comparison
8 misc-non-private-member-variables-in-classes
6 bugprone-empty-catch
6 readability-misleading-indentation
6 misc-redundant-expression
6 cert-int09-c
5 misc-use-internal-linkage

Elsewhere

SonarCloud carries the findings this panel does not: rule-level issues, duplication, cognitive complexity and technical debt, with the same third-party exclusions.