diff --git a/HISTORY.rst b/HISTORY.rst index 69bba4161..d04cfefae 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,14 @@ Release History --------------- +Unreleased +++++++++++ + +* **Fixed** – Issues #1497 / #1494: adding an image whose header reports + `dpi = 0` now falls back to `72 dpi` instead of raising + `ZeroDivisionError` when using `Document.add_picture()`. + + 1.2.0 (2025-06-16) ++++++++++++++++++ diff --git a/src/docx/image/image.py b/src/docx/image/image.py index e5e7f8a13..c81e6e1b0 100644 --- a/src/docx/image/image.py +++ b/src/docx/image/image.py @@ -87,19 +87,27 @@ def px_height(self) -> int: @property def horz_dpi(self) -> int: - """Integer dots per inch for the width of this image. - - Defaults to 72 when not present in the file, as is often the case. """ - return self._image_header.horz_dpi + Horizontal DPI reported for this image. Returns the header value + unless it is `None` **or** `0`, in which case it defaults to + 72 dpi, matching Word's internal assumption. + """ + dpi = self._image_header.horz_dpi + if dpi in (None, 0): + return 72 + return dpi @property def vert_dpi(self) -> int: - """Integer dots per inch for the height of this image. - - Defaults to 72 when not present in the file, as is often the case. """ - return self._image_header.vert_dpi + Vertical DPI reported for this image. Returns the header value + unless it is `None` **or** `0`, in which case it defaults to + 72 dpi, matching Word's internal assumption. + """ + dpi = self._image_header.vert_dpi + if dpi in (None, 0): + return 72 + return dpi @property def width(self) -> Inches: @@ -219,16 +227,24 @@ def px_height(self): @property def horz_dpi(self): - """Integer dots per inch for the width of this image. - - Defaults to 72 when not present in the file, as is often the case. """ - return self._horz_dpi + Horizontal DPI reported for this image. Returns the header value + unless it is `None` **or** `0`, in which case it defaults to + 72 dpi, matching Word's internal assumption. + """ + dpi = self._horz_dpi + if dpi in (None, 0): + return 72 + return dpi @property def vert_dpi(self): - """Integer dots per inch for the height of this image. - - Defaults to 72 when not present in the file, as is often the case. """ - return self._vert_dpi + Vertical DPI reported for this image. Returns the header value + unless it is `None` **or** `0`, in which case it defaults to + 72 dpi, matching Word's internal assumption. + """ + dpi = self._vert_dpi + if dpi in (None, 0): + return 72 + return dpi diff --git a/tests/test_files/zero_dpi.jpg b/tests/test_files/zero_dpi.jpg new file mode 100644 index 000000000..6dab8de8c Binary files /dev/null and b/tests/test_files/zero_dpi.jpg differ diff --git a/tests/test_zero_dpi.py b/tests/test_zero_dpi.py new file mode 100644 index 000000000..303b8a044 --- /dev/null +++ b/tests/test_zero_dpi.py @@ -0,0 +1,17 @@ +"""Regression test for issues #1497 and #1494 – ZeroDivisionError when adding a +JPEG whose header reports 0 × 0 DPI. +""" + +from pathlib import Path + +from docx import Document + +FIX = Path(__file__).with_name("test_files") / "zero_dpi.jpg" + + +class DescribeZeroDensityJPEG: + """Suite covering `Document.add_picture()` with 0-DPI images.""" + + def it_handles_zero_dpi(self): + doc = Document() + doc.add_picture(str(FIX)) \ No newline at end of file