Files
OpenVulkano/openVulkanoCpp/Image/ExifBuilder.hpp
2025-08-12 14:55:55 +02:00

95 lines
2.6 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <vector>
#include <string>
#include <stdint.h>
#include <ctime>
#include <optional>
#include <variant>
namespace OpenVulkano::Image
{
struct RationalValue
{
uint32_t nominator;
uint32_t denominator;
RationalValue() : nominator(0), denominator(0) {}
explicit RationalValue(float val) : nominator(val * 10000), denominator(10000) {}
explicit RationalValue(double val) : nominator(val * 10000), denominator(10000) {}
explicit RationalValue(uint32_t nominator, uint32_t denominator = 1) : nominator(nominator), denominator(denominator) {}
operator bool() const { return nominator || denominator; }
RationalValue& operator =(float val) { nominator = val * 10000; denominator = 10000; return *this; }
RationalValue& operator =(uint32_t val) { nominator = val; denominator = 1; return *this; }
RationalValue& operator =(const RationalValue& val) = default;
};
enum class LatitudeRef
{
NORTH,
SOUTH,
};
enum class LongitudeRef
{
EAST,
WEST,
};
enum class GPSTrackRef
{
TRUE_NORTH,
MAGNETIC
};
struct GPSCoords
{
int32_t degrees, minutes, seconds;
std::variant<LatitudeRef, LongitudeRef> ref;
GPSCoords(float decimalDegrees, bool isLatitude);
GPSCoords(int32_t degrees, int32_t minutes, int32_t seconds, LatitudeRef ref);
GPSCoords(int32_t degrees, int32_t minutes, int32_t seconds, LongitudeRef ref);
};
struct GPSInfo
{
GPSCoords latitude = { 0, 0, 0, LatitudeRef::NORTH };
GPSCoords longitude = { 0, 0, 0, LongitudeRef::EAST };
bool altitudeIsAboveSeaLevel = true;
uint32_t altitude = 0;
GPSTrackRef trackRef = GPSTrackRef::TRUE_NORTH;
float track = 0; // range is [0.0; 360.0)
void SetAltitude(float level);
};
class ExifBuilder
{
public:
int orientation = 0;
std::string make;
std::string model;
RationalValue xResolution, yResolution;
int resolutionUnit = 0;
RationalValue exposureTime, fNumber, focalLength;
std::string dateTaken; // format: yyyy:mm:dd hh:mm:ss
std::string softwareUsed = "OpenVulkano";
std::optional<GPSInfo> gpsInfo;
void SetResolution(uint32_t dpi = 72) { xResolution = yResolution = dpi; resolutionUnit = 2;}
void SetOrientation(float orientationRad);
// Typical usage is -> jpeg_write_marker(cinfo, JPEG_APP0 + 1, exif_data.data(), exif_data.size());
[[nodiscard]] std::vector<uint8_t> Build();
[[nodiscard]] static std::string GetCurrentTimestamp();
};
}