I have a file which contains a single image of a specific format at a
specific offset. I can already get a file-like for the embedded image
which supports read(), seek(), and tell(). I want to take advantage
of an existing PIL decoder to handle the embedded image, but be able to
treat the entire file as an "image file" in its own right.

I have not been able to figure out how to do this given the
documentation
available and was wondering if anyone had any insights as to how I could
do this.

2 Answers
2

The relevant chapter of the docs is this one and I think it's fairly clear: if for example you want to decode image files in the new .zap-format, you write a ZapImagePlugin.py module which must perform a couple things:

have a class ZapImageFile(ImageFile.ImageFile): with string attributes format and format_description, and a hook-method def _open(self) (of which more later);

The specs for the _open method are very clearly laid out in the chapter -- it must read image data and metadata from open binary file-like object self.fp, raise SyntaxError (or another exception) ASAP if it detects that the file's not actually in the right format, set at least self.size and self.mode attributes, and in order to allow reading the image, also self.tile, a list of tile descriptors again in the format specified in that chapter (including the file-offset, which you say you know, and a decoder -- if the raw or bit decoders, documented in the chapter, don't meet your needs, the chapter recommends studying the sources of some of the many supplied decoders, such as JPEG, PNG, etc).

What I did to solve this was to derive from the ImageFile.ImageFile child belonging to the embedded format instead of ImageFile.ImageFile directly. Then in _open() I replaced self.fp with the file-like to the embedded image, and called the parent's _open(). I can't say that I'm particularly happy doing it this way, but it seems to have worked.

Sounds like good code reuse. Q: Did your approach result in a new image type and extension being registered, and if so was there anything tricky about doing it?
–
martineauJan 20 at 15:25

@martineau: I needed this to operate on an existing binary stream so I didn't attempt to register anything. To be specific, I was reading a PNG embedded in a game datafile.
–
Ignacio Vazquez-AbramsJan 20 at 16:04