Skip to content

Commit 79efb67

Browse files
author
Steve Canny
committed
img: add _MarkerFactory()
1 parent 17610b0 commit 79efb67

File tree

2 files changed

+81
-3
lines changed

2 files changed

+81
-3
lines changed

docx/image/jpeg.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,27 @@ def _MarkerFactory(marker_code, stream, offset):
215215
Return |_Marker| or subclass instance appropriate for marker at *offset*
216216
in *stream* having *marker_code*.
217217
"""
218-
raise NotImplementedError
218+
if marker_code == JPEG_MARKER_CODE.APP0:
219+
return _App0Marker.from_stream(stream, marker_code, offset)
220+
elif marker_code in JPEG_MARKER_CODE.SOF_MARKER_CODES:
221+
return _SofMarker.from_stream(stream, marker_code, offset)
222+
else:
223+
return _Marker.from_stream(stream, marker_code, offset)
219224

220225

221226
class _Marker(object):
222227
"""
223228
Base class for JFIF marker classes. Represents a marker and its segment
224229
occuring in a JPEG byte stream.
225230
"""
231+
@classmethod
232+
def from_stream(cls, stream, marker_code, offset):
233+
"""
234+
Return a generic |_Marker| instance for the marker at *offset* in
235+
*stream* having *marker_code*.
236+
"""
237+
raise NotImplementedError
238+
226239
@property
227240
def marker_code(self):
228241
"""
@@ -243,9 +256,23 @@ class _App0Marker(_Marker):
243256
"""
244257
Represents a JFIF APP0 marker segment.
245258
"""
259+
@classmethod
260+
def from_stream(cls, stream, marker_code, offset):
261+
"""
262+
Return an |_App0Marker| instance for the APP0 marker at *offset* in
263+
*stream*.
264+
"""
265+
raise NotImplementedError
246266

247267

248268
class _SofMarker(_Marker):
249269
"""
250270
Represents a JFIF start of frame (SOFx) marker segment.
251271
"""
272+
@classmethod
273+
def from_stream(cls, stream, marker_code, offset):
274+
"""
275+
Return an |_SofMarker| instance for the SOFn marker at *offset* in
276+
stream.
277+
"""
278+
raise NotImplementedError

tests/image/test_jpeg.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
from docx.image.constants import JPEG_MARKER_CODE
1515
from docx.image.helpers import BIG_ENDIAN, StreamReader
1616
from docx.image.jpeg import (
17-
_App0Marker, Jfif, _JfifMarkers, _Marker, _MarkerFinder, _MarkerParser,
18-
_SofMarker
17+
_App0Marker, Jfif, _JfifMarkers, _Marker, _MarkerFactory, _MarkerFinder,
18+
_MarkerParser, _SofMarker
1919
)
2020

2121
from ..unitutil import class_mock, initializer_mock, instance_mock
@@ -151,6 +151,57 @@ def stream_(self, request):
151151
return instance_mock(request, BytesIO)
152152

153153

154+
class Describe_MarkerFactory(object):
155+
156+
def it_constructs_the_appropriate_marker_object(self, call_fixture):
157+
marker_code, stream_, offset_, marker_cls_ = call_fixture
158+
marker = _MarkerFactory(marker_code, stream_, offset_)
159+
marker_cls_.from_stream.assert_called_once_with(
160+
stream_, marker_code, offset_
161+
)
162+
assert marker is marker_cls_.from_stream.return_value
163+
164+
# fixtures -------------------------------------------------------
165+
166+
@pytest.fixture(params=[
167+
JPEG_MARKER_CODE.APP0,
168+
JPEG_MARKER_CODE.SOF0,
169+
JPEG_MARKER_CODE.SOF7,
170+
JPEG_MARKER_CODE.SOS,
171+
])
172+
def call_fixture(
173+
self, request, stream_, offset_, _App0Marker_, _SofMarker_,
174+
_Marker_):
175+
marker_code = request.param
176+
if marker_code == JPEG_MARKER_CODE.APP0:
177+
marker_cls_ = _App0Marker_
178+
elif marker_code in JPEG_MARKER_CODE.SOF_MARKER_CODES:
179+
marker_cls_ = _SofMarker_
180+
else:
181+
marker_cls_ = _Marker_
182+
return marker_code, stream_, offset_, marker_cls_
183+
184+
@pytest.fixture
185+
def _App0Marker_(self, request):
186+
return class_mock(request, 'docx.image.jpeg._App0Marker')
187+
188+
@pytest.fixture
189+
def _Marker_(self, request):
190+
return class_mock(request, 'docx.image.jpeg._Marker')
191+
192+
@pytest.fixture
193+
def offset_(self, request):
194+
return instance_mock(request, int)
195+
196+
@pytest.fixture
197+
def _SofMarker_(self, request):
198+
return class_mock(request, 'docx.image.jpeg._SofMarker')
199+
200+
@pytest.fixture
201+
def stream_(self, request):
202+
return instance_mock(request, BytesIO)
203+
204+
154205
class Describe_MarkerFinder(object):
155206

156207
def it_can_construct_from_a_stream(self, from_stream_fixture):

0 commit comments

Comments
 (0)