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 808
Lines of code 339,687
Comment lines 85,649
Blank lines 63,868
Comment ratio 20.1 %
Language Files Code Comment
C 441 304,633 56,832
C/C++ Header 357 27,609 27,465
C++ 9 7,216 1,308
Objective-C++ 1 229 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,693
Total CCN 65,657
Mean CCN 5.17
Median CCN 2
90th percentile 11
99th percentile 44
Maximum CCN 189
Mean function length (NLOC) 23.3
Threshold Functions Share
CCN > 15 (worth refactoring) 780 6.1 %
CCN > 25 (hard to test) 340 2.7 %
CCN > 50 88 0.7 %
CCN > 100 17 0.1 %
Longer than 100 lines 445 3.5 %
Longer than 300 lines 40 0.3 %
More than 7 parameters 463 3.6 %

Most complex functions

CCN NLOC Params Function File
189 812 5 process src/iop/cacorrect.c
188 604 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
162 657 3 dt_init src/darktable.c
152 571 1 main src/apps/ansel-cli/main.c
136 158 3 gui_changed src/iop/channelmixerrgb.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 312 5 mouse_moved src/iop/clipping.c
111 337 3 _cf_stage_cl_selftest src/iop/highlights/selftests.c
110 568 11 _aniso_stage_cl src/iop/highlights/chroma.c
110 342 5 xtrans_markesteijn_interpolate src/iop/demosaic/markesteijn.c
107 493 8 pixelpipe_process_on_GPU src/develop/pixelpipe_gpu.c
106 308 3 strptime src/win/strptime.c
105 346 6 _sp_chol_factor_cl src/math/sparse_cholesky_cl.h
98 535 8 process_markesteijn_cl src/iop/demosaic/markesteijn.c
97 532 0 polar_decomposition src/math/polar_decomposition.h
95 301 7 _hl_knee_estimate src/iop/highlights/knee.c
93 286 0 dtwin_get_locale src/win/dtwin.c
92 393 12 write_image src/imageio/format/tiff.c
89 387 5 dt_develop_blend_process_cl src/develop/blend.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 229 6 _polygon_crop_to_roi src/develop/masks/polygon.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 494 4 dt_opencl_device_init src/common/opencl.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
77 219 3 _selfdome_stage_cl_selftest src/iop/highlights/selftests.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
76 184 3 _joint_core_stage_cl_selftest src/iop/highlights/selftests.c
75 304 7 _polygon_get_mask_roi src/develop/masks/polygon.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
657 162 dt_init src/darktable.c
604 188 _cf_reconstruct src/iop/highlights/coefficient_field.c
603 80 dt_iop_tonecurve_draw src/iop/filmicrgb.c
571 152 main src/apps/ansel-cli/main.c
568 110 _aniso_stage_cl src/iop/highlights/chroma.c
535 98 process_markesteijn_cl src/iop/demosaic/markesteijn.c
532 97 polar_decomposition src/math/polar_decomposition.h
494 79 dt_opencl_device_init src/common/opencl.c
493 107 pixelpipe_process_on_GPU src/develop/pixelpipe_gpu.c
492 163 _lrop src/develop/lightroom.c
471 80 process_harmonic_cl src/iop/highlights/process.c
414 132 get_query_string src/database/collection_query.c
410 77 _cf_harmonic_fill_cl_n src/iop/highlights/coefficient_field.c
400 3 gui_init src/iop/channelmixerrgb.c
393 92 write_image src/imageio/format/tiff.c
393 20 gui_init src/libs/print_settings.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 851 21
Dependency edges 5,810 198
Cycles 0 1
Units caught in a cycle 0 20
Backward dependencies 0 52
Includes on them 0 343
Share of all includes 0.0 % 7.8 %

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 < history < osx < widgets < common < control < (root) < pixel < views < imageio < develop < gui < libs < iop < apps

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

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 311
Share of cross-directory includes 7.0 %
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 12 5 0.29
colorprofiles 12 6 0.33
metadata 12 7 0.37
caches 15 9 0.38
history 8 5 0.38
widgets 9 6 0.4
common 18 17 0.49
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 11 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 19
Total 19

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.13 %
Core size 0 files (0.0 %)
Peripheral 851
Measure Value
Files in the graph 851
Headers reaching over half the tree 10
Headers reaching over a quarter 40
Headers pulled in per source file, median 43
Headers pulled in per source file, mean 40.6
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
570 67.0 % 0 src/win/win.h
568 66.7 % 1 src/system/macros.h
544 63.9 % 2 src/system/mem_alloc.h
494 58.0 % 0 src/system/openmp.h
480 56.4 % 4 src/system/simd.h
470 55.2 % 0 src/common/paths.h
458 53.8 % 0 src/system/dtpthread.h
456 53.6 % 5 src/pixel/format.h
437 51.4 % 0 lensserious_vendor.h
436 51.2 % 8 src/common/image.h
423 49.7 % 0 src/common/logging.h
399 46.9 % 0 src/colorprofiles/profile_types.h
397 46.7 % 0 src/system/atomic.h
385 45.2 % 1 src/caches/cache.h
361 42.4 % 0 src/common/module_api.h
358 42.1 % 2 src/common/conf.h
352 41.4 % 5 src/math/math.h
340 40.0 % 6 src/math/matrices.h
333 39.1 % 13 src/caches/mipmap_cache.h
326 38.3 % 0 src/common/gui_module_api.h
324 38.1 % 8 src/colorprofiles/colorspaces.h
320 37.6 % 0 src/history/history.h
317 37.3 % 0 src/common/metadata_export.h
315 37.0 % 1 src/imageio/storage/imageio_storage_api.h
315 37.0 % 2 src/imageio/format/imageio_format_api.h
314 36.9 % 13 src/imageio/imageio_module.h
310 36.4 % 22 src/imageio/imageio_core.h
309 36.3 % 0 src/common/dlopencl.h
307 36.1 % 5 src/common/opencl.h
301 35.4 % 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,990 270 37 src/develop/imageop.h
9,315 207 45 src/develop/develop.h
8,204 293 28 src/develop/pixelpipe_hb.h
6,820 310 22 src/imageio/imageio_core.h
6,270 209 30 src/develop/dev_pixelpipe.h
4,329 333 13 src/caches/mipmap_cache.h
4,251 109 39 src/develop/imageop_gui.h
4,165 85 49 src/develop/blend.h
4,082 314 13 src/imageio/imageio_module.h
3,488 436 8 src/common/image.h
2,691 299 9 src/caches/pixelpipe_cache.h
2,592 324 8 src/colorprofiles/colorspaces.h
2,322 86 27 src/control/control.h
2,310 105 22 src/libs/lib.h
2,300 50 46 src/gui/color_picker_proxy.h
2,280 456 5 src/pixel/format.h
2,280 60 38 src/develop/imageop_math.h
2,200 55 40 src/common/imagebuf.h
2,185 115 19 src/views/view.h
2,091 41 51 src/gui/presets.h
2,040 340 6 src/math/matrices.h
1,920 480 4 src/system/simd.h
1,886 41 46 src/develop/tiling.h
1,785 35 51 src/develop/masks.h
1,764 98 18 src/gui/window_manager.h
1,760 352 5 src/math/math.h
1,740 87 20 src/gui/application.h
1,700 100 17 src/gui/dtgtk/thumbtable.h
1,616 101 16 src/gui/dtgtk/thumbnail.h
1,535 307 5 src/common/opencl.h

Translation units pulling in the most headers

Headers pulled File
127 src/darktable.c
118 src/develop/imageop.c
115 src/develop/imageop_gui.c
113 src/views/darkroom.c
110 src/iop/toneequal.c
108 src/iop/drawlayer.c
104 src/develop/blend_gui.c
102 src/develop/masks/masks_gui.c
101 src/gui/application.c
101 src/iop/retouch.c
98 src/iop/colorequal.c
97 src/libs/histogram.c
93 src/libs/shape_manager.c
91 src/gui/preferences.c
91 src/libs/print_settings.c
91 src/views/studio_capture.c
90 src/iop/channelmixerrgb.c
89 src/develop/develop.c
89 src/libs/lib.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
273 src/system/macros.h
254 src/system/mem_alloc.h
159 src/develop/imageop.h
144 src/common/module_versioning.h
142 src/develop/develop.h
132 src/common/logging.h
132 src/system/openmp.h
127 src/common/conf.h
118 src/widgets/bauhaus.h
116 src/system/target_clones.h
108 src/develop/imageop_gui.h
95 src/caches/pixelpipe_cache_alloc.h
95 src/widgets/widget_settings.h
93 src/iop/iop_api.h
90 src/system/simd.h
87 src/common/image.h
86 src/gui/application.h
86 src/control/control.h
81 src/control/signal.h
73 src/common/opencl.h
69 src/common/paths.h
64 src/widgets/label.h
60 src/widgets/accelerators.h
58 src/develop/imageop_math.h
56 src/common/utility.h
54 src/widgets/widget_style.h
51 src/math/math.h
48 src/common/imagebuf.h
43 src/colorprofiles/colorspaces.h
42 src/caches/image_cache.h
42 src/osx/osx.h
42 src/database/database.h
41 src/common/file_location.h
41 src/gui/presets.h
39 src/views/view.h
39 src/libs/lib.h
39 src/gui/color_picker_proxy.h
38 src/common/collection.h
37 src/system/dtpthread.h
37 src/control/user_message.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 848
Symbols total 29,754
Mean per file 35.1
Files with > 100 symbols 71
Files with > 50 symbols 186

Largest interfaces

Symbols Functions Variables Typedefs Macros Enums File
372 105 194 24 37 12 src/iop/ashift.c
291 88 155 14 30 4 src/iop/channelmixerrgb.c
289 137 116 19 9 8 src/iop/retouch.c
274 56 188 16 11 3 src/iop/denoiseprofile.c
274 82 158 17 9 8 src/iop/filmicrgb.c
265 4 206 8 43 4 src/iop/highlights/common.h
242 181 54 5 2 0 src/develop/masks/masks_gui.c
226 11 181 26 2 6 src/iop/drawlayer/runtime.h
225 114 90 17 1 3 src/develop/masks_gui.h
220 136 64 13 5 2 src/libs/collect.c
211 80 99 13 15 4 src/widgets/bauhaus.h
208 78 116 5 8 1 src/iop/toneequal.c
204 79 103 11 1 10 src/develop/develop.h
201 87 85 15 2 12 src/common/image.h
198 102 71 2 16 7 src/iop/liquify.c
194 92 66 8 25 3 src/common/opencl.h
176 23 108 22 18 5 src/develop/lightroom.c
175 93 63 11 3 5 src/iop/lens.c
174 71 70 8 22 3 src/iop/colorequal.c
167 112 46 4 2 3 src/libs/tagging.c
164 116 37 10 1 0 src/iop/drawlayer.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
159 48 101 7 1 2 src/develop/pixelpipe_hb.h
157 65 84 6 0 2 src/iop/clipping.c
154 126 17 3 5 3 src/develop/blend_gui.c
153 2 76 75 0 0 src/common/dlopencl.h
152 149 0 0 3 0 src/widgets/paint.c
151 106 33 6 3 3 src/libs/shape_manager.c
149 75 56 11 2 5 src/develop/imageop.h
149 33 103 6 5 2 src/iop/colorbalancergb.c
149 145 0 2 1 1 src/widgets/paint.h
146 42 88 10 6 0 src/iop/basecurve.c
144 114 27 3 0 0 src/common/opencl.c
144 40 83 10 6 5 src/iop/demosaic.c
142 93 38 6 4 1 src/widgets/accelerators.c
139 84 46 4 5 0 src/views/darkroom.c
138 100 30 5 2 1 src/caches/pixelpipe_cache.c
137 43 84 8 0 2 src/database/preset_repository.h
135 113 16 6 0 0 src/common/image.c
135 43 84 3 3 2 src/gui/lut_viewer.c
134 81 40 8 4 1 src/iop/drawlayer/worker.c
131 4 102 23 1 1 src/common/introspection.h
130 45 72 4 9 0 src/control/control.h
128 82 36 6 4 0 src/develop/masks/brush.c
127 49 64 7 3 4 src/views/view.h
125 55 47 8 12 3 src/iop/colorzones.c
123 53 46 16 1 7 src/develop/masks.h
120 12 104 4 0 0 src/develop/blend_gui.h
120 35 70 11 3 1 src/iop/colorreconstruction.c
120 46 59 9 5 1 src/iop/crystgrain.c
120 65 46 7 1 1 src/libs/geotagging.c
117 44 56 9 3 5 src/iop/colorbalance.c
117 47 52 8 7 3 src/iop/rawdenoiseai.c
115 37 61 10 5 2 src/iop/tonecurve.c
114 96 15 0 3 0 src/colorprofiles/colorspaces.c
114 51 45 7 9 2 src/iop/colorprimaries.c
113 50 49 7 5 2 src/iop/splittoningrgb.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.118
Q of the derived grouping 0.346
Gap 0.228
Directories 21
Derived clusters 70
Files whose directory matches their cluster 485 (57.0 %)
Includes staying inside one directory 1,278 of 5,810 (22.0 %)

Largest derived clusters, in files: 195, 111, 83, 79, 49, 48, 32, 26, 19, 17

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 29,754
Documented 5,721
Coverage 19.2 %
Kind Symbols Documented Coverage
function 16,269 4,727 29.1 %
variable 9,856 564 5.7 %
typedef 1,732 275 15.9 %
macro definition 1,458 86 5.9 %
enumeration 439 69 15.7 %

Files with the most undocumented symbols:

Undocumented of File
369 372 src/iop/ashift.c
286 289 src/iop/retouch.c
277 291 src/iop/channelmixerrgb.c
272 274 src/iop/denoiseprofile.c
268 274 src/iop/filmicrgb.c
265 265 src/iop/highlights/common.h
218 220 src/libs/collect.c
218 226 src/iop/drawlayer/runtime.h
209 211 src/widgets/bauhaus.h
201 208 src/iop/toneequal.c
179 198 src/iop/liquify.c
174 176 src/develop/lightroom.c
170 242 src/develop/masks/masks_gui.c
168 174 src/iop/colorequal.c
165 167 src/libs/tagging.c
164 164 src/libs/print_settings.c
162 225 src/develop/masks_gui.h
160 160 src/views/map.c
158 204 src/develop/develop.h
155 161 src/libs/histogram.c
153 153 src/common/dlopencl.h
152 157 src/iop/clipping.c
149 149 src/iop/colorbalancergb.c
147 154 src/develop/blend_gui.c
145 151 src/libs/shape_manager.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 3,204
Files touched 1,535
Lines added + deleted 620,295
Authors per file, mean 1.25
Authors per file, most 4
Files with a single author 1,184

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
141,680 140 1,012 24,630 src/iop/drawlayer.c
133,665 105 1,273 8,424 src/develop/masks/masks_gui.c
124,200 135 920 6,286 src/develop/blend_gui.c
118,570 167 710 9,905 src/develop/masks/polygon.c
116,466 177 658 12,199 src/develop/masks/brush.c
114,114 231 494 9,634 src/views/darkroom.c
103,806 237 438 6,722 src/develop/develop.c
99,199 227 437 17,492 src/develop/masks/masks.c
97,104 136 714 6,793 src/iop/channelmixerrgb.c
95,988 114 842 3,749 src/iop/ashift.c
89,157 113 789 5,431 src/iop/retouch.c
80,676 243 332 11,231 src/develop/pixelpipe_hb.c
70,065 135 519 5,589 src/develop/dev_history.c
60,762 82 741 3,076 src/common/opencl.c
59,508 116 513 3,078 src/iop/toneequal.c
56,202 87 646 1,405 src/iop/liquify.c
55,942 166 337 4,939 src/develop/imageop.c
54,320 140 388 4,507 src/develop/dev_pixelpipe.c
52,400 100 524 3,979 src/libs/histogram.c
52,046 106 491 3,381 src/common/image.c
49,685 95 523 4,035 src/iop/filmicrgb.c
44,583 77 579 1,325 src/iop/clipping.c
40,004 137 292 5,030 src/develop/masks/ellipse.c
36,750 125 294 4,320 src/develop/masks/gradient.c
32,395 55 589 6,524 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.

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

Together Confidence Pair
96 57 % src/develop/masks/brush.c <-> src/develop/masks/polygon.c
85 66 % src/develop/masks/circle.c <-> src/develop/masks/ellipse.c
84 66 % src/develop/masks.h <-> src/develop/masks/masks.c
77 56 % src/develop/masks/brush.c <-> src/develop/masks/ellipse.c
76 61 % src/develop/masks/ellipse.c <-> src/develop/masks/gradient.c
76 43 % src/develop/masks/brush.c <-> src/develop/masks/masks.c
75 58 % src/develop/masks/brush.c <-> src/develop/masks/circle.c
69 55 % src/develop/masks/circle.c <-> src/develop/masks/gradient.c
67 49 % src/develop/masks/ellipse.c <-> src/develop/masks/polygon.c
64 47 % src/develop/masks/ellipse.c <-> src/develop/masks/masks.c
63 50 % src/develop/masks/brush.c <-> src/develop/masks/gradient.c
63 49 % src/develop/masks.h <-> src/develop/masks/brush.c
63 49 % src/develop/masks/circle.c <-> src/develop/masks/polygon.c
62 62 % src/develop/develop.c <-> src/develop/develop.h
62 50 % src/develop/masks/gradient.c <-> src/develop/masks/polygon.c
60 47 % src/develop/masks/circle.c <-> src/develop/masks/masks.c
57 45 % src/develop/masks.h <-> src/develop/masks/ellipse.c
53 42 % src/develop/masks/gradient.c <-> src/develop/masks/masks.c
49 79 % src/develop/pixelpipe_cache.c <-> src/develop/pixelpipe_cache.h
41 62 % src/develop/pixelpipe_hb.c <-> src/develop/pixelpipe_hb.h
40 43 % src/develop/masks/brush.c <-> src/develop/masks/group.c
38 40 % src/develop/masks/group.c <-> src/develop/masks/masks.c
28 45 % src/develop/pixelpipe_cache.h <-> src/develop/pixelpipe_hb.c
24 73 % src/develop/dev_history.c <-> src/develop/dev_history.h
21 60 % src/develop/blend.h <-> src/develop/blend_gui.c

Most revised files

Revisions Churn File
243 11,231 src/develop/pixelpipe_hb.c
237 6,722 src/develop/develop.c
231 9,634 src/views/darkroom.c
227 17,492 src/develop/masks/masks.c
177 12,199 src/develop/masks/brush.c
167 9,905 src/develop/masks/polygon.c
166 4,939 src/develop/imageop.c
146 7,492 src/develop/pixelpipe_cache.c
140 24,630 src/iop/drawlayer.c
140 4,507 src/develop/dev_pixelpipe.c
137 5,030 src/develop/masks/ellipse.c
136 6,793 src/iop/channelmixerrgb.c
135 5,589 src/develop/dev_history.c
135 6,286 src/develop/blend_gui.c
129 3,566 src/develop/masks/circle.c

Static analysis

cppcheck

Severity Findings
style 416
error 221
warning 15
portability 6
information 3
Findings Rule
207 unknownMacro
111 constVariablePointer
81 cstyleCast
66 constParameterPointer
41 constParameterCallback
28 variableScope
24 knownConditionTrueFalse
22 unreadVariable
9 clarifyCalculation
7 constParameter
6 nullPointerRedundantCheck
5 syntaxError
5 unusedStructMember
5 truncLongCastAssignment
5 invalidPointerCast
4 uselessAssignmentPtrArg
3 uninitvar
3 constVariable
3 unusedVariable
3 clarifyCondition
2 legacyUninitvar
2 redundantAssignment
2 identicalConditionAfterEarlyExit
2 checkLevelNormal
2 duplicateCondition

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.