Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
exif_internal.h
Go to the documentation of this file.
1/*
2 This file is part of Ansel,
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18
33#ifndef DT_METADATA_EXIF_INTERNAL_H
34#define DT_METADATA_EXIF_INTERNAL_H
35
36#include "common/image.h"
37
38#include <exiv2/exiv2.hpp>
39#include <string>
40
41/* Windows path handling for exiv2.
42 *
43 * Every path in Ansel is UTF-8: that is what GLib hands us, what the database stores, and
44 * what the film-roll scanner produces. On Windows the narrow CRT reads a `const char *`
45 * path in the process ANSI code page instead -- CP-1252, CP-850, whatever the machine is
46 * set to -- so a path holding a single byte above 0x7F simply does not resolve. Every
47 * library Ansel hands a path to therefore gets a wide one: `libraw_open_wfile()` in
48 * `imageio/imageio_libraw.c`, `TIFFOpenW()` in `imageio/imageio_tiff.c`, `g_fopen()` (which
49 * is `_wfopen()` underneath) in the XMP sidecar writer. exiv2 is the same case, and
50 * WIDEN() is where it happens.
51 *
52 * exiv2 0.28.0 deleted the wide overloads, and this is where that showed: WIDEN() quietly
53 * became the identity, everything still compiled, and Windows users lost all EXIF for any
54 * image below a folder with an accent in its name (issue #474, and darktable #15478 and
55 * #19572 for the same bug in the same place). So a build that cannot widen is now a build
56 * error rather than a silent runtime data loss. `-DUSE_BUNDLED_EXIV2=ON` -- the default --
57 * is what supplies the capability; see `doc/exiv2.md`.
58 */
59#if defined(_WIN32) && !defined(EXV_UNICODE_PATH) && !defined(ANSEL_ALLOW_NARROW_EXIV2_PATHS)
60#error "This exiv2 was built without EXV_UNICODE_PATH (EXIV2_ENABLE_WIN_UNICODE), so there is no way to give it a Windows path holding a non-ASCII character: EXIF reads, thumbnail extraction and XMP sidecar writes would all fail at runtime, silently, for those images. Configure with -DUSE_BUNDLED_EXIV2=ON (the default) and see doc/exiv2.md. Define ANSEL_ALLOW_NARROW_EXIV2_PATHS to build anyway and accept that."
61#endif
62
63#if defined(_WIN32) && defined(EXV_UNICODE_PATH)
64
69std::wstring dt_exiv2_widen_path(const char *utf8_path);
70
71#define WIDEN(s) dt_exiv2_widen_path(s)
72
73#else
74
75/* Everywhere else a path is bytes, and those bytes are already UTF-8. */
76#define WIDEN(s) (s)
77
78#endif
79
80/* There used to be a read_metadata_threadsafe() macro here, wrapping readMetadata() in a
81 * process-wide lock. The lock is gone -- exiv2 0.27.7's Exif and IPTC code is reentrant and
82 * its XMP path serializes itself, so the only entry points that are not thread-safe are
83 * XmpParser::initialize() and XmpProperties::registerNs(), which Ansel calls exclusively
84 * from dt_exif_init() before any thread exists. See doc/lock-audit.md.
85 *
86 * The macro is gone with it rather than left as a no-op: a wrapper called "threadsafe" that
87 * does nothing is worse than no wrapper, because it reads like a guarantee. Call
88 * image->readMetadata() directly. */
89
91void dt_remove_exif_keys(Exiv2::ExifData &exif, const char *keys[], unsigned int n_keys);
92
97bool dt_exif_read_exif_tag(Exiv2::ExifData &exifData, Exiv2::ExifData::const_iterator *pos,
98 std::string key);
99
105bool dt_exif_decode_xmp_data(dt_image_t *img, Exiv2::XmpData &xmpData, int version,
106 bool exif_read);
107
108#endif // DT_METADATA_EXIF_INTERNAL_H
109
110// clang-format off
111// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
112// vim: shiftwidth=2 expandtab tabstop=2 cindent
113// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
114// clang-format on
bool dt_exif_decode_xmp_data(dt_image_t *img, Exiv2::XmpData &xmpData, int version, bool exif_read)
Apply one XMP packet's metadata, tags and colour labels to img.
Definition exif.cc:428
void dt_remove_exif_keys(Exiv2::ExifData &exif, const char *keys[], unsigned int n_keys)
Strip the given EXIF keys from exif, ignoring any that are absent.
Definition exif.cc:389
bool dt_exif_read_exif_tag(Exiv2::ExifData &exifData, Exiv2::ExifData::const_iterator *pos, std::string key)
Read one EXIF tag into pos, FALSE if the image does not carry it.
Definition exif.cc:676
char * key