Skip to content

Commit 98f3f24

Browse files
author
Steve Canny
committed
img: add Jpeg formats to recognizer
Along the way: * move image_cls_that_can_parse(stream) import into the calling method to avoid circular import
1 parent a78fb40 commit 98f3f24

File tree

7 files changed

+38
-8
lines changed

7 files changed

+38
-8
lines changed

docx/image/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@
1919

2020
from docx.compat import BytesIO, is_string
2121
from docx.exceptions import UnrecognizedImageError
22+
from docx.image.jpeg import Exif, Jfif
2223
from docx.image.png import Png
2324
from docx.opc.constants import CONTENT_TYPE as CT
2425
from docx.shared import lazyproperty
2526

2627

2728
SIGNATURES = (
2829
# class, offset, signature_bytes
29-
(Png, 0, b'\x89PNG\x0D\x0A\x1A\x0A'),
30+
(Png, 0, b'\x89PNG\x0D\x0A\x1A\x0A'),
31+
(Jfif, 6, b'JFIF'),
32+
(Exif, 6, b'Exif'),
3033
)
3134

3235

docx/image/image.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@
55
size, as a required step in including them in a document.
66
"""
77

8-
from __future__ import (
9-
absolute_import, division, print_function, unicode_literals
10-
)
8+
from __future__ import absolute_import, division, print_function
119

1210
import os
1311

1412
from docx.compat import BytesIO, is_string
15-
from docx.image import image_cls_that_can_parse
1613

1714

1815
class Image(object):
@@ -45,5 +42,7 @@ def _from_stream(cls, stream, blob, filename=None):
4542
Return an instance of the |Image| subclass corresponding to the
4643
format of the image in *stream*.
4744
"""
45+
# import at execution time to avoid circular import
46+
from docx.image import image_cls_that_can_parse
4847
ImageSubclass = image_cls_that_can_parse(stream)
4948
return ImageSubclass(stream, blob, filename)

docx/image/jpeg.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# encoding: utf-8
2+
3+
from __future__ import absolute_import, division, print_function
4+
5+
from .image import Image
6+
7+
8+
class Jpeg(Image):
9+
"""
10+
Base class for JFIF and EXIF subclasses.
11+
"""
12+
13+
14+
class Exif(Jpeg):
15+
"""
16+
Image header parser for Exif image format
17+
"""
18+
19+
20+
class Jfif(Jpeg):
21+
"""
22+
Image header parser for JFIF image format
23+
"""

docx/image/png.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
from __future__ import absolute_import, division, print_function
44

5+
from .image import Image
56

6-
class Png(object):
7+
8+
class Png(Image):
79
"""
810
Image header parser for PNG images
911
"""

tests/image/test_image.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from docx.exceptions import UnrecognizedImageError
1313
from docx.image import image_cls_that_can_parse, Image_OLD
1414
from docx.image.image import Image
15+
from docx.image.jpeg import Exif, Jfif
1516
from docx.image.png import Png
1617
from docx.opc.constants import CONTENT_TYPE as CT
1718

@@ -36,7 +37,9 @@ def it_raises_on_unrecognized_image_stream(self):
3637
# fixtures -------------------------------------------------------
3738

3839
@pytest.fixture(params=[
39-
('python-icon.png', Png),
40+
('python-icon.png', Png),
41+
('python-icon.jpeg', Jfif),
42+
('exif-420-dpi.jpg', Exif),
4043
])
4144
def image_cls_lookup_fixture(self, request):
4245
image_filename, expected_class = request.param
@@ -130,7 +133,7 @@ def image_cls_(self, request, image_):
130133
@pytest.fixture
131134
def image_cls_that_can_parse_(self, request, image_cls_):
132135
return function_mock(
133-
request, 'docx.image.image.image_cls_that_can_parse',
136+
request, 'docx.image.image_cls_that_can_parse',
134137
return_value=image_cls_
135138
)
136139

tests/test_files/exif-420-dpi.jpg

751 KB
Loading

tests/test_files/jfif-iguana.jpg

7.77 KB
Loading

0 commit comments

Comments
 (0)