-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Pure Python Decoder objects #1938
Conversation
Looking at merging this soon after 3.3 |
Don't forget to rebase. |
yeah. and docs. |
544267b
to
32c3fcd
Compare
I'm going to assume since rebasing and documentation are still needed that this one will have to wait for 3.5. |
Yeah, the case study got converted to C. So, either we ship it as an example, but with no actual use case, or ... I'm not sure. I'd like to have a set of example code in here somewhere. |
f76c966
to
fb383de
Compare
Now includes #2384, and a re-implementation of the Msp Decoder in python. |
PIL/Image.py
Outdated
:param encoder: A callable(mode, args) that returns an | ||
ImageFile.PyEncoder object | ||
|
||
.. versionadded:: 3.3.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bump
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About docs/example/DdsImagePlugin.py
Is it the same as the one in PIL? Can we instead refer to the live file? A copy in docs will be unmaintained and may at some point stop working or be a misleading example.
def register_decoder(name, decoder): | ||
""" | ||
Registers an image decoder. This function should not be | ||
used in application code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this function shouldn't be used in application code, should it begin with an underscore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scroll up. This is the same as register_extension/save/open/mime/foo. It's not for application code, it's for plugin developers.
def register_encoder(name, encoder): | ||
""" | ||
Registers an image encoder. This function should not be | ||
used in application code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this function shouldn't be used in application code, should it begin with an underscore?
@@ -433,6 +440,11 @@ def _getencoder(mode, encoder_name, args, extra=()): | |||
args = (args,) | |||
|
|||
try: | |||
encoder = ENCODERS[encoder_name] | |||
return encoder(mode, *args + extra) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line isn't covered by tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we don't have a pure python encoder yet.
|
||
.. versionadded:: 4.1.0 | ||
""" | ||
ENCODERS[name] = encoder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line isn't covered by tests.
PIL/ImageFile.py
Outdated
|
||
@property | ||
def handles_eof(self): | ||
return self._handles_eof |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line isn't covered by tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That property was removed in 4.0 anyway
Tests/test_file_msp.py
Outdated
@@ -1,8 +1,12 @@ | |||
from helper import unittest, PillowTestCase, hopper | |||
|
|||
from PIL import Image, MspImagePlugin | |||
from PIL import Image, ImageFile, MspImagePlugin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ImageFile
imported but unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. You imported it to get the LOAD_TRUNCATED_IMAGES variable.
@@ -1,6 +1,5 @@ | |||
# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file contains tabs and spaces. Let's remove tabs.
attributes. To be able to load the file, the method must also create a list of | ||
:py:attr:`tile` descriptors. The class must be explicitly registered, via a | ||
call to the :py:mod:`~PIL.Image` module. | ||
A image plug-in should contain a format handler derived from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> "An image"
:py:attr:`~PIL.Image.Image.size` attributes. To be able to load the | ||
file, the method must also create a list of :py:attr:`tile` | ||
descriptors, which contain a decoder name, extents of the tile, and | ||
any decoder specific data. The format handler class must be explicitly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> "decoder-specific data"
decode method. File decoders should be registered using | ||
:py:meth:`PIL.Image.register_decoder`. As in the C implementation of | ||
the file decoders, there are three stages in the lifetime of a Python | ||
based file decoder: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> "Python-based"
dc976ea
to
d70de6e
Compare
d93f01a
to
184d4f8
Compare
Ok, I think this is tested as much as I can get. |
File format decoders are currently complicated to put together.
load
phase is stuffed into theopen
phase. This breaks the convention of open being a relatively quick operation and by deferring the heavy work to the load phase. As an added bonus, parsing errors here will no longer lead to "cannot identify image file" errors.This pr builds on the Python fd changes from #1934, but the underlying concept doesn't need to rely on that. It's still likely that the interface chosen there will change, requiring changes here.
Changes proposed in this pull request:
Image.register_decoder
andImage.register_encoder
to map decoder name -> a callable that returns a de/encoder.ImageFile.PyDecoder
class that implements the interface used by the C layer decoder object. (Undone, an encoder object)