diff --git a/pyproject.toml b/pyproject.toml index c05ba39a..a2942b52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "c2pa-python" -version = "0.32.13" +version = "0.32.14" requires-python = ">=3.10" description = "Python bindings for the C2PA Content Authenticity Initiative (CAI) library" readme = { file = "README.md", content-type = "text/markdown" } diff --git a/src/c2pa/c2pa.py b/src/c2pa/c2pa.py index 71cfb80f..ae8b307e 100644 --- a/src/c2pa/c2pa.py +++ b/src/c2pa/c2pa.py @@ -48,6 +48,7 @@ 'c2pa_reader_from_manifest_data_and_stream', 'c2pa_reader_json', 'c2pa_reader_detailed_json', + 'c2pa_reader_crjson', 'c2pa_reader_resource_to_stream', 'c2pa_reader_from_context', 'c2pa_reader_with_stream', @@ -561,6 +562,9 @@ def _setup_function(func, argtypes, restype=None): _setup_function( _lib.c2pa_reader_detailed_json, [ ctypes.POINTER(C2paReader)], ctypes.c_void_p) +_setup_function( + _lib.c2pa_reader_crjson, [ + ctypes.POINTER(C2paReader)], ctypes.c_void_p) _setup_function(_lib.c2pa_reader_resource_to_stream, [ctypes.POINTER( C2paReader), ctypes.c_char_p, ctypes.POINTER(C2paStream)], ctypes.c_int64) _setup_function( @@ -2631,6 +2635,27 @@ def detailed_json(self) -> str: return _convert_to_py_string(result) + def crjson(self) -> str: + """Get the manifest store as a crJSON string. + + crJSON is a standardized JSON format for C2PA manifest data. This + call yields empty JSON ("{}") when there are no Content Credentials. + + Returns: + The manifest store as a crJSON string. + + Raises: + C2paError: If the Reader has been closed or the underlying C + call returns null. + """ + + self._ensure_valid_state() + + result = _lib.c2pa_reader_crjson(self._handle) + _check_ffi_operation_result(result, "Error parsing crJSON") + + return _convert_to_py_string(result) + def _get_manifest_field(self, extractor): """Extract a field from (cached) manifest data, or None if unavailable. diff --git a/tests/test_unit_tests.py b/tests/test_unit_tests.py index 57e0d755..ecdd1bc6 100644 --- a/tests/test_unit_tests.py +++ b/tests/test_unit_tests.py @@ -271,6 +271,19 @@ def test_stream_read_detailed_and_parse(self): title = manifest_store["manifests"][manifest_store["active_manifest"]]["claim"]["dc:title"] self.assertEqual(title, DEFAULT_TEST_FILE_NAME) + def test_stream_read_crjson_and_parse(self): + with open(self.testPath, "rb") as file: + reader = Reader("image/jpeg", file) + crjson = reader.crjson() + self.assertTrue(crjson) + json.loads(crjson) + + def test_stream_read_crjson_path_only(self): + with Reader(self.testPath) as reader: + crjson = reader.crjson() + self.assertTrue(crjson) + json.loads(crjson) + def test_stream_read_string_stream_path_only(self): with Reader(self.testPath) as reader: json_data = reader.json()