Update ArRecorder to append metadata and depth image to jpg

This commit is contained in:
Georg Hagen
2025-05-19 20:58:05 +02:00
parent 8716857efe
commit 257430da1d
3 changed files with 35 additions and 19 deletions

View File

@@ -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<ArFrame>& 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);
}
}
}

View File

@@ -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<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool saveAux);

View File

@@ -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<uint8_t>& exifTag) const
void WriteExifTag(const std::span<const uint8_t>& 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<uint8_t>& imageData)
void WriteImageData(const std::span<uint8_t>& 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; }
};
}