# Path: third_party/xiuminglib/xiuminglib/log.py
# def get_logger(level=None):
#     """Creates a logger for functions in the library.
# 
#     Args:
#         level (str, optional): Logging level. Defaults to ``logging.INFO``.
# 
#     Returns:
#         logging.Logger: Logger created.
#     """
#     if level is None:
#         level = logging.INFO
#     logging.basicConfig(level=level)
#     logger = logging.getLogger()
#     return logger
# 
# Path: third_party/xiuminglib/xiuminglib/os.py
# def makedirs(directory, rm_if_exists=False):
#     """Wraps :func:`os.makedirs` to support removing the directory if it
#     alread exists.
# 
#     Google Colossus-compatible: it tries to use ``gfile`` first for speed. This
#     will fail if Blaze is not used, in which case it then falls back to using
#     ``fileutil`` CLI as external process calls.
# 
#     Args:
#         directory (str)
#         rm_if_exists (bool, optional): Whether to remove the directory (and
#             its contents) if it already exists.
#     """
#     def exists_cns_cli(directory):
#         cmd = 'fileutil test -d %s' % directory
#         retcode, _, _ = call(cmd, quiet=True)
#         if retcode == 0:
#             return True
#         if retcode == 1:
#             return False
#         raise ValueError(retcode)
# 
#     def mkdir_cns_cli(directory):
#         cmd = 'fileutil mkdir -p %s' % directory
#         _call_assert_success(cmd, quiet=True)
# 
#     if _is_cnspath(directory):
#         # Is a CNS path
#         gfile = preset_import('gfile')
#         if gfile is None:
#             exists_func = exists_cns_cli
#             mkdir_func = mkdir_cns_cli
#         else:
#             exists_func = gfile.Exists
#             mkdir_func = gfile.MakeDirs
#     else:
#         # Is just a regular local path
#         exists_func = exists
#         mkdir_func = os.makedirs
# 
#     # Do the job
#     if exists_func(directory):
#         if rm_if_exists:
#             rm(directory)
#             mkdir_func(directory)
#             logger.info("Removed and then remade:\n\t%s", directory)
#     else:
#         mkdir_func(directory)
# 
# def open_file(path, mode):
#     """Opens a file.
# 
#     Supports Google Colossus if ``gfile`` can be imported.
# 
#     Args:
#         path (str): Path to open.
#         mode (str): ``'r'``, ``'rb'``, ``'w'``, or ``'wb'``.
# 
#     Returns:
#         File handle that can be used as a context.
#     """
#     gfile = preset_import('gfile')
# 
#     open_func = open if gfile is None else gfile.Open
#     handle = open_func(path, mode)
# 
#     return handle


from os.path import dirname
from PIL import Image, ExifTags
from ..log import get_logger
from ..os import makedirs, open_file
import numpy as np
                Image.ROTATE_270).transpose(Image.FLIP_TOP_BOTTOM)
        elif orientation in (8, '8'):
            img = img.transpose(Image.ROTATE_90)
        else:
            raise ValueError(f"Invalid orientation: {orientation}")

    img = np.array(img)

    logger.debug("Image read from:\n\t%s", path)

    return img


def write_uint(arr_uint, outpath):
    r"""Writes an ``uint`` array as an image to disk.

    Args:
        arr_uint (numpy.ndarray): A ``uint`` array.
        outpath (str): Output path.

    Writes
        - The resultant image.
    """
    if arr_uint.ndim == 3 and arr_uint.shape[2] == 1:
        arr_uint = np.dstack([arr_uint] * 3)

    img = Image.fromarray(arr_uint)

    # Write to disk
    makedirs(dirname(outpath))

# Path: third_party/xiuminglib/xiuminglib/log.py
# def get_logger(level=None):
#     """Creates a logger for functions in the library.
# 
#     Args:
#         level (str, optional): Logging level. Defaults to ``logging.INFO``.
# 
#     Returns:
#         logging.Logger: Logger created.
#     """
#     if level is None:
#         level = logging.INFO
#     logging.basicConfig(level=level)
#     logger = logging.getLogger()
#     return logger
# 
# Path: third_party/xiuminglib/xiuminglib/os.py
# def makedirs(directory, rm_if_exists=False):
#     """Wraps :func:`os.makedirs` to support removing the directory if it
#     alread exists.
# 
#     Google Colossus-compatible: it tries to use ``gfile`` first for speed. This
#     will fail if Blaze is not used, in which case it then falls back to using
#     ``fileutil`` CLI as external process calls.
# 
#     Args:
#         directory (str)
#         rm_if_exists (bool, optional): Whether to remove the directory (and
#             its contents) if it already exists.
#     """
#     def exists_cns_cli(directory):
#         cmd = 'fileutil test -d %s' % directory
#         retcode, _, _ = call(cmd, quiet=True)
#         if retcode == 0:
#             return True
#         if retcode == 1:
#             return False
#         raise ValueError(retcode)
# 
#     def mkdir_cns_cli(directory):
#         cmd = 'fileutil mkdir -p %s' % directory
#         _call_assert_success(cmd, quiet=True)
# 
#     if _is_cnspath(directory):
#         # Is a CNS path
#         gfile = preset_import('gfile')
#         if gfile is None:
#             exists_func = exists_cns_cli
#             mkdir_func = mkdir_cns_cli
#         else:
#             exists_func = gfile.Exists
#             mkdir_func = gfile.MakeDirs
#     else:
#         # Is just a regular local path
#         exists_func = exists
#         mkdir_func = os.makedirs
# 
#     # Do the job
#     if exists_func(directory):
#         if rm_if_exists:
#             rm(directory)
#             mkdir_func(directory)
#             logger.info("Removed and then remade:\n\t%s", directory)
#     else:
#         mkdir_func(directory)
# 
# def open_file(path, mode):
#     """Opens a file.
# 
#     Supports Google Colossus if ``gfile`` can be imported.
# 
#     Args:
#         path (str): Path to open.
#         mode (str): ``'r'``, ``'rb'``, ``'w'``, or ``'wb'``.
# 
#     Returns:
#         File handle that can be used as a context.
#     """
#     gfile = preset_import('gfile')
# 
#     open_func = open if gfile is None else gfile.Open
#     handle = open_func(path, mode)
# 
#     return handle


# Path: third_party/xiuminglib/xiuminglib/io/img.py
from os.path import dirname
from PIL import Image, ExifTags
from ..log import get_logger
from ..os import makedirs, open_file
import numpy as np

                Image.ROTATE_270).transpose(Image.FLIP_TOP_BOTTOM)
        elif orientation in (8, '8'):
            img = img.transpose(Image.ROTATE_90)
        else:
            raise ValueError(f"Invalid orientation: {orientation}")

    img = np.array(img)

    logger.debug("Image read from:\n\t%s", path)

    return img


def write_uint(arr_uint, outpath):
    r"""Writes an ``uint`` array as an image to disk.

    Args:
        arr_uint (numpy.ndarray): A ``uint`` array.
        outpath (str): Output path.

    Writes
        - The resultant image.
    """
    if arr_uint.ndim == 3 and arr_uint.shape[2] == 1:
        arr_uint = np.dstack([arr_uint] * 3)

    img = Image.fromarray(arr_uint)

    # Write to disk
    makedirs(dirname(outpath))

    with open_file(outpath, 'wb') as h: