Update ArRecorder to append metadata and depth image to jpg
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
#include "ArSession.hpp"
|
#include "ArSession.hpp"
|
||||||
#include "ArFrame.hpp"
|
#include "ArFrame.hpp"
|
||||||
#include "IO/Archive/MultiPartArchiveWriter.hpp"
|
#include "IO/Archive/MultiPartArchiveWriter.hpp"
|
||||||
|
#include "IO/Archive/ArchiveConfiguration.hpp"
|
||||||
#include "IO/Files/Pfm.hpp"
|
#include "IO/Files/Pfm.hpp"
|
||||||
#include "IO/Files/Pnm.hpp"
|
#include "IO/Files/Pnm.hpp"
|
||||||
#include "IO/AppFolders.hpp"
|
#include "IO/AppFolders.hpp"
|
||||||
@@ -85,7 +86,7 @@ namespace OpenVulkano::AR
|
|||||||
else m_asyncProcessor.Close();
|
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");
|
//BlockProfiler profile("Save AR Frame - Image");
|
||||||
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
|
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
|
||||||
@@ -134,13 +135,9 @@ namespace OpenVulkano::AR
|
|||||||
{
|
{
|
||||||
if (colorWriter) [[likely]]
|
if (colorWriter) [[likely]]
|
||||||
colorWriter->AddFile(fileName.c_str(), outBuffer, size);
|
colorWriter->AddFile(fileName.c_str(), outBuffer, size);
|
||||||
if (path) [[unlikely]]
|
if (jpgWriter) [[unlikely]]
|
||||||
{
|
{
|
||||||
auto exif = MakeExifTag(arFrame);
|
jpgWriter->WriteImageData({ outBuffer, size }, false); // Keep open, livetime is managed outside
|
||||||
JpegWithTagsWriter writer(*path);
|
|
||||||
writer.WriteExifTag(exif);
|
|
||||||
writer.WriteXmpTag(MakeXmpTag(arFrame));
|
|
||||||
writer.WriteImageData({ outBuffer, size });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tjFree(outBuffer);
|
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)
|
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)
|
if (includeAux)
|
||||||
{
|
{
|
||||||
auto fName = path.string();
|
FILE* file = jpgWriter.GetFilePtr();
|
||||||
fName.replace(fName.size() - 3, 3, "aux");
|
{
|
||||||
ArchiveWriter writer(fName);
|
ArchiveWriter writer(file, ArchiveConfiguration(ArchiveType::ZIP));
|
||||||
WriteMetadata(frame.get(), &writer);
|
WriteMetadata(frame.get(), &writer);
|
||||||
WriteDepthImage(frame.get(), &writer, &writer);
|
WriteDepthImage(frame.get(), &writer, &writer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace OpenVulkano
|
|||||||
class IEventHandler;
|
class IEventHandler;
|
||||||
class IArchiveWriter;
|
class IArchiveWriter;
|
||||||
class MultiPartArchiveWriter;
|
class MultiPartArchiveWriter;
|
||||||
|
class JpegWithTagsWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OpenVulkano::AR
|
namespace OpenVulkano::AR
|
||||||
@@ -100,7 +101,7 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
void Write(ArFrame* frame, bool highRes = false);
|
void Write(ArFrame* frame, bool highRes = false);
|
||||||
void WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter);
|
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 WriteDepthImage(ArFrame *arFrame, IArchiveWriter* depthWriter, IArchiveWriter* confWriter);
|
||||||
void WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool saveAux);
|
void WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool saveAux);
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace OpenVulkano
|
|||||||
// ReSharper disable once CppDFAConstantParameter
|
// ReSharper disable once CppDFAConstantParameter
|
||||||
void WriteAppMarker(const int app = 1) const
|
void WriteAppMarker(const int app = 1) const
|
||||||
{
|
{
|
||||||
|
Check();
|
||||||
// ReSharper disable once CppDFAConstantConditions
|
// ReSharper disable once CppDFAConstantConditions
|
||||||
if (app > 0xF) [[unlikely]] throw std::runtime_error("App marker is out of range.");
|
if (app > 0xF) [[unlikely]] throw std::runtime_error("App marker is out of range.");
|
||||||
fputc(0xFF, file);
|
fputc(0xFF, file);
|
||||||
@@ -72,8 +73,20 @@ namespace OpenVulkano
|
|||||||
fputc(0xFF, file);
|
fputc(0xFF, file);
|
||||||
fputc(0xD8, 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();
|
WriteAppMarker();
|
||||||
Write16(exifTag.size() + 2); // 2 byte extra for the size value itself
|
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
|
// 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();
|
Check();
|
||||||
// write image data and skip soi marker from og data
|
// write image data and skip soi marker from og data
|
||||||
fwrite(imageData.data() + 2, sizeof(uint8_t), imageData.size() - 2, file);
|
fwrite(imageData.data() + 2, sizeof(uint8_t), imageData.size() - 2, file);
|
||||||
fclose(file);
|
if (close) Close();
|
||||||
file = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const { return file != nullptr; }
|
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; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user