diff --git a/frame_serialize/JFJochFrameSerializer.cpp b/frame_serialize/JFJochFrameSerializer.cpp index 5dbd51ac..51d59eb8 100644 --- a/frame_serialize/JFJochFrameSerializer.cpp +++ b/frame_serialize/JFJochFrameSerializer.cpp @@ -82,8 +82,8 @@ inline void CBOR_ENC_MULTIDIM_TYPED_ARRAY(CborEncoder &encoder, const char* key, const void *image, size_t image_size, size_t xpixel, size_t ypixel, CompressionAlgorithm algorithm, size_t elem_size, bool elem_sign) { - if ((algorithm == CompressionAlgorithm::NO_COMPRESSION) && (xpixel * ypixel != image_size / elem_size)) - throw JFJochException(JFJochExceptionCategory::CBORError, "Mismatch in array size"); + //if ((algorithm == CompressionAlgorithm::NO_COMPRESSION) && (xpixel * ypixel != image_size / elem_size)) + // throw JFJochException(JFJochExceptionCategory::CBORError, "Mismatch in array size"); CborEncoder arrayEncoder, arrayEncoder_2; cborErr(cbor_encode_text_stringz(&encoder, key)); @@ -296,10 +296,35 @@ const uint8_t *JFJochFrameSerializer::GetBuffer() const { return buffer.data(); } +uint8_t *JFJochFrameSerializer::GetImageAppendLocation() { + return buffer.data() + curr_size + sizeof(size_t); +} + size_t JFJochFrameSerializer::GetBufferSize() const { return curr_size; } +size_t JFJochFrameSerializer::GetRemainingBuffer() const { + return max_buffer_size - curr_size; +} + +void JFJochFrameSerializer::AppendImage(size_t image_size) { + if (curr_size + image_size + sizeof(size_t) >= max_buffer_size) + throw JFJochException(JFJochExceptionCategory::CBORError, "No space to extend the image"); + curr_size--; + buffer[curr_size] = 0x40 | 27; + curr_size++; +#ifdef LITTLE_ENDIAN + size_t image_size_be = __builtin_bswap64(image_size); +#else + size_t image_size_be = image_size; +#endif + memcpy(buffer.data() + curr_size, &image_size_be, sizeof(size_t)); + curr_size += sizeof(size_t); + curr_size += image_size; +} + + void JFJochFrameSerializer::SerializeSequenceStart(const StartMessage& message) { CborEncoder encoder, mapEncoder; @@ -397,3 +422,4 @@ void JFJochFrameSerializer::SerializeImage(const DataMessage& message) { curr_size = cbor_encoder_get_buffer_size(&encoder, buffer.data()); } + diff --git a/frame_serialize/JFJochFrameSerializer.h b/frame_serialize/JFJochFrameSerializer.h index 251f407b..fc48c895 100644 --- a/frame_serialize/JFJochFrameSerializer.h +++ b/frame_serialize/JFJochFrameSerializer.h @@ -19,10 +19,14 @@ class JFJochFrameSerializer { public: explicit JFJochFrameSerializer(size_t buffer_size); [[nodiscard]] const uint8_t *GetBuffer() const; + [[nodiscard]] uint8_t *GetImageAppendLocation(); [[nodiscard]] size_t GetBufferSize() const; + [[nodiscard]] size_t GetRemainingBuffer() const; void SerializeSequenceStart(const StartMessage& message); void SerializeSequenceEnd(const EndMessage& message); void SerializeImage(const DataMessage& message); + void AppendImage(size_t image_size); + }; diff --git a/tests/CBORTest.cpp b/tests/CBORTest.cpp index b22bb1dc..e82c91a6 100644 --- a/tests/CBORTest.cpp +++ b/tests/CBORTest.cpp @@ -254,6 +254,54 @@ TEST_CASE("CBORSerialize_Image_2", "[CBOR]") { REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0); } +TEST_CASE("CBORSerialize_Image_Append", "[CBOR]") { + JFJochFrameSerializer serializer(8*1024*1024); + + 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(serializer.GetImageAppendLocation(), test.data(), 512*1024); + REQUIRE_NOTHROW(serializer.AppendImage(512*1024)); + + JFJochFrameDeserializer deserializer; + REQUIRE_NOTHROW(deserializer.Process(serializer.GetBuffer(), 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]") { JFJochFrameSerializer serializer(8*1024*1024);