PreviewImage: remove mutex

This commit is contained in:
2024-05-23 22:58:52 +02:00
parent 500222bdcc
commit f85b87bfd2
10 changed files with 181 additions and 139 deletions

View File

@@ -31,28 +31,7 @@ constexpr const static rgb plotly[] = {{0x1f, 0x77, 0xb4},
constexpr const static rgb indigo = {.r = 0x3f, .g = 0x51, .b = 0xb5};
constexpr const static rgb gray = {.r = 0xbe, .g = 0xbe, .b = 0xbe};
PreviewImage::PreviewImage(const DiffractionExperiment &in_experiment) :
experiment(in_experiment),
initialized(false),
xpixel(experiment.GetXPixelsNum()),
ypixel(experiment.GetYPixelsNum()),
beam_x(experiment.GetBeamX_pxl()),
beam_y(experiment.GetBeamY_pxl()),
pixel_depth_bytes(experiment.GetPixelDepth()),
pixel_is_signed(experiment.IsPixelSigned()),
uncompressed_image(experiment.GetPixelsNum() * experiment.GetPixelDepth()),
roi_map(experiment.ROI()),
counter(experiment.GetPreviewPeriod()) {}
void PreviewImage::UpdateImage(const void *in_uncompressed_image,
const std::vector<SpotToSave> &in_spots) {
if (counter.GeneratePreview()) {
std::unique_lock<std::mutex> ul(m);
initialized = true;
memcpy(uncompressed_image.data(), in_uncompressed_image, xpixel * ypixel * pixel_depth_bytes);
spots = in_spots;
}
}
PreviewImage::PreviewImage(std::chrono::microseconds period) : counter(period) {}
void colormap(std::vector<unsigned char>& ret, float v, size_t pixel) {
if ((v < 0.0) || (v > 1.0)) {
@@ -106,55 +85,6 @@ std::vector<unsigned char> GenerateRGB(const T* value, size_t npixel, uint32_t s
return ret;
}
std::string PreviewImage::GenerateJPEG(const PreviewJPEGSettings &settings) const {
std::vector<unsigned char> v;
{
// JPEG compression is outside the critical loop protected by m
std::unique_lock<std::mutex> ul(m);
if (!initialized)
return {};
if (!pixel_is_signed) {
if (pixel_depth_bytes == 2)
v = GenerateRGB<uint16_t>((uint16_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, UINT16_MAX);
else
v = GenerateRGB<uint32_t>((uint32_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, UINT32_MAX);
} else {
if (pixel_depth_bytes == 2)
v = GenerateRGB<int16_t>((int16_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, INT16_MIN);
else
v = GenerateRGB<int32_t>((int32_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, INT32_MIN);
}
if (settings.show_spots)
AddSpots(v);
}
if (settings.show_roi)
AddROI(v);
if (settings.resolution_ring)
AddResolutionRing(v, settings.resolution_ring.value());
AddBeamCenter(v);
return WriteJPEGToMem(v, xpixel, ypixel, settings.jpeg_quality);
}
std::string PreviewImage::GenerateTIFF() const {
std::unique_lock<std::mutex> ul(m);
if (!initialized)
return {};
std::string s = WriteTIFFToString(const_cast<uint8_t *>(uncompressed_image.data()),
xpixel, ypixel, pixel_depth_bytes, pixel_is_signed);
return s;
}
template <class T>
std::vector<uint16_t> GenerateDioptasPreview(const void* input, size_t xpixel, size_t ypixel, T special_value) {
auto input_ptr = (T *) input;
@@ -174,26 +104,6 @@ std::vector<uint16_t> GenerateDioptasPreview(const void* input, size_t xpixel, s
return vec;
}
std::string PreviewImage::GenerateTIFFDioptas() const {
std::unique_lock<std::mutex> ul(m);
if (!initialized)
return {};
std::vector<uint16_t> vec;
if (pixel_is_signed) {
if (pixel_depth_bytes == 2)
vec = GenerateDioptasPreview<int16_t>(uncompressed_image.data(), xpixel, ypixel, INT16_MIN);
else
vec = GenerateDioptasPreview<int32_t>(uncompressed_image.data(), xpixel, ypixel, INT32_MIN);
} else {
if (pixel_depth_bytes == 2)
vec = GenerateDioptasPreview<uint16_t>(uncompressed_image.data(), xpixel, ypixel, UINT16_MAX);
else
vec = GenerateDioptasPreview<uint32_t>(uncompressed_image.data(), xpixel, ypixel, UINT32_MAX);
}
return WriteTIFFToString(vec.data(), xpixel, ypixel, 2, false);
}
void PreviewImage::AddBeamCenter(std::vector<uint8_t> &rgb_image) const {
size_t beam_x_int = std::lround(beam_x);
size_t beam_y_int = std::lround(beam_y);
@@ -230,7 +140,7 @@ void PreviewImage::AddSpots(std::vector<uint8_t> &rgb_image) const {
void PreviewImage::AddROI(std::vector<uint8_t> &rgb_image) const {
int64_t roi_counter = 0;
for (const auto &box: roi_map.GetROIBox()) {
for (const auto &box: experiment.ROI().GetROIBox()) {
int rectangle_width = 5;
for (auto x = box.GetXMin() - rectangle_width; x <= box.GetXMax() + rectangle_width; x++) {
@@ -249,7 +159,7 @@ void PreviewImage::AddROI(std::vector<uint8_t> &rgb_image) const {
roi_counter++;
}
for (const auto &circle: roi_map.GetROICircle()) {
for (const auto &circle: experiment.ROI().GetROICircle()) {
int width = 5;
for (int64_t y = std::floor(circle.GetY() - circle.GetRadius_pxl() - width);
@@ -281,3 +191,116 @@ void PreviewImage::AddResolutionRing(std::vector<uint8_t> &rgb_image, float d) c
}
}
}
void PreviewImage::Configure(const DiffractionExperiment &in_experiment) {
std::unique_lock<std::mutex> ul(m);
experiment = in_experiment;
initialized = false;
xpixel = experiment.GetXPixelsNum();
ypixel = experiment.GetYPixelsNum();
beam_x = experiment.GetBeamX_pxl();
beam_y = experiment.GetBeamY_pxl();
pixel_depth_bytes = experiment.GetPixelDepth();
pixel_is_signed = experiment.IsPixelSigned();
uncompressed_image.resize(experiment.GetPixelsNum() * experiment.GetPixelDepth());
memset(uncompressed_image.data(), 0, experiment.GetPixelsNum() * experiment.GetPixelDepth());
}
void PreviewImage::Configure() {
std::unique_lock<std::mutex> ul(m);
initialized = false;
xpixel = 0;
ypixel = 0;
}
void PreviewImage::UpdateImage(const void *in_uncompressed_image,
const std::vector<SpotToSave> &in_spots) {
if (counter.GeneratePreview()) {
std::unique_lock<std::mutex> ul(m);
if (xpixel * ypixel == 0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Preview not configured");
initialized = true;
memcpy(uncompressed_image.data(), in_uncompressed_image, xpixel * ypixel * pixel_depth_bytes);
spots = in_spots;
}
}
std::string PreviewImage::GenerateJPEG(const PreviewJPEGSettings &settings) const {
std::vector<unsigned char> v;
size_t local_xpixel;
size_t local_ypixel;
{
// JPEG compression is outside the critical loop protected by m
std::unique_lock<std::mutex> ul(m);
local_xpixel = xpixel;
local_ypixel = ypixel;
if (!initialized)
return {};
if (!pixel_is_signed) {
if (pixel_depth_bytes == 2)
v = GenerateRGB<uint16_t>((uint16_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, UINT16_MAX);
else
v = GenerateRGB<uint32_t>((uint32_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, UINT32_MAX);
} else {
if (pixel_depth_bytes == 2)
v = GenerateRGB<int16_t>((int16_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, INT16_MIN);
else
v = GenerateRGB<int32_t>((int32_t *) uncompressed_image.data(), xpixel * ypixel,
settings.saturation_value, INT32_MIN);
}
if (settings.show_spots)
AddSpots(v);
if (settings.show_roi)
AddROI(v);
if (settings.resolution_ring)
AddResolutionRing(v, settings.resolution_ring.value());
AddBeamCenter(v);
}
return WriteJPEGToMem(v, local_xpixel, local_ypixel, settings.jpeg_quality);
}
std::string PreviewImage::GenerateTIFF() const {
std::unique_lock<std::mutex> ul(m);
if (!initialized)
return {};
std::string s = WriteTIFFToString(const_cast<uint8_t *>(uncompressed_image.data()),
xpixel, ypixel, pixel_depth_bytes, pixel_is_signed);
return s;
}
std::string PreviewImage::GenerateTIFFDioptas() const {
std::unique_lock<std::mutex> ul(m);
if (!initialized)
return {};
std::vector<uint16_t> vec;
if (pixel_is_signed) {
if (pixel_depth_bytes == 2)
vec = GenerateDioptasPreview<int16_t>(uncompressed_image.data(), xpixel, ypixel, INT16_MIN);
else
vec = GenerateDioptasPreview<int32_t>(uncompressed_image.data(), xpixel, ypixel, INT32_MIN);
} else {
if (pixel_depth_bytes == 2)
vec = GenerateDioptasPreview<uint16_t>(uncompressed_image.data(), xpixel, ypixel, UINT16_MAX);
else
vec = GenerateDioptasPreview<uint32_t>(uncompressed_image.data(), xpixel, ypixel, UINT32_MAX);
}
return WriteTIFFToString(vec.data(), xpixel, ypixel, 2, false);
}