Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

raw denoise: X-Trans green sensels in the last column get a red neighbor's value

Open Beginner friendly
#22,455 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
c

Research direction

Start in src/iop/rawdenoise.c at the green pass in wavelet_denoise_xtrans(), especially lines 356 and 398-414, and reproduce the integration test from src/tests/integration with the supplied XMP and comparison command. Ensure last-column green sensels retain their own transformed values, then confirm the low-threshold comparison reports zero changed sensels and that the normal-strength export no longer has the erroneous values.

Written by the indexing model from the issue text.

Description

Is there an existing issue for this?
  • I checked and did not find my issue in the already reported ones
Describe the bug

With raw denoise enabled on an X-Trans image, some green sensels in the last column leave the module with the value of a neighboring red sensel. At a noise threshold of 1e-6, where the module returns all other sensels nearly unchanged, 1228 sensels of the integration test image change by more than 0.2% of the full range. All of them are in the last column, one row in three. At the test's normal strength, the wrong values spread over the rightmost 39 columns of the export. It does not depend on the thread count.

Steps to reproduce
  1. In a darktable checkout with the src/tests/integration submodule, run cd src/tests/integration.
  2. Save the attached rawdenoise-low-threshold.xmp in that directory. It is the history of test 0068 with the raw denoise noise threshold set to 1e-6.
  3. Run OMP_NUM_THREADS=1 darktable-cli images/mire1-xtrans.raf rawdenoise-low-threshold.xmp /tmp/low.png --core --disable-opencl -t 1 --configdir /tmp/dt-low --dump-pipe rawdenoise.
  4. Note the directory in the log line [init] darktable dump directory is '...'.
  5. In that directory, run compare -metric AE -fuzz 0.2% export/0000_rawdenoise_cpu_in.pgm export/0001_rawdenoise_cpu_out.pgm /tmp/diff.png. It prints 1228. All the marked sensels in /tmp/diff.png are in column 6251, in rows 2, 5, 8 and so on.
Expected behavior

Each green sensel is denoised from green values only.

Logfile | Screenshot | Screencast

Input and output of three changed sensels, from the dumps in step 5:

sensel (row, col)   input   output   red neighbor with the output value
(2, 6251)           2807    2049     (3, 6251) = 2049
(5, 6251)           2721    2115     (5, 6250) = 2114
(8, 6251)           2884    2310     (9, 6251) = 2310
Commit

Not bisected. The last-column code came with c61568e7a3 (#7202, 2020), which set out to fill the edge columns.

Where did you obtain darktable from?

self compiled

darktable version

5.7.0+1090~gd060937f63-dirty

What OS are you using?

Linux

What is the version of your OS?

Ubuntu 26.04.1 LTS

Describe your system

AMD Ryzen 5 5600X (6 cores, 12 threads), 62 GiB RAM, glibc 2.43, GTK 3.24.52, GraphicsMagick 1.3.46. Only darktable-cli was used.

Are you using OpenCL GPU in darktable?

No

If yes, what is the GPU card and driver?

No response

Please provide additional context if applicable. You can attach files too, but might need to rename to .txt or .zip
  • Other versions: not tried. The runs used master fa3fc72294. The printed version belongs to the build tree, which is one commit later and differs from master only in src/common/darktable.c. The runs linked that file from master.
  • RAW or JPEG: X-Trans raw only.
  • Fresh edit: the history is the XMP of integration test 0068 with one parameter changed.
  • Empty config dir: yes.
  • Lua: none.
  • -t 1 keeps separate thread-count defects in the same loop (#22456, #22457). With -t 4 and -t 5, the same 1391 green positions are affected.

Cause (confirmed). In the green pass of wavelet_denoise_xtrans(), a green sensel in the last column whose left neighbor is not green is never written into the plane. The main loop stops at width-2 (src/iop/rawdenoise.c:356), and neither branch of the last-column code (:398-414) handles a green sensel in the green pass. The plane buffer serves all three channels (:316), so that position keeps the red plane's value. Confirmed with a build that fills the plane with NaN before each pass: 1391 positions stay NaN, all green sensels in column 6251. Writing the sensel's own value there (else if(c == 1) fimgp[width-1] = vstransform(inp[width-1]); after :414) brings the count in step 5 to 0. It changes 13952 pixels of the normal-strength export, by up to 11/255. Which rows are hit depends on which column of the CFA pattern ends the image: one row in three, two in three, or none.

Found and reproduced by an AI agent (Claude). Not yet reproduced by a human.

Dominant language
C
Stars
13.1k
Forks
1.4k
Avg merge
1d 27m
Merged PRs (30d)
200

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from darktable-org/darktable

All issues in darktable-org/darktable

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.