exempi 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +34 -0
- data/README.md +61 -0
- data/Rakefile +9 -0
- data/exempi.gemspec +26 -0
- data/lib/exempi.rb +4 -0
- data/lib/exempi/consts.rb +338 -0
- data/lib/exempi/errors.rb +97 -0
- data/lib/exempi/exceptions.rb +24 -0
- data/lib/exempi/exempi.rb +325 -0
- data/lib/exempi/namespaces.rb +161 -0
- data/lib/exempi/version.rb +3 -0
- data/test/dataconverter_test.rb +48 -0
- data/test/datetime_test.rb +35 -0
- data/test/helpers_test.rb +22 -0
- metadata +95 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f8b542870176af4c52ddf7a13d1f4bae891db89b
|
4
|
+
data.tar.gz: 3cea7bcc51f8f8921f45277bd43980b90dfcd810
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8002302d3272d602a1c50ec9e2932bd2c25e00298439d09754b5500c5a817aaacd1614499ae229ccac144fd9c8e826ebcb9d37da247a1d1e7cbd74888b1dda67
|
7
|
+
data.tar.gz: b95e971af05e2f0b82810031449c511414fa2eb5dcd1e7ceee52677039be54f10680c4fb9c00c76d1529ad00db8ae5f783e4ec37030510496191613a352aa64d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
Copyright (C) 2015 Misty De Meo
|
2
|
+
Copyright (C) 2012 Canadian Museum for Human Rights
|
3
|
+
Copyright (C) 2007-2008,2012 Hubert Figuiere
|
4
|
+
Copyright 2002-2007 Adobe Systems Incorporated
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions
|
9
|
+
are met:
|
10
|
+
|
11
|
+
1 Redistributions of source code must retain the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer.
|
13
|
+
|
14
|
+
2 Redistributions in binary form must reproduce the above copyright
|
15
|
+
notice, this list of conditions and the following disclaimer in the
|
16
|
+
documentation and/or other materials provided with the
|
17
|
+
distribution.
|
18
|
+
|
19
|
+
3 Neither the name of the Authors, nor the names of its
|
20
|
+
contributors may be used to endorse or promote products derived
|
21
|
+
from this software wit hout specific prior written permission.
|
22
|
+
|
23
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
24
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
25
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
26
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
27
|
+
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
28
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
29
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
30
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
31
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
32
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
33
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
34
|
+
OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Exempi
|
2
|
+
|
3
|
+
Exempi is an ultra-thin [FFI](https://github.com/ffi/ffi)-based wrapper for the [Exempi](http://libopenraw.freedesktop.org/wiki/Exempi) C library. It wraps Exempi's functions in the Exempi module.
|
4
|
+
|
5
|
+
Don't like dealing with C functions directly? Check out [Fasttrack](https://github.com/mistydemeo/fasttrack), an object-oriented wrapper around Exempi.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'exempi'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install exempi
|
20
|
+
|
21
|
+
## Usage samples
|
22
|
+
|
23
|
+
Opening a file:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# create an empty file pointer
|
27
|
+
file_ptr = Exempi.xmp_files_new
|
28
|
+
Exempi.xmp_files_open file_ptr, "myfile.jpg", :XMP_OPEN_READ
|
29
|
+
```
|
30
|
+
|
31
|
+
Extracting XMP from a file:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
xmp_ptr = Exempi.files_get_new_xmp file_ptr
|
35
|
+
```
|
36
|
+
|
37
|
+
Fetching an XMP property from a file:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# Exempi provides a set of standard namespace URIs for you
|
41
|
+
exif_ns = Exempi::Namespaces::XMP_NS_EXIF
|
42
|
+
xmp_string = Exempi.xmp_string_new
|
43
|
+
|
44
|
+
Exempi.xmp_get_property xmp_ptr, exif_ns, 'DateTimeOriginal', xmp_string
|
45
|
+
datetime = Exempi.xmp_string_cstr xmp_string
|
46
|
+
Exempi.xmp_string_free xmp_string
|
47
|
+
```
|
48
|
+
|
49
|
+
For more information see Exempi's function documentation, included in lib/exempi/exempi.rb.
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Fork it
|
54
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
55
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
56
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
57
|
+
5. Create new Pull Request
|
58
|
+
|
59
|
+
## License
|
60
|
+
|
61
|
+
3-clause BSD, identical to the license used by Exempi and Adobe XMP Toolkit. For the license text, see LICENSE.
|
data/Rakefile
ADDED
data/exempi.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/exempi/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Misty De Meo"]
|
6
|
+
gem.email = ["mistydemeo@gmail.com"]
|
7
|
+
gem.description = <<-EOS
|
8
|
+
Exempi is a thin FFI-based wrapper around the
|
9
|
+
Exempi library. It provides a variety of
|
10
|
+
functions for reading, writing, and manipulating
|
11
|
+
XMP metadata.
|
12
|
+
EOS
|
13
|
+
gem.summary = %q{Ruby wrapper for Exempi}
|
14
|
+
gem.homepage = "https://github.com/mistydemeo/exempi"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($\)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.name = "exempi"
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
gem.version = Exempi::VERSION
|
22
|
+
|
23
|
+
gem.add_dependency 'ffi', '>= 1.1.5'
|
24
|
+
|
25
|
+
gem.add_development_dependency 'rake', '>= 0.9.2.2'
|
26
|
+
end
|
data/lib/exempi.rb
ADDED
@@ -0,0 +1,338 @@
|
|
1
|
+
# These constants and comments are taken from Exempi's xmp.h
|
2
|
+
#
|
3
|
+
# Copyright (C) 2015 Misty De Meo
|
4
|
+
# Copyright (C) 2012 Canadian Museum for Human Rights
|
5
|
+
# Copyright (C) 2007-2008,2012 Hubert Figuiere
|
6
|
+
# Copyright 2002-2007 Adobe Systems Incorporated
|
7
|
+
# All rights reserved.
|
8
|
+
#
|
9
|
+
# Redistribution and use in source and binary forms, with or without
|
10
|
+
# modification, are permitted provided that the following conditions
|
11
|
+
# are met:
|
12
|
+
#
|
13
|
+
# 1 Redistributions of source code must retain the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer.
|
15
|
+
#
|
16
|
+
# 2 Redistributions in binary form must reproduce the above copyright
|
17
|
+
# notice, this list of conditions and the following disclaimer in the
|
18
|
+
# documentation and/or other materials provided with the
|
19
|
+
# distribution.
|
20
|
+
#
|
21
|
+
# 3 Neither the name of the Authors, nor the names of its
|
22
|
+
# contributors may be used to endorse or promote products derived
|
23
|
+
# from this software wit hout specific prior written permission.
|
24
|
+
#
|
25
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
26
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
27
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
28
|
+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
29
|
+
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
30
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
31
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
32
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
33
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
34
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
36
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
require 'exempi/exceptions'
|
39
|
+
|
40
|
+
require 'date'
|
41
|
+
require 'ffi'
|
42
|
+
|
43
|
+
module Exempi
|
44
|
+
extend FFI::Library
|
45
|
+
|
46
|
+
# Option bits for xmp_files_open()
|
47
|
+
XMP_OPEN_FILE_OPTIONS = enum [
|
48
|
+
:XMP_OPEN_NOOPTION, 0x00000000, # No open option
|
49
|
+
:XMP_OPEN_READ, 0x00000001, # Open for read-only access.
|
50
|
+
:XMP_OPEN_FORUPDATE, 0x00000002, # Open for reading and writing.
|
51
|
+
:XMP_OPEN_ONLYXMP, 0x00000004, # Only the XMP is wanted, allows space/time optimizations.
|
52
|
+
:XMP_OPEN_CACHETNAIL, 0x00000008, # Cache thumbnail if possible, GetThumbnail will be called.
|
53
|
+
:XMP_OPEN_STRICTLY, 0x00000010, # Be strict about locating XMP and reconciling with other forms.
|
54
|
+
:XMP_OPEN_USESMARTHANDLER, 0x00000020, # Require the use of a smart handler.
|
55
|
+
:XMP_OPEN_USEPACKETSCANNING, 0x00000040, # Force packet scanning, don't use a smart handler.
|
56
|
+
:XMP_OPEN_LIMITSCANNING, 0x00000080, # Only packet scan files "known" to need scanning.
|
57
|
+
:XMP_OPEN_REPAIR_FILE, 0x00000100, # Attempt to repair a file opened for update, default is to not open (throw an exception).
|
58
|
+
:XMP_OPEN_INBACKGROUND, 0x10000000 # Set if calling from background thread.
|
59
|
+
]
|
60
|
+
|
61
|
+
# Option bits for xmp_files_close()
|
62
|
+
XMP_CLOSE_FILE_OPTIONS = enum [
|
63
|
+
:XMP_CLOSE_NOOPTION, 0x0000,
|
64
|
+
:XMP_CLOSE_SAFEUPDATE, 0x0001
|
65
|
+
]
|
66
|
+
|
67
|
+
# File formats
|
68
|
+
XMP_FILE_TYPE = enum [
|
69
|
+
:XMP_FT_PDF, 0x50444620, # 'PDF '
|
70
|
+
:XMP_FT_PS, 0x50532020, # 'PS ', general PostScript following DSC conventions.
|
71
|
+
:XMP_FT_EPS, 0x45505320, # 'EPS ', encapsulated PostScript.
|
72
|
+
|
73
|
+
:XMP_FT_JPEG, 0x4A504547, # 'JPEG'
|
74
|
+
:XMP_FT_JPEG2K, 0x4A505820, # 'JPX ', ISO 15444-1
|
75
|
+
:XMP_FT_TIFF, 0x54494646, # 'TIFF'
|
76
|
+
:XMP_FT_GIF, 0x47494620, # 'GIF '
|
77
|
+
:XMP_FT_PNG, 0x504E4720, # 'PNG '
|
78
|
+
|
79
|
+
:XMP_FT_SWF, 0x53574620, # 'SWF '
|
80
|
+
:XMP_FT_FLA, 0x464C4120, # 'FLA '
|
81
|
+
:XMP_FT_FLV, 0x464C5620, # 'FLV '
|
82
|
+
|
83
|
+
:XMP_FT_MOV, 0x4D4F5620, # 'MOV ', Quicktime
|
84
|
+
:XMP_FT_AVI, 0x41564920, # 'AVI '
|
85
|
+
:XMP_FT_CIN, 0x43494E20, # 'CIN ', Cineon
|
86
|
+
:XMP_FT_WAV, 0x57415620, # 'WAV '
|
87
|
+
:XMP_FT_MP3, 0x4D503320, # 'MP3 '
|
88
|
+
:XMP_FT_SES, 0x53455320, # 'SES ', Audition session
|
89
|
+
:XMP_FT_CEL, 0x43454C20, # 'CEL ', Audition loop
|
90
|
+
:XMP_FT_MPEG, 0x4D504547, # 'MPEG'
|
91
|
+
:XMP_FT_MPEG2, 0x4D503220, # 'MP2 '
|
92
|
+
:XMP_FT_MPEG4, 0x4D503420, # 'MP4 ', ISO 14494-12 and -14
|
93
|
+
:XMP_FT_WMAV, 0x574D4156, # 'WMAV', Windows Media Audio and Video
|
94
|
+
:XMP_FT_AIFF, 0x41494646, # 'AIFF'
|
95
|
+
|
96
|
+
:XMP_FT_HTML, 0x48544D4C, # 'HTML'
|
97
|
+
:XMP_FT_XML, 0x584D4C20, # 'XML '
|
98
|
+
:XMP_FT_TEXT, 0x74657874, # 'text'
|
99
|
+
|
100
|
+
# Adobe application file formats.
|
101
|
+
:XMP_FT_PHOTOSHOP, 0x50534420, # 'PSD '
|
102
|
+
:XMP_FT_ILLUSTRATOR, 0x41492020, # 'AI '
|
103
|
+
:XMP_FT_INDESIGN, 0x494E4444, # 'INDD'
|
104
|
+
:XMP_FT_AEPROJECT, 0x41455020, # 'AEP '
|
105
|
+
:XMP_FT_AEPROJTEMPLATE, 0x41455420, # 'AET ', After Effects Project Template
|
106
|
+
:XMP_FT_AEFILTERPRESET, 0x46465820, # 'FFX '
|
107
|
+
:XMP_FT_ENCOREPROJECT, 0x4E434F52, # 'NCOR'
|
108
|
+
:XMP_FT_PREMIEREPROJECT, 0x5052504A, # 'PRPJ'
|
109
|
+
:XMP_FT_PREMIERETITLE, 0x5052544C, # 'PRTL'
|
110
|
+
|
111
|
+
# Catch all.
|
112
|
+
:XMP_FT_UNKNOWN, 0x20202020
|
113
|
+
]
|
114
|
+
|
115
|
+
XMP_FILE_FORMAT_OPTIONS = enum [
|
116
|
+
:XMP_FMT_CAN_INJECT_XMP, 0x00000001,
|
117
|
+
:XMP_FMT_CAN_EXPAND, 0x00000002,
|
118
|
+
:XMP_FMT_CAN_REWRITE, 0x00000004,
|
119
|
+
:XMP_FMT_PREFERS_IN_PLACE, 0x00000008,
|
120
|
+
:XMP_FMT_CAN_RECONCILE, 0x00000010,
|
121
|
+
:XMP_FMT_ALLOWS_ONLY_XMP, 0x00000020,
|
122
|
+
:XMP_FMT_RETURNS_RAW_PACKET, 0x00000040,
|
123
|
+
:XMP_FMT_HANDLER_OWNS_FILE, 0x00000100,
|
124
|
+
:XMP_FMT_ALLOW_SAFE_UPDATE, 0x00000200,
|
125
|
+
:XMP_FMT_NEEDS_READONLY_PACKET, 0x00000400,
|
126
|
+
:XMP_FMT_USE_SIDECAR_XMP, 0x00000800,
|
127
|
+
:XMP_FMT_FOLDER_BASED_FORMAT, 0x00001000,
|
128
|
+
:_XMP_FMT_LAST
|
129
|
+
]
|
130
|
+
|
131
|
+
XMP_ITER_OPTIONS = enum [
|
132
|
+
:XMP_ITER_CLASSMASK, 0x00FF, # The low 8 bits are an enum of what data structure to iterate.
|
133
|
+
:XMP_ITER_PROPERTIES, 0x0000, # Iterate the property tree of a TXMPMeta object.
|
134
|
+
:XMP_ITER_ALIASES, 0x0001, # Iterate the global alias table.
|
135
|
+
:XMP_ITER_NAMESPACES, 0x0002, # Iterate the global namespace table.
|
136
|
+
:XMP_ITER_JUSTCHILDREN, 0x0100, # Just do the immediate children of the root, default is subtree.
|
137
|
+
:XMP_ITER_JUSTLEAFNODES, 0x0200, # Just do the leaf nodes, default is all nodes in the subtree.
|
138
|
+
:XMP_ITER_JUSTLEAFNAME, 0x0400, # Return just the leaf part of the path, default is the full path.
|
139
|
+
:XMP_ITER_INCLUDEALIASES, 0x0800, # Include aliases, default is just actual properties.
|
140
|
+
:XMP_ITER_OMITQUALIFIERS, 0x1000 # Omit all qualifiers.
|
141
|
+
]
|
142
|
+
|
143
|
+
XMP_ITER_SKIP_OPTIONS = enum [
|
144
|
+
:XMP_ITER_SKIPSUBTREE, 0x0001, # Skip the subtree below the current node.
|
145
|
+
:XMP_ITER_SKIPSIBLINGS, 0x0002 # Skip the subtree below and remaining siblings of the current node.
|
146
|
+
]
|
147
|
+
|
148
|
+
XMP_PROPS_BITS = enum [
|
149
|
+
# Options relating to the XML string form of the property value.
|
150
|
+
:XMP_PROP_VALUE_IS_URI, 0x00000002, # The value is a URI, use rdf:resource attribute.
|
151
|
+
# DISCOURAGED
|
152
|
+
|
153
|
+
# Options relating to qualifiers attached to a property.
|
154
|
+
:XMP_PROP_HAS_QUALIFIERS, 0x00000010, # The property has qualifiers, includes rdf:type and xml:lang.
|
155
|
+
:XMP_PROP_IS_QUALIFIER, 0x00000020, # This is a qualifier, includes rdf:type and xml:lang.
|
156
|
+
:XMP_PROP_HAS_LANG, 0x00000040, # Implies XMP_PropHasQualifiers, property has xml:lang.
|
157
|
+
:XMP_PROP_HAS_TYPE, 0x00000080, # Implies XMP_PropHasQualifiers, property has rdf:type.
|
158
|
+
|
159
|
+
# Options relating to the data structure form.
|
160
|
+
:XMP_PROP_VALUE_IS_STRUCT, 0x00000100, # The value is a structure with nested fields.
|
161
|
+
:XMP_PROP_VALUE_IS_ARRAY, 0x00000200, # The value is an array (RDF alt/bag/seq).
|
162
|
+
:XMP_PROP_ARRAY_IS_UNORDERED, 0x00000200, # The item order does not matter. (e.g. same as XMP_PROP_VALUE_IS_ARRAY)
|
163
|
+
:XMP_PROP_ARRAY_IS_ORDERED, 0x00000400, # Implies XMP_PropValueIsArray, item order matters.
|
164
|
+
:XMP_PROP_ARRAY_IS_ALT, 0x00000800, # Implies XMP_PropArrayIsOrdered, items are alternates.
|
165
|
+
|
166
|
+
# Additional struct and array options.
|
167
|
+
:XMP_PROP_ARRAY_IS_ALTTEXT, 0x00001000, # Implies kXMP_PropArrayIsAlternate, items are localized text.
|
168
|
+
:XMP_PROP_ARRAY_INSERT_BEFORE, 0x00004000, # Used by array functions.
|
169
|
+
:XMP_PROP_ARRAY_INSERT_AFTER, 0x00008000, # Used by array functions.
|
170
|
+
|
171
|
+
# Other miscellaneous options.
|
172
|
+
:XMP_PROP_IS_ALIAS, 0x00010000, # This property is an alias name for another property.
|
173
|
+
:XMP_PROP_HAS_ALIASES, 0x00020000, # This property is the base value for a set of aliases.
|
174
|
+
:XMP_PROP_IS_INTERNAL, 0x00040000, # This property is an "internal" property, owned by applications.
|
175
|
+
:XMP_PROP_IS_STABLE, 0x00100000, # This property is not derived from the document content.
|
176
|
+
:XMP_PROP_IS_DERIVED, 0x00200000, # This property is derived from the document content.
|
177
|
+
|
178
|
+
# Note that these are commented out in Exempi
|
179
|
+
# kXMPUtil_AllowCommas, 0x10000000UL, ! Used by TXMPUtils::CatenateArrayItems and ::SeparateArrayItems.
|
180
|
+
# kXMP_DeleteExisting, 0x20000000UL, ! Used by TXMPMeta::SetXyz functions to delete any pre-existing property.
|
181
|
+
# kXMP_SchemaNode, 0x80000000UL, ! Returned by iterators - #define to avoid warnings
|
182
|
+
|
183
|
+
# Original values of these bitmasks noted; we can't access them by name
|
184
|
+
# XMP_PROP_ARRAY_FORM_MASK = XMP_PROP_VALUE_IS_ARRAY | XMP_PROP_ARRAY_IS_ORDERED | XMP_PROP_ARRAY_IS_ALT | XMP_PROP_ARRAY_IS_ALTTEXT,
|
185
|
+
:XMP_PROP_ARRAY_FORM_MASK, 0x00000200 | 0x00000400 | 0x00000800 | 0x00001000,
|
186
|
+
|
187
|
+
# XMP_PROP_COMPOSITE_MASK = XMP_PROP_VALUE_IS_STRUCT | XMP_PROP_ARRAY_FORM_MASK, /* Is it simple or composite (array or struct)? */
|
188
|
+
:XMP_PROP_COMPOSITE_MASK, 0x00000100 | 0x00001E00,
|
189
|
+
:XMP_IMPL_RESERVED_MASK, 0x70000000 # Reserved for transient use by the implementation.
|
190
|
+
]
|
191
|
+
|
192
|
+
# These values are used in the enum below
|
193
|
+
XMP_LITTLEENDIAN_BIT = 0x0001 # ! Don't use directly, see the combined values below!
|
194
|
+
XMP_UTF16_BIT = 0x0002
|
195
|
+
XMP_UTF32_BIT = 0x0004
|
196
|
+
|
197
|
+
# Options for xmp_serialize
|
198
|
+
# Unnamed in exempi, named :XmpSerialOptions here
|
199
|
+
XMP_SERIAL_OPTIONS = enum [
|
200
|
+
:XMP_SERIAL_OMITPACKETWRAPPER, 0x0010, # Omit the XML packet wrapper. */
|
201
|
+
:XMP_SERIAL_READONLYPACKET, 0x0020, # Defat is a writeable packet. */
|
202
|
+
:XMP_SERIAL_USECOMPACTFORMAT, 0x0040, # Use a compact form of RDF. */
|
203
|
+
|
204
|
+
:XMP_SERIAL_INCLUDETHUMBNAILPAD, 0x0100, # Include a padding allowance for a thumbnail image. */
|
205
|
+
:XMP_SERIAL_EXACTPACKETLENGTH, 0x0200, # The padding parameter is the overall packet length. */
|
206
|
+
:XMP_SERIAL_WRITEALIASCOMMENTS, 0x0400, # Show aliases as XML comments. */
|
207
|
+
:XMP_SERIAL_OMITALLFORMATTING, 0x0800, # Omit all formatting whitespace. */
|
208
|
+
|
209
|
+
:XMP_SERIAL_ENCODINGMASK, 0x0007,
|
210
|
+
:XMP_SERIAL_ENCODEUTF8, 0,
|
211
|
+
:XMP_SERIAL_ENCODEUTF16BIG, XMP_UTF16_BIT,
|
212
|
+
:XMP_SERIAL_ENCODEUTF16LITTLE, XMP_UTF16_BIT | XMP_LITTLEENDIAN_BIT,
|
213
|
+
:XMP_SERIAL_ENCODEUTF32BIG, XMP_UTF32_BIT,
|
214
|
+
:XMP_SERIAL_ENCODEUTF32LITTLE, XMP_UTF32_BIT | XMP_LITTLEENDIAN_BIT
|
215
|
+
]
|
216
|
+
|
217
|
+
# Values used for tzSign field.
|
218
|
+
# Another unnamed enum, used in XmpDateTime below
|
219
|
+
TzSignValues = enum [
|
220
|
+
:XMP_TZ_WEST, -1, # West of UTC
|
221
|
+
:XMP_TZ_UTC, 0, # UTC
|
222
|
+
:XMP_TZ_EAST, +1 # East of UTC
|
223
|
+
]
|
224
|
+
|
225
|
+
class XmpDateTime < FFI::Struct
|
226
|
+
layout(
|
227
|
+
:year, :int32,
|
228
|
+
:month, :int32, # 1..12
|
229
|
+
:day, :int32, # 1..31
|
230
|
+
:hour, :int32, # 0..23
|
231
|
+
:minute, :int32, # 0..59
|
232
|
+
:second, :int32, # 0..59
|
233
|
+
:tzSign, Exempi::TzSignValues, # -1..+1, 0 means UTC, -1 is west, +1 is east.
|
234
|
+
:tzHour, :int32, # 0..23
|
235
|
+
:tzMinute, :int32, # 0..59
|
236
|
+
:nanoSecond, :int32
|
237
|
+
)
|
238
|
+
|
239
|
+
# Converts a XmpDateTime struct into a Ruby object
|
240
|
+
# @return [DateTime] A new Ruby DateTime object
|
241
|
+
def to_datetime
|
242
|
+
sign = self[:tzSign] == :XMP_TZ_WEST ? '-' : '+'
|
243
|
+
zone = "%s%02d:%02d" % [sign, self[:tzHour], self[:tzMinute]]
|
244
|
+
|
245
|
+
second = self[:second] + Rational(self[:nanoSecond],1000000000)
|
246
|
+
|
247
|
+
DateTime.new self[:year], self[:month], self[:day], self[:hour],
|
248
|
+
self[:minute], second, zone
|
249
|
+
end
|
250
|
+
|
251
|
+
# Creates an XmpDateTime struct using a Ruby DateTime object,
|
252
|
+
# or a date string which is parseable by DateTime
|
253
|
+
# @param [DateTime, String] source the date to convert
|
254
|
+
# @return [Exempi::XmpDateTime] an XmpDateTime struct
|
255
|
+
def self.from_datetime source
|
256
|
+
if source.is_a? String
|
257
|
+
source = DateTime.parse source
|
258
|
+
end
|
259
|
+
|
260
|
+
struct = self.new
|
261
|
+
[:year, :month, :day, :hour, :minute, :second].each do |field|
|
262
|
+
struct[field] = source.send field
|
263
|
+
end
|
264
|
+
struct[:nanoSecond] = source.to_time.nsec
|
265
|
+
|
266
|
+
match = source.zone.match /(?<sign>[-+]){1}(?<hour>\d\d){1}:(?<minute>\d\d){1}/
|
267
|
+
if match
|
268
|
+
if match[:sign] == '-' then struct[:tzSign] = -1
|
269
|
+
elsif match[:hour] == '00' && match[:minute] == '00' then struct[:tzSign] = 0
|
270
|
+
else struct[:tzSign] = 1
|
271
|
+
end
|
272
|
+
|
273
|
+
struct[:tzHour] = match[:hour].to_i
|
274
|
+
struct[:tzMinute] = match[:minute].to_i
|
275
|
+
end
|
276
|
+
|
277
|
+
struct
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# Creates DataConverter classes from each of these enums
|
282
|
+
[ "XMP_OPEN_FILE_OPTIONS", "XMP_CLOSE_FILE_OPTIONS", "XMP_FILE_TYPE",
|
283
|
+
"XMP_FILE_FORMAT_OPTIONS", "XMP_ITER_OPTIONS", "XMP_ITER_SKIP_OPTIONS",
|
284
|
+
"XMP_PROPS_BITS", "XMP_SERIAL_OPTIONS" ].each do |enum|
|
285
|
+
klass = Class.new do
|
286
|
+
extend FFI::DataConverter
|
287
|
+
native_type FFI::Type::INT
|
288
|
+
@enum = enum
|
289
|
+
|
290
|
+
def self.to_native(values, ctx)
|
291
|
+
case values
|
292
|
+
when Symbol
|
293
|
+
val = Exempi.const_get(@enum)[values]
|
294
|
+
if not val
|
295
|
+
raise Exempi::InvalidOptionError,
|
296
|
+
"#{values} is not a valid option for #{@enum}"
|
297
|
+
else
|
298
|
+
val
|
299
|
+
end
|
300
|
+
when Fixnum then values
|
301
|
+
when NilClass then 0
|
302
|
+
else
|
303
|
+
invalid_opt = values.find {|v| Exempi.const_get(@enum)[v].nil?}
|
304
|
+
if invalid_opt
|
305
|
+
raise Exempi::InvalidOptionError,
|
306
|
+
"#{invalid_opt} is not a valid option for #{@enum}"
|
307
|
+
end
|
308
|
+
|
309
|
+
values.inject(0) {|mask, value| mask |= Exempi.const_get(@enum)[value]}
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
klass_name = enum.split("_").map {|str| str.capitalize}.join
|
315
|
+
const_set klass_name, klass
|
316
|
+
end
|
317
|
+
|
318
|
+
# Converts a bitfield into a hash of named options via bitwise AND.
|
319
|
+
# @param [Integer] int the bitfield integer
|
320
|
+
# @param [FFI::Enum] enum the enum with which to compare
|
321
|
+
# @param [Boolean] short_name true to return shortened option names
|
322
|
+
# @return [Hash] a hash which includes symbol representations of the included options
|
323
|
+
def self.parse_bitmask int, enum, short_name=false
|
324
|
+
enum_hash = enum.to_hash
|
325
|
+
opt_hash = {}
|
326
|
+
enum_hash.each do |k,v|
|
327
|
+
if short_name
|
328
|
+
option = k.to_s.split("_")[2..-1].join("_").downcase.to_sym
|
329
|
+
else
|
330
|
+
option = k
|
331
|
+
end
|
332
|
+
|
333
|
+
opt_hash[option] = ((int & v) == v)
|
334
|
+
end
|
335
|
+
|
336
|
+
opt_hash
|
337
|
+
end
|
338
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Error values and comments are taken from Exempi's xmperrors.h
|
2
|
+
#
|
3
|
+
# Copyright (C) 2015 Misty De Meo
|
4
|
+
# Copyright (C) 2012 Canadian Museum for Human Rights
|
5
|
+
# Copyright (C) 2007 Hubert Figuiere
|
6
|
+
# Copyright 2002-2007 Adobe Systems Incorporated
|
7
|
+
# All rights reserved.
|
8
|
+
#
|
9
|
+
# Redistribution and use in source and binary forms, with or without
|
10
|
+
# modification, are permitted provided that the following conditions
|
11
|
+
# are met:
|
12
|
+
#
|
13
|
+
# 1 Redistributions of source code must retain the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer.
|
15
|
+
#
|
16
|
+
# 2 Redistributions in binary form must reproduce the above copyright
|
17
|
+
# notice, this list of conditions and the following disclaimer in the
|
18
|
+
# documentation and/or other materials provided with the
|
19
|
+
# distribution.
|
20
|
+
#
|
21
|
+
# 3 Neither the name of the Authors, nor the names of its
|
22
|
+
# contributors may be used to endorse or promote products derived
|
23
|
+
# from this software wit hout specific prior written permission.
|
24
|
+
#
|
25
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
26
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
27
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
28
|
+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
29
|
+
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
30
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
31
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
32
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
33
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
34
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
36
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
module Exempi
|
39
|
+
# This maps the numeric exceptions to their names.
|
40
|
+
# The numeric values are output by xmp_get_error()
|
41
|
+
ErrorCodes = {
|
42
|
+
# More or less generic error codes.
|
43
|
+
0 => :XMPErr_Unknown,
|
44
|
+
-1 => :XMPErr_TBD,
|
45
|
+
-2 => :XMPErr_Unavailable,
|
46
|
+
-3 => :XMPErr_BadObject,
|
47
|
+
-4 => :XMPErr_BadParam,
|
48
|
+
-5 => :XMPErr_BadValue,
|
49
|
+
-6 => :XMPErr_AssertFailure,
|
50
|
+
-7 => :XMPErr_EnforceFailure,
|
51
|
+
-8 => :XMPErr_Unimplemented,
|
52
|
+
-9 => :XMPErr_InternalFailure,
|
53
|
+
-10 => :XMPErr_Deprecated,
|
54
|
+
-11 => :XMPErr_ExternalFailure,
|
55
|
+
-12 => :XMPErr_UserAbort,
|
56
|
+
-13 => :XMPErr_StdException,
|
57
|
+
-14 => :XMPErr_UnknownException,
|
58
|
+
-15 => :XMPErr_NoMemory,
|
59
|
+
|
60
|
+
# More specific parameter error codes.
|
61
|
+
-101 => :XMPErr_BadSchema,
|
62
|
+
-102 => :XMPErr_BadXPath,
|
63
|
+
-103 => :XMPErr_BadOptions,
|
64
|
+
-104 => :XMPErr_BadIndex,
|
65
|
+
-105 => :XMPErr_BadIterPosition,
|
66
|
+
-106 => :XMPErr_BadParse,
|
67
|
+
-107 => :XMPErr_BadSerialize,
|
68
|
+
-108 => :XMPErr_BadFileFormat,
|
69
|
+
-109 => :XMPErr_NoFileHandler,
|
70
|
+
-110 => :XMPErr_TooLargeForJPEG,
|
71
|
+
|
72
|
+
# File format and internal structure error codes.
|
73
|
+
-201 => :XMPErr_BadXML,
|
74
|
+
-202 => :XMPErr_BadRDF,
|
75
|
+
-203 => :XMPErr_BadXMP,
|
76
|
+
-204 => :XMPErr_EmptyIterator,
|
77
|
+
-205 => :XMPErr_BadUnicode,
|
78
|
+
-206 => :XMPErr_BadTIFF,
|
79
|
+
-207 => :XMPErr_BadJPEG,
|
80
|
+
-208 => :XMPErr_BadPSD,
|
81
|
+
-209 => :XMPErr_BadPSIR,
|
82
|
+
-210 => :XMPErr_BadIPTC,
|
83
|
+
-211 => :XMPErr_BadMPEG
|
84
|
+
}
|
85
|
+
|
86
|
+
# Returns a symbol representing the XMP error for an int code.
|
87
|
+
# Used with the output of Exempi.xmp_get_error
|
88
|
+
# This is just a bit of sugar over Exempi::ErrorCodes[code]
|
89
|
+
# @param [Integer] code integer error code; should be obtained from
|
90
|
+
# Exempi.xmp_get_error
|
91
|
+
def self.exception_for code
|
92
|
+
if !ErrorCodes[code]
|
93
|
+
raise ArgumentError, "#{error_code} is not an Exempi error code"
|
94
|
+
end
|
95
|
+
ErrorCodes[code]
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'exempi/errors'
|
2
|
+
|
3
|
+
module Exempi
|
4
|
+
# This class provides a convenient interface for throwing exceptions
|
5
|
+
# when using Exempi functions. It allows the caller to specify an
|
6
|
+
# error code (retrievable from xmp_get_error()), and provides a
|
7
|
+
# method to retrieve the error name based on the code.
|
8
|
+
class ExempiError < StandardError
|
9
|
+
attr :error_code
|
10
|
+
def initialize error_code=0
|
11
|
+
if !Exempi::ErrorCodes[error_code]
|
12
|
+
raise ArgumentError, "#{error_code} is not an Exempi error code"
|
13
|
+
end
|
14
|
+
@error_code = error_code
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Symbol] Exempi's error string for this exception
|
18
|
+
def xmp_error
|
19
|
+
Exempi::ErrorCodes[@error_code]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class InvalidOptionError < StandardError; end
|
24
|
+
end
|
@@ -0,0 +1,325 @@
|
|
1
|
+
# These comments are taken from Exempi's xmp.h
|
2
|
+
#
|
3
|
+
# Copyright (C) 2015 Misty De Meo
|
4
|
+
# Copyright (C) 2012 Canadian Museum for Human Rights
|
5
|
+
# Copyright (C) 2007-2008,2012 Hubert Figuiere
|
6
|
+
# Copyright 2002-2007 Adobe Systems Incorporated
|
7
|
+
# All rights reserved.
|
8
|
+
#
|
9
|
+
# Redistribution and use in source and binary forms, with or without
|
10
|
+
# modification, are permitted provided that the following conditions
|
11
|
+
# are met:
|
12
|
+
#
|
13
|
+
# 1 Redistributions of source code must retain the above copyright
|
14
|
+
# notice, this list of conditions and the following disclaimer.
|
15
|
+
#
|
16
|
+
# 2 Redistributions in binary form must reproduce the above copyright
|
17
|
+
# notice, this list of conditions and the following disclaimer in the
|
18
|
+
# documentation and/or other materials provided with the
|
19
|
+
# distribution.
|
20
|
+
#
|
21
|
+
# 3 Neither the name of the Authors, nor the names of its
|
22
|
+
# contributors may be used to endorse or promote products derived
|
23
|
+
# from this software wit hout specific prior written permission.
|
24
|
+
#
|
25
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
26
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
27
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
28
|
+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
29
|
+
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
30
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
31
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
32
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
33
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
34
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
35
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
36
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
|
38
|
+
require 'exempi/consts'
|
39
|
+
|
40
|
+
require 'ffi'
|
41
|
+
|
42
|
+
module Exempi
|
43
|
+
extend FFI::Library
|
44
|
+
ffi_lib 'exempi'
|
45
|
+
|
46
|
+
# we redefine attach_function so we can wrap all of the C functions
|
47
|
+
class << self
|
48
|
+
def verbose?; @verbose; end
|
49
|
+
attr_writer :verbose
|
50
|
+
|
51
|
+
def attach_function name, func, args, returns=nil, options={}
|
52
|
+
super
|
53
|
+
old_method = method(name)
|
54
|
+
define_singleton_method(name) do |*args|
|
55
|
+
shutup! { old_method.call(*args) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
# Exempi spews stderr all over the place without giving you any way
|
62
|
+
# to quiet it! Boo!
|
63
|
+
def shutup!
|
64
|
+
if not verbose?
|
65
|
+
io = IO.new 2
|
66
|
+
stderr = io.dup
|
67
|
+
io.reopen IO::NULL
|
68
|
+
end
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
io.reopen stderr unless verbose?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Init the library. Must be called before anything else
|
76
|
+
attach_function :xmp_init, [ ], :bool
|
77
|
+
attach_function :xmp_terminate, [ ], :void
|
78
|
+
|
79
|
+
# get the error code that last occurred.
|
80
|
+
# @todo make this thread-safe. Getting the error code
|
81
|
+
# from another thread than the on it occurred in is undefined.
|
82
|
+
attach_function :xmp_get_error, [ ], :int
|
83
|
+
|
84
|
+
attach_function :xmp_files_new, [ ], :pointer
|
85
|
+
attach_function :xmp_files_open_new, [ :string, XmpOpenFileOptions ], :pointer
|
86
|
+
attach_function :xmp_files_open, [ :pointer, :string, XmpOpenFileOptions ], :bool
|
87
|
+
|
88
|
+
# Close an XMP file. Will flush the changes.
|
89
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xf the file object
|
90
|
+
# @param [Exempi::XmpCloseFileOptions] options the options to close.
|
91
|
+
# @return [Boolean] true on succes, false on error
|
92
|
+
# xmp_get_error() will give the error code.
|
93
|
+
attach_function :xmp_files_close, [ :pointer, XmpCloseFileOptions ], :bool
|
94
|
+
|
95
|
+
attach_function :xmp_files_get_new_xmp, [ :pointer ], :pointer
|
96
|
+
attach_function :xmp_files_get_xmp, [ :pointer, :pointer ], :bool
|
97
|
+
|
98
|
+
attach_function :xmp_files_can_put_xmp, [ :pointer, :pointer ], :bool
|
99
|
+
attach_function :xmp_files_put_xmp, [ :pointer, :pointer ], :bool
|
100
|
+
|
101
|
+
# Get the file info from the open file
|
102
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xf the file object
|
103
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] filePath the file path object to store the path in. Pass NULL if not needed.
|
104
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] options the options for open. Pass NULL if not needed.
|
105
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] file_format the detected file format. Pass NULL if not needed.
|
106
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] handler_flags the format options like from %xmp_files_get_format_info.
|
107
|
+
# @return [Boolean] false in case of error.
|
108
|
+
attach_function :xmp_files_get_file_info, [ :pointer, :pointer, :pointer, :pointer, :pointer ], :bool
|
109
|
+
|
110
|
+
# Free a XmpFilePtr.
|
111
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xf the file ptr. Cannot be NULL
|
112
|
+
# @return [Boolean] false on error.
|
113
|
+
# xmp_get_error() will give the error code.
|
114
|
+
attach_function :xmp_files_free, [ :pointer ], :bool
|
115
|
+
|
116
|
+
# Get the format info
|
117
|
+
# @param [Integer] format type identifier
|
118
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] option the options for the file format handler
|
119
|
+
# @return [Boolean] false on error
|
120
|
+
attach_function :xmp_files_get_format_info, [ :int, :pointer ], :bool
|
121
|
+
|
122
|
+
# Check the file format of a file. Use the same logic as in xmp_files_open()
|
123
|
+
# @param [String] filePath the path to the file
|
124
|
+
# @return [Integer] XMP_FT_UNKNOWN on error or if the file type is unknown
|
125
|
+
attach_function :xmp_files_check_file_format, [ :string ], :int
|
126
|
+
|
127
|
+
# Register a new namespace to add properties to.
|
128
|
+
# This is done automatically when reading the metadata block
|
129
|
+
# @param [String] namespaceURI the namespace URI to register
|
130
|
+
# @param [String] suggestedPrefix the suggested prefix
|
131
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] registeredPrefix the really registered prefix. Not necessarily
|
132
|
+
# %suggestedPrefix.
|
133
|
+
# @return [Boolean] true if success, false otherwise.
|
134
|
+
attach_function :xmp_register_namespace, [ :string, :string, :pointer ], :bool
|
135
|
+
|
136
|
+
# Check if a namespace is registered.
|
137
|
+
# @param [String] ns the namespace to check.
|
138
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] prefix The prefix associated if registered. Pass NULL
|
139
|
+
# if not interested.
|
140
|
+
# @return [Boolean] true if registered.
|
141
|
+
# NEW in 2.1
|
142
|
+
attach_function :xmp_namespace_prefix, [ :string, :pointer ], :bool
|
143
|
+
|
144
|
+
# Check if a ns prefix is registered.
|
145
|
+
# @param [String] prefix the prefix to check.
|
146
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] ns the namespace associated if registered. Pass NULL
|
147
|
+
# if not interested.
|
148
|
+
# @return [Boolean] true if registered.
|
149
|
+
# NEW in 2.1
|
150
|
+
attach_function :xmp_prefix_namespace_uri, [ :string, :pointer ], :bool
|
151
|
+
|
152
|
+
attach_function :xmp_new_empty, [ ], :pointer
|
153
|
+
|
154
|
+
# Create a new XMP packet
|
155
|
+
# @param [String] buffer the buffer to load data from. UTF-8 encoded.
|
156
|
+
# @param [Integer] len the buffer length in byte
|
157
|
+
# @return [FFI::Pointer] the packet pointer. Must be free with xmp_free()
|
158
|
+
attach_function :xmp_new, [ :string, :uint ], :pointer
|
159
|
+
|
160
|
+
# Create a new XMP packet from the one passed.
|
161
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the instance to copy. Can be NULL.
|
162
|
+
# @return [FFI::Pointer] the packet pointer. NULL is failer (or NULL is passed).
|
163
|
+
attach_function :xmp_copy, [ :pointer ], :pointer
|
164
|
+
|
165
|
+
# Free the xmp packet
|
166
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the xmp packet to free
|
167
|
+
attach_function :xmp_free, [ :pointer ], :bool
|
168
|
+
|
169
|
+
# Parse the XML passed through the buffer and load
|
170
|
+
# it.
|
171
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet.
|
172
|
+
# @param [String] buffer the buffer.
|
173
|
+
# @param [Integer] len the length of the buffer.
|
174
|
+
attach_function :xmp_parse, [ :pointer, :string, :uint ], :bool
|
175
|
+
|
176
|
+
# Serialize the XMP Packet to the given buffer
|
177
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP Packet
|
178
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] buffer the buffer to write the XMP to
|
179
|
+
# @param [Exempi::XmpSerialOptions] options options on how to write the XMP. See XMP_SERIAL_*
|
180
|
+
# @param [Integer] padding number of bytes of padding, useful for modifying
|
181
|
+
# embedded XMP in place.
|
182
|
+
# @return [Boolean] TRUE if success.
|
183
|
+
attach_function :xmp_serialize, [ :pointer, :pointer, XmpSerialOptions, :uint32 ], :bool
|
184
|
+
|
185
|
+
# Serialize the XMP Packet to the given buffer with formatting
|
186
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP Packet
|
187
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] buffer the buffer to write the XMP to
|
188
|
+
# @param [Exempi::XmpSerialOptions] options options on how to write the XMP. See XMP_SERIAL_*
|
189
|
+
# @param [Integer] padding number of bytes of padding, useful for modifying
|
190
|
+
# embedded XMP in place.
|
191
|
+
# @param [String] newline the new line character to use
|
192
|
+
# @param [String] tab the indentation character to use
|
193
|
+
# @param [Integer] indent the initial indentation level
|
194
|
+
# @return [Boolean] TRUE if success.
|
195
|
+
attach_function :xmp_serialize_and_format, [ :pointer, :pointer, XmpSerialOptions, :uint32, :string, :string, :int32 ], :bool
|
196
|
+
|
197
|
+
# Get an XMP property and it option bits from the XMP packet
|
198
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
199
|
+
# @param [String] schema
|
200
|
+
# @param [String] name
|
201
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] property the allocated XmpStringPtr
|
202
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] propsBits pointer to the option bits. Pass NULL if not needed
|
203
|
+
# @return [Boolean] true if found
|
204
|
+
attach_function :xmp_get_property, [ :pointer, :string, :string, :pointer, :pointer ], :bool
|
205
|
+
attach_function :xmp_get_property_date, [ :pointer, :string, :string, XmpDateTime, :pointer ], :bool
|
206
|
+
attach_function :xmp_get_property_float, [ :pointer, :string, :string, :pointer, :pointer ], :bool
|
207
|
+
attach_function :xmp_get_property_bool, [ :pointer, :string, :string, :pointer, :pointer ], :bool
|
208
|
+
attach_function :xmp_get_property_int32, [ :pointer, :string, :string, :pointer, :pointer ], :bool
|
209
|
+
attach_function :xmp_get_property_int64, [ :pointer, :string, :string, :pointer, :pointer ], :bool
|
210
|
+
|
211
|
+
# Get an item frpm an array property
|
212
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the xmp meta
|
213
|
+
# @param [String] schema the schema
|
214
|
+
# @param [String] name the property name
|
215
|
+
# @param [Integer] index the index in the array
|
216
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] property the property value
|
217
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] propsBits the property bits. Pass NULL is unwanted.
|
218
|
+
# @return [Boolean] TRUE if success.
|
219
|
+
attach_function :xmp_get_array_item, [ :pointer, :string, :string, :int32, :pointer, :pointer ], :bool
|
220
|
+
|
221
|
+
# Set an XMP property in the XMP packet
|
222
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
223
|
+
# @param [String] schema
|
224
|
+
# @param [String] name
|
225
|
+
# @param [String] value 0 terminated string
|
226
|
+
# @param [Exempi::XmpPropsBits] optionBits
|
227
|
+
# @return [Boolean] false if failure
|
228
|
+
attach_function :xmp_set_property, [ :pointer, :string, :string, :string, XmpPropsBits ], :bool
|
229
|
+
|
230
|
+
# Set a date XMP property in the XMP packet
|
231
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
232
|
+
# @param [String] schema
|
233
|
+
# @param [String] name
|
234
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] value the date-time struct
|
235
|
+
# @param [Exempi::XmpPropsBits] optionBits
|
236
|
+
# @return [Boolean] false if failure
|
237
|
+
attach_function :xmp_set_property_date, [ :pointer, :string, :string, :pointer, XmpPropsBits ], :bool
|
238
|
+
|
239
|
+
# Set a float XMP property in the XMP packet
|
240
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
241
|
+
# @param [String] schema
|
242
|
+
# @param [String] name
|
243
|
+
# @param [Float] value the float value
|
244
|
+
# @param [Exempi::XmpPropsBits] optionBits
|
245
|
+
# @return [Boolean] false if failure
|
246
|
+
attach_function :xmp_set_property_float, [ :pointer, :string, :string, :double, XmpPropsBits ], :bool
|
247
|
+
attach_function :xmp_set_property_bool, [ :pointer, :string, :string, :bool, XmpPropsBits ], :bool
|
248
|
+
attach_function :xmp_set_property_int32, [ :pointer, :string, :string, :int32, XmpPropsBits ], :bool
|
249
|
+
attach_function :xmp_set_property_int64, [ :pointer, :string, :string, :int64, XmpPropsBits ], :bool
|
250
|
+
attach_function :xmp_set_array_item, [ :pointer, :string, :string, :int32, :string, :uint32 ], :bool
|
251
|
+
|
252
|
+
attach_function :xmp_append_array_item, [ :pointer, :string, :string, :uint32, :string, :uint32 ], :bool
|
253
|
+
|
254
|
+
# Delete a property from the XMP Packet provided
|
255
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
256
|
+
# @param [String] schema the schema of the property
|
257
|
+
# @param [String] name the name of the property
|
258
|
+
attach_function :xmp_delete_property, [ :pointer, :string, :string ], :bool
|
259
|
+
|
260
|
+
# Determines if a property exists in the XMP Packet provided
|
261
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
262
|
+
# @param [String] schema the schema of the property. Can't be NULL or empty.
|
263
|
+
# @param [String] name the name of the property. Can't be NULL or empty.
|
264
|
+
# @return [Boolean] true is the property exists
|
265
|
+
attach_function :xmp_has_property, [ :pointer, :string, :string ], :bool
|
266
|
+
|
267
|
+
# Get a localised text from a localisable property.
|
268
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
269
|
+
# @param [String] schema the schema
|
270
|
+
# @param [String] name the property name.
|
271
|
+
# @param [String] genericLang the generic language you may want as a fall back.
|
272
|
+
# Can be NULL or empty.
|
273
|
+
# @param [String] specificLang the specific language you want. Can't be NULL or empty.
|
274
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] actualLang the actual language of the value. Can be NULL if
|
275
|
+
# not wanted.
|
276
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] itemValue the localized value. Can be NULL if not wanted.
|
277
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] propBits the options flags describing the property. Can be NULL.
|
278
|
+
# @return [Boolean] true if found, false otherwise.
|
279
|
+
attach_function :xmp_get_localized_text, [ :pointer, :string, :string, :string, :string, :pointer, :pointer, :pointer ], :bool
|
280
|
+
|
281
|
+
# Set a localised text in a localisable property.
|
282
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] xmp the XMP packet
|
283
|
+
# @param [String] schema the schema
|
284
|
+
# @param [String] name the property name.
|
285
|
+
# @param [String] genericLang the generic language you may want to set too.
|
286
|
+
# Can be NULL or empty.
|
287
|
+
# @param [String] specificLang the specific language you want. Can't be NULL or empty.
|
288
|
+
# @param [String] value the localized value. Cannot be NULL.
|
289
|
+
# @param [Exempi::XmpPropsBits] optionBits the options flags describing the property.
|
290
|
+
# @return [Boolean] true if set, false otherwise.
|
291
|
+
attach_function :xmp_set_localized_text, [ :pointer, :string, :string, :string, :string, :string, XmpPropsBits ], :bool
|
292
|
+
|
293
|
+
attach_function :xmp_delete_localized_text, [ :pointer, :string, :string, :string, :string ], :bool
|
294
|
+
|
295
|
+
# Instanciate a new string
|
296
|
+
# @return [FFI::Pointer] the new instance. Must be freed with
|
297
|
+
# xmp_string_free()
|
298
|
+
attach_function :xmp_string_new, [ ], :pointer
|
299
|
+
|
300
|
+
# Free a XmpStringPtr
|
301
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] s the string to free
|
302
|
+
attach_function :xmp_string_free, [ :pointer ], :void
|
303
|
+
|
304
|
+
# Get the C string from the XmpStringPtr
|
305
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] s the string object
|
306
|
+
# @return [String] the const char * for the XmpStringPtr. It
|
307
|
+
# belong to the object.
|
308
|
+
attach_function :xmp_string_cstr, [ :pointer ], :string
|
309
|
+
|
310
|
+
attach_function :xmp_iterator_new, [ :pointer, :string, :string, XmpIterOptions ], :pointer
|
311
|
+
attach_function :xmp_iterator_free, [ :pointer ], :bool
|
312
|
+
|
313
|
+
# Iterate to the next value
|
314
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] iter the iterator
|
315
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] schema the schema name. Pass NULL if not wanted
|
316
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] propName the property path. Pass NULL if not wanted
|
317
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] propValue the value of the property. Pass NULL if not wanted.
|
318
|
+
# @param [FFI::Pointer, FFI::MemoryPointer] options the options for the property. Pass NULL if not wanted.
|
319
|
+
# @return [Boolean] true if still something, false if none
|
320
|
+
attach_function :xmp_iterator_next, [ :pointer, :pointer, :pointer, :pointer, :pointer ], :bool
|
321
|
+
attach_function :xmp_iterator_skip, [ :pointer, XmpIterSkipOptions ], :bool
|
322
|
+
|
323
|
+
# We do this first, before anything else!!
|
324
|
+
xmp_init
|
325
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
# Copyright 2002 Adobe Systems Incorporated
|
2
|
+
# All Rights Reserved.
|
3
|
+
#
|
4
|
+
# NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
|
5
|
+
# of the Adobe license agreement accompanying it.
|
6
|
+
#
|
7
|
+
# Copyright (c) 1999 - 2010, Adobe Systems IncorporatedAll rights reserved.
|
8
|
+
#
|
9
|
+
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
10
|
+
#
|
11
|
+
# * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
12
|
+
#
|
13
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# * Neither the name of Adobe Systems Incorporated, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER ORCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ORPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDINGNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
18
|
+
|
19
|
+
module Exempi
|
20
|
+
module Namespaces
|
21
|
+
# Standard namespace URI constants
|
22
|
+
#
|
23
|
+
# \name XML namespace constants for standard XMP schema.
|
24
|
+
# @{
|
25
|
+
#
|
26
|
+
# \def XMP_NS_XMP
|
27
|
+
# \brief The XML namespace for the XMP "basic" schema.
|
28
|
+
#
|
29
|
+
# \def XMP_NS_XMP_Rights
|
30
|
+
# \brief The XML namespace for the XMP copyright schema.
|
31
|
+
#
|
32
|
+
# \def XMP_NS_XMP_MM
|
33
|
+
# \brief The XML namespace for the XMP digital asset management schema.
|
34
|
+
#
|
35
|
+
# \def XMP_NS_XMP_BJ
|
36
|
+
# \brief The XML namespace for the job management schema.
|
37
|
+
#
|
38
|
+
# \def XMP_NS_XMP_T
|
39
|
+
# \brief The XML namespace for the XMP text document schema.
|
40
|
+
#
|
41
|
+
# \def XMP_NS_XMP_T_PG
|
42
|
+
# \brief The XML namespace for the XMP paged document schema.
|
43
|
+
#
|
44
|
+
# \def XMP_NS_PDF
|
45
|
+
# \brief The XML namespace for the PDF schema.
|
46
|
+
#
|
47
|
+
# \def XMP_NS_Photoshop
|
48
|
+
# \brief The XML namespace for the Photoshop custom schema.
|
49
|
+
#
|
50
|
+
# \def XMP_NS_EXIF
|
51
|
+
# \brief The XML namespace for Adobe's EXIF schema.
|
52
|
+
#
|
53
|
+
# \def XMP_NS_TIFF
|
54
|
+
# \brief The XML namespace for Adobe's TIFF schema.
|
55
|
+
|
56
|
+
XMP_NS_XMP = "http://ns.adobe.com/xap/1.0/"
|
57
|
+
|
58
|
+
XMP_NS_XMP_Rights = "http://ns.adobe.com/xap/1.0/rights/"
|
59
|
+
XMP_NS_XMP_MM = "http://ns.adobe.com/xap/1.0/mm/"
|
60
|
+
XMP_NS_XMP_BJ = "http://ns.adobe.com/xap/1.0/bj/"
|
61
|
+
|
62
|
+
XMP_NS_PDF = "http://ns.adobe.com/pdf/1.3/"
|
63
|
+
XMP_NS_Photoshop = "http://ns.adobe.com/photoshop/1.0/"
|
64
|
+
XMP_NS_PSAlbum = "http://ns.adobe.com/album/1.0/"
|
65
|
+
XMP_NS_EXIF = "http://ns.adobe.com/exif/1.0/"
|
66
|
+
XMP_NS_EXIF_Aux = "http://ns.adobe.com/exif/1.0/aux/"
|
67
|
+
XMP_NS_TIFF = "http://ns.adobe.com/tiff/1.0/"
|
68
|
+
XMP_NS_PNG = "http://ns.adobe.com/png/1.0/"
|
69
|
+
XMP_NS_SWF = "http://ns.adobe.com/swf/1.0/"
|
70
|
+
XMP_NS_JPEG = "http://ns.adobe.com/jpeg/1.0/"
|
71
|
+
XMP_NS_JP2K = "http://ns.adobe.com/jp2k/1.0/"
|
72
|
+
XMP_NS_CameraRaw = "http://ns.adobe.com/camera-raw-settings/1.0/"
|
73
|
+
XMP_NS_DM = "http://ns.adobe.com/xmp/1.0/DynamicMedia/"
|
74
|
+
XMP_NS_Script = "http://ns.adobe.com/xmp/1.0/Script/"
|
75
|
+
XMP_NS_ASF = "http://ns.adobe.com/asf/1.0/"
|
76
|
+
XMP_NS_WAV = "http://ns.adobe.com/xmp/wav/1.0/"
|
77
|
+
XMP_NS_BWF = "http://ns.adobe.com/bwf/bext/1.0/"
|
78
|
+
|
79
|
+
XMP_NS_XMP_Note = "http://ns.adobe.com/xmp/note/"
|
80
|
+
|
81
|
+
XMP_NS_AdobeStockPhoto = "http://ns.adobe.com/StockPhoto/1.0/"
|
82
|
+
XMP_NS_CreatorAtom = "http://ns.adobe.com/creatorAtom/1.0/"
|
83
|
+
|
84
|
+
# \name XML namespace constants for qualifiers and structured property fields.
|
85
|
+
# @{
|
86
|
+
#
|
87
|
+
# \def XMP_NS_XMP_IdentifierQual
|
88
|
+
# \brief The XML namespace for qualifiers of the xmp:Identifier property.
|
89
|
+
#
|
90
|
+
# \def XMP_NS_XMP_Dimensions
|
91
|
+
# \brief The XML namespace for fields of the Dimensions type.
|
92
|
+
#
|
93
|
+
# \def XMP_NS_XMP_Image
|
94
|
+
# \brief The XML namespace for fields of a graphical image. Used for the Thumbnail type.
|
95
|
+
#
|
96
|
+
# \def XMP_NS_XMP_ResourceEvent
|
97
|
+
# \brief The XML namespace for fields of the ResourceEvent type.
|
98
|
+
#
|
99
|
+
# \def XMP_NS_XMP_ResourceRef
|
100
|
+
# \brief The XML namespace for fields of the ResourceRef type.
|
101
|
+
#
|
102
|
+
# \def XMP_NS_XMP_ST_Version
|
103
|
+
# \brief The XML namespace for fields of the Version type.
|
104
|
+
#
|
105
|
+
# \def XMP_NS_XMP_ST_Job
|
106
|
+
# \brief The XML namespace for fields of the JobRef type.
|
107
|
+
|
108
|
+
XMP_NS_XMP_IdentifierQual = "http://ns.adobe.com/xmp/Identifier/qual/1.0/"
|
109
|
+
XMP_NS_XMP_Dimensions = "http://ns.adobe.com/xap/1.0/sType/Dimensions#"
|
110
|
+
XMP_NS_XMP_Text = "http://ns.adobe.com/xap/1.0/t/"
|
111
|
+
XMP_NS_XMP_PagedFile = "http://ns.adobe.com/xap/1.0/t/pg/"
|
112
|
+
XMP_NS_XMP_Graphics = "http://ns.adobe.com/xap/1.0/g/"
|
113
|
+
XMP_NS_XMP_Image = "http://ns.adobe.com/xap/1.0/g/img/"
|
114
|
+
XMP_NS_XMP_Font = "http://ns.adobe.com/xap/1.0/sType/Font#"
|
115
|
+
XMP_NS_XMP_ResourceEvent = "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
|
116
|
+
XMP_NS_XMP_ResourceRef = "http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
|
117
|
+
XMP_NS_XMP_ST_Version = "http://ns.adobe.com/xap/1.0/sType/Version#"
|
118
|
+
XMP_NS_XMP_ST_Job = "http://ns.adobe.com/xap/1.0/sType/Job#"
|
119
|
+
XMP_NS_XMP_ManifestItem = "http://ns.adobe.com/xap/1.0/sType/ManifestItem#"
|
120
|
+
|
121
|
+
# Deprecated XML namespace constants
|
122
|
+
XMP_NS_XMP_T = "http://ns.adobe.com/xap/1.0/t/"
|
123
|
+
XMP_NS_XMP_T_PG = "http://ns.adobe.com/xap/1.0/t/pg/"
|
124
|
+
XMP_NS_XMP_G_IMG = "http://ns.adobe.com/xap/1.0/g/img/"
|
125
|
+
|
126
|
+
# XML namespace constants from outside Adobe.
|
127
|
+
# @{
|
128
|
+
#
|
129
|
+
# \def XMP_NS_DC
|
130
|
+
# \brief The XML namespace for the Dublin Core schema.
|
131
|
+
#
|
132
|
+
# \def XMP_NS_IPTCCore
|
133
|
+
# \brief The XML namespace for the IPTC Core schema.
|
134
|
+
#
|
135
|
+
# \def XMP_NS_RDF
|
136
|
+
# \brief The XML namespace for RDF.
|
137
|
+
#
|
138
|
+
# \def XMP_NS_XML
|
139
|
+
# \brief The XML namespace for XML.
|
140
|
+
|
141
|
+
XMP_NS_DC = "http://purl.org/dc/elements/1.1/"
|
142
|
+
|
143
|
+
XMP_NS_IPTCCore = "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/"
|
144
|
+
|
145
|
+
XMP_NS_DICOM = "http://ns.adobe.com/DICOM/"
|
146
|
+
|
147
|
+
XMP_NS_PDFA_Schema = "http://www.aiim.org/pdfa/ns/schema#"
|
148
|
+
XMP_NS_PDFA_Property = "http://www.aiim.org/pdfa/ns/property#"
|
149
|
+
XMP_NS_PDFA_Type = "http://www.aiim.org/pdfa/ns/type#"
|
150
|
+
XMP_NS_PDFA_Field = "http://www.aiim.org/pdfa/ns/field#"
|
151
|
+
XMP_NS_PDFA_ID = "http://www.aiim.org/pdfa/ns/id/"
|
152
|
+
XMP_NS_PDFA_Extension = "http://www.aiim.org/pdfa/ns/extension/"
|
153
|
+
|
154
|
+
XMP_NS_PDFX = "http://ns.adobe.com/pdfx/1.3/"
|
155
|
+
XMP_NS_PDFX_ID = "http://www.npes.org/pdfx/ns/id/"
|
156
|
+
|
157
|
+
XMP_NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
158
|
+
XMP_NS_XML = "http://www.w3.org/XML/1998/namespace"
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'exempi/consts'
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
describe "dataconverter helper" do
|
6
|
+
it "should be able to look up single symbol values" do
|
7
|
+
Exempi::XmpOpenFileOptions.to_native(:XMP_OPEN_READ, nil).must_equal 0x00000001
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be able to look up an array of symbol values" do
|
11
|
+
Exempi::XmpOpenFileOptions.to_native([:XMP_OPEN_USESMARTHANDLER,
|
12
|
+
:XMP_OPEN_USEPACKETSCANNING], nil).must_equal 0x00000060
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to handle pure integer values" do
|
16
|
+
Exempi::XmpOpenFileOptions.to_native(0x00000001, nil).must_equal 0x00000001
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return 0 when nil is passed" do
|
20
|
+
Exempi::XmpOpenFileOptions.to_native(nil, nil).must_equal 0
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise when invalid options are passed" do
|
24
|
+
lambda do
|
25
|
+
Exempi::XmpOpenFileOptions.to_native(:notanoption, nil)
|
26
|
+
end.must_raise Exempi::InvalidOptionError
|
27
|
+
|
28
|
+
lambda do
|
29
|
+
Exempi::XmpOpenFileOptions.to_native([:notanoption, :notanoption], nil)
|
30
|
+
end.must_raise Exempi::InvalidOptionError
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be able to translate integers into hashes of options" do
|
34
|
+
hash = Exempi.parse_bitmask 0x00000060, Exempi::XMP_OPEN_FILE_OPTIONS
|
35
|
+
|
36
|
+
assert hash[:XMP_OPEN_USESMARTHANDLER]
|
37
|
+
assert hash[:XMP_OPEN_USEPACKETSCANNING]
|
38
|
+
refute hash[:XMP_OPEN_FORUPDATE]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should optionally be able to return short option names" do
|
42
|
+
hash = Exempi.parse_bitmask 0x00000060, Exempi::XMP_OPEN_FILE_OPTIONS, true
|
43
|
+
|
44
|
+
assert hash[:usesmarthandler]
|
45
|
+
assert hash[:usepacketscanning]
|
46
|
+
refute hash[:forupdate]
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'exempi/consts'
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
describe "DateTime struct wrapper" do
|
6
|
+
it "should be able to construct an XmpDateTime struct manually" do
|
7
|
+
date = Exempi::XmpDateTime.new
|
8
|
+
date[:year] = 2012
|
9
|
+
date[:month] = 9
|
10
|
+
date[:day] = 7
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to create an XmpDateTime struct from a DateTime object" do
|
14
|
+
today = DateTime.now
|
15
|
+
date = Exempi::XmpDateTime.from_datetime today
|
16
|
+
|
17
|
+
date[:year].must_equal today.year
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be able to create an XmpDateTime struct from a string" do
|
21
|
+
today = '2012-09-07'
|
22
|
+
date = Exempi::XmpDateTime.from_datetime today
|
23
|
+
|
24
|
+
date[:year].must_equal 2012
|
25
|
+
date[:month].must_equal 9
|
26
|
+
date[:day].must_equal 7
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be able to translate XmpDateTime structs into DateTime objects" do
|
30
|
+
today = DateTime.now
|
31
|
+
date = Exempi::XmpDateTime.from_datetime today
|
32
|
+
|
33
|
+
date.to_datetime.must_equal today
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'exempi'
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
describe "Exempi helpers" do
|
6
|
+
it "should be able to silence stderr for noisy blocks" do
|
7
|
+
Exempi.verbose = false
|
8
|
+
lambda do
|
9
|
+
Exempi.send(:shutup!) { STDERR.puts "You should not see this" }
|
10
|
+
end.must_be_silent
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should wrap Exempi functions correctly" do
|
14
|
+
Exempi.verbose = false
|
15
|
+
lambda do
|
16
|
+
# Exempi spews errors to stderr, so we've wrapped attach_function
|
17
|
+
# in order to ensure that every function call is wrapped with
|
18
|
+
# the silencing shutup! method
|
19
|
+
Exempi.xmp_files_open_new('no_file_here', 0)
|
20
|
+
end.must_be_silent
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: exempi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Misty De Meo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.2.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.9.2.2
|
41
|
+
description: |2
|
42
|
+
Exempi is a thin FFI-based wrapper around the
|
43
|
+
Exempi library. It provides a variety of
|
44
|
+
functions for reading, writing, and manipulating
|
45
|
+
XMP metadata.
|
46
|
+
email:
|
47
|
+
- mistydemeo@gmail.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- ".gitignore"
|
53
|
+
- Gemfile
|
54
|
+
- LICENSE
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- exempi.gemspec
|
58
|
+
- lib/exempi.rb
|
59
|
+
- lib/exempi/consts.rb
|
60
|
+
- lib/exempi/errors.rb
|
61
|
+
- lib/exempi/exceptions.rb
|
62
|
+
- lib/exempi/exempi.rb
|
63
|
+
- lib/exempi/namespaces.rb
|
64
|
+
- lib/exempi/version.rb
|
65
|
+
- test/dataconverter_test.rb
|
66
|
+
- test/datetime_test.rb
|
67
|
+
- test/helpers_test.rb
|
68
|
+
homepage: https://github.com/mistydemeo/exempi
|
69
|
+
licenses: []
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.4.5.1
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Ruby wrapper for Exempi
|
91
|
+
test_files:
|
92
|
+
- test/dataconverter_test.rb
|
93
|
+
- test/datetime_test.rb
|
94
|
+
- test/helpers_test.rb
|
95
|
+
has_rdoc:
|