prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  unwrap_phase SegFaults when passed a masked array with all elements masked
  The **unwrap_phase** function in the skimage.restoration namespace Segmentation faults when passed a masked array with all elements masked.  For example:
  
  ``` Python
  import numpy as np
  from skimage.restoration import unwrap_phase
  image = np.ma.arange(100, dtype='float32').reshape(10, 10)
  image[:] = np.ma.masked
  unwrap_phase(image)
  ```
  
  The Segmentation fault occurs in the find_pivot function in unwrap_2d_ljmu.c which is called from quicker_sort.  The issue is that the routine is attempting to sort a length 0 array.  A check should be added in the unwrap2D (and related functions) to see if params.no_of_edges is not 0 (or 1?)
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `skimage/restoration/unwrap.py`
  Content:
  ```
  1 import numpy as np
  2 import warnings
  3 from six import string_types
  4 
  5 from ._unwrap_1d import unwrap_1d
  6 from ._unwrap_2d import unwrap_2d
  7 from ._unwrap_3d import unwrap_3d
  8 
  9 
  10 def unwrap_phase(image, wrap_around=False, seed=None):
  11     '''Recover the original from a wrapped phase image.
  12 
  13     From an image wrapped to lie in the interval [-pi, pi), recover the
  14     original, unwrapped image.
  15 
  16     Parameters
  17     ----------
  18     image : 1D, 2D or 3D ndarray of floats, optionally a masked array
  19         The values should be in the range [-pi, pi). If a masked array is
  20         provided, the masked entries will not be changed, and their values
  21         will not be used to guide the unwrapping of neighboring, unmasked
  22         values. Masked 1D arrays are not allowed, and will raise a
  23         `ValueError`.
  24     wrap_around : bool or sequence of bool, optional
  25         When an element of the sequence is  `True`, the unwrapping process
  26         will regard the edges along the corresponding axis of the image to be
  27         connected and use this connectivity to guide the phase unwrapping
  28         process. If only a single boolean is given, it will apply to all axes.
  29         Wrap around is not supported for 1D arrays.
  30     seed : int, optional
  31         Unwrapping 2D or 3D images uses random initialization. This sets the
  32         seed of the PRNG to achieve deterministic behavior.
  33 
  34     Returns
  35     -------
  36     image_unwrapped : array_like, double
  37         Unwrapped image of the same shape as the input. If the input `image`
  38         was a masked array, the mask will be preserved.
  39 
  40     Raises
  41     ------
  42     ValueError
  43         If called with a masked 1D array or called with a 1D array and
  44         ``wrap_around=True``.
  45 
  46     Examples
  47     --------
  48     >>> c0, c1 = np.ogrid[-1:1:128j, -1:1:128j]
  49     >>> image = 12 * np.pi * np.exp(-(c0**2 + c1**2))
  50     >>> image_wrapped = np.angle(np.exp(1j * image))
  51     >>> image_unwrapped = unwrap_phase(image_wrapped)
  52     >>> np.std(image_unwrapped - image) < 1e-6   # A constant offset is normal
  53     True
  54 
  55     References
  56     ----------
  57     .. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor,
  58            and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping
  59            algorithm based on sorting by reliability following a noncontinuous
  60            path", Journal Applied Optics, Vol. 41, No. 35 (2002) 7437,
  61     .. [2] Abdul-Rahman, H., Gdeisat, M., Burton, D., & Lalor, M., "Fast
  62            three-dimensional phase-unwrapping algorithm based on sorting by
  63            reliability following a non-continuous path. In W. Osten,
  64            C. Gorecki, & E. L. Novak (Eds.), Optical Metrology (2005) 32--40,
  65            International Society for Optics and Photonics.
  66     '''
  67     if image.ndim not in (1, 2, 3):
  68         raise ValueError('Image must be 1, 2, or 3 dimensional')
  69     if isinstance(wrap_around, bool):
  70         wrap_around = [wrap_around] * image.ndim
  71     elif (hasattr(wrap_around, '__getitem__')
  72           and not isinstance(wrap_around, string_types)):
  73         if len(wrap_around) != image.ndim:
  74             raise ValueError('Length of `wrap_around` must equal the '
  75                              'dimensionality of image')
  76         wrap_around = [bool(wa) for wa in wrap_around]
  77     else:
  78         raise ValueError('`wrap_around` must be a bool or a sequence with '
  79                          'length equal to the dimensionality of image')
  80     if image.ndim == 1:
  81         if np.ma.isMaskedArray(image):
  82             raise ValueError('1D masked images cannot be unwrapped')
  83         if wrap_around[0]:
  84             raise ValueError('`wrap_around` is not supported for 1D images')
  85     if image.ndim in (2, 3) and 1 in image.shape:
  86         warnings.warn('Image has a length 1 dimension. Consider using an '
  87                       'array of lower dimensionality to use a more efficient '
  88                       'algorithm')
  89 
  90     if np.ma.isMaskedArray(image):
  91         mask = np.require(image.mask, np.uint8, ['C'])
  92         image = image.data
  93     else:
  94         mask = np.zeros_like(image, dtype=np.uint8, order='C')
  95 
  96     image_not_masked = np.asarray(image, dtype=np.double, order='C')
  97     image_unwrapped = np.empty_like(image, dtype=np.double, order='C')
  98 
  99     if image.ndim == 1:
  100         unwrap_1d(image_not_masked, image_unwrapped)
  101     elif image.ndim == 2:
  102         unwrap_2d(image_not_masked, mask, image_unwrapped,
  103                   wrap_around, seed)
  104     elif image.ndim == 3:
  105         unwrap_3d(image_not_masked, mask, image_unwrapped,
  106                   wrap_around, seed)
  107 
  108     if np.ma.isMaskedArray(image):
  109         return np.ma.array(image_unwrapped, mask=mask)
  110     else:
  111         return image_unwrapped
  112
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/skimage/restoration/unwrap.py b/skimage/restoration/unwrap.py
  --- a/skimage/restoration/unwrap.py
  +++ b/skimage/restoration/unwrap.py
  @@ -88,13 +88,14 @@
                         'algorithm')
   
       if np.ma.isMaskedArray(image):
  -        mask = np.require(image.mask, np.uint8, ['C'])
  -        image = image.data
  +        mask = np.require(np.ma.getmaskarray(image), np.uint8, ['C'])
       else:
           mask = np.zeros_like(image, dtype=np.uint8, order='C')
   
  -    image_not_masked = np.asarray(image, dtype=np.double, order='C')
  -    image_unwrapped = np.empty_like(image, dtype=np.double, order='C')
  +    image_not_masked = np.asarray(
  +        np.ma.getdata(image), dtype=np.double, order='C')
  +    image_unwrapped = np.empty_like(image, dtype=np.double, order='C',
  +                                    subok=False)
   
       if image.ndim == 1:
           unwrap_1d(image_not_masked, image_unwrapped)
  
verification_info: {"golden_diff": "diff --git a/skimage/restoration/unwrap.py b/skimage/restoration/unwrap.py\n--- a/skimage/restoration/unwrap.py\n+++ b/skimage/restoration/unwrap.py\n@@ -88,13 +88,14 @@\n                       'algorithm')\n \n     if np.ma.isMaskedArray(image):\n-        mask = np.require(image.mask, np.uint8, ['C'])\n-        image = image.data\n+        mask = np.require(np.ma.getmaskarray(image), np.uint8, ['C'])\n     else:\n         mask = np.zeros_like(image, dtype=np.uint8, order='C')\n \n-    image_not_masked = np.asarray(image, dtype=np.double, order='C')\n-    image_unwrapped = np.empty_like(image, dtype=np.double, order='C')\n+    image_not_masked = np.asarray(\n+        np.ma.getdata(image), dtype=np.double, order='C')\n+    image_unwrapped = np.empty_like(image, dtype=np.double, order='C',\n+                                    subok=False)\n \n     if image.ndim == 1:\n         unwrap_1d(image_not_masked, image_unwrapped)\n", "issue": "unwrap_phase SegFaults when passed a masked array with all elements masked\nThe **unwrap_phase** function in the skimage.restoration namespace Segmentation faults when passed a masked array with all elements masked.  For example:\n\n``` Python\nimport numpy as np\nfrom skimage.restoration import unwrap_phase\nimage = np.ma.arange(100, dtype='float32').reshape(10, 10)\nimage[:] = np.ma.masked\nunwrap_phase(image)\n```\n\nThe Segmentation fault occurs in the find_pivot function in unwrap_2d_ljmu.c which is called from quicker_sort.  The issue is that the routine is attempting to sort a length 0 array.  A check should be added in the unwrap2D (and related functions) to see if params.no_of_edges is not 0 (or 1?)\n\n", "before_files": [{"content": "import numpy as np\nimport warnings\nfrom six import string_types\n\nfrom ._unwrap_1d import unwrap_1d\nfrom ._unwrap_2d import unwrap_2d\nfrom ._unwrap_3d import unwrap_3d\n\n\ndef unwrap_phase(image, wrap_around=False, seed=None):\n    '''Recover the original from a wrapped phase image.\n\n    From an image wrapped to lie in the interval [-pi, pi), recover the\n    original, unwrapped image.\n\n    Parameters\n    ----------\n    image : 1D, 2D or 3D ndarray of floats, optionally a masked array\n        The values should be in the range [-pi, pi). If a masked array is\n        provided, the masked entries will not be changed, and their values\n        will not be used to guide the unwrapping of neighboring, unmasked\n        values. Masked 1D arrays are not allowed, and will raise a\n        `ValueError`.\n    wrap_around : bool or sequence of bool, optional\n        When an element of the sequence is  `True`, the unwrapping process\n        will regard the edges along the corresponding axis of the image to be\n        connected and use this connectivity to guide the phase unwrapping\n        process. If only a single boolean is given, it will apply to all axes.\n        Wrap around is not supported for 1D arrays.\n    seed : int, optional\n        Unwrapping 2D or 3D images uses random initialization. This sets the\n        seed of the PRNG to achieve deterministic behavior.\n\n    Returns\n    -------\n    image_unwrapped : array_like, double\n        Unwrapped image of the same shape as the input. If the input `image`\n        was a masked array, the mask will be preserved.\n\n    Raises\n    ------\n    ValueError\n        If called with a masked 1D array or called with a 1D array and\n        ``wrap_around=True``.\n\n    Examples\n    --------\n    >>> c0, c1 = np.ogrid[-1:1:128j, -1:1:128j]\n    >>> image = 12 * np.pi * np.exp(-(c0**2 + c1**2))\n    >>> image_wrapped = np.angle(np.exp(1j * image))\n    >>> image_unwrapped = unwrap_phase(image_wrapped)\n    >>> np.std(image_unwrapped - image) < 1e-6   # A constant offset is normal\n    True\n\n    References\n    ----------\n    .. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor,\n           and Munther A. Gdeisat, \"Fast two-dimensional phase-unwrapping\n           algorithm based on sorting by reliability following a noncontinuous\n           path\", Journal Applied Optics, Vol. 41, No. 35 (2002) 7437,\n    .. [2] Abdul-Rahman, H., Gdeisat, M., Burton, D., & Lalor, M., \"Fast\n           three-dimensional phase-unwrapping algorithm based on sorting by\n           reliability following a non-continuous path. In W. Osten,\n           C. Gorecki, & E. L. Novak (Eds.), Optical Metrology (2005) 32--40,\n           International Society for Optics and Photonics.\n    '''\n    if image.ndim not in (1, 2, 3):\n        raise ValueError('Image must be 1, 2, or 3 dimensional')\n    if isinstance(wrap_around, bool):\n        wrap_around = [wrap_around] * image.ndim\n    elif (hasattr(wrap_around, '__getitem__')\n          and not isinstance(wrap_around, string_types)):\n        if len(wrap_around) != image.ndim:\n            raise ValueError('Length of `wrap_around` must equal the '\n                             'dimensionality of image')\n        wrap_around = [bool(wa) for wa in wrap_around]\n    else:\n        raise ValueError('`wrap_around` must be a bool or a sequence with '\n                         'length equal to the dimensionality of image')\n    if image.ndim == 1:\n        if np.ma.isMaskedArray(image):\n            raise ValueError('1D masked images cannot be unwrapped')\n        if wrap_around[0]:\n            raise ValueError('`wrap_around` is not supported for 1D images')\n    if image.ndim in (2, 3) and 1 in image.shape:\n        warnings.warn('Image has a length 1 dimension. Consider using an '\n                      'array of lower dimensionality to use a more efficient '\n                      'algorithm')\n\n    if np.ma.isMaskedArray(image):\n        mask = np.require(image.mask, np.uint8, ['C'])\n        image = image.data\n    else:\n        mask = np.zeros_like(image, dtype=np.uint8, order='C')\n\n    image_not_masked = np.asarray(image, dtype=np.double, order='C')\n    image_unwrapped = np.empty_like(image, dtype=np.double, order='C')\n\n    if image.ndim == 1:\n        unwrap_1d(image_not_masked, image_unwrapped)\n    elif image.ndim == 2:\n        unwrap_2d(image_not_masked, mask, image_unwrapped,\n                  wrap_around, seed)\n    elif image.ndim == 3:\n        unwrap_3d(image_not_masked, mask, image_unwrapped,\n                  wrap_around, seed)\n\n    if np.ma.isMaskedArray(image):\n        return np.ma.array(image_unwrapped, mask=mask)\n    else:\n        return image_unwrapped\n", "path": "skimage/restoration/unwrap.py"}], "after_files": [{"content": "import numpy as np\nimport warnings\nfrom six import string_types\n\nfrom ._unwrap_1d import unwrap_1d\nfrom ._unwrap_2d import unwrap_2d\nfrom ._unwrap_3d import unwrap_3d\n\n\ndef unwrap_phase(image, wrap_around=False, seed=None):\n    '''Recover the original from a wrapped phase image.\n\n    From an image wrapped to lie in the interval [-pi, pi), recover the\n    original, unwrapped image.\n\n    Parameters\n    ----------\n    image : 1D, 2D or 3D ndarray of floats, optionally a masked array\n        The values should be in the range [-pi, pi). If a masked array is\n        provided, the masked entries will not be changed, and their values\n        will not be used to guide the unwrapping of neighboring, unmasked\n        values. Masked 1D arrays are not allowed, and will raise a\n        `ValueError`.\n    wrap_around : bool or sequence of bool, optional\n        When an element of the sequence is  `True`, the unwrapping process\n        will regard the edges along the corresponding axis of the image to be\n        connected and use this connectivity to guide the phase unwrapping\n        process. If only a single boolean is given, it will apply to all axes.\n        Wrap around is not supported for 1D arrays.\n    seed : int, optional\n        Unwrapping 2D or 3D images uses random initialization. This sets the\n        seed of the PRNG to achieve deterministic behavior.\n\n    Returns\n    -------\n    image_unwrapped : array_like, double\n        Unwrapped image of the same shape as the input. If the input `image`\n        was a masked array, the mask will be preserved.\n\n    Raises\n    ------\n    ValueError\n        If called with a masked 1D array or called with a 1D array and\n        ``wrap_around=True``.\n\n    Examples\n    --------\n    >>> c0, c1 = np.ogrid[-1:1:128j, -1:1:128j]\n    >>> image = 12 * np.pi * np.exp(-(c0**2 + c1**2))\n    >>> image_wrapped = np.angle(np.exp(1j * image))\n    >>> image_unwrapped = unwrap_phase(image_wrapped)\n    >>> np.std(image_unwrapped - image) < 1e-6   # A constant offset is normal\n    True\n\n    References\n    ----------\n    .. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor,\n           and Munther A. Gdeisat, \"Fast two-dimensional phase-unwrapping\n           algorithm based on sorting by reliability following a noncontinuous\n           path\", Journal Applied Optics, Vol. 41, No. 35 (2002) 7437,\n    .. [2] Abdul-Rahman, H., Gdeisat, M., Burton, D., & Lalor, M., \"Fast\n           three-dimensional phase-unwrapping algorithm based on sorting by\n           reliability following a non-continuous path. In W. Osten,\n           C. Gorecki, & E. L. Novak (Eds.), Optical Metrology (2005) 32--40,\n           International Society for Optics and Photonics.\n    '''\n    if image.ndim not in (1, 2, 3):\n        raise ValueError('Image must be 1, 2, or 3 dimensional')\n    if isinstance(wrap_around, bool):\n        wrap_around = [wrap_around] * image.ndim\n    elif (hasattr(wrap_around, '__getitem__')\n          and not isinstance(wrap_around, string_types)):\n        if len(wrap_around) != image.ndim:\n            raise ValueError('Length of `wrap_around` must equal the '\n                             'dimensionality of image')\n        wrap_around = [bool(wa) for wa in wrap_around]\n    else:\n        raise ValueError('`wrap_around` must be a bool or a sequence with '\n                         'length equal to the dimensionality of image')\n    if image.ndim == 1:\n        if np.ma.isMaskedArray(image):\n            raise ValueError('1D masked images cannot be unwrapped')\n        if wrap_around[0]:\n            raise ValueError('`wrap_around` is not supported for 1D images')\n    if image.ndim in (2, 3) and 1 in image.shape:\n        warnings.warn('Image has a length 1 dimension. Consider using an '\n                      'array of lower dimensionality to use a more efficient '\n                      'algorithm')\n\n    if np.ma.isMaskedArray(image):\n        mask = np.require(np.ma.getmaskarray(image), np.uint8, ['C'])\n    else:\n        mask = np.zeros_like(image, dtype=np.uint8, order='C')\n\n    image_not_masked = np.asarray(\n        np.ma.getdata(image), dtype=np.double, order='C')\n    image_unwrapped = np.empty_like(image, dtype=np.double, order='C',\n                                    subok=False)\n\n    if image.ndim == 1:\n        unwrap_1d(image_not_masked, image_unwrapped)\n    elif image.ndim == 2:\n        unwrap_2d(image_not_masked, mask, image_unwrapped,\n                  wrap_around, seed)\n    elif image.ndim == 3:\n        unwrap_3d(image_not_masked, mask, image_unwrapped,\n                  wrap_around, seed)\n\n    if np.ma.isMaskedArray(image):\n        return np.ma.array(image_unwrapped, mask=mask)\n    else:\n        return image_unwrapped\n", "path": "skimage/restoration/unwrap.py"}]}