![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
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.
| 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 |
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 % |
| 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 |
| 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 |
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:
| 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 % |
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 |
| Directories | Cycle |
|---|---|
| 20 | (root), caches, colorprofiles, common, control, database, develop, gui, history, imageio, iop, libs, math, metadata, osx, pixel, system, views, widgets, win |
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 |
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 |
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 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 |
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.
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.
| 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 |
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.
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 |
The complete per-file table is in code-health.json, published next to this page.
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
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.
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' |
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 |
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 |
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 |
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).
| 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 |
| 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 |
| 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 |
SonarCloud carries the findings this panel does not: rule-level issues, duplication, cognitive complexity and technical debt, with the same third-party exclusions.