Writing x/y resolution and exposureTime properly, storing Track direction
This commit is contained in:
@@ -127,6 +127,16 @@ namespace
|
||||
return result;
|
||||
}
|
||||
|
||||
int appendRational(std::vector<uint8_t>& array, const OpenVulkano::Image::RationalValue& rational, bool endianSwap = false)
|
||||
{
|
||||
int result = array.size();
|
||||
|
||||
appendU32(array, rational.nominator, endianSwap);
|
||||
appendU32(array, rational.denominator, endianSwap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int appendGPSCoords(std::vector<uint8_t>& array, const OpenVulkano::Image::GPSCoords& coords, bool endianSwap = false)
|
||||
{
|
||||
int result = array.size();
|
||||
@@ -210,30 +220,42 @@ namespace OpenVulkano::Image
|
||||
}
|
||||
|
||||
// XResolution
|
||||
int xresolutionOffset = 0;
|
||||
if(xresolution.nominator || xresolution.denominator)
|
||||
{
|
||||
appendU16(result, (uint16_t)IFDTag::XRESOLUTION, true);
|
||||
appendU16(result, (uint16_t)IFDValueType::RATIONAL, true);
|
||||
appendU32(result, xresolution.nominator, true);
|
||||
appendU32(result, xresolution.denominator, true);
|
||||
appendU32(result, 1, true); // number of components
|
||||
xresolutionOffset = appendU32(result, data.size(), true);
|
||||
int offsetInData = appendRational(data, xresolution, true);
|
||||
uint32_t* ptr = (uint32_t *)(result.data() + xresolutionOffset);
|
||||
*ptr = offsetInData;
|
||||
}
|
||||
|
||||
// YResolution
|
||||
int yresolutionOffset = 0;
|
||||
if(yresolution.nominator || yresolution.denominator)
|
||||
{
|
||||
appendU16(result, (uint16_t)IFDTag::YRESOLUTION, true);
|
||||
appendU16(result, (uint16_t)IFDValueType::RATIONAL, true);
|
||||
appendU32(result, yresolution.nominator, true);
|
||||
appendU32(result, yresolution.denominator, true);
|
||||
appendU32(result, 1, true); // number of components
|
||||
yresolutionOffset = appendU32(result, data.size(), true);
|
||||
int offsetInData = appendRational(data, yresolution, true);
|
||||
uint32_t* ptr = (uint32_t *)(result.data() + yresolutionOffset);
|
||||
*ptr = offsetInData;
|
||||
}
|
||||
|
||||
// Exposure Time
|
||||
int exposureTimeOffset = 0;
|
||||
if(exposureTime.nominator || exposureTime.denominator)
|
||||
{
|
||||
appendU16(result, (uint16_t)IFDTag::EXPOSURE_TIME, true);
|
||||
appendU16(result, (uint16_t)IFDValueType::RATIONAL, true);
|
||||
appendU32(result, exposureTime.nominator, true);
|
||||
appendU32(result, exposureTime.denominator, true);
|
||||
appendU32(result, 1, true); // number of components
|
||||
exposureTimeOffset = appendU32(result, data.size(), true);
|
||||
int offsetInData = appendRational(data, exposureTime, true);
|
||||
uint32_t* ptr = (uint32_t *)(result.data() + exposureTimeOffset);
|
||||
*ptr = offsetInData;
|
||||
}
|
||||
|
||||
// ResolutionUnit
|
||||
@@ -285,20 +307,41 @@ namespace OpenVulkano::Image
|
||||
appendVector(result, data);
|
||||
int ifdAndSubdataSize = result.size();
|
||||
|
||||
if(modelOffset)
|
||||
if(model != "")
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + modelOffset);
|
||||
*ptr += resultSize - EXIF_HEADER_SIZE;
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
if(makeOffset)
|
||||
if(make != "")
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + makeOffset);
|
||||
*ptr += resultSize - EXIF_HEADER_SIZE;
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
if(xresolutionOffset)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + xresolutionOffset);
|
||||
*ptr += resultSize - EXIF_HEADER_SIZE;
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
if(yresolutionOffset)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + yresolutionOffset);
|
||||
*ptr += resultSize - EXIF_HEADER_SIZE;
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
if(exposureTimeOffset)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + exposureTimeOffset);
|
||||
*ptr += resultSize - EXIF_HEADER_SIZE;
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
if(dateTakenOffset)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + dateTakenOffset);
|
||||
@@ -319,7 +362,7 @@ namespace OpenVulkano::Image
|
||||
}
|
||||
|
||||
// Writing GPS Info structure
|
||||
int numberOfGPSInfoTags = 6;
|
||||
int numberOfGPSInfoTags = 8;
|
||||
appendU16(result, numberOfGPSInfoTags, true);
|
||||
|
||||
// Latitude Ref
|
||||
@@ -367,6 +410,23 @@ namespace OpenVulkano::Image
|
||||
appendU32(result, 1, true); // number of components
|
||||
int altitudeOffset = appendU32(result, 48); // 6 * sizeof(RationalValue)
|
||||
|
||||
// Track Ref
|
||||
appendU16(result, 14, true);
|
||||
appendU16(result, (uint16_t) IFDValueType::ASCII, true);
|
||||
appendU32(result, 2, true); // 2 for T/M + \0
|
||||
appendU8(result, trackRef == GPSTrackRef::TRUE_ ? 'T' : 'M');
|
||||
appendU8(result, 0);
|
||||
appendU8(result, 0); // padding
|
||||
appendU8(result, 0); // padding
|
||||
|
||||
// Track
|
||||
appendU16(result, 15, true);
|
||||
appendU16(result, (uint16_t) IFDValueType::RATIONAL, true);
|
||||
appendU32(result, 1, true); // number of components
|
||||
int trackOffset = appendU32(result, 56); // 7 * sizeof(RationalValue)
|
||||
|
||||
//
|
||||
|
||||
int sizeOfResultSoFar = result.size();
|
||||
|
||||
// Latitude
|
||||
@@ -390,13 +450,25 @@ namespace OpenVulkano::Image
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
// Track
|
||||
{
|
||||
uint32_t *ptr = (uint32_t *) (result.data() + trackOffset);
|
||||
*ptr += sizeOfResultSoFar - EXIF_HEADER_SIZE;
|
||||
*ptr = endianSwap(*ptr);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
appendGPSCoords(result, latitude, true);
|
||||
appendGPSCoords(result, longitude, true);
|
||||
|
||||
appendU32(result, altitude, true);
|
||||
appendU32(result, 1, true); // denominator for altitude
|
||||
|
||||
int const TRACK_PRECISION = 10000;
|
||||
appendU32(result, track * TRACK_PRECISION, true);
|
||||
appendU32(result, TRACK_PRECISION, true);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user