Re: [Image-SIG] PIL 1.1.6 ImageFile.Parser destroys data for PngImagePlugin
by Fredrik Lundh other posts by this author
Nov 4 2009 7:45AM messages near this date
[Image-SIG] PIL 1.1.6 ImageFile.Parser destroys data for PngImagePlugin
|
Re: [Image-SIG] PIL 1.1.6 ImageFile.Parser destroys data for PngImagePlugin
Thanks for the detailed analysis. The fix in 1.1.7 is slightly
different from the one you propose:
http://hg.effbot.org/pil-2009-raclette/changeset/fe4688f15fed/
Not sure why the code considers it important to close the file at that
point; I'll take another look at a look at the code and the history of
that file when I find the time.
</F>
On Wed, Nov 4, 2009 at 2:16 PM, Nils Olaf de Reus
<nils.de.reus@[...].nl> wrote:
> 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
>
_______________________________________________
Image-SIG maillist - Image-SIG@[...].org
http://mail.python.org/mailman/listinfo/image-sig
Thread:
Nils Olaf de Reus
Fredrik Lundh
Alexey Borzenkov
|