The marCCD reader read each frame's 16-bit scanlines into scratch and widened them to int32 on the worker thread (marccd::ReadInto, ~20 % of the image-loop worker CPU on 4nwv), and the 4-byte image was uploaded. ReadRawImage now reads the scanlines straight into the image's buffer and hands them over as a new read-only CompressionAlgorithm::UINT16_WIDENED (mode Int32): two bytes a pixel cross PCIe, from page-locked memory, and the preprocessing kernel widens them itself. It is not CompressedImageMode::Uint16, which calls 65535 an error pixel; a marCCD's 65535 is its saturation marker. So the kernel compares each pixel with int32's error marker and the int32 saturation cap - the comparisons are made on the pixel's value, in int64, rather than in the storage type - and decides every pixel exactly as for the int32 image the host would have widened it to. The host widening (JFJochDecompressPtr) is the CPU path. Test: ImagePreprocessorGPU_StoredEncodingsMatchCPU, with a frame carrying 65535 at a saturation of 65535, against the CPU preprocessor on the host-widened image. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EizBKhTqrAYago9KJG3dA3
17 lines
1.1 KiB
C
17 lines
1.1 KiB
C
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
// LZ4_NO_SHUFFLE is READ-ONLY: HDF5 filter 32004, plain LZ4 with no bit shuffle, written by DECTRIS
|
|
// Eiger firmware 1.x. Nothing here produces it. It is last so the values of the others do not move -
|
|
// the enum crosses the CBOR stream.
|
|
//
|
|
// CBF_BYTE_OFFSET and UINT16_WIDENED are READ-ONLY too, and never leave the process: they are how the
|
|
// miniCBF and marCCD readers hand over a frame as the file stores it, so that the GPU path can upload
|
|
// those bytes and decode them on the device. The image's mode is what they decode to (Int32). CBF_BYTE_OFFSET
|
|
// is the x-CBF_BYTE_OFFSET payload; UINT16_WIDENED is unsigned 16-bit pixels, each one the int32 of the
|
|
// same value - which is not CompressedImageMode::Uint16, whose largest value means an error pixel.
|
|
enum class CompressionAlgorithm {BSHUF_LZ4, BSHUF_ZSTD, BSHUF_ZSTD_RLE, BSHUF_ZSTD_RLE_HUFF, NO_COMPRESSION,
|
|
LZ4_NO_SHUFFLE, CBF_BYTE_OFFSET, UINT16_WIDENED};
|