marCCD frames are widened on the device
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
This commit is contained in:
@@ -38,14 +38,17 @@ class ImagePreprocessorGPU : public ImagePreprocessor {
|
||||
// Which decoder the last AnalyzeCompressed used, for GetLastDecompressionTime_s.
|
||||
enum class LastDecode { None, BSLZ4, CBF } last_decode = LastDecode::None;
|
||||
|
||||
// The file encoding of the miniCBF reader (CompressionAlgorithmEnum.h): the stored bytes are
|
||||
// uploaded, decoded into gpu_decompressed_image as the int32 image the host would have produced,
|
||||
// and preprocessed by the same kernel as an uploaded int32 image.
|
||||
// The file encodings of the miniCBF and marCCD readers (CompressionAlgorithmEnum.h): the stored
|
||||
// bytes are uploaded, decoded into gpu_decompressed_image as the int32 image the host would have
|
||||
// produced, and preprocessed by the same kernel as an uploaded int32 image.
|
||||
ImageStatistics AnalyzeStoredInt32(ImagePreprocessorBuffer &processed_image, const CompressedImage &image);
|
||||
|
||||
template <class T> ImageStatistics Analyze(ImagePreprocessorBuffer &processed_image, const uint8_t *input, T err_value, T sat_value);
|
||||
// Preprocess an image already sitting in gpu_decompressed_image (the host-upload path).
|
||||
template <class T> ImageStatistics AnalyzeOnDevice(ImagePreprocessorBuffer &processed_image, T err_value, T sat_value);
|
||||
// err_value and sat_value are compared with the pixel's value, not its bits, so a narrower T can
|
||||
// carry the int32 semantics of the image it widens to.
|
||||
template <class T> ImageStatistics AnalyzeOnDevice(ImagePreprocessorBuffer &processed_image,
|
||||
int64_t err_value, int64_t sat_value);
|
||||
// Preprocess straight out of the bitshuffled bytes (the device-decode path). Same per-pixel
|
||||
// decision and same statistics as AnalyzeOnDevice, with the un-transpose folded in.
|
||||
template <class T, int ES> ImageStatistics UntransposeAndAnalyze(ImagePreprocessorBuffer &processed_image,
|
||||
|
||||
Reference in New Issue
Block a user