c2pa-c
C++ API for c2pa-c library
Loading...
Searching...
No Matches
c2pa.hpp
Go to the documentation of this file.
1// Copyright 2024 Adobe. All rights reserved.
2// This file is licensed to you under the Apache License,
3// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
4// or the MIT license (http://opensource.org/licenses/MIT),
5// at your option.
6// Unless required by applicable law or agreed to in writing,
7// this software is distributed on an "AS IS" BASIS, WITHOUT
8// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
9// implied. See the LICENSE-MIT and LICENSE-APACHE files for the
10// specific language governing permissions and limitations under
11// each license.
12
13/// @file c2pa.hpp
14/// @brief C++ wrapper for the C2PA C library.
15/// @details This is used for creating and verifying C2PA manifests.
16/// This is an early version, and has not been fully tested.
17/// Thread safety is not guaranteed due to the use of errno and etc.
18
19#ifndef C2PA_H
20#define C2PA_H
21
22// Suppress unused function warning for GCC/Clang
23#ifdef __GNUC__
24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wunused-function"
26#endif
27
28// Suppress unused function warning for MSVC
29#ifdef _MSC_VER
30#pragma warning(push)
31#pragma warning(disable : 4505)
32#endif
33
34#include <cerrno>
35#include <filesystem>
36#include <fstream>
37#include <istream>
38#include <ostream>
39#include <string>
40#include <vector>
41#include <optional>
42#include <memory>
43#include <utility>
44
45#include "c2pa.h"
46
47// NOOP for now, can use later to define static library
48#define C2PA_CPP_API
49
50namespace c2pa
51{
52 /// @typedef SignerInfo
53 /// @brief Type alias for C2paSignerInfo from the C API.
54 typedef C2paSignerInfo SignerInfo;
55
56 // Forward declarations for context types
57 class Settings;
58 class Context;
59 class IContextProvider;
60 class Signer;
61
62 /// @brief Result codes for C API operations (matches C API return convention).
63 enum class OperationResult : int {
64 Success = 0, ///< Operation succeeded
65 Error = -1 ///< Operation failed (check C2paException for details)
66 };
67
68 /// @brief Stream/FFI error codes (maps to errno values used by the C layer).
69 enum class StreamError : int {
70 InvalidArgument = EINVAL,
71 IoError = EIO,
72 NoBufferSpace = ENOBUFS
73 };
74
75 /// @brief Set errno from StreamError and return error sentinel.
76 /// @param e The StreamError value to convert to errno.
77 /// @return OperationResult::Error (-1) for use as C API error return.
78 inline int stream_error_return(StreamError e) noexcept {
79 errno = static_cast<int>(e);
80 return static_cast<int>(OperationResult::Error);
81 }
82
83 /// @brief Exception class for C2pa errors.
84 /// This class is used to throw exceptions for errors encountered by the C2pa library via c2pa_error().
85 class C2PA_CPP_API C2paException : public std::exception
86 {
87 public:
88 /// @brief Default constructor.
89 /// @details Creates an exception and retrieves the error message from the C2PA library.
91
92 /// @brief Construct an exception with a custom error message.
93 /// @param message The error message.
94 explicit C2paException(std::string message);
95
96 ~C2paException() override = default;
97
98 C2paException(const C2paException&) = default;
99
101
103
105
106 /// @brief Get the exception message.
107 /// @return Null-terminated error message string.
108 const char* what() const noexcept override;
109
110 private:
111 std::string message_;
112 };
113
114 /// @brief Interface for types that can provide C2PA context functionality.
115 /// @details This interface can be implemented by external libraries to provide
116 /// custom context implementations (e.g. AdobeContext wrappers).
117 /// Reader and Builder take the context by reference and use it only at
118 /// construction; the underlying implementation copies context state
119 /// into the reader/builder, so the context does not need to outlive them.
120 ///
121 /// @par Move semantics
122 /// Move construction and move assignment are defaulted. After move, the moved-from
123 /// object is left in a valid but unspecified state: is_valid() may be false and
124 /// c_context() may return nullptr. Implementations that own a C2paContext* (e.g. Context)
125 /// must set the source's handle to nullptr on move to avoid double-free; callers must
126 /// not use a moved-from provider without checking is_valid() first.
127 ///
128 /// @par Implementation Requirements for is_valid()
129 /// The is_valid() method exists to support implementations that may have:
130 /// - Optional or lazy context initialization
131 /// - Contexts that can be invalidated or moved
132 /// - A "no context" state as part of their lifecycle
133 ///
134 /// @par Why Both c_context() and is_valid()?
135 /// While c_context() can return nullptr, is_valid() provides:
136 /// 1. A boolean check without pointer inspection (yes/no answer for intialization)
137 /// 2. Forward compatibility for implementations with complex context lifecycles (lazy load)
138 ///
139 /// @par Impact on Reader and Builder
140 /// Reader and Builder constructors validate that a provider both exists and
141 /// is_valid() returns true before using c_context(). This ensures that:
142 /// - External implementations cannot be used in an uninitialized state
143 /// - A consistent validation pattern exists across all context-using classes
144 /// - Errors are caught early at construction time rather than during operations
145 ///
146 /// @par Standard Context Implementation
147 /// The built-in Context class always returns true from is_valid() after
148 /// successful construction, as it validates the context pointer in its constructor.
149 /// External implementations may have different invariants.
151 public:
152 virtual ~IContextProvider() noexcept = default;
153
154 /// @brief Get the underlying C2PA context pointer for FFI operations.
155 /// @return Pointer to C2paContext, or nullptr if not available.
156 /// @note Provider retains ownership; pointer valid for provider's lifetime.
157 [[nodiscard]] virtual C2paContext* c_context() const noexcept = 0;
158
159 /// @brief Check if this provider has a valid context.
160 /// @return true if context is available, false otherwise.
161 /// @note For standard Context objects, this always returns true after construction.
162 /// External implementations may return false to indicate uninitialized or
163 /// invalidated state. Reader and Builder constructors check this before use.
164 /// @warning Implementations must ensure is_valid() == true implies c_context() != nullptr.
165 [[nodiscard]] virtual bool is_valid() const noexcept = 0;
166
167 protected:
168 IContextProvider() = default;
169
171 IContextProvider& operator=(const IContextProvider&) = delete;
172 };
173
174 /// @brief (C2PA SDK) Settings configuration object for creating contexts.
175 /// @details Settings can be configured via JSON strings or programmatically
176 /// via set() and update() methods. Once passed to Context::ContextBuilder,
177 /// the settings are copied into the context and the Settings
178 /// object can be reused or discarded.
179 ///
180 /// @par Validity
181 /// Settings uses is_valid() to indicate whether the object holds a valid underlying
182 /// C settings handle. After move-from, is_valid() is false. set(), update(), and callers
183 /// passing this object to the C API must ensure is_valid() is true or check before use.
185 public:
186 /// @brief Create default settings.
188
189 /// @brief Create settings from a configuration string.
190 /// @param data Configuration data in JSON format.
191 /// @param format Format of the data ("json").
192 /// @throws C2paException if parsing fails.
193 Settings(const std::string& data, const std::string& format);
194
195 // Move semantics
196 Settings(Settings&&) noexcept;
197 Settings& operator=(Settings&&) noexcept;
198
199 // Non-copyable
200 Settings(const Settings&) = delete;
201 Settings& operator=(const Settings&) = delete;
202
203 ~Settings() noexcept;
204
205 /// @brief Check if this Settings object is valid (holds a C settings handle).
206 /// @return true if the object can be used (set, update, c_settings, or passed to Context/ContextBuilder).
207 /// @return false if moved-from (or otherwise invalid). Callers must check before use.
208 [[nodiscard]] bool is_valid() const noexcept;
209
210 /// @brief Set a single configuration value by path.
211 /// @param path Dot-separated path to the setting (e.g., "verify.verify_after_sign").
212 /// @param json_value JSON-encoded value to set.
213 /// @return Reference to this Settings for method chaining.
214 /// @throws C2paException if the path or value is invalid.
215 Settings& set(const std::string& path, const std::string& json_value);
216
217 /// @brief Merge configuration from a JSON string (latest configuration wins).
218 /// @param data Configuration data in JSON format.
219 /// @return Reference to this Settings for method chaining.
220 /// @throws C2paException if parsing fails, or if this object is invalid.
221 /// @note This is the recommended overload when configuration is JSON.
222 Settings& update(const std::string& data) { return update(data, "json"); }
223
224 /// @brief Merge configuration from a std::string (latest configuration wins).
225 /// @param data Configuration data in JSON or TOML format.
226 /// @param format Format of the data ("json" or "toml").
227 /// @return Reference to this Settings for method chaining.
228 /// @throws C2paException if parsing fails, or if this object is invalid.
229 Settings& update(const std::string& data, const std::string& format);
230
231 /// @brief Get the raw C FFI settings pointer.
232 /// @return Pointer to C2paSettings when is_valid() is true; nullptr when invalid.
233 /// @note Callers passing this to the C API should check is_valid() first and treat nullptr as invalid.
234 [[nodiscard]] C2paSettings* c_settings() const noexcept;
235
236 private:
237 C2paSettings* settings_ptr;
238 };
239
240 /// @brief C2PA context implementing IContextProvider.
241 /// @details Context objects manage C2PA SDK configuration and state.
242 /// Contexts can be created via direct construction or the ContextBuilder:
243 ///
244 /// Direct construction:
245 /// @code
246 /// c2pa::Context ctx; // default
247 /// c2pa::Context ctx(settings); // from Settings
248 /// c2pa::Context ctx(json); // from JSON string
249 /// @endcode
250 ///
251 /// ContextBuilder (for multi-step configuration):
252 /// @code
253 /// auto ctx = c2pa::Context::ContextBuilder()
254 /// .with_settings(settings)
255 /// .with_json(json)
256 /// .create_context();
257 /// @endcode
258 ///
259 /// Builder and Reader take the context by reference (IContextProvider&).
260 /// The context object must outlive the Builder or Reader instance.
262 public:
263 /// @brief ContextBuilder for creating customized Context instances.
264 /// @details Provides a builder pattern for configuring contexts with multiple settings.
265 /// Note: create_context() consumes the builder.
266 /// @note For most use cases, prefer direct construction via the Context constructors.
267 /// The ContextBuilder is useful when you need to layer multiple configuration
268 /// sources (e.g. with_settings() followed by with_json()).
270 public:
272 ~ContextBuilder() noexcept;
273
274 // Move semantics
276 ContextBuilder& operator=(ContextBuilder&&) noexcept;
277
278 // Non-copyable
280 ContextBuilder& operator=(const ContextBuilder&) = delete;
281
282 /// @brief Check if the builder is in a valid state.
283 /// @return true if the builder can be used, false if moved from.
284 [[nodiscard]] bool is_valid() const noexcept;
285
286 /// @brief Configure with Settings object.
287 /// @param settings Settings to use (will be copied into the context). Must be valid (is_valid() true).
288 /// @return Reference to this ContextBuilder for method chaining.
289 /// @throws C2paException if settings are invalid or settings.is_valid() is false.
290 ContextBuilder& with_settings(const Settings& settings);
291
292 /// @brief Configure settings with JSON string.
293 /// @param json JSON configuration string.
294 /// @return Reference to this ContextBuilder for method chaining.
295 /// @throws C2paException if JSON is invalid.
296 ContextBuilder& with_json(const std::string& json);
297
298 /// @brief Configure settings from a JSON settings file.
299 /// @param settings_path Full path to the JSON settings file.
300 /// @return Reference to this ContextBuilder for method chaining.
301 /// @throws C2paException if file cannot be read or JSON is invalid.
302 ContextBuilder& with_json_settings_file(const std::filesystem::path& settings_path);
303
304 /// @brief Set a Signer on the context being built.
305 /// @details After this call the source Signer object is consumed and must
306 /// not be reused, as it becomes part to the context and tied to it.
307 /// If settings also contain a signer, the programmatic signer
308 /// set through this API will be used for signing.
309 /// @param signer Signer to put into the context.
310 /// @return Reference to this ContextBuilder for method chaining.
311 /// @throws C2paException if the builder or signer is invalid.
312 ContextBuilder& with_signer(Signer&& signer);
313
314 /// @brief Create a Context from the current builder configuration.
315 /// @return A new Context instance.
316 /// @throws C2paException if context creation fails.
317 /// @note This consumes the builder. After calling this, is_valid() returns false.
318 [[nodiscard]] Context create_context();
319
320 private:
321 C2paContextBuilder* context_builder;
322 };
323
324 // Direct construction
325 /// @brief Create a Context with default settings.
326 /// @throws C2paException if context creation fails.
328
329 /// @brief Create a Context configured with a Settings object.
330 /// @param settings Settings configuration to apply. Must be valid (settings.is_valid() true).
331 /// @throws C2paException if settings are invalid, settings.is_valid() is false, or context creation fails.
332 explicit Context(const Settings& settings);
333
334 /// @brief Create a Context configured with a JSON string.
335 /// @param json JSON configuration string.
336 /// @throws C2paException if JSON is invalid or context creation fails.
337 explicit Context(const std::string& json);
338
339 /// @brief Create a Context with a Settings object and a Signer.
340 /// @param settings Settings configuration to apply.
341 /// @param signer Signer to move into the context. Consumed after this call.
342 /// The programmatic Signer from the signer parameter
343 /// takes priority over the Signer in settings, so use this API
344 /// when wanting to explicitly set a Signer (or override the Signer in settings).
345 /// @throws C2paException if settings or signer are invalid, or context creation fails.
346 Context(const Settings& settings, Signer&& signer);
347
348 // Non-copyable, moveable
349 Context(const Context&) = delete;
350 Context& operator=(const Context&) = delete;
351 Context(Context&&) noexcept;
352 Context& operator=(Context&&) noexcept;
353
354 ~Context() noexcept override;
355
356 // IContextProvider implementation
357 /// @brief Get the underlying C2PA context pointer.
358 /// @return C2paContext pointer when is_valid() is true; nullptr when moved-from (is_valid() false).
359 /// @note Callers must check is_valid() before using the result; do not pass nullptr to the C API.
360 [[nodiscard]] C2paContext* c_context() const noexcept override;
361
362 /// @brief Check if this Context has a valid context (validity check for context-like types).
363 /// @return true when the object holds a valid C context; false when moved-from.
364 /// @note After move, is_valid() is false and c_context() returns nullptr.
365 [[nodiscard]] bool is_valid() const noexcept override;
366
367 /// @brief Internal constructor from raw FFI pointer (prefer public constructors).
368 /// @param ctx Raw C2paContext pointer — Context takes ownership.
369 /// @throws C2paException if ctx is nullptr.
370 explicit Context(C2paContext* ctx);
371
372 private:
373 C2paContext* context;
374 };
375
376 /// @brief Get the version of the C2PA library.
377 /// @return Version string.
378 std::string C2PA_CPP_API version();
379
380 /// @brief Load C2PA settings from a string in a given format.
381 /// @param data The configuration data to load.
382 /// @param format The mimetype of the string.
383 /// @throws C2paException for errors encountered by the C2PA library.
384 /// @deprecated Use Context constructors or Context::ContextBuilder instead for better thread safety.
385 [[deprecated("Use Context::from_json() or Context::from_settings() instead")]]
386 void C2PA_CPP_API load_settings(const std::string& data, const std::string& format);
387
388 /// @brief Read a file and return the manifest JSON.
389 /// @param source_path The path to the file to read.
390 /// @param data_dir Optional directory to store binary resources.
391 /// @return Optional string containing the manifest JSON if a manifest was found.
392 /// @throws C2paException for errors encountered by the C2PA library.
393 /// @deprecated Use Reader object instead.
394 [[deprecated("Use Reader object instead")]]
395 std::optional<std::string> C2PA_CPP_API read_file(const std::filesystem::path &source_path, const std::optional<std::filesystem::path> data_dir = std::nullopt);
396
397 /// @brief Read a file and return an ingredient JSON.
398 /// @param source_path The path to the file to read.
399 /// @param data_dir The directory to store binary resources.
400 /// @return String containing the ingredient JSON.
401 /// @throws C2paException for errors encountered by the C2PA library.
402 /// @deprecated Use Reader and Builder.add_ingredient instead.
403 [[deprecated("Use Reader and Builder.add_ingredient")]]
404 std::string C2PA_CPP_API read_ingredient_file(const std::filesystem::path &source_path, const std::filesystem::path &data_dir);
405
406 /// @brief Add a manifest and sign a file.
407 /// @param source_path The path to the asset to be signed.
408 /// @param dest_path The path to write the signed file to.
409 /// @param manifest The manifest JSON to add to the file.
410 /// @param signer_info The signer info to use for signing.
411 /// @param data_dir Optional directory to store binary resources.
412 /// @throws C2paException for errors encountered by the C2PA library.
413 /// @deprecated Use Builder.sign instead.
414 [[deprecated("Use Builder.sign instead")]]
415 void C2PA_CPP_API sign_file(const std::filesystem::path &source_path,
416 const std::filesystem::path &dest_path,
417 const char *manifest,
418 SignerInfo *signer_info,
419 const std::optional<std::filesystem::path> data_dir = std::nullopt);
420
421 /// @defgroup StreamWrappers Stream wrappers for C2PA C API
422 /// @brief C++ stream types that adapt stream types to C2paStream.
423 ///
424 /// The C2PA C API expects a C2paStream with four callbacks: reader, writer, seeker, flusher.
425 /// The contract for each callback is:
426 /// - reader(context, buffer, size): read up to size bytes into buffer; return bytes read, or -1 on error (set errno).
427 /// - writer(context, buffer, size): write size bytes from buffer; return bytes written, or -1 on error (set errno).
428 /// - seeker(context, offset, whence): seek to offset (whence = Start/Current/End); return new position or -1 (set errno).
429 /// - flusher(context): flush; return 0 on success, -1 on error (set errno).
430
431 /// @brief Input stream IStream wrapper for C2paStream.
432 /// @details This class is used to wrap an input stream for use with the C2PA library.
433 class C2PA_CPP_API CppIStream : public C2paStream
434 {
435 public:
436 /// @brief Pointer to the underlying C2paStream.
437 C2paStream *c_stream;
438
439 /// @brief Construct an input stream wrapper from a std::istream-derived object.
440 /// @tparam IStream Type derived from std::istream.
441 /// @param istream The input stream to wrap (must be open and valid).
442 /// @throws C2paException if stream wrapper creation fails.
443 template <typename IStream>
444 explicit CppIStream(IStream &istream) {
445 static_assert(std::is_base_of<std::istream, IStream>::value,
446 "Stream must be derived from std::istream");
447 c_stream = c2pa_create_stream(reinterpret_cast<StreamContext *>(&istream), reader, seeker, writer, flusher);
448 if (c_stream == nullptr) {
449 throw C2paException("Failed to create input stream wrapper: is stream open and valid?");
450 }
451 }
452
453 CppIStream(const CppIStream &) = delete;
454
455 CppIStream &operator=(const CppIStream &) = delete;
456
457 CppIStream(CppIStream &&) = delete;
458
460
462
463 private:
464 /// @brief Reader callback implementation.
465 /// @param context Stream context pointer.
466 /// @param buffer Buffer to read into.
467 /// @param size Number of bytes to read.
468 /// @return Number of bytes read, or -1 on error (sets errno).
469 static intptr_t reader(StreamContext *context, uint8_t *buffer, intptr_t size);
470
471 /// @brief Writer callback implementation (not used for input streams).
472 /// @param context Stream context pointer.
473 /// @param buffer Buffer to write from.
474 /// @param size Number of bytes to write.
475 /// @return -1 (always fails for input streams).
476 static intptr_t writer(StreamContext *context, const uint8_t *buffer, intptr_t size);
477
478 /// @brief Seeker callback implementation.
479 /// @param context Stream context pointer.
480 /// @param offset Offset to seek to.
481 /// @param whence Seek mode (Start/Current/End).
482 /// @return New stream position, or -1 on error (sets errno).
483 static intptr_t seeker(StreamContext *context, intptr_t offset, C2paSeekMode whence);
484
485 /// @brief Flusher callback implementation (no-op for input streams).
486 /// @param context Stream context pointer.
487 /// @return 0 on success.
488 static intptr_t flusher(StreamContext *context);
489
490 friend class Reader;
491 };
492
493 /// @brief Output stream OStream wrapper for C2paStream.
494 /// @details This class is used to wrap an output stream for use with the C2PA library.
495 class C2PA_CPP_API CppOStream : public C2paStream
496 {
497 public:
498 /// @brief Pointer to the underlying C2paStream.
499 C2paStream *c_stream;
500
501 /// @brief Construct an output stream wrapper from a std::ostream-derived object.
502 /// @tparam OStream Type derived from std::ostream.
503 /// @param ostream The output stream to wrap (must be open and valid).
504 /// @throws C2paException if stream wrapper creation fails.
505 template <typename OStream>
506 explicit CppOStream(OStream &ostream) {
507 static_assert(std::is_base_of<std::ostream, OStream>::value, "Stream must be derived from std::ostream");
508 c_stream = c2pa_create_stream(reinterpret_cast<StreamContext *>(&ostream), reader, seeker, writer, flusher);
509 if (c_stream == nullptr) {
510 throw C2paException("Failed to create output stream wrapper: is stream open and valid?");
511 }
512 }
513
514 CppOStream(const CppOStream &) = delete;
515
516 CppOStream &operator=(const CppOStream &) = delete;
517
518 CppOStream(CppOStream &&) = delete;
519
521
523
524 private:
525 /// @brief Reader callback implementation (not used for output streams).
526 /// @param context Stream context pointer.
527 /// @param buffer Buffer to read into.
528 /// @param size Number of bytes to read.
529 /// @return -1 (always fails for output streams).
530 static intptr_t reader(StreamContext *context, uint8_t *buffer, intptr_t size);
531
532 /// @brief Writer callback implementation.
533 /// @param context Stream context pointer.
534 /// @param buffer Buffer to write from.
535 /// @param size Number of bytes to write.
536 /// @return Number of bytes written, or -1 on error (sets errno).
537 static intptr_t writer(StreamContext *context, const uint8_t *buffer, intptr_t size);
538
539 /// @brief Seeker callback implementation.
540 /// @param context Stream context pointer.
541 /// @param offset Offset to seek to.
542 /// @param whence Seek mode (Start/Current/End).
543 /// @return New stream position, or -1 on error (sets errno).
544 static intptr_t seeker(StreamContext *context, intptr_t offset, C2paSeekMode whence);
545
546 /// @brief Flusher callback implementation.
547 /// @param context Stream context pointer.
548 /// @return 0 on success, -1 on error (sets errno).
549 static intptr_t flusher(StreamContext *context);
550 };
551
552 /// @brief IOStream Class wrapper for C2paStream.
553 /// @details This class is used to wrap an input/output stream for use with the C2PA library.
554 class C2PA_CPP_API CppIOStream : public C2paStream
555 {
556 public:
557 /// @brief Pointer to the underlying C2paStream.
558 C2paStream *c_stream;
559
560 /// @brief Construct an I/O stream wrapper from a std::iostream-derived object.
561 /// @tparam IOStream Type derived from std::iostream.
562 /// @param iostream The I/O stream to wrap (must be open and valid).
563 /// @throws C2paException if stream wrapper creation fails.
564 template <typename IOStream>
565 CppIOStream(IOStream &iostream) {
566 static_assert(std::is_base_of<std::iostream, IOStream>::value, "Stream must be derived from std::iostream");
567 c_stream = c2pa_create_stream(reinterpret_cast<StreamContext *>(&iostream), reader, seeker, writer, flusher);
568 if (c_stream == nullptr) {
569 throw C2paException("Failed to create I/O stream wrapper: is stream open and valid?");
570 }
571 }
572
573 CppIOStream(const CppIOStream &) = delete;
574
576
578
580
582
583 private:
584 /// @brief Reader callback implementation.
585 /// @param context Stream context pointer.
586 /// @param buffer Buffer to read into.
587 /// @param size Number of bytes to read.
588 /// @return Number of bytes read, or -1 on error (sets errno).
589 static intptr_t reader(StreamContext *context, uint8_t *buffer, intptr_t size);
590
591 /// @brief Writer callback implementation.
592 /// @param context Stream context pointer.
593 /// @param buffer Buffer to write from.
594 /// @param size Number of bytes to write.
595 /// @return Number of bytes written, or -1 on error (sets errno).
596 static intptr_t writer(StreamContext *context, const uint8_t *buffer, intptr_t size);
597
598 /// @brief Seeker callback implementation.
599 /// @param context Stream context pointer.
600 /// @param offset Offset to seek to.
601 /// @param whence Seek mode (Start/Current/End).
602 /// @return New stream position, or -1 on error (sets errno).
603 static intptr_t seeker(StreamContext *context, intptr_t offset, C2paSeekMode whence);
604
605 /// @brief Flusher callback implementation.
606 /// @param context Stream context pointer.
607 /// @return 0 on success, -1 on error (sets errno).
608 static intptr_t flusher(StreamContext *context);
609 };
610
611 /// @brief Reader class for reading a manifest.
612 /// @details This class is used to read and validate a manifest from a stream or file.
613 /// Resources are managed using RAII; member order ensures cpp_stream (which
614 /// holds a C stream pointing at the ifstream) is destroyed before owned_stream.
616 {
617 private:
618 C2paReader *c2pa_reader;
619 std::unique_ptr<std::ifstream> owned_stream; // Owns file stream when created from path
620 std::unique_ptr<CppIStream> cpp_stream; // Wraps stream for C API; destroyed before owned_stream
621
622 public:
623 /// @brief Create a Reader from a context and stream.
624 /// @param context Context provider; used at construction to configure settings.
625 /// @param format The mime format of the stream.
626 /// @param stream The input stream to read from.
627 /// @throws C2paException if context.is_valid() returns false,
628 /// or for other errors encountered by the C2PA library.
629 Reader(IContextProvider& context, const std::string &format, std::istream &stream);
630
631 /// @brief Create a Reader from a context and file path.
632 /// @param context Context provider; used at construction only to configure settings.
633 /// @param source_path The path to the file to read.
634 /// @throws C2paException if context.is_valid() returns false,
635 /// or for other errors encountered by the C2PA library.
636 /// @note Prefer using the streaming APIs if possible.
637 Reader(IContextProvider& context, const std::filesystem::path &source_path);
638
639 /// @brief Create a Reader from a stream (will use global settings if any loaded).
640 /// @details The validation_status field in the JSON contains validation results.
641 /// @param format The mime format of the stream.
642 /// @param stream The input stream to read from.
643 /// @throws C2paException for errors encountered by the C2PA library.
644 /// @deprecated Use Reader(IContextProvider& context, format, stream) instead.
645 [[deprecated("Use Reader(IContextProvider& context, format, stream) instead")]]
646 Reader(const std::string &format, std::istream &stream);
647
648 /// @brief Create a Reader from a file path (will use global settings if any loaded).
649 /// @param source_path The path to the file to read.
650 /// @throws C2paException for errors encountered by the C2PA library.
651 /// @deprecated Use Reader(IContextProvider& context, source_path) instead.
652 /// @note Prefer using the streaming APIs if possible.
653 [[deprecated("Use Reader(IContextProvider& context, source_path) instead")]]
654 Reader(const std::filesystem::path &source_path);
655
656 // Non-copyable
657 Reader(const Reader&) = delete;
658
659 Reader& operator=(const Reader&) = delete;
660
661 Reader(Reader&& other) noexcept
662 : c2pa_reader(std::exchange(other.c2pa_reader, nullptr)),
663 owned_stream(std::move(other.owned_stream)),
664 cpp_stream(std::move(other.cpp_stream)) {
665 }
666
667 Reader& operator=(Reader&& other) noexcept {
668 if (this != &other) {
669 c2pa_free(c2pa_reader);
670 c2pa_reader = std::exchange(other.c2pa_reader, nullptr);
671 owned_stream = std::move(other.owned_stream);
672 cpp_stream = std::move(other.cpp_stream);
673 }
674 return *this;
675 }
676
678
679 /// @brief Check if the reader was created from an embedded manifest.
680 /// @return true if the manifest was embedded in the asset, false if external.
681 /// @throws C2paException for errors encountered by the C2PA library.
682 [[nodiscard]] inline bool is_embedded() const {
683 return c2pa_reader_is_embedded(c2pa_reader);
684 }
685
686 /// @brief Returns the remote url of the manifest if this `Reader`
687 /// obtained the manifest remotely
688 /// @return Optional string containing the remote URL, or std::nullopt if manifest was embedded.
689 /// @throws C2paException for errors encountered by the C2PA library.
690 [[nodiscard]] std::optional<std::string> remote_url() const;
691
692 /// @brief Get the manifest as a JSON string.
693 /// @return The manifest as a JSON string.
694 /// @throws C2paException for errors encountered by the C2PA library.
695 std::string json() const;
696
697 /// @brief Get a resource from the reader and write it to a file.
698 /// @param uri The URI of the resource.
699 /// @param path The file path to write the resource to.
700 /// @return The number of bytes written.
701 /// @throws C2paException for errors encountered by the C2PA library.
702 /// @note Prefer using the streaming APIs if possible.
703 int64_t get_resource(const std::string &uri, const std::filesystem::path &path);
704
705 /// @brief Get a resource from the reader and write it to an output stream.
706 /// @param uri The URI of the resource.
707 /// @param stream The output stream to write the resource to.
708 /// @return The number of bytes written.
709 /// @throws C2paException for errors encountered by the C2PA library.
710 int64_t get_resource(const std::string &uri, std::ostream &stream);
711
712 /// @brief Get the raw C2paReader pointer.
713 /// @return The raw C2paReader pointer.
714 /// @note This is intended for internal API use and compatibility with C APIs.
715 C2paReader* get_api_internal_raw_reader() const { return c2pa_reader; }
716
717 /// @brief Get a list of mime types that the SDK can read manifests from.
718 /// @return Vector of supported MIME type strings.
719 static std::vector<std::string> supported_mime_types();
720 };
721
722 /// @brief Signer callback function type.
723 /// @details This function type is used to create a callback function for signing.
724 /// The callback receives data to sign and returns the signature.
725 /// @param data The data to sign.
726 /// @return The signature as a vector of bytes.
727 using SignerFunc = std::vector<unsigned char>(const std::vector<unsigned char> &);
728
729 /// @brief Signer class for creating a Signer
730 /// @details This class is used to create a signer from a signing algorithm, certificate, and TSA URI.
731 /// Supports both callback-based and direct signing methods.
733 {
735
736 private:
737 C2paSigner *signer;
738
739 /// @brief Transfers ownership of the underlying C2paSigner pointer out
740 /// of this wrapper, without freeing it.
741 /// @details Used by ContextBuilder::with_signer() to pass the raw pointer
742 /// to c2pa_context_builder_set_signer(), which takes ownership on
743 /// the Rust side via Box::from_raw. After this call the Signer
744 /// wrapper holds nullptr and its destructor is a no-op.
745 /// This is not the same as c2pa_signer_free(), which destroys
746 /// the signer. Similar to std::unique_ptr::release().
747 /// @return Raw C2paSigner pointer, or nullptr if already released.
748 C2paSigner* release() noexcept {
749 return std::exchange(signer, nullptr);
750 }
751
752 /// @brief Validate a TSA URI string.
753 /// @param tsa_uri The TSA URI to validate.
754 /// @return Validated C-string pointer.
755 static const char *validate_tsa_uri(const std::string &tsa_uri);
756
757 /// @brief Validate an optional TSA URI.
758 /// @param tsa_uri The optional TSA URI to validate.
759 /// @return Validated C-string pointer, or nullptr if nullopt.
760 static const char *validate_tsa_uri(const std::optional<std::string> &tsa_uri);
761
762 public:
763 /// @brief Create a Signer from a callback function.
764 /// @param callback The callback function to use for signing.
765 /// @param alg The signing algorithm to use (e.g., C2paSigningAlg::PS256).
766 /// @param sign_cert The signing certificate in PEM format.
767 /// @param tsa_uri The timestamp authority URI for time-stamping.
768 /// @throws C2paException if signer creation fails.
769 Signer(SignerFunc *callback, C2paSigningAlg alg, const std::string &sign_cert, const std::string &tsa_uri);
770
771 /// @brief Create a signer from a Signer pointer and take ownership of that pointer.
772 /// @param c_signer The C2paSigner pointer (must be non-null).
773 Signer(C2paSigner *c_signer) : signer(c_signer) {
774 if (!c_signer) {
775 throw C2paException("Signer can not be null");
776 }
777 }
778
779 /// @brief Create a Signer from signing credentials.
780 /// @param alg Signing algorithm name (e.g., "ps256", "es256").
781 /// @param sign_cert Signing certificate in PEM format.
782 /// @param private_key Private key in PEM format.
783 /// @param tsa_uri Optional timestamp authority URI.
784 /// @throws C2paException if signer creation fails.
785 Signer(const std::string &alg, const std::string &sign_cert, const std::string &private_key, const std::optional<std::string> &tsa_uri = std::nullopt);
786
787 Signer(const Signer&) = delete;
788
789 Signer& operator=(const Signer&) = delete;
790
791 /// @brief Move constructor.
792 /// @param other Signer to move from.
793 Signer(Signer&& other) noexcept : signer(std::exchange(other.signer, nullptr)) {
794 }
795
796 Signer& operator=(Signer&& other) noexcept {
797 if (this != &other) {
798 c2pa_free(signer);
799 signer = std::exchange(other.signer, nullptr);
800 }
801 return *this;
802 }
803
805
806 /// @brief Get the size to reserve for a signature for this Signer.
807 /// @return Reserved size for the signature in bytes.
808 uintptr_t reserve_size();
809
810 /// @brief Get the underlying C2paSigner pointer.
811 /// @return Pointer to the C2paSigner object.
812 C2paSigner *c2pa_signer() const noexcept;
813 };
814
815 /// @brief Builder class for creating a manifest.
816 /// @details This class is used to create a manifest from a json std::string and add resources and ingredients to the manifest.
818 {
819 private:
820 C2paBuilder *builder;
821
822 public:
823 /// @brief Create a Builder from a context with an empty manifest.
824 /// @param context Context provider; used at construction to configure settings.
825 /// @throws C2paException if context.is_valid() returns false,
826 /// or for other errors encountered by the C2PA library.
827 explicit Builder(IContextProvider& context);
828
829 /// @brief Create a Builder from a context and manifest JSON string.
830 /// @param context Context provider; used at construction to configure settings.
831 /// @param manifest_json The manifest JSON string.
832 /// @throws C2paException if context.is_valid() returns false,
833 /// or for other errors encountered by the C2PA library.
834 Builder(IContextProvider& context, const std::string &manifest_json);
835
836 /// @brief Create a Builder from a manifest JSON string (will use global settings if any loaded).
837 /// @param manifest_json The manifest JSON string.
838 /// @throws C2paException for errors encountered by the C2PA library.
839 /// @deprecated Use Builder(IContextProvider& context, manifest_json) instead.
840 [[deprecated("Use Builder(IContextProvider& context, manifest_json) instead")]]
841 Builder(const std::string &manifest_json);
842
843 /// @brief Create a Builder from a raw C FFI builder.
844 /// @param builder Raw C2paBuilder pointer to wrap.
845 /// @throws C2paException if builder is nullptr.
846 explicit Builder(C2paBuilder *builder);
847
848 Builder(const Builder&) = delete;
849
850 Builder& operator=(const Builder&) = delete;
851
852 Builder(Builder&& other) noexcept : builder(std::exchange(other.builder, nullptr)) {
853 }
854
855 Builder& operator=(Builder&& other) noexcept {
856 if (this != &other) {
857 c2pa_free(builder);
858 builder = std::exchange(other.builder, nullptr);
859 }
860 return *this;
861 }
862
864
865 /// @brief Get the underlying C2paBuilder pointer.
866 /// @return Pointer managed by this wrapper.
867 C2paBuilder *c2pa_builder() const noexcept;
868
869 /// @brief Set or update the manifest definition.
870 /// @param manifest_json The manifest JSON string.
871 /// @return Reference to this Builder for method chaining.
872 /// @throws C2pa::C2paException for errors encountered by the C2PA library.
873 Builder& with_definition(const std::string &manifest_json);
874
875 /// @brief Set the no-embed flag to prevent embedding the manifest in the asset.
876 /// @details When set, the manifest will be stored externally rather than embedded.
877 void set_no_embed();
878
879 /// @brief Set the remote URL.
880 /// @param remote_url The remote URL to set.
881 /// @throws C2paException for errors encountered by the C2PA library.
882 void set_remote_url(const std::string &remote_url);
883
884 /// @brief Set the base path for loading resources from files.
885 /// @details When set, resources are loaded from files relative to this path.
886 /// If not set, resources are loaded from memory.
887 /// @param base_path The base directory path.
888 /// @throws C2paException for errors encountered by the C2PA library.
889 /// @deprecated This method is planned to be deprecated in a future release.
890 /// Usage should be limited and temporary. Use add_resource instead.
891 void set_base_path(const std::string &base_path);
892
893 /// @brief Add a resource to the builder from a stream.
894 /// @param uri The URI identifier for the resource.
895 /// @param source The input stream to read the resource from.
896 /// @throws C2paException for errors encountered by the C2PA library.
897 void add_resource(const std::string &uri, std::istream &source);
898
899 /// @brief Add a resource to the builder from a file.
900 /// @param uri The URI identifier for the resource.
901 /// @param source_path The path to the resource file.
902 /// @throws C2paException for errors encountered by the C2PA library.
903 /// @note Prefer using the streaming APIs if possible.
904 void add_resource(const std::string &uri, const std::filesystem::path &source_path);
905
906 /// @brief Add an ingredient to the builder from a stream.
907 /// @param ingredient_json Any fields of the ingredient you want to define.
908 /// @param format The mime format of the ingredient.
909 /// @param source The input stream to read the ingredient from.
910 /// @throws C2paException for errors encountered by the C2PA library.
911 void add_ingredient(const std::string &ingredient_json, const std::string &format, std::istream &source);
912
913 /// @brief Add an ingredient to the builder from a file.
914 /// @param ingredient_json Any fields of the ingredient you want to define.
915 /// @param source_path The path to the ingredient file.
916 /// @throws C2paException for errors encountered by the C2PA library.
917 /// @note Prefer using the streaming APIs if possible.
918 void add_ingredient(const std::string &ingredient_json, const std::filesystem::path &source_path);
919
920 /// @brief Add an action to the manifest.
921 /// @param action_json JSON string containing the action data.
922 /// @throws C2paException for errors encountered by the C2PA library.
923 void add_action(const std::string &action_json);
924
925 /// @brief Set the intent for this Builder, controlling what kind of manifest to create.
926 /// @param intent The intent type: Create, Edit, or Update.
927 /// @param digital_source_type Required for Create intent. Describes how the asset was produced.
928 /// Defaults to Empty.
929 /// @throws C2paException if the intent cannot be set.
930 void set_intent(C2paBuilderIntent intent, C2paDigitalSourceType digital_source_type = Empty);
931
932 /// @brief Sign an input stream and write the signed data to an output stream.
933 /// @param format The mime format of the output stream.
934 /// @param source The input stream to sign.
935 /// @param dest The output stream to write the signed data to.
936 /// @param signer The Signer object to use for signing.
937 /// @return A vector containing the signed manifest bytes.
938 /// @throws C2paException for errors encountered by the C2PA library.
939 /// @deprecated Use sign(const string&, std::istream&, std::iostream&, Signer&) instead.
940 std::vector<unsigned char> sign(const std::string &format, std::istream &source, std::ostream &dest, Signer &signer);
941
942 /// @brief Sign an input stream and write the signed data to an I/O stream.
943 /// @param format The mime format of the output.
944 /// @param source The input stream to sign.
945 /// @param dest The I/O stream to write the signed data to.
946 /// @param signer The Signer object to use for signing.
947 /// @return A vector containing the signed manifest bytes.
948 /// @throws C2paException for errors encountered by the C2PA library.
949 std::vector<unsigned char> sign(const std::string &format, std::istream &source, std::iostream &dest, Signer &signer);
950
951 /// @brief Sign a file and write the signed data to an output file.
952 /// @param source_path The path to the file to sign.
953 /// @param dest_path The path to write the signed file to.
954 /// @param signer The signer object to use for signing.
955 /// @return A vector containing the signed manifest bytes.
956 /// @throws C2paException for errors encountered by the C2PA library.
957 /// @note Prefer using the streaming APIs if possible.
958 std::vector<unsigned char> sign(const std::filesystem::path &source_path, const std::filesystem::path &dest_path, Signer &signer);
959
960 /// @brief Sign using the signer from the Builder's Context.
961 /// @details The Signer may have been set programmatically via
962 /// ContextBuilder::with_signer(), or configured in settings JSON.
963 /// If both programmatic and settings signers are present,
964 /// the programmatic signer takes priority.
965 /// @param format The mime format of the output.
966 /// @param source The input stream to sign.
967 /// @param dest The I/O stream to write the signed data to.
968 /// @return A vector containing the signed manifest bytes.
969 /// @throws C2paException if the context has no signer or on other errors.
970 std::vector<unsigned char> sign(const std::string &format, std::istream &source, std::iostream &dest);
971
972 /// @brief Sign a file using the signer from the Builder's Context.
973 /// @details The signer may have been set programmatically via
974 /// ContextBuilder::with_signer(), or configured in settings JSON.
975 /// If both programmatic and settings signers are present,
976 /// the programmatic signer takes priority.
977 /// @param source_path The path to the file to sign.
978 /// @param dest_path The path to write the signed file to.
979 /// @return A vector containing the signed manifest bytes.
980 /// @throws C2paException if the context has no signer or on other errors.
981 std::vector<unsigned char> sign(const std::filesystem::path &source_path, const std::filesystem::path &dest_path);
982
983 /// @brief Create a Builder from an archived Builder stream.
984 /// @param archive The input stream to read the archive from.
985 /// @return A new Builder instance loaded from the archive.
986 /// @throws C2paException for errors encountered by the C2PA library.
987 static Builder from_archive(std::istream &archive);
988
989 /// @brief Create a Builder from an archive.
990 /// @param archive_path The path to the archive file.
991 /// @return A new Builder instance loaded from the archive.
992 /// @throws C2paException for errors encountered by the C2PA library.
993 /// @note Prefer using the streaming APIs if possible.
994 static Builder from_archive(const std::filesystem::path &archive_path);
995
996 /// @brief Load an archive into this builder.
997 /// @details Replaces the current definition with the archived builder state.
998 /// @param archive The input stream to read the archive from.
999 /// @return Reference to this builder for method chaining.
1000 /// @throws C2paException for errors encountered by the C2PA library.
1001 /// @note This allows setting a context before loading the archive, preserving context settings.
1002 Builder& with_archive(std::istream &archive);
1003
1004 /// @brief Write the builder to an archive stream.
1005 /// @param dest The output stream to write the archive to.
1006 /// @throws C2paException for errors encountered by the C2PA library.
1007 void to_archive(std::ostream &dest);
1008
1009 /// @brief Write the builder to an archive file.
1010 /// @param dest_path The path to write the archive file to.
1011 /// @throws C2paException for errors encountered by the C2PA library.
1012 /// @note Prefer using the streaming APIs if possible.
1013 void to_archive(const std::filesystem::path &dest_path);
1014
1015 /// @brief Create a hashed placeholder from the builder.
1016 /// @param reserved_size The size required for a signature from the intended signer (in bytes).
1017 /// @param format The mime format or extension of the asset.
1018 /// @return A vector containing the hashed placeholder bytes.
1019 /// @throws C2paException for errors encountered by the C2PA library.
1020 std::vector<unsigned char> data_hashed_placeholder(uintptr_t reserved_size, const std::string &format);
1021
1022 /// @brief Sign a Builder using the specified signer and data hash.
1023 /// @param signer The signer to use for signing.
1024 /// @param data_hash The data hash ranges to sign (must contain hashes unless an asset is provided).
1025 /// @param format The mime format for embedding. Use "c2pa" for an unformatted result.
1026 /// @param asset Optional asset to hash according to the data_hash information.
1027 /// @return A vector containing the signed embeddable data.
1028 /// @throws C2paException for errors encountered by the C2PA library.
1029 std::vector<unsigned char> sign_data_hashed_embeddable(Signer &signer, const std::string &data_hash, const std::string &format, std::istream *asset = nullptr);
1030
1031 /// @brief Convert unformatted manifest data to an embeddable format.
1032 /// @param format The format for embedding.
1033 /// @param data Unformatted manifest data from sign_data_hashed_embeddable using "c2pa" format.
1034 /// @return A formatted copy of the data.
1035 static std::vector<unsigned char> format_embeddable(const std::string &format, std::vector<unsigned char> &data);
1036
1037 /// @brief Check if the given format requires a placeholder embedding step.
1038 /// @details Returns false for BoxHash-capable formats when prefer_box_hash is enabled in
1039 /// the context settings (no placeholder needed — hash covers the full asset).
1040 /// Always returns true for BMFF formats (MP4, etc.) regardless of settings.
1041 /// @param format The MIME type or extension of the asset (e.g. "image/jpeg", "video/mp4").
1042 /// @return true if placeholder() must be called and embedded before sign_embeddable(); false otherwise.
1043 /// @throws C2paException on error.
1044 bool needs_placeholder(const std::string &format);
1045
1046 /// @brief Create a composed placeholder manifest to embed in the asset.
1047 /// @details The signer (and its reserve size) are obtained from the Builder's Context.
1048 /// For BMFF assets, the placeholder includes a BmffHash assertion with
1049 /// default exclusions for the manifest UUID box.
1050 /// Returns empty bytes for formats that do not need a placeholder (BoxHash).
1051 /// The placeholder size is stored internally so sign_embeddable() returns bytes
1052 /// of exactly the same size, enabling in-place patching.
1053 /// @param format The MIME type or extension of the asset (e.g. "image/jpeg", "video/mp4").
1054 /// @return Composed placeholder bytes ready to embed into the asset.
1055 /// @throws C2paException on error.
1056 std::vector<unsigned char> placeholder(const std::string &format);
1057
1058 /// @brief Register the byte ranges where the placeholder was embedded (DataHash workflow).
1059 /// @details Call this after embedding the placeholder bytes into the asset and before
1060 /// update_hash_from_stream(). The exclusions replace the dummy ranges set by
1061 /// placeholder() so the asset hash covers all bytes except the manifest slot.
1062 /// Exclusions are (start, length) pairs in asset byte coordinates.
1063 /// @param exclusions Vector of (start, length) pairs describing the embedded placeholder region.
1064 /// @throws C2paException if no DataHash assertion exists or on other error.
1065 void set_data_hash_exclusions(const std::vector<std::pair<uint64_t, uint64_t>> &exclusions);
1066
1067 /// @brief Compute and store the asset hash by reading a stream.
1068 /// @details Automatically detects the hard binding type from the builder state:
1069 /// - DataHash: uses exclusion ranges already registered via set_data_hash_exclusions().
1070 /// - BmffHash: uses path-based exclusions from the BMFF assertion (UUID box, mdat).
1071 /// - BoxHash: hashes each format-specific box individually.
1072 /// Call set_data_hash_exclusions() before this for DataHash workflows.
1073 /// @param format The MIME type or extension of the asset (e.g. "image/jpeg", "video/mp4").
1074 /// @param stream The asset stream to hash. Must include the embedded placeholder bytes.
1075 /// @throws C2paException on error.
1076 void update_hash_from_stream(const std::string &format, std::istream &stream);
1077
1078 /// @brief Sign and return the final manifest bytes, ready for embedding.
1079 /// @details Operates in two modes:
1080 /// - Placeholder mode (after placeholder()): zero-pads the signed manifest to the
1081 /// pre-committed placeholder size, enabling in-place patching of the asset.
1082 /// - Direct mode (no placeholder): returns the actual signed manifest size.
1083 /// Requires a valid hard binding assertion (set via update_hash_from_stream()).
1084 /// The signer is obtained from the Builder's Context.
1085 /// @param format The MIME type or extension of the asset (e.g. "image/jpeg", "video/mp4").
1086 /// @return Signed manifest bytes ready to embed into the asset.
1087 /// @throws C2paException on error.
1088 std::vector<unsigned char> sign_embeddable(const std::string &format);
1089
1090 /// @brief Get a list of mime types that the Builder supports.
1091 /// @return Vector of supported MIME type strings.
1092 static std::vector<std::string> supported_mime_types();
1093
1094 private:
1095 explicit Builder(std::istream &archive);
1096 };
1097}
1098
1099// Restore warnings
1100#ifdef __GNUC__
1101#pragma GCC diagnostic pop
1102#endif
1103
1104#ifdef _MSC_VER
1105#pragma warning(pop)
1106#endif
1107
1108#endif // C2PA_H
#define C2PA_CPP_API
Definition c2pa.hpp:48
Builder class for creating a manifest.
Definition c2pa.hpp:818
Builder(const std::string &manifest_json)
Create a Builder from a manifest JSON string (will use global settings if any loaded).
Builder & operator=(const Builder &)=delete
Builder(Builder &&other) noexcept
Definition c2pa.hpp:852
Builder(C2paBuilder *builder)
Create a Builder from a raw C FFI builder.
Builder(const Builder &)=delete
C2paBuilder * c2pa_builder() const noexcept
Get the underlying C2paBuilder pointer.
Builder & operator=(Builder &&other) noexcept
Definition c2pa.hpp:855
Builder(IContextProvider &context)
Create a Builder from a context with an empty manifest.
Builder(IContextProvider &context, const std::string &manifest_json)
Create a Builder from a context and manifest JSON string.
Exception class for C2pa errors. This class is used to throw exceptions for errors encountered by the...
Definition c2pa.hpp:86
C2paException & operator=(C2paException &&)=default
~C2paException() override=default
C2paException(const C2paException &)=default
const char * what() const noexcept override
Get the exception message.
C2paException(std::string message)
Construct an exception with a custom error message.
C2paException & operator=(const C2paException &)=default
C2paException(C2paException &&)=default
C2paException()
Default constructor.
ContextBuilder for creating customized Context instances.
Definition c2pa.hpp:269
C2PA context implementing IContextProvider.
Definition c2pa.hpp:261
IOStream Class wrapper for C2paStream.
Definition c2pa.hpp:555
CppIOStream & operator=(const CppIOStream &)=delete
CppIOStream(const CppIOStream &)=delete
CppIOStream & operator=(CppIOStream &&)=delete
C2paStream * c_stream
Pointer to the underlying C2paStream.
Definition c2pa.hpp:558
CppIOStream(IOStream &iostream)
Construct an I/O stream wrapper from a std::iostream-derived object.
Definition c2pa.hpp:565
CppIOStream(CppIOStream &&)=delete
Input stream IStream wrapper for C2paStream.
Definition c2pa.hpp:434
CppIStream & operator=(const CppIStream &)=delete
CppIStream(CppIStream &&)=delete
CppIStream & operator=(CppIStream &&)=delete
C2paStream * c_stream
Pointer to the underlying C2paStream.
Definition c2pa.hpp:437
CppIStream(IStream &istream)
Construct an input stream wrapper from a std::istream-derived object.
Definition c2pa.hpp:444
CppIStream(const CppIStream &)=delete
Output stream OStream wrapper for C2paStream.
Definition c2pa.hpp:496
CppOStream(OStream &ostream)
Construct an output stream wrapper from a std::ostream-derived object.
Definition c2pa.hpp:506
CppOStream(CppOStream &&)=delete
CppOStream & operator=(CppOStream &&)=delete
C2paStream * c_stream
Pointer to the underlying C2paStream.
Definition c2pa.hpp:499
CppOStream & operator=(const CppOStream &)=delete
CppOStream(const CppOStream &)=delete
Interface for types that can provide C2PA context functionality.
Definition c2pa.hpp:150
virtual ~IContextProvider() noexcept=default
Reader class for reading a manifest.
Definition c2pa.hpp:616
bool is_embedded() const
Check if the reader was created from an embedded manifest.
Definition c2pa.hpp:682
std::string json() const
Get the manifest as a JSON string.
int64_t get_resource(const std::string &uri, const std::filesystem::path &path)
Get a resource from the reader and write it to a file.
Reader(const std::string &format, std::istream &stream)
Create a Reader from a stream (will use global settings if any loaded).
int64_t get_resource(const std::string &uri, std::ostream &stream)
Get a resource from the reader and write it to an output stream.
Reader(Reader &&other) noexcept
Definition c2pa.hpp:661
Reader(const Reader &)=delete
Reader & operator=(const Reader &)=delete
std::optional< std::string > remote_url() const
Returns the remote url of the manifest if this Reader obtained the manifest remotely.
Reader(IContextProvider &context, const std::string &format, std::istream &stream)
Create a Reader from a context and stream.
Reader & operator=(Reader &&other) noexcept
Definition c2pa.hpp:667
Reader(const std::filesystem::path &source_path)
Create a Reader from a file path (will use global settings if any loaded).
C2paReader * get_api_internal_raw_reader() const
Get the raw C2paReader pointer.
Definition c2pa.hpp:715
Reader(IContextProvider &context, const std::filesystem::path &source_path)
Create a Reader from a context and file path.
static std::vector< std::string > supported_mime_types()
Get a list of mime types that the SDK can read manifests from.
(C2PA SDK) Settings configuration object for creating contexts.
Definition c2pa.hpp:184
Settings & update(const std::string &data)
Merge configuration from a JSON string (latest configuration wins).
Definition c2pa.hpp:222
C2paSettings * c_settings() const noexcept
Get the raw C FFI settings pointer.
Settings(const std::string &data, const std::string &format)
Create settings from a configuration string.
Settings()
Create default settings.
Settings(Settings &&) noexcept
Settings & update(const std::string &data, const std::string &format)
Merge configuration from a std::string (latest configuration wins).
Signer class for creating a Signer.
Definition c2pa.hpp:733
Signer & operator=(Signer &&other) noexcept
Definition c2pa.hpp:796
uintptr_t reserve_size()
Get the size to reserve for a signature for this Signer.
C2paSigner * c2pa_signer() const noexcept
Get the underlying C2paSigner pointer.
Signer(SignerFunc *callback, C2paSigningAlg alg, const std::string &sign_cert, const std::string &tsa_uri)
Create a Signer from a callback function.
Signer(C2paSigner *c_signer)
Create a signer from a Signer pointer and take ownership of that pointer.
Definition c2pa.hpp:773
Signer & operator=(const Signer &)=delete
Signer(Signer &&other) noexcept
Move constructor.
Definition c2pa.hpp:793
Signer(const Signer &)=delete
Signer(const std::string &alg, const std::string &sign_cert, const std::string &private_key, const std::optional< std::string > &tsa_uri=std::nullopt)
Create a Signer from signing credentials.
Definition c2pa.hpp:51
OperationResult
Result codes for C API operations (matches C API return convention).
Definition c2pa.hpp:63
@ Success
Operation succeeded.
@ Error
Operation failed (check C2paException for details)
int stream_error_return(StreamError e) noexcept
Set errno from StreamError and return error sentinel.
Definition c2pa.hpp:78
C2paSignerInfo SignerInfo
Type alias for C2paSignerInfo from the C API.
Definition c2pa.hpp:54
StreamError
Stream/FFI error codes (maps to errno values used by the C layer).
Definition c2pa.hpp:69
std::vector< unsigned char >(const std::vector< unsigned char > &) SignerFunc
Signer callback function type.
Definition c2pa.hpp:727