Skip to content

Commit 8bb5636

Browse files
authored
Merge branch 'Exiv2:main' into WebAssembly
2 parents c1286b7 + fe44c8c commit 8bb5636

File tree

15 files changed

+205
-34
lines changed

15 files changed

+205
-34
lines changed

.github/workflows/on_PR_meson.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,17 @@ jobs:
163163
meson setup "${{github.workspace}}/build" -Dwarning_level=3 -Dcpp_std=c++20
164164
meson compile -C "${{github.workspace}}/build" --verbose
165165
meson test -C "${{github.workspace}}/build" --verbose
166+
Emscripten:
167+
runs-on: ubuntu-latest
168+
name: Emscripten
169+
steps:
170+
- uses: actions/checkout@v4
171+
- name: Install packages
172+
run: |
173+
python3 -m pip install meson ninja
174+
- name: Emscripten
175+
uses: mymindstorm/setup-emsdk@v11
176+
- name: Compile
177+
run: |
178+
meson setup "${{github.workspace}}/build" --cross-file="${{github.workspace}}/em.txt" --wrap-mode=forcefallback -Ddefault_library=static -Dwarning_level=3 -Dcpp_std=c++20 -DunitTests=disabled
179+
meson compile -C "${{github.workspace}}/build" --verbose

app/actions.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,7 +1826,13 @@ int renameFile(std::string& newPath, const tm* tm) {
18261826
std::string path = newPath;
18271827
auto oldFsPath = fs::path(path);
18281828
std::string format = Params::instance().format_;
1829+
std::string filename = p.stem().string();
1830+
std::string basesuffix = "";
1831+
int pos = filename.find('.');
1832+
if (pos > 0)
1833+
basesuffix = filename.substr(filename.find('.'));
18291834
replace(format, ":basename:", p.stem().string());
1835+
replace(format, ":basesuffix:", basesuffix);
18301836
replace(format, ":dirname:", p.parent_path().filename().string());
18311837
replace(format, ":parentname:", p.parent_path().parent_path().filename().string());
18321838

app/exiv2.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ void Params::help(std::ostream& os) const {
334334
<< _(" -r fmt Filename format for the 'rename' action. The format string\n")
335335
<< _(" follows strftime(3). The following keywords are also supported:\n")
336336
<< _(" :basename: - original filename without extension\n")
337+
<< _(" :basesuffix: - suffix in original filename, starts with first dot and ends before extension\n")
337338
<< _(" :dirname: - name of the directory holding the original file\n")
338339
<< _(" :parentname: - name of parent directory\n") << _(" Default 'fmt' is %Y%m%d_%H%M%S\n")
339340
<< _(" -c txt JPEG comment string to set in the image.\n")

em.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[binaries]
2+
c = 'emcc'
3+
cpp = 'em++'
4+
ar = 'emar'
5+
nm = 'emnm'
6+
7+
[host_machine]
8+
system = 'emscripten'
9+
cpu_family = 'x86_64'
10+
cpu = 'x86_64'
11+
endian = 'little'

exiv2.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,12 @@ environment variable). The *fmt* string follows the definitions in
455455
date and time. In addition, the following special character sequences are
456456
also provided:
457457

458-
| Variable | Description |
459-
|:------ |:---- |
460-
| :basename: | Original filename without extension |
461-
| :dirname: | Name of the directory holding the original file |
462-
| :parentname: | Name of parent directory |
458+
| Variable | Description |
459+
|:------ |:---- |
460+
| :basename: | Original filename without extension |
461+
| :basesuffix: | Suffix in original filename, starts with first dot and ends before extension, e.g. PANO, MP, NIGHT added by Google Camera app |
462+
| :dirname: | Name of the directory holding the original file |
463+
| :parentname: | Name of parent directory |
463464

464465
The default *fmt* is %Y%m%d_%H%M%S
465466

@@ -491,6 +492,12 @@ exiv2.exe: File `./Stonehenge_16_Jul_2015.jpg' exists. [O]verwrite, [r]ename or
491492
Renaming file to ./Stonehenge_16_Jul_2015_1.jpg
492493
```
493494

495+
If the filename contains a suffix, which shall be included in new filename:
496+
```
497+
$ exiv2 --verbose --rename '%d_%b_%Y:basesuffix:' Stonehenge.PANO.jpg
498+
File 1/1: Stonehenge.PANO.jpg
499+
Renaming file to '16_Jul_2015.PANO'.jpg```
500+
494501
<div id="adjust_time">
495502
496503
### **-a** *time*, **--adjust** *time*

src/canonmn_int.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ constexpr TagDetails canonModelId[] = {
387387
{0x80000480, "EOS R50"},
388388
{0x80000481, "EOS R6 Mark II"},
389389
{0x80000487, "EOS R8"},
390+
{0x80000491, "PowerShot V10"},
391+
{0x80000498, "EOS R100"},
390392
{0x80000520, "EOS D2000C"},
391393
{0x80000560, "EOS D6000C"},
392394
};
@@ -2062,6 +2064,8 @@ constexpr TagDetails canonCsLensType[] = {
20622064
{61182, "Canon RF 400mm F2.8L IS USM + RF1.4x"},
20632065
{61182, "Canon RF 400mm F2.8L IS USM + RF2x"},
20642066
{61182, "Canon RF 600mm F4L IS USM"},
2067+
{61182, "Canon RF 600mm F4L IS USM + RF1.4x"},
2068+
{61182, "Canon RF 600mm F4L IS USM + RF2x"},
20652069
{61182, "Canon RF 800mm F5.6L IS USM"},
20662070
{61182, "Canon RF 800mm F5.6L IS USM + RF1.4x"},
20672071
{61182, "Canon RF 800mm F5.6L IS USM + RF2x"},
@@ -2072,7 +2076,11 @@ constexpr TagDetails canonCsLensType[] = {
20722076
{61182, "Canon RF 135mm F1.8 L IS USM"},
20732077
{61182, "Canon RF 24-50mm F4.5-6.3 IS STM"},
20742078
{61182, "Canon RF-S 55-210mm F5-7.1 IS STM"},
2075-
{65535, "n/a"},
2079+
{61182, "Canon RF 100-300mm F2.8L IS USM"},
2080+
{61182, "Canon RF 100-300mm F2.8L IS USM + RF1.4x"},
2081+
{61182, "Canon RF 100-300mm F2.8L IS USM + RF2x"},
2082+
{61182, "Canon RF 28mm F2.8 STM"},
2083+
{65535, N_("n/a")},
20762084
};
20772085

20782086
//! FlashActivity, tag 0x001c
@@ -2490,7 +2498,7 @@ constexpr TagDetails canonToningEffect[] = {
24902498
};
24912499

24922500
//! RFLensType, tag 0x003D
2493-
// from https://github.com/exiftool/exiftool/blob/12.49/lib/Image/ExifTool/Canon.pm#L6791
2501+
// from https://github.com/exiftool/exiftool/blob/12.67/lib/Image/ExifTool/Canon.pm#L6833
24942502
constexpr TagDetails canonRFLensType[] = {
24952503
{0, N_("n/a")},
24962504
{257, "Canon RF 50mm F1.2L USM"},
@@ -2529,6 +2537,8 @@ constexpr TagDetails canonRFLensType[] = {
25292537
{290, "Canon RF 400mm F2.8L IS USM + RF1.4x"},
25302538
{291, "Canon RF 400mm F2.8L IS USM + RF2x"},
25312539
{292, "Canon RF 600mm F4L IS USM"},
2540+
{293, "Canon RF 600mm F4L IS USM + RF1.4x"},
2541+
{294, "Canon RF 600mm F4L IS USM + RF2x"},
25322542
{295, "Canon RF 800mm F5.6L IS USM"},
25332543
{296, "Canon RF 800mm F5.6L IS USM + RF1.4x"},
25342544
{297, "Canon RF 800mm F5.6L IS USM + RF2x"},
@@ -2539,6 +2549,10 @@ constexpr TagDetails canonRFLensType[] = {
25392549
{303, "Canon RF 135mm F1.8 L IS USM"},
25402550
{304, "Canon RF 24-50mm F4.5-6.3 IS STM"},
25412551
{305, "Canon RF-S 55-210mm F5-7.1 IS STM"},
2552+
{306, "Canon RF 100-300mm F2.8L IS USM"},
2553+
{307, "Canon RF 100-300mm F2.8L IS USM + RF1.4x"},
2554+
{308, "Canon RF 100-300mm F2.8L IS USM + RF2x"},
2555+
{313, "Canon RF 28mm F2.8 STM"},
25422556
};
25432557

25442558
// Canon File Info Tag

src/easyaccess.cpp

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ ExifData::const_iterator findMetadatum(const ExifData& ed, const char* const key
2525
return ed.end();
2626
} // findMetadatum
2727

28+
/*!
29+
@brief Search \em ed for a Metadatum specified by the \em keys.
30+
The \em keys are searched in the order of their appearance, the
31+
first available Metadatum is returned, except it is in NikonLd4
32+
and its value 0.
33+
Example: Exif.NikonLd4.LensID and Exif.NikonLd4.LensIDNumber are
34+
usually together included, one of them has value 0 (which means
35+
undefined), so skip tag with value 0.
36+
37+
@param ed The %Exif metadata container to search
38+
@param keys Array of keys to look for
39+
@param count Number of elements in the array
40+
*/
41+
ExifData::const_iterator findMetadatumSkip0inNikonLd4(const ExifData& ed, const char* const keys[], size_t count) {
42+
for (size_t i = 0; i < count; ++i) {
43+
auto pos = ed.findKey(ExifKey(keys[i]));
44+
if (pos != ed.end()) {
45+
if (strncmp(keys[i], "Exif.NikonLd4", 13) != 0 || pos->getValue()->toInt64(0) > 0)
46+
return pos;
47+
}
48+
}
49+
return ed.end();
50+
} // findMetadatumSkip0inNikonLd4
2851
} // anonymous namespace
2952

3053
// *****************************************************************************
@@ -201,7 +224,6 @@ ExifData::const_iterator sceneMode(const ExifData& ed) {
201224
"Exif.Panasonic.SceneMode",
202225
"Exif.Pentax.PictureMode",
203226
"Exif.PentaxDng.PictureMode",
204-
"Exif.Photo.SceneCaptureType",
205227
};
206228
return findMetadatum(ed, keys, std::size(keys));
207229
}
@@ -263,26 +285,18 @@ ExifData::const_iterator lensName(const ExifData& ed) {
263285
"Exif.Nikon3.Lens",
264286
};
265287

266-
for (const auto& key : keys) {
267-
auto pos = ed.findKey(ExifKey(key));
268-
if (pos != ed.end()) {
269-
// Exif.NikonLd4.LensID and Exif.NikonLd4.LensIDNumber are usually together included,
270-
// one of them has value 0 (which means undefined), so skip tag with value 0
271-
if (strncmp(key, "Exif.NikonLd4", 13) != 0 || pos->getValue()->toInt64(0) > 0)
272-
return pos;
273-
}
274-
}
275-
return ed.end();
288+
return findMetadatumSkip0inNikonLd4(ed, keys, std::size(keys));
276289
}
277290

278291
ExifData::const_iterator saturation(const ExifData& ed) {
279292
static constexpr const char* keys[] = {
280293
"Exif.Photo.Saturation", "Exif.CanonCs.Saturation", "Exif.MinoltaCsNew.Saturation",
281294
"Exif.MinoltaCsOld.Saturation", "Exif.MinoltaCs7D.Saturation", "Exif.MinoltaCs5D.Saturation",
282-
"Exif.Fujifilm.Color", "Exif.Nikon3.Saturation", "Exif.NikonPc.Saturation",
283-
"Exif.Panasonic.Saturation", "Exif.Pentax.Saturation", "Exif.PentaxDng.Saturation",
284-
"Exif.Sigma.Saturation", "Exif.Sony1.Saturation", "Exif.Sony2.Saturation",
285-
"Exif.Casio.Saturation", "Exif.Casio2.Saturation", "Exif.Casio2.Saturation2",
295+
"Exif.Fujifilm.Color", "Exif.Nikon3.Saturation", "Exif.Nikon3.Saturation2",
296+
"Exif.NikonPc.Saturation", "Exif.Panasonic.Saturation", "Exif.Pentax.Saturation",
297+
"Exif.PentaxDng.Saturation", "Exif.Sigma.Saturation", "Exif.Sony1.Saturation",
298+
"Exif.Sony2.Saturation", "Exif.Casio.Saturation", "Exif.Casio2.Saturation",
299+
"Exif.Casio2.Saturation2",
286300
};
287301
return findMetadatum(ed, keys, std::size(keys));
288302
}
@@ -418,10 +432,11 @@ ExifData::const_iterator subjectDistance(const ExifData& ed) {
418432
"Exif.Photo.SubjectDistance", "Exif.Image.SubjectDistance", "Exif.CanonSi.SubjectDistance",
419433
"Exif.CanonFi.FocusDistanceUpper", "Exif.CanonFi.FocusDistanceLower", "Exif.MinoltaCsNew.FocusDistance",
420434
"Exif.Nikon1.FocusDistance", "Exif.Nikon3.FocusDistance", "Exif.NikonLd2.FocusDistance",
421-
"Exif.NikonLd3.FocusDistance", "Exif.NikonLd4.FocusDistance", "Exif.Olympus.FocusDistance",
422-
"Exif.OlympusFi.FocusDistance", "Exif.Casio.ObjectDistance", "Exif.Casio2.ObjectDistance",
435+
"Exif.NikonLd3.FocusDistance", "Exif.NikonLd4.FocusDistance", "Exif.NikonLd4.FocusDistance2",
436+
"Exif.Olympus.FocusDistance", "Exif.OlympusFi.FocusDistance", "Exif.Casio.ObjectDistance",
437+
"Exif.Casio2.ObjectDistance",
423438
};
424-
return findMetadatum(ed, keys, std::size(keys));
439+
return findMetadatumSkip0inNikonLd4(ed, keys, std::size(keys));
425440
}
426441

427442
ExifData::const_iterator lightSource(const ExifData& ed) {
@@ -453,11 +468,12 @@ ExifData::const_iterator serialNumber(const ExifData& ed) {
453468

454469
ExifData::const_iterator focalLength(const ExifData& ed) {
455470
static constexpr const char* keys[] = {
456-
"Exif.Photo.FocalLength", "Exif.Image.FocalLength", "Exif.Canon.FocalLength",
457-
"Exif.NikonLd2.FocalLength", "Exif.NikonLd3.FocalLength", "Exif.MinoltaCsNew.FocalLength",
458-
"Exif.Pentax.FocalLength", "Exif.PentaxDng.FocalLength", "Exif.Casio2.FocalLength",
471+
"Exif.Photo.FocalLength", "Exif.Image.FocalLength", "Exif.Canon.FocalLength",
472+
"Exif.NikonLd2.FocalLength", "Exif.NikonLd3.FocalLength", "Exif.NikonLd4.FocalLength2",
473+
"Exif.MinoltaCsNew.FocalLength", "Exif.Pentax.FocalLength", "Exif.PentaxDng.FocalLength",
474+
"Exif.Casio2.FocalLength",
459475
};
460-
return findMetadatum(ed, keys, std::size(keys));
476+
return findMetadatumSkip0inNikonLd4(ed, keys, std::size(keys));
461477
}
462478

463479
ExifData::const_iterator subjectArea(const ExifData& ed) {

src/nikonmn_int.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3943,6 +3943,10 @@ std::ostream& Nikon3MakerNote::printLensId4ZMount(std::ostream& os, const Value&
39433943
{38, "Nikon", "Nikkor Z 85mm f/1.2 S"}, // 28
39443944
{39, "Nikon", "Nikkor Z 17-28mm f/2.8"}, // IB
39453945
{40, "Nikon", "Nikkor Z 26mm f/2.8"},
3946+
{41, "Nikon", "Nikkor Z DX 12-28mm f/3.5-5.6 PZ VR"},
3947+
{42, "Nikon", "Nikkor Z 180-600mm f/5.6-6.3 VR"},
3948+
{43, "Nikon", "Nikkor Z DX 24mm f/1.7"},
3949+
{44, "Nikon", "Nikkor Z 70-180mm f/2.8"},
39463950
};
39473951

39483952
auto lid = static_cast<uint16_t>(value.toInt64());

src/pentaxmn_int.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ constexpr TagDetails pentaxModel[] = {
165165
{0x13240, "K-1 Mark II"},
166166
{0x13254, "K-3 Mark III"},
167167
{0x13290, "WG-70"},
168+
{0x1329a, "GR IIIx"},
169+
{0x132d6, "K-3 Mark III Monochrome"},
168170
};
169171

170172
//! Quality, tag 0x0008
@@ -664,6 +666,7 @@ constexpr TagDetails pentaxLensType[] = {
664666
{0x0402, "smc PENTAX-FA 80-320mm F4.5-5.6"},
665667
{0x0403, "smc PENTAX-FA 43mm F1.9 Limited"},
666668
{0x0406, "smc PENTAX-FA 35-80mm F4-5.6"},
669+
{0x0407, "Irix 45mm F/1.4"},
667670
{0x0408, "Irix 150mm F/2.8 Macro"},
668671
{0x0409, "Irix 11mm F/4"},
669672
{0x040a, "Irix 15mm F/2.4"},

src/tags_int.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ constexpr TagDetails exifCompression[] = {
263263
{34712, N_("Leadtools JPEG 2000")},
264264
{34713, N_("Nikon NEF Compressed")},
265265
{34892, N_("JPEG (lossy)")}, // DNG 1.4
266+
{52546, N_("JPEG XL")}, // DNG 1.7
266267
{65000, N_("Kodak DCR Compressed")},
267268
{65535, N_("Pentax PEF Compressed")},
268269
};
@@ -283,8 +284,8 @@ constexpr TagDetails exifPhotometricInterpretation[] = {
283284
{32844, N_("Pixar LogL")},
284285
{32845, N_("Pixar LogLuv")},
285286
{34892, N_("Linear Raw")},
286-
{51177, N_("Depth Map")}, // DNG 1.5
287-
{52527, N_("Semantic Mask")}, // DNG 1.6
287+
{51177, N_("Depth Map")}, // DNG 1.5
288+
{52527, N_("Photometric Mask")}, // DNG 1.6
288289
};
289290

290291
//! Thresholding, tag 0x0107
@@ -404,6 +405,7 @@ constexpr TagDetails dngMakerNoteSafety[] = {
404405
constexpr TagDetails dngColorimetricReference[] = {
405406
{0, N_("XYZ values are scene-referred")},
406407
{1, N_("XYZ values are output-referred")},
408+
{2, N_("XYZ values are output-referred and may be HDR")}, // DNG 1.7
407409
};
408410

409411
//! ProfileEmbedPolicy, DNG 1.2 tag 0xc6fd
@@ -451,6 +453,7 @@ constexpr TagDetails dngDepthMeasureType[] = {
451453
{2, N_("Optical ray")},
452454
};
453455

456+
// clang-format off
454457
//! Base IFD Tags (IFD0 and IFD1)
455458
constexpr TagInfo ifdTagInfo[] = {
456459
{0x000b, "ProcessingSoftware", N_("Processing Software"),
@@ -1707,12 +1710,44 @@ constexpr TagInfo ifdTagInfo[] = {
17071710
"combination of the color tables, weighted by their corresponding Semantic "
17081711
"Masks."),
17091712
IfdId::ifd0Id, SectionId::dngTags, undefined, -1, printValue}, // DNG 1.6 tag
1713+
{0xcd40, "ProfileGainTableMap2", N_("Profile Gain Table Map 2"),
1714+
N_("This tag is an extended version of ProfileGainTableMap."),
1715+
IfdId::ifd0Id, SectionId::dngTags, undefined, -1, printValue}, // DNG 1.7 tag
1716+
{0xcd43, "ColumnInterleaveFactor", N_("Column Interleave Factor"),
1717+
N_("This tag specifies that columns of the image are stored in interleaved "
1718+
"order. The value of the tag specifies the number of interleaved fields. "
1719+
"The use of a non-default value for this tag requires setting the "
1720+
"DNGBackwardVersion tag to at least 1.7.0.0."),
1721+
IfdId::ifd0Id, SectionId::dngTags, unsignedLong, 1, printValue}, // DNG 1.7 tag
1722+
{0xcd44, "ImageSequenceInfo", N_("Image Sequence Info"),
1723+
N_("This is an informative tag that describes how the image file relates "
1724+
"to other image files captured in a sequence. Applications include focus "
1725+
"stacking, merging multiple frames to reduce noise, time lapses, exposure "
1726+
"brackets, stitched images for super resolution, and so on."),
1727+
IfdId::ifd0Id, SectionId::dngTags, undefined, -1, printValue}, // DNG 1.7 tag
1728+
{0xcd46, "ImageStats", N_("Image Stats"),
1729+
N_("This is an informative tag that provides basic statistical information "
1730+
"about the pixel values of the image in this IFD. Possible applications "
1731+
"include normalizing brightness of images when multiple images are displayed "
1732+
"together (especially when mixing Standard Dynamic Range and High Dynamic "
1733+
"Range images), identifying underexposed or overexposed images, and so on."),
1734+
IfdId::ifd0Id, SectionId::dngTags, undefined, -1, printValue}, // DNG 1.7 tag
1735+
{0xcd47, "ProfileDynamicRange", N_("Profile Dynamic Range"),
1736+
N_("This tag describes the intended rendering output dynamic range for a given "
1737+
"camera profile."),
1738+
IfdId::ifd0Id, SectionId::dngTags, undefined, 8, printValue}, // DNG 1.7 tag
1739+
{0xcd48, "ProfileGroupName", N_("Profile Group Name"),
1740+
N_("A UTF-8 encoded string containing the 'group name' of the camera profile. "
1741+
"The purpose of this tag is to associate two or more related camera profiles "
1742+
"into a common group."),
1743+
IfdId::ifd0Id, SectionId::dngTags, asciiString, -1, printValue}, // DNG 1.7 tag
17101744

17111745
////////////////////////////////////////
17121746
// End of list marker
17131747
{0xffff, "(UnknownIfdTag)", N_("Unknown IFD tag"), N_("Unknown IFD tag"), IfdId::ifd0Id, SectionId::sectionIdNotSet,
17141748
asciiString, -1, printValue},
17151749
};
1750+
// clang-format on
17161751

17171752
const TagInfo* ifdTagList() {
17181753
return ifdTagInfo;

0 commit comments

Comments
 (0)