// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include "../frame_serialize/JFJochFrameSerializer.h" #include "../frame_serialize/JFJochFrameDeserializer.h" #include "../compression/JFJochCompressor.h" #include "stream2.h" #include "../frame_serialize/CborUtil.h" TEST_CASE("CBORSerialize_Start", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); StartMessage message { .data_file_count = 3, .detector_distance = 0.0005, .beam_center_x = 456.6, .beam_center_y = 124.3, .number_of_images = 34567, .image_size_x = 456, .image_size_y = 457, .pixel_bit_depth = 32, .pixel_signed = true, .incident_energy = 12400, .incident_wavelength = 0.988, .frame_time = 0.0001, .count_time = 0.000098, .saturation_value = 65535, .min_value = -32767, .pixel_size_x = 0.000075, .pixel_size_y = 0.000075, .sensor_thickness = 0.0005, .sensor_material = "Si", .compression_algorithm = CompressionAlgorithm::BSHUF_LZ4, .compression_block_size = 8192, .unit_cell = {45,37,45,90,108,120}, .space_group_number = 154, .max_spot_count = 250, .storage_cell_number = 16, .pixel_mask_enabled = true, .arm_date = "abc", .sample_name = "lyso", .file_prefix = "lyso1/dir/file", .channels = {"default", "sc2"}, .detector_description = "EIGER 16M", .detector_serial_number = "123", .series_unique_id = "bla", .series_id = 4567, .goniometer = {{"omega", { .increment = 0.1f, .start = 10.0f }}}, .detector_translation = {0.5f, 0.0f, 0.5f}, .source_name = "Swiss Light Source", .source_name_short = "SLS", .instrument_name = "X06SA", .instrument_name_short = "PXIII", .rad_int_bin_number = 35, .summation = 567, .rad_int_bin_to_q = {0.1, 0.2, 0.3, 0.5}, .rad_int_solid_angle_corr = {10, 20, 30, 50} }; message.pixel_mask["sc0"] = std::vector(456*457, 15); REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::START); StartMessage output_message; REQUIRE_NOTHROW(output_message = deserializer.GetStartMessage()); REQUIRE(output_message.pixel_mask.contains("sc0")); CHECK(output_message.data_file_count == message.data_file_count); CHECK(output_message.detector_distance == Approx(message.detector_distance)); CHECK(output_message.beam_center_x == Approx(message.beam_center_x)); CHECK(output_message.beam_center_y == Approx(message.beam_center_y)); CHECK(output_message.number_of_images == message.number_of_images); CHECK(output_message.image_size_x == message.image_size_x); CHECK(output_message.image_size_y == message.image_size_y); CHECK(output_message.pixel_bit_depth == message.pixel_bit_depth); CHECK(output_message.incident_energy == Approx(message.incident_energy)); CHECK(output_message.incident_wavelength == Approx(message.incident_wavelength)); CHECK(output_message.frame_time == Approx(message.frame_time)); CHECK(output_message.count_time == Approx(message.count_time)); CHECK(output_message.saturation_value == message.saturation_value); CHECK(output_message.min_value == message.min_value); CHECK(output_message.pixel_size_x == Approx(message.pixel_size_x)); CHECK(output_message.pixel_size_y == Approx(message.pixel_size_y)); CHECK(output_message.sensor_thickness == Approx(message.sensor_thickness)); CHECK(output_message.sensor_material == message.sensor_material); CHECK(output_message.pixel_mask == message.pixel_mask); CHECK(output_message.pixel_mask_enabled == message.pixel_mask_enabled); CHECK(output_message.compression_algorithm == message.compression_algorithm); CHECK(output_message.compression_block_size == message.compression_block_size); CHECK(output_message.space_group_number == message.space_group_number); CHECK(output_message.arm_date == message.arm_date); CHECK(output_message.storage_cell_number == message.storage_cell_number); CHECK(output_message.pixel_signed == message.pixel_signed); CHECK(output_message.sample_name == message.sample_name); CHECK(output_message.file_prefix == message.file_prefix); CHECK(output_message.max_spot_count == message.max_spot_count); CHECK(output_message.channels == message.channels); CHECK(output_message.detector_description == message.detector_description); CHECK(output_message.detector_serial_number == message.detector_serial_number); CHECK(output_message.series_unique_id == message.series_unique_id); CHECK(output_message.series_id == message.series_id); CHECK(output_message.source_name == message.source_name); CHECK(output_message.source_name_short == message.source_name_short); CHECK(output_message.instrument_name == message.instrument_name); CHECK(output_message.instrument_name_short == message.instrument_name_short); CHECK(output_message.rad_int_bin_number == message.rad_int_bin_number); CHECK(output_message.summation == message.summation); CHECK(output_message.rad_int_bin_to_q == message.rad_int_bin_to_q); CHECK(output_message.rad_int_solid_angle_corr == message.rad_int_solid_angle_corr); for (int i = 0; i < 3; i++) CHECK(output_message.detector_translation[i] == message.detector_translation[i]); for (int i = 0; i < 6; i++) CHECK(output_message.unit_cell[i] == message.unit_cell[i]); REQUIRE(output_message.goniometer.contains("omega")); CHECK(output_message.goniometer["omega"].increment == 0.1f); CHECK(output_message.goniometer["omega"].start == 10.0f); } TEST_CASE("CBORSerialize_End", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); EndMessage message { .number_of_images = 57789, .max_receiver_delay = 3456, .efficiency = 0.99, .write_master_file = true, .end_date = "ccc", .series_unique_id = "bla5", .series_id = 45676782 }; REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::END); EndMessage output_message{}; REQUIRE_NOTHROW(output_message = deserializer.GetEndMessage()); REQUIRE(output_message.max_receiver_delay == message.max_receiver_delay); REQUIRE(output_message.number_of_images == message.number_of_images); REQUIRE(output_message.efficiency == Approx(message.efficiency)); REQUIRE(output_message.end_date == message.end_date); REQUIRE(output_message.write_master_file == message.write_master_file); REQUIRE(output_message.series_id == message.series_id); REQUIRE(output_message.series_unique_id == message.series_unique_id); REQUIRE(output_message.rad_int_result.empty()); } TEST_CASE("CBORSerialize_End_RadIntResult", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); EndMessage message { .number_of_images = 57789, .max_receiver_delay = 3456, .efficiency = 0.99, .write_master_file = true, .end_date = "ccc", .series_unique_id = "bla5", .series_id = 45676782 }; message.rad_int_result["avg"] = {11.0, 12.0, 13.0}; message.rad_int_result["file0"] = {56.0, 75.0, 34.0}; REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::END); EndMessage output_message{}; REQUIRE_NOTHROW(output_message = deserializer.GetEndMessage()); REQUIRE(output_message.rad_int_result.size() == 2); REQUIRE(output_message.rad_int_result.contains("avg")); REQUIRE(output_message.rad_int_result.contains("file0")); CHECK(message.rad_int_result["avg"] == output_message.rad_int_result["avg"]); CHECK(message.rad_int_result["file0"] == output_message.rad_int_result["file0"]); } TEST_CASE("CBORSerialize_Image", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; std::vector test(1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image { .data = test.data(), .size = 1024, .xpixel = 256, .ypixel = 2, .pixel_depth_bytes = 2, .pixel_is_signed = true, .algorithm = CompressionAlgorithm::NO_COMPRESSION, .channel = "default" }; DataMessage message { .number = 456, .image = image, .spots = spots, .indexing_result = 1, .bunch_id = UINT64_MAX, .jf_info = UINT32_MAX, .receiver_available_send_buffers = 786.546, .receiver_aq_dev_delay = 2323, .timestamp = 1ul<<27 | 1ul <<35, .storage_cell = 0xF, .exptime = 1000, .series_unique_id = "bla2", .series_id = 4567678 }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::IMAGE); auto image_array = deserializer.GetDataMessage(); REQUIRE(image_array.image.algorithm == CompressionAlgorithm::NO_COMPRESSION); REQUIRE(image_array.image.xpixel == 256); REQUIRE(image_array.image.ypixel == 2); REQUIRE(image_array.image.pixel_depth_bytes == 2); REQUIRE(image_array.image.pixel_is_signed); REQUIRE(image_array.image.channel == "default"); REQUIRE(image_array.image.size == test.size()); REQUIRE(image_array.indexing_result == message.indexing_result); REQUIRE(image_array.number == 456); REQUIRE(image_array.series_id == message.series_id); REQUIRE(image_array.series_unique_id == message.series_unique_id); REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); REQUIRE(image_array.bunch_id == message.bunch_id); REQUIRE(image_array.jf_info == message.jf_info); REQUIRE(image_array.timestamp == message.timestamp); REQUIRE(image_array.storage_cell == message.storage_cell); REQUIRE(image_array.exptime == message.exptime); REQUIRE(image_array.receiver_available_send_buffers == image_array.receiver_available_send_buffers); REQUIRE(image_array.receiver_aq_dev_delay == image_array.receiver_aq_dev_delay); } TEST_CASE("CBORSerialize_Image_2", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; std::vector test(512*1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image { .data = test.data(), .size = 1024 * 512, .xpixel = 1024, .ypixel = 512, .pixel_depth_bytes = 1, .pixel_is_signed = false, .algorithm = CompressionAlgorithm::NO_COMPRESSION, .channel = "default" }; DataMessage message { .number = 480, .image = image, .spots = spots, .indexing_result = 3 }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::IMAGE); auto image_array = deserializer.GetDataMessage(); REQUIRE(image_array.image.algorithm == CompressionAlgorithm::NO_COMPRESSION); REQUIRE(image_array.image.xpixel == 1024); REQUIRE(image_array.image.ypixel == 512); REQUIRE(image_array.image.pixel_depth_bytes == 1); REQUIRE(!image_array.image.pixel_is_signed); REQUIRE(image_array.image.channel == "default"); REQUIRE(image_array.image.size == test.size()); REQUIRE(image_array.indexing_result == message.indexing_result); REQUIRE(image_array.receiver_available_send_buffers == message.receiver_available_send_buffers); REQUIRE(image_array.number == 480); REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); } TEST_CASE("CBORSerialize_Image_Append", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; std::vector test(512*1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image { .data = nullptr, .size = 0, .xpixel = 1024, .ypixel = 512, .pixel_depth_bytes = 1, .pixel_is_signed = false, .algorithm = CompressionAlgorithm::NO_COMPRESSION, .channel = "default" }; DataMessage message { .number = 480, .image = image, .spots = spots, .indexing_result = 3 }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); memcpy(buffer.data() + serializer.GetImageAppendOffset(), test.data(), 512*1024); REQUIRE_NOTHROW(serializer.AppendImage(512*1024)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::IMAGE); auto image_array = deserializer.GetDataMessage(); REQUIRE(image_array.image.algorithm == CompressionAlgorithm::NO_COMPRESSION); REQUIRE(image_array.image.xpixel == 1024); REQUIRE(image_array.image.ypixel == 512); REQUIRE(image_array.image.pixel_depth_bytes == 1); REQUIRE(!image_array.image.pixel_is_signed); REQUIRE(image_array.image.channel == "default"); REQUIRE(image_array.image.size == test.size()); REQUIRE(image_array.indexing_result == message.indexing_result); REQUIRE(image_array.number == 480); REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); } TEST_CASE("CBORSerialize_Image_Compressed", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; std::vector test(512); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image { .data = test.data(), .size = 512, .xpixel = 256, .ypixel = 2, .pixel_depth_bytes = 4, .pixel_is_signed = true, .algorithm = CompressionAlgorithm::BSHUF_LZ4, .channel = "default" }; DataMessage message { .number = 456, .image = image, .spots = spots }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::IMAGE); auto image_array = deserializer.GetDataMessage(); REQUIRE(image_array.image.algorithm == CompressionAlgorithm::BSHUF_LZ4); REQUIRE(image_array.image.xpixel == 256); REQUIRE(image_array.image.ypixel == 2); REQUIRE(image_array.image.pixel_depth_bytes == 4); REQUIRE(image_array.image.channel == "default"); REQUIRE(image_array.image.size == test.size()); REQUIRE(image_array.image.pixel_is_signed == true); REQUIRE(image_array.number == 456); REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); } TEST_CASE("CBORSerialize_Image_Rad_Int_Profile", "[CBOR]") { std::vector buffer(8 * 1024 * 1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector test(1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image{ .data = test.data(), .size = 1024, .xpixel = 256, .ypixel = 2, .pixel_depth_bytes = 2, .algorithm = CompressionAlgorithm::NO_COMPRESSION, .channel = "default" }; DataMessage message{ .number = 789, .image = image, .rad_int_profile = {4.0, 5.0, 7.0, 12.0, 13.25, 0.125} }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::IMAGE); auto image_array = deserializer.GetDataMessage(); REQUIRE(image_array.number == 789); REQUIRE(image_array.image.size == test.size()); REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); REQUIRE(image_array.rad_int_profile == message.rad_int_profile); } TEST_CASE("CBORSerialize_Image_Spots", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; spots.push_back(SpotToSave{.x = 7, .y = 8, .intensity = 34, .indexed = false}); spots.push_back(SpotToSave{.x = 37, .y = 48, .intensity = 123, .indexed = true}); std::vector test(1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image { .data = test.data(), .size = 1024, .xpixel = 256, .ypixel = 2, .pixel_depth_bytes = 2, .algorithm = CompressionAlgorithm::NO_COMPRESSION, .channel = "default" }; DataMessage message { .number = 789, .image = image, .spots = spots }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); JFJochFrameDeserializer deserializer; REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize())); REQUIRE(deserializer.GetType() == JFJochFrameDeserializer::Type::IMAGE); auto image_array = deserializer.GetDataMessage(); REQUIRE(image_array.number == 789); REQUIRE(image_array.image.size == test.size()); REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); REQUIRE(image_array.spots.size() == 2); REQUIRE(image_array.spots[0].intensity == 34); REQUIRE(!image_array.spots[0].indexed); REQUIRE(image_array.spots[1].x == 37); REQUIRE(image_array.spots[1].y == 48); REQUIRE(image_array.spots[1].intensity == 123); REQUIRE(image_array.spots[1].indexed); } inline bool CmpString(const char *str1, const std::string& str2) { return (strncmp(str1, str2.c_str(), str2.size()) == 0); } TEST_CASE("CBORSerialize_Start_stream2", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); StartMessage message { .data_file_count = 3, .detector_distance = 0.0005, .beam_center_x = 456.6, .beam_center_y = 124.3, .number_of_images = 34567, .image_size_x = 456, .image_size_y = 457, .pixel_bit_depth = 32, .pixel_signed = true, .incident_energy = 12400, .incident_wavelength = 0.988, .frame_time = 0.0001, .count_time = 0.000098, .saturation_value = 65535, .min_value = -32767, .pixel_size_x = 0.000075, .pixel_size_y = 0.000075, .sensor_thickness = 0.0005, .sensor_material = "Si", .compression_algorithm = CompressionAlgorithm::BSHUF_LZ4, .compression_block_size = 8192, .unit_cell = {45,37,45,90,108,120}, .space_group_number = 154, .max_spot_count = 250, .storage_cell_number = 16, .pixel_mask_enabled = true, .arm_date = "abc", .sample_name = "lyso", .file_prefix = "lyso1/dir/file", .channels = {"default", "sc2"}, .detector_description = "EIGER 16M", .detector_serial_number = "123", .series_unique_id = "bla", .series_id = 4567, .goniometer = {{"omega", { .increment = 0.1f, .start = 10.0f }}}, .detector_translation = {0.5f, 0.0f, 0.5f}, .source_name = "Swiss Light Source", .source_name_short = "SLS", .instrument_name = "X06SA", .instrument_name_short = "PXIII", .rad_int_bin_number = 35, .summation = 567 }; message.pixel_mask["sc0"] = std::vector(456*457, 15); REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message)); stream2_msg *msg; auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg); REQUIRE(ret == STREAM2_OK); CHECK(msg->type == STREAM2_MSG_START); auto msg2 = (stream2_start_msg *) msg; CHECK(msg2->beam_center_x == message.beam_center_x); CHECK(msg2->beam_center_y == message.beam_center_y); CHECK(msg2->image_size_x == message.image_size_x); CHECK(msg2->image_size_y == message.image_size_y); CHECK(msg2->series_id == message.series_id); CHECK(CmpString(msg2->series_unique_id, message.series_unique_id)); CHECK(CmpString(msg2->detector_description, message.detector_description)); CHECK(CmpString(msg2->arm_date, message.arm_date)); CHECK(msg2->number_of_images == message.number_of_images); CHECK(msg2->frame_time == message.frame_time); CHECK(msg2->count_time == message.count_time); CHECK(msg2->pixel_mask_enabled == message.pixel_mask_enabled); CHECK(msg2->pixel_mask.len == 1); CHECK(CmpString(msg2->pixel_mask.ptr[0].channel, "sc0")); CHECK(msg2->pixel_mask.ptr[0].pixel_mask.dim[0] == 457); CHECK(msg2->pixel_mask.ptr[0].pixel_mask.dim[1] == 456); CHECK(msg2->pixel_mask.ptr[0].pixel_mask.array.data.len == 456 * 457 * sizeof(uint32_t)); CHECK(memcmp(msg2->pixel_mask.ptr[0].pixel_mask.array.data.ptr, message.pixel_mask["sc0"].data(), 456 * 457 * sizeof(uint32_t)) == 0); CHECK(msg2->pixel_mask.ptr[0].pixel_mask.array.tag == TagUnsignedInt32BitLE); stream2_free_msg(msg); } TEST_CASE("CBORSerialize_End_stream2", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); EndMessage message { .number_of_images = 57789, .max_receiver_delay = 3456, .efficiency = 0.99, .write_master_file = true, .end_date = "ccc", .series_unique_id = "bla5", .series_id = 45676782 }; REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message)); stream2_msg *msg; auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg); REQUIRE(ret == STREAM2_OK); CHECK(msg->type == STREAM2_MSG_END); auto msg2 = (stream2_end_msg *) msg; CHECK(msg2->series_id == message.series_id); CHECK(CmpString(msg2->series_unique_id, message.series_unique_id)); stream2_free_msg(msg); } TEST_CASE("CBORSerialize_Image_compressed_stream2", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; std::vector test(512*1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; std::vector compressed_test(512*1024*4); JFJochBitShuffleCompressor compressor(CompressionAlgorithm::BSHUF_LZ4); size_t compressed_size = compressor.Compress(compressed_test.data(), test); CBORImage image { .data = compressed_test.data(), .size = compressed_size, .xpixel = 1024, .ypixel = 512, .pixel_depth_bytes = 2, .pixel_is_signed = false, .algorithm = CompressionAlgorithm::BSHUF_LZ4, .channel = "default" }; DataMessage message { .number = 456, .image = image, .spots = spots }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); stream2_msg *msg; auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg); REQUIRE(ret == STREAM2_OK); CHECK(msg->type == STREAM2_MSG_IMAGE); auto msg2 = (stream2_image_msg *) msg; CHECK(msg2->image_id == message.number); CHECK(msg2->data.len == 1); CHECK(CmpString(msg2->data.ptr[0].channel, "default")); CHECK(msg2->data.ptr[0].data.dim[0] == 512); CHECK(msg2->data.ptr[0].data.dim[1] == 1024); CHECK(CmpString(msg2->data.ptr[0].data.array.data.compression.algorithm, "bslz4")); CHECK(msg2->data.ptr[0].data.array.data.compression.elem_size == 2); CHECK(msg2->data.ptr[0].data.array.data.compression.orig_size == 1024 * 512 * 2); REQUIRE(msg2->data.ptr[0].data.array.data.len == compressed_size); CHECK(memcmp(msg2->data.ptr[0].data.array.data.ptr, compressed_test.data(), compressed_size) == 0); CHECK(msg2->data.ptr[0].data.array.tag == TagUnsignedInt16BitLE); CHECK(msg2->series_id == message.series_id); CHECK(CmpString(msg2->series_unique_id, message.series_unique_id)); stream2_free_msg(msg); } TEST_CASE("CBORSerialize_Image_uncompressed_stream2", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size()); std::vector spots; std::vector test(512*1024); for (int i = 0; i < test.size(); i++) test[i] = (i * 253 + 56) % 256; CBORImage image { .data = test.data(), .size = 1024 * 512, .xpixel = 1024, .ypixel = 512, .pixel_depth_bytes = 1, .pixel_is_signed = false, .algorithm = CompressionAlgorithm::NO_COMPRESSION, .channel = "default" }; DataMessage message { .number = 456, .image = image, .spots = spots }; REQUIRE_NOTHROW(serializer.SerializeImage(message)); auto cbor_image = buffer.data(); stream2_msg *msg; auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg); REQUIRE(ret == STREAM2_OK); CHECK(msg->type == STREAM2_MSG_IMAGE); auto msg2 = (stream2_image_msg *) msg; CHECK(msg2->image_id == message.number); CHECK(msg2->data.len == 1); CHECK(CmpString(msg2->data.ptr->channel, "default")); CHECK(msg2->data.ptr[0].data.array.data.compression.algorithm == nullptr); REQUIRE(msg2->data.ptr[0].data.array.data.len == 512*1024); CHECK(memcmp(msg2->data.ptr[0].data.array.data.ptr, test.data(), 512*1024) == 0); CHECK(msg2->data.ptr[0].data.array.tag == TagUnsignedInt8Bit); CHECK(msg2->series_id == message.series_id); CHECK(CmpString(msg2->series_unique_id, message.series_unique_id)); stream2_free_msg(msg); }