You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 and more than one thread, some pixels near the image edge depend on memory that darktable never wrote. On the image of integration test 0068 with -t 4, making glibc fill new allocations with a pattern (MALLOC_PERTURB_=129) changes 8231 pixels of the export, by up to 141/255. The changes form three areas of about 40×100 pixels at the right edge, around rows 1044, 2088 and 3132. The first one is a blue and black block (attached crop). With -t 1 the same test changes nothing.
Steps to reproduce
In a darktable checkout with the src/tests/integration submodule, run cd src/tests/integration.
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.
Empty config dir: yes, a new --configdir for every run.
Without MALLOC_PERTURB_, repeated exports are identical, and the damage is small: -t 4 differs from -t 1 in 326 pixels, by up to 10/255, at the same places. MALLOC_PERTURB_ is a glibc feature. I did not check what other platforms' allocators return here.
Cause (confirmed).wavelet_denoise_xtrans() builds each color plane in row chunks, and the last row of a chunk skips its red and blue copies into the row below (src/iop/rawdenoise.c:380). For this image, position (first row of the next chunk, width-2) then gets no value in the red plane, because the last-column code (:398-403) and the repair loop (:422) do not reach it. The plane keeps what the buffer held there: memory from dt_alloc_align_float() (:316) in the red pass, or the previous channel's plane in the blue pass. Confirmed with a build that fills the plane with NaN before each pass: with -t 4, red-plane positions (1044, 6250), (2088, 6250) and (3132, 6250) stay NaN, and with -t 1 no red or blue position does. Building the plane in a single chunk (nthreads = 1 at :338) removes the effect. A replay of the loop shows the same gap at column 1 for other CFA alignments, which this image does not have.
Related: a separate report on the same boundaries, where concurrent chunks overwrite green values and the export changes with the thread count.
Found and reproduced by an AI agent (Claude). Not yet reproduced by a human.
Is there an existing issue for this?
Describe the bug
With raw denoise enabled on an X-Trans image and more than one thread, some pixels near the image edge depend on memory that darktable never wrote. On the image of integration test 0068 with
-t 4, making glibc fill new allocations with a pattern (MALLOC_PERTURB_=129) changes 8231 pixels of the export, by up to 141/255. The changes form three areas of about 40×100 pixels at the right edge, around rows 1044, 2088 and 3132. The first one is a blue and black block (attached crop). With-t 1the same test changes nothing.Steps to reproduce
src/tests/integrationsubmodule, runcd src/tests/integration.OMP_NUM_THREADS=4 darktable-cli images/mire1-xtrans.raf 0068-rawdenoise-xtrans/rawdenoise-xtrans.xmp /tmp/a.png --core --disable-opencl -t 4 --configdir /tmp/dt-a.OMP_NUM_THREADS=4 MALLOC_PERTURB_=129 darktable-cli images/mire1-xtrans.raf 0068-rawdenoise-xtrans/rawdenoise-xtrans.xmp /tmp/b.png --core --disable-opencl -t 4 --configdir /tmp/dt-b.compare -metric AE /tmp/a.png /tmp/b.png null:. It prints8231./tmp/b.pngat the right edge, around rows 990-1100. It shows a blue and black block that/tmp/a.pngdoes not have.Expected behavior
The export does not depend on the contents of newly allocated memory.
Logfile | Screenshot | Screencast
200×200 crop at x=6052, y=944, 3× enlarged: step 2 left, step 3 right:
Commit
Not bisected. The skipped copy that causes it came with c61568e (#7202, 2020).
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
fa3fc72294. The printed version belongs to the build tree, which is one commit later and differs from master only insrc/common/darktable.c. The runs linked that file from master.--configdirfor every run.OMP_NUM_THREADSmatches-tbecause on master, darktable-cli crashes on X-Trans images with-tbelow the CPU count (darktable-cli:-t Nbelow the CPU count corrupts the heap #22436, fix in common: restore OpenMP thread limit after GraphicsMagick init #22438).MALLOC_PERTURB_, repeated exports are identical, and the damage is small:-t 4differs from-t 1in 326 pixels, by up to 10/255, at the same places.MALLOC_PERTURB_is a glibc feature. I did not check what other platforms' allocators return here.Cause (confirmed).
wavelet_denoise_xtrans()builds each color plane in row chunks, and the last row of a chunk skips its red and blue copies into the row below (src/iop/rawdenoise.c:380). For this image, position(first row of the next chunk, width-2)then gets no value in the red plane, because the last-column code (:398-403) and the repair loop (:422) do not reach it. The plane keeps what the buffer held there: memory fromdt_alloc_align_float()(:316) in the red pass, or the previous channel's plane in the blue pass. Confirmed with a build that fills the plane with NaN before each pass: with-t 4, red-plane positions (1044, 6250), (2088, 6250) and (3132, 6250) stay NaN, and with-t 1no red or blue position does. Building the plane in a single chunk (nthreads = 1at:338) removes the effect. A replay of the loop shows the same gap at column 1 for other CFA alignments, which this image does not have.Related: a separate report on the same boundaries, where concurrent chunks overwrite green values and the export changes with the thread count.
Found and reproduced by an AI agent (Claude). Not yet reproduced by a human.