diff --git a/frame_serialize/JFJochFrameDeserializer.cpp b/frame_serialize/JFJochFrameDeserializer.cpp index 72574490..226c13b0 100644 --- a/frame_serialize/JFJochFrameDeserializer.cpp +++ b/frame_serialize/JFJochFrameDeserializer.cpp @@ -422,6 +422,20 @@ bool JFJochFrameDeserializer::ProcessImageMessageElement(CborValue &value) { } } +void JFJochFrameDeserializer::ProcessCalibration(CborValue &value) { + CborValue map_value; + cborErr(cbor_value_enter_container(&value, &map_value)); + while (! cbor_value_at_end(&map_value)) { + auto key = GetCBORString(map_value); + CBORImage image; + image.channel = key; + GetCBORMultidimTypedArray(image, map_value); + start_message.calibration.push_back(image); + } + cborErr(cbor_value_leave_container(&value, &map_value)); + +} + void JFJochFrameDeserializer::ProcessPixelMaskElement(CborValue &value) { CborValue map_value; cborErr(cbor_value_enter_container(&value, &map_value)); @@ -547,6 +561,8 @@ void JFJochFrameDeserializer::ProcessStartMessageUserDataElement(CborValue &valu throw JFJochException(JFJochExceptionCategory::CBORError, "Unsupported compression"); } else if (key == "compression_block_size") start_message.compression_block_size = GetCBORUInt(map_value); + else if (key == "calibration") + ProcessCalibration(map_value); else cbor_value_advance(&map_value); } diff --git a/frame_serialize/JFJochFrameDeserializer.h b/frame_serialize/JFJochFrameDeserializer.h index e78ce8d0..748b1948 100644 --- a/frame_serialize/JFJochFrameDeserializer.h +++ b/frame_serialize/JFJochFrameDeserializer.h @@ -36,6 +36,7 @@ private: GoniometerAxis ProcessGoniometer(CborValue &value); void ProcessDetTranslation(CborValue &value); + void ProcessCalibration(CborValue &value); void ProcessChannels(CborValue &value); void ProcessImageData(CborValue &value); void ProcessPixelMaskElement(CborValue &value); diff --git a/frame_serialize/JFJochFrameSerializer.cpp b/frame_serialize/JFJochFrameSerializer.cpp index 92747332..832eee07 100644 --- a/frame_serialize/JFJochFrameSerializer.cpp +++ b/frame_serialize/JFJochFrameSerializer.cpp @@ -265,11 +265,21 @@ inline void CBOR_ENC_UNIT_CELL(CborEncoder &encoder, const char* key, const floa cborErr(cbor_encoder_close_container(&encoder, &mapEncoder)); } +inline void CBOR_ENC(CborEncoder &encoder, const char* key, const std::vector &v) { + CborEncoder mapEncoder; + + cborErr(cbor_encode_text_stringz(&encoder, key)); + cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, v.size())); + for (const auto &i: v) + CBOR_ENC_2D_TYPED_ARRAY(mapEncoder, i); + cborErr(cbor_encoder_close_container(&encoder, &mapEncoder)); +} + inline void CBOR_ENC_USER_DATA(CborEncoder &encoder, const StartMessage& message) { CborEncoder mapEncoder; cborErr(cbor_encode_text_stringz(&encoder, "user_data")); - cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 20)); + cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 21)); CBOR_ENC(mapEncoder, "file_prefix", message.file_prefix); CBOR_ENC(mapEncoder, "sample_name", message.sample_name); @@ -304,6 +314,7 @@ inline void CBOR_ENC_USER_DATA(CborEncoder &encoder, const StartMessage& message CBOR_ENC(mapEncoder, "rad_int_bin_to_q", message.rad_int_bin_to_q); CBOR_ENC(mapEncoder, "rad_int_solid_angle_corr", message.rad_int_solid_angle_corr); CBOR_ENC(mapEncoder, "summation", message.summation); + CBOR_ENC(mapEncoder, "calibration", message.calibration); cborErr(cbor_encoder_close_container(&encoder, &mapEncoder)); } diff --git a/frame_serialize/StartMessage.h b/frame_serialize/StartMessage.h index 870cdff9..cfa11c94 100644 --- a/frame_serialize/StartMessage.h +++ b/frame_serialize/StartMessage.h @@ -9,6 +9,7 @@ #include #include #include "../compression/CompressionAlgorithmEnum.h" +#include "ImageMessage.h" struct GoniometerAxis { float increment; @@ -80,6 +81,8 @@ struct StartMessage { std::vector rad_int_bin_to_q; std::vector rad_int_solid_angle_corr; + + std::vector calibration; }; #endif //JUNGFRAUJOCH_STARTMESSAGE_H diff --git a/tests/CBORTest.cpp b/tests/CBORTest.cpp index e2fdc3ab..a335a211 100644 --- a/tests/CBORTest.cpp +++ b/tests/CBORTest.cpp @@ -127,6 +127,69 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") { } + +TEST_CASE("CBORSerialize_Start_Calibration", "[CBOR]") { + std::vector buffer(8*1024*1024); + JFJochFrameSerializer serializer(buffer.data(), buffer.size()); + + std::vector calib1(256); + std::vector calib2(256); + + for (int i = 0; i < 256; i++) { + calib1[i] = i * 34.567; + calib2[i] = i * 76.33456; + } + + CBORImage image1 { + .data = reinterpret_cast(calib1.data()), + .size = 16 * 16 * sizeof(float), + .xpixel = 16, + .ypixel = 16, + .pixel_depth_bytes = 4, + .pixel_is_signed = true, + .pixel_is_float = true, + .algorithm = CompressionAlgorithm::NO_COMPRESSION, + .channel = "calib1" + }; + + + CBORImage image2 { + .data = reinterpret_cast(calib2.data()), + .size = 16 * 16 * sizeof(float), + .xpixel = 16, + .ypixel = 16, + .pixel_depth_bytes = 4, + .pixel_is_signed = true, + .pixel_is_float = true, + .algorithm = CompressionAlgorithm::NO_COMPRESSION, + .channel = "calib2" + }; + + StartMessage message { + .calibration = {image2, image1} + }; + + 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.calibration.size() == 2); + CHECK(output_message.calibration[0].pixel_is_float); + CHECK(output_message.calibration[1].pixel_is_float); + CHECK(output_message.calibration[0].xpixel == 16); + CHECK(output_message.calibration[0].ypixel == 16); + CHECK(output_message.calibration[1].xpixel == 16); + CHECK(output_message.calibration[1].ypixel == 16); + CHECK(output_message.calibration[0].channel == "calib2"); + CHECK(output_message.calibration[1].channel == "calib1"); + CHECK(memcmp(output_message.calibration[0].data, calib2.data(), 256 * sizeof(float)) == 0); + CHECK(memcmp(output_message.calibration[1].data, calib1.data(), 256 * sizeof(float)) == 0); +} + TEST_CASE("CBORSerialize_End", "[CBOR]") { std::vector buffer(8*1024*1024); JFJochFrameSerializer serializer(buffer.data(), buffer.size());