1+ # Copyright 2025 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+
7+ # Unless required by applicable law or agreed to in writing,
8+ # this software is distributed on an "AS IS" BASIS, WITHOUT
9+ # WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
10+ # implied. See the LICENSE-MIT and LICENSE-APACHE files for the
11+ # specific language governing permissions and limitations under
12+ # each license.
13+
114import ctypes
215import enum
316import json
@@ -664,6 +677,33 @@ def load_settings(settings: str, format: str = "json") -> None:
664677 return result
665678
666679
680+ def _get_mime_type_from_path (path : Union [str , Path ]) -> str :
681+ """Attempt to guess the MIME type from a file path (with extension).
682+
683+ Args:
684+ path: File path as string or Path object
685+
686+ Returns:
687+ MIME type string
688+
689+ Raises:
690+ C2paError.NotSupported: If MIME type cannot be determined
691+ """
692+ path_obj = Path (path )
693+ file_extension = path_obj .suffix .lower () if path_obj .suffix else ""
694+
695+ if file_extension == ".dng" :
696+ # mimetypes guesses the wrong type for dng,
697+ # so we bypass it and set the correct type
698+ return "image/dng"
699+ else :
700+ mime_type = mimetypes .guess_type (str (path ))[0 ]
701+ if not mime_type :
702+ raise C2paError .NotSupported (
703+ f"Could not determine MIME type for file: { path } " )
704+ return mime_type
705+
706+
667707def read_ingredient_file (
668708 path : Union [str , Path ], data_dir : Union [str , Path ]) -> str :
669709 """Read a file as C2PA ingredient.
@@ -1290,7 +1330,11 @@ def __init__(self,
12901330 """Create a new Reader.
12911331
12921332 Args:
1293- format_or_path: The format or path to read from
1333+ format_or_path: The format or path to read from.
1334+ The stream API (params format and an open stream) is
1335+ the recommended way to use the Reader. For paths, we
1336+ will attempt to guess the mimetype of the source
1337+ file based on the extension.
12941338 stream: Optional stream to read from (Python stream-like object)
12951339 manifest_data: Optional manifest data in bytes
12961340
@@ -1312,12 +1356,8 @@ def __init__(self,
13121356 # If we don't get a stream as param:
13131357 # Create a stream from the file path in format_or_path
13141358 path = str (format_or_path )
1315- mime_type = mimetypes .guess_type (
1316- path )[0 ]
13171359
1318- if not mime_type :
1319- raise C2paError .NotSupported (
1320- f"Could not determine MIME type for file: { path } " )
1360+ mime_type = _get_mime_type_from_path (path )
13211361
13221362 if mime_type not in Reader .get_supported_mime_types ():
13231363 raise C2paError .NotSupported (
@@ -2449,7 +2489,9 @@ def sign_file(self,
24492489 """Sign a file and write the signed data to an output file.
24502490
24512491 Args:
2452- source_path: Path to the source file
2492+ source_path: Path to the source file. We will attempt
2493+ to guess the mimetype of the source file based on
2494+ the extension.
24532495 dest_path: Path to write the signed file to
24542496 signer: The signer to use
24552497
@@ -2459,11 +2501,8 @@ def sign_file(self,
24592501 Raises:
24602502 C2paError: If there was an error during signing
24612503 """
2462- # Get the MIME type from the file extension
2463- mime_type = mimetypes .guess_type (str (source_path ))[0 ]
2464- if not mime_type :
2465- raise C2paError .NotSupported (
2466- f"Could not determine MIME type for file: { source_path } " )
2504+
2505+ mime_type = _get_mime_type_from_path (source_path )
24672506
24682507 try :
24692508 # Open source file and destination file, then use the sign method
0 commit comments