Skip to content

Commit 90c5dae

Browse files
committed
MIT License
1 parent 77eb72c commit 90c5dae

File tree

2 files changed

+84
-18
lines changed

2 files changed

+84
-18
lines changed

ExifBulider/ExifBuilder.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2025 Erium Vladlen
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
125
#pragma once
226
#include <vector>
327
#include <cstdint>
@@ -48,6 +72,19 @@ struct ExifTag {
4872
std::memcpy(value.data() + 4, &denom, 4);
4973
}
5074

75+
// Constructor for SLONG (32-bit signed integer)
76+
ExifTag(uint16_t t, uint16_t tp, uint32_t cnt, int32_t val)
77+
: tag(t), type(tp), count(cnt), value(4) {
78+
std::memcpy(value.data(), &val, 4);
79+
}
80+
81+
// Constructor for SRATIONAL (Two 32-bit signed integers: numerator and denominator)
82+
ExifTag(uint16_t t, uint16_t tp, uint32_t cnt, int32_t num, int32_t denom)
83+
: tag(t), type(tp), count(cnt), value(8) {
84+
std::memcpy(value.data(), &num, 4);
85+
std::memcpy(value.data() + 4, &denom, 4);
86+
}
87+
5188
// Constructor for string values, copying the string into the vector
5289
ExifTag(uint16_t t, uint16_t tp, const std::string& val)
5390
: tag(t), type(tp), count(static_cast<uint32_t>(val.size() + 1)), value(val.begin(), val.end()) {
@@ -161,6 +198,7 @@ class ExifBuilder {
161198
buffer[bufSize + (bigendian ? 0 : 1)] = tag.value[1];
162199
break;
163200
case 0x0004: // LONG
201+
case 0x0009: // SLONG
164202
buffer.resize(bufSize + 4, 0);
165203
buffer[bufSize + (bigendian ? 3 : 0)] = tag.value[0];
166204
buffer[bufSize + (bigendian ? 2 : 1)] = tag.value[1];
@@ -175,7 +213,7 @@ class ExifBuilder {
175213
}
176214

177215
bool tagFitsInField(const ExifTag& tag) const {
178-
if (tag.type == 0x0001 || tag.type == 0x0003 || tag.type == 0x0004) {
216+
if (tag.type == 0x0001 || tag.type == 0x0003 || tag.type == 0x0004 || tag.type == 0x0009 ) {
179217
return true;
180218
}
181219
else if (tag.type == 0x0002) {

ExifBulider/ExifBulider.cpp

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,40 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2025 Erium Vladlen
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
125
#include <cstdint>
226
#include <cstring>
327
#include <ctime>
428
#include <fstream>
529
#include <iostream>
30+
#include <filesystem>
631
#include <memory>
732
#include <string>
833
#include <variant>
934
#include <vector>
1035

1136
#include "ExifBuilder.h"
1237

13-
////////////////////////////////////////////////////////////////////////////////////
14-
///
15-
1638
// Function to read a JPEG file into a dynamically allocated array
1739
uint8_t* readJpegFile(const std::string& filename, size_t& fileSize) {
1840
std::ifstream file(filename, std::ios::binary | std::ios::ate);
@@ -71,30 +93,30 @@ void writeNewJpegWithExif(const std::string& originalFile, const std::string& ne
7193
}
7294

7395
////////////////////////////////////////////////////////////////////////////////////
74-
int main() {
96+
int main(int argc, char* argv[]) {
97+
98+
if (argc < 2) {
99+
std::cerr << "Usage: " << argv[0] << " <JPEG file>" << std::endl;
100+
return 1;
101+
}
102+
103+
75104
ExifBuilder builder;
76105

77106
// Add Manufacturer tag
78-
builder.addTag(ExifTag(0x010F, 0x0002, "EVT"));
79-
107+
builder.addTag(ExifTag(0x010F, 0x0002, "Ximea"));
80108
// Add Model tag
81-
builder.addTag(ExifTag(0x0110, 0x0002, "HB-25000-SBC"));
82-
109+
builder.addTag(ExifTag(0x0110, 0x0002, "MX245CG-SY-X4G3-FF"));
83110
// Add LensModel tag
84111
builder.addTag(ExifTag(0xA434, 0x0002, "F3526-MPT"));
85-
86112
// Add ExposureTime tag
87113
builder.addTag(ExifTag(0x829A, 0x0005, 1, 1, 100));
88-
89114
// Add FNumber tag 5.6
90115
builder.addTag(ExifTag(0x829D, 0x0005, 1, 56, 10));
91-
92116
// Add ISOSpeedRatings tag
93117
builder.addTag(ExifTag(0x8827, 0x0003, 1, uint16_t(200)));
94-
95118
// Add FocalLength tag
96119
builder.addTag(ExifTag(0x920A, 0x0005, 1, 35, 1));
97-
98120
// Add FocalLengthIn35mmFormat tag
99121
builder.addTag(ExifTag(0xA405, 0x0003, 1, uint16_t(79)));
100122

@@ -109,14 +131,14 @@ int main() {
109131
builder.addTag(ExifTag(0x9004, 0x0002, timeStr));
110132

111133
// Add Software tag
112-
builder.addTag(ExifTag(0x0131, 0x0002, "4D Capture"));
134+
builder.addTag(ExifTag(0x0131, 0x0002, "V Capture"));
113135

114136
// Add Orientation tag (1 - top-left)
115137
// 1 = Horizontal (normal), 3 = Rotate 180, 6 = Rotate 90 CW, 8 = Rotate 270 CW
116138
builder.addTag(ExifTag(0x0112, 0x0003, 1, uint16_t(8)));
117139

118140
// Add Copyright tag
119-
builder.addTag(ExifTag(0x8298, 0x0002, "2024 CyberAgent, Japan"));
141+
builder.addTag(ExifTag(0x8298, 0x0002, "2024 Vlad Erium, Japan"));
120142

121143
// Build EXIF blob
122144
std::vector<uint8_t> exifBlob = builder.buildExifBlob();
@@ -138,8 +160,14 @@ int main() {
138160

139161
try {
140162
// Inject EXIF data into a new JPEG file
141-
std::string originalFile = "x:/4DTEMP/24.08.22_13.45.15_10bit/0DC_14_2005513/000001.jpg";
142-
std::string newFile = "x:/4DTEMP/24.08.22_13.45.15_10bit/0DC_14_2005513/000001_exif.jpg";
163+
std::string originalFile = argv[1];
164+
std::filesystem::path path = originalFile;
165+
if (!std::filesystem::exists(path)) {
166+
throw std::runtime_error("File not found.");
167+
}
168+
169+
std::string newFile = path.parent_path().string() + "/" + path.stem().string() + "_exif.jpg";
170+
143171
writeNewJpegWithExif(originalFile, newFile, exifBlob.data(), exifBlob.size());
144172

145173
std::cout << "EXIF data injected and new file created: " << newFile << std::endl;

0 commit comments

Comments
 (0)