Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/core/files/images.py: 15%
50 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2Utility functions for handling images.
4Requires Pillow as you might imagine.
5"""
6import struct
7import zlib
9from django.core.files import File
12class ImageFile(File):
13 """
14 A mixin for use alongside django.core.files.base.File, which provides
15 additional features for dealing with images.
16 """
18 @property
19 def width(self):
20 return self._get_image_dimensions()[0]
22 @property
23 def height(self):
24 return self._get_image_dimensions()[1]
26 def _get_image_dimensions(self):
27 if not hasattr(self, "_dimensions_cache"):
28 close = self.closed
29 self.open()
30 self._dimensions_cache = get_image_dimensions(self, close=close)
31 return self._dimensions_cache
34def get_image_dimensions(file_or_path, close=False):
35 """
36 Return the (width, height) of an image, given an open file or a path. Set
37 'close' to True to close the file at the end if it is initially in an open
38 state.
39 """
40 from PIL import ImageFile as PillowImageFile
42 p = PillowImageFile.Parser()
43 if hasattr(file_or_path, "read"):
44 file = file_or_path
45 file_pos = file.tell()
46 file.seek(0)
47 else:
48 try:
49 file = open(file_or_path, "rb")
50 except OSError:
51 return (None, None)
52 close = True
53 try:
54 # Most of the time Pillow only needs a small chunk to parse the image
55 # and get the dimensions, but with some TIFF files Pillow needs to
56 # parse the whole file.
57 chunk_size = 1024
58 while 1:
59 data = file.read(chunk_size)
60 if not data:
61 break
62 try:
63 p.feed(data)
64 except zlib.error as e:
65 # ignore zlib complaining on truncated stream, just feed more
66 # data to parser (ticket #19457).
67 if e.args[0].startswith("Error -5"):
68 pass
69 else:
70 raise
71 except struct.error:
72 # Ignore PIL failing on a too short buffer when reads return
73 # less bytes than expected. Skip and feed more data to the
74 # parser (ticket #24544).
75 pass
76 except RuntimeError:
77 # e.g. "RuntimeError: could not create decoder object" for
78 # WebP files. A different chunk_size may work.
79 pass
80 if p.image:
81 return p.image.size
82 chunk_size *= 2
83 return (None, None)
84 finally:
85 if close:
86 file.close()
87 else:
88 file.seek(file_pos)