// Copyright (2019-2023) Paul Scherrer Institute #include #include "bitshuffle/bitshuffle.h" #include "FrameTransformation.h" #include "../common/RawToConvertedGeometry.h" #include "../common/JFJochException.h" template void FillVector(std::vector &v, T fill_value) { auto ptr = (T *) v.data(); for (int i = 0; i < v.size() / sizeof(T); i++) ptr[i] = fill_value; } FrameTransformation::FrameTransformation(const DiffractionExperiment &in_experiment) : experiment(in_experiment), pixel_depth(experiment.GetPixelDepth()), pixel_signed(experiment.IsPixelSigned()), compressor(in_experiment.GetCompressionAlgorithm()), err_value(experiment.GetPixelDepth() * RAW_MODULE_SIZE) { precompression_buffer.resize(experiment.GetPixelsNum() * pixel_depth); if (pixel_depth == 2) { if (pixel_signed) { FillVector(precompression_buffer, INT16_MIN); FillVector(err_value, INT16_MIN); } else { FillVector(precompression_buffer, UINT16_MAX); FillVector(err_value, UINT16_MAX); } } else if (pixel_depth == 4) { if (pixel_signed) { FillVector(precompression_buffer, INT32_MIN); FillVector(err_value, INT32_MIN); } else { FillVector(precompression_buffer, UINT32_MAX); FillVector(err_value, UINT32_MAX); } } } size_t FrameTransformation::CompressImage(void *output) { return compressor.Compress(output, precompression_buffer.data(), experiment.GetPixelsNum(), experiment.GetPixelDepth()); } CompressedImage FrameTransformation::GetCompressedImage() { CompressedImage image{}; if (experiment.GetCompressionAlgorithm() == CompressionAlgorithm::NO_COMPRESSION) { image.data = (uint8_t *) precompression_buffer.data(); image.size = experiment.GetPixelsNum() * experiment.GetPixelDepth(); } else { compressed_buffer.resize(MaxCompressedSize(experiment.GetCompressionAlgorithm(), experiment.GetPixelsNum(), experiment.GetPixelDepth())); image.data = (uint8_t *) compressed_buffer.data(); image.size = CompressImage(compressed_buffer.data()); } image.xpixel = experiment.GetXPixelsNum(); image.ypixel = experiment.GetYPixelsNum(); image.algorithm = experiment.GetCompressionAlgorithm(); image.pixel_depth_bytes = experiment.GetPixelDepth(); image.pixel_is_signed = pixel_signed; image.pixel_is_float = false; image.channel = "default"; return image; } void FrameTransformation::ProcessModule(const void *input, uint16_t module_number, int data_stream) { size_t module_number_abs = experiment.GetFirstModuleOfDataStream(data_stream) + module_number; if (experiment.GetDetectorMode() != DetectorMode::Conversion) { size_t mod_size = RAW_MODULE_SIZE * pixel_depth; memcpy(precompression_buffer.data() + module_number_abs * mod_size, input, mod_size); } else { if (pixel_depth == 2) { if (pixel_signed) TransferModuleAdjustMultipixels((int16_t *) precompression_buffer.data(), (int16_t *) input, experiment.GetModuleSlowDirectionStep(module_number_abs), static_cast(INT16_MIN), static_cast(INT16_MAX), experiment.GetModuleFastDirectionStep(module_number_abs), experiment.GetPixel0OfModule(module_number_abs)); else TransferModuleAdjustMultipixels((uint16_t *) precompression_buffer.data(), (uint16_t *) input, experiment.GetModuleSlowDirectionStep(module_number_abs), static_cast(0), static_cast(UINT16_MAX - 1), experiment.GetModuleFastDirectionStep(module_number_abs), experiment.GetPixel0OfModule(module_number_abs)); } else if (pixel_depth == 4) { if (pixel_signed) TransferModuleAdjustMultipixels((int32_t *) precompression_buffer.data(), (int32_t *) input, experiment.GetModuleSlowDirectionStep(module_number_abs), static_cast(INT32_MIN), static_cast(INT32_MAX), experiment.GetModuleFastDirectionStep(module_number_abs), experiment.GetPixel0OfModule(module_number_abs)); else TransferModuleAdjustMultipixels((uint32_t *) precompression_buffer.data(), (uint32_t *) input, experiment.GetModuleSlowDirectionStep(module_number_abs), static_cast(0), static_cast(UINT32_MAX - 1), experiment.GetModuleFastDirectionStep(module_number_abs), experiment.GetPixel0OfModule(module_number_abs)); } } } void FrameTransformation::ProcessModule(const DeviceOutput *output, int data_stream) { ProcessModule(output->pixels, output->module_statistics.module_number, data_stream); } const void *FrameTransformation::GetImage() const { return precompression_buffer.data(); } void FrameTransformation::FillNotCollectedModule(uint16_t module_number, int data_stream) { ProcessModule(err_value.data(), module_number, data_stream); }