def pad(arr, top=<NUM_LIT:0>, right=<NUM_LIT:0>, bottom=<NUM_LIT:0>, left=<NUM_LIT:0>, mode="<STR_LIT>", cval=<NUM_LIT:0>):
do_assert(arr.ndim in [<NUM_LIT:2>, <NUM_LIT:3>])<EOL>do_assert(top >= <NUM_LIT:0>)<EOL>do_assert(right >= <NUM_LIT:0>)<EOL>do_assert(bottom >= <NUM_LIT:0>)<EOL>do_assert(left >= <NUM_LIT:0>)<EOL>if top > <NUM_LIT:0> or right > <NUM_LIT:0> or bottom > <NUM_LIT:0> or left > <NUM_LIT:0>:<EOL><INDENT>mapping_mode_np_to_cv2 = {<EOL>"<STR_LIT>": cv2.BORDER_CONSTANT,<EOL>"<STR_LIT>": cv2.BORDER_REPLICATE,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": cv2.BORDER_REFLECT_101,<EOL>"<STR_LIT>": cv2.BORDER_REFLECT,<EOL>"<STR_LIT>": None,<EOL>cv2.BORDER_CONSTANT: cv2.BORDER_CONSTANT,<EOL>cv2.BORDER_REPLICATE: cv2.BORDER_REPLICATE,<EOL>cv2.BORDER_REFLECT_101: cv2.BORDER_REFLECT_101,<EOL>cv2.BORDER_REFLECT: cv2.BORDER_REFLECT<EOL>}<EOL>bad_mode_cv2 = mapping_mode_np_to_cv2.get(mode, None) is None<EOL>bad_datatype_cv2 = arr.dtype.name in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT:bool>"]<EOL>if not bad_datatype_cv2 and not bad_mode_cv2:<EOL><INDENT>cval = float(cval) if arr.dtype.kind == "<STR_LIT:f>" else int(cval)  <EOL>if arr.ndim == <NUM_LIT:2> or arr.shape[<NUM_LIT:2>] <= <NUM_LIT:4>:<EOL><INDENT>if arr.ndim == <NUM_LIT:3>:<EOL><INDENT>cval = tuple([cval] * arr.shape[<NUM_LIT:2>])<EOL><DEDENT>arr_pad = cv2.copyMakeBorder(arr, top=top, bottom=bottom, left=left, right=right,<EOL>borderType=mapping_mode_np_to_cv2[mode], value=cval)<EOL>if arr.ndim == <NUM_LIT:3> and arr_pad.ndim == <NUM_LIT:2>:<EOL><INDENT>arr_pad = arr_pad[..., np.newaxis]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>result = []<EOL>channel_start_idx = <NUM_LIT:0><EOL>while channel_start_idx < arr.shape[<NUM_LIT:2>]:<EOL><INDENT>arr_c = arr[..., channel_start_idx:channel_start_idx+<NUM_LIT:4>]<EOL>cval_c = tuple([cval] * arr_c.shape[<NUM_LIT:2>])<EOL>arr_pad_c = cv2.copyMakeBorder(arr_c, top=top, bottom=bottom, left=left, right=right,<EOL>borderType=mapping_mode_np_to_cv2[mode], value=cval_c)<EOL>arr_pad_c = np.atleast_3d(arr_pad_c)<EOL>result.append(arr_pad_c)<EOL>channel_start_idx += <NUM_LIT:4><EOL><DEDENT>arr_pad = np.concatenate(result, axis=<NUM_LIT:2>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>paddings_np = [(top, bottom), (left, right)]  <EOL>if arr.ndim == <NUM_LIT:3>:<EOL><INDENT>paddings_np.append((<NUM_LIT:0>, <NUM_LIT:0>))  <EOL><DEDENT>if mode == "<STR_LIT>":<EOL><INDENT>arr_pad = np.pad(arr, paddings_np, mode=mode, constant_values=cval)<EOL><DEDENT>elif mode == "<STR_LIT>":<EOL><INDENT>arr_pad = np.pad(arr, paddings_np, mode=mode, end_values=cval)<EOL><DEDENT>else:<EOL><INDENT>arr_pad = np.pad(arr, paddings_np, mode=mode)<EOL><DEDENT><DEDENT>return arr_pad<EOL><DEDENT>return np.copy(arr)<EOL>
Pad an image-like array on its top/right/bottom/left side.

This function is a wrapper around :func:`numpy.pad`.

dtype support::

    * ``uint8``: yes; fully tested (1)
    * ``uint16``: yes; fully tested (1)
    * ``uint32``: yes; fully tested (2) (3)
    * ``uint64``: yes; fully tested (2) (3)
    * ``int8``: yes; fully tested (1)
    * ``int16``: yes; fully tested (1)
    * ``int32``: yes; fully tested (1)
    * ``int64``: yes; fully tested (2) (3)
    * ``float16``: yes; fully tested (2) (3)
    * ``float32``: yes; fully tested (1)
    * ``float64``: yes; fully tested (1)
    * ``float128``: yes; fully tested (2) (3)
    * ``bool``: yes; tested (2) (3)

    - (1) Uses ``cv2`` if `mode` is one of: ``"constant"``, ``"edge"``, ``"reflect"``, ``"symmetric"``.
          Otherwise uses ``numpy``.
    - (2) Uses ``numpy``.
    - (3) Rejected by ``cv2``.

Parameters
----------
arr : (H,W) ndarray or (H,W,C) ndarray
    Image-like array to pad.

top : int, optional
    Amount of pixels to add at the top side of the image. Must be 0 or greater.

right : int, optional
    Amount of pixels to add at the right side of the image. Must be 0 or greater.

bottom : int, optional
    Amount of pixels to add at the bottom side of the image. Must be 0 or greater.

left : int, optional
    Amount of pixels to add at the left side of the image. Must be 0 or greater.

mode : str, optional
    Padding mode to use. See :func:`numpy.pad` for details.
    In case of mode ``constant``, the parameter `cval` will be used as the ``constant_values``
    parameter to :func:`numpy.pad`.
    In case of mode ``linear_ramp``, the parameter `cval` will be used as the ``end_values``
    parameter to :func:`numpy.pad`.

cval : number, optional
    Value to use for padding if `mode` is ``constant``. See :func:`numpy.pad` for details.
    The cval is expected to match the input array's dtype and value range.

Returns
-------
arr_pad : (H',W') ndarray or (H',W',C) ndarray
    Padded array with height ``H'=H+top+bottom`` and width ``W'=W+left+right``.