diff --git a/openVulkanoCpp/AR/ArRecorder.cpp b/openVulkanoCpp/AR/ArRecorder.cpp index 32a0bdb..ec93f81 100644 --- a/openVulkanoCpp/AR/ArRecorder.cpp +++ b/openVulkanoCpp/AR/ArRecorder.cpp @@ -8,6 +8,7 @@ #include "ArSession.hpp" #include "ArFrame.hpp" #include "IO/Archive/MultiPartArchiveWriter.hpp" +#include "IO/Archive/ArchiveConfiguration.hpp" #include "IO/Files/Pfm.hpp" #include "IO/Files/Pnm.hpp" #include "IO/AppFolders.hpp" @@ -85,7 +86,7 @@ namespace OpenVulkano::AR else m_asyncProcessor.Close(); } - void ArRecorder::WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const + void ArRecorder::WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, JpegWithTagsWriter* jpgWriter, bool highRes) const { //BlockProfiler profile("Save AR Frame - Image"); std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg"); @@ -134,13 +135,9 @@ namespace OpenVulkano::AR { if (colorWriter) [[likely]] colorWriter->AddFile(fileName.c_str(), outBuffer, size); - if (path) [[unlikely]] + if (jpgWriter) [[unlikely]] { - auto exif = MakeExifTag(arFrame); - JpegWithTagsWriter writer(*path); - writer.WriteExifTag(exif); - writer.WriteXmpTag(MakeXmpTag(arFrame)); - writer.WriteImageData({ outBuffer, size }); + jpgWriter->WriteImageData({ outBuffer, size }, false); // Keep open, livetime is managed outside } } tjFree(outBuffer); @@ -302,14 +299,18 @@ namespace OpenVulkano::AR void ArRecorder::WriteToFile(const std::shared_ptr& frame, const std::filesystem::path& path, bool downsample, bool includeAux) { - WriteColorImage(frame.get(), nullptr, &path, !downsample); + JpegWithTagsWriter jpgWriter(path); + jpgWriter.WriteExifTag(MakeExifTag(frame.get())); + jpgWriter.WriteXmpTag(MakeXmpTag(frame.get())); + WriteColorImage(frame.get(), nullptr, &jpgWriter, !downsample); if (includeAux) { - auto fName = path.string(); - fName.replace(fName.size() - 3, 3, "aux"); - ArchiveWriter writer(fName); - WriteMetadata(frame.get(), &writer); - WriteDepthImage(frame.get(), &writer, &writer); + FILE* file = jpgWriter.GetFilePtr(); + { + ArchiveWriter writer(file, ArchiveConfiguration(ArchiveType::ZIP)); + WriteMetadata(frame.get(), &writer); + WriteDepthImage(frame.get(), &writer, &writer); + } } } diff --git a/openVulkanoCpp/AR/ArRecorder.hpp b/openVulkanoCpp/AR/ArRecorder.hpp index a33d4f2..96c61d7 100644 --- a/openVulkanoCpp/AR/ArRecorder.hpp +++ b/openVulkanoCpp/AR/ArRecorder.hpp @@ -24,6 +24,7 @@ namespace OpenVulkano class IEventHandler; class IArchiveWriter; class MultiPartArchiveWriter; + class JpegWithTagsWriter; } namespace OpenVulkano::AR @@ -100,7 +101,7 @@ namespace OpenVulkano::AR void Write(ArFrame* frame, bool highRes = false); void WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter); - void WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const; + void WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, JpegWithTagsWriter* jpgWriter, bool highRes) const; void WriteDepthImage(ArFrame *arFrame, IArchiveWriter* depthWriter, IArchiveWriter* confWriter); void WriteToFile(const std::shared_ptr& frame, const std::filesystem::path& path, bool downsample, bool saveAux); diff --git a/openVulkanoCpp/Image/JpegWithTagsWriter.hpp b/openVulkanoCpp/Image/JpegWithTagsWriter.hpp index 382df75..cfd2985 100644 --- a/openVulkanoCpp/Image/JpegWithTagsWriter.hpp +++ b/openVulkanoCpp/Image/JpegWithTagsWriter.hpp @@ -36,6 +36,7 @@ namespace OpenVulkano // ReSharper disable once CppDFAConstantParameter void WriteAppMarker(const int app = 1) const { + Check(); // ReSharper disable once CppDFAConstantConditions if (app > 0xF) [[unlikely]] throw std::runtime_error("App marker is out of range."); fputc(0xFF, file); @@ -72,8 +73,20 @@ namespace OpenVulkano fputc(0xFF, file); fputc(0xD8, file); } + + ~JpegWithTagsWriter() + { + if (file) Close(); + } + + void Close() + { + if (!file) throw std::runtime_error("Jpeg file alreay closed!"); + fclose(file); + file = nullptr; + } - void WriteExifTag(const std::span& exifTag) const + void WriteExifTag(const std::span& exifTag) const { WriteAppMarker(); Write16(exifTag.size() + 2); // 2 byte extra for the size value itself @@ -91,17 +104,18 @@ namespace OpenVulkano } // Must be called as last function, as this will finalize the image writing and will close the file - void WriteImageData(const std::span& imageData) + void WriteImageData(const std::span& imageData, bool close = true) { Check(); // write image data and skip soi marker from og data fwrite(imageData.data() + 2, sizeof(uint8_t), imageData.size() - 2, file); - fclose(file); - file = nullptr; + if (close) Close(); } operator bool() const { return file != nullptr; } - bool IsOpen() const { return file != nullptr; } + [[nodiscard]] bool IsOpen() const { return file != nullptr; } + + [[nodiscard]] FILE* GetFilePtr() const { return file; } }; }