ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> image-sig
image-sig
[Image-SIG] PIL 1.1.6 ImageFile.Parser destroys data for PngImagePlugin
by Nils Olaf de Reus other posts by this author
Nov 4 2009 5:22AM messages near this date
[Image-SIG] Does PIL support PPM files with 32-bit MaxColor value? | Re: [Image-SIG] PIL 1.1.6 ImageFile.Parser destroys data for PngImagePlugin
I am experiencing inconvenience from the behaviour of ImageFile.py in
PIL 1.1.6 when attempting to read in a PNG image.

The method I see documented to retreive an image through ImageFile is by
invoking close() on the ImageFile.Parser, like this.

> >> import ImageFile
> >> import urllib
> >> 
> >> f = urllib.urlopen('<url-path-to-png-file>')
> >> 
> >> p = ImageFile.Parser()
> >> 
> >> while True:
...     s = f.read(1024)
...     if not s:
...         break
...     p.feed(s)
... 
> >> im = p.close()

The way ImageFile.Parser works, it creates an ImageFile._ParserFile to
act as a file, and calls Image.open() on that. So far so good, and this
results in a valid png image object.. for a very brief moment, because
in the 'finally' section immediately after, it calls close() on that
ImageFile._ParserFile.

The definition of close() in ImageFile._ParserFile is as follows:

    def close(self):
        self.data = self.offset = None

But PngImagePlugin does not copy data on opening - it just keeps a
reference to the source. So this just now destroyed the data on the
object that PngImagePlugin is still referring to as the location of its
IDAT chunks.. not a bright move, because we have now created a condition
where from the point of view of the PngImagePlugin, self.fp is an
ImageFile._ParserFile instance, and self.fp.data is None.

Which means that as soon as we try to do anything with that image,
PngImagePlugin is going to be firing read() instructions at its self.fp,
which in turn blindly trusts that its self.data supports __getitem__()..
and predictably, there is our Traceback:

> >> im.convert('RGB')
Traceback (most recent call last):
  File "<stdin> ", line 1, in <module>
  File "/usr/lib/python2.5/site-packages/PIL/Image.py", line 653, in
convert
    self.load()
  File "/usr/lib/python2.5/site-packages/PIL/ImageFile.py", line 189, in
load
    s = read(self.decodermaxblock)
  File "/usr/lib/python2.5/site-packages/PIL/PngImagePlugin.py", line
365, in load_read
    return self.fp.read(bytes)
  File "/usr/lib/python2.5/site-packages/PIL/ImageFile.py", line 300, in
read
    data = self.data[pos:pos+bytes]
TypeError: 'NoneType' object is unsubscriptable


I am currently working around the issue by creating my own
ImageFile._ParserFile object that avoids having its data None'd.

> >> import ImageFile
> >> import urllib
> >> 
> >> f = urllib.urlopen('<url-path-to-png-file>')
> >> 
> >> p = ImageFile.Parser()
> >> 
> >> while True:
...     s = f.read(1024)
...     if not s:
...         break
...     p.feed(s)
... 
> >> virtualfile = ImageFile._ParserFile(p.data)
> >> im = Image.open(virtualfile)
> >> p.close()
> >> im.convert('RGB')
<Image.Image instance at 0x2b890f5cff80> 


This works great -just need to keep the virtualfile around until I'm
really done with it- but obviously I am not happy having to use what is
supposed to be an internal from ImageFile.

From where I stand, the sensible thing would be to eliminate these two
lines from ImageFile.Parser.close():

            finally:
                fp.close() # explicitly close the virtual file

..except that because of the comment, I must assume that there is a
reason to be doing this. Could someone please shed light on why it is
necessary to explicitly close fp there?

Kind regards,
  Nils Olaf de Reus


_______________________________________________
Image-SIG maillist  -  Image-SIG@[...].org
http://mail.python.org/mailman/listinfo/image-sig
Thread:
Nils Olaf de Reus
Fredrik Lundh
Alexey Borzenkov

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved