gexiv2_sys/
lib.rs

1// Copyright © 2015–2022 Felix A. Crux <felixc@felixcrux.com> and contributors
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16//! Raw FFI declarations for gexiv2.
17//!
18//! This library provides Rust FFI declarations for the gexiv2 library, which
19//! is a GObject-based wrapper around the Exiv2 library, which provides read
20//! and write access to the Exif, XMP, and IPTC metadata in media files.
21//!
22//! Only FFI declarations are provided here; for a usable Rust library,
23//! consider the rexiv2 crate.
24
25#![crate_type = "lib"]
26
27extern crate libc;
28
29use self::libc::{c_char, c_double, c_int, c_long, c_uchar, c_uint};
30
31/// An opaque structure that serves as a container for a media file's metadata.
32///
33/// You can only create one via [`gexiv2_metadata_new()`](fn.gexiv2_metadata_new.html).
34///
35/// Be sure to free it after use with [`gexiv2_metadata_free()`](fn.gexiv2_metadata_free.html).
36pub enum GExiv2Metadata {}
37
38/// An opaque container structure for information about a media file preview image.
39///
40/// You can only get hold of one (or, rather, a null-terminated array of them) via
41/// [`gexiv2_metadata_get_preview_properties()`](fn.gexiv2_metadata_get_preview_properties.html).
42pub enum GExiv2PreviewProperties {}
43
44/// An opaque container structure for a media file preview image.
45///
46/// You can only get one via
47/// [`gexiv2_metadata_get_preview_image()`](fn.gexiv2_metadata_get_preview_image.html).
48///
49/// Be sure to free it with [`gexiv2_preview_image_free()`](fn.gexiv2_preview_image_free.html).
50pub enum GExiv2PreviewImage {}
51
52/// Container for information about recoverable runtime errors.
53#[repr(C)]
54#[derive(Clone, Copy, Debug, Eq, PartialEq)]
55pub struct GError {
56    /// Part of the program from which the error originated.
57    pub domain: u32,
58    /// Identifier for the error that occurred.
59    pub code: c_int,
60    /// Human-readable description of the problem.
61    pub message: *const c_char,
62}
63
64/// All the possible orientations for an image.
65#[repr(C)]
66#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
67pub enum Orientation {
68    Unspecified,
69    Normal,
70    HorizontalFlip,
71    Rotate180,
72    VerticalFlip,
73    Rotate90HorizontalFlip,
74    Rotate90,
75    Rotate90VerticalFlip,
76    Rotate270,
77}
78
79impl Default for Orientation {
80    fn default() -> Orientation { Orientation::Unspecified }
81}
82
83/// Log levels.
84#[repr(C)]
85#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
86pub enum GExiv2LogLevel {
87    DEBUG,
88    INFO,
89    WARN,
90    ERROR,
91    MUTE,
92}
93
94impl Default for GExiv2LogLevel {
95    fn default() -> GExiv2LogLevel { GExiv2LogLevel::ERROR }
96}
97
98/// Handler function that receives gexiv2 log messages and processes them as desired.
99pub type GExiv2LogHandler = extern fn(level: GExiv2LogLevel, msg: *const c_char);
100
101extern {
102    pub fn gexiv2_get_version() -> c_int;
103    pub fn gexiv2_initialize() -> c_int;
104
105    // GExiv2Metadata lifecycle management.
106    pub fn gexiv2_metadata_new() -> *mut GExiv2Metadata;
107    pub fn gexiv2_metadata_free(this: *mut GExiv2Metadata);
108    pub fn gexiv2_metadata_open_path(this: *mut GExiv2Metadata, path: *const c_char, error: *mut *mut GError) -> c_int;
109    pub fn gexiv2_metadata_open_buf(Gthis: *mut GExiv2Metadata, data: *const u8, data_len: c_long, error: *mut *mut GError) -> c_int;
110    pub fn gexiv2_metadata_from_app1_segment(Gthis: *mut GExiv2Metadata, data: *const u8, data_len: c_long, error: *mut *mut GError) -> c_int;
111    pub fn gexiv2_metadata_save_file(this: *mut GExiv2Metadata, path: *const c_char, error: *mut *mut GError) -> c_int;
112
113    // Image information.
114    pub fn gexiv2_metadata_get_supports_exif(this: *mut GExiv2Metadata) -> c_int;
115    pub fn gexiv2_metadata_get_supports_iptc(this: *mut GExiv2Metadata) -> c_int;
116    pub fn gexiv2_metadata_get_supports_xmp(this: *mut GExiv2Metadata) -> c_int;
117    pub fn gexiv2_metadata_get_mime_type(this: *mut GExiv2Metadata) -> *const c_char;
118    pub fn gexiv2_metadata_get_pixel_width(this: *mut GExiv2Metadata) -> c_int;
119    pub fn gexiv2_metadata_get_pixel_height(this: *mut GExiv2Metadata) -> c_int;
120
121    // Tag management.
122    pub fn gexiv2_metadata_has_tag(this: *mut GExiv2Metadata, tag: *const c_char) -> c_int;
123    pub fn gexiv2_metadata_clear_tag(this: *mut GExiv2Metadata, tag: *const c_char) -> c_int;
124    pub fn gexiv2_metadata_clear(this: *mut GExiv2Metadata);
125    pub fn gexiv2_metadata_has_exif(this: *mut GExiv2Metadata) -> c_int;
126    pub fn gexiv2_metadata_clear_exif(this: *mut GExiv2Metadata);
127    pub fn gexiv2_metadata_get_exif_tags(this: *mut GExiv2Metadata) -> *mut *mut c_char;
128    pub fn gexiv2_metadata_has_xmp(this: *mut GExiv2Metadata) -> c_int;
129    pub fn gexiv2_metadata_clear_xmp(this: *mut GExiv2Metadata);
130    pub fn gexiv2_metadata_get_xmp_tags(this: *mut GExiv2Metadata) -> *mut *mut c_char;
131    pub fn gexiv2_metadata_has_iptc(this: *mut GExiv2Metadata) -> c_int;
132    pub fn gexiv2_metadata_clear_iptc(this: *mut GExiv2Metadata);
133    pub fn gexiv2_metadata_get_iptc_tags(this: *mut GExiv2Metadata) -> *mut *mut c_char;
134
135    // Tag data getters/setters.
136    pub fn gexiv2_metadata_get_tag_string(this: *mut GExiv2Metadata, tag: *const c_char) -> *const c_char;
137    pub fn gexiv2_metadata_set_tag_string(this: *mut GExiv2Metadata, tag: *const c_char, value: *const c_char) -> c_int;
138    pub fn gexiv2_metadata_get_tag_interpreted_string(this: *mut GExiv2Metadata, tag: *const c_char) -> *const c_char;
139    pub fn gexiv2_metadata_get_tag_multiple(this: *mut GExiv2Metadata, tag: *const c_char) -> *mut *mut c_char;
140    pub fn gexiv2_metadata_set_tag_multiple(this: *mut GExiv2Metadata, tag: *const c_char, values: *mut *const c_char) -> c_int;
141    pub fn gexiv2_metadata_get_tag_long(this: *mut GExiv2Metadata, tag: *const c_char) -> c_long;
142    pub fn gexiv2_metadata_set_tag_long(this: *mut GExiv2Metadata, tag: *const c_char, value: c_long) -> c_int;
143    pub fn gexiv2_metadata_get_exif_tag_rational(this: *mut GExiv2Metadata, tag: *const c_char, nom: *mut c_int, den: *mut c_int) -> c_int;
144    pub fn gexiv2_metadata_set_exif_tag_rational(this: *mut GExiv2Metadata, tag: *const c_char, nom: c_int, den: c_int) -> c_int;
145
146    // Helper & convenience getters/setters.
147    pub fn gexiv2_metadata_get_orientation(this: *mut GExiv2Metadata) -> Orientation;
148    pub fn gexiv2_metadata_set_orientation(this: *mut GExiv2Metadata, orientation: Orientation);
149    pub fn gexiv2_metadata_get_metadata_pixel_width(this: *mut GExiv2Metadata) -> c_int;
150    pub fn gexiv2_metadata_get_metadata_pixel_height(this: *mut GExiv2Metadata) -> c_int;
151    pub fn gexiv2_metadata_set_metadata_pixel_width(this: *mut GExiv2Metadata, width: c_int);
152    pub fn gexiv2_metadata_set_metadata_pixel_height(this: *mut GExiv2Metadata, height: c_int);
153    pub fn gexiv2_metadata_get_exposure_time(this: *mut GExiv2Metadata, nom: *mut c_int, den: *mut c_int) -> c_int;
154    pub fn gexiv2_metadata_get_fnumber(this: *mut GExiv2Metadata) -> c_double;
155    pub fn gexiv2_metadata_get_focal_length(this: *mut GExiv2Metadata) -> c_double;
156    pub fn gexiv2_metadata_get_iso_speed(this: *mut GExiv2Metadata) -> c_int;
157    pub fn gexiv2_metadata_get_comment(this: *mut GExiv2Metadata) -> *const c_char;
158    pub fn gexiv2_metadata_set_comment(this: *mut GExiv2Metadata, comment: *const c_char);
159    pub fn gexiv2_metadata_clear_comment(this: *mut GExiv2Metadata);
160
161    // GPS-related functions.
162    pub fn gexiv2_metadata_get_gps_longitude(this: *mut GExiv2Metadata, longitude: *mut c_double) -> c_int;
163    pub fn gexiv2_metadata_get_gps_latitude(this: *mut GExiv2Metadata, latitude: *mut c_double) -> c_int;
164    pub fn gexiv2_metadata_get_gps_altitude(this: *mut GExiv2Metadata, altitude: *mut c_double) -> c_int;
165    pub fn gexiv2_metadata_get_gps_info(this: *mut GExiv2Metadata, longitude: *mut c_double, latitude: *mut c_double, altitude: *mut c_double) -> c_int;
166    pub fn gexiv2_metadata_set_gps_info(this: *mut GExiv2Metadata, longitude: c_double, latitude: c_double, altitude: c_double) -> c_int;
167    pub fn gexiv2_metadata_delete_gps_info(this: *mut GExiv2Metadata);
168
169    // Tag information functions.
170    pub fn gexiv2_metadata_is_exif_tag(tag: *const c_char) -> c_int;
171    pub fn gexiv2_metadata_is_iptc_tag(tag: *const c_char) -> c_int;
172    pub fn gexiv2_metadata_is_xmp_tag(tag: *const c_char) -> c_int;
173    pub fn gexiv2_metadata_get_tag_label(tag: *const c_char) -> *const c_char;
174    pub fn gexiv2_metadata_get_tag_description(tag: *const c_char) -> *const c_char;
175    pub fn gexiv2_metadata_get_tag_type(tag: *const c_char) -> *const c_char;
176
177    // Exif thumbnail getter/setters.
178    pub fn gexiv2_metadata_get_exif_thumbnail(this: *mut GExiv2Metadata, buffer: *mut *mut u8, size: *mut c_int) -> c_int;
179    pub fn gexiv2_metadata_set_exif_thumbnail_from_file(this: *mut GExiv2Metadata, path: *const c_char, error: *mut *mut GError) -> c_int;
180    pub fn gexiv2_metadata_set_exif_thumbnail_from_buffer(this: *mut GExiv2Metadata, buffer: *const u8, size: c_int);
181    pub fn gexiv2_metadata_erase_exif_thumbnail(this: *mut GExiv2Metadata);
182
183    // Preview image properties.
184    pub fn gexiv2_metadata_get_preview_properties(this: *mut GExiv2Metadata) -> *mut *mut GExiv2PreviewProperties;
185    pub fn gexiv2_preview_properties_get_mime_type(this: *mut GExiv2PreviewProperties) -> *const c_char;
186    pub fn gexiv2_preview_properties_get_extension(this: *mut GExiv2PreviewProperties) -> *const c_char;
187    pub fn gexiv2_preview_properties_get_size(this: *mut GExiv2PreviewProperties) -> c_uint;
188    pub fn gexiv2_preview_properties_get_width(this: *mut GExiv2PreviewProperties) -> c_uint;
189    pub fn gexiv2_preview_properties_get_height(this: *mut GExiv2PreviewProperties) -> c_uint;
190
191    // Preview images.
192    pub fn gexiv2_metadata_get_preview_image(this: *mut GExiv2Metadata, props: *mut GExiv2PreviewProperties) -> *mut GExiv2PreviewImage;
193    pub fn gexiv2_preview_image_free(this: *mut GExiv2PreviewImage);
194    pub fn gexiv2_preview_image_get_data(this: *mut GExiv2PreviewImage, size: *mut c_uint) -> *const c_uchar;
195    pub fn gexiv2_preview_image_get_mime_type(this: *mut GExiv2PreviewImage) -> *const c_char;
196    pub fn gexiv2_preview_image_get_extension(this: *mut GExiv2PreviewImage) -> *const c_char;
197    pub fn gexiv2_preview_image_get_width(this: *mut GExiv2PreviewImage) -> c_uint;
198    pub fn gexiv2_preview_image_get_height(this: *mut GExiv2PreviewImage) -> c_uint;
199    pub fn gexiv2_preview_image_write_file(this: *mut GExiv2PreviewImage, path: *const c_char) -> c_long;
200
201    // XMP namespace management.
202    pub fn gexiv2_metadata_register_xmp_namespace(name: *const c_char, prefix: *const c_char) -> c_int;
203    pub fn gexiv2_metadata_unregister_xmp_namespace(name: *const c_char) -> c_int;
204    pub fn gexiv2_metadata_unregister_all_xmp_namespaces();
205
206    // Logging.
207    pub fn gexiv2_log_get_default_handler() -> GExiv2LogHandler;
208    pub fn gexiv2_log_get_handler() -> GExiv2LogHandler;
209    pub fn gexiv2_log_set_handler(handler: GExiv2LogHandler);
210    pub fn gexiv2_log_get_level() -> GExiv2LogLevel;
211    pub fn gexiv2_log_set_level(level: GExiv2LogLevel);
212    pub fn gexiv2_log_use_glib_logging();
213}
214
215
216#[cfg(feature = "raw-tag-access")]
217extern crate glib_sys as glib;
218
219#[cfg(feature = "raw-tag-access")]
220extern {
221    pub fn gexiv2_metadata_get_tag_raw(this: *mut GExiv2Metadata, tag: *const libc::c_char) -> *mut glib::GBytes;
222}
223
224
225#[cfg(feature = "xmp-packet-access")]
226#[macro_use]
227extern crate bitflags;
228
229#[cfg(feature = "xmp-packet-access")]
230bitflags! {
231    pub struct GExiv2XmpFormatFlags: u64 {
232        const OMIT_PACKET_WRAPPER   = 0x0010;
233        const READ_ONLY_PACKET      = 0x0020;
234        const USE_COMPACT_FORMAT    = 0x0040;
235        const INCLUDE_THUMBNAIL_PAD = 0x0100;
236        const EXACT_PACKET_LENGTH   = 0x0200;
237        const WRITE_ALIAS_COMMENTS  = 0x0400;
238        const OMIT_ALL_FORMATTING   = 0x0800;
239    }
240}
241
242#[cfg(feature = "xmp-packet-access")]
243extern {
244    pub fn gexiv2_metadata_generate_xmp_packet(this: *mut GExiv2Metadata, xmp_format_flags: libc::c_ulong, padding: u32) -> *const c_char;
245    pub fn gexiv2_metadata_get_xmp_packet(this: *mut GExiv2Metadata) -> *const c_char;
246}
247
248
249#[cfg(test)]
250mod test;