We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Clean up and Document the io.image enhancements
PR #3024 introduced a few enhancements on the `io.image` methods used for reading JPEG and PNG images. The code changes were merged but there are a few nice-to-have improvements missing.

More specifically:
- [x] Provide better error messages for [JPEG](https://github.com/pytorch/vision/pull/3024#discussion_r527066925) and [PNG](https://github.com/pytorch/vision/pull/3024#discussion_r527093866) when a specific `ImageReadMode` value is not supported.
- [x] Ensure that `image_read_mode.h` has a new line at the [end of the file](https://github.com/pytorch/vision/pull/3024#discussion_r526710809).
- [x] [Replace](https://github.com/pytorch/vision/pull/3024#discussion_r527065253) the old `#define` with the newer `constexpr` expression at `image_read_mode.h`.
- [x] [Move the documentation](https://github.com/pytorch/vision/pull/3024#discussion_r527095264) of `ImageReadMode` values from the methods to the enum.

**Note:** `constexpr` might cause problems on Windows. If that's the case, try using const instead.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `torchvision/io/image.py`
Content:
```
1 import torch
2 
3 import os
4 import os.path as osp
5 import importlib.machinery
6 
7 from enum import Enum
8 
9 _HAS_IMAGE_OPT = False
10 
11 try:
12     lib_dir = osp.abspath(osp.join(osp.dirname(__file__), ".."))
13 
14     loader_details = (
15         importlib.machinery.ExtensionFileLoader,
16         importlib.machinery.EXTENSION_SUFFIXES
17     )
18 
19     extfinder = importlib.machinery.FileFinder(lib_dir, loader_details)  # type: ignore[arg-type]
20     ext_specs = extfinder.find_spec("image")
21 
22     if os.name == 'nt':
23         # Load the image extension using LoadLibraryExW
24         import ctypes
25         import sys
26 
27         kernel32 = ctypes.WinDLL('kernel32.dll', use_last_error=True)
28         with_load_library_flags = hasattr(kernel32, 'AddDllDirectory')
29         prev_error_mode = kernel32.SetErrorMode(0x0001)
30 
31         kernel32.LoadLibraryW.restype = ctypes.c_void_p
32         if with_load_library_flags:
33             kernel32.LoadLibraryExW.restype = ctypes.c_void_p
34 
35         if ext_specs is not None:
36             res = kernel32.LoadLibraryExW(ext_specs.origin, None, 0x00001100)
37             if res is None:
38                 err = ctypes.WinError(ctypes.get_last_error())
39                 err.strerror += (f' Error loading "{ext_specs.origin}" or any or '
40                                  'its dependencies.')
41                 raise err
42 
43         kernel32.SetErrorMode(prev_error_mode)
44 
45     if ext_specs is not None:
46         torch.ops.load_library(ext_specs.origin)
47         _HAS_IMAGE_OPT = True
48 except (ImportError, OSError):
49     pass
50 
51 
52 class ImageReadMode(Enum):
53     UNCHANGED = 0
54     GRAY = 1
55     GRAY_ALPHA = 2
56     RGB = 3
57     RGB_ALPHA = 4
58 
59 
60 def read_file(path: str) -> torch.Tensor:
61     """
62     Reads and outputs the bytes contents of a file as a uint8 Tensor
63     with one dimension.
64 
65     Arguments:
66         path (str): the path to the file to be read
67 
68     Returns:
69         data (Tensor)
70     """
71     data = torch.ops.image.read_file(path)
72     return data
73 
74 
75 def write_file(filename: str, data: torch.Tensor) -> None:
76     """
77     Writes the contents of a uint8 tensor with one dimension to a
78     file.
79 
80     Arguments:
81         filename (str): the path to the file to be written
82         data (Tensor): the contents to be written to the output file
83     """
84     torch.ops.image.write_file(filename, data)
85 
86 
87 def decode_png(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:
88     """
89     Decodes a PNG image into a 3 dimensional RGB Tensor.
90     Optionally converts the image to the desired format.
91     The values of the output tensor are uint8 between 0 and 255.
92 
93     Arguments:
94         input (Tensor[1]): a one dimensional uint8 tensor containing
95     the raw bytes of the PNG image.
96         mode (ImageReadMode): the read mode used for optionally
97     converting the image. Use `ImageReadMode.UNCHANGED` for loading
98     the image as-is, `ImageReadMode.GRAY` for converting to grayscale,
99     `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,
100     `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for
101      RGB with transparency. Default: `ImageReadMode.UNCHANGED`
102 
103     Returns:
104         output (Tensor[image_channels, image_height, image_width])
105     """
106     output = torch.ops.image.decode_png(input, mode.value)
107     return output
108 
109 
110 def encode_png(input: torch.Tensor, compression_level: int = 6) -> torch.Tensor:
111     """
112     Takes an input tensor in CHW layout and returns a buffer with the contents
113     of its corresponding PNG file.
114 
115     Parameters
116     ----------
117     input: Tensor[channels, image_height, image_width]
118         int8 image tensor of `c` channels, where `c` must 3 or 1.
119     compression_level: int
120         Compression factor for the resulting file, it must be a number
121         between 0 and 9. Default: 6
122 
123     Returns
124     -------
125     output: Tensor[1]
126         A one dimensional int8 tensor that contains the raw bytes of the
127         PNG file.
128     """
129     output = torch.ops.image.encode_png(input, compression_level)
130     return output
131 
132 
133 def write_png(input: torch.Tensor, filename: str, compression_level: int = 6):
134     """
135     Takes an input tensor in CHW layout (or HW in the case of grayscale images)
136     and saves it in a PNG file.
137 
138     Parameters
139     ----------
140     input: Tensor[channels, image_height, image_width]
141         int8 image tensor of `c` channels, where `c` must be 1 or 3.
142     filename: str
143         Path to save the image.
144     compression_level: int
145         Compression factor for the resulting file, it must be a number
146         between 0 and 9. Default: 6
147     """
148     output = encode_png(input, compression_level)
149     write_file(filename, output)
150 
151 
152 def decode_jpeg(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:
153     """
154     Decodes a JPEG image into a 3 dimensional RGB Tensor.
155     Optionally converts the image to the desired format.
156     The values of the output tensor are uint8 between 0 and 255.
157 
158     Arguments:
159         input (Tensor[1]): a one dimensional uint8 tensor containing
160     the raw bytes of the JPEG image.
161         mode (ImageReadMode): the read mode used for optionally
162     converting the image. Use `ImageReadMode.UNCHANGED` for loading
163     the image as-is, `ImageReadMode.GRAY` for converting to grayscale
164     and `ImageReadMode.RGB` for RGB. Default: `ImageReadMode.UNCHANGED`
165 
166     Returns:
167         output (Tensor[image_channels, image_height, image_width])
168     """
169     output = torch.ops.image.decode_jpeg(input, mode.value)
170     return output
171 
172 
173 def encode_jpeg(input: torch.Tensor, quality: int = 75) -> torch.Tensor:
174     """
175     Takes an input tensor in CHW layout and returns a buffer with the contents
176     of its corresponding JPEG file.
177 
178     Parameters
179     ----------
180     input: Tensor[channels, image_height, image_width])
181         int8 image tensor of `c` channels, where `c` must be 1 or 3.
182     quality: int
183         Quality of the resulting JPEG file, it must be a number between
184         1 and 100. Default: 75
185 
186     Returns
187     -------
188     output: Tensor[1]
189         A one dimensional int8 tensor that contains the raw bytes of the
190         JPEG file.
191     """
192     if quality < 1 or quality > 100:
193         raise ValueError('Image quality should be a positive number '
194                          'between 1 and 100')
195 
196     output = torch.ops.image.encode_jpeg(input, quality)
197     return output
198 
199 
200 def write_jpeg(input: torch.Tensor, filename: str, quality: int = 75):
201     """
202     Takes an input tensor in CHW layout and saves it in a JPEG file.
203 
204     Parameters
205     ----------
206     input: Tensor[channels, image_height, image_width]
207         int8 image tensor of `c` channels, where `c` must be 1 or 3.
208     filename: str
209         Path to save the image.
210     quality: int
211         Quality of the resulting JPEG file, it must be a number
212         between 1 and 100. Default: 75
213     """
214     output = encode_jpeg(input, quality)
215     write_file(filename, output)
216 
217 
218 def decode_image(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:
219     """
220     Detects whether an image is a JPEG or PNG and performs the appropriate
221     operation to decode the image into a 3 dimensional RGB Tensor.
222 
223     Optionally converts the image to the desired format.
224     The values of the output tensor are uint8 between 0 and 255.
225 
226     Parameters
227     ----------
228     input: Tensor
229         a one dimensional uint8 tensor containing the raw bytes of the
230         PNG or JPEG image.
231     mode: ImageReadMode
232         the read mode used for optionally converting the image. JPEG
233         and PNG images have different permitted values. The default
234         value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.
235         See `decode_jpeg()` and `decode_png()` for more information.
236         Default: `ImageReadMode.UNCHANGED`
237 
238     Returns
239     -------
240     output: Tensor[image_channels, image_height, image_width]
241     """
242     output = torch.ops.image.decode_image(input, mode.value)
243     return output
244 
245 
246 def read_image(path: str, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:
247     """
248     Reads a JPEG or PNG image into a 3 dimensional RGB Tensor.
249     Optionally converts the image to the desired format.
250     The values of the output tensor are uint8 between 0 and 255.
251 
252     Parameters
253     ----------
254     path: str
255         path of the JPEG or PNG image.
256     mode: ImageReadMode
257         the read mode used for optionally converting the image. JPEG
258         and PNG images have different permitted values. The default
259         value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.
260         See `decode_jpeg()` and `decode_png()` for more information.
261         Default: `ImageReadMode.UNCHANGED`
262 
263     Returns
264     -------
265     output: Tensor[image_channels, image_height, image_width]
266     """
267     data = read_file(path)
268     return decode_image(data, mode)
269
```
--- 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()

```

diff --git a/torchvision/io/image.py b/torchvision/io/image.py
--- a/torchvision/io/image.py
+++ b/torchvision/io/image.py
@@ -50,6 +50,15 @@
 
 
 class ImageReadMode(Enum):
+    """
+    Support for various modes while reading images.
+
+    Use `ImageReadMode.UNCHANGED` for loading the image as-is,
+    `ImageReadMode.GRAY` for converting to grayscale,
+    `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,
+    `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for
+    RGB with transparency.
+    """
     UNCHANGED = 0
     GRAY = 1
     GRAY_ALPHA = 2
@@ -94,11 +103,9 @@
         input (Tensor[1]): a one dimensional uint8 tensor containing
     the raw bytes of the PNG image.
         mode (ImageReadMode): the read mode used for optionally
-    converting the image. Use `ImageReadMode.UNCHANGED` for loading
-    the image as-is, `ImageReadMode.GRAY` for converting to grayscale,
-    `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,
-    `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for
-     RGB with transparency. Default: `ImageReadMode.UNCHANGED`
+    converting the image. Default: `ImageReadMode.UNCHANGED`.
+    See `ImageReadMode` class for more information on various
+    available modes.
 
     Returns:
         output (Tensor[image_channels, image_height, image_width])
@@ -159,9 +166,9 @@
         input (Tensor[1]): a one dimensional uint8 tensor containing
     the raw bytes of the JPEG image.
         mode (ImageReadMode): the read mode used for optionally
-    converting the image. Use `ImageReadMode.UNCHANGED` for loading
-    the image as-is, `ImageReadMode.GRAY` for converting to grayscale
-    and `ImageReadMode.RGB` for RGB. Default: `ImageReadMode.UNCHANGED`
+    converting the image. Default: `ImageReadMode.UNCHANGED`.
+    See `ImageReadMode` class for more information on various
+    available modes.
 
     Returns:
         output (Tensor[image_channels, image_height, image_width])
@@ -229,11 +236,10 @@
         a one dimensional uint8 tensor containing the raw bytes of the
         PNG or JPEG image.
     mode: ImageReadMode
-        the read mode used for optionally converting the image. JPEG
-        and PNG images have different permitted values. The default
-        value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.
-        See `decode_jpeg()` and `decode_png()` for more information.
-        Default: `ImageReadMode.UNCHANGED`
+        the read mode used for optionally converting the image.
+        Default: `ImageReadMode.UNCHANGED`.
+        See `ImageReadMode` class for more information on various
+        available modes.
 
     Returns
     -------
@@ -254,11 +260,10 @@
     path: str
         path of the JPEG or PNG image.
     mode: ImageReadMode
-        the read mode used for optionally converting the image. JPEG
-        and PNG images have different permitted values. The default
-        value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.
-        See `decode_jpeg()` and `decode_png()` for more information.
-        Default: `ImageReadMode.UNCHANGED`
+        the read mode used for optionally converting the image.
+        Default: `ImageReadMode.UNCHANGED`.
+        See `ImageReadMode` class for more information on various
+        available modes.
 
     Returns
     -------

{"golden_diff": "diff --git a/torchvision/io/image.py b/torchvision/io/image.py\n--- a/torchvision/io/image.py\n+++ b/torchvision/io/image.py\n@@ -50,6 +50,15 @@\n \n \n class ImageReadMode(Enum):\n+    \"\"\"\n+    Support for various modes while reading images.\n+\n+    Use `ImageReadMode.UNCHANGED` for loading the image as-is,\n+    `ImageReadMode.GRAY` for converting to grayscale,\n+    `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,\n+    `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for\n+    RGB with transparency.\n+    \"\"\"\n     UNCHANGED = 0\n     GRAY = 1\n     GRAY_ALPHA = 2\n@@ -94,11 +103,9 @@\n         input (Tensor[1]): a one dimensional uint8 tensor containing\n     the raw bytes of the PNG image.\n         mode (ImageReadMode): the read mode used for optionally\n-    converting the image. Use `ImageReadMode.UNCHANGED` for loading\n-    the image as-is, `ImageReadMode.GRAY` for converting to grayscale,\n-    `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,\n-    `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for\n-     RGB with transparency. Default: `ImageReadMode.UNCHANGED`\n+    converting the image. Default: `ImageReadMode.UNCHANGED`.\n+    See `ImageReadMode` class for more information on various\n+    available modes.\n \n     Returns:\n         output (Tensor[image_channels, image_height, image_width])\n@@ -159,9 +166,9 @@\n         input (Tensor[1]): a one dimensional uint8 tensor containing\n     the raw bytes of the JPEG image.\n         mode (ImageReadMode): the read mode used for optionally\n-    converting the image. Use `ImageReadMode.UNCHANGED` for loading\n-    the image as-is, `ImageReadMode.GRAY` for converting to grayscale\n-    and `ImageReadMode.RGB` for RGB. Default: `ImageReadMode.UNCHANGED`\n+    converting the image. Default: `ImageReadMode.UNCHANGED`.\n+    See `ImageReadMode` class for more information on various\n+    available modes.\n \n     Returns:\n         output (Tensor[image_channels, image_height, image_width])\n@@ -229,11 +236,10 @@\n         a one dimensional uint8 tensor containing the raw bytes of the\n         PNG or JPEG image.\n     mode: ImageReadMode\n-        the read mode used for optionally converting the image. JPEG\n-        and PNG images have different permitted values. The default\n-        value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.\n-        See `decode_jpeg()` and `decode_png()` for more information.\n-        Default: `ImageReadMode.UNCHANGED`\n+        the read mode used for optionally converting the image.\n+        Default: `ImageReadMode.UNCHANGED`.\n+        See `ImageReadMode` class for more information on various\n+        available modes.\n \n     Returns\n     -------\n@@ -254,11 +260,10 @@\n     path: str\n         path of the JPEG or PNG image.\n     mode: ImageReadMode\n-        the read mode used for optionally converting the image. JPEG\n-        and PNG images have different permitted values. The default\n-        value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.\n-        See `decode_jpeg()` and `decode_png()` for more information.\n-        Default: `ImageReadMode.UNCHANGED`\n+        the read mode used for optionally converting the image.\n+        Default: `ImageReadMode.UNCHANGED`.\n+        See `ImageReadMode` class for more information on various\n+        available modes.\n \n     Returns\n     -------\n", "issue": "Clean up and Document the io.image enhancements\nPR #3024 introduced a few enhancements on the `io.image` methods used for reading JPEG and PNG images. The code changes were merged but there are a few nice-to-have improvements missing.\r\n\r\nMore specifically:\r\n- [x] Provide better error messages for [JPEG](https://github.com/pytorch/vision/pull/3024#discussion_r527066925) and [PNG](https://github.com/pytorch/vision/pull/3024#discussion_r527093866) when a specific `ImageReadMode` value is not supported.\r\n- [x] Ensure that `image_read_mode.h` has a new line at the [end of the file](https://github.com/pytorch/vision/pull/3024#discussion_r526710809).\r\n- [x] [Replace](https://github.com/pytorch/vision/pull/3024#discussion_r527065253) the old `#define` with the newer `constexpr` expression at `image_read_mode.h`.\r\n- [x] [Move the documentation](https://github.com/pytorch/vision/pull/3024#discussion_r527095264) of `ImageReadMode` values from the methods to the enum.\r\n\r\n**Note:** `constexpr` might cause problems on Windows. If that's the case, try using const instead.\n", "before_files": [{"content": "import torch\n\nimport os\nimport os.path as osp\nimport importlib.machinery\n\nfrom enum import Enum\n\n_HAS_IMAGE_OPT = False\n\ntry:\n    lib_dir = osp.abspath(osp.join(osp.dirname(__file__), \"..\"))\n\n    loader_details = (\n        importlib.machinery.ExtensionFileLoader,\n        importlib.machinery.EXTENSION_SUFFIXES\n    )\n\n    extfinder = importlib.machinery.FileFinder(lib_dir, loader_details)  # type: ignore[arg-type]\n    ext_specs = extfinder.find_spec(\"image\")\n\n    if os.name == 'nt':\n        # Load the image extension using LoadLibraryExW\n        import ctypes\n        import sys\n\n        kernel32 = ctypes.WinDLL('kernel32.dll', use_last_error=True)\n        with_load_library_flags = hasattr(kernel32, 'AddDllDirectory')\n        prev_error_mode = kernel32.SetErrorMode(0x0001)\n\n        kernel32.LoadLibraryW.restype = ctypes.c_void_p\n        if with_load_library_flags:\n            kernel32.LoadLibraryExW.restype = ctypes.c_void_p\n\n        if ext_specs is not None:\n            res = kernel32.LoadLibraryExW(ext_specs.origin, None, 0x00001100)\n            if res is None:\n                err = ctypes.WinError(ctypes.get_last_error())\n                err.strerror += (f' Error loading \"{ext_specs.origin}\" or any or '\n                                 'its dependencies.')\n                raise err\n\n        kernel32.SetErrorMode(prev_error_mode)\n\n    if ext_specs is not None:\n        torch.ops.load_library(ext_specs.origin)\n        _HAS_IMAGE_OPT = True\nexcept (ImportError, OSError):\n    pass\n\n\nclass ImageReadMode(Enum):\n    UNCHANGED = 0\n    GRAY = 1\n    GRAY_ALPHA = 2\n    RGB = 3\n    RGB_ALPHA = 4\n\n\ndef read_file(path: str) -> torch.Tensor:\n    \"\"\"\n    Reads and outputs the bytes contents of a file as a uint8 Tensor\n    with one dimension.\n\n    Arguments:\n        path (str): the path to the file to be read\n\n    Returns:\n        data (Tensor)\n    \"\"\"\n    data = torch.ops.image.read_file(path)\n    return data\n\n\ndef write_file(filename: str, data: torch.Tensor) -> None:\n    \"\"\"\n    Writes the contents of a uint8 tensor with one dimension to a\n    file.\n\n    Arguments:\n        filename (str): the path to the file to be written\n        data (Tensor): the contents to be written to the output file\n    \"\"\"\n    torch.ops.image.write_file(filename, data)\n\n\ndef decode_png(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Decodes a PNG image into a 3 dimensional RGB Tensor.\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Arguments:\n        input (Tensor[1]): a one dimensional uint8 tensor containing\n    the raw bytes of the PNG image.\n        mode (ImageReadMode): the read mode used for optionally\n    converting the image. Use `ImageReadMode.UNCHANGED` for loading\n    the image as-is, `ImageReadMode.GRAY` for converting to grayscale,\n    `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,\n    `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for\n     RGB with transparency. Default: `ImageReadMode.UNCHANGED`\n\n    Returns:\n        output (Tensor[image_channels, image_height, image_width])\n    \"\"\"\n    output = torch.ops.image.decode_png(input, mode.value)\n    return output\n\n\ndef encode_png(input: torch.Tensor, compression_level: int = 6) -> torch.Tensor:\n    \"\"\"\n    Takes an input tensor in CHW layout and returns a buffer with the contents\n    of its corresponding PNG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width]\n        int8 image tensor of `c` channels, where `c` must 3 or 1.\n    compression_level: int\n        Compression factor for the resulting file, it must be a number\n        between 0 and 9. Default: 6\n\n    Returns\n    -------\n    output: Tensor[1]\n        A one dimensional int8 tensor that contains the raw bytes of the\n        PNG file.\n    \"\"\"\n    output = torch.ops.image.encode_png(input, compression_level)\n    return output\n\n\ndef write_png(input: torch.Tensor, filename: str, compression_level: int = 6):\n    \"\"\"\n    Takes an input tensor in CHW layout (or HW in the case of grayscale images)\n    and saves it in a PNG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width]\n        int8 image tensor of `c` channels, where `c` must be 1 or 3.\n    filename: str\n        Path to save the image.\n    compression_level: int\n        Compression factor for the resulting file, it must be a number\n        between 0 and 9. Default: 6\n    \"\"\"\n    output = encode_png(input, compression_level)\n    write_file(filename, output)\n\n\ndef decode_jpeg(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Decodes a JPEG image into a 3 dimensional RGB Tensor.\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Arguments:\n        input (Tensor[1]): a one dimensional uint8 tensor containing\n    the raw bytes of the JPEG image.\n        mode (ImageReadMode): the read mode used for optionally\n    converting the image. Use `ImageReadMode.UNCHANGED` for loading\n    the image as-is, `ImageReadMode.GRAY` for converting to grayscale\n    and `ImageReadMode.RGB` for RGB. Default: `ImageReadMode.UNCHANGED`\n\n    Returns:\n        output (Tensor[image_channels, image_height, image_width])\n    \"\"\"\n    output = torch.ops.image.decode_jpeg(input, mode.value)\n    return output\n\n\ndef encode_jpeg(input: torch.Tensor, quality: int = 75) -> torch.Tensor:\n    \"\"\"\n    Takes an input tensor in CHW layout and returns a buffer with the contents\n    of its corresponding JPEG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width])\n        int8 image tensor of `c` channels, where `c` must be 1 or 3.\n    quality: int\n        Quality of the resulting JPEG file, it must be a number between\n        1 and 100. Default: 75\n\n    Returns\n    -------\n    output: Tensor[1]\n        A one dimensional int8 tensor that contains the raw bytes of the\n        JPEG file.\n    \"\"\"\n    if quality < 1 or quality > 100:\n        raise ValueError('Image quality should be a positive number '\n                         'between 1 and 100')\n\n    output = torch.ops.image.encode_jpeg(input, quality)\n    return output\n\n\ndef write_jpeg(input: torch.Tensor, filename: str, quality: int = 75):\n    \"\"\"\n    Takes an input tensor in CHW layout and saves it in a JPEG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width]\n        int8 image tensor of `c` channels, where `c` must be 1 or 3.\n    filename: str\n        Path to save the image.\n    quality: int\n        Quality of the resulting JPEG file, it must be a number\n        between 1 and 100. Default: 75\n    \"\"\"\n    output = encode_jpeg(input, quality)\n    write_file(filename, output)\n\n\ndef decode_image(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Detects whether an image is a JPEG or PNG and performs the appropriate\n    operation to decode the image into a 3 dimensional RGB Tensor.\n\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Parameters\n    ----------\n    input: Tensor\n        a one dimensional uint8 tensor containing the raw bytes of the\n        PNG or JPEG image.\n    mode: ImageReadMode\n        the read mode used for optionally converting the image. JPEG\n        and PNG images have different permitted values. The default\n        value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.\n        See `decode_jpeg()` and `decode_png()` for more information.\n        Default: `ImageReadMode.UNCHANGED`\n\n    Returns\n    -------\n    output: Tensor[image_channels, image_height, image_width]\n    \"\"\"\n    output = torch.ops.image.decode_image(input, mode.value)\n    return output\n\n\ndef read_image(path: str, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Reads a JPEG or PNG image into a 3 dimensional RGB Tensor.\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Parameters\n    ----------\n    path: str\n        path of the JPEG or PNG image.\n    mode: ImageReadMode\n        the read mode used for optionally converting the image. JPEG\n        and PNG images have different permitted values. The default\n        value is `ImageReadMode.UNCHANGED` and it keeps the image as-is.\n        See `decode_jpeg()` and `decode_png()` for more information.\n        Default: `ImageReadMode.UNCHANGED`\n\n    Returns\n    -------\n    output: Tensor[image_channels, image_height, image_width]\n    \"\"\"\n    data = read_file(path)\n    return decode_image(data, mode)\n", "path": "torchvision/io/image.py"}], "after_files": [{"content": "import torch\n\nimport os\nimport os.path as osp\nimport importlib.machinery\n\nfrom enum import Enum\n\n_HAS_IMAGE_OPT = False\n\ntry:\n    lib_dir = osp.abspath(osp.join(osp.dirname(__file__), \"..\"))\n\n    loader_details = (\n        importlib.machinery.ExtensionFileLoader,\n        importlib.machinery.EXTENSION_SUFFIXES\n    )\n\n    extfinder = importlib.machinery.FileFinder(lib_dir, loader_details)  # type: ignore[arg-type]\n    ext_specs = extfinder.find_spec(\"image\")\n\n    if os.name == 'nt':\n        # Load the image extension using LoadLibraryExW\n        import ctypes\n        import sys\n\n        kernel32 = ctypes.WinDLL('kernel32.dll', use_last_error=True)\n        with_load_library_flags = hasattr(kernel32, 'AddDllDirectory')\n        prev_error_mode = kernel32.SetErrorMode(0x0001)\n\n        kernel32.LoadLibraryW.restype = ctypes.c_void_p\n        if with_load_library_flags:\n            kernel32.LoadLibraryExW.restype = ctypes.c_void_p\n\n        if ext_specs is not None:\n            res = kernel32.LoadLibraryExW(ext_specs.origin, None, 0x00001100)\n            if res is None:\n                err = ctypes.WinError(ctypes.get_last_error())\n                err.strerror += (f' Error loading \"{ext_specs.origin}\" or any or '\n                                 'its dependencies.')\n                raise err\n\n        kernel32.SetErrorMode(prev_error_mode)\n\n    if ext_specs is not None:\n        torch.ops.load_library(ext_specs.origin)\n        _HAS_IMAGE_OPT = True\nexcept (ImportError, OSError):\n    pass\n\n\nclass ImageReadMode(Enum):\n    \"\"\"\n    Support for various modes while reading images.\n\n    Use `ImageReadMode.UNCHANGED` for loading the image as-is,\n    `ImageReadMode.GRAY` for converting to grayscale,\n    `ImageReadMode.GRAY_ALPHA` for grayscale with transparency,\n    `ImageReadMode.RGB` for RGB and `ImageReadMode.RGB_ALPHA` for\n    RGB with transparency.\n    \"\"\"\n    UNCHANGED = 0\n    GRAY = 1\n    GRAY_ALPHA = 2\n    RGB = 3\n    RGB_ALPHA = 4\n\n\ndef read_file(path: str) -> torch.Tensor:\n    \"\"\"\n    Reads and outputs the bytes contents of a file as a uint8 Tensor\n    with one dimension.\n\n    Arguments:\n        path (str): the path to the file to be read\n\n    Returns:\n        data (Tensor)\n    \"\"\"\n    data = torch.ops.image.read_file(path)\n    return data\n\n\ndef write_file(filename: str, data: torch.Tensor) -> None:\n    \"\"\"\n    Writes the contents of a uint8 tensor with one dimension to a\n    file.\n\n    Arguments:\n        filename (str): the path to the file to be written\n        data (Tensor): the contents to be written to the output file\n    \"\"\"\n    torch.ops.image.write_file(filename, data)\n\n\ndef decode_png(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Decodes a PNG image into a 3 dimensional RGB Tensor.\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Arguments:\n        input (Tensor[1]): a one dimensional uint8 tensor containing\n    the raw bytes of the PNG image.\n        mode (ImageReadMode): the read mode used for optionally\n    converting the image. Default: `ImageReadMode.UNCHANGED`.\n    See `ImageReadMode` class for more information on various\n    available modes.\n\n    Returns:\n        output (Tensor[image_channels, image_height, image_width])\n    \"\"\"\n    output = torch.ops.image.decode_png(input, mode.value)\n    return output\n\n\ndef encode_png(input: torch.Tensor, compression_level: int = 6) -> torch.Tensor:\n    \"\"\"\n    Takes an input tensor in CHW layout and returns a buffer with the contents\n    of its corresponding PNG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width]\n        int8 image tensor of `c` channels, where `c` must 3 or 1.\n    compression_level: int\n        Compression factor for the resulting file, it must be a number\n        between 0 and 9. Default: 6\n\n    Returns\n    -------\n    output: Tensor[1]\n        A one dimensional int8 tensor that contains the raw bytes of the\n        PNG file.\n    \"\"\"\n    output = torch.ops.image.encode_png(input, compression_level)\n    return output\n\n\ndef write_png(input: torch.Tensor, filename: str, compression_level: int = 6):\n    \"\"\"\n    Takes an input tensor in CHW layout (or HW in the case of grayscale images)\n    and saves it in a PNG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width]\n        int8 image tensor of `c` channels, where `c` must be 1 or 3.\n    filename: str\n        Path to save the image.\n    compression_level: int\n        Compression factor for the resulting file, it must be a number\n        between 0 and 9. Default: 6\n    \"\"\"\n    output = encode_png(input, compression_level)\n    write_file(filename, output)\n\n\ndef decode_jpeg(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Decodes a JPEG image into a 3 dimensional RGB Tensor.\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Arguments:\n        input (Tensor[1]): a one dimensional uint8 tensor containing\n    the raw bytes of the JPEG image.\n        mode (ImageReadMode): the read mode used for optionally\n    converting the image. Default: `ImageReadMode.UNCHANGED`.\n    See `ImageReadMode` class for more information on various\n    available modes.\n\n    Returns:\n        output (Tensor[image_channels, image_height, image_width])\n    \"\"\"\n    output = torch.ops.image.decode_jpeg(input, mode.value)\n    return output\n\n\ndef encode_jpeg(input: torch.Tensor, quality: int = 75) -> torch.Tensor:\n    \"\"\"\n    Takes an input tensor in CHW layout and returns a buffer with the contents\n    of its corresponding JPEG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width])\n        int8 image tensor of `c` channels, where `c` must be 1 or 3.\n    quality: int\n        Quality of the resulting JPEG file, it must be a number between\n        1 and 100. Default: 75\n\n    Returns\n    -------\n    output: Tensor[1]\n        A one dimensional int8 tensor that contains the raw bytes of the\n        JPEG file.\n    \"\"\"\n    if quality < 1 or quality > 100:\n        raise ValueError('Image quality should be a positive number '\n                         'between 1 and 100')\n\n    output = torch.ops.image.encode_jpeg(input, quality)\n    return output\n\n\ndef write_jpeg(input: torch.Tensor, filename: str, quality: int = 75):\n    \"\"\"\n    Takes an input tensor in CHW layout and saves it in a JPEG file.\n\n    Parameters\n    ----------\n    input: Tensor[channels, image_height, image_width]\n        int8 image tensor of `c` channels, where `c` must be 1 or 3.\n    filename: str\n        Path to save the image.\n    quality: int\n        Quality of the resulting JPEG file, it must be a number\n        between 1 and 100. Default: 75\n    \"\"\"\n    output = encode_jpeg(input, quality)\n    write_file(filename, output)\n\n\ndef decode_image(input: torch.Tensor, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Detects whether an image is a JPEG or PNG and performs the appropriate\n    operation to decode the image into a 3 dimensional RGB Tensor.\n\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Parameters\n    ----------\n    input: Tensor\n        a one dimensional uint8 tensor containing the raw bytes of the\n        PNG or JPEG image.\n    mode: ImageReadMode\n        the read mode used for optionally converting the image.\n        Default: `ImageReadMode.UNCHANGED`.\n        See `ImageReadMode` class for more information on various\n        available modes.\n\n    Returns\n    -------\n    output: Tensor[image_channels, image_height, image_width]\n    \"\"\"\n    output = torch.ops.image.decode_image(input, mode.value)\n    return output\n\n\ndef read_image(path: str, mode: ImageReadMode = ImageReadMode.UNCHANGED) -> torch.Tensor:\n    \"\"\"\n    Reads a JPEG or PNG image into a 3 dimensional RGB Tensor.\n    Optionally converts the image to the desired format.\n    The values of the output tensor are uint8 between 0 and 255.\n\n    Parameters\n    ----------\n    path: str\n        path of the JPEG or PNG image.\n    mode: ImageReadMode\n        the read mode used for optionally converting the image.\n        Default: `ImageReadMode.UNCHANGED`.\n        See `ImageReadMode` class for more information on various\n        available modes.\n\n    Returns\n    -------\n    output: Tensor[image_channels, image_height, image_width]\n    \"\"\"\n    data = read_file(path)\n    return decode_image(data, mode)\n", "path": "torchvision/io/image.py"}]}