def calculate_shape(new_shape, orig_shape):
    """Calculate a new image shape given the desired width and/or height.

    Parameters
    ----------
    new_shape : tuple
        The desired height and/or width of the image. Each may be None.
    orig_shape : tuple
        The shape of the original image. Will be used to calculate the
        width and height in case one or both are None.

    Returns
    -------
    tuple
        The output shape

    """
    if new_shape is None:
        return orig_shape

    height, width = new_shape
    if height is None:
        if width is not None:
            # Determine height from given width
            height = width * orig_shape[0] / orig_shape[1]
            height = height // 2 * 2
        else:
            # Both are None: Use original shape
            height = orig_shape[0]
            width = orig_shape[1]
    elif width is None:
        # Determine width from given height
        width = height * orig_shape[1] / orig_shape[0]
        width = width // 2 * 2

    return (int(height), int(width))